PageSourceSearch

https://osm2cdr.com/account

html osm2cdr.com collected 2026-09-25 20:39:03 UTC 69,396 bytes, 721 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en">
3<head>
4  
4<script>window.LOCALE_V='20260924wallet';</script>
4<!-- 24.09 (T-260924-36b8, один кошелёк): +3 ключа acc_wallet_enough, acc_wallet_enough_none и acc_bill_meter («хватит ещё карт» — число и цену считает сервер), +1 ключ acc_bill_meter и переписан acc_bill_beta — порядок списания выбирается по состоянию гейта взимания (billing_active), а не зашит одной фразой, карточка карт перестала быть подарком (acc_bonus_h / acc_bonus_sum / acc_bonus_nocash), ключ acc_bonus_zero удалён вместе с разметкой, а acc_money_beta больше не обещает, что деньги за сборку не списываются. Без бампа страница берёт словарь из кэша и продолжает обещать бесплатность. --><!-- 24.09 (T-260924-126d, первые живые деньги): +13 ключей — окно подтверждения покупки пакета (acc_pack_confirm_*) и разбор счёта «откуда эта сумма» (acc_
4wallet_origin_*). Без бампа страница берёт словарь из кэша, и окно, которое спрашивает согласие на списание чужих денег, выходит ключами. --><!-- 22.09 (T-260921-b791, витрина покупки в кабинете): +5 ключей acc_sum_cards / acc_sum_cards_none / acc_sum_pack_buy / acc_price_h / acc_price_keep — остаток карт с кнопкой пакета и краткие тарифы на «Главной»; ключ acc_plan_free (плашка «Бесплатный») больше никем не зовётся. Без бампа страница берёт словарь из кэша и новые подписи выходят ключами. --><!-- 21.09 (T-260921-5344, текст про деньги на счету больше не врёт): acc_money_beta переписан БЕЗ хвоста про сумму на счету, +1 ключ acc_money_have — отдельная фраза про деньги, которую кабинет показывает только тогда, когда остаток действительно покрывает названную сумму. Без бампа страница берёт словарь из кэша и продолжает обещать деньги тем, у кого на счету ноль. --><!-- 21.09 (T-260921-fdbb, кнопка «+» рядом с суммой на счету): +1 ключ acc_sum_topup_open — подпись кнопки для читалки экрана. Заголовок окошка и подпись кнопки оплаты взяты готовые (acc_wallet_amount_ph, acc_wallet_topup) — вторых текстов о том же не заводится. Без бампа страница берёт словарь из кэша и читалка называет кнопку ключом. --><!-- 21.09 (T-260921-cc04, подарок деньгами доезжает до всех): ушли ключи acc_sum_bonus и acc_money_gift, а acc_money_beta и acc_money_nocash переписаны без слова «подарок» — на счету просто лежат деньги. Без бампа страница берёт словарь из кэша и по-прежнему обещает «подарок», которого в разметке уже нет. --><!-- 21.09 (T-260920-091a, условия возврата одной правдой с экраном оплаты): в карточке «Оплата и возвраты» появился текст возврата — ТЕМ ЖЕ ключом pay_scr_promise, что читает плательщик, плюс новый ключ pay_scr_promise_offer («оферте»). Фраза переписана: переделать файл обещаем сами, а про деньги отсылаем в оферту её же словами. Без бампа страница берёт словарь из кэша и показывает прежнее «переделаем или вернём деньги». --><!-- 21.09 (T-260921-a8c7, деньги кабинета одной правдой): +12 ключей acc_sum_* / acc_money_* / acc_docs_h — сводка «Главной» (остаток, его подаренная часть, число заказов, срок хранения файлов и судьба истёкших), подаренная часть остатка отдельной строкой у денег, честная пометка про бету, отказ пополнения при закрытой продаже и карточка «Оплата и возвраты». Без бампа страница берёт словарь из кэша и новые подписи выходят ключами. --><!-- 20.09 (подаренные карты на счёте, узел 2): +4 ключа acc_bonus_* — карточка «Подарочные карты» на «Главной»: остаток, подарено/израсходовано, текст нуля без цен и оговорка о невыводимости. Без бампа страница берёт словарь из кэша и новые подписи выходят ключами. --><!-- 16.09 (самостоятельное удаление учётной записи, решение #2002): +19 ключей acc_del_* — карточка «опасной зоны» панели безопасности: честный текст о безвозвратности удаления, остатки, которые сгорят (карты, деньги на баÐ
4»Ð°Ð½ÑÐµ, оплаченные области, заказы), повторное доказательство личности (пароль либо точный ввод почты) и разбор отказов 400/429. Без бампа страница берёт словарь из кэша и новые подписи выходят ключами. --><!-- 01.09 (ответы Jan: 142): волна входа на 53 языка — auth_* (форма, сброс пароля, экран подтверждения почты). Без бампа кабинет держит прежний словарь и экраны входа остаются английскими. --><!-- 01.09 (накопленный долг i18n, namespace ui): 1 534 клетки на 53 языках вернулись в ведомость и наполнены — эталон менялся, а перевод оставался прежним (пометку стирал сид-импортёр до #951). В словаре поехали в том числе stat_free, section_pricing, tab_batch, detail_min/max, tip_mbtiles, wiz_* и cdr_export_*. Без бампа страница берёт словарь из кэша и показывает прежние тексты («2 экспорта/день», «Перейти на Pro»). --><!-- 10.09 (волна 1 кошелька, решение #1266): +24 ключа — деньги на балансе, быстрые суммы пополнения, покупка пакета с баланса, выписка (acc_wallet_*) и блок реквизитов для документов в профиле (acc_company_*); плюс два переименования — раздел «Оплата» стал «Балансом» (acc_tab_billing), «Движения счёта» стали «Выпиской» (acc_bill_hist_h). Без бампа страница берёт словарь из кэша и показывает прежние заголовки, а новые подписи выходят ключами. --><!-- 21.08 (личный кабинет): 40 ключей acc_* — профиль, смена пароля и почты, счётчик карт, список заказов (ru+en, остальные языки английским фолбэком через account_i18n.js). Без бампа страница берёт словарь из кэша и подписи выходят ключами. 21.08 (#866, перенос с замороженной ветки): +13 ключей — «чем вы входите», повторное письмо подтверждения, правило пароля. 21.08 (переделка облика): +19 ключей — разделы боковой панели, плитки лимитов, короткий список последних заказов, подвал. 22.08 (#885, раздел «Оплата»): +21 ключ — счёт карт, витрина пополнения, движения счёта; валюта ровно в одном ключе acc_bill_price. 24.08 (единица оплаты — ОБЛАСТЬ, слова владельца): +5 ключей acc_areas_* — раздел «Мои области», бессрочное хранение, возврат в конструктор. -->
5  <meta charset="UTF-8">
6  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7  <title>Личный кабинет — OSM2CDR</title>
8  <!-- Страница личная: ни в один индекс не входит. Заголовок X-Robots-Tag
9       ставит сам обработчик /account — это вторая линия обороны. -->
10  <meta name="robots" content="noindex,nofollow">
11  <link rel="icon" href="/favicon.svg" type="image/svg+xml">
12  <link rel="icon" type="image/x-icon" href="/favicon.ico" sizes="any">
13
14  <link rel="preconnect" href="https://fonts.googleapis.com">
15  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
16  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
17
18  <link rel="stylesheet" href="/css/tokens.css?v=20260903assetparity"><!-- 03.09: метка сведена к ЕДИНОЙ по всем страницам. Один файл под двумя ?v= — две записи в immutable-кэше (public, immutable, max-age=31536000): правка доезжает до той страницы, чью метку бампнули, и НИКОГДА до второй. Сторож класса — src/tests/test_asset_version_tag_parity.py. -->
19  <link rel="stylesheet" href="/css/components.css?v=20260920fontfloor20260920regofferpreview"><!-- 03.09: метка сведена к ЕДИНОЙ по всем страницам. Один файл под двумя ?v= — две записи в immutable-кэше (public, immutable, max-age=31536000): правка доезжает до той страницы, чью метку бампнули, и НИКОГДА до второй. Сторож класса — src/tests/test_asset_version_tag_parity.py. -->
20  <link rel="stylesheet" href="/css/account.css?v=20260921pricingtab"><!-- 21.09 (T-260921-c8aa): в .acc-tab добавлены box-sizing и text-decoration ради пункта-ссылки «Тарифы». Файл отдаётся immutable на год — без бампа ?v= правка не доедет до вернувшегося посетителя НИКОГДА. Метка у account.css своя: этот файл подключает только кабинет (сторож — src/tests/test_asset_version_tag_parity.py). -->
21  <link rel="stylesheet" href="/css/account_panels.css?v=20260922shop">
22</head>
23<body class="acc-body">
24
25<noscript>
26  <p class="acc-noscript">
27    Личный кабинет работает только с включённым JavaScript.<br>
28    Your account page needs JavaScript to be enabled.
29  </p>
30</noscript>
31
32<!-- ===== ШАПКА САЙТА (та же разметка и те же id, что на главной и в мастере:
33     их оживляет auth.js, языковой пикер — lang-picker.js) ===== -->
34<nav aria-label="Основная навигация" data-i18n-aria="aria_main_nav">
35  <div class="nav-inner">
36    <a href="/" class="site-logo">
37      <span style="font-size:1.25rem;font-weight:800;color:#f1f5f9">osm2<span style="color:#60a5fa">cdr</span></span>
38    </a>
39    <ul class="nav-links" role="list">
40      <li><a href="/formats/" data-i18n="nav_formats">Форматы</a></li>
41      <li><a href="/map/" data-i18n="nav_library">Каталог</a></li>
42      <li><a href="/blog/" data-i18n="nav_blog">Блог</a></li>
43      <li><a href="/help/" class="nav-help-link" data-i18n="nav_help" data-i18n-title="nav_help_title" title="Как пользоваться">?</a></li>
44      <li><a href="/wizard" class="nav-builder-cta" data-i18n="nav_wizard" title="Конструктор карт">Конструктор карт</a></li>
45    </ul>
46    <div class="lang-picker" id="langPicker">
47      <button class="lang-picker-toggle" type="button" aria-expanded="false" aria-haspopup="listbox" title="Language">
48        <svg class="lang-picker-globe" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 014 10 15.3 15.3 0 01-4 10 15.3 15.3 0 01-4-10 15.3 15.3 0 014-10z"/></svg>
49        <span class="lang-picker-code" id="langCode">RU</span>
50        <svg class="lang-picker-arrow" width="10" height="6" viewBox="0 0 10 6"><path d="M0 0l5 6 5-6z" fill="currentColor"/></svg>
51      </button>
52      <div class="lang-picker-dropdown" role="listbox" aria-label="Language" data-i18n-aria="aria_lang_picker">
53        <div class="lang-picker-search-wrap">
54          <input class="lang-picker-search" type="text" placeholder="Search..." autocomplete="off" spellcheck="false" aria-label="Поиск языка" data-i18n-aria="wiz_s5_search_aria">
55        </div>
56        <div class="lang-picker-list" id="langList"></div>
57      </div>
58    </div>
59    <!-- Блок входа — те же id, что на главной: их читает auth.js. Анонима эта
60         страница не показывает вовсе (account.js уводит на вход), но шапка
61         обязана быть цельной: без #navAuth auth.js на ней просто молчит. -->
62    <div class="nav-auth" id="navAuth">
63      <button class="nav-auth-btn" id="navLoginBtn" type="button" data-login-link>
64        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
65        <span data-i18n="nav_login">Войти</span>
66      </button>
67      <div class="nav-user-info" id="navUserInfo" style="display:none">
68        <span class="nav-user-email" id="navUserEmail"></span>
69        <button class="nav-auth-btn nav-logout-btn" id="navLogoutBtn" type="button" data-i18n="nav_logout" onclick="handleOAuthLogout()">Выйти</button>
70      </div>
71    </div>
72  </div>
73</nav>
74
75<div class="acc-shell">
76
77  <!-- ===== БОКОВАЯ ПАНЕЛЬ: кто вошёл + разделы ===== -->
78  <aside class="acc-side">
79    <div class="acc-side-user">
80      <span class="acc-avatar" id="accAvatar" aria-hidden="true"></span>
81      <span class="acc-side-id">
82        <span class="acc-side-email" id="accSideEmail"></span>
83      </span>
84    </div>
85
86    <nav class="acc-side-nav" id="accTabs" aria-label="Разделы кабинета" data-i18n-aria="acc_tabs_aria">
87      <button type="button" class="acc-tab is-active" data-acc-tab="overview" aria-current="page">
88        <svg class="acc-tab-ic" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg>
89        <span data-i18n="acc_tab_overview">Главная</span>
90      </button>
91      <button type="button" class="acc-tab" data-acc-tab="orders">
92        <svg class="acc-tab-ic" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M4 4h16v5H4z"/><path d="M6 9v11h12V9"/><path d="M10 13h4"/></svg>
93        <span data-i18n="acc_orders_h">Мои заказы</span>
94      </button>
95      <button type="button" class="acc-tab" data-acc-tab="areas" id="accTabAreas" hidden>
96        <svg class="acc-tab-ic" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M9 4 3 6v14l6-2 6 2 6-2V4l-6 2-6-2z"/><path d="M9 4v14"/><path d="M15 6v14"/></svg>
97        <span data-i18n="acc_areas_h">Мои области</span>
98      </button>
99      <button type="button" class="acc-tab" data-acc-tab="billing" id="accTabBilling" hidden>
100        <svg class="acc-tab-ic" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="2" y="5" width="20" height="14" rx="2"/><path d="M2 10h20"/></svg>
101        <span data-i18n="acc_tab_billing">Баланс</span>
102      </button>
103      <button type="button" class="acc-tab" data-acc-tab="profile">
104        <svg class="acc-tab-ic" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
105        <span data-i18n="acc_profile_h">Профиль</span>
106      </button>
107      <button type="button" class="acc-tab" data-acc-tab="security">
108        <svg class="acc-tab-ic" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><rect x="4" y="10" width="16" height="10" rx="2"/><path d="M8 10V7a4 4 0 0 1 8 0v3"/></svg>
109        <span data-i18n="acc_tab_security">Вход и защита</span>
110      </button>
111      <!-- Тарифы — ПОСЛЕДНИМ пунктом и единственной ссылкой среди вкладок
112           (слово Jan 21.09.2026): соседи переключают панели этой же страницы,
113           тарифы — отдельная страница сайта. Подставляется серверно
114           (routes_homepage_nav_pricing) под гейтом pricing_visible: при
115           выключенном флаге пункта нет физически, иначе кабинет вёл бы на 404.
116           Атрибута data-acc-tab у ссылки нет — js/account_nav.js ищет вкладки
117           ровно по нему и ссылку не трогает. -->
118      <a class="acc-tab" href="/pricing/"><svg class="acc-tab-ic" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M20.6 13.4 13.4 20.6a2 2 0 0 1-2.8 0l-7.2-7.2A2 2 0 0 1 3 12V5a2 2 0 0 1 2-2h7a2 2 0 0 1 1.4.6l7.2 7.2a2 2 0 0 1 0 2.6z"/><circle cx="7.5" cy="7.5" r="1.5"/></svg><span>Pricing</span></a>
119    </nav>
120
121    <button type="button" class="acc-btn acc-btn-ghost acc-side-out" id="accLogout"
122            data-i18n="acc_logout">Выйти</button>
123  </aside>
124
125  <!-- ===== РАБОЧАЯ ОБЛАСТЬ ===== -->
126  <main class="acc-main">
127    <header class="acc-head">
128      <div>
129        <h1 data-i18n="acc_h1">Личный кабинет</h1>
130        <p class="acc-head-sub" id="accHeadSub" data-i18n="acc_head_sub">Ваши заказы, счёт и настройки входа</p>
131      </div>
132    </header>
133
134    <!-- ГЛАВНАЯ: что осталось и что заказано. Настройки сюда не попадают
135         сознательно — они живут в разделах боковой панели. -->
136    <section class="acc-panel is-active" data-acc-panel="overview">
137
138      <!-- СВОДКА (T-260921-a8c7). Панель управления «Главной»: остаток,
139           сколько заказов и сколько живёт готовый файл — одним взглядом и
140           без догадок. Плитка «Из них подарок» убрана 21.09 по слову
141           владельца (T-260921-cc04): на счету просто лежат деньги, и вторая
142           плитка о тех же деньгах читалась как второй счёт. Числа приходят из
143           /api/auth/me/overview: ручка ТОЛЬКО на чтение и гейта продажи не
144           знает, поэтому сводку видит любой вошедший, а не владелец
145           куки-пропуска. Число заказов берётся из ответа /api/auth/me/orders,
146           который страница и так запрашивает, — второго запроса за тем же
147           числом не делается.
148           Карточки нет, пока ручка не ответила 200: три прочерка — не
149           сводка, а пустая рамка.
150           Строки с подстановкой ({rub}, {h}) на data-i18n висеть не имеют
151           права — их наполняет account_money.js через VMSAccountText.tf,
152           иначе человек прочитал бы фигурные скобки. -->
153      <section class="acc-card" id="accSummaryCard" hidden>
154        <div class="acc-card-head">
155          <h2 data-i18n="acc_sum_h">Панель управления</h2>
156          <button type="button" class="acc-btn-link acc-btn" data-acc-tab-link="orders"
157                  data-i18n="acc_recent_all">Вся история</button>
158        </div>
159        <div class="acc-stats">
160          <!-- КНОПКА «+» СТОИТ РЯДОМ С ЧИСЛОМ (слово владельца 21.09,
161               T-260921-fdbb): человек видит своё число именно здесь, а пополнять
162               уходил во вкладку «Баланс», до которой надо было догадаться. Это
163               настоящая кнопка, а не значок и не ссылка: читалка экрана читает
164               подпись из словаря (acc_sum_topup_open), а не голый плюс.
165               Окошко стоит ПОД плитками, а не в самой плитке: на 375 px плитка
166               узкая, и поле суммы внутри неё уехало бы вбок. -->
167          <div class="acc-stat acc-stat-money">
168            <span class="acc-stat-k" data-i18n="acc_sum_balance">На счету</span>
169            <span class="acc-stat-v" id="accSumBalance">—</span>
170            <button type="button" class="acc-btn acc-topup-plus" id="accSumTopup"
171                    aria-expanded="false" aria-controls="accSumTopupBox"
172                    data-i18n-aria="acc_sum_topup_open"
173                    aria-label="Пополнить счёт">+</button>
174          </div>
175          <div class="acc-stat">
176            <span class="acc-stat-k" data-i18n="acc_sum_orders">Заказов</span>
177            <span class="acc-stat-v" id="accSumOrders">—</span>
178          </div>
179          <!-- ОСТАТОК КАРТ ВЕРНУЛСЯ НА «ГЛАВНУЮ» (слово владельца 22.09,
180               T-260921-b791). На его месте стояла плитка «Файлы хранятся 24 ч» —
181               владелец назвал её лишней; поле retention_hours ручки сводки и сам
182               срок хранения при этом НЕ тронуты, убрана витрина, а не механизм.
183               Число пишет js/account_cards.js ОТВЕТОМ ТОГО ЖЕ запроса
184               /api/auth/me/credits, который и так делает account_bonus.js:
185               второго читателя счёта на странице нет. Пакет не покупался
186               (доказанный ноль) — вместо числа стоит зов «Оплатить пакет карт»,
187               а кнопка ведёт к списку тарифов ниже. -->
188          <div class="acc-stat acc-stat-money">
189            <span class="acc-stat-k" data-i18n="acc_sum_cards">Осталось карт</span>
190            <span class="acc-stat-v" id="accSumCards">—</span>
191            <button type="button" class="acc-btn acc-btn-link" id="accSumPack"
192                    data-i18n="acc_sum_pack_buy">Купить пакет</button>
193          </div>
194        </div>
195        <!-- Разбор суммы на счету — ТОТ ЖЕ, что во вкладке «Баланс», одной
196             формулой (js/account_wallet_origin.js): «Начислено: подарок … и
197             ваши пополнения …. Потрачено: …». Стоит ПОД плитками: на 375 px
198             строка внутри плитки уехала бы вбок. -->
199        <p class="acc-note" id="accSumOrigin" hidden></p>
200        <!-- ОКОШКО СУММЫ. Пороги min/max — ЗЕРКАЛО api/wallet_kinds.py
201             (MIN_TOPUP_RUB, MAX_TOPUP_KOP), тем же способом, что и у поля
202             accWalletAmount во вкладке «Баланс»; совпадение стережёт
203             src/tests/test_account_wallet_ui.py. Саму оплату ведёт ТОТ ЖЕ
204             VMSAccountWallet.topup(), что и кнопка «Пополнить», — второй копии
205             пути оплаты в проекте нет. При закрытой продаже строку с полем
206             прячет js/account_topup_quick.js, а в окошке остаётся честное
207             объяснение канонического гейта (acc_money_closed). -->
208        <div class="acc-topup-box" id="accSumTopupBox" hidden>
209          <div class="acc-field" id="accSumTopupRow">
210            <label class="acc-label" for="accSumTopupAmount"
211                   data-i18n="acc_wallet_amount_ph">Своя сумма в рублях</label>
212            <input type="number" id="accSumTopupAmount" class="acc-input"
213                   min="500" max="100000" step="1" inputmode="numeric">
214            <button type="button" class="acc-btn acc-btn-primary" id="accSumTopupGo"
215                    data-i18n="acc_wallet_topup">Пополнить</button>
216          </div>
217          <p class="acc-msg" id="accSumTopupStatus" hidden></p>
218        </div>
219        <p class="acc-note acc-money-beta" id="accSumBeta" hidden></p>
220        <!-- ОДНА строка о том, что карты за заказы пока не списываются: без
221             неё купленный пакет стоял бы на месте и человек решил бы, что
222             счётчик сломан. Слова ГОТОВЫЕ (acc_bill_beta) — те же, что у
223             витрины вкладки «Баланс»;
223 признак беты называет сервер. -->
224        <p class="acc-note" id="accSumCardsBeta" hidden></p>
225      </section>
226
227      <!-- КРАТКИЕ ЦЕНЫ БЛОКОМ (слово владельца 22.09: «тарифы кратко и аккуратно на
228           главную блоки перенести — цена за карту и цены за пакет; только не
229           такие огромные и меньше текста»). Цены НЕ ВПИСАНЫ в разметку ни
230           одним числом: их называет витрина сервера (/api/billing/catalog —
231           те же resolve_map_packs и pricing_ladder, что рисуют /pricing/), и
232           приезжают они ТЕМ ЖЕ ответом, который уже запросил
233           js/account_billing.js. Витрина закрыта — вместо цен одна кнопка,
234           честно объясняющая, что покупка откроется после беты.
235           Фраза под списком — ровно то, что просил сказать чётко владелец:
236           оплаченную карту можно скачивать и править сколько угодно раз,
237           пока не меняется выделенная область. -->
238      <section class="acc-card" id="accPriceCard">
239        <h2 data-i18n="acc_price_h">Цены</h2>
240        <ul class="acc-bill-shop" id="accPriceList"></ul>
241        <p class="acc-note" data-i18n="acc_price_keep">Оплатив карту, вы скачиваете и правите её сколько угодно раз, пока не меняете выделенную область.</p>
242        <p class="acc-msg" id="accPriceStatus" hidden></p>
243      </section>
244
245      <!-- ОПЛАТА И ВОЗВРАТЫ. Карточка видна ВСЕГДА и каждому вошедшему: до
246           21.09.2026 единственная ссылка на условия покупки и возврата лежала
247           внутри витрины продажи, а витрина закрыта гейтом — и человек,
248           пришедший за порядком возврата, не находил его в кабинете вовсе.
249           Ссылка на оферту на странице ровно одна (сторож
250           src/tests/test_account_refund_link_guard.py), адрес строго /offer/:
251           на /terms/ порядка возврата нет. -->
252      <section class="acc-card" id="accDocsCard">
253        <h2 data-i18n="acc_docs_h">Оплата и возвраты</h2>
254        <p class="acc-note"><a href="/offer/" data-i18n="acc_bill_terms">Условия покупки и возврата</a></p>
255        <!-- УСЛОВИЯ ВОЗВРАТА словами. Текст сюда кладёт account_money.js —
256             ТЕМ ЖЕ ключом pay_scr_promise, который человек читает на экране
257             оплаты (решение владельца 21.09, задача T-260920-091a). Своей
258             копии фразы у кабинета нет СОЗНАТЕЛЬНО: две копии одного обещания
259             разъехались бы в 55 языках, и кабинет обещал бы не то, что экран
260             оплаты. Слово-отсылка к оферте подставляется сюда ПРОСТЫМ
261             ТЕКСТОМ, без ссылки: ссылка на /offer/ в этой карточке обязана
262             быть ровно одна (сторож src/tests/test_account_refund_link_guard.py),
263             и вторая уронила бы его. Узел в разметке пуст — наполняет его JS. -->
264        <div class="acc-note" id="accRefundTerms"></div>
265      </section>
266
267      <!-- КАРТЫ НА СЧЕТУ: сколько начислено, сколько израсходовано, что
268           осталось и куда ушла каждая карта. ПОДАРКОМ они больше не
269           называются (24.09, T-260924-36b8, слово владельца «один кошелёк»):
270           подарок в проекте один и он деньгами, а карты на счету — это то,
271           что у человека есть, и тратятся они ПЕРВЫМИ, и лишь потом деньги.
272           Карточка видна ТОЛЬКО при доÐ
272ºÐ°Ð·Ð°Ð½Ð½Ð¾Ð¼ остатке больше нуля: ноль
273           карт — строки про карты нет вовсе, а прочерк значит «журнал не
274           ответил», и рисовать по нему счёт нельзя. Абзаца нуля здесь
275           больше нет (ключ acc_bonus_zero удалён) — на нуле нет и карточки.
276           Ни цены, ни кнопки пополнения тут не бывает: за деньгами человек
277           идёт к остатку выше. Строки с подстановкой ({n}, {granted}, {spent})
278           на data-i18n висеть не имеют права — их наполняет account_bonus.js
279           через VMSAccountText.tf, иначе человек прочитал бы фигурные скобки. -->
280      <section class="acc-card" id="accBonusCard" hidden>
281        <div class="acc-card-head">
282          <h2 data-i18n="acc_bonus_h">Карты на счету</h2>
283        </div>
284        <p class="acc-bill-balance"><b id="accBonusLeft">—</b></p>
285        <p class="acc-note" id="accBonusSum"></p>
286        <p class="acc-note" id="accBonusNote" data-i18n="acc_bonus_nocash">Карты на счету тратятся ПЕРВЫМИ: сборка карты берёт сперва карту со счёта и только потом деньги с баланса. Вывести или обменять карты нельзя.</p>
287        <p class="acc-msg" id="accBonusStatus" hidden></p>
288        <ul class="acc-orders" id="accBonusMoves"></ul>
289        <div class="acc-empty" id="accBonusMovesEmpty" hidden>
290          <p data-i18n="acc_bill_hist_empty">Движений по счёту пока не было.</p>
291        </div>
292      </section>
293
294      <section class="acc-card">
295        <div class="acc-card-head">
296          <h2 data-i18n="acc_recent_h">Последние заказы</h2>
297          <button type="button" class="acc-btn-link acc-btn" data-acc-tab-link="orders"
298                  data-i18n="acc_recent_all">Вся история</button>
299        </div>
300        <p class="acc-msg" id="accRecentStatus" hidden></p>
301        <ul class="acc-orders" id="accRecentList"></ul>
302        <div class="acc-empty" id="accRecentEmpty" hidden>
303          <p data-i18n="acc_orders_empty">Заказов пока нет.</p>
304          <a class="acc-btn acc-btn-primary" href="/wizard"
305             data-i18n="acc_orders_empty_cta">Собрать первую карту</a>
306        </div>
307      </section>
308
309      <section class="acc-card">
310        <div class="acc-card-head">
311          <h2 data-i18n="acc_next_h">Что дальше</h2>
312        </div>
313        <p class="acc-note" data-i18n="acc_next_note">Выберите область на карте, соберите её в нужном формате и заберите файл — заказ появится здесь.</p>
314        <a class="acc-btn acc-btn-primary" href="/wizard" data-i18n="acc_next_cta">Собрать карту</a>
315      </section>
316    </section>
317
318    <!-- ЗАКАЗЫ: вся история со страницами. -->
319    <section class="acc-panel" data-acc-panel="orders">
320      <section class="acc-card">
321        <h2 data-i18n="acc_orders_h">Мои заказы</h2>
322        <p class="acc-msg" id="accOrdersStatus" hidden></p>
323        <p class="acc-note" id="accOrdersNote" hidden></p>
324
325        <ul class="acc-orders" id="accOrdersList"></ul>
326
327        <div class="acc-empty" id="accOrdersEmpty" hidden>
328          <p data-i18n="acc_orders_empty">Заказов пока нет.</p>
329          <a class="acc-btn acc-btn-primary" href="/wizard"
330             data-i18n="acc_orders_empty_cta">Собрать первую карту</a>
331        </div>
332
333        <button type="button" class="acc-btn acc-more" id="accOrdersMore" hidden
334                data-i18n="acc_more">Показать ещё</button>
335      </section>
336    </section>
337
338    <!-- ОБЛАСТИ: за что заплачено. Единица оплаты — область, а не файл и не
339         формат (слова владельца 24.08), поэтому сюда человек возвращается
340         менять настройки и скачивать снова. Вкладка скрыта до ответа
341         сервера ровно по той же причине, что и вкладка «Оплата» ниже. -->
342    <section class="acc-panel" data-acc-panel="areas">
343      <section class="acc-card">
344        <h2 data-i18n="acc_areas_h">Мои области</h2>
345        <p class="acc-note" id="accAreasNote" data-i18n="acc_areas_note" hidden>Оплаченные области хранятся бессрочно. Ð
345’ернитесь к любой из них, поменяйте формат и настройки и скачайте карту снова — повторная оплата не берётся.</p>
346
347        <ul class="acc-orders" id="accAreasList"></ul>
348
349        <div class="acc-empty" id="accAreasEmpty" hidden>
350          <p data-i18n="acc_areas_empty">Оплаченных областей пока нет.</p>
351        </div>
352      </section>
353    </section>
354
355    <!-- ОПЛАТА: счёт карт, покупка и движения. Раздела НЕТ в разметке до
356         ответа сервера: пока продажа закрыта, ручки отвечают как несуществующий
357         путь, и показывать пустую витрину было бы обещанием без товара. -->
358    <section class="acc-panel" data-acc-panel="billing">
359
360      <!-- ДЕНЬГИ (волна 1 кошелька, #1266; открыта вошедшему 21.09.2026,
361           T-260921-a8c7). Карточка скрыта, пока НЕ ответила 200 ручка
362           /api/auth/me/overview — она только читает и гейта продажи не знает.
363           Прежде карточку открывал ответ /api/billing/wallet, ручки ПРОДАЖИ:
364           на бою продажа закрыта для всех, и вошедший не видел в кабинете ни
365           остатка, ни подарка, ни кнопки «Пополнить» вовсе.
366           Пороги суммы в поле — зеркало api/wallet_kinds.py; кнопки быстрых
367           сумм строит JS из той же константы, чтобы третьей копии не было. -->
368      <section class="acc-card" id="accWalletCard" hidden>
369        <h2 data-i18n="acc_wallet_h">Баланс</h2>
370        <p class="acc-bill-balance"><b id="accWalletLine">—</b></p>
371        <!-- ОТКУДА ЭТА СУММА (24.09, T-260924-126d, слово владельца: жена
372             положила 500 ₽, увидела 2 001 ₽ и не поняла, откуда число).
373             Строку считает js/account_wallet_origin.js из полей bonus_kop /
374             topup_kop / balance_kop, которые ручка отдаёт давно; узел скрыт,
375             пока разбора нет (молчит ручка, стоит unavailable или числа не
376             сходятся) — выдумывать числа о деньгах нельзя. -->
377        <p class="acc-note" id="accWalletOrigin" hidden></p>
378        <!-- Природа денег на счету: они тратятся на сборку карт и
379             наличными не выдаются. Оговорка стоит РЯДОМ с остатком и ровно
380             один раз на кабинет; текст ставит js/account_money.js. Без неё
381             «2 000 ₽» читаются как настоящие деньги к выводу — поэтому
382             строка осталась и после того, как слово «подарок» ушло со
383             страницы (21.09, T-260921-cc04). Правило, которое она
384             описывает, живёт не здесь, а в каноне (api/wallet_kinds.py,
385             NON_WITHDRAWABLE_KINDS), и стережёт его
386             test_gift_rubles_not_cashable.py. -->
387        <p class="acc-note acc-money-gift" id="accMoneyNocash" hidden></p>
388        <p class="acc-note acc-money-beta" id="accWalletBeta" hidden></p>
389        <!-- ПОЛЕ СУММЫ И БЫСТРЫЕ СУММЫ прячет js/account_money.js, пока
390             sales_open ложно: предлагать пополнение кошелька, которого сервер
391             не признаёт, — значит принять деньги в никуда. Сама кнопка
392             «Пополнить» при этом ВИДНА и по нажатию честно объясняет, что
393             пополнение откроется после беты: спрятанная кнопка оставила бы
394             человека с вопросом «где пополнить» и без ответа. Ни одного
395             обращения в /api/billing/wallet/topup при закрытой продаже не
396             уходит — гейт стоит в самом topup() (js/account_wallet.js). -->
397        <div class="acc-field" id="accWalletQuick"></div>
398        <div class="acc-field" id="accWalletAmountRow">
399          <label class="acc-label" for="accWalletAmount"
400                 data-i18n="acc_wallet_amount_ph">Своя сумма в рублях</label>
401          <input type="number" id="accWalletAmount" class="acc-input"
402                 min="500" max="100000" step="1" inputmode="numeric">
403        </div>
404        <div class="acc-field">
405          <button type="button" class="acc-btn acc-btn-primary" id="accWalletTopup"
406                  data-i18n="acc_wallet_topup">Пополнить</button>
407        </div>
408        <p class="acc-msg" id="accWalletStatus" hidden></p>
409        <p class="acc-note" id="accWalletNote" data-i18n="acc_wallet_note">
409Деньги на балансе не сгорают: тратьте их на пакеты карт, когда удобно.</p>
410        <!-- «За что платим» — короткая подпись и ссылка на страницу цен.
411             Ссылку подставляет сервер (routes_homepage_nav_pricing) под тем же
412             флагом, что и пункт боковой панели: при выключенном флаге страницы
413             цен нет, и кабинет вёл бы на 404. Подпись показывается ровно
414             тогда, когда ссылка рядом действительно появилась. -->
415        <p class="acc-note" id="accMoneyPricing" data-i18n="acc_money_pricing" hidden>За что мы берём деньги — на странице цен.</p>
416        <p class="acc-note"><a href="/pricing/">Pricing</a></p>
417      </section>
418
419      <!-- СЧЁТ КАРТ. Карты перестали быть единицей подарка 21.09.2026
420           (T-260921-a8c7): подарок рублёвый и стоит строкой в карточке денег
421           выше. Здесь остаются только купленные пакеты, поэтому карточка
422           показывается, лишь когда продажа открыта: при закрытой продаже
423           пакет купить нельзя, и счёт карт был бы разговором ни о чём. -->
424      <section class="acc-card" id="accBillCard" hidden>
425        <h2 data-i18n="acc_bill_h">Счёт карт</h2>
426        <p class="acc-bill-balance"><span data-i18n="acc_bill_balance">На счету</span>:
427          <b id="accBillBalance">—</b></p>
428        <p class="acc-note" id="accBillBeta" hidden></p>
429      </section>
430
431      <section class="acc-card" id="accBillShopCard" hidden>
432        <h2 data-i18n="acc_bill_buy_h">Пополнить счёт</h2>
433        <ul class="acc-bill-shop" id="accBillShop"></ul>
434        <p class="acc-msg" id="accBillStatus" hidden></p>
435        <p class="acc-note" data-i18n="acc_bill_keep">Купленные карты не сгорают: они останутся на счету и после беты, по той цене, по которой вы их купили.</p>
436        <!-- Ссылка «Условия покупки и возврата» уехала отсюда на «Главную»
437             (карточка accDocsCard) 21.09.2026: эта витрина закрыта гейтом
438             продажи, и человек, пришедший за порядком возврата, не находил
439             его в кабинете вовсе. -->
440      </section>
441
442      <!-- КРИПТА: второй способ оплаты того же раздела, а не отдельная
443           страница. Карточка скрыта, пока сервер не подтвердил, что рельс
444           настроен: показывать адрес для перевода, которого никто не
445           слушает, — это принять деньги в никуда. -->
446      <section class="acc-card" id="accUsdtCard" hidden>
447        <h2 data-i18n="acc_usdt_h">Оплата в USDT (TRON)</h2>
448        <p class="acc-note" data-i18n="acc_usdt_intro">Если карта не проходит, счёт можно пополнить в USDT по сети TRON (TRC-20). Выберите пакет — мы выставим счёт с точной суммой.</p>
449        <ul class="acc-bill-shop" id="accUsdtShop"></ul>
450        <p class="acc-msg" id="accUsdtStatus" hidden></p>
451
452        <!-- Выставленный счёт. Сумма показывается ЦЕЛИКОМ, со всеми знаками:
453             младшие знаки — это идентификатор платежа, и округлив их,
454             покупатель заплатил бы неопознаваемо. -->
455        <div class="acc-usdt-invoice" id="accUsdtInvoice" hidden>
456          <p><span data-i18n="acc_usdt_amount">Сумма перевода</span>:
457            <b id="accUsdtAmount"></b> USDT</p>
458          <p class="acc-note" data-i18n="acc_usdt_exact">Переведите сумму точно до последнего знака — по ней мы узнаем ваш платёж.</p>
459          <p><span data-i18n="acc_usdt_address">Адрес (сеть TRON, TRC-20)</span>:
460            <code id="accUsdtAddress"></code></p>
461          <p class="acc-note" data-i18n="acc_usdt_network">Только сеть TRON (TRC-20). Перевод в другой сети до нас не дойдёт.</p>
462          <p><span data-i18n="acc_usdt_state">Состояние</span>:
463            <b id="accUsdtState"></b></p>
464          <p class="acc-note" data-i18n="acc_usdt_wait_note">Зачисление занимает около минуты после подтверждения сети. Страницу можно закрыть — карты придут на счёт сами.</p>
465        </div>
466      </section>
467
468      <!-- ВЫПИСКА закрыта, пока продажа не открыта: движения ей даёт
469           /api/billing/statement — ручка за гейтом ПРОДАЖИ, и при
470           staged человек увидел бы пустую рамку или ошибку вместо
471           истории счёта. Прячет js/account_money.js (gateSale), гейт
472           ручки при этом не тронут. -->
473      <section class="acc-card" id="accBillHistCard" hidden>
474        <h2 data-i18n="acc_bill_hist_h">Выписка</h2>
475        <p class="acc-msg" id="accBillHistStatus" hidden></p>
476        <ul class="acc-orders" id="accBillHist"></ul>
477        <div class="acc-empty" id="accBillHistEmpty" hidden>
478          <p data-i18n="acc_bill_hist_empty">Движений по счёту пока не было.</p>
479        </div>
480      </section>
481    </section>
482
483    <!-- ПРОФИЛЬ: кто я и как со мной связаться. -->
484    <section class="acc-panel" data-acc-panel="profile">
485      <section class="acc-card">
486        <h2 data-i18n="acc_profile_h">Профиль</h2>
487
488        <div class="acc-row">
489          <span class="acc-label" data-i18n="acc_email">Почта</span>
490          <span class="acc-value" id="accEmail"></span>
491          <span class="acc-chip acc-chip-bad" id="accUnverified" hidden
492                data-i18n="acc_unverified">Почта не подтверждена</span>
493          <!-- Без кнопки отметка «не подтверждена» стоит без единого выхода:
494               письмо уходит ровно один раз, при регистрации или смене адреса.
495               Ручка общая с экраном подтверждения — /api/auth/resend-verification
496               (#863); своей копии кабинет не заводит. -->
497          <button type="button" class="acc-btn acc-btn-ghost" id="accResend" hidden
498                  data-i18n="acc_resend">Отправить письмо заново</button>
499        </div>
500        <p class="acc-msg" id="accResendMsg" hidden></p>
501
502        <div class="acc-row" id="accSinceRow" hidden>
503          <span class="acc-label" data-i18n="acc_since">С нами с</span>
504          <span class="acc-value" id="accSince"></span>
505        </div>
506
507        <div class="acc-field">
508          <label class="acc-label" for="accName" data-i18n="acc_name">Имя</label>
509          <input type="text" id="accName" class="acc-input" maxlength="100"
510                 autocomplete="name"
511                 data-i18n-placeholder="acc_name_ph"
512                 placeholder="Как к вам обращаться">
513          <button type="button" class="acc-btn" id="accNameSave"
514                  data-i18n="acc_save">Сохранить</button>
515        </div>
516        <p class="acc-msg" id="accProfileMsg"></p>
517      </section>
518
519      <!-- РЕКВИЗИТЫ (волна 1 кошелька, #1266): счёт и закрывающие док
519ументы
520           юрлицу начинаются с них, а спросить их в момент оплаты — значит
521           прервать оплату формой. Контрольную сумму ИНН считает клиент до
522           запроса (account_company.js), зеркало — api/inn_validator.py. -->
523      <section class="acc-card">
524        <h2 data-i18n="acc_company_h">Реквизиты для документов</h2>
525        <p class="acc-note" data-i18n="acc_company_note">Нужны для счетов и закрывающих документов. Счёт на оплату для юрлиц появится позже.</p>
526
527        <div class="acc-field">
528          <label class="acc-label" for="accCompanyName"
529                 data-i18n="acc_company_name">Название компании</label>
530          <input type="text" id="accCompanyName" class="acc-input" maxlength="255"
531                 autocomplete="organization">
532        </div>
533        <div class="acc-field">
534          <label class="acc-label" for="accCompanyInn"
535                 data-i18n="acc_company_inn">ИНН</label>
536          <input type="text" id="accCompanyInn" class="acc-input" maxlength="12"
537                 inputmode="numeric">
538        </div>
539        <div class="acc-field">
540          <label class="acc-label" for="accCompanyKpp"
541                 data-i18n="acc_company_kpp">КПП</label>
542          <input type="text" id="accCompanyKpp" class="acc-input" maxlength="9">
543        </div>
544        <div class="acc-field">
545          <label class="acc-label" for="accCompanyAddress"
546                 data-i18n="acc_company_address">Юридический адрес</label>
547          <input type="text" id="accCompanyAddress" class="acc-input" maxlength="1000">
548        </div>
549        <div class="acc-field">
550          <button type="button" class="acc-btn" id="accCompanySave"
551                  data-i18n="acc_save">Сохранить</button>
552        </div>
553        <p class="acc-msg" id="accCompanyMsg" hidden></p>
554      </section>
555
556      <section class="acc-card">
557        <h2 data-i18n="acc_mail_h">Смена почты</h2>
558        <p class="acc-note" data-i18n="acc_mail_note">Нужен текущий пароль. Пока новый адрес не подтверждён, почта считается неподтверждённой.</p>
559        <div class="acc-field">
560          <input type="email" id="accMailNew" class="acc-input" autocomplete="email"
561                 data-i18n-placeholder="acc_mail_new"
562                 placeholder="Новый адрес">
563        </div>
564        <div class="acc-field">
565          <input type="password" id="accMailPw" class="acc-input"
566                 autocomplete="current-password"
567                 data-i18n-placeholder="acc_pw_current"
568                 placeholder="Текущий пароль">
569          <button type="button" class="acc-btn" id="accMailSubmit"
570                  data-i18n="acc_mail_change">Сменить почту</button>
571        </div>
572        <p class="acc-msg" id="accMailMsg"></p>
573      </section>
574    </section>
575
576    <!-- ВХОД И ЗАЩИТА: чем вхожу и как меняю пароль. -->
577    <section class="acc-panel" data-acc-panel="security">
578      <!-- Список привязанных сервисов приходит из /api/auth/me (auth_providers),
579           строка про пароль — только когда он ДОКАЗАН (has_password === true).
580           На null страница про пароль не утверждает ничего и советует
581           «Забыли пароль?»: колонка password_hash непустая ВСЕГДА, аккаунту от
582           провайдера туда кладётся случайная строка. -->
583      <section class="acc-card" id="accHowCard" hidden>
584        <h2 data-i18n="acc_how_h">Чем вы входите</h2>
585        <ul class="acc-methods" id="accMethods"></ul>
586        <p class="acc-note" id="accHowNote" hidden
587           data-i18n="acc_how_note">Если вы входили только через сервис из списка и пароль не задавали, войти по паролю не получится — заведите его ссылкой «Забыли пароль?» в окне входа.</p>
588      </section>
589
590      <section class="acc-card">
591        <h2 data-i18n="acc_pw_h">Смена пароля</h2>
592        <div class="acc-field">
593          <input type="password" id="accPwCurrent" class="acc-input"
594                 autocomplete="current-password"
595                 data-i18n-placeholder="acc_pw_current"
596                 placeholder="Текущий пароль">
597        </div>
598        <div class="acc-field">
599          <input type="password" id="accPwNew" class="acc-input"
600                 autocomplete="new-password"
601                 data-i18n-placeholder="acc_pw_new"
602                 placeholder="Новый пароль">
603          <button type="button" class="acc-btn" id="accPwSubmit"
604                  data-i18n="acc_pw_change">Сменить пароль</button>
605        </div>
606        <p class="acc-msg" id="accPwMsg"></p>
607        <!-- Вход через провайдера выдаёт аккаунту случайный пароль: человек его Ð
607½Ðµ
608             знает и сменить не сможет. Восстановление живёт в окне входа на
609             главной (auth_form.js) — своей копии формы здесь нет, поэтому ссылка
610             ведёт туда, а не обещает восстановление на этой странице. -->
611        <a class="acc-link" href="/?login=1"
612           data-i18n="acc_pw_forgot">Не помните текущий пароль? Восстановите его в окне входа</a>
613      </section>
614    </section>
615  </main>
616</div>
617
618<!-- ===== ПОДВАЛ ===== Короткий: подписи с {format_count} и data-ps здесь не
619     повторяем — их наполняют скрипты главной, которых у кабинета нет, и
620     человек увидел бы фигурные скобки. -->
621<footer class="acc-footer">
622  <div class="acc-footer-inner">
623    <nav class="acc-footer-links" aria-label="Ссылки подвала" data-i18n-aria="acc_footer_aria">
624      <a href="/" data-i18n="acc_back">На главную</a>
625      <a href="/formats/" data-i18n="nav_formats">Форматы</a>
626      <a href="/help/" data-i18n="nav_help_title">Как пользоваться</a>
627      <a href="/contact/" data-i18n="footer_contact">Контакты</a>
628      <a href="/terms/" data-i18n="footer_terms">Условия</a>
629      <a href="/privacy/" data-i18n="footer_privacy">Конфиденциальность</a>
630      <a href="/pricing/">Pricing</a>
631    </nav>
632    <p>osm2cdr © 2026</p>
633  </div>
634</footer>
635
636<script src="/js/i18n.js?v=20260817attrlabel" defer></script>
vendor: 1 bytes, line 636
636
637<script src="/js/lang-picker.js?v=20260903assetparity" defer></script>
637<!-- 03.09: метка сведена к ЕДИНОЙ по всем страницам. Один файл под двумя ?v= — две записи в immutable-кэше (public, immutable, max-age=31536000): правка доезжает до той страницы, чью метку бампнули, и НИКОГДА до второй. Сторож класса — src/tests/test_asset_version_tag_parity.py. -->
638<!-- Общие запасные тексты входа; ПЕРЕД auth.js — он их читает. -->
639<script src="/js/auth_i18n.js?v=20260916accdeleted" defer></script>
vendor: 1 bytes, line 639
639
640<script src="/js/auth.js?v=20260924loginondownload" defer></script>
640<!-- 24.09 (T-260921-8830, вход просим на кнопке скачивания): метка сдвинута вместе с остальными скриптами входа — без бампа вернувшийся посетитель взял бы старый скрипт из immutable-кэша, пошёл качать файл без билета и получил бы от сервера 403. --><!-- 03.09: метка сведена с wizard.html/account.html (было reggate 01.09 против keepalive 21.08). Требование совпадения стояло тут же ПРОЗОЙ с 16.08 и всё равно разошлось: 01.09 волна рег-гейта бампнула метку только на главной. Прозу держит теперь сторож — src/tests/test_asset_version_tag_parity.py. -->
641<!-- ПОСЛЕ auth.js: дописывает в его namespace продление сессии по refresh-токену
642     (access живёт 30 минут — без продления кабинет уводил бы на вход при живой
643     по ощущению сессии) и VMSAuth.updateEmail для шапки остального сайта. -->
644<script src="/js/auth_session.js?v=20260821cabinet" defer></script>
644
645<!-- ПОСЛЕ auth.js: кнопка входа в шапке уводит на главную с возвратом сюда. -->
646<script src="/js/auth_entry.js?v=20260924loginondownload" defer></script>
646<!-- 24.09 (T-260921-8830, вход просим на кнопке скачивания): метка сдвинута вместе с остальными скриптами входа — без бампа вернувшийся посетитель взял бы старый скрипт из immutable-кэша, пошёл качать файл без билета и получил бы от сервера 403. -->
647<!-- Лимиты открытой беты — из общего /api/product-state, своего запроса нет. -->
648<script src="/js/product_state.js?v=20260510a" defer></script>
vendor: 1 bytes, line 648
648
649<script src="/js/account_i18n.js?v=20260924wallet" defer></script>
vendor: 1 bytes, line 649
649
650<script src="/js/account_i18n_wallet.js?v=20260924wallet" defer></script>
650<!-- 22.09 (T-260921-b791): осколок запасного словаря — слова покупки и кошелька (acc_bill_*, acc_wallet_*, витрина «Главной»). Базовый файл упёрся в жёсткий потолок 350 строк, и новому ключу места не было. Осколок ДОПИСЫВАЕТ в тот же TEXTS (VMSAccountText.add) и обязан стоять сразу за базовым файлом и ПЕРЕД читателями. -->
651<script src="/js/account_nav.js?v=20260821cabinet" defer></script>
vendor: 1 bytes, line 651
651
652<script src="/js/account_orders.js?v=20260921money" defer></script>
vendor: 1 bytes, line 652
652
653<script src="/js/account.js?v=20260922shop" defer></script>
653
654<!-- ПОСЛЕ account.js: раздел «Оплата» (#885) берёт его VMSAccount.request.
655     Сам решает, показываться ли: без открытой продажи его ручки отвечают
656     как несуществующий путь, и вкладка не появляется. -->
657<script src="/js/account_billing.js?v=20260924wallet" defer></script>
657
658<!-- ПОСЛЕ account_billing.js: движения счёта рисует ОДИН модуль — и выписку
659     кошелька (#1266), и прежний журнал карт. Два рисователя одного узла рано
660     или поздно затрут друг друга. -->
661<script src="/js/account_statement.js?v=20260921topuprefund" defer></script>
661
662<!-- ПОСЛЕ account_statement.js: денежный баланс, пополнение и покупка пакета
663     с баланса (волна 1 кошелька, #1266). Гейт тот же, что у витрины карт: без
664     открытой продажи /api/billing/wallet отвечает как несуществующий путь, и
665     карточка баланса не появляется. -->
666<!-- ПЕРЕД account_wallet.js, и это важно: отложенный (defer) скрипт
667     исполняется, когда readyState уже 'interactive', поэтому кошелёк
668     запускается ПРЯМО при исполнении своего файла и зовёт этих троих. -->
669<!-- Окно подтверждения перед списанием денег за пакет (24.09, T-260924-126d):
670     единственный гейт покупки, один на обе витрины. -->
671<script src="/js/account_pack_confirm.js?v=20260924money" defer></script>
671
672<!-- Разбор счёта «откуда эта сумма»: одна формула на вкладку «Баланс» и на
673     «Главную». -->
674<script src="/js/account_wallet_origin.js?v=20260924money" defer></script>
674
675<!-- Подсказка о сумме пополнения при вводе; годность судит тот же
676     VMSAccountWallet.validAmount, второй проверки не заводится. -->
677<script src="/js/account_amount_hint.js?v=20260924money" defer></script>
vendor: 1 bytes, line 677
677
678<script src="/js/account_wallet.js?v=20260924wallet" defer></script>
678
679<!-- ПОСЛЕ account_wallet.js: деньги кабинета одной правдой (T-260921-a8c7).
680     Ходит РОВНО в /api/auth/me/overview — ручку на чтение без гейта продажи, —
681     и по её ответу открывает карточку денег, вкладку «Баланс» и сводку
682     «Главной». Формат суммы берёт у кошелька (rubFromKop): второй копии
683     правила о деньгах в проекте не заводится. Подключён ПЕРЕД
684     account_bonus.js и отдаёт витрине «Главной» числа «хватит ещё карт»:
685     при закрытой продаже ручка кошелька молчит, а эта отвечает. -->
686<script src="/js/account_money.js?v=20260924wallet" defer></script>
686
687<!-- ПОСЛЕ account_wallet.js и account_money.js: короткий вход к пополнению
688     от суммы на «Главной» — кнопка «+» и окошко суммы (T-260921-fdbb).
689     Своего запроса у модуля НЕТ: сумму он отдаёт в тот же
690     VMSAccountWallet.topup(), что и кнопка «Пополнить», а гейт продажи
691     спрашивает у VMSAccountMoney.refuseTopup(). Оба модуля обязаны быть
692     раньше. -->
693<script src="/js/account_topup_quick.js?v=20260924money" defer></script>
vendor: 1 bytes, line 693
693
694<script src="/js/account_cards.js?v=20260924wallet" defer></script>
694<!-- 22.09 (T-260921-b791): остаток карт с кнопкой покупки и краткие тарифы на «Главной». Подключается ПОСЛЕ витрины, кошелька и денег (берёт их buyPack, цену и канонический отказ) и ПЕРЕД account_bonus.js: тот отдаёт сюда счёт карт своим единственным запросом. -->
695<!-- ПОСЛЕ account_wallet.js: возврат из банка. Адрес возврата у пополнения
696     ДЕНЕГ и у покупки пакета карт один, поэтому зачисление ждут по счетам
697     кошелька — обоим сразу, — а витрина карт по слову этого модуля в свой
698     опрос не входит: иначе после пополнения рублей экран досчитывал бы до
699     «карты вот-вот появятся» (#1266). -->
700<script src="/js/account_wallet_return.js?v=20260910wallet" defer></script>
700
701<!-- ПОСЛЕ account.js и account_billing.js: карты на счету и их расход на
702     «Главной» (узел 2). Ходит РОВНО в /api/auth/me/credits — ручки продажи
703     этого раздела не касаются; карточки нет, пока счётчик не подтверждён и
704     пока остаток не доказан БОЛЬШЕ НУЛЯ (24.09, T-260924-36b8). -->
705<script src="/js/account_bonus.js?v=20260924wallet" defer></script>
705
706<!-- ПОСЛЕ account.js: форму реквизитов наполняет его ответ /api/auth/me. -->
707<script src="/js/account_company.js?v=20260910wallet" defer></script>
707
708<!-- ПОСЛЕ account.js: раздел «Мои области» (24.08, единица оплаты — область).
709     Гейт тот же, что у «Оплаты»: без открытой продажи витрина отвечает как
710     несуществующий путь, и вкладка не появляется. -->
711<script src="/js/account_areas.js?v=20260824paidarea2" defer></script>
711<!-- 24.08: раздел молчит на ответе unavailable ручки /api/me/areas (отказ БД, ненакаченная миграция 32). Без бампа возвращающийся клиент берёт из кэша копию, рисующую «оплаченных областей пока нет» поверх недоказанного пустого списка. -->
712<script src="/js/account_billing_usdt.js?v=20260822usdt" defer></script>
712
713<!-- ПОСЛЕ account.js: читает его window.VMSAccount. -->
714<script src="/js/account_login.js?v=20260821cabinet" defer></script>
714
715<!-- ПОСЛЕ account.js и account_wallet.js: карточка удаления учётной записи
716     (#2002) берёт у первого VMSAccount.request/say/serverError, у второго —
717     rubFromKop для суммы, которая сгорит вместе с аккаунтом. Пока ручка
718     /api/auth/me/delete-preview не отвечает, карточки на странице нет. -->
719<script src="/js/account_delete.js?v=20260916accdelete" defer></script>
719
720</body>
721</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.