diff --git a/CryptoWallet-DeFi-Guide.md b/CryptoWallet-DeFi-Guide.md new file mode 100644 index 0000000..1c531ea --- /dev/null +++ b/CryptoWallet-DeFi-Guide.md @@ -0,0 +1,590 @@ +# CryptoWallet DeFi API — гайд для фронтендера + +Сектор DeFi: **Стейкинг** · **Пулы (Uniswap v3 LP)** · **Отвязка кошельков (approvals)** + +Базовый URL: `https://app.cryptowallet.elcsa.ru/api` + +--- + +## Общие правила (читать один раз) + +**Авторизация:** все запросы требуют `Authorization: Bearer `. +**CSRF (для всех `POST`):** double-submit — +- cookie `csrf_token=` (сервер выдаёт) +- header `X-CSRF-Token: <тот же value>` + +**Idempotency-Key (для мутирующих `POST`: stake/unstake/claim/lp add/remove/revoke/revoke-all):** +заголовок `Idempotency-Key: `. Сгенерь UUID на фронте; при retry шли **тот же** — сервер вернёт +кэшированный ответ, не выполнит операцию дважды (анти-дабл-спенд). + +**Конверт ответа:** +- успех → `{ "success": true, "data": { ... } }` +- ошибка → `{ "success": false, "error": "текст", "code": "OPTIONAL_CODE" }` + +**Кастодиальность:** ключи на сервере. Все транзакции подписывает и броадкастит сервер мнемоникой +пользователя — фронту **не нужно ничего подписывать**. Достаточно вызвать endpoint. + +**Числа — два формата.** Почти у каждого «сырого» поля сумм есть человекочитаемый спутник: +- `amount0Desired` (smallest units, строка) + `amount0DesiredHuman` (обычное число, строка). +- Для UI бери `*Human`. Для повторной отправки на сервер — сырое поле. + +**Газ.** Любая мутация тратит газ нативной монетой (ETH для ETH/LP, SOL для Solana). Если на кошельке +нет нативки — операция упадёт. Проверить заранее можно через баланс в LP-квоте (см. 2.2) или +`POST /wallets/{chain}/op-cost` (см. примечание в конце). + +**Комиссия сервиса:** 0.7% (70 bps) на стейк и на LP-депозит. На **вывод** (unstake / lp remove / +revoke) комиссии нет. + +--- + +# 1. СТЕЙКИНГ + +ETH → **Lido** (stETH). SOL → **нативный** стейкинг (StakeProgram, делегирование валидатору). +`chain` в пути = `ETH` или `SOL`. + +--- + +### 1.1. `POST /wallets/{chain}/stake/quote` + +**Что делает:** превью стейка — считает комиссию 0.7%, сумму после комиссии, ожидаемый результат и +доходность. Ничего не подписывает. + +**Вход (body):** +```json +{ "amount": "100000000000000000" } +``` +- `amount` — сумма в smallest units (ETH = wei 10^18; SOL = lamports 10^9), строка, > 0. + +**Возвращает (ETH):** +```json +{ "success": true, "data": { + "amountWei": "100000000000000000", "amountWeiHuman": "0.1", + "appFeeWei": "700000000000000", "appFeeWeiHuman": "0.0007", + "stakeAmountWei": "99300000000000000", "stakeAmountWeiHuman": "0.0993", + "expectedStEthWei": "99300000000000000","expectedStEthWeiHuman": "0.0993", + "aprPercent": 3.1 +}} +``` + +**Возвращает (SOL):** +```json +{ "success": true, "data": { + "amountLamports": "1000000000", "amountLamportsHuman": "1", + "appFeeLamports": "7000000", "appFeeLamportsHuman": "0.007", + "stakeLamports": "993000000", "stakeLamportsHuman": "0.993", + "validator": "", + "estApyPercent": 6.5 +}} +``` + +**Примечание:** `aprPercent` (ETH) может быть `null`, если внешний источник APR недоступен — это не +блокирует стейк. Lido даёт stETH ~1:1 к внесённому ETH (после комиссии). + +--- + +### 1.2. `POST /wallets/{chain}/stake` + +**Что делает:** выполняет стейк. ETH: списывает комиссию 0.7% → `Lido.submit()`. SOL: создаёт +stake-аккаунт + делегирует валидатору (+ комиссия). Подписывает и броадкастит сам. + +**Вход:** header `Idempotency-Key: ` + body: +```json +{ "amount": "100000000000000000" } +``` +- `amount` — то же, что в quote (smallest units). + +**Возвращает (ETH):** +```json +{ "success": true, "data": { + "feeTxid": "0x...", "stakeTxid": "0x...", + "stakeAmountWei": "99300000000000000", "stakeAmountWeiHuman": "0.0993", + "appFeeWei": "700000000000000", "appFeeWeiHuman": "0.0007" +}} +``` + +**Возвращает (SOL):** +```json +{ "success": true, "data": { + "stakeTxid": "", + "stakeAccount": "", + "stakeLamports": "993000000", "stakeLamportsHuman": "0.993", + "appFeeLamports": "7000000", "appFeeLamportsHuman": "0.007", + "validator": "" +}} +``` + +**Примечание:** `stakeAccount` (SOL) **сохрани** — он нужен для unstake и для отображения позиции. + +--- + +### 1.3. `GET /wallets/{chain}/stake/positions` + +**Что делает:** читает текущие позиции стейкинга прямо из блокчейна (без БД). + +**Вход:** только `chain` в пути. Тела нет. + +**Возвращает (ETH):** +```json +{ "success": true, "data": { + "protocol": "lido", "chain": "ETH", + "stEthBalanceWei": "99300000000000000", "stEthBalanceWeiHuman": "0.0993", + "aprPercent": 3.1, + "withdrawalRequests": [ + { "requestId": "12345", "amountStEthWei": "50000000000000000", + "amountStEthWeiHuman": "0.05", "isFinalized": true, "isClaimed": false } + ] +}} +``` + +**Возвращает (SOL):** +```json +{ "success": true, "data": { + "protocol": "native", "chain": "SOL", "validator": "", + "positions": [ + { "stakeAccount": "", "lamports": "993000000", "lamportsHuman": "0.993", + "state": "active", "validator": "", + "delegatedLamports": "993000000", "delegatedLamportsHuman": "0.993" } + ] +}} +``` + +**Примечание:** +- ETH `withdrawalRequests` — это заявки на вывод через очередь (mode=queue). Когда `isFinalized:true` и + `isClaimed:false` → можно забирать через `/unstake/claim` (см. 1.5). +- SOL `state` ∈ `active | activating | deactivating | inactive`. Unstake зависит от состояния (см. 1.4). + +--- + +### 1.4. `POST /wallets/{chain}/unstake` + +**Что делает:** вывод из стейкинга. **Без комиссии.** +- ETH: `mode=swap` — мгновенно через Curve (stETH→ETH); `mode=queue` — заявка в Lido Withdrawal Queue. +- SOL: один endpoint, два шага по состоянию: `active`→деактивация (cooldown 1-2 эпохи), затем повторный + вызов → `withdraw`. + +**Вход:** header `Idempotency-Key: ` + body: + +ETH: +```json +{ "amount": "50000000000000000", "mode": "swap" } +``` +- `amount` — сумма stETH в wei. +- `mode` — `"swap"` (мгновенно, дефолт) или `"queue"` (очередь Lido). + +SOL: +```json +{ "stakeAccount": "" } +``` +- `stakeAccount` — адрес из позиции (1.3) или из ответа stake (1.2). + +**Возвращает (ETH, mode=swap):** +```json +{ "success": true, "data": { + "mode": "swap", "approveTxid": "0x...", "swapTxid": "0x...", + "swapAmountStEthWei": "50000000000000000", "swapAmountStEthWeiHuman": "0.05", + "minEthOutWei": "49800000000000000", "minEthOutWeiHuman": "0.0498" +}} +``` + +**Возвращает (ETH, mode=queue):** +```json +{ "success": true, "data": { + "mode": "queue", "approveTxid": "0x...", "requestTxid": "0x...", + "requestedStEthWei": "50000000000000000", "requestedStEthWeiHuman": "0.05", + "note": "requestId появится в /stake/positions; затем /unstake/claim когда isFinalized" +}} +``` + +**Возвращает (SOL):** +```json +{ "success": true, "data": { + "action": "deactivate", + "txid": "", + "note": "Деактивация запущена. Через 1-2 эпохи вызови /unstake снова — выведет средства." +}} +``` +либо после cooldown: +```json +{ "success": true, "data": { + "action": "withdraw", "txid": "", + "withdrawnLamports": "993000000", "withdrawnLamportsHuman": "0.993" +}} +``` + +**Примечание:** +- SOL unstake — **двухфазный**. Первый вызов на `active`-аккаунте вернёт `action:"deactivate"`. Покажи + юзеру «средства разблокируются через 1-2 эпохи». Когда `state` станет `inactive` — повторный вызов + вернёт `action:"withdraw"`. +- Если вызвать SOL unstake пока `state:"deactivating"` → 400 (ещё рано, идёт cooldown). + +--- + +### 1.5. `POST /wallets/ETH/unstake/claim` + +**Что делает:** забирает ETH по готовой заявке из Lido Withdrawal Queue (только ETH, только mode=queue). + +**Вход:** header `Idempotency-Key: ` + body: +```json +{ "requestId": "12345" } +``` +- `requestId` — id заявки из `/stake/positions.withdrawalRequests`, у которой `isFinalized:true`. + +**Возвращает:** +```json +{ "success": true, "data": { "claimTxid": "0x..." } } +``` + +**Примечание:** сервер заранее проверяет, что `requestId` принадлежит юзеру и существует — иначе 400 +(без потери газа). Доступно только при `isFinalized:true`. + +--- + +# 2. ПУЛЫ — Uniswap v3 LP (только ETH) + +Курируемый список пулов (например WETH/USDT, WBTC/WETH, XAUt/USDT). Пользователь выбирает пул, +диапазон цен и суммы — сервер минтит позицию (NFT). Путь всегда `chain=ETH`. + +--- + +### 2.1. `GET /wallets/ETH/lp/pools` + +**Что делает:** список курируемых пулов со статистикой (TVL, объём, APR) и текущей ценой. + +**Вход:** нет тела. + +**Возвращает:** +```json +{ "success": true, "data": [ + { + "poolAddress": "0x4e68ccd3e89f51c3074ca5072bbac773960dfa36", + "token0": "0xC02a...", "token1": "0xdAC1...", + "symbol0": "WETH", "symbol1": "USDT", + "decimals0": 18, "decimals1": 6, + "feeTier": 3000, + "currentPrice": 1665.75, + "currentTick": -202300, + "tvlUSD": 33000000, "volumeUSD24h": 5400000, "aprPercent": 40.33 + } +]} +``` + +**Примечание:** +- `feeTier` в сотых долях процента (3000 = 0.3%, 500 = 0.05%). +- `currentPrice` = сколько token1 за 1 token0 (та же конвенция, что в quote ниже). +- `tvlUSD`/`volumeUSD24h`/`aprPercent` могут быть `null`, если внешняя статистика недоступна (не + блокирует депозит). + +--- + +### 2.2. `POST /wallets/ETH/lp/quote` ⭐ (с комиссией и проверкой баланса) + +**Что делает:** превью депозита — по диапазону цен и желаемым суммам считает тики, фактические суммы, +slippage-минимумы, APR, **нашу комиссию 0.7% (в токенах + USD + ETH)** и **достаточность баланса** +(хватает ли token0/token1 на взнос И ETH на газ). Ничего не подписывает. + +**Вход (body):** +```json +{ + "pool": "0x4e68ccd3e89f51c3074ca5072bbac773960dfa36", + "priceLower": 1568.75, + "priceUpper": 1665.75, + "amount0Desired": "100000000000000000", + "amount1Desired": "263359", + "slippageBps": 100, + "useNativeEth": true +} +``` +- `pool` — адрес из `/lp/pools`. +- `priceLower` / `priceUpper` — границы диапазона (token1 за token0). +- `amount0Desired` / `amount1Desired` — желаемые суммы в smallest units (по decimals каждого токена). +- `slippageBps` — опционально, 0..5000 (дефолт 100 = 1%). +- `useNativeEth` — опционально. Если у пула есть нога WETH, а у юзера на балансе **ETH** (не WETH) — + поставь `true`: сервер сам завернёт ETH→WETH. Влияет на проверку баланса (проверяет ETH вместо WETH). + +**Возвращает:** +```json +{ "success": true, "data": { + "poolAddress": "0x4e68ccd3...", + "tickLower": -202740, "tickUpper": -202140, + "priceLower": 1568.75, "priceUpper": 1665.75, + "amount0Desired": "99999999999872", "amount0DesiredHuman": "0.000099999999999872", + "amount1Desired": "263359", "amount1DesiredHuman": "0.263359", + "amount0Min": "98999999999873", "amount0MinHuman": "0.000098999999999873", + "amount1Min": "260725", "amount1MinHuman": "0.260725", + "liquidity": "354877171283", + "aprPercent": 40.33, + + "appFee0Human": "0.0007", "appFee1Human": "0.001843", + "appFee0Usd": 1.20, "appFee1Usd": 1.84, + "appFeeTotalUsd": 3.04, + "appFeeTotalEth": "0.00182", + + "balance": { + "token0": { "symbol": "WETH", "have": "0.5", "need": "0.0001", "sufficient": true, "shortfall": "0" }, + "token1": { "symbol": "USDT", "have": "0", "need": "0.263359", "sufficient": false, "shortfall": "0.263359" }, + "gas": { "symbol": "ETH", "have": "0.02", "needReserve": "0.001", "sufficient": true }, + "sufficient": false + } +}} +``` + +**Примечание:** +- **Комиссия:** `appFee0Human`/`appFee1Human` — 0.7% по каждой ноге в самом токене. `appFeeTotalUsd` — + суммарно в долларах, `appFeeTotalEth` — суммарно в ETH (монета сети). USD/ETH могут быть `null`, если у + токена нет цены в whitelist (например XAUt) — это не ошибка. +- **Баланс:** показывай красным, если `balance.sufficient === false`. `sufficient` у ноги может быть + `null` (не проверялось / нога покрыта нативным ETH при `useNativeEth`) — это не «не хватает». +- `balance` присутствует только если у юзера есть ETH-кошелёк (он есть всегда у custodial-юзера). +- Реальные суммы депозита = `amount0DesiredHuman`/`amount1DesiredHuman` (могут быть меньше введённых — + ограничивает диапазон). + +--- + +### 2.3. `POST /wallets/ETH/lp/add` + +**Что делает:** депозит в пул. Списывает комиссию 0.7% по каждому токену → approve×2 → `NFPM.mint()`. +При `useNativeEth` сначала заворачивает ETH→WETH. Возвращает `tokenId` позиции. + +**Вход:** header `Idempotency-Key: ` + body **тот же, что в quote** (`pool`, `priceLower`, +`priceUpper`, `amount0Desired`, `amount1Desired`, `slippageBps?`, `useNativeEth?`). + +**Возвращает:** +```json +{ "success": true, "data": { + "feeTxids": ["0x...", "0x..."], + "approveTxids": ["0x...", "0x..."], + "mintTxid": "0x...", + "wrapTxid": "0x... (если useNativeEth)", + "tickLower": -202740, "tickUpper": -202140, + "appFee0": "700000000000", "appFee0Human": "0.0007", + "appFee1": "1843", "appFee1Human": "0.001843" +}} +``` + +**Примечание:** сервер делает pre-check баланса ОБОИХ токенов ДО любых транзакций — если не хватает +второй ноги, операция падает с 400 **до** wrap/комиссии (ничего не теряется). Поэтому сначала всегда +показывай `quote` с `balance.sufficient`. + +--- + +### 2.4. `POST /wallets/ETH/lp/remove` + +**Что делает:** выводит ликвидность из позиции (`decreaseLiquidity` + `collect` тела и накопленных +комиссий). При `percent=100` ещё и сжигает NFT (`burn`). **Без комиссии.** + +**Вход:** header `Idempotency-Key: ` + body: +```json +{ "tokenId": "123456", "percent": 100 } +``` +- `tokenId` — id позиции из `/lp/positions`. +- `percent` — опционально, (0..100], дефолт 100. + +**Возвращает:** +```json +{ "success": true, "data": { + "removeTxid": "0x...", + "removedLiquidity": "354877171283", + "burned": true +}} +``` + +**Примечание:** сервер проверяет, что `tokenId` принадлежит кошельку юзера (`ownerOf`), иначе 400. + +--- + +### 2.5. `GET /wallets/ETH/lp/positions` + +**Что делает:** читает LP-позиции юзера (NFT) в курируемых пулах прямо из блокчейна: диапазон, текущая +стоимость по каждому токену, накопленные комиссии, в диапазоне ли цена. + +**Вход:** нет тела. + +**Возвращает:** +```json +{ "success": true, "data": { + "chain": "ETH", + "positions": [ + { + "tokenId": "123456", + "poolAddress": "0x4e68...", "symbol0": "WETH", "symbol1": "USDT", "feeTier": 3000, + "tickLower": -202740, "tickUpper": -202140, + "priceLower": 1568.75, "priceUpper": 1665.75, + "liquidity": "354877171283", + "currentAmount0": "99000000000000", "currentAmount0Human": "0.000099", + "currentAmount1": "260000", "currentAmount1Human": "0.26", + "feesOwed0": "1200000000", "feesOwed0Human": "0.0000000012", + "feesOwed1": "500", "feesOwed1Human": "0.0005", + "inRange": true + } + ], + "totalNfts": 3, "scanned": 3, "truncated": false +}} +``` + +**Примечание:** +- `inRange:false` → цена вышла за диапазон, позиция временно не зарабатывает комиссии (покажи ⚠️). +- `feesOwed*` — накопленные комиссии, которые заберутся при `remove`. +- `truncated:true` → у юзера слишком много NFT, показаны не все (на практике редко). + +--- + +# 3. ОТВЯЗКА КОШЕЛЬКОВ (Approvals) — ETH / BSC + +Назначение: ERC20-approval — это «разрешение» контракту тратить токен. Повисший **unlimited** approval +(MAX) на роутер/солвер позволяет внешней стороне выводить будущие поступления токена → деньги «утекают». +Этот блок даёт **увидеть** открытые двери и **закрыть** их. `chain` = `ETH` или `BSC`. + +--- + +### 3.1. `GET /wallets/{chain}/approvals` + +**Что делает:** сканирует кошелёк по известным спендерам (Relay-роутеры, Permit2, Uniswap NFPM) × +известным токенам и возвращает только **ненулевые** allowance (открытые двери) с флагом `unlimited`. +Read-only, ничего не подписывает. + +**Вход:** только `chain` в пути. + +**Возвращает:** +```json +{ "success": true, "data": { + "chain": "ETH", + "owner": "0x9dB8...21ea9", + "approvals": [ + { + "token": "USDT", "tokenAddress": "0xdAC1...", + "spender": "Relay Router v2", "spenderAddress": "0xb92f...", + "allowance": "115792089237316195423570985008687907853269984665640564039457584007913129639935", + "allowanceHuman": "unlimited", + "unlimited": true + } + ] +}} +``` + +**Примечание:** +- Пустой `approvals: []` → все двери закрыты ✅. +- `unlimited:true` (и `allowanceHuman:"unlimited"`) — главный риск, выделяй красным. Конечный allowance + (например ровно на сумму свопа) низкорисковый. + +--- + +### 3.2. `POST /wallets/{chain}/approvals/revoke` + +**Что делает:** отзывает ОДНУ конкретную дверь — сервер подписывает `token.approve(spender, 0)`. +Сумма **всегда 0** (можно только отозвать, не выдать). + +**Вход:** header `Idempotency-Key: ` + body: +```json +{ + "token": "0xdAC17F958D2ee523a2206206994597C13D831ec7", + "spender": "0xb92fe925dc43a0ecde6c8b1a2709c170ec4fff4f" +} +``` +- `token` — адрес ERC20 (поле `tokenAddress` из скана). +- `spender` — адрес спендера (поле `spenderAddress` из скана). + +**Возвращает:** +```json +{ "success": true, "data": { + "chain": "ETH", "token": "0xdAC1...", "spender": "0xb92f...", + "txid": "0x...", "previousAllowance": "1157920..." +}} +``` +либо, если уже было 0: +```json +{ "success": true, "data": { "txid": null, "alreadyZero": true, + "message": "Allowance already 0 — nothing to revoke" } } +``` + +**Примечание:** если allowance уже 0 — газ не тратится (`alreadyZero:true`, `txid:null`). Иначе нужен +небольшой газ (нативка) на одну транзакцию. + +--- + +### 3.3. `POST /wallets/{chain}/approvals/revoke-all` ⭐ «отвязать от всего» + +**Что делает:** одним вызовом закрывает **ВСЕ** открытые двери: сервер сам сканирует ненулевые +allowance и последовательно подписывает `approve(spender, 0)` по каждой. + +**Вход:** header `Idempotency-Key: ` + body (опционально): +```json +{ "onlyUnlimited": false } +``` +- `onlyUnlimited` — `false` (дефолт) = отозвать ВСЕ ненулевые; `true` = только unlimited/oversized. +- Тело можно не передавать (`{}`) — эквивалент `onlyUnlimited:false`. + +**Возвращает:** +```json +{ "success": true, "data": { + "chain": "ETH", "owner": "0x9dB8...", + "total": 2, + "revoked": [ + { "token": "USDT", "spender": "Relay Router v2", + "tokenAddress": "0xdAC1...", "spenderAddress": "0xb92f...", + "txid": "0x...", "previousAllowance": "1157920..." } + ], + "failed": [], + "skipped": [] +}} +``` +Если открытых дверей нет: +```json +{ "success": true, "data": { "total": 0, "revoked": [], "failed": [], "skipped": [], + "message": "no open approvals — nothing to revoke" } } +``` + +**Примечание:** +- Выполняется **последовательно** (по 1 транзакции на дверь, ждёт подтверждения каждой) — может занять + минуту-две. Покажи лоадер. +- При нехватке газа: отзывает сколько успел → остальное помечает `skipped` («пополни нативку и повтори»). + Повторный вызов безопасен (уже закрытые двери скан не покажет, газ не тратится). +- `total` — сколько открытых дверей нашлось; разбивка по `revoked` / `failed` / `skipped`. + +--- + +# 4. Типичные флоу (end-to-end) + +**Стейк ETH:** +1. `POST /wallets/ETH/stake/quote` → показать комиссию + ожидаемый stETH + APR. +2. По «Подтвердить» → `POST /wallets/ETH/stake` (с `Idempotency-Key`). +3. `GET /wallets/ETH/stake/positions` → обновить баланс stETH. + +**LP-депозит:** +1. `GET /wallets/ETH/lp/pools` → таблица пулов (APR/TVL). +2. Юзер выбрал пул, ввёл диапазон + суммы → `POST /wallets/ETH/lp/quote` → + показать комиссию (`appFeeTotal*`) и баннер при `balance.sufficient === false`. +3. Если хватает → `POST /wallets/ETH/lp/add` (с `Idempotency-Key`). +4. `GET /wallets/ETH/lp/positions` → список позиций; `remove` по кнопке. + +**Защита от слива (отвязка):** +1. `GET /wallets/ETH/approvals` (и/или `BSC`) → если есть `unlimited` — предупредить. +2. `POST /wallets/ETH/approvals/revoke-all` → закрыть все двери одной кнопкой. +3. Повторный `GET /approvals` → список пуст ✅. + +--- + +# 5. Коды ошибок + +| HTTP | code | Что значит / что делать | +|---|---|---| +| 401 | — | Нет/невалидный JWT. | +| 403 | — | JWT валиден, но нет кошелька для chain, либо CSRF не прошёл. | +| 400 | — | Невалидный body (chain вне whitelist, amount не число, requestId чужой, token/spender не адрес и т.п.). | +| 400 | `INSUFFICIENT_BALANCE` | Не хватает токена/нативки (LP add при нехватке второй ноги — падает до списаний). | +| 404 | — | Нет кошелька / mnemonic не найден / endpoint вне whitelist. | +| 409 | — | Конфликт Idempotency-Key (тот же ключ с другим телом). | +| 429 | — | Rate limit. | +| 502 | — | Upstream (RPC / внешний API) или broadcast не прошёл. | +| 503 | — | Сервис аудита недоступен (мутация не выполнена — безопасно повторить). | + +--- + +# Примечание: вспомогательный endpoint стоимости (опционально) + +Если нужно показать комиссию 0.7% (в токене + native + USD) и проверку баланса **до** стейка/свопа в +едином виде — есть read-only `POST /wallets/{chain}/op-cost` (ETH/BSC/SOL/TRX): + +**Вход:** `{ "token": "USDT", "amountHuman": "10" }` (или `amount` в smallest units; пусто/нативный +символ = нативная монета). +**Возвращает:** `appCommission { inToken, inNative, usd }` + `balance { token, gas }` + `sufficient` +(всё обычными числами). В LP-секторе эта информация уже встроена в `/lp/quote` (см. 2.2). diff --git a/dist/assets/index-5UhazDjJ.js b/dist/assets/index-5UhazDjJ.js new file mode 100644 index 0000000..8b50184 --- /dev/null +++ b/dist/assets/index-5UhazDjJ.js @@ -0,0 +1,161 @@ +var Lm=a=>{throw TypeError(a)};var fd=(a,i,c)=>i.has(a)||Lm("Cannot "+c);var T=(a,i,c)=>(fd(a,i,"read from private field"),c?c.call(a):i.get(a)),ie=(a,i,c)=>i.has(a)?Lm("Cannot add the same private member more than once"):i instanceof WeakSet?i.add(a):i.set(a,c),J=(a,i,c,r)=>(fd(a,i,"write to private field"),r?r.call(a,c):i.set(a,c),c),Se=(a,i,c)=>(fd(a,i,"access private method"),c);var jo=(a,i,c,r)=>({set _(d){J(a,i,d,c)},get _(){return T(a,i,r)}});(function(){const i=document.createElement("link").relList;if(i&&i.supports&&i.supports("modulepreload"))return;for(const d of document.querySelectorAll('link[rel="modulepreload"]'))r(d);new MutationObserver(d=>{for(const f of d)if(f.type==="childList")for(const p of f.addedNodes)p.tagName==="LINK"&&p.rel==="modulepreload"&&r(p)}).observe(document,{childList:!0,subtree:!0});function c(d){const f={};return d.integrity&&(f.integrity=d.integrity),d.referrerPolicy&&(f.referrerPolicy=d.referrerPolicy),d.crossOrigin==="use-credentials"?f.credentials="include":d.crossOrigin==="anonymous"?f.credentials="omit":f.credentials="same-origin",f}function r(d){if(d.ep)return;d.ep=!0;const f=c(d);fetch(d.href,f)}})();function r3(a){return a&&a.__esModule&&Object.prototype.hasOwnProperty.call(a,"default")?a.default:a}var hd={exports:{}},Ec={};/** + * @license React + * react-jsx-runtime.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var zm;function ny(){if(zm)return Ec;zm=1;var a=Symbol.for("react.transitional.element"),i=Symbol.for("react.fragment");function c(r,d,f){var p=null;if(f!==void 0&&(p=""+f),d.key!==void 0&&(p=""+d.key),"key"in d){f={};for(var g in d)g!=="key"&&(f[g]=d[g])}else f=d;return d=f.ref,{$$typeof:a,type:r,key:p,ref:d!==void 0?d:null,props:f}}return Ec.Fragment=i,Ec.jsx=c,Ec.jsxs=c,Ec}var Dm;function ly(){return Dm||(Dm=1,hd.exports=ny()),hd.exports}var l=ly(),md={exports:{}},ve={};/** + * @license React + * react.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var km;function ay(){if(km)return ve;km=1;var a=Symbol.for("react.transitional.element"),i=Symbol.for("react.portal"),c=Symbol.for("react.fragment"),r=Symbol.for("react.strict_mode"),d=Symbol.for("react.profiler"),f=Symbol.for("react.consumer"),p=Symbol.for("react.context"),g=Symbol.for("react.forward_ref"),h=Symbol.for("react.suspense"),m=Symbol.for("react.memo"),v=Symbol.for("react.lazy"),y=Symbol.for("react.activity"),b=Symbol.iterator;function N(R){return R===null||typeof R!="object"?null:(R=b&&R[b]||R["@@iterator"],typeof R=="function"?R:null)}var S={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},C=Object.assign,w={};function O(R,V,Z){this.props=R,this.context=V,this.refs=w,this.updater=Z||S}O.prototype.isReactComponent={},O.prototype.setState=function(R,V){if(typeof R!="object"&&typeof R!="function"&&R!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,R,V,"setState")},O.prototype.forceUpdate=function(R){this.updater.enqueueForceUpdate(this,R,"forceUpdate")};function H(){}H.prototype=O.prototype;function L(R,V,Z){this.props=R,this.context=V,this.refs=w,this.updater=Z||S}var U=L.prototype=new H;U.constructor=L,C(U,O.prototype),U.isPureReactComponent=!0;var I=Array.isArray;function W(){}var B={H:null,A:null,T:null,S:null},Y=Object.prototype.hasOwnProperty;function le(R,V,Z){var te=Z.ref;return{$$typeof:a,type:R,key:V,ref:te!==void 0?te:null,props:Z}}function me(R,V){return le(R.type,V,R.props)}function he(R){return typeof R=="object"&&R!==null&&R.$$typeof===a}function Ee(R){var V={"=":"=0",":":"=2"};return"$"+R.replace(/[=:]/g,function(Z){return V[Z]})}var re=/\/+/g;function ge(R,V){return typeof R=="object"&&R!==null&&R.key!=null?Ee(""+R.key):V.toString(36)}function de(R){switch(R.status){case"fulfilled":return R.value;case"rejected":throw R.reason;default:switch(typeof R.status=="string"?R.then(W,W):(R.status="pending",R.then(function(V){R.status==="pending"&&(R.status="fulfilled",R.value=V)},function(V){R.status==="pending"&&(R.status="rejected",R.reason=V)})),R.status){case"fulfilled":return R.value;case"rejected":throw R.reason}}throw R}function q(R,V,Z,te,pe){var be=typeof R;(be==="undefined"||be==="boolean")&&(R=null);var De=!1;if(R===null)De=!0;else switch(be){case"bigint":case"string":case"number":De=!0;break;case"object":switch(R.$$typeof){case a:case i:De=!0;break;case v:return De=R._init,q(De(R._payload),V,Z,te,pe)}}if(De)return pe=pe(R),De=te===""?"."+ge(R,0):te,I(pe)?(Z="",De!=null&&(Z=De.replace(re,"$&/")+"/"),q(pe,V,Z,"",function(ll){return ll})):pe!=null&&(he(pe)&&(pe=me(pe,Z+(pe.key==null||R&&R.key===pe.key?"":(""+pe.key).replace(re,"$&/")+"/")+De)),V.push(pe)),1;De=0;var Nt=te===""?".":te+":";if(I(R))for(var tt=0;tt>>1,Re=q[Te];if(0>>1;Ted(Z,se))ted(pe,Z)?(q[Te]=pe,q[te]=se,Te=te):(q[Te]=Z,q[V]=se,Te=V);else if(ted(pe,se))q[Te]=pe,q[te]=se,Te=te;else break e}}return P}function d(q,P){var se=q.sortIndex-P.sortIndex;return se!==0?se:q.id-P.id}if(a.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var f=performance;a.unstable_now=function(){return f.now()}}else{var p=Date,g=p.now();a.unstable_now=function(){return p.now()-g}}var h=[],m=[],v=1,y=null,b=3,N=!1,S=!1,C=!1,w=!1,O=typeof setTimeout=="function"?setTimeout:null,H=typeof clearTimeout=="function"?clearTimeout:null,L=typeof setImmediate<"u"?setImmediate:null;function U(q){for(var P=c(m);P!==null;){if(P.callback===null)r(m);else if(P.startTime<=q)r(m),P.sortIndex=P.expirationTime,i(h,P);else break;P=c(m)}}function I(q){if(C=!1,U(q),!S)if(c(h)!==null)S=!0,W||(W=!0,Ee());else{var P=c(m);P!==null&&de(I,P.startTime-q)}}var W=!1,B=-1,Y=5,le=-1;function me(){return w?!0:!(a.unstable_now()-leq&&me());){var Te=y.callback;if(typeof Te=="function"){y.callback=null,b=y.priorityLevel;var Re=Te(y.expirationTime<=q);if(q=a.unstable_now(),typeof Re=="function"){y.callback=Re,U(q),P=!0;break t}y===c(h)&&r(h),U(q)}else r(h);y=c(h)}if(y!==null)P=!0;else{var R=c(m);R!==null&&de(I,R.startTime-q),P=!1}}break e}finally{y=null,b=se,N=!1}P=void 0}}finally{P?Ee():W=!1}}}var Ee;if(typeof L=="function")Ee=function(){L(he)};else if(typeof MessageChannel<"u"){var re=new MessageChannel,ge=re.port2;re.port1.onmessage=he,Ee=function(){ge.postMessage(null)}}else Ee=function(){O(he,0)};function de(q,P){B=O(function(){q(a.unstable_now())},P)}a.unstable_IdlePriority=5,a.unstable_ImmediatePriority=1,a.unstable_LowPriority=4,a.unstable_NormalPriority=3,a.unstable_Profiling=null,a.unstable_UserBlockingPriority=2,a.unstable_cancelCallback=function(q){q.callback=null},a.unstable_forceFrameRate=function(q){0>q||125Te?(q.sortIndex=se,i(m,q),c(h)===null&&q===c(m)&&(C?(H(B),B=-1):C=!0,de(I,se-Te))):(q.sortIndex=Re,i(h,q),S||N||(S=!0,W||(W=!0,Ee()))),q},a.unstable_shouldYield=me,a.unstable_wrapCallback=function(q){var P=b;return function(){var se=b;b=P;try{return q.apply(this,arguments)}finally{b=se}}}})(gd)),gd}var $m;function iy(){return $m||($m=1,_d.exports=sy()),_d.exports}var vd={exports:{}},Gt={};/** + * @license React + * react-dom.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Hm;function cy(){if(Hm)return Gt;Hm=1;var a=f2();function i(h){var m="https://react.dev/errors/"+h;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(a)}catch(i){console.error(i)}}return a(),vd.exports=cy(),vd.exports}/** + * @license React + * react-dom-client.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Fm;function oy(){if(Fm)return Tc;Fm=1;var a=iy(),i=f2(),c=ry();function r(e){var t="https://react.dev/errors/"+e;if(1Re||(e.current=Te[Re],Te[Re]=null,Re--)}function Z(e,t){Re++,Te[Re]=e.current,e.current=t}var te=R(null),pe=R(null),be=R(null),De=R(null);function Nt(e,t){switch(Z(be,t),Z(pe,e),Z(te,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?nm(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=nm(t),e=lm(t,e);else switch(e){case"svg":e=1;break;case"math":e=2;break;default:e=0}}V(te),Z(te,e)}function tt(){V(te),V(pe),V(be)}function ll(e){e.memoizedState!==null&&Z(De,e);var t=te.current,n=lm(t,e.type);t!==n&&(Z(pe,e),Z(te,n))}function _l(e){pe.current===e&&(V(te),V(pe)),De.current===e&&(V(De),Sc._currentValue=se)}var Pl,Xl;function Ce(e){if(Pl===void 0)try{throw Error()}catch(n){var t=n.stack.trim().match(/\n( *(at )?)/);Pl=t&&t[1]||"",Xl=-1)":-1o||E[s]!==D[o]){var F=` +`+E[s].replace(" at new "," at ");return e.displayName&&F.includes("")&&(F=F.replace("",e.displayName)),F}while(1<=s&&0<=o);break}}}finally{Pt=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:"")?Ce(n):""}function Ke(e,t){switch(e.tag){case 26:case 27:case 5:return Ce(e.type);case 16:return Ce("Lazy");case 13:return e.child!==t&&t!==null?Ce("Suspense Fallback"):Ce("Suspense");case 19:return Ce("SuspenseList");case 0:case 15:return gl(e.type,!1);case 11:return gl(e.type.render,!1);case 1:return gl(e.type,!0);case 31:return Ce("Activity");default:return""}}function ln(e){try{var t="",n=null;do t+=Ke(e,n),n=e,e=e.return;while(e);return t}catch(s){return` +Error generating stack: `+s.message+` +`+s.stack}}var bs=Object.prototype.hasOwnProperty,js=a.unstable_scheduleCallback,Jo=a.unstable_cancelCallback,z_=a.unstable_shouldYield,D_=a.unstable_requestPaint,gn=a.unstable_now,k_=a.unstable_getCurrentPriorityLevel,L2=a.unstable_ImmediatePriority,z2=a.unstable_UserBlockingPriority,ar=a.unstable_NormalPriority,B_=a.unstable_LowPriority,D2=a.unstable_IdlePriority,U_=a.log,$_=a.unstable_setDisableYieldValue,Di=null,vn=null;function Zl(e){if(typeof U_=="function"&&$_(e),vn&&typeof vn.setStrictMode=="function")try{vn.setStrictMode(Di,e)}catch{}}var yn=Math.clz32?Math.clz32:F_,H_=Math.log,q_=Math.LN2;function F_(e){return e>>>=0,e===0?32:31-(H_(e)/q_|0)|0}var sr=256,ir=262144,cr=4194304;function ka(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function rr(e,t,n){var s=e.pendingLanes;if(s===0)return 0;var o=0,u=e.suspendedLanes,_=e.pingedLanes;e=e.warmLanes;var x=s&134217727;return x!==0?(s=x&~u,s!==0?o=ka(s):(_&=x,_!==0?o=ka(_):n||(n=x&~e,n!==0&&(o=ka(n))))):(x=s&~u,x!==0?o=ka(x):_!==0?o=ka(_):n||(n=s&~e,n!==0&&(o=ka(n)))),o===0?0:t!==0&&t!==o&&(t&u)===0&&(u=o&-o,n=t&-t,u>=n||u===32&&(n&4194048)!==0)?t:o}function ki(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function G_(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function k2(){var e=cr;return cr<<=1,(cr&62914560)===0&&(cr=4194304),e}function eu(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function Bi(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function V_(e,t,n,s,o,u){var _=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var x=e.entanglements,E=e.expirationTimes,D=e.hiddenUpdates;for(n=_&~n;0"u")return null;try{return e.activeElement||e.body}catch{return e.body}}var Z_=/[\n"\\]/g;function kn(e){return e.replace(Z_,function(t){return"\\"+t.charCodeAt(0).toString(16)+" "})}function iu(e,t,n,s,o,u,_,x){e.name="",_!=null&&typeof _!="function"&&typeof _!="symbol"&&typeof _!="boolean"?e.type=_:e.removeAttribute("type"),t!=null?_==="number"?(t===0&&e.value===""||e.value!=t)&&(e.value=""+Dn(t)):e.value!==""+Dn(t)&&(e.value=""+Dn(t)):_!=="submit"&&_!=="reset"||e.removeAttribute("value"),t!=null?cu(e,_,Dn(t)):n!=null?cu(e,_,Dn(n)):s!=null&&e.removeAttribute("value"),o==null&&u!=null&&(e.defaultChecked=!!u),o!=null&&(e.checked=o&&typeof o!="function"&&typeof o!="symbol"),x!=null&&typeof x!="function"&&typeof x!="symbol"&&typeof x!="boolean"?e.name=""+Dn(x):e.removeAttribute("name")}function X2(e,t,n,s,o,u,_,x){if(u!=null&&typeof u!="function"&&typeof u!="symbol"&&typeof u!="boolean"&&(e.type=u),t!=null||n!=null){if(!(u!=="submit"&&u!=="reset"||t!=null)){su(e);return}n=n!=null?""+Dn(n):"",t=t!=null?""+Dn(t):n,x||t===e.value||(e.value=t),e.defaultValue=t}s=s??o,s=typeof s!="function"&&typeof s!="symbol"&&!!s,e.checked=x?e.checked:!!s,e.defaultChecked=!!s,_!=null&&typeof _!="function"&&typeof _!="symbol"&&typeof _!="boolean"&&(e.name=_),su(e)}function cu(e,t,n){t==="number"&&dr(e.ownerDocument)===e||e.defaultValue===""+n||(e.defaultValue=""+n)}function Ts(e,t,n,s){if(e=e.options,t){t={};for(var o=0;o"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),fu=!1;if(xl)try{var qi={};Object.defineProperty(qi,"passive",{get:function(){fu=!0}}),window.addEventListener("test",qi,qi),window.removeEventListener("test",qi,qi)}catch{fu=!1}var Wl=null,hu=null,hr=null;function nf(){if(hr)return hr;var e,t=hu,n=t.length,s,o="value"in Wl?Wl.value:Wl.textContent,u=o.length;for(e=0;e=Vi),of=" ",uf=!1;function df(e,t){switch(e){case"keyup":return Ng.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function ff(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var Ms=!1;function Cg(e,t){switch(e){case"compositionend":return ff(t);case"keypress":return t.which!==32?null:(uf=!0,of);case"textInput":return e=t.data,e===of&&uf?null:e;default:return null}}function Eg(e,t){if(Ms)return e==="compositionend"||!vu&&df(e,t)?(e=nf(),hr=hu=Wl=null,Ms=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=s}e:{for(;n;){if(n.nextSibling){n=n.nextSibling;break e}n=n.parentNode}n=void 0}n=xf(n)}}function jf(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?jf(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Sf(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=dr(e.document);t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href=="string"}catch{n=!1}if(n)e=t.contentWindow;else break;t=dr(e.document)}return t}function bu(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||t==="textarea"||e.contentEditable==="true")}var Dg=xl&&"documentMode"in document&&11>=document.documentMode,Ls=null,ju=null,Pi=null,Su=!1;function Nf(e,t,n){var s=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;Su||Ls==null||Ls!==dr(s)||(s=Ls,"selectionStart"in s&&bu(s)?s={start:s.selectionStart,end:s.selectionEnd}:(s=(s.ownerDocument&&s.ownerDocument.defaultView||window).getSelection(),s={anchorNode:s.anchorNode,anchorOffset:s.anchorOffset,focusNode:s.focusNode,focusOffset:s.focusOffset}),Pi&&Ii(Pi,s)||(Pi=s,s=io(ju,"onSelect"),0>=_,o-=_,al=1<<32-yn(t)+o|n<je?(ze=ae,ae=null):ze=ae.sibling;var He=k(M,ae,z[je],G);if(He===null){ae===null&&(ae=ze);break}e&&ae&&He.alternate===null&&t(M,ae),A=u(He,A,je),$e===null?ce=He:$e.sibling=He,$e=He,ae=ze}if(je===z.length)return n(M,ae),ke&&jl(M,je),ce;if(ae===null){for(;jeje?(ze=ae,ae=null):ze=ae.sibling;var xa=k(M,ae,He.value,G);if(xa===null){ae===null&&(ae=ze);break}e&&ae&&xa.alternate===null&&t(M,ae),A=u(xa,A,je),$e===null?ce=xa:$e.sibling=xa,$e=xa,ae=ze}if(He.done)return n(M,ae),ke&&jl(M,je),ce;if(ae===null){for(;!He.done;je++,He=z.next())He=Q(M,He.value,G),He!==null&&(A=u(He,A,je),$e===null?ce=He:$e.sibling=He,$e=He);return ke&&jl(M,je),ce}for(ae=s(ae);!He.done;je++,He=z.next())He=$(ae,M,je,He.value,G),He!==null&&(e&&He.alternate!==null&&ae.delete(He.key===null?je:He.key),A=u(He,A,je),$e===null?ce=He:$e.sibling=He,$e=He);return e&&ae.forEach(function(ty){return t(M,ty)}),ke&&jl(M,je),ce}function Pe(M,A,z,G){if(typeof z=="object"&&z!==null&&z.type===C&&z.key===null&&(z=z.props.children),typeof z=="object"&&z!==null){switch(z.$$typeof){case N:e:{for(var ce=z.key;A!==null;){if(A.key===ce){if(ce=z.type,ce===C){if(A.tag===7){n(M,A.sibling),G=o(A,z.props.children),G.return=M,M=G;break e}}else if(A.elementType===ce||typeof ce=="object"&&ce!==null&&ce.$$typeof===Y&&Ia(ce)===A.type){n(M,A.sibling),G=o(A,z.props),ec(G,z),G.return=M,M=G;break e}n(M,A);break}else t(M,A);A=A.sibling}z.type===C?(G=Fa(z.props.children,M.mode,G,z.key),G.return=M,M=G):(G=Sr(z.type,z.key,z.props,null,M.mode,G),ec(G,z),G.return=M,M=G)}return _(M);case S:e:{for(ce=z.key;A!==null;){if(A.key===ce)if(A.tag===4&&A.stateNode.containerInfo===z.containerInfo&&A.stateNode.implementation===z.implementation){n(M,A.sibling),G=o(A,z.children||[]),G.return=M,M=G;break e}else{n(M,A);break}else t(M,A);A=A.sibling}G=Au(z,M.mode,G),G.return=M,M=G}return _(M);case Y:return z=Ia(z),Pe(M,A,z,G)}if(de(z))return ne(M,A,z,G);if(Ee(z)){if(ce=Ee(z),typeof ce!="function")throw Error(r(150));return z=ce.call(z),fe(M,A,z,G)}if(typeof z.then=="function")return Pe(M,A,Ar(z),G);if(z.$$typeof===L)return Pe(M,A,Cr(M,z),G);Or(M,z)}return typeof z=="string"&&z!==""||typeof z=="number"||typeof z=="bigint"?(z=""+z,A!==null&&A.tag===6?(n(M,A.sibling),G=o(A,z),G.return=M,M=G):(n(M,A),G=Ru(z,M.mode,G),G.return=M,M=G),_(M)):n(M,A)}return function(M,A,z,G){try{Ji=0;var ce=Pe(M,A,z,G);return Vs=null,ce}catch(ae){if(ae===Gs||ae===Tr)throw ae;var $e=bn(29,ae,null,M.mode);return $e.lanes=G,$e.return=M,$e}finally{}}}var Xa=If(!0),Pf=If(!1),la=!1;function Fu(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Gu(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function aa(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function sa(e,t,n){var s=e.updateQueue;if(s===null)return null;if(s=s.shared,(qe&2)!==0){var o=s.pending;return o===null?t.next=t:(t.next=o.next,o.next=t),s.pending=t,t=jr(e),Of(e,null,n),t}return br(e,s,t,n),jr(e)}function tc(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,(n&4194048)!==0)){var s=t.lanes;s&=e.pendingLanes,n|=s,t.lanes=n,U2(e,n)}}function Vu(e,t){var n=e.updateQueue,s=e.alternate;if(s!==null&&(s=s.updateQueue,n===s)){var o=null,u=null;if(n=n.firstBaseUpdate,n!==null){do{var _={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};u===null?o=u=_:u=u.next=_,n=n.next}while(n!==null);u===null?o=u=t:u=u.next=t}else o=u=t;n={baseState:s.baseState,firstBaseUpdate:o,lastBaseUpdate:u,shared:s.shared,callbacks:s.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var Qu=!1;function nc(){if(Qu){var e=Fs;if(e!==null)throw e}}function lc(e,t,n,s){Qu=!1;var o=e.updateQueue;la=!1;var u=o.firstBaseUpdate,_=o.lastBaseUpdate,x=o.shared.pending;if(x!==null){o.shared.pending=null;var E=x,D=E.next;E.next=null,_===null?u=D:_.next=D,_=E;var F=e.alternate;F!==null&&(F=F.updateQueue,x=F.lastBaseUpdate,x!==_&&(x===null?F.firstBaseUpdate=D:x.next=D,F.lastBaseUpdate=E))}if(u!==null){var Q=o.baseState;_=0,F=D=E=null,x=u;do{var k=x.lane&-536870913,$=k!==x.lane;if($?(Le&k)===k:(s&k)===k){k!==0&&k===qs&&(Qu=!0),F!==null&&(F=F.next={lane:0,tag:x.tag,payload:x.payload,callback:null,next:null});e:{var ne=e,fe=x;k=t;var Pe=n;switch(fe.tag){case 1:if(ne=fe.payload,typeof ne=="function"){Q=ne.call(Pe,Q,k);break e}Q=ne;break e;case 3:ne.flags=ne.flags&-65537|128;case 0:if(ne=fe.payload,k=typeof ne=="function"?ne.call(Pe,Q,k):ne,k==null)break e;Q=y({},Q,k);break e;case 2:la=!0}}k=x.callback,k!==null&&(e.flags|=64,$&&(e.flags|=8192),$=o.callbacks,$===null?o.callbacks=[k]:$.push(k))}else $={lane:k,tag:x.tag,payload:x.payload,callback:x.callback,next:null},F===null?(D=F=$,E=Q):F=F.next=$,_|=k;if(x=x.next,x===null){if(x=o.shared.pending,x===null)break;$=x,x=$.next,$.next=null,o.lastBaseUpdate=$,o.shared.pending=null}}while(!0);F===null&&(E=Q),o.baseState=E,o.firstBaseUpdate=D,o.lastBaseUpdate=F,u===null&&(o.shared.lanes=0),ua|=_,e.lanes=_,e.memoizedState=Q}}function Xf(e,t){if(typeof e!="function")throw Error(r(191,e));e.call(t)}function Zf(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;eu?u:8;var _=q.T,x={};q.T=x,u0(e,!1,t,n);try{var E=o(),D=q.S;if(D!==null&&D(x,E),E!==null&&typeof E=="object"&&typeof E.then=="function"){var F=Vg(E,s);ic(e,t,F,Cn(e))}else ic(e,t,s,Cn(e))}catch(Q){ic(e,t,{then:function(){},status:"rejected",reason:Q},Cn())}finally{P.p=u,_!==null&&x.types!==null&&(_.types=x.types),q.T=_}}function Zg(){}function r0(e,t,n,s){if(e.tag!==5)throw Error(r(476));var o=Th(e).queue;Eh(e,o,t,se,n===null?Zg:function(){return Rh(e),n(s)})}function Th(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:se,baseState:se,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Cl,lastRenderedState:se},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Cl,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function Rh(e){var t=Th(e);t.next===null&&(t=e.alternate.memoizedState),ic(e,t.next.queue,{},Cn())}function o0(){return $t(Sc)}function Ah(){return pt().memoizedState}function Oh(){return pt().memoizedState}function Kg(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=Cn();e=aa(n);var s=sa(t,e,n);s!==null&&(dn(s,t,n),tc(s,t,n)),t={cache:Uu()},e.payload=t;return}t=t.return}}function Wg(e,t,n){var s=Cn();n={lane:s,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},qr(e)?Lh(t,n):(n=Eu(e,t,n,s),n!==null&&(dn(n,e,s),zh(n,t,s)))}function Mh(e,t,n){var s=Cn();ic(e,t,n,s)}function ic(e,t,n,s){var o={lane:s,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(qr(e))Lh(t,o);else{var u=e.alternate;if(e.lanes===0&&(u===null||u.lanes===0)&&(u=t.lastRenderedReducer,u!==null))try{var _=t.lastRenderedState,x=u(_,n);if(o.hasEagerState=!0,o.eagerState=x,xn(x,_))return br(e,t,o,0),Ze===null&&xr(),!1}catch{}finally{}if(n=Eu(e,t,o,s),n!==null)return dn(n,e,s),zh(n,t,s),!0}return!1}function u0(e,t,n,s){if(s={lane:2,revertLane:F0(),gesture:null,action:s,hasEagerState:!1,eagerState:null,next:null},qr(e)){if(t)throw Error(r(479))}else t=Eu(e,n,s,2),t!==null&&dn(t,e,2)}function qr(e){var t=e.alternate;return e===xe||t!==null&&t===xe}function Lh(e,t){Ys=zr=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function zh(e,t,n){if((n&4194048)!==0){var s=t.lanes;s&=e.pendingLanes,n|=s,t.lanes=n,U2(e,n)}}var cc={readContext:$t,use:Br,useCallback:ut,useContext:ut,useEffect:ut,useImperativeHandle:ut,useLayoutEffect:ut,useInsertionEffect:ut,useMemo:ut,useReducer:ut,useRef:ut,useState:ut,useDebugValue:ut,useDeferredValue:ut,useTransition:ut,useSyncExternalStore:ut,useId:ut,useHostTransitionStatus:ut,useFormState:ut,useActionState:ut,useOptimistic:ut,useMemoCache:ut,useCacheRefresh:ut};cc.useEffectEvent=ut;var Dh={readContext:$t,use:Br,useCallback:function(e,t){return Xt().memoizedState=[e,t===void 0?null:t],e},useContext:$t,useEffect:vh,useImperativeHandle:function(e,t,n){n=n!=null?n.concat([e]):null,$r(4194308,4,jh.bind(null,t,e),n)},useLayoutEffect:function(e,t){return $r(4194308,4,e,t)},useInsertionEffect:function(e,t){$r(4,2,e,t)},useMemo:function(e,t){var n=Xt();t=t===void 0?null:t;var s=e();if(Za){Zl(!0);try{e()}finally{Zl(!1)}}return n.memoizedState=[s,t],s},useReducer:function(e,t,n){var s=Xt();if(n!==void 0){var o=n(t);if(Za){Zl(!0);try{n(t)}finally{Zl(!1)}}}else o=t;return s.memoizedState=s.baseState=o,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:o},s.queue=e,e=e.dispatch=Wg.bind(null,xe,e),[s.memoizedState,e]},useRef:function(e){var t=Xt();return e={current:e},t.memoizedState=e},useState:function(e){e=l0(e);var t=e.queue,n=Mh.bind(null,xe,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:i0,useDeferredValue:function(e,t){var n=Xt();return c0(n,e,t)},useTransition:function(){var e=l0(!1);return e=Eh.bind(null,xe,e.queue,!0,!1),Xt().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var s=xe,o=Xt();if(ke){if(n===void 0)throw Error(r(407));n=n()}else{if(n=t(),Ze===null)throw Error(r(349));(Le&127)!==0||nh(s,t,n)}o.memoizedState=n;var u={value:n,getSnapshot:t};return o.queue=u,vh(ah.bind(null,s,u,e),[e]),s.flags|=2048,Ps(9,{destroy:void 0},lh.bind(null,s,u,n,t),null),n},useId:function(){var e=Xt(),t=Ze.identifierPrefix;if(ke){var n=sl,s=al;n=(s&~(1<<32-yn(s)-1)).toString(32)+n,t="_"+t+"R_"+n,n=Dr++,0<\/script>",u=u.removeChild(u.firstChild);break;case"select":u=typeof s.is=="string"?_.createElement("select",{is:s.is}):_.createElement("select"),s.multiple?u.multiple=!0:s.size&&(u.size=s.size);break;default:u=typeof s.is=="string"?_.createElement(o,{is:s.is}):_.createElement(o)}}u[Bt]=t,u[an]=s;e:for(_=t.child;_!==null;){if(_.tag===5||_.tag===6)u.appendChild(_.stateNode);else if(_.tag!==4&&_.tag!==27&&_.child!==null){_.child.return=_,_=_.child;continue}if(_===t)break e;for(;_.sibling===null;){if(_.return===null||_.return===t)break e;_=_.return}_.sibling.return=_.return,_=_.sibling}t.stateNode=u;e:switch(qt(u,o,s),o){case"button":case"input":case"select":case"textarea":s=!!s.autoFocus;break e;case"img":s=!0;break e;default:s=!1}s&&Tl(t)}}return lt(t),N0(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==s&&Tl(t);else{if(typeof s!="string"&&t.stateNode===null)throw Error(r(166));if(e=be.current,$s(t)){if(e=t.stateNode,n=t.memoizedProps,s=null,o=Ut,o!==null)switch(o.tag){case 27:case 5:s=o.memoizedProps}e[Bt]=t,e=!!(e.nodeValue===n||s!==null&&s.suppressHydrationWarning===!0||em(e.nodeValue,n)),e||ta(t,!0)}else e=co(e).createTextNode(s),e[Bt]=t,t.stateNode=e}return lt(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(s=$s(t),n!==null){if(e===null){if(!s)throw Error(r(318));if(e=t.memoizedState,e=e!==null?e.dehydrated:null,!e)throw Error(r(557));e[Bt]=t}else Ga(),(t.flags&128)===0&&(t.memoizedState=null),t.flags|=4;lt(t),e=!1}else n=zu(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(Sn(t),t):(Sn(t),null);if((t.flags&128)!==0)throw Error(r(558))}return lt(t),null;case 13:if(s=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(o=$s(t),s!==null&&s.dehydrated!==null){if(e===null){if(!o)throw Error(r(318));if(o=t.memoizedState,o=o!==null?o.dehydrated:null,!o)throw Error(r(317));o[Bt]=t}else Ga(),(t.flags&128)===0&&(t.memoizedState=null),t.flags|=4;lt(t),o=!1}else o=zu(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=o),o=!0;if(!o)return t.flags&256?(Sn(t),t):(Sn(t),null)}return Sn(t),(t.flags&128)!==0?(t.lanes=n,t):(n=s!==null,e=e!==null&&e.memoizedState!==null,n&&(s=t.child,o=null,s.alternate!==null&&s.alternate.memoizedState!==null&&s.alternate.memoizedState.cachePool!==null&&(o=s.alternate.memoizedState.cachePool.pool),u=null,s.memoizedState!==null&&s.memoizedState.cachePool!==null&&(u=s.memoizedState.cachePool.pool),u!==o&&(s.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),Yr(t,t.updateQueue),lt(t),null);case 4:return tt(),e===null&&Y0(t.stateNode.containerInfo),lt(t),null;case 10:return Nl(t.type),lt(t),null;case 19:if(V(mt),s=t.memoizedState,s===null)return lt(t),null;if(o=(t.flags&128)!==0,u=s.rendering,u===null)if(o)oc(s,!1);else{if(dt!==0||e!==null&&(e.flags&128)!==0)for(e=t.child;e!==null;){if(u=Lr(e),u!==null){for(t.flags|=128,oc(s,!1),e=u.updateQueue,t.updateQueue=e,Yr(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)Mf(n,e),n=n.sibling;return Z(mt,mt.current&1|2),ke&&jl(t,s.treeForkCount),t.child}e=e.sibling}s.tail!==null&&gn()>Kr&&(t.flags|=128,o=!0,oc(s,!1),t.lanes=4194304)}else{if(!o)if(e=Lr(u),e!==null){if(t.flags|=128,o=!0,e=e.updateQueue,t.updateQueue=e,Yr(t,e),oc(s,!0),s.tail===null&&s.tailMode==="hidden"&&!u.alternate&&!ke)return lt(t),null}else 2*gn()-s.renderingStartTime>Kr&&n!==536870912&&(t.flags|=128,o=!0,oc(s,!1),t.lanes=4194304);s.isBackwards?(u.sibling=t.child,t.child=u):(e=s.last,e!==null?e.sibling=u:t.child=u,s.last=u)}return s.tail!==null?(e=s.tail,s.rendering=e,s.tail=e.sibling,s.renderingStartTime=gn(),e.sibling=null,n=mt.current,Z(mt,o?n&1|2:n&1),ke&&jl(t,s.treeForkCount),e):(lt(t),null);case 22:case 23:return Sn(t),Iu(),s=t.memoizedState!==null,e!==null?e.memoizedState!==null!==s&&(t.flags|=8192):s&&(t.flags|=8192),s?(n&536870912)!==0&&(t.flags&128)===0&&(lt(t),t.subtreeFlags&6&&(t.flags|=8192)):lt(t),n=t.updateQueue,n!==null&&Yr(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),s=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(s=t.memoizedState.cachePool.pool),s!==n&&(t.flags|=2048),e!==null&&V(Ya),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),Nl(yt),lt(t),null;case 25:return null;case 30:return null}throw Error(r(156,t.tag))}function lv(e,t){switch(Mu(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Nl(yt),tt(),e=t.flags,(e&65536)!==0&&(e&128)===0?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return _l(t),null;case 31:if(t.memoizedState!==null){if(Sn(t),t.alternate===null)throw Error(r(340));Ga()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(Sn(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(r(340));Ga()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return V(mt),null;case 4:return tt(),null;case 10:return Nl(t.type),null;case 22:case 23:return Sn(t),Iu(),e!==null&&V(Ya),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return Nl(yt),null;case 25:return null;default:return null}}function s1(e,t){switch(Mu(t),t.tag){case 3:Nl(yt),tt();break;case 26:case 27:case 5:_l(t);break;case 4:tt();break;case 31:t.memoizedState!==null&&Sn(t);break;case 13:Sn(t);break;case 19:V(mt);break;case 10:Nl(t.type);break;case 22:case 23:Sn(t),Iu(),e!==null&&V(Ya);break;case 24:Nl(yt)}}function uc(e,t){try{var n=t.updateQueue,s=n!==null?n.lastEffect:null;if(s!==null){var o=s.next;n=o;do{if((n.tag&e)===e){s=void 0;var u=n.create,_=n.inst;s=u(),_.destroy=s}n=n.next}while(n!==o)}}catch(x){Ve(t,t.return,x)}}function ra(e,t,n){try{var s=t.updateQueue,o=s!==null?s.lastEffect:null;if(o!==null){var u=o.next;s=u;do{if((s.tag&e)===e){var _=s.inst,x=_.destroy;if(x!==void 0){_.destroy=void 0,o=t;var E=n,D=x;try{D()}catch(F){Ve(o,E,F)}}}s=s.next}while(s!==u)}}catch(F){Ve(t,t.return,F)}}function i1(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{Zf(t,n)}catch(s){Ve(e,e.return,s)}}}function c1(e,t,n){n.props=Ka(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(s){Ve(e,t,s)}}function dc(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var s=e.stateNode;break;case 30:s=e.stateNode;break;default:s=e.stateNode}typeof n=="function"?e.refCleanup=n(s):n.current=s}}catch(o){Ve(e,t,o)}}function il(e,t){var n=e.ref,s=e.refCleanup;if(n!==null)if(typeof s=="function")try{s()}catch(o){Ve(e,t,o)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n=="function")try{n(null)}catch(o){Ve(e,t,o)}else n.current=null}function r1(e){var t=e.type,n=e.memoizedProps,s=e.stateNode;try{e:switch(t){case"button":case"input":case"select":case"textarea":n.autoFocus&&s.focus();break e;case"img":n.src?s.src=n.src:n.srcSet&&(s.srcset=n.srcSet)}}catch(o){Ve(e,e.return,o)}}function w0(e,t,n){try{var s=e.stateNode;wv(s,e.type,n,t),s[an]=t}catch(o){Ve(e,e.return,o)}}function o1(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&pa(e.type)||e.tag===4}function C0(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||o1(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.tag===27&&pa(e.type)||e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function E0(e,t,n){var s=e.tag;if(s===5||s===6)e=e.stateNode,t?(n.nodeType===9?n.body:n.nodeName==="HTML"?n.ownerDocument.body:n).insertBefore(e,t):(t=n.nodeType===9?n.body:n.nodeName==="HTML"?n.ownerDocument.body:n,t.appendChild(e),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=yl));else if(s!==4&&(s===27&&pa(e.type)&&(n=e.stateNode,t=null),e=e.child,e!==null))for(E0(e,t,n),e=e.sibling;e!==null;)E0(e,t,n),e=e.sibling}function Ir(e,t,n){var s=e.tag;if(s===5||s===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(s!==4&&(s===27&&pa(e.type)&&(n=e.stateNode),e=e.child,e!==null))for(Ir(e,t,n),e=e.sibling;e!==null;)Ir(e,t,n),e=e.sibling}function u1(e){var t=e.stateNode,n=e.memoizedProps;try{for(var s=e.type,o=t.attributes;o.length;)t.removeAttributeNode(o[0]);qt(t,s,n),t[Bt]=e,t[an]=n}catch(u){Ve(e,e.return,u)}}var Rl=!1,jt=!1,T0=!1,d1=typeof WeakSet=="function"?WeakSet:Set,At=null;function av(e,t){if(e=e.containerInfo,X0=po,e=Sf(e),bu(e)){if("selectionStart"in e)var n={start:e.selectionStart,end:e.selectionEnd};else e:{n=(n=e.ownerDocument)&&n.defaultView||window;var s=n.getSelection&&n.getSelection();if(s&&s.rangeCount!==0){n=s.anchorNode;var o=s.anchorOffset,u=s.focusNode;s=s.focusOffset;try{n.nodeType,u.nodeType}catch{n=null;break e}var _=0,x=-1,E=-1,D=0,F=0,Q=e,k=null;t:for(;;){for(var $;Q!==n||o!==0&&Q.nodeType!==3||(x=_+o),Q!==u||s!==0&&Q.nodeType!==3||(E=_+s),Q.nodeType===3&&(_+=Q.nodeValue.length),($=Q.firstChild)!==null;)k=Q,Q=$;for(;;){if(Q===e)break t;if(k===n&&++D===o&&(x=_),k===u&&++F===s&&(E=_),($=Q.nextSibling)!==null)break;Q=k,k=Q.parentNode}Q=$}n=x===-1||E===-1?null:{start:x,end:E}}else n=null}n=n||{start:0,end:0}}else n=null;for(Z0={focusedElem:e,selectionRange:n},po=!1,At=t;At!==null;)if(t=At,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,At=e;else for(;At!==null;){switch(t=At,u=t.alternate,e=t.flags,t.tag){case 0:if((e&4)!==0&&(e=t.updateQueue,e=e!==null?e.events:null,e!==null))for(n=0;n title"))),qt(u,s,n),u[Bt]=e,Rt(u),s=u;break e;case"link":var _=gm("link","href",o).get(s+(n.href||""));if(_){for(var x=0;x<_.length;x++)if(u=_[x],u.getAttribute("href")===(n.href==null||n.href===""?null:n.href)&&u.getAttribute("rel")===(n.rel==null?null:n.rel)&&u.getAttribute("title")===(n.title==null?null:n.title)&&u.getAttribute("crossorigin")===(n.crossOrigin==null?null:n.crossOrigin)){_.splice(x,1);break t}}u=o.createElement(s),qt(u,s,n),o.head.appendChild(u);break;case"meta":if(_=gm("meta","content",o).get(s+(n.content||""))){for(x=0;x<_.length;x++)if(u=_[x],u.getAttribute("content")===(n.content==null?null:""+n.content)&&u.getAttribute("name")===(n.name==null?null:n.name)&&u.getAttribute("property")===(n.property==null?null:n.property)&&u.getAttribute("http-equiv")===(n.httpEquiv==null?null:n.httpEquiv)&&u.getAttribute("charset")===(n.charSet==null?null:n.charSet)){_.splice(x,1);break t}}u=o.createElement(s),qt(u,s,n),o.head.appendChild(u);break;default:throw Error(r(468,s))}u[Bt]=e,Rt(u),s=u}e.stateNode=s}else vm(o,e.type,e.stateNode);else e.stateNode=_m(o,s,e.memoizedProps);else u!==s?(u===null?n.stateNode!==null&&(n=n.stateNode,n.parentNode.removeChild(n)):u.count--,s===null?vm(o,e.type,e.stateNode):_m(o,s,e.memoizedProps)):s===null&&e.stateNode!==null&&w0(e,e.memoizedProps,n.memoizedProps)}break;case 27:rn(t,e),on(e),s&512&&(jt||n===null||il(n,n.return)),n!==null&&s&4&&w0(e,e.memoizedProps,n.memoizedProps);break;case 5:if(rn(t,e),on(e),s&512&&(jt||n===null||il(n,n.return)),e.flags&32){o=e.stateNode;try{Rs(o,"")}catch(ne){Ve(e,e.return,ne)}}s&4&&e.stateNode!=null&&(o=e.memoizedProps,w0(e,o,n!==null?n.memoizedProps:o)),s&1024&&(T0=!0);break;case 6:if(rn(t,e),on(e),s&4){if(e.stateNode===null)throw Error(r(162));s=e.memoizedProps,n=e.stateNode;try{n.nodeValue=s}catch(ne){Ve(e,e.return,ne)}}break;case 3:if(uo=null,o=Xn,Xn=ro(t.containerInfo),rn(t,e),Xn=o,on(e),s&4&&n!==null&&n.memoizedState.isDehydrated)try{ii(t.containerInfo)}catch(ne){Ve(e,e.return,ne)}T0&&(T0=!1,v1(e));break;case 4:s=Xn,Xn=ro(e.stateNode.containerInfo),rn(t,e),on(e),Xn=s;break;case 12:rn(t,e),on(e);break;case 31:rn(t,e),on(e),s&4&&(s=e.updateQueue,s!==null&&(e.updateQueue=null,Pr(e,s)));break;case 13:rn(t,e),on(e),e.child.flags&8192&&e.memoizedState!==null!=(n!==null&&n.memoizedState!==null)&&(Zr=gn()),s&4&&(s=e.updateQueue,s!==null&&(e.updateQueue=null,Pr(e,s)));break;case 22:o=e.memoizedState!==null;var E=n!==null&&n.memoizedState!==null,D=Rl,F=jt;if(Rl=D||o,jt=F||E,rn(t,e),jt=F,Rl=D,on(e),s&8192)e:for(t=e.stateNode,t._visibility=o?t._visibility&-2:t._visibility|1,o&&(n===null||E||Rl||jt||Wa(e)),n=null,t=e;;){if(t.tag===5||t.tag===26){if(n===null){E=n=t;try{if(u=E.stateNode,o)_=u.style,typeof _.setProperty=="function"?_.setProperty("display","none","important"):_.display="none";else{x=E.stateNode;var Q=E.memoizedProps.style,k=Q!=null&&Q.hasOwnProperty("display")?Q.display:null;x.style.display=k==null||typeof k=="boolean"?"":(""+k).trim()}}catch(ne){Ve(E,E.return,ne)}}}else if(t.tag===6){if(n===null){E=t;try{E.stateNode.nodeValue=o?"":E.memoizedProps}catch(ne){Ve(E,E.return,ne)}}}else if(t.tag===18){if(n===null){E=t;try{var $=E.stateNode;o?cm($,!0):cm(E.stateNode,!1)}catch(ne){Ve(E,E.return,ne)}}}else if((t.tag!==22&&t.tag!==23||t.memoizedState===null||t===e)&&t.child!==null){t.child.return=t,t=t.child;continue}if(t===e)break e;for(;t.sibling===null;){if(t.return===null||t.return===e)break e;n===t&&(n=null),t=t.return}n===t&&(n=null),t.sibling.return=t.return,t=t.sibling}s&4&&(s=e.updateQueue,s!==null&&(n=s.retryQueue,n!==null&&(s.retryQueue=null,Pr(e,n))));break;case 19:rn(t,e),on(e),s&4&&(s=e.updateQueue,s!==null&&(e.updateQueue=null,Pr(e,s)));break;case 30:break;case 21:break;default:rn(t,e),on(e)}}function on(e){var t=e.flags;if(t&2){try{for(var n,s=e.return;s!==null;){if(o1(s)){n=s;break}s=s.return}if(n==null)throw Error(r(160));switch(n.tag){case 27:var o=n.stateNode,u=C0(e);Ir(e,u,o);break;case 5:var _=n.stateNode;n.flags&32&&(Rs(_,""),n.flags&=-33);var x=C0(e);Ir(e,x,_);break;case 3:case 4:var E=n.stateNode.containerInfo,D=C0(e);E0(e,D,E);break;default:throw Error(r(161))}}catch(F){Ve(e,e.return,F)}e.flags&=-3}t&4096&&(e.flags&=-4097)}function v1(e){if(e.subtreeFlags&1024)for(e=e.child;e!==null;){var t=e;v1(t),t.tag===5&&t.flags&1024&&t.stateNode.reset(),e=e.sibling}}function Ol(e,t){if(t.subtreeFlags&8772)for(t=t.child;t!==null;)f1(e,t.alternate,t),t=t.sibling}function Wa(e){for(e=e.child;e!==null;){var t=e;switch(t.tag){case 0:case 11:case 14:case 15:ra(4,t,t.return),Wa(t);break;case 1:il(t,t.return);var n=t.stateNode;typeof n.componentWillUnmount=="function"&&c1(t,t.return,n),Wa(t);break;case 27:xc(t.stateNode);case 26:case 5:il(t,t.return),Wa(t);break;case 22:t.memoizedState===null&&Wa(t);break;case 30:Wa(t);break;default:Wa(t)}e=e.sibling}}function Ml(e,t,n){for(n=n&&(t.subtreeFlags&8772)!==0,t=t.child;t!==null;){var s=t.alternate,o=e,u=t,_=u.flags;switch(u.tag){case 0:case 11:case 15:Ml(o,u,n),uc(4,u);break;case 1:if(Ml(o,u,n),s=u,o=s.stateNode,typeof o.componentDidMount=="function")try{o.componentDidMount()}catch(D){Ve(s,s.return,D)}if(s=u,o=s.updateQueue,o!==null){var x=s.stateNode;try{var E=o.shared.hiddenCallbacks;if(E!==null)for(o.shared.hiddenCallbacks=null,o=0;oPe&&(_=Pe,Pe=fe,fe=_);var M=bf(x,fe),A=bf(x,Pe);if(M&&A&&($.rangeCount!==1||$.anchorNode!==M.node||$.anchorOffset!==M.offset||$.focusNode!==A.node||$.focusOffset!==A.offset)){var z=Q.createRange();z.setStart(M.node,M.offset),$.removeAllRanges(),fe>Pe?($.addRange(z),$.extend(A.node,A.offset)):(z.setEnd(A.node,A.offset),$.addRange(z))}}}}for(Q=[],$=x;$=$.parentNode;)$.nodeType===1&&Q.push({element:$,left:$.scrollLeft,top:$.scrollTop});for(typeof x.focus=="function"&&x.focus(),x=0;xn?32:n,q.T=null,n=D0,D0=null;var u=fa,_=zl;if(wt=0,Js=fa=null,zl=0,(qe&6)!==0)throw Error(r(331));var x=qe;if(qe|=4,j1(u.current),y1(u,u.current,_,n),qe=x,gc(0,!1),vn&&typeof vn.onPostCommitFiberRoot=="function")try{vn.onPostCommitFiberRoot(Di,u)}catch{}return!0}finally{P.p=o,q.T=s,H1(e,t)}}function F1(e,t,n){t=Un(n,t),t=m0(e.stateNode,t,2),e=sa(e,t,2),e!==null&&(Bi(e,2),cl(e))}function Ve(e,t,n){if(e.tag===3)F1(e,e,n);else for(;t!==null;){if(t.tag===3){F1(t,e,n);break}else if(t.tag===1){var s=t.stateNode;if(typeof t.type.getDerivedStateFromError=="function"||typeof s.componentDidCatch=="function"&&(da===null||!da.has(s))){e=Un(n,e),n=Gh(2),s=sa(t,n,2),s!==null&&(Vh(n,s,t,e),Bi(s,2),cl(s));break}}t=t.return}}function $0(e,t,n){var s=e.pingCache;if(s===null){s=e.pingCache=new cv;var o=new Set;s.set(t,o)}else o=s.get(t),o===void 0&&(o=new Set,s.set(t,o));o.has(n)||(O0=!0,o.add(n),e=fv.bind(null,e,t,n),t.then(e,e))}function fv(e,t,n){var s=e.pingCache;s!==null&&s.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,Ze===e&&(Le&n)===n&&(dt===4||dt===3&&(Le&62914560)===Le&&300>gn()-Zr?(qe&2)===0&&ei(e,0):M0|=n,Ws===Le&&(Ws=0)),cl(e)}function G1(e,t){t===0&&(t=k2()),e=qa(e,t),e!==null&&(Bi(e,t),cl(e))}function hv(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),G1(e,n)}function mv(e,t){var n=0;switch(e.tag){case 31:case 13:var s=e.stateNode,o=e.memoizedState;o!==null&&(n=o.retryLane);break;case 19:s=e.stateNode;break;case 22:s=e.stateNode._retryCache;break;default:throw Error(r(314))}s!==null&&s.delete(t),G1(e,n)}function pv(e,t){return js(e,t)}var lo=null,ni=null,H0=!1,ao=!1,q0=!1,ma=0;function cl(e){e!==ni&&e.next===null&&(ni===null?lo=ni=e:ni=ni.next=e),ao=!0,H0||(H0=!0,gv())}function gc(e,t){if(!q0&&ao){q0=!0;do for(var n=!1,s=lo;s!==null;){if(e!==0){var o=s.pendingLanes;if(o===0)var u=0;else{var _=s.suspendedLanes,x=s.pingedLanes;u=(1<<31-yn(42|e)+1)-1,u&=o&~(_&~x),u=u&201326741?u&201326741|1:u?u|2:0}u!==0&&(n=!0,I1(s,u))}else u=Le,u=rr(s,s===Ze?u:0,s.cancelPendingCommit!==null||s.timeoutHandle!==-1),(u&3)===0||ki(s,u)||(n=!0,I1(s,u));s=s.next}while(n);q0=!1}}function _v(){V1()}function V1(){ao=H0=!1;var e=0;ma!==0&&Ev()&&(e=ma);for(var t=gn(),n=null,s=lo;s!==null;){var o=s.next,u=Q1(s,t);u===0?(s.next=null,n===null?lo=o:n.next=o,o===null&&(ni=n)):(n=s,(e!==0||(u&3)!==0)&&(ao=!0)),s=o}wt!==0&&wt!==5||gc(e),ma!==0&&(ma=0)}function Q1(e,t){for(var n=e.suspendedLanes,s=e.pingedLanes,o=e.expirationTimes,u=e.pendingLanes&-62914561;0x)break;var F=E.transferSize,Q=E.initiatorType;F&&tm(Q)&&(E=E.responseEnd,_+=F*(E"u"?null:document;function hm(e,t,n){var s=li;if(s&&typeof t=="string"&&t){var o=kn(t);o='link[rel="'+e+'"][href="'+o+'"]',typeof n=="string"&&(o+='[crossorigin="'+n+'"]'),fm.has(o)||(fm.add(o),e={rel:e,crossOrigin:n,href:t},s.querySelector(o)===null&&(t=s.createElement("link"),qt(t,"link",e),Rt(t),s.head.appendChild(t)))}}function kv(e){Dl.D(e),hm("dns-prefetch",e,null)}function Bv(e,t){Dl.C(e,t),hm("preconnect",e,t)}function Uv(e,t,n){Dl.L(e,t,n);var s=li;if(s&&e&&t){var o='link[rel="preload"][as="'+kn(t)+'"]';t==="image"&&n&&n.imageSrcSet?(o+='[imagesrcset="'+kn(n.imageSrcSet)+'"]',typeof n.imageSizes=="string"&&(o+='[imagesizes="'+kn(n.imageSizes)+'"]')):o+='[href="'+kn(e)+'"]';var u=o;switch(t){case"style":u=ai(e);break;case"script":u=si(e)}Vn.has(u)||(e=y({rel:"preload",href:t==="image"&&n&&n.imageSrcSet?void 0:e,as:t},n),Vn.set(u,e),s.querySelector(o)!==null||t==="style"&&s.querySelector(bc(u))||t==="script"&&s.querySelector(jc(u))||(t=s.createElement("link"),qt(t,"link",e),Rt(t),s.head.appendChild(t)))}}function $v(e,t){Dl.m(e,t);var n=li;if(n&&e){var s=t&&typeof t.as=="string"?t.as:"script",o='link[rel="modulepreload"][as="'+kn(s)+'"][href="'+kn(e)+'"]',u=o;switch(s){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":u=si(e)}if(!Vn.has(u)&&(e=y({rel:"modulepreload",href:e},t),Vn.set(u,e),n.querySelector(o)===null)){switch(s){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(n.querySelector(jc(u)))return}s=n.createElement("link"),qt(s,"link",e),Rt(s),n.head.appendChild(s)}}}function Hv(e,t,n){Dl.S(e,t,n);var s=li;if(s&&e){var o=Cs(s).hoistableStyles,u=ai(e);t=t||"default";var _=o.get(u);if(!_){var x={loading:0,preload:null};if(_=s.querySelector(bc(u)))x.loading=5;else{e=y({rel:"stylesheet",href:e,"data-precedence":t},n),(n=Vn.get(u))&&ld(e,n);var E=_=s.createElement("link");Rt(E),qt(E,"link",e),E._p=new Promise(function(D,F){E.onload=D,E.onerror=F}),E.addEventListener("load",function(){x.loading|=1}),E.addEventListener("error",function(){x.loading|=2}),x.loading|=4,oo(_,t,s)}_={type:"stylesheet",instance:_,count:1,state:x},o.set(u,_)}}}function qv(e,t){Dl.X(e,t);var n=li;if(n&&e){var s=Cs(n).hoistableScripts,o=si(e),u=s.get(o);u||(u=n.querySelector(jc(o)),u||(e=y({src:e,async:!0},t),(t=Vn.get(o))&&ad(e,t),u=n.createElement("script"),Rt(u),qt(u,"link",e),n.head.appendChild(u)),u={type:"script",instance:u,count:1,state:null},s.set(o,u))}}function Fv(e,t){Dl.M(e,t);var n=li;if(n&&e){var s=Cs(n).hoistableScripts,o=si(e),u=s.get(o);u||(u=n.querySelector(jc(o)),u||(e=y({src:e,async:!0,type:"module"},t),(t=Vn.get(o))&&ad(e,t),u=n.createElement("script"),Rt(u),qt(u,"link",e),n.head.appendChild(u)),u={type:"script",instance:u,count:1,state:null},s.set(o,u))}}function mm(e,t,n,s){var o=(o=be.current)?ro(o):null;if(!o)throw Error(r(446));switch(e){case"meta":case"title":return null;case"style":return typeof n.precedence=="string"&&typeof n.href=="string"?(t=ai(n.href),n=Cs(o).hoistableStyles,s=n.get(t),s||(s={type:"style",instance:null,count:0,state:null},n.set(t,s)),s):{type:"void",instance:null,count:0,state:null};case"link":if(n.rel==="stylesheet"&&typeof n.href=="string"&&typeof n.precedence=="string"){e=ai(n.href);var u=Cs(o).hoistableStyles,_=u.get(e);if(_||(o=o.ownerDocument||o,_={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},u.set(e,_),(u=o.querySelector(bc(e)))&&!u._p&&(_.instance=u,_.state.loading=5),Vn.has(e)||(n={rel:"preload",as:"style",href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},Vn.set(e,n),u||Gv(o,e,n,_.state))),t&&s===null)throw Error(r(528,""));return _}if(t&&s!==null)throw Error(r(529,""));return null;case"script":return t=n.async,n=n.src,typeof n=="string"&&t&&typeof t!="function"&&typeof t!="symbol"?(t=si(n),n=Cs(o).hoistableScripts,s=n.get(t),s||(s={type:"script",instance:null,count:0,state:null},n.set(t,s)),s):{type:"void",instance:null,count:0,state:null};default:throw Error(r(444,e))}}function ai(e){return'href="'+kn(e)+'"'}function bc(e){return'link[rel="stylesheet"]['+e+"]"}function pm(e){return y({},e,{"data-precedence":e.precedence,precedence:null})}function Gv(e,t,n,s){e.querySelector('link[rel="preload"][as="style"]['+t+"]")?s.loading=1:(t=e.createElement("link"),s.preload=t,t.addEventListener("load",function(){return s.loading|=1}),t.addEventListener("error",function(){return s.loading|=2}),qt(t,"link",n),Rt(t),e.head.appendChild(t))}function si(e){return'[src="'+kn(e)+'"]'}function jc(e){return"script[async]"+e}function _m(e,t,n){if(t.count++,t.instance===null)switch(t.type){case"style":var s=e.querySelector('style[data-href~="'+kn(n.href)+'"]');if(s)return t.instance=s,Rt(s),s;var o=y({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return s=(e.ownerDocument||e).createElement("style"),Rt(s),qt(s,"style",o),oo(s,n.precedence,e),t.instance=s;case"stylesheet":o=ai(n.href);var u=e.querySelector(bc(o));if(u)return t.state.loading|=4,t.instance=u,Rt(u),u;s=pm(n),(o=Vn.get(o))&&ld(s,o),u=(e.ownerDocument||e).createElement("link"),Rt(u);var _=u;return _._p=new Promise(function(x,E){_.onload=x,_.onerror=E}),qt(u,"link",s),t.state.loading|=4,oo(u,n.precedence,e),t.instance=u;case"script":return u=si(n.src),(o=e.querySelector(jc(u)))?(t.instance=o,Rt(o),o):(s=n,(o=Vn.get(u))&&(s=y({},n),ad(s,o)),e=e.ownerDocument||e,o=e.createElement("script"),Rt(o),qt(o,"link",s),e.head.appendChild(o),t.instance=o);case"void":return null;default:throw Error(r(443,t.type))}else t.type==="stylesheet"&&(t.state.loading&4)===0&&(s=t.instance,t.state.loading|=4,oo(s,n.precedence,e));return t.instance}function oo(e,t,n){for(var s=n.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),o=s.length?s[s.length-1]:null,u=o,_=0;_ title"):null)}function Vv(e,t,n){if(n===1||t.itemProp!=null)return!1;switch(e){case"meta":case"title":return!0;case"style":if(typeof t.precedence!="string"||typeof t.href!="string"||t.href==="")break;return!0;case"link":if(typeof t.rel!="string"||typeof t.href!="string"||t.href===""||t.onLoad||t.onError)break;switch(t.rel){case"stylesheet":return e=t.disabled,typeof t.precedence=="string"&&e==null;default:return!0}case"script":if(t.async&&typeof t.async!="function"&&typeof t.async!="symbol"&&!t.onLoad&&!t.onError&&t.src&&typeof t.src=="string")return!0}return!1}function ym(e){return!(e.type==="stylesheet"&&(e.state.loading&3)===0)}function Qv(e,t,n,s){if(n.type==="stylesheet"&&(typeof s.media!="string"||matchMedia(s.media).matches!==!1)&&(n.state.loading&4)===0){if(n.instance===null){var o=ai(s.href),u=t.querySelector(bc(o));if(u){t=u._p,t!==null&&typeof t=="object"&&typeof t.then=="function"&&(e.count++,e=fo.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=u,Rt(u);return}u=t.ownerDocument||t,s=pm(s),(o=Vn.get(o))&&ld(s,o),u=u.createElement("link"),Rt(u);var _=u;_._p=new Promise(function(x,E){_.onload=x,_.onerror=E}),qt(u,"link",s),n.instance=u}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&(n.state.loading&3)===0&&(e.count++,n=fo.bind(e),t.addEventListener("load",n),t.addEventListener("error",n))}}var sd=0;function Yv(e,t){return e.stylesheets&&e.count===0&&mo(e,e.stylesheets),0sd?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(s),clearTimeout(o)}}:null}function fo(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)mo(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var ho=null;function mo(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,ho=new Map,t.forEach(Iv,e),ho=null,fo.call(e))}function Iv(e,t){if(!(t.state.loading&4)){var n=ho.get(e);if(n)var s=n.get(null);else{n=new Map,ho.set(e,n);for(var o=e.querySelectorAll("link[data-precedence],style[data-precedence]"),u=0;u"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(a)}catch(i){console.error(i)}}return a(),pd.exports=oy(),pd.exports}var dy=uy();/** + * react-router v7.14.2 + * + * Copyright (c) Remix Software Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE.md file in the root directory of this source tree. + * + * @license MIT + */var Vm="popstate";function Qm(a){return typeof a=="object"&&a!=null&&"pathname"in a&&"search"in a&&"hash"in a&&"state"in a&&"key"in a}function fy(a={}){function i(r,d){var m;let f=(m=d.state)==null?void 0:m.masked,{pathname:p,search:g,hash:h}=f||r.location;return $d("",{pathname:p,search:g,hash:h},d.state&&d.state.usr||null,d.state&&d.state.key||"default",f?{pathname:r.location.pathname,search:r.location.search,hash:r.location.hash}:void 0)}function c(r,d){return typeof d=="string"?d:qc(d)}return my(i,c,null,a)}function ct(a,i){if(a===!1||a===null||typeof a>"u")throw new Error(i)}function el(a,i){if(!a){typeof console<"u"&&console.warn(i);try{throw new Error(i)}catch{}}}function hy(){return Math.random().toString(36).substring(2,10)}function Ym(a,i){return{usr:a.state,key:a.key,idx:i,masked:a.unstable_mask?{pathname:a.pathname,search:a.search,hash:a.hash}:void 0}}function $d(a,i,c=null,r,d){return{pathname:typeof a=="string"?a:a.pathname,search:"",hash:"",...typeof i=="string"?Ri(i):i,state:c,key:i&&i.key||r||hy(),unstable_mask:d}}function qc({pathname:a="/",search:i="",hash:c=""}){return i&&i!=="?"&&(a+=i.charAt(0)==="?"?i:"?"+i),c&&c!=="#"&&(a+=c.charAt(0)==="#"?c:"#"+c),a}function Ri(a){let i={};if(a){let c=a.indexOf("#");c>=0&&(i.hash=a.substring(c),a=a.substring(0,c));let r=a.indexOf("?");r>=0&&(i.search=a.substring(r),a=a.substring(0,r)),a&&(i.pathname=a)}return i}function my(a,i,c,r={}){let{window:d=document.defaultView,v5Compat:f=!1}=r,p=d.history,g="POP",h=null,m=v();m==null&&(m=0,p.replaceState({...p.state,idx:m},""));function v(){return(p.state||{idx:null}).idx}function y(){g="POP";let w=v(),O=w==null?null:w-m;m=w,h&&h({action:g,location:C.location,delta:O})}function b(w,O){g="PUSH";let H=Qm(w)?w:$d(C.location,w,O);m=v()+1;let L=Ym(H,m),U=C.createHref(H.unstable_mask||H);try{p.pushState(L,"",U)}catch(I){if(I instanceof DOMException&&I.name==="DataCloneError")throw I;d.location.assign(U)}f&&h&&h({action:g,location:C.location,delta:1})}function N(w,O){g="REPLACE";let H=Qm(w)?w:$d(C.location,w,O);m=v();let L=Ym(H,m),U=C.createHref(H.unstable_mask||H);p.replaceState(L,"",U),f&&h&&h({action:g,location:C.location,delta:0})}function S(w){return py(w)}let C={get action(){return g},get location(){return a(d,p)},listen(w){if(h)throw new Error("A history only accepts one active listener");return d.addEventListener(Vm,y),h=w,()=>{d.removeEventListener(Vm,y),h=null}},createHref(w){return i(d,w)},createURL:S,encodeLocation(w){let O=S(w);return{pathname:O.pathname,search:O.search,hash:O.hash}},push:b,replace:N,go(w){return p.go(w)}};return C}function py(a,i=!1){let c="http://localhost";typeof window<"u"&&(c=window.location.origin!=="null"?window.location.origin:window.location.href),ct(c,"No window.location.(origin|href) available to create URL");let r=typeof a=="string"?a:qc(a);return r=r.replace(/ $/,"%20"),!i&&r.startsWith("//")&&(r=c+r),new URL(r,c)}function o3(a,i,c="/"){return _y(a,i,c,!1)}function _y(a,i,c,r){let d=typeof i=="string"?Ri(i):i,f=Vl(d.pathname||"/",c);if(f==null)return null;let p=u3(a);gy(p);let g=null;for(let h=0;g==null&&h{let v={relativePath:m===void 0?p.path||"":m,caseSensitive:p.caseSensitive===!0,childrenIndex:g,route:p};if(v.relativePath.startsWith("/")){if(!v.relativePath.startsWith(r)&&h)return;ct(v.relativePath.startsWith(r),`Absolute route path "${v.relativePath}" nested under path "${r}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),v.relativePath=v.relativePath.slice(r.length)}let y=Jn([r,v.relativePath]),b=c.concat(v);p.children&&p.children.length>0&&(ct(p.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${y}".`),u3(p.children,i,b,y,h)),!(p.path==null&&!p.index)&&i.push({path:y,score:Ny(y,p.index),routesMeta:b})};return a.forEach((p,g)=>{var h;if(p.path===""||!((h=p.path)!=null&&h.includes("?")))f(p,g);else for(let m of d3(p.path))f(p,g,!0,m)}),i}function d3(a){let i=a.split("/");if(i.length===0)return[];let[c,...r]=i,d=c.endsWith("?"),f=c.replace(/\?$/,"");if(r.length===0)return d?[f,""]:[f];let p=d3(r.join("/")),g=[];return g.push(...p.map(h=>h===""?f:[f,h].join("/"))),d&&g.push(...p),g.map(h=>a.startsWith("/")&&h===""?"/":h)}function gy(a){a.sort((i,c)=>i.score!==c.score?c.score-i.score:wy(i.routesMeta.map(r=>r.childrenIndex),c.routesMeta.map(r=>r.childrenIndex)))}var vy=/^:[\w-]+$/,yy=3,xy=2,by=1,jy=10,Sy=-2,Im=a=>a==="*";function Ny(a,i){let c=a.split("/"),r=c.length;return c.some(Im)&&(r+=Sy),i&&(r+=xy),c.filter(d=>!Im(d)).reduce((d,f)=>d+(vy.test(f)?yy:f===""?by:jy),r)}function wy(a,i){return a.length===i.length&&a.slice(0,-1).every((r,d)=>r===i[d])?a[a.length-1]-i[i.length-1]:0}function Cy(a,i,c=!1){let{routesMeta:r}=a,d={},f="/",p=[];for(let g=0;g{if(v==="*"){let S=g[b]||"";p=f.slice(0,f.length-S.length).replace(/(.)\/+$/,"$1")}const N=g[b];return y&&!N?m[v]=void 0:m[v]=(N||"").replace(/%2F/g,"/"),m},{}),pathname:f,pathnameBase:p,pattern:a}}function Ey(a,i=!1,c=!0){el(a==="*"||!a.endsWith("*")||a.endsWith("/*"),`Route path "${a}" will be treated as if it were "${a.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${a.replace(/\*$/,"/*")}".`);let r=[],d="^"+a.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(p,g,h,m,v)=>{if(r.push({paramName:g,isOptional:h!=null}),h){let y=v.charAt(m+p.length);return y&&y!=="/"?"/([^\\/]*)":"(?:/([^\\/]*))?"}return"/([^\\/]+)"}).replace(/\/([\w-]+)\?(\/|$)/g,"(/$1)?$2");return a.endsWith("*")?(r.push({paramName:"*"}),d+=a==="*"||a==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):c?d+="\\/*$":a!==""&&a!=="/"&&(d+="(?:(?=\\/|$))"),[new RegExp(d,i?void 0:"i"),r]}function Ty(a){try{return a.split("/").map(i=>decodeURIComponent(i).replace(/\//g,"%2F")).join("/")}catch(i){return el(!1,`The URL path "${a}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${i}).`),a}}function Vl(a,i){if(i==="/")return a;if(!a.toLowerCase().startsWith(i.toLowerCase()))return null;let c=i.endsWith("/")?i.length-1:i.length,r=a.charAt(c);return r&&r!=="/"?null:a.slice(c)||"/"}var Ry=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;function Ay(a,i="/"){let{pathname:c,search:r="",hash:d=""}=typeof a=="string"?Ri(a):a,f;return c?(c=f3(c),c.startsWith("/")?f=Pm(c.substring(1),"/"):f=Pm(c,i)):f=i,{pathname:f,search:Ly(r),hash:zy(d)}}function Pm(a,i){let c=Do(i).split("/");return a.split("/").forEach(d=>{d===".."?c.length>1&&c.pop():d!=="."&&c.push(d)}),c.length>1?c.join("/"):"/"}function yd(a,i,c,r){return`Cannot include a '${a}' character in a manually specified \`to.${i}\` field [${JSON.stringify(r)}]. Please separate it out to the \`to.${c}\` field. Alternatively you may provide the full path as a string in and the router will parse it for you.`}function Oy(a){return a.filter((i,c)=>c===0||i.route.path&&i.route.path.length>0)}function h2(a){let i=Oy(a);return i.map((c,r)=>r===i.length-1?c.pathname:c.pathnameBase)}function Go(a,i,c,r=!1){let d;typeof a=="string"?d=Ri(a):(d={...a},ct(!d.pathname||!d.pathname.includes("?"),yd("?","pathname","search",d)),ct(!d.pathname||!d.pathname.includes("#"),yd("#","pathname","hash",d)),ct(!d.search||!d.search.includes("#"),yd("#","search","hash",d)));let f=a===""||d.pathname==="",p=f?"/":d.pathname,g;if(p==null)g=c;else{let y=i.length-1;if(!r&&p.startsWith("..")){let b=p.split("/");for(;b[0]==="..";)b.shift(),y-=1;d.pathname=b.join("/")}g=y>=0?i[y]:"/"}let h=Ay(d,g),m=p&&p!=="/"&&p.endsWith("/"),v=(f||p===".")&&c.endsWith("/");return!h.pathname.endsWith("/")&&(m||v)&&(h.pathname+="/"),h}var f3=a=>a.replace(/\/\/+/g,"/"),Jn=a=>f3(a.join("/")),Do=a=>a.replace(/\/+$/,""),My=a=>Do(a).replace(/^\/*/,"/"),Ly=a=>!a||a==="?"?"":a.startsWith("?")?a:"?"+a,zy=a=>!a||a==="#"?"":a.startsWith("#")?a:"#"+a,Dy=class{constructor(a,i,c,r=!1){this.status=a,this.statusText=i||"",this.internal=r,c instanceof Error?(this.data=c.toString(),this.error=c):this.data=c}};function ky(a){return a!=null&&typeof a.status=="number"&&typeof a.statusText=="string"&&typeof a.internal=="boolean"&&"data"in a}function By(a){let i=a.map(c=>c.route.path).filter(Boolean);return Jn(i)||"/"}var h3=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function m3(a,i){let c=a;if(typeof c!="string"||!Ry.test(c))return{absoluteURL:void 0,isExternal:!1,to:c};let r=c,d=!1;if(h3)try{let f=new URL(window.location.href),p=c.startsWith("//")?new URL(f.protocol+c):new URL(c),g=Vl(p.pathname,i);p.origin===f.origin&&g!=null?c=g+p.search+p.hash:d=!0}catch{el(!1,` contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:r,isExternal:d,to:c}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var p3=["POST","PUT","PATCH","DELETE"];new Set(p3);var Uy=["GET",...p3];new Set(Uy);var Ai=j.createContext(null);Ai.displayName="DataRouter";var Vo=j.createContext(null);Vo.displayName="DataRouterState";var _3=j.createContext(!1);function $y(){return j.useContext(_3)}var g3=j.createContext({isTransitioning:!1});g3.displayName="ViewTransition";var Hy=j.createContext(new Map);Hy.displayName="Fetchers";var qy=j.createContext(null);qy.displayName="Await";var On=j.createContext(null);On.displayName="Navigation";var Jc=j.createContext(null);Jc.displayName="Location";var In=j.createContext({outlet:null,matches:[],isDataRoute:!1});In.displayName="Route";var m2=j.createContext(null);m2.displayName="RouteError";var v3="REACT_ROUTER_ERROR",Fy="REDIRECT",Gy="ROUTE_ERROR_RESPONSE";function Vy(a){if(a.startsWith(`${v3}:${Fy}:{`))try{let i=JSON.parse(a.slice(28));if(typeof i=="object"&&i&&typeof i.status=="number"&&typeof i.statusText=="string"&&typeof i.location=="string"&&typeof i.reloadDocument=="boolean"&&typeof i.replace=="boolean")return i}catch{}}function Qy(a){if(a.startsWith(`${v3}:${Gy}:{`))try{let i=JSON.parse(a.slice(40));if(typeof i=="object"&&i&&typeof i.status=="number"&&typeof i.statusText=="string")return new Dy(i.status,i.statusText,i.data)}catch{}}function Yy(a,{relative:i}={}){ct(Oi(),"useHref() may be used only in the context of a component.");let{basename:c,navigator:r}=j.useContext(On),{hash:d,pathname:f,search:p}=er(a,{relative:i}),g=f;return c!=="/"&&(g=f==="/"?c:Jn([c,f])),r.createHref({pathname:g,search:p,hash:d})}function Oi(){return j.useContext(Jc)!=null}function Mn(){return ct(Oi(),"useLocation() may be used only in the context of a component."),j.useContext(Jc).location}var y3="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function x3(a){j.useContext(On).static||j.useLayoutEffect(a)}function Ln(){let{isDataRoute:a}=j.useContext(In);return a?rx():Iy()}function Iy(){ct(Oi(),"useNavigate() may be used only in the context of a component.");let a=j.useContext(Ai),{basename:i,navigator:c}=j.useContext(On),{matches:r}=j.useContext(In),{pathname:d}=Mn(),f=JSON.stringify(h2(r)),p=j.useRef(!1);return x3(()=>{p.current=!0}),j.useCallback((h,m={})=>{if(el(p.current,y3),!p.current)return;if(typeof h=="number"){c.go(h);return}let v=Go(h,JSON.parse(f),d,m.relative==="path");a==null&&i!=="/"&&(v.pathname=v.pathname==="/"?i:Jn([i,v.pathname])),(m.replace?c.replace:c.push)(v,m.state,m)},[i,c,f,d,a])}var Py=j.createContext(null);function Xy(a){let i=j.useContext(In).outlet;return j.useMemo(()=>i&&j.createElement(Py.Provider,{value:a},i),[i,a])}function Zy(){let{matches:a}=j.useContext(In),i=a[a.length-1];return(i==null?void 0:i.params)??{}}function er(a,{relative:i}={}){let{matches:c}=j.useContext(In),{pathname:r}=Mn(),d=JSON.stringify(h2(c));return j.useMemo(()=>Go(a,JSON.parse(d),r,i==="path"),[a,d,r,i])}function Ky(a,i){return b3(a,i)}function b3(a,i,c){var w;ct(Oi(),"useRoutes() may be used only in the context of a component.");let{navigator:r}=j.useContext(On),{matches:d}=j.useContext(In),f=d[d.length-1],p=f?f.params:{},g=f?f.pathname:"/",h=f?f.pathnameBase:"/",m=f&&f.route;{let O=m&&m.path||"";S3(g,!m||O.endsWith("*")||O.endsWith("*?"),`You rendered descendant (or called \`useRoutes()\`) at "${g}" (under ) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render. + +Please change the parent to .`)}let v=Mn(),y;if(i){let O=typeof i=="string"?Ri(i):i;ct(h==="/"||((w=O.pathname)==null?void 0:w.startsWith(h)),`When overriding the location using \`\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${h}" but pathname "${O.pathname}" was given in the \`location\` prop.`),y=O}else y=v;let b=y.pathname||"/",N=b;if(h!=="/"){let O=h.replace(/^\//,"").split("/");N="/"+b.replace(/^\//,"").split("/").slice(O.length).join("/")}let S=o3(a,{pathname:N});el(m||S!=null,`No routes matched location "${y.pathname}${y.search}${y.hash}" `),el(S==null||S[S.length-1].route.element!==void 0||S[S.length-1].route.Component!==void 0||S[S.length-1].route.lazy!==void 0,`Matched leaf route at location "${y.pathname}${y.search}${y.hash}" does not have an element or Component. This means it will render an with a null value by default resulting in an "empty" page.`);let C=nx(S&&S.map(O=>Object.assign({},O,{params:Object.assign({},p,O.params),pathname:Jn([h,r.encodeLocation?r.encodeLocation(O.pathname.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:O.pathname]),pathnameBase:O.pathnameBase==="/"?h:Jn([h,r.encodeLocation?r.encodeLocation(O.pathnameBase.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:O.pathnameBase])})),d,c);return i&&C?j.createElement(Jc.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",unstable_mask:void 0,...y},navigationType:"POP"}},C):C}function Wy(){let a=cx(),i=ky(a)?`${a.status} ${a.statusText}`:a instanceof Error?a.message:JSON.stringify(a),c=a instanceof Error?a.stack:null,r="rgba(200,200,200, 0.5)",d={padding:"0.5rem",backgroundColor:r},f={padding:"2px 4px",backgroundColor:r},p=null;return console.error("Error handled by React Router default ErrorBoundary:",a),p=j.createElement(j.Fragment,null,j.createElement("p",null,"💿 Hey developer 👋"),j.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",j.createElement("code",{style:f},"ErrorBoundary")," or"," ",j.createElement("code",{style:f},"errorElement")," prop on your route.")),j.createElement(j.Fragment,null,j.createElement("h2",null,"Unexpected Application Error!"),j.createElement("h3",{style:{fontStyle:"italic"}},i),c?j.createElement("pre",{style:d},c):null,p)}var Jy=j.createElement(Wy,null),j3=class extends j.Component{constructor(a){super(a),this.state={location:a.location,revalidation:a.revalidation,error:a.error}}static getDerivedStateFromError(a){return{error:a}}static getDerivedStateFromProps(a,i){return i.location!==a.location||i.revalidation!=="idle"&&a.revalidation==="idle"?{error:a.error,location:a.location,revalidation:a.revalidation}:{error:a.error!==void 0?a.error:i.error,location:i.location,revalidation:a.revalidation||i.revalidation}}componentDidCatch(a,i){this.props.onError?this.props.onError(a,i):console.error("React Router caught the following error during render",a)}render(){let a=this.state.error;if(this.context&&typeof a=="object"&&a&&"digest"in a&&typeof a.digest=="string"){const c=Qy(a.digest);c&&(a=c)}let i=a!==void 0?j.createElement(In.Provider,{value:this.props.routeContext},j.createElement(m2.Provider,{value:a,children:this.props.component})):this.props.children;return this.context?j.createElement(ex,{error:a},i):i}};j3.contextType=_3;var xd=new WeakMap;function ex({children:a,error:i}){let{basename:c}=j.useContext(On);if(typeof i=="object"&&i&&"digest"in i&&typeof i.digest=="string"){let r=Vy(i.digest);if(r){let d=xd.get(i);if(d)throw d;let f=m3(r.location,c);if(h3&&!xd.get(i))if(f.isExternal||r.reloadDocument)window.location.href=f.absoluteURL||f.to;else{const p=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(f.to,{replace:r.replace}));throw xd.set(i,p),p}return j.createElement("meta",{httpEquiv:"refresh",content:`0;url=${f.absoluteURL||f.to}`})}}return a}function tx({routeContext:a,match:i,children:c}){let r=j.useContext(Ai);return r&&r.static&&r.staticContext&&(i.route.errorElement||i.route.ErrorBoundary)&&(r.staticContext._deepestRenderedBoundaryId=i.route.id),j.createElement(In.Provider,{value:a},c)}function nx(a,i=[],c){let r=c==null?void 0:c.state;if(a==null){if(!r)return null;if(r.errors)a=r.matches;else if(i.length===0&&!r.initialized&&r.matches.length>0)a=r.matches;else return null}let d=a,f=r==null?void 0:r.errors;if(f!=null){let v=d.findIndex(y=>y.route.id&&(f==null?void 0:f[y.route.id])!==void 0);ct(v>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(f).join(",")}`),d=d.slice(0,Math.min(d.length,v+1))}let p=!1,g=-1;if(c&&r){p=r.renderFallback;for(let v=0;v=0?d=d.slice(0,g+1):d=[d[0]];break}}}}let h=c==null?void 0:c.onError,m=r&&h?(v,y)=>{var b,N;h(v,{location:r.location,params:((N=(b=r.matches)==null?void 0:b[0])==null?void 0:N.params)??{},unstable_pattern:By(r.matches),errorInfo:y})}:void 0;return d.reduceRight((v,y,b)=>{let N,S=!1,C=null,w=null;r&&(N=f&&y.route.id?f[y.route.id]:void 0,C=y.route.errorElement||Jy,p&&(g<0&&b===0?(S3("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),S=!0,w=null):g===b&&(S=!0,w=y.route.hydrateFallbackElement||null)));let O=i.concat(d.slice(0,b+1)),H=()=>{let L;return N?L=C:S?L=w:y.route.Component?L=j.createElement(y.route.Component,null):y.route.element?L=y.route.element:L=v,j.createElement(tx,{match:y,routeContext:{outlet:v,matches:O,isDataRoute:r!=null},children:L})};return r&&(y.route.ErrorBoundary||y.route.errorElement||b===0)?j.createElement(j3,{location:r.location,revalidation:r.revalidation,component:C,error:N,children:H(),routeContext:{outlet:null,matches:O,isDataRoute:!0},onError:m}):H()},null)}function p2(a){return`${a} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function lx(a){let i=j.useContext(Ai);return ct(i,p2(a)),i}function ax(a){let i=j.useContext(Vo);return ct(i,p2(a)),i}function sx(a){let i=j.useContext(In);return ct(i,p2(a)),i}function _2(a){let i=sx(a),c=i.matches[i.matches.length-1];return ct(c.route.id,`${a} can only be used on routes that contain a unique "id"`),c.route.id}function ix(){return _2("useRouteId")}function cx(){var r;let a=j.useContext(m2),i=ax("useRouteError"),c=_2("useRouteError");return a!==void 0?a:(r=i.errors)==null?void 0:r[c]}function rx(){let{router:a}=lx("useNavigate"),i=_2("useNavigate"),c=j.useRef(!1);return x3(()=>{c.current=!0}),j.useCallback(async(d,f={})=>{el(c.current,y3),c.current&&(typeof d=="number"?await a.navigate(d):await a.navigate(d,{fromRouteId:i,...f}))},[a,i])}var Xm={};function S3(a,i,c){!i&&!Xm[a]&&(Xm[a]=!0,el(!1,c))}j.memo(ox);function ox({routes:a,future:i,state:c,isStatic:r,onError:d}){return b3(a,void 0,{state:c,isStatic:r,onError:d})}function Qo({to:a,replace:i,state:c,relative:r}){ct(Oi()," may be used only in the context of a component.");let{static:d}=j.useContext(On);el(!d," must not be used on the initial render in a . This is a no-op, but you should modify your code so the is only ever rendered in response to some user interaction or state change.");let{matches:f}=j.useContext(In),{pathname:p}=Mn(),g=Ln(),h=Go(a,h2(f),p,r==="path"),m=JSON.stringify(h);return j.useEffect(()=>{g(JSON.parse(m),{replace:i,state:c,relative:r})},[g,m,r,i,c]),null}function g2(a){return Xy(a.context)}function et(a){ct(!1,"A is only ever to be used as the child of element, never rendered directly. Please wrap your in a .")}function ux({basename:a="/",children:i=null,location:c,navigationType:r="POP",navigator:d,static:f=!1,unstable_useTransitions:p}){ct(!Oi(),"You cannot render a inside another . You should never have more than one in your app.");let g=a.replace(/^\/*/,"/"),h=j.useMemo(()=>({basename:g,navigator:d,static:f,unstable_useTransitions:p,future:{}}),[g,d,f,p]);typeof c=="string"&&(c=Ri(c));let{pathname:m="/",search:v="",hash:y="",state:b=null,key:N="default",unstable_mask:S}=c,C=j.useMemo(()=>{let w=Vl(m,g);return w==null?null:{location:{pathname:w,search:v,hash:y,state:b,key:N,unstable_mask:S},navigationType:r}},[g,m,v,y,b,N,r,S]);return el(C!=null,` is not able to match the URL "${m}${v}${y}" because it does not start with the basename, so the won't render anything.`),C==null?null:j.createElement(On.Provider,{value:h},j.createElement(Jc.Provider,{children:i,value:C}))}function dx({children:a,location:i}){return Ky(Hd(a),i)}function Hd(a,i=[]){let c=[];return j.Children.forEach(a,(r,d)=>{if(!j.isValidElement(r))return;let f=[...i,d];if(r.type===j.Fragment){c.push.apply(c,Hd(r.props.children,f));return}ct(r.type===et,`[${typeof r.type=="string"?r.type:r.type.name}] is not a component. All component children of must be a or `),ct(!r.props.index||!r.props.children,"An index route cannot have child routes.");let p={id:r.props.id||f.join("-"),caseSensitive:r.props.caseSensitive,element:r.props.element,Component:r.props.Component,index:r.props.index,path:r.props.path,middleware:r.props.middleware,loader:r.props.loader,action:r.props.action,hydrateFallbackElement:r.props.hydrateFallbackElement,HydrateFallback:r.props.HydrateFallback,errorElement:r.props.errorElement,ErrorBoundary:r.props.ErrorBoundary,hasErrorBoundary:r.props.hasErrorBoundary===!0||r.props.ErrorBoundary!=null||r.props.errorElement!=null,shouldRevalidate:r.props.shouldRevalidate,handle:r.props.handle,lazy:r.props.lazy};r.props.children&&(p.children=Hd(r.props.children,f)),c.push(p)}),c}var Oo="get",Mo="application/x-www-form-urlencoded";function Yo(a){return typeof HTMLElement<"u"&&a instanceof HTMLElement}function fx(a){return Yo(a)&&a.tagName.toLowerCase()==="button"}function hx(a){return Yo(a)&&a.tagName.toLowerCase()==="form"}function mx(a){return Yo(a)&&a.tagName.toLowerCase()==="input"}function px(a){return!!(a.metaKey||a.altKey||a.ctrlKey||a.shiftKey)}function _x(a,i){return a.button===0&&(!i||i==="_self")&&!px(a)}var So=null;function gx(){if(So===null)try{new FormData(document.createElement("form"),0),So=!1}catch{So=!0}return So}var vx=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function bd(a){return a!=null&&!vx.has(a)?(el(!1,`"${a}" is not a valid \`encType\` for \`
\`/\`\` and will default to "${Mo}"`),null):a}function yx(a,i){let c,r,d,f,p;if(hx(a)){let g=a.getAttribute("action");r=g?Vl(g,i):null,c=a.getAttribute("method")||Oo,d=bd(a.getAttribute("enctype"))||Mo,f=new FormData(a)}else if(fx(a)||mx(a)&&(a.type==="submit"||a.type==="image")){let g=a.form;if(g==null)throw new Error('Cannot submit a + ))} + + ) +} diff --git a/src/widgets/staking/ui/PositionsPanel.module.css b/src/widgets/staking/ui/PositionsPanel.module.css new file mode 100644 index 0000000..c0c9beb --- /dev/null +++ b/src/widgets/staking/ui/PositionsPanel.module.css @@ -0,0 +1,168 @@ +.panel { + background: var(--glass-bg); + border: 1px solid var(--glass-border); + border-radius: 20px; + padding: 24px; + display: flex; + flex-direction: column; + gap: 14px; +} + +.head { + display: flex; + flex-direction: column; + gap: 4px; +} + +.title { + font-size: 12px; + color: var(--text-secondary); + text-transform: uppercase; + letter-spacing: 1.2px; + font-weight: 700; +} + +.total { + font-family: var(--font-mono); + font-size: 24px; + color: var(--text-primary); +} + +.totalUnit { + font-size: 14px; + color: var(--text-secondary); +} + +.subhead { + font-size: 11px; + color: var(--text-secondary); + text-transform: uppercase; + letter-spacing: 1px; + font-weight: 700; + margin-top: 4px; +} + +.list { + display: flex; + flex-direction: column; + gap: 10px; +} + +.pos { + background: var(--bg-deep); + border: 1px solid var(--glass-border); + border-radius: 14px; + padding: 14px; +} + +.reqCard { + border-color: rgba(0, 212, 255, 0.25); +} + +.posTop { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; + margin-bottom: 10px; +} + +.coin { + display: flex; + align-items: center; + gap: 8px; + font-weight: 700; + font-size: 14px; + color: var(--text-primary); +} + +.amount { + font-family: var(--font-mono); + font-size: 18px; + color: var(--text-primary); + margin-bottom: 4px; +} + +.meta { + font-size: 12px; + color: var(--text-secondary); + margin-bottom: 12px; + word-break: break-all; +} + +.badge { + font-size: 11px; + font-weight: 700; + padding: 3px 10px; + border-radius: 999px; + white-space: nowrap; +} + +.badgeActive { + color: var(--success); + background: rgba(38, 161, 123, 0.14); +} + +.badgeReady { + color: var(--highlight); + background: rgba(0, 212, 255, 0.14); +} + +.badgeMuted { + color: var(--text-secondary); + background: rgba(255, 255, 255, 0.08); +} + +.btn { + width: 100%; + height: 40px; + border: 1px solid rgba(255, 255, 255, 0.14); + border-radius: 10px; + background: transparent; + color: var(--text-primary); + font-weight: 600; + font-size: 13px; + font-family: var(--font-sans); + cursor: pointer; + transition: background 0.2s; +} + +.btn:hover { + background: rgba(255, 255, 255, 0.06); +} + +.btn:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +.btnPrimary { + border: none; + background: var(--success); + color: #fff; + font-weight: 700; +} + +.btnPrimary:hover { + background: var(--success); + filter: brightness(1.12); +} + +.note { + font-size: 12px; + color: var(--text-secondary); + text-align: center; + padding: 8px 0 2px; +} + +.empty { + font-size: 13px; + color: var(--text-secondary); + text-align: center; + padding: 24px 0; +} + +.amount + .btn, +.meta + .btn { + margin-top: 2px; +} diff --git a/src/widgets/staking/ui/PositionsPanel.tsx b/src/widgets/staking/ui/PositionsPanel.tsx new file mode 100644 index 0000000..013135d --- /dev/null +++ b/src/widgets/staking/ui/PositionsPanel.tsx @@ -0,0 +1,164 @@ +import { Spinner, TokenIcon } from '@shared/ui' +import { COIN_ICONS } from '@shared/assets/coins' +import { truncateDecimals } from '@shared/lib/utils/truncateDecimals' +import { WithdrawNotice } from './WithdrawNotice' +import { useStakePositions, getStakingErrorMessage, type StakeChain, type SolPosition } from '@features/staking' +import { SOL_STATE_META } from '../model/meta' +import styles from './PositionsPanel.module.css' + +interface Props { + chain: StakeChain + onUnstakeEth: (amountHuman: string) => void + onUnstakeSol: (position: SolPosition) => void + onClaim: (requestId: string) => void + unstakePending: boolean + claimPending: boolean +} + +export function PositionsPanel({ chain, onUnstakeEth, onUnstakeSol, onClaim, unstakePending, claimPending }: Props) { + const { data, isLoading, isError, error } = useStakePositions(chain) + + const badgeClass: Record<'active' | 'ready' | 'muted', string> = { + active: styles.badgeActive, + ready: styles.badgeReady, + muted: styles.badgeMuted, + } + + const total = + data?.chain === 'ETH' + ? data.stEthBalanceWeiHuman + : data?.chain === 'SOL' + ? data.positions.reduce((sum, p) => sum + (parseFloat(p.lamportsHuman) || 0), 0).toString() + : '0' + const unit = chain === 'ETH' ? 'stETH' : 'SOL' + + const ethEmpty = + data?.chain === 'ETH' && (parseFloat(data.stEthBalanceWeiHuman) || 0) === 0 && data.withdrawalRequests.length === 0 + const solEmpty = data?.chain === 'SOL' && data.positions.length === 0 + const empty = ethEmpty || solEmpty + + return ( +
+
+ Мои позиции +
+ {truncateDecimals(total, 6)} {unit} +
+
+ + + + {isLoading && } + + {isError &&
{getStakingErrorMessage(error)}
} + + {!isLoading && !isError && empty && ( +
У вас пока нет активных позиций стейкинга.
+ )} + + {data?.chain === 'ETH' && !empty && ( + <> + {(parseFloat(data.stEthBalanceWeiHuman) || 0) > 0 && ( +
+
+
+ + + stETH + + + Активна{data.aprPercent != null ? ` · APR ${data.aprPercent}%` : ''} + +
+
{truncateDecimals(data.stEthBalanceWeiHuman, 8)}
+ +
+
+ )} + + {data.withdrawalRequests.length > 0 && ( + <> +
Заявки на вывод
+
+ {data.withdrawalRequests.map((r) => { + const ready = r.isFinalized && !r.isClaimed + return ( +
+
+ Заявка #{r.requestId} + + {r.isClaimed ? 'Выведено' : ready ? 'Готово к выводу' : 'В очереди'} + +
+
{truncateDecimals(r.amountStEthWeiHuman, 8)} ETH
+ {ready ? ( + + ) : r.isClaimed ? null : ( +
Ожидает финализации в Lido
+ )} +
+ ) + })} +
+ + )} + + )} + + {data?.chain === 'SOL' && !empty && ( +
+ {data.positions.map((p) => { + const st = SOL_STATE_META[p.state] + return ( +
+
+ + + SOL + + {st.label} +
+
{truncateDecimals(p.lamportsHuman, 8)}
+
+ Валидатор: {p.validator} · {p.stakeAccount} +
+ {p.state === 'active' && ( + + )} + {p.state === 'inactive' && ( + + )} + {p.state === 'deactivating' &&
Разблокируется через 1–2 эпохи
} + {p.state === 'activating' &&
Активируется…
} +
+ ) + })} +
+ )} +
+ ) +} diff --git a/src/widgets/staking/ui/StakeCard.module.css b/src/widgets/staking/ui/StakeCard.module.css new file mode 100644 index 0000000..1b00aca --- /dev/null +++ b/src/widgets/staking/ui/StakeCard.module.css @@ -0,0 +1,171 @@ +.wrapper { + display: flex; + flex-direction: column; + gap: 1rem; +} + +.pillsOuter { + display: none; + gap: 6px; +} + +.card { + background: var(--glass-bg); + border: 1px solid var(--glass-border); + border-radius: 20px; + padding: 24px; +} + +.top { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + margin-bottom: 18px; +} + +.tag { + font-size: 12px; + color: var(--text-secondary); + text-transform: uppercase; + letter-spacing: 1.2px; + font-weight: 700; +} + +.right { + display: flex; + align-items: center; + gap: 12px; +} + +.apr { + font-size: 12px; + color: var(--success); + background: rgba(38, 161, 123, 0.12); + border: 1px solid rgba(38, 161, 123, 0.35); + border-radius: 999px; + padding: 4px 12px; + font-weight: 700; + white-space: nowrap; +} + +.pillsInner { + display: flex; + gap: 6px; +} + +.pill { + background: rgba(255, 255, 255, 0.07); + color: var(--text-secondary); + border: none; + border-radius: 999px; + padding: 5px 14px; + font-size: 12px; + cursor: pointer; + font-family: var(--font-sans); + font-weight: 600; + transition: all 0.2s; +} + +.pill:hover { + color: var(--text-primary); + background: rgba(255, 255, 255, 0.13); +} + +.mid { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + margin-bottom: 10px; +} + +.input { + background: none; + border: none; + outline: none; + font-family: var(--font-mono); + font-size: 40px; + font-weight: 700; + color: var(--text-primary); + width: 100%; + min-width: 0; +} + +.input::placeholder { + color: rgba(255, 255, 255, 0.15); +} + +.token { + display: flex; + align-items: center; + gap: 8px; + flex-shrink: 0; + font-weight: 700; + font-size: 16px; + color: var(--text-primary); +} + +.bottom { + display: flex; + align-items: center; + justify-content: flex-end; + margin-bottom: 20px; +} + +.balance { + font-size: 13px; + color: var(--text-secondary); + display: flex; + align-items: center; + gap: 8px; +} + +.max { + background: none; + border: none; + color: var(--interactive); + cursor: pointer; + font-weight: 700; + font-size: 13px; + font-family: var(--font-sans); + padding: 0; +} + +.max:hover { + text-decoration: underline; +} + +.hint { + margin: 14px 0 0; + font-size: 13px; + color: var(--error); + font-weight: 600; + line-height: 1.4; +} + +.stakeBtn { + margin-top: 18px; +} + +.stakeBtnDisabled { + opacity: 0.45; +} + +@media (max-width: 650px) { + .card { + padding: 16px; + } + + .input { + font-size: 32px; + } + + .pillsOuter { + display: flex; + } + + .pillsInner { + display: none; + } +} diff --git a/src/widgets/staking/ui/StakeCard.tsx b/src/widgets/staking/ui/StakeCard.tsx new file mode 100644 index 0000000..51ec3d1 --- /dev/null +++ b/src/widgets/staking/ui/StakeCard.tsx @@ -0,0 +1,162 @@ +import { PrimaryButton, TokenIcon } from '@shared/ui' +import { COIN_ICONS } from '@shared/assets/coins' +import { truncateDecimals } from '@shared/lib/utils/truncateDecimals' +import { useDebounce } from '@shared/lib/hooks/useDebounce' +import { useWalletBalance } from '@features/wallet' +import { useStakeQuote, useOpCost, type StakeChain, type StakeQuote, type OpCost } from '@features/staking' +import { StakeQuotePanel, type QuoteRow } from './StakeQuotePanel' +import { CHAIN_META } from '../model/meta' +import styles from './StakeCard.module.css' + +interface Props { + chain: StakeChain + amount: string + onAmountChange: (value: string) => void + onStake: () => void + isStaking: boolean +} + +const PERCENTS = [25, 50, 100] + +type Meta = (typeof CHAIN_META)[StakeChain] + +const DASH = '—' + +function usd(value: number): string { + return `≈ $${value.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}` +} + +function buildRows( + meta: Meta, + quote: StakeQuote | undefined, + opCost: OpCost | undefined, + amountNum: number, + nativeUsdPrice: number +): QuoteRow[] { + const resultLabel = meta.symbol === 'ETH' ? 'Получите stETH' : 'Делегируется валидатору' + const aprLabel = `Годовая доходность (${meta.aprLabel})` + + const fee = quote ? `${truncateDecimals(quote.feeHuman, 8)} ${meta.symbol}` : DASH + const afterFee = quote ? `${truncateDecimals(quote.afterFeeHuman, 8)} ${meta.symbol}` : DASH + const result = quote + ? meta.symbol === 'ETH' + ? `≈ ${truncateDecimals(quote.resultHuman, 8)}` + : `${truncateDecimals(quote.resultHuman, 8)} SOL` + : DASH + const apr = quote?.aprPercent != null ? `${quote.aprPercent}%` : DASH + + // Сетевой сбор (газ) и итог к списанию в USD — из op-cost. + const gasRaw = opCost?.balance?.gas?.needReserve + const gasNum = gasRaw != null ? parseFloat(String(gasRaw)) || 0 : 0 + const gas = gasRaw != null ? `≈ ${truncateDecimals(String(gasRaw), 8)} ${meta.symbol}` : DASH + // Из кошелька списывается сумма (комиссия 0.7% внутри неё) + газ нативкой. + const totalUsd = opCost && nativeUsdPrice > 0 && amountNum > 0 ? usd((amountNum + gasNum) * nativeUsdPrice) : DASH + + return [ + { label: 'Комиссия сервиса (0.7%)', value: fee }, + { label: 'Сетевой сбор (газ)', value: gas }, + { label: 'Сумма после комиссии', value: afterFee }, + { label: resultLabel, value: result, accent: 'highlight' }, + { label: 'Итого к списанию', value: totalUsd }, + { label: aprLabel, value: apr, accent: 'success' }, + ] +} + +export function StakeCard({ chain, amount, onAmountChange, onStake, isStaking }: Props) { + const meta = CHAIN_META[chain] + const { data: balance } = useWalletBalance(chain) + const balanceHuman = balance?.native.formatted ?? '0' + const balanceNum = parseFloat(balanceHuman) || 0 + + const debounced = useDebounce(amount, 400) + const { data: quote, isFetching } = useStakeQuote(chain, debounced) + const { data: opCost, isError: opError } = useOpCost(chain, debounced) + + const amountNum = parseFloat(amount) || 0 + const withinBalance = amountNum > 0 && amountNum <= balanceNum + // Достаточность с учётом газа проверяет сервер (op-cost). Если эндпоинт недоступен — + // не блокируем жёстко, откатываемся к проверке «не больше баланса». + const sufficient = opError ? withinBalance : opCost?.sufficient === true + const insufficient = withinBalance && opCost?.sufficient === false + const gasShort = insufficient && opCost?.balance?.gas?.sufficient === false + const canStake = withinBalance && sufficient && !isStaking + + const setPercent = (p: number) => onAmountChange(((balanceNum * p) / 100).toString()) + + const pills = ( + <> + {PERCENTS.map((p) => ( + + ))} + + ) + + return ( +
+
{pills}
+ +
+
+ Сумма стейка +
+ + {meta.aprLabel} {quote?.aprPercent != null ? `${quote.aprPercent}%` : '—'} + +
{pills}
+
+
+ +
+ { + const v = e.target.value + if (/^(\d+\.?\d*|\.?\d*)$/.test(v) || v === '') onAmountChange(v) + }} + placeholder="0" + /> +
+ + {meta.symbol} +
+
+ +
+ + Баланс: {truncateDecimals(balanceHuman, 6)} {meta.symbol} + + +
+ + + + {insufficient && ( +

+ {gasShort + ? `Недостаточно ${meta.symbol} на сетевую комиссию (газ).` + : 'Недостаточно средств для стейкинга с учётом комиссии и газа.'} +

+ )} + +
+ +
+
+
+ ) +} diff --git a/src/widgets/staking/ui/StakeQuotePanel.module.css b/src/widgets/staking/ui/StakeQuotePanel.module.css new file mode 100644 index 0000000..3a28dd5 --- /dev/null +++ b/src/widgets/staking/ui/StakeQuotePanel.module.css @@ -0,0 +1,45 @@ +.panel { + background: var(--glass-bg); + border: 1px solid var(--glass-border); + border-radius: 16px; + padding: 4px 18px; + transition: opacity 0.2s; +} + +.panel[data-loading='true'] { + opacity: 0.5; +} + +.row { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + padding: 13px 0; + border-bottom: 1px solid rgba(255, 255, 255, 0.06); +} + +.row:last-child { + border-bottom: none; +} + +.label { + font-size: 13px; + color: var(--text-secondary); +} + +.value { + font-size: 14px; + color: var(--text-primary); + font-weight: 600; + font-family: var(--font-mono); + text-align: right; +} + +.success { + color: var(--success); +} + +.highlight { + color: var(--highlight); +} diff --git a/src/widgets/staking/ui/StakeQuotePanel.tsx b/src/widgets/staking/ui/StakeQuotePanel.tsx new file mode 100644 index 0000000..12be407 --- /dev/null +++ b/src/widgets/staking/ui/StakeQuotePanel.tsx @@ -0,0 +1,25 @@ +import styles from './StakeQuotePanel.module.css' + +export interface QuoteRow { + label: string + value: string + accent?: 'success' | 'highlight' +} + +interface Props { + rows: QuoteRow[] + loading?: boolean +} + +export function StakeQuotePanel({ rows, loading }: Props) { + return ( +
+ {rows.map(({ label, value, accent }) => ( +
+ {label} + {value} +
+ ))} +
+ ) +} diff --git a/src/widgets/staking/ui/StakingWidget.module.css b/src/widgets/staking/ui/StakingWidget.module.css new file mode 100644 index 0000000..18b064b --- /dev/null +++ b/src/widgets/staking/ui/StakingWidget.module.css @@ -0,0 +1,18 @@ +.widget { + display: flex; + flex-direction: column; + gap: 20px; +} + +.grid { + display: grid; + grid-template-columns: 1.2fr 1fr; + gap: 16px; + align-items: start; +} + +@media (max-width: 1024px) { + .grid { + grid-template-columns: 1fr; + } +} diff --git a/src/widgets/staking/ui/StakingWidget.tsx b/src/widgets/staking/ui/StakingWidget.tsx new file mode 100644 index 0000000..80cc117 --- /dev/null +++ b/src/widgets/staking/ui/StakingWidget.tsx @@ -0,0 +1,139 @@ +import { useState } from 'react' +import { Notification } from '@shared/ui' +import { ChainToggle } from './ChainToggle' +import { StakeCard } from './StakeCard' +import { PositionsPanel } from './PositionsPanel' +import { UnstakeModal } from './UnstakeModal' +import { + useStake, + useUnstake, + useClaim, + getStakingErrorMessage, + type StakeChain, + type SolPosition, +} from '@features/staking' +import { CHAIN_META } from '../model/meta' +import styles from './StakingWidget.module.css' + +type ModalState = { kind: 'eth'; amount: string } | { kind: 'sol'; position: SolPosition } | null + +type Toast = { status: 'success' | 'error' | 'info'; message: string } | null + +export function StakingWidget() { + const [chain, setChain] = useState('ETH') + const [amount, setAmount] = useState('') + const [modal, setModal] = useState(null) + const [toast, setToast] = useState(null) + + const stakeM = useStake() + const unstakeM = useUnstake() + const claimM = useClaim() + + function handleChain(next: StakeChain) { + setChain(next) + setAmount('') + } + + function handleStake() { + stakeM.mutate( + { chain, amountHuman: amount }, + { + onSuccess: () => { + setToast({ status: 'success', message: `Стейкинг ${amount} ${CHAIN_META[chain].symbol} выполнен` }) + setAmount('') + }, + onError: (e) => setToast({ status: 'error', message: getStakingErrorMessage(e) }), + } + ) + } + + function handleConfirm(mode?: 'swap' | 'queue') { + if (modal?.kind === 'eth') { + const selected = mode ?? 'swap' + unstakeM.mutate( + { chain: 'ETH', amountHuman: modal.amount, mode: selected }, + { + onSuccess: () => { + setModal(null) + setToast({ + status: 'success', + message: + selected === 'queue' ? 'Заявка на вывод добавлена в очередь Lido' : 'Вывод stETH → ETH выполнен', + }) + }, + onError: (e) => setToast({ status: 'error', message: getStakingErrorMessage(e) }), + } + ) + } else if (modal?.kind === 'sol') { + unstakeM.mutate( + { chain: 'SOL', stakeAccount: modal.position.stakeAccount }, + { + onSuccess: (res) => { + setModal(null) + const withdrawn = 'action' in res && res.action === 'withdraw' + setToast({ + status: 'success', + message: withdrawn ? 'Средства выведены на кошелёк' : 'Деактивация запущена — вывод через 1–2 эпохи', + }) + }, + onError: (e) => setToast({ status: 'error', message: getStakingErrorMessage(e) }), + } + ) + } + } + + function handleClaim(requestId: string) { + claimM.mutate(requestId, { + onSuccess: () => setToast({ status: 'success', message: 'ETH забран на кошелёк' }), + onError: (e) => setToast({ status: 'error', message: getStakingErrorMessage(e) }), + }) + } + + return ( +
+ + +
+ + setModal({ kind: 'eth', amount: amountHuman })} + onUnstakeSol={(position) => setModal({ kind: 'sol', position })} + onClaim={handleClaim} + unstakePending={unstakeM.isPending} + claimPending={claimM.isPending} + /> +
+ + {modal?.kind === 'eth' && ( + setModal(null)} + /> + )} + {modal?.kind === 'sol' && ( + setModal(null)} + /> + )} + + {toast && setToast(null)} />} +
+ ) +} diff --git a/src/widgets/staking/ui/UnstakeModal.module.css b/src/widgets/staking/ui/UnstakeModal.module.css new file mode 100644 index 0000000..89322cc --- /dev/null +++ b/src/widgets/staking/ui/UnstakeModal.module.css @@ -0,0 +1,156 @@ +.overlay { + position: fixed; + inset: 0; + background: rgba(10, 11, 46, 0.75); + backdrop-filter: blur(4px); + display: flex; + align-items: center; + justify-content: center; + z-index: 100; + padding: 16px; +} + +.card { + background: var(--bg-mid); + border: 1px solid var(--glass-border); + border-radius: 24px; + padding: 28px; + width: 100%; + max-width: 420px; + display: flex; + flex-direction: column; + gap: 20px; +} + +.header { + display: flex; + align-items: center; + justify-content: space-between; +} + +.title { + font-size: 18px; + font-weight: 700; + color: var(--text-primary); +} + +.closeBtn { + background: none; + border: none; + color: var(--text-secondary); + font-size: 22px; + cursor: pointer; + line-height: 1; + padding: 0; + font-family: var(--font-sans); +} + +.closeBtn:hover { + color: var(--text-primary); +} + +.token { + background: var(--glass-bg); + border: 1px solid var(--glass-border); + border-radius: 14px; + padding: 16px 20px; + display: flex; + flex-direction: column; + gap: 4px; +} + +.tokenLabel { + font-size: 11px; + text-transform: uppercase; + letter-spacing: 1px; + color: var(--text-secondary); + font-weight: 700; +} + +.tokenAmount { + font-size: 24px; + font-weight: 700; + color: var(--text-primary); + font-family: var(--font-mono); +} + +.modes { + display: flex; + gap: 10px; +} + +.mode { + flex: 1; + display: flex; + flex-direction: column; + gap: 4px; + text-align: left; + background: var(--glass-bg); + border: 1px solid var(--glass-border); + border-radius: 12px; + padding: 12px; + cursor: pointer; + font-family: var(--font-sans); + transition: border-color 0.2s, background 0.2s; +} + +.mode:hover { + border-color: rgba(255, 255, 255, 0.25); +} + +.modeActive { + border-color: var(--interactive); + background: rgba(74, 109, 255, 0.1); +} + +.modeTitle { + font-size: 14px; + font-weight: 700; + color: var(--text-primary); +} + +.modeDesc { + font-size: 11px; + color: var(--text-secondary); + line-height: 1.3; +} + +.solNote { + margin: 0; + font-size: 13px; + color: var(--text-secondary); + line-height: 1.45; +} + +.confirmBtn { + width: 100%; + height: 56px; + background: linear-gradient(135deg, var(--grad-edge), var(--grad-center)); + border: none; + border-radius: 14px; + color: var(--text-primary); + font-size: 16px; + font-weight: 700; + cursor: pointer; + font-family: var(--font-sans); + letter-spacing: 0.3px; + transition: filter 0.25s, box-shadow 0.25s; +} + +.confirmBtn:hover { + filter: brightness(1.15); + box-shadow: 0 0 24px rgba(91, 61, 184, 0.5); +} + +.confirmBtn:disabled { + opacity: 0.6; + cursor: not-allowed; + filter: none; + box-shadow: none; +} + +@media (max-width: 480px) { + .modes { + flex-direction: column; + } +} diff --git a/src/widgets/staking/ui/UnstakeModal.tsx b/src/widgets/staking/ui/UnstakeModal.tsx new file mode 100644 index 0000000..0a852e1 --- /dev/null +++ b/src/widgets/staking/ui/UnstakeModal.tsx @@ -0,0 +1,96 @@ +import { useEffect, useState } from 'react' +import { WithdrawNotice } from './WithdrawNotice' +import type { StakeChain, SolState } from '@features/staking' +import styles from './UnstakeModal.module.css' + +interface Props { + chain: StakeChain + /** Тикер сети (ETH / SOL). */ + symbol: string + /** Сумма к выводу (human). */ + amount: string + /** Состояние SOL-позиции (для двухфазного вывода). */ + solState?: SolState + /** Идёт ли запрос вывода. */ + pending?: boolean + onConfirm: (mode?: 'swap' | 'queue') => void + onClose: () => void +} + +export function UnstakeModal({ chain, symbol, amount, solState, pending, onConfirm, onClose }: Props) { + const [mode, setMode] = useState<'swap' | 'queue'>('swap') + + useEffect(() => { + function onKey(e: KeyboardEvent) { + if (e.key === 'Escape') onClose() + } + document.addEventListener('keydown', onKey) + return () => document.removeEventListener('keydown', onKey) + }, [onClose]) + + const isSolWithdraw = chain === 'SOL' && solState === 'inactive' + const confirmLabel = pending + ? 'Отправка…' + : chain === 'ETH' + ? 'Подтвердить вывод' + : isSolWithdraw + ? 'Вывести средства' + : 'Запустить деактивацию' + + const showNotice = chain === 'SOL' || (chain === 'ETH' && mode === 'queue') + + return ( +
+
e.stopPropagation()}> +
+ Вывод из стейкинга + +
+ +
+ Сумма + + {amount} {chain === 'ETH' ? 'stETH' : symbol} + +
+ + {chain === 'ETH' && ( +
+ + +
+ )} + + {chain === 'SOL' && !isSolWithdraw && ( +

+ Средства разблокируются через 1–2 эпохи. После завершения вернитесь и подтвердите вывод. +

+ )} + + {showNotice && } + + +
+
+ ) +} diff --git a/src/widgets/staking/ui/WithdrawNotice.module.css b/src/widgets/staking/ui/WithdrawNotice.module.css new file mode 100644 index 0000000..322d705 --- /dev/null +++ b/src/widgets/staking/ui/WithdrawNotice.module.css @@ -0,0 +1,32 @@ +.notice { + display: flex; + align-items: flex-start; + gap: 10px; + background: rgba(0, 212, 255, 0.08); + border: 1px solid rgba(0, 212, 255, 0.3); + border-radius: 12px; + padding: 12px 14px; + font-size: 13px; + line-height: 1.4; + color: var(--text-secondary); +} + +.icon { + flex-shrink: 0; + width: 18px; + height: 18px; + border-radius: 50%; + background: var(--highlight); + color: var(--bg-deep); + font-weight: 800; + font-size: 12px; + display: flex; + align-items: center; + justify-content: center; + line-height: 1; +} + +.compact { + padding: 10px 12px; + font-size: 12px; +} diff --git a/src/widgets/staking/ui/WithdrawNotice.tsx b/src/widgets/staking/ui/WithdrawNotice.tsx new file mode 100644 index 0000000..2b1e63d --- /dev/null +++ b/src/widgets/staking/ui/WithdrawNotice.tsx @@ -0,0 +1,14 @@ +import styles from './WithdrawNotice.module.css' + +interface Props { + compact?: boolean +} + +export function WithdrawNotice({ compact }: Props) { + return ( +
+ + Вывод средств из стейкинга может занимать до 2 недель. +
+ ) +} diff --git a/src/widgets/wallet-header/ui/WalletHeader.tsx b/src/widgets/wallet-header/ui/WalletHeader.tsx index 0b88101..8fd59ad 100644 --- a/src/widgets/wallet-header/ui/WalletHeader.tsx +++ b/src/widgets/wallet-header/ui/WalletHeader.tsx @@ -92,6 +92,9 @@ export function WalletHeader() { setOpen(false)}> Кошелёк + setOpen(false)}> + Стейкинг + setOpen(false)}> Транзакции diff --git a/tsconfig.tsbuildinfo b/tsconfig.tsbuildinfo index 8227628..196f14a 100644 --- a/tsconfig.tsbuildinfo +++ b/tsconfig.tsbuildinfo @@ -1 +1 @@ -{"root":["./src/main.tsx","./src/vite-env.d.ts","./src/app/app.tsx","./src/app/providers/guestroute.tsx","./src/app/providers/protectedroute.tsx","./src/app/providers/queryprovider.tsx","./src/app/providers/routerprovider.tsx","./src/app/providers/scrolltotop.tsx","./src/app/providers/index.ts","./src/entities/commission/index.ts","./src/entities/commission/model/tiers.ts","./src/entities/commission/ui/commissiontable.tsx","./src/features/auth/index.ts","./src/features/auth/api/profileapi.ts","./src/features/auth/api/registrationapi.ts","./src/features/auth/hooks/useauth.ts","./src/features/auth/hooks/useisauthenticated.ts","./src/features/auth/hooks/useme.ts","./src/features/auth/hooks/useupdatephone.ts","./src/features/auth/hooks/useuploadavatar.ts","./src/features/b2b/index.ts","./src/features/b2b/api/b2bapi.ts","./src/features/b2b/hooks/usecreatepurchaserequest.ts","./src/features/b2b/hooks/usemypurchaserequests.ts","./src/features/kyc/api/kycapi.ts","./src/features/payment/index.ts","./src/features/payment/api/paymentapi.ts","./src/features/payment/hooks/usecreateorder.ts","./src/features/payment/hooks/useorders.ts","./src/features/payment/hooks/usepaymentconfig.ts","./src/features/payment/hooks/usepaymentquote.ts","./src/features/payment/hooks/usepaymentquotebyrub.ts","./src/features/payment/model/usecurrencyconversion.ts","./src/features/wallet/index.ts","./src/features/wallet/api/walletapi.ts","./src/features/wallet/model/usewalletdata.ts","./src/pages/bridge/index.ts","./src/pages/bridge/ui/bridgepage.tsx","./src/pages/converter/index.ts","./src/pages/converter/ui/converterpage.tsx","./src/pages/converter/ui/legalconverterpage.tsx","./src/pages/converter-test/index.ts","./src/pages/converter-test/ui/convertertestpage.tsx","./src/pages/home/index.ts","./src/pages/home/ui/homepage.tsx","./src/pages/kyc/index.ts","./src/pages/kyc/ui/kycpage.tsx","./src/pages/login/index.ts","./src/pages/login/ui/loginpage.tsx","./src/pages/politika-cookie/index.ts","./src/pages/politika-cookie/ui/politikacookiepage.tsx","./src/pages/politika-personalnyh-dannyh/index.ts","./src/pages/politika-personalnyh-dannyh/ui/politikapage.tsx","./src/pages/profile/index.ts","./src/pages/profile/ui/individualfields.tsx","./src/pages/profile/ui/legalentityfields.tsx","./src/pages/profile/ui/profilepage.tsx","./src/pages/publichnaya-oferta/index.ts","./src/pages/publichnaya-oferta/ui/publichnayaofertapage.tsx","./src/pages/reestr-pd-rkn/index.ts","./src/pages/reestr-pd-rkn/ui/reestrypage.tsx","./src/pages/register/index.ts","./src/pages/register/ui/registerpage.tsx","./src/pages/register-test/index.ts","./src/pages/register-test/ui/registertestpage.tsx","./src/pages/restore-password/index.ts","./src/pages/restore-password/ui/restorepasswordpage.tsx","./src/pages/seed-phrase/index.ts","./src/pages/seed-phrase/ui/seedphrasepage.tsx","./src/pages/soglasie-personalnyh-dannyh/index.ts","./src/pages/soglasie-personalnyh-dannyh/ui/soglasiepage.tsx","./src/pages/swap/index.ts","./src/pages/swap/ui/swappage.tsx","./src/pages/transactions/index.ts","./src/pages/transactions/ui/transactionspage.tsx","./src/pages/wallet/index.ts","./src/pages/wallet/ui/walletpage.tsx","./src/shared/api/base.ts","./src/shared/api/csrf.ts","./src/shared/api/tokenstore.ts","./src/shared/api/types.ts","./src/shared/assets/coins/index.ts","./src/shared/config/constants.ts","./src/shared/config/env.ts","./src/shared/config/routes.ts","./src/shared/lib/hooks/usedebounce.ts","./src/shared/lib/hooks/uselocalstorage.ts","./src/shared/lib/utils/baseunits.ts","./src/shared/lib/utils/cn.ts","./src/shared/lib/utils/truncatedecimals.ts","./src/shared/types/index.ts","./src/shared/ui/index.ts","./src/shared/ui/button/button.tsx","./src/shared/ui/button/index.ts","./src/shared/ui/convertfield/convertfield.tsx","./src/shared/ui/convertfield/index.ts","./src/shared/ui/directionswapbutton/directionswapbutton.tsx","./src/shared/ui/directionswapbutton/index.ts","./src/shared/ui/formfield/formfield.tsx","./src/shared/ui/formfield/index.ts","./src/shared/ui/notification/notification.tsx","./src/shared/ui/notification/index.ts","./src/shared/ui/pill/pill.tsx","./src/shared/ui/pill/index.ts","./src/shared/ui/primarybutton/primarybutton.tsx","./src/shared/ui/primarybutton/index.ts","./src/shared/ui/select/select.tsx","./src/shared/ui/select/index.ts","./src/shared/ui/spinner/spinner.tsx","./src/shared/ui/spinner/index.ts","./src/shared/ui/title/title.tsx","./src/shared/ui/tokenicon/tokenicon.tsx","./src/shared/ui/tokenicon/index.ts","./src/widgets/about/index.ts","./src/widgets/about/ui/about.tsx","./src/widgets/balance-card/index.ts","./src/widgets/balance-card/ui/balancecard.tsx","./src/widgets/bridge-form/index.ts","./src/widgets/bridge-form/ui/bridgeconfirmmodal.tsx","./src/widgets/bridge-form/ui/bridgeform.tsx","./src/widgets/bridge-form/ui/networkselect.tsx","./src/widgets/converter-page/index.ts","./src/widgets/converter-page/model/useconvertersection.ts","./src/widgets/converter-page/ui/agreementcheck.tsx","./src/widgets/converter-page/ui/convertersection.tsx","./src/widgets/currency-converter/index.ts","./src/widgets/currency-converter/ui/agreementcheckbox.tsx","./src/widgets/currency-converter/ui/converter.tsx","./src/widgets/footer/index.ts","./src/widgets/footer/ui/footer.tsx","./src/widgets/header/index.ts","./src/widgets/header/ui/header.tsx","./src/widgets/hero/index.ts","./src/widgets/hero/lib/usecountdown.ts","./src/widgets/hero/ui/conversionflow.tsx","./src/widgets/hero/ui/countdown.tsx","./src/widgets/hero/ui/exchangecard.tsx","./src/widgets/hero/ui/hero.tsx","./src/widgets/kyc-verification/index.ts","./src/widgets/kyc-verification/model/usekyc.ts","./src/widgets/kyc-verification/ui/kycmodal.tsx","./src/widgets/kyc-verification/ui/kycwidget.tsx","./src/widgets/login-form/index.ts","./src/widgets/login-form/model/useloginform.ts","./src/widgets/login-form/ui/loginform.tsx","./src/widgets/networks-table/index.ts","./src/widgets/networks-table/model/networks.ts","./src/widgets/networks-table/ui/networkstable.tsx","./src/widgets/profile/index.ts","./src/widgets/profile/ui/avatarcropmodal.tsx","./src/widgets/profile/ui/profileavatar.tsx","./src/widgets/profile/ui/profilesection.tsx","./src/widgets/profile/ui/getcroppedimg.ts","./src/widgets/purchase-requests-list/index.ts","./src/widgets/purchase-requests-list/ui/purchaserequestslist.tsx","./src/widgets/receive-modal/index.ts","./src/widgets/receive-modal/ui/receivemodal.tsx","./src/widgets/register-form/index.ts","./src/widgets/register-form/model/useregisterform.ts","./src/widgets/register-form/ui/individualform.tsx","./src/widgets/register-form/ui/legalregisterinfo.tsx","./src/widgets/register-form/ui/registerform.tsx","./src/widgets/restore-password-form/index.ts","./src/widgets/restore-password-form/ui/restorepasswordform.tsx","./src/widgets/seed-phrase/index.ts","./src/widgets/seed-phrase/model/useseedphrase.ts","./src/widgets/seed-phrase/ui/seedphrasewidget.tsx","./src/widgets/send-modal/index.ts","./src/widgets/send-modal/model/sendtypes.ts","./src/widgets/send-modal/ui/sendmodal.tsx","./src/widgets/swap-bridge-tabs/index.ts","./src/widgets/swap-bridge-tabs/ui/swapbridgetabs.tsx","./src/widgets/swap-form/index.ts","./src/widgets/swap-form/model/useswapform.ts","./src/widgets/swap-form/ui/raterow.tsx","./src/widgets/swap-form/ui/swapcard.tsx","./src/widgets/swap-form/ui/swapconfirmmodal.tsx","./src/widgets/swap-form/ui/swapdirectionbutton.tsx","./src/widgets/swap-form/ui/swapform.tsx","./src/widgets/swap-form/ui/swapinfopanel.tsx","./src/widgets/swap-form/ui/tokenselect.tsx","./src/widgets/swap-form/ui/trxconfirmmodal.tsx","./src/widgets/token-table/index.ts","./src/widgets/token-table/model/tokens.ts","./src/widgets/token-table/model/usechaintokenrows.ts","./src/widgets/token-table/ui/tokentable.tsx","./src/widgets/transactions-list/index.ts","./src/widgets/transactions-list/model/format.ts","./src/widgets/transactions-list/model/paymentstatuslabels.ts","./src/widgets/transactions-list/ui/copybutton.tsx","./src/widgets/transactions-list/ui/orderaccordion.tsx","./src/widgets/transactions-list/ui/statusbadge.tsx","./src/widgets/transactions-list/ui/transactionslist.tsx","./src/widgets/wallet-chain-tabs/index.ts","./src/widgets/wallet-chain-tabs/ui/walletchaintabs.tsx","./src/widgets/wallet-header/index.ts","./src/widgets/wallet-header/ui/walletheader.tsx","./src/widgets/wallet-layout/index.ts","./src/widgets/wallet-layout/ui/walletlayout.tsx"],"version":"5.6.3"} \ No newline at end of file +{"root":["./src/main.tsx","./src/vite-env.d.ts","./src/app/app.tsx","./src/app/providers/guestroute.tsx","./src/app/providers/protectedroute.tsx","./src/app/providers/queryprovider.tsx","./src/app/providers/routerprovider.tsx","./src/app/providers/scrolltotop.tsx","./src/app/providers/index.ts","./src/entities/commission/index.ts","./src/entities/commission/model/tiers.ts","./src/entities/commission/ui/commissiontable.tsx","./src/features/auth/index.ts","./src/features/auth/api/profileapi.ts","./src/features/auth/api/registrationapi.ts","./src/features/auth/hooks/useauth.ts","./src/features/auth/hooks/useisauthenticated.ts","./src/features/auth/hooks/useme.ts","./src/features/auth/hooks/useupdatephone.ts","./src/features/auth/hooks/useuploadavatar.ts","./src/features/b2b/index.ts","./src/features/b2b/api/b2bapi.ts","./src/features/b2b/hooks/usecreatepurchaserequest.ts","./src/features/b2b/hooks/usemypurchaserequests.ts","./src/features/kyc/api/kycapi.ts","./src/features/payment/index.ts","./src/features/payment/api/paymentapi.ts","./src/features/payment/hooks/usecreateorder.ts","./src/features/payment/hooks/useorders.ts","./src/features/payment/hooks/usepaymentconfig.ts","./src/features/payment/hooks/usepaymentquote.ts","./src/features/payment/hooks/usepaymentquotebyrub.ts","./src/features/payment/model/usecurrencyconversion.ts","./src/features/staking/index.ts","./src/features/staking/api/stakingapi.ts","./src/features/staking/model/usestaking.ts","./src/features/wallet/index.ts","./src/features/wallet/api/walletapi.ts","./src/features/wallet/model/usewalletdata.ts","./src/pages/bridge/index.ts","./src/pages/bridge/ui/bridgepage.tsx","./src/pages/converter/index.ts","./src/pages/converter/ui/converterpage.tsx","./src/pages/converter/ui/legalconverterpage.tsx","./src/pages/converter-test/index.ts","./src/pages/converter-test/ui/convertertestpage.tsx","./src/pages/home/index.ts","./src/pages/home/ui/homepage.tsx","./src/pages/kyc/index.ts","./src/pages/kyc/ui/kycpage.tsx","./src/pages/login/index.ts","./src/pages/login/ui/loginpage.tsx","./src/pages/politika-cookie/index.ts","./src/pages/politika-cookie/ui/politikacookiepage.tsx","./src/pages/politika-personalnyh-dannyh/index.ts","./src/pages/politika-personalnyh-dannyh/ui/politikapage.tsx","./src/pages/profile/index.ts","./src/pages/profile/ui/individualfields.tsx","./src/pages/profile/ui/legalentityfields.tsx","./src/pages/profile/ui/profilepage.tsx","./src/pages/publichnaya-oferta/index.ts","./src/pages/publichnaya-oferta/ui/publichnayaofertapage.tsx","./src/pages/reestr-pd-rkn/index.ts","./src/pages/reestr-pd-rkn/ui/reestrypage.tsx","./src/pages/register/index.ts","./src/pages/register/ui/registerpage.tsx","./src/pages/register-test/index.ts","./src/pages/register-test/ui/registertestpage.tsx","./src/pages/restore-password/index.ts","./src/pages/restore-password/ui/restorepasswordpage.tsx","./src/pages/seed-phrase/index.ts","./src/pages/seed-phrase/ui/seedphrasepage.tsx","./src/pages/soglasie-personalnyh-dannyh/index.ts","./src/pages/soglasie-personalnyh-dannyh/ui/soglasiepage.tsx","./src/pages/staking/index.ts","./src/pages/staking/ui/stakingpage.tsx","./src/pages/swap/index.ts","./src/pages/swap/ui/swappage.tsx","./src/pages/transactions/index.ts","./src/pages/transactions/ui/transactionspage.tsx","./src/pages/wallet/index.ts","./src/pages/wallet/ui/walletpage.tsx","./src/shared/api/base.ts","./src/shared/api/csrf.ts","./src/shared/api/tokenstore.ts","./src/shared/api/types.ts","./src/shared/assets/coins/index.ts","./src/shared/config/constants.ts","./src/shared/config/env.ts","./src/shared/config/routes.ts","./src/shared/lib/hooks/usedebounce.ts","./src/shared/lib/hooks/uselocalstorage.ts","./src/shared/lib/utils/baseunits.ts","./src/shared/lib/utils/cn.ts","./src/shared/lib/utils/truncatedecimals.ts","./src/shared/types/index.ts","./src/shared/ui/index.ts","./src/shared/ui/button/button.tsx","./src/shared/ui/button/index.ts","./src/shared/ui/convertfield/convertfield.tsx","./src/shared/ui/convertfield/index.ts","./src/shared/ui/directionswapbutton/directionswapbutton.tsx","./src/shared/ui/directionswapbutton/index.ts","./src/shared/ui/formfield/formfield.tsx","./src/shared/ui/formfield/index.ts","./src/shared/ui/notification/notification.tsx","./src/shared/ui/notification/index.ts","./src/shared/ui/pill/pill.tsx","./src/shared/ui/pill/index.ts","./src/shared/ui/primarybutton/primarybutton.tsx","./src/shared/ui/primarybutton/index.ts","./src/shared/ui/select/select.tsx","./src/shared/ui/select/index.ts","./src/shared/ui/spinner/spinner.tsx","./src/shared/ui/spinner/index.ts","./src/shared/ui/title/title.tsx","./src/shared/ui/tokenicon/tokenicon.tsx","./src/shared/ui/tokenicon/index.ts","./src/widgets/about/index.ts","./src/widgets/about/ui/about.tsx","./src/widgets/balance-card/index.ts","./src/widgets/balance-card/ui/balancecard.tsx","./src/widgets/bridge-form/index.ts","./src/widgets/bridge-form/ui/bridgeconfirmmodal.tsx","./src/widgets/bridge-form/ui/bridgeform.tsx","./src/widgets/bridge-form/ui/networkselect.tsx","./src/widgets/converter-page/index.ts","./src/widgets/converter-page/model/useconvertersection.ts","./src/widgets/converter-page/ui/agreementcheck.tsx","./src/widgets/converter-page/ui/convertersection.tsx","./src/widgets/currency-converter/index.ts","./src/widgets/currency-converter/ui/agreementcheckbox.tsx","./src/widgets/currency-converter/ui/converter.tsx","./src/widgets/footer/index.ts","./src/widgets/footer/ui/footer.tsx","./src/widgets/header/index.ts","./src/widgets/header/ui/header.tsx","./src/widgets/hero/index.ts","./src/widgets/hero/lib/usecountdown.ts","./src/widgets/hero/ui/conversionflow.tsx","./src/widgets/hero/ui/countdown.tsx","./src/widgets/hero/ui/exchangecard.tsx","./src/widgets/hero/ui/hero.tsx","./src/widgets/kyc-verification/index.ts","./src/widgets/kyc-verification/model/usekyc.ts","./src/widgets/kyc-verification/ui/kycmodal.tsx","./src/widgets/kyc-verification/ui/kycwidget.tsx","./src/widgets/login-form/index.ts","./src/widgets/login-form/model/useloginform.ts","./src/widgets/login-form/ui/loginform.tsx","./src/widgets/networks-table/index.ts","./src/widgets/networks-table/model/networks.ts","./src/widgets/networks-table/ui/networkstable.tsx","./src/widgets/profile/index.ts","./src/widgets/profile/ui/avatarcropmodal.tsx","./src/widgets/profile/ui/profileavatar.tsx","./src/widgets/profile/ui/profilesection.tsx","./src/widgets/profile/ui/getcroppedimg.ts","./src/widgets/purchase-requests-list/index.ts","./src/widgets/purchase-requests-list/ui/purchaserequestslist.tsx","./src/widgets/receive-modal/index.ts","./src/widgets/receive-modal/ui/receivemodal.tsx","./src/widgets/register-form/index.ts","./src/widgets/register-form/model/useregisterform.ts","./src/widgets/register-form/ui/individualform.tsx","./src/widgets/register-form/ui/legalregisterinfo.tsx","./src/widgets/register-form/ui/registerform.tsx","./src/widgets/restore-password-form/index.ts","./src/widgets/restore-password-form/ui/restorepasswordform.tsx","./src/widgets/seed-phrase/index.ts","./src/widgets/seed-phrase/model/useseedphrase.ts","./src/widgets/seed-phrase/ui/seedphrasewidget.tsx","./src/widgets/send-modal/index.ts","./src/widgets/send-modal/model/sendtypes.ts","./src/widgets/send-modal/ui/sendmodal.tsx","./src/widgets/staking/index.ts","./src/widgets/staking/model/meta.ts","./src/widgets/staking/ui/chaintoggle.tsx","./src/widgets/staking/ui/positionspanel.tsx","./src/widgets/staking/ui/stakecard.tsx","./src/widgets/staking/ui/stakequotepanel.tsx","./src/widgets/staking/ui/stakingwidget.tsx","./src/widgets/staking/ui/unstakemodal.tsx","./src/widgets/staking/ui/withdrawnotice.tsx","./src/widgets/swap-bridge-tabs/index.ts","./src/widgets/swap-bridge-tabs/ui/swapbridgetabs.tsx","./src/widgets/swap-form/index.ts","./src/widgets/swap-form/model/useswapform.ts","./src/widgets/swap-form/ui/raterow.tsx","./src/widgets/swap-form/ui/swapcard.tsx","./src/widgets/swap-form/ui/swapconfirmmodal.tsx","./src/widgets/swap-form/ui/swapdirectionbutton.tsx","./src/widgets/swap-form/ui/swapform.tsx","./src/widgets/swap-form/ui/swapinfopanel.tsx","./src/widgets/swap-form/ui/tokenselect.tsx","./src/widgets/swap-form/ui/trxconfirmmodal.tsx","./src/widgets/token-table/index.ts","./src/widgets/token-table/model/tokens.ts","./src/widgets/token-table/model/usechaintokenrows.ts","./src/widgets/token-table/ui/tokentable.tsx","./src/widgets/transactions-list/index.ts","./src/widgets/transactions-list/model/format.ts","./src/widgets/transactions-list/model/paymentstatuslabels.ts","./src/widgets/transactions-list/ui/copybutton.tsx","./src/widgets/transactions-list/ui/orderaccordion.tsx","./src/widgets/transactions-list/ui/statusbadge.tsx","./src/widgets/transactions-list/ui/transactionslist.tsx","./src/widgets/wallet-chain-tabs/index.ts","./src/widgets/wallet-chain-tabs/ui/walletchaintabs.tsx","./src/widgets/wallet-header/index.ts","./src/widgets/wallet-header/ui/walletheader.tsx","./src/widgets/wallet-layout/index.ts","./src/widgets/wallet-layout/ui/walletlayout.tsx"],"version":"5.6.3"} \ No newline at end of file