Проверяется конкретный подписанный APK-кандидат, затем опубликованный артефакт. Зелёный CI, успешный dry-run и тест подключения не заменяют проверку захвата на Android. Это регламент, а не отчёт о выполненных проверках.
Каждый сценарий на каждом устройстве получает PASS, FAIL, BLOCKED, NOT TESTED или N/A. N/A требует причины, связанной с продуктом или платформой; отсутствие устройства/времени — NOT TESTED. JVM-тест и анализ исходников не заполняют ячейку проверки на устройстве. Для частичного результата укажите, что именно выполнено.
Запись: ID сценария, время UTC, commit и SHA-256 APK, устройство/ОС, предусловия,
действие, expected/actual, ссылки на доказательства, статус и результат восстановления.
Для доставки сопоставьте синтетический маркер и event_id в Журнале, HTTP-запросе
и n8n Executions; проверьте тело и статус ответа. Отрицательный сценарий требует
исправного положительного контроля до и после. Существенные ошибки авторизации,
утечки и потерю данных воспроизводите дважды с новыми маркерами.
accepted означает подтверждение веб-хука, а HTTP 2xx без ACK — только HTTP-успех.
Они не подтверждают Telegram или другой последующий узел: его проверяют отдельно.
Повторная отправка после потери ответа может создать несколько executions с одним
event_id; Message487 не обещает exactly-once. Стенд и downstream должны дедуплицировать
по ID, если это требуется сценарию.
Сырые логи, дампы БД/UI, сетевые захваты и n8n executions держите локально в каталоге 0700, чувствительные файлы — 0600. Даже URL веб-хука может содержать секрет. В Git включайте только проверенные обезличенные выдержки и синтетические фикстуры. Не отправляйте диагностическое письмо, не загружайте APK на VirusTotal, не публикуйте issues/релизы и не меняйте внешний F-Droid MR в рамках обычного тестового прогона.
| ID | Действия и доказательства |
|---|---|
| A01 | Зафиксируйте commit кандидата, diff после прошлого релиза, versionName/code, min/target SDK, зависимости/toolchain и точный источник APK. Версия берётся из app/build.gradle.kts, подпись — из scripts/build-release-apk.sh. Сохраните чужие изменения; не увеличивайте production versionCode ради теста. |
| A02 | Выполните bundle exec fastlane android checks, PYTHON=.venv/bin/python bundle exec fastlane android python_checks; после запуска локального n8n — bundle exec fastlane android server_tests. Сохраните статусы и ссылки CI именно кандидата. Нет signing-переменных в PR-проверках. Инструкции окружения — в Тесты и CI. |
| A03 | Выполните bundle exec fastlane android release_artifacts либо получите подписанный артефакт режима сборки без публикации. Сохраните SHA256SUMS, вывод apksigner verify --verbose --print-certs, aapt dump badging, permissions/merged manifest. APK должен быть release, нужного пакета/версии, с прежним ключом. Debug APK не заменяет этот шаг. |
| A04 | Сверьте исходный и merged manifest, FileProvider, exported-компоненты, backup/data extraction, ограничения HTTP, разрешения зависимостей и изменения лицензий. Объясните RECEIVE_SMS, notification listener, POST_NOTIFICATIONS, REQUEST_INSTALL_PACKAGES и компоненты планировщиков. Не требуются SMS history, default SMS role, Accessibility, QUERY_ALL_PACKAGES. Сверьте описание/PRIVACY с поведением. |
| A05 | Опишите два телефона и два выделенных эмулятора: модель, ОС/API/OEM build/patch, ABI/размер страницы, экран/шрифт/язык, пакет/версия/подпись/installer, разрешения, батарея, сеть, VPN/Private DNS. Эмуляторы — минимальный поддерживаемый API и современный. Если Samsung недоступен, OEM-проверка остаётся NOT TESTED. |
| A06 | На телефонах сохраните исходные настройки, используйте только синтетические SMS и выбранные тестовые приложения. Не включайте захват личных приложений/OTP. Не удаляйте существующую установку и не очищайте её данные. Перезагрузка, смена сети/PIN и разрушительные проверки требуют применимого разрешения; выполняйте их сначала на выделенном эмуляторе. |
| A07 | Поднимите закрытый HTTPS-стенд с доверенным сертификатом, отдельными токенами и контролируемыми ответами. Проверьте стенд прямым запросом. Локальный DevServer — HTTP/debug-фикстура, не проверка release HTTPS; для кандидата нужен HTTPS-вход. Не публикуйте стенд с общедоступными тестовыми реквизитами. Запишите ресурсы для последующей очистки. |
- Выберите commit кандидата и предыдущий подписанный релиз для миграции. Сохраните
git status,git rev-parse HEADи diff; работайте в отдельном чистом checkout, если в рабочем каталоге есть чужие изменения. Для теста до выпуска используйте подписанный кандидат, а не последний опубликованный APK с постоянной ссылки. - Подготовьте JDK 21, Ruby/Bundler, Android SDK из Gradle-конфигурации, Platform Tools,
Python и Docker. SDK задайте через
ANDROID_HOMEили локальныйlocal.properties. Для Python:python3 -m venv .venv, затем.venv/bin/python -m pip install -r requirements-dev.txt; для Ruby —bundle install. - Запустите локальный стенд:
docker compose -f DevServer/compose.yaml up -d --wait --wait-timeout 300. Выполните команды A02. Это проверка фикстур; для signed release настройте закрытый HTTPS-вход с сертификатом, которому доверяет телефон, и отдельной авторизацией. - Соберите кандидат командой A03, используя прежний ключ и signing-конфигурацию
MESSAGE487_KEYSTORE_PATH,MESSAGE487_KEY_PASSWORD_FILE,MESSAGE487_KEY_ALIAS. Не печатайте пароли. Проверьтеdist/release/SHA256SUMS; каждый последующий результат должен ссылаться на hash установленного кандидата. При F-Droid-канале выполните отдельный официальный build ниже и идентифицируйте его артефакт. - Для каждого устройства запишите serial/параметры и исходные настройки. Выберите
нужный serial в
adb -s SERIAL; установите кандидат черезadb -s SERIAL install -r /path/to/candidate.apk. Чистая установка допустима только на пустом тестовом устройстве/профиле. Сохранитеadb -s SERIAL shell pm path life.andre.message487, скачайте выведенный путь черезadb -s SERIAL pullи сравните SHA-256. Для migration сначала установите старый signed APK и создайте тестовую очередь. - На экране Подключение задайте полный опубликованный webhook URL, токен без
префикса
Bearerи синтетический код устройства; включите n8n confirmation только для стенда с описанным ниже ACK. Нажмите Save/send test, сопоставьте ID в Журнале и серверном execution. Затем отдельно разрешите SMS/notification access и выберите только тестовые приложения; выполните I/C/Q/L/D/U, фиксируя матрицу по устройствам. - После каждого отрицательного сценария верните рабочий стенд и подтвердите доставку новым маркером. В конце восстановите устройства, заполните отчёт и решение. R01/R02 не выпускают версию; R03 выполняется только после отдельно разрешённой публикации.
Сервер принимает POST с Content-Type: application/json и
Authorization: Bearer <тестовый токен>. JSON содержит schema_version, event_id,
device_id, device_code, message_type, occurred_at, source, source_name, text;
уведомление добавляет title, SMS — sender. Сохраните эти поля и время приёма
в закрытом журнале стенда. Для каждой пробы используйте новый синтетический маркер.
При включённом n8n confirmation успешный ответ — HTTP 2xx и
{"status":"accepted","event_id":"ID_ИЗ_ЗАПРОСА"}. Такой ACK настраивается workflow,
а не возникает автоматически от самого n8n. При выключенном confirmation достаточно 2xx.
Подготовьте управляемые режимы: корректный ACK, 500, 401/403, чужой event_id, malformed
JSON, задержка дольше клиентского timeout и приём запроса с потерей ответа.
Запись успешного execution без проверки HTTP-ответа не доказывает принятие клиентом.
Для раздельной проверки адресатов используйте endpoints A/B с разными тестовыми токенами.
Положительный контроль отправляйте через приложение, а не только curl. На эмуляторе
adb -s SERIAL emu sms send +15551234567 'Message487 synthetic RUN-ID' даёт отдельную
пробу SMS broadcast. Для уведомлений основная проверка — обычное приложение, создающее
уведомление с известными полями и собственным UID; shell/root используется только
дополнительно. Оба пути должны подтверждаться реальным серверным запросом.
В fdroiddata выберите build block именно
кандидата для life.andre.message487, зафиксируйте recipe SHA, upstream SHA,
fdroiddata/fdroidserver revisions, Binaries и AllowedAPKSigningKeys, если заданы.
Для внешнего MR проверяйте его текущее состояние; при независимом review требуется
соответствующее приглашение к review. Существующий опубликованный рецепт тоже допустим
как цель проверки; не заменяйте его предполагаемым новым build block.
Используйте официальный registry.gitlab.com/fdroid/fdroidserver:buildserver, запишите
фактический digest/platform, штатного пользователя сборки и конфигурацию fdroiddata.
В отдельном checkout выполните применимые команды поддерживаемой версии fdroidserver:
fdroid readmeta
fdroid lint life.andre.message487
fdroid fetchsrclibs life.andre.message487:VERSION_CODE --verbose
fdroid build --verbose --test --scan-binary --on-server --no-tarball life.andre.message487:VERSION_CODEVERSION_CODE заменяется кодом из выбранного recipe. Объясните отличие команды,
если его требует официальное окружение. Сохраните exit codes, source/binary scanner
results и путь APK. Не изменяйте recipe для получения PASS. Предупреждения исследуйте,
а не объявляйте автоматически блокерами; отдельно проверьте updater/APK downloads,
зависимости, бинарные assets и применимость Inclusion Policy.
При воспроизводимой сборке выполните официальный механизм binary comparison/signature-copy с точным upstream APK и разрешённым сертификатом. Обычный Gradle build и сравнение SHA-256 APK с разными подписями не заменяют эту проверку. Руководство F-Droid. Если matching upstream APK ещё не опубликован, проверка BLOCKED/NOT TESTED; не публикуйте релиз только ради теста и не объявляйте воспроизводимость заранее.
Для runtime установите именно проверенный подписанный APK; локальный unsigned результат
не обновляет прежнюю signed установку. Если проверяется подпись F-Droid, идентифицируйте
её отдельно. Прочитайте установленный APK через pm path/adb pull и сверяйте hash
с ожидаемым артефактом на каждом устройстве. Реальная установка клиентом F-Droid нужна
для проверки источника обновлений; установка через ADB не доказывает этот путь.
Сценарии ниже выполняйте на всех четырёх устройствах, где применимы. Для сценария, недоступного на телефоне, не подставляйте PASS эмулятора. Деструктивные сбои БД/Keystore, подмену APK/времени, process kill, Doze и искусственные ответы сначала проверяйте на выделенном стенде. На телефоне без возможности SMS используйте N/A с причиной; эмуляторная SMS не доказывает доставку от оператора.
| ID | Действие → требуемый результат |
|---|---|
| I01 | Чистая установка в пустой эмулятор/тестовый профиль; два холодных запуска. Захват SMS и уведомлений выключен, приложения не выбраны; без настройки нет отправки личных данных. Автопроверка обновлений — отдельная функция, её запросы учитывайте отдельно. |
| I02 | Установите предыдущий signed релиз, сохраните синтетические URL/токен/код устройства, выбор источников и недоставленные события, затем обновите до кандидата без удаления. Сохраняются настройки, installation ID, пауза, очередь и старые адресаты; выполните новую доставку и доставку старой очереди. Переустановка той же версии не является миграцией. |
| I03 | Отказать → выдать → отозвать RECEIVE_SMS и notification access. Нет захвата отключённого источника, нет падения/ложного статуса; повторное разрешение восстанавливает захват только новых событий. Разрешение обычных уведомлений относится к напоминаниям обновлений, а не notification listener. |
| I04 | Restricted settings после APK-install: официальный путь разрешения, повторное открытие notification access. На Samsung — Auto Blocker при первой установке и обновлении, возврат защиты после теста. См. установку APK. Не считать разрешение unknown sources решением любой блокировки. |
| I05 | Обзор/Подключение/Источники/Журнал/Диагностика/Обновления; Back/Home, rotation, узкий экран, большой шрифт, EN/RU, светлая/тёмная тема, клавиатура, внешний/внутренний экран складного телефона. Действия и длинные диалоги доступны. Цветная и themed launcher icon проверяются реальным переключателем лаунчера, где поддерживается. |
| ID | Действие → требуемый результат |
|---|---|
| C01 | Обычное тестовое приложение с собственным UID публикует выбранное уведомление; независимая сверка title/text/time/package/source_name на сервере. Повторить с невыбранным приложением: нет события. Shell notification — дополнительная проба, не замена обычного UID. |
| C02 | Обычный текст, big text, строки InboxStyle, пустое содержимое, ongoing и group summary; обновление текста уведомления. Исключённые ongoing/summary/свои уведомления не пересылаются. Уже существующее уведомление при выдаче доступа не воспроизводится. Не обещать доступ к скрытому Android содержимому. |
| C03 | Выбор/снятие приложения, ручной пакет без launcher, поиск и «Выбрать все». Массовый выбор действует на весь список, сохраняет ручные пакеты; установленное позже приложение не выбирается само. UI-перезапуск сохраняет выбор. Не выбирайте приложение, получающее downstream сообщения: возможен цикл. |
| C04 | На телефоне получите синтетическую SMS с другого разрешённого тестового номера. Проверьте sender/text/occurred_at и source android; история SMS не импортируется, приложение не становится default SMS и не отправляет ответ. Отдельно — длинная multipart SMS, кириллица/Unicode и две разные SMS. Зафиксируйте сегментацию/время, а не только длину строки. |
| C05 | Дедупликация SMS и уведомлений: оба переключателя включены по умолчанию; проверьте независимо все четыре сочетания, выключение/включение, перезапуск и перенос старой общей настройки при обновлении. Ключ — source package + точный text, время сравнивается в настраиваемом окне ± с включёнными границами. Проверьте обе границы и значения сразу за ними, нулевое окно (точное время), сохранение настройки после перезапуска и изменение окна. Одинаковые настоящие сообщения внутри окна тоже пропускаются. Изменение title/sender само по себе не меняет ключ. Управляемую идентичность события проверяйте фикстурой/JVM и отдельно runtime с доступными контролями; не выводите PASS из двух команд с разным временем. |
| C06 | Отключение источника и пауза при захвате/отправке. Нет новых событий после отключения/паузы; пауза также задерживает старую очередь. Уже выполняющийся запрос может завершиться. После Resume старые события доставляются, пропущенные во время паузы не импортируются. Две ручные проверки подключения не должны подавляться дедупликацией сообщений. |
| ID | Действие → требуемый результат |
|---|---|
| Q01 | Save/send test, затем реальные capture events через HTTPS. Правильный Bearer в Authorization, JSON schema/поля, уникальный event_id и совпадающий ACK. Device code сохраняется, installation ID стабилен. Journal не показывает тело сообщения. Успех ручного test не доказывает RECEIVE_SMS или listener. |
| Q02 | Правильный → неверный → отсутствующий/некорректный → восстановленный токен. Невалидный ввод не сохраняется; сервер отклоняет неправильный, UI не показывает принятие. Неверная TLS CA/hostname, self-signed без доверия и HTTP в release отклоняются. Редирект не пересылает тело/Authorization на новый адрес. Держите положительные контроли до/после. |
| Q03 | n8n ACK: чужой/отсутствующий event_id, неверный status, malformed/слишком большой JSON; generic webhook с ACK выключенным. HTTP 2xx с неверным ACK — BLOCKED и ручной retry, а generic 2xx — HTTP_SUCCESS. Отличайте отказ клиента от успеха выполнения n8n error-workflow. |
| Q04 | Timeout/network failure, HTTP 408/425/429/5xx → очередь повторяет; прочие HTTP failures → ручное исправление/retry. После восстановления сохраняются event_id, тело, старый URL/токен/ACK. Ответ потерян после приёма: возможен повтор на сервере, ID прежний. Нет обещания точного времени WorkManager retry. |
| Q05 | Создайте offline очередь на endpoint A, смените настройку на B. Старые события идут только на A с прежними реквизитами; новые — на B. Ротация токена в UI не исправляет старый encrypted envelope. Используйте отдельные тестовые endpoints; при необходимости старые события явно удаляют, а не тихо перенаправляют. |
| Q06 | Retry now, удаление тестовой записи, быстрые повторные действия и открытый detail при смене состояния. Нет дублирования локального события/потери очереди; активную отправку нельзя удалить как свободную запись. После acceptance payload удаляется из активной записи, metadata остаётся ограниченной; logical delete не доказывает физическое стирание. |
| Q07 | Offline enqueue → обычное завершение процесса/rotation/relaunch → восстановление сети. Проверить сохранность encrypted payload и доставку, включая очередь предыдущей версии. Недоступный Keystore/повреждённое хранилище — изолированный сценарий: нет отправки мусора или тихого удаления; ошибка видна. Успех Robolectric не доказывает настоящий Keystore. |
| ID | Действие → требуемый результат |
|---|---|
| L01 | Home, блокировка экрана, удаление задачи и возвращение: новый capture и доставка с серверным доказательством. Два цикла сервер unavailable → available и offline → online; отдельно реальный Wi-Fi → мобильная → Wi-Fi на телефоне. ADB reverse/виртуальная cellular не доказывают handover оператора. |
| L02 | На выделенном эмуляторе отдельно process death и am force-stop. Force-stop — системная остановка, не креш. После неё открыть приложение и проверить восстановление сохранённой очереди; не обещать захват событий, потерянных пока Android держал пакет stopped. Настоящий LMKD/OOM — отдельная проверка. |
| L03 | Reboot при доступной/недоступной сети, разблокировка и новая SMS/notification; delivery recovery и источник/расписание обновлений сохраняются. Работу до первого unlock не считать обещанной: компоненты не заявлены directBootAware. Пробу в RUNNING_LOCKED фиксировать отдельно от результата после unlock. |
| L04 | Forced Doze и OEM battery restriction, затем восстановление нормального режима; pending сохраняется, доставка возобновляется. Записать actual idle/exemption/network и длительность. Forced job не доказывает естественное суточное расписание. Foreground/background soak — не менее 15 минут с несколькими событиями; более длительные/суточные прогоны отмечать отдельно. |
| L05 | Обновление APK при очереди и включённых источниках, затем при паузе. Сохраняется decryptability/адресат/состояние; пауза не снимается, источник не включается сам. Проверить новые события после установки и listener reconnect. |
| ID | Действие → требуемый результат |
|---|---|
| D01 | Синтетические маркеры в body/title/sender/URL/token/device code/ID/response. Искать в app logs, crash file, ZIP и доступных системных логах; нет утечки исключаемых полей. Часть private preferences и delivery metadata не имеет дополнительного шифрования — сверять с PRIVACY, а не обещать полное шифрование данных. Проверка SQLite/Keystore только на разрешённом стенде. |
| D02 | Диагностика refresh/clear/ZIP/email chooser, Cancel и отсутствие mail app. Очистка логов не удаляет очередь. FileProvider даёт временное чтение выбранного вложения без произвольного доступа к данным/записи. Остановитесь на редакторе письма, ничего не отправляя. |
| D03 | На выделенном эмуляторе вызвать app crash и повторный запуск: prompt, crash file, ZIP. Debug injection — отдельное доказательство, не PASS release-candidate crash handling. Проверить release crash, если воспроизводимый механизм доступен. ANR/native crash/kill не считать обработанными Java handler. Сопоставить logcat, exit reason и действия. |
| D04 | Обычным probe APK попробовать чужие intents/broadcasts/provider access: нет доступа к секретам, управления приватными update actions или подделки SMS защищённому receiver. Проверить BIND_NOTIFICATION_LISTENER_SERVICE/BROADCAST_SMS/BIND_JOB_SERVICE и merged components. Shell UID/root не доказывают изоляцию от обычного приложения. |
| ID | Действие → требуемый результат |
|---|---|
| U01 | Реальные установки официальным/сторонним F-Droid клиентом, браузером/файловым менеджером, неизвестным установщиком; ручной выбор. Источник следует installer и поддержке repo links, выбор сохраняется. Просто установленный F-Droid не меняет browser installation. 404/offline не переводят на другой источник. Подмена installer metadata — только моделирование. |
| U02 | Новая/та же/старая/повреждённая metadata; consent/Cancel download, ошибка/обрыв/size/digest/package/version/signer. Без согласия нет APK download, проверка обновлений от согласия не зависит. Неверные APK сначала JVM/изолированный эмулятор. Fixture-версии не публиковать и production versionCode не менять ради проверки. |
| U03 | GitHub download → отдельное Install, отказ/выдача unknown-source permission, возврат из Settings, Cancel/успех, rotation/background. Сверить установленную версию/hash/подпись и доставку после установки. F-Droid открывает страницу, установку выполняет клиент. Разные подписи не обновляют друг друга; не удалять приложение как первое «исправление». |
| U04 | Reminder permission/channel, Open/Skip/Disable, manual check после Skip, выключение при running job, reboot. Проверить повтор через неделю и отсутствие раннего повторения управляемым временем на эмуляторе. Принудительный запуск и simulation не считать естественным daily/weekly результатом. |
| R01 | Dry-run с явно заданной предполагаемой версией: генерация EN/RU и проверки чтения, без файлов/релизной ветки/PR/merge/tag/Release. Пустое поле CI означает обычный CI. Перед/после сравнить refs/PR/releases; mock-тест и live run отметить отдельно. Dry-run не доказывает права записи, signing или прохождение ruleset. |
| R02 | Перед реальным выпуском прочитать EN/RU changelog, сравнить versionName/code, историю и список файлов релизного PR. Gate должен ждать полный CI конкретного head/base; старый/skipped CI не принимается, изменённый main/head останавливает merge. Эти отказные случаи тестировать локально с mocks, не ломая production правила. |
| R03 | Только после отдельного запуска выпуска проверить фактический merged commit/tag, tree и источник опубликованных APK, checksum/подпись, постоянный и versioned URL, changelog обеих локалей. Сверить APK с проверенным кандидатом; различающийся артефакт требует расследования/retest. F-Droid build/publication подтверждается отдельно. |
Сначала APK identity, доставка test/SMS/notification на каждом устройстве, отрицательная авторизация/ACK, offline recovery и migration. Затем фон, updater, приватность и OEM/UI. При сокращении матрицы оставляйте NOT TESTED; оно не становится PASS. Для небольшого follow-up опишите diff, обязательные соседние регрессии и границы сокращённого прогона. Старые phone results не переносите на новую версию даже при неизменённом UI.
В конце остановите только созданные стенды/captures, удалите только свои ADB forwards/reverses, probe APK и синтетические события; верните сеть, permissions, источник/автопроверку, батарею, экран/шрифт/язык, Auto Blocker и исходные настройки приложения. Не удаляйте чужие workflow/volumes и личные сообщения. Удаление локального события не удаляет копию из n8n/downstream: очистите синтетические executions отдельно. Запишите остаточные изменения и проверьте устройства после восстановления.
Не рекомендовать выпуск при потере очереди/секретов, неверной подписи, обходе авторизации, утечке исключаемых данных, необъяснённых падениях или неработающем захвате/доставке на поддерживаемом устройстве. Критическая непроверенная миграция или BLOCKED gate означают РЕЛИЗ НЕ ПРОВЕРЕН. Для каналов GitHub и F-Droid фиксируйте отдельную готовность. Исправление: минимальная отдельная ветка, воспроизведение/регрессионный тест, новый APK, повтор affected и соседних сценариев; старый FAIL остаётся до retest.
Отчёт — docs/reviews/release-YYYY-MM-DD.md, только обезличенный материал:
Кандидат: commit, версия/код, SHA-256, сертификат, канал/происхождение APK
Окружение и устройства: фактические параметры и ограничения
Команды/CI/F-Droid: версии инструментов, recipe/image digest, результаты
Матрица: ID | устройство | PASS/FAIL/BLOCKED/NOT TESTED/N/A | доказательства
Находки: expected/actual, серьёзность, контроли, функция, retest commit/APK
Восстановление: ресурсы, что удалено/возвращено, остаточные изменения
Решение: готовность GitHub/F-Droid, blockers и непроверенные сценарии
До публикации устройство должно проверять подписанный кандидат из релизного PR; для проверки changelog до merge нужен human review gate в релизном флоу. Постпубликационный R03 — дополнительная проверка, а не разрешение выпускать непроверенный APK. В рамках подготовки этого регламента тесты на устройствах не выполнялись.
Запишите точные head/base PR, URL CI, отдельные результаты API 26/35, JUnit Checks, ссылку на APK и SHA-256. Ссылки обновляются в описании PR; неподписанные PR APK и тесты debug на эмуляторах не подтверждают приёмку подписанного релизного кандидата. Новому коммиту нужен новый CI; skipped или отсутствующие результаты эмуляторов блокируют финализацию.