# mawo-pymorphy3
[](https://badge.fury.io/py/mawo-pymorphy3)
[](https://www.python.org/downloads/)
[](https://opensource.org/licenses/MIT)
**Улучшенный морфологический анализатор для русского языка** с DAWG-оптимизацией и сокращением потребления памяти на 90%.
## Возможности
- **Компактные словари DAWG**: Всего ~11МБ на диске (против 69МБ XML)
- **Работа офлайн**: После установки не требует интернета
- **Потокобезопасность**: Безопасно для многопоточного использования
- **OpenCorpora 2025**: Самый свежий словарь русского языка
- **Быстрая загрузка**: ~1-2 секунды с кэшем (против 30-60 секунд разбора XML)
- **100% Совместимость**: Полная замена для pymorphy2/pymorphy3
## Установка
```bash
pip install mawo-pymorphy3
```
### С дополнительными зависимостями
```bash
# Безопасность (рекомендуется для production)
pip install mawo-pymorphy3[security]
# Красивый вывод в консоль
pip install mawo-pymorphy3[rich]
# Все дополнения
pip install mawo-pymorphy3[all]
```
## Быстрый старт
```python
from mawo_pymorphy3 import create_analyzer
# Создаём анализатор (автоматически загружает DAWG словарь)
analyzer = create_analyzer()
# Разбираем русские слова
word = analyzer.parse("стали")[0]
print(word.tag) # VERB,perf,intr plur,past,indc
print(word.normal_form) # стать
print(word.inflect({"sing", "femn"})) # стала
# Морфологический анализ
for parse in analyzer.parse("дом"):
print(f"{parse.word} -> {parse.normal_form} ({parse.tag})")
```
## Продвинутое использование
### Потокобезопасный синглтон
```python
from mawo_pymorphy3 import get_global_analyzer
# Получаем глобальный экземпляр (потокобезопасный)
analyzer = get_global_analyzer()
```
### Анализ падежей
```python
# Поддержка русских падежей
word = analyzer.parse("дома")[0]
# Получаем все падежные формы
cases = {
"именительный": word.inflect({"nomn"}),
"родительный": word.inflect({"gent"}),
"дательный": word.inflect({"datv"}),
"винительный": word.inflect({"accs"}),
"творительный": word.inflect({"ablt"}),
"предложный": word.inflect({"loct"}),
}
for case_name, form in cases.items():
if form:
print(f"{case_name}: {form.word}")
```
### Управление DAWG кэшем
```python
from mawo_pymorphy3 import MAWODictionaryManager
manager = MAWODictionaryManager()
# Проверяем наличие DAWG кэша
if manager.is_dawg_cache_available():
print("✅ DAWG кэш готов")
else:
# Создаём DAWG кэш из OpenCorpora XML
manager.build_dawg_cache()
```
### Оптимизированный анализатор с кэшированием
```python
from mawo_pymorphy3 import MAWOOptimizedMorphAnalyzer
# Создаём оптимизированный анализатор (с кэшем результатов)
analyzer = MAWOOptimizedMorphAnalyzer()
# Анализируем текст целиком
results = analyzer.analyze("Я иду домой")
for result in results:
print(f"{result['word']} -> {result['normal_form']} ({result['pos']})")
print(f" Падеж: {result['case']}, Число: {result['number']}")
```
## Производительность
### Использование памяти
| Формат словаря | Размер на диске | Память в RAM | Время загрузки |
|----------------|-----------------|--------------|----------------|
| OpenCorpora XML (raw) | ~69МБ | ~500МБ | 30-60 сек |
| **DAWG словари (включены)** | **~11МБ** | **~10-20МБ** | **<1 сек** |
| С pickle кэшем | ~11МБ + кэш | ~10-20МБ | <1 сек |
**Экономия места на диске: ~84%** (11МБ против 69МБ)
### Бенчмарки
```python
import time
from mawo_pymorphy3 import create_analyzer
analyzer = create_analyzer()
# Прогрев
analyzer.parse("тест")
# Замер производительности
start = time.time()
for _ in range(10000):
analyzer.parse("стали")
elapsed = time.time() - start
print(f"10000 разборов: {elapsed:.2f}сек ({10000/elapsed:.0f} слов/сек)")
# Типично: ~15k-25k слов/сек (однопоточно)
```
## Файлы данных
Пакет включает оптимизированные DAWG словари (~13МБ):
```
mawo_pymorphy3/
├── dicts_ru/
│ ├── words.dawg # Основной словарь
│ ├── prediction-suffixes-0.dawg # Суффиксы для предсказания
│ ├── prediction-suffixes-1.dawg
│ └── prediction-suffixes-2.dawg
└── data/
└── dict.opcorpora.xml # OpenCorpora 2025 (опционально)
```
### 📦 Репозиторий данных MAWO
Все справочные данные, модели и корпуса для библиотек MAWO доступны в отдельном репозитории:
**🔗 [mawo-nlp-data](https://github.com/mawo-ru/mawo-nlp-data)**
Репозиторий содержит:
- **OpenCorpora 2025** (69MB) - полный корпус для продвинутого морфологического анализа
- **SlovNet модели** (2-3MB каждая) - NER, морфология, синтаксис
- **Navec эмбеддинги** (26MB) - векторные представления слов
- **Словари имён** (2025) - мужские/женские имена, фамилии, отчества
### Скачать полный OpenCorpora (опционально)
Для продвинутого использования или пересборки словаря:
```bash
# Скачать с релизов MAWO (69МБ)
wget https://github.com/mawo-ru/mawo-nlp-data/releases/download/v1.0.0/opencorpora-2025.tar.gz
tar -xzf opencorpora-2025.tar.gz -C ~/.mawo-pymorphy3/
# Проверить контрольную сумму
wget https://github.com/mawo-ru/mawo-nlp-data/releases/download/v1.0.0/checksums.txt
sha256sum -c checksums.txt
```
Подробнее о данных, моделях и способах установки см. в [mawo-nlp-data README](https://github.com/mawo-ru/mawo-nlp-data#readme).
## Миграция с pymorphy2/pymorphy3
**100% совместимость!** Просто замените импорт:
```python
# Было (pymorphy2)
from pymorphy2 import MorphAnalyzer
analyzer = MorphAnalyzer()
# Было (pymorphy3)
from pymorphy3 import MorphAnalyzer
analyzer = MorphAnalyzer()
# Стало
from mawo_pymorphy3 import create_analyzer
analyzer = create_analyzer()
# или
from mawo_pymorphy3 import MorphAnalyzer
analyzer = MorphAnalyzer()
```
Все API остаются прежними. Ваш код будет работать без изменений.
## Настройка
### Свой путь к словарю
```python
from pathlib import Path
from mawo_pymorphy3 import MAWOMorphAnalyzer
analyzer = MAWOMorphAnalyzer(
dict_path=Path("/свой/путь/к/словарям")
)
```
### Отключить DAWG оптимизацию
```python
# Использовать оригинальный XML словарь (медленнее, больше памяти)
analyzer = create_analyzer(use_dawg=False)
```
## Технические детали
### DAWG (Направленный ациклический граф слов)
- **Сжатие**: Без потерь, 100% точность
- **Структура**: Префиксное дерево с общими суффиксами
- **Поиск**: O(|слово|) временная сложность
- **Размер**: ~50МБ для 391,845 лексем
### Источники словаря
- **OpenCorpora 2025**: Морфологический словарь русского языка
- **Ревизия**: 417260 (сентябрь 2025)
- **Лексем**: 391,845
- **Словоформ**: ~5 миллионов
### Потокобезопасность
Все операции потокобезопасны:
- Глобальный синглтон использует threading.Lock
- DAWG словари неизменяемы (только чтение)
- Нет разделяемого изменяемого состояния
## Решение проблем
### Модуль не найден
```python
# Если видите: ModuleNotFoundError: No module named 'mawo_pymorphy3'
pip install --upgrade mawo-pymorphy3
```
### Отсутствует DAWG кэш
```python
# Создайте кэш вручную
from mawo_pymorphy3 import MAWODictionaryManager
manager = MAWODictionaryManager()
manager.build_dawg_cache()
```
### Нехватка памяти
```python
# Используйте DAWG (по умолчанию, только 50МБ)
analyzer = create_analyzer(use_dawg=True)
```
## Разработка
### Настройка окружения
```bash
git clone https://github.com/mawo-ru/mawo-pymorphy3.git
cd mawo-pymorphy3
pip install -e ".[dev]"
```
### Запуск тестов
```bash
pytest tests/
```
### Форматирование кода
```bash
black mawo_pymorphy3/
ruff check mawo_pymorphy3/
```
## Благодарности
Основано на **pymorphy3** и **pymorphy2** от Михаила Коробова и контрибьюторов.
**Улучшения MAWO:**
- DAWG оптимизация памяти (сокращение на 90%)
- Потокобезопасный паттерн синглтон
- Архитектура offline-first
- Интеграция с OpenCorpora 2025
## Лицензия
Лицензия MIT - см. файл [LICENSE](LICENSE).
## Ссылки
- **GitHub**: https://github.com/mawo-ru/mawo-pymorphy3
- **PyPI**: https://pypi.org/project/mawo-pymorphy3/
- **Проблемы**: https://github.com/mawo-ru/mawo-pymorphy3/issues
- **Данные и модели**: https://github.com/mawo-ru/mawo-nlp-data
- **Оригинальный pymorphy2**: https://github.com/pymorphy2/pymorphy2
- **Оригинальный pymorphy3**: https://github.com/no-plagiarism/pymorphy3
- **OpenCorpora**: http://opencorpora.org/
---
Сделано с ❤️ командой [MAWO](https://github.com/mawo-ru)
Raw data
{
"_id": null,
"home_page": null,
"name": "mawo-pymorphy3",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": "MAWO Team <team@mawo.ru>",
"keywords": "nlp, russian, morphology, pymorphy3, dawg, mawo",
"author": null,
"author_email": "MAWO Team <team@mawo.ru>",
"download_url": "https://files.pythonhosted.org/packages/f0/c5/e706d2e76381f9dc5a51608ef920fb656724ef78e3715a053f1b061b39ce/mawo_pymorphy3-1.0.2.tar.gz",
"platform": null,
"description": "# mawo-pymorphy3\n\n[](https://badge.fury.io/py/mawo-pymorphy3)\n[](https://www.python.org/downloads/)\n[](https://opensource.org/licenses/MIT)\n\n**\u0423\u043b\u0443\u0447\u0448\u0435\u043d\u043d\u044b\u0439 \u043c\u043e\u0440\u0444\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u0434\u043b\u044f \u0440\u0443\u0441\u0441\u043a\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430** \u0441 DAWG-\u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0438 \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u0435\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u0438 \u043d\u0430 90%.\n\n## \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438\n\n- **\u041a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u044b\u0435 \u0441\u043b\u043e\u0432\u0430\u0440\u0438 DAWG**: \u0412\u0441\u0435\u0433\u043e ~11\u041c\u0411 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435 (\u043f\u0440\u043e\u0442\u0438\u0432 69\u041c\u0411 XML)\n- **\u0420\u0430\u0431\u043e\u0442\u0430 \u043e\u0444\u043b\u0430\u0439\u043d**: \u041f\u043e\u0441\u043b\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0430\n- **\u041f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c**: \u0411\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u0434\u043b\u044f \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f\n- **OpenCorpora 2025**: \u0421\u0430\u043c\u044b\u0439 \u0441\u0432\u0435\u0436\u0438\u0439 \u0441\u043b\u043e\u0432\u0430\u0440\u044c \u0440\u0443\u0441\u0441\u043a\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430\n- **\u0411\u044b\u0441\u0442\u0440\u0430\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430**: ~1-2 \u0441\u0435\u043a\u0443\u043d\u0434\u044b \u0441 \u043a\u044d\u0448\u0435\u043c (\u043f\u0440\u043e\u0442\u0438\u0432 30-60 \u0441\u0435\u043a\u0443\u043d\u0434 \u0440\u0430\u0437\u0431\u043e\u0440\u0430 XML)\n- **100% \u0421\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c**: \u041f\u043e\u043b\u043d\u0430\u044f \u0437\u0430\u043c\u0435\u043d\u0430 \u0434\u043b\u044f pymorphy2/pymorphy3\n\n## \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430\n\n```bash\npip install mawo-pymorphy3\n```\n\n### \u0421 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u043c\u0438\n\n```bash\n# \u0411\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c (\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f production)\npip install mawo-pymorphy3[security]\n\n# \u041a\u0440\u0430\u0441\u0438\u0432\u044b\u0439 \u0432\u044b\u0432\u043e\u0434 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c\npip install mawo-pymorphy3[rich]\n\n# \u0412\u0441\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f\npip install mawo-pymorphy3[all]\n```\n\n## \u0411\u044b\u0441\u0442\u0440\u044b\u0439 \u0441\u0442\u0430\u0440\u0442\n\n```python\nfrom mawo_pymorphy3 import create_analyzer\n\n# \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 (\u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 DAWG \u0441\u043b\u043e\u0432\u0430\u0440\u044c)\nanalyzer = create_analyzer()\n\n# \u0420\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u043c \u0440\u0443\u0441\u0441\u043a\u0438\u0435 \u0441\u043b\u043e\u0432\u0430\nword = analyzer.parse(\"\u0441\u0442\u0430\u043b\u0438\")[0]\nprint(word.tag) # VERB,perf,intr plur,past,indc\nprint(word.normal_form) # \u0441\u0442\u0430\u0442\u044c\nprint(word.inflect({\"sing\", \"femn\"})) # \u0441\u0442\u0430\u043b\u0430\n\n# \u041c\u043e\u0440\u0444\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\nfor parse in analyzer.parse(\"\u0434\u043e\u043c\"):\n print(f\"{parse.word} -> {parse.normal_form} ({parse.tag})\")\n```\n\n## \u041f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\n\n### \u041f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0439 \u0441\u0438\u043d\u0433\u043b\u0442\u043e\u043d\n\n```python\nfrom mawo_pymorphy3 import get_global_analyzer\n\n# \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 (\u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0439)\nanalyzer = get_global_analyzer()\n```\n\n### \u0410\u043d\u0430\u043b\u0438\u0437 \u043f\u0430\u0434\u0435\u0436\u0435\u0439\n\n```python\n# \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0440\u0443\u0441\u0441\u043a\u0438\u0445 \u043f\u0430\u0434\u0435\u0436\u0435\u0439\nword = analyzer.parse(\"\u0434\u043e\u043c\u0430\")[0]\n\n# \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432\u0441\u0435 \u043f\u0430\u0434\u0435\u0436\u043d\u044b\u0435 \u0444\u043e\u0440\u043c\u044b\ncases = {\n \"\u0438\u043c\u0435\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439\": word.inflect({\"nomn\"}),\n \"\u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439\": word.inflect({\"gent\"}),\n \"\u0434\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439\": word.inflect({\"datv\"}),\n \"\u0432\u0438\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439\": word.inflect({\"accs\"}),\n \"\u0442\u0432\u043e\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439\": word.inflect({\"ablt\"}),\n \"\u043f\u0440\u0435\u0434\u043b\u043e\u0436\u043d\u044b\u0439\": word.inflect({\"loct\"}),\n}\n\nfor case_name, form in cases.items():\n if form:\n print(f\"{case_name}: {form.word}\")\n```\n\n### \u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 DAWG \u043a\u044d\u0448\u0435\u043c\n\n```python\nfrom mawo_pymorphy3 import MAWODictionaryManager\n\nmanager = MAWODictionaryManager()\n\n# \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 DAWG \u043a\u044d\u0448\u0430\nif manager.is_dawg_cache_available():\n print(\"\u2705 DAWG \u043a\u044d\u0448 \u0433\u043e\u0442\u043e\u0432\")\nelse:\n # \u0421\u043e\u0437\u0434\u0430\u0451\u043c DAWG \u043a\u044d\u0448 \u0438\u0437 OpenCorpora XML\n manager.build_dawg_cache()\n```\n\n### \u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u0441 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c\n\n```python\nfrom mawo_pymorphy3 import MAWOOptimizedMorphAnalyzer\n\n# \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 (\u0441 \u043a\u044d\u0448\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432)\nanalyzer = MAWOOptimizedMorphAnalyzer()\n\n# \u0410\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0442\u0435\u043a\u0441\u0442 \u0446\u0435\u043b\u0438\u043a\u043e\u043c\nresults = analyzer.analyze(\"\u042f \u0438\u0434\u0443 \u0434\u043e\u043c\u043e\u0439\")\n\nfor result in results:\n print(f\"{result['word']} -> {result['normal_form']} ({result['pos']})\")\n print(f\" \u041f\u0430\u0434\u0435\u0436: {result['case']}, \u0427\u0438\u0441\u043b\u043e: {result['number']}\")\n```\n\n## \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\n\n### \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438\n\n| \u0424\u043e\u0440\u043c\u0430\u0442 \u0441\u043b\u043e\u0432\u0430\u0440\u044f | \u0420\u0430\u0437\u043c\u0435\u0440 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435 | \u041f\u0430\u043c\u044f\u0442\u044c \u0432 RAM | \u0412\u0440\u0435\u043c\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 |\n|----------------|-----------------|--------------|----------------|\n| OpenCorpora XML (raw) | ~69\u041c\u0411 | ~500\u041c\u0411 | 30-60 \u0441\u0435\u043a |\n| **DAWG \u0441\u043b\u043e\u0432\u0430\u0440\u0438 (\u0432\u043a\u043b\u044e\u0447\u0435\u043d\u044b)** | **~11\u041c\u0411** | **~10-20\u041c\u0411** | **<1 \u0441\u0435\u043a** |\n| \u0421 pickle \u043a\u044d\u0448\u0435\u043c | ~11\u041c\u0411 + \u043a\u044d\u0448 | ~10-20\u041c\u0411 | <1 \u0441\u0435\u043a |\n\n**\u042d\u043a\u043e\u043d\u043e\u043c\u0438\u044f \u043c\u0435\u0441\u0442\u0430 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435: ~84%** (11\u041c\u0411 \u043f\u0440\u043e\u0442\u0438\u0432 69\u041c\u0411)\n\n### \u0411\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0438\n\n```python\nimport time\nfrom mawo_pymorphy3 import create_analyzer\n\nanalyzer = create_analyzer()\n\n# \u041f\u0440\u043e\u0433\u0440\u0435\u0432\nanalyzer.parse(\"\u0442\u0435\u0441\u0442\")\n\n# \u0417\u0430\u043c\u0435\u0440 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438\nstart = time.time()\nfor _ in range(10000):\n analyzer.parse(\"\u0441\u0442\u0430\u043b\u0438\")\nelapsed = time.time() - start\n\nprint(f\"10000 \u0440\u0430\u0437\u0431\u043e\u0440\u043e\u0432: {elapsed:.2f}\u0441\u0435\u043a ({10000/elapsed:.0f} \u0441\u043b\u043e\u0432/\u0441\u0435\u043a)\")\n# \u0422\u0438\u043f\u0438\u0447\u043d\u043e: ~15k-25k \u0441\u043b\u043e\u0432/\u0441\u0435\u043a (\u043e\u0434\u043d\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e)\n```\n\n## \u0424\u0430\u0439\u043b\u044b \u0434\u0430\u043d\u043d\u044b\u0445\n\n\u041f\u0430\u043a\u0435\u0442 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 DAWG \u0441\u043b\u043e\u0432\u0430\u0440\u0438 (~13\u041c\u0411):\n\n```\nmawo_pymorphy3/\n\u251c\u2500\u2500 dicts_ru/\n\u2502 \u251c\u2500\u2500 words.dawg # \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0441\u043b\u043e\u0432\u0430\u0440\u044c\n\u2502 \u251c\u2500\u2500 prediction-suffixes-0.dawg # \u0421\u0443\u0444\u0444\u0438\u043a\u0441\u044b \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0430\u043d\u0438\u044f\n\u2502 \u251c\u2500\u2500 prediction-suffixes-1.dawg\n\u2502 \u2514\u2500\u2500 prediction-suffixes-2.dawg\n\u2514\u2500\u2500 data/\n \u2514\u2500\u2500 dict.opcorpora.xml # OpenCorpora 2025 (\u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e)\n```\n\n### \ud83d\udce6 \u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 MAWO\n\n\u0412\u0441\u0435 \u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u043c\u043e\u0434\u0435\u043b\u0438 \u0438 \u043a\u043e\u0440\u043f\u0443\u0441\u0430 \u0434\u043b\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a MAWO \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438:\n\n**\ud83d\udd17 [mawo-nlp-data](https://github.com/mawo-ru/mawo-nlp-data)**\n\n\u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442:\n- **OpenCorpora 2025** (69MB) - \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0440\u043f\u0443\u0441 \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u043e\u0433\u043e \u043c\u043e\u0440\u0444\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430\n- **SlovNet \u043c\u043e\u0434\u0435\u043b\u0438** (2-3MB \u043a\u0430\u0436\u0434\u0430\u044f) - NER, \u043c\u043e\u0440\u0444\u043e\u043b\u043e\u0433\u0438\u044f, \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\n- **Navec \u044d\u043c\u0431\u0435\u0434\u0434\u0438\u043d\u0433\u0438** (26MB) - \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u044b\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043b\u043e\u0432\n- **\u0421\u043b\u043e\u0432\u0430\u0440\u0438 \u0438\u043c\u0451\u043d** (2025) - \u043c\u0443\u0436\u0441\u043a\u0438\u0435/\u0436\u0435\u043d\u0441\u043a\u0438\u0435 \u0438\u043c\u0435\u043d\u0430, \u0444\u0430\u043c\u0438\u043b\u0438\u0438, \u043e\u0442\u0447\u0435\u0441\u0442\u0432\u0430\n\n### \u0421\u043a\u0430\u0447\u0430\u0442\u044c \u043f\u043e\u043b\u043d\u044b\u0439 OpenCorpora (\u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e)\n\n\u0414\u043b\u044f \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0441\u0431\u043e\u0440\u043a\u0438 \u0441\u043b\u043e\u0432\u0430\u0440\u044f:\n\n```bash\n# \u0421\u043a\u0430\u0447\u0430\u0442\u044c \u0441 \u0440\u0435\u043b\u0438\u0437\u043e\u0432 MAWO (69\u041c\u0411)\nwget https://github.com/mawo-ru/mawo-nlp-data/releases/download/v1.0.0/opencorpora-2025.tar.gz\ntar -xzf opencorpora-2025.tar.gz -C ~/.mawo-pymorphy3/\n\n# \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c\u043d\u0443\u044e \u0441\u0443\u043c\u043c\u0443\nwget https://github.com/mawo-ru/mawo-nlp-data/releases/download/v1.0.0/checksums.txt\nsha256sum -c checksums.txt\n```\n\n\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e \u0434\u0430\u043d\u043d\u044b\u0445, \u043c\u043e\u0434\u0435\u043b\u044f\u0445 \u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u0445 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0441\u043c. \u0432 [mawo-nlp-data README](https://github.com/mawo-ru/mawo-nlp-data#readme).\n\n## \u041c\u0438\u0433\u0440\u0430\u0446\u0438\u044f \u0441 pymorphy2/pymorphy3\n\n**100% \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c!** \u041f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u0435 \u0438\u043c\u043f\u043e\u0440\u0442:\n\n```python\n# \u0411\u044b\u043b\u043e (pymorphy2)\nfrom pymorphy2 import MorphAnalyzer\nanalyzer = MorphAnalyzer()\n\n# \u0411\u044b\u043b\u043e (pymorphy3)\nfrom pymorphy3 import MorphAnalyzer\nanalyzer = MorphAnalyzer()\n\n# \u0421\u0442\u0430\u043b\u043e\nfrom mawo_pymorphy3 import create_analyzer\nanalyzer = create_analyzer()\n# \u0438\u043b\u0438\nfrom mawo_pymorphy3 import MorphAnalyzer\nanalyzer = MorphAnalyzer()\n```\n\n\u0412\u0441\u0435 API \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u043f\u0440\u0435\u0436\u043d\u0438\u043c\u0438. \u0412\u0430\u0448 \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439.\n\n## \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\n\n### \u0421\u0432\u043e\u0439 \u043f\u0443\u0442\u044c \u043a \u0441\u043b\u043e\u0432\u0430\u0440\u044e\n\n```python\nfrom pathlib import Path\nfrom mawo_pymorphy3 import MAWOMorphAnalyzer\n\nanalyzer = MAWOMorphAnalyzer(\n dict_path=Path(\"/\u0441\u0432\u043e\u0439/\u043f\u0443\u0442\u044c/\u043a/\u0441\u043b\u043e\u0432\u0430\u0440\u044f\u043c\")\n)\n```\n\n### \u041e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u044c DAWG \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044e\n\n```python\n# \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 XML \u0441\u043b\u043e\u0432\u0430\u0440\u044c (\u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435, \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u0430\u043c\u044f\u0442\u0438)\nanalyzer = create_analyzer(use_dawg=False)\n```\n\n## \u0422\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0434\u0435\u0442\u0430\u043b\u0438\n\n### DAWG (\u041d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u0430\u0446\u0438\u043a\u043b\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0433\u0440\u0430\u0444 \u0441\u043b\u043e\u0432)\n\n- **\u0421\u0436\u0430\u0442\u0438\u0435**: \u0411\u0435\u0437 \u043f\u043e\u0442\u0435\u0440\u044c, 100% \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c\n- **\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430**: \u041f\u0440\u0435\u0444\u0438\u043a\u0441\u043d\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0441 \u043e\u0431\u0449\u0438\u043c\u0438 \u0441\u0443\u0444\u0444\u0438\u043a\u0441\u0430\u043c\u0438\n- **\u041f\u043e\u0438\u0441\u043a**: O(|\u0441\u043b\u043e\u0432\u043e|) \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c\n- **\u0420\u0430\u0437\u043c\u0435\u0440**: ~50\u041c\u0411 \u0434\u043b\u044f 391,845 \u043b\u0435\u043a\u0441\u0435\u043c\n\n### \u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u0441\u043b\u043e\u0432\u0430\u0440\u044f\n\n- **OpenCorpora 2025**: \u041c\u043e\u0440\u0444\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0441\u043b\u043e\u0432\u0430\u0440\u044c \u0440\u0443\u0441\u0441\u043a\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430\n- **\u0420\u0435\u0432\u0438\u0437\u0438\u044f**: 417260 (\u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044c 2025)\n- **\u041b\u0435\u043a\u0441\u0435\u043c**: 391,845\n- **\u0421\u043b\u043e\u0432\u043e\u0444\u043e\u0440\u043c**: ~5 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432\n\n### \u041f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c\n\n\u0412\u0441\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b:\n- \u0413\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0438\u043d\u0433\u043b\u0442\u043e\u043d \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 threading.Lock\n- DAWG \u0441\u043b\u043e\u0432\u0430\u0440\u0438 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b (\u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u0435\u043d\u0438\u0435)\n- \u041d\u0435\u0442 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\n\n## \u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\n\n### \u041c\u043e\u0434\u0443\u043b\u044c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\n\n```python\n# \u0415\u0441\u043b\u0438 \u0432\u0438\u0434\u0438\u0442\u0435: ModuleNotFoundError: No module named 'mawo_pymorphy3'\npip install --upgrade mawo-pymorphy3\n```\n\n### \u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 DAWG \u043a\u044d\u0448\n\n```python\n# \u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043a\u044d\u0448 \u0432\u0440\u0443\u0447\u043d\u0443\u044e\nfrom mawo_pymorphy3 import MAWODictionaryManager\nmanager = MAWODictionaryManager()\nmanager.build_dawg_cache()\n```\n\n### \u041d\u0435\u0445\u0432\u0430\u0442\u043a\u0430 \u043f\u0430\u043c\u044f\u0442\u0438\n\n```python\n# \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 DAWG (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u0442\u043e\u043b\u044c\u043a\u043e 50\u041c\u0411)\nanalyzer = create_analyzer(use_dawg=True)\n```\n\n## \u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430\n\n### \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f\n\n```bash\ngit clone https://github.com/mawo-ru/mawo-pymorphy3.git\ncd mawo-pymorphy3\npip install -e \".[dev]\"\n```\n\n### \u0417\u0430\u043f\u0443\u0441\u043a \u0442\u0435\u0441\u0442\u043e\u0432\n\n```bash\npytest tests/\n```\n\n### \u0424\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u0434\u0430\n\n```bash\nblack mawo_pymorphy3/\nruff check mawo_pymorphy3/\n```\n\n## \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u043d\u043e\u0441\u0442\u0438\n\n\u041e\u0441\u043d\u043e\u0432\u0430\u043d\u043e \u043d\u0430 **pymorphy3** \u0438 **pymorphy2** \u043e\u0442 \u041c\u0438\u0445\u0430\u0438\u043b\u0430 \u041a\u043e\u0440\u043e\u0431\u043e\u0432\u0430 \u0438 \u043a\u043e\u043d\u0442\u0440\u0438\u0431\u044c\u044e\u0442\u043e\u0440\u043e\u0432.\n\n**\u0423\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f MAWO:**\n- DAWG \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u0438 (\u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043d\u0430 90%)\n- \u041f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d \u0441\u0438\u043d\u0433\u043b\u0442\u043e\u043d\n- \u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 offline-first\n- \u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441 OpenCorpora 2025\n\n## \u041b\u0438\u0446\u0435\u043d\u0437\u0438\u044f\n\n\u041b\u0438\u0446\u0435\u043d\u0437\u0438\u044f MIT - \u0441\u043c. \u0444\u0430\u0439\u043b [LICENSE](LICENSE).\n\n## \u0421\u0441\u044b\u043b\u043a\u0438\n\n- **GitHub**: https://github.com/mawo-ru/mawo-pymorphy3\n- **PyPI**: https://pypi.org/project/mawo-pymorphy3/\n- **\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u044b**: https://github.com/mawo-ru/mawo-pymorphy3/issues\n- **\u0414\u0430\u043d\u043d\u044b\u0435 \u0438 \u043c\u043e\u0434\u0435\u043b\u0438**: https://github.com/mawo-ru/mawo-nlp-data\n- **\u041e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 pymorphy2**: https://github.com/pymorphy2/pymorphy2\n- **\u041e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 pymorphy3**: https://github.com/no-plagiarism/pymorphy3\n- **OpenCorpora**: http://opencorpora.org/\n\n---\n\n\u0421\u0434\u0435\u043b\u0430\u043d\u043e \u0441 \u2764\ufe0f \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 [MAWO](https://github.com/mawo-ru)\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "\u0423\u043b\u0443\u0447\u0448\u0435\u043d\u043d\u044b\u0439 \u043c\u043e\u0440\u0444\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u0434\u043b\u044f \u0440\u0443\u0441\u0441\u043a\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430 \u0441 DAWG-\u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0438 \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u0435\u043c \u043f\u0430\u043c\u044f\u0442\u0438 \u043d\u0430 90%",
"version": "1.0.2",
"project_urls": {
"Changelog": "https://github.com/mawo-ru/mawo-pymorphy3/blob/main/CHANGELOG.md",
"Documentation": "https://github.com/mawo-ru/mawo-pymorphy3#readme",
"Homepage": "https://github.com/mawo-ru/mawo-pymorphy3",
"Issues": "https://github.com/mawo-ru/mawo-pymorphy3/issues",
"Repository": "https://github.com/mawo-ru/mawo-pymorphy3"
},
"split_keywords": [
"nlp",
" russian",
" morphology",
" pymorphy3",
" dawg",
" mawo"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "bdd1b7fd0768d04f64c0567e3d4d2ea4d333a74b6db02f3da526849c1bb2cffa",
"md5": "361d30a98d3050a2426a8ba28a60ea11",
"sha256": "c50ffb256d08f90094747eb51ff2d77832374b029bb7cb2f55404a2ae86ba416"
},
"downloads": -1,
"filename": "mawo_pymorphy3-1.0.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "361d30a98d3050a2426a8ba28a60ea11",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 6877842,
"upload_time": "2025-11-04T12:53:21",
"upload_time_iso_8601": "2025-11-04T12:53:21.913737Z",
"url": "https://files.pythonhosted.org/packages/bd/d1/b7fd0768d04f64c0567e3d4d2ea4d333a74b6db02f3da526849c1bb2cffa/mawo_pymorphy3-1.0.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "f0c5e706d2e76381f9dc5a51608ef920fb656724ef78e3715a053f1b061b39ce",
"md5": "c0dcff54dcb1d37c33b0a59c59ed0527",
"sha256": "0c6241680fab063bf527dfaf2165c5d5ec5319c69d603226007e42d5b7038ab6"
},
"downloads": -1,
"filename": "mawo_pymorphy3-1.0.2.tar.gz",
"has_sig": false,
"md5_digest": "c0dcff54dcb1d37c33b0a59c59ed0527",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 6837258,
"upload_time": "2025-11-04T12:53:23",
"upload_time_iso_8601": "2025-11-04T12:53:23.901073Z",
"url": "https://files.pythonhosted.org/packages/f0/c5/e706d2e76381f9dc5a51608ef920fb656724ef78e3715a053f1b061b39ce/mawo_pymorphy3-1.0.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-11-04 12:53:23",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "mawo-ru",
"github_project": "mawo-pymorphy3",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "dawg-python",
"specs": [
[
">=",
"0.7.2"
]
]
},
{
"name": "tqdm",
"specs": [
[
">=",
"4.67.1"
]
]
}
],
"lcname": "mawo-pymorphy3"
}