@searpent/react-image-annotate 2.0.80 → 2.0.82-cand-2
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/Annotator/examplePhotos.js +28 -28
- package/Annotator/index.js +15 -21
- package/Annotator/reducers/combine-reducers.js +18 -3
- package/Annotator/reducers/convert-expanding-line-to-polygon.js +15 -16
- package/Annotator/reducers/get-implied-video-regions.js +18 -30
- package/ClassSelectionMenu/index.js +8 -8
- package/Crosshairs/index.js +2 -2
- package/DebugSidebarBox/index.js +4 -4
- package/DemoSite/Editor.js +15 -15
- package/DemoSite/ErrorBoundaryDialog.js +3 -5
- package/DemoSite/index.js +3 -3
- package/Editor/annotation-plugin/annotation.js +1 -3
- package/Editor/index.js +12 -31
- package/Editor/readOnly.js +395 -47
- package/Errorer/index.js +2 -2
- package/FullImageSegmentationAnnotator/index.js +1 -1
- package/GroupSelectorSidebarBox/index.js +7 -7
- package/GroupsEditorSidebarBox/index.js +11 -11
- package/HelpSidebarBox/index.js +4 -4
- package/HighlightBox/index.js +3 -3
- package/HistorySidebarBox/index.js +8 -8
- package/ImageCanvas/index.js +16 -16
- package/ImageMask/index.js +1 -1
- package/ImageSelectorSidebarBox/index.js +7 -7
- package/KeyframeTimeline/index.js +30 -14
- package/KeyframesSelectorSidebarBox/index.js +8 -8
- package/LandingPage/index.js +12 -12
- package/Locker/index.js +2 -2
- package/MainLayout/RightSidebarItemsWrapper.js +1 -1
- package/MainLayout/icon-dictionary.js +11 -11
- package/MainLayout/index.js +25 -23
- package/MetadataEditorSidebarBox/index.js +18 -18
- package/PageSelector/index.js +21 -21
- package/PointDistances/index.js +4 -4
- package/PreventScrollToParents/index.js +3 -3
- package/RegionLabel/index.js +24 -24
- package/RegionSelectAndTransformBoxes/index.js +8 -8
- package/RegionSelectorSidebarBox/index.js +33 -33
- package/RegionShapes/index.js +22 -22
- package/RegionTags/index.js +6 -6
- package/SettingsDialog/index.js +4 -4
- package/SettingsProvider/index.js +1 -1
- package/Shortcuts/ShortcutField.js +3 -3
- package/Shortcuts/index.js +2 -2
- package/ShortcutsManager/index.js +9 -9
- package/Sidebar/index.js +7 -7
- package/SidebarBoxContainer/index.js +3 -3
- package/SmallToolButton/index.js +2 -2
- package/TagsSidebarBox/index.js +6 -6
- package/TaskDescriptionSidebarBox/index.js +4 -4
- package/Theme/index.js +2 -2
- package/VideoOrImageCanvasBackground/index.js +5 -5
- package/mj_smaz_hist.log +20015 -0
- package/package.json +4 -3
- package/utils/blocks-to-article.js +3 -3
- package/utils/get-landmarks-with-transform.js +13 -15
- package/utils/spellcheck-nspell.js +635 -0
|
@@ -0,0 +1,635 @@
|
|
|
1
|
+
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
2
|
+
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
3
|
+
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
4
|
+
|
|
5
|
+
function _createForOfIteratorHelper(o) { if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) { var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var it, normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
6
|
+
|
|
7
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
8
|
+
|
|
9
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Multi-language spellcheck system with priority-based language detection
|
|
13
|
+
*
|
|
14
|
+
* Language Detection Priority:
|
|
15
|
+
* 1. Explicit spellcheck language setting (setSpellcheckLanguage())
|
|
16
|
+
* 2. Text content analysis (character frequency)
|
|
17
|
+
* 3. Browser language preferences
|
|
18
|
+
* 4. Default fallback (en-US)
|
|
19
|
+
*
|
|
20
|
+
* Usage:
|
|
21
|
+
* - setSpellcheckEnabled(true) // Enable spellchecking (disabled by default for performance)
|
|
22
|
+
* - setSpellcheckLanguage('cs-CZ') // Set explicit language
|
|
23
|
+
* - setSpellcheckLanguage(null) // Clear setting (use auto-detection)
|
|
24
|
+
* - highlightMisspellingsInHtml(html, 'auto') // Auto-detect with priority
|
|
25
|
+
*
|
|
26
|
+
* Configuration:
|
|
27
|
+
* - Set REACT_APP_SPELLCHECK_ENABLED=true in .env file to enable spellchecking (default: disabled)
|
|
28
|
+
* - Or call setSpellcheckEnabled(true) programmatically at app startup to enable
|
|
29
|
+
*/
|
|
30
|
+
// Simple nspell loader usable in the browser. It lazy-loads the aff/dic
|
|
31
|
+
// and exposes a singleton spell instance plus a helper to check words.
|
|
32
|
+
// Cache for different language spellcheckers
|
|
33
|
+
var spellInstances = new Map();
|
|
34
|
+
var loadPromises = new Map();
|
|
35
|
+
export function getSpell() {
|
|
36
|
+
return _getSpell.apply(this, arguments);
|
|
37
|
+
} // Available dictionaries mapping
|
|
38
|
+
|
|
39
|
+
function _getSpell() {
|
|
40
|
+
_getSpell = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
|
|
41
|
+
var lang,
|
|
42
|
+
result,
|
|
43
|
+
promise,
|
|
44
|
+
_args2 = arguments;
|
|
45
|
+
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
|
|
46
|
+
while (1) {
|
|
47
|
+
switch (_context2.prev = _context2.next) {
|
|
48
|
+
case 0:
|
|
49
|
+
lang = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : 'en-US';
|
|
50
|
+
|
|
51
|
+
if (AVAILABLE_DICTIONARIES[lang]) {
|
|
52
|
+
_context2.next = 4;
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
console.warn("Dictionary not available for language: ".concat(lang));
|
|
57
|
+
return _context2.abrupt("return", null);
|
|
58
|
+
|
|
59
|
+
case 4:
|
|
60
|
+
if (!spellInstances.has(lang)) {
|
|
61
|
+
_context2.next = 6;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return _context2.abrupt("return", spellInstances.get(lang));
|
|
66
|
+
|
|
67
|
+
case 6:
|
|
68
|
+
if (!loadPromises.has(lang)) {
|
|
69
|
+
_context2.next = 11;
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
_context2.next = 9;
|
|
74
|
+
return loadPromises.get(lang);
|
|
75
|
+
|
|
76
|
+
case 9:
|
|
77
|
+
result = _context2.sent;
|
|
78
|
+
return _context2.abrupt("return", result);
|
|
79
|
+
|
|
80
|
+
case 11:
|
|
81
|
+
promise = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
82
|
+
var _yield$import, nspell, dictName, affUrl, dicUrl, _yield$Promise$all, _yield$Promise$all2, affRes, dicRes, errorMsg, _yield$Promise$all3, _yield$Promise$all4, affBuf, dicBuf, utf8Decoder, affUtf8, enc, setMatch, raw, map, mapped, decoder, aff, dic, spellInstance;
|
|
83
|
+
|
|
84
|
+
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
85
|
+
while (1) {
|
|
86
|
+
switch (_context.prev = _context.next) {
|
|
87
|
+
case 0:
|
|
88
|
+
_context.prev = 0;
|
|
89
|
+
_context.next = 3;
|
|
90
|
+
return import('nspell');
|
|
91
|
+
|
|
92
|
+
case 3:
|
|
93
|
+
_yield$import = _context.sent;
|
|
94
|
+
nspell = _yield$import.default;
|
|
95
|
+
// Use the mapped dictionary name
|
|
96
|
+
dictName = AVAILABLE_DICTIONARIES[lang];
|
|
97
|
+
affUrl = "/dicts/".concat(dictName, ".aff");
|
|
98
|
+
dicUrl = "/dicts/".concat(dictName, ".dic");
|
|
99
|
+
console.log('Loading dictionary files:', affUrl, dicUrl);
|
|
100
|
+
_context.next = 11;
|
|
101
|
+
return Promise.all([fetch(affUrl, {
|
|
102
|
+
mode: 'cors'
|
|
103
|
+
}), fetch(dicUrl, {
|
|
104
|
+
mode: 'cors'
|
|
105
|
+
})]);
|
|
106
|
+
|
|
107
|
+
case 11:
|
|
108
|
+
_yield$Promise$all = _context.sent;
|
|
109
|
+
_yield$Promise$all2 = _slicedToArray(_yield$Promise$all, 2);
|
|
110
|
+
affRes = _yield$Promise$all2[0];
|
|
111
|
+
dicRes = _yield$Promise$all2[1];
|
|
112
|
+
console.log('Fetch responses:', affRes.status, dicRes.status);
|
|
113
|
+
|
|
114
|
+
if (!(!affRes.ok || !dicRes.ok)) {
|
|
115
|
+
_context.next = 22;
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
errorMsg = "Failed to load dictionary files: ".concat(affUrl, " (").concat(affRes.status, "), ").concat(dicUrl, " (").concat(dicRes.status, ")");
|
|
120
|
+
console.error("[Spellcheck Error] ".concat(errorMsg));
|
|
121
|
+
console.error("[Spellcheck Error] Make sure dictionary files are served from /dicts/ path");
|
|
122
|
+
console.error("[Spellcheck Error] Check that public/dicts/ files are copied during build");
|
|
123
|
+
return _context.abrupt("return", null);
|
|
124
|
+
|
|
125
|
+
case 22:
|
|
126
|
+
_context.next = 24;
|
|
127
|
+
return Promise.all([affRes.arrayBuffer(), dicRes.arrayBuffer()]);
|
|
128
|
+
|
|
129
|
+
case 24:
|
|
130
|
+
_yield$Promise$all3 = _context.sent;
|
|
131
|
+
_yield$Promise$all4 = _slicedToArray(_yield$Promise$all3, 2);
|
|
132
|
+
affBuf = _yield$Promise$all4[0];
|
|
133
|
+
dicBuf = _yield$Promise$all4[1];
|
|
134
|
+
// Decode .aff as UTF-8 first to read SET <encoding>
|
|
135
|
+
utf8Decoder = new TextDecoder('utf-8');
|
|
136
|
+
affUtf8 = utf8Decoder.decode(affBuf);
|
|
137
|
+
enc = 'utf-8';
|
|
138
|
+
setMatch = /\n\s*SET\s+([^\r\n]+)/i.exec("\n" + affUtf8);
|
|
139
|
+
|
|
140
|
+
if (setMatch) {
|
|
141
|
+
raw = setMatch[1].trim(); // Map common Hunspell enc names to TextDecoder labels
|
|
142
|
+
|
|
143
|
+
map = {
|
|
144
|
+
'UTF-8': 'utf-8',
|
|
145
|
+
'UTF8': 'utf-8',
|
|
146
|
+
'ISO8859-1': 'iso-8859-1',
|
|
147
|
+
'ISO-8859-1': 'iso-8859-1',
|
|
148
|
+
'ISO8859-2': 'iso-8859-2',
|
|
149
|
+
'ISO-8859-2': 'iso-8859-2',
|
|
150
|
+
'ISO8859-5': 'iso-8859-5',
|
|
151
|
+
'ISO-8859-5': 'iso-8859-5',
|
|
152
|
+
'KOI8-R': 'koi8-r',
|
|
153
|
+
'KOI8-U': 'koi8-u',
|
|
154
|
+
'WINDOWS-1250': 'windows-1250',
|
|
155
|
+
'CP1250': 'windows-1250',
|
|
156
|
+
'WINDOWS-1251': 'windows-1251',
|
|
157
|
+
'CP1251': 'windows-1251',
|
|
158
|
+
'WINDOWS-1252': 'windows-1252',
|
|
159
|
+
'CP1252': 'windows-1252',
|
|
160
|
+
'MICROSOFT-CP1251': 'windows-1251',
|
|
161
|
+
'microsoft-cp1251': 'windows-1251'
|
|
162
|
+
};
|
|
163
|
+
mapped = map[raw.toUpperCase()] || raw;
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
// Probe if browser supports it
|
|
167
|
+
new TextDecoder(mapped);
|
|
168
|
+
enc = mapped;
|
|
169
|
+
} catch (_) {
|
|
170
|
+
console.warn("Unsupported dictionary encoding '".concat(raw, "' resolved to '").concat(mapped, "'. Falling back to UTF-8."));
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
decoder = new TextDecoder(enc);
|
|
175
|
+
aff = enc === 'utf-8' ? affUtf8 : decoder.decode(affBuf);
|
|
176
|
+
dic = decoder.decode(dicBuf);
|
|
177
|
+
spellInstance = nspell(aff, dic);
|
|
178
|
+
spellInstances.set(lang, spellInstance);
|
|
179
|
+
console.log("Dictionary loaded successfully for ".concat(lang));
|
|
180
|
+
return _context.abrupt("return", spellInstance);
|
|
181
|
+
|
|
182
|
+
case 42:
|
|
183
|
+
_context.prev = 42;
|
|
184
|
+
_context.t0 = _context["catch"](0);
|
|
185
|
+
console.error("[Spellcheck Error] Failed to load dictionary for ".concat(lang, ":"), _context.t0);
|
|
186
|
+
return _context.abrupt("return", null);
|
|
187
|
+
|
|
188
|
+
case 46:
|
|
189
|
+
case "end":
|
|
190
|
+
return _context.stop();
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}, _callee, null, [[0, 42]]);
|
|
194
|
+
}))();
|
|
195
|
+
loadPromises.set(lang, promise);
|
|
196
|
+
return _context2.abrupt("return", promise);
|
|
197
|
+
|
|
198
|
+
case 14:
|
|
199
|
+
case "end":
|
|
200
|
+
return _context2.stop();
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}, _callee2);
|
|
204
|
+
}));
|
|
205
|
+
return _getSpell.apply(this, arguments);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
var AVAILABLE_DICTIONARIES = {
|
|
209
|
+
'en-US': 'en_US',
|
|
210
|
+
'en': 'en_US',
|
|
211
|
+
'cs-CZ': 'cs_CZ',
|
|
212
|
+
'cs': 'cs_CZ',
|
|
213
|
+
'sk-SK': 'sk_SK',
|
|
214
|
+
'sk': 'sk_SK',
|
|
215
|
+
'pt-BR': 'pt_BR',
|
|
216
|
+
'pt_BR': 'pt_BR',
|
|
217
|
+
'pt': 'pt_BR',
|
|
218
|
+
'mk-MK': 'mk_MK',
|
|
219
|
+
'mk': 'mk_MK'
|
|
220
|
+
}; // Spellcheck language setting (can be set by user)
|
|
221
|
+
|
|
222
|
+
var spellcheckLanguageSetting = null; // Spellcheck enabled/disabled flag
|
|
223
|
+
// Defaults to false (disabled) for performance. Enable via REACT_APP_SPELLCHECK_ENABLED=true or setSpellcheckEnabled()
|
|
224
|
+
|
|
225
|
+
var spellcheckEnabled = function () {
|
|
226
|
+
try {
|
|
227
|
+
// Check for environment variable (works in Create React App, Storybook, etc.)
|
|
228
|
+
if (typeof process !== 'undefined' && process.env && process.env.REACT_APP_SPELLCHECK_ENABLED !== undefined) {
|
|
229
|
+
var envValue = process.env.REACT_APP_SPELLCHECK_ENABLED;
|
|
230
|
+
console.log('[Spellcheck] REACT_APP_SPELLCHECK_ENABLED from env:', envValue);
|
|
231
|
+
var enabledFromEnv = envValue === 'true' || envValue === '1';
|
|
232
|
+
console.log('[Spellcheck] Initial spellcheckEnabled from env:', enabledFromEnv);
|
|
233
|
+
return enabledFromEnv;
|
|
234
|
+
}
|
|
235
|
+
} catch (e) {
|
|
236
|
+
// Ignore errors accessing process.env
|
|
237
|
+
console.warn('[Spellcheck] Failed to read REACT_APP_SPELLCHECK_ENABLED from process.env:', e);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
console.log('[Spellcheck] REACT_APP_SPELLCHECK_ENABLED not set, defaulting spellcheckEnabled=false');
|
|
241
|
+
return false; // Default to disabled for performance
|
|
242
|
+
}(); // Function to enable/disable spellchecking
|
|
243
|
+
// Call this from your application to control spellchecking at runtime
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
export function setSpellcheckEnabled(enabled) {
|
|
247
|
+
spellcheckEnabled = Boolean(enabled);
|
|
248
|
+
console.log("Spellcheck ".concat(spellcheckEnabled ? 'enabled' : 'disabled'));
|
|
249
|
+
} // Function to check if spellchecking is enabled
|
|
250
|
+
|
|
251
|
+
export function isSpellcheckEnabled() {
|
|
252
|
+
return spellcheckEnabled;
|
|
253
|
+
} // Function to set spellcheck language preference
|
|
254
|
+
|
|
255
|
+
export function setSpellcheckLanguage(lang) {
|
|
256
|
+
if (lang && AVAILABLE_DICTIONARIES[lang]) {
|
|
257
|
+
spellcheckLanguageSetting = lang;
|
|
258
|
+
console.log("Spellcheck language set to: ".concat(lang));
|
|
259
|
+
} else if (lang === null) {
|
|
260
|
+
spellcheckLanguageSetting = null;
|
|
261
|
+
console.log('Spellcheck language setting cleared');
|
|
262
|
+
} else {
|
|
263
|
+
console.warn("Invalid spellcheck language: ".concat(lang, ". Available: ").concat(Object.keys(AVAILABLE_DICTIONARIES).join(', ')));
|
|
264
|
+
}
|
|
265
|
+
} // Function to get current spellcheck language setting
|
|
266
|
+
|
|
267
|
+
export function getSpellcheckLanguage() {
|
|
268
|
+
return spellcheckLanguageSetting;
|
|
269
|
+
} // Get browser language preferences for spellcheck
|
|
270
|
+
|
|
271
|
+
function getBrowserSpellcheckLanguage() {
|
|
272
|
+
if (typeof navigator === 'undefined') return 'en-US'; // Get browser language preferences
|
|
273
|
+
|
|
274
|
+
var languages = navigator.languages || [navigator.language || navigator.userLanguage || 'en-US']; // Find first available language
|
|
275
|
+
|
|
276
|
+
var _iterator = _createForOfIteratorHelper(languages),
|
|
277
|
+
_step;
|
|
278
|
+
|
|
279
|
+
try {
|
|
280
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
281
|
+
var lang = _step.value;
|
|
282
|
+
var normalized = lang.toLowerCase(); // Direct match
|
|
283
|
+
|
|
284
|
+
if (AVAILABLE_DICTIONARIES[lang]) return lang; // Match by prefix (e.g., 'en-US' matches 'en')
|
|
285
|
+
|
|
286
|
+
var prefix = normalized.split('-')[0];
|
|
287
|
+
if (AVAILABLE_DICTIONARIES[prefix]) return prefix; // Match by full language code
|
|
288
|
+
|
|
289
|
+
if (AVAILABLE_DICTIONARIES[normalized]) return normalized;
|
|
290
|
+
}
|
|
291
|
+
} catch (err) {
|
|
292
|
+
_iterator.e(err);
|
|
293
|
+
} finally {
|
|
294
|
+
_iterator.f();
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return 'en-US'; // fallback
|
|
298
|
+
} // Enhanced language detection with priority: spellcheck setting → text analysis → browser settings
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
function detectLanguage(text) {
|
|
302
|
+
var browserLang = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
303
|
+
var spellcheckLang = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
304
|
+
|
|
305
|
+
// console.log(`Language detection inputs - browserLang: ${browserLang}, spellcheckLang: ${spellcheckLang}, text length: ${text ? text.length : 0}`)
|
|
306
|
+
// Priority 1: Use explicit spellcheck language setting if available
|
|
307
|
+
if (spellcheckLang && AVAILABLE_DICTIONARIES[spellcheckLang]) {
|
|
308
|
+
console.log("Using explicit spellcheck language: ".concat(spellcheckLang));
|
|
309
|
+
return spellcheckLang;
|
|
310
|
+
} // Priority 2: Detect from text content if available
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
if (text) {
|
|
314
|
+
// Check for Czech-specific characters first (highest priority for distinctive characters)
|
|
315
|
+
var czechChars = text.match(/[áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]/g) || [];
|
|
316
|
+
var czechScore = czechChars.length; // Check for Slovak-specific characters
|
|
317
|
+
|
|
318
|
+
var slovakChars = text.match(/[áäčďéíĺľňóôŕšťúýžÁÄČĎÉÍĹĽŇÓÔŔŠŤÚÝŽ]/g) || [];
|
|
319
|
+
var slovakScore = slovakChars.length; // Check for Portuguese-specific characters (including Brazilian Portuguese)
|
|
320
|
+
|
|
321
|
+
var portugueseChars = text.match(/[áàâãäéêëíîïóôõöúûüçÁÀÂÃÄÉÊËÍÎÏÓÔÕÖÚÛÜÇ]/g) || [];
|
|
322
|
+
var portugueseScore = portugueseChars.length; // Check for Macedonian-specific Cyrillic characters
|
|
323
|
+
// Macedonian uses letters like ѓ (U+0453), ќ (U+045C), ѕ (U+0455), џ (U+045F), ј (U+0458)
|
|
324
|
+
// and their uppercase counterparts Ѓ (U+0403), Ќ (U+040C), Ѕ (U+0405), Џ (U+040F), Ј (U+0408)
|
|
325
|
+
// We also include the broader Cyrillic range to capture words.
|
|
326
|
+
|
|
327
|
+
var macedonianChars = text.match(/[ЃЌЅЏЈѓќѕџјА-Яа-яЀ-Џѐ-џ]/g) || [];
|
|
328
|
+
var macedonianScore = macedonianChars.length; // console.log(`Language detection scores - Czech: ${czechScore}, Slovak: ${slovakScore}, Portuguese: ${portugueseScore}`)
|
|
329
|
+
// Find the language with the highest score
|
|
330
|
+
|
|
331
|
+
var languageScores = [{
|
|
332
|
+
lang: 'cs-CZ',
|
|
333
|
+
score: czechScore,
|
|
334
|
+
name: 'Czech'
|
|
335
|
+
}, {
|
|
336
|
+
lang: 'sk-SK',
|
|
337
|
+
score: slovakScore,
|
|
338
|
+
name: 'Slovak'
|
|
339
|
+
}, {
|
|
340
|
+
lang: 'pt-BR',
|
|
341
|
+
score: portugueseScore,
|
|
342
|
+
name: 'Portuguese'
|
|
343
|
+
}, {
|
|
344
|
+
lang: 'mk-MK',
|
|
345
|
+
score: macedonianScore,
|
|
346
|
+
name: 'Macedonian'
|
|
347
|
+
}]; // Filter out languages with no score and check if dictionary is available
|
|
348
|
+
|
|
349
|
+
var validLanguages = languageScores.filter(function (lang) {
|
|
350
|
+
return lang.score > 0 && AVAILABLE_DICTIONARIES[lang.lang];
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
if (validLanguages.length > 0) {
|
|
354
|
+
// Sort by score (highest first) and return the top language
|
|
355
|
+
var bestMatch = validLanguages.sort(function (a, b) {
|
|
356
|
+
return b.score - a.score;
|
|
357
|
+
})[0]; // console.log(`Detected language from text: ${bestMatch.lang} (${bestMatch.name} diacritics: ${bestMatch.score})`)
|
|
358
|
+
|
|
359
|
+
return bestMatch.lang;
|
|
360
|
+
} // If we have text but no distinctive diacritics, it's likely English
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
if (text.trim().length > 0) {
|
|
364
|
+
// console.log(`Detected language from text: en-US (no distinctive diacritics found)`)
|
|
365
|
+
return 'en-US';
|
|
366
|
+
}
|
|
367
|
+
} // Priority 3: Fall back to browser language if available
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
if (browserLang && AVAILABLE_DICTIONARIES[browserLang]) {
|
|
371
|
+
console.log("Using browser language: ".concat(browserLang));
|
|
372
|
+
return browserLang;
|
|
373
|
+
} // Final fallback
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
console.log('Using default language: en-US');
|
|
377
|
+
return 'en-US';
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
export function findMisspellings(_x) {
|
|
381
|
+
return _findMisspellings.apply(this, arguments);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
function _findMisspellings() {
|
|
385
|
+
_findMisspellings = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(text) {
|
|
386
|
+
var lang,
|
|
387
|
+
browserLang,
|
|
388
|
+
spellcheckLang,
|
|
389
|
+
detectedLang,
|
|
390
|
+
spell,
|
|
391
|
+
wordRegex,
|
|
392
|
+
words,
|
|
393
|
+
miss,
|
|
394
|
+
_iterator2,
|
|
395
|
+
_step2,
|
|
396
|
+
w,
|
|
397
|
+
word,
|
|
398
|
+
_args3 = arguments;
|
|
399
|
+
|
|
400
|
+
return _regeneratorRuntime.wrap(function _callee3$(_context3) {
|
|
401
|
+
while (1) {
|
|
402
|
+
switch (_context3.prev = _context3.next) {
|
|
403
|
+
case 0:
|
|
404
|
+
lang = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : 'auto';
|
|
405
|
+
|
|
406
|
+
if (spellcheckEnabled) {
|
|
407
|
+
_context3.next = 3;
|
|
408
|
+
break;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
return _context3.abrupt("return", []);
|
|
412
|
+
|
|
413
|
+
case 3:
|
|
414
|
+
_context3.prev = 3;
|
|
415
|
+
// Get browser language preferences
|
|
416
|
+
browserLang = getBrowserSpellcheckLanguage(); // Get spellcheck language setting
|
|
417
|
+
|
|
418
|
+
spellcheckLang = getSpellcheckLanguage(); // Auto-detect language if not specified
|
|
419
|
+
|
|
420
|
+
detectedLang = lang === 'auto' ? detectLanguage(text, browserLang, spellcheckLang) : lang; // Check if dictionary is available
|
|
421
|
+
|
|
422
|
+
if (AVAILABLE_DICTIONARIES[detectedLang]) {
|
|
423
|
+
_context3.next = 10;
|
|
424
|
+
break;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
console.warn("Dictionary not available for ".concat(detectedLang, ", skipping spellcheck"));
|
|
428
|
+
return _context3.abrupt("return", []);
|
|
429
|
+
|
|
430
|
+
case 10:
|
|
431
|
+
_context3.next = 12;
|
|
432
|
+
return getSpell(detectedLang);
|
|
433
|
+
|
|
434
|
+
case 12:
|
|
435
|
+
spell = _context3.sent;
|
|
436
|
+
|
|
437
|
+
if (spell) {
|
|
438
|
+
_context3.next = 16;
|
|
439
|
+
break;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
console.warn("[Spellcheck] Dictionary not available for ".concat(detectedLang, ", skipping spellcheck"));
|
|
443
|
+
return _context3.abrupt("return", []);
|
|
444
|
+
|
|
445
|
+
case 16:
|
|
446
|
+
// Unicode-aware word extraction across scripts (Latin, Cyrillic, etc.)
|
|
447
|
+
// Matches sequences of letters, allowing internal apostrophes/dashes.
|
|
448
|
+
wordRegex = /(?:[A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08C7\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BF\u31F0-\u31FF\u3400-\u4DBF\u4E00-\u9FFC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA7BF\uA7C2-\uA7CA\uA7F5-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF40\uDF42-\uDF49\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDD00-\uDD23\uDE80-\uDEA9\uDEB0\uDEB1\uDF00-\uDF1C\uDF27\uDF30-\uDF45\uDFB0-\uDFC4\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDEB8\uDF00-\uDF1A]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCDF\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDEE0-\uDEF2\uDFB0]|\uD808[\uDC00-\uDF99]|\uD809[\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE7F\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82C[\uDC00-\uDD1E\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD838[\uDD00-\uDD2C\uDD37-\uDD3D\uDD4E\uDEC0-\uDEEB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43\uDD4B]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDEDD\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A])(?:['\x2DA-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08C7\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2019\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BF\u31F0-\u31FF\u3400-\u4DBF\u4E00-\u9FFC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA7BF\uA7C2-\uA7CA\uA7F5-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF40\uDF42-\uDF49\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDD00-\uDD23\uDE80-\uDEA9\uDEB0\uDEB1\uDF00-\uDF1C\uDF27\uDF30-\uDF45\uDFB0-\uDFC4\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDEB8\uDF00-\uDF1A]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCDF\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDEE0-\uDEF2\uDFB0]|\uD808[\uDC00-\uDF99]|\uD809[\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE7F\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82C[\uDC00-\uDD1E\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD838[\uDD00-\uDD2C\uDD37-\uDD3D\uDD4E\uDEC0-\uDEEB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43\uDD4B]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDEDD\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A])*/g;
|
|
449
|
+
words = text.match(wordRegex) || [];
|
|
450
|
+
miss = new Set();
|
|
451
|
+
_iterator2 = _createForOfIteratorHelper(words);
|
|
452
|
+
_context3.prev = 20;
|
|
453
|
+
|
|
454
|
+
_iterator2.s();
|
|
455
|
+
|
|
456
|
+
case 22:
|
|
457
|
+
if ((_step2 = _iterator2.n()).done) {
|
|
458
|
+
_context3.next = 30;
|
|
459
|
+
break;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
w = _step2.value;
|
|
463
|
+
word = w.replace(/^'+|'+$/g, '');
|
|
464
|
+
|
|
465
|
+
if (word) {
|
|
466
|
+
_context3.next = 27;
|
|
467
|
+
break;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
return _context3.abrupt("continue", 28);
|
|
471
|
+
|
|
472
|
+
case 27:
|
|
473
|
+
if (!spell.correct(word)) miss.add(word);
|
|
474
|
+
|
|
475
|
+
case 28:
|
|
476
|
+
_context3.next = 22;
|
|
477
|
+
break;
|
|
478
|
+
|
|
479
|
+
case 30:
|
|
480
|
+
_context3.next = 35;
|
|
481
|
+
break;
|
|
482
|
+
|
|
483
|
+
case 32:
|
|
484
|
+
_context3.prev = 32;
|
|
485
|
+
_context3.t0 = _context3["catch"](20);
|
|
486
|
+
|
|
487
|
+
_iterator2.e(_context3.t0);
|
|
488
|
+
|
|
489
|
+
case 35:
|
|
490
|
+
_context3.prev = 35;
|
|
491
|
+
|
|
492
|
+
_iterator2.f();
|
|
493
|
+
|
|
494
|
+
return _context3.finish(35);
|
|
495
|
+
|
|
496
|
+
case 38:
|
|
497
|
+
return _context3.abrupt("return", Array.from(miss));
|
|
498
|
+
|
|
499
|
+
case 41:
|
|
500
|
+
_context3.prev = 41;
|
|
501
|
+
_context3.t1 = _context3["catch"](3);
|
|
502
|
+
console.error("[Spellcheck Error] Spellcheck failed for language ".concat(lang, ":"), _context3.t1);
|
|
503
|
+
console.error("[Spellcheck Error] Stack:", _context3.t1.stack);
|
|
504
|
+
return _context3.abrupt("return", []);
|
|
505
|
+
|
|
506
|
+
case 46:
|
|
507
|
+
case "end":
|
|
508
|
+
return _context3.stop();
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
}, _callee3, null, [[3, 41], [20, 32, 35, 38]]);
|
|
512
|
+
}));
|
|
513
|
+
return _findMisspellings.apply(this, arguments);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
export function highlightMisspellingsInHtml(_x2) {
|
|
517
|
+
return _highlightMisspellingsInHtml.apply(this, arguments);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
function _highlightMisspellingsInHtml() {
|
|
521
|
+
_highlightMisspellingsInHtml = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4(html) {
|
|
522
|
+
var lang,
|
|
523
|
+
textForSpellcheck,
|
|
524
|
+
browserLang,
|
|
525
|
+
spellcheckLang,
|
|
526
|
+
detectedLang,
|
|
527
|
+
miss,
|
|
528
|
+
segments,
|
|
529
|
+
wrapped,
|
|
530
|
+
_args4 = arguments;
|
|
531
|
+
return _regeneratorRuntime.wrap(function _callee4$(_context4) {
|
|
532
|
+
while (1) {
|
|
533
|
+
switch (_context4.prev = _context4.next) {
|
|
534
|
+
case 0:
|
|
535
|
+
lang = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : 'auto';
|
|
536
|
+
|
|
537
|
+
if (html) {
|
|
538
|
+
_context4.next = 3;
|
|
539
|
+
break;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
return _context4.abrupt("return", html);
|
|
543
|
+
|
|
544
|
+
case 3:
|
|
545
|
+
if (spellcheckEnabled) {
|
|
546
|
+
_context4.next = 5;
|
|
547
|
+
break;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
return _context4.abrupt("return", html);
|
|
551
|
+
|
|
552
|
+
case 5:
|
|
553
|
+
_context4.prev = 5;
|
|
554
|
+
// Decode HTML entities for spellchecking, but preserve original HTML
|
|
555
|
+
textForSpellcheck = html.replace(/<[^>]+>/g, ' ') // strip tags
|
|
556
|
+
.replace(/ /g, ' ') // convert non-breaking spaces to regular spaces
|
|
557
|
+
.replace(/&[a-zA-Z0-9#]+;/g, ' ') // remove other HTML entities
|
|
558
|
+
.replace(/\s+/g, ' ') // normalize whitespace
|
|
559
|
+
.trim();
|
|
560
|
+
browserLang = getBrowserSpellcheckLanguage();
|
|
561
|
+
spellcheckLang = getSpellcheckLanguage();
|
|
562
|
+
detectedLang = lang === 'auto' ? detectLanguage(textForSpellcheck, browserLang, spellcheckLang) : lang; // Check if dictionary is available
|
|
563
|
+
|
|
564
|
+
if (AVAILABLE_DICTIONARIES[detectedLang]) {
|
|
565
|
+
_context4.next = 13;
|
|
566
|
+
break;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
console.warn("Dictionary not available for ".concat(detectedLang, ", skipping spellcheck"));
|
|
570
|
+
return _context4.abrupt("return", html);
|
|
571
|
+
|
|
572
|
+
case 13:
|
|
573
|
+
_context4.next = 15;
|
|
574
|
+
return findMisspellings(textForSpellcheck, detectedLang);
|
|
575
|
+
|
|
576
|
+
case 15:
|
|
577
|
+
miss = _context4.sent;
|
|
578
|
+
|
|
579
|
+
if (!(miss.length === 0)) {
|
|
580
|
+
_context4.next = 18;
|
|
581
|
+
break;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
return _context4.abrupt("return", html);
|
|
585
|
+
|
|
586
|
+
case 18:
|
|
587
|
+
// Replace whole-word occurrences with span wrapper. Do not touch inside tags or HTML entities
|
|
588
|
+
// We split on tags and HTML entities, only operate on text segments.
|
|
589
|
+
segments = html.split(/(<[^>]+>|&[a-zA-Z0-9#]+;)/g);
|
|
590
|
+
wrapped = segments.map(function (seg) {
|
|
591
|
+
if (/^<[^>]+>$/.test(seg) || /^&[a-zA-Z0-9#]+;$/.test(seg)) {
|
|
592
|
+
return seg; // tag or HTML entity segment - leave unchanged
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
var out = seg;
|
|
596
|
+
|
|
597
|
+
var _iterator3 = _createForOfIteratorHelper(miss),
|
|
598
|
+
_step3;
|
|
599
|
+
|
|
600
|
+
try {
|
|
601
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
602
|
+
var m = _step3.value;
|
|
603
|
+
// Use Unicode-aware boundaries: ensure preceding/following chars are not letters
|
|
604
|
+
var re = new RegExp("(?<!\\p{L})".concat(escapeRegExp(m), "(?!\\p{L})"), 'gu');
|
|
605
|
+
out = out.replace(re, "<span class=\"spell-error\">$&</span>");
|
|
606
|
+
}
|
|
607
|
+
} catch (err) {
|
|
608
|
+
_iterator3.e(err);
|
|
609
|
+
} finally {
|
|
610
|
+
_iterator3.f();
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
return out;
|
|
614
|
+
});
|
|
615
|
+
return _context4.abrupt("return", wrapped.join(''));
|
|
616
|
+
|
|
617
|
+
case 23:
|
|
618
|
+
_context4.prev = 23;
|
|
619
|
+
_context4.t0 = _context4["catch"](5);
|
|
620
|
+
console.warn('Spellcheck failed, returning original HTML:', _context4.t0);
|
|
621
|
+
return _context4.abrupt("return", html);
|
|
622
|
+
|
|
623
|
+
case 27:
|
|
624
|
+
case "end":
|
|
625
|
+
return _context4.stop();
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}, _callee4, null, [[5, 23]]);
|
|
629
|
+
}));
|
|
630
|
+
return _highlightMisspellingsInHtml.apply(this, arguments);
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
function escapeRegExp(s) {
|
|
634
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
635
|
+
}
|