ssml-builder-js 2.14.0 → 2.16.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/dist/react.js CHANGED
@@ -2960,34 +2960,51 @@ function createAzureUrlValidatorRunner(validator, options = {}) {
2960
2960
  const inFlight = /* @__PURE__ */ new Map();
2961
2961
  const waiters = [];
2962
2962
  let active = 0;
2963
- const acquire = async () => {
2963
+ const configuredSignal = options.signal ?? new AbortController().signal;
2964
+ const acquire = async (signal) => {
2965
+ if (signal.aborted) throw new Error("URL validation was aborted.");
2964
2966
  if (active < concurrency) {
2965
2967
  active += 1;
2966
2968
  return;
2967
2969
  }
2968
- await new Promise((resolve) => waiters.push(resolve));
2970
+ await new Promise((resolve, reject) => {
2971
+ let waiter;
2972
+ const abortHandler = () => {
2973
+ const index = waiters.indexOf(waiter);
2974
+ if (index >= 0) waiters.splice(index, 1);
2975
+ signal.removeEventListener("abort", abortHandler);
2976
+ reject(new Error("URL validation was aborted."));
2977
+ };
2978
+ signal.addEventListener("abort", abortHandler, { once: true });
2979
+ waiter = () => {
2980
+ signal.removeEventListener("abort", abortHandler);
2981
+ resolve();
2982
+ };
2983
+ waiters.push(waiter);
2984
+ });
2969
2985
  active += 1;
2970
2986
  };
2971
2987
  const release = () => {
2972
2988
  active -= 1;
2973
2989
  waiters.shift()?.();
2974
2990
  };
2975
- const check = async (url, context) => {
2976
- if (options.signal?.aborted) throw new Error("URL validation was aborted.");
2977
- const cached = cache.get(url);
2991
+ const check = async (url, context, signal = configuredSignal) => {
2992
+ if (signal.aborted) throw new Error("URL validation was aborted.");
2993
+ const key = `${context.tag}:${context.attribute}:${url}`;
2994
+ const cached = cache.get(key);
2978
2995
  if (cached !== void 0) return cached;
2979
- const existing = inFlight.get(url);
2996
+ const existing = inFlight.get(key);
2980
2997
  if (existing) return existing;
2981
2998
  const promise = (async () => {
2982
- await acquire();
2999
+ await acquire(signal);
2983
3000
  try {
2984
- if (options.signal?.aborted) throw new Error("URL validation was aborted.");
2985
- const validation = Promise.resolve(validator(url, context));
3001
+ if (signal.aborted) throw new Error("URL validation was aborted.");
3002
+ const validation = Promise.resolve(validator(url, context, signal));
2986
3003
  let timer;
2987
3004
  let abortHandler;
2988
3005
  const cancellation = new Promise((_resolve, reject) => {
2989
3006
  abortHandler = () => reject(new Error("URL validation was aborted."));
2990
- options.signal?.addEventListener("abort", abortHandler, { once: true });
3007
+ signal.addEventListener("abort", abortHandler, { once: true });
2991
3008
  if (options.timeoutMs !== void 0 && options.timeoutMs > 0) {
2992
3009
  timer = setTimeout(
2993
3010
  () => reject(new Error(`URL validation timed out after ${options.timeoutMs} ms.`)),
@@ -2997,24 +3014,24 @@ function createAzureUrlValidatorRunner(validator, options = {}) {
2997
3014
  });
2998
3015
  try {
2999
3016
  const result = await (timer || abortHandler ? Promise.race([validation, cancellation]) : validation);
3000
- cache.set(url, result);
3017
+ cache.set(key, result);
3001
3018
  return result;
3002
3019
  } finally {
3003
3020
  if (timer) clearTimeout(timer);
3004
- if (abortHandler) options.signal?.removeEventListener("abort", abortHandler);
3021
+ if (abortHandler) signal.removeEventListener("abort", abortHandler);
3005
3022
  }
3006
3023
  } finally {
3007
3024
  release();
3008
3025
  }
3009
3026
  })();
3010
- inFlight.set(url, promise);
3027
+ inFlight.set(key, promise);
3011
3028
  try {
3012
3029
  return await promise;
3013
3030
  } finally {
3014
- inFlight.delete(url);
3031
+ inFlight.delete(key);
3015
3032
  }
3016
3033
  };
3017
- return (url, context) => check(url, context);
3034
+ return (url, context, signal) => check(url, context, signal ?? configuredSignal);
3018
3035
  }
3019
3036
  var ALLOWED_BREAK_STRENGTHS = /* @__PURE__ */ new Set(["none", "x-weak", "weak", "medium", "strong", "x-strong"]);
3020
3037
  var ALLOWED_SAY_AS = /* @__PURE__ */ new Set([
@@ -3127,6 +3144,7 @@ function tokenizeElements(source) {
3127
3144
  if (parent) parent.childElementCount += 1;
3128
3145
  const parentVoiceName = [...openElements].reverse().find((element) => element.voiceName)?.voiceName;
3129
3146
  const tokenName = nameMatch[1];
3147
+ const path = parent ? [...parent.path, `${tokenName}[${childElementIndex ?? 0}]`] : [tokenName];
3130
3148
  const tokenVoiceName = tokenName.toLowerCase() === "voice" ? attributes.get("name") : tokenName.toLowerCase() === "mstts:turn" ? attributes.get("voice") ?? parentVoiceName : parentVoiceName;
3131
3149
  tokens.push({
3132
3150
  attributes,
@@ -3137,12 +3155,14 @@ function tokenizeElements(source) {
3137
3155
  parentName: parent?.name,
3138
3156
  parentVoiceName,
3139
3157
  selfClosing,
3140
- start
3158
+ start,
3159
+ path
3141
3160
  });
3142
3161
  if (!selfClosing) {
3143
3162
  openElements.push({
3144
3163
  childElementCount: 0,
3145
3164
  name: tokenName,
3165
+ path,
3146
3166
  voiceName: tokenVoiceName
3147
3167
  });
3148
3168
  }
@@ -3155,13 +3175,14 @@ function location(source, offset) {
3155
3175
  const line = before.split("\n").length;
3156
3176
  return { line, column: before.length - (before.lastIndexOf("\n") + 1) + 1 };
3157
3177
  }
3158
- function addDiagnostic(diagnostics, source, offset, message, severity = "error", code2) {
3178
+ function addDiagnostic(diagnostics, source, offset, message, severity = "error", code2, metadata = {}) {
3159
3179
  diagnostics.push({
3160
3180
  ...location(source, offset),
3161
3181
  message,
3162
3182
  severity,
3163
3183
  source: "ssml-static-validator",
3164
- ...code2 ? { code: code2 } : {}
3184
+ ...code2 ? { code: code2 } : {},
3185
+ ...metadata
3165
3186
  });
3166
3187
  }
3167
3188
  function isSupportedProsodyRate(value) {
@@ -3624,9 +3645,11 @@ function validateAzureSsmlStatic(ssml, options = {}) {
3624
3645
  for (const token of tokens) {
3625
3646
  const tokenName = token.name.toLowerCase();
3626
3647
  const tokenVoiceName = tokenName === "voice" ? attr(token, "name")?.trim() : tokenName === "mstts:turn" ? attr(token, "voice")?.trim() || token.parentVoiceName : options.validateNestedVoices === false ? voiceName : token.parentVoiceName;
3648
+ const tokenDiagnosticStart = diagnostics.length;
3627
3649
  validateElement(token, ssml, diagnostics, tokenVoiceName, options, voiceCatalog);
3628
3650
  const definition = tokenVoiceName ? voiceCatalog.get(tokenVoiceName.toLowerCase()) : void 0;
3629
3651
  validateVoiceFeatureMatrix(token, ssml, diagnostics, tokenVoiceName, definition);
3652
+ annotateTokenDiagnostics(diagnostics, tokenDiagnosticStart, token, options, tokenVoiceName);
3630
3653
  if (tokenName === "voice" && options.model && definition?.models && !definition.models.some((model) => model.toLowerCase() === options.model?.toLowerCase())) {
3631
3654
  addDiagnostic(
3632
3655
  diagnostics,
@@ -3648,18 +3671,37 @@ function urlAttributes(token) {
3648
3671
  return value === void 0 ? [] : [{ attribute, value }];
3649
3672
  });
3650
3673
  }
3674
+ function annotateTokenDiagnostics(diagnostics, startIndex, token, options, voiceName) {
3675
+ const attributes = [...token.attributes.keys()];
3676
+ for (const diagnostic of diagnostics.slice(startIndex)) {
3677
+ const attributeName = attributes.find(
3678
+ (attribute) => new RegExp(`(?:<[^> ]+\\s+|")${attribute}(?:"|>|\\s)`, "i").test(diagnostic.message)
3679
+ );
3680
+ const nodePath = options.sourceNodePath ? [...options.sourceNodePath] : [...token.path];
3681
+ Object.assign(diagnostic, {
3682
+ range: { start: token.start, end: token.end + 1 },
3683
+ tagName: token.name,
3684
+ ...attributeName ? { attributeName } : {},
3685
+ ...voiceName ? { voiceName } : {},
3686
+ ...options.chunkIndex !== void 0 ? { chunkIndex: options.chunkIndex } : {},
3687
+ nodePath,
3688
+ targetNodePath: [...token.path]
3689
+ });
3690
+ }
3691
+ }
3651
3692
  function validateAzureSsml(ssml, options = {}) {
3652
3693
  const diagnostics = validateAzureSsmlStatic(ssml, options);
3653
3694
  const validator = options.urlValidator ?? options.customUrlValidator;
3654
3695
  if (!validator || typeof ssml !== "string") return diagnostics;
3655
3696
  const runnerOptions = options.urlValidation ?? {};
3656
- const boundedValidator = createAzureUrlValidatorRunner(validator, {
3697
+ const boundedValidator = options.urlValidatorRunner ?? createAzureUrlValidatorRunner(validator, {
3657
3698
  ...runnerOptions,
3658
3699
  ...options.urlValidatorConcurrency !== void 0 ? { concurrency: options.urlValidatorConcurrency } : {},
3659
3700
  ...options.urlValidatorTimeoutMs !== void 0 ? { timeoutMs: options.urlValidatorTimeoutMs } : {},
3660
3701
  ...options.urlValidatorSignal ? { signal: options.urlValidatorSignal } : {},
3661
3702
  ...options.urlValidatorCache ? { cache: options.urlValidatorCache } : {}
3662
3703
  });
3704
+ const validationSignal = options.urlValidatorSignal ?? options.urlValidation?.signal ?? new AbortController().signal;
3663
3705
  let tokens;
3664
3706
  try {
3665
3707
  tokens = tokenizeElements(ssml);
@@ -3669,25 +3711,33 @@ function validateAzureSsml(ssml, options = {}) {
3669
3711
  const checks = tokens.flatMap(
3670
3712
  (token) => urlAttributes(token).map(async ({ attribute, value }) => {
3671
3713
  try {
3672
- const result = await boundedValidator(value, { tag: token.name, attribute });
3714
+ const result = await boundedValidator(
3715
+ value,
3716
+ { tag: token.name, attribute, ...options.sourceNodePath ? { sourceNodePath: options.sourceNodePath } : {} },
3717
+ validationSignal
3718
+ );
3673
3719
  const valid = typeof result === "boolean" ? result : result.valid;
3674
3720
  if (!valid) {
3675
3721
  const reason = typeof result === "boolean" ? void 0 : result.reason;
3722
+ const diagnosticStart = diagnostics.length;
3676
3723
  addDiagnostic(
3677
3724
  diagnostics,
3678
3725
  ssml,
3679
3726
  token.start,
3680
3727
  `<${token.name} ${attribute}> was rejected by the custom URL validator${reason ? `: ${reason}` : "."}`
3681
3728
  );
3729
+ annotateTokenDiagnostics(diagnostics, diagnosticStart, token, options, token.parentVoiceName);
3682
3730
  }
3683
3731
  } catch (error) {
3684
3732
  const reason = error instanceof Error ? error.message : String(error);
3733
+ const diagnosticStart = diagnostics.length;
3685
3734
  addDiagnostic(
3686
3735
  diagnostics,
3687
3736
  ssml,
3688
3737
  token.start,
3689
3738
  `<${token.name} ${attribute}> could not be validated by the custom URL validator: ${reason}`
3690
3739
  );
3740
+ annotateTokenDiagnostics(diagnostics, diagnosticStart, token, options, token.parentVoiceName);
3691
3741
  }
3692
3742
  })
3693
3743
  );
@@ -6841,6 +6891,40 @@ function VoiceCapabilityMatrix({
6841
6891
  const status = voice.status ?? (voice.preview ? "preview" : void 0);
6842
6892
  return /* @__PURE__ */ React.createElement("div", { className: "ssml-editor-voice-capabilities", "data-voice-capabilities": "" }, /* @__PURE__ */ React.createElement("div", null, locale === "ja" ? "\u30B9\u30C6\u30FC\u30BF\u30B9" : "Status", ": ", status?.toUpperCase() ?? (locale === "ja" ? "GA" : "GA"), status === "preview" || status === "deprecated" ? /* @__PURE__ */ React.createElement("span", { role: "status", "aria-label": status, className: "ssml-editor-voice-warning-badge" }, status === "preview" ? "\u26A0 Preview" : "\u26A0 Deprecated") : null), (voice.regions?.length || voice.region) && /* @__PURE__ */ React.createElement("div", null, locale === "ja" ? "\u30EA\u30FC\u30B8\u30E7\u30F3" : "Regions", ":", " ", [...voice.regions ?? [], ...voice.region ? [voice.region] : []].filter((region, index, all) => all.indexOf(region) === index).join(", ")), voice.supportedTags && voice.supportedTags.length > 0 && /* @__PURE__ */ React.createElement("div", null, locale === "ja" ? "\u5BFE\u5FDC\u30BF\u30B0" : "Supported tags", ": ", voice.supportedTags.join(", ")), voice.unsupportedTags && voice.unsupportedTags.length > 0 && /* @__PURE__ */ React.createElement("div", { className: "ssml-editor-voice-unsupported" }, locale === "ja" ? "\u975E\u5BFE\u5FDC\u30BF\u30B0" : "Unsupported tags", ": ", voice.unsupportedTags.join(", ")));
6843
6893
  }
6894
+ function diagnosticMatchesElement(diagnostic, element) {
6895
+ const name = elementLabel(element).toLowerCase().replace("expressas", "mstts:express-as");
6896
+ if (diagnostic.code === "azure-unsupported-style") return name === "mstts:express-as" || name === "express-as";
6897
+ if (diagnostic.code === "azure-unsupported-tag-for-voice") {
6898
+ return diagnostic.message.toLowerCase().includes(`<${name}>`) || diagnostic.message.toLowerCase().includes(`<${name.replace("mstts:", "")}>`);
6899
+ }
6900
+ if (diagnostic.code === "azure-locale-mismatch" || diagnostic.code === "azure-unsupported-model-for-voice")
6901
+ return name === "voice" || name === "mstts:turn";
6902
+ return false;
6903
+ }
6904
+ function elementWarnings(diagnostics, element) {
6905
+ return diagnostics.filter((diagnostic) => diagnosticMatchesElement(diagnostic, element));
6906
+ }
6907
+ function fieldWarnings(diagnostics, element, field) {
6908
+ return elementWarnings(diagnostics, element).filter((diagnostic) => {
6909
+ if (diagnostic.code === "azure-unsupported-style") return field.key === "style";
6910
+ return field.key === "name" || field.key === "voice";
6911
+ });
6912
+ }
6913
+ function WarningBadge({ messages }) {
6914
+ if (messages.length === 0) return null;
6915
+ return /* @__PURE__ */ React.createElement(
6916
+ "span",
6917
+ {
6918
+ role: "status",
6919
+ "aria-label": messages.map((message) => message.message).join(" "),
6920
+ title: messages.map((message) => message.message).join(" "),
6921
+ "data-ssml-warning-badge": "",
6922
+ "data-testid": "ssml-editor-warning-badge",
6923
+ className: "ssml-editor-warning-badge"
6924
+ },
6925
+ "\u26A0"
6926
+ );
6927
+ }
6844
6928
  function DefaultVoiceSelector({
6845
6929
  value,
6846
6930
  voices,
@@ -6873,7 +6957,8 @@ function VisualElementInspector({
6873
6957
  voiceCatalog,
6874
6958
  voiceLocale,
6875
6959
  voiceRegion,
6876
- voiceStyle
6960
+ voiceStyle,
6961
+ diagnostics
6877
6962
  }) {
6878
6963
  if (customInspector) {
6879
6964
  return /* @__PURE__ */ React.createElement(React.Fragment, null, customInspector({ document: document2, element, path, readOnly, onChange: commit, locale }));
@@ -6884,7 +6969,7 @@ function VisualElementInspector({
6884
6969
  (voice) => voice.name === (element.type === "voice" ? element.name : void 0)
6885
6970
  );
6886
6971
  const renderSelector = renderVoiceSelector ?? DefaultVoiceSelector;
6887
- return /* @__PURE__ */ React.createElement("fieldset", null, /* @__PURE__ */ React.createElement("legend", null, `<${elementLabel(element)}>`), fields.length === 0 ? /* @__PURE__ */ React.createElement("p", null, "This element is preserved in the visual tree. Edit its attributes in Code mode.") : fields.map((field) => {
6972
+ return /* @__PURE__ */ React.createElement("fieldset", null, /* @__PURE__ */ React.createElement("legend", null, `<${elementLabel(element)}>`, " ", /* @__PURE__ */ React.createElement(WarningBadge, { messages: elementWarnings(diagnostics, element) })), fields.length === 0 ? /* @__PURE__ */ React.createElement("p", null, "This element is preserved in the visual tree. Edit its attributes in Code mode.") : fields.map((field) => {
6888
6973
  const value = element[field.key];
6889
6974
  const inputValue = value === void 0 ? "" : String(value);
6890
6975
  const inputId = `ssml-visual-${field.key}`;
@@ -6921,7 +7006,7 @@ function VisualElementInspector({
6921
7006
  speakerProfileId: "\u8A71\u8005\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB ID",
6922
7007
  url: "\u97F3\u58F0\u5909\u63DB URL",
6923
7008
  profile: "\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB"
6924
- }[field.key] ?? field.label : field.label, field.key === "name" && elementLabel(element) === "voice" && voiceCatalog ? renderSelector({
7009
+ }[field.key] ?? field.label : field.label, /* @__PURE__ */ React.createElement(WarningBadge, { messages: fieldWarnings(diagnostics, element, field) }), field.key === "name" && elementLabel(element) === "voice" && voiceCatalog ? renderSelector({
6925
7010
  value: inputValue,
6926
7011
  voices: availableVoices,
6927
7012
  selectedVoice,
@@ -6999,19 +7084,21 @@ function TreeNode({
6999
7084
  node,
7000
7085
  path,
7001
7086
  selectedPath,
7002
- onSelect
7087
+ onSelect,
7088
+ getWarnings
7003
7089
  }) {
7004
7090
  if (!isElement(node)) return null;
7005
7091
  const name = elementLabel(node);
7006
7092
  const isSelected = selectedPath?.join(".") === path.join(".");
7007
- return /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement("button", { type: "button", "aria-current": isSelected ? "true" : void 0, onClick: () => onSelect(path) }, `<${name}>`), (node.children ?? []).length > 0 && /* @__PURE__ */ React.createElement("ul", null, node.children?.map((child, index) => /* @__PURE__ */ React.createElement(
7093
+ return /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement("button", { type: "button", "aria-current": isSelected ? "true" : void 0, onClick: () => onSelect(path) }, `<${name}>`, /* @__PURE__ */ React.createElement(WarningBadge, { messages: getWarnings(node) })), (node.children ?? []).length > 0 && /* @__PURE__ */ React.createElement("ul", null, node.children?.map((child, index) => /* @__PURE__ */ React.createElement(
7008
7094
  TreeNode,
7009
7095
  {
7010
7096
  key: `${path.join(".")}/${isElement(child) ? elementLabel(child) : JSON.stringify(child)}`,
7011
7097
  node: child,
7012
7098
  path: [...path, index],
7013
7099
  selectedPath,
7014
- onSelect
7100
+ onSelect,
7101
+ getWarnings
7015
7102
  }
7016
7103
  ))));
7017
7104
  }
@@ -7026,7 +7113,9 @@ function VisualSsmlEditor({
7026
7113
  voiceCatalog,
7027
7114
  voiceLocale,
7028
7115
  voiceRegion,
7029
- voiceStyle
7116
+ voiceStyle,
7117
+ voiceModel,
7118
+ model
7030
7119
  }) {
7031
7120
  const [selectedPath, setSelectedPath] = (0, import_react3.useState)(null);
7032
7121
  const [selection, setSelection] = (0, import_react3.useState)({ start: 0, end: 0 });
@@ -7034,7 +7123,27 @@ function VisualSsmlEditor({
7034
7123
  const selectedLeaf = textLeaves.find((leaf) => leaf.path.join(".") === selectedPath?.join(".")) ?? textLeaves[0];
7035
7124
  const selectedElement = selectedPath ? getNodeAtPath(document2.children ?? [], selectedPath) : void 0;
7036
7125
  const selectedCustomInspector = selectedElement && isElement(selectedElement) ? customInspectors?.[elementLabel(selectedElement)] ?? customInspectors?.[selectedElement.type] : void 0;
7037
- const diagnostics = (0, import_react3.useMemo)(() => validateAzureSsml(buildSsml(document2)), [document2]);
7126
+ const validationOptions = (0, import_react3.useMemo)(
7127
+ () => ({
7128
+ model: voiceModel ?? model,
7129
+ customVoiceDefinitions: voiceCatalog?.map((voice) => ({
7130
+ name: voice.name,
7131
+ locale: voice.locale,
7132
+ regions: voice.regions ?? (voice.region ? [voice.region] : void 0),
7133
+ styles: voice.styles,
7134
+ supportedTags: voice.supportedTags,
7135
+ unsupportedTags: voice.unsupportedTags,
7136
+ models: voice.models,
7137
+ status: voice.status ?? (voice.preview ? "preview" : "ga")
7138
+ }))
7139
+ }),
7140
+ [model, voiceCatalog, voiceModel]
7141
+ );
7142
+ const diagnostics = (0, import_react3.useMemo)(
7143
+ () => validateAzureSsml(buildSsml(document2), validationOptions),
7144
+ [document2, validationOptions]
7145
+ );
7146
+ const getWarnings = (element) => elementWarnings(diagnostics, element);
7038
7147
  const commit = (nextDocument) => onChange?.(nextDocument);
7039
7148
  const applyWrapper = (tag, attributes) => {
7040
7149
  if (readOnly || !selectedLeaf) return;
@@ -7049,7 +7158,8 @@ function VisualSsmlEditor({
7049
7158
  node,
7050
7159
  path: [index],
7051
7160
  selectedPath,
7052
- onSelect: setSelectedPath
7161
+ onSelect: setSelectedPath,
7162
+ getWarnings
7053
7163
  }
7054
7164
  )))), /* @__PURE__ */ React.createElement("div", { className: "ssml-editor-visual-form" }, selectedCustomInspector && selectedElement && isElement(selectedElement) ? selectedCustomInspector({
7055
7165
  document: document2,
@@ -7066,7 +7176,7 @@ function VisualSsmlEditor({
7066
7176
  onClick: () => commit(addDialogTurn(document2, selectedPath ?? []))
7067
7177
  },
7068
7178
  locale === "ja" ? "\u30BF\u30FC\u30F3\u3092\u8FFD\u52A0" : "Add turn"
7069
- )) : selectedElement && isElement(selectedElement) && selectedElement.type === "mstts:turn" ? /* @__PURE__ */ React.createElement("fieldset", null, /* @__PURE__ */ React.createElement("legend", null, localizedElementLabel(selectedElement, locale)), /* @__PURE__ */ React.createElement("label", { htmlFor: "ssml-visual-turn-voice" }, locale === "ja" ? "\u97F3\u58F0" : "Voice", voiceCatalog ? (renderVoiceSelector ?? DefaultVoiceSelector)({
7179
+ )) : selectedElement && isElement(selectedElement) && selectedElement.type === "mstts:turn" ? /* @__PURE__ */ React.createElement("fieldset", null, /* @__PURE__ */ React.createElement("legend", null, localizedElementLabel(selectedElement, locale)), /* @__PURE__ */ React.createElement("label", { htmlFor: "ssml-visual-turn-voice" }, locale === "ja" ? "\u97F3\u58F0" : "Voice", /* @__PURE__ */ React.createElement(WarningBadge, { messages: elementWarnings(diagnostics, selectedElement) }), voiceCatalog ? (renderVoiceSelector ?? DefaultVoiceSelector)({
7070
7180
  value: selectedElement.voice ?? "",
7071
7181
  voices: filteredVoices(voiceCatalog, voiceLocale, voiceRegion, voiceStyle),
7072
7182
  selectedVoice: voiceCatalog?.find((voice) => voice.name === selectedElement.voice),
@@ -7143,7 +7253,8 @@ function VisualSsmlEditor({
7143
7253
  voiceCatalog,
7144
7254
  voiceLocale,
7145
7255
  voiceRegion,
7146
- voiceStyle
7256
+ voiceStyle,
7257
+ diagnostics
7147
7258
  }
7148
7259
  ) : selectedLeaf ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("label", null, "Text", /* @__PURE__ */ React.createElement(
7149
7260
  "textarea",
@@ -7767,6 +7878,8 @@ var SsmlEditor = (0, import_react4.forwardRef)(function SsmlEditor2({
7767
7878
  voiceLocale,
7768
7879
  voiceRegion,
7769
7880
  voiceStyle,
7881
+ voiceModel,
7882
+ model,
7770
7883
  emotionStyles,
7771
7884
  className,
7772
7885
  style,
@@ -8165,7 +8278,9 @@ var SsmlEditor = (0, import_react4.forwardRef)(function SsmlEditor2({
8165
8278
  voiceCatalog,
8166
8279
  voiceLocale,
8167
8280
  voiceRegion,
8168
- voiceStyle
8281
+ voiceStyle,
8282
+ voiceModel,
8283
+ model
8169
8284
  }
8170
8285
  )) : /* @__PURE__ */ React.createElement("div", { style: { ...editorStyles.editor, minHeight: editorMinHeight } }, /* @__PURE__ */ React.createElement(
8171
8286
  import_react5.default,