@mdaemon/html-editor 1.2.1 → 1.4.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/index.js CHANGED
@@ -23057,6 +23057,96 @@ var StarterKit = Extension.create({
23057
23057
  return extensions;
23058
23058
  }
23059
23059
  });
23060
+ var Subscript = Mark2.create({
23061
+ name: "subscript",
23062
+ addOptions() {
23063
+ return {
23064
+ HTMLAttributes: {}
23065
+ };
23066
+ },
23067
+ parseHTML() {
23068
+ return [
23069
+ {
23070
+ tag: "sub"
23071
+ },
23072
+ {
23073
+ style: "vertical-align",
23074
+ getAttrs(value) {
23075
+ if (value !== "sub") {
23076
+ return false;
23077
+ }
23078
+ return null;
23079
+ }
23080
+ }
23081
+ ];
23082
+ },
23083
+ renderHTML({ HTMLAttributes }) {
23084
+ return ["sub", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
23085
+ },
23086
+ addCommands() {
23087
+ return {
23088
+ setSubscript: () => ({ commands }) => {
23089
+ return commands.setMark(this.name);
23090
+ },
23091
+ toggleSubscript: () => ({ commands }) => {
23092
+ return commands.toggleMark(this.name);
23093
+ },
23094
+ unsetSubscript: () => ({ commands }) => {
23095
+ return commands.unsetMark(this.name);
23096
+ }
23097
+ };
23098
+ },
23099
+ addKeyboardShortcuts() {
23100
+ return {
23101
+ "Mod-,": () => this.editor.commands.toggleSubscript()
23102
+ };
23103
+ }
23104
+ });
23105
+ var Superscript = Mark2.create({
23106
+ name: "superscript",
23107
+ addOptions() {
23108
+ return {
23109
+ HTMLAttributes: {}
23110
+ };
23111
+ },
23112
+ parseHTML() {
23113
+ return [
23114
+ {
23115
+ tag: "sup"
23116
+ },
23117
+ {
23118
+ style: "vertical-align",
23119
+ getAttrs(value) {
23120
+ if (value !== "super") {
23121
+ return false;
23122
+ }
23123
+ return null;
23124
+ }
23125
+ }
23126
+ ];
23127
+ },
23128
+ renderHTML({ HTMLAttributes }) {
23129
+ return ["sup", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
23130
+ },
23131
+ addCommands() {
23132
+ return {
23133
+ setSuperscript: () => ({ commands }) => {
23134
+ return commands.setMark(this.name);
23135
+ },
23136
+ toggleSuperscript: () => ({ commands }) => {
23137
+ return commands.toggleMark(this.name);
23138
+ },
23139
+ unsetSuperscript: () => ({ commands }) => {
23140
+ return commands.unsetMark(this.name);
23141
+ }
23142
+ };
23143
+ },
23144
+ addKeyboardShortcuts() {
23145
+ return {
23146
+ "Mod-.": () => this.editor.commands.toggleSuperscript()
23147
+ };
23148
+ }
23149
+ });
23060
23150
  var TextAlign = Extension.create({
23061
23151
  name: "textAlign",
23062
23152
  addOptions() {
@@ -41871,7 +41961,22 @@ class EmojiPicker {
41871
41961
  }
41872
41962
  }
41873
41963
  const DEFAULT_MAX_FILE_SIZE = 10 * 1024 * 1024;
41874
- const ACCEPTED_IMAGE_TYPES = ["image/jpeg", "image/png", "image/gif", "image/webp", "image/svg+xml"];
41964
+ const ACCEPTED_IMAGE_TYPES = ["image/jpeg", "image/png", "image/gif", "image/webp", "image/svg+xml", "image/bmp"];
41965
+ const EXT_TO_MIME = {
41966
+ jpg: "image/jpeg",
41967
+ jpeg: "image/jpeg",
41968
+ jpe: "image/jpeg",
41969
+ png: "image/png",
41970
+ gif: "image/gif",
41971
+ bmp: "image/bmp",
41972
+ webp: "image/webp",
41973
+ svg: "image/svg+xml"
41974
+ };
41975
+ function parseImageFileTypes(spec) {
41976
+ if (!spec) return null;
41977
+ const exts = spec.split(/[\s,|]+/).map((s) => s.trim().toLowerCase().replace(/^\./, "")).filter(Boolean);
41978
+ return exts.length > 0 ? exts : null;
41979
+ }
41875
41980
  const SVG_DANGEROUS_TAGS = [
41876
41981
  "script",
41877
41982
  "foreignobject",
@@ -42146,16 +42251,44 @@ class ImageUpload {
42146
42251
  errorEl.textContent = "";
42147
42252
  }
42148
42253
  }
42149
- handleFileSelected(file) {
42150
- this.clearError();
42254
+ /** Whether the file matches the configured/default accepted image types. */
42255
+ isAcceptedType(file) {
42256
+ const exts = parseImageFileTypes(this.options.fileTypes);
42257
+ if (!exts) {
42258
+ return ACCEPTED_IMAGE_TYPES.includes(file.type);
42259
+ }
42260
+ const name = (file.name ?? "").toLowerCase();
42261
+ const dot = name.lastIndexOf(".");
42262
+ const ext = dot >= 0 ? name.slice(dot + 1) : "";
42263
+ if (ext && exts.includes(ext)) return true;
42264
+ const acceptedMimes = exts.map((e) => EXT_TO_MIME[e]).filter(Boolean);
42265
+ return !!file.type && acceptedMimes.includes(file.type);
42266
+ }
42267
+ /**
42268
+ * Validate a file before upload. Returns an error message (translated) to
42269
+ * reject, or null to allow. Runs the caller's validate hook, then the
42270
+ * type and size guards.
42271
+ */
42272
+ validateFile(file) {
42151
42273
  const t = this.options.trans;
42152
- if (!ACCEPTED_IMAGE_TYPES.includes(file.type)) {
42153
- this.showError(t("Invalid file type"));
42154
- return;
42274
+ if (this.options.validate) {
42275
+ const msg = this.options.validate(file);
42276
+ if (msg) return msg;
42277
+ }
42278
+ if (!this.isAcceptedType(file)) {
42279
+ return t("Invalid file type");
42155
42280
  }
42156
42281
  const maxSize = this.options.uploadMaxSize ?? DEFAULT_MAX_FILE_SIZE;
42157
42282
  if (file.size > maxSize) {
42158
- this.showError(t("File too large"));
42283
+ return t("File too large");
42284
+ }
42285
+ return null;
42286
+ }
42287
+ handleFileSelected(file) {
42288
+ this.clearError();
42289
+ const validationError = this.validateFile(file);
42290
+ if (validationError) {
42291
+ this.showError(validationError);
42159
42292
  return;
42160
42293
  }
42161
42294
  this.currentFile = file;
@@ -42242,16 +42375,14 @@ class ImageUpload {
42242
42375
  this.options.onInsert(src, alt);
42243
42376
  this.close();
42244
42377
  } catch (err) {
42245
- this.showError(this.options.trans("Upload failed"));
42378
+ const message = err instanceof Error && err.message ? err.message : this.options.trans("Upload failed");
42379
+ this.showError(message);
42246
42380
  }
42247
42381
  }
42248
42382
  uploadFile(file) {
42249
- if (!ACCEPTED_IMAGE_TYPES.includes(file.type)) {
42250
- return Promise.reject(new Error("Invalid file type"));
42251
- }
42252
- const maxSize = this.options.uploadMaxSize ?? DEFAULT_MAX_FILE_SIZE;
42253
- if (file.size > maxSize) {
42254
- return Promise.reject(new Error("File too large"));
42383
+ const validationError = this.validateFile(file);
42384
+ if (validationError) {
42385
+ return Promise.reject(new Error(validationError));
42255
42386
  }
42256
42387
  if (file.type === "image/svg+xml") {
42257
42388
  return this.sanitizeAndUploadSVG(file);
@@ -42887,6 +43018,687 @@ class LinkEditor {
42887
43018
  }
42888
43019
  }
42889
43020
  }
43021
+ class AnchorDialog {
43022
+ options;
43023
+ overlay = null;
43024
+ dialog = null;
43025
+ nameInput = null;
43026
+ errorEl = null;
43027
+ constructor(options) {
43028
+ this.options = options;
43029
+ }
43030
+ get tiptap() {
43031
+ return this.options.editor.getTipTap();
43032
+ }
43033
+ open() {
43034
+ if (!this.overlay) {
43035
+ this.createDialog();
43036
+ }
43037
+ if (this.nameInput) this.nameInput.value = "";
43038
+ this.clearError();
43039
+ this.overlay.style.display = "flex";
43040
+ this.nameInput?.focus();
43041
+ }
43042
+ close() {
43043
+ if (this.overlay) {
43044
+ this.overlay.style.display = "none";
43045
+ }
43046
+ }
43047
+ clearError() {
43048
+ if (this.errorEl) {
43049
+ this.errorEl.style.display = "none";
43050
+ this.errorEl.textContent = "";
43051
+ }
43052
+ }
43053
+ showError(message) {
43054
+ if (this.errorEl) {
43055
+ this.errorEl.textContent = message;
43056
+ this.errorEl.style.display = "block";
43057
+ }
43058
+ }
43059
+ save() {
43060
+ const trans = this.options.trans;
43061
+ const name = this.nameInput?.value.trim() ?? "";
43062
+ if (!name) {
43063
+ this.showError(trans("Anchor name is required"));
43064
+ return;
43065
+ }
43066
+ if (/\s/.test(name)) {
43067
+ this.showError(trans("Anchor name cannot contain spaces"));
43068
+ return;
43069
+ }
43070
+ this.tiptap?.chain().focus().insertContent({ type: "anchor", attrs: { id: name, name } }).run();
43071
+ this.close();
43072
+ }
43073
+ createDialog() {
43074
+ const trans = this.options.trans;
43075
+ const skin = this.options.editor.getConfig().skin ?? "oxide";
43076
+ this.overlay = document.createElement("div");
43077
+ this.overlay.className = "md-dialog-overlay";
43078
+ this.overlay.addEventListener("click", (e) => {
43079
+ if (e.target === this.overlay) {
43080
+ this.close();
43081
+ }
43082
+ });
43083
+ const themeWrapper = document.createElement("div");
43084
+ themeWrapper.className = `md-editor-${skin}`;
43085
+ themeWrapper.style.display = "contents";
43086
+ this.dialog = document.createElement("div");
43087
+ this.dialog.className = "md-dialog md-anchor-dialog";
43088
+ const header = document.createElement("div");
43089
+ header.className = "md-dialog-header";
43090
+ header.innerHTML = `
43091
+ <h3>${trans("Insert anchor")}</h3>
43092
+ <button type="button" class="md-dialog-close">×</button>
43093
+ `;
43094
+ header.querySelector(".md-dialog-close")?.addEventListener("click", () => this.close());
43095
+ const body = document.createElement("div");
43096
+ body.className = "md-dialog-body";
43097
+ const nameRow = document.createElement("div");
43098
+ nameRow.className = "md-anchor-dialog-row";
43099
+ nameRow.innerHTML = `<label>${trans("Anchor name")}</label>`;
43100
+ this.nameInput = document.createElement("input");
43101
+ this.nameInput.type = "text";
43102
+ this.nameInput.className = "md-anchor-dialog-input";
43103
+ nameRow.appendChild(this.nameInput);
43104
+ this.errorEl = document.createElement("div");
43105
+ this.errorEl.className = "md-anchor-dialog-error";
43106
+ this.errorEl.style.display = "none";
43107
+ const footer = document.createElement("div");
43108
+ footer.className = "md-anchor-dialog-footer";
43109
+ footer.innerHTML = `
43110
+ <button type="button" class="md-btn md-anchor-dialog-cancel">${trans("Cancel")}</button>
43111
+ <button type="button" class="md-btn md-btn-primary md-anchor-dialog-save">${trans("Save")}</button>
43112
+ `;
43113
+ footer.querySelector(".md-anchor-dialog-cancel")?.addEventListener("click", () => this.close());
43114
+ footer.querySelector(".md-anchor-dialog-save")?.addEventListener("click", () => this.save());
43115
+ body.appendChild(nameRow);
43116
+ body.appendChild(this.errorEl);
43117
+ body.appendChild(footer);
43118
+ this.dialog.appendChild(header);
43119
+ this.dialog.appendChild(body);
43120
+ themeWrapper.appendChild(this.dialog);
43121
+ this.overlay.appendChild(themeWrapper);
43122
+ this.overlay.addEventListener("keydown", (e) => {
43123
+ if (e.key === "Escape") {
43124
+ this.close();
43125
+ } else if (e.key === "Enter") {
43126
+ this.save();
43127
+ }
43128
+ });
43129
+ document.body.appendChild(this.overlay);
43130
+ }
43131
+ destroy() {
43132
+ if (this.overlay) {
43133
+ this.overlay.remove();
43134
+ this.overlay = null;
43135
+ this.dialog = null;
43136
+ this.nameInput = null;
43137
+ this.errorEl = null;
43138
+ }
43139
+ }
43140
+ }
43141
+ const SPEECH_LANGUAGES = [
43142
+ { code: "ar-SA", name: "العربية" },
43143
+ { code: "ca-ES", name: "Català" },
43144
+ { code: "cs-CZ", name: "Čeština" },
43145
+ { code: "da-DK", name: "Dansk" },
43146
+ { code: "de-DE", name: "Deutsch" },
43147
+ { code: "el-GR", name: "Ελληνικά" },
43148
+ { code: "en-US", name: "English (US)" },
43149
+ { code: "en-GB", name: "English (UK)" },
43150
+ { code: "es-ES", name: "Español" },
43151
+ { code: "fi-FI", name: "Suomi" },
43152
+ { code: "fr-FR", name: "Français" },
43153
+ { code: "fr-CA", name: "Français (Canada)" },
43154
+ { code: "hu-HU", name: "Magyar" },
43155
+ { code: "id-ID", name: "Bahasa Indonesia" },
43156
+ { code: "it-IT", name: "Italiano" },
43157
+ { code: "ja-JP", name: "日本語" },
43158
+ { code: "ko-KR", name: "한국어" },
43159
+ { code: "nb-NO", name: "Norsk Bokmål" },
43160
+ { code: "nl-NL", name: "Nederlands" },
43161
+ { code: "pl-PL", name: "Polski" },
43162
+ { code: "pt-BR", name: "Português" },
43163
+ { code: "ro-RO", name: "Română" },
43164
+ { code: "ru-RU", name: "Русский" },
43165
+ { code: "sl-SI", name: "Slovenščina" },
43166
+ { code: "sr-RS", name: "Српски" },
43167
+ { code: "sv-SE", name: "Svenska" },
43168
+ { code: "th-TH", name: "ไทย" },
43169
+ { code: "tr-TR", name: "Türkçe" },
43170
+ { code: "vi-VN", name: "Tiếng Việt" },
43171
+ { code: "zh-CN", name: "中文 (简体)" },
43172
+ { code: "zh-TW", name: "中文 (繁體)" }
43173
+ ];
43174
+ const LOCALE_TO_BCP47$1 = {
43175
+ "ar": "ar-SA",
43176
+ "ca": "ca-ES",
43177
+ "cs": "cs-CZ",
43178
+ "da": "da-DK",
43179
+ "de": "de-DE",
43180
+ "el": "el-GR",
43181
+ "en": "en-US",
43182
+ "en-gb": "en-GB",
43183
+ "es": "es-ES",
43184
+ "fi": "fi-FI",
43185
+ "fr": "fr-FR",
43186
+ "fr-ca": "fr-CA",
43187
+ "hu": "hu-HU",
43188
+ "id": "id-ID",
43189
+ "it": "it-IT",
43190
+ "ja": "ja-JP",
43191
+ "ko": "ko-KR",
43192
+ "nb": "nb-NO",
43193
+ "nl": "nl-NL",
43194
+ "pl": "pl-PL",
43195
+ "pt": "pt-BR",
43196
+ "ro": "ro-RO",
43197
+ "ru": "ru-RU",
43198
+ "sl": "sl-SI",
43199
+ "sr": "sr-RS",
43200
+ "sv": "sv-SE",
43201
+ "th": "th-TH",
43202
+ "tr": "tr-TR",
43203
+ "vi": "vi-VN",
43204
+ "zh": "zh-CN",
43205
+ "zh-tw": "zh-TW"
43206
+ };
43207
+ function isSpeechRecognitionSupported() {
43208
+ return !!(window.SpeechRecognition || window.webkitSpeechRecognition);
43209
+ }
43210
+ function getSpeechRecognitionConstructor$1() {
43211
+ return window.SpeechRecognition || window.webkitSpeechRecognition || null;
43212
+ }
43213
+ class SpeechToText {
43214
+ options;
43215
+ overlay = null;
43216
+ dialog = null;
43217
+ recognition = null;
43218
+ isListening = false;
43219
+ finalTranscript = "";
43220
+ interimTranscript = "";
43221
+ lastConfidence = 0;
43222
+ restartTimer = null;
43223
+ // DOM references
43224
+ transcriptArea = null;
43225
+ confidenceEl = null;
43226
+ statusEl = null;
43227
+ startStopBtn = null;
43228
+ insertBtn = null;
43229
+ clearBtn = null;
43230
+ languageSelect = null;
43231
+ constructor(options) {
43232
+ this.options = options;
43233
+ }
43234
+ open() {
43235
+ if (this.overlay) {
43236
+ this.overlay.style.display = "flex";
43237
+ return;
43238
+ }
43239
+ this.createDialog();
43240
+ }
43241
+ close() {
43242
+ if (this.overlay) {
43243
+ this.overlay.style.display = "none";
43244
+ }
43245
+ this.stopRecognition();
43246
+ }
43247
+ destroy() {
43248
+ this.stopRecognition();
43249
+ this.overlay?.remove();
43250
+ this.overlay = null;
43251
+ this.dialog = null;
43252
+ this.transcriptArea = null;
43253
+ this.confidenceEl = null;
43254
+ this.statusEl = null;
43255
+ this.startStopBtn = null;
43256
+ this.insertBtn = null;
43257
+ this.clearBtn = null;
43258
+ this.languageSelect = null;
43259
+ }
43260
+ get editorLanguage() {
43261
+ return this.options.editor.getConfig().language ?? "en";
43262
+ }
43263
+ getDefaultSpeechLang() {
43264
+ return LOCALE_TO_BCP47$1[this.editorLanguage] ?? "en-US";
43265
+ }
43266
+ createDialog() {
43267
+ const trans = this.options.trans;
43268
+ this.overlay = document.createElement("div");
43269
+ this.overlay.className = "md-dialog-overlay";
43270
+ this.overlay.addEventListener("click", (e) => {
43271
+ if (e.target === this.overlay) this.close();
43272
+ });
43273
+ this.dialog = document.createElement("div");
43274
+ this.dialog.className = "md-dialog md-speechtotext-dialog";
43275
+ const header = document.createElement("div");
43276
+ header.className = "md-dialog-header";
43277
+ header.innerHTML = `
43278
+ <h3>${trans("Speech to Text")}</h3>
43279
+ <button type="button" class="md-dialog-close">×</button>
43280
+ `;
43281
+ header.querySelector(".md-dialog-close").addEventListener("click", () => this.close());
43282
+ const body = document.createElement("div");
43283
+ body.className = "md-dialog-body md-speechtotext-body";
43284
+ const langRow = document.createElement("div");
43285
+ langRow.className = "md-speechtotext-lang-row";
43286
+ const langLabel = document.createElement("label");
43287
+ langLabel.className = "md-speechtotext-label";
43288
+ langLabel.textContent = trans("Language");
43289
+ this.languageSelect = document.createElement("select");
43290
+ this.languageSelect.className = "md-speechtotext-language";
43291
+ const defaultLang = this.getDefaultSpeechLang();
43292
+ for (const lang of SPEECH_LANGUAGES) {
43293
+ const opt = document.createElement("option");
43294
+ opt.value = lang.code;
43295
+ opt.textContent = lang.name;
43296
+ if (lang.code === defaultLang) opt.selected = true;
43297
+ this.languageSelect.appendChild(opt);
43298
+ }
43299
+ langRow.appendChild(langLabel);
43300
+ langRow.appendChild(this.languageSelect);
43301
+ this.statusEl = document.createElement("div");
43302
+ this.statusEl.className = "md-speechtotext-status";
43303
+ this.statusEl.textContent = "";
43304
+ this.transcriptArea = document.createElement("div");
43305
+ this.transcriptArea.className = "md-speechtotext-transcript";
43306
+ this.confidenceEl = document.createElement("div");
43307
+ this.confidenceEl.className = "md-speechtotext-confidence";
43308
+ this.confidenceEl.textContent = "";
43309
+ const controls = document.createElement("div");
43310
+ controls.className = "md-speechtotext-controls";
43311
+ this.startStopBtn = document.createElement("button");
43312
+ this.startStopBtn.type = "button";
43313
+ this.startStopBtn.className = "md-speechtotext-btn md-speechtotext-btn-start";
43314
+ this.startStopBtn.textContent = trans("Start");
43315
+ this.startStopBtn.addEventListener("click", () => this.toggleRecognition());
43316
+ this.insertBtn = document.createElement("button");
43317
+ this.insertBtn.type = "button";
43318
+ this.insertBtn.className = "md-speechtotext-btn md-speechtotext-btn-insert";
43319
+ this.insertBtn.textContent = trans("Insert");
43320
+ this.insertBtn.addEventListener("click", () => this.insertTranscript());
43321
+ this.clearBtn = document.createElement("button");
43322
+ this.clearBtn.type = "button";
43323
+ this.clearBtn.className = "md-speechtotext-btn md-speechtotext-btn-clear";
43324
+ this.clearBtn.textContent = trans("Clear");
43325
+ this.clearBtn.addEventListener("click", () => this.clearTranscript());
43326
+ controls.appendChild(this.startStopBtn);
43327
+ controls.appendChild(this.insertBtn);
43328
+ controls.appendChild(this.clearBtn);
43329
+ body.appendChild(langRow);
43330
+ body.appendChild(this.statusEl);
43331
+ body.appendChild(this.transcriptArea);
43332
+ body.appendChild(this.confidenceEl);
43333
+ body.appendChild(controls);
43334
+ this.dialog.appendChild(header);
43335
+ this.dialog.appendChild(body);
43336
+ this.overlay.appendChild(this.dialog);
43337
+ document.body.appendChild(this.overlay);
43338
+ this.dialog.addEventListener("keydown", (e) => {
43339
+ if (e.key === "Escape") {
43340
+ this.close();
43341
+ }
43342
+ });
43343
+ }
43344
+ toggleRecognition() {
43345
+ if (this.isListening) {
43346
+ this.stopRecognition();
43347
+ } else {
43348
+ this.startRecognition();
43349
+ }
43350
+ }
43351
+ startRecognition() {
43352
+ const SpeechRecognitionCtor = getSpeechRecognitionConstructor$1();
43353
+ if (!SpeechRecognitionCtor) return;
43354
+ this.recognition = new SpeechRecognitionCtor();
43355
+ this.recognition.continuous = true;
43356
+ this.recognition.interimResults = true;
43357
+ this.recognition.maxAlternatives = 1;
43358
+ this.recognition.lang = this.languageSelect?.value ?? this.getDefaultSpeechLang();
43359
+ this.recognition.onresult = this.handleResult.bind(this);
43360
+ this.recognition.onerror = this.handleError.bind(this);
43361
+ this.recognition.onend = this.handleEnd.bind(this);
43362
+ try {
43363
+ this.recognition.start();
43364
+ this.isListening = true;
43365
+ this.updateButtonState();
43366
+ this.setStatus(this.options.trans("Listening..."));
43367
+ } catch {
43368
+ }
43369
+ }
43370
+ handleResult(event) {
43371
+ this.interimTranscript = "";
43372
+ for (let i = event.resultIndex; i < event.results.length; i++) {
43373
+ const result = event.results[i];
43374
+ if (result.isFinal) {
43375
+ const text = result[0].transcript;
43376
+ if (this.finalTranscript.length > 0 && !this.finalTranscript.endsWith(" ") && !text.startsWith(" ")) {
43377
+ this.finalTranscript += " ";
43378
+ }
43379
+ this.finalTranscript += text;
43380
+ this.lastConfidence = result[0].confidence;
43381
+ } else {
43382
+ this.interimTranscript += result[0].transcript;
43383
+ }
43384
+ }
43385
+ this.updateTranscriptDisplay();
43386
+ this.updateConfidenceDisplay();
43387
+ }
43388
+ handleError(event) {
43389
+ const trans = this.options.trans;
43390
+ if (event.error === "no-speech") ;
43391
+ else if (event.error === "not-allowed") {
43392
+ this.stopRecognition();
43393
+ this.setStatus(trans("Microphone access denied"));
43394
+ } else if (event.error === "audio-capture") {
43395
+ this.stopRecognition();
43396
+ this.setStatus(trans("No microphone found"));
43397
+ } else if (event.error === "network") {
43398
+ this.stopRecognition();
43399
+ this.setStatus(trans("Network error - speech recognition requires internet"));
43400
+ } else if (event.error !== "aborted") ;
43401
+ }
43402
+ handleEnd() {
43403
+ if (this.isListening) {
43404
+ this.restartTimer = setTimeout(() => {
43405
+ if (!this.isListening) return;
43406
+ try {
43407
+ this.recognition?.start();
43408
+ } catch {
43409
+ const Ctor = getSpeechRecognitionConstructor$1();
43410
+ if (!Ctor) return;
43411
+ this.recognition = new Ctor();
43412
+ this.recognition.continuous = true;
43413
+ this.recognition.interimResults = true;
43414
+ this.recognition.maxAlternatives = 1;
43415
+ this.recognition.lang = this.languageSelect?.value ?? this.getDefaultSpeechLang();
43416
+ this.recognition.onresult = this.handleResult.bind(this);
43417
+ this.recognition.onerror = this.handleError.bind(this);
43418
+ this.recognition.onend = this.handleEnd.bind(this);
43419
+ try {
43420
+ this.recognition.start();
43421
+ } catch {
43422
+ this.stopRecognition();
43423
+ }
43424
+ }
43425
+ }, 300);
43426
+ }
43427
+ }
43428
+ stopRecognition() {
43429
+ this.isListening = false;
43430
+ if (this.restartTimer) {
43431
+ clearTimeout(this.restartTimer);
43432
+ this.restartTimer = null;
43433
+ }
43434
+ if (this.recognition) {
43435
+ try {
43436
+ this.recognition.stop();
43437
+ } catch {
43438
+ }
43439
+ this.recognition = null;
43440
+ }
43441
+ this.updateButtonState();
43442
+ this.setStatus("");
43443
+ }
43444
+ updateButtonState() {
43445
+ const trans = this.options.trans;
43446
+ if (this.startStopBtn) {
43447
+ if (this.isListening) {
43448
+ this.startStopBtn.textContent = trans("Stop");
43449
+ this.startStopBtn.classList.remove("md-speechtotext-btn-start");
43450
+ this.startStopBtn.classList.add("md-speechtotext-btn-stop");
43451
+ } else {
43452
+ this.startStopBtn.textContent = trans("Start");
43453
+ this.startStopBtn.classList.remove("md-speechtotext-btn-stop");
43454
+ this.startStopBtn.classList.add("md-speechtotext-btn-start");
43455
+ }
43456
+ }
43457
+ if (this.statusEl) {
43458
+ this.statusEl.classList.toggle("md-speechtotext-status-active", this.isListening);
43459
+ }
43460
+ }
43461
+ setStatus(text) {
43462
+ if (this.statusEl) {
43463
+ this.statusEl.textContent = text;
43464
+ }
43465
+ }
43466
+ updateTranscriptDisplay() {
43467
+ if (!this.transcriptArea) return;
43468
+ const finalSpan = `<span class="md-speechtotext-final">${this.escapeHtml(this.finalTranscript)}</span>`;
43469
+ const interimSpan = this.interimTranscript ? `<span class="md-speechtotext-interim">${this.escapeHtml(this.interimTranscript)}</span>` : "";
43470
+ this.transcriptArea.innerHTML = finalSpan + interimSpan;
43471
+ this.transcriptArea.scrollTop = this.transcriptArea.scrollHeight;
43472
+ }
43473
+ updateConfidenceDisplay() {
43474
+ if (!this.confidenceEl) return;
43475
+ if (this.lastConfidence > 0) {
43476
+ const pct = Math.round(this.lastConfidence * 100);
43477
+ this.confidenceEl.textContent = `${this.options.trans("Confidence")}: ${pct}%`;
43478
+ }
43479
+ }
43480
+ insertTranscript() {
43481
+ const text = this.finalTranscript.trim();
43482
+ if (!text) return;
43483
+ const tiptap = this.options.editor.getTipTap();
43484
+ if (tiptap) {
43485
+ tiptap.chain().focus().insertContent(text).run();
43486
+ }
43487
+ this.clearTranscript();
43488
+ this.close();
43489
+ }
43490
+ clearTranscript() {
43491
+ this.finalTranscript = "";
43492
+ this.interimTranscript = "";
43493
+ this.lastConfidence = 0;
43494
+ if (this.transcriptArea) {
43495
+ this.transcriptArea.innerHTML = "";
43496
+ }
43497
+ if (this.confidenceEl) {
43498
+ this.confidenceEl.textContent = "";
43499
+ }
43500
+ }
43501
+ escapeHtml(text) {
43502
+ const div = document.createElement("div");
43503
+ div.textContent = text;
43504
+ return div.innerHTML;
43505
+ }
43506
+ }
43507
+ const LOCALE_TO_BCP47 = {
43508
+ "ar": "ar-SA",
43509
+ "ca": "ca-ES",
43510
+ "cs": "cs-CZ",
43511
+ "da": "da-DK",
43512
+ "de": "de-DE",
43513
+ "el": "el-GR",
43514
+ "en": "en-US",
43515
+ "en-gb": "en-GB",
43516
+ "es": "es-ES",
43517
+ "fi": "fi-FI",
43518
+ "fr": "fr-FR",
43519
+ "fr-ca": "fr-CA",
43520
+ "hu": "hu-HU",
43521
+ "id": "id-ID",
43522
+ "it": "it-IT",
43523
+ "ja": "ja-JP",
43524
+ "ko": "ko-KR",
43525
+ "nb": "nb-NO",
43526
+ "nl": "nl-NL",
43527
+ "pl": "pl-PL",
43528
+ "pt": "pt-BR",
43529
+ "ro": "ro-RO",
43530
+ "ru": "ru-RU",
43531
+ "sl": "sl-SI",
43532
+ "sr": "sr-RS",
43533
+ "sv": "sv-SE",
43534
+ "th": "th-TH",
43535
+ "tr": "tr-TR",
43536
+ "vi": "vi-VN",
43537
+ "zh": "zh-CN",
43538
+ "zh-tw": "zh-TW"
43539
+ };
43540
+ function getSpeechRecognitionConstructor() {
43541
+ return window.SpeechRecognition || window.webkitSpeechRecognition || null;
43542
+ }
43543
+ class Dictation {
43544
+ options;
43545
+ recognition = null;
43546
+ _isActive = false;
43547
+ restartTimer = null;
43548
+ // Tracks the start position of current interim text so we can replace it
43549
+ interimStart = null;
43550
+ interimLength = 0;
43551
+ constructor(options) {
43552
+ this.options = options;
43553
+ }
43554
+ get isActive() {
43555
+ return this._isActive;
43556
+ }
43557
+ toggle() {
43558
+ if (this._isActive) {
43559
+ this.stop();
43560
+ } else {
43561
+ this.start();
43562
+ }
43563
+ }
43564
+ start() {
43565
+ const Ctor = getSpeechRecognitionConstructor();
43566
+ if (!Ctor) return;
43567
+ this.recognition = new Ctor();
43568
+ this.recognition.continuous = true;
43569
+ this.recognition.interimResults = true;
43570
+ this.recognition.maxAlternatives = 1;
43571
+ this.recognition.lang = this.getSpeechLang();
43572
+ this.recognition.onresult = this.handleResult.bind(this);
43573
+ this.recognition.onerror = this.handleError.bind(this);
43574
+ this.recognition.onend = this.handleEnd.bind(this);
43575
+ try {
43576
+ this.recognition.start();
43577
+ this._isActive = true;
43578
+ this.interimStart = null;
43579
+ this.interimLength = 0;
43580
+ this.options.onStateChange?.(true);
43581
+ } catch {
43582
+ }
43583
+ }
43584
+ stop() {
43585
+ this._isActive = false;
43586
+ if (this.restartTimer) {
43587
+ clearTimeout(this.restartTimer);
43588
+ this.restartTimer = null;
43589
+ }
43590
+ this.clearInterim();
43591
+ if (this.recognition) {
43592
+ try {
43593
+ this.recognition.stop();
43594
+ } catch {
43595
+ }
43596
+ this.recognition = null;
43597
+ }
43598
+ this.options.onStateChange?.(false);
43599
+ }
43600
+ destroy() {
43601
+ this.stop();
43602
+ }
43603
+ getSpeechLang() {
43604
+ const locale = this.options.editor.getConfig().language ?? "en";
43605
+ return LOCALE_TO_BCP47[locale] ?? "en-US";
43606
+ }
43607
+ handleResult(event) {
43608
+ const tiptap = this.options.editor.getTipTap();
43609
+ if (!tiptap) return;
43610
+ for (let i = event.resultIndex; i < event.results.length; i++) {
43611
+ const result = event.results[i];
43612
+ const transcript = result[0].transcript;
43613
+ if (result.isFinal) {
43614
+ this.clearInterim();
43615
+ let text = transcript;
43616
+ if (this.needsLeadingSpace(text)) {
43617
+ text = " " + text;
43618
+ }
43619
+ tiptap.chain().focus().insertContent(text).run();
43620
+ } else {
43621
+ let text = transcript;
43622
+ if (this.interimStart === null && this.needsLeadingSpace(text)) {
43623
+ text = " " + text;
43624
+ }
43625
+ this.replaceInterim(text);
43626
+ }
43627
+ }
43628
+ }
43629
+ /** Replace the current interim text in the editor with new interim text */
43630
+ replaceInterim(text) {
43631
+ const tiptap = this.options.editor.getTipTap();
43632
+ if (!tiptap) return;
43633
+ if (this.interimStart !== null && this.interimLength > 0) {
43634
+ tiptap.chain().focus().command(({ tr: tr2 }) => {
43635
+ tr2.delete(this.interimStart, this.interimStart + this.interimLength);
43636
+ return true;
43637
+ }).run();
43638
+ }
43639
+ if (this.interimStart === null) {
43640
+ this.interimStart = tiptap.state.selection.from;
43641
+ }
43642
+ tiptap.chain().focus().insertContent(text).run();
43643
+ this.interimLength = text.length;
43644
+ }
43645
+ /** Remove interim text without inserting anything */
43646
+ clearInterim() {
43647
+ if (this.interimStart !== null && this.interimLength > 0) {
43648
+ const tiptap = this.options.editor.getTipTap();
43649
+ if (tiptap) {
43650
+ tiptap.chain().focus().command(({ tr: tr2 }) => {
43651
+ tr2.delete(this.interimStart, this.interimStart + this.interimLength);
43652
+ return true;
43653
+ }).run();
43654
+ }
43655
+ }
43656
+ this.interimStart = null;
43657
+ this.interimLength = 0;
43658
+ }
43659
+ needsLeadingSpace(newText) {
43660
+ if (newText.startsWith(" ")) return false;
43661
+ const tiptap = this.options.editor.getTipTap();
43662
+ if (!tiptap) return false;
43663
+ const { from: from2 } = tiptap.state.selection;
43664
+ if (from2 === 0) return false;
43665
+ const textBefore = tiptap.state.doc.textBetween(Math.max(0, from2 - 1), from2, "");
43666
+ if (!textBefore) return false;
43667
+ return textBefore.trim().length > 0;
43668
+ }
43669
+ handleError(event) {
43670
+ if (event.error === "no-speech") ;
43671
+ else if (event.error === "not-allowed" || event.error === "audio-capture" || event.error === "network") {
43672
+ this.stop();
43673
+ }
43674
+ }
43675
+ handleEnd() {
43676
+ if (this._isActive) {
43677
+ this.restartTimer = setTimeout(() => {
43678
+ if (!this._isActive) return;
43679
+ try {
43680
+ this.recognition?.start();
43681
+ } catch {
43682
+ const Ctor = getSpeechRecognitionConstructor();
43683
+ if (!Ctor) return;
43684
+ this.recognition = new Ctor();
43685
+ this.recognition.continuous = true;
43686
+ this.recognition.interimResults = true;
43687
+ this.recognition.maxAlternatives = 1;
43688
+ this.recognition.lang = this.getSpeechLang();
43689
+ this.recognition.onresult = this.handleResult.bind(this);
43690
+ this.recognition.onerror = this.handleError.bind(this);
43691
+ this.recognition.onend = this.handleEnd.bind(this);
43692
+ try {
43693
+ this.recognition.start();
43694
+ } catch {
43695
+ this.stop();
43696
+ }
43697
+ }
43698
+ }, 300);
43699
+ }
43700
+ }
43701
+ }
42890
43702
  const DEFAULT_BUTTON_PRIORITY = {
42891
43703
  bold: 1,
42892
43704
  italic: 1,
@@ -42896,6 +43708,13 @@ const DEFAULT_BUTTON_PRIORITY = {
42896
43708
  link: 1,
42897
43709
  forecolor: 1
42898
43710
  };
43711
+ const DEFAULT_BLOCK_FORMATS = "Paragraph=p;Heading 1=h1;Heading 2=h2;Heading 3=h3;Heading 4=h4;Heading 5=h5;Heading 6=h6";
43712
+ const DEFAULT_STYLE_FORMATS = [
43713
+ { title: "Blue Title", block: "h3", styles: { color: "Blue" } },
43714
+ { title: "Red Title", block: "h3", styles: { color: "Red" } },
43715
+ { title: "Marker: Yellow", inline: "span", styles: { "background-color": "Yellow" } },
43716
+ { title: "Marker: Green", inline: "span", styles: { "background-color": "Lime" } }
43717
+ ];
42899
43718
  const DEFAULT_COLORS = [
42900
43719
  { value: "#000000", label: "Black" },
42901
43720
  { value: "#434343", label: "Dark Gray 4" },
@@ -42949,6 +43768,9 @@ class Toolbar {
42949
43768
  searchReplace = null;
42950
43769
  sourceEditor = null;
42951
43770
  linkEditor = null;
43771
+ anchorDialog = null;
43772
+ speechToText = null;
43773
+ dictation = null;
42952
43774
  updateInterval = null;
42953
43775
  boundClickHandler = null;
42954
43776
  boundKeydownHandler = null;
@@ -43143,6 +43965,33 @@ class Toolbar {
43143
43965
  return this.createActionButton("strikethrough", this.icon("strikethrough"), this.trans("Strikethrough"), () => {
43144
43966
  this.tiptap?.chain().focus().toggleStrike().run();
43145
43967
  }, () => this.tiptap?.isActive("strike") ?? false);
43968
+ case "subscript":
43969
+ return this.createActionButton("subscript", this.icon("subscript"), this.trans("Subscript"), () => {
43970
+ this.tiptap?.chain().focus().toggleSubscript().run();
43971
+ }, () => this.tiptap?.isActive("subscript") ?? false);
43972
+ case "superscript":
43973
+ return this.createActionButton("superscript", this.icon("superscript"), this.trans("Superscript"), () => {
43974
+ this.tiptap?.chain().focus().toggleSuperscript().run();
43975
+ }, () => this.tiptap?.isActive("superscript") ?? false);
43976
+ case "hr":
43977
+ return this.createActionButton("hr", this.icon("hr"), this.trans("Horizontal rule"), () => {
43978
+ this.tiptap?.chain().focus().setHorizontalRule().run();
43979
+ });
43980
+ case "blocks":
43981
+ case "formatselect":
43982
+ return this.createFormatDropdown();
43983
+ case "styles":
43984
+ return this.createStylesDropdown();
43985
+ case "table":
43986
+ return this.createTableDropdown();
43987
+ case "anchor":
43988
+ return this.createActionButton("anchor", this.icon("anchor"), this.trans("Insert anchor"), () => {
43989
+ this.openAnchorDialog();
43990
+ });
43991
+ case "unlink":
43992
+ return this.createActionButton("unlink", this.icon("unlink"), this.trans("Unlink"), () => {
43993
+ this.tiptap?.chain().focus().unsetLink().run();
43994
+ }, () => this.tiptap?.isActive("link") ?? false);
43146
43995
  case "bullist":
43147
43996
  return this.createActionButton("bullist", this.icon("bullist"), this.trans("Bullet list"), () => {
43148
43997
  this.tiptap?.chain().focus().toggleBulletList().run();
@@ -43265,6 +44114,32 @@ class Toolbar {
43265
44114
  return this.createActionButton("searchreplace", this.icon("searchreplace"), this.trans("Find and replace"), () => {
43266
44115
  this.openSearchReplace();
43267
44116
  });
44117
+ case "speechtotext": {
44118
+ if (this.options.config.speech_to_text === false) return null;
44119
+ if (!isSpeechRecognitionSupported()) {
44120
+ const btn = this.createActionButton("speechtotext", this.icon("speechtotext"), this.trans("Speech to text is not supported in this browser"), () => {
44121
+ });
44122
+ btn.classList.add("md-toolbar-btn-disabled");
44123
+ btn.setAttribute("aria-disabled", "true");
44124
+ return btn;
44125
+ }
44126
+ return this.createActionButton("speechtotext", this.icon("speechtotext"), this.trans("Speech to Text"), () => {
44127
+ this.openSpeechToText();
44128
+ });
44129
+ }
44130
+ case "dictate": {
44131
+ if (this.options.config.speech_to_text === false) return null;
44132
+ if (!isSpeechRecognitionSupported()) {
44133
+ const btn = this.createActionButton("dictate", this.icon("dictate"), this.trans("Speech to text is not supported in this browser"), () => {
44134
+ });
44135
+ btn.classList.add("md-toolbar-btn-disabled");
44136
+ btn.setAttribute("aria-disabled", "true");
44137
+ return btn;
44138
+ }
44139
+ return this.createActionButton("dictate", this.icon("dictate"), this.trans("Dictate"), () => {
44140
+ this.toggleDictation();
44141
+ });
44142
+ }
43268
44143
  case "template":
43269
44144
  return this.createTemplateDropdown();
43270
44145
  default:
@@ -43369,6 +44244,126 @@ class Toolbar {
43369
44244
  }
43370
44245
  });
43371
44246
  }
44247
+ createFormatDropdown() {
44248
+ const spec = this.options.config.block_formats ?? DEFAULT_BLOCK_FORMATS;
44249
+ const options = spec.split(";").map((entry) => {
44250
+ const [label, value] = entry.split("=");
44251
+ return { label: this.trans(label.trim()), value: (value ?? label).trim().toLowerCase() };
44252
+ }).filter((o) => o.value);
44253
+ return this.createDropdown("blocks", this.trans("Format"), options, (option) => {
44254
+ const chain = this.tiptap?.chain().focus();
44255
+ if (!chain) return;
44256
+ const m = /^h([1-6])$/.exec(option.value);
44257
+ if (m) {
44258
+ chain.toggleHeading({ level: Number(m[1]) }).run();
44259
+ } else {
44260
+ chain.setParagraph().run();
44261
+ }
44262
+ }, () => {
44263
+ for (let level = 1; level <= 6; level++) {
44264
+ if (this.tiptap?.isActive("heading", { level })) return `h${level}`;
44265
+ }
44266
+ return this.tiptap?.isActive("paragraph") ? "p" : "";
44267
+ });
44268
+ }
44269
+ getStyleFormats() {
44270
+ return this.options.config.style_formats ?? DEFAULT_STYLE_FORMATS;
44271
+ }
44272
+ createStylesDropdown() {
44273
+ const formats = this.getStyleFormats();
44274
+ const options = formats.map((f, i) => ({ label: f.title, value: String(i) }));
44275
+ return this.createDropdown("styles", this.trans("Styles"), options, (option) => {
44276
+ const fmt = formats[Number(option.value)];
44277
+ if (fmt) this.applyStyleFormat(fmt);
44278
+ });
44279
+ }
44280
+ /**
44281
+ * Apply a StyleFormat to the current selection. Block elements map to
44282
+ * heading/paragraph; color and background map to the existing Color /
44283
+ * Highlight marks; classes map to the InlineStyle textStyle class.
44284
+ * (Arbitrary element wrapping from CKEditor stylesSet is not supported.)
44285
+ */
44286
+ applyStyleFormat(fmt) {
44287
+ const chain = this.tiptap?.chain().focus();
44288
+ if (!chain) return;
44289
+ const blockEl = fmt.block;
44290
+ if (blockEl) {
44291
+ const m = /^h([1-6])$/.exec(blockEl);
44292
+ if (m) {
44293
+ chain.setHeading({ level: Number(m[1]) });
44294
+ } else if (blockEl === "p") {
44295
+ chain.setParagraph();
44296
+ }
44297
+ }
44298
+ if (fmt.styles) {
44299
+ if (fmt.styles.color) {
44300
+ chain.setColor(fmt.styles.color);
44301
+ }
44302
+ const bg = fmt.styles["background-color"];
44303
+ if (bg) {
44304
+ chain.setHighlight({ color: bg });
44305
+ }
44306
+ }
44307
+ if (fmt.classes) {
44308
+ chain.setInlineClass(fmt.classes);
44309
+ }
44310
+ chain.run();
44311
+ }
44312
+ createTableDropdown() {
44313
+ const t = this.trans;
44314
+ const options = [
44315
+ { label: t("Insert table"), value: "insert" },
44316
+ { label: t("Insert row before"), value: "rowBefore" },
44317
+ { label: t("Insert row after"), value: "rowAfter" },
44318
+ { label: t("Delete row"), value: "deleteRow" },
44319
+ { label: t("Insert column before"), value: "colBefore" },
44320
+ { label: t("Insert column after"), value: "colAfter" },
44321
+ { label: t("Delete column"), value: "deleteCol" },
44322
+ { label: t("Merge cells"), value: "merge" },
44323
+ { label: t("Split cell"), value: "split" },
44324
+ { label: t("Toggle header row"), value: "headerRow" },
44325
+ { label: t("Delete table"), value: "deleteTable" }
44326
+ ];
44327
+ return this.createDropdown("table", this.trans("Table"), options, (option) => {
44328
+ const chain = this.tiptap?.chain().focus();
44329
+ if (!chain) return;
44330
+ switch (option.value) {
44331
+ case "insert":
44332
+ chain.insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run();
44333
+ break;
44334
+ case "rowBefore":
44335
+ chain.addRowBefore().run();
44336
+ break;
44337
+ case "rowAfter":
44338
+ chain.addRowAfter().run();
44339
+ break;
44340
+ case "deleteRow":
44341
+ chain.deleteRow().run();
44342
+ break;
44343
+ case "colBefore":
44344
+ chain.addColumnBefore().run();
44345
+ break;
44346
+ case "colAfter":
44347
+ chain.addColumnAfter().run();
44348
+ break;
44349
+ case "deleteCol":
44350
+ chain.deleteColumn().run();
44351
+ break;
44352
+ case "merge":
44353
+ chain.mergeCells().run();
44354
+ break;
44355
+ case "split":
44356
+ chain.splitCell().run();
44357
+ break;
44358
+ case "headerRow":
44359
+ chain.toggleHeaderRow().run();
44360
+ break;
44361
+ case "deleteTable":
44362
+ chain.deleteTable().run();
44363
+ break;
44364
+ }
44365
+ });
44366
+ }
43372
44367
  /**
43373
44368
  * Position a fixed-position menu below its trigger button.
43374
44369
  * Uses getBoundingClientRect so the menu escapes any overflow:hidden ancestor.
@@ -43606,6 +44601,15 @@ class Toolbar {
43606
44601
  case "strikethrough":
43607
44602
  isActive2 = this.tiptap?.isActive("strike") ?? false;
43608
44603
  break;
44604
+ case "subscript":
44605
+ isActive2 = this.tiptap?.isActive("subscript") ?? false;
44606
+ break;
44607
+ case "superscript":
44608
+ isActive2 = this.tiptap?.isActive("superscript") ?? false;
44609
+ break;
44610
+ case "unlink":
44611
+ isActive2 = this.tiptap?.isActive("link") ?? false;
44612
+ break;
43609
44613
  case "bullist":
43610
44614
  isActive2 = this.tiptap?.isActive("bulletList") ?? false;
43611
44615
  break;
@@ -43652,6 +44656,9 @@ class Toolbar {
43652
44656
  uploadBasePath: this.options.config.images_upload_base_path,
43653
44657
  uploadMaxSize: this.options.config.images_upload_max_size,
43654
44658
  uploadHeaders: this.options.config.images_upload_headers,
44659
+ fileTypes: this.options.config.images_file_types,
44660
+ validate: this.options.config.images_upload_validate,
44661
+ onError: this.options.config.images_upload_error,
43655
44662
  trans: this.trans
43656
44663
  });
43657
44664
  }
@@ -43666,6 +44673,25 @@ class Toolbar {
43666
44673
  }
43667
44674
  this.linkEditor.open();
43668
44675
  }
44676
+ openAnchorDialog() {
44677
+ if (!this.anchorDialog) {
44678
+ this.anchorDialog = new AnchorDialog({
44679
+ editor: this.options.editor,
44680
+ trans: this.trans
44681
+ });
44682
+ }
44683
+ this.anchorDialog.open();
44684
+ }
44685
+ /**
44686
+ * Enable or disable the whole toolbar (used for read-only mode).
44687
+ * Blocks pointer interaction and dims the toolbar via CSS.
44688
+ */
44689
+ setEnabled(enabled) {
44690
+ this.container.classList.toggle("md-toolbar-disabled", !enabled);
44691
+ if (!enabled) {
44692
+ this.closeAllDropdowns();
44693
+ }
44694
+ }
43669
44695
  openCharMap() {
43670
44696
  if (!this.charMap) {
43671
44697
  this.charMap = new CharacterMap({
@@ -43697,6 +44723,31 @@ class Toolbar {
43697
44723
  }
43698
44724
  this.searchReplace.open();
43699
44725
  }
44726
+ openSpeechToText() {
44727
+ if (!this.speechToText) {
44728
+ this.speechToText = new SpeechToText({
44729
+ editor: this.options.editor,
44730
+ trans: this.trans
44731
+ });
44732
+ }
44733
+ this.speechToText.open();
44734
+ }
44735
+ toggleDictation() {
44736
+ if (!this.dictation) {
44737
+ this.dictation = new Dictation({
44738
+ editor: this.options.editor,
44739
+ trans: this.trans,
44740
+ onStateChange: (isActive2) => {
44741
+ const btn = this.buttonElements.get("dictate");
44742
+ if (btn) {
44743
+ btn.classList.toggle("md-toolbar-btn-active", isActive2);
44744
+ btn.classList.toggle("md-toolbar-btn-dictating", isActive2);
44745
+ }
44746
+ }
44747
+ });
44748
+ }
44749
+ this.dictation.toggle();
44750
+ }
43700
44751
  openSourceCode() {
43701
44752
  if (!this.sourceEditor) {
43702
44753
  this.sourceEditor = new SourceEditor({
@@ -43745,6 +44796,16 @@ class Toolbar {
43745
44796
  this.imageUpload = null;
43746
44797
  this.searchReplace?.destroy();
43747
44798
  this.searchReplace = null;
44799
+ this.speechToText?.destroy();
44800
+ this.speechToText = null;
44801
+ this.dictation?.destroy();
44802
+ this.dictation = null;
44803
+ this.anchorDialog?.destroy();
44804
+ this.anchorDialog = null;
44805
+ this.linkEditor?.destroy();
44806
+ this.linkEditor = null;
44807
+ this.sourceEditor?.destroy();
44808
+ this.sourceEditor = null;
43748
44809
  this.buttonElements.clear();
43749
44810
  this.dropdowns.clear();
43750
44811
  this.removeBodyMenus();
@@ -43767,6 +44828,11 @@ class Toolbar {
43767
44828
  this.emojiPicker?.destroy();
43768
44829
  this.imageUpload?.destroy();
43769
44830
  this.searchReplace?.destroy();
44831
+ this.speechToText?.destroy();
44832
+ this.dictation?.destroy();
44833
+ this.anchorDialog?.destroy();
44834
+ this.linkEditor?.destroy();
44835
+ this.sourceEditor?.destroy();
43770
44836
  this.buttonElements.clear();
43771
44837
  this.dropdowns.clear();
43772
44838
  this.removeBodyMenus();
@@ -43785,6 +44851,10 @@ const SVG_ALIGN_RIGHT = '<svg width="16" height="16" viewBox="0 0 24 24" fill="n
43785
44851
  const SVG_ALIGN_JUSTIFY = '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>';
43786
44852
  const SVG_IMAGE = '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>';
43787
44853
  const SVG_CODE = '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>';
44854
+ const SVG_HR = '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="3" y1="12" x2="21" y2="12"/></svg>';
44855
+ const SVG_TABLE = '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="1"/><line x1="3" y1="9" x2="21" y2="9"/><line x1="3" y1="15" x2="21" y2="15"/><line x1="9" y1="3" x2="9" y2="21"/><line x1="15" y1="3" x2="15" y2="21"/></svg>';
44856
+ const SVG_ANCHOR = '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="5" r="3"/><line x1="12" y1="22" x2="12" y2="8"/><path d="M5 12H2a10 10 0 0 0 20 0h-3"/></svg>';
44857
+ const SVG_UNLINK = '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18.84 12.25l1.72-1.71a4 4 0 0 0-5.66-5.66l-1.71 1.72"/><path d="M5.17 11.75l-1.71 1.71a4 4 0 0 0 5.66 5.66l1.71-1.71"/><line x1="2" y1="2" x2="22" y2="22"/></svg>';
43788
44858
  const DEFAULT_ICONS = {
43789
44859
  bold: "B",
43790
44860
  italic: "I",
@@ -43816,7 +44886,17 @@ const DEFAULT_ICONS = {
43816
44886
  ltr: "⇐",
43817
44887
  rtl: "⇒",
43818
44888
  searchreplace: "🔍",
43819
- togglemore: ""
44889
+ speechtotext: "🎤",
44890
+ dictate: "🎙️",
44891
+ togglemore: "…",
44892
+ subscript: "X₂",
44893
+ superscript: "X²",
44894
+ hr: SVG_HR,
44895
+ table: SVG_TABLE,
44896
+ anchor: SVG_ANCHOR,
44897
+ unlink: SVG_UNLINK,
44898
+ blocks: "¶",
44899
+ styles: "A"
43820
44900
  };
43821
44901
  const CONFAB_ICONS = {
43822
44902
  bold: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"/><path d="M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"/></svg>',
@@ -43849,7 +44929,17 @@ const CONFAB_ICONS = {
43849
44929
  ltr: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="18" y1="5" x2="18" y2="19"/><path d="M8 5a4 4 0 0 0 0 8h4"/><polyline points="4 17 8 21 12 17"/></svg>',
43850
44930
  rtl: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="6" y1="5" x2="6" y2="19"/><path d="M16 5a4 4 0 0 1 0 8h-4"/><polyline points="20 17 16 21 12 17"/></svg>',
43851
44931
  searchreplace: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.6" y2="16.6"/></svg>',
43852
- togglemore: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="1" fill="currentColor"/><circle cx="5" cy="12" r="1" fill="currentColor"/><circle cx="19" cy="12" r="1" fill="currentColor"/></svg>'
44932
+ speechtotext: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" y1="19" x2="12" y2="23"/><line x1="8" y1="23" x2="16" y2="23"/></svg>',
44933
+ dictate: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><circle cx="12" cy="12" r="1" fill="currentColor" stroke="none"/><circle cx="12" cy="8" r="1" fill="currentColor" stroke="none"/><circle cx="12" cy="16" r="0.5" fill="currentColor" stroke="none"/></svg>',
44934
+ togglemore: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="1" fill="currentColor"/><circle cx="5" cy="12" r="1" fill="currentColor"/><circle cx="19" cy="12" r="1" fill="currentColor"/></svg>',
44935
+ subscript: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 5l8 10M12 5L4 15"/><path d="M20 19h-4c0-1.5.44-2 1.5-2.5S20 15.33 20 14c0-.47-.17-.93-.48-1.29a2 2 0 0 0-2.62-.44c-.42.24-.74.62-.9 1.07"/></svg>',
44936
+ superscript: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 9l8 10M12 9l-8 10"/><path d="M20 8h-4c0-1.5.44-2 1.5-2.5S20 4.33 20 3c0-.47-.17-.93-.48-1.29a2 2 0 0 0-2.62-.44c-.42.24-.74.62-.9 1.07"/></svg>',
44937
+ hr: SVG_HR,
44938
+ table: SVG_TABLE,
44939
+ anchor: SVG_ANCHOR,
44940
+ unlink: SVG_UNLINK,
44941
+ blocks: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M13 4v16"/><path d="M17 4v16"/><path d="M19 4H9.5a4.5 4.5 0 0 0 0 9H13"/></svg>',
44942
+ styles: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3l4 7h-8z"/><path d="M8 10h8l-4 11z"/></svg>'
43853
44943
  };
43854
44944
  const FontSize = Extension.create({
43855
44945
  name: "fontSize",
@@ -43994,7 +45084,10 @@ const SignatureBlock = Node3.create({
43994
45084
  parseHTML() {
43995
45085
  return [
43996
45086
  {
43997
- tag: 'div[id="signature"]'
45087
+ // Higher priority than the generic div->paragraph rule used when
45088
+ // forced_root_block is 'div', so the signature wrapper still matches.
45089
+ tag: 'div[id="signature"]',
45090
+ priority: 100
43998
45091
  }
43999
45092
  ];
44000
45093
  },
@@ -44050,6 +45143,80 @@ const Mention = Node3.create({
44050
45143
  ];
44051
45144
  }
44052
45145
  });
45146
+ const Anchor = Node3.create({
45147
+ name: "anchor",
45148
+ inline: true,
45149
+ group: "inline",
45150
+ atom: true,
45151
+ selectable: true,
45152
+ addOptions() {
45153
+ return {
45154
+ HTMLAttributes: { class: "md-anchor" }
45155
+ };
45156
+ },
45157
+ addAttributes() {
45158
+ return {
45159
+ id: {
45160
+ default: null,
45161
+ parseHTML: (element) => element.getAttribute("id"),
45162
+ renderHTML: (attributes) => attributes.id ? { id: attributes.id } : {}
45163
+ },
45164
+ name: {
45165
+ default: null,
45166
+ parseHTML: (element) => element.getAttribute("name"),
45167
+ renderHTML: (attributes) => attributes.name ? { name: attributes.name } : {}
45168
+ }
45169
+ };
45170
+ },
45171
+ parseHTML() {
45172
+ return [{ tag: "a[id]:not([href])", priority: 60 }];
45173
+ },
45174
+ renderHTML({ HTMLAttributes }) {
45175
+ return ["a", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)];
45176
+ },
45177
+ addCommands() {
45178
+ return {
45179
+ setAnchor: (name) => ({ commands }) => commands.insertContent({ type: this.name, attrs: { id: name, name } })
45180
+ };
45181
+ }
45182
+ });
45183
+ const InlineStyle = Extension.create({
45184
+ name: "inlineStyle",
45185
+ addOptions() {
45186
+ return {
45187
+ types: ["textStyle"]
45188
+ };
45189
+ },
45190
+ addGlobalAttributes() {
45191
+ return [
45192
+ {
45193
+ types: this.options.types,
45194
+ attributes: {
45195
+ styleClass: {
45196
+ default: null,
45197
+ parseHTML: (element) => element.getAttribute("class") || null,
45198
+ renderHTML: (attributes) => {
45199
+ if (!attributes.styleClass) {
45200
+ return {};
45201
+ }
45202
+ return { class: attributes.styleClass };
45203
+ }
45204
+ }
45205
+ }
45206
+ }
45207
+ ];
45208
+ },
45209
+ addCommands() {
45210
+ return {
45211
+ setInlineClass: (className) => ({ chain }) => {
45212
+ return chain().setMark("textStyle", { styleClass: className }).run();
45213
+ },
45214
+ unsetInlineClass: () => ({ chain }) => {
45215
+ return chain().setMark("textStyle", { styleClass: null }).removeEmptyTextStyle().run();
45216
+ }
45217
+ };
45218
+ }
45219
+ });
44053
45220
  const WORD_MARKERS = [
44054
45221
  'xmlns:o="urn:schemas-microsoft-com:office:office"',
44055
45222
  'xmlns:w="urn:schemas-microsoft-com:office:word"',
@@ -44498,7 +45665,50 @@ const en = {
44498
45665
  "Title": "Title",
44499
45666
  "Open link in...": "Open link in...",
44500
45667
  "Current window": "Current window",
44501
- "New window": "New window"
45668
+ "New window": "New window",
45669
+ "Speech to Text": "Speech to Text",
45670
+ "Dictate": "Dictate",
45671
+ "Start": "Start",
45672
+ "Stop": "Stop",
45673
+ "Clear": "Clear",
45674
+ "Language": "Language",
45675
+ "Confidence": "Confidence",
45676
+ "Listening...": "Listening...",
45677
+ "Speech to text is not supported in this browser": "Speech to text is not supported in this browser",
45678
+ "No speech detected": "No speech detected",
45679
+ "Microphone access denied": "Microphone access denied",
45680
+ "No microphone found": "No microphone found",
45681
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
45682
+ "Subscript": "Subscript",
45683
+ "Superscript": "Superscript",
45684
+ "Horizontal rule": "Horizontal rule",
45685
+ "Unlink": "Unlink",
45686
+ "Format": "Format",
45687
+ "Paragraph": "Paragraph",
45688
+ "Heading 1": "Heading 1",
45689
+ "Heading 2": "Heading 2",
45690
+ "Heading 3": "Heading 3",
45691
+ "Heading 4": "Heading 4",
45692
+ "Heading 5": "Heading 5",
45693
+ "Heading 6": "Heading 6",
45694
+ "Styles": "Styles",
45695
+ "Insert anchor": "Insert anchor",
45696
+ "Anchor": "Anchor",
45697
+ "Anchor name": "Anchor name",
45698
+ "Anchor name is required": "Anchor name is required",
45699
+ "Anchor name cannot contain spaces": "Anchor name cannot contain spaces",
45700
+ "Table": "Table",
45701
+ "Insert table": "Insert table",
45702
+ "Insert row before": "Insert row before",
45703
+ "Insert row after": "Insert row after",
45704
+ "Delete row": "Delete row",
45705
+ "Insert column before": "Insert column before",
45706
+ "Insert column after": "Insert column after",
45707
+ "Delete column": "Delete column",
45708
+ "Merge cells": "Merge cells",
45709
+ "Split cell": "Split cell",
45710
+ "Toggle header row": "Toggle header row",
45711
+ "Delete table": "Delete table"
44502
45712
  };
44503
45713
  const ar = {
44504
45714
  "Bold": "غامق",
@@ -44556,7 +45766,7 @@ const ar = {
44556
45766
  "Browse...": "استعراض...",
44557
45767
  "Drop image here or click to browse": "أسقط الصورة هنا أو انقر للاستعراض",
44558
45768
  "Alt text": "نص بديل",
44559
- "Insert": "إدراج",
45769
+ "Insert": "?????",
44560
45770
  "Cancel": "إلغاء",
44561
45771
  "Uploading...": "جارٍ الرفع...",
44562
45772
  "Upload failed": "فشل الرفع",
@@ -44570,7 +45780,50 @@ const ar = {
44570
45780
  "Title": "Title",
44571
45781
  "Open link in...": "Open link in...",
44572
45782
  "Current window": "Current window",
44573
- "New window": "New window"
45783
+ "New window": "New window",
45784
+ "Speech to Text": "????? ?????? ??? ??",
45785
+ "Dictate": "إملاء",
45786
+ "Start": "???",
45787
+ "Stop": "?????",
45788
+ "Clear": "???",
45789
+ "Language": "?????",
45790
+ "Confidence": "?????",
45791
+ "Listening...": "???? ????????...",
45792
+ "Speech to text is not supported in this browser": "????? ?????? ??? ?? ??? ????? ?? ??? ???????",
45793
+ "No speech detected": "?? ??? ?????? ????",
45794
+ "Microphone access denied": "?? ??? ?????? ??? ??????????",
45795
+ "No microphone found": "No microphone found",
45796
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
45797
+ "Subscript": "منخفض",
45798
+ "Superscript": "مرتفع",
45799
+ "Horizontal rule": "خط أفقي",
45800
+ "Unlink": "إزالة الرابط",
45801
+ "Format": "تنسيق",
45802
+ "Paragraph": "فقرة",
45803
+ "Heading 1": "عنوان 1",
45804
+ "Heading 2": "عنوان 2",
45805
+ "Heading 3": "عنوان 3",
45806
+ "Heading 4": "عنوان 4",
45807
+ "Heading 5": "عنوان 5",
45808
+ "Heading 6": "عنوان 6",
45809
+ "Styles": "أنماط",
45810
+ "Insert anchor": "إدراج مرساة",
45811
+ "Anchor": "مرساة",
45812
+ "Anchor name": "اسم المرساة",
45813
+ "Anchor name is required": "اسم المرساة مطلوب",
45814
+ "Anchor name cannot contain spaces": "لا يمكن أن يحتوي اسم المرساة على مسافات",
45815
+ "Table": "جدول",
45816
+ "Insert table": "إدراج جدول",
45817
+ "Insert row before": "إدراج صف قبل",
45818
+ "Insert row after": "إدراج صف بعد",
45819
+ "Delete row": "حذف الصف",
45820
+ "Insert column before": "إدراج عمود قبل",
45821
+ "Insert column after": "إدراج عمود بعد",
45822
+ "Delete column": "حذف العمود",
45823
+ "Merge cells": "دمج الخلايا",
45824
+ "Split cell": "تقسيم الخلية",
45825
+ "Toggle header row": "تبديل صف الرأس",
45826
+ "Delete table": "حذف الجدول"
44574
45827
  };
44575
45828
  const ca = {
44576
45829
  "Bold": "Negreta",
@@ -44642,7 +45895,50 @@ const ca = {
44642
45895
  "Title": "Title",
44643
45896
  "Open link in...": "Open link in...",
44644
45897
  "Current window": "Current window",
44645
- "New window": "New window"
45898
+ "New window": "New window",
45899
+ "Speech to Text": "Veu a text",
45900
+ "Dictate": "Dictar",
45901
+ "Start": "Iniciar",
45902
+ "Stop": "Aturar",
45903
+ "Clear": "Esborrar",
45904
+ "Language": "Idioma",
45905
+ "Confidence": "Confian�a",
45906
+ "Listening...": "Escoltant...",
45907
+ "Speech to text is not supported in this browser": "La veu a text no �s compatible amb aquest navegador",
45908
+ "No speech detected": "No s'ha detectat veu",
45909
+ "Microphone access denied": "Acc�s al micr�fon denegat",
45910
+ "No microphone found": "No microphone found",
45911
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
45912
+ "Subscript": "Subíndex",
45913
+ "Superscript": "Superíndex",
45914
+ "Horizontal rule": "Línia horitzontal",
45915
+ "Unlink": "Treure enllaç",
45916
+ "Format": "Format",
45917
+ "Paragraph": "Paràgraf",
45918
+ "Heading 1": "Encapçalament 1",
45919
+ "Heading 2": "Encapçalament 2",
45920
+ "Heading 3": "Encapçalament 3",
45921
+ "Heading 4": "Encapçalament 4",
45922
+ "Heading 5": "Encapçalament 5",
45923
+ "Heading 6": "Encapçalament 6",
45924
+ "Styles": "Estils",
45925
+ "Insert anchor": "Inserir àncora",
45926
+ "Anchor": "Àncora",
45927
+ "Anchor name": "Nom de l'àncora",
45928
+ "Anchor name is required": "El nom de l'àncora és obligatori",
45929
+ "Anchor name cannot contain spaces": "El nom de l'àncora no pot contenir espais",
45930
+ "Table": "Taula",
45931
+ "Insert table": "Inserir taula",
45932
+ "Insert row before": "Inserir fila a sobre",
45933
+ "Insert row after": "Inserir fila a sota",
45934
+ "Delete row": "Eliminar fila",
45935
+ "Insert column before": "Inserir columna abans",
45936
+ "Insert column after": "Inserir columna després",
45937
+ "Delete column": "Eliminar columna",
45938
+ "Merge cells": "Combinar cel·les",
45939
+ "Split cell": "Dividir cel·la",
45940
+ "Toggle header row": "Alternar fila de capçalera",
45941
+ "Delete table": "Eliminar taula"
44646
45942
  };
44647
45943
  const zh = {
44648
45944
  "Bold": "粗体",
@@ -44700,7 +45996,7 @@ const zh = {
44700
45996
  "Browse...": "浏览...",
44701
45997
  "Drop image here or click to browse": "将图片拖放到此处或点击浏览",
44702
45998
  "Alt text": "替代文本",
44703
- "Insert": "插入",
45999
+ "Insert": "??",
44704
46000
  "Cancel": "取消",
44705
46001
  "Uploading...": "上传中...",
44706
46002
  "Upload failed": "上传失败",
@@ -44714,7 +46010,50 @@ const zh = {
44714
46010
  "Title": "Title",
44715
46011
  "Open link in...": "Open link in...",
44716
46012
  "Current window": "Current window",
44717
- "New window": "New window"
46013
+ "New window": "New window",
46014
+ "Speech to Text": "?????",
46015
+ "Dictate": "听写",
46016
+ "Start": "??",
46017
+ "Stop": "??",
46018
+ "Clear": "??",
46019
+ "Language": "??",
46020
+ "Confidence": "???",
46021
+ "Listening...": "????...",
46022
+ "Speech to text is not supported in this browser": "????????????",
46023
+ "No speech detected": "??????",
46024
+ "Microphone access denied": "????????",
46025
+ "No microphone found": "No microphone found",
46026
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
46027
+ "Subscript": "下标",
46028
+ "Superscript": "上标",
46029
+ "Horizontal rule": "水平线",
46030
+ "Unlink": "取消链接",
46031
+ "Format": "格式",
46032
+ "Paragraph": "段落",
46033
+ "Heading 1": "标题 1",
46034
+ "Heading 2": "标题 2",
46035
+ "Heading 3": "标题 3",
46036
+ "Heading 4": "标题 4",
46037
+ "Heading 5": "标题 5",
46038
+ "Heading 6": "标题 6",
46039
+ "Styles": "样式",
46040
+ "Insert anchor": "插入锚点",
46041
+ "Anchor": "锚点",
46042
+ "Anchor name": "锚点名称",
46043
+ "Anchor name is required": "锚点名称为必填项",
46044
+ "Anchor name cannot contain spaces": "锚点名称不能包含空格",
46045
+ "Table": "表格",
46046
+ "Insert table": "插入表格",
46047
+ "Insert row before": "在上方插入行",
46048
+ "Insert row after": "在下方插入行",
46049
+ "Delete row": "删除行",
46050
+ "Insert column before": "在左侧插入列",
46051
+ "Insert column after": "在右侧插入列",
46052
+ "Delete column": "删除列",
46053
+ "Merge cells": "合并单元格",
46054
+ "Split cell": "拆分单元格",
46055
+ "Toggle header row": "切换标题行",
46056
+ "Delete table": "删除表格"
44718
46057
  };
44719
46058
  const cs = {
44720
46059
  "Bold": "Tučné",
@@ -44772,7 +46111,7 @@ const cs = {
44772
46111
  "Browse...": "Procházet...",
44773
46112
  "Drop image here or click to browse": "Přetáhněte obrázek sem nebo klikněte pro výběr",
44774
46113
  "Alt text": "Alternativní text",
44775
- "Insert": "Vložit",
46114
+ "Insert": "Vlo�it",
44776
46115
  "Cancel": "Zrušit",
44777
46116
  "Uploading...": "Nahrávání...",
44778
46117
  "Upload failed": "Nahrávání selhalo",
@@ -44786,7 +46125,50 @@ const cs = {
44786
46125
  "Title": "Title",
44787
46126
  "Open link in...": "Open link in...",
44788
46127
  "Current window": "Current window",
44789
- "New window": "New window"
46128
+ "New window": "New window",
46129
+ "Speech to Text": "Rec na text",
46130
+ "Dictate": "Diktovat",
46131
+ "Start": "Spustit",
46132
+ "Stop": "Zastavit",
46133
+ "Clear": "Vymazat",
46134
+ "Language": "Jazyk",
46135
+ "Confidence": "Spolehlivost",
46136
+ "Listening...": "Poslouch�m...",
46137
+ "Speech to text is not supported in this browser": "Rec na text nen� v tomto prohl�eci podporov�na",
46138
+ "No speech detected": "Nebyla detekov�na rec",
46139
+ "Microphone access denied": "Pr�stup k mikrofonu zam�tnut",
46140
+ "No microphone found": "No microphone found",
46141
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
46142
+ "Subscript": "Dolní index",
46143
+ "Superscript": "Horní index",
46144
+ "Horizontal rule": "Vodorovná čára",
46145
+ "Unlink": "Odebrat odkaz",
46146
+ "Format": "Formát",
46147
+ "Paragraph": "Odstavec",
46148
+ "Heading 1": "Nadpis 1",
46149
+ "Heading 2": "Nadpis 2",
46150
+ "Heading 3": "Nadpis 3",
46151
+ "Heading 4": "Nadpis 4",
46152
+ "Heading 5": "Nadpis 5",
46153
+ "Heading 6": "Nadpis 6",
46154
+ "Styles": "Styly",
46155
+ "Insert anchor": "Vložit kotvu",
46156
+ "Anchor": "Kotva",
46157
+ "Anchor name": "Název kotvy",
46158
+ "Anchor name is required": "Název kotvy je povinný",
46159
+ "Anchor name cannot contain spaces": "Název kotvy nesmí obsahovat mezery",
46160
+ "Table": "Tabulka",
46161
+ "Insert table": "Vložit tabulku",
46162
+ "Insert row before": "Vložit řádek před",
46163
+ "Insert row after": "Vložit řádek za",
46164
+ "Delete row": "Odstranit řádek",
46165
+ "Insert column before": "Vložit sloupec před",
46166
+ "Insert column after": "Vložit sloupec za",
46167
+ "Delete column": "Odstranit sloupec",
46168
+ "Merge cells": "Sloučit buňky",
46169
+ "Split cell": "Rozdělit buňku",
46170
+ "Toggle header row": "Přepnout řádek záhlaví",
46171
+ "Delete table": "Odstranit tabulku"
44790
46172
  };
44791
46173
  const da = {
44792
46174
  "Bold": "Fed",
@@ -44844,7 +46226,7 @@ const da = {
44844
46226
  "Browse...": "Gennemse...",
44845
46227
  "Drop image here or click to browse": "Træk billede hertil eller klik for at gennemse",
44846
46228
  "Alt text": "Alternativ tekst",
44847
- "Insert": "Indsæt",
46229
+ "Insert": "Inds�t",
44848
46230
  "Cancel": "Annuller",
44849
46231
  "Uploading...": "Uploader...",
44850
46232
  "Upload failed": "Upload mislykkedes",
@@ -44858,7 +46240,50 @@ const da = {
44858
46240
  "Title": "Title",
44859
46241
  "Open link in...": "Open link in...",
44860
46242
  "Current window": "Current window",
44861
- "New window": "New window"
46243
+ "New window": "New window",
46244
+ "Speech to Text": "Tale til tekst",
46245
+ "Dictate": "Dikter",
46246
+ "Start": "Start",
46247
+ "Stop": "Stop",
46248
+ "Clear": "Ryd",
46249
+ "Language": "Sprog",
46250
+ "Confidence": "Tillid",
46251
+ "Listening...": "Lytter...",
46252
+ "Speech to text is not supported in this browser": "Tale til tekst underst�ttes ikke i denne browser",
46253
+ "No speech detected": "Ingen tale registreret",
46254
+ "Microphone access denied": "Mikrofonadgang n�gtet",
46255
+ "No microphone found": "No microphone found",
46256
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
46257
+ "Subscript": "Sænket skrift",
46258
+ "Superscript": "Hævet skrift",
46259
+ "Horizontal rule": "Vandret streg",
46260
+ "Unlink": "Fjern link",
46261
+ "Format": "Format",
46262
+ "Paragraph": "Afsnit",
46263
+ "Heading 1": "Overskrift 1",
46264
+ "Heading 2": "Overskrift 2",
46265
+ "Heading 3": "Overskrift 3",
46266
+ "Heading 4": "Overskrift 4",
46267
+ "Heading 5": "Overskrift 5",
46268
+ "Heading 6": "Overskrift 6",
46269
+ "Styles": "Typografier",
46270
+ "Insert anchor": "Indsæt anker",
46271
+ "Anchor": "Anker",
46272
+ "Anchor name": "Ankernavn",
46273
+ "Anchor name is required": "Ankernavn er påkrævet",
46274
+ "Anchor name cannot contain spaces": "Ankernavn må ikke indeholde mellemrum",
46275
+ "Table": "Tabel",
46276
+ "Insert table": "Indsæt tabel",
46277
+ "Insert row before": "Indsæt række før",
46278
+ "Insert row after": "Indsæt række efter",
46279
+ "Delete row": "Slet række",
46280
+ "Insert column before": "Indsæt kolonne før",
46281
+ "Insert column after": "Indsæt kolonne efter",
46282
+ "Delete column": "Slet kolonne",
46283
+ "Merge cells": "Flet celler",
46284
+ "Split cell": "Opdel celle",
46285
+ "Toggle header row": "Skift overskriftsrække",
46286
+ "Delete table": "Slet tabel"
44862
46287
  };
44863
46288
  const enGb = {
44864
46289
  "Bold": "Bold",
@@ -44930,7 +46355,50 @@ const enGb = {
44930
46355
  "Title": "Title",
44931
46356
  "Open link in...": "Open link in...",
44932
46357
  "Current window": "Current window",
44933
- "New window": "New window"
46358
+ "New window": "New window",
46359
+ "Speech to Text": "Speech to Text",
46360
+ "Dictate": "Dictate",
46361
+ "Start": "Start",
46362
+ "Stop": "Stop",
46363
+ "Clear": "Clear",
46364
+ "Language": "Language",
46365
+ "Confidence": "Confidence",
46366
+ "Listening...": "Listening...",
46367
+ "Speech to text is not supported in this browser": "Speech to text is not supported in this browser",
46368
+ "No speech detected": "No speech detected",
46369
+ "Microphone access denied": "Microphone access denied",
46370
+ "No microphone found": "No microphone found",
46371
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
46372
+ "Subscript": "Subscript",
46373
+ "Superscript": "Superscript",
46374
+ "Horizontal rule": "Horizontal rule",
46375
+ "Unlink": "Unlink",
46376
+ "Format": "Format",
46377
+ "Paragraph": "Paragraph",
46378
+ "Heading 1": "Heading 1",
46379
+ "Heading 2": "Heading 2",
46380
+ "Heading 3": "Heading 3",
46381
+ "Heading 4": "Heading 4",
46382
+ "Heading 5": "Heading 5",
46383
+ "Heading 6": "Heading 6",
46384
+ "Styles": "Styles",
46385
+ "Insert anchor": "Insert anchor",
46386
+ "Anchor": "Anchor",
46387
+ "Anchor name": "Anchor name",
46388
+ "Anchor name is required": "Anchor name is required",
46389
+ "Anchor name cannot contain spaces": "Anchor name cannot contain spaces",
46390
+ "Table": "Table",
46391
+ "Insert table": "Insert table",
46392
+ "Insert row before": "Insert row before",
46393
+ "Insert row after": "Insert row after",
46394
+ "Delete row": "Delete row",
46395
+ "Insert column before": "Insert column before",
46396
+ "Insert column after": "Insert column after",
46397
+ "Delete column": "Delete column",
46398
+ "Merge cells": "Merge cells",
46399
+ "Split cell": "Split cell",
46400
+ "Toggle header row": "Toggle header row",
46401
+ "Delete table": "Delete table"
44934
46402
  };
44935
46403
  const fi = {
44936
46404
  "Bold": "Lihavoitu",
@@ -44988,7 +46456,7 @@ const fi = {
44988
46456
  "Browse...": "Selaa...",
44989
46457
  "Drop image here or click to browse": "Pudota kuva tähän tai napsauta selataksesi",
44990
46458
  "Alt text": "Vaihtoehtoinen teksti",
44991
- "Insert": "Lisää",
46459
+ "Insert": "Lis��",
44992
46460
  "Cancel": "Peruuta",
44993
46461
  "Uploading...": "Ladataan...",
44994
46462
  "Upload failed": "Lataus epäonnistui",
@@ -45002,7 +46470,50 @@ const fi = {
45002
46470
  "Title": "Title",
45003
46471
  "Open link in...": "Open link in...",
45004
46472
  "Current window": "Current window",
45005
- "New window": "New window"
46473
+ "New window": "New window",
46474
+ "Speech to Text": "Puhe tekstiksi",
46475
+ "Dictate": "Sanele",
46476
+ "Start": "Aloita",
46477
+ "Stop": "Lopeta",
46478
+ "Clear": "Tyhjenn�",
46479
+ "Language": "Kieli",
46480
+ "Confidence": "Luotettavuus",
46481
+ "Listening...": "Kuuntelee...",
46482
+ "Speech to text is not supported in this browser": "Puhe tekstiksi ei ole tuettu t�ss� selaimessa",
46483
+ "No speech detected": "Puhetta ei havaittu",
46484
+ "Microphone access denied": "Mikrofonin k�ytt� estetty",
46485
+ "No microphone found": "No microphone found",
46486
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
46487
+ "Subscript": "Alaindeksi",
46488
+ "Superscript": "Yläindeksi",
46489
+ "Horizontal rule": "Vaakaviiva",
46490
+ "Unlink": "Poista linkki",
46491
+ "Format": "Muotoilu",
46492
+ "Paragraph": "Kappale",
46493
+ "Heading 1": "Otsikko 1",
46494
+ "Heading 2": "Otsikko 2",
46495
+ "Heading 3": "Otsikko 3",
46496
+ "Heading 4": "Otsikko 4",
46497
+ "Heading 5": "Otsikko 5",
46498
+ "Heading 6": "Otsikko 6",
46499
+ "Styles": "Tyylit",
46500
+ "Insert anchor": "Lisää ankkuri",
46501
+ "Anchor": "Ankkuri",
46502
+ "Anchor name": "Ankkurin nimi",
46503
+ "Anchor name is required": "Ankkurin nimi vaaditaan",
46504
+ "Anchor name cannot contain spaces": "Ankkurin nimi ei voi sisältää välilyöntejä",
46505
+ "Table": "Taulukko",
46506
+ "Insert table": "Lisää taulukko",
46507
+ "Insert row before": "Lisää rivi ennen",
46508
+ "Insert row after": "Lisää rivi jälkeen",
46509
+ "Delete row": "Poista rivi",
46510
+ "Insert column before": "Lisää sarake ennen",
46511
+ "Insert column after": "Lisää sarake jälkeen",
46512
+ "Delete column": "Poista sarake",
46513
+ "Merge cells": "Yhdistä solut",
46514
+ "Split cell": "Jaa solu",
46515
+ "Toggle header row": "Vaihda otsikkorivi",
46516
+ "Delete table": "Poista taulukko"
45006
46517
  };
45007
46518
  const fr = {
45008
46519
  "Bold": "Gras",
@@ -45060,7 +46571,7 @@ const fr = {
45060
46571
  "Browse...": "Parcourir...",
45061
46572
  "Drop image here or click to browse": "Déposez l'image ici ou cliquez pour parcourir",
45062
46573
  "Alt text": "Texte alternatif",
45063
- "Insert": "Insérer",
46574
+ "Insert": "Ins�rer",
45064
46575
  "Cancel": "Annuler",
45065
46576
  "Uploading...": "Téléchargement...",
45066
46577
  "Upload failed": "Échec du téléchargement",
@@ -45074,7 +46585,50 @@ const fr = {
45074
46585
  "Title": "Title",
45075
46586
  "Open link in...": "Open link in...",
45076
46587
  "Current window": "Current window",
45077
- "New window": "New window"
46588
+ "New window": "New window",
46589
+ "Speech to Text": "Reconnaissance vocale",
46590
+ "Dictate": "Dicter",
46591
+ "Start": "D�marrer",
46592
+ "Stop": "Arr�ter",
46593
+ "Clear": "Effacer",
46594
+ "Language": "Langue",
46595
+ "Confidence": "Confiance",
46596
+ "Listening...": "�coute en cours...",
46597
+ "Speech to text is not supported in this browser": "La reconnaissance vocale n'est pas prise en charge dans ce navigateur",
46598
+ "No speech detected": "Aucune parole d�tect�e",
46599
+ "Microphone access denied": "Acc�s au microphone refus�",
46600
+ "No microphone found": "No microphone found",
46601
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
46602
+ "Subscript": "Indice",
46603
+ "Superscript": "Exposant",
46604
+ "Horizontal rule": "Ligne horizontale",
46605
+ "Unlink": "Supprimer le lien",
46606
+ "Format": "Format",
46607
+ "Paragraph": "Paragraphe",
46608
+ "Heading 1": "Titre 1",
46609
+ "Heading 2": "Titre 2",
46610
+ "Heading 3": "Titre 3",
46611
+ "Heading 4": "Titre 4",
46612
+ "Heading 5": "Titre 5",
46613
+ "Heading 6": "Titre 6",
46614
+ "Styles": "Styles",
46615
+ "Insert anchor": "Insérer une ancre",
46616
+ "Anchor": "Ancre",
46617
+ "Anchor name": "Nom de l'ancre",
46618
+ "Anchor name is required": "Le nom de l'ancre est requis",
46619
+ "Anchor name cannot contain spaces": "Le nom de l'ancre ne peut pas contenir d'espaces",
46620
+ "Table": "Tableau",
46621
+ "Insert table": "Insérer un tableau",
46622
+ "Insert row before": "Insérer une ligne avant",
46623
+ "Insert row after": "Insérer une ligne après",
46624
+ "Delete row": "Supprimer la ligne",
46625
+ "Insert column before": "Insérer une colonne avant",
46626
+ "Insert column after": "Insérer une colonne après",
46627
+ "Delete column": "Supprimer la colonne",
46628
+ "Merge cells": "Fusionner les cellules",
46629
+ "Split cell": "Diviser la cellule",
46630
+ "Toggle header row": "Basculer la ligne d'en-tête",
46631
+ "Delete table": "Supprimer le tableau"
45078
46632
  };
45079
46633
  const frCa = {
45080
46634
  "Bold": "Gras",
@@ -45132,7 +46686,7 @@ const frCa = {
45132
46686
  "Browse...": "Parcourir...",
45133
46687
  "Drop image here or click to browse": "Déposez l'image ici ou cliquez pour parcourir",
45134
46688
  "Alt text": "Texte alternatif",
45135
- "Insert": "Insérer",
46689
+ "Insert": "Ins�rer",
45136
46690
  "Cancel": "Annuler",
45137
46691
  "Uploading...": "Téléversement...",
45138
46692
  "Upload failed": "Échec du téléversement",
@@ -45146,7 +46700,50 @@ const frCa = {
45146
46700
  "Title": "Title",
45147
46701
  "Open link in...": "Open link in...",
45148
46702
  "Current window": "Current window",
45149
- "New window": "New window"
46703
+ "New window": "New window",
46704
+ "Speech to Text": "Reconnaissance vocale",
46705
+ "Dictate": "Dicter",
46706
+ "Start": "D�marrer",
46707
+ "Stop": "Arr�ter",
46708
+ "Clear": "Effacer",
46709
+ "Language": "Langue",
46710
+ "Confidence": "Confiance",
46711
+ "Listening...": "�coute en cours...",
46712
+ "Speech to text is not supported in this browser": "La reconnaissance vocale n'est pas prise en charge dans ce navigateur",
46713
+ "No speech detected": "Aucune parole d�tect�e",
46714
+ "Microphone access denied": "Acc�s au microphone refus�",
46715
+ "No microphone found": "No microphone found",
46716
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
46717
+ "Subscript": "Indice",
46718
+ "Superscript": "Exposant",
46719
+ "Horizontal rule": "Ligne horizontale",
46720
+ "Unlink": "Supprimer le lien",
46721
+ "Format": "Format",
46722
+ "Paragraph": "Paragraphe",
46723
+ "Heading 1": "Titre 1",
46724
+ "Heading 2": "Titre 2",
46725
+ "Heading 3": "Titre 3",
46726
+ "Heading 4": "Titre 4",
46727
+ "Heading 5": "Titre 5",
46728
+ "Heading 6": "Titre 6",
46729
+ "Styles": "Styles",
46730
+ "Insert anchor": "Insérer une ancre",
46731
+ "Anchor": "Ancre",
46732
+ "Anchor name": "Nom de l'ancre",
46733
+ "Anchor name is required": "Le nom de l'ancre est requis",
46734
+ "Anchor name cannot contain spaces": "Le nom de l'ancre ne peut pas contenir d'espaces",
46735
+ "Table": "Tableau",
46736
+ "Insert table": "Insérer un tableau",
46737
+ "Insert row before": "Insérer une ligne avant",
46738
+ "Insert row after": "Insérer une ligne après",
46739
+ "Delete row": "Supprimer la ligne",
46740
+ "Insert column before": "Insérer une colonne avant",
46741
+ "Insert column after": "Insérer une colonne après",
46742
+ "Delete column": "Supprimer la colonne",
46743
+ "Merge cells": "Fusionner les cellules",
46744
+ "Split cell": "Diviser la cellule",
46745
+ "Toggle header row": "Basculer la ligne d'en-tête",
46746
+ "Delete table": "Supprimer le tableau"
45150
46747
  };
45151
46748
  const de = {
45152
46749
  "Bold": "Fett",
@@ -45204,7 +46801,7 @@ const de = {
45204
46801
  "Browse...": "Durchsuchen...",
45205
46802
  "Drop image here or click to browse": "Bild hierher ziehen oder klicken zum Durchsuchen",
45206
46803
  "Alt text": "Alternativtext",
45207
- "Insert": "Einfügen",
46804
+ "Insert": "Einf�gen",
45208
46805
  "Cancel": "Abbrechen",
45209
46806
  "Uploading...": "Wird hochgeladen...",
45210
46807
  "Upload failed": "Hochladen fehlgeschlagen",
@@ -45218,7 +46815,50 @@ const de = {
45218
46815
  "Title": "Title",
45219
46816
  "Open link in...": "Open link in...",
45220
46817
  "Current window": "Current window",
45221
- "New window": "New window"
46818
+ "New window": "New window",
46819
+ "Speech to Text": "Sprache zu Text",
46820
+ "Dictate": "Diktieren",
46821
+ "Start": "Starten",
46822
+ "Stop": "Stoppen",
46823
+ "Clear": "L�schen",
46824
+ "Language": "Sprache",
46825
+ "Confidence": "Zuverl�ssigkeit",
46826
+ "Listening...": "Zuh�ren...",
46827
+ "Speech to text is not supported in this browser": "Sprache-zu-Text wird in diesem Browser nicht unterst�tzt",
46828
+ "No speech detected": "Keine Sprache erkannt",
46829
+ "Microphone access denied": "Mikrofonzugriff verweigert",
46830
+ "No microphone found": "No microphone found",
46831
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
46832
+ "Subscript": "Tiefgestellt",
46833
+ "Superscript": "Hochgestellt",
46834
+ "Horizontal rule": "Horizontale Linie",
46835
+ "Unlink": "Link entfernen",
46836
+ "Format": "Format",
46837
+ "Paragraph": "Absatz",
46838
+ "Heading 1": "Überschrift 1",
46839
+ "Heading 2": "Überschrift 2",
46840
+ "Heading 3": "Überschrift 3",
46841
+ "Heading 4": "Überschrift 4",
46842
+ "Heading 5": "Überschrift 5",
46843
+ "Heading 6": "Überschrift 6",
46844
+ "Styles": "Formatvorlagen",
46845
+ "Insert anchor": "Anker einfügen",
46846
+ "Anchor": "Anker",
46847
+ "Anchor name": "Ankername",
46848
+ "Anchor name is required": "Ankername ist erforderlich",
46849
+ "Anchor name cannot contain spaces": "Ankername darf keine Leerzeichen enthalten",
46850
+ "Table": "Tabelle",
46851
+ "Insert table": "Tabelle einfügen",
46852
+ "Insert row before": "Zeile davor einfügen",
46853
+ "Insert row after": "Zeile danach einfügen",
46854
+ "Delete row": "Zeile löschen",
46855
+ "Insert column before": "Spalte davor einfügen",
46856
+ "Insert column after": "Spalte danach einfügen",
46857
+ "Delete column": "Spalte löschen",
46858
+ "Merge cells": "Zellen verbinden",
46859
+ "Split cell": "Zelle teilen",
46860
+ "Toggle header row": "Kopfzeile umschalten",
46861
+ "Delete table": "Tabelle löschen"
45222
46862
  };
45223
46863
  const el = {
45224
46864
  "Bold": "Έντονα",
@@ -45276,7 +46916,7 @@ const el = {
45276
46916
  "Browse...": "Αναζήτηση...",
45277
46917
  "Drop image here or click to browse": "Σύρτε την εικόνα εδώ ή κάντε κλικ για αναζήτηση",
45278
46918
  "Alt text": "Εναλλακτικό κείμενο",
45279
- "Insert": "Εισαγωγή",
46919
+ "Insert": "??sa????",
45280
46920
  "Cancel": "Ακύρωση",
45281
46921
  "Uploading...": "Μεταφόρτωση...",
45282
46922
  "Upload failed": "Η μεταφόρτωση απέτυχε",
@@ -45290,7 +46930,50 @@ const el = {
45290
46930
  "Title": "Title",
45291
46931
  "Open link in...": "Open link in...",
45292
46932
  "Current window": "Current window",
45293
- "New window": "New window"
46933
+ "New window": "New window",
46934
+ "Speech to Text": "?�???a se ?e?�e??",
46935
+ "Dictate": "Υπαγόρευση",
46936
+ "Start": "??????s?",
46937
+ "Stop": "??a??p?",
46938
+ "Clear": "???a????s?",
46939
+ "Language": "G??ssa",
46940
+ "Confidence": "????p?st?a",
46941
+ "Listening...": "????e?...",
46942
+ "Speech to text is not supported in this browser": "? ?�???a se ?e?�e?? de? ?p?st????eta? se a?t?? t?? pe?????t?",
46943
+ "No speech detected": "?e? a????e????e ?�???a",
46944
+ "Microphone access denied": "? p??s�as? st? �????f??? ap????f???e",
46945
+ "No microphone found": "No microphone found",
46946
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
46947
+ "Subscript": "Δείκτης",
46948
+ "Superscript": "Εκθέτης",
46949
+ "Horizontal rule": "Οριζόντια γραμμή",
46950
+ "Unlink": "Κατάργηση συνδέσμου",
46951
+ "Format": "Μορφή",
46952
+ "Paragraph": "Παράγραφος",
46953
+ "Heading 1": "Επικεφαλίδα 1",
46954
+ "Heading 2": "Επικεφαλίδα 2",
46955
+ "Heading 3": "Επικεφαλίδα 3",
46956
+ "Heading 4": "Επικεφαλίδα 4",
46957
+ "Heading 5": "Επικεφαλίδα 5",
46958
+ "Heading 6": "Επικεφαλίδα 6",
46959
+ "Styles": "Στυλ",
46960
+ "Insert anchor": "Εισαγωγή αγκύρωσης",
46961
+ "Anchor": "Αγκύρωση",
46962
+ "Anchor name": "Όνομα αγκύρωσης",
46963
+ "Anchor name is required": "Απαιτείται όνομα αγκύρωσης",
46964
+ "Anchor name cannot contain spaces": "Το όνομα αγκύρωσης δεν μπορεί να περιέχει κενά",
46965
+ "Table": "Πίνακας",
46966
+ "Insert table": "Εισαγωγή πίνακα",
46967
+ "Insert row before": "Εισαγωγή γραμμής πριν",
46968
+ "Insert row after": "Εισαγωγή γραμμής μετά",
46969
+ "Delete row": "Διαγραφή γραμμής",
46970
+ "Insert column before": "Εισαγωγή στήλης πριν",
46971
+ "Insert column after": "Εισαγωγή στήλης μετά",
46972
+ "Delete column": "Διαγραφή στήλης",
46973
+ "Merge cells": "Συγχώνευση κελιών",
46974
+ "Split cell": "Διαίρεση κελιού",
46975
+ "Toggle header row": "Εναλλαγή γραμμής κεφαλίδας",
46976
+ "Delete table": "Διαγραφή πίνακα"
45294
46977
  };
45295
46978
  const hu = {
45296
46979
  "Bold": "Félkövér",
@@ -45348,7 +47031,7 @@ const hu = {
45348
47031
  "Browse...": "Tallózás...",
45349
47032
  "Drop image here or click to browse": "Húzza ide a képet, vagy kattintson a tallózáshoz",
45350
47033
  "Alt text": "Alternatív szöveg",
45351
- "Insert": "Beszúrás",
47034
+ "Insert": "Besz�r�s",
45352
47035
  "Cancel": "Mégse",
45353
47036
  "Uploading...": "Feltöltés...",
45354
47037
  "Upload failed": "A feltöltés sikertelen",
@@ -45362,7 +47045,50 @@ const hu = {
45362
47045
  "Title": "Title",
45363
47046
  "Open link in...": "Open link in...",
45364
47047
  "Current window": "Current window",
45365
- "New window": "New window"
47048
+ "New window": "New window",
47049
+ "Speech to Text": "Besz�d sz�vegg�",
47050
+ "Dictate": "Diktálás",
47051
+ "Start": "Ind�t�s",
47052
+ "Stop": "Le�ll�t�s",
47053
+ "Clear": "T�rl�s",
47054
+ "Language": "Nyelv",
47055
+ "Confidence": "Megb�zhat�s�g",
47056
+ "Listening...": "Hallgat�s...",
47057
+ "Speech to text is not supported in this browser": "A besz�d sz�vegg� alak�t�s nem t�mogatott ebben a b�ng�szoben",
47058
+ "No speech detected": "Nem �szlelheto besz�d",
47059
+ "Microphone access denied": "Mikrofon hozz�f�r�s megtagadva",
47060
+ "No microphone found": "No microphone found",
47061
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
47062
+ "Subscript": "Alsó index",
47063
+ "Superscript": "Felső index",
47064
+ "Horizontal rule": "Vízszintes vonal",
47065
+ "Unlink": "Hivatkozás eltávolítása",
47066
+ "Format": "Formátum",
47067
+ "Paragraph": "Bekezdés",
47068
+ "Heading 1": "Címsor 1",
47069
+ "Heading 2": "Címsor 2",
47070
+ "Heading 3": "Címsor 3",
47071
+ "Heading 4": "Címsor 4",
47072
+ "Heading 5": "Címsor 5",
47073
+ "Heading 6": "Címsor 6",
47074
+ "Styles": "Stílusok",
47075
+ "Insert anchor": "Horgony beszúrása",
47076
+ "Anchor": "Horgony",
47077
+ "Anchor name": "Horgony neve",
47078
+ "Anchor name is required": "A horgony neve kötelező",
47079
+ "Anchor name cannot contain spaces": "A horgony neve nem tartalmazhat szóközöket",
47080
+ "Table": "Táblázat",
47081
+ "Insert table": "Táblázat beszúrása",
47082
+ "Insert row before": "Sor beszúrása elé",
47083
+ "Insert row after": "Sor beszúrása mögé",
47084
+ "Delete row": "Sor törlése",
47085
+ "Insert column before": "Oszlop beszúrása elé",
47086
+ "Insert column after": "Oszlop beszúrása mögé",
47087
+ "Delete column": "Oszlop törlése",
47088
+ "Merge cells": "Cellák egyesítése",
47089
+ "Split cell": "Cella felosztása",
47090
+ "Toggle header row": "Fejlécsor be-/kikapcsolása",
47091
+ "Delete table": "Táblázat törlése"
45366
47092
  };
45367
47093
  const id = {
45368
47094
  "Bold": "Tebal",
@@ -45434,7 +47160,50 @@ const id = {
45434
47160
  "Title": "Title",
45435
47161
  "Open link in...": "Open link in...",
45436
47162
  "Current window": "Current window",
45437
- "New window": "New window"
47163
+ "New window": "New window",
47164
+ "Speech to Text": "Ucapan ke teks",
47165
+ "Dictate": "Dikte",
47166
+ "Start": "Mulai",
47167
+ "Stop": "Berhenti",
47168
+ "Clear": "Hapus",
47169
+ "Language": "Bahasa",
47170
+ "Confidence": "Kepercayaan",
47171
+ "Listening...": "Mendengarkan...",
47172
+ "Speech to text is not supported in this browser": "Ucapan ke teks tidak didukung di browser ini",
47173
+ "No speech detected": "Tidak ada ucapan terdeteksi",
47174
+ "Microphone access denied": "Akses mikrofon ditolak",
47175
+ "No microphone found": "No microphone found",
47176
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
47177
+ "Subscript": "Subskrip",
47178
+ "Superscript": "Superskrip",
47179
+ "Horizontal rule": "Garis horizontal",
47180
+ "Unlink": "Hapus tautan",
47181
+ "Format": "Format",
47182
+ "Paragraph": "Paragraf",
47183
+ "Heading 1": "Judul 1",
47184
+ "Heading 2": "Judul 2",
47185
+ "Heading 3": "Judul 3",
47186
+ "Heading 4": "Judul 4",
47187
+ "Heading 5": "Judul 5",
47188
+ "Heading 6": "Judul 6",
47189
+ "Styles": "Gaya",
47190
+ "Insert anchor": "Sisipkan jangkar",
47191
+ "Anchor": "Jangkar",
47192
+ "Anchor name": "Nama jangkar",
47193
+ "Anchor name is required": "Nama jangkar wajib diisi",
47194
+ "Anchor name cannot contain spaces": "Nama jangkar tidak boleh mengandung spasi",
47195
+ "Table": "Tabel",
47196
+ "Insert table": "Sisipkan tabel",
47197
+ "Insert row before": "Sisipkan baris sebelum",
47198
+ "Insert row after": "Sisipkan baris sesudah",
47199
+ "Delete row": "Hapus baris",
47200
+ "Insert column before": "Sisipkan kolom sebelum",
47201
+ "Insert column after": "Sisipkan kolom sesudah",
47202
+ "Delete column": "Hapus kolom",
47203
+ "Merge cells": "Gabungkan sel",
47204
+ "Split cell": "Pisahkan sel",
47205
+ "Toggle header row": "Alihkan baris header",
47206
+ "Delete table": "Hapus tabel"
45438
47207
  };
45439
47208
  const it = {
45440
47209
  "Bold": "Grassetto",
@@ -45506,7 +47275,50 @@ const it = {
45506
47275
  "Title": "Title",
45507
47276
  "Open link in...": "Open link in...",
45508
47277
  "Current window": "Current window",
45509
- "New window": "New window"
47278
+ "New window": "New window",
47279
+ "Speech to Text": "Riconoscimento vocale",
47280
+ "Dictate": "Dettare",
47281
+ "Start": "Avvia",
47282
+ "Stop": "Ferma",
47283
+ "Clear": "Cancella",
47284
+ "Language": "Lingua",
47285
+ "Confidence": "Affidabilit�",
47286
+ "Listening...": "Ascolto in corso...",
47287
+ "Speech to text is not supported in this browser": "Il riconoscimento vocale non � supportato in questo browser",
47288
+ "No speech detected": "Nessun discorso rilevato",
47289
+ "Microphone access denied": "Accesso al microfono negato",
47290
+ "No microphone found": "No microphone found",
47291
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
47292
+ "Subscript": "Pedice",
47293
+ "Superscript": "Apice",
47294
+ "Horizontal rule": "Linea orizzontale",
47295
+ "Unlink": "Rimuovi collegamento",
47296
+ "Format": "Formato",
47297
+ "Paragraph": "Paragrafo",
47298
+ "Heading 1": "Titolo 1",
47299
+ "Heading 2": "Titolo 2",
47300
+ "Heading 3": "Titolo 3",
47301
+ "Heading 4": "Titolo 4",
47302
+ "Heading 5": "Titolo 5",
47303
+ "Heading 6": "Titolo 6",
47304
+ "Styles": "Stili",
47305
+ "Insert anchor": "Inserisci ancora",
47306
+ "Anchor": "Ancora",
47307
+ "Anchor name": "Nome ancora",
47308
+ "Anchor name is required": "Il nome dell'ancora è obbligatorio",
47309
+ "Anchor name cannot contain spaces": "Il nome dell'ancora non può contenere spazi",
47310
+ "Table": "Tabella",
47311
+ "Insert table": "Inserisci tabella",
47312
+ "Insert row before": "Inserisci riga prima",
47313
+ "Insert row after": "Inserisci riga dopo",
47314
+ "Delete row": "Elimina riga",
47315
+ "Insert column before": "Inserisci colonna prima",
47316
+ "Insert column after": "Inserisci colonna dopo",
47317
+ "Delete column": "Elimina colonna",
47318
+ "Merge cells": "Unisci celle",
47319
+ "Split cell": "Dividi cella",
47320
+ "Toggle header row": "Attiva/disattiva riga di intestazione",
47321
+ "Delete table": "Elimina tabella"
45510
47322
  };
45511
47323
  const ja = {
45512
47324
  "Bold": "太字",
@@ -45564,7 +47376,7 @@ const ja = {
45564
47376
  "Browse...": "参照...",
45565
47377
  "Drop image here or click to browse": "画像をここにドロップするかクリックして参照",
45566
47378
  "Alt text": "代替テキスト",
45567
- "Insert": "挿入",
47379
+ "Insert": "??",
45568
47380
  "Cancel": "キャンセル",
45569
47381
  "Uploading...": "アップロード中...",
45570
47382
  "Upload failed": "アップロードに失敗しました",
@@ -45578,7 +47390,50 @@ const ja = {
45578
47390
  "Title": "Title",
45579
47391
  "Open link in...": "Open link in...",
45580
47392
  "Current window": "Current window",
45581
- "New window": "New window"
47393
+ "New window": "New window",
47394
+ "Speech to Text": "????",
47395
+ "Dictate": "音声入力",
47396
+ "Start": "??",
47397
+ "Stop": "??",
47398
+ "Clear": "???",
47399
+ "Language": "??",
47400
+ "Confidence": "???",
47401
+ "Listening...": "?????...",
47402
+ "Speech to text is not supported in this browser": "????????????????????????",
47403
+ "No speech detected": "?????????????",
47404
+ "Microphone access denied": "?????????????????",
47405
+ "No microphone found": "No microphone found",
47406
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
47407
+ "Subscript": "下付き文字",
47408
+ "Superscript": "上付き文字",
47409
+ "Horizontal rule": "水平線",
47410
+ "Unlink": "リンクの解除",
47411
+ "Format": "書式",
47412
+ "Paragraph": "段落",
47413
+ "Heading 1": "見出し 1",
47414
+ "Heading 2": "見出し 2",
47415
+ "Heading 3": "見出し 3",
47416
+ "Heading 4": "見出し 4",
47417
+ "Heading 5": "見出し 5",
47418
+ "Heading 6": "見出し 6",
47419
+ "Styles": "スタイル",
47420
+ "Insert anchor": "アンカーの挿入",
47421
+ "Anchor": "アンカー",
47422
+ "Anchor name": "アンカー名",
47423
+ "Anchor name is required": "アンカー名は必須です",
47424
+ "Anchor name cannot contain spaces": "アンカー名にスペースを含めることはできません",
47425
+ "Table": "テーブル",
47426
+ "Insert table": "テーブルの挿入",
47427
+ "Insert row before": "上に行を挿入",
47428
+ "Insert row after": "下に行を挿入",
47429
+ "Delete row": "行の削除",
47430
+ "Insert column before": "左に列を挿入",
47431
+ "Insert column after": "右に列を挿入",
47432
+ "Delete column": "列の削除",
47433
+ "Merge cells": "セルの結合",
47434
+ "Split cell": "セルの分割",
47435
+ "Toggle header row": "ヘッダー行の切り替え",
47436
+ "Delete table": "テーブルの削除"
45582
47437
  };
45583
47438
  const ko = {
45584
47439
  "Bold": "굵게",
@@ -45636,7 +47491,7 @@ const ko = {
45636
47491
  "Browse...": "찾아보기...",
45637
47492
  "Drop image here or click to browse": "이미지를 여기에 끌어다 놓거나 클릭하여 찾아보기",
45638
47493
  "Alt text": "대체 텍스트",
45639
- "Insert": "삽입",
47494
+ "Insert": "??",
45640
47495
  "Cancel": "취소",
45641
47496
  "Uploading...": "업로드 중...",
45642
47497
  "Upload failed": "업로드 실패",
@@ -45650,7 +47505,50 @@ const ko = {
45650
47505
  "Title": "Title",
45651
47506
  "Open link in...": "Open link in...",
45652
47507
  "Current window": "Current window",
45653
- "New window": "New window"
47508
+ "New window": "New window",
47509
+ "Speech to Text": "?? ??",
47510
+ "Dictate": "받아쓰기",
47511
+ "Start": "??",
47512
+ "Stop": "??",
47513
+ "Clear": "???",
47514
+ "Language": "??",
47515
+ "Confidence": "???",
47516
+ "Listening...": "?? ?...",
47517
+ "Speech to text is not supported in this browser": "? ??????? ?? ??? ???? ????",
47518
+ "No speech detected": "??? ???? ?????",
47519
+ "Microphone access denied": "??? ??? ???????",
47520
+ "No microphone found": "No microphone found",
47521
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
47522
+ "Subscript": "아래 첨자",
47523
+ "Superscript": "위 첨자",
47524
+ "Horizontal rule": "가로줄",
47525
+ "Unlink": "링크 제거",
47526
+ "Format": "형식",
47527
+ "Paragraph": "단락",
47528
+ "Heading 1": "제목 1",
47529
+ "Heading 2": "제목 2",
47530
+ "Heading 3": "제목 3",
47531
+ "Heading 4": "제목 4",
47532
+ "Heading 5": "제목 5",
47533
+ "Heading 6": "제목 6",
47534
+ "Styles": "스타일",
47535
+ "Insert anchor": "앵커 삽입",
47536
+ "Anchor": "앵커",
47537
+ "Anchor name": "앵커 이름",
47538
+ "Anchor name is required": "앵커 이름은 필수입니다",
47539
+ "Anchor name cannot contain spaces": "앵커 이름에 공백을 포함할 수 없습니다",
47540
+ "Table": "표",
47541
+ "Insert table": "표 삽입",
47542
+ "Insert row before": "위에 행 삽입",
47543
+ "Insert row after": "아래에 행 삽입",
47544
+ "Delete row": "행 삭제",
47545
+ "Insert column before": "왼쪽에 열 삽입",
47546
+ "Insert column after": "오른쪽에 열 삽입",
47547
+ "Delete column": "열 삭제",
47548
+ "Merge cells": "셀 병합",
47549
+ "Split cell": "셀 분할",
47550
+ "Toggle header row": "머리글 행 전환",
47551
+ "Delete table": "표 삭제"
45654
47552
  };
45655
47553
  const nl = {
45656
47554
  "Bold": "Vet",
@@ -45722,7 +47620,50 @@ const nl = {
45722
47620
  "Title": "Title",
45723
47621
  "Open link in...": "Open link in...",
45724
47622
  "Current window": "Current window",
45725
- "New window": "New window"
47623
+ "New window": "New window",
47624
+ "Speech to Text": "Spraak naar tekst",
47625
+ "Dictate": "Dicteren",
47626
+ "Start": "Starten",
47627
+ "Stop": "Stoppen",
47628
+ "Clear": "Wissen",
47629
+ "Language": "Taal",
47630
+ "Confidence": "Betrouwbaarheid",
47631
+ "Listening...": "Luisteren...",
47632
+ "Speech to text is not supported in this browser": "Spraak naar tekst wordt niet ondersteund in deze browser",
47633
+ "No speech detected": "Geen spraak gedetecteerd",
47634
+ "Microphone access denied": "Toegang tot microfoon geweigerd",
47635
+ "No microphone found": "No microphone found",
47636
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
47637
+ "Subscript": "Subscript",
47638
+ "Superscript": "Superscript",
47639
+ "Horizontal rule": "Horizontale lijn",
47640
+ "Unlink": "Link verwijderen",
47641
+ "Format": "Opmaak",
47642
+ "Paragraph": "Alinea",
47643
+ "Heading 1": "Kop 1",
47644
+ "Heading 2": "Kop 2",
47645
+ "Heading 3": "Kop 3",
47646
+ "Heading 4": "Kop 4",
47647
+ "Heading 5": "Kop 5",
47648
+ "Heading 6": "Kop 6",
47649
+ "Styles": "Stijlen",
47650
+ "Insert anchor": "Anker invoegen",
47651
+ "Anchor": "Anker",
47652
+ "Anchor name": "Ankernaam",
47653
+ "Anchor name is required": "Ankernaam is verplicht",
47654
+ "Anchor name cannot contain spaces": "Ankernaam mag geen spaties bevatten",
47655
+ "Table": "Tabel",
47656
+ "Insert table": "Tabel invoegen",
47657
+ "Insert row before": "Rij ervoor invoegen",
47658
+ "Insert row after": "Rij erna invoegen",
47659
+ "Delete row": "Rij verwijderen",
47660
+ "Insert column before": "Kolom ervoor invoegen",
47661
+ "Insert column after": "Kolom erna invoegen",
47662
+ "Delete column": "Kolom verwijderen",
47663
+ "Merge cells": "Cellen samenvoegen",
47664
+ "Split cell": "Cel splitsen",
47665
+ "Toggle header row": "Koprij in-/uitschakelen",
47666
+ "Delete table": "Tabel verwijderen"
45726
47667
  };
45727
47668
  const nb = {
45728
47669
  "Bold": "Fet",
@@ -45794,7 +47735,50 @@ const nb = {
45794
47735
  "Title": "Title",
45795
47736
  "Open link in...": "Open link in...",
45796
47737
  "Current window": "Current window",
45797
- "New window": "New window"
47738
+ "New window": "New window",
47739
+ "Speech to Text": "Tale til tekst",
47740
+ "Dictate": "Dikter",
47741
+ "Start": "Start",
47742
+ "Stop": "Stopp",
47743
+ "Clear": "T�m",
47744
+ "Language": "Spr�k",
47745
+ "Confidence": "P�litelighet",
47746
+ "Listening...": "Lytter...",
47747
+ "Speech to text is not supported in this browser": "Tale til tekst st�ttes ikke i denne nettleseren",
47748
+ "No speech detected": "Ingen tale oppdaget",
47749
+ "Microphone access denied": "Mikrofontilgang nektet",
47750
+ "No microphone found": "No microphone found",
47751
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
47752
+ "Subscript": "Senket skrift",
47753
+ "Superscript": "Hevet skrift",
47754
+ "Horizontal rule": "Horisontal linje",
47755
+ "Unlink": "Fjern lenke",
47756
+ "Format": "Format",
47757
+ "Paragraph": "Avsnitt",
47758
+ "Heading 1": "Overskrift 1",
47759
+ "Heading 2": "Overskrift 2",
47760
+ "Heading 3": "Overskrift 3",
47761
+ "Heading 4": "Overskrift 4",
47762
+ "Heading 5": "Overskrift 5",
47763
+ "Heading 6": "Overskrift 6",
47764
+ "Styles": "Stiler",
47765
+ "Insert anchor": "Sett inn anker",
47766
+ "Anchor": "Anker",
47767
+ "Anchor name": "Ankernavn",
47768
+ "Anchor name is required": "Ankernavn er påkrevd",
47769
+ "Anchor name cannot contain spaces": "Ankernavn kan ikke inneholde mellomrom",
47770
+ "Table": "Tabell",
47771
+ "Insert table": "Sett inn tabell",
47772
+ "Insert row before": "Sett inn rad før",
47773
+ "Insert row after": "Sett inn rad etter",
47774
+ "Delete row": "Slett rad",
47775
+ "Insert column before": "Sett inn kolonne før",
47776
+ "Insert column after": "Sett inn kolonne etter",
47777
+ "Delete column": "Slett kolonne",
47778
+ "Merge cells": "Slå sammen celler",
47779
+ "Split cell": "Del celle",
47780
+ "Toggle header row": "Veksle overskriftsrad",
47781
+ "Delete table": "Slett tabell"
45798
47782
  };
45799
47783
  const pl = {
45800
47784
  "Bold": "Pogrubienie",
@@ -45866,7 +47850,50 @@ const pl = {
45866
47850
  "Title": "Title",
45867
47851
  "Open link in...": "Open link in...",
45868
47852
  "Current window": "Current window",
45869
- "New window": "New window"
47853
+ "New window": "New window",
47854
+ "Speech to Text": "Mowa na tekst",
47855
+ "Dictate": "Dyktuj",
47856
+ "Start": "Rozpocznij",
47857
+ "Stop": "Zatrzymaj",
47858
+ "Clear": "Wyczysc",
47859
+ "Language": "Jezyk",
47860
+ "Confidence": "Pewnosc",
47861
+ "Listening...": "Nasluchiwanie...",
47862
+ "Speech to text is not supported in this browser": "Mowa na tekst nie jest obslugiwana w tej przegladarce",
47863
+ "No speech detected": "Nie wykryto mowy",
47864
+ "Microphone access denied": "Odmowa dostepu do mikrofonu",
47865
+ "No microphone found": "No microphone found",
47866
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
47867
+ "Subscript": "Indeks dolny",
47868
+ "Superscript": "Indeks górny",
47869
+ "Horizontal rule": "Linia pozioma",
47870
+ "Unlink": "Usuń odnośnik",
47871
+ "Format": "Format",
47872
+ "Paragraph": "Akapit",
47873
+ "Heading 1": "Nagłówek 1",
47874
+ "Heading 2": "Nagłówek 2",
47875
+ "Heading 3": "Nagłówek 3",
47876
+ "Heading 4": "Nagłówek 4",
47877
+ "Heading 5": "Nagłówek 5",
47878
+ "Heading 6": "Nagłówek 6",
47879
+ "Styles": "Style",
47880
+ "Insert anchor": "Wstaw kotwicę",
47881
+ "Anchor": "Kotwica",
47882
+ "Anchor name": "Nazwa kotwicy",
47883
+ "Anchor name is required": "Nazwa kotwicy jest wymagana",
47884
+ "Anchor name cannot contain spaces": "Nazwa kotwicy nie może zawierać spacji",
47885
+ "Table": "Tabela",
47886
+ "Insert table": "Wstaw tabelę",
47887
+ "Insert row before": "Wstaw wiersz przed",
47888
+ "Insert row after": "Wstaw wiersz po",
47889
+ "Delete row": "Usuń wiersz",
47890
+ "Insert column before": "Wstaw kolumnę przed",
47891
+ "Insert column after": "Wstaw kolumnę po",
47892
+ "Delete column": "Usuń kolumnę",
47893
+ "Merge cells": "Scal komórki",
47894
+ "Split cell": "Podziel komórkę",
47895
+ "Toggle header row": "Przełącz wiersz nagłówka",
47896
+ "Delete table": "Usuń tabelę"
45870
47897
  };
45871
47898
  const pt = {
45872
47899
  "Bold": "Negrito",
@@ -45938,7 +47965,50 @@ const pt = {
45938
47965
  "Title": "Title",
45939
47966
  "Open link in...": "Open link in...",
45940
47967
  "Current window": "Current window",
45941
- "New window": "New window"
47968
+ "New window": "New window",
47969
+ "Speech to Text": "Voz para texto",
47970
+ "Dictate": "Ditar",
47971
+ "Start": "Iniciar",
47972
+ "Stop": "Parar",
47973
+ "Clear": "Limpar",
47974
+ "Language": "Idioma",
47975
+ "Confidence": "Confian�a",
47976
+ "Listening...": "Ouvindo...",
47977
+ "Speech to text is not supported in this browser": "Voz para texto n�o � suportado neste navegador",
47978
+ "No speech detected": "Nenhuma fala detectada",
47979
+ "Microphone access denied": "Acesso ao microfone negado",
47980
+ "No microphone found": "No microphone found",
47981
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
47982
+ "Subscript": "Subscrito",
47983
+ "Superscript": "Sobrescrito",
47984
+ "Horizontal rule": "Linha horizontal",
47985
+ "Unlink": "Remover link",
47986
+ "Format": "Formato",
47987
+ "Paragraph": "Parágrafo",
47988
+ "Heading 1": "Título 1",
47989
+ "Heading 2": "Título 2",
47990
+ "Heading 3": "Título 3",
47991
+ "Heading 4": "Título 4",
47992
+ "Heading 5": "Título 5",
47993
+ "Heading 6": "Título 6",
47994
+ "Styles": "Estilos",
47995
+ "Insert anchor": "Inserir âncora",
47996
+ "Anchor": "Âncora",
47997
+ "Anchor name": "Nome da âncora",
47998
+ "Anchor name is required": "O nome da âncora é obrigatório",
47999
+ "Anchor name cannot contain spaces": "O nome da âncora não pode conter espaços",
48000
+ "Table": "Tabela",
48001
+ "Insert table": "Inserir tabela",
48002
+ "Insert row before": "Inserir linha antes",
48003
+ "Insert row after": "Inserir linha depois",
48004
+ "Delete row": "Excluir linha",
48005
+ "Insert column before": "Inserir coluna antes",
48006
+ "Insert column after": "Inserir coluna depois",
48007
+ "Delete column": "Excluir coluna",
48008
+ "Merge cells": "Mesclar células",
48009
+ "Split cell": "Dividir célula",
48010
+ "Toggle header row": "Alternar linha de cabeçalho",
48011
+ "Delete table": "Excluir tabela"
45942
48012
  };
45943
48013
  const ro = {
45944
48014
  "Bold": "Îngroșat",
@@ -45996,7 +48066,7 @@ const ro = {
45996
48066
  "Browse...": "Răsfoiește...",
45997
48067
  "Drop image here or click to browse": "Trage imaginea aici sau dă clic pentru a răsfoi",
45998
48068
  "Alt text": "Text alternativ",
45999
- "Insert": "Inserează",
48069
+ "Insert": "Inserare",
46000
48070
  "Cancel": "Anulează",
46001
48071
  "Uploading...": "Se încarcă...",
46002
48072
  "Upload failed": "Încarcare eșuată",
@@ -46010,7 +48080,50 @@ const ro = {
46010
48080
  "Title": "Title",
46011
48081
  "Open link in...": "Open link in...",
46012
48082
  "Current window": "Current window",
46013
- "New window": "New window"
48083
+ "New window": "New window",
48084
+ "Speech to Text": "Voce �n text",
48085
+ "Dictate": "Dictare",
48086
+ "Start": "Pornire",
48087
+ "Stop": "Oprire",
48088
+ "Clear": "?tergere",
48089
+ "Language": "Limba",
48090
+ "Confidence": "�ncredere",
48091
+ "Listening...": "Ascultare...",
48092
+ "Speech to text is not supported in this browser": "Voce �n text nu este acceptata �n acest browser",
48093
+ "No speech detected": "Nu a fost detectata nicio voce",
48094
+ "Microphone access denied": "Accesul la microfon a fost refuzat",
48095
+ "No microphone found": "No microphone found",
48096
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
48097
+ "Subscript": "Indice",
48098
+ "Superscript": "Exponent",
48099
+ "Horizontal rule": "Linie orizontală",
48100
+ "Unlink": "Eliminare link",
48101
+ "Format": "Format",
48102
+ "Paragraph": "Paragraf",
48103
+ "Heading 1": "Titlu 1",
48104
+ "Heading 2": "Titlu 2",
48105
+ "Heading 3": "Titlu 3",
48106
+ "Heading 4": "Titlu 4",
48107
+ "Heading 5": "Titlu 5",
48108
+ "Heading 6": "Titlu 6",
48109
+ "Styles": "Stiluri",
48110
+ "Insert anchor": "Inserare ancoră",
48111
+ "Anchor": "Ancoră",
48112
+ "Anchor name": "Nume ancoră",
48113
+ "Anchor name is required": "Numele ancorei este obligatoriu",
48114
+ "Anchor name cannot contain spaces": "Numele ancorei nu poate conține spații",
48115
+ "Table": "Tabel",
48116
+ "Insert table": "Inserare tabel",
48117
+ "Insert row before": "Inserare rând înainte",
48118
+ "Insert row after": "Inserare rând după",
48119
+ "Delete row": "Ștergere rând",
48120
+ "Insert column before": "Inserare coloană înainte",
48121
+ "Insert column after": "Inserare coloană după",
48122
+ "Delete column": "Ștergere coloană",
48123
+ "Merge cells": "Îmbinare celule",
48124
+ "Split cell": "Divizare celulă",
48125
+ "Toggle header row": "Comutare rând antet",
48126
+ "Delete table": "Ștergere tabel"
46014
48127
  };
46015
48128
  const ru = {
46016
48129
  "Bold": "Полужирный",
@@ -46068,7 +48181,7 @@ const ru = {
46068
48181
  "Browse...": "Обзор...",
46069
48182
  "Drop image here or click to browse": "Перетащите изображение сюда или нажмите для обзора",
46070
48183
  "Alt text": "Альтернативный текст",
46071
- "Insert": "Вставить",
48184
+ "Insert": "????????",
46072
48185
  "Cancel": "Отмена",
46073
48186
  "Uploading...": "Загрузка...",
46074
48187
  "Upload failed": "Ошибка загрузки",
@@ -46082,7 +48195,50 @@ const ru = {
46082
48195
  "Title": "Title",
46083
48196
  "Open link in...": "Open link in...",
46084
48197
  "Current window": "Current window",
46085
- "New window": "New window"
48198
+ "New window": "New window",
48199
+ "Speech to Text": "????? ? ?????",
48200
+ "Dictate": "Диктовать",
48201
+ "Start": "??????",
48202
+ "Stop": "??????????",
48203
+ "Clear": "????????",
48204
+ "Language": "????",
48205
+ "Confidence": "????????",
48206
+ "Listening...": "??????...",
48207
+ "Speech to text is not supported in this browser": "????????? ???? ?? ?????????????? ? ???? ????????",
48208
+ "No speech detected": "???? ?? ??????????",
48209
+ "Microphone access denied": "?????? ? ????????? ????????",
48210
+ "No microphone found": "No microphone found",
48211
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
48212
+ "Subscript": "Подстрочный",
48213
+ "Superscript": "Надстрочный",
48214
+ "Horizontal rule": "Горизонтальная линия",
48215
+ "Unlink": "Удалить ссылку",
48216
+ "Format": "Формат",
48217
+ "Paragraph": "Абзац",
48218
+ "Heading 1": "Заголовок 1",
48219
+ "Heading 2": "Заголовок 2",
48220
+ "Heading 3": "Заголовок 3",
48221
+ "Heading 4": "Заголовок 4",
48222
+ "Heading 5": "Заголовок 5",
48223
+ "Heading 6": "Заголовок 6",
48224
+ "Styles": "Стили",
48225
+ "Insert anchor": "Вставить якорь",
48226
+ "Anchor": "Якорь",
48227
+ "Anchor name": "Имя якоря",
48228
+ "Anchor name is required": "Требуется имя якоря",
48229
+ "Anchor name cannot contain spaces": "Имя якоря не может содержать пробелы",
48230
+ "Table": "Таблица",
48231
+ "Insert table": "Вставить таблицу",
48232
+ "Insert row before": "Вставить строку выше",
48233
+ "Insert row after": "Вставить строку ниже",
48234
+ "Delete row": "Удалить строку",
48235
+ "Insert column before": "Вставить столбец слева",
48236
+ "Insert column after": "Вставить столбец справа",
48237
+ "Delete column": "Удалить столбец",
48238
+ "Merge cells": "Объединить ячейки",
48239
+ "Split cell": "Разделить ячейку",
48240
+ "Toggle header row": "Переключить строку заголовка",
48241
+ "Delete table": "Удалить таблицу"
46086
48242
  };
46087
48243
  const sr = {
46088
48244
  "Bold": "Подебљано",
@@ -46140,7 +48296,7 @@ const sr = {
46140
48296
  "Browse...": "Претражи...",
46141
48297
  "Drop image here or click to browse": "Превуците слику овде или кликните за претрагу",
46142
48298
  "Alt text": "Алтернативни текст",
46143
- "Insert": "Уметни",
48299
+ "Insert": "?????",
46144
48300
  "Cancel": "Откажи",
46145
48301
  "Uploading...": "Отпремање...",
46146
48302
  "Upload failed": "Отпремање није успело",
@@ -46154,7 +48310,50 @@ const sr = {
46154
48310
  "Title": "Title",
46155
48311
  "Open link in...": "Open link in...",
46156
48312
  "Current window": "Current window",
46157
- "New window": "New window"
48313
+ "New window": "New window",
48314
+ "Speech to Text": "????? ? ?????",
48315
+ "Dictate": "Диктирање",
48316
+ "Start": "???????",
48317
+ "Stop": "????????",
48318
+ "Clear": "??????",
48319
+ "Language": "?????",
48320
+ "Confidence": "??????????",
48321
+ "Listening...": "??????...",
48322
+ "Speech to text is not supported in this browser": "????? ? ????? ???? ??????? ? ???? ??????????",
48323
+ "No speech detected": "????? ???? ????????",
48324
+ "Microphone access denied": "??????? ????????? ???????",
48325
+ "No microphone found": "No microphone found",
48326
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
48327
+ "Subscript": "Индекс",
48328
+ "Superscript": "Експонент",
48329
+ "Horizontal rule": "Хоризонтална линија",
48330
+ "Unlink": "Уклони везу",
48331
+ "Format": "Формат",
48332
+ "Paragraph": "Пасус",
48333
+ "Heading 1": "Наслов 1",
48334
+ "Heading 2": "Наслов 2",
48335
+ "Heading 3": "Наслов 3",
48336
+ "Heading 4": "Наслов 4",
48337
+ "Heading 5": "Наслов 5",
48338
+ "Heading 6": "Наслов 6",
48339
+ "Styles": "Стилови",
48340
+ "Insert anchor": "Уметни сидро",
48341
+ "Anchor": "Сидро",
48342
+ "Anchor name": "Назив сидра",
48343
+ "Anchor name is required": "Назив сидра је обавезан",
48344
+ "Anchor name cannot contain spaces": "Назив сидра не може садржати размаке",
48345
+ "Table": "Табела",
48346
+ "Insert table": "Уметни табелу",
48347
+ "Insert row before": "Уметни ред изнад",
48348
+ "Insert row after": "Уметни ред испод",
48349
+ "Delete row": "Обриши ред",
48350
+ "Insert column before": "Уметни колону лево",
48351
+ "Insert column after": "Уметни колону десно",
48352
+ "Delete column": "Обриши колону",
48353
+ "Merge cells": "Споји ћелије",
48354
+ "Split cell": "Подели ћелију",
48355
+ "Toggle header row": "Укључи/искључи ред заглавља",
48356
+ "Delete table": "Обриши табелу"
46158
48357
  };
46159
48358
  const sl = {
46160
48359
  "Bold": "Krepko",
@@ -46226,7 +48425,50 @@ const sl = {
46226
48425
  "Title": "Title",
46227
48426
  "Open link in...": "Open link in...",
46228
48427
  "Current window": "Current window",
46229
- "New window": "New window"
48428
+ "New window": "New window",
48429
+ "Speech to Text": "Govor v besedilo",
48430
+ "Dictate": "Narekovanje",
48431
+ "Start": "Zacni",
48432
+ "Stop": "Ustavi",
48433
+ "Clear": "Pocisti",
48434
+ "Language": "Jezik",
48435
+ "Confidence": "Zaupanje",
48436
+ "Listening...": "Poslu�am...",
48437
+ "Speech to text is not supported in this browser": "Govor v besedilo ni podprt v tem brskalniku",
48438
+ "No speech detected": "Govor ni bil zaznan",
48439
+ "Microphone access denied": "Dostop do mikrofona zavrnjen",
48440
+ "No microphone found": "No microphone found",
48441
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
48442
+ "Subscript": "Podpisano",
48443
+ "Superscript": "Nadpisano",
48444
+ "Horizontal rule": "Vodoravna črta",
48445
+ "Unlink": "Odstrani povezavo",
48446
+ "Format": "Oblika",
48447
+ "Paragraph": "Odstavek",
48448
+ "Heading 1": "Naslov 1",
48449
+ "Heading 2": "Naslov 2",
48450
+ "Heading 3": "Naslov 3",
48451
+ "Heading 4": "Naslov 4",
48452
+ "Heading 5": "Naslov 5",
48453
+ "Heading 6": "Naslov 6",
48454
+ "Styles": "Slogi",
48455
+ "Insert anchor": "Vstavi sidro",
48456
+ "Anchor": "Sidro",
48457
+ "Anchor name": "Ime sidra",
48458
+ "Anchor name is required": "Ime sidra je obvezno",
48459
+ "Anchor name cannot contain spaces": "Ime sidra ne sme vsebovati presledkov",
48460
+ "Table": "Tabela",
48461
+ "Insert table": "Vstavi tabelo",
48462
+ "Insert row before": "Vstavi vrstico pred",
48463
+ "Insert row after": "Vstavi vrstico za",
48464
+ "Delete row": "Izbriši vrstico",
48465
+ "Insert column before": "Vstavi stolpec pred",
48466
+ "Insert column after": "Vstavi stolpec za",
48467
+ "Delete column": "Izbriši stolpec",
48468
+ "Merge cells": "Združi celice",
48469
+ "Split cell": "Razdeli celico",
48470
+ "Toggle header row": "Preklopi vrstico glave",
48471
+ "Delete table": "Izbriši tabelo"
46230
48472
  };
46231
48473
  const es = {
46232
48474
  "Bold": "Negrita",
@@ -46298,7 +48540,50 @@ const es = {
46298
48540
  "Title": "Title",
46299
48541
  "Open link in...": "Open link in...",
46300
48542
  "Current window": "Current window",
46301
- "New window": "New window"
48543
+ "New window": "New window",
48544
+ "Speech to Text": "Voz a texto",
48545
+ "Dictate": "Dictar",
48546
+ "Start": "Iniciar",
48547
+ "Stop": "Detener",
48548
+ "Clear": "Borrar",
48549
+ "Language": "Idioma",
48550
+ "Confidence": "Confianza",
48551
+ "Listening...": "Escuchando...",
48552
+ "Speech to text is not supported in this browser": "La voz a texto no es compatible con este navegador",
48553
+ "No speech detected": "No se detect� voz",
48554
+ "Microphone access denied": "Acceso al micr�fono denegado",
48555
+ "No microphone found": "No microphone found",
48556
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
48557
+ "Subscript": "Subíndice",
48558
+ "Superscript": "Superíndice",
48559
+ "Horizontal rule": "Línea horizontal",
48560
+ "Unlink": "Quitar enlace",
48561
+ "Format": "Formato",
48562
+ "Paragraph": "Párrafo",
48563
+ "Heading 1": "Encabezado 1",
48564
+ "Heading 2": "Encabezado 2",
48565
+ "Heading 3": "Encabezado 3",
48566
+ "Heading 4": "Encabezado 4",
48567
+ "Heading 5": "Encabezado 5",
48568
+ "Heading 6": "Encabezado 6",
48569
+ "Styles": "Estilos",
48570
+ "Insert anchor": "Insertar ancla",
48571
+ "Anchor": "Ancla",
48572
+ "Anchor name": "Nombre del ancla",
48573
+ "Anchor name is required": "El nombre del ancla es obligatorio",
48574
+ "Anchor name cannot contain spaces": "El nombre del ancla no puede contener espacios",
48575
+ "Table": "Tabla",
48576
+ "Insert table": "Insertar tabla",
48577
+ "Insert row before": "Insertar fila antes",
48578
+ "Insert row after": "Insertar fila después",
48579
+ "Delete row": "Eliminar fila",
48580
+ "Insert column before": "Insertar columna antes",
48581
+ "Insert column after": "Insertar columna después",
48582
+ "Delete column": "Eliminar columna",
48583
+ "Merge cells": "Combinar celdas",
48584
+ "Split cell": "Dividir celda",
48585
+ "Toggle header row": "Alternar fila de encabezado",
48586
+ "Delete table": "Eliminar tabla"
46302
48587
  };
46303
48588
  const sv = {
46304
48589
  "Bold": "Fet",
@@ -46370,7 +48655,50 @@ const sv = {
46370
48655
  "Title": "Title",
46371
48656
  "Open link in...": "Open link in...",
46372
48657
  "Current window": "Current window",
46373
- "New window": "New window"
48658
+ "New window": "New window",
48659
+ "Speech to Text": "Tal till text",
48660
+ "Dictate": "Diktera",
48661
+ "Start": "Starta",
48662
+ "Stop": "Stoppa",
48663
+ "Clear": "Rensa",
48664
+ "Language": "Spr�k",
48665
+ "Confidence": "Tillf�rlitlighet",
48666
+ "Listening...": "Lyssnar...",
48667
+ "Speech to text is not supported in this browser": "Tal till text st�ds inte i denna webbl�sare",
48668
+ "No speech detected": "Inget tal detekterat",
48669
+ "Microphone access denied": "Mikrofon�tkomst nekad",
48670
+ "No microphone found": "No microphone found",
48671
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
48672
+ "Subscript": "Nedsänkt",
48673
+ "Superscript": "Upphöjd",
48674
+ "Horizontal rule": "Vågrät linje",
48675
+ "Unlink": "Ta bort länk",
48676
+ "Format": "Format",
48677
+ "Paragraph": "Stycke",
48678
+ "Heading 1": "Rubrik 1",
48679
+ "Heading 2": "Rubrik 2",
48680
+ "Heading 3": "Rubrik 3",
48681
+ "Heading 4": "Rubrik 4",
48682
+ "Heading 5": "Rubrik 5",
48683
+ "Heading 6": "Rubrik 6",
48684
+ "Styles": "Stilar",
48685
+ "Insert anchor": "Infoga ankare",
48686
+ "Anchor": "Ankare",
48687
+ "Anchor name": "Ankarnamn",
48688
+ "Anchor name is required": "Ankarnamn krävs",
48689
+ "Anchor name cannot contain spaces": "Ankarnamn får inte innehålla mellanslag",
48690
+ "Table": "Tabell",
48691
+ "Insert table": "Infoga tabell",
48692
+ "Insert row before": "Infoga rad före",
48693
+ "Insert row after": "Infoga rad efter",
48694
+ "Delete row": "Ta bort rad",
48695
+ "Insert column before": "Infoga kolumn före",
48696
+ "Insert column after": "Infoga kolumn efter",
48697
+ "Delete column": "Ta bort kolumn",
48698
+ "Merge cells": "Slå samman celler",
48699
+ "Split cell": "Dela cell",
48700
+ "Toggle header row": "Växla rubrikrad",
48701
+ "Delete table": "Ta bort tabell"
46374
48702
  };
46375
48703
  const zhTw = {
46376
48704
  "Bold": "粗體",
@@ -46428,7 +48756,7 @@ const zhTw = {
46428
48756
  "Browse...": "瀏覽...",
46429
48757
  "Drop image here or click to browse": "將圖片拖放至此處或點擊瀏覽",
46430
48758
  "Alt text": "替代文字",
46431
- "Insert": "插入",
48759
+ "Insert": "??",
46432
48760
  "Cancel": "取消",
46433
48761
  "Uploading...": "上傳中...",
46434
48762
  "Upload failed": "上傳失敗",
@@ -46442,7 +48770,50 @@ const zhTw = {
46442
48770
  "Title": "Title",
46443
48771
  "Open link in...": "Open link in...",
46444
48772
  "Current window": "Current window",
46445
- "New window": "New window"
48773
+ "New window": "New window",
48774
+ "Speech to Text": "?????",
48775
+ "Dictate": "聽寫",
48776
+ "Start": "??",
48777
+ "Stop": "??",
48778
+ "Clear": "??",
48779
+ "Language": "??",
48780
+ "Confidence": "???",
48781
+ "Listening...": "????...",
48782
+ "Speech to text is not supported in this browser": "????????????",
48783
+ "No speech detected": "??????",
48784
+ "Microphone access denied": "????????",
48785
+ "No microphone found": "No microphone found",
48786
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
48787
+ "Subscript": "下標",
48788
+ "Superscript": "上標",
48789
+ "Horizontal rule": "水平線",
48790
+ "Unlink": "移除連結",
48791
+ "Format": "格式",
48792
+ "Paragraph": "段落",
48793
+ "Heading 1": "標題 1",
48794
+ "Heading 2": "標題 2",
48795
+ "Heading 3": "標題 3",
48796
+ "Heading 4": "標題 4",
48797
+ "Heading 5": "標題 5",
48798
+ "Heading 6": "標題 6",
48799
+ "Styles": "樣式",
48800
+ "Insert anchor": "插入錨點",
48801
+ "Anchor": "錨點",
48802
+ "Anchor name": "錨點名稱",
48803
+ "Anchor name is required": "錨點名稱為必填",
48804
+ "Anchor name cannot contain spaces": "錨點名稱不能包含空格",
48805
+ "Table": "表格",
48806
+ "Insert table": "插入表格",
48807
+ "Insert row before": "在上方插入列",
48808
+ "Insert row after": "在下方插入列",
48809
+ "Delete row": "刪除列",
48810
+ "Insert column before": "在左側插入欄",
48811
+ "Insert column after": "在右側插入欄",
48812
+ "Delete column": "刪除欄",
48813
+ "Merge cells": "合併儲存格",
48814
+ "Split cell": "分割儲存格",
48815
+ "Toggle header row": "切換標題列",
48816
+ "Delete table": "刪除表格"
46446
48817
  };
46447
48818
  const th = {
46448
48819
  "Bold": "ตัวหนา",
@@ -46500,7 +48871,7 @@ const th = {
46500
48871
  "Browse...": "เรียกดู...",
46501
48872
  "Drop image here or click to browse": "ลากรูปภาพมาที่นี่หรือคลิกเพื่อเรียกดู",
46502
48873
  "Alt text": "ข้อความทดแทน",
46503
- "Insert": "แทรก",
48874
+ "Insert": "????",
46504
48875
  "Cancel": "ยกเลิก",
46505
48876
  "Uploading...": "กำลังอัปโหลด...",
46506
48877
  "Upload failed": "อัปโหลดล้มเหลว",
@@ -46514,7 +48885,50 @@ const th = {
46514
48885
  "Title": "Title",
46515
48886
  "Open link in...": "Open link in...",
46516
48887
  "Current window": "Current window",
46517
- "New window": "New window"
48888
+ "New window": "New window",
48889
+ "Speech to Text": "????????????????",
48890
+ "Dictate": "เขียนตามคำบอก",
48891
+ "Start": "?????",
48892
+ "Stop": "????",
48893
+ "Clear": "????",
48894
+ "Language": "????",
48895
+ "Confidence": "?????????????",
48896
+ "Listening...": "????????...",
48897
+ "Speech to text is not supported in this browser": "?????????????????????????????????????????",
48898
+ "No speech detected": "?????????????",
48899
+ "Microphone access denied": "???????????????????????????",
48900
+ "No microphone found": "No microphone found",
48901
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
48902
+ "Subscript": "ตัวห้อย",
48903
+ "Superscript": "ตัวยก",
48904
+ "Horizontal rule": "เส้นแนวนอน",
48905
+ "Unlink": "ลบลิงก์",
48906
+ "Format": "รูปแบบ",
48907
+ "Paragraph": "ย่อหน้า",
48908
+ "Heading 1": "หัวข้อ 1",
48909
+ "Heading 2": "หัวข้อ 2",
48910
+ "Heading 3": "หัวข้อ 3",
48911
+ "Heading 4": "หัวข้อ 4",
48912
+ "Heading 5": "หัวข้อ 5",
48913
+ "Heading 6": "หัวข้อ 6",
48914
+ "Styles": "สไตล์",
48915
+ "Insert anchor": "แทรกจุดยึด",
48916
+ "Anchor": "จุดยึด",
48917
+ "Anchor name": "ชื่อจุดยึด",
48918
+ "Anchor name is required": "ต้องระบุชื่อจุดยึด",
48919
+ "Anchor name cannot contain spaces": "ชื่อจุดยึดต้องไม่มีช่องว่าง",
48920
+ "Table": "ตาราง",
48921
+ "Insert table": "แทรกตาราง",
48922
+ "Insert row before": "แทรกแถวก่อนหน้า",
48923
+ "Insert row after": "แทรกแถวถัดไป",
48924
+ "Delete row": "ลบแถว",
48925
+ "Insert column before": "แทรกคอลัมน์ก่อนหน้า",
48926
+ "Insert column after": "แทรกคอลัมน์ถัดไป",
48927
+ "Delete column": "ลบคอลัมน์",
48928
+ "Merge cells": "ผสานเซลล์",
48929
+ "Split cell": "แยกเซลล์",
48930
+ "Toggle header row": "สลับแถวส่วนหัว",
48931
+ "Delete table": "ลบตาราง"
46518
48932
  };
46519
48933
  const tr = {
46520
48934
  "Bold": "Kalın",
@@ -46586,7 +49000,50 @@ const tr = {
46586
49000
  "Title": "Title",
46587
49001
  "Open link in...": "Open link in...",
46588
49002
  "Current window": "Current window",
46589
- "New window": "New window"
49003
+ "New window": "New window",
49004
+ "Speech to Text": "Konusmayi metne �evir",
49005
+ "Dictate": "Dikte et",
49006
+ "Start": "Baslat",
49007
+ "Stop": "Durdur",
49008
+ "Clear": "Temizle",
49009
+ "Language": "Dil",
49010
+ "Confidence": "G�venilirlik",
49011
+ "Listening...": "Dinliyor...",
49012
+ "Speech to text is not supported in this browser": "Bu tarayicida konusmayi metne �evirme desteklenmiyor",
49013
+ "No speech detected": "Konusma algilanmadi",
49014
+ "Microphone access denied": "Mikrofon erisimi reddedildi",
49015
+ "No microphone found": "No microphone found",
49016
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
49017
+ "Subscript": "Alt simge",
49018
+ "Superscript": "Üst simge",
49019
+ "Horizontal rule": "Yatay çizgi",
49020
+ "Unlink": "Bağlantıyı kaldır",
49021
+ "Format": "Biçim",
49022
+ "Paragraph": "Paragraf",
49023
+ "Heading 1": "Başlık 1",
49024
+ "Heading 2": "Başlık 2",
49025
+ "Heading 3": "Başlık 3",
49026
+ "Heading 4": "Başlık 4",
49027
+ "Heading 5": "Başlık 5",
49028
+ "Heading 6": "Başlık 6",
49029
+ "Styles": "Stiller",
49030
+ "Insert anchor": "Çapa ekle",
49031
+ "Anchor": "Çapa",
49032
+ "Anchor name": "Çapa adı",
49033
+ "Anchor name is required": "Çapa adı gereklidir",
49034
+ "Anchor name cannot contain spaces": "Çapa adı boşluk içeremez",
49035
+ "Table": "Tablo",
49036
+ "Insert table": "Tablo ekle",
49037
+ "Insert row before": "Önceye satır ekle",
49038
+ "Insert row after": "Sonraya satır ekle",
49039
+ "Delete row": "Satırı sil",
49040
+ "Insert column before": "Önceye sütun ekle",
49041
+ "Insert column after": "Sonraya sütun ekle",
49042
+ "Delete column": "Sütunu sil",
49043
+ "Merge cells": "Hücreleri birleştir",
49044
+ "Split cell": "Hücreyi böl",
49045
+ "Toggle header row": "Başlık satırını aç/kapat",
49046
+ "Delete table": "Tabloyu sil"
46590
49047
  };
46591
49048
  const vi = {
46592
49049
  "Bold": "In đậm",
@@ -46644,7 +49101,7 @@ const vi = {
46644
49101
  "Browse...": "Duyệt...",
46645
49102
  "Drop image here or click to browse": "Kéo thả hình ảnh vào đây hoặc nhấp để duyệt",
46646
49103
  "Alt text": "Văn bản thay thế",
46647
- "Insert": "Chèn",
49104
+ "Insert": "Ch�n",
46648
49105
  "Cancel": "Hủy",
46649
49106
  "Uploading...": "Đang tải lên...",
46650
49107
  "Upload failed": "Tải lên thất bại",
@@ -46658,7 +49115,50 @@ const vi = {
46658
49115
  "Title": "Title",
46659
49116
  "Open link in...": "Open link in...",
46660
49117
  "Current window": "Current window",
46661
- "New window": "New window"
49118
+ "New window": "New window",
49119
+ "Speech to Text": "Gi?ng n�i th�nh van b?n",
49120
+ "Dictate": "Đọc chính tả",
49121
+ "Start": "B?t d?u",
49122
+ "Stop": "D?ng",
49123
+ "Clear": "X�a",
49124
+ "Language": "Ng�n ng?",
49125
+ "Confidence": "�? tin c?y",
49126
+ "Listening...": "�ang nghe...",
49127
+ "Speech to text is not supported in this browser": "Gi?ng n�i th�nh van b?n kh�ng du?c h? tr? trong tr�nh duy?t n�y",
49128
+ "No speech detected": "Kh�ng ph�t hi?n gi?ng n�i",
49129
+ "Microphone access denied": "Quy?n truy c?p micr� b? t? ch?i",
49130
+ "No microphone found": "No microphone found",
49131
+ "Network error - speech recognition requires internet": "Network error - speech recognition requires internet",
49132
+ "Subscript": "Chỉ số dưới",
49133
+ "Superscript": "Chỉ số trên",
49134
+ "Horizontal rule": "Đường kẻ ngang",
49135
+ "Unlink": "Bỏ liên kết",
49136
+ "Format": "Định dạng",
49137
+ "Paragraph": "Đoạn văn",
49138
+ "Heading 1": "Tiêu đề 1",
49139
+ "Heading 2": "Tiêu đề 2",
49140
+ "Heading 3": "Tiêu đề 3",
49141
+ "Heading 4": "Tiêu đề 4",
49142
+ "Heading 5": "Tiêu đề 5",
49143
+ "Heading 6": "Tiêu đề 6",
49144
+ "Styles": "Kiểu",
49145
+ "Insert anchor": "Chèn neo",
49146
+ "Anchor": "Neo",
49147
+ "Anchor name": "Tên neo",
49148
+ "Anchor name is required": "Tên neo là bắt buộc",
49149
+ "Anchor name cannot contain spaces": "Tên neo không được chứa khoảng trắng",
49150
+ "Table": "Bảng",
49151
+ "Insert table": "Chèn bảng",
49152
+ "Insert row before": "Chèn hàng phía trước",
49153
+ "Insert row after": "Chèn hàng phía sau",
49154
+ "Delete row": "Xóa hàng",
49155
+ "Insert column before": "Chèn cột phía trước",
49156
+ "Insert column after": "Chèn cột phía sau",
49157
+ "Delete column": "Xóa cột",
49158
+ "Merge cells": "Gộp ô",
49159
+ "Split cell": "Tách ô",
49160
+ "Toggle header row": "Bật/tắt hàng tiêu đề",
49161
+ "Delete table": "Xóa bảng"
46662
49162
  };
46663
49163
  const locales = {
46664
49164
  en,
@@ -46704,8 +49204,8 @@ const availableLocales = Object.keys(locales);
46704
49204
  const TRANSLATION_KEYS = Object.keys(en);
46705
49205
  const lowlight = createLowlight(grammars);
46706
49206
  const fontNames = "Andale Mono=andale mono,times; Arial=arial,helvetica,sans-serif; Arial Black=arial black,avant garde; Book Antiqua=book antiqua,palatino; Comic Sans MS=comic sans ms,sans-serif; Courier New=courier new,courier; Georgia=georgia,palatino; Helvetica=helvetica; Impact=impact,chicago; Tahoma=tahoma,arial,helvetica,sans-serif; Terminal=terminal,monaco; Times New Roman=times new roman,times; Trebuchet MS=trebuchet ms,geneva; Verdana=verdana,geneva";
46707
- const FULL_TOOLBAR = "bold italic underline strikethrough | bullist numlist outdent indent blockquote | fontfamily fontsize | lineheight alignleft aligncenter alignright alignjustify | forecolor backcolor | removeformat copy cut paste | undo redo | image charmap emoticons | fullscreen preview | code link codesample | ltr rtl | searchreplace";
46708
- const BASIC_TOOLBAR = "bold italic underline strikethrough | bullist numlist outdent indent | fontfamily fontsize blockquote | lineheight alignleft aligncenter alignright alignjustify | forecolor backcolor | removeformat copy cut paste | undo redo | charmap emoticons | link | ltr rtl | searchreplace";
49207
+ const FULL_TOOLBAR = "bold italic underline strikethrough subscript superscript | blocks styles | bullist numlist outdent indent blockquote | fontfamily fontsize | lineheight alignleft aligncenter alignright alignjustify | forecolor backcolor | removeformat copy cut paste | undo redo | image table charmap emoticons hr | fullscreen preview | code link unlink anchor codesample | ltr rtl | searchreplace";
49208
+ const BASIC_TOOLBAR = "bold italic underline strikethrough subscript superscript | bullist numlist outdent indent | fontfamily fontsize blockquote | lineheight alignleft aligncenter alignright alignjustify | forecolor backcolor | removeformat copy cut paste | undo redo | charmap emoticons | link unlink | ltr rtl | searchreplace";
46709
49209
  const DEFAULT_FONT_SIZES = "8pt 9pt 10pt 12pt 14pt 18pt 24pt 36pt";
46710
49210
  let editorIdCounter = 0;
46711
49211
  let globalTranslate = (key) => key;
@@ -46761,6 +49261,8 @@ class HTMLEditor {
46761
49261
  normalizeConfig(config) {
46762
49262
  return {
46763
49263
  basicEditor: config.basicEditor ?? false,
49264
+ readonly: config.readonly ?? false,
49265
+ forced_root_block: config.forced_root_block ?? "p",
46764
49266
  includeTemplates: config.includeTemplates ?? false,
46765
49267
  templates: config.templates ?? [],
46766
49268
  dropbox: config.dropbox ?? false,
@@ -46769,8 +49271,14 @@ class HTMLEditor {
46769
49271
  images_upload_base_path: config.images_upload_base_path ?? "/",
46770
49272
  images_upload_max_size: config.images_upload_max_size,
46771
49273
  images_upload_headers: config.images_upload_headers,
46772
- font_family_formats: config.font_family_formats ?? fontNames,
46773
- font_size_formats: config.font_size_formats ?? DEFAULT_FONT_SIZES,
49274
+ images_file_types: config.images_file_types,
49275
+ images_upload_validate: config.images_upload_validate,
49276
+ images_upload_error: config.images_upload_error,
49277
+ // CKEditor aliases: font_names / fontSize_sizes map to the TinyMCE keys
49278
+ font_family_formats: config.font_family_formats ?? config.font_names ?? fontNames,
49279
+ font_size_formats: config.font_size_formats ?? config.fontSize_sizes ?? DEFAULT_FONT_SIZES,
49280
+ block_formats: config.block_formats,
49281
+ style_formats: config.style_formats,
46774
49282
  fontName: config.fontName,
46775
49283
  fontSize: config.fontSize,
46776
49284
  directionality: config.directionality ?? "ltr",
@@ -46799,7 +49307,8 @@ class HTMLEditor {
46799
49307
  format_empty_lines: config.format_empty_lines ?? true,
46800
49308
  toolbar_narrow_breakpoint: config.toolbar_narrow_breakpoint,
46801
49309
  toolbar_priority: config.toolbar_priority,
46802
- paste_from_office: config.paste_from_office ?? true
49310
+ paste_from_office: config.paste_from_office ?? true,
49311
+ speech_to_text: config.speech_to_text ?? true
46803
49312
  };
46804
49313
  }
46805
49314
  createEditor() {
@@ -46843,6 +49352,7 @@ class HTMLEditor {
46843
49352
  element: editorContent,
46844
49353
  extensions,
46845
49354
  content: "",
49355
+ editable: !this.config.readonly,
46846
49356
  editorProps: {
46847
49357
  attributes: {
46848
49358
  class: "md-editor-body",
@@ -46881,6 +49391,10 @@ class HTMLEditor {
46881
49391
  narrowBreakpoint: this.config.toolbar_narrow_breakpoint ?? 768,
46882
49392
  priorityOverrides: this.config.toolbar_priority ?? {}
46883
49393
  });
49394
+ if (this.config.readonly) {
49395
+ this.editorWrapper.classList.add("md-editor-readonly");
49396
+ this.toolbar.setEnabled(false);
49397
+ }
46884
49398
  if (this.config.auto_focus) {
46885
49399
  setTimeout(() => this.focus(), 10);
46886
49400
  } else if (this.config.setFocus) {
@@ -46905,6 +49419,9 @@ class HTMLEditor {
46905
49419
  uploadBasePath: this.config.images_upload_base_path,
46906
49420
  uploadMaxSize: this.config.images_upload_max_size,
46907
49421
  uploadHeaders: this.config.images_upload_headers,
49422
+ fileTypes: this.config.images_file_types,
49423
+ validate: this.config.images_upload_validate,
49424
+ onError: this.config.images_upload_error,
46908
49425
  trans: globalTranslate
46909
49426
  });
46910
49427
  }
@@ -46953,19 +49470,29 @@ class HTMLEditor {
46953
49470
  const helper = this.getImageUploadHelper();
46954
49471
  helper.uploadFile(file).then((src) => {
46955
49472
  this.tiptap?.chain().focus().setImage({ src }).run();
46956
- }).catch(() => {
49473
+ }).catch((err) => {
49474
+ const message = err instanceof Error && err.message ? err.message : globalTranslate("Upload failed");
49475
+ this.config.images_upload_error?.(message);
46957
49476
  });
46958
49477
  }
46959
49478
  buildExtensions() {
49479
+ const useDivBlocks = this.config.forced_root_block === "div";
46960
49480
  const extensions = [
46961
49481
  StarterKit.configure({
46962
- codeBlock: false
49482
+ codeBlock: false,
46963
49483
  // We use CodeBlockLowlight instead
49484
+ // When forced_root_block is 'div', swap StarterKit's <p> paragraph for
49485
+ // a custom Paragraph that renders as <div> (CKEditor ENTER_DIV parity).
49486
+ ...useDivBlocks ? { paragraph: false } : {}
46964
49487
  }),
46965
49488
  SignatureBlock,
46966
49489
  Mention,
49490
+ Anchor,
49491
+ Subscript,
49492
+ Superscript,
46967
49493
  Underline,
46968
49494
  TextStyle,
49495
+ InlineStyle,
46969
49496
  FontFamily,
46970
49497
  FontSize,
46971
49498
  LineHeight,
@@ -47002,6 +49529,18 @@ class HTMLEditor {
47002
49529
  }),
47003
49530
  TextDirection
47004
49531
  ];
49532
+ if (useDivBlocks) {
49533
+ extensions.push(
49534
+ Paragraph.extend({
49535
+ parseHTML() {
49536
+ return [{ tag: "p" }, { tag: "div" }];
49537
+ },
49538
+ renderHTML({ HTMLAttributes }) {
49539
+ return ["div", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
49540
+ }
49541
+ })
49542
+ );
49543
+ }
47005
49544
  if (this.config.paste_from_office !== false) {
47006
49545
  extensions.push(PasteFromOffice);
47007
49546
  }
@@ -47071,6 +49610,12 @@ class HTMLEditor {
47071
49610
  case "strikethrough":
47072
49611
  chain.toggleStrike().run();
47073
49612
  return true;
49613
+ case "subscript":
49614
+ chain.toggleSubscript().run();
49615
+ return true;
49616
+ case "superscript":
49617
+ chain.toggleSuperscript().run();
49618
+ return true;
47074
49619
  case "fontname":
47075
49620
  if (typeof value === "string") {
47076
49621
  chain.setFontFamily(value).run();
@@ -47134,6 +49679,12 @@ class HTMLEditor {
47134
49679
  case "removeformat":
47135
49680
  chain.unsetAllMarks().clearNodes().run();
47136
49681
  return true;
49682
+ case "unlink":
49683
+ chain.unsetLink().run();
49684
+ return true;
49685
+ case "inserthorizontalrule":
49686
+ chain.setHorizontalRule().run();
49687
+ return true;
47137
49688
  case "mceremoveeditor":
47138
49689
  this.destroy();
47139
49690
  return true;
@@ -47151,6 +49702,19 @@ class HTMLEditor {
47151
49702
  this.fire("dirty", false);
47152
49703
  }
47153
49704
  }
49705
+ /**
49706
+ * Toggle read-only mode. Disables editing and dims the toolbar.
49707
+ * Mirrors CKEditor's editor.setReadOnly(bool).
49708
+ */
49709
+ setReadOnly(state) {
49710
+ this.config.readonly = state;
49711
+ this.tiptap?.setEditable(!state);
49712
+ this.editorWrapper?.classList.toggle("md-editor-readonly", state);
49713
+ this.toolbar?.setEnabled(!state);
49714
+ }
49715
+ isReadOnly() {
49716
+ return this.config.readonly ?? false;
49717
+ }
47154
49718
  focus() {
47155
49719
  this.tiptap?.commands.focus();
47156
49720
  }
@@ -47218,14 +49782,18 @@ class HTMLEditor {
47218
49782
  return this.config.basicEditor ?? false;
47219
49783
  }
47220
49784
  }
49785
+ exports.Anchor = Anchor;
49786
+ exports.AnchorDialog = AnchorDialog;
47221
49787
  exports.CHAR_MAP = CHAR_MAP;
47222
49788
  exports.CONFAB_ICONS = CONFAB_ICONS;
47223
49789
  exports.CharacterMap = CharacterMap;
47224
49790
  exports.DEFAULT_ICONS = DEFAULT_ICONS;
49791
+ exports.Dictation = Dictation;
47225
49792
  exports.EMOJI_CATEGORIES = EMOJI_CATEGORIES;
47226
49793
  exports.EmojiPicker = EmojiPicker;
47227
49794
  exports.FontSize = FontSize;
47228
49795
  exports.HTMLEditor = HTMLEditor;
49796
+ exports.InlineStyle = InlineStyle;
47229
49797
  exports.LineHeight = LineHeight;
47230
49798
  exports.LinkEditor = LinkEditor;
47231
49799
  exports.Mention = Mention;
@@ -47233,6 +49801,7 @@ exports.PasteFromOffice = PasteFromOffice;
47233
49801
  exports.SearchReplace = SearchReplace;
47234
49802
  exports.SignatureBlock = SignatureBlock;
47235
49803
  exports.SourceEditor = SourceEditor;
49804
+ exports.SpeechToText = SpeechToText;
47236
49805
  exports.TRANSLATION_KEYS = TRANSLATION_KEYS;
47237
49806
  exports.TextDirection = TextDirection;
47238
49807
  exports.Toolbar = Toolbar;
@@ -47242,6 +49811,7 @@ exports.fontNames = fontNames;
47242
49811
  exports.getGetFileSrc = getGetFileSrc;
47243
49812
  exports.getLocale = getLocale;
47244
49813
  exports.getTranslate = getTranslate;
49814
+ exports.isSpeechRecognitionSupported = isSpeechRecognitionSupported;
47245
49815
  exports.resetTranslate = resetTranslate;
47246
49816
  exports.setGetFileSrc = setGetFileSrc;
47247
49817
  exports.setTranslate = setTranslate;