# Бэклог фронта (зонный) > Ведёт зона `frontend/` (решение владельца 02.08, D39.84: фронт и платформа держат СВОИ бэклоги; единый бэклог `docs/PROGRESS.md` — трекер движка/полигона/доков, фронт-строк не принимает). Нормы те же: ID стабилен навсегда, каждая петля получает диспозицию. Запросы к ДВИЖКУ сюда не пишутся — они заходят строками единого бэклога через оркестратора (пример: строки 99–102 — пофазный прогресс · манифест глав · машиночитаемая таблица подписи · трасса). **Развод «предложить/ратифицировать» (D39.99 п.4, после инцидента остановки S3): ПРЕДЛАГАТЬ артефакты для чужих решений — черновики контрактов, входы дизайна — фронт не только может, но обязан; не может он их РАТИФИЦИРОВАТЬ. «Не заводит своим решением» значит «финальное слово не его», а не «не смей писать черновик».** Засеян оркестратором при лендинге D39.84 — дальше правят фронт-сессии. | ID | Хвост | Вес | Источник | |---|---|---|---| | Ф-1 | **Этапы S2–S7** (`FRONTEND_SESSION_PROMPT.md`): S2 оболочка + слой `src/ui/` · S3 слой данных/MSW/фикстуры всех состояний · S4 библиотека/загрузка/разбор/прогресс · S5 банк памяти и подпись (самый тяжёлый) · S6 читалка двух колонок и замечания · S7 метаданные/экспорт/настройки/сквозной прогон | по очереди сессий (S0/S1 — текущая) | FRONTEND_SESSION_PROMPT | | Ф-2 | **React Compiler** — включить ОТДЕЛЬНЫМ шагом после заморозки интерфейса, с CI-проверкой, что вставки реально попали в бандл (в MVP выключен; совместимость держит линт eslint-plugin-react-hooks) | после заморозки UI | STACK_DECISIONS §1 | | Ф-3 | **Пересмотр TS 6 → TS 7** после выхода TS 7.1 с программным API (~октябрь 2026); решение обратимо — тайпчек не участвует в сборке | триггер: релиз TS 7.1 | STACK_DECISIONS §1 | | ~~Ф-4~~ | ~~**Токен-гейт на отступы**~~ — **включён 04.08 в S2.** Значение теперь обязано быть последовательностью `var(--…)`; `0`, `auto` и `inherit` легальны (это не размеры), `calc()` намеренно запрещён: составное выражение из литералов проверить нечем, а если размер понадобился новый — его место в `tokens.css`. Свойства взяты регулярками, поэтому длинные формы (`border-top-left-radius`, `padding-inline`) закрыты тоже. Обкатка потребовала трёх токенов, которых не хватало: `--radius-round`, `--radius-bar`, `--row-inset`. Проверено шестью живыми нарушениями и тремя легальными формами (перечень — `FRONTEND_PLAN.md` §5.4) | закрыт | STACK_DECISIONS §3 | | ~~Ф-8~~ | ~~Вопрос владельцу: закрывать ли `/* eslint-disable */` в TSX~~ — **закрыт 02.08 без решения владельца.** Вопрос был поставлен как выбор из двух плохих вариантов, а у него есть отраслевой третий: `@eslint-community/eslint-plugin-eslint-comments` 4.7.2 (`no-unlimited-disable` + `require-description` + `disable-enable-pair`). Голое отключение падает тремя ошибками, точечное подавление с причиной проходит. Урок: не выносить владельцу технический вопрос, не поискав отраслевую практику | закрыт | адверсариальное ревью S1 | | ~~Ф-9~~ | ~~**Хвосты гейтов после адверсариального ревью S1**~~ — **все четыре закрыты 04.08 в S2**, каждая живым нарушением: именованные и системные цвета в TSX ловятся разрешающим списком на цветных атрибутах (`fill`/`stroke`/`color`/`stopColor`/`floodColor`/`lightingColor` — только `none`, `currentColor`, `inherit`, `transparent`, `var(--…)`) · значение CSS-переменной в `style={{…}}` обязано быть числом или токеном · носитель `style` внутри объектного литерала запрещён, и тем самым закрыт JSX-спред · системные цветовые ключевые слова закрыты `declaration-property-value-disallowed-list` по ВСЕМ свойствам, то есть и в сокращённых записях `outline`/`box-shadow`/`border`. Перечень проверенных форм (15 TSX + 14 CSS) — `FRONTEND_PLAN.md` §5.4.1. **Граница названа честно и там же:** гейт цветных атрибутов ловит литерал и шаблон, но не вычисленное значение (`const c = 'red'; `) — синтаксически это не берётся, и объявлять строку «закрытой без остатка» было бы ровно тем переобещанием, из-за которого она и заведена | закрыт для литеральных форм, граница названа | адверсариальное ревью S1 | | ~~Ф-10~~ | ~~**Хвосты структурных тестов**~~ — **закрыты 04.08 в S2.** `cssModules.test.ts` строит пары по ИМПОРТАМ, а не по совпадению имён файлов, видит деструктуризацию `const { name } = styles` и выкидывает `url(...)` и строковые литералы до поиска классов; проверка сиротства стала «модуль, который никто не импортирует». `tokens.test.ts` получил замок полноты: каждый токен обязан попасть либо в замеры, либо в явный список подобранных, и обратно — список не может ссылаться на исчезнувший токен. Плюс новое: числа для виртуализатора живут в `src/tokens/measures.ts` и сверяются с одноимёнными токенами. Семь живых нарушений, перечень — `FRONTEND_PLAN.md` §5.4 | закрыт | адверсариальное ревью S1 | | Ф-11 | **Контраст ниже порога WCAG на 4 узлах на маршрут** (приглушённый текст `#707479` и `#8a8e91` на `#17191a`); число сверено живым прогоном `npm run check:full` 04.08 — axe печатает по 4 узла и на `/showcase`, и на `/scale`, а записанные здесь «5» устарели после фикс-пака S2. Это прямое следствие копирования палитры Fleet, которую владелец принял; axe отчитывается о них отдельно и команду не валит. Решение владельца: оставить как есть ради верности референсу или поднять приглушённые тона | решение владельца | ревью S1 №2 | | Ф-12 | **Масштаб списков** — **главное закрыто 04.08 в S2 замером, а не обещанием.** Заведён маршрут `/scale`: та же оболочка на настоящем масштабе — 2284 раздела и банк на 1200 терминов (`src/mock/scale.ts` через `getScaleFixture()`). Дерево и банк виртуализованы по умолчанию (RAC `Virtualizer` + `ListLayout`), и это измерено в живом браузере: на 2293 узлах дерева в DOM держится **31 строка**, `scrollHeight` 59 618px, кадр при прокрутке — медиана 22 мс, p95 31 мс; банк на 1200 терминах — 30 строк в DOM, медиана 16,7 мс. Прокрутка до конца и обратно счётчик строк не растит. **Замечания намеренно НЕ виртуализованы:** их список пер-главный, а юнитов на главу ≈1,9 (ПТ-21) и флаг у юнита один — 10³ там не бывает по построению; сводный вид по книге, если он появится, придёт с S6 и получит тот же примитив `ui/List`. **Два хвоста строки НЕ сделаны и получают диспозицию, а не зачёркивание** (нашло адверсариальное ревью S2): дерево осталось плоским без группировки по сотням — это работа экрана глав (S4), у оболочки для неё нет ни данных, ни требования; банк без разделения «подписано / ждёт решения» — это работа подписного экрана (S5), справочному виду в 320px разделение только мешает | масштаб закрыт; группировка — S4, разделение банка — S5 | ревью S1 №2 | | Ф-14 | **Вход фронта в контракт API (единый бэклог, строка 95)** — **доведён до артефакта 04.08 в S3: [`API_CONTRACT_INPUT.md`](API_CONTRACT_INPUT.md)**, перечень с обоснованием на каждый пункт, каждое обоснование грунтовано `file:line` движка (прочитано, не пересказано). Внутри: язык кодами · идентификатор главы отдельно от номера (номер производный от чанкера, `chunker.go:101-118` — пустая глава не потребляет номер, правка исходника сдвигает нумерацию) · единица пары = ЮНИТ с ключом лидера `(chapter, firstChunkIdx)`, `export.go:88-93` · состояние у прогона, у главы выполнение · прогресс пофазно по юнитам · `run_id` · трёхзначный `auto\|draft\|approved` вместо булева `signed` · непрозрачный ключ строки банка (автоинкремент движка стабильным НЕ является — `migrate.go:172-174`, банк заменяется целиком каждый прогон) · поля `type`/`sense`/`since_ch`/`source` с точным словарём · подпись = набор решений promote/decline, стоп снимается ТОЛЬКО полным набором (`mining.go:200-202`) · продуктовый словарь вердиктов и запрет `detail` на стороне контракта · монотонный `id` + `Last-Event-ID` + ревизия на чтениях из того же счётчика · **разрешающий список полей вместо вычитания** (инвентарь протечек `StatusReport`/`ChapterPassport`: деньги · `routing`/модели · снапшот/дрифт/ре-билл) · правило эволюции словарей под Ф-22. Плюс 6 вопросов (К-1..К-6), на которые фронт ответа не имеет. **Найдено при сборке — четвёртый экземпляр класса «фикстура выдумала форму»:** титульная политика pack-13 рендерит заголовок ДЕТЕРМИНИСТИЧЕСКИ («Глава {n}» из `configs/langpacks/zh-ru/heading.txt`), вырезает исходный маркер из текста для модели (`chunker.go:110-118`) и ВКЛЕИВАЕТ титул внутрь финального текста первого юнита (`export.go:209-215`), оставляя колонку исходника без него — а фикстура рисует «Раздел N. …» в дереве и неснятый «第二节:» в оригинале. Не чинится до ответа на К-2: правка формы заголовка без контракта даст пятую выдумку. **По слову владельца тем же днём написан и ЧЕРНОВИК самого контракта — [`API_CONTRACT_DRAFT.md`](API_CONTRACT_DRAFT.md)** (12 разделов + приложение-карта вердиктов; каждое место помечено «выведено из кода» / «предложено фронтом» / «открыто»; двухфазный поток ВЫВЕДЕН из `--verify-bank`, а не спроектирован; в конце — прогон ревью-вопроса строки 95 по шести изменениям движка). Самопроверка черновика нашла дыру в самой лестнице статусов строки 95: между «разбор» и «перевод» нет состояния покоя, а библиотека обязана показывать разобранную книгу, которую не запускали ⇒ заведено `not_started`, и сегодняшние девять значений типов разводятся на десять. **Дофикс по ревью оркестратора (04.08) исполнен, форма сменена по решению владельца:** нормативная поверхность контракта — теперь **OpenAPI 3.1 `docs/api-contract/openapi.yaml`** (spectral шестым шагом `check`, openapi-typescript генерит `src/api/schema.ts`, тест дрифта + ветка неизвестного значения на шве `src/api/contract.ts`, MSW-хендлер как proof-of-form); md стал спутником — провенанс, обоснования, К-вопросы. Закрыты оба блокера ревью (состояние пары выводится из ПАРЫ «вердикт + наличие текста», а не из вердикта — флагнутый юнит легально приходит С текстом; чтение банка помечено зависимостью «канала нет»), восемь ✓-инфляций пере-размечены на ◆, внесены все фактические правки (фантом `auto` в провенансе убран по путям записи · `upstream_not_ok` добавлен · ПТ-34 заведён пунктом · стоп по потолку разведён с `failed` · правило разрыва `Last-Event-ID` · смягчён §12 про чанкер). Открытых вопросов стало девять: добавлен К-9 — **отказ прескрина (строка 94) не выразим ни одним из десяти статусов**. **Ратифицировать и перенести в `docs/architecture/14-api-contract/` — оркестратор; фронт этого не может** (шапка этого файла). **Подрезана 04.08 по слову владельца:** из описаний спеки убран провенанс и грунты `file:line` — они дублировали спутник и разошлись бы с ним при первой правке; осталось норматив плюс та оговорка «почему», что предотвращает конкретную ошибку. Спека переведена на английский, потому что её описания приезжают доккомментариями в генерённый `src/api/schema.ts` (Ф-25). Адверсариальная проверка подрезки нашла в спеке три расхождения с самим спутником (провенанс `mined` подан как «никем не подписано» — это ось `status`; ревизия кадра объявлена фактом при открытом К-4; `Run.status` берёт книжный словарь целиком) и два вопроса, которых не было: **К-10** пофазность выполнения главы и **К-11** условная обязательность полей ⇒ открытых стало одиннадцать. **Бумага сокращена тем же днём:** `API_CONTRACT_INPUT.md` под ⚠-баннером «исполнено, не поддерживается» — его 18 разделов лежат один-в-один в §2 спутника, и как живой документ он был третьим местом правки; не удалён (untracked, удаление невосстановимо), перенос в `docs/archive/` — оркестратору. Из спутника убран §1 (пины и отклонение по пиру дублировали `STACK_DECISIONS.md` §3 и Ф-23/Ф-24). **Второй пасс ревью (round-2) исполнен:** чтение выгрузки + К-12 · условие `if action=promote → dst` непустой (spectral валидирует, генератор ИГНОРИРУЕТ — записано в К-11 измерением) · `kind` nullable с правилом пустого, пометка ✓→◆ · `resume` после потолка помечен зависимостью на платформенный механизм поднятия · §2.7 переписан: «текст + замечание» это класс, но `glossary_miss` в него не входит (проверено по `memberDrops`/`waverun`), фикстура `r2-2` переведена на c-lite drop · ветка неизвестного добита до шести словарей. Открытых вопросов двенадцать | спека + спутник готовы · ждут ратификации | ревью S1 №3 · сборка S3 04.08 · дофикс ревью 04.08 · подрезка 04.08 | | Ф-15 | **`src/api/` синхронен, состояний загрузки и ошибки в типах нет** — диспозиция: НЕ чинить сейчас. Два независимых скептика показали, что S2 данных не читает вовсе, а асинхронность приезжает на S3 вместе с MSW и TanStack Query, до первого продуктового экрана; самодельный хук сегодня = работа S3, которую S3 выбросит. Строка держит обязательство S3: ветки ожидания/ошибки/пустоты появляются вместе с MSW, а не после первого экрана. **04.08 (S3): замок проверен исполнением — `docs/architecture/14-api-contract.md` не существует, строка 95 единого бэклога всё ещё «дизайн-промт по слову владельца». Строка НЕ закрыта и переносится в сессию, которая застанет замок открытым**; чинить «пока на своих типах» запрещено промтом S3 по той же причине, по которой заведена строка 95 **Дофикс 04.08 продвинул строку, но НЕ закрыл:** типы контракта теперь генерятся из спеки (`src/api/schema.ts` + дружественные псевдонимы `src/api/contract.ts`), ветка неизвестного значения стоит на шве, MSW отдаёт одно тело как proof-of-form. Экраны при этом по-прежнему живут на `src/api/types.ts` — рабочей гипотезе до контракта: перевод экранов на генерённые типы и удаление `types.ts` это и есть S3, и делать его до РАТИФИКАЦИИ спеки нельзя по той же причине, по какой заведена строка 95. Ветки ожидания/ошибки/пустоты и фикстуры всех состояний тоже ждут S3 | S3, вход закрыт ратификацией контракта (перепроверено 04.08) | ревью S1 №3 | | Ф-13 | **`eslint-plugin-jsx-a11y` не встаёт на ESLint 10** (peer `^3..^9`, проверено `--dry-run` → ERESOLVE). Статическую половину доступности держит axe в скриншот-цикле; плагин подключить, когда выйдет совместимый мажор | триггер: мажор плагина | ревью S1 №2 | | Ф-7 | **Хвосты сведения витрины с референсом** (`FRONTEND_PLAN.md` §5.2). **Часть S2 закрыта 04.08:** `+` стоит в ряду вкладок ЛЕВОЙ панели и запускает «Добавить книгу» (решение владельца 04.08); дублирующая строка «+ Добавить книгу» из дерева убрана — одна вещь, одно место. В центре и справа `+` нет и не будет: наборы вкладок там фиксированные, пользователь их не расширяет, и кнопка вышла бы декоративной — ровно то, что эта строка запрещает. Состояния наведения перестали быть «непроверенными»: они сняты не статичным кадром, а прогоном браузера (`data-hovered`/`data-selected`/`data-focus-visible` у кнопки, вкладки, строки дерева и списка). **Осталось на S6:** приглушённая колонка оригинала — решение, а не замер, пересмотреть на настоящей читалке | ~~S2~~ · S6 | S1, сверка с fleet.png | | Ф-16 | **Выгрузка книги (§3.11) ушла из верхней полосы.** В витрине S1 там висела иконка загрузки без действия; по правилу Ф-7 («кнопка только вместе с действием») она снята до S7, который строит экспорт. Вернуть иконку вместе с самим действием | S7 | S2 | | Ф-17 | **Закрытие вкладки с клавиатуры не объявлено скринридеру.** Крестик у вкладки-документа сознательно НЕ кнопка: у роли `tab` дети презентационные (ARIA), вложенный фокусируемый элемент выпал бы из дерева доступности, оставшись в порядке табуляции (это же ловит axe правилом `nested-interactive`). Мышь закрывает крестиком, клавиатура — `Delete` на выбранной вкладке. Объявить сочетание нечем: `aria-keyshortcuts` не входит в типизированный API `Tab`/`TabList` в react-aria-components 1.20.0. Пересмотреть при обновлении библиотеки либо при появлении палитры команд | триггер: мажор RAC или экран горячих клавиш | S2 | | Ф-19 | **Переключение вкладки размонтирует её содержимое, и прокрутка длинного списка теряется.** Нашло адверсариальное ревью S2 и подтвердило независимым прогоном: `react-aria-components` не рендерит невыбранную `TabPanel` (`dist/private/Tabs.mjs:276` — `if (!isSelected && !shouldForceMount) return null`), поэтому на `/scale` прокрутка дерева `scrollTop=9000` → вкладка «Поиск» → обратно даёт `scrollTop=0`, а пересборка коллекции из 2284 узлов стоит 70–140 мс (два независимых замера). Ф-12 это не переоткрывает: там речь про поведение списка при 10³, и оно держится. **Чинить сейчас не стали:** `shouldForceMount` не лечит (панель остаётся видимым `div` и легла бы поверх соседней в той же ячейке грида), а настоящее лекарство — keep-alive либо запоминание офсета на вкладку — это решение об устройстве оболочки, и принимать его вслепую, до настоящих экранов, значит строить механизм не под задачу | S4 (экран глав) либо раньше, если владелец увидит потерю места | адверсариальное ревью S2 | | Ф-20 | **Мёртвый шрифт и мёртвые токены в поставке.** `@fontsource-variable/jetbrains-mono` грузится в бандл, но `--font-mono` не выбран ни одним правилом: художественную прозу моноширинным не набирают, а во Fleet на этом месте был код. Туда же несколько токенов, которые ни разу не используются (`--color-current-line`, `--color-hint`). Замок полноты токенов (S2) требует классифицировать токен, но не требует его использовать. Решать на S6, когда читалка станет настоящей: либо моноширинный находит работу, либо импорт и токены уходят | S6 | адверсариальное ревью S2 | | Ф-22 | **У закрытых юнионов нет ветки неизвестного значения, и тайпчек здесь не страхует.** `runStates[book.state]` (`showcase/Library.tsx:103`) — обращение к `Record` по КОНЕЧНОМУ юниону, а `noUncheckedIndexedAccess` добавляет `undefined` только индексным сигнатурам: проверено пробой `tsc` — обращение по юниону компилируется молча, ругается лишь `Record`. Значение вне юниона (новое состояние прогона из контракта API) даёт `undefined.tone`, то есть падение дерева библиотеки, а не пустую метку; тем же классом `noteTone` тихо уводит незнакомую ступень замечания в спокойную ветку. Лечение — ветка неизвестного значения НА ШВЕ `src/api/`, где значение входит, а не в каждом компоненте. В S2 находку отвели скептики формулировкой «это работа S3» — она и есть работа S3, но хвост записан здесь, чтобы не жить только в промте. **04.08 (S3): не сделано — вход закрыт вместе с Ф-15.** Разбор при сборке Ф-14 добавил к строке то, чего в ней не было: поведение ветки (показать нейтрально ↔ отвергнуть ответ) зависит от того, минор это или мажор по version-хендшейку, а это знание КОНТРАКТА — значит ветку нельзя написать раньше него не только организационно, но и по существу. Просьба объявить правило эволюции словарей ушла в артефакт §7; сам движок такую дисциплину уже держит (`status.go:180` ранг по умолчанию, `banknote.go:73` фолбэк в `term`) | S3 (вместе с приведением типов к контракту) | адверсариальное ревью S2 → ревью оркестратора 04.08 | | Ф-21 | **Ступень замечания различается только цветом полоски** (`attention` синяя, `glance` серая). Зрячему разница читается ещё и светлотой, но скринридеру приоритет не достаётся вовсе. Лечение — слово, как это уже сделано для состояния прогона книги; **какое именно слово, решает владелец**: словарь замечаний продуктовый (ПТ-33), а §3.8 требует, чтобы экран не выглядел тревожным, так что «важно/неважно» не годится | решение владельца | адверсариальное ревью S2 | | Ф-18 | **Бандл 545 КБ (168 КБ gzip) одним куском** — замер 04.08 после установки `react-aria-components`; Rolldown предупреждает про порог 500 КБ. Для десктопного SPA за логином это не авария (индексации нет, сеть локальная), но одним куском едут и экраны, которых пользователь ещё не открыл. Лечение — разбиение по маршрутам, и делать его осмысленно после S4–S7, когда экраны появятся: сейчас резать нечего | после S7 либо при жалобе на первый экран | S2, замер | | Ф-23 | **`openapi-typescript` держится на точечном `overrides`, а не на честном пире.** Генератор объявляет `typescript@^5.x` (7.13.0 вышла 11.02.2026, до релиза TS 6), у нас намеренный TS 6 — Ф-3. `--legacy-peer-deps` **отвергнут проверкой исполнением:** после него обычный `npm install` падает, то есть дерево ломается у каждой следующей сессии и у `prepare`-инсталлера pre-commit хука. Взят `overrides` на ОДИН пакет (`{"openapi-typescript":{"typescript":"$typescript"}}`) вместо глобального ослабления проверки пиров; работоспособность доказана: `npm ci` с нуля зелёный (0 уязвимостей), генератор запускается на TS 6, тест дрифта проходит. Снять, когда генератор расширит пир либо когда приедет TS 7.1 и Ф-3 закроется | триггер: пир генератора расширен ИЛИ TS 7.1 (Ф-3) | S3, дофикс контракта 04.08 | | Ф-24 | **AsyncAPI рассмотрен и отложен.** Он описал бы SSE-канал строже, чем нынешняя таблица «имя события → схема» в описании `EventEnvelope`. Отложен, потому что это второй нормативный артефакт и второй линтер ради ОДНОГО эндпоинта, при том что полезные нагрузки уже описаны схемами OpenAPI и попадают в генерённые типы. Пересмотреть, когда каналов станет больше одного либо когда понадобится генерировать клиент потока, а не разбирать кадры руками | триггер: второй канал ИЛИ генерация клиента потока | S3, дофикс контракта 04.08 | | Ф-25 | **`src/` смешанный по языку комментариев.** Конвенция владельца от 04.08 — исходники английские; мой дифф S3 ей приведён (`api/contract.ts`, `api/contract.test.ts`, `mock/handlers.ts`, `.spectral.yaml`, `.prettierignore`, хунк в `tokens/tokens.test.ts`), а комментарии S1/S2 в ~40 файлах остались русскими (`api/index.ts`, `api/types.ts`, `showcase/*`, `ui/*`, `tokens/*`, `scripts/*`). Свод — отдельный проход: он трогает уже отревьюенный и залэнденный код, то есть даёт дифф чистой косметики поверх чужой работы, и делать его надо одним движением, а не по файлу за сессию. **Границу держать явно:** переводятся комментарии, имена тестов и служебные строки; UI-текст и фикстурная проза остаются русскими — это продукт, а не код | отдельный проход, по слову владельца/оркестратора | слово владельца 04.08 | | Ф-5 | **Tauri 2.x вторым шагом** — по явным триггерам (трей · глобальные горячие клавиши · распространяемый .exe · офлайн · хранилище учёток ОС); до того — установимое PWA, только браузерные API | триггеры названы | STACK_DECISIONS §6, D39.84 | | Ф-6 | **`@tanstack/react-virtual`** — в резерве, подключать только по замеру (дефолт виртуализации — RAC Virtualizer). **Замер сделан 04.08 (S2) и триггер НЕ наступил:** RAC `Virtualizer` держит 2284 раздела на 31 строке в DOM при медиане кадра 22 мс и 1200 терминов на 30 строках при 16,7 мс. Вторая библиотека виртуализации сейчас была бы платой без выигрыша; пересматривать — если появится список с переменной высотой строки (читалка S6) и `estimatedRowSize` не справится | по замеру; замер 04.08 отрицательный | STACK_DECISIONS §2 |