ssml-builder-js 2.5.0 → 2.7.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 CHANGED
@@ -138,6 +138,16 @@ const parsed = parseSsml(ssml);
138
138
  | `mapSsmlTextNodes(xml, transform, options?)` | タグ構造を維持したままテキストノードだけを同期・非同期変換。スキップタグとコンテキストフィルターに対応 |
139
139
  | `validateAzureSsml(xml, options?)` | Azure Speech 向けの意味検証結果を Diagnostic 配列で返す |
140
140
 
141
+ ### 3段階の検証モデル
142
+
143
+ SSML の検証は、構文、Azure 固有の静的な意味、実サービスのランタイム状態を分けて扱います。前段の検証に通っても、後段の検証結果までは保証しません。
144
+
145
+ | 段階 | API / 操作 | 検証する範囲 | 検証しない範囲 |
146
+ | --- | --- | --- | --- |
147
+ | XML 構文 | `validateSsml` | XML の整形式性、タグの対応、属性・エンティティの構文 | Azure の音声・属性・スタイル対応、アカウント状態、実際の合成可否 |
148
+ | 静的意味 | `validateAzureSsml` | Azure SSML の必須要素、属性値、音声と `xml:lang` の整合性、音声スタイル、文字数、`audio` URL/オリジン | Azure 側の最新音声一覧、キー・リージョン権限、サービス障害、実際の音声生成結果 |
149
+ | ランタイム | `AzureTtsClient.synthesize` / Azure Speech API | アカウント、リージョン、キー、最新の音声・スタイル提供状況、サービス側の SSML 制約、通信状態 | 静的検証の代替ではないため、入力検証や SSRF 対策を自動で補完しない |
150
+
141
151
  `voice`、`prosody`、`break`、`express-as`、`say-as`、`phoneme`、`audio`、`lang`、`mark` などの要素を型付きで表現できます。`type: "custom"` と `name` を指定すれば、未定義の XML 要素や追加属性も扱えます。`mstts:` 要素を含むドキュメントを生成すると、必要な Azure Speech 名前空間が自動的に追加されます。
142
152
 
143
153
  翻訳などで本文だけを置き換える場合は、`mapSsmlTextNodes` に変換関数を渡します。変換関数には直近の親タグと祖先タグの `path` が渡され、戻り値は `string` または `Promise<string>` を指定できます。`validateAzureSsml` は音声、属性値、音声スタイル、文字数、`audio` URL/オリジンを検証します。
@@ -152,7 +162,33 @@ const translated = await mapSsmlTextNodes(ssml, translate, {
152
162
  });
153
163
  ```
154
164
 
155
- `validateAzureSsml` は `AzureValidationOptions` で音声・スタイルの定義を追加できます。`unknownVoicePolicy` のデフォルトは `"warn"`、`validateNestedVoices` のデフォルトは `true` です。`audio` の外部 URL はデフォルトで拒否されるため、利用する場合は `allowedAudioOrigins` に許可するオリジンを列挙するか、構成を理解した上で `allowExternalAudio: true` を指定してください。
165
+ `validateAzureSsml` は `AzureValidationOptions` で音声・スタイルの定義を追加できます。言語比較は `Intl.Locale` を使って BCP 47 として正規化し、組み込みで `zh-Hans` `zh-CN`、`zh-Hant` `zh-TW` を同一視します。独自の別名や正規化関数も注入できます。
166
+
167
+ ```ts
168
+ const diagnostics = validateAzureSsml(ssml, {
169
+ languageAliases: { "ja": ["ja-JP", "ja-Japan"] },
170
+ normalizeLanguage: (language) => language.replace("_", "-"),
171
+ });
172
+ ```
173
+
174
+ 音声カタログは `AzureVoiceDefinition` の `name`、`locale`、`secondaryLocales`、`styles` で表現できます。`voiceDefinitions`(または `voiceCatalog`)を渡すと、組み込み台帳を外部定義で補完・上書きできます。`customVoiceStyleMap` は既存利用者向けに引き続き利用でき、指定した音声のスタイルを上書きします。組み込み台帳にない音声は `azure-unknown-voice`(`unknownVoicePolicy` に従う)、登録済み音声への非対応スタイルは `azure-unsupported-style`、ロケール不一致は `azure-locale-mismatch` として区別されます。
175
+
176
+ ```ts
177
+ const diagnostics = validateAzureSsml(ssml, {
178
+ voiceDefinitions: [
179
+ {
180
+ name: "my-custom-voice",
181
+ locale: "ja-JP",
182
+ secondaryLocales: ["zh-Hant"],
183
+ styles: ["narration"],
184
+ },
185
+ ],
186
+ unknownVoicePolicy: "error", // "error" | "warn" | "ignore"
187
+ allowedAudioOrigins: ["https://cdn.example.com"],
188
+ });
189
+ ```
190
+
191
+ Azure の音声・スタイル一覧はサービス更新やリージョン差分があるため、組み込み一覧は固定の完全な台帳ではありません。新しい音声を完全に静的検証したい場合は、音声名だけでなくロケールとスタイルを `voiceDefinitions` に定義してください。`validateNestedVoices` のデフォルトは `true` です。`audio` の外部 URL はデフォルトで拒否されるため、利用する場合は `allowedAudioOrigins` に許可するオリジンを列挙するか、構成を理解した上で `allowExternalAudio: true` を指定してください。
156
192
 
157
193
  ```ts
158
194
  const diagnostics = validateAzureSsml(ssml, {
@@ -508,6 +544,16 @@ The main `buildSsml` and `parseSsml` signatures are:
508
544
  | `mapSsmlTextNodes(xml, transform, options?)` | Transforms only text nodes while preserving the XML structure; supports sync/async transforms, skipped tags, and context filters |
509
545
  | `validateAzureSsml(xml, options?)` | Returns Azure Speech semantic-validation diagnostics |
510
546
 
547
+ ### Three-stage validation model
548
+
549
+ SSML validation separates XML syntax, Azure-specific static semantics, and runtime service state. Passing an earlier stage does not guarantee the result of a later stage.
550
+
551
+ | Stage | API / operation | What it validates | Boundary |
552
+ | --- | --- | --- | --- |
553
+ | XML syntax | `validateSsml` | Well-formed XML, matching tags, and attribute/entity syntax | Azure voice, attribute, and style support; account state; and actual synthesis availability |
554
+ | Static semantics | `validateAzureSsml` | Required Azure SSML elements, attribute values, voice/`xml:lang` alignment, voice styles, character limits, and `audio` URL/origin policy | Azure's latest voice catalog, key/region permissions, service incidents, and the actual generated audio |
555
+ | Runtime | `AzureTtsClient.synthesize` / Azure Speech API | Account, region, key, current voice/style availability, service-side SSML constraints, and network state | It does not replace input validation or automatically provide SSRF protection |
556
+
511
557
  Typed representations are available for elements such as `voice`, `prosody`, `break`, `express-as`, `say-as`, `phoneme`, `audio`, `lang`, and `mark`. Use `type: "custom"` and `name` to handle undefined XML elements or additional attributes. When a document contains `mstts:` elements, the required Azure Speech namespace is added automatically.
512
558
 
513
559
  Use `mapSsmlTextNodes` to replace translatable content without changing tags, attributes, or nesting. The transform receives the immediate parent tag and ancestor `path`, and may return a `string` or a `Promise<string>`. The third argument supports `skipTags` and a `filter` callback; `phoneme`, `say-as`, and `sub` are skipped by default. The callback receives `parentTag`, decoded `parentAttributes`, `ancestorTags`, and `path`.
@@ -520,7 +566,33 @@ const translated = await mapSsmlTextNodes(ssml, translate, {
520
566
  });
521
567
  ```
522
568
 
523
- `validateAzureSsml` accepts `AzureValidationOptions` for extending the voice/style map. `unknownVoicePolicy` defaults to `"warn"` and `validateNestedVoices` defaults to `true`. External `<audio>` URLs are blocked by default; provide `allowedAudioOrigins` or explicitly set `allowExternalAudio: true` only when the deployment is configured to control those requests.
569
+ `validateAzureSsml` accepts `AzureValidationOptions` for extending the voice/style catalog. Language comparison uses `Intl.Locale` and BCP 47 normalization; the built-in aliases treat `zh-Hans` and `zh-CN`, and `zh-Hant` and `zh-TW`, as equivalent. Custom aliases or a custom normalizer can be injected as well.
570
+
571
+ ```ts
572
+ const diagnostics = validateAzureSsml(ssml, {
573
+ languageAliases: { ja: ["ja-JP", "ja-Japan"] },
574
+ normalizeLanguage: (language) => language.replace("_", "-"),
575
+ });
576
+ ```
577
+
578
+ The catalog is represented by `AzureVoiceDefinition` with `name`, `locale`, optional `secondaryLocales`, and optional `styles`. Pass `voiceDefinitions` (or `voiceCatalog`) to supplement or override the built-in catalog with an external definition. `customVoiceStyleMap` remains supported for backward compatibility and overrides styles for the named voice. Diagnostics distinguish an unregistered voice (`azure-unknown-voice`, controlled by `unknownVoicePolicy`), an unsupported style on a registered voice (`azure-unsupported-style`), and a locale mismatch (`azure-locale-mismatch`).
579
+
580
+ ```ts
581
+ const diagnostics = validateAzureSsml(ssml, {
582
+ voiceDefinitions: [
583
+ {
584
+ name: "my-custom-voice",
585
+ locale: "ja-JP",
586
+ secondaryLocales: ["zh-Hant"],
587
+ styles: ["narration"],
588
+ },
589
+ ],
590
+ unknownVoicePolicy: "error", // "error" | "warn" | "ignore"
591
+ allowedAudioOrigins: ["https://cdn.example.com"],
592
+ });
593
+ ```
594
+
595
+ Azure's voice and style catalog changes over time and can differ by region, so the built-in catalog is a fixed snapshot rather than a complete live catalog. For complete static validation of a new voice, define its name, locale, and supported styles in `voiceDefinitions`. `validateNestedVoices` defaults to `true`. External `<audio>` URLs are blocked by default; provide `allowedAudioOrigins` or explicitly set `allowExternalAudio: true` only when the deployment is configured to control those requests.
524
596
 
525
597
  ```ts
526
598
  const diagnostics = validateAzureSsml(ssml, {
@@ -1194,29 +1194,123 @@ function location(source, offset) {
1194
1194
  const line = before.split("\n").length;
1195
1195
  return { line, column: before.length - (before.lastIndexOf("\n") + 1) + 1 };
1196
1196
  }
1197
- function addDiagnostic(diagnostics, source, offset, message, severity = "error") {
1198
- diagnostics.push({ ...location(source, offset), message, severity });
1197
+ function addDiagnostic(diagnostics, source, offset, message, severity = "error", code) {
1198
+ diagnostics.push({ ...location(source, offset), message, severity, ...code ? { code } : {} });
1199
1199
  }
1200
1200
  function attr(token, name) {
1201
1201
  return token.attributes.get(name.toLowerCase());
1202
1202
  }
1203
- function normalizeVoiceStyleMap(customVoiceStyleMap) {
1204
- const map = new Map(
1205
- Object.entries(EXPRESS_AS_STYLES).map(([voiceName, styles]) => [voiceName.toLowerCase(), styles])
1206
- );
1207
- for (const [voiceName, styles] of Object.entries(customVoiceStyleMap ?? {})) {
1208
- map.set(
1209
- voiceName.toLowerCase(),
1210
- styles.map((style) => style.toLowerCase())
1211
- );
1203
+ var ADDITIONAL_VOICE_DEFINITIONS = [
1204
+ { name: "zh-TW-HsiaoChenNeural", locale: "zh-TW" },
1205
+ { name: "es-ES-ElviraNeural", locale: "es-ES" },
1206
+ { name: "th-TH-PremwadeeNeural", locale: "th-TH" },
1207
+ { name: "fil-PH-AngeloNeural", locale: "fil-PH" },
1208
+ { name: "vi-VN-HoaiMyNeural", locale: "vi-VN" },
1209
+ { name: "id-ID-GadisNeural", locale: "id-ID" },
1210
+ { name: "ms-MY-YasminNeural", locale: "ms-MY" }
1211
+ ];
1212
+ var DEFAULT_LANGUAGE_ALIASES = {
1213
+ "zh-CN": ["zh-Hans"],
1214
+ "zh-TW": ["zh-Hant"]
1215
+ };
1216
+ function canonicalLanguageTag(language) {
1217
+ const trimmed = language.trim();
1218
+ if (!trimmed) return "";
1219
+ try {
1220
+ return new Intl.Locale(trimmed).toString().toLowerCase();
1221
+ } catch {
1222
+ return trimmed.toLowerCase();
1212
1223
  }
1213
- return map;
1224
+ }
1225
+ function createLanguageNormalizer(options) {
1226
+ const aliases = /* @__PURE__ */ new Map();
1227
+ const addAliasGroup = (canonical, values) => {
1228
+ const normalizedCanonical = canonicalLanguageTag(canonical);
1229
+ if (!normalizedCanonical) return;
1230
+ aliases.set(normalizedCanonical, normalizedCanonical);
1231
+ for (const value of values) {
1232
+ const normalizedValue = canonicalLanguageTag(value);
1233
+ if (normalizedValue) aliases.set(normalizedValue, normalizedCanonical);
1234
+ }
1235
+ };
1236
+ for (const [canonical, values] of Object.entries(DEFAULT_LANGUAGE_ALIASES)) addAliasGroup(canonical, values);
1237
+ for (const [canonical, valueOrValues] of Object.entries(options.languageAliases ?? {}))
1238
+ addAliasGroup(canonical, typeof valueOrValues === "string" ? [valueOrValues] : valueOrValues);
1239
+ return (language) => {
1240
+ const customValue = options.normalizeLanguage ? options.normalizeLanguage(language) : language;
1241
+ const normalized = canonicalLanguageTag(customValue);
1242
+ return aliases.get(normalized) ?? normalized;
1243
+ };
1244
+ }
1245
+ function normalizeAzureLanguage(language, options = {}) {
1246
+ return createLanguageNormalizer(options)(language);
1247
+ }
1248
+ function areAzureLanguagesEquivalent(first, second, options = {}) {
1249
+ const normalize = createLanguageNormalizer(options);
1250
+ const normalizedFirst = normalize(first);
1251
+ const normalizedSecond = normalize(second);
1252
+ if (normalizedFirst === normalizedSecond) return true;
1253
+ return normalizedFirst === languagePart(normalizedFirst) && languagePart(normalizedFirst) === languagePart(normalizedSecond);
1254
+ }
1255
+ function voiceLocalePrefix(voiceName) {
1256
+ const match = /^(?<language>[A-Za-z]{2,3})-(?<region>[A-Za-z]{2}|\d{3})(?:-|$)/.exec(voiceName.trim());
1257
+ if (!match?.groups) return void 0;
1258
+ const tag = `${match.groups.language}-${match.groups.region}`;
1259
+ return {
1260
+ language: match.groups.language.toLowerCase(),
1261
+ region: match.groups.region.toLowerCase(),
1262
+ tag
1263
+ };
1264
+ }
1265
+ function definitionFromStyleMap(voiceName, styles) {
1266
+ return {
1267
+ name: voiceName,
1268
+ locale: voiceLocalePrefix(voiceName)?.tag ?? "",
1269
+ styles
1270
+ };
1271
+ }
1272
+ function normalizeVoiceCatalog(options) {
1273
+ const definitions = /* @__PURE__ */ new Map();
1274
+ for (const [name, styles] of Object.entries(EXPRESS_AS_STYLES)) {
1275
+ definitions.set(name.toLowerCase(), definitionFromStyleMap(name, styles));
1276
+ }
1277
+ for (const definition of ADDITIONAL_VOICE_DEFINITIONS) definitions.set(definition.name.toLowerCase(), definition);
1278
+ for (const definition of options.voiceCatalog ?? []) definitions.set(definition.name.toLowerCase(), definition);
1279
+ for (const definition of options.voiceDefinitions ?? []) definitions.set(definition.name.toLowerCase(), definition);
1280
+ for (const definition of options.customVoiceDefinitions ?? [])
1281
+ definitions.set(definition.name.toLowerCase(), definition);
1282
+ for (const [voiceName, styles] of Object.entries(options.customVoiceStyleMap ?? {})) {
1283
+ const key = voiceName.toLowerCase();
1284
+ const current = definitions.get(key);
1285
+ definitions.set(key, {
1286
+ ...current ?? definitionFromStyleMap(voiceName, styles),
1287
+ name: current?.name ?? voiceName,
1288
+ styles: styles.map((style) => style.toLowerCase())
1289
+ });
1290
+ }
1291
+ return definitions;
1214
1292
  }
1215
1293
  function diagnosticSeverity(policy) {
1216
1294
  if (policy === "ignore") return void 0;
1217
1295
  return policy === "error" ? "error" : "warning";
1218
1296
  }
1219
- function validateElement(token, source, diagnostics, voiceName, options, voiceStyleMap) {
1297
+ function languagePart(language) {
1298
+ try {
1299
+ return new Intl.Locale(language).language.toLowerCase();
1300
+ } catch {
1301
+ return language.split("-")[0]?.toLowerCase() ?? "";
1302
+ }
1303
+ }
1304
+ function definitionMatchesLanguage(definition, voiceName, language, normalizeLanguage) {
1305
+ const candidateLanguages = definition ? [definition.locale, ...definition.secondaryLocales ?? []].filter(Boolean) : [voiceLocalePrefix(voiceName)?.tag ?? ""];
1306
+ if (candidateLanguages.length === 0 || !language.trim()) return void 0;
1307
+ const normalizedLanguage = normalizeLanguage(language);
1308
+ const normalizedCandidates = candidateLanguages.map(normalizeLanguage);
1309
+ if (normalizedCandidates.includes(normalizedLanguage)) return true;
1310
+ if (!normalizedLanguage || !normalizedCandidates.some(Boolean)) return void 0;
1311
+ return normalizedLanguage === languagePart(normalizedLanguage) ? normalizedCandidates.some((candidate) => languagePart(candidate) === normalizedLanguage) : false;
1312
+ }
1313
+ function validateElement(token, source, diagnostics, voiceName, options, voiceCatalog) {
1220
1314
  const name = token.name.toLowerCase();
1221
1315
  if (name === "voice" && !attr(token, "name")?.trim())
1222
1316
  addDiagnostic(diagnostics, source, token.start, '<voice> requires a non-empty "name" attribute.');
@@ -1258,17 +1352,19 @@ function validateElement(token, source, diagnostics, voiceName, options, voiceSt
1258
1352
  const role = attr(token, "role");
1259
1353
  if (role && !ALLOWED_ROLES.has(role))
1260
1354
  addDiagnostic(diagnostics, source, token.start, `Unsupported <mstts:express-as role> value "${role}".`);
1261
- const supportedStyles = voiceName ? voiceStyleMap.get(voiceName.toLowerCase()) : void 0;
1262
- const severity = diagnosticSeverity(options.unknownVoicePolicy ?? "warn");
1263
- if (style && supportedStyles && !supportedStyles.includes(style.toLowerCase()) && severity)
1355
+ const definition = voiceName ? voiceCatalog.get(voiceName.toLowerCase()) : void 0;
1356
+ const supportedStyles = definition?.styles;
1357
+ const severity = diagnosticSeverity(options.unsupportedStylePolicy ?? options.unknownVoicePolicy ?? "warn");
1358
+ if (style && definition && !supportedStyles?.some((candidate) => candidate.toLowerCase() === style.toLowerCase()) && severity)
1264
1359
  addDiagnostic(
1265
1360
  diagnostics,
1266
1361
  source,
1267
1362
  token.start,
1268
1363
  `Unknown style "${style}" is not supported by voice "${voiceName}" according to the configured voice style map.`,
1269
- severity
1364
+ severity,
1365
+ "azure-unsupported-style"
1270
1366
  );
1271
- if (style && voiceName && !supportedStyles && severity)
1367
+ if (style && voiceName && !definition && severity)
1272
1368
  addDiagnostic(
1273
1369
  diagnostics,
1274
1370
  source,
@@ -1373,23 +1469,36 @@ function validateAzureSsml(ssml, options = {}) {
1373
1469
  "Azure SSML requires at least one <voice> element under <speak>."
1374
1470
  );
1375
1471
  const voiceName = voices[0] ? attr(voices[0], "name") : void 0;
1376
- const voiceStyleMap = normalizeVoiceStyleMap(options.customVoiceStyleMap);
1472
+ const voiceCatalog = normalizeVoiceCatalog(options);
1473
+ const normalizeLanguage = createLanguageNormalizer(options);
1377
1474
  const policySeverity = diagnosticSeverity(options.unknownVoicePolicy ?? "warn");
1378
1475
  const voicesToValidate = options.validateNestedVoices === false ? voices.slice(0, 1) : voices;
1379
1476
  for (const token of voicesToValidate) {
1380
1477
  const name = attr(token, "name")?.trim();
1381
- if (name && !voiceStyleMap.has(name.toLowerCase()) && policySeverity)
1478
+ const language = attr(token, "xml:lang")?.trim() || (speak ? attr(speak, "xml:lang")?.trim() : void 0);
1479
+ const definition = name ? voiceCatalog.get(name.toLowerCase()) : void 0;
1480
+ if (name && !definition && policySeverity)
1481
+ addDiagnostic(
1482
+ diagnostics,
1483
+ ssml,
1484
+ token.start,
1485
+ `Unknown voice "${name}" is not registered in the voice catalog.`,
1486
+ policySeverity,
1487
+ "azure-unknown-voice"
1488
+ );
1489
+ if (name && language && definitionMatchesLanguage(definition, name, language, normalizeLanguage) === false)
1382
1490
  addDiagnostic(
1383
1491
  diagnostics,
1384
1492
  ssml,
1385
1493
  token.start,
1386
- `Unknown voice "${name}" is not registered in the voice style map.`,
1387
- policySeverity
1494
+ `Voice "${name}" does not match language "${language}"; the voice name prefix indicates a different language or region.`,
1495
+ "warning",
1496
+ "azure-locale-mismatch"
1388
1497
  );
1389
1498
  }
1390
1499
  for (const token of tokens) {
1391
1500
  const tokenVoiceName = options.validateNestedVoices === false ? voiceName : token.parentVoiceName;
1392
- validateElement(token, ssml, diagnostics, tokenVoiceName, options, voiceStyleMap);
1501
+ validateElement(token, ssml, diagnostics, tokenVoiceName, options, voiceCatalog);
1393
1502
  }
1394
1503
  return diagnostics;
1395
1504
  }
@@ -1401,6 +1510,8 @@ export {
1401
1510
  validateSsml,
1402
1511
  extractSsmlText,
1403
1512
  mapSsmlTextNodes,
1513
+ normalizeAzureLanguage,
1514
+ areAzureLanguagesEquivalent,
1404
1515
  validateAzureSsml
1405
1516
  };
1406
- //# sourceMappingURL=chunk-4RHHW33A.mjs.map
1517
+ //# sourceMappingURL=chunk-D6ITDU3A.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../packages/ssml-core/src/constants/ssml.ts","../packages/ssml-core/src/builder.ts","../packages/ssml-core/src/parser.ts","../packages/ssml-core/src/partial.ts","../packages/ssml-core/src/validation.ts","../packages/ssml-core/src/textNodes.ts","../packages/ssml-core/src/azureValidation.ts"],"sourcesContent":["export const SYNTHESIS_NAMESPACE = \"http://www.w3.org/2001/10/synthesis\" as const;\nexport const MSTTS_NAMESPACE = \"http://www.w3.org/2001/mstts\" as const;\nexport const DEFAULT_SSML_VERSION = \"1.0\" as const;\nexport const DEFAULT_SSML_LANGUAGE = \"en-US\" as const;\nexport const MAX_NESTING_DEPTH = 1000;\nexport const XML_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_.:-]*$/;\nexport const MSTTS_TAG_PREFIX = \"mstts:\" as const;\n\nexport const SSML_TAGS = {\n SPEAK: \"speak\",\n VOICE: \"voice\",\n PROSODY: \"prosody\",\n BREAK: \"break\",\n EXPRESS_AS: \"express-as\",\n EXPRESS_AS_CAMEL: \"expressAs\",\n MSTTS_EXPRESS_AS: \"mstts:express-as\",\n SAY_AS: \"say-as\",\n SAY_AS_CAMEL: \"sayAs\",\n PHONEME: \"phoneme\",\n EMPHASIS: \"emphasis\",\n AUDIO: \"audio\",\n SUB: \"sub\",\n LANG: \"lang\",\n MARK: \"mark\",\n BOOKMARK: \"bookmark\",\n LEXICON: \"lexicon\",\n PARAGRAPH: \"p\",\n SENTENCE: \"s\",\n WORD: \"w\",\n MSTTS_SILENCE: \"mstts:silence\",\n SILENCE: \"silence\",\n MSTTS_VISEME: \"mstts:viseme\",\n VISEME: \"viseme\",\n} as const;\n\nexport const SSML_ATTRS = {\n VERSION: \"version\",\n XMLNS: \"xmlns\",\n XML_LANG: \"xml:lang\",\n LANG: \"lang\",\n MSTTS_XMLNS: \"xmlns:mstts\",\n NAME: \"name\",\n EFFECT: \"effect\",\n RATE: \"rate\",\n PITCH: \"pitch\",\n VOLUME: \"volume\",\n CONTOUR: \"contour\",\n RANGE: \"range\",\n TIME: \"time\",\n STRENGTH: \"strength\",\n STYLE: \"style\",\n STYLE_DEGREE: \"styledegree\",\n STYLE_DEGREE_CAMEL: \"styleDegree\",\n STYLE_DEGREE_HYPHEN: \"style-degree\",\n ROLE: \"role\",\n INTERPRET_AS: \"interpret-as\",\n FORMAT: \"format\",\n DETAIL: \"detail\",\n ALPHABET: \"alphabet\",\n PH: \"ph\",\n LEVEL: \"level\",\n SRC: \"src\",\n DESC: \"desc\",\n CLIP_BEGIN: \"clipBegin\",\n CLIP_END: \"clipEnd\",\n SPEED: \"speed\",\n REPEAT_COUNT: \"repeatCount\",\n REPEAT_DURATION: \"repeatDuration\",\n SOUND_LEVEL: \"soundLevel\",\n ALIAS: \"alias\",\n MARK: \"mark\",\n URI: \"uri\",\n TYPE: \"type\",\n VALUE: \"value\",\n} as const;\n","import type {\n SsmlAttributeValue,\n SsmlAttributes,\n SsmlDocument,\n SsmlElement,\n SsmlElementBase,\n SsmlNode,\n} from \"./types.ts\";\nimport {\n DEFAULT_SSML_LANGUAGE,\n DEFAULT_SSML_VERSION,\n MSTTS_NAMESPACE,\n MSTTS_TAG_PREFIX,\n SSML_ATTRS,\n SSML_TAGS,\n SYNTHESIS_NAMESPACE,\n XML_NAME_PATTERN,\n} from \"./constants/ssml.ts\";\n\nfunction escapeText(value: string): string {\n return value.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n}\n\nfunction escapeAttribute(value: string): string {\n return escapeText(value).replace(/\"/g, \"&quot;\").replace(/'/g, \"&apos;\");\n}\n\nfunction addAttribute(attributes: SsmlAttributes, name: string, value: SsmlAttributeValue | undefined): void {\n if (value !== undefined) {\n attributes[name] = value;\n }\n}\n\nfunction getAttributes(element: SsmlElement): SsmlAttributes {\n const attributes: SsmlAttributes = {\n ...(element.attributes ?? {}),\n };\n\n switch (element.type) {\n case SSML_TAGS.VOICE:\n addAttribute(attributes, SSML_ATTRS.NAME, element.name);\n addAttribute(attributes, SSML_ATTRS.EFFECT, element.effect);\n break;\n case SSML_TAGS.PROSODY:\n addAttribute(attributes, SSML_ATTRS.RATE, element.rate);\n addAttribute(attributes, SSML_ATTRS.PITCH, element.pitch);\n addAttribute(attributes, SSML_ATTRS.VOLUME, element.volume);\n addAttribute(attributes, SSML_ATTRS.CONTOUR, element.contour);\n addAttribute(attributes, SSML_ATTRS.RANGE, element.range);\n break;\n case SSML_TAGS.BREAK:\n addAttribute(attributes, SSML_ATTRS.TIME, element.time);\n addAttribute(attributes, SSML_ATTRS.STRENGTH, element.strength);\n break;\n case SSML_TAGS.EXPRESS_AS:\n case SSML_TAGS.EXPRESS_AS_CAMEL:\n case SSML_TAGS.MSTTS_EXPRESS_AS:\n addAttribute(attributes, SSML_ATTRS.STYLE, element.style);\n addAttribute(attributes, SSML_ATTRS.STYLE_DEGREE, element.styleDegree);\n addAttribute(attributes, SSML_ATTRS.ROLE, element.role);\n break;\n case SSML_TAGS.SAY_AS:\n case SSML_TAGS.SAY_AS_CAMEL:\n addAttribute(attributes, SSML_ATTRS.INTERPRET_AS, element.interpretAs);\n addAttribute(attributes, SSML_ATTRS.FORMAT, element.format);\n addAttribute(attributes, SSML_ATTRS.DETAIL, element.detail);\n break;\n case SSML_TAGS.PHONEME:\n addAttribute(attributes, SSML_ATTRS.ALPHABET, element.alphabet);\n addAttribute(attributes, SSML_ATTRS.PH, element.ph);\n break;\n case SSML_TAGS.EMPHASIS:\n addAttribute(attributes, SSML_ATTRS.LEVEL, element.level);\n break;\n case SSML_TAGS.AUDIO:\n addAttribute(attributes, SSML_ATTRS.SRC, element.src);\n addAttribute(attributes, SSML_ATTRS.DESC, element.desc);\n addAttribute(attributes, SSML_ATTRS.CLIP_BEGIN, element.clipBegin);\n addAttribute(attributes, SSML_ATTRS.CLIP_END, element.clipEnd);\n addAttribute(attributes, SSML_ATTRS.SPEED, element.speed);\n addAttribute(attributes, SSML_ATTRS.REPEAT_COUNT, element.repeatCount);\n addAttribute(attributes, SSML_ATTRS.REPEAT_DURATION, element.repeatDuration);\n addAttribute(attributes, SSML_ATTRS.SOUND_LEVEL, element.soundLevel);\n break;\n case SSML_TAGS.SUB:\n addAttribute(attributes, SSML_ATTRS.ALIAS, element.alias);\n break;\n case SSML_TAGS.LANG:\n addAttribute(attributes, SSML_ATTRS.XML_LANG, element.lang);\n break;\n case SSML_TAGS.MARK:\n addAttribute(attributes, SSML_ATTRS.NAME, element.name);\n break;\n case SSML_TAGS.BOOKMARK:\n addAttribute(attributes, SSML_ATTRS.MARK, element.mark);\n break;\n case SSML_TAGS.LEXICON:\n addAttribute(attributes, SSML_ATTRS.URI, element.uri);\n break;\n case SSML_TAGS.MSTTS_SILENCE:\n case SSML_TAGS.SILENCE:\n addAttribute(attributes, SSML_ATTRS.TYPE, element.typeValue ?? element.silenceType);\n addAttribute(attributes, SSML_ATTRS.VALUE, element.value);\n break;\n case SSML_TAGS.MSTTS_VISEME:\n case SSML_TAGS.VISEME:\n addAttribute(attributes, SSML_ATTRS.TYPE, element.typeValue ?? element.visemeType);\n break;\n case SSML_TAGS.PARAGRAPH:\n case SSML_TAGS.SENTENCE:\n case SSML_TAGS.WORD:\n case \"element\":\n case \"custom\":\n break;\n }\n\n return attributes;\n}\n\nfunction getTagName(element: SsmlElement): string {\n switch (element.type) {\n case SSML_TAGS.EXPRESS_AS:\n case SSML_TAGS.EXPRESS_AS_CAMEL:\n case SSML_TAGS.MSTTS_EXPRESS_AS:\n return SSML_TAGS.MSTTS_EXPRESS_AS;\n case SSML_TAGS.SAY_AS:\n case SSML_TAGS.SAY_AS_CAMEL:\n return SSML_TAGS.SAY_AS;\n case SSML_TAGS.SILENCE:\n case SSML_TAGS.MSTTS_SILENCE:\n return SSML_TAGS.MSTTS_SILENCE;\n case SSML_TAGS.VISEME:\n case SSML_TAGS.MSTTS_VISEME:\n return SSML_TAGS.MSTTS_VISEME;\n case \"element\":\n case \"custom\":\n return element.name;\n default:\n return element.type;\n }\n}\n\nfunction getChildren(element: SsmlElementBase): SsmlNode[] {\n return element.children ?? [];\n}\n\nfunction validateName(name: string, kind: \"element\" | \"attribute\"): void {\n if (!XML_NAME_PATTERN.test(name)) {\n throw new Error(`Invalid XML ${kind} name: ${name}`);\n }\n}\n\nfunction serializeAttributes(attributes: SsmlAttributes): string {\n return Object.entries(attributes)\n .map(([name, value]) => {\n validateName(name, \"attribute\");\n return ` ${name}=\"${escapeAttribute(String(value))}\"`;\n })\n .join(\"\");\n}\n\nfunction serializeNode(node: SsmlNode): string {\n if (typeof node === \"string\") {\n return escapeText(node);\n }\n\n if (node.type === \"text\") {\n return escapeText(node.value);\n }\n\n const tagName = getTagName(node);\n validateName(tagName, \"element\");\n\n const attributes = serializeAttributes(getAttributes(node));\n const children = getChildren(node);\n if (children.length === 0) {\n return `<${tagName}${attributes}/>`;\n }\n\n return `<${tagName}${attributes}>${children.map(serializeNode).join(\"\")}</${tagName}>`;\n}\n\nfunction usesMsttsNamespace(nodes: SsmlNode[]): boolean {\n return nodes.some((node) => {\n if (typeof node === \"string\" || node.type === \"text\") {\n return false;\n }\n\n const tagName = getTagName(node);\n return tagName.startsWith(MSTTS_TAG_PREFIX) || usesMsttsNamespace(getChildren(node));\n });\n}\n\nfunction serializeDocument(document: SsmlDocument): string {\n const children = document.children ?? (document.content === undefined ? [] : [document.content]);\n const attributes: SsmlAttributes = {\n ...(document.attributes ?? {}),\n [SSML_ATTRS.VERSION]: document.version,\n [SSML_ATTRS.XMLNS]: SYNTHESIS_NAMESPACE,\n [SSML_ATTRS.XML_LANG]: document.lang,\n };\n\n if (usesMsttsNamespace(children) && attributes[SSML_ATTRS.MSTTS_XMLNS] === undefined) {\n attributes[SSML_ATTRS.MSTTS_XMLNS] = MSTTS_NAMESPACE;\n }\n\n return `<${SSML_TAGS.SPEAK}${serializeAttributes(attributes)}>${children.map(serializeNode).join(\"\")}</${SSML_TAGS.SPEAK}>`;\n}\n\nexport function buildSsml(document: SsmlDocument): string;\nexport function buildSsml(content: string, lang?: string): SsmlDocument;\nexport function buildSsml(\n documentOrContent: SsmlDocument | string,\n lang: string = DEFAULT_SSML_LANGUAGE,\n): string | SsmlDocument {\n if (typeof documentOrContent === \"string\") {\n return {\n version: DEFAULT_SSML_VERSION,\n lang,\n content: documentOrContent,\n };\n }\n\n return serializeDocument(documentOrContent);\n}\n","import type {\n AudioElement,\n BookmarkElement,\n BreakElement,\n CustomElement,\n EmphasisElement,\n ExpressAsElement,\n LangElement,\n LexiconElement,\n MarkElement,\n MsttsSilenceElement,\n MsttsVisemeElement,\n ParagraphElement,\n PhonemeElement,\n ProsodyElement,\n SayAsElement,\n SentenceElement,\n SsmlAttributes,\n SsmlDocument,\n SsmlElement,\n SsmlNode,\n SubElement,\n VoiceElement,\n WordElement,\n} from \"./types.ts\";\nimport { MAX_NESTING_DEPTH, MSTTS_NAMESPACE, SSML_ATTRS, SSML_TAGS, SYNTHESIS_NAMESPACE } from \"./constants/ssml.ts\";\n\ninterface XmlElementNode {\n name: string;\n attributes: SsmlAttributes;\n children: XmlNode[];\n}\n\ntype XmlNode = string | XmlElementNode;\n\nconst XML_ENTITIES: Record<string, string> = {\n amp: \"&\",\n apos: \"'\",\n gt: \">\",\n lt: \"<\",\n quot: '\"',\n};\n\nfunction hasOwn(object: object, property: PropertyKey): boolean {\n return Object.getOwnPropertyDescriptor(object, property) !== undefined;\n}\n\nfunction setAttribute(attributes: SsmlAttributes, name: string, value: string): void {\n Object.defineProperty(attributes, name, {\n configurable: true,\n enumerable: true,\n value,\n writable: true,\n });\n}\n\nfunction decodeEntity(entity: string): string {\n const namedValue = hasOwn(XML_ENTITIES, entity) ? XML_ENTITIES[entity] : undefined;\n if (namedValue !== undefined) {\n return namedValue;\n }\n\n const isHexadecimal = entity.startsWith(\"#x\") || entity.startsWith(\"#X\");\n const isDecimal = entity.startsWith(\"#\");\n if (!isHexadecimal && !isDecimal) {\n throw new Error(`Unknown XML entity: &${entity};`);\n }\n\n const digits = entity.slice(isHexadecimal ? 2 : 1);\n const codePoint = Number.parseInt(digits, isHexadecimal ? 16 : 10);\n if (\n !digits ||\n !Number.isInteger(codePoint) ||\n codePoint < 0 ||\n codePoint > 0x10ffff ||\n (codePoint >= 0xd800 && codePoint <= 0xdfff) ||\n (codePoint < 0x20 && ![9, 10, 13].includes(codePoint))\n ) {\n throw new Error(`Invalid XML character reference: &${entity};`);\n }\n\n return String.fromCodePoint(codePoint);\n}\n\nfunction decodeXmlEntities(value: string): string {\n let result = \"\";\n let start = 0;\n\n while (true) {\n const ampersand = value.indexOf(\"&\", start);\n if (ampersand === -1) {\n return result + value.slice(start);\n }\n\n result += value.slice(start, ampersand);\n const semicolon = value.indexOf(\";\", ampersand + 1);\n if (semicolon === -1) {\n throw new Error(\"Unterminated XML entity reference\");\n }\n\n result += decodeEntity(value.slice(ampersand + 1, semicolon));\n start = semicolon + 1;\n }\n}\n\nfunction isXmlNameStart(value: string | undefined): boolean {\n return value !== undefined && /[A-Za-z_]/.test(value);\n}\n\nfunction isXmlNameCharacter(value: string | undefined): boolean {\n return value !== undefined && /[A-Za-z0-9_.:-]/.test(value);\n}\n\nfunction isXmlWhitespace(value: string | undefined): boolean {\n return value === \" \" || value === \"\\t\" || value === \"\\r\" || value === \"\\n\";\n}\n\nfunction removeStandardNamespaceAttributes(attributes: SsmlAttributes): void {\n if (attributes[SSML_ATTRS.XMLNS] === SYNTHESIS_NAMESPACE) {\n delete attributes[SSML_ATTRS.XMLNS];\n }\n if (attributes[SSML_ATTRS.MSTTS_XMLNS] === MSTTS_NAMESPACE) {\n delete attributes[SSML_ATTRS.MSTTS_XMLNS];\n }\n}\n\nclass XmlParser {\n #index = 0;\n private readonly source: string;\n\n constructor(source: string) {\n this.source = source;\n }\n\n parse(): XmlElementNode {\n if (this.source.charCodeAt(0) === 0xfeff) {\n this.#index += 1;\n }\n\n this.skipMisc();\n if (this.#index >= this.source.length) {\n this.fail(\"SSML input is empty\");\n }\n if (this.source[this.#index] !== \"<\") {\n this.fail(\"SSML input must start with an XML element\");\n }\n\n const root = this.parseElement(0);\n this.skipMisc();\n if (this.#index !== this.source.length) {\n this.fail(\"Unexpected content after the root XML element\");\n }\n return root;\n }\n\n private parseElement(depth: number): XmlElementNode {\n if (depth > MAX_NESTING_DEPTH) {\n this.fail(\"XML nesting depth exceeds the supported limit\");\n }\n\n this.expect(\"<\");\n if (this.source[this.#index] === \"/\") {\n this.fail(\"Unexpected closing XML element\");\n }\n\n const name = this.parseName();\n const { attributes, selfClosing } = this.parseStartTag();\n if (selfClosing) {\n return { name, attributes, children: [] };\n }\n\n const children: XmlNode[] = [];\n while (this.#index < this.source.length) {\n if (this.source.startsWith(\"</\", this.#index)) {\n this.#index += 2;\n const closingName = this.parseName();\n this.skipWhitespace();\n this.expect(\">\");\n if (closingName !== name) {\n this.fail(`Mismatched closing element: expected </${name}> but found </${closingName}>`);\n }\n return { name, attributes, children };\n }\n\n if (this.source.startsWith(\"<!--\", this.#index)) {\n this.skipComment();\n continue;\n }\n\n if (this.source.startsWith(\"<![CDATA[\", this.#index)) {\n this.appendText(children, this.parseCdata());\n continue;\n }\n\n if (this.source.startsWith(\"<?\", this.#index)) {\n this.skipProcessingInstruction();\n continue;\n }\n\n if (this.source.startsWith(\"<!\", this.#index)) {\n this.fail(\"Unsupported XML declaration inside an element\");\n }\n\n if (this.source[this.#index] === \"<\") {\n children.push(this.parseElement(depth + 1));\n } else {\n this.appendText(children, this.parseText());\n }\n }\n\n this.fail(`Unclosed XML element: <${name}>`);\n }\n\n private parseStartTag(): {\n attributes: SsmlAttributes;\n selfClosing: boolean;\n } {\n const attributes: SsmlAttributes = {};\n\n while (this.#index < this.source.length) {\n this.skipWhitespace();\n\n if (this.source.startsWith(\"/>\", this.#index)) {\n this.#index += 2;\n return { attributes, selfClosing: true };\n }\n if (this.source[this.#index] === \">\") {\n this.#index += 1;\n return { attributes, selfClosing: false };\n }\n\n const name = this.parseName();\n this.skipWhitespace();\n this.expect(\"=\");\n this.skipWhitespace();\n\n const quote = this.source[this.#index];\n if (quote !== '\"' && quote !== \"'\") {\n this.fail(`XML attribute ${name} must use a quoted value`);\n }\n this.#index += 1;\n\n const valueStart = this.#index;\n while (this.#index < this.source.length && this.source[this.#index] !== quote) {\n if (this.source[this.#index] === \"<\") {\n this.fail(`Invalid \"<\" in XML attribute ${name}`);\n }\n this.#index += 1;\n }\n if (this.#index >= this.source.length) {\n this.fail(`Unclosed XML attribute ${name}`);\n }\n\n const value = decodeXmlEntities(this.source.slice(valueStart, this.#index));\n this.#index += 1;\n\n if (hasOwn(attributes, name)) {\n this.fail(`Duplicate XML attribute: ${name}`);\n }\n setAttribute(attributes, name, value);\n }\n\n this.fail(\"Unclosed XML start tag\");\n }\n\n private parseText(): string {\n const start = this.#index;\n while (this.#index < this.source.length && this.source[this.#index] !== \"<\") {\n this.#index += 1;\n }\n\n const value = this.source.slice(start, this.#index);\n if (value.includes(\"]]>\")) {\n this.fail(\"CDATA termination is not valid in ordinary XML text\");\n }\n return decodeXmlEntities(value);\n }\n\n private parseCdata(): string {\n this.#index += \"<![CDATA[\".length;\n const end = this.source.indexOf(\"]]>\", this.#index);\n if (end === -1) {\n this.fail(\"Unclosed XML CDATA section\");\n }\n\n const value = this.source.slice(this.#index, end);\n this.#index = end + 3;\n return value;\n }\n\n private skipComment(): void {\n this.#index += \"<!--\".length;\n const end = this.source.indexOf(\"-->\", this.#index);\n if (end === -1) {\n this.fail(\"Unclosed XML comment\");\n }\n if (this.source.slice(this.#index, end).includes(\"--\")) {\n this.fail(\"XML comments cannot contain consecutive hyphens\");\n }\n this.#index = end + 3;\n }\n\n private skipProcessingInstruction(): void {\n this.#index += \"<?\".length;\n this.parseName();\n const end = this.source.indexOf(\"?>\", this.#index);\n if (end === -1) {\n this.fail(\"Unclosed XML processing instruction\");\n }\n this.#index = end + 2;\n }\n\n private skipMisc(): void {\n while (this.#index < this.source.length) {\n this.skipWhitespace();\n if (this.source.startsWith(\"<!--\", this.#index)) {\n this.skipComment();\n continue;\n }\n if (this.source.startsWith(\"<?\", this.#index)) {\n this.skipProcessingInstruction();\n continue;\n }\n if (this.source.startsWith(\"<!DOCTYPE\", this.#index)) {\n this.fail(\"DOCTYPE declarations are not supported\");\n }\n break;\n }\n }\n\n private parseName(): string {\n const first = this.source[this.#index];\n if (!isXmlNameStart(first)) {\n this.fail(\"Invalid XML name\");\n }\n\n const start = this.#index;\n this.#index += 1;\n while (isXmlNameCharacter(this.source[this.#index])) {\n this.#index += 1;\n }\n return this.source.slice(start, this.#index);\n }\n\n private appendText(children: XmlNode[], value: string): void {\n if (!value) {\n return;\n }\n\n const previous = children[children.length - 1];\n if (typeof previous === \"string\") {\n children[children.length - 1] = previous + value;\n } else {\n children.push(value);\n }\n }\n\n private skipWhitespace(): void {\n while (isXmlWhitespace(this.source[this.#index])) {\n this.#index += 1;\n }\n }\n\n private expect(value: string): void {\n if (!this.source.startsWith(value, this.#index)) {\n this.fail(`Expected \"${value}\"`);\n }\n this.#index += value.length;\n }\n\n private fail(message: string): never {\n throw new Error(`${message} at position ${this.#index}`);\n }\n}\n\nfunction readAttribute(attributes: SsmlAttributes, ...names: string[]): string | undefined {\n let found = false;\n let value: string | undefined;\n\n for (const name of names) {\n if (hasOwn(attributes, name)) {\n if (!found) {\n value = String(attributes[name]);\n found = true;\n }\n delete attributes[name];\n }\n }\n\n return value;\n}\n\nfunction getElementAttributes(node: XmlElementNode): SsmlAttributes {\n const attributes: SsmlAttributes = { ...node.attributes };\n removeStandardNamespaceAttributes(attributes);\n return attributes;\n}\n\nfunction finishElement<T extends SsmlElement>(element: T, node: XmlElementNode, attributes: SsmlAttributes): T {\n if (node.children.length > 0) {\n element.children = node.children.map(convertNode);\n }\n if (Object.keys(attributes).length > 0) {\n element.attributes = attributes;\n }\n return element;\n}\n\nfunction convertElement(node: XmlElementNode): SsmlElement {\n const attributes = getElementAttributes(node);\n\n switch (node.name) {\n case SSML_TAGS.VOICE: {\n const element: VoiceElement = { type: SSML_TAGS.VOICE };\n const name = readAttribute(attributes, SSML_ATTRS.NAME);\n const effect = readAttribute(attributes, SSML_ATTRS.EFFECT);\n if (name !== undefined) element.name = name;\n if (effect !== undefined) element.effect = effect;\n return finishElement(element, node, attributes);\n }\n case SSML_TAGS.PROSODY: {\n const element: ProsodyElement = { type: SSML_TAGS.PROSODY };\n const rate = readAttribute(attributes, SSML_ATTRS.RATE);\n const pitch = readAttribute(attributes, SSML_ATTRS.PITCH);\n const volume = readAttribute(attributes, SSML_ATTRS.VOLUME);\n const contour = readAttribute(attributes, SSML_ATTRS.CONTOUR);\n const range = readAttribute(attributes, SSML_ATTRS.RANGE);\n if (rate !== undefined) element.rate = rate;\n if (pitch !== undefined) element.pitch = pitch;\n if (volume !== undefined) element.volume = volume;\n if (contour !== undefined) element.contour = contour;\n if (range !== undefined) element.range = range;\n return finishElement(element, node, attributes);\n }\n case SSML_TAGS.BREAK: {\n const element: BreakElement = { type: SSML_TAGS.BREAK };\n const time = readAttribute(attributes, SSML_ATTRS.TIME);\n const strength = readAttribute(attributes, SSML_ATTRS.STRENGTH);\n if (time !== undefined) element.time = time;\n if (strength !== undefined) element.strength = strength;\n return finishElement(element, node, attributes);\n }\n case SSML_TAGS.EXPRESS_AS:\n case SSML_TAGS.EXPRESS_AS_CAMEL:\n case SSML_TAGS.MSTTS_EXPRESS_AS: {\n const element: ExpressAsElement = { type: node.name };\n const style = readAttribute(attributes, SSML_ATTRS.STYLE);\n const styleDegree = readAttribute(\n attributes,\n SSML_ATTRS.STYLE_DEGREE,\n SSML_ATTRS.STYLE_DEGREE_CAMEL,\n SSML_ATTRS.STYLE_DEGREE_HYPHEN,\n );\n const role = readAttribute(attributes, SSML_ATTRS.ROLE);\n if (style !== undefined) element.style = style;\n if (styleDegree !== undefined) element.styleDegree = styleDegree;\n if (role !== undefined) element.role = role;\n return finishElement(element, node, attributes);\n }\n case SSML_TAGS.SAY_AS:\n case SSML_TAGS.SAY_AS_CAMEL: {\n const element: SayAsElement = { type: node.name };\n const interpretAs = readAttribute(attributes, SSML_ATTRS.INTERPRET_AS);\n const format = readAttribute(attributes, SSML_ATTRS.FORMAT);\n const detail = readAttribute(attributes, SSML_ATTRS.DETAIL);\n if (interpretAs !== undefined) element.interpretAs = interpretAs;\n if (format !== undefined) element.format = format;\n if (detail !== undefined) element.detail = detail;\n return finishElement(element, node, attributes);\n }\n case SSML_TAGS.PHONEME: {\n const element: PhonemeElement = { type: SSML_TAGS.PHONEME };\n const alphabet = readAttribute(attributes, SSML_ATTRS.ALPHABET);\n const ph = readAttribute(attributes, SSML_ATTRS.PH);\n if (alphabet !== undefined) element.alphabet = alphabet;\n if (ph !== undefined) element.ph = ph;\n return finishElement(element, node, attributes);\n }\n case SSML_TAGS.EMPHASIS: {\n const element: EmphasisElement = { type: SSML_TAGS.EMPHASIS };\n const level = readAttribute(attributes, SSML_ATTRS.LEVEL);\n if (level !== undefined) element.level = level;\n return finishElement(element, node, attributes);\n }\n case SSML_TAGS.AUDIO: {\n const element: AudioElement = { type: SSML_TAGS.AUDIO };\n const src = readAttribute(attributes, SSML_ATTRS.SRC);\n const desc = readAttribute(attributes, SSML_ATTRS.DESC);\n const clipBegin = readAttribute(attributes, SSML_ATTRS.CLIP_BEGIN);\n const clipEnd = readAttribute(attributes, SSML_ATTRS.CLIP_END);\n const speed = readAttribute(attributes, SSML_ATTRS.SPEED);\n const repeatCount = readAttribute(attributes, SSML_ATTRS.REPEAT_COUNT);\n const repeatDuration = readAttribute(attributes, SSML_ATTRS.REPEAT_DURATION);\n const soundLevel = readAttribute(attributes, SSML_ATTRS.SOUND_LEVEL);\n if (src !== undefined) element.src = src;\n if (desc !== undefined) element.desc = desc;\n if (clipBegin !== undefined) element.clipBegin = clipBegin;\n if (clipEnd !== undefined) element.clipEnd = clipEnd;\n if (speed !== undefined) element.speed = speed;\n if (repeatCount !== undefined) element.repeatCount = repeatCount;\n if (repeatDuration !== undefined) element.repeatDuration = repeatDuration;\n if (soundLevel !== undefined) element.soundLevel = soundLevel;\n return finishElement(element, node, attributes);\n }\n case SSML_TAGS.SUB: {\n const element: SubElement = { type: SSML_TAGS.SUB };\n const alias = readAttribute(attributes, SSML_ATTRS.ALIAS);\n if (alias !== undefined) element.alias = alias;\n return finishElement(element, node, attributes);\n }\n case SSML_TAGS.LANG: {\n const element: LangElement = { type: SSML_TAGS.LANG };\n const lang = readAttribute(attributes, SSML_ATTRS.XML_LANG, SSML_ATTRS.LANG);\n if (lang !== undefined) element.lang = lang;\n return finishElement(element, node, attributes);\n }\n case SSML_TAGS.MARK: {\n const element: MarkElement = { type: SSML_TAGS.MARK };\n const name = readAttribute(attributes, SSML_ATTRS.NAME);\n if (name !== undefined) element.name = name;\n return finishElement(element, node, attributes);\n }\n case SSML_TAGS.BOOKMARK: {\n const element: BookmarkElement = { type: SSML_TAGS.BOOKMARK };\n const mark = readAttribute(attributes, SSML_ATTRS.MARK);\n if (mark !== undefined) element.mark = mark;\n return finishElement(element, node, attributes);\n }\n case SSML_TAGS.LEXICON: {\n const element: LexiconElement = { type: SSML_TAGS.LEXICON };\n const uri = readAttribute(attributes, SSML_ATTRS.URI);\n if (uri !== undefined) element.uri = uri;\n return finishElement(element, node, attributes);\n }\n case SSML_TAGS.PARAGRAPH: {\n const element: ParagraphElement = { type: SSML_TAGS.PARAGRAPH };\n return finishElement(element, node, attributes);\n }\n case SSML_TAGS.SENTENCE: {\n const element: SentenceElement = { type: SSML_TAGS.SENTENCE };\n return finishElement(element, node, attributes);\n }\n case SSML_TAGS.WORD: {\n const element: WordElement = { type: SSML_TAGS.WORD };\n return finishElement(element, node, attributes);\n }\n case SSML_TAGS.MSTTS_SILENCE:\n case SSML_TAGS.SILENCE: {\n const element: MsttsSilenceElement = {\n type: node.name === SSML_TAGS.MSTTS_SILENCE ? SSML_TAGS.MSTTS_SILENCE : SSML_TAGS.SILENCE,\n };\n const typeValue = readAttribute(attributes, SSML_ATTRS.TYPE);\n const value = readAttribute(attributes, SSML_ATTRS.VALUE);\n if (typeValue !== undefined) element.typeValue = typeValue;\n if (value !== undefined) element.value = value;\n return finishElement(element, node, attributes);\n }\n case SSML_TAGS.MSTTS_VISEME:\n case SSML_TAGS.VISEME: {\n const element: MsttsVisemeElement = {\n type: node.name === SSML_TAGS.MSTTS_VISEME ? SSML_TAGS.MSTTS_VISEME : SSML_TAGS.VISEME,\n };\n const typeValue = readAttribute(attributes, SSML_ATTRS.TYPE);\n if (typeValue !== undefined) element.typeValue = typeValue;\n return finishElement(element, node, attributes);\n }\n default: {\n const element: CustomElement = {\n name: node.name,\n type: \"custom\",\n };\n return finishElement(element, node, attributes);\n }\n }\n}\n\nfunction convertNode(node: XmlNode): SsmlNode {\n return typeof node === \"string\" ? node : convertElement(node);\n}\n\nexport function parseSsml(xmlString: string): SsmlDocument {\n if (typeof xmlString !== \"string\") {\n throw new TypeError(\"SSML input must be a string\");\n }\n\n const root = new XmlParser(xmlString).parse();\n if (root.name !== SSML_TAGS.SPEAK) {\n throw new Error(`SSML root element must be <${SSML_TAGS.SPEAK}>, found <${root.name}>`);\n }\n\n const attributes: SsmlAttributes = { ...root.attributes };\n const version = readAttribute(attributes, SSML_ATTRS.VERSION);\n const lang = readAttribute(attributes, SSML_ATTRS.XML_LANG, SSML_ATTRS.LANG);\n if (version === undefined) {\n throw new Error(`SSML <${SSML_TAGS.SPEAK}> element is missing the \"${SSML_ATTRS.VERSION}\" attribute`);\n }\n if (lang === undefined) {\n throw new Error(`SSML <${SSML_TAGS.SPEAK}> element is missing the \"${SSML_ATTRS.XML_LANG}\" attribute`);\n }\n\n removeStandardNamespaceAttributes(attributes);\n const document: SsmlDocument = {\n children: root.children.map(convertNode),\n lang,\n type: SSML_TAGS.SPEAK,\n version,\n };\n if (Object.keys(attributes).length > 0) {\n document.attributes = attributes;\n }\n return document;\n}\n","import { buildSsml } from \"./builder.ts\";\nimport {\n DEFAULT_SSML_LANGUAGE,\n DEFAULT_SSML_VERSION,\n SSML_ATTRS,\n SSML_TAGS,\n SYNTHESIS_NAMESPACE,\n} from \"./constants/ssml.ts\";\nimport { parseSsml } from \"./parser.ts\";\nimport type { ProsodyElement, SsmlAttributes, SsmlDocument, SsmlNode, VoiceElement } from \"./types.ts\";\n\nexport type SsmlPartialVoice = Pick<VoiceElement, \"name\" | \"effect\" | \"attributes\">;\n\nexport type SsmlPartialProsody = Pick<ProsodyElement, \"rate\" | \"pitch\" | \"volume\" | \"contour\" | \"range\" | \"attributes\">;\n\nexport interface SsmlPartialContext {\n /** SSML version used for the generated document. */\n version?: string;\n /** BCP-47 language tag used for the generated document. */\n lang?: string;\n /** Preferred voice name; a voice object takes precedence, while this overrides a string `voice` shorthand. */\n voiceName?: string;\n /** Optional Azure voice effect used with `voiceName` or a string `voice` shorthand. */\n voiceEffect?: string;\n /** A voice name shorthand or a voice object whose attributes are preserved. */\n voice?: string | SsmlPartialVoice;\n /** Optional prosody values applied around the partial text. */\n prosody?: SsmlPartialProsody;\n /** Additional attributes added to the generated `speak` element. */\n attributes?: SsmlAttributes;\n}\n\nexport interface BuildPartialSsmlOptions extends SsmlPartialContext {\n text: string;\n}\n\nfunction escapeAttribute(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/'/g, \"&apos;\");\n}\n\nfunction getPartialTextNodes(text: string, version: string, lang: string): SsmlNode[] {\n if (!text.includes(\"<\")) {\n return [text];\n }\n\n try {\n const openingTag = `<${SSML_TAGS.SPEAK} ${SSML_ATTRS.VERSION}=\"${escapeAttribute(version)}\" ${SSML_ATTRS.XMLNS}=\"${SYNTHESIS_NAMESPACE}\" ${SSML_ATTRS.XML_LANG}=\"${escapeAttribute(lang)}\">`;\n return parseSsml(`${openingTag}${text}</${SSML_TAGS.SPEAK}>`).children ?? [];\n } catch {\n return [{ type: \"text\", value: text }];\n }\n}\n\nfunction getVoiceContext(context: SsmlPartialContext): SsmlPartialVoice | undefined {\n const voice = context.voice;\n if (typeof voice === \"object\" && voice !== null) {\n return voice;\n }\n\n if (context.voiceName === undefined && context.voiceEffect === undefined && typeof voice !== \"string\") {\n return undefined;\n }\n\n return {\n name: context.voiceName ?? voice,\n effect: context.voiceEffect,\n };\n}\n\nfunction serializePartialSsml(text: string, context: SsmlPartialContext): string {\n const version = context.version ?? DEFAULT_SSML_VERSION;\n const lang = context.lang ?? DEFAULT_SSML_LANGUAGE;\n let children = getPartialTextNodes(text, version, lang);\n\n if (context.prosody) {\n children = [\n {\n type: SSML_TAGS.PROSODY,\n ...context.prosody,\n children,\n },\n ];\n }\n\n const voice = getVoiceContext(context);\n if (voice) {\n children = [\n {\n type: SSML_TAGS.VOICE,\n ...voice,\n children,\n },\n ];\n }\n\n const document: SsmlDocument = {\n type: SSML_TAGS.SPEAK,\n version,\n lang,\n attributes: context.attributes,\n children,\n };\n return buildSsml(document);\n}\n\nexport function buildPartialSsml(text: string, context?: SsmlPartialContext): string;\nexport function buildPartialSsml(options: BuildPartialSsmlOptions): string;\nexport function buildPartialSsml(\n textOrOptions: string | BuildPartialSsmlOptions,\n context?: SsmlPartialContext,\n): string {\n if (typeof textOrOptions === \"string\") {\n return serializePartialSsml(textOrOptions, context ?? {});\n }\n\n return serializePartialSsml(textOrOptions.text, textOrOptions);\n}\n","import { parseSsml } from \"./parser.ts\";\n\nconst PARSER_POSITION_SUFFIX = / at position (\\d+)$/;\n\nexport interface SsmlValidationError {\n message: string;\n position: number;\n}\n\nexport function validateSsml(xmlString: string): SsmlValidationError | null {\n try {\n parseSsml(xmlString);\n return null;\n } catch (error) {\n const rawMessage = error instanceof Error ? error.message : String(error);\n const positionMatch = PARSER_POSITION_SUFFIX.exec(rawMessage);\n\n return {\n message: positionMatch ? rawMessage.slice(0, positionMatch.index) : rawMessage,\n position: positionMatch ? Number.parseInt(positionMatch[1], 10) : 0,\n };\n }\n}\n","import { parseSsml } from \"./parser.ts\";\n\nexport interface SsmlTextNodeContext {\n parentTag: string;\n parentAttributes: Record<string, string>;\n ancestorTags: string[];\n path: string[];\n}\n\nexport interface MapSsmlTextNodesOptions {\n /** Element names whose text should not be passed to the transform. */\n skipTags?: readonly string[];\n /** Decides whether an individual text node should be passed to the transform. */\n filter?: (context: SsmlTextNodeContext) => boolean;\n}\n\ninterface TextNodeRecord {\n context: SsmlTextNodeContext;\n decodedText: string;\n end: number;\n sourceEnd: number;\n sourceStart: number;\n start: number;\n}\n\ninterface OpenElement {\n attributes: Record<string, string>;\n name: string;\n}\n\nfunction decodeXmlText(value: string): string {\n return value.replace(/&(?:amp|apos|gt|lt|quot);|&#(?:x[\\da-f]+|\\d+);/gi, (entity) => {\n if (entity === \"&amp;\") return \"&\";\n if (entity === \"&apos;\") return \"'\";\n if (entity === \"&gt;\") return \">\";\n if (entity === \"&lt;\") return \"<\";\n if (entity === \"&quot;\") return '\"';\n const hexadecimal = entity.toLowerCase().startsWith(\"&#x\");\n const digits = entity.slice(hexadecimal ? 3 : 2, -1);\n return String.fromCodePoint(Number.parseInt(digits, hexadecimal ? 16 : 10));\n });\n}\n\nfunction encodeXmlText(value: string): string {\n return value.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n}\n\nfunction decodeXmlAttribute(value: string): string {\n return decodeXmlText(value);\n}\n\nfunction findTagEnd(source: string, start: number): number {\n let quote = \"\";\n for (let index = start; index < source.length; index += 1) {\n const character = source[index];\n if (quote) {\n if (character === quote) quote = \"\";\n } else if (character === '\"' || character === \"'\") {\n quote = character;\n } else if (character === \">\") {\n return index;\n }\n }\n return source.length - 1;\n}\n\nfunction readTagName(tag: string): string | undefined {\n const match = /^<\\s*([A-Za-z_][A-Za-z0-9_.:-]*)/.exec(tag);\n return match?.[1];\n}\n\nfunction readTagAttributes(tag: string, name: string): Record<string, string> {\n const attributes: Record<string, string> = {};\n const nameStart = tag.indexOf(name);\n const attributeSource = tag.slice(nameStart + name.length, tag.length - 1).replace(/\\/\\s*$/, \"\");\n const attributePattern = /([A-Za-z_][A-Za-z0-9_.:-]*)\\s*=\\s*([\"'])([\\s\\S]*?)\\2/g;\n for (const match of attributeSource.matchAll(attributePattern)) {\n attributes[match[1].toLowerCase()] = decodeXmlAttribute(match[3]);\n }\n return attributes;\n}\n\nfunction collectTextNodes(source: string): TextNodeRecord[] {\n const nodes: TextNodeRecord[] = [];\n const elements: OpenElement[] = [];\n let index = 0;\n\n const addText = (start: number, end: number, rawText: string, sourceStart = start, sourceEnd = end): void => {\n if (!rawText) return;\n const path = elements.map((element) => element.name);\n const parent = elements[elements.length - 1];\n nodes.push({\n context: {\n ancestorTags: path.slice(0, -1),\n parentAttributes: { ...(parent?.attributes ?? {}) },\n parentTag: parent?.name ?? \"\",\n path,\n },\n decodedText: decodeXmlText(rawText),\n end,\n sourceEnd,\n sourceStart,\n start,\n });\n };\n\n while (index < source.length) {\n if (source[index] !== \"<\") {\n const nextTag = source.indexOf(\"<\", index);\n const end = nextTag === -1 ? source.length : nextTag;\n addText(index, end, source.slice(index, end));\n index = end;\n continue;\n }\n\n if (source.startsWith(\"<!--\", index)) {\n const end = source.indexOf(\"-->\", index + 4);\n index = end === -1 ? source.length : end + 3;\n continue;\n }\n if (source.startsWith(\"<![CDATA[\", index)) {\n const contentStart = index + 9;\n const end = source.indexOf(\"]]>\", contentStart);\n const contentEnd = end === -1 ? source.length : end;\n addText(\n contentStart,\n contentEnd,\n source.slice(contentStart, contentEnd),\n index,\n end === -1 ? source.length : end + 3,\n );\n index = end === -1 ? source.length : end + 3;\n continue;\n }\n if (source.startsWith(\"<?\", index)) {\n const end = source.indexOf(\"?>\", index + 2);\n index = end === -1 ? source.length : end + 2;\n continue;\n }\n if (source.startsWith(\"</\", index)) {\n const end = findTagEnd(source, index + 2);\n elements.pop();\n index = end + 1;\n continue;\n }\n\n const end = findTagEnd(source, index + 1);\n const tag = source.slice(index, end + 1);\n const name = readTagName(tag);\n if (name && !/\\/\\s*>$/.test(tag)) elements.push({ attributes: readTagAttributes(tag, name), name });\n index = end + 1;\n }\n\n return nodes;\n}\n\nexport function extractSsmlText(ssml: string): string[] {\n parseSsml(ssml);\n return collectTextNodes(ssml).map((node) => node.decodedText);\n}\n\nexport async function mapSsmlTextNodes(\n ssml: string,\n transform: (text: string, context: SsmlTextNodeContext) => string | Promise<string>,\n options: MapSsmlTextNodesOptions = {},\n): Promise<string> {\n parseSsml(ssml);\n const nodes = collectTextNodes(ssml);\n const skipTags = new Set((options.skipTags ?? [\"phoneme\", \"say-as\", \"sub\"]).map((tag) => tag.toLowerCase()));\n const replacements = await Promise.all(\n nodes.map(async (node) => {\n const context = {\n ancestorTags: [...node.context.ancestorTags],\n parentAttributes: { ...node.context.parentAttributes },\n parentTag: node.context.parentTag,\n path: [...node.context.path],\n };\n const shouldTransform = !skipTags.has(context.parentTag.toLowerCase()) && (options.filter?.(context) ?? true);\n if (!shouldTransform) return ssml.slice(node.sourceStart, node.sourceEnd);\n const transformed = await transform(node.decodedText, context);\n if (typeof transformed !== \"string\") {\n throw new TypeError(\"SSML text node transform must return a string\");\n }\n return transformed === node.decodedText\n ? ssml.slice(node.sourceStart, node.sourceEnd)\n : encodeXmlText(transformed);\n }),\n );\n\n let result = \"\";\n let cursor = 0;\n nodes.forEach((node, nodeIndex) => {\n result += ssml.slice(cursor, node.sourceStart) + replacements[nodeIndex];\n cursor = node.sourceEnd;\n });\n return result + ssml.slice(cursor);\n}\n","import { parseSsml } from \"./parser.ts\";\n\nexport type SsmlDiagnosticSeverity = \"error\" | \"warning\";\n\nexport type AzureDiagnosticCode = \"azure-unknown-voice\" | \"azure-unsupported-style\" | \"azure-locale-mismatch\";\n\nexport interface SsmlDiagnostic {\n code?: AzureDiagnosticCode;\n line: number;\n column: number;\n message: string;\n severity: SsmlDiagnosticSeverity;\n}\n\nexport interface AzureVoiceDefinition {\n name: string;\n locale: string;\n secondaryLocales?: readonly string[];\n styles?: readonly string[];\n}\n\n/** Alias retained for consumers that prefer the metadata terminology. */\nexport interface AzureVoiceMetadata extends AzureVoiceDefinition {}\n\nexport interface AzureValidationOptions {\n allowedAudioOrigins?: readonly string[];\n allowExternalAudio?: boolean;\n allowHttpAudio?: boolean;\n customVoiceStyleMap?: Record<string, readonly string[]>;\n customVoiceDefinitions?: readonly AzureVoiceDefinition[];\n languageAliases?: Record<string, string | readonly string[]>;\n maxLength?: number;\n normalizeLanguage?: (lang: string) => string;\n unknownVoicePolicy?: \"error\" | \"warn\" | \"ignore\";\n unsupportedStylePolicy?: \"error\" | \"warn\" | \"ignore\";\n validateNestedVoices?: boolean;\n voiceCatalog?: readonly AzureVoiceDefinition[];\n voiceDefinitions?: readonly AzureVoiceDefinition[];\n}\n\nexport type AzureLanguageNormalizationOptions = Pick<AzureValidationOptions, \"languageAliases\" | \"normalizeLanguage\">;\n\n/** @deprecated Use AzureValidationOptions instead. */\nexport type AzureSsmlValidationOptions = AzureValidationOptions;\n\ninterface ElementToken {\n attributes: Map<string, string>;\n end: number;\n name: string;\n parentVoiceName?: string;\n start: number;\n selfClosing: boolean;\n}\n\nconst EXPRESS_AS_STYLES: Readonly<Record<string, readonly string[]>> = {\n \"en-us-jennyneural\": [\n \"assistant\",\n \"chat\",\n \"customerservice\",\n \"newscast\",\n \"cheerful\",\n \"empathetic\",\n \"excited\",\n \"friendly\",\n \"hopeful\",\n \"sad\",\n \"shouting\",\n \"terrified\",\n \"unfriendly\",\n \"whispering\",\n ],\n \"en-us-guyneural\": [\n \"angry\",\n \"cheerful\",\n \"excited\",\n \"friendly\",\n \"hopeful\",\n \"newscast\",\n \"sad\",\n \"shouting\",\n \"terrified\",\n \"unfriendly\",\n \"whispering\",\n ],\n \"en-us-jennymultilingualneural\": [\n \"cheerful\",\n \"empathetic\",\n \"excited\",\n \"friendly\",\n \"hopeful\",\n \"sad\",\n \"shouting\",\n \"terrified\",\n \"unfriendly\",\n \"whispering\",\n ],\n \"en-us-andrewneural\": [\"empathetic\", \"relieved\"],\n \"ja-jp-mayuneural\": [\"calm\", \"cheerful\", \"sad\"],\n \"ja-jp-nanamineural\": [\"chat\", \"customerservice\", \"cheerful\", \"whispering\", \"sad\"],\n \"ja-jp-keitaneural\": [\"chat\"],\n \"ko-kr-sunhineural\": [\"cheerful\", \"sad\"],\n \"zh-cn-yunxineural\": [\n \"narration-relaxed\",\n \"embarrassed\",\n \"fearful\",\n \"sad\",\n \"disgruntled\",\n \"serious\",\n \"angry\",\n \"depressed\",\n \"chat\",\n \"cheerful\",\n \"assistant\",\n ],\n \"zh-cn-xiaoxiaoneural\": [\n \"assistant\",\n \"chat\",\n \"customerservice\",\n \"newscast\",\n \"cheerful\",\n \"empathetic\",\n \"excited\",\n \"friendly\",\n \"hopeful\",\n \"sad\",\n \"terrified\",\n \"whispering\",\n \"poetry-reading\",\n \"sports_commentary\",\n \"sports_commentary_excited\",\n \"story\",\n ],\n \"fr-fr-deniseneural\": [\"cheerful\", \"sad\"],\n \"fr-fr-henrineural\": [\"cheerful\", \"sad\"],\n \"pt-br-franciscaneural\": [\"calm\"],\n \"it-it-elsaneural\": [\"cheerful\", \"sad\"],\n \"de-de-katjaneural\": [\"cheerful\", \"sad\"],\n \"de-de-conradneural\": [\"cheerful\", \"sad\"],\n \"ru-ru-svetlananeural\": [\"cheerful\", \"sad\", \"angry\", \"disgruntled\", \"embarrassed\", \"fearful\"],\n};\n\nconst ALLOWED_BREAK_STRENGTHS = new Set([\"none\", \"x-weak\", \"weak\", \"medium\", \"strong\", \"x-strong\"]);\nconst ALLOWED_SAY_AS = new Set([\n \"characters\",\n \"spell-out\",\n \"cardinal\",\n \"ordinal\",\n \"number\",\n \"date\",\n \"time\",\n \"telephone\",\n \"fraction\",\n \"address\",\n \"name\",\n \"currency\",\n]);\nconst ALLOWED_ROLES = new Set([\n \"Girl\",\n \"Boy\",\n \"YoungAdultFemale\",\n \"YoungAdultMale\",\n \"OlderAdultFemale\",\n \"OlderAdultMale\",\n \"SeniorFemale\",\n \"SeniorMale\",\n]);\nconst ALLOWED_EMPHASIS_LEVELS = new Set([\"strong\", \"moderate\", \"reduced\", \"none\"]);\nconst ALLOWED_SILENCE_TYPES = new Set([\n \"Leading\",\n \"Tailing\",\n \"Sentenceboundary\",\n \"Comma\",\n \"Semicolon\",\n \"Enumerationcomma\",\n]);\nconst ALLOWED_VISEME_TYPES = new Set([\"redlips_front\", \"FacialExpression\"]);\n\nfunction decodeAttribute(value: string): string {\n return value.replace(\n /&(?:amp|apos|gt|lt|quot);/gi,\n (entity) =>\n ({ \"&amp;\": \"&\", \"&apos;\": \"'\", \"&gt;\": \">\", \"&lt;\": \"<\", \"&quot;\": '\"' })[entity.toLowerCase()] ?? entity,\n );\n}\n\nfunction findTagEnd(source: string, start: number): number {\n let quote = \"\";\n for (let index = start; index < source.length; index += 1) {\n const character = source[index];\n if (quote) {\n if (character === quote) quote = \"\";\n } else if (character === '\"' || character === \"'\") quote = character;\n else if (character === \">\") return index;\n }\n return source.length - 1;\n}\n\nfunction tokenizeElements(source: string): ElementToken[] {\n const tokens: ElementToken[] = [];\n const openElements: Array<{ name: string; voiceName?: string }> = [];\n let index = 0;\n while (index < source.length) {\n const start = source.indexOf(\"<\", index);\n if (start === -1) break;\n if (source.startsWith(\"<!--\", start)) {\n const end = source.indexOf(\"-->\", start + 4);\n index = end === -1 ? source.length : end + 3;\n continue;\n }\n if (source.startsWith(\"<![CDATA[\", start)) {\n const end = source.indexOf(\"]]>\", start + 9);\n index = end === -1 ? source.length : end + 3;\n continue;\n }\n if (source.startsWith(\"<?\", start)) {\n const end = source.indexOf(\"?>\", start + 2);\n index = end === -1 ? source.length : end + 2;\n continue;\n }\n const end = findTagEnd(source, start + 1);\n const raw = source.slice(start, end + 1);\n if (raw.startsWith(\"</\")) {\n openElements.pop();\n index = end + 1;\n continue;\n }\n const nameMatch = /^<\\s*([A-Za-z_][A-Za-z0-9_.:-]*)/.exec(raw);\n if (!nameMatch?.[1]) {\n index = end + 1;\n continue;\n }\n const attributes = new Map<string, string>();\n const attributeSource = raw.slice(nameMatch[0].length, raw.length - 1).replace(/\\/\\s*$/, \"\");\n const attributePattern = /([A-Za-z_][A-Za-z0-9_.:-]*)\\s*=\\s*([\"'])([\\s\\S]*?)\\2/g;\n for (const match of attributeSource.matchAll(attributePattern)) {\n attributes.set(match[1].toLowerCase(), decodeAttribute(match[3]));\n }\n const selfClosing = /\\/\\s*>$/.test(raw);\n const parentVoiceName = [...openElements].reverse().find((element) => element.voiceName)?.voiceName;\n tokens.push({ attributes, end, name: nameMatch[1], parentVoiceName, selfClosing, start });\n if (!selfClosing) {\n openElements.push({\n name: nameMatch[1],\n voiceName: nameMatch[1].toLowerCase() === \"voice\" ? attributes.get(\"name\") : parentVoiceName,\n });\n }\n index = end + 1;\n }\n return tokens;\n}\n\nfunction location(source: string, offset: number): { column: number; line: number } {\n const before = source.slice(0, Math.max(0, offset));\n const line = before.split(\"\\n\").length;\n return { line, column: before.length - (before.lastIndexOf(\"\\n\") + 1) + 1 };\n}\n\nfunction addDiagnostic(\n diagnostics: SsmlDiagnostic[],\n source: string,\n offset: number,\n message: string,\n severity: SsmlDiagnosticSeverity = \"error\",\n code?: AzureDiagnosticCode,\n): void {\n diagnostics.push({ ...location(source, offset), message, severity, ...(code ? { code } : {}) });\n}\n\nfunction attr(token: ElementToken, name: string): string | undefined {\n return token.attributes.get(name.toLowerCase());\n}\n\nconst ADDITIONAL_VOICE_DEFINITIONS: readonly AzureVoiceDefinition[] = [\n { name: \"zh-TW-HsiaoChenNeural\", locale: \"zh-TW\" },\n { name: \"es-ES-ElviraNeural\", locale: \"es-ES\" },\n { name: \"th-TH-PremwadeeNeural\", locale: \"th-TH\" },\n { name: \"fil-PH-AngeloNeural\", locale: \"fil-PH\" },\n { name: \"vi-VN-HoaiMyNeural\", locale: \"vi-VN\" },\n { name: \"id-ID-GadisNeural\", locale: \"id-ID\" },\n { name: \"ms-MY-YasminNeural\", locale: \"ms-MY\" },\n];\n\nconst DEFAULT_LANGUAGE_ALIASES: Readonly<Record<string, readonly string[]>> = {\n \"zh-CN\": [\"zh-Hans\"],\n \"zh-TW\": [\"zh-Hant\"],\n};\n\nfunction canonicalLanguageTag(language: string): string {\n const trimmed = language.trim();\n if (!trimmed) return \"\";\n try {\n return new Intl.Locale(trimmed).toString().toLowerCase();\n } catch {\n return trimmed.toLowerCase();\n }\n}\n\nfunction createLanguageNormalizer(options: AzureValidationOptions): (language: string) => string {\n const aliases = new Map<string, string>();\n const addAliasGroup = (canonical: string, values: readonly string[]): void => {\n const normalizedCanonical = canonicalLanguageTag(canonical);\n if (!normalizedCanonical) return;\n aliases.set(normalizedCanonical, normalizedCanonical);\n for (const value of values) {\n const normalizedValue = canonicalLanguageTag(value);\n if (normalizedValue) aliases.set(normalizedValue, normalizedCanonical);\n }\n };\n for (const [canonical, values] of Object.entries(DEFAULT_LANGUAGE_ALIASES)) addAliasGroup(canonical, values);\n for (const [canonical, valueOrValues] of Object.entries(options.languageAliases ?? {}))\n addAliasGroup(canonical, typeof valueOrValues === \"string\" ? [valueOrValues] : valueOrValues);\n\n return (language: string): string => {\n const customValue = options.normalizeLanguage ? options.normalizeLanguage(language) : language;\n const normalized = canonicalLanguageTag(customValue);\n return aliases.get(normalized) ?? normalized;\n };\n}\n\n/** Normalizes an Azure language tag using BCP 47 and the configured aliases. */\nexport function normalizeAzureLanguage(language: string, options: AzureLanguageNormalizationOptions = {}): string {\n return createLanguageNormalizer(options)(language);\n}\n\n/** Compares two Azure language tags after BCP 47 and alias normalization. */\nexport function areAzureLanguagesEquivalent(\n first: string,\n second: string,\n options: AzureLanguageNormalizationOptions = {},\n): boolean {\n const normalize = createLanguageNormalizer(options);\n const normalizedFirst = normalize(first);\n const normalizedSecond = normalize(second);\n if (normalizedFirst === normalizedSecond) return true;\n return (\n normalizedFirst === languagePart(normalizedFirst) &&\n languagePart(normalizedFirst) === languagePart(normalizedSecond)\n );\n}\n\nfunction voiceLocalePrefix(voiceName: string): { language: string; region: string; tag: string } | undefined {\n const match = /^(?<language>[A-Za-z]{2,3})-(?<region>[A-Za-z]{2}|\\d{3})(?:-|$)/.exec(voiceName.trim());\n if (!match?.groups) return undefined;\n const tag = `${match.groups.language}-${match.groups.region}`;\n return {\n language: match.groups.language.toLowerCase(),\n region: match.groups.region.toLowerCase(),\n tag,\n };\n}\n\nfunction definitionFromStyleMap(voiceName: string, styles: readonly string[]): AzureVoiceDefinition {\n return {\n name: voiceName,\n locale: voiceLocalePrefix(voiceName)?.tag ?? \"\",\n styles,\n };\n}\n\nfunction normalizeVoiceCatalog(options: AzureValidationOptions): ReadonlyMap<string, AzureVoiceDefinition> {\n const definitions = new Map<string, AzureVoiceDefinition>();\n for (const [name, styles] of Object.entries(EXPRESS_AS_STYLES)) {\n definitions.set(name.toLowerCase(), definitionFromStyleMap(name, styles));\n }\n for (const definition of ADDITIONAL_VOICE_DEFINITIONS) definitions.set(definition.name.toLowerCase(), definition);\n for (const definition of options.voiceCatalog ?? []) definitions.set(definition.name.toLowerCase(), definition);\n for (const definition of options.voiceDefinitions ?? []) definitions.set(definition.name.toLowerCase(), definition);\n for (const definition of options.customVoiceDefinitions ?? [])\n definitions.set(definition.name.toLowerCase(), definition);\n for (const [voiceName, styles] of Object.entries(options.customVoiceStyleMap ?? {})) {\n const key = voiceName.toLowerCase();\n const current = definitions.get(key);\n definitions.set(key, {\n ...(current ?? definitionFromStyleMap(voiceName, styles)),\n name: current?.name ?? voiceName,\n styles: styles.map((style) => style.toLowerCase()),\n });\n }\n return definitions;\n}\n\nfunction diagnosticSeverity(policy: AzureValidationOptions[\"unknownVoicePolicy\"]): SsmlDiagnosticSeverity | undefined {\n if (policy === \"ignore\") return undefined;\n return policy === \"error\" ? \"error\" : \"warning\";\n}\n\nfunction languagePart(language: string): string {\n try {\n return new Intl.Locale(language).language.toLowerCase();\n } catch {\n return language.split(\"-\")[0]?.toLowerCase() ?? \"\";\n }\n}\n\nfunction definitionMatchesLanguage(\n definition: AzureVoiceDefinition | undefined,\n voiceName: string,\n language: string,\n normalizeLanguage: (language: string) => string,\n): boolean | undefined {\n const candidateLanguages = definition\n ? [definition.locale, ...(definition.secondaryLocales ?? [])].filter(Boolean)\n : [voiceLocalePrefix(voiceName)?.tag ?? \"\"];\n if (candidateLanguages.length === 0 || !language.trim()) return undefined;\n const normalizedLanguage = normalizeLanguage(language);\n const normalizedCandidates = candidateLanguages.map(normalizeLanguage);\n if (normalizedCandidates.includes(normalizedLanguage)) return true;\n if (!normalizedLanguage || !normalizedCandidates.some(Boolean)) return undefined;\n return normalizedLanguage === languagePart(normalizedLanguage)\n ? normalizedCandidates.some((candidate) => languagePart(candidate) === normalizedLanguage)\n : false;\n}\n\nfunction validateElement(\n token: ElementToken,\n source: string,\n diagnostics: SsmlDiagnostic[],\n voiceName: string | undefined,\n options: AzureValidationOptions,\n voiceCatalog: ReadonlyMap<string, AzureVoiceDefinition>,\n): void {\n const name = token.name.toLowerCase();\n if (name === \"voice\" && !attr(token, \"name\")?.trim())\n addDiagnostic(diagnostics, source, token.start, '<voice> requires a non-empty \"name\" attribute.');\n if (name === \"break\") {\n const time = attr(token, \"time\");\n const strength = attr(token, \"strength\");\n if (!time && !strength)\n addDiagnostic(diagnostics, source, token.start, '<break> requires either \"time\" or \"strength\".');\n if (time && strength)\n addDiagnostic(diagnostics, source, token.start, '<break> must not specify both \"time\" and \"strength\".');\n if (time && !/^\\d+(?:\\.\\d+)?(?:ms|s)$/.test(time.trim()))\n addDiagnostic(diagnostics, source, token.start, '<break time> must use a numeric value followed by \"ms\" or \"s\".');\n if (strength && !ALLOWED_BREAK_STRENGTHS.has(strength))\n addDiagnostic(diagnostics, source, token.start, `Unsupported <break strength> value \"${strength}\".`);\n }\n if (name === \"prosody\") {\n const rate = attr(token, \"rate\");\n const pitch = attr(token, \"pitch\");\n const volume = attr(token, \"volume\");\n if (rate && !/^(x-slow|slow|medium|fast|x-fast|[+-]?\\d+(?:\\.\\d+)?%)$/.test(rate.trim()))\n addDiagnostic(diagnostics, source, token.start, `Unsupported <prosody rate> value \"${rate}\".`);\n if (pitch && !/^(x-low|low|medium|high|x-high|[+-]?\\d+(?:\\.\\d+)?(?:st|Hz|%)?)$/.test(pitch.trim()))\n addDiagnostic(diagnostics, source, token.start, `Unsupported <prosody pitch> value \"${pitch}\".`);\n if (volume && !/^(silent|x-soft|soft|medium|loud|x-loud|[+-]?\\d+(?:\\.\\d+)?(?:dB|%)?)$/.test(volume.trim()))\n addDiagnostic(diagnostics, source, token.start, `Unsupported <prosody volume> value \"${volume}\".`);\n }\n if (name === \"mstts:express-as\" || name === \"express-as\" || name === \"expressas\") {\n const style = attr(token, \"style\");\n if (!style?.trim())\n addDiagnostic(diagnostics, source, token.start, '<mstts:express-as> requires a non-empty \"style\" attribute.');\n const degree = attr(token, \"styledegree\") ?? attr(token, \"style-degree\");\n if (degree && (!/^\\d+(?:\\.\\d+)?$/.test(degree) || Number(degree) < 0.01 || Number(degree) > 2))\n addDiagnostic(\n diagnostics,\n source,\n token.start,\n \"<mstts:express-as styledegree> must be a number between 0.01 and 2.\",\n );\n const role = attr(token, \"role\");\n if (role && !ALLOWED_ROLES.has(role))\n addDiagnostic(diagnostics, source, token.start, `Unsupported <mstts:express-as role> value \"${role}\".`);\n const definition = voiceName ? voiceCatalog.get(voiceName.toLowerCase()) : undefined;\n const supportedStyles = definition?.styles;\n const severity = diagnosticSeverity(options.unsupportedStylePolicy ?? options.unknownVoicePolicy ?? \"warn\");\n if (\n style &&\n definition &&\n !supportedStyles?.some((candidate) => candidate.toLowerCase() === style.toLowerCase()) &&\n severity\n )\n addDiagnostic(\n diagnostics,\n source,\n token.start,\n `Unknown style \"${style}\" is not supported by voice \"${voiceName}\" according to the configured voice style map.`,\n severity,\n \"azure-unsupported-style\",\n );\n if (style && voiceName && !definition && severity)\n addDiagnostic(\n diagnostics,\n source,\n token.start,\n `Unknown style \"${style}\" cannot be verified because voice \"${voiceName}\" is not registered in the voice style map.`,\n severity,\n );\n }\n if (name === \"say-as\" || name === \"sayas\") {\n const interpretAs = attr(token, \"interpret-as\");\n if (!interpretAs || !ALLOWED_SAY_AS.has(interpretAs))\n addDiagnostic(diagnostics, source, token.start, `<say-as> requires a supported \"interpret-as\" value.`);\n }\n if (name === \"phoneme\" && (!attr(token, \"alphabet\") || !attr(token, \"ph\")))\n addDiagnostic(diagnostics, source, token.start, '<phoneme> requires both \"alphabet\" and \"ph\" attributes.');\n if (name === \"emphasis\" && attr(token, \"level\") && !ALLOWED_EMPHASIS_LEVELS.has(attr(token, \"level\") ?? \"\"))\n addDiagnostic(diagnostics, source, token.start, `Unsupported <emphasis level> value \"${attr(token, \"level\")}\".`);\n if (name === \"sub\" && !attr(token, \"alias\")?.trim())\n addDiagnostic(diagnostics, source, token.start, '<sub> requires a non-empty \"alias\" attribute.');\n if (name === \"lang\" && !attr(token, \"xml:lang\")?.trim() && !attr(token, \"lang\")?.trim())\n addDiagnostic(diagnostics, source, token.start, '<lang> requires an \"xml:lang\" attribute.');\n if (name === \"mark\" && !attr(token, \"name\")?.trim())\n addDiagnostic(diagnostics, source, token.start, '<mark> requires a non-empty \"name\" attribute.');\n if (name === \"bookmark\" && !attr(token, \"mark\")?.trim())\n addDiagnostic(diagnostics, source, token.start, '<bookmark> requires a non-empty \"mark\" attribute.');\n if (name === \"lexicon\") {\n const uri = attr(token, \"uri\");\n if (!uri) addDiagnostic(diagnostics, source, token.start, '<lexicon> requires a \"uri\" attribute.');\n else {\n try {\n const parsed = new URL(uri);\n if (parsed.protocol !== \"https:\")\n addDiagnostic(diagnostics, source, token.start, \"<lexicon uri> must use HTTPS.\");\n } catch {\n addDiagnostic(diagnostics, source, token.start, \"<lexicon uri> must be an absolute HTTPS URL.\");\n }\n }\n }\n if (name === \"mstts:silence\") {\n const type = attr(token, \"type\");\n const value = attr(token, \"value\");\n if (!type || !ALLOWED_SILENCE_TYPES.has(type))\n addDiagnostic(diagnostics, source, token.start, '<mstts:silence> requires a supported \"type\" attribute.');\n if (!value || !/^\\d+(?:\\.\\d+)?(?:ms|s)$/.test(value.trim()))\n addDiagnostic(diagnostics, source, token.start, '<mstts:silence> requires a time-valued \"value\" attribute.');\n }\n if (name === \"mstts:viseme\") {\n const type = attr(token, \"type\");\n if (!type || !ALLOWED_VISEME_TYPES.has(type))\n addDiagnostic(diagnostics, source, token.start, '<mstts:viseme> requires a supported \"type\" attribute.');\n }\n if (name === \"audio\") {\n const src = attr(token, \"src\");\n if (!src) addDiagnostic(diagnostics, source, token.start, '<audio> requires a \"src\" attribute.');\n else {\n let parsed: URL;\n try {\n parsed = new URL(src);\n } catch {\n addDiagnostic(diagnostics, source, token.start, \"<audio src> must be an absolute HTTP(S) URL.\");\n return;\n }\n if (parsed.protocol !== \"https:\" && !(options.allowHttpAudio && parsed.protocol === \"http:\"))\n addDiagnostic(diagnostics, source, token.start, \"<audio src> must use HTTPS.\");\n if (options.allowedAudioOrigins && !options.allowedAudioOrigins.includes(parsed.origin))\n addDiagnostic(diagnostics, source, token.start, `<audio src> origin \"${parsed.origin}\" is not allowed.`);\n else if (!options.allowExternalAudio)\n addDiagnostic(\n diagnostics,\n source,\n token.start,\n `<audio src> external origin \"${parsed.origin}\" is blocked by default; set allowExternalAudio to true or provide allowedAudioOrigins.`,\n \"error\",\n );\n }\n }\n}\n\nexport function validateAzureSsml(ssml: string, options: AzureValidationOptions = {}): SsmlDiagnostic[] {\n const diagnostics: SsmlDiagnostic[] = [];\n if (typeof ssml !== \"string\") {\n return [{ line: 1, column: 1, message: \"SSML input must be a string\", severity: \"error\" }];\n }\n const maxLength = options.maxLength ?? 10_000;\n if (ssml.length > maxLength)\n addDiagnostic(diagnostics, ssml, maxLength, `SSML exceeds the maximum length of ${maxLength} characters.`);\n try {\n parseSsml(ssml);\n } catch (error) {\n const message = error instanceof Error ? error.message.replace(/ at position \\d+$/, \"\") : String(error);\n const match = / at position (\\d+)$/.exec(error instanceof Error ? error.message : \"\");\n addDiagnostic(diagnostics, ssml, match ? Number(match[1]) : 0, message);\n return diagnostics;\n }\n const tokens = tokenizeElements(ssml);\n const speak = tokens.find((token) => token.name.toLowerCase() === \"speak\");\n const voices = tokens.filter((token) => token.name.toLowerCase() === \"voice\");\n if (!speak || voices.length === 0)\n addDiagnostic(\n diagnostics,\n ssml,\n speak?.start ?? 0,\n \"Azure SSML requires at least one <voice> element under <speak>.\",\n );\n const voiceName = voices[0] ? attr(voices[0], \"name\") : undefined;\n const voiceCatalog = normalizeVoiceCatalog(options);\n const normalizeLanguage = createLanguageNormalizer(options);\n const policySeverity = diagnosticSeverity(options.unknownVoicePolicy ?? \"warn\");\n const voicesToValidate = options.validateNestedVoices === false ? voices.slice(0, 1) : voices;\n for (const token of voicesToValidate) {\n const name = attr(token, \"name\")?.trim();\n const language = attr(token, \"xml:lang\")?.trim() || (speak ? attr(speak, \"xml:lang\")?.trim() : undefined);\n const definition = name ? voiceCatalog.get(name.toLowerCase()) : undefined;\n if (name && !definition && policySeverity)\n addDiagnostic(\n diagnostics,\n ssml,\n token.start,\n `Unknown voice \"${name}\" is not registered in the voice catalog.`,\n policySeverity,\n \"azure-unknown-voice\",\n );\n if (name && language && definitionMatchesLanguage(definition, name, language, normalizeLanguage) === false)\n addDiagnostic(\n diagnostics,\n ssml,\n token.start,\n `Voice \"${name}\" does not match language \"${language}\"; the voice name prefix indicates a different language or region.`,\n \"warning\",\n \"azure-locale-mismatch\",\n );\n }\n for (const token of tokens) {\n const tokenVoiceName = options.validateNestedVoices === false ? voiceName : token.parentVoiceName;\n validateElement(token, ssml, diagnostics, tokenVoiceName, options, voiceCatalog);\n }\n return diagnostics;\n}\n"],"mappings":"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","names":["escapeAttribute","end","findTagEnd","end"]}
@@ -3510,4 +3510,4 @@ export {
3510
3510
  findSsmlHoverTarget,
3511
3511
  formatSsmlHover
3512
3512
  };
3513
- //# sourceMappingURL=chunk-ALFYHSCR.mjs.map
3513
+ //# sourceMappingURL=chunk-QJTVHANI.mjs.map