ssml-builder-js 2.11.0 → 2.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -3
- package/dist/{chunk-SNRI43QJ.mjs → chunk-25LOR4AJ.mjs} +248 -4
- package/dist/chunk-25LOR4AJ.mjs.map +1 -0
- package/dist/chunk-CZ2F3TET.mjs +1745 -0
- package/dist/chunk-CZ2F3TET.mjs.map +1 -0
- package/dist/{chunk-FWWMWI2C.mjs → chunk-LCTE26LS.mjs} +248 -1701
- package/dist/chunk-LCTE26LS.mjs.map +1 -0
- package/dist/core.d.mts +54 -2
- package/dist/core.d.ts +54 -2
- package/dist/core.js +248 -3
- package/dist/core.js.map +1 -1
- package/dist/core.mjs +3 -1
- package/dist/elements.js +141 -3
- package/dist/elements.js.map +1 -1
- package/dist/elements.mjs +6 -4
- package/dist/elements.mjs.map +1 -1
- package/dist/index.d-Xbr6ZWnK.d.mts +214 -0
- package/dist/index.d-Xbr6ZWnK.d.ts +214 -0
- package/dist/index.d.mts +123 -2
- package/dist/index.d.ts +123 -2
- package/dist/index.js +1882 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +176 -3
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.mts +61 -163
- package/dist/react.d.ts +61 -163
- package/dist/react.js +557 -16
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +276 -17
- package/dist/react.mjs.map +1 -1
- package/package.json +3 -2
- package/dist/chunk-FWWMWI2C.mjs.map +0 -1
- package/dist/chunk-SNRI43QJ.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -11,10 +11,14 @@ import {
|
|
|
11
11
|
mapSsmlTextNodes,
|
|
12
12
|
normalizeAzureLanguage,
|
|
13
13
|
parseSsml,
|
|
14
|
+
splitSsmlDocument,
|
|
14
15
|
validateAzureSsml,
|
|
15
16
|
validateSsml,
|
|
16
17
|
validateSsmlStructureIntegrity
|
|
17
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-25LOR4AJ.mjs";
|
|
19
|
+
import {
|
|
20
|
+
validateAzureSsml as validateAzureSsml2
|
|
21
|
+
} from "./chunk-CZ2F3TET.mjs";
|
|
18
22
|
import {
|
|
19
23
|
__privateAdd,
|
|
20
24
|
__privateGet,
|
|
@@ -127,7 +131,8 @@ function closeSpeechResources(speechConfig, synthesizer) {
|
|
|
127
131
|
} catch {
|
|
128
132
|
}
|
|
129
133
|
}
|
|
130
|
-
|
|
134
|
+
var ticksToMilliseconds = (ticks) => Math.max(0, ticks) / 1e4;
|
|
135
|
+
async function synthesizeSsml(ssml, config) {
|
|
131
136
|
if (config.signal?.aborted) {
|
|
132
137
|
throw createSpeechSdkError("Speech synthesis was cancelled.");
|
|
133
138
|
}
|
|
@@ -154,6 +159,22 @@ async function synthesizeSpeech(ssml, config) {
|
|
|
154
159
|
closeResources();
|
|
155
160
|
reject(createSpeechSdkError(error));
|
|
156
161
|
};
|
|
162
|
+
const boundaries = [];
|
|
163
|
+
const visemes = [];
|
|
164
|
+
const bookmarks = [];
|
|
165
|
+
synthesizer.wordBoundary = (_sender, event) => {
|
|
166
|
+
boundaries.push({
|
|
167
|
+
text: event.text,
|
|
168
|
+
audioOffsetMs: ticksToMilliseconds(event.audioOffset),
|
|
169
|
+
durationMs: ticksToMilliseconds(event.duration)
|
|
170
|
+
});
|
|
171
|
+
};
|
|
172
|
+
synthesizer.visemeReceived = (_sender, event) => {
|
|
173
|
+
visemes.push({ visemeId: event.visemeId, audioOffsetMs: ticksToMilliseconds(event.audioOffset) });
|
|
174
|
+
};
|
|
175
|
+
synthesizer.bookmarkReached = (_sender, event) => {
|
|
176
|
+
bookmarks.push({ name: event.text, audioOffsetMs: ticksToMilliseconds(event.audioOffset) });
|
|
177
|
+
};
|
|
157
178
|
const cb = (result) => {
|
|
158
179
|
if (settled) return;
|
|
159
180
|
const { reason, errorDetails } = result;
|
|
@@ -165,7 +186,31 @@ async function synthesizeSpeech(ssml, config) {
|
|
|
165
186
|
settled = true;
|
|
166
187
|
cleanup();
|
|
167
188
|
closeResources();
|
|
168
|
-
|
|
189
|
+
const eventDurationMs = Math.max(
|
|
190
|
+
0,
|
|
191
|
+
...(boundaries ?? []).map((boundary) => boundary.audioOffsetMs + boundary.durationMs),
|
|
192
|
+
...(visemes ?? []).map((viseme) => viseme.audioOffsetMs),
|
|
193
|
+
...(bookmarks ?? []).map((bookmark) => bookmark.audioOffsetMs)
|
|
194
|
+
);
|
|
195
|
+
const durationMs = result.audioDuration ? ticksToMilliseconds(result.audioDuration) : eventDurationMs;
|
|
196
|
+
const requestId = result.resultId;
|
|
197
|
+
const addSourceMetadata = (event) => ({
|
|
198
|
+
...event,
|
|
199
|
+
...config.sourceTextRange ? { textRange: { ...config.sourceTextRange } } : {},
|
|
200
|
+
...requestId ? { requestId } : {}
|
|
201
|
+
});
|
|
202
|
+
const sourceBoundaries = boundaries.map((boundary) => addSourceMetadata(boundary));
|
|
203
|
+
const sourceVisemes = visemes.map((viseme) => addSourceMetadata(viseme));
|
|
204
|
+
const sourceBookmarks = bookmarks.map((bookmark) => addSourceMetadata(bookmark));
|
|
205
|
+
resolve({
|
|
206
|
+
audioData: result.audioData,
|
|
207
|
+
durationMs,
|
|
208
|
+
...config.sourceTextRange ? { textRange: { ...config.sourceTextRange } } : {},
|
|
209
|
+
...requestId ? { requestId } : {},
|
|
210
|
+
...sourceBoundaries.length > 0 ? { boundaries: sourceBoundaries, wordBoundary: sourceBoundaries, wordBoundaries: sourceBoundaries } : {},
|
|
211
|
+
...sourceVisemes.length > 0 ? { visemes: sourceVisemes } : {},
|
|
212
|
+
...sourceBookmarks.length > 0 ? { bookmarks: sourceBookmarks } : {}
|
|
213
|
+
});
|
|
169
214
|
};
|
|
170
215
|
try {
|
|
171
216
|
if (config.signal) {
|
|
@@ -184,6 +229,107 @@ async function synthesizeSpeech(ssml, config) {
|
|
|
184
229
|
}
|
|
185
230
|
});
|
|
186
231
|
}
|
|
232
|
+
async function synthesizeSsmlChunks(chunks, config) {
|
|
233
|
+
const results = [];
|
|
234
|
+
const totalChunks = chunks.length;
|
|
235
|
+
for (const [index, chunk] of chunks.entries()) {
|
|
236
|
+
const input = typeof chunk === "string" ? { ssml: chunk } : chunk;
|
|
237
|
+
const result = await synthesizeSsml(input.ssml, {
|
|
238
|
+
...config,
|
|
239
|
+
...input.originalTextRange ? { sourceTextRange: input.originalTextRange } : {},
|
|
240
|
+
onProgress: void 0
|
|
241
|
+
});
|
|
242
|
+
results.push(result);
|
|
243
|
+
config.onProgress?.({
|
|
244
|
+
currentChunk: index + 1,
|
|
245
|
+
totalChunks,
|
|
246
|
+
percent: totalChunks === 0 ? 100 : Math.round((index + 1) / totalChunks * 100)
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
return mergeSynthesisResults(results);
|
|
250
|
+
}
|
|
251
|
+
function mergeSynthesisResults(results) {
|
|
252
|
+
const audioLength = results.reduce((total, result) => total + result.audioData.byteLength, 0);
|
|
253
|
+
const audioData = new Uint8Array(audioLength);
|
|
254
|
+
const boundaries = [];
|
|
255
|
+
const visemes = [];
|
|
256
|
+
const bookmarks = [];
|
|
257
|
+
let byteOffset = 0;
|
|
258
|
+
let durationOffset = 0;
|
|
259
|
+
for (const result of results) {
|
|
260
|
+
audioData.set(new Uint8Array(result.audioData), byteOffset);
|
|
261
|
+
byteOffset += result.audioData.byteLength;
|
|
262
|
+
const chunkBoundaries = result.boundaries && result.boundaries.length > 0 ? result.boundaries : result.wordBoundary ?? result.wordBoundaries ?? [];
|
|
263
|
+
for (const boundary of chunkBoundaries) {
|
|
264
|
+
const textRange = boundary.textRange ?? result.textRange;
|
|
265
|
+
const requestId = boundary.requestId ?? result.requestId;
|
|
266
|
+
boundaries.push({
|
|
267
|
+
...boundary,
|
|
268
|
+
audioOffsetMs: boundary.audioOffsetMs + durationOffset,
|
|
269
|
+
...textRange ? { textRange: { ...textRange } } : {},
|
|
270
|
+
...requestId ? { requestId } : {}
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
for (const viseme of result.visemes ?? []) {
|
|
274
|
+
const textRange = viseme.textRange ?? result.textRange;
|
|
275
|
+
const requestId = viseme.requestId ?? result.requestId;
|
|
276
|
+
visemes.push({
|
|
277
|
+
...viseme,
|
|
278
|
+
audioOffsetMs: viseme.audioOffsetMs + durationOffset,
|
|
279
|
+
...textRange ? { textRange: { ...textRange } } : {},
|
|
280
|
+
...requestId ? { requestId } : {}
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
for (const bookmark of result.bookmarks ?? []) {
|
|
284
|
+
const textRange = bookmark.textRange ?? result.textRange;
|
|
285
|
+
const requestId = bookmark.requestId ?? result.requestId;
|
|
286
|
+
bookmarks.push({
|
|
287
|
+
...bookmark,
|
|
288
|
+
audioOffsetMs: bookmark.audioOffsetMs + durationOffset,
|
|
289
|
+
...textRange ? { textRange: { ...textRange } } : {},
|
|
290
|
+
...requestId ? { requestId } : {}
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
durationOffset += Math.max(0, result.durationMs);
|
|
294
|
+
}
|
|
295
|
+
return {
|
|
296
|
+
audioData: audioData.buffer,
|
|
297
|
+
durationMs: durationOffset,
|
|
298
|
+
...boundaries.length > 0 ? { boundaries, wordBoundary: boundaries, wordBoundaries: boundaries } : {},
|
|
299
|
+
...visemes.length > 0 ? { visemes } : {},
|
|
300
|
+
...bookmarks.length > 0 ? { bookmarks } : {},
|
|
301
|
+
...results.length === 1 && results[0]?.requestId ? { requestId: results[0].requestId } : {},
|
|
302
|
+
...results.length === 1 && results[0]?.textRange ? { textRange: { ...results[0].textRange } } : {}
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
async function synthesizeSpeech(ssml, config) {
|
|
306
|
+
return (await synthesizeSsml(ssml, config)).audioData;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// packages/azure-tts-client/src/safe.ts
|
|
310
|
+
async function synthesizeSsmlSafe(client, ssml, options = {}) {
|
|
311
|
+
const validationOptions = options.validation ?? options;
|
|
312
|
+
const diagnostics = await Promise.resolve(validateAzureSsml2(ssml, validationOptions));
|
|
313
|
+
const errors = diagnostics.filter((diagnostic) => diagnostic.severity === "error");
|
|
314
|
+
if (errors.length > 0) {
|
|
315
|
+
return {
|
|
316
|
+
ok: false,
|
|
317
|
+
success: false,
|
|
318
|
+
status: "validation-error",
|
|
319
|
+
error: {
|
|
320
|
+
kind: "validation",
|
|
321
|
+
message: "SSML validation failed; the Azure Speech API was not called.",
|
|
322
|
+
diagnostics: errors
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
try {
|
|
327
|
+
return { ok: true, success: true, status: "success", value: await client.synthesizeSsml(ssml) };
|
|
328
|
+
} catch (error) {
|
|
329
|
+
const azureError = error instanceof AzureTtsError ? error : createSpeechSdkError(error);
|
|
330
|
+
return { ok: false, success: false, status: "azure-api-error", error: azureError };
|
|
331
|
+
}
|
|
332
|
+
}
|
|
187
333
|
|
|
188
334
|
// packages/azure-tts-client/src/client.ts
|
|
189
335
|
var ENDPOINT_TEMPLATE = "https://{region}.tts.speech.microsoft.com/cognitiveservices/v1";
|
|
@@ -200,6 +346,28 @@ var AzureTtsClient = class {
|
|
|
200
346
|
const config = { endpoint, region, subscriptionKey, outputFormat, signal, timeoutMs };
|
|
201
347
|
return synthesizeSpeech(ssml, config);
|
|
202
348
|
}
|
|
349
|
+
async synthesizeSsml(ssml) {
|
|
350
|
+
const { region, subscriptionKey, outputFormat, signal, timeoutMs } = __privateGet(this, _options);
|
|
351
|
+
const endpoint = __privateGet(this, _options).endpoint?.trim() || ENDPOINT_TEMPLATE.replace("{region}", region);
|
|
352
|
+
__privateGet(this, _options).logger?.debug?.("Using Azure TTS endpoint:", endpoint);
|
|
353
|
+
return synthesizeSsml(ssml, { endpoint, region, subscriptionKey, outputFormat, signal, timeoutMs });
|
|
354
|
+
}
|
|
355
|
+
async synthesizeChunks(chunks, options = {}) {
|
|
356
|
+
const { region, subscriptionKey, outputFormat, signal, timeoutMs } = __privateGet(this, _options);
|
|
357
|
+
const endpoint = __privateGet(this, _options).endpoint?.trim() || ENDPOINT_TEMPLATE.replace("{region}", region);
|
|
358
|
+
return synthesizeSsmlChunks(chunks, {
|
|
359
|
+
endpoint,
|
|
360
|
+
region,
|
|
361
|
+
subscriptionKey,
|
|
362
|
+
outputFormat,
|
|
363
|
+
signal,
|
|
364
|
+
timeoutMs,
|
|
365
|
+
onProgress: options.onProgress ?? __privateGet(this, _options).onProgress
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
async synthesizeSsmlSafe(ssml, options = {}) {
|
|
369
|
+
return synthesizeSsmlSafe(this, ssml, options);
|
|
370
|
+
}
|
|
203
371
|
};
|
|
204
372
|
_options = new WeakMap();
|
|
205
373
|
|
|
@@ -295,9 +463,14 @@ export {
|
|
|
295
463
|
getBuiltInVoiceCatalogMetadata,
|
|
296
464
|
isValidAzureAudioDuration,
|
|
297
465
|
mapSsmlTextNodes,
|
|
466
|
+
mergeSynthesisResults,
|
|
298
467
|
normalizeAzureLanguage,
|
|
299
468
|
parseSsml,
|
|
469
|
+
splitSsmlDocument,
|
|
300
470
|
synthesizeSpeech,
|
|
471
|
+
synthesizeSsml,
|
|
472
|
+
synthesizeSsmlChunks,
|
|
473
|
+
synthesizeSsmlSafe,
|
|
301
474
|
validateAzureSsml,
|
|
302
475
|
validateSsml,
|
|
303
476
|
validateSsmlStructureIntegrity
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../packages/azure-tts-client/src/errors.ts","../packages/azure-tts-client/src/synthesis.ts","../packages/azure-tts-client/src/speechConfig.ts","../packages/azure-tts-client/src/outputFormats.ts","../packages/azure-tts-client/src/client.ts","../packages/azure-tts-client/src/voiceCatalog.ts"],"sourcesContent":["export class AzureTtsError extends Error {\n readonly status: number;\n readonly statusText: string;\n readonly responseBody: string;\n readonly requestId: string | null;\n\n constructor(status: number, statusText: string, responseBody: string, requestId: string | null) {\n super(`Azure TTS request failed: ${status} ${statusText}`);\n this.name = \"AzureTtsError\";\n this.status = status;\n this.statusText = statusText;\n this.responseBody = responseBody;\n this.requestId = requestId;\n }\n}\n\nexport class AzureTtsSdkError extends AzureTtsError {\n readonly errorDetails: string;\n\n constructor(errorDetails: string) {\n super(0, \"Speech SDK\", errorDetails, null);\n this.name = \"AzureTtsSdkError\";\n this.message = `Azure TTS synthesis failed: ${errorDetails}`;\n this.errorDetails = errorDetails;\n }\n}\n\nexport function createSpeechSdkError(error: unknown): AzureTtsSdkError {\n const message = error instanceof Error ? error.message : String(error);\n return new AzureTtsSdkError(message);\n}\n","import * as SpeechSDK from \"microsoft-cognitiveservices-speech-sdk\";\nimport { createSpeechSdkError } from \"./errors.ts\";\nimport { createSpeechConfig } from \"./speechConfig.ts\";\nimport type { TtsConfig } from \"./types.ts\";\n\nfunction closeSpeechResources(speechConfig: SpeechSDK.SpeechConfig, synthesizer: SpeechSDK.SpeechSynthesizer): void {\n try {\n synthesizer.close();\n } catch {}\n\n try {\n speechConfig.close();\n } catch {}\n}\n\nexport async function synthesizeSpeech(ssml: string, config: TtsConfig): Promise<ArrayBuffer> {\n if (config.signal?.aborted) {\n throw createSpeechSdkError(\"Speech synthesis was cancelled.\");\n }\n\n const speechConfig = createSpeechConfig(config);\n const synthesizer = new SpeechSDK.SpeechSynthesizer(speechConfig, null);\n\n return await new Promise<ArrayBuffer>((resolve, reject) => {\n let resourcesClosed = false;\n let settled = false;\n let timeout: ReturnType<typeof setTimeout> | undefined;\n let abortHandler: (() => void) | undefined;\n const cleanup = () => {\n if (timeout) clearTimeout(timeout);\n if (abortHandler) config.signal?.removeEventListener(\"abort\", abortHandler);\n };\n const closeResources = () => {\n if (resourcesClosed) return;\n resourcesClosed = true;\n closeSpeechResources(speechConfig, synthesizer);\n };\n const rejectWithError = (error: unknown) => {\n if (settled) return;\n settled = true;\n cleanup();\n closeResources();\n reject(createSpeechSdkError(error));\n };\n\n const cb = (result: SpeechSDK.SpeechSynthesisResult) => {\n if (settled) return;\n const { reason, errorDetails } = result;\n if (reason !== SpeechSDK.ResultReason.SynthesizingAudioCompleted) {\n const err = errorDetails || `Speech synthesis failed with reason ${reason}.`;\n rejectWithError(err);\n return;\n }\n settled = true;\n cleanup();\n closeResources();\n resolve(result.audioData);\n };\n\n try {\n if (config.signal) {\n abortHandler = () => rejectWithError(\"Speech synthesis was cancelled.\");\n config.signal.addEventListener(\"abort\", abortHandler, { once: true });\n }\n if (config.timeoutMs !== undefined && config.timeoutMs > 0) {\n timeout = setTimeout(\n () => rejectWithError(`Speech synthesis timed out after ${config.timeoutMs} ms.`),\n config.timeoutMs,\n );\n }\n synthesizer.speakSsmlAsync(ssml, cb, rejectWithError);\n } catch (error) {\n rejectWithError(error);\n }\n });\n}\n","import { SpeechConfig } from \"microsoft-cognitiveservices-speech-sdk\";\nimport { DEFAULT_OUTPUT_FORMAT, resolveOutputFormat } from \"./outputFormats.ts\";\nimport type { TtsConfig } from \"./types.ts\";\n\nexport function resolveEndpoint(config: TtsConfig): string {\n const endpoint = config.endpoint?.trim() || \"https://{region}.tts.speech.microsoft.com/cognitiveservices/v1\";\n return endpoint.replace(/\\{region\\}/g, encodeURIComponent(config.region));\n}\n\nexport function createSpeechConfig(config: TtsConfig): SpeechConfig {\n const { outputFormat = DEFAULT_OUTPUT_FORMAT, subscriptionKey } = config;\n\n const endpoint = new URL(resolveEndpoint(config));\n const speechConfig = SpeechConfig.fromEndpoint(endpoint, subscriptionKey);\n speechConfig.speechSynthesisOutputFormat = resolveOutputFormat(outputFormat);\n return speechConfig;\n}\n","import * as SpeechSDK from \"microsoft-cognitiveservices-speech-sdk\";\n\nexport const DEFAULT_OUTPUT_FORMAT = \"audio-16khz-128kbitrate-mono-mp3\";\n\nconst OUTPUT_FORMATS: Record<string, SpeechSDK.SpeechSynthesisOutputFormat> = {\n \"raw-8khz-8bit-mono-mulaw\": SpeechSDK.SpeechSynthesisOutputFormat.Raw8Khz8BitMonoMULaw,\n \"riff-16khz-16kbps-mono-siren\": SpeechSDK.SpeechSynthesisOutputFormat.Riff16Khz16KbpsMonoSiren,\n \"audio-16khz-16kbps-mono-siren\": SpeechSDK.SpeechSynthesisOutputFormat.Audio16Khz16KbpsMonoSiren,\n \"audio-16khz-32kbitrate-mono-mp3\": SpeechSDK.SpeechSynthesisOutputFormat.Audio16Khz32KBitRateMonoMp3,\n \"audio-16khz-128kbitrate-mono-mp3\": SpeechSDK.SpeechSynthesisOutputFormat.Audio16Khz128KBitRateMonoMp3,\n \"audio-16khz-64kbitrate-mono-mp3\": SpeechSDK.SpeechSynthesisOutputFormat.Audio16Khz64KBitRateMonoMp3,\n \"audio-24khz-48kbitrate-mono-mp3\": SpeechSDK.SpeechSynthesisOutputFormat.Audio24Khz48KBitRateMonoMp3,\n \"audio-24khz-96kbitrate-mono-mp3\": SpeechSDK.SpeechSynthesisOutputFormat.Audio24Khz96KBitRateMonoMp3,\n \"audio-24khz-160kbitrate-mono-mp3\": SpeechSDK.SpeechSynthesisOutputFormat.Audio24Khz160KBitRateMonoMp3,\n \"raw-16khz-16bit-mono-truesilk\": SpeechSDK.SpeechSynthesisOutputFormat.Raw16Khz16BitMonoTrueSilk,\n \"riff-16khz-16bit-mono-pcm\": SpeechSDK.SpeechSynthesisOutputFormat.Riff16Khz16BitMonoPcm,\n \"riff-8khz-16bit-mono-pcm\": SpeechSDK.SpeechSynthesisOutputFormat.Riff8Khz16BitMonoPcm,\n \"riff-24khz-16bit-mono-pcm\": SpeechSDK.SpeechSynthesisOutputFormat.Riff24Khz16BitMonoPcm,\n \"riff-8khz-8bit-mono-mulaw\": SpeechSDK.SpeechSynthesisOutputFormat.Riff8Khz8BitMonoMULaw,\n \"raw-16khz-16bit-mono-pcm\": SpeechSDK.SpeechSynthesisOutputFormat.Raw16Khz16BitMonoPcm,\n \"raw-24khz-16bit-mono-pcm\": SpeechSDK.SpeechSynthesisOutputFormat.Raw24Khz16BitMonoPcm,\n \"raw-8khz-16bit-mono-pcm\": SpeechSDK.SpeechSynthesisOutputFormat.Raw8Khz16BitMonoPcm,\n \"ogg-16khz-16bit-mono-opus\": SpeechSDK.SpeechSynthesisOutputFormat.Ogg16Khz16BitMonoOpus,\n \"ogg-24khz-16bit-mono-opus\": SpeechSDK.SpeechSynthesisOutputFormat.Ogg24Khz16BitMonoOpus,\n \"raw-48khz-16bit-mono-pcm\": SpeechSDK.SpeechSynthesisOutputFormat.Raw48Khz16BitMonoPcm,\n \"riff-48khz-16bit-mono-pcm\": SpeechSDK.SpeechSynthesisOutputFormat.Riff48Khz16BitMonoPcm,\n \"audio-48khz-96kbitrate-mono-mp3\": SpeechSDK.SpeechSynthesisOutputFormat.Audio48Khz96KBitRateMonoMp3,\n \"audio-48khz-192kbitrate-mono-mp3\": SpeechSDK.SpeechSynthesisOutputFormat.Audio48Khz192KBitRateMonoMp3,\n \"ogg-48khz-16bit-mono-opus\": SpeechSDK.SpeechSynthesisOutputFormat.Ogg48Khz16BitMonoOpus,\n \"webm-16khz-16bit-mono-opus\": SpeechSDK.SpeechSynthesisOutputFormat.Webm16Khz16BitMonoOpus,\n \"webm-24khz-16bit-mono-opus\": SpeechSDK.SpeechSynthesisOutputFormat.Webm24Khz16BitMonoOpus,\n \"webm-24khz-16bit-24kbps-mono-opus\": SpeechSDK.SpeechSynthesisOutputFormat.Webm24Khz16Bit24KbpsMonoOpus,\n \"raw-24khz-16bit-mono-truesilk\": SpeechSDK.SpeechSynthesisOutputFormat.Raw24Khz16BitMonoTrueSilk,\n \"raw-8khz-8bit-mono-alaw\": SpeechSDK.SpeechSynthesisOutputFormat.Raw8Khz8BitMonoALaw,\n \"riff-8khz-8bit-mono-alaw\": SpeechSDK.SpeechSynthesisOutputFormat.Riff8Khz8BitMonoALaw,\n \"audio-16khz-16bit-32kbps-mono-opus\": SpeechSDK.SpeechSynthesisOutputFormat.Audio16Khz16Bit32KbpsMonoOpus,\n \"audio-24khz-16bit-48kbps-mono-opus\": SpeechSDK.SpeechSynthesisOutputFormat.Audio24Khz16Bit48KbpsMonoOpus,\n \"audio-24khz-16bit-24kbps-mono-opus\": SpeechSDK.SpeechSynthesisOutputFormat.Audio24Khz16Bit24KbpsMonoOpus,\n \"raw-22050hz-16bit-mono-pcm\": SpeechSDK.SpeechSynthesisOutputFormat.Raw22050Hz16BitMonoPcm,\n \"riff-22050hz-16bit-mono-pcm\": SpeechSDK.SpeechSynthesisOutputFormat.Riff22050Hz16BitMonoPcm,\n \"raw-44100hz-16bit-mono-pcm\": SpeechSDK.SpeechSynthesisOutputFormat.Raw44100Hz16BitMonoPcm,\n \"riff-44100hz-16bit-mono-pcm\": SpeechSDK.SpeechSynthesisOutputFormat.Riff44100Hz16BitMonoPcm,\n \"amr-wb-16000hz\": SpeechSDK.SpeechSynthesisOutputFormat.AmrWb16000Hz,\n \"g722-16khz-64kbps\": SpeechSDK.SpeechSynthesisOutputFormat.G72216Khz64Kbps,\n};\n\nexport function resolveOutputFormat(outputFormat: string): SpeechSDK.SpeechSynthesisOutputFormat {\n const resolvedFormat = OUTPUT_FORMATS[outputFormat];\n if (resolvedFormat === undefined) {\n throw new Error(`Unsupported Azure Speech output format: ${outputFormat}`);\n }\n\n return resolvedFormat;\n}\n","import { synthesizeSpeech } from \"./synthesis.ts\";\nimport type { AzureTtsClientOptions } from \"./types.ts\";\n\nconst ENDPOINT_TEMPLATE = \"https://{region}.tts.speech.microsoft.com/cognitiveservices/v1\";\n\nexport class AzureTtsClient {\n readonly #options: AzureTtsClientOptions;\n\n constructor(options: AzureTtsClientOptions) {\n this.#options = options;\n }\n\n async synthesize(ssml: string): Promise<ArrayBuffer> {\n const { region, subscriptionKey, outputFormat, signal, timeoutMs } = this.#options;\n const endpoint = this.#options.endpoint?.trim() || ENDPOINT_TEMPLATE.replace(\"{region}\", region);\n this.#options.logger?.debug?.(\"Using Azure TTS endpoint:\", endpoint);\n\n const config = { endpoint, region, subscriptionKey, outputFormat, signal, timeoutMs };\n return synthesizeSpeech(ssml, config);\n }\n}\n","const AZURE_VOICE_API_VERSION = \"2025-10-01\";\n\nexport interface FetchAzureVoiceCatalogOptions {\n apiKey: string;\n region: string | string[];\n}\n\nexport interface AzureVoiceCatalogVoice {\n name: string;\n locale: string;\n secondaryLocales?: readonly string[];\n styles?: readonly string[];\n regions: readonly string[];\n status?: \"ga\" | \"preview\" | \"deprecated\";\n}\n\nexport interface FetchedAzureVoiceCatalogMetadata {\n voiceCount: number;\n generatedAt: string;\n apiVersion: string;\n regions: readonly string[];\n}\n\nexport interface AzureVoiceCatalog {\n voices: readonly AzureVoiceCatalogVoice[];\n metadata: FetchedAzureVoiceCatalogMetadata;\n}\n\ninterface AzureVoiceApiRecord {\n Locale?: unknown;\n Name?: unknown;\n SecondaryLocaleList?: unknown;\n ShortName?: unknown;\n Status?: unknown;\n StyleList?: unknown;\n}\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nfunction stringList(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return [...new Set(value.map(stringValue).filter((item): item is string => item !== undefined))];\n}\n\nfunction normalizeStatus(value: unknown): AzureVoiceCatalogVoice[\"status\"] {\n const status = stringValue(value)?.toLowerCase();\n if (status === \"preview\" || status === \"deprecated\" || status === \"ga\") return status;\n return undefined;\n}\n\nfunction normalizeRegions(region: string | string[]): string[] {\n const regions = Array.isArray(region) ? region : [region];\n const result = [...new Set(regions.map((item) => item.trim()).filter(Boolean))];\n if (result.length === 0) throw new TypeError(\"At least one Azure Speech region is required.\");\n return result;\n}\n\nasync function fetchRegionVoices(region: string, apiKey: string): Promise<AzureVoiceApiRecord[]> {\n const endpoint = `https://${encodeURIComponent(region)}.tts.speech.microsoft.com/cognitiveservices/voices/list`;\n const response = await fetch(endpoint, {\n headers: {\n Accept: \"application/json\",\n \"Ocp-Apim-Subscription-Key\": apiKey,\n },\n });\n if (!response.ok) {\n throw new Error(`Azure List Voices API request failed for region \"${region}\" with HTTP ${response.status}.`);\n }\n const payload: unknown = await response.json();\n if (!Array.isArray(payload)) throw new Error(`Azure List Voices API returned an invalid response for \"${region}\".`);\n return payload.filter((item): item is AzureVoiceApiRecord => Boolean(item && typeof item === \"object\"));\n}\n\n/** Fetches and deduplicates the current Azure Speech voice catalog for one or more regions. */\nexport async function fetchAzureVoiceCatalog(options: FetchAzureVoiceCatalogOptions): Promise<AzureVoiceCatalog> {\n if (!options || typeof options.apiKey !== \"string\" || !options.apiKey.trim())\n throw new TypeError(\"An Azure Speech API key is required.\");\n const regions = normalizeRegions(options.region);\n const payloads = await Promise.all(regions.map((region) => fetchRegionVoices(region, options.apiKey)));\n const voices = new Map<string, AzureVoiceCatalogVoice>();\n\n for (let regionIndex = 0; regionIndex < payloads.length; regionIndex += 1) {\n const region = regions[regionIndex];\n for (const record of payloads[regionIndex]) {\n const name = stringValue(record.ShortName) ?? stringValue(record.Name);\n const locale = stringValue(record.Locale);\n if (!name || !locale) continue;\n const key = name.toLowerCase();\n const existing = voices.get(key);\n const secondaryLocales = stringList(record.SecondaryLocaleList);\n const styles = stringList(record.StyleList);\n const status = normalizeStatus(record.Status);\n const merged: AzureVoiceCatalogVoice = {\n name: existing?.name ?? name,\n locale: existing?.locale ?? locale,\n regions: [...new Set([...(existing?.regions ?? []), region])],\n };\n const mergedSecondaryLocales = [...new Set([...(existing?.secondaryLocales ?? []), ...secondaryLocales])];\n if (mergedSecondaryLocales.length > 0) merged.secondaryLocales = mergedSecondaryLocales;\n const mergedStyles = [...new Set([...(existing?.styles ?? []), ...styles])];\n if (mergedStyles.length > 0) merged.styles = mergedStyles;\n if (status) merged.status = status;\n else if (existing?.status) merged.status = existing.status;\n voices.set(key, merged);\n }\n }\n\n const sortedVoices = [...voices.values()].sort((first, second) => first.name.localeCompare(second.name));\n return {\n voices: sortedVoices,\n metadata: {\n voiceCount: sortedVoices.length,\n generatedAt: new Date().toISOString(),\n apiVersion: AZURE_VOICE_API_VERSION,\n regions,\n },\n };\n}\n"],"mappings":"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","names":["SpeechSDK"]}
|
|
1
|
+
{"version":3,"sources":["../packages/azure-tts-client/src/errors.ts","../packages/azure-tts-client/src/synthesis.ts","../packages/azure-tts-client/src/speechConfig.ts","../packages/azure-tts-client/src/outputFormats.ts","../packages/azure-tts-client/src/safe.ts","../packages/azure-tts-client/src/client.ts","../packages/azure-tts-client/src/voiceCatalog.ts"],"sourcesContent":["export class AzureTtsError extends Error {\n readonly status: number;\n readonly statusText: string;\n readonly responseBody: string;\n readonly requestId: string | null;\n\n constructor(status: number, statusText: string, responseBody: string, requestId: string | null) {\n super(`Azure TTS request failed: ${status} ${statusText}`);\n this.name = \"AzureTtsError\";\n this.status = status;\n this.statusText = statusText;\n this.responseBody = responseBody;\n this.requestId = requestId;\n }\n}\n\nexport class AzureTtsSdkError extends AzureTtsError {\n readonly errorDetails: string;\n\n constructor(errorDetails: string) {\n super(0, \"Speech SDK\", errorDetails, null);\n this.name = \"AzureTtsSdkError\";\n this.message = `Azure TTS synthesis failed: ${errorDetails}`;\n this.errorDetails = errorDetails;\n }\n}\n\nexport function createSpeechSdkError(error: unknown): AzureTtsSdkError {\n const message = error instanceof Error ? error.message : String(error);\n return new AzureTtsSdkError(message);\n}\n","import * as SpeechSDK from \"microsoft-cognitiveservices-speech-sdk\";\nimport { createSpeechSdkError } from \"./errors.ts\";\nimport { createSpeechConfig } from \"./speechConfig.ts\";\nimport type { SsmlSynthesisChunk, SsmlSynthesisResult, TtsConfig } from \"./types.ts\";\n\nfunction closeSpeechResources(speechConfig: SpeechSDK.SpeechConfig, synthesizer: SpeechSDK.SpeechSynthesizer): void {\n try {\n synthesizer.close();\n } catch {}\n\n try {\n speechConfig.close();\n } catch {}\n}\n\nconst ticksToMilliseconds = (ticks: number): number => Math.max(0, ticks) / 10_000;\n\nexport async function synthesizeSsml(ssml: string, config: TtsConfig): Promise<SsmlSynthesisResult> {\n if (config.signal?.aborted) {\n throw createSpeechSdkError(\"Speech synthesis was cancelled.\");\n }\n\n const speechConfig = createSpeechConfig(config);\n const synthesizer = new SpeechSDK.SpeechSynthesizer(speechConfig, null);\n\n return await new Promise<SsmlSynthesisResult>((resolve, reject) => {\n let resourcesClosed = false;\n let settled = false;\n let timeout: ReturnType<typeof setTimeout> | undefined;\n let abortHandler: (() => void) | undefined;\n const cleanup = () => {\n if (timeout) clearTimeout(timeout);\n if (abortHandler) config.signal?.removeEventListener(\"abort\", abortHandler);\n };\n const closeResources = () => {\n if (resourcesClosed) return;\n resourcesClosed = true;\n closeSpeechResources(speechConfig, synthesizer);\n };\n const rejectWithError = (error: unknown) => {\n if (settled) return;\n settled = true;\n cleanup();\n closeResources();\n reject(createSpeechSdkError(error));\n };\n\n const boundaries: SsmlSynthesisResult[\"boundaries\"] = [];\n const visemes: SsmlSynthesisResult[\"visemes\"] = [];\n const bookmarks: SsmlSynthesisResult[\"bookmarks\"] = [];\n synthesizer.wordBoundary = (_sender, event) => {\n boundaries.push({\n text: event.text,\n audioOffsetMs: ticksToMilliseconds(event.audioOffset),\n durationMs: ticksToMilliseconds(event.duration),\n });\n };\n synthesizer.visemeReceived = (_sender, event) => {\n visemes.push({ visemeId: event.visemeId, audioOffsetMs: ticksToMilliseconds(event.audioOffset) });\n };\n synthesizer.bookmarkReached = (_sender, event) => {\n bookmarks.push({ name: event.text, audioOffsetMs: ticksToMilliseconds(event.audioOffset) });\n };\n\n const cb = (result: SpeechSDK.SpeechSynthesisResult) => {\n if (settled) return;\n const { reason, errorDetails } = result;\n if (reason !== SpeechSDK.ResultReason.SynthesizingAudioCompleted) {\n const err = errorDetails || `Speech synthesis failed with reason ${reason}.`;\n rejectWithError(err);\n return;\n }\n settled = true;\n cleanup();\n closeResources();\n const eventDurationMs = Math.max(\n 0,\n ...(boundaries ?? []).map((boundary) => boundary.audioOffsetMs + boundary.durationMs),\n ...(visemes ?? []).map((viseme) => viseme.audioOffsetMs),\n ...(bookmarks ?? []).map((bookmark) => bookmark.audioOffsetMs),\n );\n const durationMs = result.audioDuration ? ticksToMilliseconds(result.audioDuration) : eventDurationMs;\n const requestId = (result as SpeechSDK.SpeechSynthesisResult & { resultId?: string }).resultId;\n const addSourceMetadata = <T extends { audioOffsetMs: number }>(event: T): T => ({\n ...event,\n ...(config.sourceTextRange ? { textRange: { ...config.sourceTextRange } } : {}),\n ...(requestId ? { requestId } : {}),\n });\n const sourceBoundaries = boundaries.map((boundary) => addSourceMetadata(boundary));\n const sourceVisemes = visemes.map((viseme) => addSourceMetadata(viseme));\n const sourceBookmarks = bookmarks.map((bookmark) => addSourceMetadata(bookmark));\n resolve({\n audioData: result.audioData,\n durationMs,\n ...(config.sourceTextRange ? { textRange: { ...config.sourceTextRange } } : {}),\n ...(requestId ? { requestId } : {}),\n ...(sourceBoundaries.length > 0\n ? { boundaries: sourceBoundaries, wordBoundary: sourceBoundaries, wordBoundaries: sourceBoundaries }\n : {}),\n ...(sourceVisemes.length > 0 ? { visemes: sourceVisemes } : {}),\n ...(sourceBookmarks.length > 0 ? { bookmarks: sourceBookmarks } : {}),\n });\n };\n\n try {\n if (config.signal) {\n abortHandler = () => rejectWithError(\"Speech synthesis was cancelled.\");\n config.signal.addEventListener(\"abort\", abortHandler, { once: true });\n }\n if (config.timeoutMs !== undefined && config.timeoutMs > 0) {\n timeout = setTimeout(\n () => rejectWithError(`Speech synthesis timed out after ${config.timeoutMs} ms.`),\n config.timeoutMs,\n );\n }\n synthesizer.speakSsmlAsync(ssml, cb, rejectWithError);\n } catch (error) {\n rejectWithError(error);\n }\n });\n}\n\n/** Synthesizes chunks sequentially, annotates synchronization events, and merges the results. */\nexport async function synthesizeSsmlChunks(\n chunks: readonly (SsmlSynthesisChunk | string)[],\n config: TtsConfig,\n): Promise<SsmlSynthesisResult> {\n const results: SsmlSynthesisResult[] = [];\n const totalChunks = chunks.length;\n for (const [index, chunk] of chunks.entries()) {\n const input = typeof chunk === \"string\" ? { ssml: chunk } : chunk;\n const result = await synthesizeSsml(input.ssml, {\n ...config,\n ...(input.originalTextRange ? { sourceTextRange: input.originalTextRange } : {}),\n onProgress: undefined,\n });\n results.push(result);\n config.onProgress?.({\n currentChunk: index + 1,\n totalChunks,\n percent: totalChunks === 0 ? 100 : Math.round(((index + 1) / totalChunks) * 100),\n });\n }\n return mergeSynthesisResults(results);\n}\n\n/** Concatenates audio buffers and shifts all synchronization events by prior chunk durations. */\nexport function mergeSynthesisResults(results: readonly SsmlSynthesisResult[]): SsmlSynthesisResult {\n const audioLength = results.reduce((total, result) => total + result.audioData.byteLength, 0);\n const audioData = new Uint8Array(audioLength);\n const boundaries: NonNullable<SsmlSynthesisResult[\"boundaries\"]> = [];\n const visemes: NonNullable<SsmlSynthesisResult[\"visemes\"]> = [];\n const bookmarks: NonNullable<SsmlSynthesisResult[\"bookmarks\"]> = [];\n let byteOffset = 0;\n let durationOffset = 0;\n\n for (const result of results) {\n audioData.set(new Uint8Array(result.audioData), byteOffset);\n byteOffset += result.audioData.byteLength;\n const chunkBoundaries =\n result.boundaries && result.boundaries.length > 0\n ? result.boundaries\n : (result.wordBoundary ?? result.wordBoundaries ?? []);\n for (const boundary of chunkBoundaries) {\n const textRange = boundary.textRange ?? result.textRange;\n const requestId = boundary.requestId ?? result.requestId;\n boundaries.push({\n ...boundary,\n audioOffsetMs: boundary.audioOffsetMs + durationOffset,\n ...(textRange ? { textRange: { ...textRange } } : {}),\n ...(requestId ? { requestId } : {}),\n });\n }\n for (const viseme of result.visemes ?? []) {\n const textRange = viseme.textRange ?? result.textRange;\n const requestId = viseme.requestId ?? result.requestId;\n visemes.push({\n ...viseme,\n audioOffsetMs: viseme.audioOffsetMs + durationOffset,\n ...(textRange ? { textRange: { ...textRange } } : {}),\n ...(requestId ? { requestId } : {}),\n });\n }\n for (const bookmark of result.bookmarks ?? []) {\n const textRange = bookmark.textRange ?? result.textRange;\n const requestId = bookmark.requestId ?? result.requestId;\n bookmarks.push({\n ...bookmark,\n audioOffsetMs: bookmark.audioOffsetMs + durationOffset,\n ...(textRange ? { textRange: { ...textRange } } : {}),\n ...(requestId ? { requestId } : {}),\n });\n }\n durationOffset += Math.max(0, result.durationMs);\n }\n\n return {\n audioData: audioData.buffer,\n durationMs: durationOffset,\n ...(boundaries.length > 0 ? { boundaries, wordBoundary: boundaries, wordBoundaries: boundaries } : {}),\n ...(visemes.length > 0 ? { visemes } : {}),\n ...(bookmarks.length > 0 ? { bookmarks } : {}),\n ...(results.length === 1 && results[0]?.requestId ? { requestId: results[0].requestId } : {}),\n ...(results.length === 1 && results[0]?.textRange ? { textRange: { ...results[0].textRange } } : {}),\n };\n}\n\n/** Backward-compatible audio-only synthesis helper. */\nexport async function synthesizeSpeech(ssml: string, config: TtsConfig): Promise<ArrayBuffer> {\n return (await synthesizeSsml(ssml, config)).audioData;\n}\n","import { SpeechConfig } from \"microsoft-cognitiveservices-speech-sdk\";\nimport { DEFAULT_OUTPUT_FORMAT, resolveOutputFormat } from \"./outputFormats.ts\";\nimport type { TtsConfig } from \"./types.ts\";\n\nexport function resolveEndpoint(config: TtsConfig): string {\n const endpoint = config.endpoint?.trim() || \"https://{region}.tts.speech.microsoft.com/cognitiveservices/v1\";\n return endpoint.replace(/\\{region\\}/g, encodeURIComponent(config.region));\n}\n\nexport function createSpeechConfig(config: TtsConfig): SpeechConfig {\n const { outputFormat = DEFAULT_OUTPUT_FORMAT, subscriptionKey } = config;\n\n const endpoint = new URL(resolveEndpoint(config));\n const speechConfig = SpeechConfig.fromEndpoint(endpoint, subscriptionKey);\n speechConfig.speechSynthesisOutputFormat = resolveOutputFormat(outputFormat);\n return speechConfig;\n}\n","import * as SpeechSDK from \"microsoft-cognitiveservices-speech-sdk\";\n\nexport const DEFAULT_OUTPUT_FORMAT = \"audio-16khz-128kbitrate-mono-mp3\";\n\nconst OUTPUT_FORMATS: Record<string, SpeechSDK.SpeechSynthesisOutputFormat> = {\n \"raw-8khz-8bit-mono-mulaw\": SpeechSDK.SpeechSynthesisOutputFormat.Raw8Khz8BitMonoMULaw,\n \"riff-16khz-16kbps-mono-siren\": SpeechSDK.SpeechSynthesisOutputFormat.Riff16Khz16KbpsMonoSiren,\n \"audio-16khz-16kbps-mono-siren\": SpeechSDK.SpeechSynthesisOutputFormat.Audio16Khz16KbpsMonoSiren,\n \"audio-16khz-32kbitrate-mono-mp3\": SpeechSDK.SpeechSynthesisOutputFormat.Audio16Khz32KBitRateMonoMp3,\n \"audio-16khz-128kbitrate-mono-mp3\": SpeechSDK.SpeechSynthesisOutputFormat.Audio16Khz128KBitRateMonoMp3,\n \"audio-16khz-64kbitrate-mono-mp3\": SpeechSDK.SpeechSynthesisOutputFormat.Audio16Khz64KBitRateMonoMp3,\n \"audio-24khz-48kbitrate-mono-mp3\": SpeechSDK.SpeechSynthesisOutputFormat.Audio24Khz48KBitRateMonoMp3,\n \"audio-24khz-96kbitrate-mono-mp3\": SpeechSDK.SpeechSynthesisOutputFormat.Audio24Khz96KBitRateMonoMp3,\n \"audio-24khz-160kbitrate-mono-mp3\": SpeechSDK.SpeechSynthesisOutputFormat.Audio24Khz160KBitRateMonoMp3,\n \"raw-16khz-16bit-mono-truesilk\": SpeechSDK.SpeechSynthesisOutputFormat.Raw16Khz16BitMonoTrueSilk,\n \"riff-16khz-16bit-mono-pcm\": SpeechSDK.SpeechSynthesisOutputFormat.Riff16Khz16BitMonoPcm,\n \"riff-8khz-16bit-mono-pcm\": SpeechSDK.SpeechSynthesisOutputFormat.Riff8Khz16BitMonoPcm,\n \"riff-24khz-16bit-mono-pcm\": SpeechSDK.SpeechSynthesisOutputFormat.Riff24Khz16BitMonoPcm,\n \"riff-8khz-8bit-mono-mulaw\": SpeechSDK.SpeechSynthesisOutputFormat.Riff8Khz8BitMonoMULaw,\n \"raw-16khz-16bit-mono-pcm\": SpeechSDK.SpeechSynthesisOutputFormat.Raw16Khz16BitMonoPcm,\n \"raw-24khz-16bit-mono-pcm\": SpeechSDK.SpeechSynthesisOutputFormat.Raw24Khz16BitMonoPcm,\n \"raw-8khz-16bit-mono-pcm\": SpeechSDK.SpeechSynthesisOutputFormat.Raw8Khz16BitMonoPcm,\n \"ogg-16khz-16bit-mono-opus\": SpeechSDK.SpeechSynthesisOutputFormat.Ogg16Khz16BitMonoOpus,\n \"ogg-24khz-16bit-mono-opus\": SpeechSDK.SpeechSynthesisOutputFormat.Ogg24Khz16BitMonoOpus,\n \"raw-48khz-16bit-mono-pcm\": SpeechSDK.SpeechSynthesisOutputFormat.Raw48Khz16BitMonoPcm,\n \"riff-48khz-16bit-mono-pcm\": SpeechSDK.SpeechSynthesisOutputFormat.Riff48Khz16BitMonoPcm,\n \"audio-48khz-96kbitrate-mono-mp3\": SpeechSDK.SpeechSynthesisOutputFormat.Audio48Khz96KBitRateMonoMp3,\n \"audio-48khz-192kbitrate-mono-mp3\": SpeechSDK.SpeechSynthesisOutputFormat.Audio48Khz192KBitRateMonoMp3,\n \"ogg-48khz-16bit-mono-opus\": SpeechSDK.SpeechSynthesisOutputFormat.Ogg48Khz16BitMonoOpus,\n \"webm-16khz-16bit-mono-opus\": SpeechSDK.SpeechSynthesisOutputFormat.Webm16Khz16BitMonoOpus,\n \"webm-24khz-16bit-mono-opus\": SpeechSDK.SpeechSynthesisOutputFormat.Webm24Khz16BitMonoOpus,\n \"webm-24khz-16bit-24kbps-mono-opus\": SpeechSDK.SpeechSynthesisOutputFormat.Webm24Khz16Bit24KbpsMonoOpus,\n \"raw-24khz-16bit-mono-truesilk\": SpeechSDK.SpeechSynthesisOutputFormat.Raw24Khz16BitMonoTrueSilk,\n \"raw-8khz-8bit-mono-alaw\": SpeechSDK.SpeechSynthesisOutputFormat.Raw8Khz8BitMonoALaw,\n \"riff-8khz-8bit-mono-alaw\": SpeechSDK.SpeechSynthesisOutputFormat.Riff8Khz8BitMonoALaw,\n \"audio-16khz-16bit-32kbps-mono-opus\": SpeechSDK.SpeechSynthesisOutputFormat.Audio16Khz16Bit32KbpsMonoOpus,\n \"audio-24khz-16bit-48kbps-mono-opus\": SpeechSDK.SpeechSynthesisOutputFormat.Audio24Khz16Bit48KbpsMonoOpus,\n \"audio-24khz-16bit-24kbps-mono-opus\": SpeechSDK.SpeechSynthesisOutputFormat.Audio24Khz16Bit24KbpsMonoOpus,\n \"raw-22050hz-16bit-mono-pcm\": SpeechSDK.SpeechSynthesisOutputFormat.Raw22050Hz16BitMonoPcm,\n \"riff-22050hz-16bit-mono-pcm\": SpeechSDK.SpeechSynthesisOutputFormat.Riff22050Hz16BitMonoPcm,\n \"raw-44100hz-16bit-mono-pcm\": SpeechSDK.SpeechSynthesisOutputFormat.Raw44100Hz16BitMonoPcm,\n \"riff-44100hz-16bit-mono-pcm\": SpeechSDK.SpeechSynthesisOutputFormat.Riff44100Hz16BitMonoPcm,\n \"amr-wb-16000hz\": SpeechSDK.SpeechSynthesisOutputFormat.AmrWb16000Hz,\n \"g722-16khz-64kbps\": SpeechSDK.SpeechSynthesisOutputFormat.G72216Khz64Kbps,\n};\n\nexport function resolveOutputFormat(outputFormat: string): SpeechSDK.SpeechSynthesisOutputFormat {\n const resolvedFormat = OUTPUT_FORMATS[outputFormat];\n if (resolvedFormat === undefined) {\n throw new Error(`Unsupported Azure Speech output format: ${outputFormat}`);\n }\n\n return resolvedFormat;\n}\n","import { validateAzureSsml, type AzureValidationOptions, type SsmlDiagnostic } from \"@ssml-builder-js/ssml-core\";\nimport { AzureTtsError, createSpeechSdkError } from \"./errors.ts\";\nimport type { AzureTtsClient } from \"./client.ts\";\nimport type { SsmlSynthesisResult } from \"./types.ts\";\n\nexport interface SsmlValidationError {\n readonly kind: \"validation\";\n readonly message: string;\n readonly diagnostics: readonly SsmlDiagnostic[];\n}\n\nexport type Result<T, E> =\n | { readonly ok: true; readonly success: true; readonly status: \"success\"; readonly value: T }\n | {\n readonly ok: false;\n readonly success: false;\n readonly status: \"validation-error\" | \"azure-api-error\";\n readonly error: E;\n };\n\nexport type SynthesisResult<T, E> = Result<T, E>;\n\nexport type Success<T> = Extract<Result<T, never>, { readonly ok: true }>;\nexport type ValidationErrorResult = Extract<\n Result<never, SsmlValidationError>,\n { readonly status: \"validation-error\" }\n>;\nexport type AzureApiErrorResult = Extract<Result<never, AzureTtsError>, { readonly status: \"azure-api-error\" }>;\n\nexport type SsmlSynthesisSafeResult =\n | Result<SsmlSynthesisResult, never>\n | Result<never, SsmlValidationError>\n | Result<never, AzureTtsError>;\n\nexport interface SynthesizeSsmlSafeOptions extends AzureValidationOptions {\n /** Optional nested form for callers that want to keep validation settings grouped. */\n validation?: AzureValidationOptions;\n}\n\ninterface SynthesisClient {\n synthesizeSsml(ssml: string): Promise<SsmlSynthesisResult>;\n}\n\n/** Validates SSML before invoking Azure and converts validation/API failures to one result shape. */\nexport async function synthesizeSsmlSafe(\n client: Pick<AzureTtsClient, \"synthesizeSsml\"> | SynthesisClient,\n ssml: string,\n options: SynthesizeSsmlSafeOptions = {},\n): Promise<SsmlSynthesisSafeResult> {\n const validationOptions = options.validation ?? options;\n const diagnostics = await Promise.resolve(validateAzureSsml(ssml, validationOptions));\n const errors = diagnostics.filter((diagnostic) => diagnostic.severity === \"error\");\n if (errors.length > 0) {\n return {\n ok: false,\n success: false,\n status: \"validation-error\",\n error: {\n kind: \"validation\",\n message: \"SSML validation failed; the Azure Speech API was not called.\",\n diagnostics: errors,\n },\n };\n }\n\n try {\n return { ok: true, success: true, status: \"success\", value: await client.synthesizeSsml(ssml) };\n } catch (error) {\n const azureError = error instanceof AzureTtsError ? error : createSpeechSdkError(error);\n return { ok: false, success: false, status: \"azure-api-error\", error: azureError };\n }\n}\n","import { synthesizeSpeech, synthesizeSsml, synthesizeSsmlChunks } from \"./synthesis.ts\";\nimport { synthesizeSsmlSafe } from \"./safe.ts\";\nimport type { SynthesizeSsmlSafeOptions } from \"./safe.ts\";\nimport type {\n AzureTtsClientOptions,\n SsmlSynthesisChunk,\n SsmlSynthesisResult,\n SynthesizeChunksOptions,\n} from \"./types.ts\";\n\nconst ENDPOINT_TEMPLATE = \"https://{region}.tts.speech.microsoft.com/cognitiveservices/v1\";\n\nexport class AzureTtsClient {\n readonly #options: AzureTtsClientOptions;\n\n constructor(options: AzureTtsClientOptions) {\n this.#options = options;\n }\n\n async synthesize(ssml: string): Promise<ArrayBuffer> {\n const { region, subscriptionKey, outputFormat, signal, timeoutMs } = this.#options;\n const endpoint = this.#options.endpoint?.trim() || ENDPOINT_TEMPLATE.replace(\"{region}\", region);\n this.#options.logger?.debug?.(\"Using Azure TTS endpoint:\", endpoint);\n\n const config = { endpoint, region, subscriptionKey, outputFormat, signal, timeoutMs };\n return synthesizeSpeech(ssml, config);\n }\n\n async synthesizeSsml(ssml: string): Promise<SsmlSynthesisResult> {\n const { region, subscriptionKey, outputFormat, signal, timeoutMs } = this.#options;\n const endpoint = this.#options.endpoint?.trim() || ENDPOINT_TEMPLATE.replace(\"{region}\", region);\n this.#options.logger?.debug?.(\"Using Azure TTS endpoint:\", endpoint);\n\n return synthesizeSsml(ssml, { endpoint, region, subscriptionKey, outputFormat, signal, timeoutMs });\n }\n\n async synthesizeChunks(\n chunks: readonly (SsmlSynthesisChunk | string)[],\n options: SynthesizeChunksOptions = {},\n ): Promise<SsmlSynthesisResult> {\n const { region, subscriptionKey, outputFormat, signal, timeoutMs } = this.#options;\n const endpoint = this.#options.endpoint?.trim() || ENDPOINT_TEMPLATE.replace(\"{region}\", region);\n return synthesizeSsmlChunks(chunks, {\n endpoint,\n region,\n subscriptionKey,\n outputFormat,\n signal,\n timeoutMs,\n onProgress: options.onProgress ?? this.#options.onProgress,\n });\n }\n\n async synthesizeSsmlSafe(ssml: string, options: SynthesizeSsmlSafeOptions = {}) {\n return synthesizeSsmlSafe(this, ssml, options);\n }\n}\n","const AZURE_VOICE_API_VERSION = \"2025-10-01\";\n\nexport interface FetchAzureVoiceCatalogOptions {\n apiKey: string;\n region: string | string[];\n}\n\nexport interface AzureVoiceCatalogVoice {\n name: string;\n locale: string;\n secondaryLocales?: readonly string[];\n styles?: readonly string[];\n regions: readonly string[];\n status?: \"ga\" | \"preview\" | \"deprecated\";\n}\n\nexport interface FetchedAzureVoiceCatalogMetadata {\n voiceCount: number;\n generatedAt: string;\n apiVersion: string;\n regions: readonly string[];\n}\n\nexport interface AzureVoiceCatalog {\n voices: readonly AzureVoiceCatalogVoice[];\n metadata: FetchedAzureVoiceCatalogMetadata;\n}\n\ninterface AzureVoiceApiRecord {\n Locale?: unknown;\n Name?: unknown;\n SecondaryLocaleList?: unknown;\n ShortName?: unknown;\n Status?: unknown;\n StyleList?: unknown;\n}\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nfunction stringList(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return [...new Set(value.map(stringValue).filter((item): item is string => item !== undefined))];\n}\n\nfunction normalizeStatus(value: unknown): AzureVoiceCatalogVoice[\"status\"] {\n const status = stringValue(value)?.toLowerCase();\n if (status === \"preview\" || status === \"deprecated\" || status === \"ga\") return status;\n return undefined;\n}\n\nfunction normalizeRegions(region: string | string[]): string[] {\n const regions = Array.isArray(region) ? region : [region];\n const result = [...new Set(regions.map((item) => item.trim()).filter(Boolean))];\n if (result.length === 0) throw new TypeError(\"At least one Azure Speech region is required.\");\n return result;\n}\n\nasync function fetchRegionVoices(region: string, apiKey: string): Promise<AzureVoiceApiRecord[]> {\n const endpoint = `https://${encodeURIComponent(region)}.tts.speech.microsoft.com/cognitiveservices/voices/list`;\n const response = await fetch(endpoint, {\n headers: {\n Accept: \"application/json\",\n \"Ocp-Apim-Subscription-Key\": apiKey,\n },\n });\n if (!response.ok) {\n throw new Error(`Azure List Voices API request failed for region \"${region}\" with HTTP ${response.status}.`);\n }\n const payload: unknown = await response.json();\n if (!Array.isArray(payload)) throw new Error(`Azure List Voices API returned an invalid response for \"${region}\".`);\n return payload.filter((item): item is AzureVoiceApiRecord => Boolean(item && typeof item === \"object\"));\n}\n\n/** Fetches and deduplicates the current Azure Speech voice catalog for one or more regions. */\nexport async function fetchAzureVoiceCatalog(options: FetchAzureVoiceCatalogOptions): Promise<AzureVoiceCatalog> {\n if (!options || typeof options.apiKey !== \"string\" || !options.apiKey.trim())\n throw new TypeError(\"An Azure Speech API key is required.\");\n const regions = normalizeRegions(options.region);\n const payloads = await Promise.all(regions.map((region) => fetchRegionVoices(region, options.apiKey)));\n const voices = new Map<string, AzureVoiceCatalogVoice>();\n\n for (let regionIndex = 0; regionIndex < payloads.length; regionIndex += 1) {\n const region = regions[regionIndex];\n for (const record of payloads[regionIndex]) {\n const name = stringValue(record.ShortName) ?? stringValue(record.Name);\n const locale = stringValue(record.Locale);\n if (!name || !locale) continue;\n const key = name.toLowerCase();\n const existing = voices.get(key);\n const secondaryLocales = stringList(record.SecondaryLocaleList);\n const styles = stringList(record.StyleList);\n const status = normalizeStatus(record.Status);\n const merged: AzureVoiceCatalogVoice = {\n name: existing?.name ?? name,\n locale: existing?.locale ?? locale,\n regions: [...new Set([...(existing?.regions ?? []), region])],\n };\n const mergedSecondaryLocales = [...new Set([...(existing?.secondaryLocales ?? []), ...secondaryLocales])];\n if (mergedSecondaryLocales.length > 0) merged.secondaryLocales = mergedSecondaryLocales;\n const mergedStyles = [...new Set([...(existing?.styles ?? []), ...styles])];\n if (mergedStyles.length > 0) merged.styles = mergedStyles;\n if (status) merged.status = status;\n else if (existing?.status) merged.status = existing.status;\n voices.set(key, merged);\n }\n }\n\n const sortedVoices = [...voices.values()].sort((first, second) => first.name.localeCompare(second.name));\n return {\n voices: sortedVoices,\n metadata: {\n voiceCount: sortedVoices.length,\n generatedAt: new Date().toISOString(),\n apiVersion: AZURE_VOICE_API_VERSION,\n regions,\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAO,IAAM,gBAAN,cAA4B,MAAM;AAAA,EAMvC,YAAY,QAAgB,YAAoB,cAAsB,WAA0B;AAC9F,UAAM,6BAA6B,MAAM,IAAI,UAAU,EAAE;AACzD,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,aAAa;AAClB,SAAK,eAAe;AACpB,SAAK,YAAY;AAAA,EACnB;AACF;AAEO,IAAM,mBAAN,cAA+B,cAAc;AAAA,EAGlD,YAAY,cAAsB;AAChC,UAAM,GAAG,cAAc,cAAc,IAAI;AACzC,SAAK,OAAO;AACZ,SAAK,UAAU,+BAA+B,YAAY;AAC1D,SAAK,eAAe;AAAA,EACtB;AACF;AAEO,SAAS,qBAAqB,OAAkC;AACrE,QAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,SAAO,IAAI,iBAAiB,OAAO;AACrC;;;AC9BA,YAAYA,gBAAe;;;ACA3B,SAAS,oBAAoB;;;ACA7B,YAAY,eAAe;AAEpB,IAAM,wBAAwB;AAErC,IAAM,iBAAwE;AAAA,EAC5E,4BAAsC,sCAA4B;AAAA,EAClE,gCAA0C,sCAA4B;AAAA,EACtE,iCAA2C,sCAA4B;AAAA,EACvE,mCAA6C,sCAA4B;AAAA,EACzE,oCAA8C,sCAA4B;AAAA,EAC1E,mCAA6C,sCAA4B;AAAA,EACzE,mCAA6C,sCAA4B;AAAA,EACzE,mCAA6C,sCAA4B;AAAA,EACzE,oCAA8C,sCAA4B;AAAA,EAC1E,iCAA2C,sCAA4B;AAAA,EACvE,6BAAuC,sCAA4B;AAAA,EACnE,4BAAsC,sCAA4B;AAAA,EAClE,6BAAuC,sCAA4B;AAAA,EACnE,6BAAuC,sCAA4B;AAAA,EACnE,4BAAsC,sCAA4B;AAAA,EAClE,4BAAsC,sCAA4B;AAAA,EAClE,2BAAqC,sCAA4B;AAAA,EACjE,6BAAuC,sCAA4B;AAAA,EACnE,6BAAuC,sCAA4B;AAAA,EACnE,4BAAsC,sCAA4B;AAAA,EAClE,6BAAuC,sCAA4B;AAAA,EACnE,mCAA6C,sCAA4B;AAAA,EACzE,oCAA8C,sCAA4B;AAAA,EAC1E,6BAAuC,sCAA4B;AAAA,EACnE,8BAAwC,sCAA4B;AAAA,EACpE,8BAAwC,sCAA4B;AAAA,EACpE,qCAA+C,sCAA4B;AAAA,EAC3E,iCAA2C,sCAA4B;AAAA,EACvE,2BAAqC,sCAA4B;AAAA,EACjE,4BAAsC,sCAA4B;AAAA,EAClE,sCAAgD,sCAA4B;AAAA,EAC5E,sCAAgD,sCAA4B;AAAA,EAC5E,sCAAgD,sCAA4B;AAAA,EAC5E,8BAAwC,sCAA4B;AAAA,EACpE,+BAAyC,sCAA4B;AAAA,EACrE,8BAAwC,sCAA4B;AAAA,EACpE,+BAAyC,sCAA4B;AAAA,EACrE,kBAA4B,sCAA4B;AAAA,EACxD,qBAA+B,sCAA4B;AAC7D;AAEO,SAAS,oBAAoB,cAA6D;AAC/F,QAAM,iBAAiB,eAAe,YAAY;AAClD,MAAI,mBAAmB,QAAW;AAChC,UAAM,IAAI,MAAM,2CAA2C,YAAY,EAAE;AAAA,EAC3E;AAEA,SAAO;AACT;;;ADjDO,SAAS,gBAAgB,QAA2B;AACzD,QAAM,WAAW,OAAO,UAAU,KAAK,KAAK;AAC5C,SAAO,SAAS,QAAQ,eAAe,mBAAmB,OAAO,MAAM,CAAC;AAC1E;AAEO,SAAS,mBAAmB,QAAiC;AAClE,QAAM,EAAE,eAAe,uBAAuB,gBAAgB,IAAI;AAElE,QAAM,WAAW,IAAI,IAAI,gBAAgB,MAAM,CAAC;AAChD,QAAM,eAAe,aAAa,aAAa,UAAU,eAAe;AACxE,eAAa,8BAA8B,oBAAoB,YAAY;AAC3E,SAAO;AACT;;;ADXA,SAAS,qBAAqB,cAAsC,aAAgD;AAClH,MAAI;AACF,gBAAY,MAAM;AAAA,EACpB,QAAQ;AAAA,EAAC;AAET,MAAI;AACF,iBAAa,MAAM;AAAA,EACrB,QAAQ;AAAA,EAAC;AACX;AAEA,IAAM,sBAAsB,CAAC,UAA0B,KAAK,IAAI,GAAG,KAAK,IAAI;AAE5E,eAAsB,eAAe,MAAc,QAAiD;AAClG,MAAI,OAAO,QAAQ,SAAS;AAC1B,UAAM,qBAAqB,iCAAiC;AAAA,EAC9D;AAEA,QAAM,eAAe,mBAAmB,MAAM;AAC9C,QAAM,cAAc,IAAc,6BAAkB,cAAc,IAAI;AAEtE,SAAO,MAAM,IAAI,QAA6B,CAAC,SAAS,WAAW;AACjE,QAAI,kBAAkB;AACtB,QAAI,UAAU;AACd,QAAI;AACJ,QAAI;AACJ,UAAM,UAAU,MAAM;AACpB,UAAI,QAAS,cAAa,OAAO;AACjC,UAAI,aAAc,QAAO,QAAQ,oBAAoB,SAAS,YAAY;AAAA,IAC5E;AACA,UAAM,iBAAiB,MAAM;AAC3B,UAAI,gBAAiB;AACrB,wBAAkB;AAClB,2BAAqB,cAAc,WAAW;AAAA,IAChD;AACA,UAAM,kBAAkB,CAAC,UAAmB;AAC1C,UAAI,QAAS;AACb,gBAAU;AACV,cAAQ;AACR,qBAAe;AACf,aAAO,qBAAqB,KAAK,CAAC;AAAA,IACpC;AAEA,UAAM,aAAgD,CAAC;AACvD,UAAM,UAA0C,CAAC;AACjD,UAAM,YAA8C,CAAC;AACrD,gBAAY,eAAe,CAAC,SAAS,UAAU;AAC7C,iBAAW,KAAK;AAAA,QACd,MAAM,MAAM;AAAA,QACZ,eAAe,oBAAoB,MAAM,WAAW;AAAA,QACpD,YAAY,oBAAoB,MAAM,QAAQ;AAAA,MAChD,CAAC;AAAA,IACH;AACA,gBAAY,iBAAiB,CAAC,SAAS,UAAU;AAC/C,cAAQ,KAAK,EAAE,UAAU,MAAM,UAAU,eAAe,oBAAoB,MAAM,WAAW,EAAE,CAAC;AAAA,IAClG;AACA,gBAAY,kBAAkB,CAAC,SAAS,UAAU;AAChD,gBAAU,KAAK,EAAE,MAAM,MAAM,MAAM,eAAe,oBAAoB,MAAM,WAAW,EAAE,CAAC;AAAA,IAC5F;AAEA,UAAM,KAAK,CAAC,WAA4C;AACtD,UAAI,QAAS;AACb,YAAM,EAAE,QAAQ,aAAa,IAAI;AACjC,UAAI,WAAqB,wBAAa,4BAA4B;AAChE,cAAM,MAAM,gBAAgB,uCAAuC,MAAM;AACzE,wBAAgB,GAAG;AACnB;AAAA,MACF;AACA,gBAAU;AACV,cAAQ;AACR,qBAAe;AACf,YAAM,kBAAkB,KAAK;AAAA,QAC3B;AAAA,QACA,IAAI,cAAc,CAAC,GAAG,IAAI,CAAC,aAAa,SAAS,gBAAgB,SAAS,UAAU;AAAA,QACpF,IAAI,WAAW,CAAC,GAAG,IAAI,CAAC,WAAW,OAAO,aAAa;AAAA,QACvD,IAAI,aAAa,CAAC,GAAG,IAAI,CAAC,aAAa,SAAS,aAAa;AAAA,MAC/D;AACA,YAAM,aAAa,OAAO,gBAAgB,oBAAoB,OAAO,aAAa,IAAI;AACtF,YAAM,YAAa,OAAmE;AACtF,YAAM,oBAAoB,CAAsC,WAAiB;AAAA,QAC/E,GAAG;AAAA,QACH,GAAI,OAAO,kBAAkB,EAAE,WAAW,EAAE,GAAG,OAAO,gBAAgB,EAAE,IAAI,CAAC;AAAA,QAC7E,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,MACnC;AACA,YAAM,mBAAmB,WAAW,IAAI,CAAC,aAAa,kBAAkB,QAAQ,CAAC;AACjF,YAAM,gBAAgB,QAAQ,IAAI,CAAC,WAAW,kBAAkB,MAAM,CAAC;AACvE,YAAM,kBAAkB,UAAU,IAAI,CAAC,aAAa,kBAAkB,QAAQ,CAAC;AAC/E,cAAQ;AAAA,QACN,WAAW,OAAO;AAAA,QAClB;AAAA,QACA,GAAI,OAAO,kBAAkB,EAAE,WAAW,EAAE,GAAG,OAAO,gBAAgB,EAAE,IAAI,CAAC;AAAA,QAC7E,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,QACjC,GAAI,iBAAiB,SAAS,IAC1B,EAAE,YAAY,kBAAkB,cAAc,kBAAkB,gBAAgB,iBAAiB,IACjG,CAAC;AAAA,QACL,GAAI,cAAc,SAAS,IAAI,EAAE,SAAS,cAAc,IAAI,CAAC;AAAA,QAC7D,GAAI,gBAAgB,SAAS,IAAI,EAAE,WAAW,gBAAgB,IAAI,CAAC;AAAA,MACrE,CAAC;AAAA,IACH;AAEA,QAAI;AACF,UAAI,OAAO,QAAQ;AACjB,uBAAe,MAAM,gBAAgB,iCAAiC;AACtE,eAAO,OAAO,iBAAiB,SAAS,cAAc,EAAE,MAAM,KAAK,CAAC;AAAA,MACtE;AACA,UAAI,OAAO,cAAc,UAAa,OAAO,YAAY,GAAG;AAC1D,kBAAU;AAAA,UACR,MAAM,gBAAgB,oCAAoC,OAAO,SAAS,MAAM;AAAA,UAChF,OAAO;AAAA,QACT;AAAA,MACF;AACA,kBAAY,eAAe,MAAM,IAAI,eAAe;AAAA,IACtD,SAAS,OAAO;AACd,sBAAgB,KAAK;AAAA,IACvB;AAAA,EACF,CAAC;AACH;AAGA,eAAsB,qBACpB,QACA,QAC8B;AAC9B,QAAM,UAAiC,CAAC;AACxC,QAAM,cAAc,OAAO;AAC3B,aAAW,CAAC,OAAO,KAAK,KAAK,OAAO,QAAQ,GAAG;AAC7C,UAAM,QAAQ,OAAO,UAAU,WAAW,EAAE,MAAM,MAAM,IAAI;AAC5D,UAAM,SAAS,MAAM,eAAe,MAAM,MAAM;AAAA,MAC9C,GAAG;AAAA,MACH,GAAI,MAAM,oBAAoB,EAAE,iBAAiB,MAAM,kBAAkB,IAAI,CAAC;AAAA,MAC9E,YAAY;AAAA,IACd,CAAC;AACD,YAAQ,KAAK,MAAM;AACnB,WAAO,aAAa;AAAA,MAClB,cAAc,QAAQ;AAAA,MACtB;AAAA,MACA,SAAS,gBAAgB,IAAI,MAAM,KAAK,OAAQ,QAAQ,KAAK,cAAe,GAAG;AAAA,IACjF,CAAC;AAAA,EACH;AACA,SAAO,sBAAsB,OAAO;AACtC;AAGO,SAAS,sBAAsB,SAA8D;AAClG,QAAM,cAAc,QAAQ,OAAO,CAAC,OAAO,WAAW,QAAQ,OAAO,UAAU,YAAY,CAAC;AAC5F,QAAM,YAAY,IAAI,WAAW,WAAW;AAC5C,QAAM,aAA6D,CAAC;AACpE,QAAM,UAAuD,CAAC;AAC9D,QAAM,YAA2D,CAAC;AAClE,MAAI,aAAa;AACjB,MAAI,iBAAiB;AAErB,aAAW,UAAU,SAAS;AAC5B,cAAU,IAAI,IAAI,WAAW,OAAO,SAAS,GAAG,UAAU;AAC1D,kBAAc,OAAO,UAAU;AAC/B,UAAM,kBACJ,OAAO,cAAc,OAAO,WAAW,SAAS,IAC5C,OAAO,aACN,OAAO,gBAAgB,OAAO,kBAAkB,CAAC;AACxD,eAAW,YAAY,iBAAiB;AACtC,YAAM,YAAY,SAAS,aAAa,OAAO;AAC/C,YAAM,YAAY,SAAS,aAAa,OAAO;AAC/C,iBAAW,KAAK;AAAA,QACd,GAAG;AAAA,QACH,eAAe,SAAS,gBAAgB;AAAA,QACxC,GAAI,YAAY,EAAE,WAAW,EAAE,GAAG,UAAU,EAAE,IAAI,CAAC;AAAA,QACnD,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,MACnC,CAAC;AAAA,IACH;AACA,eAAW,UAAU,OAAO,WAAW,CAAC,GAAG;AACzC,YAAM,YAAY,OAAO,aAAa,OAAO;AAC7C,YAAM,YAAY,OAAO,aAAa,OAAO;AAC7C,cAAQ,KAAK;AAAA,QACX,GAAG;AAAA,QACH,eAAe,OAAO,gBAAgB;AAAA,QACtC,GAAI,YAAY,EAAE,WAAW,EAAE,GAAG,UAAU,EAAE,IAAI,CAAC;AAAA,QACnD,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,MACnC,CAAC;AAAA,IACH;AACA,eAAW,YAAY,OAAO,aAAa,CAAC,GAAG;AAC7C,YAAM,YAAY,SAAS,aAAa,OAAO;AAC/C,YAAM,YAAY,SAAS,aAAa,OAAO;AAC/C,gBAAU,KAAK;AAAA,QACb,GAAG;AAAA,QACH,eAAe,SAAS,gBAAgB;AAAA,QACxC,GAAI,YAAY,EAAE,WAAW,EAAE,GAAG,UAAU,EAAE,IAAI,CAAC;AAAA,QACnD,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,MACnC,CAAC;AAAA,IACH;AACA,sBAAkB,KAAK,IAAI,GAAG,OAAO,UAAU;AAAA,EACjD;AAEA,SAAO;AAAA,IACL,WAAW,UAAU;AAAA,IACrB,YAAY;AAAA,IACZ,GAAI,WAAW,SAAS,IAAI,EAAE,YAAY,cAAc,YAAY,gBAAgB,WAAW,IAAI,CAAC;AAAA,IACpG,GAAI,QAAQ,SAAS,IAAI,EAAE,QAAQ,IAAI,CAAC;AAAA,IACxC,GAAI,UAAU,SAAS,IAAI,EAAE,UAAU,IAAI,CAAC;AAAA,IAC5C,GAAI,QAAQ,WAAW,KAAK,QAAQ,CAAC,GAAG,YAAY,EAAE,WAAW,QAAQ,CAAC,EAAE,UAAU,IAAI,CAAC;AAAA,IAC3F,GAAI,QAAQ,WAAW,KAAK,QAAQ,CAAC,GAAG,YAAY,EAAE,WAAW,EAAE,GAAG,QAAQ,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC;AAAA,EACpG;AACF;AAGA,eAAsB,iBAAiB,MAAc,QAAyC;AAC5F,UAAQ,MAAM,eAAe,MAAM,MAAM,GAAG;AAC9C;;;AGtKA,eAAsB,mBACpB,QACA,MACA,UAAqC,CAAC,GACJ;AAClC,QAAM,oBAAoB,QAAQ,cAAc;AAChD,QAAM,cAAc,MAAM,QAAQ,QAAQC,mBAAkB,MAAM,iBAAiB,CAAC;AACpF,QAAM,SAAS,YAAY,OAAO,CAAC,eAAe,WAAW,aAAa,OAAO;AACjF,MAAI,OAAO,SAAS,GAAG;AACrB,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,OAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS;AAAA,QACT,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,MAAI;AACF,WAAO,EAAE,IAAI,MAAM,SAAS,MAAM,QAAQ,WAAW,OAAO,MAAM,OAAO,eAAe,IAAI,EAAE;AAAA,EAChG,SAAS,OAAO;AACd,UAAM,aAAa,iBAAiB,gBAAgB,QAAQ,qBAAqB,KAAK;AACtF,WAAO,EAAE,IAAI,OAAO,SAAS,OAAO,QAAQ,mBAAmB,OAAO,WAAW;AAAA,EACnF;AACF;;;AC7DA,IAAM,oBAAoB;AAV1B;AAYO,IAAM,iBAAN,MAAqB;AAAA,EAG1B,YAAY,SAAgC;AAF5C,uBAAS;AAGP,uBAAK,UAAW;AAAA,EAClB;AAAA,EAEA,MAAM,WAAW,MAAoC;AACnD,UAAM,EAAE,QAAQ,iBAAiB,cAAc,QAAQ,UAAU,IAAI,mBAAK;AAC1E,UAAM,WAAW,mBAAK,UAAS,UAAU,KAAK,KAAK,kBAAkB,QAAQ,YAAY,MAAM;AAC/F,uBAAK,UAAS,QAAQ,QAAQ,6BAA6B,QAAQ;AAEnE,UAAM,SAAS,EAAE,UAAU,QAAQ,iBAAiB,cAAc,QAAQ,UAAU;AACpF,WAAO,iBAAiB,MAAM,MAAM;AAAA,EACtC;AAAA,EAEA,MAAM,eAAe,MAA4C;AAC/D,UAAM,EAAE,QAAQ,iBAAiB,cAAc,QAAQ,UAAU,IAAI,mBAAK;AAC1E,UAAM,WAAW,mBAAK,UAAS,UAAU,KAAK,KAAK,kBAAkB,QAAQ,YAAY,MAAM;AAC/F,uBAAK,UAAS,QAAQ,QAAQ,6BAA6B,QAAQ;AAEnE,WAAO,eAAe,MAAM,EAAE,UAAU,QAAQ,iBAAiB,cAAc,QAAQ,UAAU,CAAC;AAAA,EACpG;AAAA,EAEA,MAAM,iBACJ,QACA,UAAmC,CAAC,GACN;AAC9B,UAAM,EAAE,QAAQ,iBAAiB,cAAc,QAAQ,UAAU,IAAI,mBAAK;AAC1E,UAAM,WAAW,mBAAK,UAAS,UAAU,KAAK,KAAK,kBAAkB,QAAQ,YAAY,MAAM;AAC/F,WAAO,qBAAqB,QAAQ;AAAA,MAClC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY,QAAQ,cAAc,mBAAK,UAAS;AAAA,IAClD,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,mBAAmB,MAAc,UAAqC,CAAC,GAAG;AAC9E,WAAO,mBAAmB,MAAM,MAAM,OAAO;AAAA,EAC/C;AACF;AA3CW;;;ACbX,IAAM,0BAA0B;AAqChC,SAAS,YAAY,OAAoC;AACvD,SAAO,OAAO,UAAU,YAAY,MAAM,KAAK,IAAI,MAAM,KAAK,IAAI;AACpE;AAEA,SAAS,WAAW,OAA0B;AAC5C,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO,CAAC;AACnC,SAAO,CAAC,GAAG,IAAI,IAAI,MAAM,IAAI,WAAW,EAAE,OAAO,CAAC,SAAyB,SAAS,MAAS,CAAC,CAAC;AACjG;AAEA,SAAS,gBAAgB,OAAkD;AACzE,QAAM,SAAS,YAAY,KAAK,GAAG,YAAY;AAC/C,MAAI,WAAW,aAAa,WAAW,gBAAgB,WAAW,KAAM,QAAO;AAC/E,SAAO;AACT;AAEA,SAAS,iBAAiB,QAAqC;AAC7D,QAAM,UAAU,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;AACxD,QAAM,SAAS,CAAC,GAAG,IAAI,IAAI,QAAQ,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EAAE,OAAO,OAAO,CAAC,CAAC;AAC9E,MAAI,OAAO,WAAW,EAAG,OAAM,IAAI,UAAU,+CAA+C;AAC5F,SAAO;AACT;AAEA,eAAe,kBAAkB,QAAgB,QAAgD;AAC/F,QAAM,WAAW,WAAW,mBAAmB,MAAM,CAAC;AACtD,QAAM,WAAW,MAAM,MAAM,UAAU;AAAA,IACrC,SAAS;AAAA,MACP,QAAQ;AAAA,MACR,6BAA6B;AAAA,IAC/B;AAAA,EACF,CAAC;AACD,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,oDAAoD,MAAM,eAAe,SAAS,MAAM,GAAG;AAAA,EAC7G;AACA,QAAM,UAAmB,MAAM,SAAS,KAAK;AAC7C,MAAI,CAAC,MAAM,QAAQ,OAAO,EAAG,OAAM,IAAI,MAAM,2DAA2D,MAAM,IAAI;AAClH,SAAO,QAAQ,OAAO,CAAC,SAAsC,QAAQ,QAAQ,OAAO,SAAS,QAAQ,CAAC;AACxG;AAGA,eAAsB,uBAAuB,SAAoE;AAC/G,MAAI,CAAC,WAAW,OAAO,QAAQ,WAAW,YAAY,CAAC,QAAQ,OAAO,KAAK;AACzE,UAAM,IAAI,UAAU,sCAAsC;AAC5D,QAAM,UAAU,iBAAiB,QAAQ,MAAM;AAC/C,QAAM,WAAW,MAAM,QAAQ,IAAI,QAAQ,IAAI,CAAC,WAAW,kBAAkB,QAAQ,QAAQ,MAAM,CAAC,CAAC;AACrG,QAAM,SAAS,oBAAI,IAAoC;AAEvD,WAAS,cAAc,GAAG,cAAc,SAAS,QAAQ,eAAe,GAAG;AACzE,UAAM,SAAS,QAAQ,WAAW;AAClC,eAAW,UAAU,SAAS,WAAW,GAAG;AAC1C,YAAM,OAAO,YAAY,OAAO,SAAS,KAAK,YAAY,OAAO,IAAI;AACrE,YAAM,SAAS,YAAY,OAAO,MAAM;AACxC,UAAI,CAAC,QAAQ,CAAC,OAAQ;AACtB,YAAM,MAAM,KAAK,YAAY;AAC7B,YAAM,WAAW,OAAO,IAAI,GAAG;AAC/B,YAAM,mBAAmB,WAAW,OAAO,mBAAmB;AAC9D,YAAM,SAAS,WAAW,OAAO,SAAS;AAC1C,YAAM,SAAS,gBAAgB,OAAO,MAAM;AAC5C,YAAM,SAAiC;AAAA,QACrC,MAAM,UAAU,QAAQ;AAAA,QACxB,QAAQ,UAAU,UAAU;AAAA,QAC5B,SAAS,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAI,UAAU,WAAW,CAAC,GAAI,MAAM,CAAC,CAAC;AAAA,MAC9D;AACA,YAAM,yBAAyB,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAI,UAAU,oBAAoB,CAAC,GAAI,GAAG,gBAAgB,CAAC,CAAC;AACxG,UAAI,uBAAuB,SAAS,EAAG,QAAO,mBAAmB;AACjE,YAAM,eAAe,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAI,UAAU,UAAU,CAAC,GAAI,GAAG,MAAM,CAAC,CAAC;AAC1E,UAAI,aAAa,SAAS,EAAG,QAAO,SAAS;AAC7C,UAAI,OAAQ,QAAO,SAAS;AAAA,eACnB,UAAU,OAAQ,QAAO,SAAS,SAAS;AACpD,aAAO,IAAI,KAAK,MAAM;AAAA,IACxB;AAAA,EACF;AAEA,QAAM,eAAe,CAAC,GAAG,OAAO,OAAO,CAAC,EAAE,KAAK,CAAC,OAAO,WAAW,MAAM,KAAK,cAAc,OAAO,IAAI,CAAC;AACvG,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,UAAU;AAAA,MACR,YAAY,aAAa;AAAA,MACzB,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,YAAY;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AACF;","names":["SpeechSDK","validateAzureSsml"]}
|
package/dist/react.d.mts
CHANGED
|
@@ -1,160 +1,8 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { ReactNode,
|
|
2
|
+
import { ReactNode, ReactElement, CSSProperties } from 'react';
|
|
3
|
+
import { a as SsmlDocument, b as SsmlElement } from './index.d-Xbr6ZWnK.mjs';
|
|
3
4
|
import { OnMount, Monaco } from '@monaco-editor/react';
|
|
4
5
|
|
|
5
|
-
type SsmlAttributeValue = string | number;
|
|
6
|
-
type SsmlAttributes = Record<string, SsmlAttributeValue>;
|
|
7
|
-
interface SsmlText {
|
|
8
|
-
type: "text";
|
|
9
|
-
value: string;
|
|
10
|
-
}
|
|
11
|
-
type SsmlNode = string | SsmlText | SsmlElement;
|
|
12
|
-
interface SsmlElementBase {
|
|
13
|
-
children?: SsmlNode[];
|
|
14
|
-
attributes?: SsmlAttributes;
|
|
15
|
-
}
|
|
16
|
-
interface VoiceElement extends SsmlElementBase {
|
|
17
|
-
type: "voice";
|
|
18
|
-
name?: string;
|
|
19
|
-
effect?: string;
|
|
20
|
-
}
|
|
21
|
-
interface ProsodyElement extends SsmlElementBase {
|
|
22
|
-
type: "prosody";
|
|
23
|
-
rate?: SsmlAttributeValue;
|
|
24
|
-
pitch?: SsmlAttributeValue;
|
|
25
|
-
volume?: SsmlAttributeValue;
|
|
26
|
-
contour?: string;
|
|
27
|
-
range?: SsmlAttributeValue;
|
|
28
|
-
}
|
|
29
|
-
interface BreakElement extends SsmlElementBase {
|
|
30
|
-
type: "break";
|
|
31
|
-
time?: SsmlAttributeValue;
|
|
32
|
-
strength?: string;
|
|
33
|
-
}
|
|
34
|
-
interface ExpressAsElement extends SsmlElementBase {
|
|
35
|
-
type: "express-as" | "expressAs" | "mstts:express-as";
|
|
36
|
-
style?: string;
|
|
37
|
-
styleDegree?: SsmlAttributeValue;
|
|
38
|
-
role?: string;
|
|
39
|
-
}
|
|
40
|
-
interface SayAsElement extends SsmlElementBase {
|
|
41
|
-
type: "say-as" | "sayAs";
|
|
42
|
-
interpretAs?: string;
|
|
43
|
-
format?: string;
|
|
44
|
-
detail?: string;
|
|
45
|
-
}
|
|
46
|
-
interface PhonemeElement extends SsmlElementBase {
|
|
47
|
-
type: "phoneme";
|
|
48
|
-
alphabet?: string;
|
|
49
|
-
ph?: string;
|
|
50
|
-
}
|
|
51
|
-
interface EmphasisElement extends SsmlElementBase {
|
|
52
|
-
type: "emphasis";
|
|
53
|
-
level?: string;
|
|
54
|
-
}
|
|
55
|
-
interface AudioElement extends SsmlElementBase {
|
|
56
|
-
type: "audio";
|
|
57
|
-
src?: string;
|
|
58
|
-
desc?: string;
|
|
59
|
-
clipBegin?: SsmlAttributeValue;
|
|
60
|
-
clipEnd?: SsmlAttributeValue;
|
|
61
|
-
speed?: SsmlAttributeValue;
|
|
62
|
-
repeatCount?: SsmlAttributeValue;
|
|
63
|
-
repeatDuration?: SsmlAttributeValue;
|
|
64
|
-
soundLevel?: SsmlAttributeValue;
|
|
65
|
-
}
|
|
66
|
-
interface SubElement extends SsmlElementBase {
|
|
67
|
-
type: "sub";
|
|
68
|
-
alias?: string;
|
|
69
|
-
}
|
|
70
|
-
interface LangElement extends SsmlElementBase {
|
|
71
|
-
type: "lang";
|
|
72
|
-
lang?: string;
|
|
73
|
-
}
|
|
74
|
-
interface MarkElement extends SsmlElementBase {
|
|
75
|
-
type: "mark";
|
|
76
|
-
name?: string;
|
|
77
|
-
}
|
|
78
|
-
interface BookmarkElement extends SsmlElementBase {
|
|
79
|
-
type: "bookmark";
|
|
80
|
-
mark?: string;
|
|
81
|
-
}
|
|
82
|
-
interface LexiconElement extends SsmlElementBase {
|
|
83
|
-
type: "lexicon";
|
|
84
|
-
uri?: string;
|
|
85
|
-
}
|
|
86
|
-
interface ParagraphElement extends SsmlElementBase {
|
|
87
|
-
type: "p";
|
|
88
|
-
}
|
|
89
|
-
interface SentenceElement extends SsmlElementBase {
|
|
90
|
-
type: "s";
|
|
91
|
-
}
|
|
92
|
-
interface WordElement extends SsmlElementBase {
|
|
93
|
-
type: "w";
|
|
94
|
-
}
|
|
95
|
-
interface MsttsSilenceElement extends SsmlElementBase {
|
|
96
|
-
type: "mstts:silence" | "silence";
|
|
97
|
-
typeValue?: string;
|
|
98
|
-
silenceType?: string;
|
|
99
|
-
value?: SsmlAttributeValue;
|
|
100
|
-
}
|
|
101
|
-
interface MsttsVisemeElement extends SsmlElementBase {
|
|
102
|
-
type: "mstts:viseme" | "viseme";
|
|
103
|
-
typeValue?: string;
|
|
104
|
-
visemeType?: string;
|
|
105
|
-
}
|
|
106
|
-
interface MsttsAudioDurationElement extends SsmlElementBase {
|
|
107
|
-
type: "mstts:audioduration";
|
|
108
|
-
value?: SsmlAttributeValue;
|
|
109
|
-
}
|
|
110
|
-
interface SsmlDialogNode extends SsmlElementBase {
|
|
111
|
-
type: "mstts:dialog";
|
|
112
|
-
}
|
|
113
|
-
interface SsmlTurnNode extends SsmlElementBase {
|
|
114
|
-
type: "mstts:turn";
|
|
115
|
-
voice?: string;
|
|
116
|
-
speaker?: string;
|
|
117
|
-
}
|
|
118
|
-
interface SsmlBackgroundAudioNode extends SsmlElementBase {
|
|
119
|
-
type: "mstts:backgroundaudio";
|
|
120
|
-
src?: string;
|
|
121
|
-
volume?: SsmlAttributeValue;
|
|
122
|
-
fadeIn?: SsmlAttributeValue;
|
|
123
|
-
fadeOut?: SsmlAttributeValue;
|
|
124
|
-
/** XML spelling aliases retained for ergonomic object construction. */
|
|
125
|
-
fadein?: SsmlAttributeValue;
|
|
126
|
-
fadeout?: SsmlAttributeValue;
|
|
127
|
-
}
|
|
128
|
-
interface MsttsTtsEmbeddingElement extends SsmlElementBase {
|
|
129
|
-
type: "mstts:ttsembedding";
|
|
130
|
-
speakerProfileId?: string;
|
|
131
|
-
}
|
|
132
|
-
interface MsttsEmbeddingElement extends SsmlElementBase {
|
|
133
|
-
type: "mstts:embedding";
|
|
134
|
-
id?: string;
|
|
135
|
-
speakerProfileId?: string;
|
|
136
|
-
}
|
|
137
|
-
interface MsttsVoiceConversionElement extends SsmlElementBase {
|
|
138
|
-
type: "mstts:voiceconversion";
|
|
139
|
-
url?: string;
|
|
140
|
-
profile?: string;
|
|
141
|
-
speakerProfileId?: string;
|
|
142
|
-
}
|
|
143
|
-
interface CustomElement extends SsmlElementBase {
|
|
144
|
-
type: "custom" | "element";
|
|
145
|
-
name: string;
|
|
146
|
-
}
|
|
147
|
-
type SsmlElement = VoiceElement | ProsodyElement | BreakElement | ExpressAsElement | SayAsElement | PhonemeElement | EmphasisElement | AudioElement | SubElement | LangElement | MarkElement | BookmarkElement | LexiconElement | ParagraphElement | SentenceElement | WordElement | MsttsSilenceElement | MsttsVisemeElement | MsttsAudioDurationElement | SsmlDialogNode | SsmlTurnNode | SsmlBackgroundAudioNode | MsttsTtsEmbeddingElement | MsttsEmbeddingElement | MsttsVoiceConversionElement | CustomElement;
|
|
148
|
-
interface SsmlDocument {
|
|
149
|
-
type?: "speak";
|
|
150
|
-
version: string;
|
|
151
|
-
lang: string;
|
|
152
|
-
children?: SsmlNode[];
|
|
153
|
-
/** @deprecated Use children to represent the document body. */
|
|
154
|
-
content?: string;
|
|
155
|
-
attributes?: SsmlAttributes;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
6
|
type SsmlEditorInsertionButton = "break" | "emphasis" | "rate" | "pitch" | "volume" | "emotion" | "say-as" | "phoneme" | "audio" | "sub" | "lang" | "mark" | "bookmark" | "mstts:silence" | "mstts:audioduration" | "mstts:viseme" | (string & {});
|
|
159
7
|
type SsmlEditorButton = "help" | SsmlEditorInsertionButton | "undo" | "redo" | "clearAll" | "format" | "decorations" | (string & {});
|
|
160
8
|
type SsmlEditorButtonVisibility = Readonly<Partial<Record<string, boolean>>>;
|
|
@@ -215,10 +63,56 @@ interface SsmlHoverLocale {
|
|
|
215
63
|
noParameters: string;
|
|
216
64
|
tags: Readonly<Record<string, SsmlHoverTagCopy>>;
|
|
217
65
|
}
|
|
66
|
+
interface SsmlElementLocaleCopy {
|
|
67
|
+
label: string;
|
|
68
|
+
description: string;
|
|
69
|
+
validationErrors: Readonly<Record<string, string>>;
|
|
70
|
+
}
|
|
71
|
+
/** Localized labels and validation copy for Azure extension elements. */
|
|
72
|
+
declare const SSML_ELEMENT_COPY: Readonly<Record<SsmlEditorLocale, Readonly<Record<string, SsmlElementLocaleCopy>>>>;
|
|
218
73
|
declare const EDITOR_COPY: Readonly<Record<SsmlEditorLocale, EditorCopy>>;
|
|
219
74
|
declare const INLINE_BADGE_COPY: Readonly<Record<SsmlEditorLocale, InlineBadgeCopy>>;
|
|
220
75
|
declare const SSML_HOVER_COPY: Readonly<Record<SsmlEditorLocale, SsmlHoverLocale>>;
|
|
221
76
|
|
|
77
|
+
interface VisualVoiceCatalogEntry {
|
|
78
|
+
name: string;
|
|
79
|
+
locale: string;
|
|
80
|
+
region?: string;
|
|
81
|
+
styles?: readonly string[];
|
|
82
|
+
preview?: boolean;
|
|
83
|
+
status?: "ga" | "preview" | "deprecated";
|
|
84
|
+
}
|
|
85
|
+
interface VoiceSelectorRenderProps {
|
|
86
|
+
value: string;
|
|
87
|
+
voices: readonly VisualVoiceCatalogEntry[];
|
|
88
|
+
readOnly: boolean;
|
|
89
|
+
locale: SsmlEditorLocale;
|
|
90
|
+
onChange: (voice: string) => void;
|
|
91
|
+
}
|
|
92
|
+
interface VisualInspectorRenderProps {
|
|
93
|
+
document: SsmlDocument;
|
|
94
|
+
element: SsmlElement;
|
|
95
|
+
path: number[];
|
|
96
|
+
readOnly: boolean;
|
|
97
|
+
onChange: (document: SsmlDocument) => void;
|
|
98
|
+
locale: SsmlEditorLocale;
|
|
99
|
+
}
|
|
100
|
+
type VisualInspectorRenderer = (props: VisualInspectorRenderProps) => ReactNode;
|
|
101
|
+
interface VisualSsmlEditorProps {
|
|
102
|
+
document: SsmlDocument;
|
|
103
|
+
readOnly?: boolean;
|
|
104
|
+
onChange?: (document: SsmlDocument) => void;
|
|
105
|
+
onPreviewSelection?: (ssml: string) => void;
|
|
106
|
+
locale?: SsmlEditorLocale;
|
|
107
|
+
customInspectors?: Readonly<Record<string, VisualInspectorRenderer>>;
|
|
108
|
+
renderVoiceSelector?: (props: VoiceSelectorRenderProps) => ReactNode;
|
|
109
|
+
voiceCatalog?: readonly VisualVoiceCatalogEntry[];
|
|
110
|
+
voiceLocale?: string;
|
|
111
|
+
voiceRegion?: string;
|
|
112
|
+
voiceStyle?: string;
|
|
113
|
+
}
|
|
114
|
+
declare function VisualSsmlEditor({ document, readOnly, onChange, onPreviewSelection, locale, customInspectors, renderVoiceSelector, voiceCatalog, voiceLocale, voiceRegion, voiceStyle, }: VisualSsmlEditorProps): ReactElement;
|
|
115
|
+
|
|
222
116
|
type SsmlEditorInsertionMode = "insert" | "wrap";
|
|
223
117
|
interface SsmlEditorInsertionOption {
|
|
224
118
|
value: string;
|
|
@@ -391,6 +285,18 @@ interface SsmlEditorProps {
|
|
|
391
285
|
customInsertions?: SsmlEditorCustomInsertionCollection;
|
|
392
286
|
/** Adds insertion definitions without replacing built-in definitions. */
|
|
393
287
|
additionalInsertions?: SsmlEditorCustomInsertionCollection;
|
|
288
|
+
/** Replaces the visual inspector for an element type or serialized tag name. */
|
|
289
|
+
customInspectors?: Readonly<Record<string, VisualInspectorRenderer>>;
|
|
290
|
+
/** Replaces the built-in voice catalog selector in visual mode. */
|
|
291
|
+
renderVoiceSelector?: (props: VoiceSelectorRenderProps) => ReactNode;
|
|
292
|
+
/** Voice metadata used by the visual selector. */
|
|
293
|
+
voiceCatalog?: readonly VisualVoiceCatalogEntry[];
|
|
294
|
+
/** Optional locale filter for the visual voice selector. */
|
|
295
|
+
voiceLocale?: string;
|
|
296
|
+
/** Optional region filter for the visual voice selector. */
|
|
297
|
+
voiceRegion?: string;
|
|
298
|
+
/** Optional style filter for the visual voice selector. */
|
|
299
|
+
voiceStyle?: string;
|
|
394
300
|
/** Candidate style values shown by the built-in emotion insertion. */
|
|
395
301
|
emotionStyles?: readonly string[];
|
|
396
302
|
/** Class name applied to the editor container. */
|
|
@@ -419,14 +325,6 @@ interface SsmlEditorRef {
|
|
|
419
325
|
}
|
|
420
326
|
declare const SsmlEditor: react.ForwardRefExoticComponent<SsmlEditorProps & react.RefAttributes<SsmlEditorRef>>;
|
|
421
327
|
|
|
422
|
-
interface VisualSsmlEditorProps {
|
|
423
|
-
document: SsmlDocument;
|
|
424
|
-
readOnly?: boolean;
|
|
425
|
-
onChange?: (document: SsmlDocument) => void;
|
|
426
|
-
onPreviewSelection?: (ssml: string) => void;
|
|
427
|
-
}
|
|
428
|
-
declare function VisualSsmlEditor({ document, readOnly, onChange, onPreviewSelection, }: VisualSsmlEditorProps): ReactElement;
|
|
429
|
-
|
|
430
328
|
type MonacoEditor = Parameters<OnMount>[0];
|
|
431
329
|
|
|
432
330
|
interface SsmlTagRange {
|
|
@@ -448,4 +346,4 @@ type SsmlCodeLensAction = {
|
|
|
448
346
|
type SsmlCodeLensCallback = (action: SsmlCodeLensAction) => void;
|
|
449
347
|
declare function registerSsmlCodeLens(monaco: Monaco, editor: MonacoEditor, onOpenPopover: SsmlCodeLensCallback): ReturnType<Monaco["languages"]["registerCodeLensProvider"]>;
|
|
450
348
|
|
|
451
|
-
export { EDITOR_COPY, type EditorCopy, INLINE_BADGE_COPY, type InlineBadgeCopy, SSML_HOVER_COPY, SSML_INSERTIONS, type SelectionInfo, type SsmlCodeLensAction, type SsmlCodeLensCallback, SsmlEditor, type SsmlEditorButton, type SsmlEditorButtonVisibility, type SsmlEditorCustomInsertion, type SsmlEditorCustomInsertionCollection, type SsmlEditorCustomInsertionDefinition, type SsmlEditorEditMode, type SsmlEditorInsertionButton, type SsmlEditorInsertionDefinition, type SsmlEditorInsertionGroup, type SsmlEditorInsertionMode, type SsmlEditorInsertionOption, type SsmlEditorInsertionTemplate, type SsmlEditorLanguage, type SsmlEditorLineNumbers, type SsmlEditorLocale, type SsmlEditorLocalizedText, type SsmlEditorOptions, type SsmlEditorProps, type SsmlEditorRef, type SsmlEditorTheme, type SsmlEditorToolbarGroup, type SsmlEditorWordWrap, type SsmlHoverLocale, type SsmlHoverParameterCopy, type SsmlHoverTagCopy, type SsmlInsertionDefinition, type SsmlInsertionOption, type SsmlInsertionTemplate, type SsmlTagRange, VisualSsmlEditor, type VisualSsmlEditorProps, createSsmlEditorInsertionDefinition, registerSsmlCodeLens, updateTagAttribute };
|
|
349
|
+
export { EDITOR_COPY, type EditorCopy, INLINE_BADGE_COPY, type InlineBadgeCopy, SSML_ELEMENT_COPY, SSML_HOVER_COPY, SSML_INSERTIONS, type SelectionInfo, type SsmlCodeLensAction, type SsmlCodeLensCallback, SsmlEditor, type SsmlEditorButton, type SsmlEditorButtonVisibility, type SsmlEditorCustomInsertion, type SsmlEditorCustomInsertionCollection, type SsmlEditorCustomInsertionDefinition, type SsmlEditorEditMode, type SsmlEditorInsertionButton, type SsmlEditorInsertionDefinition, type SsmlEditorInsertionGroup, type SsmlEditorInsertionMode, type SsmlEditorInsertionOption, type SsmlEditorInsertionTemplate, type SsmlEditorLanguage, type SsmlEditorLineNumbers, type SsmlEditorLocale, type SsmlEditorLocalizedText, type SsmlEditorOptions, type SsmlEditorProps, type SsmlEditorRef, type SsmlEditorTheme, type SsmlEditorToolbarGroup, type SsmlEditorWordWrap, type SsmlElementLocaleCopy, type SsmlHoverLocale, type SsmlHoverParameterCopy, type SsmlHoverTagCopy, type SsmlInsertionDefinition, type SsmlInsertionOption, type SsmlInsertionTemplate, type SsmlTagRange, type VisualInspectorRenderProps, type VisualInspectorRenderer, VisualSsmlEditor, type VisualSsmlEditorProps, type VisualVoiceCatalogEntry, type VoiceSelectorRenderProps, createSsmlEditorInsertionDefinition, registerSsmlCodeLens, updateTagAttribute };
|