|
59 | 59 | "COMMON": GenderValues[3] |
60 | 60 | }); |
61 | 61 |
|
| 62 | + function toLowerCaseRu(s) { |
| 63 | + // Это на самом деле быстрее, чем нативный toLowerCase, во всяком случае в Chrome, |
| 64 | + // поскольку нативный toLowerCase преобразует все алфавиты, а здесь только кириллица. |
| 65 | + |
| 66 | + let codes = new Array(s.length); |
| 67 | + |
| 68 | + for (let i = 0; i < s.length; i++) { |
| 69 | + let ch = s.charCodeAt(i); |
| 70 | + |
| 71 | + if ((ch >= 0x0410) && (ch <= 0x042F)) { |
| 72 | + ch += 0x20; |
| 73 | + } else if ((ch >= 0x0400) && (ch <= 0x040F)) { |
| 74 | + ch += 0x50; |
| 75 | + } |
| 76 | + |
| 77 | + codes[i] = ch; |
| 78 | + } |
| 79 | + |
| 80 | + // Функция apply может вызвать RangeError при очень длинных |
| 81 | + // массивах (лимит аргументов), но для слов — это не проблема. |
| 82 | + |
| 83 | + return String.fromCharCode.apply(null, codes); |
| 84 | + } |
| 85 | + |
62 | 86 | /** |
63 | 87 | * @param o A plain old JavaScript object. |
64 | 88 | * @returns {string|null} Описание ошибки на английском или null. |
|
312 | 336 | const vowels = 0b11101000000010000100000100100001; |
313 | 337 |
|
314 | 338 | function isVowel(ch) { |
315 | | - return bincludes(vowels, ch.toLowerCase()); |
| 339 | + return bincludes(vowels, toLowerCaseRu(ch)); |
316 | 340 | } |
317 | 341 |
|
318 | 342 | function isConsonantLc(lcChar) { |
|
1592 | 1616 | head = 'полу' + head.substring(3); |
1593 | 1617 | } |
1594 | 1618 |
|
1595 | | - let lcStem = stem.toLowerCase(); |
| 1619 | + let lcStem = toLowerCaseRu(stem); |
1596 | 1620 |
|
1597 | 1621 | const soft = () => (half && lcWord.endsWith('я')) || softD1(lcWord); |
1598 | 1622 |
|
|
1874 | 1898 | const lcWord = lemma.lower(); |
1875 | 1899 |
|
1876 | 1900 | const stem = getNounStem(lemma, lcWord); |
1877 | | - const lcStem = stem.toLowerCase(); |
| 1901 | + const lcStem = toLowerCaseRu(stem); |
1878 | 1902 |
|
1879 | 1903 | const head = init(word); |
1880 | 1904 | const lcHead = init(lcWord); |
|
2302 | 2326 | Object.freeze(stressedEnding); |
2303 | 2327 |
|
2304 | 2328 | const stem = getNounStem(lemma, lcWord, stressedEnding[0]); |
2305 | | - const lcStem = stem.toLowerCase(); |
| 2329 | + const lcStem = toLowerCaseRu(stem); |
2306 | 2330 |
|
2307 | 2331 | if (lcWord.endsWith('яя')) { |
2308 | 2332 | result.push(nInit(word, 2) + 'ие'); |
|
2335 | 2359 |
|
2336 | 2360 | function softPatronymicForm2() { |
2337 | 2361 | const part = simpleFirstPart; |
2338 | | - const index = part.toLowerCase().indexOf('ье'); |
| 2362 | + const index = toLowerCaseRu(part).indexOf('ье'); |
2339 | 2363 | const r = upperLike('и', part[index]); |
2340 | 2364 | return part.substring(0, index) + r + part.substring(index + 1); |
2341 | 2365 | } |
|
2806 | 2830 | // молодцы |
2807 | 2831 |
|
2808 | 2832 | function declinePlural(engine, lemma, grCase, plural) { |
2809 | | - const lcPlural = plural.toLowerCase(); |
| 2833 | + const lcPlural = toLowerCaseRu(plural); |
2810 | 2834 |
|
2811 | 2835 | const lcLastChar = last(lcPlural); |
2812 | 2836 | const lcLastBit = lcBit(lcLastChar); |
|
2874 | 2898 | const declension = lemma.getDeclension(); |
2875 | 2899 |
|
2876 | 2900 | const genitiveStem = () => { |
2877 | | - const lcStem = stem.toLowerCase(); |
| 2901 | + const lcStem = toLowerCaseRu(stem); |
2878 | 2902 |
|
2879 | 2903 | const dependsOnStress = ['жки', 'шки', 'чки', 'ножны']; |
2880 | 2904 |
|
|
3081 | 3105 | } |
3082 | 3106 | } |
3083 | 3107 |
|
3084 | | - if (stem.toLowerCase().endsWith('ийк')) { |
| 3108 | + if (toLowerCaseRu(stem).endsWith('ийк')) { |
3085 | 3109 | return nInit(stem, 2) + 'ек'; |
3086 | 3110 | } |
3087 | 3111 |
|
3088 | 3112 | if ((stem.length === lcPlural.length - 1) && endsWithLeaf(lcPlural, declinePluralSoftEndings)) { |
3089 | 3113 |
|
3090 | | - if ('ьй'.includes(lastOfNInitial(stem, 1).toLowerCase()) && !lemma.isAnimate()) { |
| 3114 | + if ('ьй'.includes(toLowerCaseRu(lastOfNInitial(stem, 1))) && !lemma.isAnimate()) { |
3091 | 3115 | const end = last(stem); |
3092 | 3116 | return nInit(stem, 2) + upperLike('е', end) + end; |
3093 | 3117 | } else if (endsWithAny(lcPlural, ['земли', 'петли', 'пли', 'вли'])) { |
|
0 commit comments