{"version":3,"sources":["../src/browser.ts","../src/browser-utils.ts","../src/exceptions.ts","../src/tts_config.ts","../src/constants.ts","../src/browser-drm.ts","../src/browser-communicate.ts","../src/browser-simple.ts","../src/browser-voices.ts","../src/submaker.ts"],"names":["WIN_EPOCH","S_TO_NS"],"mappings":"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","file":"browser.cjs","sourcesContent":["/**\r\n * Browser-compatible version of edge-tts Simple API\r\n * Uses native browser APIs instead of Node.js dependencies\r\n */\r\n\r\n/**\r\n * Options for controlling the voice prosody (rate, pitch, volume).\r\n */\r\nexport interface ProsodyOptions {\r\n  /**\r\n   * The speaking rate of the voice.\r\n   * Examples: \"+10.00%\", \"-20.00%\"\r\n   */\r\n  rate?: string;\r\n  /**\r\n   * The speaking volume of the voice.\r\n   * Examples: \"+15.00%\", \"-10.00%\"\r\n   */\r\n  volume?: string;\r\n  /**\r\n   * The speaking pitch of the voice.\r\n   * Examples: \"+20Hz\", \"-10Hz\"\r\n   */\r\n  pitch?: string;\r\n}\r\n\r\n/**\r\n * Represents a single word boundary with its timing and text.\r\n * The API provides timing in 100-nanosecond units.\r\n */\r\nexport interface WordBoundary {\r\n  /**\r\n   * The offset from the beginning of the audio stream in 100-nanosecond units.\r\n   */\r\n  offset: number;\r\n  /**\r\n   * The duration of the word in 100-nanosecond units.\r\n   */\r\n  duration: number;\r\n  /**\r\n   * The text of the spoken word.\r\n   */\r\n  text: string;\r\n}\r\n\r\n/**\r\n * The final result of the synthesis process.\r\n */\r\nexport interface SynthesisResult {\r\n  /**\r\n   * The generated audio as a Blob, which can be used in an <audio> element.\r\n   */\r\n  audio: Blob;\r\n  /**\r\n   * An array of word boundaries containing timing and text for creating subtitles.\r\n   */\r\n  subtitle: WordBoundary[];\r\n}\r\n\r\n/**\r\n * Browser-compatible Edge TTS class that uses native browser APIs.\r\n * \r\n * @remarks This uses an undocumented Microsoft API. CORS policy may prevent\r\n * direct usage from web apps. Consider using a proxy server.\r\n */\r\nexport class EdgeTTSBrowser {\r\n  public text: string;\r\n  public voice: string;\r\n  public rate: string;\r\n  public volume: string;\r\n  public pitch: string;\r\n\r\n  private ws: WebSocket | null = null;\r\n  private readonly WSS_URL = \"wss://speech.platform.bing.com/consumer/speech/synthesize/readaloud/edge/v1\";\r\n  private readonly TRUSTED_CLIENT_TOKEN = \"6A5AA1D4EAFF4E9FB37E23D68491D6F4\";\r\n\r\n  /**\r\n   * @param text The text to be synthesized.\r\n   * @param voice The voice to use for synthesis.\r\n   * @param options Prosody options (rate, volume, pitch).\r\n   */\r\n  constructor(\r\n    text: string,\r\n    voice = \"Microsoft Server Speech Text to Speech Voice (en-US, EmmaMultilingualNeural)\",\r\n    options: ProsodyOptions = {}\r\n  ) {\r\n    this.text = text;\r\n    this.voice = voice;\r\n    this.rate = options.rate || \"+0%\";\r\n    this.volume = options.volume || \"+0%\";\r\n    this.pitch = options.pitch || \"+0Hz\";\r\n  }\r\n\r\n  /**\r\n   * Initiates the synthesis process.\r\n   * @returns A promise that resolves with the synthesized audio and subtitle data.\r\n   */\r\n  public async synthesize(): Promise<SynthesisResult> {\r\n    await this.connect();\r\n\r\n    if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\r\n      throw new Error(\"WebSocket is not connected.\");\r\n    }\r\n\r\n    this.ws.send(this.createSpeechConfig());\r\n    this.ws.send(this.createSSML());\r\n\r\n    return new Promise((resolve, reject) => {\r\n      const audioChunks: Uint8Array[] = [];\r\n      let wordBoundaries: WordBoundary[] = [];\r\n\r\n      if (this.ws) {\r\n        this.ws.onmessage = (event: MessageEvent) => {\r\n          if (typeof event.data === \"string\") {\r\n            // Text message\r\n            const { headers, body } = this.parseMessage(event.data);\r\n            if (headers.Path === \"audio.metadata\") {\r\n              try {\r\n                const metadata = JSON.parse(body);\r\n                if (metadata.Metadata && Array.isArray(metadata.Metadata)) {\r\n                  const boundaries = metadata.Metadata\r\n                    .filter((item: any) => item.Type === \"WordBoundary\" && item.Data)\r\n                    .map((item: any) => ({\r\n                      offset: item.Data.Offset,\r\n                      duration: item.Data.Duration,\r\n                      text: item.Data.text.Text,\r\n                    }));\r\n                  wordBoundaries = wordBoundaries.concat(boundaries);\r\n                }\r\n              } catch (e) {\r\n                // Ignore JSON parsing errors for metadata\r\n              }\r\n            } else if (headers.Path === \"turn.end\") {\r\n              if (this.ws) this.ws.close();\r\n            }\r\n          } else if (event.data instanceof Blob) {\r\n            // Binary audio message\r\n            event.data.arrayBuffer().then(arrayBuffer => {\r\n              const dataView = new DataView(arrayBuffer);\r\n              const headerLength = dataView.getUint16(0);\r\n\r\n              if (arrayBuffer.byteLength > headerLength + 2) {\r\n                const audioData = new Uint8Array(arrayBuffer, headerLength + 2);\r\n                audioChunks.push(audioData);\r\n              }\r\n            });\r\n          }\r\n        };\r\n\r\n        this.ws.onclose = () => {\r\n          // TS 5.5+ requires BlobPart views to be ArrayBuffer-backed.\r\n          // Our chunks are Uint8Array; cast them for type compatibility.\r\n          const audioBlob = new Blob(\r\n            audioChunks as unknown as ArrayBufferView<ArrayBuffer>[],\r\n            { type: \"audio/mpeg\" }\r\n          );\r\n          resolve({ audio: audioBlob, subtitle: wordBoundaries });\r\n        };\r\n\r\n        this.ws.onerror = (error) => {\r\n          reject(error);\r\n        };\r\n      }\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Establishes a connection to the WebSocket server.\r\n   */\r\n  private connect(): Promise<void> {\r\n    const connectionId = this.generateConnectionId();\r\n    const secMsGec = this.generateSecMsGec();\r\n    const url = `${this.WSS_URL}?TrustedClientToken=${this.TRUSTED_CLIENT_TOKEN}&ConnectionId=${connectionId}&Sec-MS-GEC=${secMsGec}&Sec-MS-GEC-Version=1-130.0.2849.68`;\r\n\r\n    this.ws = new WebSocket(url);\r\n\r\n    return new Promise((resolve, reject) => {\r\n      if (!this.ws) {\r\n        return reject(new Error(\"WebSocket not initialized\"));\r\n      }\r\n      this.ws.onopen = () => {\r\n        resolve();\r\n      };\r\n      this.ws.onerror = (error) => {\r\n        reject(error);\r\n      };\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Parses a string message from the WebSocket into headers and a body.\r\n   */\r\n  private parseMessage(message: string): { headers: Record<string, string>; body: string } {\r\n    const parts = message.split(\"\\r\\n\\r\\n\");\r\n    const headerLines = parts[0].split(\"\\r\\n\");\r\n    const headers: Record<string, string> = {};\r\n    headerLines.forEach(line => {\r\n      const [key, value] = line.split(\":\", 2);\r\n      if (key && value) {\r\n        headers[key.trim()] = value.trim();\r\n      }\r\n    });\r\n    return { headers, body: parts[1] || '' };\r\n  }\r\n\r\n  /**\r\n   * Creates the speech configuration message.\r\n   */\r\n  private createSpeechConfig(): string {\r\n    const config = {\r\n      context: {\r\n        synthesis: {\r\n          audio: {\r\n            metadataoptions: {\r\n              sentenceBoundaryEnabled: false,\r\n              wordBoundaryEnabled: true,\r\n            },\r\n            outputFormat: \"audio-24khz-48kbitrate-mono-mp3\",\r\n          },\r\n        },\r\n      },\r\n    };\r\n    return `X-Timestamp:${this.getTimestamp()}\\r\\nContent-Type:application/json; charset=utf-8\\r\\nPath:speech.config\\r\\n\\r\\n${JSON.stringify(config)}`;\r\n  }\r\n\r\n  /**\r\n   * Creates the SSML (Speech Synthesis Markup Language) message.\r\n   */\r\n  private createSSML(): string {\r\n    const ssml = `<speak version='1.0' xmlns='http://www.w3.org/2001/10/synthesis' xml:lang='en-US'>\r\n      <voice name='${this.voice}'>\r\n        <prosody pitch='${this.pitch}' rate='${this.rate}' volume='${this.volume}'>\r\n          ${this.escapeXml(this.text)}\r\n        </prosody>\r\n      </voice>\r\n    </speak>`;\r\n    return `X-RequestId:${this.generateConnectionId()}\\r\\nContent-Type:application/ssml+xml\\r\\nX-Timestamp:${this.getTimestamp()}Z\\r\\nPath:ssml\\r\\n\\r\\n${ssml}`;\r\n  }\r\n\r\n  private generateConnectionId(): string {\r\n    return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\r\n      const r = (Math.random() * 16) | 0;\r\n      const v = c === \"x\" ? r : (r & 0x3) | 0x8;\r\n      return v.toString(16);\r\n    });\r\n  }\r\n\r\n  private getTimestamp(): string {\r\n    return new Date().toISOString().replace(/[:-]|\\.\\d{3}/g, \"\");\r\n  }\r\n\r\n  private escapeXml(text: string): string {\r\n    return text.replace(/[<>&'\"]/g, (char) => {\r\n      switch (char) {\r\n        case \"<\": return \"&lt;\";\r\n        case \">\": return \"&gt;\";\r\n        case \"&\": return \"&amp;\";\r\n        case \"'\": return \"&apos;\";\r\n        case '\"': return \"&quot;\";\r\n        default: return char;\r\n      }\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Browser-compatible version of DRM security token generation\r\n   * Uses Web Crypto API instead of Node.js crypto\r\n   */\r\n  private async generateSecMsGec(): Promise<string> {\r\n    const WIN_EPOCH = 11644473600;\r\n    const S_TO_NS = 1e9;\r\n\r\n    let ticks = Date.now() / 1000;\r\n    ticks += WIN_EPOCH;\r\n    ticks -= ticks % 300;\r\n    ticks *= S_TO_NS / 100;\r\n\r\n    const strToHash = `${ticks.toFixed(0)}${this.TRUSTED_CLIENT_TOKEN}`;\r\n\r\n    // Use Web Crypto API for hashing\r\n    const encoder = new TextEncoder();\r\n    const data = encoder.encode(strToHash);\r\n    const hashBuffer = await crypto.subtle.digest('SHA-256', data);\r\n    const hashArray = Array.from(new Uint8Array(hashBuffer));\r\n    return hashArray.map(b => b.toString(16).padStart(2, '0')).join('').toUpperCase();\r\n  }\r\n}\r\n\r\n// ==================================================================================\r\n// Subtitle Generation Utilities (Browser Compatible)\r\n// ==================================================================================\r\n\r\n/**\r\n * Formats a time value from 100-nanosecond units into a VTT or SRT timestamp string.\r\n */\r\nfunction formatTimestamp(timeIn100ns: number, format: 'vtt' | 'srt'): string {\r\n  const totalSeconds = Math.floor(timeIn100ns / 10000000);\r\n  const hours = Math.floor(totalSeconds / 3600);\r\n  const minutes = Math.floor((totalSeconds % 3600) / 60);\r\n  const seconds = totalSeconds % 60;\r\n  const milliseconds = Math.floor((timeIn100ns % 10000000) / 10000);\r\n  const separator = format === 'vtt' ? '.' : ',';\r\n  return `${padNumber(hours)}:${padNumber(minutes)}:${padNumber(seconds)}${separator}${padNumber(milliseconds, 3)}`;\r\n}\r\n\r\n/**\r\n * Pads a number with leading zeros to a specified length.\r\n */\r\nfunction padNumber(num: number, length = 2): string {\r\n  return num.toString().padStart(length, '0');\r\n}\r\n\r\n/**\r\n * Creates a subtitle file content in VTT (WebVTT) format.\r\n */\r\nexport function createVTT(wordBoundaries: WordBoundary[]): string {\r\n  let vttContent = \"WEBVTT\\n\\n\";\r\n  wordBoundaries.forEach((word, index) => {\r\n    const startTime = formatTimestamp(word.offset, 'vtt');\r\n    const endTime = formatTimestamp(word.offset + word.duration, 'vtt');\r\n    vttContent += `${index + 1}\\n`;\r\n    vttContent += `${startTime} --> ${endTime}\\n`;\r\n    vttContent += `${word.text}\\n\\n`;\r\n  });\r\n  return vttContent;\r\n}\r\n\r\n/**\r\n * Creates a subtitle file content in SRT (SubRip) format.\r\n */\r\nexport function createSRT(wordBoundaries: WordBoundary[]): string {\r\n  let srtContent = \"\";\r\n  wordBoundaries.forEach((word, index) => {\r\n    const startTime = formatTimestamp(word.offset, 'srt');\r\n    const endTime = formatTimestamp(word.offset + word.duration, 'srt');\r\n    srtContent += `${index + 1}\\n`;\r\n    srtContent += `${startTime} --> ${endTime}\\n`;\r\n    srtContent += `${word.text}\\n\\n`;\r\n  });\r\n  return srtContent;\r\n} \r\n","/**\r\n * Browser-specific utility functions that avoid Node.js dependencies.\r\n * Provides browser-native implementations of UUID generation and XML escaping.\r\n */\r\n\r\n/**\r\n * Generates a UUID v4 string without hyphens using browser's crypto API.\r\n * @returns UUID string with hyphens removed\r\n */\r\nexport function browserConnectId(): string {\r\n  // Use crypto.getRandomValues for browser-native UUID generation\r\n  const array = new Uint8Array(16);\r\n  crypto.getRandomValues(array);\r\n\r\n  // Set version (4) and variant bits according to RFC 4122\r\n  array[6] = (array[6] & 0x0f) | 0x40;\r\n  array[8] = (array[8] & 0x3f) | 0x80;\r\n\r\n  // Convert to hex string and format as UUID, then remove hyphens\r\n  const hex = Array.from(array, byte => byte.toString(16).padStart(2, '0')).join('');\r\n  const uuid = `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;\r\n\r\n  return uuid.replace(/-/g, '');\r\n}\r\n\r\n/**\r\n * Browser-native XML escaping function.\r\n * @param text - Text to escape\r\n * @returns XML-escaped text\r\n */\r\nexport function browserEscape(text: string): string {\r\n  return text\r\n    .replace(/&/g, '&amp;')\r\n    .replace(/</g, '&lt;')\r\n    .replace(/>/g, '&gt;')\r\n    .replace(/\"/g, '&quot;')\r\n    .replace(/'/g, '&apos;');\r\n}\r\n\r\n/**\r\n * Unescapes XML entities in text.\r\n * @param text - Text containing XML entities to unescape\r\n * @returns Text with XML entities converted back to their original characters\r\n */\r\nexport function browserUnescape(text: string): string {\r\n  return text\r\n    .replace(/&quot;/g, '\"')\r\n    .replace(/&apos;/g, \"'\")\r\n    .replace(/&lt;/g, '<')\r\n    .replace(/&gt;/g, '>')\r\n    .replace(/&amp;/g, '&'); // Do &amp; last to avoid double unescaping\r\n}\r\n\r\n/**\r\n * Removes control characters that are incompatible with TTS processing.\r\n * @param text - Input text to clean\r\n * @returns Text with control characters replaced by spaces\r\n */\r\nexport function browserRemoveIncompatibleCharacters(text: string): string {\r\n  // Remove control characters (U+0000 to U+001F except \\t, \\n, \\r)\r\n  // eslint-disable-next-line no-control-regex\r\n  return text.replace(/[\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F]/g, ' ');\r\n}\r\n\r\n/**\r\n * Formats the current date as a string in the format expected by the TTS service.\r\n * @returns Formatted date string\r\n */\r\nexport function browserDateToString(): string {\r\n  return new Date().toUTCString().replace(\"GMT\", \"GMT+0000 (Coordinated Universal Time)\");\r\n}\r\n\r\n/**\r\n * Creates SSML (Speech Synthesis Markup Language) from text and voice configuration.\r\n * @param voice - Voice name\r\n * @param rate - Speech rate (e.g., \"+0%\")\r\n * @param volume - Speech volume (e.g., \"+0%\") \r\n * @param pitch - Speech pitch (e.g., \"+0Hz\")\r\n * @param escapedText - Text content (should be XML-escaped)\r\n * @returns Complete SSML document string\r\n */\r\nexport function browserMkssml(voice: string, rate: string, volume: string, pitch: string, escapedText: string): string {\r\n  return (\r\n    \"<speak version='1.0' xmlns='http://www.w3.org/2001/10/synthesis' xml:lang='en-US'>\"\r\n    + `<voice name='${voice}'>`\r\n    + `<prosody pitch='${pitch}' rate='${rate}' volume='${volume}'>`\r\n    + `${escapedText}`\r\n    + \"</prosody>\"\r\n    + \"</voice>\"\r\n    + \"</speak>\"\r\n  );\r\n}\r\n\r\n/**\r\n * Creates a complete WebSocket message with headers and SSML data.\r\n * @param requestId - Unique request identifier\r\n * @param timestamp - Timestamp string for the request\r\n * @param ssml - SSML content to include in the message\r\n * @returns Complete WebSocket message string with headers and data\r\n */\r\nexport function browserSsmlHeadersPlusData(requestId: string, timestamp: string, ssml: string): string {\r\n  return (\r\n    `X-RequestId:${requestId}\\r\\n`\r\n    + \"Content-Type:application/ssml+xml\\r\\n\"\r\n    + `X-Timestamp:${timestamp}Z\\r\\n`  // This is not a mistake, Microsoft Edge bug.\r\n    + \"Path:ssml\\r\\n\\r\\n\"\r\n    + `${ssml}`\r\n  );\r\n}\r\n\r\n/**\r\n * Calculates the maximum message size for text chunks based on WebSocket limits.\r\n * @param voice - Voice name\r\n * @param rate - Speech rate\r\n * @param volume - Speech volume\r\n * @param pitch - Speech pitch\r\n * @returns Maximum byte size for text content in a single message\r\n */\r\nexport function browserCalcMaxMesgSize(voice: string, rate: string, volume: string, pitch: string): number {\r\n  const websocketMaxSize = 2 ** 16;\r\n  const overheadPerMessage = browserSsmlHeadersPlusData(\r\n    browserConnectId(),\r\n    browserDateToString(),\r\n    browserMkssml(voice, rate, volume, pitch, \"\"),\r\n  ).length + 50; // margin of error\r\n  return websocketMaxSize - overheadPerMessage;\r\n} ","/**\r\n * Base exception class for all Edge TTS related errors.\r\n */\r\nexport class EdgeTTSException extends Error {\r\n  constructor(message: string) {\r\n    super(message);\r\n    this.name = \"EdgeTTSException\";\r\n  }\r\n}\r\n\r\n/**\r\n * Exception raised when there's an error adjusting clock skew for API requests.\r\n * This typically occurs when the client and server clocks are significantly out of sync.\r\n */\r\nexport class SkewAdjustmentError extends EdgeTTSException {\r\n  constructor(message: string) {\r\n    super(message);\r\n    this.name = \"SkewAdjustmentError\";\r\n  }\r\n}\r\n\r\n/**\r\n * Exception raised when an unknown response is received from the TTS service.\r\n * This indicates an unexpected message type or format that the client cannot handle.\r\n */\r\nexport class UnknownResponse extends EdgeTTSException {\r\n  constructor(message: string) {\r\n    super(message);\r\n    this.name = \"UnknownResponse\";\r\n  }\r\n}\r\n\r\n/**\r\n * Exception raised when an unexpected response is received from the TTS service.\r\n * This indicates a response that doesn't match the expected protocol flow.\r\n */\r\nexport class UnexpectedResponse extends EdgeTTSException {\r\n  constructor(message: string) {\r\n    super(message);\r\n    this.name = \"UnexpectedResponse\";\r\n  }\r\n}\r\n\r\n/**\r\n * Exception raised when no audio data is received during synthesis.\r\n * This typically indicates a problem with the synthesis request or service.\r\n */\r\nexport class NoAudioReceived extends EdgeTTSException {\r\n  constructor(message: string) {\r\n    super(message);\r\n    this.name = \"NoAudioReceived\";\r\n  }\r\n}\r\n\r\n/**\r\n * Exception raised when there's an error with the WebSocket connection.\r\n * This can occur during connection establishment, data transmission, or connection closure.\r\n */\r\nexport class WebSocketError extends EdgeTTSException {\r\n  constructor(message: string) {\r\n    super(message);\r\n    this.name = \"WebSocketError\";\r\n  }\r\n}\r\n\r\n/**\r\n * Exception raised when an invalid value is provided to a function or method.\r\n * This is typically used for input validation errors.\r\n */\r\nexport class ValueError extends EdgeTTSException {\r\n  constructor(message: string) {\r\n    super(message);\r\n    this.name = \"ValueError\";\r\n  }\r\n} ","import { ValueError } from \"./exceptions\";\r\n\r\n/**\r\n * Interface defining the configuration options for TTS synthesis.\r\n */\r\nexport interface ITTSConfig {\r\n  /** Voice name to use for synthesis */\r\n  voice: string;\r\n  /** Speech rate adjustment (e.g., \"+20%\", \"-10%\") */\r\n  rate: string;\r\n  /** Volume level adjustment (e.g., \"+50%\", \"-25%\") */\r\n  volume: string;\r\n  /** Pitch adjustment in Hz (e.g., \"+5Hz\", \"-10Hz\") */\r\n  pitch: string;\r\n}\r\n\r\n/**\r\n * Configuration class for TTS synthesis parameters.\r\n * Handles voice name normalization and parameter validation.\r\n * \r\n * @example\r\n * ```typescript\r\n * const config = new TTSConfig({\r\n *   voice: 'en-US-EmmaMultilingualNeural',\r\n *   rate: '+20%',\r\n *   volume: '+10%',\r\n *   pitch: '+5Hz'\r\n * });\r\n * ```\r\n */\r\nexport class TTSConfig implements ITTSConfig {\r\n  public voice: string;\r\n  public rate: string;\r\n  public volume: string;\r\n  public pitch: string;\r\n\r\n  /**\r\n   * Creates a new TTSConfig instance with the specified parameters.\r\n   * \r\n   * @param options - Configuration options\r\n   * @param options.voice - Voice name (supports both short and full formats)\r\n   * @param options.rate - Speech rate adjustment (default: \"+0%\")\r\n   * @param options.volume - Volume adjustment (default: \"+0%\") \r\n   * @param options.pitch - Pitch adjustment (default: \"+0Hz\")\r\n   * @throws {ValueError} If any parameter has an invalid format\r\n   */\r\n  constructor({\r\n    voice,\r\n    rate = \"+0%\",\r\n    volume = \"+0%\",\r\n    pitch = \"+0Hz\",\r\n  }: {\r\n    voice: string,\r\n    rate?: string,\r\n    volume?: string,\r\n    pitch?: string,\r\n  }) {\r\n    this.voice = voice;\r\n    this.rate = rate;\r\n    this.volume = volume;\r\n    this.pitch = pitch;\r\n\r\n    this.validate();\r\n  }\r\n\r\n  private validate() {\r\n    // Voice validation and transformation\r\n    const match = /^([a-z]{2,})-([A-Z]{2,})-(.+Neural)$/.exec(this.voice);\r\n    if (match) {\r\n      const [, lang] = match;\r\n      let [, , region, name] = match;\r\n      if (name.includes('-')) {\r\n        const parts = name.split('-');\r\n        region += `-${parts[0]}`;\r\n        name = parts[1];\r\n      }\r\n      this.voice = `Microsoft Server Speech Text to Speech Voice (${lang}-${region}, ${name})`;\r\n    }\r\n\r\n    TTSConfig.validateStringParam(\r\n      \"voice\",\r\n      this.voice,\r\n      /^Microsoft Server Speech Text to Speech Voice \\(.+,.+\\)$/\r\n    );\r\n    TTSConfig.validateStringParam(\"rate\", this.rate, /^[+-]\\d+%$/);\r\n    TTSConfig.validateStringParam(\"volume\", this.volume, /^[+-]\\d+%$/);\r\n    TTSConfig.validateStringParam(\"pitch\", this.pitch, /^[+-]\\d+Hz$/);\r\n  }\r\n\r\n  private static validateStringParam(paramName: string, paramValue: string, pattern: RegExp) {\r\n    if (typeof paramValue !== 'string') {\r\n      throw new TypeError(`${paramName} must be a string`);\r\n    }\r\n    if (!pattern.test(paramValue)) {\r\n      throw new ValueError(`Invalid ${paramName} '${paramValue}'.`);\r\n    }\r\n  }\r\n} ","/** Base URL for Microsoft Edge TTS service endpoints */\r\nexport const BASE_URL = \"speech.platform.bing.com/consumer/speech/synthesize/readaloud\";\r\n\r\n/** Trusted client token used for authentication with the TTS service */\r\nexport const TRUSTED_CLIENT_TOKEN = \"6A5AA1D4EAFF4E9FB37E23D68491D6F4\";\r\n\r\n/** WebSocket URL for TTS streaming synthesis */\r\nexport const WSS_URL = `wss://${BASE_URL}/edge/v1?TrustedClientToken=${TRUSTED_CLIENT_TOKEN}`;\r\n\r\n/** HTTP URL for fetching available voices list */\r\nexport const VOICE_LIST_URL = `https://${BASE_URL}/voices/list?trustedclienttoken=${TRUSTED_CLIENT_TOKEN}`;\r\n\r\n/** Default voice to use when none is specified */\r\nexport const DEFAULT_VOICE = \"en-US-EmmaMultilingualNeural\";\r\n\r\n/** Version string for Chromium browser emulation */\r\nexport const CHROMIUM_FULL_VERSION = \"142.0.3595.94\";\r\n\r\n/** Major version number extracted from the full Chromium version */\r\nexport const CHROMIUM_MAJOR_VERSION = CHROMIUM_FULL_VERSION.split(\".\")[0];\r\n\r\n/** Security token version for API authentication */\r\nexport const SEC_MS_GEC_VERSION = `1-${CHROMIUM_FULL_VERSION}`;\r\n\r\n/** Base HTTP headers for API requests, mimicking a real browser */\r\nexport const BASE_HEADERS = {\r\n  \"User-Agent\": `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${CHROMIUM_MAJOR_VERSION}.0.0.0 Safari/537.36 Edg/${CHROMIUM_MAJOR_VERSION}.0.0.0`,\r\n  \"Accept-Encoding\": \"gzip, deflate, br\",\r\n  \"Accept-Language\": \"en-US,en;q=0.9\",\r\n};\r\n\r\n/** HTTP headers specific to WebSocket connection requests */\r\nexport const WSS_HEADERS = {\r\n  ...BASE_HEADERS,\r\n  \"Pragma\": \"no-cache\",\r\n  \"Cache-Control\": \"no-cache\",\r\n  \"Origin\": \"chrome-extension://jdiccldimpdaibmpdkjnbmckianbfold\",\r\n  \"Sec-WebSocket-Protocol\": \"synthesize\",\r\n  \"Sec-WebSocket-Version\": \"13\",\r\n};\r\n\r\n/** HTTP headers specific to voice list API requests */\r\nexport const VOICE_HEADERS = {\r\n  ...BASE_HEADERS,\r\n  \"Authority\": \"speech.platform.bing.com\",\r\n  \"Sec-CH-UA\": `\"Chromium\";v=\"${CHROMIUM_MAJOR_VERSION}\", \"Microsoft Edge\";v=\"${CHROMIUM_MAJOR_VERSION}\", \"Not_A Brand\";v=\"99\"`,\r\n  \"Sec-CH-UA-Mobile\": \"?0\",\r\n  \"Accept\": \"*/*\",\r\n  \"Sec-Fetch-Site\": \"none\",\r\n  \"Sec-Fetch-Mode\": \"cors\",\r\n  \"Sec-Fetch-Dest\": \"empty\",\r\n}; ","import { TRUSTED_CLIENT_TOKEN } from './constants';\r\nimport { SkewAdjustmentError } from \"./exceptions\";\r\n\r\nconst WIN_EPOCH = 11644473600;\r\nconst S_TO_NS = 1e9;\r\n\r\n/**\r\n * Browser-specific DRM class that uses only Web APIs.\r\n * Uses the Web Crypto API instead of Node.js crypto module.\r\n */\r\nexport class BrowserDRM {\r\n  private static clockSkewSeconds = 0.0;\r\n\r\n  static adjClockSkewSeconds(skewSeconds: number) {\r\n    BrowserDRM.clockSkewSeconds += skewSeconds;\r\n  }\r\n\r\n  static getUnixTimestamp(): number {\r\n    return Date.now() / 1000 + BrowserDRM.clockSkewSeconds;\r\n  }\r\n\r\n  static parseRfc2616Date(date: string): number | null {\r\n    try {\r\n      return new Date(date).getTime() / 1000;\r\n    } catch (e) {\r\n      return null;\r\n    }\r\n  }\r\n\r\n  static handleClientResponseError(response: { status: number; headers: Record<string, string> }) {\r\n    if (!response.headers) {\r\n      throw new SkewAdjustmentError(\"No headers in response.\");\r\n    }\r\n    const serverDate = response.headers[\"date\"] || response.headers[\"Date\"];\r\n    if (!serverDate) {\r\n      throw new SkewAdjustmentError(\"No server date in headers.\");\r\n    }\r\n    const serverDateParsed = BrowserDRM.parseRfc2616Date(serverDate);\r\n    if (serverDateParsed === null) {\r\n      throw new SkewAdjustmentError(`Failed to parse server date: ${serverDate}`);\r\n    }\r\n    const clientDate = BrowserDRM.getUnixTimestamp();\r\n    BrowserDRM.adjClockSkewSeconds(serverDateParsed - clientDate);\r\n  }\r\n\r\n  static async generateSecMsGec(): Promise<string> {\r\n    let ticks = BrowserDRM.getUnixTimestamp();\r\n    ticks += WIN_EPOCH;\r\n    ticks -= ticks % 300;\r\n    ticks *= S_TO_NS / 100;\r\n\r\n    const strToHash = `${ticks.toFixed(0)}${TRUSTED_CLIENT_TOKEN}`;\r\n\r\n    // Use Web Crypto API - guaranteed to be available in browsers\r\n    const encoder = new TextEncoder();\r\n    const data = encoder.encode(strToHash);\r\n    const hashBuffer = await crypto.subtle.digest('SHA-256', data);\r\n    const hashArray = Array.from(new Uint8Array(hashBuffer));\r\n    return hashArray.map(b => b.toString(16).padStart(2, '0')).join('').toUpperCase();\r\n  }\r\n} ","import {\r\n  browserConnectId,\r\n  browserEscape,\r\n  browserUnescape,\r\n  browserSsmlHeadersPlusData,\r\n  browserDateToString,\r\n  browserMkssml,\r\n  browserRemoveIncompatibleCharacters,\r\n} from './browser-utils';\r\nimport {\r\n  NoAudioReceived,\r\n  UnexpectedResponse,\r\n  UnknownResponse,\r\n  WebSocketError\r\n} from \"./exceptions\";\r\nimport { TTSConfig } from './tts_config';\r\nimport { DEFAULT_VOICE, WSS_URL, SEC_MS_GEC_VERSION } from './constants';\r\nimport { BrowserDRM } from './browser-drm';\r\nimport { AudioOutputFormat } from './types';\r\n\r\n// Browser-specific types (avoiding Node.js Buffer dependency)\r\nexport type BrowserTTSChunk = {\r\n  type: \"audio\" | \"WordBoundary\";\r\n  data?: Uint8Array;\r\n  duration?: number;\r\n  offset?: number;\r\n  text?: string;\r\n};\r\n\r\nexport type BrowserCommunicateState = {\r\n  partialText: Uint8Array;\r\n  offsetCompensation: number;\r\n  lastDurationOffset: number;\r\n  streamWasCalled: boolean;\r\n};\r\n\r\n// Browser-compatible Buffer utilities\r\nclass BrowserBuffer {\r\n  static from(input: string | ArrayBuffer | Uint8Array, encoding?: string): Uint8Array {\r\n    if (typeof input === 'string') {\r\n      return new TextEncoder().encode(input);\r\n    } else if (input instanceof ArrayBuffer) {\r\n      return new Uint8Array(input);\r\n    } else if (input instanceof Uint8Array) {\r\n      return input;\r\n    }\r\n    throw new Error('Unsupported input type for BrowserBuffer.from');\r\n  }\r\n\r\n  static concat(arrays: Uint8Array[]): Uint8Array {\r\n    const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0);\r\n    const result = new Uint8Array(totalLength);\r\n    let offset = 0;\r\n    for (const arr of arrays) {\r\n      result.set(arr, offset);\r\n      offset += arr.length;\r\n    }\r\n    return result;\r\n  }\r\n}\r\n\r\n// Browser-compatible versions of utility functions\r\nfunction browserGetHeadersAndDataFromText(message: Uint8Array): [{ [key: string]: string }, Uint8Array] {\r\n  const messageString = new TextDecoder().decode(message);\r\n  const headerEndIndex = messageString.indexOf('\\r\\n\\r\\n');\r\n\r\n  const headers: { [key: string]: string } = {};\r\n  if (headerEndIndex !== -1) {\r\n    const headerString = messageString.substring(0, headerEndIndex);\r\n    const headerLines = headerString.split('\\r\\n');\r\n    for (const line of headerLines) {\r\n      const [key, value] = line.split(':', 2);\r\n      if (key && value) {\r\n        headers[key] = value.trim();\r\n      }\r\n    }\r\n  }\r\n\r\n  const headerByteLength = new TextEncoder().encode(messageString.substring(0, headerEndIndex + 4)).length;\r\n  return [headers, message.slice(headerByteLength)];\r\n}\r\n\r\nfunction browserGetHeadersAndDataFromBinary(message: Uint8Array): [{ [key: string]: string }, Uint8Array] {\r\n  if (message.length < 2) {\r\n    throw new Error('Message too short to contain header length');\r\n  }\r\n\r\n  const headerLength = (message[0] << 8) | message[1]; // Read big-endian uint16\r\n  const headers: { [key: string]: string } = {};\r\n\r\n  if (headerLength > 0 && headerLength + 2 <= message.length) {\r\n    const headerBytes = message.slice(2, headerLength + 2);\r\n    const headerString = new TextDecoder().decode(headerBytes);\r\n    const headerLines = headerString.split('\\r\\n');\r\n    for (const line of headerLines) {\r\n      const [key, value] = line.split(':', 2);\r\n      if (key && value) {\r\n        headers[key] = value.trim();\r\n      }\r\n    }\r\n  }\r\n\r\n  return [headers, message.slice(headerLength + 2)];\r\n}\r\n\r\nfunction browserSplitTextByByteLength(text: string, byteLength: number): Generator<Uint8Array> {\r\n  return (function* () {\r\n    let buffer = new TextEncoder().encode(text);\r\n\r\n    if (byteLength <= 0) {\r\n      throw new Error(\"byteLength must be greater than 0\");\r\n    }\r\n\r\n    while (buffer.length > byteLength) {\r\n      let splitAt = byteLength;\r\n\r\n      // Try to find a good split point (space or newline)\r\n      const slice = buffer.slice(0, byteLength);\r\n      const sliceText = new TextDecoder().decode(slice);\r\n      const lastNewline = sliceText.lastIndexOf('\\n');\r\n      const lastSpace = sliceText.lastIndexOf(' ');\r\n\r\n      if (lastNewline > 0) {\r\n        splitAt = new TextEncoder().encode(sliceText.substring(0, lastNewline)).length;\r\n      } else if (lastSpace > 0) {\r\n        splitAt = new TextEncoder().encode(sliceText.substring(0, lastSpace)).length;\r\n      }\r\n\r\n      const chunk = buffer.slice(0, splitAt);\r\n      const chunkText = new TextDecoder().decode(chunk).trim();\r\n      if (chunkText) {\r\n        yield new TextEncoder().encode(chunkText);\r\n      }\r\n\r\n      buffer = buffer.slice(splitAt);\r\n    }\r\n\r\n    const remainingText = new TextDecoder().decode(buffer).trim();\r\n    if (remainingText) {\r\n      yield new TextEncoder().encode(remainingText);\r\n    }\r\n  })();\r\n}\r\n\r\n/**\r\n * Configuration options for the browser Communicate class.\r\n */\r\nexport interface BrowserCommunicateOptions {\r\n  /** Voice to use for synthesis (e.g., \"en-US-EmmaMultilingualNeural\") */\r\n  voice?: string;\r\n  /** Speech rate adjustment (e.g., \"+20%\", \"-10%\") */\r\n  rate?: string;\r\n  /** Volume level adjustment (e.g., \"+50%\", \"-25%\") */\r\n  volume?: string;\r\n  /** Pitch adjustment in Hz (e.g., \"+5Hz\", \"-10Hz\") */\r\n  pitch?: string;\r\n  /** Audio output format (default: \"audio-24khz-48kbitrate-mono-mp3\") */\r\n  format?: AudioOutputFormat;\r\n  /** WebSocket connection timeout in milliseconds */\r\n  connectionTimeout?: number;\r\n}\r\n\r\n/**\r\n * Browser-specific Communicate class that uses only browser-native APIs.\r\n * Uses native WebSocket and Web Crypto API, avoiding any Node.js dependencies.\r\n * \r\n * @example\r\n * ```typescript\r\n * const communicate = new BrowserCommunicate('Hello, world!', {\r\n *   voice: 'en-US-EmmaMultilingualNeural',\r\n *   format: 'audio-24khz-48kbitrate-mono-mp3',\r\n * });\r\n * \r\n * for await (const chunk of communicate.stream()) {\r\n *   if (chunk.type === 'audio' && chunk.data) {\r\n *     // Handle audio data\r\n *   }\r\n * }\r\n * ```\r\n */\r\nexport class BrowserCommunicate {\r\n  private readonly ttsConfig: TTSConfig;\r\n  private readonly texts: Generator<Uint8Array>;\r\n  private readonly format: AudioOutputFormat;\r\n  private readonly connectionTimeout?: number;\r\n\r\n  private state: BrowserCommunicateState = {\r\n    partialText: BrowserBuffer.from(''),\r\n    offsetCompensation: 0,\r\n    lastDurationOffset: 0,\r\n    streamWasCalled: false,\r\n  };\r\n\r\n  /**\r\n   * Creates a new browser Communicate instance for text-to-speech synthesis.\r\n   * \r\n   * @param text - The text to synthesize\r\n   * @param options - Configuration options for synthesis\r\n   * @param options.format - Audio output format (default: \"audio-24khz-48kbitrate-mono-mp3\")\r\n   */\r\n  constructor(text: string, options: BrowserCommunicateOptions = {}) {\r\n    this.ttsConfig = new TTSConfig({\r\n      voice: options.voice || DEFAULT_VOICE,\r\n      rate: options.rate,\r\n      volume: options.volume,\r\n      pitch: options.pitch,\r\n    });\r\n\r\n    if (typeof text !== 'string') {\r\n      throw new TypeError('text must be a string');\r\n    }\r\n\r\n    this.texts = browserSplitTextByByteLength(\r\n      browserEscape(browserRemoveIncompatibleCharacters(text)),\r\n      // browserCalcMaxMesgSize(this.ttsConfig.voice, this.ttsConfig.rate, this.ttsConfig.volume, this.ttsConfig.pitch),\r\n      4096,\r\n    );\r\n\r\n    this.format = options.format || ('audio-24khz-48kbitrate-mono-mp3' as AudioOutputFormat);\r\n    this.connectionTimeout = options.connectionTimeout;\r\n  }\r\n\r\n  private parseMetadata(data: Uint8Array): BrowserTTSChunk {\r\n    const metadata = JSON.parse(new TextDecoder().decode(data));\r\n    for (const metaObj of metadata['Metadata']) {\r\n      const metaType = metaObj['Type'];\r\n      if (metaType === 'WordBoundary') {\r\n        const currentOffset = metaObj['Data']['Offset'] + this.state.offsetCompensation;\r\n        const currentDuration = metaObj['Data']['Duration'];\r\n        return {\r\n          type: metaType,\r\n          offset: currentOffset,\r\n          duration: currentDuration,\r\n          text: browserUnescape(metaObj['Data']['text']['Text']),\r\n        };\r\n      }\r\n      if (metaType === 'SessionEnd') {\r\n        continue;\r\n      }\r\n      throw new UnknownResponse(`Unknown metadata type: ${metaType}`);\r\n    }\r\n    throw new UnexpectedResponse('No WordBoundary metadata found');\r\n  }\r\n\r\n  private async * _stream(): AsyncGenerator<BrowserTTSChunk, void, unknown> {\r\n    const url = `${WSS_URL}&Sec-MS-GEC=${await BrowserDRM.generateSecMsGec()}&Sec-MS-GEC-Version=${SEC_MS_GEC_VERSION}&ConnectionId=${browserConnectId()}`;\r\n\r\n    const websocket = new WebSocket(url);\r\n    const messageQueue: (BrowserTTSChunk | Error | 'close')[] = [];\r\n    let resolveMessage: (() => void) | null = null;\r\n\r\n    // Set connection timeout if specified\r\n    let timeoutId: number | undefined;\r\n    if (this.connectionTimeout) {\r\n      timeoutId = window.setTimeout(() => {\r\n        websocket.close();\r\n        messageQueue.push(new WebSocketError('Connection timeout'));\r\n        if (resolveMessage) resolveMessage();\r\n      }, this.connectionTimeout);\r\n    }\r\n\r\n    websocket.onmessage = (event: MessageEvent) => {\r\n      // Clear timeout on first message\r\n      if (timeoutId) {\r\n        window.clearTimeout(timeoutId);\r\n        timeoutId = undefined;\r\n      }\r\n\r\n      const data = event.data;\r\n      const isBinary = data instanceof ArrayBuffer || data instanceof Blob;\r\n\r\n      if (typeof data === 'string') {\r\n        // Text message\r\n        const [headers, parsedData] = browserGetHeadersAndDataFromText(BrowserBuffer.from(data));\r\n\r\n        const path = headers['Path'];\r\n        if (path === 'audio.metadata') {\r\n          try {\r\n            const parsedMetadata = this.parseMetadata(parsedData);\r\n            this.state.lastDurationOffset = parsedMetadata.offset! + parsedMetadata.duration!;\r\n            messageQueue.push(parsedMetadata);\r\n          } catch (e) {\r\n            messageQueue.push(e as Error);\r\n          }\r\n        } else if (path === 'turn.end') {\r\n          this.state.offsetCompensation = this.state.lastDurationOffset;\r\n          websocket.close();\r\n        } else if (path !== 'response' && path !== 'turn.start') {\r\n          messageQueue.push(new UnknownResponse(`Unknown path received: ${path}`));\r\n        }\r\n      } else if (data instanceof ArrayBuffer) {\r\n        // Binary message\r\n        const bufferData = BrowserBuffer.from(data);\r\n        if (bufferData.length < 2) {\r\n          messageQueue.push(new UnexpectedResponse('We received a binary message, but it is missing the header length.'));\r\n        } else {\r\n          const [headers, audioData] = browserGetHeadersAndDataFromBinary(bufferData);\r\n\r\n          if (headers['Path'] !== 'audio') {\r\n            messageQueue.push(new UnexpectedResponse('Received binary message, but the path is not audio.'));\r\n          } else {\r\n            const contentType = headers['Content-Type'];\r\n            if (contentType !== 'audio/mpeg') {\r\n              if (audioData.length > 0) {\r\n                messageQueue.push(new UnexpectedResponse('Received binary message, but with an unexpected Content-Type.'));\r\n              }\r\n            } else if (audioData.length === 0) {\r\n              messageQueue.push(new UnexpectedResponse('Received binary message, but it is missing the audio data.'));\r\n            } else {\r\n              messageQueue.push({ type: 'audio', data: audioData });\r\n            }\r\n          }\r\n        }\r\n      } else if (data instanceof Blob) {\r\n        // Handle Blob data (convert to ArrayBuffer first)\r\n        data.arrayBuffer().then(arrayBuffer => {\r\n          const bufferData = BrowserBuffer.from(arrayBuffer);\r\n          if (bufferData.length < 2) {\r\n            messageQueue.push(new UnexpectedResponse('We received a binary message, but it is missing the header length.'));\r\n          } else {\r\n            const [headers, audioData] = browserGetHeadersAndDataFromBinary(bufferData);\r\n\r\n            if (headers['Path'] !== 'audio') {\r\n              messageQueue.push(new UnexpectedResponse('Received binary message, but the path is not audio.'));\r\n            } else {\r\n              const contentType = headers['Content-Type'];\r\n              if (contentType !== 'audio/mpeg') {\r\n                if (audioData.length > 0) {\r\n                  messageQueue.push(new UnexpectedResponse('Received binary message, but with an unexpected Content-Type.'));\r\n                }\r\n              } else if (audioData.length === 0) {\r\n                messageQueue.push(new UnexpectedResponse('Received binary message, but it is missing the audio data.'));\r\n              } else {\r\n                messageQueue.push({ type: 'audio', data: audioData });\r\n              }\r\n            }\r\n          }\r\n          if (resolveMessage) resolveMessage();\r\n        });\r\n      }\r\n\r\n      if (resolveMessage) resolveMessage();\r\n    };\r\n\r\n    websocket.onerror = (error: Event) => {\r\n      if (timeoutId) {\r\n        window.clearTimeout(timeoutId);\r\n        timeoutId = undefined;\r\n      }\r\n      messageQueue.push(new WebSocketError('WebSocket error occurred'));\r\n      if (resolveMessage) resolveMessage();\r\n    };\r\n\r\n    websocket.onclose = () => {\r\n      if (timeoutId) {\r\n        window.clearTimeout(timeoutId);\r\n        timeoutId = undefined;\r\n      }\r\n      messageQueue.push('close');\r\n      if (resolveMessage) resolveMessage();\r\n    };\r\n\r\n    await new Promise<void>((resolve, reject) => {\r\n      websocket.onopen = () => {\r\n        if (timeoutId) {\r\n          window.clearTimeout(timeoutId);\r\n          timeoutId = undefined;\r\n        }\r\n        resolve();\r\n      };\r\n\r\n      // Set up a timeout for connection establishment\r\n      if (this.connectionTimeout) {\r\n        setTimeout(() => {\r\n          if (websocket.readyState === WebSocket.CONNECTING) {\r\n            websocket.close();\r\n            reject(new WebSocketError('Connection timeout'));\r\n          }\r\n        }, this.connectionTimeout);\r\n      }\r\n    });\r\n\r\n    websocket.send(\r\n      `X-Timestamp:${browserDateToString()}\\r\\n`\r\n      + 'Content-Type:application/json; charset=utf-8\\r\\n'\r\n      + 'Path:speech.config\\r\\n\\r\\n'\r\n      + `{\"context\":{\"synthesis\":{\"audio\":{\"metadataoptions\":{`\r\n      + `\"sentenceBoundaryEnabled\":\"false\",\"wordBoundaryEnabled\":\"true\"},`\r\n      + `\"outputFormat\":\"${this.format}\"`\r\n      + `}}}}\\r\\n`\r\n    );\r\n\r\n    websocket.send(\r\n      browserSsmlHeadersPlusData(\r\n        browserConnectId(),\r\n        browserDateToString(),\r\n        browserMkssml(this.ttsConfig.voice, this.ttsConfig.rate, this.ttsConfig.volume, this.ttsConfig.pitch, new TextDecoder().decode(this.state.partialText)),\r\n      )\r\n    );\r\n\r\n    let audioWasReceived = false;\r\n    while (true) {\r\n      if (messageQueue.length > 0) {\r\n        const message = messageQueue.shift()!;\r\n        if (message === 'close') {\r\n          if (!audioWasReceived) {\r\n            throw new NoAudioReceived('No audio was received.');\r\n          }\r\n          break;\r\n        } else if (message instanceof Error) {\r\n          throw message;\r\n        } else {\r\n          if (message.type === 'audio') audioWasReceived = true;\r\n          yield message;\r\n        }\r\n      } else {\r\n        // Use a more responsive wait mechanism\r\n        await new Promise<void>(resolve => {\r\n          resolveMessage = resolve;\r\n          // Add a small timeout to prevent indefinite waiting\r\n          setTimeout(resolve, 50);\r\n        });\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Streams text-to-speech synthesis results using native browser WebSocket.\r\n   * Uses only browser-native APIs, avoiding Node.js dependencies.\r\n   * \r\n   * @yields BrowserTTSChunk - Audio data or word boundary information\r\n   * @throws {Error} If called more than once\r\n   * @throws {NoAudioReceived} If no audio data is received\r\n   * @throws {WebSocketError} If WebSocket connection fails\r\n   */\r\n  async * stream(): AsyncGenerator<BrowserTTSChunk, void, unknown> {\r\n    if (this.state.streamWasCalled) {\r\n      throw new Error('stream can only be called once.');\r\n    }\r\n    this.state.streamWasCalled = true;\r\n\r\n    for (const partialText of this.texts) {\r\n      this.state.partialText = partialText;\r\n      for await (const message of this._stream()) {\r\n        yield message;\r\n      }\r\n    }\r\n  }\r\n} ","import { BrowserCommunicate, BrowserTTSChunk } from './browser-communicate';\r\n\r\n/**\r\n * Options for controlling the voice prosody (rate, pitch, volume).\r\n */\r\nexport interface ProsodyOptions {\r\n  /**\r\n   * The speaking rate of the voice.\r\n   * Examples: \"+10.00%\", \"-20.00%\"\r\n   */\r\n  rate?: string;\r\n  /**\r\n   * The speaking volume of the voice.\r\n   * Examples: \"+15.00%\", \"-10.00%\"\r\n   */\r\n  volume?: string;\r\n  /**\r\n   * The speaking pitch of the voice.\r\n   * Examples: \"+20Hz\", \"-10Hz\"\r\n   */\r\n  pitch?: string;\r\n}\r\n\r\n/**\r\n * Represents a single word boundary with its timing and text.\r\n * The API provides timing in 100-nanosecond units.\r\n */\r\nexport interface WordBoundary {\r\n  /**\r\n   * The offset from the beginning of the audio stream in 100-nanosecond units.\r\n   */\r\n  offset: number;\r\n  /**\r\n   * The duration of the word in 100-nanosecond units.\r\n   */\r\n  duration: number;\r\n  /**\r\n   * The text of the spoken word.\r\n   */\r\n  text: string;\r\n}\r\n\r\n/**\r\n * The final result of the synthesis process.\r\n */\r\nexport interface SynthesisResult {\r\n  /**\r\n   * The generated audio as a Blob, which can be used in an <audio> element.\r\n   */\r\n  audio: Blob;\r\n  /**\r\n   * An array of word boundaries containing timing and text for creating subtitles.\r\n   */\r\n  subtitle: WordBoundary[];\r\n}\r\n\r\n// Browser-compatible buffer concatenation utility with improved audio handling\r\nfunction concatUint8Arrays(arrays: Uint8Array[]): Uint8Array {\r\n  if (arrays.length === 0) return new Uint8Array(0);\r\n  if (arrays.length === 1) return arrays[0];\r\n\r\n  // For audio data, we want to ensure smooth concatenation\r\n  const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0);\r\n  const result = new Uint8Array(totalLength);\r\n  let offset = 0;\r\n\r\n  for (const arr of arrays) {\r\n    if (arr.length > 0) {\r\n      result.set(arr, offset);\r\n      offset += arr.length;\r\n    }\r\n  }\r\n\r\n  return result;\r\n}\r\n\r\n/**\r\n * Browser-specific Edge TTS class that uses only browser-native APIs.\r\n * Avoids any Node.js dependencies that could cause issues in browser environments.\r\n */\r\nexport class BrowserEdgeTTS {\r\n  public text: string;\r\n  public voice: string;\r\n  public rate: string;\r\n  public volume: string;\r\n  public pitch: string;\r\n\r\n  /**\r\n   * @param text The text to be synthesized.\r\n   * @param voice The voice to use for synthesis.\r\n   * @param options Prosody options (rate, volume, pitch).\r\n   */\r\n  constructor(\r\n    text: string,\r\n    voice = \"Microsoft Server Speech Text to Speech Voice (en-US, EmmaMultilingualNeural)\",\r\n    options: ProsodyOptions = {}\r\n  ) {\r\n    this.text = text;\r\n    this.voice = voice;\r\n    this.rate = options.rate || \"+0%\";\r\n    this.volume = options.volume || \"+0%\";\r\n    this.pitch = options.pitch || \"+0Hz\";\r\n  }\r\n\r\n  /**\r\n   * Initiates the synthesis process using browser-native APIs.\r\n   * @returns A promise that resolves with the synthesized audio and subtitle data.\r\n   */\r\n  public async synthesize(): Promise<SynthesisResult> {\r\n    const communicate = new BrowserCommunicate(this.text, {\r\n      voice: this.voice,\r\n      rate: this.rate,\r\n      volume: this.volume,\r\n      pitch: this.pitch,\r\n    });\r\n\r\n    const audioChunks: Uint8Array[] = [];\r\n    const wordBoundaries: WordBoundary[] = [];\r\n\r\n    for await (const chunk of communicate.stream()) {\r\n      if (chunk.type === 'audio' && chunk.data) {\r\n        audioChunks.push(chunk.data);\r\n      } else if (chunk.type === 'WordBoundary' && chunk.offset !== undefined && chunk.duration !== undefined && chunk.text !== undefined) {\r\n        wordBoundaries.push({\r\n          offset: chunk.offset,\r\n          duration: chunk.duration,\r\n          text: chunk.text,\r\n        });\r\n      }\r\n    }\r\n\r\n    // Convert Uint8Array chunks to Blob\r\n    const audioBuffer = concatUint8Arrays(audioChunks);\r\n    // TS 5.5+ tightens BlobPart to ArrayBuffer-backed views; cast accordingly.\r\n    const audioBlob = new Blob([\r\n      audioBuffer as unknown as ArrayBufferView<ArrayBuffer>\r\n    ], { type: \"audio/mpeg\" });\r\n\r\n    return {\r\n      audio: audioBlob,\r\n      subtitle: wordBoundaries,\r\n    };\r\n  }\r\n}\r\n\r\n// ==================================================================================\r\n// Subtitle Generation Utilities (Browser Compatible)\r\n// ==================================================================================\r\n\r\n/**\r\n * Formats a time value from 100-nanosecond units into a VTT or SRT timestamp string.\r\n * @param timeIn100ns The time value in 100-nanosecond units.\r\n * @param format The subtitle format, which determines the decimal separator.\r\n * @returns A formatted timestamp string (e.g., \"00:01:23.456\").\r\n */\r\nfunction formatTimestamp(timeIn100ns: number, format: 'vtt' | 'srt'): string {\r\n  const totalSeconds = Math.floor(timeIn100ns / 10000000);\r\n  const hours = Math.floor(totalSeconds / 3600);\r\n  const minutes = Math.floor((totalSeconds % 3600) / 60);\r\n  const seconds = totalSeconds % 60;\r\n  const milliseconds = Math.floor((timeIn100ns % 10000000) / 10000);\r\n  const separator = format === 'vtt' ? '.' : ',';\r\n  return `${padNumber(hours)}:${padNumber(minutes)}:${padNumber(seconds)}${separator}${padNumber(milliseconds, 3)}`;\r\n}\r\n\r\n/**\r\n * Pads a number with leading zeros to a specified length.\r\n * @param num The number to pad.\r\n * @param length The desired length of the string.\r\n * @returns The padded number as a string.\r\n */\r\nfunction padNumber(num: number, length = 2): string {\r\n  return num.toString().padStart(length, '0');\r\n}\r\n\r\n/**\r\n * Creates a subtitle file content in VTT (WebVTT) format.\r\n * @param wordBoundaries The array of word boundary data.\r\n * @returns A string containing the VTT formatted subtitles.\r\n */\r\nexport function createVTT(wordBoundaries: WordBoundary[]): string {\r\n  let vttContent = \"WEBVTT\\n\\n\";\r\n  wordBoundaries.forEach((word, index) => {\r\n    const startTime = formatTimestamp(word.offset, 'vtt');\r\n    const endTime = formatTimestamp(word.offset + word.duration, 'vtt');\r\n    vttContent += `${index + 1}\\n`;\r\n    vttContent += `${startTime} --> ${endTime}\\n`;\r\n    vttContent += `${word.text}\\n\\n`;\r\n  });\r\n  return vttContent;\r\n}\r\n\r\n/**\r\n * Creates a subtitle file content in SRT (SubRip) format.\r\n * @param wordBoundaries The array of word boundary data.\r\n * @returns A string containing the SRT formatted subtitles.\r\n */\r\nexport function createSRT(wordBoundaries: WordBoundary[]): string {\r\n  let srtContent = \"\";\r\n  wordBoundaries.forEach((word, index) => {\r\n    const startTime = formatTimestamp(word.offset, 'srt');\r\n    const endTime = formatTimestamp(word.offset + word.duration, 'srt');\r\n    srtContent += `${index + 1}\\n`;\r\n    srtContent += `${startTime} --> ${endTime}\\n`;\r\n    srtContent += `${word.text}\\n\\n`;\r\n  });\r\n  return srtContent;\r\n} \r\n","import { SEC_MS_GEC_VERSION, VOICE_HEADERS, VOICE_LIST_URL } from './constants';\r\nimport { BrowserDRM } from './browser-drm';\r\nimport { Voice, VoicesManagerFind, VoicesManagerVoice } from './types';\r\n\r\n/**\r\n * Error class for fetch-related errors (browser-specific)\r\n */\r\nexport class BrowserFetchError extends Error {\r\n  response?: {\r\n    status: number;\r\n    headers: Record<string, string>;\r\n  };\r\n\r\n  constructor(message: string, response?: { status: number; headers: Record<string, string> }) {\r\n    super(message);\r\n    this.name = 'BrowserFetchError';\r\n    this.response = response;\r\n  }\r\n}\r\n\r\nasync function _listVoices(): Promise<Voice[]> {\r\n  const url = `${VOICE_LIST_URL}&Sec-MS-GEC=${await BrowserDRM.generateSecMsGec()}&Sec-MS-GEC-Version=${SEC_MS_GEC_VERSION}`;\r\n\r\n  try {\r\n    const response = await fetch(url, {\r\n      headers: VOICE_HEADERS,\r\n    });\r\n\r\n    if (!response.ok) {\r\n      const headers: Record<string, string> = {};\r\n      response.headers.forEach((value, key) => {\r\n        headers[key] = value;\r\n      });\r\n\r\n      throw new BrowserFetchError(`HTTP ${response.status}`, {\r\n        status: response.status,\r\n        headers\r\n      });\r\n    }\r\n\r\n    const data: Voice[] = await response.json();\r\n\r\n    for (const voice of data) {\r\n      voice.VoiceTag.ContentCategories = voice.VoiceTag.ContentCategories.map(c => c.trim() as any);\r\n      voice.VoiceTag.VoicePersonalities = voice.VoiceTag.VoicePersonalities.map(p => p.trim() as any);\r\n    }\r\n\r\n    return data;\r\n  } catch (error) {\r\n    if (error instanceof BrowserFetchError) {\r\n      throw error;\r\n    }\r\n    // Convert other fetch errors to our BrowserFetchError format\r\n    throw new BrowserFetchError(error instanceof Error ? error.message : 'Unknown fetch error');\r\n  }\r\n}\r\n\r\n/**\r\n * Fetches all available voices from the Microsoft Edge TTS service (browser version).\r\n * Uses native browser fetch API and Web Crypto.\r\n * \r\n * @returns Promise resolving to array of available voices\r\n */\r\nexport async function listVoices(): Promise<Voice[]> {\r\n  try {\r\n    return await _listVoices();\r\n  } catch (e) {\r\n    if (e instanceof BrowserFetchError && e.response?.status === 403) {\r\n      BrowserDRM.handleClientResponseError(e.response);\r\n      return await _listVoices();\r\n    }\r\n    throw e;\r\n  }\r\n}\r\n\r\n/**\r\n * Browser-specific utility class for finding and filtering available voices.\r\n * Uses only browser-native APIs.\r\n * \r\n * @example\r\n * ```typescript\r\n * const voicesManager = await BrowserVoicesManager.create();\r\n * const englishVoices = voicesManager.find({ Language: 'en' });\r\n * ```\r\n */\r\nexport class BrowserVoicesManager {\r\n  private voices: VoicesManagerVoice[] = [];\r\n  private calledCreate = false;\r\n\r\n  /**\r\n   * Creates a new BrowserVoicesManager instance.\r\n   * \r\n   * @param customVoices - Optional custom voice list instead of fetching from API\r\n   * @returns Promise resolving to BrowserVoicesManager instance\r\n   */\r\n  public static async create(customVoices?: Voice[]): Promise<BrowserVoicesManager> {\r\n    const manager = new BrowserVoicesManager();\r\n    const voices = customVoices ?? await listVoices();\r\n    manager.voices = voices.map(voice => ({\r\n      ...voice,\r\n      Language: voice.Locale.split('-')[0],\r\n    }));\r\n    manager.calledCreate = true;\r\n    return manager;\r\n  }\r\n\r\n  /**\r\n   * Finds voices matching the specified criteria.\r\n   * \r\n   * @param filter - Filter criteria for voice selection\r\n   * @returns Array of voices matching the filter\r\n   * @throws {Error} If called before create()\r\n   */\r\n  public find(filter: VoicesManagerFind): VoicesManagerVoice[] {\r\n    if (!this.calledCreate) {\r\n      throw new Error('BrowserVoicesManager.find() called before BrowserVoicesManager.create()');\r\n    }\r\n\r\n    return this.voices.filter(voice => {\r\n      return Object.entries(filter).every(([key, value]) => {\r\n        return voice[key as keyof VoicesManagerFind] === value;\r\n      });\r\n    });\r\n  }\r\n} ","import { TTSChunk } from \"./types\";\r\nimport { ValueError } from \"./exceptions\";\r\n\r\ninterface Cue {\r\n  index: number;\r\n  start: number; // in seconds\r\n  end: number; // in seconds\r\n  content: string;\r\n}\r\n\r\nfunction formatTime(seconds: number): string {\r\n  const h = Math.floor(seconds / 3600);\r\n  const m = Math.floor((seconds % 3600) / 60);\r\n  const s = Math.floor(seconds % 60);\r\n  const ms = Math.round((seconds - Math.floor(seconds)) * 1000);\r\n\r\n  const pad = (num: number, size = 2) => num.toString().padStart(size, '0');\r\n\r\n  return `${pad(h)}:${pad(m)}:${pad(s)},${pad(ms, 3)}`;\r\n}\r\n\r\n/**\r\n * Utility class for generating SRT subtitles from WordBoundary events.\r\n * \r\n * @example\r\n * ```typescript\r\n * const subMaker = new SubMaker();\r\n * \r\n * for await (const chunk of communicate.stream()) {\r\n *   if (chunk.type === 'WordBoundary') {\r\n *     subMaker.feed(chunk);\r\n *   }\r\n * }\r\n * \r\n * const srt = subMaker.getSrt();\r\n * ```\r\n */\r\nexport class SubMaker {\r\n  private cues: Cue[] = [];\r\n\r\n  /**\r\n   * Adds a WordBoundary chunk to the subtitle maker.\r\n   * \r\n   * @param msg - Must be a WordBoundary type chunk with offset, duration, and text\r\n   * @throws {ValueError} If chunk is not a WordBoundary with required fields\r\n   */\r\n  feed(msg: TTSChunk): void {\r\n    if (msg.type !== 'WordBoundary' || msg.offset === undefined || msg.duration === undefined || msg.text === undefined) {\r\n      throw new ValueError(\"Invalid message type, expected 'WordBoundary' with offset, duration and text\");\r\n    }\r\n\r\n    // offset and duration are in 100-nanosecond intervals.\r\n    // srt timestamps are in seconds. 1s = 10^7 * 100ns\r\n    const start = msg.offset / 1e7;\r\n    const end = (msg.offset + msg.duration) / 1e7;\r\n\r\n    this.cues.push({\r\n      index: this.cues.length + 1,\r\n      start: start,\r\n      end: end,\r\n      content: msg.text,\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Merges consecutive cues to create subtitle entries with multiple words.\r\n   * This is useful for creating more readable subtitles instead of word-by-word display.\r\n   * \r\n   * @param words - Maximum number of words per merged cue\r\n   * @throws {ValueError} If words parameter is invalid\r\n   */\r\n  mergeCues(words: number): void {\r\n    if (words <= 0) {\r\n      throw new ValueError(\"Invalid number of words to merge, expected > 0\");\r\n    }\r\n    if (this.cues.length === 0) {\r\n      return;\r\n    }\r\n\r\n    const newCues: Cue[] = [];\r\n    let currentCue: Cue = this.cues[0];\r\n\r\n    for (const cue of this.cues.slice(1)) {\r\n      if (currentCue.content.split(' ').length < words) {\r\n        currentCue = {\r\n          ...currentCue,\r\n          end: cue.end,\r\n          content: `${currentCue.content} ${cue.content}`,\r\n        };\r\n      } else {\r\n        newCues.push(currentCue);\r\n        currentCue = cue;\r\n      }\r\n    }\r\n    newCues.push(currentCue);\r\n\r\n    // re-index\r\n    this.cues = newCues.map((cue, i) => ({ ...cue, index: i + 1 }));\r\n  }\r\n\r\n  /**\r\n   * Returns the subtitles in SRT format.\r\n   * \r\n   * @returns SRT formatted subtitles\r\n   */\r\n  getSrt(): string {\r\n    return this.cues.map(cue => {\r\n      return `${cue.index}\\r\\n${formatTime(cue.start)} --> ${formatTime(cue.end)}\\r\\n${cue.content}\\r\\n`;\r\n    }).join('\\r\\n');\r\n  }\r\n\r\n  toString(): string {\r\n    return this.getSrt();\r\n  }\r\n} "]}