├── .eslintignore ├── .eslintrc.js ├── .github ├── FUNDING.yml └── workflows │ └── nodejs.yml ├── .gitignore ├── .markdownlint.json ├── .npmignore ├── .prettierrc ├── .vscode └── settings.json ├── LICENSE.md ├── README.md ├── jest.config.js ├── package.json ├── rollup.config.js ├── src ├── __tests__ │ ├── city-test.ts │ ├── gender-test.ts │ ├── incline-test.ts │ ├── inclineRules-test.ts │ ├── maps.vlasenko.net │ │ ├── by-list.csv │ │ ├── ru-list.csv │ │ └── ua-list.csv │ ├── opencorpora-test.ts │ └── opencorpora │ │ ├── firstnames.gender.tsv │ │ └── surnames.gender.tsv ├── city.ts ├── gender.ts ├── incline.ts ├── inclineRules.ts ├── index.ts ├── rules │ ├── cityRules.ts │ ├── genderRules.ts │ ├── inclineRulesFirstname.ts │ ├── inclineRulesLastname.ts │ └── inclineRulesMiddlename.ts └── utils.ts ├── tsconfig.build-esm.json ├── tsconfig.build-lib.json ├── tsconfig.json └── yarn.lock /.eslintignore: -------------------------------------------------------------------------------- 1 | lib 2 | mjs 3 | esm 4 | dist 5 | coverage 6 | *.js -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | parser: '@typescript-eslint/parser', 5 | plugins: ['@typescript-eslint', 'prettier'], 6 | extends: ['plugin:@typescript-eslint/recommended', 'prettier', 'plugin:prettier/recommended'], 7 | parserOptions: { 8 | sourceType: 'module', 9 | useJSXTextNode: true, 10 | project: [path.resolve(__dirname, 'tsconfig.json')], 11 | }, 12 | rules: { 13 | 'no-underscore-dangle': 0, 14 | 'arrow-body-style': 0, 15 | 'no-unused-expressions': 0, 16 | 'no-plusplus': 0, 17 | 'no-console': 0, 18 | 'func-names': 0, 19 | 'comma-dangle': [ 20 | 'error', 21 | { 22 | arrays: 'always-multiline', 23 | objects: 'always-multiline', 24 | imports: 'always-multiline', 25 | exports: 'always-multiline', 26 | functions: 'ignore', 27 | }, 28 | ], 29 | 'no-prototype-builtins': 0, 30 | 'prefer-destructuring': 0, 31 | 'no-else-return': 0, 32 | 'lines-between-class-members': ['error', 'always', { exceptAfterSingleLine: true }], 33 | '@typescript-eslint/explicit-member-accessibility': 0, 34 | '@typescript-eslint/no-explicit-any': 0, 35 | '@typescript-eslint/no-inferrable-types': 0, 36 | '@typescript-eslint/explicit-function-return-type': 0, 37 | '@typescript-eslint/no-use-before-define': 0, 38 | '@typescript-eslint/no-empty-function': 0, 39 | '@typescript-eslint/camelcase': 0, 40 | '@typescript-eslint/ban-ts-comment': 0, 41 | }, 42 | env: { 43 | jasmine: true, 44 | jest: true, 45 | }, 46 | }; 47 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [nodkz] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Patreon username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Node.js CI 5 | 6 | on: [push, pull_request] 7 | 8 | jobs: 9 | tests: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v2 13 | - name: Use Node.js 14 14 | uses: actions/setup-node@v2 15 | with: 16 | node-version: '14' 17 | - name: Install node_modules 18 | run: yarn 19 | - name: Test – Jest 20 | run: yarn coverage 21 | env: 22 | CI: true 23 | - name: Test – Eslint 24 | run: yarn eslint 25 | - name: Test – TSCheck 26 | run: yarn tscheck 27 | - name: Publish Test Report 28 | uses: mikepenz/action-junit-report@v2 29 | with: 30 | check_name: JUnit Annotations for Node ${{ matrix.node-version }} 31 | report_paths: '**/coverage/junit/**/*.xml' 32 | - name: Send codecov.io stats 33 | run: bash <(curl -s https://codecov.io/bash) || echo '' 34 | 35 | publish: 36 | if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/alpha' || github.ref == 'refs/heads/beta' 37 | needs: [tests] 38 | runs-on: ubuntu-latest 39 | steps: 40 | - uses: actions/checkout@v2 41 | - name: Use Node.js 14 42 | uses: actions/setup-node@v2 43 | with: 44 | node-version: 14 45 | - name: Install node_modules 46 | run: yarn install 47 | - name: Build 48 | run: yarn build 49 | - name: Semantic Release (publish to npm) 50 | run: yarn semantic-release 51 | env: 52 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 53 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 54 | 55 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | 15 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 16 | .grunt 17 | 18 | # node-waf configuration 19 | .lock-wscript 20 | 21 | # Compiled binary addons (http://nodejs.org/api/addons.html) 22 | build/Release 23 | 24 | # IntelliJ Files 25 | *.iml 26 | *.ipr 27 | *.iws 28 | /out/ 29 | .idea/ 30 | .idea_modules/ 31 | 32 | # Dependency directory 33 | node_modules 34 | 35 | # Optional npm cache directory 36 | .npm 37 | 38 | # Optional REPL history 39 | .node_repl_history 40 | 41 | # Transpiled code 42 | /es 43 | /lib 44 | /esm 45 | /mjs 46 | /dist 47 | 48 | coverage 49 | .nyc_output 50 | -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "line-length": false, 3 | "no-trailing-punctuation": { 4 | "punctuation": ".,;:!" 5 | }, 6 | "first-line-h1": false, 7 | "no-inline-html": false 8 | } -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.log 3 | src 4 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "printWidth": 100, 6 | "trailingComma": "es5" 7 | } 8 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "javascript.validate.enable": false, 3 | "cSpell.words": [ 4 | "constantize", 5 | "Declention", 6 | "firstname", 7 | "lastname", 8 | "lvovich", 9 | "middlename" 10 | ] 11 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018-present @nodkz 4 | Copyright (c) 2013-2018 [Petrovich](https://github.com/petrovich/petrovich-js/blob/master/LICENSE) 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Lvovich (Львович) - JS library to inflect people names, cities names in Russian 2 | 3 | [![npm](https://img.shields.io/npm/v/lvovich.svg)](https://www.npmjs.com/package/lvovich) 4 | [![codecov coverage](https://img.shields.io/codecov/c/github/nodkz/lvovich.svg)](https://codecov.io/github/nodkz/lvovich) 5 | [![Travis](https://img.shields.io/travis/nodkz/lvovich.svg?maxAge=2592000)](https://travis-ci.org/nodkz/lvovich) 6 | [![npmtrends](https://img.shields.io/npm/dt/lvovich.svg)](http://www.npmtrends.com/lvovich) 7 | [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/) 8 | ![TypeScript compatible](https://img.shields.io/badge/typescript-compatible-brightgreen.svg) 9 | 10 | 0 сторонних зависимостей, может работать как на сервере, так и в браузере. 11 | 12 | Этот пакет для: 13 | 14 | - склонения названий городов (работает для большинства составных названий: Санкт-Петербург, Ростов-на-Дону и пр.) 15 | - определения пола по имени фамилии и отчеству 16 | - склонения падежей русских имен, фамилий и отчеств 17 | 18 | Может использоваться как в браузере, так и на сервере. Нет никаких зависимостей и работает в оффлайне. Самое то: 19 | 20 | - для генерации красивых писем с [mjml](https://github.com/mjmlio/mjml) 21 | - для генерации PDF c [@react-pdf](https://github.com/diegomura/react-pdf) 22 | - для генерации SEO-заголовков c [головой на плечах](https://comic.browserling.com/seo-expert-ru.png) 23 | - чтоб по максимуму избавиться от **Уважаемый(-ая)**, когда есть ФИО но нет пола 24 | 25 | **Минифицированный размер пакета 20KB, gzipped 6KB.** Бедные, бедные иностранцы - им надо загрузить в голову 20 килобайт правил и уметь быстро ими пользоваться в разговорной речи. Ужос! 26 | 27 | PS. Если вдруг вы ищете список всех городов и сел с гео-координатами [России](https://maps.vlasenko.net/russia/ru-list.csv), [Белоруси](https://maps.vlasenko.net/belarus/by-list.csv) и [Украины](https://maps.vlasenko.net/ukraine/ua-list.csv) - их можно найти в формате csv на сайте [https://maps.vlasenko.net/](https://maps.vlasenko.net/). 28 | 29 | ## [Live Demo](https://codesandbox.io/s/nr8k2241wj) 30 | 31 | [Live Demo](https://codesandbox.io/s/nr8k2241wj) 32 | 33 | ## Cклонение названий городов 34 | 35 | ```js 36 | import { cityIn, cityFrom, cityTo } from 'lvovich'; 37 | ``` 38 | 39 | ### `cityIn(name: string, gender?: GenderStrT): string` - в каком городе живете/находитесь? (предложный падеж) 40 | 41 | ```js 42 | cityIn('Санкт-Петербург'); // вернет `Санкт-Петербурге` 43 | ``` 44 | 45 | ### `cityFrom(name: string, gender?: GenderStrT): string` - из какого города приехали? (родительный падеж) 46 | 47 | ```js 48 | cityFrom('Санкт-Петербург'); // вернет `Санкт-Петербурга` 49 | ``` 50 | 51 | ### `cityTo(name: string): string` - в какой город направляетесь? (направительный или посылательный падеж :) 52 | 53 | ```js 54 | cityTo('Санкт-Петербург'); // вернет `Санкт-Петербург` 55 | cityTo('Москва'); // вернет `Москву` 56 | ``` 57 | 58 | ## Определения пола по имени фамилии и отчеству 59 | 60 | ```js 61 | import { getGender, getFirstnameGender, getLastnameGender, getMiddlenameGender } from 'lvovich'; 62 | ``` 63 | 64 | Методы определения пола возвращают тип `GenderStrT`: 65 | 66 | - `male` - мужской, 67 | - `female` - женский, 68 | - `androgynous` - может быть и мальчиком и девочкой 69 | - `null` - не удалось определить пол 70 | 71 | ### `getGender(fio: FioT): ?GenderStrT` - передаете ФИО, получаете пол 72 | 73 | Входящий аргумент `fio` являеется объектов со следующими необязательными полями: 74 | 75 | ```js 76 | type FioT = { 77 | first?: ?string, 78 | last?: ?string, 79 | middle?: ?string, 80 | } 81 | ``` 82 | 83 | ```js 84 | getGender({ last: 'Друзь', first: 'Саша', middle: 'Петрович' }); // вернет `male` 85 | getGender({ first: 'Саша' }); // вернет `androgynous`, т.к. может быть мальчик или девочка 86 | getGender({ first: 'Саша', middle: 'Петровна' }); // вернет `female` 87 | getGender({ last: 'Абуова', first: 'Андрей' }); // вернет `null`, ну нафиг гадать т.к. вроде фамилия женская и имя мужское. 88 | ``` 89 | 90 | ### `getFirstnameGender(str: string): ?GenderStrT` - вернет пол для Имени 91 | 92 | ```js 93 | getFirstnameGender('Павел'); // вернет `male` 94 | getFirstnameGender('Анна'); // вернет `female` 95 | getFirstnameGender('Саша'); // вернет `androgynous` 96 | getFirstnameGender('аааа'); // вернет `null` 97 | ``` 98 | 99 | ### `getLastnameGender(str: string): ?GenderStrT` - вернет пол для Фамилии 100 | 101 | ```js 102 | getLastnameGender('Градский'); // вернет `male` 103 | getLastnameGender('Таптыгина'); // вернет `female` 104 | getLastnameGender('Борейко'); // вернет `androgynous` 105 | getLastnameGender('аааа'); // вернет `null` 106 | ``` 107 | 108 | ### `getMiddlenameGender(str: string): ?GenderStrT` - вернет пол для Отчества 109 | 110 | ```js 111 | getMiddlenameGender('Павлович'); // вернет `male` 112 | getMiddlenameGender('Петрова'); // вернет `female` 113 | getMiddlenameGender('иваново'); // вернет `null` 114 | getMiddlenameGender('аааа'); // вернет `null` 115 | ``` 116 | 117 | ## Cклонения падежей русских имен, фамилий и отчеств 118 | 119 | ```js 120 | import { incline, inclineFirstname, inclineLastname, inclineMiddlename } from 'lvovich'; 121 | ``` 122 | 123 | Падежи (тип `DeclentionStrT`): 124 | 125 | - `nominative` - именительный (кто? что?) 126 | - `genitive` - родительный (кого? чего?) 127 | - `dative` - дательный (кому? чему?) 128 | - `accusative` - винительный (кого? что?) 129 | - `instrumental` - творительный (кем? чем?) 130 | - `prepositional` - предложный (о ком? о чем?) 131 | 132 | ### `incline(person: LvovichPersonT, declension?: DeclentionStrT): LvovichPersonT` - просклонять по падежам 133 | 134 | Если не указан `declension`, то будет использован винительный падеж. 135 | 136 | ```js 137 | incline({ first: 'Саша', last: 'Иванов' }, 'dative'); 138 | // вернет { first: 'Саше', last: 'Иванову', gender: 'male' } 139 | 140 | incline({ first: 'Паша' }, 'instrumental'); 141 | // вернет { first: 'Пашей', gender: 'male' }) 142 | ``` 143 | 144 | Тип `LvovichPersonT` для `incline(person: LvovichPersonT)` является объектом с необязательными полями: 145 | 146 | ```js 147 | { 148 | first?: ?string, 149 | last?: ?string, 150 | middle?: ?string, 151 | gender?: ?GenderStrT, 152 | } 153 | ``` 154 | 155 | ### `inclineFirstname(str: string, declension?: DeclentionStrT, gender?: GenderStrT): string` - просклонять Имя по падежам 156 | 157 | Если пол `gender` не указан, то будет запущено автоопределение, если не указано склонение `declension` то будет применен винительный падеж. 158 | 159 | ```js 160 | inclineFirstname('Павел', 'genitive'); // вернет 'Павла' 161 | inclineFirstname('Женя', 'instrumental'); // вернет 'Женя' 162 | inclineFirstname('Женя', 'instrumental', 'male'); // вернет 'Женей' 163 | inclineFirstname('Женя', 'instrumental', 'female'); // вернет 'Женей' 164 | ``` 165 | 166 | ### `inclineLastname(str: string, declension?: DeclentionStrT, gender?: GenderStrT): string` - просклонять Фамилию по падежам 167 | 168 | ```js 169 | inclineLastname('Иванова', 'genitive'); // вернет 'Ивановой' 170 | inclineLastname('Петросян', 'instrumental'); // вернет 'Петросян' 171 | inclineLastname('Петросян', 'instrumental', 'male'); // вернет 'Петросяном' 172 | ``` 173 | 174 | ### `inclineMiddlename(str: string, declension?: DeclentionStrT, gender?: GenderStrT): string` - просклонять Отчество по падежам 175 | 176 | ```js 177 | inclineMiddlename('Львович', 'genitive'); // вернет 'Львовича' 178 | ``` 179 | 180 | ## Установка 181 | 182 | Через npm: 183 | 184 | ```bash 185 | npm install lvovich 186 | ``` 187 | 188 | Или в браузере: 189 | 190 | ```html 191 | 192 | 198 | ``` 199 | 200 | ## Разработчику 201 | 202 | Сборка новой версии пакета происходит автоматически через [semantic-release](https://github.com/semantic-release/semantic-release) и Travis. Ваши изменения я могу опубликовать хоть с телефона. 203 | 204 | От вас просто необходимо склонировать репозиторий, внести изменения в код и открыть Pull Request. 205 | 206 | Клонирование репозитория и установка модулей: 207 | 208 | ```bash 209 | git clone https://github.com/nodkz/lvovich.git 210 | cd lvovich 211 | yarn install 212 | ``` 213 | 214 | Тесты находятся в директории ```src/__tests__```. Запуск тестов: 215 | 216 | ```bash 217 | yarn test 218 | ``` 219 | 220 | ## Лицензия 221 | 222 | [MIT](./LICENSE.md) 223 | 224 | В основу этого пакета лег код и правила из [petrovich-js](https://github.com/petrovich/petrovich-js). Код был переписан и оптимизирован, часть правил была расширена. API полностью был изменен, и стал использовать `camelCase`. 225 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | testEnvironment: 'node', 4 | globals: { 5 | 'ts-jest': { 6 | tsconfig: '/tsconfig.json', 7 | isolatedModules: true, 8 | diagnostics: false, 9 | }, 10 | }, 11 | moduleFileExtensions: ['ts', 'js'], 12 | transform: { 13 | '^.+\\.(ts|js)$': 'ts-jest', 14 | }, 15 | roots: ['/src'], 16 | testPathIgnorePatterns: ['/node_modules/', '/lib/'], 17 | reporters: [ 18 | 'default', 19 | [ 20 | 'jest-junit', 21 | { 22 | outputDirectory: 'coverage/junit/', 23 | outputName: 'jest-junit.xml', 24 | classNameTemplate: '{classname} › {title}', 25 | titleTemplate: '{classname} › {title}', 26 | suiteName: '{filepath}', 27 | addFileAttribute: 'true', 28 | ancestorSeparator: ' › ', 29 | usePathForSuiteName: 'true', 30 | }, 31 | ], 32 | ], 33 | }; 34 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lvovich", 3 | "version": "0.0.0-semantic-release", 4 | "description": "Library to decline people & city names in Russian, and to detect gender by name", 5 | "engines": { 6 | "node": ">= 6" 7 | }, 8 | "files": [ 9 | "lib", 10 | "esm", 11 | "dist" 12 | ], 13 | "authors": [ 14 | "@thaumant ", 15 | "@dustalov ", 16 | "@nodkz " 17 | ], 18 | "main": "lib/index.js", 19 | "types": "lib/index.d.ts", 20 | "repository": { 21 | "type": "git", 22 | "url": "https://github.com/nodkz/lvovich.git" 23 | }, 24 | "keywords": [ 25 | "petrovich", 26 | "lvovich" 27 | ], 28 | "license": "MIT", 29 | "bugs": { 30 | "url": "https://github.com/nodkz/lvovich/issues" 31 | }, 32 | "homepage": "https://github.com/nodkz/lvovich", 33 | "devDependencies": { 34 | "@rollup/plugin-typescript": "^8.3.0", 35 | "@types/jest": "^27.0.3", 36 | "@typescript-eslint/eslint-plugin": "^5.7.0", 37 | "@typescript-eslint/parser": "^5.7.0", 38 | "cz-conventional-changelog": "3.3.0", 39 | "eslint": "8.4.1", 40 | "eslint-config-airbnb-base": "15.0.0", 41 | "eslint-config-prettier": "8.3.0", 42 | "eslint-plugin-import": "2.25.3", 43 | "eslint-plugin-prettier": "4.0.0", 44 | "jest": "27.4.5", 45 | "jest-junit": "^13.0.0", 46 | "prettier": "2.5.1", 47 | "rimraf": "3.0.2", 48 | "rollup": "2.61.1", 49 | "rollup-plugin-commonjs": "10.1.0", 50 | "rollup-plugin-gzip": "3.0.0", 51 | "rollup-plugin-uglify": "6.0.4", 52 | "semantic-release": "18.0.1", 53 | "ts-jest": "^27.1.1", 54 | "typescript": "4.5.4" 55 | }, 56 | "config": { 57 | "commitizen": { 58 | "path": "./node_modules/cz-conventional-changelog" 59 | } 60 | }, 61 | "scripts": { 62 | "build": "npm run build-cjs && npm run build-esm && npm run build-umd", 63 | "build-umd": "rimraf umd && BABEL_ENV=umd NODE_ENV=production rollup src/index.ts --config --sourcemap --file dist/lvovich.min.js", 64 | "build-cjs": "rimraf lib && tsc -p ./tsconfig.build-lib.json", 65 | "build-esm": "rimraf esm && tsc -p ./tsconfig.build-esm.json", 66 | "watch": "jest --watch", 67 | "coverage": "jest --coverage", 68 | "lint": "npm run eslint && npm run tscheck", 69 | "eslint": "eslint --ext .ts ./src", 70 | "tscheck": "tsc --noEmit", 71 | "test": "npm run coverage && npm run lint", 72 | "semantic-release": "semantic-release" 73 | }, 74 | "dependencies": {} 75 | } 76 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import commonjs from 'rollup-plugin-commonjs'; 2 | import { uglify } from 'rollup-plugin-uglify'; 3 | import gzip from 'rollup-plugin-gzip'; 4 | import typescript from '@rollup/plugin-typescript'; 5 | 6 | export default { 7 | output: { 8 | name: 'lvovich', 9 | format: 'umd', 10 | }, 11 | plugins: [ 12 | typescript({ 13 | module: 'esnext', 14 | tsconfig: './tsconfig.json', 15 | }), 16 | commonjs(), 17 | uglify({ 18 | compress: { 19 | pure_getters: true, 20 | unsafe: true, 21 | unsafe_comps: true, 22 | }, 23 | }), 24 | gzip(), 25 | ], 26 | }; 27 | -------------------------------------------------------------------------------- /src/__tests__/city-test.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-use-before-define, no-continue, arrow-parens */ 2 | 3 | import { cityIn, cityFrom, cityTo } from '../city'; 4 | import { cityRules } from '../rules/cityRules'; 5 | import { findRule } from '../inclineRules'; 6 | import { ANDROGYNOUS } from '../gender'; 7 | 8 | describe('lvovich/city', () => { 9 | describe('cityIn() cityFrom(), cityTo()', () => { 10 | function expect3fn(str: string) { 11 | const lines = str 12 | .split(/\n|\r/g) 13 | .map((s) => s.trim()) 14 | .map((s) => s.replace(/#.*|\/\/.*/, '')) 15 | .filter((s) => !!s); 16 | lines.forEach((line) => { 17 | const [arg, res1, res2, res3] = line.split(',').map((s) => s.trim()); 18 | 19 | const generated = `${arg}, ${cityIn(arg)}, ${cityFrom(arg)}, ${cityTo(arg)}`; 20 | const fromTest = `${arg}, ${res1}, ${res2}, ${res3}`; 21 | if (generated !== fromTest) { 22 | console.error( 23 | 'Format HINT: [city|именит, cityIn|предлож, cityFrom|родит, cityTo|направительный]\n' + 24 | `Generated: ${arg}, в ${cityIn(arg)}, из ${cityFrom(arg)}, to ${cityTo(arg)}\n` + 25 | `In test file: ${arg}, в ${res1}, из ${res2}, to ${res3}` 26 | ); 27 | const cityRule = findRule(arg, ANDROGYNOUS, cityRules); 28 | if (cityRule) { 29 | console.error( 30 | `Was used rule from cityRules.js: ${JSON.stringify(cityRule)}` + 31 | '\nYou need to review this rule firstly!' 32 | ); 33 | } 34 | } 35 | expect(generated).toMatch(fromTest); 36 | }); 37 | } 38 | 39 | function expect3fnFromDemo(str: string) { 40 | if (!str) return; 41 | const s = str.replace(/(, в)|(, из)|(, to)/gi, ', '); 42 | expect3fn(s); 43 | } 44 | 45 | it('correct declension for KZ cities', () => { 46 | expect3fn( 47 | ` 48 | Абай, Абае, Абая, Абай 49 | Акколь, Акколе, Акколя, Акколь 50 | Аксай, Аксае, Аксая, Аксай 51 | Аксу, Аксу, Аксу, Аксу 52 | Актау, Актау, Актау, Актау 53 | Актобе, Актобе, Актобе, Актобе 54 | Алга, Алге, Алги, Алгу 55 | Алматы, Алматы, Алматы, Алматы 56 | Аральск, Аральске, Аральска, Аральск 57 | Аркалык, Аркалыке, Аркалыка, Аркалык 58 | Арысь, Арысе, Арыся, Арысь 59 | Астана, Астане, Астаны, Астану 60 | Нур-Султан, Нур-Султане, Нур-Султана, Нур-Султан 61 | Атбасар, Атбасаре, Атбасара, Атбасар 62 | Атырау, Атырау, Атырау, Атырау 63 | Аягоз, Аягозе, Аягоза, Аягоз 64 | Байконыр, Байконыре, Байконыра, Байконыр 65 | Балхаш, Балхаше, Балхаша, Балхаш 66 | Булаево, Булаево, Булаево, Булаево 67 | Державинск, Державинске, Державинска, Державинск 68 | Ерейментау, Ерейментау, Ерейментау, Ерейментау 69 | Есик, Есике, Есика, Есик 70 | Есиль, Есиле, Есиля, Есиль 71 | Жанаозен, Жанаозене, Жанаозена, Жанаозен 72 | Жанатас, Жанатасе, Жанатаса, Жанатас 73 | Жаркент, Жаркенте, Жаркента, Жаркент 74 | Жезказган, Жезказгане, Жезказгана, Жезказган 75 | Жем, Жеме, Жема, Жем 76 | Жетысай, Жетысае, Жетысая, Жетысай 77 | Житикара, Житикаре, Житикары, Житикару 78 | Зайсан, Зайсане, Зайсана, Зайсан 79 | Зыряновск, Зыряновске, Зыряновска, Зыряновск 80 | Казалинск, Казалинске, Казалинска, Казалинск 81 | Кандыагаш, Кандыагаше, Кандыагаша, Кандыагаш 82 | Капчагай, Капчагае, Капчагая, Капчагай 83 | Караганда, Караганде, Караганды, Караганду 84 | Каражал, Каражале, Каражала, Каражал 85 | Карасу, Карасу, Карасу, Карасу 86 | Каратау, Каратау, Каратау, Каратау 87 | Каркаралинск, Каркаралинске, Каркаралинска, Каркаралинск 88 | Каскелен, Каскелене, Каскелена, Каскелен 89 | Кентау, Кентау, Кентау, Кентау 90 | Кокшетау, Кокшетау, Кокшетау, Кокшетау 91 | Костанай, Костанае, Костаная, Костанай 92 | Кронштадт, Кронштадте, Кронштадта, Кронштадт 93 | Кульсары, Кульсарах, Кульсар, Кульсары 94 | Курчатов, Курчатове, Курчатова, Курчатов 95 | Кызылорда, Кызылорде, Кызылорды, Кызылорду 96 | Ленгер, Ленгере, Ленгера, Ленгер 97 | Лисаковск, Лисаковске, Лисаковска, Лисаковск 98 | Макинск, Макинске, Макинска, Макинск 99 | Мамлютка, Мамлютке, Мамлютки, Мамлютку 100 | Павлодар, Павлодаре, Павлодара, Павлодар 101 | Петропавловск, Петропавловске, Петропавловска, Петропавловск 102 | Приозёрск, Приозёрске, Приозёрска, Приозёрск 103 | Риддер, Риддере, Риддера, Риддер 104 | Рудный, Рудном, Рудного, Рудный 105 | Сарань, Сарани, Сарани, Сарань 106 | Сарканд, Сарканде, Сарканда, Сарканд 107 | Сарыагаш, Сарыагаше, Сарыагаша, Сарыагаш 108 | Сатпаев, Сатпаеве, Сатпаева, Сатпаев 109 | Семей, Семее, Семея, Семей 110 | Сергеевка, Сергеевке, Сергеевки, Сергеевку 111 | Серебрянск, Серебрянске, Серебрянска, Серебрянск 112 | Степногорск, Степногорске, Степногорска, Степногорск 113 | Степняк, Степняке, Степняка, Степняк 114 | Тайынша, Тайынше, Тайынши, Тайыншу 115 | Талгар, Талгаре, Талгара, Талгар 116 | Талдыкорган, Талдыкоргане, Талдыкоргана, Талдыкорган 117 | Тараз, Таразе, Тараза, Тараз 118 | Текели, Текели, Текели, Текели 119 | Темир, Темире, Темира, Темир 120 | Темиртау, Темиртау, Темиртау, Темиртау 121 | Туркестан, Туркестане, Туркестана, Туркестан 122 | Уральск, Уральске, Уральска, Уральск 123 | Ушарал, Ушарале, Ушарала, Ушарал 124 | Уштобе, Уштобе, Уштобе, Уштобе 125 | Хромтау, Хромтау, Хромтау, Хромтау 126 | Шардара, Шардаре, Шардары, Шардару 127 | Шалкар, Шалкаре, Шалкара, Шалкар 128 | Шар, Шаре, Шара, Шар 129 | Шахтинск, Шахтинске, Шахтинска, Шахтинск 130 | Шемонаиха, Шемонаихе, Шемонаихи, Шемонаиху 131 | Шу, Шу, Шу, Шу 132 | Шымкент, Шымкенте, Шымкента, Шымкент 133 | Щучинск, Щучинске, Щучинска, Щучинск 134 | Экибастуз, Экибастузе, Экибастуза, Экибастуз 135 | Эмба, Эмбе, Эмбы, Эмбу 136 | Усть-Каменогорск, Усть-Каменогорске, Усть-Каменогорска, Усть-Каменогорск 137 | Форт-Шевченко, Форт-Шевченко, Форт-Шевченко, Форт-Шевченко 138 | село Чемолган, селе Чемолган, села Чемолган, село Чемолган 139 | вахтовый поселок Тенгиз, вахтовом поселке Тенгиз, вахтового поселка Тенгиз, вахтовый поселок Тенгиз, 140 | ` 141 | ); 142 | // city, cityIn, cityFrom, cityTo 143 | }); 144 | 145 | it('correct declension for RU cities', () => { 146 | expect3fn( 147 | ` 148 | Москва, Москве, Москвы, Москву 149 | Новосибирск, Новосибирске, Новосибирска, Новосибирск 150 | Екатеринбург, Екатеринбурге, Екатеринбурга, Екатеринбург 151 | Казань, Казани, Казани, Казань 152 | Челябинск, Челябинске, Челябинска, Челябинск 153 | Омск, Омске, Омска, Омск 154 | Самара, Самаре, Самары, Самару 155 | Уфа, Уфе, Уфы, Уфу 156 | Красноярск, Красноярске, Красноярска, Красноярск 157 | Воронеж, Воронеже, Воронежа, Воронеж 158 | Волгоград, Волгограде, Волгограда, Волгоград 159 | Краснодар, Краснодаре, Краснодара, Краснодар 160 | Саратов, Саратове, Саратова, Саратов 161 | Тольятти, Тольятти, Тольятти, Тольятти 162 | Ижевск, Ижевске, Ижевска, Ижевск 163 | Барнаул, Барнауле, Барнаула, Барнаул 164 | Иркутск, Иркутске, Иркутска, Иркутск 165 | Ульяновск, Ульяновске, Ульяновска, Ульяновск 166 | Хабаровск, Хабаровске, Хабаровска, Хабаровск 167 | Владивосток, Владивостоке, Владивостока, Владивосток 168 | Махачкала, Махачкале, Махачкалы, Махачкалу 169 | Томск, Томске, Томска, Томск 170 | Оренбург, Оренбурге, Оренбурга, Оренбург 171 | Кемерово, Кемерово, Кемерово, Кемерово 172 | Новокузнецк, Новокузнецке, Новокузнецка, Новокузнецк 173 | Рязань, Рязани, Рязани, Рязань 174 | Астрахань, Астрахани, Астрахани, Астрахань 175 | Пенза, Пензе, Пензы, Пензу 176 | Липецк, Липецке, Липецка, Липецк 177 | Киров, Кирове, Кирова, Киров 178 | Чебоксары, Чебоксарах, Чебоксар, Чебоксары 179 | Тула, Туле, Тулы, Тулу 180 | Калининград, Калининграде, Калининграда, Калининград 181 | Курск, Курске, Курска, Курск 182 | Улан-Удэ, Улан-Удэ, Улан-Удэ, Улан-Удэ 183 | Балашиха, Балашихе, Балашихи, Балашиху 184 | Тверь, Твери, Твери, Тверь 185 | Магнитогорск, Магнитогорске, Магнитогорска, Магнитогорск 186 | Иваново, Иваново, Иваново, Иваново 187 | Брянск, Брянске, Брянска, Брянск 188 | Сочи, Сочи, Сочи, Сочи 189 | Белгород, Белгороде, Белгорода, Белгород 190 | Владимир, Владимире, Владимира, Владимир 191 | Архангельск, Архангельске, Архангельска, Архангельск 192 | Сургут, Сургуте, Сургута, Сургут 193 | Чита, Чите, Читы, Читу 194 | Калуга, Калуге, Калуги, Калугу 195 | Смоленск, Смоленске, Смоленска, Смоленск 196 | Курган, Кургане, Кургана, Курган 197 | Вологда, Вологде, Вологды, Вологду 198 | Саранск, Саранске, Саранска, Саранск 199 | Владикавказ, Владикавказе, Владикавказа, Владикавказ 200 | Якутск, Якутске, Якутска, Якутск 201 | Мурманск, Мурманске, Мурманска, Мурманск 202 | Подольск, Подольске, Подольска, Подольск 203 | Тамбов, Тамбове, Тамбова, Тамбов 204 | Грозный, Грозном, Грозного, Грозный 205 | Стерлитамак, Стерлитамаке, Стерлитамака, Стерлитамак 206 | Петрозаводск, Петрозаводске, Петрозаводска, Петрозаводск 207 | Кострома, Костроме, Костромы, Кострому 208 | Нижневартовск, Нижневартовске, Нижневартовска, Нижневартовск 209 | Новороссийск, Новороссийске, Новороссийска, Новороссийск 210 | Йошкар-Ола, Йошкар-Оле, Йошкар-Олы, Йошкар-Олу 211 | Таганрог, Таганроге, Таганрога, Таганрог 212 | Сыктывкар, Сыктывкаре, Сыктывкара, Сыктывкар 213 | Нальчик, Нальчике, Нальчика, Нальчик 214 | Шахты, Шахты, Шахты, Шахты 215 | Нижнекамск, Нижнекамске, Нижнекамска, Нижнекамск 216 | Братск, Братске, Братска, Братск 217 | Дзержинск, Дзержинске, Дзержинска, Дзержинск 218 | Орск, Орске, Орска, Орск 219 | Ангарск, Ангарске, Ангарска, Ангарск 220 | Благовещенск, Благовещенске, Благовещенска, Благовещенск 221 | Псков, Пскове, Пскова, Псков 222 | Бийск, Бийске, Бийска, Бийск 223 | Прокопьевск, Прокопьевске, Прокопьевска, Прокопьевск 224 | Южно-Сахалинск, Южно-Сахалинске, Южно-Сахалинска, Южно-Сахалинск 225 | Балаково, Балаково, Балаково, Балаково 226 | Рыбинск, Рыбинске, Рыбинска, Рыбинск 227 | Армавир, Армавире, Армавира, Армавир 228 | Люберцы, Люберцах, Люберц, Люберцы 229 | Северодвинск, Северодвинске, Северодвинска, Северодвинск 230 | Абакан, Абакане, Абакана, Абакан 231 | Норильск, Норильске, Норильска, Норильск 232 | Сызрань, Сызрани, Сызрани, Сызрань 233 | Волгодонск, Волгодонске, Волгодонска, Волгодонск 234 | Новочеркасск, Новочеркасске, Новочеркасска, Новочеркасск 235 | Златоуст, Златоусте, Златоуста, Златоуст 236 | Уссурийск, Уссурийске, Уссурийска, Уссурийск 237 | Электросталь, Электростале, Электросталя, Электросталь 238 | Салават, Салавате, Салавата, Салават 239 | Находка, Находке, Находки, Находку 240 | Альметьевск, Альметьевске, Альметьевска, Альметьевск 241 | Рубцовск, Рубцовске, Рубцовска, Рубцовск 242 | Копейск, Копейске, Копейска, Копейск 243 | Пятигорск, Пятигорске, Пятигорска, Пятигорск 244 | Красногорск, Красногорске, Красногорска, Красногорск 245 | Майкоп, Майкопе, Майкопа, Майкоп 246 | Коломна, Коломне, Коломны, Коломну 247 | Одинцово, Одинцово, Одинцово, Одинцово 248 | Ковров, Коврове, Коврова, Ковров 249 | Хасавюрт, Хасавюрте, Хасавюрта, Хасавюрт 250 | Кисловодск, Кисловодске, Кисловодска, Кисловодск 251 | Серпухов, Серпухове, Серпухова, Серпухов 252 | Новомосковск, Новомосковске, Новомосковска, Новомосковск 253 | Нефтекамск, Нефтекамске, Нефтекамска, Нефтекамск 254 | Новочебоксарск, Новочебоксарске, Новочебоксарска, Новочебоксарск 255 | Нефтеюганск, Нефтеюганске, Нефтеюганска, Нефтеюганск 256 | Первоуральск, Первоуральске, Первоуральска, Первоуральск 257 | Щёлково, Щёлково, Щёлково, Щёлково 258 | Дербент, Дербенте, Дербента, Дербент 259 | Черкесск, Черкесске, Черкесска, Черкесск 260 | Батайск, Батайске, Батайска, Батайск 261 | Орехово-Зуево, Орехово-Зуево, Орехово-Зуево, Орехово-Зуево 262 | Невинномысск, Невинномысске, Невинномысска, Невинномысск 263 | Домодедово, Домодедово, Домодедово, Домодедово 264 | Димитровград, Димитровграде, Димитровграда, Димитровград 265 | Кызыл, Кызыле, Кызыла, Кызыл 266 | Назрань, Назрани, Назрани, Назрань 267 | Камышин, Камышине, Камышина, Камышин 268 | Обнинск, Обнинске, Обнинска, Обнинск 269 | Каспийск, Каспийске, Каспийска, Каспийск 270 | Муром, Муроме, Мурома, Муром 271 | Новошахтинск, Новошахтинске, Новошахтинска, Новошахтинск 272 | Северск, Северске, Северска, Северск 273 | Пушкино, Пушкино, Пушкино, Пушкино 274 | Ноябрьск, Ноябрьске, Ноябрьска, Ноябрьск 275 | Евпатория, Евпатории, Евпатории, Евпаторию 276 | Ачинск, Ачинске, Ачинска, Ачинск 277 | Арзамас, Арзамасе, Арзамаса, Арзамас 278 | Элиста, Элисте, Элисты, Элисту 279 | Новокуйбышевск, Новокуйбышевске, Новокуйбышевска, Новокуйбышевск 280 | Бердск, Бердске, Бердска, Бердск 281 | Ногинск, Ногинске, Ногинска, Ногинск 282 | Долгопрудный, Долгопрудном, Долгопрудного, Долгопрудный 283 | Реутов, Реутове, Реутова, Реутов 284 | Пермь, Перми, Перми, Пермь 285 | Тюмень, Тюмени, Тюмени, Тюмень 286 | Керчь, Керчи, Керчи, Керчь 287 | Ярославль, Ярославле, Ярославля, Ярославль 288 | Ставрополь, Ставрополе, Ставрополя, Ставрополь 289 | Севастополь, Севастополе, Севастополя, Севастополь 290 | Симферополь, Симферополе, Симферополя, Симферополь 291 | Королёв, Королёве, Королёва, Королёв 292 | Артём, Артёме, Артёма, Артём 293 | Орёл, Орле, Орла, Орёл 294 | Елец, Елеце, Елеца, Елец 295 | Череповец, Череповеце, Череповеца, Череповец 296 | Миасс, Миассе, Миасса, Миасс 297 | Энгельс, Энгельсе, Энгельса, Энгельс 298 | Химки, Химках, Химков, Химки 299 | Березники, Березниках, Березников, Березники 300 | Ессентуки, Ессентуках, Ессентуков, Ессентуки 301 | Мытищи, Мытищах, Мытищ, Мытищи 302 | Нижний Новгород, Нижнем Новгороде, Нижнего Новгорода, Нижний Новгород 303 | Нижний Тагил, Нижнем Тагиле, Нижнего Тагила, Нижний Тагил 304 | Великий Новгород, Великом Новгороде, Великого Новгорода, Великий Новгород 305 | Новый Уренгой, Новом Уренгое, Нового Уренгоя, Новый Уренгой 306 | Санкт-Петербург, Санкт-Петербурге, Санкт-Петербурга, Санкт-Петербург 307 | Ростов-на-Дону, Ростове-на-Дону, Ростова-на-Дону, Ростов-на-Дону 308 | Комсомольск-на-Амуре, Комсомольске-на-Амуре, Комсомольска-на-Амуре, Комсомольск-на-Амуре 309 | Старый Оскол, Старом Осколе, Старого Оскола, Старый Оскол 310 | Волжский, Волжском, Волжского, Волжский 311 | Октябрьский, Октябрьском, Октябрьского, Октябрьский 312 | Жуковский, Жуковском, Жуковского, Жуковский 313 | Раменское, Раменском, Раменского, Раменское 314 | Рижская, Рижской, Рижской, Рижскую 315 | Рижский, Рижском, Рижского, Рижский 316 | Сергиев Посад, Сергиевом Посаде, Сергиева Посада, Сергиев Посад 317 | Каменск-Уральский, Каменске-Уральском, Каменска-Уральского, Каменск-Уральский 318 | Петропавловск-Камчатский, Петропавловске-Камчатском, Петропавловска-Камчатского, Петропавловск-Камчатский 319 | Набережные Челны, Набережных Челнах, Набережных Челнов, Набережные Челны 320 | Вышний Волочёк, Вышнем Волочке, Вышнего Волочка, Вышний Волочёк 321 | Чик, Чике, Чика, Чик 322 | Хлевище, Хлевище, Хлевища, Хлевище 323 | Щучье, Щучье, Щучья, Щучье 324 | Холмечь, Холмечи, Холмечи, Холмечь 325 | Чепеничи, Чепеничах, Чепеничей, Чепеничи 326 | Ропша, Ропше, Ропши, Ропшу 327 | Крым, Крыму, Крыма, Крым 328 | ` 329 | ); 330 | }); 331 | 332 | it('correct declension for other cities', () => { 333 | expect3fn( 334 | ` 335 | Тбилиси, Тбилиси, Тбилиси, Тбилиси 336 | Утрехт, Утрехте, Утрехта, Утрехт 337 | Апелдорн, Апелдорне, Апелдорна, Апелдорн 338 | Ситтард-Гелен, Ситтард-Гелене, Ситтард-Гелена, Ситтард-Гелен 339 | Хельсинки, Хельсинки, Хельсинки, Хельсинки 340 | ` 341 | ); 342 | }); 343 | 344 | it('correct declension from demo https://codesandbox.io/s/nr8k2241wj', () => { 345 | expect3fnFromDemo(` 346 | красный боец, в красном боеце, из красного боеца, to красный боец 347 | Ропша, в Ропше, из Ропши, to Ропшу 348 | стрый, в стром, из строго, to стрый 349 | Актау, в Актау, из Актау, to Актау 350 | Барнаул, в Барнауле, из Барнаула, to Барнаул 351 | Бель, в Беле, из Беля, to Бель 352 | Боровичи, в Боровичах, из Боровичей, to Боровичи 353 | великие луки, в великих луках, из великих луков, to великие луки 354 | Владимир, в Владимире, из Владимира, to Владимир 355 | Екатеринбург, в Екатеринбурге, из Екатеринбурга, to Екатеринбург 356 | Калязин, в Калязине, из Калязина, to Калязин 357 | Комсомольск-на-Амуре, в Комсомольске-на-Амуре, из Комсомольска-на-Амуре, to Комсомольск-на-Амуре 358 | Красноармейск, в Красноармейске, из Красноармейска, to Красноармейск 359 | Краснодар, в Краснодаре, из Краснодара, to Краснодар 360 | Краснощеково, в Краснощеково, из Краснощеково, to Краснощеково 361 | Красный Боец, в Красном Боеце, из Красного Боеца, to Красный Боец 362 | Красный май, в Красном мае, из Красного мая, to Красный май 363 | Красный Яр, в Красном Яре, из Красного Яра, to Красный Яр 364 | николаевск-на-амуре, в николаевске-на-амуре, из николаевска-на-амуре, to николаевск-на-амуре 365 | новосиб, в новосибе, из новосиба, to новосиб 366 | Обухов, в Обухове, из Обухова, to Обухов 367 | Оскемен, в Оскемене, из Оскемена, to Оскемен 368 | Павел, в Павле, из Павла, to Павел 369 | Пески-Речицкие, в Песках-Речицких, из Песков-Речицких, to Пески-Речицкие 370 | питер, в питере, из питера, to питер 371 | Порча, в Порче, из Порчи, to Порчу 372 | пушкино, в пушкино, из пушкино, to пушкино 373 | Саша, в Саше, из Саши, to Сашу 374 | Симферополь, в Симферополе, из Симферополя, to Симферополь 375 | Тюрли, в Тюрли, из Тюрли, to Тюрли 376 | Усть-Камменогорск, в Усть-Камменогорске, из Усть-Камменогорска, to Усть-Камменогорск 377 | уфа, в уфе, из уфы, to уфу 378 | Удомля, в Удомле, из Удомли, to Удомлю 379 | тарасовка, в тарасовке, из тарасовки, to тарасовку 380 | Бельтны, в Бельтнах, из Бельтнов, to Бельтны 381 | Великие Кочаны, в Великих Кочанах, из Великих Кочанов, to Великие Кочаны 382 | Вышний Волочек, в Вышнем Волочке, из Вышнего Волочка, to Вышний Волочек 383 | Гавнарь, в Гавнари, из Гавнари, to Гавнарь 384 | шереметьево, в шереметьево, из шереметьево, to шереметьево 385 | Душанбе, в Душанбе, из Душанбе, to Душанбе 386 | Екат, в Екате, из Еката, to Екат 387 | Иванов, в Иванове, из Иванова, to Иванов 388 | Казахстане, в Казахстане, из Казахстане, to Казахстане 389 | Каменский, в Каменском, из Каменского, to Каменский 390 | Кемерово, в Кемерово, из Кемерово, to Кемерово 391 | Красный, в Красном, из Красного, to Красный 392 | Москва, в Москве, из Москвы, to Москву 393 | Коломинск, в Коломинске, из Коломинска, to Коломинск 394 | Ново-Ебенёва, в Ново-Ебенёве, из Ново-Ебенёвы, to Ново-Ебенёву 395 | Питер, в Питере, из Питера, to Питер 396 | Освенцим, в Освенциме, из Освенцима, to Освенцим 397 | Санкт-Петербург, в Санкт-Петербурге, из Санкт-Петербурга, to Санкт-Петербург 398 | Саратов, в Саратове, из Саратова, to Саратов 399 | тбилиси, в тбилиси, из тбилиси, to тбилиси 400 | Жордрехт, в Жордрехте, из Жордрехта, to Жордрехт 401 | Дордрехт, в Дордрехте, из Дордрехта, to Дордрехт 402 | Ситтард-Гелен, в Ситтард-Гелене, из Ситтард-Гелена, to Ситтард-Гелен 403 | Хельсинки, в Хельсинки, из Хельсинки, to Хельсинки 404 | Утрехт, в Утрехте, из Утрехта, to Утрехт 405 | Апелдорн, в Апелдорне, из Апелдорна, to Апелдорн 406 | Шушары, в Шушарах, из Шушар, to Шушары 407 | Камень-на-оби, в Камне-на-оби, из Камня-на-оби, to Камень-на-оби 408 | чебоксары, в чебоксарах, из чебоксар, to чебоксары 409 | Бельцы, в Бельцах, из Бельц, to Бельцы 410 | Киев, в Киеве, из Киева, to Киев 411 | Кёльн, в Кёльне, из Кёльна, to Кёльн 412 | минеральные воды, в минеральных водах, из минеральных вод, to минеральные воды 413 | Урочище зеленая роща, в Урочище зеленая роща, из Урочища зеленая роща, to Урочище зеленая роща 414 | верхние киги, в верхних кигах, из верхних киг, to верхние киги 415 | норильский никель, в норильском никеле, из норильского никеля, to норильский никель 416 | Гленц, в Гленце, из Гленца, to Гленц 417 | Гримм, в Гримме, из Гримма, to Гримм 418 | Гузерипль, в Гузерипле, из Гузерипля, to Гузерипль 419 | Углич, в Угличе, из Углича, to Углич 420 | Черновцы, в Черновцах, из Черновцов, to Черновцы 421 | `); 422 | }); 423 | 424 | it('correct declension for some place words', () => { 425 | expect3fnFromDemo( 426 | ` 427 | область, в области, из области, to область 428 | регион, в регионе, из региона, to регион 429 | станица, в станице, из станицы, to станицу 430 | станиция, в станиции, из станиции, to станицию 431 | аул, в ауле, из аула, to аул 432 | село, в селе, из села, to село 433 | поселок, в поселке, из поселка, to поселок 434 | город, в городе, из города, to город 435 | деревня, в деревне, из деревни, to деревню 436 | урочище, в урочище, из урочища, to урочище 437 | река, в реке, из реки, to реку 438 | озеро, в озере, из озера, to озеро 439 | море, в море, из моря, to море 440 | гора, в горе, из горы, to гору 441 | холм, в холме, из холма, to холм 442 | место, в месте, из места, to место 443 | дорога, в дороге, из дороги, to дорогу 444 | пирс, в пирсе, из пирса, to пирс 445 | порт, в порте, из порта, to порт 446 | лодка, в лодке, из лодки, to лодку 447 | ` 448 | ); 449 | }); 450 | }); 451 | }); 452 | -------------------------------------------------------------------------------- /src/__tests__/gender-test.ts: -------------------------------------------------------------------------------- 1 | import { 2 | getFirstnameGender, 3 | getMiddlenameGender, 4 | getLastnameGender, 5 | getGender, 6 | mergeGenders, 7 | MALE, 8 | FEMALE, 9 | ANDROGYNOUS, 10 | getGenderConst, 11 | convertGenderStr, 12 | getGenderByRule, 13 | getGenderByRuleSet, 14 | } from '../gender'; 15 | 16 | function expectList(fn: (s: string) => any, str: string) { 17 | const lines = str 18 | .split(/\n|\r/g) 19 | .map((s) => s.trim()) 20 | .map((s) => s.replace(/#.*|\/\/.*/, '')) 21 | .filter((s) => !!s); 22 | lines.forEach((line) => { 23 | const [arg, res] = line.split(/\s+/g); 24 | expect(`${arg} ${fn(arg) || 'null'}`).toEqual(`${arg} ${res}`); 25 | }); 26 | } 27 | 28 | describe('lvovich/gender', () => { 29 | describe('internal methods', () => { 30 | describe('mergeGenders()', () => { 31 | it('return ANDROGYNOUS', () => { 32 | expect(mergeGenders(ANDROGYNOUS, null)).toEqual(null); 33 | expect(mergeGenders(null, ANDROGYNOUS)).toEqual(null); 34 | expect(mergeGenders(ANDROGYNOUS, ANDROGYNOUS)).toEqual(ANDROGYNOUS); 35 | }); 36 | 37 | it('return MALE', () => { 38 | expect(mergeGenders(MALE, null)).toEqual(null); 39 | expect(mergeGenders(MALE, ANDROGYNOUS)).toEqual(MALE); 40 | expect(mergeGenders(null, MALE)).toEqual(null); 41 | expect(mergeGenders(ANDROGYNOUS, MALE)).toEqual(MALE); 42 | }); 43 | 44 | it('return FEMALE', () => { 45 | expect(mergeGenders(FEMALE, null)).toEqual(null); 46 | expect(mergeGenders(FEMALE, ANDROGYNOUS)).toEqual(FEMALE); 47 | expect(mergeGenders(null, FEMALE)).toEqual(null); 48 | expect(mergeGenders(ANDROGYNOUS, FEMALE)).toEqual(FEMALE); 49 | }); 50 | 51 | it('return null if gender not match', () => { 52 | expect(mergeGenders(null, null)).toEqual(null); 53 | expect(mergeGenders(FEMALE, MALE)).toEqual(null); 54 | expect(mergeGenders(MALE, FEMALE)).toEqual(null); 55 | }); 56 | }); 57 | 58 | describe('getGenderConst()', () => { 59 | it('return GENDER', () => { 60 | expect(getGenderConst('male')).toEqual(MALE); 61 | expect(getGenderConst('female')).toEqual(FEMALE); 62 | expect(getGenderConst('androgynous')).toEqual(ANDROGYNOUS); 63 | expect(getGenderConst(MALE)).toEqual(MALE); 64 | expect(getGenderConst(FEMALE)).toEqual(FEMALE); 65 | expect(getGenderConst(ANDROGYNOUS)).toEqual(ANDROGYNOUS); 66 | }); 67 | 68 | it('return null', () => { 69 | expect(getGenderConst(null)).toEqual(null); 70 | expect(getGenderConst('strange' as any)).toEqual(null); 71 | }); 72 | }); 73 | 74 | describe('convertGenderStr()', () => { 75 | it('return GENDER', () => { 76 | expect(convertGenderStr(MALE)).toEqual('male'); 77 | expect(convertGenderStr(FEMALE)).toEqual('female'); 78 | expect(convertGenderStr(ANDROGYNOUS)).toEqual('androgynous'); 79 | expect(convertGenderStr('male')).toEqual('male'); 80 | expect(convertGenderStr('female')).toEqual('female'); 81 | expect(convertGenderStr('androgynous')).toEqual('androgynous'); 82 | }); 83 | 84 | it('return null', () => { 85 | expect(convertGenderStr(null)).toEqual(null); 86 | expect(convertGenderStr('strange')).toEqual(null); 87 | }); 88 | }); 89 | 90 | describe('getGenderByRule()', () => { 91 | it('should return GENDER', () => { 92 | const rules = { 93 | female: ['ова'], 94 | male: ['ов'], 95 | androgynous: ['о'], 96 | }; 97 | 98 | expect(getGenderByRule(rules, (some) => 'Петров'.endsWith(some))).toEqual(MALE); 99 | 100 | expect(getGenderByRule(rules, (some) => 'Иванова'.endsWith(some))).toEqual(FEMALE); 101 | 102 | expect(getGenderByRule(rules, (some) => 'Зубко'.endsWith(some))).toEqual(ANDROGYNOUS); 103 | }); 104 | 105 | it('should return null if no match with rules', () => { 106 | const rules = { 107 | male: ['ов'], 108 | }; 109 | expect(getGenderByRule(rules, (some) => 'Рыбак'.endsWith(some))).toEqual(null); 110 | }); 111 | 112 | it('should return null if match several genders', () => { 113 | const rulesOverlapped = { 114 | female: ['a'], 115 | male: ['a'], 116 | }; 117 | 118 | expect(getGenderByRule(rulesOverlapped, (some) => 'Рыбка'.endsWith(some))).toEqual(null); 119 | }); 120 | }); 121 | 122 | describe('getGenderByRuleSet()', () => { 123 | const ruleSet = { 124 | exceptions: { 125 | androgynous: ['дарвин', 'грин'], 126 | male: ['-ага'], 127 | }, 128 | suffixes: { 129 | male: ['н'], 130 | female: ['на', 'га'], 131 | }, 132 | }; 133 | 134 | it('should return null if name is empty', () => { 135 | expect(getGenderByRuleSet('', ruleSet)).toEqual(null); 136 | }); 137 | 138 | it('should check exceptions firstly', () => { 139 | expect(getGenderByRuleSet('Дарвин', ruleSet)).toEqual(ANDROGYNOUS); 140 | }); 141 | 142 | it('should check exceptions with suffix', () => { 143 | expect(getGenderByRuleSet('ольга', ruleSet)).toEqual(FEMALE); 144 | expect(getGenderByRuleSet('адилага', ruleSet)).toEqual(MALE); 145 | }); 146 | 147 | it('should check suffixes', () => { 148 | expect(getGenderByRuleSet('Пилевин', ruleSet)).toEqual(MALE); 149 | expect(getGenderByRuleSet('Пилевина', ruleSet)).toEqual(FEMALE); 150 | }); 151 | }); 152 | }); 153 | 154 | describe('getFirstnameGender()', () => { 155 | it('should determine by gender firstname rules', () => { 156 | expectList( 157 | getFirstnameGender, 158 | ` 159 | // MALES 160 | Павел male 161 | Петр male 162 | 163 | // FEMALES 164 | Анна female 165 | Катя female 166 | 167 | // ANDROGYNOUS 168 | Саша androgynous 169 | Женя androgynous 170 | Бахыт androgynous 171 | Муса androgynous 172 | 173 | // UNDETERMINED BY RULES 174 | тттт null 175 | аааа null 176 | yes null 177 | ` 178 | ); 179 | }); 180 | }); 181 | 182 | describe('getMiddlenameGender()', () => { 183 | it('should determine gender by middlename rules', () => { 184 | expectList( 185 | getMiddlenameGender, 186 | ` 187 | // MALES 188 | Павлович male 189 | Бауржанулы male 190 | 191 | // FEMALES 192 | Ивановна female 193 | Маманкызы female 194 | 195 | // UNDETERMINED BY RULES 196 | иваново null 197 | тттт null 198 | аааа null 199 | yes null 200 | ` 201 | ); 202 | }); 203 | }); 204 | 205 | describe('getLastnameGender()', () => { 206 | it('should determine gender by lastname rules', () => { 207 | expectList( 208 | getLastnameGender, 209 | ` 210 | // MALES 211 | Иванов male 212 | Градский male 213 | Ананьев male 214 | 215 | // FEMALES 216 | Иванова female 217 | Кабазёва female 218 | Кабазева female 219 | Таптыгина female 220 | 221 | // ANDROGYNOUS 222 | Грин androgynous 223 | Борейко androgynous 224 | 225 | // UNDETERMINED BY RULES 226 | ким null 227 | тттт null 228 | аааа null 229 | yes null 230 | ` 231 | ); 232 | }); 233 | }); 234 | 235 | describe('getGender()', () => { 236 | it('should determine androgynous', () => { 237 | expect( 238 | getGender({ 239 | first: 'Саша', 240 | }) 241 | ).toEqual('androgynous'); 242 | }); 243 | 244 | it('should determine gender by lastname', () => { 245 | expect( 246 | getGender({ 247 | last: 'Иванов', 248 | first: 'Саша', 249 | }) 250 | ).toEqual('male'); 251 | }); 252 | 253 | it('should determine gender by middlename', () => { 254 | expect( 255 | getGender({ 256 | first: 'Саша', 257 | middle: 'Петрович', 258 | }) 259 | ).toEqual('male'); 260 | }); 261 | 262 | it('should return null for wrong male/female data', () => { 263 | expect( 264 | getGender({ 265 | last: 'Абуова', 266 | first: 'Андрей', 267 | }) 268 | ).toEqual(null); 269 | }); 270 | 271 | it('should skip null for lastname', () => { 272 | expect( 273 | getGender({ 274 | last: 'Шкарупа', 275 | first: 'Евгений', 276 | middle: 'Ваганович', 277 | }) 278 | ).toEqual('male'); 279 | 280 | expect( 281 | getGender({ 282 | last: 'Шкарупа', 283 | first: 'Ольга', 284 | middle: 'Александровна', 285 | }) 286 | ).toEqual('female'); 287 | }); 288 | }); 289 | }); 290 | -------------------------------------------------------------------------------- /src/__tests__/incline-test.ts: -------------------------------------------------------------------------------- 1 | import { incline, inclineFirstname, inclineLastname, inclineMiddlename } from '../incline'; 2 | 3 | describe('lvovich/incline', () => { 4 | describe('lvovich()', () => { 5 | it('should autodetect gender and incline person', () => { 6 | expect(incline({ first: 'Павел' }, 'dative')).toEqual({ 7 | first: 'Павлу', 8 | gender: 'male', 9 | }); 10 | }); 11 | 12 | it('should autodetect gender and incline person', () => { 13 | expect(incline({ first: 'Паша' }, 'instrumental')).toEqual({ 14 | first: 'Пашей', 15 | gender: 'male', 16 | }); 17 | }); 18 | 19 | it('should incline person with androgynous name', () => { 20 | expect(incline({ first: 'Саша' }, 'dative')).toEqual({ 21 | first: 'Саше', 22 | gender: 'androgynous', 23 | }); 24 | expect(incline({ first: 'Саша', last: 'Иванов' }, 'dative')).toEqual({ 25 | first: 'Саше', 26 | last: 'Иванову', 27 | gender: 'male', 28 | }); 29 | }); 30 | }); 31 | 32 | describe('inclineFirstname()', () => { 33 | it('should incline firstname', () => { 34 | expect(inclineFirstname('Павел', 'genitive')).toEqual('Павла'); 35 | expect(inclineFirstname('Санёк', 'genitive')).toEqual('Санька'); 36 | }); 37 | 38 | it('should accept gender for androgynous name', () => { 39 | expect(inclineFirstname('Женя', 'instrumental')).toEqual('Женя'); 40 | expect(inclineFirstname('Женя', 'instrumental', 'male')).toEqual('Женей'); 41 | expect(inclineFirstname('Женя', 'instrumental', 'female')).toEqual('Женей'); 42 | }); 43 | }); 44 | 45 | describe('inclineMiddlename()', () => { 46 | it('should incline middlename', () => { 47 | expect(inclineMiddlename('Львович', 'genitive')).toEqual('Львовича'); 48 | }); 49 | }); 50 | 51 | describe('inclineLastname()', () => { 52 | it('should incline middlename', () => { 53 | expect(inclineLastname('Иванова', 'genitive')).toEqual('Ивановой'); 54 | }); 55 | 56 | it('should accept gender for androgynous name', () => { 57 | expect(inclineLastname('Петросян', 'instrumental')).toEqual('Петросян'); 58 | expect(inclineLastname('Петросян', 'instrumental', 'male')).toEqual('Петросяном'); 59 | }); 60 | }); 61 | }); 62 | -------------------------------------------------------------------------------- /src/__tests__/inclineRules-test.ts: -------------------------------------------------------------------------------- 1 | import { 2 | NOMINATIVE, 3 | GENITIVE, 4 | DATIVE, 5 | ACCUSATIVE, 6 | INSTRUMENTAL, 7 | PREPOSITIONAL, 8 | getDeclensionConst, 9 | getDeclensionStr, 10 | applyRule, 11 | findExactRule, 12 | findRule, 13 | inclineByRules, 14 | applyMod, 15 | DeclensionRuleSetT, 16 | DeclensionRuleT, 17 | } from '../inclineRules'; 18 | 19 | import { MALE, FEMALE, ANDROGYNOUS } from '../gender'; 20 | 21 | describe('lvovich/rules', () => { 22 | describe('getDeclensionConst()', () => { 23 | it('return DECLENSION as const', () => { 24 | expect(getDeclensionConst('nominative')).toEqual(NOMINATIVE); 25 | expect(getDeclensionConst(NOMINATIVE)).toEqual(NOMINATIVE); 26 | 27 | expect(getDeclensionConst('genitive')).toEqual(GENITIVE); 28 | expect(getDeclensionConst(GENITIVE)).toEqual(GENITIVE); 29 | 30 | expect(getDeclensionConst('dative')).toEqual(DATIVE); 31 | expect(getDeclensionConst(DATIVE)).toEqual(DATIVE); 32 | 33 | expect(getDeclensionConst('accusative')).toEqual(ACCUSATIVE); 34 | expect(getDeclensionConst(ACCUSATIVE)).toEqual(ACCUSATIVE); 35 | 36 | expect(getDeclensionConst('instrumental')).toEqual(INSTRUMENTAL); 37 | expect(getDeclensionConst(INSTRUMENTAL)).toEqual(INSTRUMENTAL); 38 | 39 | expect(getDeclensionConst('prepositional')).toEqual(PREPOSITIONAL); 40 | expect(getDeclensionConst(PREPOSITIONAL)).toEqual(PREPOSITIONAL); 41 | }); 42 | 43 | it('return null', () => { 44 | expect(getDeclensionConst(null)).toEqual(null); 45 | expect(getDeclensionConst('strange')).toEqual(null); 46 | }); 47 | }); 48 | 49 | describe('getDeclensionStr()', () => { 50 | it('return DECLENSION as string', () => { 51 | expect(getDeclensionStr('nominative')).toEqual('nominative'); 52 | expect(getDeclensionStr(NOMINATIVE)).toEqual('nominative'); 53 | 54 | expect(getDeclensionStr('genitive')).toEqual('genitive'); 55 | expect(getDeclensionStr(GENITIVE)).toEqual('genitive'); 56 | 57 | expect(getDeclensionStr('dative')).toEqual('dative'); 58 | expect(getDeclensionStr(DATIVE)).toEqual('dative'); 59 | 60 | expect(getDeclensionStr('accusative')).toEqual('accusative'); 61 | expect(getDeclensionStr(ACCUSATIVE)).toEqual('accusative'); 62 | 63 | expect(getDeclensionStr('instrumental')).toEqual('instrumental'); 64 | expect(getDeclensionStr(INSTRUMENTAL)).toEqual('instrumental'); 65 | 66 | expect(getDeclensionStr('prepositional')).toEqual('prepositional'); 67 | expect(getDeclensionStr(PREPOSITIONAL)).toEqual('prepositional'); 68 | }); 69 | 70 | it('return null', () => { 71 | expect(getDeclensionStr(null)).toEqual(null); 72 | expect(getDeclensionStr('strange')).toEqual(null); 73 | }); 74 | }); 75 | 76 | describe('applyMod()', () => { 77 | it('should skip . in mod', () => { 78 | expect(applyMod('test', '.')).toEqual('test'); 79 | }); 80 | 81 | it('should remove char on -', () => { 82 | expect(applyMod('test', '-')).toEqual('tes'); 83 | expect(applyMod('test', '--')).toEqual('te'); 84 | expect(applyMod('test', '---ABC')).toEqual('tABC'); 85 | }); 86 | 87 | it('should add char otherwise', () => { 88 | expect(applyMod('test', 'ABC')).toEqual('testABC'); 89 | }); 90 | }); 91 | 92 | describe('applyRule()', () => { 93 | it('should choose correct declension mod', () => { 94 | const rule = { mods: ['-ы', '-е', '-у', '-ой', '-Е'] } as any; 95 | expect(applyRule(rule, 'мама', NOMINATIVE)).toEqual('мама'); 96 | expect(applyRule(rule, 'мама', GENITIVE)).toEqual('мамы'); 97 | expect(applyRule(rule, 'мама', DATIVE)).toEqual('маме'); 98 | expect(applyRule(rule, 'мама', ACCUSATIVE)).toEqual('маму'); 99 | expect(applyRule(rule, 'мама', INSTRUMENTAL)).toEqual('мамой'); 100 | expect(applyRule(rule, 'мама', PREPOSITIONAL)).toEqual('мамЕ'); 101 | }); 102 | }); 103 | 104 | describe('findExactRule()', () => { 105 | it('should return null if rule not found', () => { 106 | const rules = [{ gender: FEMALE, mods: [], test: ['а'] }] as DeclensionRuleT[]; 107 | expect(findExactRule(rules, MALE, () => true, [])).toEqual(null); 108 | }); 109 | 110 | it('should filter by matchFn', () => { 111 | const rules = [ 112 | { gender: MALE, test: ['а', 'б'], mods: [] }, 113 | { gender: MALE, test: ['в'], mods: [] }, 114 | ] as DeclensionRuleT[]; 115 | expect(findExactRule(rules, MALE, (s) => 'ввв'.endsWith(s))).toEqual(rules[1]); 116 | expect(findExactRule(rules, MALE, (s) => 'ббб'.endsWith(s))).toEqual(rules[0]); 117 | expect(findExactRule(rules, MALE, (s) => 'ффф'.endsWith(s))).toEqual(null); 118 | }); 119 | 120 | it('should filter by same gender', () => { 121 | const rules = [ 122 | { gender: MALE, test: ['а'], tags: ['firstWord'], mods: [] }, 123 | { gender: MALE, test: ['а'], mods: [] }, 124 | { gender: FEMALE, test: ['а'], mods: [] }, 125 | ] as DeclensionRuleT[]; 126 | expect(findExactRule(rules, MALE, () => true)).toEqual(rules[1]); 127 | expect(findExactRule(rules, FEMALE, () => true)).toEqual(rules[2]); 128 | }); 129 | 130 | it('should filter by tags', () => { 131 | const rules = [ 132 | { gender: FEMALE, mods: [], test: ['а'] }, 133 | { gender: MALE, test: ['а'], tags: ['firstWord'], mods: [] }, 134 | { gender: MALE, test: ['а'], mods: [] }, 135 | ] as DeclensionRuleT[]; 136 | expect(findExactRule(rules, MALE, () => true, ['firstWord'])).toEqual(rules[1]); 137 | expect(findExactRule(rules, MALE, () => true, ['someTag'])).toEqual(rules[2]); 138 | }); 139 | 140 | it('should accept ANDROGYNOUS for male and female', () => { 141 | const rules = [{ gender: ANDROGYNOUS, test: ['а'], mods: [] }] as any; 142 | expect(findExactRule(rules, ANDROGYNOUS, () => true)).toEqual(rules[0]); 143 | expect(findExactRule(rules, MALE, () => true)).toEqual(rules[0]); 144 | expect(findExactRule(rules, FEMALE, () => true)).toEqual(rules[0]); 145 | }); 146 | }); 147 | 148 | describe('findRule()', () => { 149 | const ruleSet = { 150 | exceptions: [ 151 | { 152 | gender: MALE, 153 | test: ['лев'], 154 | mods: ['--ьва', '--ьву', '--ьва', '--ьвом', '--ьве'], 155 | }, 156 | ], 157 | suffixes: [ 158 | { 159 | gender: MALE, 160 | test: ['б', 'в'], 161 | mods: ['а', 'у', 'а', 'ом', 'е'], 162 | }, 163 | ], 164 | } as DeclensionRuleSetT; 165 | 166 | it('should return null if empty string', () => { 167 | expect(findRule('', MALE, ruleSet)).toEqual(null); 168 | }); 169 | 170 | it('should firstly look exceptions by matching whole string', () => { 171 | expect(findRule('лев', MALE, ruleSet)).toEqual(ruleSet.exceptions?.[0]); 172 | }); 173 | 174 | it('should look suffixes by matching end of string', () => { 175 | expect(findRule('ярослав', MALE, ruleSet)).toEqual(ruleSet.suffixes?.[0]); 176 | }); 177 | 178 | it('should lowercase string', () => { 179 | expect(findRule('ЛЕВ', MALE, ruleSet)).toEqual(ruleSet.exceptions?.[0]); 180 | expect(findRule('ЯРОСЛАВ', MALE, ruleSet)).toEqual(ruleSet.suffixes?.[0]); 181 | }); 182 | }); 183 | 184 | describe('inclineByRules()', () => { 185 | const ruleSet = { 186 | exceptions: [ 187 | { 188 | gender: MALE, 189 | test: ['лев'], 190 | mods: ['--ьва', '--ьву', '--ьва', '--ьвом', '--ьве'], 191 | }, 192 | ], 193 | suffixes: [ 194 | { 195 | gender: MALE, 196 | test: ['б', 'в'], 197 | mods: ['а', 'у', 'а', 'ом', 'е'], 198 | }, 199 | ], 200 | } as DeclensionRuleSetT; 201 | 202 | it('should incline word by rules', () => { 203 | expect(inclineByRules('лев', GENITIVE, MALE, ruleSet)).toEqual('льва'); 204 | expect(inclineByRules('лев', DATIVE, MALE, ruleSet)).toEqual('льву'); 205 | expect(inclineByRules('лев', ACCUSATIVE, MALE, ruleSet)).toEqual('льва'); 206 | expect(inclineByRules('вячеслав', INSTRUMENTAL, MALE, ruleSet)).toEqual('вячеславом'); 207 | expect(inclineByRules('вячеслав', PREPOSITIONAL, MALE, ruleSet)).toEqual('вячеславе'); 208 | }); 209 | 210 | it('should incline both words written via dash', () => { 211 | expect(inclineByRules('лев-лев', DATIVE, MALE, ruleSet)).toEqual('льву-льву'); 212 | }); 213 | }); 214 | }); 215 | -------------------------------------------------------------------------------- /src/__tests__/maps.vlasenko.net/by-list.csv: -------------------------------------------------------------------------------- 1 | Брестская;Барановичский;Барановичи;26;53.116 2 | Брестская;Барановичский;Городище;26;53.316 3 | Брестская;Барановичский;Задвея;26.283;53.316 4 | Брестская;Барановичский;Лесная;25.766;52.983 5 | Брестская;Барановичский;Люшнево;25.716;53.233 6 | Брестская;Барановичский;Малая Своротва;25.7;53.366 7 | Брестская;Барановичский;Миловиды;25.85;52.9 8 | Брестская;Барановичский;Молчадь;25.7;53.316 9 | Брестская;Барановичский;Новая Мышь;25.9;53.133 10 | Брестская;Барановичский;Подгорная;25.583;52.983 11 | Брестская;Барановичский;Полонка;25.7;53.15 12 | Брестская;Барановичский;Постаринье;25.916;53.216 13 | Брестская;Барановичский;Стайки;26.166;53.25 14 | Брестская;Барановичский;Тешевля;25.816;53.233 15 | Брестская;Барановичский;Утес;25.916;52.966 16 | Брестская;Березовский;Белоозерск;25.183;52.466 17 | Брестская;Березовский;Березино;24.683;52.3 18 | Брестская;Березовский;Бобровичи;25.766;52.616 19 | Брестская;Березовский;Борки;24.15;52.783 20 | Брестская;Березовский;Бронная Гора;25.1;52.616 21 | Брестская;Березовский;Верхи;24.5;52.316 22 | Брестская;Березовский;Высокое;23.366;52.366 23 | Брестская;Березовский;Давид-Городок;27.233;52.5 24 | Брестская;Березовский;Деревня;24.9;52.3 25 | Брестская;Березовский;Доброе;24.683;52.66 26 | Брестская;Березовский;Дуги;27.5;52.55 27 | Брестская;Березовский;Здитово;25.266;52.433 28 | Брестская;Березовский;Колония;24.583;52.333 29 | Брестская;Березовский;Литва;26.15;53.1 30 | Брестская;Березовский;Лососин;24.883;52.783 31 | Брестская;Березовский;Люша;26.716;52.45 32 | Брестская;Березовский;Медно;23.75;51.866 33 | Брестская;Березовский;Невель;25.833;51.933 34 | Брестская;Березовский;Осса;24.466;51.916 35 | Брестская;Березовский;Паре;26.15;51.9 36 | Брестская;Березовский;Первомайская;24.9;52.533 37 | Брестская;Березовский;Пугачево;23.75;52.66 38 | Брестская;Березовский;Рачки;23.916;52.166 39 | Брестская;Березовский;Селец;24.866;52.583 40 | Брестская;Березовский;Сосновка;24.333;52.416 41 | Брестская;Березовский;Спорово;25.316;52.433 42 | Брестская;Березовский;Старые Пески;25.2;52.516 43 | Брестская;Березовский;Стригин;25.33;52.516 44 | Брестская;Березовский;Судиловичи;25.5;52.35 45 | Брестская;Березовский;Хороша;25.25;52.816 46 | Брестская;Брестский;Брест;23.683;52.116 47 | Брестская;Брестский;Днепровско;24.883;52.1 48 | Брестская;Брестский;Домачево;23.616;51.733 49 | Брестская;Брестский;Леплевка;23.65;51.766 50 | Брестская;Брестский;Мотыкалы;23.583;52.2 51 | Брестская;Брестский;Оберовщина;23.383;52.416 52 | Брестская;Брестский;Приборово;23.566;51.633 53 | Брестская;Брестский;Радваничи-Большие;24.16;52.16 54 | Брестская;Брестский;Старое Село;24.1;52.83 55 | Брестская;Брестский;Страдичи;23.666;51.933 56 | Брестская;Брестский;Стрии;24.4;52.316 57 | Брестская;Брестский;Томашевка;23.6;51.55 58 | Брестская;Брестский;Чернавчицы;23.733;52.233 59 | Брестская;Ганцевичский;Будча;26.833;52.766 60 | Брестская;Ганцевичский;Ганцевичи;26.433;52.75 61 | Брестская;Ганцевичский;Денисковичи;26.683;52.716 62 | Брестская;Ганцевичский;Задубье;26.45;52.533 63 | Брестская;Ганцевичский;Локтыши;26.716;52.833 64 | Брестская;Ганцевичский;Люсино;26.516;52.633 65 | Брестская;Ганцевичский;Мальковичи;26.583;52.533 66 | Брестская;Ганцевичский;Огаревичи;26.516;52.766 67 | Брестская;Ганцевичский;Раздяловичи;26.15;52.633 68 | Брестская;Ганцевичский;Хотыничи;26.3;52.633 69 | Брестская;Ганцевичский;Чудин;26.966;52.733 70 | Брестская;Дрогичинский;Антополь;24.45;52.2 71 | Брестская;Дрогичинский;Бездеж;25.3;52.316 72 | Брестская;Дрогичинский;Головчицы;24.866;52.15 73 | Брестская;Дрогичинский;Гутово;25.333;52.183 74 | Брестская;Дрогичинский;Детковичи;24.816;52.316 75 | Брестская;Дрогичинский;Дрогичин;25.15;52.183 76 | Брестская;Дрогичинский;Заречка;25.116;52.5 77 | Брестская;Дрогичинский;Малиновка;25.233;52.16 78 | Брестская;Дрогичинский;Радостов;24.95;51.966 79 | Брестская;Дрогичинский;Суличево;25.33;52.1 80 | Брестская;Дрогичинский;Хомск;25.233;52.333 81 | Брестская;Жабинковский;Жабинка;24.16;52.2 82 | Брестская;Жабинковский;Хмелево;23.916;52.25 83 | Брестская;Ивановский;Бусни;24.133;52.15 84 | Брестская;Ивановский;Великая Гать;25.65;52.55 85 | Брестская;Ивановский;Достоево;25.683;52.233 86 | Брестская;Ивановский;Дружиловичи;25.55;52.233 87 | Брестская;Ивановский;Иваново;25.55;52.133 88 | Брестская;Ивановский;Карчово;26.1;53.366 89 | Брестская;Ивановский;Колено;25.55;51.933 90 | Брестская;Ивановский;Крытышин;25.483;52.83 91 | Брестская;Ивановский;Молодово;25.7;52.283 92 | Брестская;Ивановский;Мотоль;25.583;52.316 93 | Брестская;Ивановский;Мохро;25.55;51.966 94 | Брестская;Ивановский;Одрижин;25.45;51.966 95 | Брестская;Ивановский;Ополь;25.45;52.316 96 | Брестская;Ивановский;Потаповичи;25.666;52.66 97 | Брестская;Ивановский;Снитово;25.433;52.133 98 | Брестская;Ивановский;Тышковичи;25.616;52.35 99 | Брестская;Ивацевичский;Бытень;25.5;52.883 100 | Брестская;Ивацевичский;Волька;25.633;52.783 101 | Брестская;Ивацевичский;Гортоль;25.9;52.5 102 | Брестская;Ивацевичский;Гощево;25.2;52.683 103 | Брестская;Ивацевичский;Добромысль;25.716;52.833 104 | Брестская;Ивацевичский;Доманово;25.483;52.833 105 | Брестская;Ивацевичский;Житлин;25.366;52.566 106 | Брестская;Ивацевичский;Ивацевичи;25.35;52.716 107 | Брестская;Ивацевичский;Квасевичи;25.66;52.75 108 | Брестская;Ивацевичский;Колонск;25.783;52.466 109 | Брестская;Ивацевичский;Коссово;25.133;52.75 110 | Брестская;Ивацевичский;Краи;26;52.5 111 | Брестская;Ивацевичский;Любищицы;25.416;52.766 112 | Брестская;Ивацевичский;Мироним;25.45;52.95 113 | Брестская;Ивацевичский;Нехачево;25.2;52.65 114 | Брестская;Ивацевичский;Оброво;25.55;52.516 115 | Брестская;Ивацевичский;Углы;25.583;52.933 116 | Брестская;Каменецкий;Верховичи;23.5;52.466 117 | Брестская;Каменецкий;Видомля;23.783;52.333 118 | Брестская;Каменецкий;Войская;23.616;52.416 119 | Брестская;Каменецкий;Волчин;23.316;52.283 120 | Брестская;Каменецкий;Дмитровичи;23.783;52.5 121 | Брестская;Каменецкий;Каменец;23.816;52.4 122 | Брестская;Каменецкий;Каменюки;23.8;52.55 123 | Брестская;Каменецкий;Омеленец;23.55;52.533 124 | Брестская;Каменецкий;Пелище;23.916;52.333 125 | Брестская;Каменецкий;Ратайчицы;23.616;52.35 126 | Брестская;Кобринский;Батчи;24.233;52.25 127 | Брестская;Кобринский;Береза;24.983;52.533 128 | Брестская;Кобринский;Болота;24.533;52.133 129 | Брестская;Кобринский;Верхолесье;24.3;52.83 130 | Брестская;Кобринский;Вуйвичи;26.5;52.66 131 | Брестская;Кобринский;Городец;24.666;52.2 132 | Брестская;Кобринский;Грушево;24.733;52.233 133 | Брестская;Кобринский;Девятки;24.183;52.35 134 | Брестская;Кобринский;Дивин;24.6;51.95 135 | Брестская;Кобринский;Именин;24.916;52.25 136 | Брестская;Кобринский;Камень;26.366;52.333 137 | Брестская;Кобринский;Кобрин;24.35;52.216 138 | Брестская;Кобринский;Леликов;24.7;51.916 139 | Брестская;Кобринский;Новоселки;24.35;52.33 140 | Брестская;Кобринский;Октябрь;24.6;52.233 141 | Брестская;Кобринский;Пески;24.266;52.2 142 | Брестская;Кобринский;Повитье;24.783;51.983 143 | Брестская;Кобринский;Тевли;24.25;52.333 144 | Брестская;Кобринский;Хидры;24.66;52.533 145 | Брестская;Лунинецкий;Богдановка;26.45;52.366 146 | Брестская;Лунинецкий;Большие Чучевичи;26.85;52.583 147 | Брестская;Лунинецкий;Бостынь;26.766;52.4 148 | Брестская;Лунинецкий;Бродница;25.683;52.133 149 | Брестская;Лунинецкий;Велута;26.783;52.466 150 | Брестская;Лунинецкий;Воля;24.33;52.416 151 | Брестская;Лунинецкий;Вулька;26.233;52.2 152 | Брестская;Лунинецкий;Дворец;26.966;52.283 153 | Брестская;Лунинецкий;Дятловичи;26.833;52.35 154 | Брестская;Лунинецкий;Лахва;27.83;52.216 155 | Брестская;Лунинецкий;Лунин;26.633;52.3 156 | Брестская;Лунинецкий;Лунинец;26.8;52.25 157 | Брестская;Лунинецкий;Межлесье;27.66;52.383 158 | Брестская;Лунинецкий;Микашевичи;27.466;52.216 159 | Брестская;Лунинецкий;Озерница;27.16;52.3 160 | Брестская;Лунинецкий;Ракитно;26.933;52.216 161 | Брестская;Лунинецкий;Синкевичи;27.25;52.216 162 | Брестская;Ляховичский;Жеребковичи;26.45;53.66 163 | Брестская;Ляховичский;Кожан-Городок;27;52.2 164 | Брестская;Ляховичский;Кривошин;26.133;52.883 165 | Брестская;Ляховичский;Куршиновичи;26.316;52.883 166 | Брестская;Ляховичский;Липск;26.83;52.833 167 | Брестская;Ляховичский;Ляховичи;26.266;53.33 168 | Брестская;Ляховичский;Медведичи;26.3;52.933 169 | Брестская;Ляховичский;Остров;25.966;52.883 170 | Брестская;Ляховичский;Подлесье;26.35;53.83 171 | Брестская;Ляховичский;Святица;26.33;52.75 172 | Брестская;Ляховичский;Совейки;26.416;52.916 173 | Брестская;Ляховичский;Трухановичи;24.516;52.716 174 | Брестская;Ляховичский;Туховичи;25.966;52.816 175 | Брестская;Малоритский;Бродятин;23.85;51.85 176 | Брестская;Малоритский;Великорита;24.5;51.933 177 | Брестская;Малоритский;Доропеевичи;24.316;51.95 178 | Брестская;Малоритский;Збураж;23.966;51.766 179 | Брестская;Малоритский;Луково;24.233;51.883 180 | Брестская;Малоритский;Лыща;26.15;52.366 181 | Брестская;Малоритский;Ляховцы;24.2;51.8 182 | Брестская;Малоритский;Малечь;24.716;52.483 183 | Брестская;Малоритский;Малорита;24.83;51.783 184 | Брестская;Малоритский;Масевичи;23.966;51.95 185 | Брестская;Малоритский;Меленково;24.7;52.1 186 | Брестская;Малоритский;Мокраны;24.266;51.833 187 | Брестская;Малоритский;Олтуш;23.966;51.666 188 | Брестская;Малоритский;Орехово;23.95;51.633 189 | Брестская;Малоритский;Радеж;23.816;51.7 190 | Брестская;Малоритский;Хотислав;24.1;51.716 191 | Брестская;Малоритский;Черняны;24.216;51.983 192 | Брестская;Пинский;Березовичи;25.866;52.166 193 | Брестская;Пинский;Березцы;26.6;52.133 194 | Брестская;Пинский;Доброславка;26.25;52.4 195 | Брестская;Пинский;Дубновичи;26.416;52.283 196 | Брестская;Пинский;Дубой;26.866;52.33 197 | Брестская;Пинский;Еловая;26.366;52.55 198 | Брестская;Пинский;Завидчицы;26.5;52.66 199 | Брестская;Пинский;Кончицы;25.8;52.66 200 | Брестская;Пинский;Кочановичи;26.433;52.1 201 | Брестская;Пинский;Купятичи;26.183;52.183 202 | Брестская;Пинский;Ласицк;26.3;51.916 203 | Брестская;Пинский;Лемешевичи;26.316;52.1 204 | Брестская;Пинский;Логишин;25.983;52.333 205 | Брестская;Пинский;Лосичи;26.233;52.33 206 | Брестская;Пинский;Малая Плотница;26.4;52.466 207 | Брестская;Пинский;Мерчицы;25.933;52.266 208 | Брестская;Пинский;Молотковичи;25.916;52.116 209 | Брестская;Пинский;Новый Двор;26.233;52.3 210 | Брестская;Пинский;Озаричи;25.85;52.416 211 | Брестская;Пинский;Охово;25.916;52.183 212 | Брестская;Пинский;Парохонск;26.45;52.233 213 | Брестская;Пинский;Пинск;26.116;52.116 214 | Брестская;Пинский;Плещицы;26.2;52.66 215 | Брестская;Пинский;Плоскинь;26.266;52.45 216 | Брестская;Пинский;Плотница;26.65;52.5 217 | Брестская;Пинский;Поречье;25.816;52.283 218 | Брестская;Пинский;Чухово;26.25;52.333 219 | Брестская;Пинский;Шилин;25.33;52.45 220 | Брестская;Пружанский;Бакуны;24.233;52.65 221 | Брестская;Пружанский;Близная;24.95;52.95 222 | Брестская;Пружанский;Броды;24.15;52.483 223 | Брестская;Пружанский;Великое Село;24.333;52.633 224 | Брестская;Пружанский;Вулька 1-я;26.7;52.283 225 | Брестская;Пружанский;Добучин;24.516;52.616 226 | Брестская;Пружанский;Колозубы;24.983;52.833 227 | Брестская;Пружанский;Линово;24.516;52.483 228 | Брестская;Пружанский;Лысково;24.616;52.866 229 | Брестская;Пружанский;Могилевцы;24.683;52.866 230 | Брестская;Пружанский;Пружаны;24.466;52.55 231 | Брестская;Пружанский;Ровбицк;24.83;52.666 232 | Брестская;Пружанский;Ружаны;24.883;52.866 233 | Брестская;Пружанский;Скорцы;24.683;52.616 234 | Брестская;Пружанский;Смоляница;24.633;52.7 235 | Брестская;Пружанский;Хорево;24.583;52.633 236 | Брестская;Пружанский;Шени;24.4;52.533 237 | Брестская;Пружанский;Шерешево;24.2;52.55 238 | Брестская;Пружанский;Юндилы;25.33;52.883 239 | Брестская;Столинский;Белоуша;26.916;51.933 240 | Брестская;Столинский;Бережное;27;51.983 241 | Брестская;Столинский;Бухличи;26.766;51.8 242 | Брестская;Столинский;Велемичи;27.233;52.16 243 | Брестская;Столинский;Воловель;24.95;52.133 244 | Брестская;Столинский;Вулька Малая;26;51.983 245 | Брестская;Столинский;Глинка;26.666;51.916 246 | Брестская;Столинский;Городная;26.5;51.866 247 | Брестская;Столинский;Колодно;26.5;51.95 248 | Брестская;Столинский;Куляны;24.816;52.933 249 | Брестская;Столинский;Лядец;27.1;52.66 250 | Брестская;Столинский;Нырча;27.45;52.166 251 | Брестская;Столинский;Оздамичи;27.483;52.16 252 | Брестская;Столинский;Ольманы;27.66;51.8 253 | Брестская;Столинский;Осовцы;25.25;52.83 254 | Брестская;Столинский;Посеничи;26.83;52.183 255 | Брестская;Столинский;Речица;25.133;52.566 256 | Брестская;Столинский;Рубель;27.5;51.966 257 | Брестская;Столинский;Рухча-Первая;26.6;51.983 258 | Брестская;Столинский;Сварынь;25.33;51.966 259 | Брестская;Столинский;Семигостичи;27.416;52.1 260 | Брестская;Столинский;Серебрище;25.65;53.266 261 | Брестская;Столинский;Стахово;26.716;52.83 262 | Брестская;Столинский;Столин;26.85;51.883 263 | Брестская;Столинский;Струга;26.9;51.85 264 | Брестская;Столинский;Теребличи;27.4;52.5 265 | Брестская;Столинский;Федоры;26.4;51.95 266 | Брестская;Столинский;Хоромск;27.116;52.33 267 | Брестская;Столинский;Хотомель;27.5;51.933 268 | Витебская;Бешенковичский;Бешенковичи;29.45;55.5 269 | Витебская;Бешенковичский;Бочейково;29.15;55.16 270 | Витебская;Бешенковичский;Будилово;29.683;55.1 271 | Витебская;Бешенковичский;Верховье;29.383;54.966 272 | Витебская;Бешенковичский;Забелье;29.7;55.33 273 | Витебская;Бешенковичский;Остров;28.1;56.5 274 | Витебская;Бешенковичский;Островно;29.883;55.133 275 | Витебская;Бешенковичский;Плиса;27.95;55.216 276 | Витебская;Бешенковичский;Рубеж;29.616;54.983 277 | Витебская;Бешенковичский;Свеча;29.283;55.33 278 | Витебская;Бешенковичский;Улла;29.233;55.216 279 | Витебская;Браславский;Ахремовцы;27.133;55.583 280 | Витебская;Браславский;Богино;26.8;55.416 281 | Витебская;Браславский;Большой Озерецк;29.466;54.783 282 | Витебская;Браславский;Бородиничи;27.3;55.533 283 | Витебская;Браславский;Босяные;27.75;55.683 284 | Витебская;Браславский;Браслав;27.33;55.633 285 | Витебская;Браславский;Бухово;29.35;55.85 286 | Витебская;Браславский;Видзы;26.633;55.4 287 | Витебская;Браславский;Воеводки;29.966;55.1 288 | Витебская;Браславский;Возгеляны;26.566;55.483 289 | Витебская;Браславский;Волесы;28.45;56.83 290 | Витебская;Браславский;Воронь;28.633;55.16 291 | Витебская;Браславский;Голбея;27.216;55.2 292 | Витебская;Браславский;Городиловичи;28.283;56.16 293 | Витебская;Браславский;Гриблы;27.83;55.316 294 | Витебская;Браславский;Гридьки;26.95;55.15 295 | Витебская;Браславский;Гурец;29.33;54.7 296 | Витебская;Браславский;Далекие;26.866;55.483 297 | Витебская;Браславский;Домути;26.3;54.983 298 | Витебская;Браславский;Дрисвяты;26.683;55.583 299 | Витебская;Браславский;Друйск;27.283;55.733 300 | Витебская;Браславский;Друя;27.45;55.783 301 | Витебская;Браславский;Дулино;27.4;55.3 302 | Витебская;Браславский;Едловичи;26.933;55.583 303 | Витебская;Браславский;Жауры;29.816;55.5 304 | Витебская;Браславский;Загоряне;30.5;55.633 305 | Витебская;Браславский;Задетуни;30.716;55.25 306 | Витебская;Браславский;Заесье;28.916;54.633 307 | Витебская;Браславский;Иказнь;27.266;55.616 308 | Витебская;Браславский;Искозы;31.5;54.566 309 | Витебская;Браславский;Канево;29.483;54.85 310 | Витебская;Браславский;Караевичи;28.983;54.916 311 | Витебская;Браславский;Козьяны;29.5;55.533 312 | Витебская;Браславский;Козяны;26.85;55.3 313 | Витебская;Браславский;Коковино;30.83;54.683 314 | Витебская;Браславский;Конаши;30.416;55.5 315 | Витебская;Браславский;Конный Бор;29.83;55.683 316 | Витебская;Браславский;Кончани;29.766;55.483 317 | Витебская;Браславский;Костеево;30.516;54.95 318 | Витебская;Браславский;Лиопино;30.783;55.333 319 | Витебская;Браславский;Лозичи;27.533;55.2 320 | Витебская;Браславский;Малашенки;29.983;55.616 321 | Витебская;Браславский;Манулки;30.533;55.2 322 | Витебская;Браславский;Мацуты;26.733;55.83 323 | Витебская;Браславский;Межа;30.416;55.683 324 | Витебская;Браславский;Межаны;26.766;55.65 325 | Витебская;Браславский;Мишутки;30.583;55.316 326 | Витебская;Браславский;Мозолово;30.15;55.283 327 | Витебская;Браславский;Низкоборье;30.816;55.533 328 | Витебская;Браславский;Новая Земля;30.883;54.716 329 | Витебская;Браславский;Норковичи;26.666;55.116 330 | Витебская;Браславский;Обруб-Березвечский;27.716;55.183 331 | Витебская;Браславский;Опса;26.816;55.533 332 | Витебская;Браславский;Опса;26.833;55.533 333 | Витебская;Браславский;Осово;27.816;54.833 334 | Витебская;Браславский;Пантелейки;27.16;55.666 335 | Витебская;Браславский;Плюсы;27.5;55.816 336 | Витебская;Браславский;Погостище;30.55;55.5 337 | Витебская;Браславский;Погоща;26.916;55.55 338 | Витебская;Браславский;Приперное;27.666;55.83 339 | Витебская;Браславский;Раветичи;29.75;54.55 340 | Витебская;Браславский;Рамшино;29.933;54.966 341 | Витебская;Браславский;Ромальдово;30.533;54.766 342 | Витебская;Браславский;Рюм;29.1;55.783 343 | Витебская;Браславский;Савченки;30.83;55.333 344 | Витебская;Браславский;Свольно;28.116;55.733 345 | Витебская;Браславский;Свядица;28.7;54.783 346 | Витебская;Браславский;Слободка;27.183;55.683 347 | Витебская;Браславский;Стальмаково;27.966;55.516 348 | Витебская;Браславский;Стариновичи;29.45;55.466 349 | Витебская;Браславский;Суромщина;27.616;55.75 350 | Витебская;Браславский;Теплюки;27.966;56.83 351 | Витебская;Браславский;Тетерки;27.25;55.55 352 | Витебская;Браславский;Тимошково;28.5;55.633 353 | Витебская;Браславский;Тофели;28.916;55.8 354 | Витебская;Браславский;Усяны;26.9;55.633 355 | Витебская;Браславский;Хомищево;30.33;55.1 356 | Витебская;Браславский;Цевьи;29.416;55.383 357 | Витебская;Браславский;Шерстово;29.283;55.95 358 | Витебская;Браславский;Шклянцы;27.85;54.716 359 | Витебская;Браславский;Щеперня;28.95;55.716 360 | Витебская;Браславский;Щербы;27.866;55.233 361 | Витебская;Верхнедвинский;Бигосово;27.75;55.833 362 | Витебская;Верхнедвинский;Борковичи;28.333;55.666 363 | Витебская;Верхнедвинский;Верхнедвинск;27.95;55.816 364 | Витебская;Верхнедвинский;Волынцы;28.183;55.716 365 | Витебская;Верхнедвинский;Дерновичи;28.45;55.716 366 | Витебская;Верхнедвинский;Зельки;28.283;55.616 367 | Витебская;Верхнедвинский;Кохановичи;28.133;55.866 368 | Витебская;Верхнедвинский;Лисно;28.416;56.33 369 | Витебская;Верхнедвинский;Освея;28.1;56.16 370 | Витебская;Верхнедвинский;Первомайская;28.5;55.816 371 | Витебская;Верхнедвинский;Росица;27.766;55.916 372 | Витебская;Верхнедвинский;Сарья;27.883;55.9 373 | Витебская;Верхнедвинский;Стрелки;28.2;55.933 374 | Витебская;Витебский;Белый Двор;27.733;55.466 375 | Витебская;Витебский;Беляи;27.516;55.3 376 | Витебская;Витебский;Витебск;30.216;55.166 377 | Витебская;Витебский;Вороны;30.383;55.15 378 | Витебская;Витебский;Гора;29.35;54.633 379 | Витебская;Витебский;Должа;30.66;55.366 380 | Витебская;Витебский;Дрожаки;30.16;55.7 381 | Витебская;Витебский;Дубиново;26.95;55.766 382 | Витебская;Витебский;Еремино;30.45;55.133 383 | Витебская;Витебский;Загородно;30.783;55.233 384 | Витебская;Витебский;Загорье;28.9;55.166 385 | Витебская;Витебский;Замосточье;27.983;54.65 386 | Витебская;Витебский;Заречье;29.733;55.566 387 | Витебская;Витебский;Зароново;29.883;55.3 388 | Витебская;Витебский;Заслоново;28.916;54.883 389 | Витебская;Витебский;Княжица;30.16;55.183 390 | Витебская;Витебский;Комаи;26.616;55.66 391 | Витебская;Витебский;Коммунарка;30.383;55.233 392 | Витебская;Витебский;Копти;30.35;55.66 393 | Витебская;Витебский;Кострово;28.266;56.83 394 | Витебская;Витебский;Кравцово;29.683;55.483 395 | Витебская;Витебский;Курино;30.416;55.366 396 | Витебская;Витебский;Липовка;27.816;55.966 397 | Витебская;Витебский;Липск;28.183;54.85 398 | Витебская;Витебский;Ложок;29.75;55.2 399 | Витебская;Витебский;Луговая;30.866;54.416 400 | Витебская;Витебский;Лыськово;30.55;55.65 401 | Витебская;Витебский;Малиновка;28.2;55.5 402 | Витебская;Витебский;Низкий Городец;29.55;54.616 403 | Витебская;Витебский;Озеры;30.766;54.766 404 | Витебская;Витебский;Оконо;28.55;54.816 405 | Витебская;Витебский;Ольгово;30.233;55.233 406 | Витебская;Витебский;Ольховик;30.766;55.66 407 | Витебская;Витебский;Осиновка;30.316;54.933 408 | Витебская;Витебский;Остановка;27.4;55.45 409 | Витебская;Витебский;Островские;30.6;55.45 410 | Витебская;Витебский;Посад;30.15;54.8 411 | Витебская;Витебский;Пятигорск;29.316;55.83 412 | Витебская;Витебский;Ровное;29.366;55.483 413 | Витебская;Витебский;Романово;30.15;55.483 414 | Витебская;Витебский;Руба;30.283;55.283 415 | Витебская;Витебский;Саньково;27.966;56.16 416 | Витебская;Витебский;Скрыдлево;30.5;55.16 417 | Витебская;Витебский;Сосновка;30.183;55.83 418 | Витебская;Витебский;Сосновый Бор;28.583;55.983 419 | Витебская;Витебский;Староселье;28.766;55.33 420 | Витебская;Витебский;Столбцы;29.16;54.65 421 | Витебская;Витебский;Стриги;30.5;54.883 422 | Витебская;Витебский;Сураж;30.733;55.416 423 | Витебская;Витебский;Фролово;30.216;55.633 424 | Витебская;Витебский;Шатилово;29.5;55.383 425 | Витебская;Витебский;Шо;28.25;55.183 426 | Витебская;Витебский;Яновичи;30.7;55.3 427 | Витебская;Глубокский;Глубокое;27.683;55.133 428 | Витебская;Глубокский;Залесье;27.716;55.283 429 | Витебская;Глубокский;Зябки;28.166;55.266 430 | Витебская;Глубокский;Кульгаи;28.283;55.3 431 | Витебская;Глубокский;Мосар;27.466;55.233 432 | Витебская;Глубокский;Подсвилье;27.95;55.15 433 | Витебская;Глубокский;Прозороки;28.216;55.3 434 | Витебская;Глубокский;Псуя;28.15;55.2 435 | Витебская;Глубокский;Узречье;27.6;55.25 436 | Витебская;Глубокский;Урожайная;27.916;55.66 437 | Витебская;Городокский;Большие Стайки;29.9;55.416 438 | Витебская;Городокский;Веречье;30.383;55.583 439 | Витебская;Городокский;Вировля;29.85;55.633 440 | Витебская;Городокский;Городок;29.983;55.466 441 | Витебская;Городокский;Гурки;30.16;55.783 442 | Витебская;Городокский;Езерище;29.983;55.833 443 | Витебская;Городокский;Меховое;29.95;55.716 444 | Витебская;Городокский;Новый Болецк;30.33;55.533 445 | Витебская;Городокский;Пролетарск;29.65;55.6 446 | Витебская;Городокский;Смоловка;30.216;55.55 447 | Витебская;Городокский;Хвошно;30.15;55.733 448 | Витебская;Городокский;Холомерье;29.716;55.75 449 | Витебская;Докшицкий;Барсуки;30.283;54.416 450 | Витебская;Докшицкий;Бегомль;28.66;54.733 451 | Витебская;Докшицкий;Березино;28.2;54.9 452 | Витебская;Докшицкий;Бересневка;28.83;54.8 453 | Витебская;Докшицкий;Волколата;27.366;54.933 454 | Витебская;Докшицкий;Докшицы;27.75;54.883 455 | Витебская;Докшицкий;Комайск;27.9;54.883 456 | Витебская;Докшицкий;Крулевщина;27.783;55.33 457 | Витебская;Докшицкий;Нестеровщина;28.16;54.95 458 | Витебская;Докшицкий;Парафьяново;27.616;54.883 459 | Витебская;Докшицкий;Понизовье;30.45;54.466 460 | Витебская;Докшицкий;Порплище;27.65;54.966 461 | Витебская;Докшицкий;Торгуны;27.85;54.933 462 | Витебская;Докшицкий;Юрковщина;28.666;54.95 463 | Витебская;Дубровенский;Баево;31.83;54.483 464 | Витебская;Дубровенский;Боброво;28.983;55.16 465 | Витебская;Дубровенский;Добрынь;30.783;54.45 466 | Витебская;Дубровенский;Дубровно;30.683;54.583 467 | Витебская;Дубровенский;Ляды;31.15;54.6 468 | Витебская;Дубровенский;Осинторф;30.65;54.716 469 | Витебская;Дубровенский;Россасно;30.883;54.65 470 | Витебская;Дубровенский;Якубово;30.566;54.6 471 | Витебская;Лепельский;Большой Полсвиж;28.733;54.85 472 | Витебская;Лепельский;Домжерицы;28.316;54.75 473 | Витебская;Лепельский;Камень;28.883;55.16 474 | Витебская;Лепельский;Лепель;28.7;54.883 475 | Витебская;Лепельский;Новые Волосовичи;28.85;54.766 476 | Витебская;Лепельский;Пышно;28.483;54.95 477 | Витебская;Лепельский;Старое Лядно;28.766;54.933 478 | Витебская;Лепельский;Юхновка;27.966;54.8 479 | Витебская;Лиозненский;Бабиновичи;30.55;54.833 480 | Витебская;Лиозненский;Велешковичи;30.766;55.133 481 | Витебская;Лиозненский;Великое Село;27.666;55.4 482 | Витебская;Лиозненский;Высочаны;30.433;54.983 483 | Витебская;Лиозненский;Выходцы;30.7;54.833 484 | Витебская;Лиозненский;Добромысли;30.666;54.933 485 | Витебская;Лиозненский;Заольша;30.916;54.983 486 | Витебская;Лиозненский;Ковали;27.833;55.116 487 | Витебская;Лиозненский;Колышки;30.95;55.166 488 | Витебская;Лиозненский;Крынки;30.433;55.33 489 | Витебская;Лиозненский;Лиозно;30.8;55.33 490 | Витебская;Лиозненский;Осипово;30.383;54.9 491 | Витебская;Лиозненский;Стасево;30.65;55.83 492 | Витебская;Миорский;Борки;28.65;55.683 493 | Витебская;Миорский;Волковщина;27.433;55.55 494 | Витебская;Миорский;Дворное Село;27.666;55.566 495 | Витебская;Миорский;Дисна;28.166;55.55 496 | Витебская;Миорский;Заутье;28.116;55.466 497 | Витебская;Миорский;Канцерово;28.183;55.383 498 | Витебская;Миорский;Леонполь;27.8;55.8 499 | Витебская;Миорский;Миоры;27.633;55.616 500 | Витебская;Миорский;Николаево;29.266;55.233 501 | Витебская;Миорский;Новгороды;27.6;55.516 502 | Витебская;Миорский;Новый Погост;27.5;55.5 503 | Витебская;Миорский;Повятье;27.65;55.7 504 | Витебская;Миорский;Погост;30.2;54.5 505 | Витебская;Миорский;Слобода;28.35;54.816 506 | Витебская;Миорский;Черес;27.716;55.633 507 | Витебская;Миорский;Язно;28.15;55.416 508 | Витебская;Оршанский;Барань;30.3;54.483 509 | Витебская;Оршанский;Боровуха 1-я;28.6;55.583 510 | Витебская;Оршанский;Бурое;30.733;54.616 511 | Витебская;Оршанский;Высокое;30.433;54.65 512 | Витебская;Оршанский;Жегули;27.983;55.733 513 | Витебская;Оршанский;Зайково;30.516;55.733 514 | Витебская;Оршанский;Заполье;30.766;55.5 515 | Витебская;Оршанский;Зубово;30.4;54.366 516 | Витебская;Оршанский;Клюковка;30.4;54.75 517 | Витебская;Оршанский;Копысь;30.3;54.316 518 | Витебская;Оршанский;Крапивно;30.583;54.516 519 | Витебская;Оршанский;Лисуны;30.133;54.45 520 | Витебская;Оршанский;Луговские;30.45;55.8 521 | Витебская;Оршанский;Милашки;27.16;55.466 522 | Витебская;Оршанский;Ореховск;30.5;54.683 523 | Витебская;Оршанский;Орша;30.4;54.5 524 | Витебская;Оршанский;Росский Селец;30.15;54.55 525 | Витебская;Оршанский;Стайки;30.266;54.683 526 | Витебская;Оршанский;Струсто;26.983;55.683 527 | Витебская;Оршанский;Шаши;29.66;55.316 528 | Витебская;Оршанский;Юрцево;30.366;54.616 529 | Витебская;Оршанский;Яковлевичи;30.5;54.333 530 | Витебская;Полоцкий;Адамово;28.466;55.616 531 | Витебская;Полоцкий;Азино;28.65;55.633 532 | Витебская;Полоцкий;Бабцы;28.133;54.75 533 | Витебская;Полоцкий;Белое Село;29.983;54.683 534 | Витебская;Полоцкий;Бобыничи;28.4;55.283 535 | Витебская;Полоцкий;Веремеево;29.966;55.533 536 | Витебская;Полоцкий;Ветрино;28.466;55.416 537 | Витебская;Полоцкий;Волча;28.1;54.7 538 | Витебская;Полоцкий;Вороничи;28.633;55.333 539 | Витебская;Полоцкий;Глоты;28.733;55.95 540 | Витебская;Полоцкий;Гомель;28.766;55.3 541 | Витебская;Полоцкий;Горчаки;28.566;55.433 542 | Витебская;Полоцкий;Горы;29.116;55.85 543 | Витебская;Полоцкий;Горяны;29.33;55.416 544 | Витебская;Полоцкий;Грамоще;28.466;55.666 545 | Витебская;Полоцкий;Домники;29.15;55.5 546 | Витебская;Полоцкий;Дретунь;29.216;55.7 547 | Витебская;Полоцкий;Дубравы;28.233;56 548 | Витебская;Полоцкий;Заозерье;30.5;54.416 549 | Витебская;Полоцкий;Заскорки;28.65;55.383 550 | Витебская;Полоцкий;Захарничи;28.866;55.55 551 | Витебская;Полоцкий;Зеленка;28.85;55.65 552 | Витебская;Полоцкий;Зубаки;30.616;54.983 553 | Витебская;Полоцкий;Ковалева;30.666;55.55 554 | Витебская;Полоцкий;Красники;27.95;54.683 555 | Витебская;Полоцкий;Литовцы;27.75;54.983 556 | Витебская;Полоцкий;Ловжа;29.483;55.3 557 | Витебская;Полоцкий;Малое Ситно;29.35;55.683 558 | Витебская;Полоцкий;Миловиды;28.4;55.933 559 | Витебская;Полоцкий;Мирная;29.9;55.366 560 | Витебская;Полоцкий;Мосейки;30.33;54.816 561 | Витебская;Полоцкий;Навлица;28.5;55.366 562 | Витебская;Полоцкий;Новая Полота;29.33;55.6 563 | Витебская;Полоцкий;Новое Село;29.633;54.466 564 | Витебская;Полоцкий;Новополоцк;28.633;55.516 565 | Витебская;Полоцкий;Новые Крюки;27.866;55.65 566 | Витебская;Полоцкий;Орлово;30.283;55.116 567 | Витебская;Полоцкий;Подворица;29.633;54.933 568 | Витебская;Полоцкий;Пола;29.5;55.133 569 | Витебская;Полоцкий;Полоцк;28.766;55.466 570 | Витебская;Полоцкий;Ремни;30.3;55.683 571 | Витебская;Полоцкий;Ровное Поле;28.466;55.9 572 | Витебская;Полоцкий;Русины;26.933;55.33 573 | Витебская;Полоцкий;Семенцово;29.6;55.83 574 | Витебская;Полоцкий;Ситенец;29.16;55.566 575 | Витебская;Полоцкий;Смоленская Возвышенность;30.7;54.483 576 | Витебская;Полоцкий;Смоляны;30.66;54.6 577 | Витебская;Полоцкий;Соколово;29.116;55.1 578 | Витебская;Полоцкий;Старая Белица;29.633;54.7 579 | Витебская;Полоцкий;Старый Погост;27.616;55.483 580 | Витебская;Полоцкий;Труды;29.383;55.633 581 | Витебская;Полоцкий;Туровля;28.933;55.366 582 | Витебская;Полоцкий;Уно;30.7;55.5 583 | Витебская;Полоцкий;Христово;27.45;55.66 584 | Витебская;Полоцкий;Черное;27.283;55.15 585 | Витебская;Полоцкий;Шпаковщина;28.333;55.466 586 | Витебская;Поставский;Бель;31.16;54.65 587 | Витебская;Поставский;Бельки;27.2;55.266 588 | Витебская;Поставский;Воропаево;27.216;55.15 589 | Витебская;Поставский;Дуниловичи;27.25;55.66 590 | Витебская;Поставский;Курополье;26.866;55.216 591 | Витебская;Поставский;Лынтупы;26.316;55.5 592 | Витебская;Поставский;Новоселки;29.833;54.983 593 | Витебская;Поставский;Полесье;26.383;55.1 594 | Витебская;Поставский;Поставы;26.833;55.116 595 | Витебская;Россонский;Горбачево;29.5;55.95 596 | Витебская;Россонский;Заборье;28.983;54.716 597 | Витебская;Россонский;Клястицы;28.6;55.883 598 | Витебская;Россонский;Краснополье;29.266;55.816 599 | Витебская;Россонский;Россоны;28.816;55.883 600 | Витебская;Россонский;Селявщина;28.8;55.816 601 | Витебская;Россонский;Соколище;28.6;55.766 602 | Витебская;Россонский;Юховичи;28.666;56.16 603 | Витебская;Россонский;Янковичи;28.783;55.766 604 | Витебская;Сенненский;Алексиничи;29.966;54.766 605 | Витебская;Сенненский;Белая Липа;29.733;54.916 606 | Витебская;Сенненский;Богушевск;30.216;54.85 607 | Витебская;Сенненский;Латыгаль;29.616;54.766 608 | Витебская;Сенненский;Ледневичи;30.15;54.716 609 | Витебская;Сенненский;Мошканы;30.33;54.95 610 | Витебская;Сенненский;Оболь;29.733;55.683 611 | Витебская;Сенненский;Рясно;29.833;54.65 612 | Витебская;Сенненский;Сенно;29.683;54.816 613 | Витебская;Сенненский;Яново;30.1;54.75 614 | Витебская;Толочинский;Волосово;29.533;54.55 615 | Витебская;Толочинский;Воронцевичи;29.916;54.366 616 | Витебская;Толочинский;Горщевщина;29.966;54.566 617 | Витебская;Толочинский;Коханово;30;54.466 618 | Витебская;Толочинский;Обольцы;29.816;54.6 619 | Витебская;Толочинский;Плоское;29.533;54.45 620 | Витебская;Толочинский;Славени;29.516;54.333 621 | Витебская;Толочинский;Славное;29.45;54.316 622 | Витебская;Толочинский;Толочин;29.7;54.416 623 | Витебская;Ушачский;Арлея;29.466;55.633 624 | Витебская;Ушачский;Большие Дольцы;28.433;55.66 625 | Витебская;Ушачский;Весницк;28.333;55.5 626 | Витебская;Ушачский;Глыбочка;28.966;55.266 627 | Витебская;Ушачский;Двор-Усвея;29.1;55.233 628 | Витебская;Ушачский;Дубровка;26.933;55.35 629 | Витебская;Ушачский;Жары;28.666;55.83 630 | Витебская;Ушачский;Завечелье;28.75;55.133 631 | Витебская;Ушачский;Задежье;28.266;55.85 632 | Витебская;Ушачский;Косари;28.316;55.33 633 | Витебская;Ушачский;Кругляны;29.983;54.9 634 | Витебская;Ушачский;Кубличи;28.333;55.166 635 | Витебская;Ушачский;Малые Дольцы;28.383;54.983 636 | Витебская;Ушачский;Матырино;28.533;55.25 637 | Витебская;Ушачский;Несино;28.95;55 638 | Витебская;Ушачский;Полюдовичи;28.35;55.516 639 | Витебская;Ушачский;Селище;28.416;55.2 640 | Витебская;Ушачский;Сорочино;28.75;55.2 641 | Витебская;Ушачский;Старое Село;29.883;55.216 642 | Витебская;Ушачский;Старое Соколино;29.716;54.5 643 | Витебская;Ушачский;Туросы;29;55.15 644 | Витебская;Ушачский;Усая;29.5;55.166 645 | Витебская;Ушачский;Ушачи;28.616;55.183 646 | Витебская;Чашникский;Замошье;27.1;55.5 647 | Витебская;Чашникский;Иванск;29.133;54.933 648 | Витебская;Чашникский;Краснолуки;28.833;54.616 649 | Витебская;Чашникский;Латыголичи;28.7;54.616 650 | Витебская;Чашникский;Лукомль;29.15;54.7 651 | Витебская;Чашникский;Новолукомль;29.133;54.65 652 | Витебская;Чашникский;Октябрьский;29.333;54.866 653 | Витебская;Чашникский;Соболи;29.3;54.683 654 | Витебская;Чашникский;Тяпино;29.66;54.833 655 | Витебская;Чашникский;Чашники;29.133;54.866 656 | Витебская;Чашникский;Черея;29.283;54.616 657 | Витебская;Шарковщинский;Веретеи;27.816;55.316 658 | Витебская;Шарковщинский;Германовичи;27.733;55.416 659 | Витебская;Шарковщинский;Иоды;27.233;55.45 660 | Витебская;Шарковщинский;Лонские;27.233;55.383 661 | Витебская;Шарковщинский;Лужки;27.883;55.35 662 | Витебская;Шарковщинский;Столица;27.816;55.416 663 | Витебская;Шарковщинский;Шарковщина;27.466;55.366 664 | Витебская;Шумилинский;Добрино;30.266;54.783 665 | Витебская;Шумилинский;Кордон;29.233;55.266 666 | Витебская;Шумилинский;Кривое Село;29.566;55.133 667 | Витебская;Шумилинский;Лесковичи;29.65;55.25 668 | Витебская;Шумилинский;Мишковичи;29.35;55.183 669 | Витебская;Шумилинский;Сиротино;29.616;55.383 670 | Витебская;Шумилинский;Шумилино;29.616;55.3 671 | Витебская;Шумилинский;Язвино;29.75;55.25 672 | Гомельская;Брагинский;Асаревичи;30.483;51.616 673 | Гомельская;Брагинский;Брагин;30.266;51.783 674 | Гомельская;Брагинский;Верхние Жары;30.583;51.333 675 | Гомельская;Брагинский;Гдень;30.433;51.333 676 | Гомельская;Брагинский;Глуховичи;30.216;51.766 677 | Гомельская;Брагинский;Дерновичи;29.733;51.6 678 | Гомельская;Брагинский;Железники;31.333;52.75 679 | Гомельская;Брагинский;Кливы;29.833;51.9 680 | Гомельская;Брагинский;Комарин;30.566;51.433 681 | Гомельская;Брагинский;Кононовщина;30.2;51.95 682 | Гомельская;Брагинский;Красное;30.933;52.466 683 | Гомельская;Брагинский;Малейки;30.333;51.8 684 | Гомельская;Брагинский;Микуличи;30.15;51.85 685 | Гомельская;Брагинский;Нижние Жары;30.55;51.3 686 | Гомельская;Брагинский;Новая Иолча;30.533;51.5 687 | Гомельская;Брагинский;Новая Мильча;30.933;52.45 688 | Гомельская;Брагинский;Острогляды;30.15;51.783 689 | Гомельская;Брагинский;Пирки;30.383;51.55 690 | Гомельская;Брагинский;Рудня;27.716;51.883 691 | Гомельская;Брагинский;Рудня-Маримонова;30.733;52.166 692 | Гомельская;Брагинский;Сперижье;30.233;51.716 693 | Гомельская;Брагинский;Сувиды;30.383;51.566 694 | Гомельская;Брагинский;Углы;30.3;51.866 695 | Гомельская;Брагинский;Чемерисы;30.45;51.7 696 | Гомельская;Брагинский;Чернин;29.316;52.7 697 | Гомельская;Буда-Кошелевский;Глазовка;30.516;52.633 698 | Гомельская;Буда-Кошелевский;Губичи;30.316;52.683 699 | Гомельская;Буда-Кошелевский;Дербичи;30.683;52.9 700 | Гомельская;Буда-Кошелевский;Дуравичи;30.716;52.7 701 | Гомельская;Буда-Кошелевский;Еленец;30.316;52.633 702 | Гомельская;Буда-Кошелевский;Калинино;30.85;52.6 703 | Гомельская;Буда-Кошелевский;Неговка;30.5;52.866 704 | Гомельская;Буда-Кошелевский;Недойка;30.4;52.65 705 | Гомельская;Буда-Кошелевский;Потаповка;30.5;52.75 706 | Гомельская;Буда-Кошелевский;Радеево;30.75;52.65 707 | Гомельская;Буда-Кошелевский;Рогинь;30.633;52.883 708 | Гомельская;Буда-Кошелевский;Уваровичи;30.716;52.6 709 | Гомельская;Буда-Кошелевский;Уза;30.833;52.6 710 | Гомельская;Буда-Кошелевский;Ховхло;30.433;52.516 711 | Гомельская;Буда-Кошелевский;Чеботовичи;30.433;52.566 712 | Гомельская;Буда-Кошелевский;Шарибовка;30.533;52.783 713 | Гомельская;Ветковский;Беседь;31.216;52.633 714 | Гомельская;Ветковский;Великие Немки;31.333;52.866 715 | Гомельская;Ветковский;Ветка;31.166;52.55 716 | Гомельская;Ветковский;Даниловичи;30.966;52.633 717 | Гомельская;Ветковский;Казацкие Болсуны;31.35;52.933 718 | Гомельская;Ветковский;Неглюбка;31.533;52.766 719 | Гомельская;Ветковский;Присно;31;52.666 720 | Гомельская;Ветковский;Радуга;31.1;52.583 721 | Гомельская;Ветковский;Светиловичи;31.316;52.8 722 | Гомельская;Ветковский;Столбун;31.416;52.8 723 | Гомельская;Ветковский;Шерстин;31.66;52.65 724 | Гомельская;Гомельский;Бережцы;27.65;52 725 | Гомельская;Гомельский;Бобовичи;30.933;52.333 726 | Гомельская;Гомельский;Большая Крушиновка;29.816;53.233 727 | Гомельская;Гомельский;Большевик;30.883;52.566 728 | Гомельская;Гомельский;Васильевка;31.516;52.25 729 | Гомельская;Гомельский;Грабовка;31.166;52.183 730 | Гомельская;Гомельский;Еремино;30.933;52.516 731 | Гомельская;Гомельский;Зябровка;31.2;52.333 732 | Гомельская;Гомельский;Климовка;31.116;52.3 733 | Гомельская;Гомельский;Костюковка;30.916;52.533 734 | Гомельская;Гомельский;Малевичская Рудня;29.866;52.9 735 | Гомельская;Гомельский;Маложин;30.5;51.733 736 | Гомельская;Гомельский;Марковичи;31.233;52.116 737 | Гомельская;Гомельский;Михальки;30.8;52.25 738 | Гомельская;Гомельский;Михедовичи;28.383;52.333 739 | Гомельская;Гомельский;Новая Гута;30.983;52.1 740 | Гомельская;Гомельский;Новые Громыки;31.366;52.683 741 | Гомельская;Гомельский;Очесо-Рудня;31.583;52.566 742 | Гомельская;Гомельский;Поколюбичи;31.5;52.516 743 | Гомельская;Гомельский;Прибор;30.766;52.416 744 | Гомельская;Гомельский;Романовичи;31.15;52.433 745 | Гомельская;Гомельский;Селицкая;31.1;52.8 746 | Гомельская;Гомельский;Скрыгалово;28.816;52.1 747 | Гомельская;Гомельский;Телеши;30.633;52.483 748 | Гомельская;Гомельский;Тереничи;30.683;52.533 749 | Гомельская;Гомельский;Терюха;31.16;52.2 750 | Гомельская;Гомельский;Ужинец;29.65;52.16 751 | Гомельская;Гомельский;Урицкое;30.816;52.466 752 | Гомельская;Гомельский;Шарпиловка;30.95;52.116 753 | Гомельская;Добрушский;Большие Селютичи;28.216;52.3 754 | Гомельская;Добрушский;Гордуны;31.35;52.233 755 | Гомельская;Добрушский;Гороховищи;29.283;52.616 756 | Гомельская;Добрушский;Добруш;31.316;52.416 757 | Гомельская;Добрушский;Жгуно-Буда;31.266;52.35 758 | Гомельская;Добрушский;Корма;31.516;52.35 759 | Гомельская;Добрушский;Красная Буда;31.5;52.183 760 | Гомельская;Добрушский;Лешня;28.816;52.5 761 | Гомельская;Добрушский;Тереховка;31.433;52.216 762 | Гомельская;Ельский;Богутичи;29.1;51.75 763 | Гомельская;Ельский;Валавск;28.783;51.666 764 | Гомельская;Ельский;Движки;29.33;51.833 765 | Гомельская;Ельский;Ельск;29.15;51.8 766 | Гомельская;Ельский;Кочище;28.933;51.733 767 | Гомельская;Ельский;Ремезы;28.966;51.816 768 | Гомельская;Ельский;Скородное;28.816;51.616 769 | Гомельская;Ельский;Словечно;29.5;51.633 770 | Гомельская;Житковичский;Белев;28.33;52.3 771 | Гомельская;Житковичский;Березняки;27.5;52.5 772 | Гомельская;Житковичский;Бронислав;27.6;52.2 773 | Гомельская;Житковичский;Вересница;27.65;52.83 774 | Гомельская;Житковичский;Ветчин;28.166;52.45 775 | Гомельская;Житковичский;Житковичи;27.866;52.216 776 | Гомельская;Житковичский;Залютичи;27.566;52.4 777 | Гомельская;Житковичский;Кольно;27.9;52.133 778 | Гомельская;Житковичский;Люденевичи;27.7;52.216 779 | Гомельская;Житковичский;Милевичи;27.6;52.466 780 | Гомельская;Житковичский;Переров;28.16;52.66 781 | Гомельская;Житковичский;Погост;27.866;52.5 782 | Гомельская;Житковичский;Пуховичи;27.966;52.383 783 | Гомельская;Житковичский;Тимошевичи;27.433;52.4 784 | Гомельская;Житковичский;Туров;27.716;52.66 785 | Гомельская;Житковичский;Хвоенск;27.933;52.5 786 | Гомельская;Житковичский;Юркевичи;27.6;52.3 787 | Гомельская;Жлобинский;Верхняя Олба;30.2;52.65 788 | Гомельская;Жлобинский;Доброгоща;29.866;52.7 789 | Гомельская;Жлобинский;Жлобин;30.33;52.9 790 | Гомельская;Жлобинский;Китин;29.633;52.85 791 | Гомельская;Жлобинский;Коротковичи;29.783;52.8 792 | Гомельская;Жлобинский;Красный Берег;29.766;52.95 793 | Гомельская;Жлобинский;Луки;29.766;52.35 794 | Гомельская;Жлобинский;Майское;30.183;52.966 795 | Гомельская;Жлобинский;Мормаль;29.883;52.766 796 | Гомельская;Жлобинский;Пиревичи;30.316;52.783 797 | Гомельская;Жлобинский;Проскурни;30.66;52.816 798 | Гомельская;Жлобинский;Радуша;29.683;52.933 799 | Гомельская;Жлобинский;Симоновичи;28.83;51.866 800 | Гомельская;Жлобинский;Скепня;30.233;52.75 801 | Гомельская;Жлобинский;Солоное;30.16;52.85 802 | Гомельская;Жлобинский;Старая Рудня;30.266;52.85 803 | Гомельская;Жлобинский;Стрешин;30.1;52.733 804 | Гомельская;Жлобинский;Шихов;30.166;52.683 805 | Гомельская;Жлобинский;Щедрин;29.55;52.9 806 | Гомельская;Калинковичский;Великие Автюки;29.516;52.66 807 | Гомельская;Калинковичский;Горбовичи;29.216;52.2 808 | Гомельская;Калинковичский;Горочичи;29.433;52.266 809 | Гомельская;Калинковичский;Гулевичи;29.383;52.83 810 | Гомельская;Калинковичский;Дудичи;29.333;52.183 811 | Гомельская;Калинковичский;Замостье;29.616;52.25 812 | Гомельская;Калинковичский;Золотуха;29.783;52.333 813 | Гомельская;Калинковичский;Калинковичи;29.333;52.133 814 | Гомельская;Калинковичский;Козловичи;29.35;52.366 815 | Гомельская;Калинковичский;Кротов;29.1;52.3 816 | Гомельская;Калинковичский;Малые Автюки;29.516;52.133 817 | Гомельская;Калинковичский;Михновичи;29.16;52.166 818 | Гомельская;Калинковичский;Нахов;29.716;52.233 819 | Гомельская;Калинковичский;Озаричи;29.266;52.466 820 | Гомельская;Калинковичский;Хобное;29.75;52.83 821 | Гомельская;Калинковичский;Холодники;29.466;52.366 822 | Гомельская;Калинковичский;Хомичи;29.633;52.366 823 | Гомельская;Калинковичский;Юровичи;29.533;51.933 824 | Гомельская;Калинковичский;Якимовичи;29.83;52.25 825 | Гомельская;Кормянский;Буда;28.16;52.5 826 | Гомельская;Кормянский;Ворновка;30.866;53.33 827 | Гомельская;Кормянский;Задубье;30.6;53.15 828 | Гомельская;Кормянский;Каменка;30.666;53.183 829 | Гомельская;Кормянский;Кляпин;31.5;53.166 830 | Гомельская;Кормянский;Корма;30.8;53.133 831 | Гомельская;Кормянский;Литвиновичи;30.866;53.2 832 | Гомельская;Кормянский;Новые Журавичи;30.583;53.233 833 | Гомельская;Кормянский;Октябрево;30.766;53.266 834 | Гомельская;Кормянский;Себровичи;30.916;52.8 835 | Гомельская;Кормянский;Сметаничи;28.533;52.233 836 | Гомельская;Кормянский;Тульговичи;29.666;51.783 837 | Гомельская;Кормянский;Холочье;30.766;52.783 838 | Гомельская;Лельчицкий;Боровое;28.5;51.7 839 | Гомельская;Лельчицкий;Буйновичи;28.55;51.866 840 | Гомельская;Лельчицкий;Букча;27.683;51.75 841 | Гомельская;Лельчицкий;Глушкевичи;27.783;51.566 842 | Гомельская;Лельчицкий;Гребени;28.416;51.666 843 | Гомельская;Лельчицкий;Данилевичи;27.983;51.766 844 | Гомельская;Лельчицкий;Дзержинск;27.55;51.666 845 | Гомельская;Лельчицкий;Дуброва;28.216;51.783 846 | Гомельская;Лельчицкий;Жмурное;28.35;51.716 847 | Гомельская;Лельчицкий;Замошье;28.4;51.966 848 | Гомельская;Лельчицкий;Краснобережье;28.433;51.866 849 | Гомельская;Лельчицкий;Лельчицы;28.316;51.783 850 | Гомельская;Лельчицкий;Липляны;28.366;51.8 851 | Гомельская;Лельчицкий;Милашевичи;27.933;51.65 852 | Гомельская;Лельчицкий;Первомайск;30.5;52.516 853 | Гомельская;Лельчицкий;Приболовичи;27.816;51.666 854 | Гомельская;Лельчицкий;Синицкое Поле;28.65;51.8 855 | Гомельская;Лельчицкий;Слобода;29;52.33 856 | Гомельская;Лельчицкий;Средние Печи;28.2;51.85 857 | Гомельская;Лельчицкий;Стодоличи;28.483;51.716 858 | Гомельская;Лельчицкий;Тонеж;27.783;51.816 859 | Гомельская;Лоевский;Бывальки;30.633;51.85 860 | Гомельская;Лоевский;Деражичи;30.616;51.783 861 | Гомельская;Лоевский;Крупейки;30.716;51.916 862 | Гомельская;Лоевский;Липняки;30.566;52.83 863 | Гомельская;Лоевский;Лоев;30.766;51.933 864 | Гомельская;Лоевский;Мохов;30.733;51.983 865 | Гомельская;Лоевский;Новая Борщовка;30.483;51.983 866 | Гомельская;Лоевский;Переделка;30.733;52.33 867 | Гомельская;Лоевский;Ручаевка;30.516;51.883 868 | Гомельская;Лоевский;Хоминка;30.933;52.5 869 | Гомельская;Мозырьский;Барбаров;29.466;51.9 870 | Гомельская;Мозырьский;Козенки;29.183;52.16 871 | Гомельская;Мозырьский;Махновичи;28.8;51.883 872 | Гомельская;Мозырьский;Мелешковичи;28.983;51.916 873 | Гомельская;Мозырьский;Мозырь;29.216;52.33 874 | Гомельская;Мозырьский;Моисеевка;29.133;52.7 875 | Гомельская;Мозырьский;Новая Рудня;29.1;51.666 876 | Гомельская;Мозырьский;Осовец;28.7;52.5 877 | Гомельская;Мозырьский;Прудок;29.5;52.75 878 | Гомельская;Мозырьский;Романовка;29.333;51.816 879 | Гомельская;Наровлянский;Александровка;29.483;51.433 880 | Гомельская;Наровлянский;Вербовичи;29.516;51.716 881 | Гомельская;Наровлянский;Головчицы;29.333;51.716 882 | Гомельская;Наровлянский;Грушевка;29.416;51.666 883 | Гомельская;Наровлянский;Демидов;29.283;51.666 884 | Гомельская;Наровлянский;Красновка;29.333;52.866 885 | Гомельская;Наровлянский;Наровля;29.483;51.8 886 | Гомельская;Октябрьский;Алексеевка;30.416;51.75 887 | Гомельская;Октябрьский;Бабчин;30.16;51.783 888 | Гомельская;Октябрьский;Бартоломеевка;31.333;52.65 889 | Гомельская;Октябрьский;Белобережская Рудня;29.533;51.666 890 | Гомельская;Октябрьский;Белый Переезд;28.316;52.45 891 | Гомельская;Октябрьский;Береговая Слобода;30.233;52.533 892 | Гомельская;Октябрьский;Беседки;28.916;52.166 893 | Гомельская;Октябрьский;Богдановичи;30.683;53.83 894 | Гомельская;Октябрьский;Буда-Кошелево;30.566;52.716 895 | Гомельская;Октябрьский;Васильково;29.983;52.4 896 | Гомельская;Октябрьский;Вить;29.783;51.883 897 | Гомельская;Октябрьский;Володарск;30.116;52.45 898 | Гомельская;Октябрьский;Волосовичи;31.166;53 899 | Гомельская;Октябрьский;Вороново;28.433;51.616 900 | Гомельская;Октябрьский;Гарусты;31.283;52.7 901 | Гомельская;Октябрьский;Глубочица;30.8;52.933 902 | Гомельская;Октябрьский;Гомель;30.95;52.4 903 | Гомельская;Октябрьский;Грабье;29.16;52.566 904 | Гомельская;Октябрьский;Добрынь;29.183;51.766 905 | Гомельская;Октябрьский;Довляды;29.883;51.516 906 | Гомельская;Октябрьский;Дубровица;30.1;52.5 907 | Гомельская;Октябрьский;Дьяковичи;28.33;52.45 908 | Гомельская;Октябрьский;Загорье;30.966;53.33 909 | Гомельская;Октябрьский;Зарубаное;28.566;51.916 910 | Гомельская;Октябрьский;Зеленый Мох;28.716;51.916 911 | Гомельская;Октябрьский;Зимовище;30.183;51.416 912 | Гомельская;Октябрьский;Зломное;30.5;52.683 913 | Гомельская;Октябрьский;Ипполитовка;30.916;52.966 914 | Гомельская;Октябрьский;Карналин;30.766;52.283 915 | Гомельская;Октябрьский;Кнышевичи;29.3;52.766 916 | Гомельская;Октябрьский;Кожушки;29.75;51.7 917 | Гомельская;Октябрьский;Козлы;28.7;51.516 918 | Гомельская;Октябрьский;Колыбань;30.383;51.483 919 | Гомельская;Октябрьский;Конотоп;29.566;51.75 920 | Гомельская;Октябрьский;Кравцовка;31.66;52.116 921 | Гомельская;Октябрьский;Крушники;28.7;51.983 922 | Гомельская;Октябрьский;Крынки;30.66;52.35 923 | Гомельская;Октябрьский;Крюки;30.266;51.516 924 | Гомельская;Октябрьский;Кузьмичи;28.983;51.65 925 | Гомельская;Октябрьский;Липа;30.8;52.733 926 | Гомельская;Октябрьский;Лисное;28.45;51.816 927 | Гомельская;Октябрьский;Ломовичи;28.95;52.55 928 | Гомельская;Октябрьский;Ломыш;29.583;51.816 929 | Гомельская;Октябрьский;Лохница;28.3;51.7 930 | Гомельская;Октябрьский;Лубень;29.316;51.566 931 | Гомельская;Октябрьский;Любань;29.133;52.6 932 | Гомельская;Октябрьский;Ляды;29.95;52.65 933 | Гомельская;Октябрьский;Лясковичи;28.15;52.116 934 | Гомельская;Октябрьский;Марьино;31.283;52.483 935 | Гомельская;Октябрьский;Машево;30.133;51.483 936 | Гомельская;Октябрьский;Молочки;29.983;51.566 937 | Гомельская;Октябрьский;Новая Дуброва;28.883;52.683 938 | Гомельская;Октябрьский;Новое Полесье;28.266;51.916 939 | Гомельская;Октябрьский;Огородня-Кузьмининская;31.566;52.316 940 | Гомельская;Октябрьский;Октябрь;30.833;52.683 941 | Гомельская;Октябрьский;Октябрьский;28.883;52.633 942 | Гомельская;Октябрьский;Петрицкое;30.383;51.9 943 | Гомельская;Октябрьский;Поречье;28.75;52.633 944 | Гомельская;Октябрьский;Протасы;29.83;52.783 945 | Гомельская;Октябрьский;Расова;29.65;52.616 946 | Гомельская;Октябрьский;Речки;31.166;52.716 947 | Гомельская;Октябрьский;Руденка;29.916;51.983 948 | Гомельская;Октябрьский;Рудня-Бартоломеевка;31.183;53.5 949 | Гомельская;Октябрьский;Рудня-Каменева;30.75;52.1 950 | Гомельская;Октябрьский;Семеновка;30.4;52.133 951 | Гомельская;Октябрьский;Сивинка;31.35;52.566 952 | Гомельская;Октябрьский;Сколодин;28.583;52.33 953 | Гомельская;Октябрьский;Старо-высокое;28.816;51.766 954 | Гомельская;Октябрьский;Старое Закружье;31.5;52.633 955 | Гомельская;Октябрьский;Старые Новоселки;29.233;52.366 956 | Гомельская;Октябрьский;Старые-Дятловичи;30.9;52.233 957 | Гомельская;Октябрьский;Тесны;30.616;51.816 958 | Гомельская;Октябрьский;Толстыки;30.33;52.616 959 | Гомельская;Октябрьский;Уласы;30.1;51.533 960 | Гомельская;Октябрьский;Усов;28.533;51.633 961 | Гомельская;Октябрьский;Хоромцы;28.616;52.683 962 | Гомельская;Октябрьский;Хорошовка;31.6;52.35 963 | Гомельская;Октябрьский;Червонная Слобода;28.566;52.55 964 | Гомельская;Октябрьский;Шкава;29;52.7 965 | Гомельская;Октябрьский;Юшки;29.383;52.233 966 | Гомельская;Петриковский;Бобрик;28.4;52.4 967 | Гомельская;Петриковский;Бринев;28.183;52.183 968 | Гомельская;Петриковский;Велавск;28.616;52.1 969 | Гомельская;Петриковский;Грабов;28.266;52.366 970 | Гомельская;Петриковский;Залесье;30.983;52.9 971 | Гомельская;Петриковский;Зосинцы;28.733;51.55 972 | Гомельская;Петриковский;Ивашковичи;28.783;52.266 973 | Гомельская;Петриковский;Колки;28.966;52.416 974 | Гомельская;Петриковский;Комаровичи;28.466;52.45 975 | Гомельская;Петриковский;Конковичи;28.7;52.166 976 | Гомельская;Петриковский;Копа;30.516;52.366 977 | Гомельская;Петриковский;Копаткевичи;28.816;52.316 978 | Гомельская;Петриковский;Копцевичи;28.316;52.233 979 | Гомельская;Петриковский;Кошевичи;28.733;52.5 980 | Гомельская;Петриковский;Куритичи;28.616;52.283 981 | Гомельская;Петриковский;Лучицы;28.816;52.45 982 | Гомельская;Петриковский;Макаричи;28.433;52.116 983 | Гомельская;Петриковский;Новоселки;28.55;52.4 984 | Гомельская;Петриковский;Петриков;28.5;52.133 985 | Гомельская;Петриковский;Рог;28.716;52.233 986 | Гомельская;Петриковский;Снядин;28.316;52.66 987 | Гомельская;Петриковский;Теребов;28.95;52.25 988 | Гомельская;Петриковский;Фастовичи;28.483;52.516 989 | Гомельская;Речицкий;Артуки;30.533;52.15 990 | Гомельская;Речицкий;Борхов;30.583;52.416 991 | Гомельская;Речицкий;Бронное;30.466;52.316 992 | Гомельская;Речицкий;Василевичи;29.833;52.25 993 | Гомельская;Речицкий;Демьянки;31.5;52.533 994 | Гомельская;Речицкий;Заспа;30.5;52.266 995 | Гомельская;Речицкий;Капоровка;30.233;52.283 996 | Гомельская;Речицкий;Ковчицы 1-е;29.2;52.866 997 | Гомельская;Речицкий;Короватичи;30.1;52.233 998 | Гомельская;Речицкий;Леваши;30.55;52.216 999 | Гомельская;Речицкий;Лиски;30.83;52.316 1000 | Гомельская;Речицкий;Макановичи;29.916;52.133 1001 | Гомельская;Речицкий;Малодуша;30.233;52.15 1002 | Гомельская;Речицкий;Новые Дятловичи;30.933;52.183 1003 | Гомельская;Речицкий;Новый Барсук;30.3;52.116 1004 | Гомельская;Речицкий;Озерщина;30.333;52.416 1005 | Гомельская;Речицкий;Переволока;30.216;52.216 1006 | Гомельская;Речицкий;Придне;30.933;52.16 1007 | Гомельская;Речицкий;Радин;30.83;51.583 1008 | Гомельская;Речицкий;Речица;30.416;52.366 1009 | Гомельская;Речицкий;Ровенская Слобода;30.316;52.233 1010 | Гомельская;Речицкий;Сологубов;27.916;51.766 1011 | Гомельская;Речицкий;Солтаново;30.233;52.35 1012 | Гомельская;Речицкий;Старые Храковичи;30.45;51.666 1013 | Гомельская;Речицкий;Струмень;30.916;53.166 1014 | Гомельская;Речицкий;Узнож;29.983;52.483 1015 | Гомельская;Речицкий;Ходосовичи;30.116;53.33 1016 | Гомельская;Речицкий;Холмеч;30.633;52.15 1017 | Гомельская;Речицкий;Черное;30.366;52.466 1018 | Гомельская;Речицкий;Чижовка;30.616;52.383 1019 | Гомельская;Рогачевский;Белицк;30.45;52.916 1020 | Гомельская;Рогачевский;Гадиловичи;30.266;53.83 1021 | Гомельская;Рогачевский;Городец;30.333;52.966 1022 | Гомельская;Рогачевский;Довск;30.466;53.166 1023 | Гомельская;Рогачевский;Журавичи;30.55;53.25 1024 | Гомельская;Рогачевский;Заполье;29.95;53.116 1025 | Гомельская;Рогачевский;Звонец;30.433;53.25 1026 | Гомельская;Рогачевский;Кистени;30.233;53.166 1027 | Гомельская;Рогачевский;Красница;30.366;53.5 1028 | Гомельская;Рогачевский;Кривск;30.516;52.583 1029 | Гомельская;Рогачевский;Лучин;30.16;53.16 1030 | Гомельская;Рогачевский;Мадора;30.183;53.15 1031 | Гомельская;Рогачевский;Новый Кривск;30.533;53.83 1032 | Гомельская;Рогачевский;Озераны;29.916;53.25 1033 | Гомельская;Рогачевский;Поболово;29.783;53.16 1034 | Гомельская;Рогачевский;Рогачев;30.5;53.83 1035 | Гомельская;Рогачевский;Серебрянка;30.383;53.116 1036 | Гомельская;Рогачевский;Станьков;30.66;53.216 1037 | Гомельская;Рогачевский;Стреньки;29.95;53.66 1038 | Гомельская;Рогачевский;Тихиничи;29.85;53.15 1039 | Гомельская;Рогачевский;Турск;30.216;53.5 1040 | Гомельская;Рогачевский;Хатовня;30.533;53.283 1041 | Гомельская;Рогачевский;Шапчицы;30.35;53.233 1042 | Гомельская;Светлогорский;Боровики;29.85;52.55 1043 | Гомельская;Светлогорский;Здудичи;29.583;52.733 1044 | Гомельская;Светлогорский;Корени;29.433;52.45 1045 | Гомельская;Светлогорский;Осташковичи;29.6;52.45 1046 | Гомельская;Светлогорский;Паричи;29.416;52.8 1047 | Гомельская;Светлогорский;Светлогорск;29.7;52.633 1048 | Гомельская;Светлогорский;Сосновый Бор;29.6;52.516 1049 | Гомельская;Светлогорский;Хлевно;30.916;53.283 1050 | Гомельская;Светлогорский;Хутор;29.75;52.5 1051 | Гомельская;Светлогорский;Челюшевичи;28.75;52.35 1052 | Гомельская;Светлогорский;Чирковичи;29.65;52.666 1053 | Гомельская;Хойникский;Велетин;30.1;51.866 1054 | Гомельская;Хойникский;Великий Бор;29.933;52.33 1055 | Гомельская;Хойникский;Дворище;29.55;52.833 1056 | Гомельская;Хойникский;Дроньки;29.866;51.65 1057 | Гомельская;Хойникский;Ломачи;29.716;51.733 1058 | Гомельская;Хойникский;Омельковщина;30.2;52.33 1059 | Гомельская;Хойникский;Рудаков;30.5;51.816 1060 | Гомельская;Хойникский;Стреличево;29.883;51.816 1061 | Гомельская;Хойникский;Хойники;29.933;51.883 1062 | Гомельская;Чечерский;Беляевка;31.16;52.966 1063 | Гомельская;Чечерский;Ленин;27.5;52.333 1064 | Гомельская;Чечерский;Ленино;31.683;52.183 1065 | Гомельская;Чечерский;Меркуловичи;30.6;52.983 1066 | Гомельская;Чечерский;Покоть;31.116;52.866 1067 | Гомельская;Чечерский;Ровковичи;30.766;52.85 1068 | Гомельская;Чечерский;Сидоровичи;31.15;53.33 1069 | Гомельская;Чечерский;Чечерск;30.916;52.916 1070 | Гродненская;Берестовицкий;Берестовица;23.966;53.116 1071 | Гродненская;Берестовицкий;Большие Эйсмонты;24.83;53.366 1072 | Гродненская;Берестовицкий;Дворец;25.566;53.4 1073 | Гродненская;Берестовицкий;Малая Берестовица;23.933;53.3 1074 | Гродненская;Берестовицкий;Олекшицы;23.933;53.333 1075 | Гродненская;Берестовицкий;Сенкенята;25.883;54.2 1076 | Гродненская;Волковысский;Большие Шиловичи;25.4;53.33 1077 | Гродненская;Волковысский;Верейки;24.2;53.25 1078 | Гродненская;Волковысский;Верхненеманская;25.316;53.65 1079 | Гродненская;Волковысский;Войтковичи;24.6;53.166 1080 | Гродненская;Волковысский;Волковыск;24.45;53.166 1081 | Гродненская;Волковысский;Волковысская;24.33;53.233 1082 | Гродненская;Волковысский;Волпа;24.366;53.366 1083 | Гродненская;Волковысский;Духовляны;24.166;53.316 1084 | Гродненская;Волковысский;Зарудовье;24.516;53.333 1085 | Гродненская;Волковысский;Збляны;25.25;53.616 1086 | Гродненская;Волковысский;Мстибово;24.266;53.116 1087 | Гродненская;Волковысский;Подороск;24.616;52.983 1088 | Гродненская;Волковысский;Россь;24.4;53.283 1089 | Гродненская;Волковысский;Салтанишки;24.85;54.16 1090 | Гродненская;Волковысский;Сырмеж;26.6;54.783 1091 | Гродненская;Волковысский;Хатьковцы;24.383;53.66 1092 | Гродненская;Волковысский;Чапунь;26.66;53.85 1093 | Гродненская;Волковысский;Шиловичи;24.25;53.166 1094 | Гродненская;Вороновский;Бастуны;25.3;54.83 1095 | Гродненская;Вороновский;Бенякони;25.35;54.25 1096 | Гродненская;Вороновский;Вороново;25.316;54.15 1097 | Гродненская;Вороновский;Жирмуны;25.216;54.16 1098 | Гродненская;Вороновский;Заболоть;24.8;53.916 1099 | Гродненская;Вороновский;Конвелишки;25.466;54.233 1100 | Гродненская;Вороновский;Нача;24.85;54.66 1101 | Гродненская;Вороновский;Погородно;25.183;54.1 1102 | Гродненская;Вороновский;Полецкишки;25.183;54.183 1103 | Гродненская;Вороновский;Трокели;25.416;54.33 1104 | Гродненская;Гродненский;Богушевка;23.933;53.766 1105 | Гродненская;Гродненский;Большая Берестовица;24.16;53.183 1106 | Гродненская;Гродненский;Вертилишки;24.16;53.7 1107 | Гродненская;Гродненский;Глушнево;24.233;53.883 1108 | Гродненская;Гродненский;Гожа;23.85;53.816 1109 | Гродненская;Гродненский;Головачи;24.266;53.633 1110 | Гродненская;Гродненский;Грандичи;23.816;53.733 1111 | Гродненская;Гродненский;Гродно;24.5;53.6 1112 | Гродненская;Гродненский;Деревня;25.466;53.2 1113 | Гродненская;Гродненский;Житомля;24.116;53.633 1114 | Гродненская;Гродненский;Заберезь;26.2;53.933 1115 | Гродненская;Гродненский;Заполье;24.466;53.45 1116 | Гродненская;Гродненский;Индура;23.866;53.45 1117 | Гродненская;Гродненский;Калеты;23.566;53.916 1118 | Гродненская;Гродненский;Коптевка;23.866;53.566 1119 | Гродненская;Гродненский;Королино;23.7;53.633 1120 | Гродненская;Гродненский;Лаздуны;25.966;53.966 1121 | Гродненская;Гродненский;Новая Руда;24.25;53.816 1122 | Гродненская;Гродненский;Новики;26.83;54.533 1123 | Гродненская;Гродненский;Одельск;23.75;53.4 1124 | Гродненская;Гродненский;Озеры;24.183;53.716 1125 | Гродненская;Гродненский;Поречаны;25.15;53.783 1126 | Гродненская;Гродненский;Ратичи;23.65;53.766 1127 | Гродненская;Гродненский;Рудевичи;24.733;53.33 1128 | Гродненская;Гродненский;Рудня;24.66;52.85 1129 | Гродненская;Гродненский;Рыбница;24.33;53.816 1130 | Гродненская;Гродненский;Скидель;24.25;53.583 1131 | Гродненская;Гродненский;Скирдимы;26.133;54.366 1132 | Гродненская;Гродненский;Соничи;23.666;53.866 1133 | Гродненская;Гродненский;Сопоцкин;23.65;53.833 1134 | Гродненская;Гродненский;Стриевка;24.15;53.733 1135 | Гродненская;Гродненский;Суботники;25.75;54.1 1136 | Гродненская;Гродненский;Сухари;24.383;53.766 1137 | Гродненская;Гродненский;Суходолы;25.9;54.5 1138 | Гродненская;Гродненский;Шинковцы;24.583;53.683 1139 | Гродненская;Гродненский;Щенец;24.416;53.7 1140 | Гродненская;Дятловский;Вензовец;25.333;53.416 1141 | Гродненская;Дятловский;Демяновцы;25.1;53.516 1142 | Гродненская;Дятловский;Дятлово;25.4;53.466 1143 | Гродненская;Дятловский;Козловщина;25.3;53.316 1144 | Гродненская;Дятловский;Липичанка;24.966;53.55 1145 | Гродненская;Дятловский;Медвиновичи;25.3;53.383 1146 | Гродненская;Дятловский;Мир;26.45;53.45 1147 | Гродненская;Дятловский;Новоельня;25.583;53.466 1148 | Гродненская;Дятловский;Охоново;25.533;53.55 1149 | Гродненская;Дятловский;Подвеликое;25.15;53.3 1150 | Гродненская;Дятловский;Руда Яворская;25.116;53.4 1151 | Гродненская;Дятловский;Сочевляны;25.4;53.366 1152 | Гродненская;Зельвенский;Бородичи;24.766;53.15 1153 | Гродненская;Зельвенский;Деречин;24.916;53.25 1154 | Гродненская;Зельвенский;Зельва;24.816;53.15 1155 | Гродненская;Зельвенский;Золотеево;24.816;53.233 1156 | Гродненская;Зельвенский;Кривичи;25.7;53.85 1157 | Гродненская;Ивьевский;Геранены;25.583;54.116 1158 | Гродненская;Ивьевский;Ивье;25.766;53.933 1159 | Гродненская;Ивьевский;Каменчане;25.683;54.33 1160 | Гродненская;Ивьевский;Липнишки;25.6;54.16 1161 | Гродненская;Ивьевский;Малые Князиковцы;25.566;53.95 1162 | Гродненская;Ивьевский;Морино;25.683;53.866 1163 | Гродненская;Ивьевский;Токаришки;26.33;54.33 1164 | Гродненская;Ивьевский;Трабы;25.9;54.15 1165 | Гродненская;Ивьевский;Юратишки;25.933;54.16 1166 | Гродненская;Кореличский;Большие Жуховичи;26.3;53.416 1167 | Гродненская;Кореличский;Кореличи;26.133;53.566 1168 | Гродненская;Кореличский;Луки;26.233;53.483 1169 | Гродненская;Кореличский;Малюшичи;26.66;53.483 1170 | Гродненская;Кореличский;Миратичи;25.933;53.45 1171 | Гродненская;Кореличский;Турец;26.3;53.533 1172 | Гродненская;Кореличский;Цирин;26.166;53.4 1173 | Гродненская;Лидский;Бабиничи;25.233;53.183 1174 | Гродненская;Лидский;Березовка;25.483;53.716 1175 | Гродненская;Лидский;Ваверка;24.966;53.833 1176 | Гродненская;Лидский;Гончары;25.416;53.733 1177 | Гродненская;Лидский;Докудово;25.5;53.783 1178 | Гродненская;Лидский;Игнатковцы;25.66;53.716 1179 | Гродненская;Лидский;Крупово;25.183;53.933 1180 | Гродненская;Лидский;Лида;25.316;53.85 1181 | Гродненская;Лидский;Лунно;24.266;53.45 1182 | Гродненская;Лидский;Минойты;25.366;53.8 1183 | Гродненская;Лидский;Мотевичи;25.116;53.55 1184 | Гродненская;Лидский;Нетечь;25.233;53.7 1185 | Гродненская;Лидский;Паперня;24.983;53.783 1186 | Гродненская;Лидский;Первомайский;25.383;53.883 1187 | Гродненская;Лидский;Рулевичи;25.33;53.866 1188 | Гродненская;Лидский;Селец;25.416;53.666 1189 | Гродненская;Лидский;Симаково;26.483;53.4 1190 | Гродненская;Лидский;Соколово;25.2;53.5 1191 | Гродненская;Лидский;Стерково;25.466;53.9 1192 | Гродненская;Лидский;Ходоровцы;25.66;53.65 1193 | Гродненская;Мостовский;Барово;25.95;53.833 1194 | Гродненская;Мостовский;Бондари;24.3;53.666 1195 | Гродненская;Мостовский;Дубно;24.383;53.433 1196 | Гродненская;Мостовский;Куриловичи;24.883;53.35 1197 | Гродненская;Мостовский;Микелевщина;24.666;53.483 1198 | Гродненская;Мостовский;Мосты;24.533;53.416 1199 | Гродненская;Мостовский;Пацевичи;24.683;53.316 1200 | Гродненская;Мостовский;Пески;24.633;53.35 1201 | Гродненская;Мостовский;Погорелка;26.3;53.566 1202 | Гродненская;Мостовский;Рогозница;24.683;53.266 1203 | Гродненская;Мостовский;Сухиничи;24.433;53.483 1204 | Гродненская;Мостовский;Уртишки;25.783;53.983 1205 | Гродненская;Новогрудский;Большая Изва;25.633;53.633 1206 | Гродненская;Новогрудский;Валевка;25.883;53.466 1207 | Гродненская;Новогрудский;Вересково;25.9;53.766 1208 | Гродненская;Новогрудский;Вселюб;25.8;53.716 1209 | Гродненская;Новогрудский;Гнесичи;26.166;53.7 1210 | Гродненская;Новогрудский;Делятичи;25.966;53.783 1211 | Гродненская;Новогрудский;Ивесь;25.533;53.35 1212 | Гродненская;Новогрудский;Каменка;24.516;53.55 1213 | Гродненская;Новогрудский;Куписк;26.133;53.733 1214 | Гродненская;Новогрудский;Любча;26.5;53.75 1215 | Гродненская;Новогрудский;Негневичи;26.66;53.65 1216 | Гродненская;Новогрудский;Несутичи;25.95;53.65 1217 | Гродненская;Новогрудский;Новогрудок;25.833;53.6 1218 | Гродненская;Новогрудский;Отминово;25.7;53.8 1219 | Гродненская;Новогрудский;Сенежицы;25.95;53.55 1220 | Гродненская;Новогрудский;Щорсы;26.166;53.65 1221 | Гродненская;Островецкий;Быстрица;25.883;54.8 1222 | Гродненская;Островецкий;Ворняны;26.16;54.716 1223 | Гродненская;Островецкий;Гервяты;26.15;54.683 1224 | Гродненская;Островецкий;Гири;26.2;54.633 1225 | Гродненская;Островецкий;Гудогай;25.9;54.6 1226 | Гродненская;Островецкий;Древеники;25.833;54.65 1227 | Гродненская;Островецкий;Изабелин;24.55;53.1 1228 | Гродненская;Островецкий;Кемелишки;25.883;54.85 1229 | Гродненская;Островецкий;Клющаны;26.15;54.966 1230 | Гродненская;Островецкий;Мали;26;54.65 1231 | Гродненская;Островецкий;Маркуны;26.183;54.783 1232 | Гродненская;Островецкий;Михалишки;26.166;54.816 1233 | Гродненская;Островецкий;Островец;25.95;54.616 1234 | Гродненская;Островецкий;Рымдюны;26.216;54.666 1235 | Гродненская;Островецкий;Супроненты;26.316;54.8 1236 | Гродненская;Ошмянский;Боруны;26.133;54.316 1237 | Гродненская;Ошмянский;Гольшаны;26.16;54.266 1238 | Гродненская;Ошмянский;Жупраны;26.83;54.466 1239 | Гродненская;Ошмянский;Клевица;25.733;54.283 1240 | Гродненская;Ошмянский;Муровано-Ошмянка;25.783;54.466 1241 | Гродненская;Ошмянский;Новоселки;26.66;54.4 1242 | Гродненская;Ошмянский;Ошмянская;26.366;54.35 1243 | Гродненская;Ошмянский;Ошмяны;25.933;54.416 1244 | Гродненская;Ошмянский;Песчанка;24.933;53.383 1245 | Гродненская;Ошмянский;Привалка;23.916;53.95 1246 | Гродненская;Свислочский;Вердомичи;24.283;53.33 1247 | Гродненская;Свислочский;Горностаевичи;24.4;52.983 1248 | Гродненская;Свислочский;Гринки;24.116;52.95 1249 | Гродненская;Свислочский;Дашковичи;24.533;52.95 1250 | Гродненская;Свислочский;Доброволя;24.33;52.916 1251 | Гродненская;Свислочский;Новый Двор;24.35;52.833 1252 | Гродненская;Свислочский;Порозово;24.35;52.933 1253 | Гродненская;Свислочский;Свислочь;24.1;53.33 1254 | Гродненская;Свислочский;Студеники;24.3;52.9 1255 | Гродненская;Свислочский;Тиховоля;23.983;52.85 1256 | Гродненская;Свислочский;Хоневичи;24.366;53.533 1257 | Гродненская;Слонимский;Аталезь;26.6;53.566 1258 | Гродненская;Слонимский;Гловсевичи;25.266;52.983 1259 | Гродненская;Слонимский;Дубники;25.933;54.716 1260 | Гродненская;Слонимский;Жировицы;25.333;53.16 1261 | Гродненская;Слонимский;Залужье;26.6;53.433 1262 | Гродненская;Слонимский;Каменица;24.5;53.16 1263 | Гродненская;Слонимский;Колпаки;23.933;53.566 1264 | Гродненская;Слонимский;Костенево;24.816;53.716 1265 | Гродненская;Слонимский;Костени;25.2;53.66 1266 | Гродненская;Слонимский;Кули;23.9;53.2 1267 | Гродненская;Слонимский;Лепешки;25.916;54.66 1268 | Гродненская;Слонимский;Мижевичи;25.83;52.983 1269 | Гродненская;Слонимский;Михайловщина;26;54.166 1270 | Гродненская;Слонимский;Нагуевичи;25.466;53.133 1271 | Гродненская;Слонимский;Нестанишки;26.333;54.75 1272 | Гродненская;Слонимский;Ногородовичи;25.366;53.583 1273 | Гродненская;Слонимский;Озерница;25.16;53.66 1274 | Гродненская;Слонимский;Осташино;26;53.7 1275 | Гродненская;Слонимский;Острово;25.33;53.25 1276 | Гродненская;Слонимский;Павлово;25.283;53.266 1277 | Гродненская;Слонимский;Пелеса;24.966;53.95 1278 | Гродненская;Слонимский;Поречье;24.133;53.883 1279 | Гродненская;Слонимский;Самаровичи;24.75;53.216 1280 | Гродненская;Слонимский;Слоним;25.316;53.1 1281 | Гродненская;Слонимский;Сосновка;25.1;52.883 1282 | Гродненская;Слонимский;Старая Голынка;25.33;53.216 1283 | Гродненская;Слонимский;Струга;24.25;53.4 1284 | Гродненская;Слонимский;Сухая Долина;24.16;53.466 1285 | Гродненская;Слонимский;Ярутичи;25.116;52.916 1286 | Гродненская;Сморгоньский;Вишнево;26.516;54.7 1287 | Гродненская;Сморгоньский;Войстом;26.616;54.583 1288 | Гродненская;Сморгоньский;Жодишки;26.45;54.616 1289 | Гродненская;Сморгоньский;Залесье;26.533;54.416 1290 | Гродненская;Сморгоньский;Крево;26.3;54.316 1291 | Гродненская;Сморгоньский;Мицкевичи;26.6;54.483 1292 | Гродненская;Сморгоньский;Сивица;26.5;54.366 1293 | Гродненская;Сморгоньский;Сморгонь;26.4;54.483 1294 | Гродненская;Сморгоньский;Солы;26.183;54.516 1295 | Гродненская;Сморгоньский;Старая-Руда;24.166;53.85 1296 | Гродненская;Сморгоньский;Шутовичи;26.433;54.433 1297 | Гродненская;Щучинский;Бакшты;24.7;53.8 1298 | Гродненская;Щучинский;Бершты;24.383;53.85 1299 | Гродненская;Щучинский;Василишки;24.85;53.783 1300 | Гродненская;Щучинский;Демброво;24.483;53.633 1301 | Гродненская;Щучинский;Желудок;24.983;53.6 1302 | Гродненская;Щучинский;Малые Озерки;24.916;53.316 1303 | Гродненская;Щучинский;Мотыли;24.633;53.933 1304 | Гродненская;Щучинский;Орля;24.966;53.516 1305 | Гродненская;Щучинский;Острына;24.533;53.716 1306 | Гродненская;Щучинский;Рожанка;24.733;53.533 1307 | Гродненская;Щучинский;Таневичи;24.616;53.85 1308 | Гродненская;Щучинский;Ходилони;24.716;53.883 1309 | Гродненская;Щучинский;Щучин;24.75;53.6 1310 | Минская;Березинский;Березино;28.983;53.833 1311 | Минская;Березинский;Богушевичи;28.816;53.716 1312 | Минская;Березинский;Бор;28.16;53.516 1313 | Минская;Березинский;Дмитровичи;29.116;53.983 1314 | Минская;Березинский;Макаричи;28.316;52.983 1315 | Минская;Березинский;Маковье;28.233;54.583 1316 | Минская;Березинский;Маческ;29.316;53.816 1317 | Минская;Березинский;Микуличи;28.8;53.833 1318 | Минская;Березинский;Орешковичи;28.966;54.16 1319 | Минская;Березинский;Палик;28.45;54.516 1320 | Минская;Березинский;Погост;29.15;53.85 1321 | Минская;Березинский;Поплавы;28.866;53.816 1322 | Минская;Березинский;Притерпа;28.95;53.533 1323 | Минская;Березинский;Целевичи;27.383;52.95 1324 | Минская;Березинский;Шеверничи;29.5;53.95 1325 | Минская;Березинский;Якшицы;28.9;53.616 1326 | Минская;Борисовский;Барань;28.666;54.5 1327 | Минская;Борисовский;Бобровичи;26.583;54.5 1328 | Минская;Борисовский;Большое Стахово;28.383;54.266 1329 | Минская;Борисовский;Борисов;28.516;54.216 1330 | Минская;Борисовский;Бродовка;28.583;54.416 1331 | Минская;Борисовский;Бытча;28.4;54.316 1332 | Минская;Борисовский;Велятичи;28.916;54.166 1333 | Минская;Борисовский;Гливин;28.6;54.166 1334 | Минская;Борисовский;Житьково;28.566;54.333 1335 | Минская;Борисовский;Жортай;28.566;54.566 1336 | Минская;Борисовский;Забашевичи;28.616;54.5 1337 | Минская;Борисовский;Зачистье;28.75;54.4 1338 | Минская;Борисовский;Зембин;28.216;54.366 1339 | Минская;Борисовский;Зоричи;28.883;54.216 1340 | Минская;Борисовский;Корсаковичи;28.283;54.466 1341 | Минская;Борисовский;Кострица;28.616;54.35 1342 | Минская;Борисовский;Лошница;28.766;54.283 1343 | Минская;Борисовский;Моисеевщина;28.7;54.566 1344 | Минская;Борисовский;Мстиж;28.2;54.566 1345 | Минская;Борисовский;Неман;26.983;53.416 1346 | Минская;Борисовский;Нивки;27.116;54.65 1347 | Минская;Борисовский;Оздятичи;28.833;54.1 1348 | Минская;Борисовский;Пересады;28.416;54.133 1349 | Минская;Борисовский;Сутоки;28.66;54.2 1350 | Минская;Борисовский;Трояновка;28.8;54.55 1351 | Минская;Борисовский;Трояново;26.933;53.2 1352 | Минская;Борисовский;Черневичи;28.766;54.33 1353 | Минская;Вилейский;Баровцы;26.783;54.516 1354 | Минская;Вилейский;Бубны;27.566;54.75 1355 | Минская;Вилейский;Вилейка;26.9;54.483 1356 | Минская;Вилейский;Вязынь;27.166;54.416 1357 | Минская;Вилейский;Долгиново;27.483;54.65 1358 | Минская;Вилейский;Ижа;26.766;54.666 1359 | Минская;Вилейский;Илья;27.283;54.416 1360 | Минская;Вилейский;Костеневичи;27.216;54.583 1361 | Минская;Вилейский;Латыголь;27.15;54.366 1362 | Минская;Вилейский;Лыцевичи;26.633;54.716 1363 | Минская;Вилейский;Мильча;27.633;54.683 1364 | Минская;Вилейский;Осиповичи;26.85;54.45 1365 | Минская;Вилейский;Партизанский;27.333;54.366 1366 | Минская;Вилейский;Рабунь;27.15;54.5 1367 | Минская;Вилейский;Русское Село;26.683;54.533 1368 | Минская;Вилейский;Ручица;26.666;54.466 1369 | Минская;Вилейский;Стешицы;27.4;54.583 1370 | Минская;Вилейский;Талуть;26.933;54.683 1371 | Минская;Вилейский;Язни;27.35;54.683 1372 | Минская;Воложинский;Вишнево;26.233;54.133 1373 | Минская;Воложинский;Воложин;26.533;54.83 1374 | Минская;Воложинский;Городьки;26.433;54.216 1375 | Минская;Воложинский;Доры;26.766;54.66 1376 | Минская;Воложинский;Ивенец;26.75;53.883 1377 | Минская;Воложинский;Камень;26.666;53.866 1378 | Минская;Воложинский;Лоск;26.45;54.266 1379 | Минская;Воложинский;Раков;27.5;53.966 1380 | Минская;Воложинский;Саковщина;26.366;54.116 1381 | Минская;Воложинский;Турец-Бояры;26.666;54.383 1382 | Минская;Воложинский;Яршевичи;26.9;54.33 1383 | Минская;Дзержинский;Александровка;28.316;53.83 1384 | Минская;Дзержинский;Александрово;27.583;53.783 1385 | Минская;Дзержинский;Большие Бесяды;27.566;54.233 1386 | Минская;Дзержинский;Большое Быково;27.6;52.883 1387 | Минская;Дзержинский;Боровое;27.16;53.683 1388 | Минская;Дзержинский;Волма;26.966;53.866 1389 | Минская;Дзержинский;Восточный;27.716;53.95 1390 | Минская;Дзержинский;Горелый Луг;28.183;54.5 1391 | Минская;Дзержинский;Горное;27.733;54.6 1392 | Минская;Дзержинский;Гриневичи;27.533;54.516 1393 | Минская;Дзержинский;Даниловичи;27.366;53.6 1394 | Минская;Дзержинский;Дзержинск;27.133;53.683 1395 | Минская;Дзержинский;Добринево;27.366;53.633 1396 | Минская;Дзержинский;Дулебы;29.333;53.75 1397 | Минская;Дзержинский;Душково;27.16;53.933 1398 | Минская;Дзержинский;Жерновка;28.983;53.883 1399 | Минская;Дзержинский;Заостровичи;26.783;52.9 1400 | Минская;Дзержинский;Иваничи;28.333;53.666 1401 | Минская;Дзержинский;Каменка;27.166;53.5 1402 | Минская;Дзержинский;Кимия;28.25;54.4 1403 | Минская;Дзержинский;Кишина-Слобода;28.466;54.383 1404 | Минская;Дзержинский;Колки;26.916;52.833 1405 | Минская;Дзержинский;Корма;27.483;53.583 1406 | Минская;Дзержинский;Кременец;27.5;54.366 1407 | Минская;Дзержинский;Кристинполье;27.733;53.55 1408 | Минская;Дзержинский;Кузмичи;28.83;52.583 1409 | Минская;Дзержинский;Лостоянцы;26.283;54.2 1410 | Минская;Дзержинский;Лужаны;26.683;54.15 1411 | Минская;Дзержинский;Лютые;29.283;54.483 1412 | Минская;Дзержинский;Мардасы;27.433;54.333 1413 | Минская;Дзержинский;Машуки;26.516;52.883 1414 | Минская;Дзержинский;Мгле;28.66;54.133 1415 | Минская;Дзержинский;Мощница;27.15;53.766 1416 | Минская;Дзержинский;Негорелое;27.66;53.616 1417 | Минская;Дзержинский;Недаль;28.183;54.633 1418 | Минская;Дзержинский;Новая Дуброва;27.8;52.683 1419 | Минская;Дзержинский;Новое Село;26.533;53.35 1420 | Минская;Дзержинский;Озерцы;27.466;53.35 1421 | Минская;Дзержинский;Погодица;28.65;54.316 1422 | Минская;Дзержинский;Погост 2-Й;27.616;52.85 1423 | Минская;Дзержинский;Поречье;27.933;53.316 1424 | Минская;Дзержинский;Правда;28.4;53.816 1425 | Минская;Дзержинский;Прощицы;27.65;53.66 1426 | Минская;Дзержинский;Прудины;29.316;54.433 1427 | Минская;Дзержинский;Путчино;27.33;53.8 1428 | Минская;Дзержинский;Радица;28.983;54.35 1429 | Минская;Дзержинский;Речки;27.1;54.583 1430 | Минская;Дзержинский;Рубилки;27.4;53.683 1431 | Минская;Дзержинский;Руденка;29.15;53.75 1432 | Минская;Дзержинский;Рум;26.383;54.16 1433 | Минская;Дзержинский;Синча;28.66;53.433 1434 | Минская;Дзержинский;Станьково;27.216;53.633 1435 | Минская;Дзержинский;Старинки;27.316;54.5 1436 | Минская;Дзержинский;Фаниполь;27.333;53.75 1437 | Минская;Дзержинский;Хорошее;27.8;54.566 1438 | Минская;Дзержинский;Щемыслица;27.466;53.816 1439 | Минская;Дзержинский;Юшковичи;26.95;54.95 1440 | Минская;Дзержинский;Язовка;28.516;53.666 1441 | Минская;Дзержинский;Ясковичи;27.5;52.583 1442 | Минская;Клецкий;Грицевичи;26.716;52.983 1443 | Минская;Клецкий;Клецк;26.633;53.66 1444 | Минская;Клецкий;Морочь;26.866;52.883 1445 | Минская;Клецкий;Синявка;26.466;52.966 1446 | Минская;Копыльский;Блевчицы;27.5;53.16 1447 | Минская;Копыльский;Букатово;26.216;54.1 1448 | Минская;Копыльский;Бучатино;27.83;52.916 1449 | Минская;Копыльский;Ванелевичи;27.15;53.1 1450 | Минская;Копыльский;Веснино;27.683;54.15 1451 | Минская;Копыльский;Докторовичи;27.2;53.1 1452 | Минская;Копыльский;Душево;26.983;53.2 1453 | Минская;Копыльский;Колодезное;26.933;53.133 1454 | Минская;Копыльский;Копыль;27.83;53.15 1455 | Минская;Копыльский;Лотвины;26.983;53.283 1456 | Минская;Копыльский;Низковичи;27.33;53.2 1457 | Минская;Копыльский;Песочное;27.1;53.333 1458 | Минская;Копыльский;Прончейково;26.833;54.133 1459 | Минская;Копыльский;Семежево;27.16;52.95 1460 | Минская;Копыльский;Слобода-Кучинка;27.183;53.25 1461 | Минская;Копыльский;Старица;27.266;53.233 1462 | Минская;Копыльский;Тимковичи;26.983;53.66 1463 | Минская;Крупский;Белавичи;29.183;54.5 1464 | Минская;Крупский;Бобр;29.266;54.333 1465 | Минская;Крупский;Буда-Гресская;27.533;53.266 1466 | Минская;Крупский;Выдрица;29.5;54.183 1467 | Минская;Крупский;Глебовщина;28;54.516 1468 | Минская;Крупский;Грозово;27.333;53.166 1469 | Минская;Крупский;Дедиловичи;28.1;54.583 1470 | Минская;Крупский;Есьмановцы;26.9;54.66 1471 | Минская;Крупский;Жилин-Брод;27.766;53.216 1472 | Минская;Крупский;Журавок;29.483;53.8 1473 | Минская;Крупский;Журовка;29.66;53.9 1474 | Минская;Крупский;Игрушка;29.5;54.4 1475 | Минская;Крупский;Колодница;29.2;54.55 1476 | Минская;Крупский;Коптевщина;26.466;53.316 1477 | Минская;Крупский;Косеничи;29.45;54.6 1478 | Минская;Крупский;Костеши;27.5;53.35 1479 | Минская;Крупский;Крупки;29.133;54.316 1480 | Минская;Крупский;Крупский;29.66;54.316 1481 | Минская;Крупский;Курдуны;26.8;53.933 1482 | Минская;Крупский;Лисичино;29.33;54.583 1483 | Минская;Крупский;Малые Негновичи;28.783;54.233 1484 | Минская;Крупский;Матеевичи;28.2;53.366 1485 | Минская;Крупский;Мирославка;28.966;53.65 1486 | Минская;Крупский;Нача;28.966;54.283 1487 | Минская;Крупский;Обчуга;29.35;54.5 1488 | Минская;Крупский;Очижа;28.516;53.616 1489 | Минская;Крупский;Перетоки;26.65;53.466 1490 | Минская;Крупский;Потичево;28.466;53.933 1491 | Минская;Крупский;Птичанская;27.85;53.466 1492 | Минская;Крупский;Рованичская Слобода;28.566;53.916 1493 | Минская;Крупский;Соколовичи;29.3;54.283 1494 | Минская;Крупский;Старая Слобода;29.316;54.116 1495 | Минская;Крупский;Тройчаны;28.35;52.766 1496 | Минская;Крупский;Узнацк;28.983;54.466 1497 | Минская;Крупский;Ухвала;29.216;54.1 1498 | Минская;Крупский;Хидра;28.366;53.516 1499 | Минская;Крупский;Холопеничи;28.95;54.516 1500 | Минская;Крупский;Хотово;26.633;53.766 1501 | Минская;Крупский;Хотюхово;28.883;54.433 1502 | Минская;Крупский;Худовцы;29.183;54.383 1503 | Минская;Крупский;Черногрядь;28.233;53.783 1504 | Минская;Крупский;Чертовичи;26.433;54.66 1505 | Минская;Крупский;Шинки;29.316;54.2 1506 | Минская;Крупский;Яченка;27.5;53.566 1507 | Минская;Логойский;Березенское;26.616;54.233 1508 | Минская;Логойский;Гайна;27.7;54.25 1509 | Минская;Логойский;Гостиловичи;27.9;54.216 1510 | Минская;Логойский;Знаменка;27.933;54.15 1511 | Минская;Логойский;Козеково;27.433;54.116 1512 | Минская;Логойский;Корень;27.716;54.35 1513 | Минская;Логойский;Королищевичи;27.683;53.8 1514 | Минская;Логойский;Логойск;27.816;54.2 1515 | Минская;Логойский;Малые Гаяны;27.6;54.166 1516 | Минская;Логойский;Новопольцы;26.683;53.35 1517 | Минская;Логойский;Паперня;27.566;54.33 1518 | Минская;Логойский;Плещеницы;27.833;54.416 1519 | Минская;Логойский;Савони;26.65;53.4 1520 | Минская;Логойский;Семково;27.433;54.16 1521 | Минская;Логойский;Янушковичи;27.6;54.283 1522 | Минская;Любаньский;Дарасино;27.783;52.9 1523 | Минская;Любаньский;Доматкановичи;26.55;53.116 1524 | Минская;Любаньский;Заболоть;27.883;52.8 1525 | Минская;Любаньский;Закальное;27.8;52.766 1526 | Минская;Любаньский;Калиновка;28.233;52.583 1527 | Минская;Любаньский;Костюки;28.316;54.35 1528 | Минская;Любаньский;Любань;28;52.8 1529 | Минская;Любаньский;Ляховка;28.283;54.3 1530 | Минская;Любаньский;Нежин;28.166;52.633 1531 | Минская;Любаньский;Осовец;28.183;52.85 1532 | Минская;Любаньский;Пласток;28.15;52.8 1533 | Минская;Любаньский;Сосны;27.983;52.583 1534 | Минская;Любаньский;Таль;27.966;52.85 1535 | Минская;Любаньский;Уречье;27.883;52.933 1536 | Минская;Любаньский;Яминск;28.266;52.766 1537 | Минская;Минский;Белевичи;27.2;52.966 1538 | Минская;Минский;Большая Ганута;28.75;53.7 1539 | Минская;Минский;Большая Раевка;26.883;53.133 1540 | Минская;Минский;Брусы;26.966;54.766 1541 | Минская;Минский;Городище;27.333;53.833 1542 | Минская;Минский;Городок;26.916;54.15 1543 | Минская;Минский;Заславль;27.25;54.16 1544 | Минская;Минский;Колодищи;27.783;53.95 1545 | Минская;Минский;Колядичи;27.566;53.816 1546 | Минская;Минский;Лоша;27.416;53.416 1547 | Минская;Минский;Луговая;27.85;53.783 1548 | Минская;Минский;Любяча;27.55;53.433 1549 | Минская;Минский;Мервины;26.716;52.95 1550 | Минская;Минский;Минск;27.633;53.933 1551 | Минская;Минский;Михановичи;27.683;53.75 1552 | Минская;Минский;Мокрица;26.716;54.8 1553 | Минская;Минский;Низок;27.15;53.4 1554 | Минская;Минский;Новая Нива;28.666;53.733 1555 | Минская;Минский;Новые Денисовичи;29.233;54.2 1556 | Минская;Минский;Озерцо;27.4;53.833 1557 | Минская;Минский;Острошицкий Городок;27.7;54.66 1558 | Минская;Минский;Пережиры;26.966;53.966 1559 | Минская;Минский;Першай;26.683;54.33 1560 | Минская;Минский;Понятичи;27.66;54.416 1561 | Минская;Минский;Прусы;28.383;52.85 1562 | Минская;Минский;Пятевщина;27.516;53.7 1563 | Минская;Минский;Ратомка;27.333;53.933 1564 | Минская;Минский;Рог;27.816;52.483 1565 | Минская;Минский;Рогово;27.3;54.133 1566 | Минская;Минский;Рымаши;26.9;53.266 1567 | Минская;Минский;Самохваловичи;27.516;53.733 1568 | Минская;Минский;Слобода;26.75;54.716 1569 | Минская;Минский;Стайки;27.433;54.466 1570 | Минская;Минский;Старое Село;27.266;53.883 1571 | Минская;Минский;Студенка;28.25;53.966 1572 | Минская;Минский;Тарасово;27.383;53.916 1573 | Минская;Молодеченский;Дуброво;27.1;54.1 1574 | Минская;Молодеченский;Засковичи;26.6;54.4 1575 | Минская;Молодеченский;Красное;27.83;54.25 1576 | Минская;Молодеченский;Лебедево;26.7;54.316 1577 | Минская;Молодеченский;Молодечно;26.816;54.316 1578 | Минская;Молодеченский;Мясота;27.5;54.283 1579 | Минская;Молодеченский;Олехновичи;27.1;54.15 1580 | Минская;Молодеченский;Полочаны;26.7;54.233 1581 | Минская;Молодеченский;Радошковичи;27.233;54.166 1582 | Минская;Молодеченский;Раевка;27.216;54.3 1583 | Минская;Молодеченский;Турец;28.83;53.666 1584 | Минская;Мядельский;Будслав;27.466;54.783 1585 | Минская;Мядельский;Выголовичи;27.66;54.683 1586 | Минская;Мядельский;Константиново;26.466;54.916 1587 | Минская;Мядельский;Лукьяновичи;27.16;54.85 1588 | Минская;Мядельский;Мядель;26.95;54.883 1589 | Минская;Мядельский;Осово;27.216;54.716 1590 | Минская;Мядельский;Пузыри;27.283;54.783 1591 | Минская;Мядельский;Сватки;27.1;54.75 1592 | Минская;Мядельский;Свирь;26.4;54.85 1593 | Минская;Мядельский;Старые Габы;27.266;54.883 1594 | Минская;Мядельский;Черемшицы;26.833;54.783 1595 | Минская;Несвижский;Городея;26.533;53.316 1596 | Минская;Несвижский;Несвиж;26.666;53.216 1597 | Минская;Несвижский;Новоселки;26.883;53.16 1598 | Минская;Несвижский;Погорельцы;26.3;53.2 1599 | Минская;Несвижский;Сейловичи;26.766;53.283 1600 | Минская;Несвижский;Снов;26.4;53.216 1601 | Минская;Несвижский;Хожево;26.833;54.25 1602 | Минская;Пуховичский;Блужа;28.266;53.416 1603 | Минская;Пуховичский;Горелец;27.933;53.433 1604 | Минская;Пуховичский;Дукора;27.966;53.666 1605 | Минская;Пуховичский;Марьина Горка;28.116;53.533 1606 | Минская;Пуховичский;Октябрь;27.266;52.85 1607 | Минская;Пуховичский;Омельно;28.33;53.366 1608 | Минская;Пуховичский;Правдинский;27.816;53.516 1609 | Минская;Пуховичский;Пуховичи;28.25;53.533 1610 | Минская;Пуховичский;Руденск;27.85;53.6 1611 | Минская;Пуховичский;Селецк;27.883;53.266 1612 | Минская;Пуховичский;Сергеевичи;27.766;53.5 1613 | Минская;Пуховичский;Сутин;28.233;53.3 1614 | Минская;Пуховичский;Талька;28.333;53.383 1615 | Минская;Пуховичский;Узляны;27.716;53.616 1616 | Минская;Пуховичский;Цитва;27.866;53.55 1617 | Минская;Пуховичский;Шацк;27.7;53.433 1618 | Минская;Слуцкий;Болотчицы;27.4;52.916 1619 | Минская;Слуцкий;Великая Липа;26.516;53.25 1620 | Минская;Слуцкий;Великая Слива;27.633;52.95 1621 | Минская;Слуцкий;Весея;27.683;53.66 1622 | Минская;Слуцкий;Греск;27.483;53.166 1623 | Минская;Слуцкий;Замостье;27.6;53.2 1624 | Минская;Слуцкий;Козыри;27.85;54.333 1625 | Минская;Слуцкий;Ленино;27.233;53.5 1626 | Минская;Слуцкий;Никольцы;26.866;54.883 1627 | Минская;Слуцкий;Омговичи;27.816;53.1 1628 | Минская;Слуцкий;Рухово;28.3;52.883 1629 | Минская;Слуцкий;Селище;27.4;53 1630 | Минская;Слуцкий;Серяги;27.466;53.66 1631 | Минская;Слуцкий;Слуцк;27.55;53.33 1632 | Минская;Слуцкий;Сороги;27.933;53.33 1633 | Минская;Слуцкий;Шищицы;27.55;53.216 1634 | Минская;Смолевичский;Большой Рожан;27.116;52.766 1635 | Минская;Смолевичский;Верхмень;28.233;53.933 1636 | Минская;Смолевичский;Драчков;28.66;53.816 1637 | Минская;Смолевичский;Драчково;28.83;53.816 1638 | Минская;Смолевичский;Жодино;28.35;54.1 1639 | Минская;Смолевичский;Заболотье;27.266;53.683 1640 | Минская;Смолевичский;Зеленый Бор;28.466;54.16 1641 | Минская;Смолевичский;Пережир;27.766;53.683 1642 | Минская;Смолевичский;Плиса;28.2;54.33 1643 | Минская;Смолевичский;Рудня-Налибокская;26.433;53.85 1644 | Минская;Смолевичский;Смолевичи;28.83;54.33 1645 | Минская;Смолевичский;Уголец;28.3;53.6 1646 | Минская;Смолевичский;Усяжа;27.9;54.1 1647 | Минская;Смолевичский;Юрьево;28.83;54.166 1648 | Минская;Солигорский;Ананчицы;27.65;52.533 1649 | Минская;Солигорский;Большая Гуменовщина;26.683;53.65 1650 | Минская;Солигорский;Большие Городятичи;28.366;52.516 1651 | Минская;Солигорский;Веска;27.266;52.8 1652 | Минская;Солигорский;Вынищи;27.583;53.15 1653 | Минская;Солигорский;Гаврильчицы;27.83;52.633 1654 | Минская;Солигорский;Гоцк;27.15;52.516 1655 | Минская;Солигорский;Зажевичи;27.633;52.783 1656 | Минская;Солигорский;Копацевичи;27.383;52.633 1657 | Минская;Солигорский;Красная Слобода;27.166;52.85 1658 | Минская;Солигорский;Левки;28.5;53.2 1659 | Минская;Солигорский;Малые Нестановичи;27.65;54.45 1660 | Минская;Солигорский;Махновичи;27.633;52.616 1661 | Минская;Солигорский;Саковичи;27.616;54.633 1662 | Минская;Солигорский;Сковшин;27.833;52.533 1663 | Минская;Солигорский;Солигорск;27.533;52.8 1664 | Минская;Солигорский;Старобин;27.466;52.733 1665 | Минская;Солигорский;Челонец;27.3;52.516 1666 | Минская;Солигорский;Чепели;27.483;52.866 1667 | Минская;Солигорский;Шипиловичи;28.16;52.733 1668 | Минская;Стародорожский;Верхутино;28.5;52.966 1669 | Минская;Стародорожский;Залужье;28.166;53.133 1670 | Минская;Стародорожский;Кривоносы;28.4;52.883 1671 | Минская;Стародорожский;Пасека;28.233;52.933 1672 | Минская;Стародорожский;Пастовичи;28.483;53.5 1673 | Минская;Стародорожский;Солон;28.116;53.5 1674 | Минская;Стародорожский;Старые Дороги;28.266;53.33 1675 | Минская;Стародорожский;Теребуты;28.33;53.25 1676 | Минская;Стародорожский;Щитковичи;27.983;53.216 1677 | Минская;Стародорожский;Языль;27.983;52.983 1678 | Минская;Столбцовский;Деревное;26.566;53.7 1679 | Минская;Столбцовский;Засулье;26.833;53.566 1680 | Минская;Столбцовский;Клетище;26.35;53.816 1681 | Минская;Столбцовский;Литва;26.8;53.766 1682 | Минская;Столбцовский;Налибоки;26.466;53.766 1683 | Минская;Столбцовский;Николаевщина;26.833;53.4 1684 | Минская;Столбцовский;Опечки;26.666;53.533 1685 | Минская;Столбцовский;Пруды;26.516;53.783 1686 | Минская;Столбцовский;Рубежевичи;26.866;53.683 1687 | Минская;Столбцовский;Столбцы;26.733;53.483 1688 | Минская;Столбцовский;Тоново;26.766;53.716 1689 | Минская;Узденский;Зеньковичи;27.25;53.5 1690 | Минская;Узденский;Озеро;27.45;53.633 1691 | Минская;Узденский;Теляково;27.4;53.516 1692 | Минская;Узденский;Узда;27.216;53.45 1693 | Минская;Червеньский;Гребенка;28.233;53.833 1694 | Минская;Червеньский;Заполье;27.983;53.766 1695 | Минская;Червеньский;Клинок;28.183;53.666 1696 | Минская;Червеньский;Ляды;28.7;53.616 1697 | Минская;Червеньский;Рованичи;28.6;53.866 1698 | Минская;Червеньский;Рудня;28.383;53.883 1699 | Минская;Червеньский;Смиловичи;28.16;53.733 1700 | Минская;Червеньский;Хутор;28.683;53.75 1701 | Минская;Червеньский;Червень;28.433;53.7 1702 | Минская;Червеньский;Чернова;28.35;53.866 1703 | Могилевская;Белыничcкий;Белыничи;29.7;53.983 1704 | Могилевская;Белыничcкий;Головчин;29.916;54.66 1705 | Могилевская;Белыничcкий;Ермоловичи;30.66;53.983 1706 | Могилевская;Белыничcкий;Заполье;29.6;53.833 1707 | Могилевская;Белыничcкий;Новоселки;30.233;53.783 1708 | Могилевская;Белыничcкий;Староселье;30.116;54.316 1709 | Могилевская;Белыничcкий;Техтин;29.733;53.85 1710 | Могилевская;Бобруйский;Бобруйск;29.183;53.216 1711 | Могилевская;Бобруйский;Большие Бортники;29.566;53.116 1712 | Могилевская;Бобруйский;Брожа;29.1;52.966 1713 | Могилевская;Бобруйский;Вишневка;29.183;53.16 1714 | Могилевская;Бобруйский;Глуша;28.866;53.83 1715 | Могилевская;Бобруйский;Орсичи;29.1;52.916 1716 | Могилевская;Бобруйский;Осово;28.933;53.166 1717 | Могилевская;Бобруйский;Панкратовичи;29.45;52.95 1718 | Могилевская;Бобруйский;Петровичи;29.33;53.16 1719 | Могилевская;Бобруйский;Побоковичи;29.16;53.133 1720 | Могилевская;Бобруйский;Стасевка;29.333;52.966 1721 | Могилевская;Бобруйский;Сычково;29.116;53.2 1722 | Могилевская;Бобруйский;Телуша;29.4;53.5 1723 | Могилевская;Бобруйский;Турки;29.6;53.5 1724 | Могилевская;Быховский;Бовки;30.683;53.55 1725 | Могилевская;Быховский;Болонов Селец;29.916;53.633 1726 | Могилевская;Быховский;Быхов;30.25;53.516 1727 | Могилевская;Быховский;Виляховка;30.3;53.266 1728 | Могилевская;Быховский;Восточная;30.1;53.616 1729 | Могилевская;Быховский;Глухи;30.66;53.65 1730 | Могилевская;Быховский;Грудиновка;30.466;53.633 1731 | Могилевская;Быховский;Красница;30.55;53.583 1732 | Могилевская;Быховский;Красный Берег;30.2;53.333 1733 | Могилевская;Быховский;Кузьковичи;30.416;53.55 1734 | Могилевская;Быховский;Лудчицы;30.25;53.433 1735 | Могилевская;Быховский;Мокрое;30.216;53.566 1736 | Могилевская;Быховский;Никоновичи;30.433;53.45 1737 | Могилевская;Быховский;Новый Быхов;30.35;53.333 1738 | Могилевская;Быховский;Обидовичи;30.416;53.333 1739 | Могилевская;Быховский;Рыжковка;30.516;53.65 1740 | Могилевская;Быховский;Селец-Холопеев;30.4;53.4 1741 | Могилевская;Быховский;Тощица;30.133;53.3 1742 | Могилевская;Быховский;Хомичи;29.966;53.35 1743 | Могилевская;Быховский;Чечевичи;29.816;53.516 1744 | Могилевская;Быховский;Ямное;30.133;53.516 1745 | Могилевская;Глусский;Бабирово;28.55;53.33 1746 | Могилевская;Глусский;Балашевичи;28.766;52.9 1747 | Могилевская;Глусский;Глуск;28.683;52.9 1748 | Могилевская;Глусский;Городок;28.766;53.5 1749 | Могилевская;Глусский;Зубаревичи;28.866;52.783 1750 | Могилевская;Глусский;Клетное;28.633;52.816 1751 | Могилевская;Глусский;Симоновичи;28.633;53.83 1752 | Могилевская;Глусский;Славковичи;28.5;52.716 1753 | Могилевская;Горецкий;Горки;30.933;54.3 1754 | Могилевская;Горецкий;Добрая;30.933;54.183 1755 | Могилевская;Горецкий;Коптевка;31.266;54.183 1756 | Могилевская;Горецкий;Котелево;31.83;54.316 1757 | Могилевская;Горецкий;Ленино;31.116;54.4 1758 | Могилевская;Горецкий;Маслаки;30.65;54.316 1759 | Могилевская;Горецкий;Паршино;31.66;54.233 1760 | Могилевская;Горецкий;Рудковщина;30.7;54.4 1761 | Могилевская;Горецкий;Чепелинка;30.833;54.266 1762 | Могилевская;Дрибинский;Дрибин;31.83;54.133 1763 | Могилевская;Дрибинский;Жевань;30.9;54.66 1764 | Могилевская;Дрибинский;Кледневичи;31.1;54.183 1765 | Могилевская;Дрибинский;Рясна;31.183;54.16 1766 | Могилевская;Дрибинский;Темный Лес;31.216;54.1 1767 | Могилевская;Кировский;Белая Дубровка;31.966;53.25 1768 | Могилевская;Кировский;Белица;31.3;53.8 1769 | Могилевская;Кировский;Бобровичи;28.65;52.733 1770 | Могилевская;Кировский;Большая Комаровка;30.283;54.133 1771 | Могилевская;Кировский;Большое Черное;30.116;54.183 1772 | Могилевская;Кировский;Большой Осов;31.183;53.266 1773 | Могилевская;Кировский;Борки;29.7;53.466 1774 | Могилевская;Кировский;Будино;31.5;54 1775 | Могилевская;Кировский;Быковичи;31.566;54.16 1776 | Могилевская;Кировский;Быново;31.166;53.866 1777 | Могилевская;Кировский;Веть;30.416;53.3 1778 | Могилевская;Кировский;Вязьма;29.916;53.383 1779 | Могилевская;Кировский;Голынка;29.66;53.283 1780 | Могилевская;Кировский;Добосна;29.683;53.2 1781 | Могилевская;Кировский;Доманы;30.616;54.83 1782 | Могилевская;Кировский;Дубровка 1-я;30.516;54.133 1783 | Могилевская;Кировский;Дуброво;28.55;52.95 1784 | Могилевская;Кировский;Загатье;29.683;53.65 1785 | Могилевская;Кировский;Заозерье;29.45;54.66 1786 | Могилевская;Кировский;Зубры;30.75;54.35 1787 | Могилевская;Кировский;Кировск;29.483;53.266 1788 | Могилевская;Кировский;Козуличи;29.35;53.266 1789 | Могилевская;Кировский;Корытница;29.416;53.916 1790 | Могилевская;Кировский;Костинка;30.45;53.733 1791 | Могилевская;Кировский;Красная Белорусь;30.15;53.416 1792 | Могилевская;Кировский;Красная Буда;31.833;53.716 1793 | Могилевская;Кировский;Красное;29.5;53.316 1794 | Могилевская;Кировский;Кремок;28.216;53.25 1795 | Могилевская;Кировский;Круги;30.533;54.16 1796 | Могилевская;Кировский;Кузминичи;30.933;53.683 1797 | Могилевская;Кировский;Любоничи;29.233;53.266 1798 | Могилевская;Кировский;Могилев;30.66;53.95 1799 | Могилевская;Кировский;Моисеевичи;28.283;53.216 1800 | Могилевская;Кировский;Мышковичи;29.5;53.216 1801 | Могилевская;Кировский;Низки;32.16;53.416 1802 | Могилевская;Кировский;Норки;31.3;53.716 1803 | Могилевская;Кировский;Пеньковка;32.5;53.716 1804 | Могилевская;Кировский;Пильня;31.35;53.466 1805 | Могилевская;Кировский;Раздел;31.366;54.133 1806 | Могилевская;Кировский;Ржавцы;30.3;54.25 1807 | Могилевская;Кировский;Роги;30.733;53.366 1808 | Могилевская;Кировский;Рудня;29.883;53.916 1809 | Могилевская;Кировский;Сава;30.816;54.366 1810 | Могилевская;Кировский;Сергеевичи;29.216;53.3 1811 | Могилевская;Кировский;Скачок;29.6;53.366 1812 | Могилевская;Кировский;Слободка;30.233;54.266 1813 | Могилевская;Кировский;Смолка;30.6;53.75 1814 | Могилевская;Кировский;Старинка;31.166;53.416 1815 | Могилевская;Кировский;Старый Остров;28.983;53.55 1816 | Могилевская;Кировский;Старый Стан;32.216;53.65 1817 | Могилевская;Кировский;Тереховка;30.9;53.333 1818 | Могилевская;Кировский;Тетерино;29.75;54.166 1819 | Могилевская;Кировский;Усохи;29.266;53.35 1820 | Могилевская;Кировский;Устье;31.533;53.6 1821 | Могилевская;Кировский;Ушаки;31.283;53.466 1822 | Могилевская;Кировский;Чашники;31.33;54.383 1823 | Могилевская;Кировский;Чигиринка;29.85;53.416 1824 | Могилевская;Кировский;Щекотово;30.933;54.33 1825 | Могилевская;Кировский;Юрьево;29.566;53.16 1826 | Могилевская;Климовичский;Борисовичи;31.666;53.6 1827 | Могилевская;Климовичский;Великий Мох;32.166;53.716 1828 | Могилевская;Климовичский;Галичи;32.333;53.583 1829 | Могилевская;Климовичский;Домамеричи;31.966;53.716 1830 | Могилевская;Климовичский;Забелышин;32.366;53.5 1831 | Могилевская;Климовичский;Звенчатка;32.233;53.75 1832 | Могилевская;Климовичский;Климовичи;31.966;53.616 1833 | Могилевская;Климовичский;Красавичи;31.866;53.466 1834 | Могилевская;Климовичский;Лобжа;31.766;53.6 1835 | Могилевская;Климовичский;Макеевичи;32.4;53.683 1836 | Могилевская;Климовичский;Милославичи;32.25;53.7 1837 | Могилевская;Климовичский;Недведь;32.233;53.6 1838 | Могилевская;Климовичский;Осмоловичи;31.983;53.533 1839 | Могилевская;Климовичский;Палуж 2-Й;31.55;53.333 1840 | Могилевская;Климовичский;Родня;32.15;53.516 1841 | Могилевская;Климовичский;Силичи;31.75;53.266 1842 | Могилевская;Климовичский;Судилы;32.15;53.55 1843 | Могилевская;Климовичский;Тимоново;31.883;53.566 1844 | Могилевская;Климовичский;Титовка;31.7;53.433 1845 | Могилевская;Климовичский;Ходунь;31.983;53.766 1846 | Могилевская;Кличевский;Бацевичи;29.216;53.4 1847 | Могилевская;Кличевский;Долгое;29.683;53.6 1848 | Могилевская;Кличевский;Закутье;29.333;53.583 1849 | Могилевская;Кличевский;Замочулье;29.6;53.783 1850 | Могилевская;Кличевский;Кличев;29.333;53.5 1851 | Могилевская;Кличевский;Колбча;29.233;53.65 1852 | Могилевская;Кличевский;Любаны;31.1;53.666 1853 | Могилевская;Кличевский;Несята;29.216;53.483 1854 | Могилевская;Кличевский;Стан;30.9;54.25 1855 | Могилевская;Кличевский;Стоялово;29.35;53.533 1856 | Могилевская;Кличевский;Усакино;29.45;53.616 1857 | Могилевская;Костюковичский;Белынковичи;32.133;53.233 1858 | Могилевская;Костюковичский;Большая Зимница;30.633;53.333 1859 | Могилевская;Костюковичский;Бороньки;32.133;53.15 1860 | Могилевская;Костюковичский;Великий Бор;31.916;53.183 1861 | Могилевская;Костюковичский;Ветухна;31.866;53.333 1862 | Могилевская;Костюковичский;Видуйцы;31.733;53.233 1863 | Могилевская;Костюковичский;Витунь;32.233;53.316 1864 | Могилевская;Костюковичский;Забычанье;31.883;53.416 1865 | Могилевская;Костюковичский;Каничи;32.183;53.283 1866 | Могилевская;Костюковичский;Колодезская;31.766;53.35 1867 | Могилевская;Костюковичский;Костюковичи;32.66;53.35 1868 | Могилевская;Костюковичский;Кривелицк;31.116;53.3 1869 | Могилевская;Костюковичский;Кульшичи;30.766;53.466 1870 | Могилевская;Костюковичский;Липовка;30.216;53.683 1871 | Могилевская;Костюковичский;Мартьяновичи;29.616;54.2 1872 | Могилевская;Костюковичский;Михеевичи;31.816;53.7 1873 | Могилевская;Костюковичский;Пролетарское;32.116;53.416 1874 | Могилевская;Костюковичский;Рогалино;31.183;53.566 1875 | Могилевская;Костюковичский;Селец;30.666;54.283 1876 | Могилевская;Костюковичский;Старые Максимовичи;29.133;53.6 1877 | Могилевская;Костюковичский;Студенец;32.33;53.3 1878 | Могилевская;Костюковичский;Травна;31.466;53.366 1879 | Могилевская;Костюковичский;Тупичино;32.233;53.383 1880 | Могилевская;Краснопольский;Выдренка;31.3;53.133 1881 | Могилевская;Краснопольский;Городецкая;31.266;53.333 1882 | Могилевская;Краснопольский;Горы;31.2;54.266 1883 | Могилевская;Краснопольский;Копани;30.733;53.716 1884 | Могилевская;Краснопольский;Краснополье;31.4;53.333 1885 | Могилевская;Краснопольский;Мхиничи;31.333;53.2 1886 | Могилевская;Краснопольский;Почепы;31.333;53.283 1887 | Могилевская;Кричевский;Вишни;31.966;53.1 1888 | Могилевская;Кричевский;Волчас;31.466;53.7 1889 | Могилевская;Кричевский;Дяговичи;31.816;53.766 1890 | Могилевская;Кричевский;Кожемякино;31.4;53.4 1891 | Могилевская;Кричевский;Кричев;31.716;53.7 1892 | Могилевская;Кричевский;Кучин;29.966;53.683 1893 | Могилевская;Кричевский;Лобковичи;31.75;53.833 1894 | Могилевская;Кричевский;Молятичи;31.55;53.85 1895 | Могилевская;Кричевский;Монастырек;31.316;53.5 1896 | Могилевская;Кричевский;Осовец;29.666;53.916 1897 | Могилевская;Кричевский;Усушек;30.783;53.666 1898 | Могилевская;Круглянский;Ельковщина;29.916;54.25 1899 | Могилевская;Круглянский;Комсеничи;29.883;54.15 1900 | Могилевская;Круглянский;Круглое;29.8;54.25 1901 | Могилевская;Круглянский;Круча;29.55;54.233 1902 | Могилевская;Круглянский;Павловичи;32.5;53.6 1903 | Могилевская;Круглянский;Старые Чемоданы;30.566;54.166 1904 | Могилевская;Круглянский;Филатово;29.633;54.3 1905 | Могилевская;Круглянский;Шепелевичи;29.566;54.133 1906 | Могилевская;Могилевский;Большая Мощаница;29.616;53.95 1907 | Могилевская;Могилевский;Большие Белевичи;29.833;53.8 1908 | Могилевская;Могилевский;Браково;30.133;54.16 1909 | Могилевская;Могилевский;Брыли;30.55;53.9 1910 | Могилевская;Могилевский;Вендорож;30.16;53.85 1911 | Могилевская;Могилевский;Вьюн;30.5;53.466 1912 | Могилевская;Могилевский;Дашковка;30.25;53.75 1913 | Могилевская;Могилевский;Ждановичи;30.733;54.5 1914 | Могилевская;Могилевский;Журбин;32.283;53.166 1915 | Могилевская;Могилевский;Ильковичи;29.8;54.1 1916 | Могилевская;Могилевский;Каменица;29.9;53.983 1917 | Могилевская;Могилевский;Княжицы;30.133;53.983 1918 | Могилевская;Могилевский;Красница;31.866;53.3 1919 | Могилевская;Могилевский;Крынка;28.4;53.216 1920 | Могилевская;Могилевский;Личинка;30.66;54.5 1921 | Могилевская;Могилевский;Махово;30.5;53.7 1922 | Могилевская;Могилевский;Межисятки;30.166;53.783 1923 | Могилевская;Могилевский;Мосток;30.466;53.983 1924 | Могилевская;Могилевский;Осман-Касаево;29.716;53.8 1925 | Могилевская;Могилевский;Полыковичи;30.35;53.983 1926 | Могилевская;Могилевский;Самотевичи;31.833;53.216 1927 | Могилевская;Могилевский;Сидоровичи;30.383;53.683 1928 | Могилевская;Могилевский;Сухари;30.716;53.966 1929 | Могилевская;Мстиславский;Барчицы;29.666;53.25 1930 | Могилевская;Мстиславский;Бастеновичи;31.383;54.5 1931 | Могилевская;Мстиславский;Бахань;30.633;53.4 1932 | Могилевская;Мстиславский;Большое Хоново;29.983;53.766 1933 | Могилевская;Мстиславский;Борисовщина;28.733;52.983 1934 | Могилевская;Мстиславский;Борколабово;30.266;53.633 1935 | Могилевская;Мстиславский;Голынец 1-й;30.183;53.866 1936 | Могилевская;Мстиславский;Дедня;31.166;53.916 1937 | Могилевская;Мстиславский;Долговичи;31.316;53.95 1938 | Могилевская;Мстиславский;Дроковка;31.66;53.716 1939 | Могилевская;Мстиславский;Дулебка;29.2;53.533 1940 | Могилевская;Мстиславский;Зимницы;32.33;53.65 1941 | Могилевская;Мстиславский;Иванищевичи;30.75;53.55 1942 | Могилевская;Мстиславский;Курманово;31.383;54.116 1943 | Могилевская;Мстиславский;Мстиславль;31.7;54.33 1944 | Могилевская;Мстиславский;Парадино;31.833;53.983 1945 | Могилевская;Мстиславский;Пацова Слобода;29.4;53.283 1946 | Могилевская;Мстиславский;Переволочная;32.383;53.633 1947 | Могилевская;Мстиславский;Плещицы;30.416;54.83 1948 | Могилевская;Мстиславский;Подлужье;31.833;53.95 1949 | Могилевская;Мстиславский;Савиничи;31.766;53.466 1950 | Могилевская;Мстиславский;Саприновичи;31.816;54.33 1951 | Могилевская;Мстиславский;Смолица;30.55;53.533 1952 | Могилевская;Мстиславский;Столпище;29.4;53.233 1953 | Могилевская;Мстиславский;Темровичи;30.866;53.9 1954 | Могилевская;Мстиславский;Ходосы;31.466;53.933 1955 | Могилевская;Мстиславский;Хоньковичи;30.833;53.983 1956 | Могилевская;Мстиславский;Хотиловичи;31.633;53.683 1957 | Могилевская;Мстиславский;Шамовщина;31.6;53.983 1958 | Могилевская;Осиповичский;Березяки;31.116;53.233 1959 | Могилевская;Осиповичский;Верейцы;28.516;53.333 1960 | Могилевская;Осиповичский;Воевичи;29.316;53.416 1961 | Могилевская;Осиповичский;Вязовница;28.833;53.45 1962 | Могилевская;Осиповичский;Вязье;28.683;53.366 1963 | Могилевская;Осиповичский;Гродзянка;28.75;53.55 1964 | Могилевская;Осиповичский;Дараганово;28.5;53.183 1965 | Могилевская;Осиповичский;Елизово;29.16;53.4 1966 | Могилевская;Осиповичский;Каменичи;28.833;53.533 1967 | Могилевская;Осиповичский;Корытное;28.766;53.166 1968 | Могилевская;Осиповичский;Лапичи;28.55;53.433 1969 | Могилевская;Осиповичский;Липень;28.816;53.416 1970 | Могилевская;Осиповичский;Мошенаки;30.566;53.966 1971 | Могилевская;Осиповичский;Новое Прибужье;31.16;54.133 1972 | Могилевская;Осиповичский;Осиповичи;28.633;53.3 1973 | Могилевская;Осиповичский;Свислочь;28.95;53.433 1974 | Могилевская;Осиповичский;Татарка;28.833;53.266 1975 | Могилевская;Осиповичский;Ясень;28.933;53.216 1976 | Могилевская;Славгородский;Березовка;30.983;53.633 1977 | Могилевская;Славгородский;Васьковичи;30.766;53.916 1978 | Могилевская;Славгородский;Вильчицы;30.35;53.783 1979 | Могилевская;Славгородский;Гайшин;31;53.35 1980 | Могилевская;Славгородский;Гиженка;31.5;53.566 1981 | Могилевская;Славгородский;Каменка;31.216;54.316 1982 | Могилевская;Славгородский;Лопатичи;30.866;53.566 1983 | Могилевская;Славгородский;Рабовичи;30.95;53.55 1984 | Могилевская;Славгородский;Ректа;30.7;53.3 1985 | Могилевская;Славгородский;Славгород;31.16;53.45 1986 | Могилевская;Славгородский;Шеломы;30.9;53.45 1987 | Могилевская;Хотимский;Батаево;32.383;53.25 1988 | Могилевская;Хотимский;Березки;32.333;53.35 1989 | Могилевская;Хотимский;Беседовичи;32.566;53.383 1990 | Могилевская;Хотимский;Боханы;32.45;53.366 1991 | Могилевская;Хотимский;Еловец;32.65;53.45 1992 | Могилевская;Хотимский;Ельня;32.366;53.433 1993 | Могилевская;Хотимский;Тростино;32.5;53.483 1994 | Могилевская;Хотимский;Хотимск;32.583;53.433 1995 | Могилевская;Чауский;Благовичи;30.85;53.833 1996 | Могилевская;Чауский;Волковичи;30.666;53.683 1997 | Могилевская;Чауский;Головенчицы;30.816;53.733 1998 | Могилевская;Чауский;Горбовичи;30.716;53.816 1999 | Могилевская;Чауский;Долгий Мох;30.783;53.616 2000 | Могилевская;Чауский;Петуховка;31.83;53.733 2001 | Могилевская;Чауский;Путьки;31.66;53.85 2002 | Могилевская;Чауский;Чаусы;30.966;53.8 2003 | Могилевская;Чериковский;Веприн;31.533;53.55 2004 | Могилевская;Чериковский;Веремейки;31.266;53.766 2005 | Могилевская;Чериковский;Глинь;31.416;53.65 2006 | Могилевская;Чериковский;Речица;31.55;53.633 2007 | Могилевская;Чериковский;Чериков;31.383;53.566 2008 | Могилевская;Чериковский;Чудяны;31.583;53.516 2009 | Могилевская;Чериковский;Шароевка;31.3;53.633 2010 | Могилевская;Шкловский;Барсуки;30.3;54.5 2011 | Могилевская;Шкловский;Высокое;31.883;53.516 2012 | Могилевская;Шкловский;Евдокимовичи;30.483;54.5 2013 | Могилевская;Шкловский;Забродье;30.45;54.25 2014 | Могилевская;Шкловский;Каменные Лавы;30.3;54.83 2015 | Могилевская;Шкловский;Копысица;30.233;54.333 2016 | Могилевская;Шкловский;Косаричи;28.766;52.75 2017 | Могилевская;Шкловский;Любиничи;30.466;54.233 2018 | Могилевская;Шкловский;Никитиничи;30.366;54.283 2019 | Могилевская;Шкловский;Ордать;30.683;54.15 2020 | Могилевская;Шкловский;Полоница;31.6;53.783 2021 | Могилевская;Шкловский;Старая Водва;30.166;54.66 2022 | Могилевская;Шкловский;Тудорово;30.5;54.133 2023 | Могилевская;Шкловский;Уланово;30.15;54.25 2024 | Могилевская;Шкловский;Черневка;30.766;54.83 2025 | Могилевская;Шкловский;Шклов;30.3;54.216 -------------------------------------------------------------------------------- /src/__tests__/opencorpora-test.ts: -------------------------------------------------------------------------------- 1 | import readline from 'readline'; 2 | import path from 'path'; 3 | import fs from 'fs'; 4 | import { getFG, getLG, MALE, FEMALE, ANDROGYNOUS } from '../gender'; 5 | 6 | describe('data set tests', () => { 7 | it('firstNames.gender.tsv', (done) => { 8 | const lineReader = readline.createInterface({ 9 | input: fs.createReadStream(path.resolve(__dirname, './opencorpora/firstnames.gender.tsv')), 10 | }); 11 | 12 | let err: Error; 13 | const counters = { 14 | skipWithoutRules: 0, 15 | skipped: [] as string[], 16 | success: 0, 17 | }; 18 | lineReader.on('line', (line) => { 19 | const [name, genderDirty] = line.split('\t'); 20 | let gender; 21 | switch (genderDirty) { 22 | case 'мр': 23 | gender = MALE; 24 | break; 25 | case 'жр': 26 | gender = FEMALE; 27 | break; 28 | case 'мр-жр': 29 | gender = ANDROGYNOUS; 30 | break; 31 | default: 32 | gender = null; 33 | } 34 | if (gender && !err) { 35 | const g = getFG(name); 36 | if (g === null) { 37 | counters.skipped.push(name); 38 | counters.skipWithoutRules += 1; 39 | return; 40 | } 41 | 42 | try { 43 | expect(`${name} ${g || ''}`).toEqual(`${name} ${gender}`); 44 | counters.success += 1; 45 | } catch (e: any) { 46 | err = e; 47 | done.fail(e); 48 | lineReader.close(); 49 | } 50 | } 51 | }); 52 | 53 | lineReader.on('close', () => { 54 | // counters.skipped = counters.skipped 55 | // .filter( 56 | // s => !s.endsWith('КА') && !s.endsWith('ША') && !s.endsWith('НЯ'), 57 | // ) 58 | // .join(' '); 59 | // console.log(counters); 60 | if (!err) done(); 61 | }); 62 | }); 63 | 64 | it('surnames.gender.tsv', (done) => { 65 | const lineReader = readline.createInterface({ 66 | input: fs.createReadStream(path.resolve(__dirname, './opencorpora/surnames.gender.tsv')), 67 | }); 68 | 69 | let err: Error; 70 | const counters = { 71 | skipWithoutRules: 0, 72 | skipped: [] as string[], 73 | success: 0, 74 | }; 75 | lineReader.on('line', (line) => { 76 | const [name, genderDirty] = line.split('\t'); 77 | let gender; 78 | switch (genderDirty) { 79 | case 'мр': 80 | gender = MALE; 81 | break; 82 | case 'жр': 83 | gender = FEMALE; 84 | break; 85 | case 'мр-жр': 86 | gender = ANDROGYNOUS; 87 | break; 88 | default: 89 | gender = null; 90 | } 91 | 92 | if (gender && !err) { 93 | const g = getLG(name); 94 | if (g === null) { 95 | counters.skipped.push(name); 96 | counters.skipWithoutRules += 1; 97 | return; 98 | } 99 | 100 | try { 101 | expect(`${name} ${g || ''}`).toEqual(`${name} ${gender}`); 102 | counters.success += 1; 103 | } catch (e: any) { 104 | err = e; 105 | done.fail(e); 106 | lineReader.close(); 107 | } 108 | } 109 | }); 110 | 111 | lineReader.on('close', () => { 112 | // counters.skipped = counters.skipped.join(' '); 113 | // console.log(counters); 114 | if (!err) done(); 115 | }); 116 | }); 117 | }); 118 | -------------------------------------------------------------------------------- /src/__tests__/opencorpora/surnames.gender.tsv: -------------------------------------------------------------------------------- 1 | lemma gender 2 | АБАЗЕВ мр 3 | АБАЗЕВА жр 4 | АБАЗОВ мр 5 | АБАЗОВА жр 6 | АБАКАДЗЕ мр-жр 7 | АБАЛИХИН мр 8 | АБАЛИХИНА жр 9 | АБАЛЬЯН мр-жр 10 | АБАРЧУК мр-жр 11 | АББАС мр-жр 12 | АБРАМАШВИЛИ мр-жр 13 | АБЕЛЬМАН мр-жр 14 | АБРАМЕНКО мр-жр 15 | АБРАМОВИЧ мр-жр 16 | АБРАМОВСКИХ мр-жр 17 | АБРАМСОН мр-жр 18 | АВАЛИАНИ мр-жр 19 | АВАНЕСЬЯНЦ мр-жр 20 | АВДУЕВСКИЙ мр 21 | АВДУЕВСКАЯ жр 22 | АВЕРБАХ мр-жр 23 | АГАССИ мр-жр 24 | АГРАНАТ мр-жр 25 | АГРИППА мр-жр 26 | АДАМС мр-жр 27 | АДЕНАУЭР мр-жр 28 | АДОМАВИЧЮС мр-жр 29 | АДОМАЙТИС мр-жр 30 | АЗЕФ мр-жр 31 | АЙДЗЕРДЗИС мр-жр 32 | АЙЗДЕРДЗИС мр-жр 33 | АЙЗЕНБЕРГ мр-жр 34 | АЙЗЕНМАНН мр-жр 35 | АКСЕЛЬРОД мр-жр 36 | АЛАКОЗ мр-жр 37 | АЛЕМИ мр-жр 38 | АЛЬБРЕХТС мр-жр 39 | АЛЬЕНДЕ мр-жр 40 | АМАТИ мр-жр 41 | АНБРЕЙТ мр-жр 42 | АНДЕРСЕН мр-жр 43 | АРАФАТ мр-жр 44 | АРКАДИ мр-жр 45 | АРНШТРЕМ мр-жр 46 | АРРЕНИУС мр-жр 47 | АСЛАНИДИ мр-жр 48 | АУЭРБАХ мр-жр 49 | АФАНАСИ мр-жр 50 | АШЕНБРЕННЕР мр-жр 51 | БАГДОНАС мр-жр 52 | БАЗАРГУР мр-жр 53 | БАЙ мр-жр 54 | БАЛАБУХА мр-жр 55 | БАЛЛАДЮР мр-жр 56 | БАЛЬМОНТ мр-жр 57 | БАРДИАН мр-жр 58 | БАРЕНБОЙМ мр-жр 59 | БАРИЛЛА мр-жр 60 | БАРТ мр-жр 61 | БАУЭР мр-жр 62 | БАХ мр-жр 63 | БАХМАТ мр-жр 64 | БАШМЕТ мр-жр 65 | БЕВЗ мр-жр 66 | БЕЗМЕЛЬНИЦЫН мр 67 | БЕЙЕРБАХ мр-жр 68 | БЕЗМЕЛЬНИЦЫНА жр 69 | БЕЛЛЕНДИР мр-жр 70 | БЕЛЫХ мр-жр 71 | БЕЛЬБЕЙ мр-жр 72 | БЕНДИТКИС мр-жр 73 | БЕНКЕНДОРФ мр-жр 74 | БЕННЕКЕ мр-жр 75 | БЕРЕНДС мр-жр 76 | БЕРИЯ мр-жр 77 | БЕРКЛИ мр-жр 78 | БЕРЛИОЗ мр-жр 79 | БЕРНАЛ мр-жр 80 | БЕРНУЛЛИ мр-жр 81 | БЕРШТЕЙН мр-жр 82 | БЕССАРАБ мр-жр 83 | БЕСЧАСТНЫХ мр-жр 84 | БИБЕРГАН мр-жр 85 | БИНЕНБОЙМ мр-жр 86 | БИРУТ мр-жр 87 | БИХЕРТ мр-жр 88 | БИЧАН мр-жр 89 | БЛУМ мр-жр 90 | БЛЭР мр-жр 91 | БОГОРАЗ мр-жр 92 | БОЛОБАН мр-жр 93 | БОМАРШЕ мр-жр 94 | БОНАПАРТ мр-жр 95 | БОННЭР мр-жр 96 | БОТТИЧЕЛЛИ мр-жр 97 | БОЧВАР мр-жр 98 | БРАНД мр-жр 99 | БРЕДБЕРИ мр-жр 100 | БРЕХТ мр-жр 101 | БРИШ мр-жр 102 | БРУТ мр-жр 103 | БРУХИС мр-жр 104 | БУЛЬБА мр-жр 105 | БУРАС мр-жр 106 | БУРБАХ мр-жр 107 | БУРБУЛИС мр-жр 108 | БУШ мр-жр 109 | ВАЙДА мр-жр 110 | ВАЙНБАУМ мр-жр 111 | ВАЙНГЕРТ мр-жр 112 | ВАЙСФЕЛЬД мр-жр 113 | ВАЛА мр-жр 114 | ВАР-РАВВАН мр-жр 115 | ВАРГА мр-жр 116 | ВАРЕНУХА мр-жр 117 | ВАРОС мр-жр 118 | ВЕЙНБЛАТ мр-жр 119 | ВЕЙНГОЛЬД мр-жр 120 | ВЕЙСФИЛЬД мр-жр 121 | ВЕРБАН мр-жр 122 | ВЕРДИ мр-жр 123 | ВИККЕРС мр-жр 124 | ВИЛИНБАХ мр-жр 125 | ВИНЧИ мр-жр 126 | ВОЛАНД мр-жр 127 | ВОЛОЖ мр-жр 128 | ВОРОБЬЁВ мр 129 | ВОРОБЬЁВА жр 130 | ВОРОНУХА мр-жр 131 | ГААЗ мр-жр 132 | ГАБУДА мр-жр 133 | ГАДЖА мр-жр 134 | ГАЙДАМАХ мр-жр 135 | ГАЙДАР мр-жр 136 | ГАЙЯР мр-жр 137 | ГАЛАГАН мр-жр 138 | ГАЛАН мр-жр 139 | ГАЛИЛЕЙ мр-жр 140 | ГАЛУА мр-жр 141 | ГАЛЬБЛАУФ мр-жр 142 | ГАМАЛЕЯ мр-жр 143 | ГАМАРРА мр-жр 144 | ГАМЗА мр-жр 145 | ГАНДИ мр-жр 146 | ГАНКА мр-жр 147 | ГАРАС мр-жр 148 | ГАРДИ мр-жр 149 | ГАУСС мр-жр 150 | ГАУФ мр-жр 151 | ГАФТ мр-жр 152 | ГЕББЕЛЬС мр-жр 153 | ГЕЙДУР мр-жр 154 | ГЕЙНЕ мр-жр 155 | ГЕЙТС мр-жр 156 | ГЕЛЬФАНД мр-жр 157 | ГЁТЕ мр-жр 158 | ГЕХТ мр-жр 159 | ГИБЕРТ мр-жр 160 | ГИГЛАВЫЙ мр 161 | ГИЛЛЕ мр-жр 162 | ГИЛЬБУХ мр-жр 163 | ГИММЕЛЬФАРБ мр-жр 164 | ГИНЕНФЕЛЬД мр-жр 165 | ГИППИУС мр-жр 166 | ГЛИНКА мр-жр 167 | ГЛИТЧАН мр-жр 168 | ГМЫРЯ мр-жр 169 | ГОДАР мр-жр 170 | ГОЙЯ мр-жр 171 | ГОЛАНДЖАН мр-жр 172 | ГОЛОВАТЫЙ мр 173 | ГОЛОВНЯ мр-жр 174 | ГОЛЬБРАЙХ мр-жр 175 | ГОМЕС мр-жр 176 | ГОНЧАР мр-жр 177 | ГРЕФ мр-жр 178 | ГРИГОРИАДИ мр-жр 179 | ГРИМИТЛИХТ мр-жр 180 | ГРИММ мр-жр 181 | ГРИН мр-жр 182 | ГРИНБЛАТ мр-жр 183 | ГРОЖАН мр-жр 184 | ГРОСФЕЛЬД мр-жр 185 | ГРОУТ мр-жр 186 | ГУДЗИЙ мр-жр 187 | ГУЛИА мр-жр 188 | ГУЛЫГА мр-жр 189 | ДАЙНЕС мр-жр 190 | ДАЛИ мр-жр 191 | ДАНЕЛИЯ мр-жр 192 | ДАНТЕС мр-жр 193 | ДАРВИН мр-жр 194 | ДЕГА мр-жр 195 | ДЕДУХ мр-жр 196 | ДЕЙНЕКА мр-жр 197 | ДЕЙЧ мр-жр 198 | ДЕКАРТ мр-жр 199 | ДЕЛАКРУА мр-жр 200 | ДЕЛОР мр-жр 201 | ДЕРВИЗ мр-жр 202 | ДЕРКАЧ мр-жр 203 | ДЖОРДАН мр-жр 204 | ДИЗЕНДОРФ мр-жр 205 | ДИККЕНС мр-жр 206 | ДИЛЕЙ мр-жр 207 | ДИОНИСИ мр-жр 208 | ДИСНЕЙ мр-жр 209 | ДОБРОБАБ мр-жр 210 | ДОВАТОР мр-жр 211 | ДОВГОПЯТЫЙ мр 212 | ДОМБИ мр-жр 213 | ДОРОШ мр-жр 214 | ДОРШ мр-жр 215 | ДРОБОТ мр-жр 216 | ДУБЕЛЬТ мр-жр 217 | ДУГЛАС мр-жр 218 | ДЭВИС мр-жр 219 | ДЮМА мр-жр 220 | ДЮССАР мр-жр 221 | ЗАБЕЙВОРОТА мр-жр 222 | ЗАБЛОЦКИС мр-жр 223 | ЗАБОЛОТНЫЙ мр 224 | ЗАКАБЛУКА мр-жр 225 | ЗОЗУЛЯ мр-жр 226 | ЗОЛЯ мр-жр 227 | ЙОРДАН мр-жр 228 | КАБАЛЬЕ мр-жр 229 | КАИФА мр-жр 230 | КАЛЛАС мр-жр 231 | КАЛЬТЛУФТ мр-жр 232 | КАЛЬЦАТЫЙ мр 233 | КАНЕЛИС мр-жр 234 | КАНТ мр-жр 235 | КАНТОР мр-жр 236 | КАПИЦА мр-жр 237 | КАПЛАН мр-жр 238 | КАПРИАТИ мр-жр 239 | КАРА-САЛ мр-жр 240 | КАРАМУРЗА мр-жр 241 | КАРДИНАЛЕ мр-жр 242 | КАРЛОС мр-жр 243 | КАРНАУХ мр-жр 244 | КАРНЕГИ мр-жр 245 | КАСТАКИ мр-жр 246 | КАСТАНЬЕ мр-жр 247 | КАТУЛЛ мр-жр 248 | КАФКА мр-жр 249 | КВАН мр-жр 250 | КВАША мр-жр 251 | КЕЙЗЕ мр-жр 252 | КЕЛДЫШ мр-жр 253 | КЕМПБЕЛЛ мр-жр 254 | КЕННЕДИ мр-жр 255 | КЕНТ мр-жр 256 | КЕЦАРИС мр-жр 257 | КИМ мр-жр 258 | КИРКЕГОР мр-жр 259 | КИТС мр-жр 260 | КИХОТ мр-жр 261 | КЛИ мр-жр 262 | КЛИЙСТЕРС мр-жр 263 | КНЫШ мр-жр 264 | КОГАН мр-жр 265 | КОЖЕДУБ мр-жр 266 | КОЛУМБ мр-жр 267 | КОЛЦУН мр-жр 268 | КОППЕРФИЛЬД мр-жр 269 | КОРВАЛАН мр-жр 270 | КОРРИГАН мр-жр 271 | КОРТЕС мр-жр 272 | КОСЫХ мр-жр 273 | КОТЛЯР мр-жр 274 | КОХ мр-жр 275 | КОШТУНИЦА мр-жр 276 | КОЭН мр-жр 277 | КРАВ мр-жр 278 | КРАСНЫХ мр-жр 279 | КРИМНУС мр-жр 280 | КРИСТЕНС мр-жр 281 | КРИСТИ мр-жр 282 | КРУЗ мр-жр 283 | КРУЗЕНШТЕРН мр-жр 284 | КРУС мр-жр 285 | КУКУРА мр-жр 286 | КУПАЛА мр-жр 287 | КУРКУЛИЯ мр-жр 288 | КУТОРГА мр-жр 289 | КУЧЕРЕНА мр-жр 290 | КУЧМА мр-жр 291 | КЭРРОЛЛ мр-жр 292 | ЛАЙКАМ мр-жр 293 | ЛАНДАУ мр-жр 294 | ЛАНЭ мр-жр 295 | ЛАПЕРУЗ мр-жр 296 | ЛАПИДУС мр-жр 297 | ЛАПЛАС мр-жр 298 | ЛЕВИТАН мр-жр 299 | ЛЕЖЕ мр-жр 300 | ЛЕНАРД мр-жр 301 | ЛИБКНЕХТ мр-жр 302 | ЛИСС мр-жр 303 | ЛОРКА мр-жр 304 | ЛОУРЕНС мр-жр 305 | ЛУГОВСКОЙ мр 306 | ЛЭЙКЕРС мр-жр 307 | ЛЮКА мр-жр 308 | МЁБИУС мр-жр 309 | МАВРОДИ мр-жр 310 | МАГАР мр-жр 311 | МАГЕЛЛАН мр-жр 312 | МАЗУР мр-жр 313 | МАЙБОРОДА мр-жр 314 | МАКВЕЙ мр-жр 315 | МАЛАКАВИЧЮС мр-жр 316 | МАМУТ мр-жр 317 | МАНДЕЛЬШТАМ мр-жр 318 | МАРГУЛИС мр-жр 319 | МАРЕ мр-жр 320 | МАРКС мр-жр 321 | МАТИСС мр-жр 322 | МЕЗОНЬЕ мр-жр 323 | МЕЙДЖОР мр-жр 324 | МЕЙЕРХОЛЬД мр-жр 325 | МЕНГЛЕТ мр-жр 326 | МЕНЗБИР мр-жр 327 | МЕРКЬЮРИ мр 328 | МИКУЧЯУСКАС мр-жр 329 | МИЛЬРУД мр-жр 330 | МИТТА мр-жр 331 | МИТТЕРАН мр-жр 332 | МИХОЭЛС мр-жр 333 | МОНТАЛЕНТИ мр-жр 334 | МОНТГОМЕРИ мр-жр 335 | МОПАССАН мр-жр 336 | МОРАВИА мр-жр 337 | МОРГАН мр-жр 338 | МОРИАРТИ мр-жр 339 | МОРОЗ мр-жр 340 | МОРУА мр-жр 341 | МОТА мр-жр 342 | МОЦАРТ мр-жр 343 | МУЛЛАНУР мр-жр 344 | МУР мр-жр 345 | НАВОША мр-жр 346 | НАМАТЖИРА мр-жр 347 | НЕССЕЛЬРОД мр-жр 348 | НИЦШЕ мр-жр 349 | НОНАКА мр-жр 350 | НОРДЕНШЕЛЬД мр-жр 351 | ОКУДЖАВА мр-жр 352 | ОЛЕША мр-жр 353 | ОССОР мр-жр 354 | ОУЭН мр-жр 355 | ПАВЛЯ мр-жр 356 | ПАПП мр-жр 357 | ПАРАДИЗ мр-жр 358 | ПАУЛЮС мр-жр 359 | ПАШЕННЫХ мр-жр 360 | ПЕРЕЛЕЙВОДА мр-жр 361 | ПЕРЕС мр-жр 362 | ПЕТИПА мр-жр 363 | ПЕТРАРКА мр-жр 364 | ПЕТРОНАВИЧУС мр-жр 365 | ПИДКАСИСТЫЙ мр 366 | ПИЛАТ мр-жр 367 | ПИНОЧЕТ мр-жр 368 | ПИХОЯ мр-жр 369 | ПОМПЕЙ мр-жр 370 | ПОРШЕ мр-жр 371 | ПРИЧАРД мр-жр 372 | ПРОУТ мр-жр 373 | ПРУСТ мр-жр 374 | ПУАРЕ мр-жр 375 | ПУСТОВОЙТ мр-жр 376 | ПЬЕЦУХ мр-жр 377 | РАБЛЕ мр-жр 378 | РАЙНГОЛЬД мр-жр 379 | РАЙТ мр-жр 380 | РАПОПОРТ мр-жр 381 | РАПОТА мр-жр 382 | РАППОПОРТ мр-жр 383 | РАУШЕНБАХ мр-жр 384 | РЕВИР мр-жр 385 | РЕГИН мр-жр 386 | РЕЗЕРФОРД мр-жр 387 | РЕЙГАН мр-жр 388 | РЕЙНЕКЕ мр-жр 389 | РЕЙНОЛЬДС мр-жр 390 | РЕЙХЕРТ мр-жр 391 | РЕНУАР мр-жр 392 | РИББЕНТРОП мр-жр 393 | РИБЕРА мр-жр 394 | РИД мр-жр 395 | РИЛЬКЕ мр-жр 396 | РОДРИГЕС мр-жр 397 | РОЗЕНБАУМ мр-жр 398 | РОЗЕНБЛАТ мр-жр 399 | РОЗЕНГАУЗ мр-жр 400 | РОЗЕНФЕЛЬД мр-жр 401 | РОЙТБЛАТ мр-жр 402 | РОМАНУС мр-жр 403 | РОМПЕ мр-жр 404 | РОПНЯ мр-жр 405 | РОСШТЕРН мр-жр 406 | РОТШИЛЬД мр-жр 407 | РУБЕНС мр-жр 408 | РУЗВЕЛЬТ мр-жр 409 | РУЛЬЕ мр-жр 410 | САВЕЛИ мр-жр 411 | САЛИ мр-жр 412 | САЛЬЕРИ мр-жр 413 | САМАРАНЧ мр-жр 414 | САРТР мр-жр 415 | САРФАТИ мр-жр 416 | САТИРИАДИ мр-жр 417 | СЕНЕКА мр-жр 418 | СЕНТ-ЭКЗЮПЕРИ мр-жр 419 | СЕРВАНТЕС мр-жр 420 | СЕРОШАПКА мр-жр 421 | СИБЕЛИУС мр-жр 422 | СИВЕРС мр-жр 423 | СКАРИ мр-жр 424 | СКВАРЫШ мр-жр 425 | СКЛЯР мр-жр 426 | СКОВОРОДА мр-жр 427 | СКОТТ мр-жр 428 | СКУМ мр-жр 429 | СЛУЧ мр-жр 430 | СМАЛИУС мр-жр 431 | СМИТ мр-жр 432 | СМОЛЯР мр-жр 433 | СНЕГУР мр-жр 434 | СОРОС мр-жр 435 | СОХАЧ мр-жр 436 | СПИНОЗА мр-жр 437 | СТАНКЕВИЧ c 438 | СТАРОДУМ мр-жр 439 | СТЕЛЬМАХ мр-жр 440 | СТРАДИВАРИ мр-жр 441 | СТРАТИЛАТ мр-жр 442 | СТЮАРТ мр-жр 443 | СУАРЕС мр-жр 444 | СУХОЛАПЫЙ мр 445 | СЫРОКОМЛЯ мр-жр 446 | ТАММ мр-жр 447 | ТАНАКИС мр-жр 448 | ТИЦИАН мр-жр 449 | ТОМС мр-жр 450 | ТРАВОЛТА мр-жр 451 | ТРОФИМОФФ мр-жр 452 | ТРУАЙЯ мр-жр 453 | ТУМАШ мр-жр 454 | УИНСЛЕТ мр-жр 455 | УСС мр-жр 456 | ФАЙНГАРТ мр-жр 457 | ФАРАДЕЙ мр-жр 458 | ФАРЕНГЕЙТ мр-жр 459 | ФАУСТ мр-жр 460 | ФЕЙЕРБАХ мр-жр 461 | ФЕРМА мр 462 | ФЕТ мр-жр 463 | ФИЦДЖЕРАЛЬД мр-жр 464 | ФЛАМБЕ мр-жр 465 | ФОСС мр-жр 466 | ФРАДКИС мр-жр 467 | ФРАМ мр-жр 468 | ФРЕЙД мр-жр 469 | ФРУНЗЕ мр-жр 470 | ФУРЬЕ мр-жр 471 | ХАЙЯМ мр-жр 472 | ХАКАМАДА мр-жр 473 | ХАКСЛИ мр-жр 474 | ХАЛАБАЛА мр-жр 475 | ХАМЗА мр-жр 476 | ХАРРИС мр-жр 477 | ХЕЙЕРДАЛ мр-жр 478 | ХЕЙС мр-жр 479 | ХЕМИНГУЭЙ мр-жр 480 | ХЕПБЕРН мр-жр 481 | ХИКМЕТ мр-жр 482 | ХИТРОУ мр-жр 483 | ХОЛМС мр-жр 484 | ХУГЕНБАНД мр-жр 485 | ЦАДАСА мр-жр 486 | ЦИКУ мр-жр 487 | ЦИН мр-жр 488 | ЦЮРУПА мр-жр 489 | ЧАЙКА мр-жр 490 | ЧЕПУРНЫХ мр-жр 491 | ЧИНЕЧЕТТИ мр-жр 492 | ЧУБ мр-жр 493 | ЧУБАЙС мр-жр 494 | ШАРЬЕ мр-жр 495 | ШЕЙНЦИС мр-жр 496 | ШЕКСПИР мр-жр 497 | ШЕЛИЩ мр-жр 498 | ШЕНГЕЛАЯ мр-жр 499 | ШИПОГЛАЗ мр-жр 500 | ШМИДТ мр-жр 501 | ШЛИППЕНБАХ мр-жр 502 | ШНИТКЕ мр-жр 503 | ШОЙГУ мр-жр 504 | ШОЙХЕТ мр-жр 505 | ШОЛОМ-АЛЕЙХЕМ мр-жр 506 | ШТАЛЬБЕ мр-жр 507 | ШТЕРН мр-жр 508 | ШТРАУС мр-жр 509 | ШТРУМ мр-жр 510 | ШТУББЕ мр-жр 511 | ШУБЕРТ мр-жр 512 | ШУЛЕПА мр-жр 513 | ЩОРС мр-жр 514 | ЭЙСФЕЛЬД мр-жр 515 | ЭККАРТ мр-жр 516 | ЭЛЬФРИД мр-жр 517 | ЭНГЕЛЬС мр-жр 518 | ЭТУШ мр-жр 519 | ЯНСОНС мр-жр 520 | КАДДАФИ мр-жр 521 | САРКОЗИ мр-жр 522 | ПРЕСЛИ мр-жр 523 | САВОНАРОЛА мр 524 | КАНДЕЛАКИ мр-жр 525 | МЕДИЧИ мр-жр 526 | ХАНЕКЕ мр-жр 527 | ПАПАНДРЕУ мр-жр 528 | КЕРРИ мр-жр 529 | КРОУЛИ мр-жр 530 | БАСБИ мр-жр 531 | РУНГЕ мр-жр 532 | ТЕЙЛОР мр-жр 533 | ДЕПАРДЬЕ мр-жр 534 | ЧИККОНЕ мр-жр 535 | УИНФРИ мр-жр 536 | ЛАМЕ мр-жр 537 | БУРЕ мр-жр 538 | МОНЕ мр-жр 539 | КРУЧЁНЫХ мр-жр 540 | -------------------------------------------------------------------------------- /src/city.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-use-before-define, no-continue, arrow-parens */ 2 | 3 | import { endsWith } from './utils'; 4 | import { ANDROGYNOUS } from './gender'; 5 | import { 6 | PREPOSITIONAL, 7 | GENITIVE, 8 | constantizeGenderInRules, 9 | findRule, 10 | applyRule, 11 | applyMod, 12 | } from './inclineRules'; 13 | import type { DeclentionT } from './inclineRules'; 14 | import { inclineFirstname } from './incline'; 15 | import { frozenWords, frozenParts, frozenPartsAfter, cityRules } from './rules/cityRules'; 16 | import type { GenderStrT } from './gender'; 17 | 18 | constantizeGenderInRules(cityRules); 19 | 20 | function declineTo(name: string, wordCase: DeclentionT, gender?: GenderStrT) { 21 | if (isFrozen(name, frozenWords)) return name; 22 | return name 23 | .split(/(\s|-)/g) 24 | .map((part, i, parts) => { 25 | if (isFrozenPart(part, i, parts)) return part; 26 | 27 | const rule = findRule(part, ANDROGYNOUS, cityRules); 28 | if (rule) { 29 | return applyRule(rule, part, wordCase); 30 | } 31 | 32 | return inclineFirstname(part, wordCase, gender) || part; 33 | }) 34 | .join(''); 35 | } 36 | 37 | /** 38 | * предложный, в каком городе живете/находитесь? 39 | */ 40 | export function cityIn(name: string, gender?: GenderStrT) { 41 | return declineTo(name, PREPOSITIONAL, gender); 42 | } 43 | 44 | /** 45 | * родительный, из какого города приехали? 46 | */ 47 | export function cityFrom(name: string, gender?: GenderStrT) { 48 | return declineTo(name, GENITIVE, gender); 49 | } 50 | 51 | /** 52 | * винительный, в какой город направляетесь? 53 | */ 54 | export function cityTo(name: string) { 55 | if (!name) return name; 56 | return name 57 | .split(/(\s|-)/g) 58 | .map((part, i, parts) => { 59 | if (isFrozenPart(part, i, parts)) return part; 60 | 61 | const partLower = part.toLowerCase(); 62 | 63 | if (endsWith(partLower, 'а')) { 64 | return applyMod(part, '-у'); 65 | } else if (endsWith(partLower, 'ая')) { 66 | return applyMod(part, '--ую'); 67 | } else if (endsWith(partLower, 'ия')) { 68 | return applyMod(part, '--ию'); 69 | } else if (endsWith(partLower, 'я')) { 70 | return applyMod(part, '-ю'); 71 | } 72 | 73 | return part; 74 | }) 75 | .join(''); 76 | } 77 | 78 | function isFrozen(str: string, words: string[]): boolean { 79 | const strLower = str.toLowerCase(); 80 | for (let k = 0; k < words.length; k++) { 81 | if (words[k] === strLower) { 82 | return true; 83 | } 84 | } 85 | return false; 86 | } 87 | 88 | function isFrozenPart(part: string, i: number, parts: string[]) { 89 | if (parts.length > 1) { 90 | if (isFrozen(part, frozenParts)) return true; 91 | for (let k = 0; k < i; k++) { 92 | if (isFrozen(parts[k], frozenPartsAfter)) return true; 93 | } 94 | } 95 | return false; 96 | } 97 | -------------------------------------------------------------------------------- /src/gender.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-use-before-define, arrow-parens */ 2 | 3 | import { startsWith, endsWith } from './utils'; 4 | import genderRules from './rules/genderRules'; 5 | 6 | export const MALE = 1; 7 | export const FEMALE = 2; 8 | export const ANDROGYNOUS = 4; 9 | 10 | export type GenderConstT = typeof MALE | typeof FEMALE | typeof ANDROGYNOUS; 11 | 12 | export type GenderStrT = 'male' | 'female' | 'androgynous'; 13 | 14 | export type FioT = { 15 | first?: string | null; 16 | last?: string | null; 17 | middle?: string | null; 18 | }; 19 | 20 | export type GenderRulesT = { 21 | androgynous?: string[]; 22 | female?: string[]; 23 | male?: string[]; 24 | }; 25 | 26 | export type GenderRuleSetT = { 27 | exceptions?: GenderRulesT; 28 | suffixes?: GenderRulesT; 29 | }; 30 | 31 | export function getFG(str: string): GenderConstT | null { 32 | return getGenderByRuleSet(str, genderRules.firstname); 33 | } 34 | 35 | export function getLG(str: string): GenderConstT | null { 36 | return getGenderByRuleSet(str, genderRules.lastname); 37 | } 38 | 39 | export function getMG(str: string): GenderConstT | null { 40 | return getGenderByRuleSet(str, genderRules.middlename); 41 | } 42 | 43 | export function getFirstnameGender(str: string): GenderStrT | null { 44 | return convertGenderStr(getFG(str)); 45 | } 46 | 47 | export function getLastnameGender(str: string): GenderStrT | null { 48 | return convertGenderStr(getLG(str)); 49 | } 50 | 51 | export function getMiddlenameGender(str: string): GenderStrT | null { 52 | return convertGenderStr(getMG(str)); 53 | } 54 | 55 | export function mergeGenders( 56 | g1: GenderConstT | null, 57 | g2: GenderConstT | null 58 | ): GenderConstT | null { 59 | if (g1 === ANDROGYNOUS) return g2; 60 | if (g2 === ANDROGYNOUS) return g1; 61 | if (g1 === g2) return g1; 62 | return null; 63 | } 64 | 65 | export function _getGender(fio: FioT): GenderConstT | null { 66 | let result = ANDROGYNOUS as GenderConstT | null; 67 | const { middle, first, last } = fio; 68 | 69 | if (middle) { 70 | result = mergeGenders(result, getMG(middle.trim())); 71 | } 72 | 73 | if (first) { 74 | result = mergeGenders(result, getFG(first.trim())); 75 | } 76 | 77 | if (last) { 78 | const lastGender = getLG(last.trim()); 79 | if (lastGender !== null) { 80 | result = mergeGenders(result, lastGender); 81 | } 82 | } 83 | 84 | return result; 85 | } 86 | 87 | export function getGender(fio: FioT): GenderStrT | null { 88 | return convertGenderStr(_getGender(fio)); 89 | } 90 | 91 | export function getGenderByRuleSet(name: string, ruleSet: GenderRuleSetT): GenderConstT | null { 92 | if (!name || !ruleSet) { 93 | return null; 94 | } 95 | const nameLower = name.toLowerCase(); 96 | if (ruleSet.exceptions) { 97 | const gender = getGenderByRule(ruleSet.exceptions, (some) => { 98 | if (startsWith(some, '-')) { 99 | return endsWith(nameLower, some.substr(1)); 100 | } 101 | return some === nameLower; 102 | }); 103 | if (gender) return gender; 104 | } 105 | return ruleSet.suffixes 106 | ? getGenderByRule(ruleSet.suffixes, (some) => endsWith(nameLower, some)) 107 | : null; 108 | } 109 | 110 | export function getGenderByRule( 111 | rules: GenderRulesT, 112 | matchFn: (some: string) => boolean 113 | ): GenderConstT | null { 114 | const genders = Object.keys(rules).filter((genderKey) => { 115 | const array = (rules as any)[genderKey]; 116 | return Array.isArray(array) && array.some(matchFn); 117 | }); 118 | if (genders.length !== 1) { 119 | // DEBUG SEVERAL RULES 120 | Object.keys(rules).forEach((genderKey) => { 121 | const array = (rules as any)[genderKey]; 122 | if (Array.isArray(array) && array.some(matchFn)) { 123 | // eslint-disable-next-line 124 | // console.log(genderKey, array); 125 | } 126 | }); 127 | 128 | return null; 129 | } 130 | return getGenderConst(genders[0]); 131 | } 132 | 133 | export function getGenderConst(key: string | GenderConstT | null | undefined): GenderConstT | null { 134 | switch (key) { 135 | case 'male': 136 | case MALE: 137 | return MALE; 138 | case 'female': 139 | case FEMALE: 140 | return FEMALE; 141 | case 'androgynous': 142 | case ANDROGYNOUS: 143 | return ANDROGYNOUS; 144 | default: 145 | return null; 146 | } 147 | } 148 | 149 | export function convertGenderStr( 150 | cnst: string | GenderConstT | null | undefined 151 | ): GenderStrT | null { 152 | switch (cnst) { 153 | case 'male': 154 | case MALE: 155 | return 'male'; 156 | case 'female': 157 | case FEMALE: 158 | return 'female'; 159 | case 'androgynous': 160 | case ANDROGYNOUS: 161 | return 'androgynous'; 162 | default: 163 | return null; 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /src/incline.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-use-before-define, no-continue, arrow-parens */ 2 | 3 | import { getGender, getFG, getLG, getMG } from './gender'; 4 | import { constantizeGenderInRules, inclineByRules } from './inclineRules'; 5 | import rulesLastname from './rules/inclineRulesLastname'; 6 | import rulesMiddlename from './rules/inclineRulesMiddlename'; 7 | import rulesFirstname from './rules/inclineRulesFirstname'; 8 | 9 | import type { GenderStrT } from './gender'; 10 | import type { DeclentionStrT } from './inclineRules'; 11 | 12 | constantizeGenderInRules(rulesLastname); 13 | constantizeGenderInRules(rulesMiddlename); 14 | constantizeGenderInRules(rulesFirstname); 15 | 16 | export type LvovichPersonT = { 17 | first?: string | null; 18 | last?: string | null; 19 | middle?: string | null; 20 | gender?: GenderStrT | null; 21 | }; 22 | 23 | export function inclineFirstname( 24 | str: string, 25 | declension: DeclentionStrT = 'accusative', 26 | gender?: GenderStrT | null 27 | ): string { 28 | return inclineByRules(str, declension, gender || getFG(str), rulesFirstname); 29 | } 30 | 31 | export function inclineLastname( 32 | str: string, 33 | declension: DeclentionStrT = 'accusative', 34 | gender?: GenderStrT | null 35 | ): string { 36 | return inclineByRules(str, declension, gender || getLG(str), rulesLastname); 37 | } 38 | 39 | export function inclineMiddlename( 40 | str: string, 41 | declension: DeclentionStrT = 'accusative', 42 | gender?: GenderStrT | null 43 | ): string { 44 | return inclineByRules(str, declension, gender || getMG(str), rulesMiddlename); 45 | } 46 | 47 | export function incline( 48 | person: Partial, 49 | declension?: DeclentionStrT 50 | ): LvovichPersonT { 51 | const res = {} as LvovichPersonT; 52 | 53 | const gender = getGender(person); 54 | res.gender = gender; 55 | 56 | const { first, last, middle } = person; 57 | if (first) { 58 | res.first = inclineFirstname(first.trim(), declension, gender); 59 | } 60 | if (last) { 61 | res.last = inclineLastname(last.trim(), declension, gender); 62 | } 63 | if (middle) { 64 | res.middle = inclineMiddlename(middle.trim(), declension, gender); 65 | } 66 | 67 | return res; 68 | } 69 | -------------------------------------------------------------------------------- /src/inclineRules.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-use-before-define, no-continue, arrow-parens */ 2 | 3 | import { endsWith } from './utils'; 4 | import { getGenderConst, ANDROGYNOUS } from './gender'; 5 | import type { GenderStrT, GenderConstT } from './gender'; 6 | 7 | export const NOMINATIVE = 1; // именительный 8 | export const GENITIVE = 2; // родительный 9 | export const DATIVE = 3; // дательный 10 | export const ACCUSATIVE = 4; // винительный 11 | export const INSTRUMENTAL = 5; // творительный 12 | export const PREPOSITIONAL = 6; // предложный 13 | 14 | export type DeclentionT = 15 | | typeof NOMINATIVE 16 | | typeof GENITIVE 17 | | typeof DATIVE 18 | | typeof ACCUSATIVE 19 | | typeof INSTRUMENTAL 20 | | typeof PREPOSITIONAL; 21 | 22 | export type DeclentionStrT = 23 | | 'nominative' 24 | | 'genitive' 25 | | 'dative' 26 | | 'accusative' 27 | | 'instrumental' 28 | | 'prepositional' 29 | | DeclentionT; 30 | 31 | export type DeclentionModsT = [string, string, string, string, string] | []; 32 | 33 | export type DeclensionRuleT = { 34 | gender?: GenderStrT | GenderConstT | null; 35 | test: string[]; 36 | mods: DeclentionModsT; 37 | tags?: string[]; 38 | }; 39 | 40 | export type DeclensionRuleSetT = { 41 | exceptions?: DeclensionRuleT[]; 42 | suffixes?: DeclensionRuleT[]; 43 | }; 44 | 45 | export function constantizeGenderInRules(rules: DeclensionRuleSetT) { 46 | if (Array.isArray(rules.exceptions)) { 47 | rules.exceptions.forEach((rule) => { 48 | rule.gender = getGenderConst(rule.gender); // eslint-disable-line 49 | }); 50 | } 51 | if (Array.isArray(rules.suffixes)) { 52 | rules.suffixes.forEach((rule) => { 53 | rule.gender = getGenderConst(rule.gender); // eslint-disable-line 54 | }); 55 | } 56 | } 57 | 58 | export function inclineByRules( 59 | str: string, 60 | declensionStr: DeclentionT | DeclentionStrT, 61 | genderStr: GenderConstT | GenderStrT | null, 62 | ruleSet: DeclensionRuleSetT 63 | ): string { 64 | const declension = getDeclensionConst(declensionStr); 65 | const gender = getGenderConst(genderStr); 66 | 67 | const parts = str.split('-'); 68 | const result = []; 69 | 70 | for (let i = 0; i < parts.length; i++) { 71 | const part = parts[i]; 72 | const isFirstWord = i === 0 && parts.length > 1; 73 | 74 | const rule = findRule(part, gender, ruleSet, { 75 | firstWord: isFirstWord, 76 | }); 77 | 78 | if (rule) { 79 | result.push(applyRule(rule, part, declension)); 80 | } else { 81 | result.push(part); 82 | } 83 | } 84 | return result.join('-'); 85 | } 86 | 87 | export function findRule( 88 | str: string, 89 | gender: GenderConstT | null, 90 | ruleSet: DeclensionRuleSetT, 91 | tags: { firstWord?: boolean } = {} 92 | ): DeclensionRuleT | null { 93 | if (!str) { 94 | return null; 95 | } 96 | const strLower = str.toLowerCase(); 97 | 98 | const tagList = [] as string[]; 99 | Object.keys(tags).forEach((key) => { 100 | if ((tags as any)[key]) { 101 | tagList.push(key); 102 | } 103 | }); 104 | 105 | if (ruleSet.exceptions) { 106 | const rule = findExactRule(ruleSet.exceptions, gender, (some) => some === strLower, tagList); 107 | if (rule) return rule; 108 | } 109 | 110 | return ruleSet.suffixes 111 | ? findExactRule(ruleSet.suffixes, gender, (some) => endsWith(strLower, some), tagList) 112 | : null; 113 | } 114 | 115 | export function findExactRule( 116 | rules: DeclensionRuleT[], 117 | gender: GenderConstT | null, 118 | matchFn: (some: string) => boolean, 119 | tags: string[] = [] 120 | ): DeclensionRuleT | null { 121 | for (let i = 0; i < rules.length; i++) { 122 | const rule = rules[i]; 123 | 124 | // rule with tag should be skipped if tag not listed in args 125 | if (rule.tags) { 126 | if (!rule.tags.find((t) => tags.indexOf(t) !== -1)) { 127 | continue; 128 | } 129 | } 130 | 131 | // rule must have same gender or be `androgynous` 132 | if (rule.gender !== ANDROGYNOUS && gender !== rule.gender) { 133 | continue; 134 | } 135 | 136 | if (rule.test) { 137 | for (let j = 0; j < rule.test.length; j++) { 138 | if (matchFn(rule.test[j])) { 139 | return rule; 140 | } 141 | } 142 | } 143 | } 144 | return null; 145 | } 146 | 147 | function getModByIdx(mods: DeclentionModsT, i: number): string { 148 | if (mods && mods.length >= i) { 149 | return mods[i]; 150 | } 151 | return '.'; 152 | } 153 | 154 | export function applyRule( 155 | rule: DeclensionRuleT | { mods: DeclentionModsT }, 156 | str: string, 157 | declension?: DeclentionT | null 158 | ) { 159 | let mod; 160 | switch (declension) { 161 | case NOMINATIVE: 162 | mod = '.'; 163 | break; 164 | case GENITIVE: 165 | mod = getModByIdx(rule.mods, 0); 166 | break; 167 | case DATIVE: 168 | mod = getModByIdx(rule.mods, 1); 169 | break; 170 | case ACCUSATIVE: 171 | mod = getModByIdx(rule.mods, 2); 172 | break; 173 | case INSTRUMENTAL: 174 | mod = getModByIdx(rule.mods, 3); 175 | break; 176 | case PREPOSITIONAL: 177 | mod = getModByIdx(rule.mods, 4); 178 | break; 179 | default: 180 | mod = '.'; 181 | } 182 | 183 | return applyMod(str, mod); 184 | } 185 | 186 | export function applyMod(str: string, mod: string): string { 187 | for (let i = 0; i < mod.length; i++) { 188 | const chr = mod[i]; 189 | switch (chr) { 190 | case '.': 191 | break; 192 | case '-': 193 | str = str.substr(0, str.length - 1); // eslint-disable-line no-param-reassign 194 | break; 195 | default: 196 | str += chr; // eslint-disable-line no-param-reassign 197 | } 198 | } 199 | return str; 200 | } 201 | 202 | export function getDeclensionConst(key?: DeclentionStrT | string | null): DeclentionT | null { 203 | switch (key) { 204 | case 'nominative': 205 | case NOMINATIVE: 206 | return NOMINATIVE; 207 | case 'genitive': 208 | case GENITIVE: 209 | return GENITIVE; 210 | case 'dative': 211 | case DATIVE: 212 | return DATIVE; 213 | case 'accusative': 214 | case ACCUSATIVE: 215 | return ACCUSATIVE; 216 | case 'instrumental': 217 | case INSTRUMENTAL: 218 | return INSTRUMENTAL; 219 | case 'prepositional': 220 | case PREPOSITIONAL: 221 | return PREPOSITIONAL; 222 | default: 223 | return null; 224 | } 225 | } 226 | 227 | export function getDeclensionStr(cnst: DeclentionT | string | null): DeclentionStrT | null { 228 | switch (cnst) { 229 | case 'nominative': 230 | case NOMINATIVE: 231 | return 'nominative'; 232 | case 'genitive': 233 | case GENITIVE: 234 | return 'genitive'; 235 | case 'dative': 236 | case DATIVE: 237 | return 'dative'; 238 | case 'accusative': 239 | case ACCUSATIVE: 240 | return 'accusative'; 241 | case 'instrumental': 242 | case INSTRUMENTAL: 243 | return 'instrumental'; 244 | case 'prepositional': 245 | case PREPOSITIONAL: 246 | return 'prepositional'; 247 | default: 248 | return null; 249 | } 250 | } 251 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { incline, inclineFirstname, inclineLastname, inclineMiddlename } from './incline'; 2 | 3 | import { getFirstnameGender, getLastnameGender, getMiddlenameGender, getGender } from './gender'; 4 | 5 | import { cityIn, cityFrom, cityTo } from './city'; 6 | 7 | export { 8 | incline, 9 | inclineFirstname, 10 | inclineLastname, 11 | inclineMiddlename, 12 | getGender, 13 | getFirstnameGender, 14 | getLastnameGender, 15 | getMiddlenameGender, 16 | cityIn, 17 | cityFrom, 18 | cityTo, 19 | }; 20 | -------------------------------------------------------------------------------- /src/rules/cityRules.ts: -------------------------------------------------------------------------------- 1 | import { ANDROGYNOUS } from '../gender'; 2 | import type { DeclentionModsT, DeclensionRuleSetT } from '../inclineRules'; 3 | 4 | export type DeclensionCityRuleT = { 5 | test: string[]; 6 | mods: DeclentionModsT; 7 | tags?: string[]; 8 | }; 9 | 10 | export type DeclensionCityRuleSetT = { 11 | exceptions: DeclensionCityRuleT[]; 12 | suffixes: DeclensionCityRuleT[]; 13 | }; 14 | 15 | export const frozenWords = ['форт-шевченко']; 16 | 17 | export const frozenParts = [ 18 | '-', 19 | ' ', 20 | 'в', 21 | 'на', 22 | 'баден', // баден-Бадене 23 | 'бледно', 24 | 'буэнос', 25 | 'вице', // вице-президенту 26 | 'гаврилов', 27 | 'йошкар', // Йошкар-Ола 28 | 'коста', 29 | 'лос', 30 | 'норд', 31 | 'нью', // Нью-Йорку, 32 | 'орехово', 33 | 'принс', 34 | 'сан', // Сан-Франциско 35 | 'санкт', // Санкт-Петербург 36 | 'санта', 37 | 'северо', 38 | 'ситтард', 39 | 'темно', 40 | 'улан', 41 | 'усолье', // Усолье-Сибирское 42 | 'усть', // Усть-Каменогорске, Усть-Илимск 43 | 'форт', // Форт-Шевченко 44 | 'царь', // царь-пушке 45 | 'экс', // экс-чемпиону 46 | 'юго', 47 | 'юрьев', 48 | 'нур', 49 | 'соль', 50 | ]; 51 | 52 | // do not decline words after this words 53 | export const frozenPartsAfter = ['село', 'поселок', 'аул', 'город', 'деревня', 'урочище']; 54 | 55 | const cityInflections: DeclensionCityRuleSetT = { 56 | exceptions: [ 57 | { 58 | test: ['сочи', 'тбилиси', 'хельсинки'], 59 | mods: ['', '', '', '', ''], 60 | }, 61 | { 62 | test: ['село', 'озеро', 'место'], 63 | mods: ['-а', '-у', '', 'м', '-е'], 64 | }, 65 | { 66 | test: ['область'], 67 | mods: ['-и', '-и', '', 'ю', '-и'], 68 | }, 69 | { 70 | test: ['деревня'], 71 | mods: ['-и', '-е', '-ю', '-ей', '-е'], 72 | }, 73 | { 74 | test: ['море'], 75 | mods: ['-я', '-ю', '', 'м', ''], 76 | }, 77 | { 78 | test: ['холм'], 79 | mods: ['а', 'у', '', 'ом', 'е'], 80 | }, 81 | { 82 | test: ['орел', 'орёл'], // Орел, Орёл 83 | mods: ['--ла', '--лу', '--ла', '--лом', '--ле'], 84 | }, 85 | { 86 | test: ['крым'], 87 | mods: ['-ма', '-му', '-ма', '-ом', '-му'], 88 | }, 89 | { 90 | test: ['бор'], 91 | mods: ['а', 'у', '', 'ом', 'у'], 92 | }, 93 | ], 94 | suffixes: [ 95 | { 96 | test: ['чёк', 'чек'], // Волочёк, Чернечек 97 | mods: ['--ка', '--ку', '', '--ком', '--ке'], 98 | }, 99 | { 100 | test: ['чик', 'ич'], // Чик, Углич 101 | mods: ['а', 'у', '', 'ом', 'е'], 102 | }, 103 | { 104 | test: ['жний', 'хний', 'шний', 'щий'], // Нижний, Вышний, Верхний 105 | mods: ['--его', '--ему', '', '-м', '--ем'], 106 | }, 107 | { 108 | test: ['ще'], // Хлевище, Городище 109 | mods: ['-а', '-у', '', 'м', ''], 110 | }, 111 | { 112 | test: ['щи'], // Мытищи 113 | mods: ['-', '-ам', '', '-ами', '-ах'], 114 | }, 115 | { 116 | test: ['чье'], // Щучье 117 | mods: ['-я', '-ю', '', 'м', ''], 118 | }, 119 | { 120 | test: ['ель', 'пль'], // норильский никель, Гузерипль 121 | mods: ['-я', '-ю', '', '-ем', '-е'], 122 | }, 123 | { 124 | test: ['чь'], // Холмечь 125 | mods: ['-и', '-и', '', 'ю', '-и'], 126 | }, 127 | { 128 | test: ['чи'], // Чепеничи 129 | mods: ['-ей', '-ам', '', '-ами', '-ах'], 130 | }, 131 | { 132 | test: ['ые', 'ие'], // Набережные 133 | mods: ['-х', '-м', '', '-ми', '-х'], 134 | }, 135 | { 136 | test: ['ый', 'ий', 'ое'], // Рижский, Раменское 137 | mods: ['--ого', '--ому', '', '-м', '--ом'], 138 | }, 139 | { 140 | test: ['ая'], // Рижская 141 | mods: ['--ой', '--ой', '--ую', '--ой', '--ой'], 142 | }, 143 | { 144 | test: ['гиев'], // Сергиев Посад, но не Киев 145 | mods: ['а', 'у', '', 'ым', 'ом'], 146 | }, 147 | { 148 | test: ['ны', 'вцы'], // Челны, Черновцы 149 | mods: ['-ов', '-ам', '', '-ами', '-ах'], 150 | }, 151 | { 152 | test: ['ша'], // Ропша 153 | mods: ['-и', '-е', '-у', '-ей', '-е'], 154 | }, 155 | { 156 | test: [ 157 | 'ры', // Чебоксары, Шушары 158 | 'цы', // Бельцы 159 | 'ды', // минеральные воды 160 | 'ги', // верхние киги 161 | ], 162 | mods: ['-', '-ам', '', '-ами', '-ах'], 163 | }, 164 | { 165 | test: ['амень'], // Камень, но не Тюмень 166 | mods: ['---ня', '---ню', '', '---нем', '---не'], 167 | }, 168 | { 169 | test: [ 170 | 'ьн', // Кёльн 171 | 'нц', // Гленц 172 | 'мм', // Гримм 173 | ], 174 | mods: ['а', 'у', '', 'ом', 'е'], 175 | }, 176 | ], 177 | // Склонения городов можно подсмотреть тут https://ru.wiktionary.org/wiki/%D0%9A%D1%91%D0%BB%D1%8C%D0%BD 178 | }; 179 | 180 | export const cityRules: DeclensionRuleSetT = { 181 | exceptions: cityInflections.exceptions.map((o) => ({ gender: ANDROGYNOUS, ...o })), 182 | suffixes: cityInflections.suffixes.map((o) => ({ gender: ANDROGYNOUS, ...o })), 183 | }; 184 | -------------------------------------------------------------------------------- /src/rules/genderRules.ts: -------------------------------------------------------------------------------- 1 | import type { GenderRuleSetT } from '../gender'; 2 | 3 | const middlename: GenderRuleSetT = { 4 | suffixes: { 5 | female: ['на', 'кызы', 'гызы'], 6 | male: ['ич', 'оглы', 'улы', 'уулу'], 7 | }, 8 | }; 9 | 10 | const lastname: GenderRuleSetT = { 11 | exceptions: { 12 | androgynous: ['бова', 'регин', 'дарвин', 'пэйлин', 'грин', 'цин', 'шенгелая'], 13 | }, 14 | suffixes: { 15 | androgynous: [ 16 | 'ан', 17 | 'ко', 18 | 'дзе', 19 | 'швили', 20 | 'ян', 21 | 'к', 22 | 'ер', 23 | 'ц', 24 | 'г', 25 | 'йн', 26 | 'дт', 27 | 'ен', 28 | 'ич', 29 | 'о', 30 | 'ун', 31 | ], 32 | female: ['ова', 'ая', 'ына', 'ина', 'ева', 'ска', 'ёва'], 33 | male: ['кий', 'ов', 'ын', 'ев', 'ин', 'ёв', 'хий', 'ний', 'ый', 'ой'], 34 | }, 35 | }; 36 | 37 | const firstname: GenderRuleSetT = { 38 | exceptions: { 39 | androgynous: [ 40 | 'анри', 41 | 'алвард', 42 | 'валери', 43 | 'женя', 44 | 'закия', 45 | 'захария', 46 | 'иона', 47 | 'кири', 48 | 'ким', 49 | 'муса', 50 | 'райхон', 51 | 'саша', 52 | 'сева', 53 | 'ардак', 54 | 'арман', 55 | 'асыл', 56 | 'баглан', 57 | 'бакыт', 58 | 'бахыт', 59 | 'еркежан', 60 | 'жанат', 61 | 'жаркын', 62 | 'куаныш', 63 | 'манат', 64 | 'мереке', 65 | 'рауан', 66 | 'сымбат', 67 | 'тлеухан', 68 | 'умит', 69 | 'улжалгас', 70 | 'ырыс', 71 | 'айбала', 72 | 'акбала', 73 | 'ирза', 74 | 'арши', 75 | 'амиль', 76 | ], 77 | male: [ 78 | 'аба', 79 | 'абиба', 80 | 'савва', 81 | 'лёва', 82 | 'вова', 83 | '-ага', 84 | 'агга', 85 | 'серега', 86 | 'алиада', 87 | 'муктада', 88 | 'абида', 89 | 'алда', 90 | 'маджуда', 91 | 'нурлыхуда', 92 | 'гиа', 93 | 'элиа', 94 | 'гарсиа', 95 | 'вавила', 96 | 'гавриила', 97 | 'генка', 98 | 'лука', 99 | 'дима', 100 | 'зосима', 101 | 'тима', 102 | 'фима', 103 | 'фома', 104 | 'кузьма', 105 | 'жора', 106 | 'миша', 107 | 'ермила', 108 | 'данила', 109 | 'гаврила', 110 | 'абдалла', 111 | 'аталла', 112 | 'абдилла', 113 | 'атилла', 114 | 'кайролла', 115 | 'абула', 116 | 'свитлана', 117 | 'бена', 118 | 'гена', 119 | 'агелина', 120 | 'джанна', 121 | 'кришна', 122 | 'степа', 123 | 'дра', 124 | 'назера', 125 | 'валера', 126 | 'эстера', 127 | 'двойра', 128 | 'калистра', 129 | 'заратустра', 130 | 'юра', 131 | 'иса', 132 | 'аиса', 133 | 'халиса', 134 | 'холиса', 135 | 'валенса', 136 | 'мусса', 137 | 'ата', 138 | 'паата', 139 | 'алета', 140 | 'никита', 141 | 'мота', 142 | 'шота', 143 | 'фаста', 144 | 'коста', 145 | 'маритта', 146 | 'малюта', 147 | 'васюта', 148 | 'вафа', 149 | 'мустафа', 150 | 'ганифа', 151 | 'лев', 152 | 'яков', 153 | 'константин', 154 | 'марсель', 155 | 'рамиль', 156 | 'эмиль', 157 | 'бактыгуль', 158 | 'даниэль', 159 | 'игорь', 160 | 'арминэ', 161 | 'изя', 162 | 'кузя', 163 | 'гия', 164 | 'мазия', 165 | 'кирикия', 166 | 'ркия', 167 | 'еркия', 168 | 'эркия', 169 | 'гулия', 170 | 'аксания', 171 | 'закария', 172 | 'зекерия', 173 | 'гарсия', 174 | 'шендля', 175 | 'филя', 176 | 'вилля', 177 | 'толя', 178 | 'коля', 179 | 'ваня', 180 | 'саня', 181 | 'загиря', 182 | 'боря', 183 | 'цайся', 184 | 'вася', 185 | 'ося', 186 | 'петя', 187 | 'витя', 188 | 'митя', 189 | 'костя', 190 | 'илья', 191 | 'абдала', 192 | 'абдель', 193 | 'фидель', 194 | 'фридель', 195 | 'абдилла', 196 | 'аталла', 197 | 'абла', 198 | 'лазарь', 199 | 'ава', 200 | 'вовка', 201 | 'семён', 202 | ], 203 | female: [ 204 | 'судаба', 205 | 'сураба', 206 | 'любава', 207 | 'джанлука', 208 | 'варвара', 209 | 'наташа', 210 | 'зайнаб', 211 | 'любов', 212 | 'сольвейг', 213 | 'шакед', 214 | 'аннаид', 215 | 'ингрид', 216 | 'синди', 217 | 'аллаберди', 218 | 'лали', 219 | 'натали', 220 | 'лили', 221 | 'нелли', 222 | 'элли', 223 | 'эмили', 224 | 'амили', 225 | 'адели', 226 | 'гулькай', 227 | 'алтынай', 228 | 'гюнай', 229 | 'гюльчитай', 230 | 'нурангиз', 231 | 'лиз', 232 | 'элиз', 233 | 'ботагоз', 234 | 'юлдуз', 235 | 'диляфруз', 236 | 'габи', 237 | 'сажи', 238 | 'фанни', 239 | 'мери', 240 | 'элдари', 241 | 'эльдари', 242 | 'хилари', 243 | 'хиллари', 244 | 'аннемари', 245 | 'розмари', 246 | 'товсари', 247 | 'ансари', 248 | 'одри', 249 | 'тери', 250 | 'ири', 251 | 'катя', 252 | 'катри', 253 | 'мэри', 254 | 'сатаней', 255 | 'ефтений', 256 | 'верунчик', 257 | 'гюзел', 258 | 'этел', 259 | 'рэйчел', 260 | 'джил', 261 | 'мерил', 262 | 'нинелл', 263 | 'бурул', 264 | 'ахлам', 265 | 'майрам', 266 | 'махаррам', 267 | 'мириам', 268 | 'дилярам', 269 | 'асем', 270 | 'мерьем', 271 | 'мирьем', 272 | 'эркаим', 273 | 'гулаим', 274 | 'айгерим', 275 | 'марьям', 276 | 'мирьям', 277 | 'эван', 278 | 'гульжиган', 279 | 'айдан', 280 | 'айжан', 281 | 'вивиан', 282 | 'гульжиан', 283 | 'лилиан', 284 | 'мариан', 285 | 'саиман', 286 | 'джоан', 287 | 'чулпан', 288 | 'лоран', 289 | 'моран', 290 | 'гульшан', 291 | 'аделин', 292 | 'жаклин', 293 | 'карин', 294 | 'каролин', 295 | 'каталин', 296 | 'катрин', 297 | 'керстин', 298 | 'кэтрин', 299 | 'мэрилин', 300 | 'рузалин', 301 | 'хелин', 302 | 'цеткин', 303 | 'ширин', 304 | 'элисон', 305 | 'дурсун', 306 | 'кристин', 307 | 'гульжиян', 308 | 'марьян', 309 | 'ренато', 310 | 'зейнеп', 311 | 'санабар', 312 | 'дильбар', 313 | 'гулизар', 314 | 'гульзар', 315 | 'пилар', 316 | 'дагмар', 317 | 'элинар', 318 | 'нилуфар', 319 | 'анхар', 320 | 'гаухар', 321 | 'естер', 322 | 'эстер', 323 | 'дженнифер', 324 | 'линор', 325 | 'элинор', 326 | 'элеонор', 327 | 'айнур', 328 | 'гульнур', 329 | 'шамсинур', 330 | 'элнур', 331 | 'ильсияр', 332 | 'нигяр', 333 | 'сигитас', 334 | 'агнес', 335 | 'анес', 336 | 'долорес', 337 | 'инес', 338 | 'анаис', 339 | 'таис', 340 | 'эллис', 341 | 'элис', 342 | 'кларис', 343 | 'амнерис', 344 | 'айрис', 345 | 'дорис', 346 | 'беатрис', 347 | 'грейс', 348 | 'грэйс', 349 | 'ботагос', 350 | 'маргос', 351 | 'джулианс', 352 | 'арус', 353 | 'диляфрус', 354 | 'саодат', 355 | 'зулхижат', 356 | 'хамат', 357 | 'патимат', 358 | 'хатимат', 359 | 'альжанат', 360 | 'маймунат', 361 | 'гульшат', 362 | 'рут', 363 | 'иргаш', 364 | 'айнаш', 365 | 'агнеш', 366 | 'зауреш', 367 | 'тэрбиш', 368 | 'ануш', 369 | 'азгануш', 370 | 'гаруш', 371 | 'николь', 372 | 'адась', 373 | 'адула', 374 | 'ахмадула', 375 | 'гейбадула', 376 | 'лив', 377 | 'ираги', 378 | 'пегги', 379 | 'абдурефи', 380 | 'адерми', 381 | 'лакшми', 382 | 'мими', 383 | 'наоми', 384 | 'изабель', 385 | 'абигейль', 386 | 'зебо', 387 | 'аширбу', 388 | 'судаба', 389 | 'айсулу', 390 | 'айши', 391 | 'жанет', 392 | 'гузаль', 393 | 'сапият', 394 | 'зауре', 395 | 'кармен', 396 | 'мадлен', 397 | 'алсу', 398 | 'айсу', 399 | 'амели', 400 | '-бану', 401 | 'ассоль', 402 | 'николь', 403 | ], 404 | }, 405 | suffixes: { 406 | androgynous: [ 407 | 'щи', // Мытищи 408 | 'ки', // Химки 409 | ], 410 | male: [ 411 | 'аба', 412 | 'б', 413 | 'ав', 414 | 'ев', 415 | 'ов', 416 | 'во', 417 | 'г', 418 | 'д', 419 | 'ж', 420 | 'з', 421 | 'би', 422 | 'ди', 423 | 'жи', 424 | 'ли', 425 | 'гани', 426 | 'ит', 427 | 'до', 428 | 'айт', 429 | 'юм', 430 | 'дула', 431 | 'ив', 432 | 'ги', 433 | 'улла', 434 | 'улль', 435 | 'фи', 436 | 'аль', 437 | 'ми', 438 | 'бель', 439 | 'була', 440 | 'йль', 441 | 'яй', 442 | 'бо', 443 | 'бу', 444 | 'кр', 445 | 'ыль', 446 | 'ыт', 447 | 'вва', 448 | 'вель', 449 | 'вни', 450 | 'аба', 451 | 'бала', 452 | 'улу', 453 | 'рза', 454 | 'ши', 455 | 'паша', 456 | 'го', 457 | 'но', 458 | 'ет', 459 | 'ят', 460 | 'ре', 461 | 'ри', 462 | 'ай', 463 | 'ей', 464 | 'ий', 465 | 'ой', 466 | 'ый', 467 | 'к', 468 | 'л', 469 | 'ам', 470 | 'ем', 471 | 'им', 472 | 'ом', 473 | 'ум', 474 | 'ым', 475 | 'ям', 476 | 'ан', 477 | 'бен', 478 | 'вен', 479 | 'ген', 480 | 'ден', 481 | 'ин', 482 | 'сейн', 483 | 'он', 484 | 'ун', 485 | 'ян', 486 | 'ио', 487 | 'ло', 488 | 'ро', 489 | 'то', 490 | 'шо', 491 | 'п', 492 | 'ар', 493 | 'др', 494 | 'ер', 495 | 'ир', 496 | 'ор', 497 | 'тр', 498 | 'ур', 499 | 'ыр', 500 | 'яр', 501 | 'ас', 502 | 'ес', 503 | 'ис', 504 | 'йс', 505 | 'кс', 506 | 'мс', 507 | 'ос', 508 | 'нс', 509 | 'рс', 510 | 'ус', 511 | 'юс', 512 | 'яс', 513 | 'ат', 514 | 'кт', 515 | 'нт', 516 | 'рт', 517 | 'ст', 518 | 'ут', 519 | 'ф', 520 | 'х', 521 | 'ш', 522 | 'ы', 523 | 'сь', 524 | 'тау', // Актау, Ерейментау, Каратау, Кокшетау, Кентау 525 | 'ен', // Жанаозен, Каскелен 526 | 'коль', // Акколь 527 | 'рау', // Атырау 528 | 'обе', // Актобе, Уштобе 529 | 'убе', 530 | 'иль', // Есиль, Адиль 531 | 'ево', // Булаево 532 | 'ово', // Медведково 533 | 'шу', // Шу, 534 | 'ду', // Катманду 535 | 'пуль', // Ливерпуль 536 | 'нко', // Ливерпуль 537 | 'су', // Аксу, Карасу 538 | 'вль', // Ярославль 539 | 'оль', // Ставрополь, Севастополь, Симферополь 540 | 'ёв', // город Королёв 541 | 'ём', // Артём 542 | 'ец', // Елец, Череповец 543 | 'сс', // Миасс 544 | 'льс', // Энгельс 545 | 'хт', // Утрехт 546 | 'рн', // Апелдорн 547 | 'дт', // Кронштадт 548 | ], 549 | female: [ 550 | 'иба', 551 | 'люба', 552 | 'лава', 553 | 'ева', 554 | 'га', 555 | 'да', 556 | 'еа', 557 | 'иза', 558 | 'иа', 559 | 'ика', 560 | 'нка', 561 | 'ска', 562 | 'ела', 563 | 'ила', 564 | 'илла', 565 | 'эла', 566 | 'има', 567 | 'на', 568 | 'ра', 569 | 'са', 570 | 'та', 571 | 'фа', 572 | 'еса', 573 | 'сса', 574 | 'гуль', 575 | 'куль', 576 | 'нуэль', 577 | 'гюль', 578 | 'нэ', 579 | 'ая', 580 | 'ея', 581 | 'ия', 582 | 'йя', 583 | 'ля', 584 | 'мя', 585 | 'оя', 586 | 'ря', 587 | 'ся', 588 | 'вья', 589 | 'лья', 590 | 'мья', 591 | 'нья', 592 | 'рья', 593 | 'сья', 594 | 'тья', 595 | 'фья', 596 | 'зя', 597 | 'нша', // Тайынша 598 | 'ха', // Шемонаиха 599 | 'тка', // Мамлютка 600 | 'нь', // Сарань, Тюмень 601 | 'чь', // Сарань, Керчь 602 | 'мь', // Сарань, Пермь 603 | 'ерь', // Тверь 604 | 'овка', // Покровка 605 | 'евка', // Сергеевка 606 | 'мба', // Эмба 607 | 'зь', // Бизь, Грязь 608 | 'лка', 609 | 'сала', 610 | 'бла', 611 | 'арь', 612 | 'ума', 613 | 'пи', 614 | 'дель', 615 | 'не', 616 | 'жка', 617 | 'си', 618 | 'ибе', 619 | 'абе', 620 | 'елла', 621 | 'ие', 622 | 'фе', 623 | 'фя', 624 | ], 625 | }, 626 | }; 627 | 628 | export default { 629 | lastname, 630 | firstname, 631 | middlename, 632 | }; 633 | -------------------------------------------------------------------------------- /src/rules/inclineRulesFirstname.ts: -------------------------------------------------------------------------------- 1 | import type { DeclensionRuleSetT } from '../inclineRules'; 2 | 3 | export default { 4 | exceptions: [ 5 | { 6 | gender: 'male', 7 | test: ['лев'], 8 | mods: ['--ьва', '--ьву', '--ьва', '--ьвом', '--ьве'], 9 | }, 10 | { 11 | gender: 'male', 12 | test: ['пётр'], 13 | mods: ['---етра', '---етру', '---етра', '---етром', '---етре'], 14 | }, 15 | { 16 | gender: 'male', 17 | test: ['павел'], 18 | mods: ['--ла', '--лу', '--ла', '--лом', '--ле'], 19 | }, 20 | { 21 | gender: 'male', 22 | test: ['яша'], 23 | mods: ['-и', '-е', '-у', '-ей', '-е'], 24 | }, 25 | { 26 | gender: 'male', 27 | test: ['шота'], 28 | mods: ['.', '.', '.', '.', '.'], 29 | }, 30 | { 31 | gender: 'female', 32 | test: ['агидель', 'жизель', 'нинель', 'рашель', 'рахиль'], 33 | mods: ['-и', '-и', '.', 'ю', '-и'], 34 | }, 35 | ], 36 | suffixes: [ 37 | { 38 | gender: 'androgynous', 39 | test: ['лок'], 40 | mods: ['--ка', '--ку', '.', '--кос', '--ке'], 41 | }, 42 | { 43 | gender: 'androgynous', 44 | test: ['ки'], 45 | mods: ['-ов', '-ам', '.', '-ами', '-ах'], 46 | }, 47 | { 48 | gender: 'androgynous', 49 | test: ['щи'], 50 | mods: ['-ев', '-ам', '.', '-ами', '-ах'], 51 | }, 52 | { 53 | gender: 'androgynous', 54 | test: ['е', 'ё', 'и', 'о', 'у', 'ы', 'э', 'ю'], 55 | mods: ['.', '.', '.', '.', '.'], 56 | }, 57 | { 58 | gender: 'male', 59 | test: ['уа', 'иа'], 60 | mods: ['.', '.', '.', '.', '.'], 61 | }, 62 | { 63 | gender: 'female', 64 | test: [ 65 | 'б', 66 | 'в', 67 | 'г', 68 | 'д', 69 | 'ж', 70 | 'з', 71 | 'й', 72 | 'к', 73 | 'л', 74 | 'м', 75 | 'н', 76 | 'п', 77 | 'р', 78 | 'с', 79 | 'т', 80 | 'ф', 81 | 'х', 82 | 'ц', 83 | 'ч', 84 | 'ш', 85 | 'щ', 86 | 'ъ', 87 | 'иа', 88 | 'ль', 89 | ], 90 | mods: ['.', '.', '.', '.', '.'], 91 | }, 92 | { 93 | gender: 'female', 94 | test: ['ь'], 95 | mods: ['-и', '-и', '.', 'ю', '-и'], 96 | }, 97 | { 98 | gender: 'male', 99 | test: ['ь'], 100 | mods: ['-я', '-ю', '-я', '-ем', '-е'], 101 | }, 102 | { 103 | gender: 'androgynous', 104 | test: ['га', 'ка', 'ха', 'ча', 'ща', 'жа'], 105 | mods: ['-и', '-е', '-у', '-ой', '-е'], 106 | }, 107 | { 108 | gender: 'female', 109 | test: ['ша'], 110 | mods: ['-и', '-е', '-у', '-ей', '-е'], 111 | }, 112 | { 113 | gender: 'male', 114 | test: ['ша', 'ча', 'жа'], 115 | mods: ['-и', '-е', '-у', '-ей', '-е'], 116 | }, 117 | { 118 | gender: 'androgynous', 119 | test: ['а'], 120 | mods: ['-ы', '-е', '-у', '-ой', '-е'], 121 | }, 122 | { 123 | gender: 'female', 124 | test: ['ия'], 125 | mods: ['-и', '-и', '-ю', '-ей', '-и'], 126 | }, 127 | { 128 | gender: 'female', 129 | test: ['ка', 'га', 'ха'], 130 | mods: ['-и', '-е', '-у', '-ой', '-е'], 131 | }, 132 | { 133 | gender: 'female', 134 | test: ['ца'], 135 | mods: ['-ы', '-е', '-у', '-ей', '-е'], 136 | }, 137 | { 138 | gender: 'female', 139 | test: ['а'], 140 | mods: ['-ы', '-е', '-у', '-ой', '-е'], 141 | }, 142 | { 143 | gender: 'female', 144 | test: ['я'], 145 | mods: ['-и', '-е', '-ю', '-ей', '-е'], 146 | }, 147 | { 148 | gender: 'male', 149 | test: ['ия'], 150 | mods: ['-и', '-и', '-ю', '-ей', '-и'], 151 | }, 152 | { 153 | gender: 'male', 154 | test: ['я'], 155 | mods: ['-и', '-е', '-ю', '-ей', '-е'], 156 | }, 157 | { 158 | gender: 'male', 159 | test: ['ий'], 160 | mods: ['-я', '-ю', '-я', '-ем', '-и'], 161 | }, // @NODKZ Рудный 162 | { 163 | gender: 'male', 164 | test: ['ый', 'кий', 'хий'], 165 | mods: ['--ого', '--ому', '--ого', '-м', '--ом'], 166 | }, 167 | { 168 | gender: 'male', 169 | test: ['ей', 'й'], 170 | mods: ['-я', '-ю', '-я', '-ем', '-е'], 171 | }, 172 | { 173 | gender: 'male', 174 | test: ['ш', 'ж'], 175 | mods: ['а', 'у', 'а', 'ем', 'е'], 176 | }, 177 | { 178 | gender: 'male', 179 | test: ['ёл'], 180 | mods: ['--ла', '--лу', '--ла', '--лом', '--ле'], 181 | }, 182 | { 183 | gender: 'male', 184 | test: ['ёк'], 185 | mods: ['--ька', '--ьку', '--ька', '--ьком', '--ьке'], 186 | }, 187 | { 188 | gender: 'male', 189 | test: [ 190 | 'б', 191 | 'в', 192 | 'г', 193 | 'д', 194 | 'ж', 195 | 'з', 196 | 'к', 197 | 'л', 198 | 'м', 199 | 'н', 200 | 'п', 201 | 'р', 202 | 'с', 203 | 'т', 204 | 'ф', 205 | 'х', 206 | 'ц', 207 | 'ч', 208 | ], 209 | mods: ['а', 'у', 'а', 'ом', 'е'], 210 | }, 211 | { 212 | gender: 'androgynous', 213 | test: ['ния', 'рия', 'вия'], 214 | mods: ['-и', '-и', '-ю', '-ем', '-ем'], 215 | }, 216 | ], 217 | } as DeclensionRuleSetT; 218 | -------------------------------------------------------------------------------- /src/rules/inclineRulesLastname.ts: -------------------------------------------------------------------------------- 1 | import type { DeclensionRuleSetT } from '../inclineRules'; 2 | 3 | export default { 4 | exceptions: [ 5 | { 6 | gender: 'androgynous', 7 | test: [ 8 | 'бонч', 9 | 'абдул', 10 | 'белиц', 11 | 'гасан', 12 | 'дюссар', 13 | 'дюмон', 14 | 'книппер', 15 | 'корвин', 16 | 'ван', 17 | 'шолом', 18 | 'тер', 19 | 'призван', 20 | 'мелик', 21 | 'вар', 22 | 'фон', 23 | ], 24 | mods: ['.', '.', '.', '.', '.'], 25 | tags: ['first_word'], 26 | }, 27 | { 28 | gender: 'androgynous', 29 | test: [ 30 | 'дюма', 31 | 'тома', 32 | 'дега', 33 | 'люка', 34 | 'ферма', 35 | 'гамарра', 36 | 'петипа', 37 | 'шандра', 38 | 'скаля', 39 | 'каруана', 40 | ], 41 | mods: ['.', '.', '.', '.', '.'], 42 | }, 43 | { 44 | gender: 'androgynous', 45 | test: [ 46 | 'гусь', 47 | 'ремень', 48 | 'камень', 49 | 'онук', 50 | 'богода', 51 | 'нечипас', 52 | 'долгопалец', 53 | 'маненок', 54 | 'рева', 55 | 'кива', 56 | ], 57 | mods: ['.', '.', '.', '.', '.'], 58 | }, 59 | { 60 | gender: 'androgynous', 61 | test: ['вий', 'сой', 'цой', 'хой'], 62 | mods: ['-я', '-ю', '-я', '-ем', '-е'], 63 | }, 64 | ], 65 | suffixes: [ 66 | { 67 | gender: 'female', 68 | test: [ 69 | 'б', 70 | 'в', 71 | 'г', 72 | 'д', 73 | 'ж', 74 | 'з', 75 | 'й', 76 | 'к', 77 | 'л', 78 | 'м', 79 | 'н', 80 | 'п', 81 | 'р', 82 | 'с', 83 | 'т', 84 | 'ф', 85 | 'х', 86 | 'ц', 87 | 'ч', 88 | 'ш', 89 | 'щ', 90 | 'ъ', 91 | 'ь', 92 | ], 93 | mods: ['.', '.', '.', '.', '.'], 94 | }, 95 | { 96 | gender: 'androgynous', 97 | test: ['орота'], 98 | mods: ['.', '.', '.', '.', '.'], 99 | }, 100 | { 101 | gender: 'female', 102 | test: ['ска', 'цка'], 103 | mods: ['-ой', '-ой', '-ую', '-ой', '-ой'], 104 | }, 105 | { 106 | gender: 'female', 107 | test: ['цкая', 'ская', 'ная', 'ая'], 108 | mods: ['--ой', '--ой', '--ую', '--ой', '--ой'], 109 | }, 110 | { 111 | gender: 'female', 112 | test: ['яя'], 113 | mods: ['--ей', '--ей', '--юю', '--ей', '--ей'], 114 | }, 115 | { 116 | gender: 'male', 117 | test: ['иной', 'уй'], 118 | mods: ['-я', '-ю', '-я', '-ем', '-е'], 119 | }, 120 | { 121 | gender: 'androgynous', 122 | test: ['ца'], 123 | mods: ['-ы', '-е', '-у', '-ей', '-е'], 124 | }, 125 | { 126 | gender: 'male', 127 | test: ['рих'], 128 | mods: ['а', 'у', 'а', 'ом', 'е'], 129 | }, 130 | { 131 | gender: 'androgynous', 132 | test: ['ия'], 133 | mods: ['-и', '-и', '-ю', '-ей', '-и'], 134 | }, 135 | { 136 | gender: 'androgynous', 137 | test: ['иа', 'аа', 'оа', 'уа', 'ыа', 'еа', 'юа', 'эа'], 138 | mods: ['.', '.', '.', '.', '.'], 139 | }, 140 | { 141 | gender: 'androgynous', 142 | test: ['о', 'е', 'э', 'и', 'ы', 'у', 'ю'], 143 | mods: ['.', '.', '.', '.', '.'], 144 | }, 145 | { 146 | gender: 'male', 147 | test: ['их', 'ых'], 148 | mods: ['.', '.', '.', '.', '.'], 149 | }, 150 | { 151 | gender: 'female', 152 | test: ['ова', 'ева', 'на', 'ёва'], 153 | mods: ['-ой', '-ой', '-у', '-ой', '-ой'], 154 | }, 155 | { 156 | gender: 'androgynous', 157 | test: ['га', 'ка', 'ха', 'ча', 'ща', 'жа', 'ша'], 158 | mods: ['-и', '-е', '-у', '-ой', '-е'], 159 | }, 160 | { 161 | gender: 'androgynous', 162 | test: ['а'], 163 | mods: ['-ы', '-е', '-у', '-ой', '-е'], 164 | }, 165 | { 166 | gender: 'male', 167 | test: ['ь'], 168 | mods: ['-я', '-ю', '-я', '-ем', '-е'], 169 | }, 170 | { 171 | gender: 'androgynous', 172 | test: ['я'], 173 | mods: ['-и', '-е', '-ю', '-ей', '-е'], 174 | }, 175 | { 176 | gender: 'male', 177 | test: ['обей'], 178 | mods: ['--ья', '--ью', '--ья', '--ьем', '--ье'], 179 | }, 180 | { 181 | gender: 'male', 182 | test: ['ей'], 183 | mods: ['-я', '-ю', '-я', '-ем', '-е'], 184 | }, 185 | { 186 | gender: 'male', 187 | test: ['ян', 'ан', 'йн'], 188 | mods: ['а', 'у', 'а', 'ом', 'е'], 189 | }, 190 | { 191 | gender: 'male', 192 | test: ['ынец', 'овец'], 193 | mods: ['--ца', '--цу', '--ца', '--цом', '--це'], 194 | }, 195 | { 196 | gender: 'male', 197 | test: ['нец', 'обец'], 198 | mods: ['--ца', '--цу', '--ца', '--цем', '--це'], 199 | }, 200 | { 201 | gender: 'male', 202 | test: ['ай'], 203 | mods: ['-я', '-ю', '-я', '-ем', '-е'], 204 | }, 205 | { 206 | gender: 'male', 207 | test: ['гой', 'кой'], 208 | mods: ['-го', '-му', '-го', '--им', '-м'], 209 | }, 210 | { 211 | gender: 'male', 212 | test: ['ой'], 213 | mods: ['-го', '-му', '-го', '--ым', '-м'], 214 | }, 215 | { 216 | gender: 'male', 217 | test: ['ах', 'ив', 'шток'], 218 | mods: ['а', 'у', 'а', 'ом', 'е'], 219 | }, 220 | { 221 | gender: 'male', 222 | test: ['ший', 'щий', 'жий', 'ний'], 223 | mods: ['--его', '--ему', '--его', '-м', '--ем'], 224 | }, 225 | { 226 | gender: 'male', 227 | test: ['ый', 'кий', 'хий'], 228 | mods: ['--ого', '--ому', '--ого', '-м', '--ом'], 229 | }, 230 | { 231 | gender: 'male', 232 | test: ['ий'], 233 | mods: ['-я', '-ю', '-я', '-ем', '-и'], 234 | }, 235 | { 236 | gender: 'male', 237 | test: ['ок'], 238 | mods: ['--ка', '--ку', '--ка', '--ком', '--ке'], 239 | }, 240 | { 241 | gender: 'male', 242 | test: ['иец', 'еец'], 243 | mods: ['--йца', '--йцу', '--йца', '--йцом', '--йце'], 244 | }, 245 | { 246 | gender: 'male', 247 | test: ['ец'], 248 | mods: ['--ца', '--цу', '--ца', '--цом', '--це'], 249 | }, 250 | { 251 | gender: 'male', 252 | test: ['ц', 'ч', 'ш', 'щ'], 253 | mods: ['а', 'у', 'а', 'ем', 'е'], 254 | }, 255 | { 256 | gender: 'male', 257 | test: [ 258 | 'ен', 259 | 'нн', 260 | 'он', 261 | 'ун', 262 | 'б', 263 | 'г', 264 | 'д', 265 | 'ж', 266 | 'з', 267 | 'к', 268 | 'л', 269 | 'м', 270 | 'п', 271 | 'р', 272 | 'с', 273 | 'т', 274 | 'ф', 275 | 'х', 276 | ], 277 | mods: ['а', 'у', 'а', 'ом', 'е'], 278 | }, 279 | { 280 | gender: 'male', 281 | test: ['в', 'н'], 282 | mods: ['а', 'у', 'а', 'ым', 'е'], 283 | }, 284 | ], 285 | } as DeclensionRuleSetT; 286 | -------------------------------------------------------------------------------- /src/rules/inclineRulesMiddlename.ts: -------------------------------------------------------------------------------- 1 | import type { DeclensionRuleSetT } from '../inclineRules'; 2 | 3 | export default { 4 | exceptions: [ 5 | { 6 | gender: 'androgynous', 7 | test: ['борух'], 8 | mods: ['.', '.', '.', '.', '.'], 9 | tags: ['first_word'], 10 | }, 11 | ], 12 | suffixes: [ 13 | { 14 | gender: 'male', 15 | test: ['мич', 'ьич', 'кич'], 16 | mods: ['а', 'у', 'а', 'ом', 'е'], 17 | }, 18 | { 19 | gender: 'male', 20 | test: ['ич'], 21 | mods: ['а', 'у', 'а', 'ем', 'е'], 22 | }, 23 | { 24 | gender: 'female', 25 | test: ['на'], 26 | mods: ['-ы', '-е', '-у', '-ой', '-е'], 27 | }, 28 | ], 29 | } as DeclensionRuleSetT; 30 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | export function endsWith(str: string, search: string): boolean { 2 | const strLength = str.length; 3 | return str.substring(strLength - search.length, strLength) === search; 4 | } 5 | 6 | export function startsWith(str: string, search: string, pos?: number): boolean { 7 | return str.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search; 8 | } 9 | -------------------------------------------------------------------------------- /tsconfig.build-esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "target": "es2020", 5 | "module": "ES6", 6 | "outDir": "./esm", 7 | "noEmit": false, 8 | "declaration": true, 9 | "declarationMap": true, 10 | "types": [], 11 | }, 12 | "include": ["src/**/*"], 13 | "exclude": ["**/__tests__", "**/__mocks__"] 14 | } -------------------------------------------------------------------------------- /tsconfig.build-lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "target": "es2015", 5 | "module": "commonjs", 6 | "outDir": "./lib", 7 | "noEmit": false, 8 | "declaration": true, 9 | "declarationMap": true, 10 | "types": [], 11 | }, 12 | "include": ["src/**/*"], 13 | "exclude": ["**/__tests__", "**/__mocks__"] 14 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "esModuleInterop": true, 6 | "noEmit": true, 7 | "sourceMap": true, 8 | "strict": true, 9 | "noImplicitAny": true, 10 | "noImplicitReturns": true, 11 | "noFallthroughCasesInSwitch": true, 12 | "noUnusedParameters": true, 13 | "noUnusedLocals": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "types": ["node", "jest"], 16 | "baseUrl": ".", 17 | "rootDir": "./src", 18 | }, 19 | "include": ["src/**/*"], 20 | "exclude": [ 21 | "./node_modules" 22 | ] 23 | } 24 | --------------------------------------------------------------------------------