diff --git a/app/api/settings.py b/app/api/settings.py index df5e792..655432a 100644 --- a/app/api/settings.py +++ b/app/api/settings.py @@ -16,6 +16,14 @@ DEFAULTS = { "check_ban": True, "max_threads": 5, "auto_revalidate_browser": True, + "auto_proxy_on_import": False, + "auto_validate_on_import": False, + "auto_proxy_on_import_mafile": True, + "auto_proxy_on_import_logpass": True, + "auto_proxy_on_import_token": True, + "auto_validate_on_import_mafile": True, + "auto_validate_on_import_logpass": True, + "auto_validate_on_import_token": True, }, "display": { "hide_passwords": False, @@ -84,6 +92,14 @@ class ValidationSettings(BaseModel): check_ban: bool = True max_threads: int = 5 auto_revalidate_browser: bool = True + auto_proxy_on_import: bool = False + auto_validate_on_import: bool = False + auto_proxy_on_import_mafile: bool = True + auto_proxy_on_import_logpass: bool = True + auto_proxy_on_import_token: bool = True + auto_validate_on_import_mafile: bool = True + auto_validate_on_import_logpass: bool = True + auto_validate_on_import_token: bool = True class DisplaySettings(BaseModel): diff --git a/app/api/token_accounts.py b/app/api/token_accounts.py index 1e5fa8e..bfdfb9a 100644 --- a/app/api/token_accounts.py +++ b/app/api/token_accounts.py @@ -3,10 +3,11 @@ import asyncio from fastapi import APIRouter, HTTPException +from fastapi.responses import Response from loguru import logger -from app.database import get_db from app.core.task_manager import task_manager +from app.database import get_db from app.models import TokenAccountCreate, TokenAccountOut, TokenAccountUpdate router = APIRouter(prefix="/api/token-accounts", tags=["token-accounts"]) @@ -23,7 +24,9 @@ async def list_tokens(): @router.get("/{account_id}", response_model=TokenAccountOut) async def get_token(account_id: int): db = await get_db() - cursor = await db.execute("SELECT * FROM token_accounts WHERE id = ?", (account_id,)) + cursor = await db.execute( + "SELECT * FROM token_accounts WHERE id = ?", (account_id,) + ) row = await cursor.fetchone() if not row: raise HTTPException(status_code=404, detail="Account not found") @@ -52,14 +55,15 @@ async def update_token(account_id: int, account: TokenAccountUpdate): raise HTTPException(status_code=400, detail="No fields to update") fields["updated_at"] = "datetime('now')" set_clause = ", ".join( - f"{k} = datetime('now')" if k == "updated_at" else f"{k} = ?" - for k in fields + f"{k} = datetime('now')" if k == "updated_at" else f"{k} = ?" for k in fields ) values = [v for k, v in fields.items() if k != "updated_at"] values.append(account_id) await db.execute(f"UPDATE token_accounts SET {set_clause} WHERE id = ?", values) await db.commit() - cursor = await db.execute("SELECT * FROM token_accounts WHERE id = ?", (account_id,)) + cursor = await db.execute( + "SELECT * FROM token_accounts WHERE id = ?", (account_id,) + ) row = await cursor.fetchone() if not row: raise HTTPException(status_code=404, detail="Account not found") @@ -140,7 +144,9 @@ async def validate_tokens(data: dict): accounts=accounts, params={}, ) - logger.info(f"token_validate submitted for {len(accounts)} accounts → task {task_id}") + logger.info( + f"token_validate submitted for {len(accounts)} accounts → task {task_id}" + ) return {"task_id": task_id, "accounts_count": len(accounts)} @@ -148,17 +154,21 @@ async def validate_tokens(data: dict): async def open_token_browser(account_id: int): """Open Chrome browser with saved session cookies for a token account.""" db = await get_db() - cursor = await db.execute("SELECT * FROM token_accounts WHERE id = ?", (account_id,)) + cursor = await db.execute( + "SELECT * FROM token_accounts WHERE id = ?", (account_id,) + ) row = await cursor.fetchone() if not row: raise HTTPException(status_code=404, detail="Account not found") account = dict(row) if not account.get("session_cookies"): - raise HTTPException(status_code=400, detail="No session cookies. Validate the account first.") + raise HTTPException( + status_code=400, detail="No session cookies. Validate the account first." + ) - from app.services.steam_auth import check_cookies_alive, _resolve_proxy from app.config import read_validation_settings + from app.services.steam_auth import _resolve_proxy, check_cookies_alive proxy = await _resolve_proxy(account) alive = await check_cookies_alive(account["session_cookies"], proxy) @@ -170,9 +180,17 @@ async def open_token_browser(account_id: int): accounts=[account], params={}, ) - logger.info(f"Cookies dead for token account {account_id}, auto-revalidating → task {task_id}") - return {"status": "revalidating", "message": "Cookies expired. Re-validating...", "task_id": task_id} - raise HTTPException(status_code=400, detail="Session cookies expired. Re-validate the account.") + logger.info( + f"Cookies dead for token account {account_id}, auto-revalidating → task {task_id}" + ) + return { + "status": "revalidating", + "message": "Cookies expired. Re-validating...", + "task_id": task_id, + } + raise HTTPException( + status_code=400, detail="Session cookies expired. Re-validate the account." + ) from app.services.browser_login import open_browser_with_cookies @@ -180,12 +198,85 @@ async def open_token_browser(account_id: int): try: await open_browser_with_cookies(account) except Exception as exc: - logger.error(f"Browser open failed for {account.get('login', account_id)}: {exc}") + logger.error( + f"Browser open failed for {account.get('login', account_id)}: {exc}" + ) asyncio.create_task(_run()) return {"status": "ok", "message": "Browser opening..."} +@router.post("/full-check") +async def full_check_tokens(data: dict): + """Submit a full-check task for selected token accounts.""" + ids: list[int] = data.get("account_ids", []) + if not ids: + raise HTTPException(status_code=400, detail="No account IDs provided") + db = await get_db() + placeholders = ",".join("?" for _ in ids) + cursor = await db.execute( + f"SELECT * FROM token_accounts WHERE id IN ({placeholders})", ids + ) + accounts = [dict(r) for r in await cursor.fetchall()] + if not accounts: + raise HTTPException(status_code=404, detail="No accounts found") + task_id = await task_manager.submit( + task_type="token_full_check", + accounts=accounts, + params={}, + ) + logger.info( + f"token_full_check submitted for {len(accounts)} accounts → task {task_id}" + ) + return {"task_id": task_id, "accounts_count": len(accounts)} + + +@router.get("/{account_id}/check-data") +async def get_token_check_data(account_id: int): + """Return stored check_data JSON for a token account.""" + import json + + db = await get_db() + cursor = await db.execute( + "SELECT check_data FROM token_accounts WHERE id = ?", (account_id,) + ) + row = await cursor.fetchone() + if not row: + raise HTTPException(status_code=404, detail="Account not found") + check_data_str = row["check_data"] + if not check_data_str: + raise HTTPException( + status_code=404, + detail="No check data available. Run a full check first.", + ) + return json.loads(check_data_str) + + +@router.get("/{account_id}/cookies") +async def download_token_cookies(account_id: int): + """Download session_cookies as a .json file.""" + db = await get_db() + cursor = await db.execute( + "SELECT login, steam_id, session_cookies FROM token_accounts WHERE id = ?", + (account_id,), + ) + row = await cursor.fetchone() + if not row: + raise HTTPException(status_code=404, detail="Account not found") + cookies = row["session_cookies"] + if not cookies: + raise HTTPException( + status_code=404, detail="No cookies saved. Validate the account first." + ) + login = row["login"] or row["steam_id"] or str(account_id) + filename = f"{login}_cookies.json" + return Response( + content=cookies, + media_type="application/json", + headers={"Content-Disposition": f'attachment; filename="{filename}"'}, + ) + + @router.post("/assign-proxies") async def token_assign_proxies(): """Round-robin assign proxies to token accounts that don't have one.""" diff --git a/app/config.py b/app/config.py index c73f9c4..f01b402 100644 --- a/app/config.py +++ b/app/config.py @@ -1,4 +1,5 @@ from pathlib import Path + from pydantic_settings import BaseSettings @@ -32,6 +33,14 @@ _VALIDATION_DEFAULTS: dict = { "max_threads": 10, "account_timeout": 90, "auto_revalidate_browser": True, + "auto_proxy_on_import": False, + "auto_validate_on_import": False, + "auto_proxy_on_import_mafile": True, + "auto_proxy_on_import_logpass": True, + "auto_proxy_on_import_token": True, + "auto_validate_on_import_mafile": True, + "auto_validate_on_import_logpass": True, + "auto_validate_on_import_token": True, } diff --git a/app/database.py b/app/database.py index 3dbeba7..b447bfa 100644 --- a/app/database.py +++ b/app/database.py @@ -1,10 +1,10 @@ +import asyncio + import aiosqlite from loguru import logger from app.config import settings -import asyncio - _db: aiosqlite.Connection | None = None _db_lock = asyncio.Lock() @@ -124,7 +124,10 @@ async def _migrate(db: aiosqlite.Connection) -> None: ("nickname", "ALTER TABLE accounts ADD COLUMN nickname TEXT"), ("avatar_url", "ALTER TABLE accounts ADD COLUMN avatar_url TEXT"), ("steam_level", "ALTER TABLE accounts ADD COLUMN steam_level INTEGER"), - ("auto_accept", "ALTER TABLE accounts ADD COLUMN auto_accept INTEGER NOT NULL DEFAULT 0"), + ( + "auto_accept", + "ALTER TABLE accounts ADD COLUMN auto_accept INTEGER NOT NULL DEFAULT 0", + ), ("ban_status", "ALTER TABLE accounts ADD COLUMN ban_status TEXT"), ("session_cookies", "ALTER TABLE accounts ADD COLUMN session_cookies TEXT"), ("last_online", "ALTER TABLE accounts ADD COLUMN last_online TEXT"), @@ -153,7 +156,10 @@ async def _migrate(db: aiosqlite.Connection) -> None: ("trophy", "ALTER TABLE logpass_accounts ADD COLUMN trophy TEXT"), ("behavior", "ALTER TABLE logpass_accounts ADD COLUMN behavior TEXT"), ("license", "ALTER TABLE logpass_accounts ADD COLUMN license TEXT"), - ("session_cookies", "ALTER TABLE logpass_accounts ADD COLUMN session_cookies TEXT"), + ( + "session_cookies", + "ALTER TABLE logpass_accounts ADD COLUMN session_cookies TEXT", + ), ("steam_level", "ALTER TABLE logpass_accounts ADD COLUMN steam_level INTEGER"), ("avatar_url", "ALTER TABLE logpass_accounts ADD COLUMN avatar_url TEXT"), ("last_online", "ALTER TABLE logpass_accounts ADD COLUMN last_online TEXT"), @@ -168,12 +174,16 @@ async def _migrate(db: aiosqlite.Connection) -> None: tk_cols = {row[1] for row in await cursor.fetchall()} tk_migrations = [ ("proxy", "ALTER TABLE token_accounts ADD COLUMN proxy TEXT"), - ("session_cookies", "ALTER TABLE token_accounts ADD COLUMN session_cookies TEXT"), + ( + "session_cookies", + "ALTER TABLE token_accounts ADD COLUMN session_cookies TEXT", + ), ("ban_status", "ALTER TABLE token_accounts ADD COLUMN ban_status TEXT"), ("nickname", "ALTER TABLE token_accounts ADD COLUMN nickname TEXT"), ("steam_level", "ALTER TABLE token_accounts ADD COLUMN steam_level INTEGER"), ("avatar_url", "ALTER TABLE token_accounts ADD COLUMN avatar_url TEXT"), ("last_online", "ALTER TABLE token_accounts ADD COLUMN last_online TEXT"), + ("check_data", "ALTER TABLE token_accounts ADD COLUMN check_data TEXT"), ] for col, sql in tk_migrations: if col not in tk_cols: @@ -186,10 +196,14 @@ async def _migrate(db: aiosqlite.Connection) -> None: idx_names = {row[1] for row in idx_rows} if "uq_logpass_login" not in idx_names: try: - await db.execute("CREATE UNIQUE INDEX uq_logpass_login ON logpass_accounts(login)") + await db.execute( + "CREATE UNIQUE INDEX uq_logpass_login ON logpass_accounts(login)" + ) logger.info("Migration: added unique index on logpass_accounts.login") except Exception: - logger.warning("Could not create unique index on logpass_accounts.login (duplicates may exist)") + logger.warning( + "Could not create unique index on logpass_accounts.login (duplicates may exist)" + ) async def close_db() -> None: diff --git a/app/services/registry.py b/app/services/registry.py index 5a7258a..af2eb34 100644 --- a/app/services/registry.py +++ b/app/services/registry.py @@ -1,10 +1,11 @@ from app.core.task_manager import task_manager -from app.services.steam_guard import remove_guard, generate_2fa -from app.services.steam_password import change_password, random_password -from app.services.steam_email import change_email, validate_account -from app.services.steam_phone import change_phone from app.services.steam_checker import check_logpass_account, full_parse_logpass_account +from app.services.steam_email import change_email, validate_account +from app.services.steam_guard import generate_2fa, remove_guard +from app.services.steam_password import change_password, random_password +from app.services.steam_phone import change_phone from app.services.steam_token_checker import check_token_account +from app.services.steam_token_full_checker import full_check_token_account def register_all_handlers() -> None: @@ -18,3 +19,4 @@ def register_all_handlers() -> None: task_manager.register_handler("logpass_validate", check_logpass_account) task_manager.register_handler("logpass_full_parse", full_parse_logpass_account) task_manager.register_handler("token_validate", check_token_account) + task_manager.register_handler("token_full_check", full_check_token_account) diff --git a/app/services/steam_token_full_checker.py b/app/services/steam_token_full_checker.py new file mode 100644 index 0000000..46cab40 --- /dev/null +++ b/app/services/steam_token_full_checker.py @@ -0,0 +1,677 @@ +"""Full-check service for token accounts. + +Performs the finalizelogin flow to obtain authenticated cookies, then calls +multiple Steam Web APIs in parallel to collect detailed account information, +and stores the result as JSON in the token_accounts.check_data column. +""" + +from __future__ import annotations + +import asyncio +import json as _json +import re +import urllib.parse +from datetime import datetime + +import aiohttp +from aiohttp import FormData +from loguru import logger + +from app.core.proxy_manager import proxy_manager +from app.core.task_manager import task_manager +from app.services.steam_auth import _resolve_proxy +from app.services.steam_profile import ( + _parse_avatar, + _parse_last_online, + _parse_level, + _parse_persona_name, +) +from pysteamauth.auth.schemas import FinalizeLoginStatus + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + + +def _extract_web_token(jar: aiohttp.CookieJar) -> str | None: + """Extract the JWT access token from the steamLoginSecure cookie.""" + for cookie in jar: + if cookie.key == "steamLoginSecure" and cookie.value: + raw = urllib.parse.unquote(cookie.value) + if "||" in raw: + return raw.split("||", 1)[1] + return None + + +def _build_cookie_jar_from_list( + cookies: list[dict], +) -> aiohttp.CookieJar: + """Reconstruct an aiohttp CookieJar from a list of cookie dicts.""" + jar = aiohttp.CookieJar(unsafe=True) + import yarl + + for c in cookies: + domain = c.get("domain", ".steamcommunity.com").lstrip(".") + scheme = "https" if c.get("secure", True) else "http" + jar.update_cookies( + {c["name"]: c["value"]}, + response_url=yarl.URL(f"{scheme}://{domain}/"), + ) + return jar + + +# --------------------------------------------------------------------------- +# Individual API fetchers (each returns a partial dict or raises) +# --------------------------------------------------------------------------- + + +async def _fetch_wallet(session: aiohttp.ClientSession, web_token: str) -> dict: + """POST wallet details → balance_raw, user_country.""" + url = ( + "https://api.steampowered.com/IUserAccountService/GetClientWalletDetails/v1/" + f"?access_token={web_token}" + ) + try: + async with session.post(url, timeout=aiohttp.ClientTimeout(total=15)) as resp: + data = await resp.json(content_type=None) + inner = data.get("response", {}) + balance_raw = inner.get("formatted_balance") or None + if not balance_raw: + # Construct from balance (cents) and currency if formatted_balance missing + cents = inner.get("balance", 0) + currency = inner.get("wallet_currency", "") + if cents: + balance_raw = f"{cents / 100:.2f} {currency}".strip() + return { + "balance_raw": balance_raw, + "user_country": inner.get("user_country") or None, + } + except Exception as exc: + logger.debug(f"[full_check] wallet API error: {exc}") + return {"balance_raw": None, "user_country": None} + + +async def _fetch_family_group(session: aiohttp.ClientSession, web_token: str) -> dict: + """GET family group → family_group (bool).""" + url = ( + "https://api.steampowered.com/IFamilyGroupsService/GetFamilyGroupForUser/v1/" + f"?access_token={web_token}" + ) + try: + async with session.get(url, timeout=aiohttp.ClientTimeout(total=15)) as resp: + data = await resp.json(content_type=None) + inner = data.get("response", {}) + # If the account is in a family group there will be a family_groupid + has_group = bool(inner.get("family_groupid") or inner.get("family_group")) + return {"family_group": has_group} + except Exception as exc: + logger.debug(f"[full_check] family group API error: {exc}") + return {"family_group": False} + + +async def _fetch_recently_played( + session: aiohttp.ClientSession, web_token: str, steam_id: str +) -> dict: + """GET recently played games → playtime_2weeks (total minutes).""" + url = ( + "https://api.steampowered.com/IPlayerService/GetRecentlyPlayedGames/v1/" + f"?access_token={web_token}&steamid={steam_id}" + ) + try: + async with session.get(url, timeout=aiohttp.ClientTimeout(total=15)) as resp: + data = await resp.json(content_type=None) + games = data.get("response", {}).get("games", []) or [] + total_minutes = sum(g.get("playtime_2weeks", 0) for g in games) + return {"playtime_2weeks": total_minutes} + except Exception as exc: + logger.debug(f"[full_check] recently played API error: {exc}") + return {"playtime_2weeks": 0} + + +async def _fetch_inventory( + session: aiohttp.ClientSession, steam_id: str, appid: int +) -> tuple[int, int]: + """GET inventory → (total_count, marketable_count). + + Uses count=1 to quickly fetch total_inventory_count. + Marketable count is set to 0 (requires full inventory scan). + """ + url = f"https://steamcommunity.com/inventory/{steam_id}/{appid}/2?l=english&count=1" + try: + async with session.get(url, timeout=aiohttp.ClientTimeout(total=20)) as resp: + if resp.status == 403: + # Private inventory + return (0, 0) + if resp.status != 200: + return (0, 0) + data = await resp.json(content_type=None) + total = data.get("total_inventory_count", 0) if data else 0 + return (total, 0) + except Exception as exc: + logger.debug(f"[full_check] inventory appid={appid} error: {exc}") + return (0, 0) + + +async def _fetch_profile_xml(session: aiohttp.ClientSession, steam_id: str) -> dict: + """GET profile XML → trade_ban, created_date.""" + url = f"https://steamcommunity.com/profiles/{steam_id}?xml=1" + try: + async with session.get(url, timeout=aiohttp.ClientTimeout(total=15)) as resp: + xml = await resp.text() + + # Trade ban + trade_ban: str | None = None + m = re.search(r"(.*?)", xml) + if m: + trade_ban = m.group(1).strip() or None + + # Member since (creation date) + created_date: str | None = None + m = re.search(r"(.*?)", xml) + if m: + created_date = m.group(1).strip() or None + + return {"trade_ban": trade_ban, "created_date": created_date} + except Exception as exc: + logger.debug(f"[full_check] profile XML error: {exc}") + return {"trade_ban": None, "created_date": None} + + +async def _fetch_profile_html(session: aiohttp.ClientSession, steam_id: str) -> dict: + """GET profile HTML → display_name, avatar_url, steam_level, last_online.""" + url = f"https://steamcommunity.com/profiles/{steam_id}/" + try: + async with session.get(url, timeout=aiohttp.ClientTimeout(total=20)) as resp: + if resp.status != 200: + return { + "display_name": None, + "avatar_url": None, + "steam_level": None, + "last_online": None, + } + html = await resp.text() + return { + "display_name": _parse_persona_name(html), + "avatar_url": _parse_avatar(html), + "steam_level": _parse_level(html), + "last_online": _parse_last_online(html), + } + except Exception as exc: + logger.debug(f"[full_check] profile HTML error: {exc}") + return { + "display_name": None, + "avatar_url": None, + "steam_level": None, + "last_online": None, + } + + +async def _fetch_phone_digits(session: aiohttp.ClientSession) -> dict: + """GET /account/ → phone last digits.""" + url = "https://store.steampowered.com/account/" + try: + async with session.get(url, timeout=aiohttp.ClientTimeout(total=15)) as resp: + html = await resp.text() + # "Ends in XX" or "ending in XX" + m = re.search(r"[Ee]nds?\s+in\s+(\d+)", html) + if not m: + m = re.search(r"ending\s+in\s+(\d+)", html) + return {"phone_digits": m.group(1) if m else None} + except Exception as exc: + logger.debug(f"[full_check] phone digits error: {exc}") + return {"phone_digits": None} + + +async def _fetch_alert_status(session: aiohttp.ClientSession) -> dict: + """GET /supportmessages/ → alert_status string.""" + url = "https://store.steampowered.com/supportmessages/" + try: + async with session.get(url, timeout=aiohttp.ClientTimeout(total=15)) as resp: + html = await resp.text() + + if re.search( + r"account[_\-\s]?locked|your account has been locked", html, re.IGNORECASE + ): + return {"alert_status": "LOCKED"} + if re.search(r"restricted|limited account", html, re.IGNORECASE): + return {"alert_status": "RESTRICTED"} + if re.search( + r"support message|alert|warning|action required", html, re.IGNORECASE + ): + return {"alert_status": "ALERT"} + return {"alert_status": "None"} + except Exception as exc: + logger.debug(f"[full_check] alert status error: {exc}") + return {"alert_status": "None"} + + +async def _fetch_market_limited(session: aiohttp.ClientSession) -> dict: + """GET /market/ → market_limited (bool).""" + url = "https://steamcommunity.com/market/" + try: + async with session.get( + url, + timeout=aiohttp.ClientTimeout(total=15), + allow_redirects=True, + ) as resp: + final_url = str(resp.url) + html = await resp.text() + + # If redirected to login or the page body indicates we are not logged in + if "login.steampowered.com" in final_url: + return {"market_limited": True} + # Steam's market page includes this container only when logged in with market access + if "market_headertip_container_warning" in html: + return {"market_limited": True} + # If it threw us to a "you must log in" page + if re.search( + r"g_bInternalBrowser|please log in|you are not logged in", + html, + re.IGNORECASE, + ): + return {"market_limited": True} + return {"market_limited": False} + except Exception as exc: + logger.debug(f"[full_check] market limited error: {exc}") + return {"market_limited": False} + + +# --------------------------------------------------------------------------- +# Finalizelogin flow (mirrors steam_token_checker.py) +# --------------------------------------------------------------------------- + + +async def _do_finalizelogin( + account: dict, +) -> tuple[str, list[dict], str | None]: + """Run the finalizelogin flow. + + Returns: + (steam_id, all_cookies_list, web_token) + Raises on failure. + """ + import base64 + + token = account["token"] + + # Decode JWT to get steam_id as fallback + parts = token.split(".") + steam_id: str = "" + if len(parts) == 3: + payload_b64 = parts[1] + "=" * (-len(parts[1]) % 4) + try: + payload = _json.loads(base64.urlsafe_b64decode(payload_b64)) + steam_id = payload.get("sub", "") + except Exception: + pass + + proxy = await _resolve_proxy(account) + connector = proxy_manager.get_connector(proxy) if proxy else aiohttp.TCPConnector() + jar = aiohttp.CookieJar(unsafe=True) + headers = { + "User-Agent": ( + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " + "AppleWebKit/537.36 (KHTML, like Gecko) " + "Chrome/124.0.0.0 Safari/537.36" + ), + "Origin": "https://steamcommunity.com", + } + timeout = aiohttp.ClientTimeout(total=30) + + async with aiohttp.ClientSession( + connector=connector, + cookie_jar=jar, + headers=headers, + timeout=timeout, + ) as session: + # Seed sessionid cookie + async with session.get("https://steamcommunity.com") as resp: + await resp.read() + + sessionid: str | None = None + for cookie in jar: + if cookie.key == "sessionid": + sessionid = cookie.value + break + if not sessionid: + raise RuntimeError( + "Failed to acquire sessionid cookie from steamcommunity.com" + ) + + # POST finalizelogin + form = FormData( + fields=[ + ("nonce", token), + ("sessionid", sessionid), + ("redir", "https://steamcommunity.com/login/home/?goto="), + ] + ) + async with session.post( + "https://login.steampowered.com/jwt/finalizelogin", + data=form, + ) as resp: + resp_text = await resp.text() + if resp.status != 200: + raise RuntimeError( + f"finalizelogin HTTP {resp.status}: {resp_text[:300]}" + ) + + resp_json = _json.loads(resp_text) + if not resp_json.get("steamID"): + error_msg = resp_json.get("message", resp_text[:200]) + raise RuntimeError(f"finalizelogin rejected: {error_msg}") + + finalize = FinalizeLoginStatus.model_validate(resp_json) + steam_id = finalize.steamID or steam_id + + # Set domain cookies via transfer_info URLs + for ti in finalize.transfer_info: + form = FormData( + fields=[ + ("nonce", ti.params.nonce), + ("auth", ti.params.auth), + ("steamID", str(steam_id)), + ] + ) + try: + async with session.post(ti.url, data=form) as _resp: + await _resp.read() + except Exception: + pass + + # Visit extra domains to collect all cookies + for url in ( + "https://store.steampowered.com", + "https://help.steampowered.com", + ): + try: + async with session.get(url) as _resp: + await _resp.read() + except Exception: + pass + + # Extract web_token from steamLoginSecure cookie + web_token = _extract_web_token(jar) + + # Serialise cookies + all_cookies: list[dict] = [] + for c in jar: + all_cookies.append( + { + "name": c.key, + "value": c.value, + "domain": c.get("domain", ""), + "path": c.get("path", "/"), + "secure": "secure" in str(c).lower(), + "httpOnly": "httponly" in str(c).lower(), + } + ) + + return str(steam_id), all_cookies, web_token + + +# --------------------------------------------------------------------------- +# Main entry point +# --------------------------------------------------------------------------- + +TOTAL_STEPS = 6 + + +async def full_check_token_account( + account: dict, params: dict, *, task_id: str +) -> None: + """Full-check a token account and persist results to the DB. + + Steps: + 1. Decode JWT / prepare + 2. finalizelogin flow + 3. Parallel API calls – Steam Web APIs + 4. Parallel API calls – Community pages + 5. Parallel API calls – Inventories + 6. Save to DB + """ + acc_id = account["id"] + login_label = account.get("login") or str(acc_id) + + await task_manager.set_step(task_id, 1, TOTAL_STEPS, "Подготовка токена", acc_id) + + # ------------------------------------------------------------------ # + # Step 2: finalizelogin # + # ------------------------------------------------------------------ # + await task_manager.set_step( + task_id, 2, TOTAL_STEPS, "Авторизация (finalizelogin)", acc_id + ) + try: + steam_id, all_cookies, web_token = await _do_finalizelogin(account) + except Exception as exc: + logger.error(f"[full_check] {login_label}: finalizelogin failed — {exc}") + await _mark_invalid(acc_id) + raise + + session_cookies_json = _json.dumps(all_cookies) + logger.debug( + f"[full_check] {login_label}: finalizelogin OK, " + f"steam_id={steam_id}, web_token={'yes' if web_token else 'NO'}, " + f"cookies={len(all_cookies)}" + ) + + # ------------------------------------------------------------------ # + # Rebuild an authenticated aiohttp session from the saved cookies # + # ------------------------------------------------------------------ # + proxy = await _resolve_proxy(account) + connector = proxy_manager.get_connector(proxy) if proxy else aiohttp.TCPConnector() + auth_jar = _build_cookie_jar_from_list(all_cookies) + auth_headers = { + "User-Agent": ( + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " + "AppleWebKit/537.36 (KHTML, like Gecko) " + "Chrome/124.0.0.0 Safari/537.36" + ), + } + + async with aiohttp.ClientSession( + connector=connector, + cookie_jar=auth_jar, + headers=auth_headers, + timeout=aiohttp.ClientTimeout(total=30), + ) as session: + # -------------------------------------------------------------- # + # Step 3: Steam Web API calls (need web_token) # + # -------------------------------------------------------------- # + await task_manager.set_step( + task_id, 3, TOTAL_STEPS, "Steam Web API (кошелёк / игры / семья)", acc_id + ) + + if web_token: + api_results = await asyncio.gather( + _fetch_wallet(session, web_token), + _fetch_family_group(session, web_token), + _fetch_recently_played(session, web_token, steam_id), + return_exceptions=True, + ) + else: + # No web_token — skip Steam Web API calls, use safe defaults + logger.warning( + f"[full_check] {login_label}: no web_token — skipping Steam Web API calls" + ) + api_results = [ + {"balance_raw": None, "user_country": None}, + {"family_group": False}, + {"playtime_2weeks": 0}, + ] + + wallet_data = ( + api_results[0] + if isinstance(api_results[0], dict) + else {"balance_raw": None, "user_country": None} + ) + family_data = ( + api_results[1] + if isinstance(api_results[1], dict) + else {"family_group": False} + ) + played_data = ( + api_results[2] + if isinstance(api_results[2], dict) + else {"playtime_2weeks": 0} + ) + + # -------------------------------------------------------------- # + # Step 4: Community/Store page calls # + # -------------------------------------------------------------- # + await task_manager.set_step( + task_id, 4, TOTAL_STEPS, "Профиль / телефон / маркет / алерты", acc_id + ) + + page_results = await asyncio.gather( + _fetch_profile_html(session, steam_id), + _fetch_profile_xml(session, steam_id), + _fetch_phone_digits(session), + _fetch_alert_status(session), + _fetch_market_limited(session), + return_exceptions=True, + ) + + profile_data = ( + page_results[0] + if isinstance(page_results[0], dict) + else { + "display_name": None, + "avatar_url": None, + "steam_level": None, + "last_online": None, + } + ) + xml_data = ( + page_results[1] + if isinstance(page_results[1], dict) + else {"trade_ban": None, "created_date": None} + ) + phone_data = ( + page_results[2] + if isinstance(page_results[2], dict) + else {"phone_digits": None} + ) + alert_data = ( + page_results[3] + if isinstance(page_results[3], dict) + else {"alert_status": "None"} + ) + market_data = ( + page_results[4] + if isinstance(page_results[4], dict) + else {"market_limited": False} + ) + + # -------------------------------------------------------------- # + # Step 5: Inventory checks # + # -------------------------------------------------------------- # + await task_manager.set_step( + task_id, 5, TOTAL_STEPS, "Инвентари (CS2 / Dota2 / TF2 / Rust)", acc_id + ) + + inv_results = await asyncio.gather( + _fetch_inventory(session, steam_id, 730), # CS2 + _fetch_inventory(session, steam_id, 570), # Dota 2 + _fetch_inventory(session, steam_id, 440), # TF2 + _fetch_inventory(session, steam_id, 252490), # Rust + return_exceptions=True, + ) + + def _inv(result: object) -> tuple[int, int]: + if isinstance(result, tuple): + return result + return (0, 0) + + cs2_total, cs2_mkt = _inv(inv_results[0]) + d2_total, d2_mkt = _inv(inv_results[1]) + tf2_total, tf2_mkt = _inv(inv_results[2]) + rust_total, rust_mkt = _inv(inv_results[3]) + + # ------------------------------------------------------------------ # + # Step 6: Assemble check_data & persist # + # ------------------------------------------------------------------ # + await task_manager.set_step( + task_id, 6, TOTAL_STEPS, "Сохранение результатов", acc_id + ) + + check_data: dict = { + "steam_id": steam_id, + # Profile + "display_name": profile_data.get("display_name"), + "avatar_url": profile_data.get("avatar_url"), + "steam_level": profile_data.get("steam_level"), + "last_online": profile_data.get("last_online"), + # Wallet + "balance_raw": wallet_data.get("balance_raw"), + "user_country": wallet_data.get("user_country"), + # Family + "family_group": family_data.get("family_group", False), + # Playtime + "playtime_2weeks": played_data.get("playtime_2weeks", 0), + # Inventories (total / marketable) + "inventory_cs2": cs2_total, + "inventory_dota2": d2_total, + "inventory_tf2": tf2_total, + "inventory_rust": rust_total, + "inventory_cs2_marketable": cs2_mkt, + "inventory_dota2_marketable": d2_mkt, + "inventory_tf2_marketable": tf2_mkt, + "inventory_rust_marketable": rust_mkt, + # Profile XML + "trade_ban": xml_data.get("trade_ban"), + "created_date": xml_data.get("created_date"), + # Store/community pages + "phone_digits": phone_data.get("phone_digits"), + "alert_status": alert_data.get("alert_status", "None"), + "market_limited": market_data.get("market_limited", False), + # Timestamp + "checked_at": datetime.utcnow().isoformat(), + } + + from app.database import get_db + + db = await get_db() + await db.execute( + """UPDATE token_accounts + SET steam_id = ?, + nickname = ?, + avatar_url = ?, + steam_level = ?, + last_online = ?, + session_cookies = ?, + check_data = ?, + status = 'valid', + updated_at = datetime('now') + WHERE id = ?""", + ( + steam_id, + check_data.get("display_name"), + check_data.get("avatar_url"), + check_data.get("steam_level"), + check_data.get("last_online"), + session_cookies_json, + _json.dumps(check_data), + acc_id, + ), + ) + await db.commit() + + logger.success( + f"[full_check] {login_label} → valid | " + f"balance={check_data['balance_raw']} | " + f"country={check_data['user_country']} | " + f"cs2={cs2_total} | dota2={d2_total} | " + f"market_limited={check_data['market_limited']}" + ) + + +async def _mark_invalid(acc_id: int) -> None: + from app.database import get_db + + db = await get_db() + await db.execute( + "UPDATE token_accounts SET status = 'invalid', updated_at = datetime('now') WHERE id = ?", + (acc_id,), + ) + await db.commit() diff --git a/app/static/assets/index-D5Q9Ekc6.js b/app/static/assets/index-D5Q9Ekc6.js deleted file mode 100644 index 3131e76..0000000 --- a/app/static/assets/index-D5Q9Ekc6.js +++ /dev/null @@ -1,14 +0,0 @@ -var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),s=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;li[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},c=(n,r,a)=>(a=n==null?{}:e(i(n)),s(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var l=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.portal`),r=Symbol.for(`react.fragment`),i=Symbol.for(`react.strict_mode`),a=Symbol.for(`react.profiler`),o=Symbol.for(`react.consumer`),s=Symbol.for(`react.context`),c=Symbol.for(`react.forward_ref`),l=Symbol.for(`react.suspense`),u=Symbol.for(`react.memo`),d=Symbol.for(`react.lazy`),f=Symbol.for(`react.activity`),p=Symbol.iterator;function m(e){return typeof e!=`object`||!e?null:(e=p&&e[p]||e[`@@iterator`],typeof e==`function`?e:null)}var h={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},g=Object.assign,_={};function v(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}v.prototype.isReactComponent={},v.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=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,e,t,`setState`)},v.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function y(){}y.prototype=v.prototype;function b(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}var x=b.prototype=new y;x.constructor=b,g(x,v.prototype),x.isPureReactComponent=!0;var S=Array.isArray;function C(){}var w={H:null,A:null,T:null,S:null},T=Object.prototype.hasOwnProperty;function E(e,n,r){var i=r.ref;return{$$typeof:t,type:e,key:n,ref:i===void 0?null:i,props:r}}function D(e,t){return E(e.type,t,e.props)}function O(e){return typeof e==`object`&&!!e&&e.$$typeof===t}function ee(e){var t={"=":`=0`,":":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var k=/\/+/g;function A(e,t){return typeof e==`object`&&e&&e.key!=null?ee(``+e.key):t.toString(36)}function j(e){switch(e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason;default:switch(typeof e.status==`string`?e.then(C,C):(e.status=`pending`,e.then(function(t){e.status===`pending`&&(e.status=`fulfilled`,e.value=t)},function(t){e.status===`pending`&&(e.status=`rejected`,e.reason=t)})),e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason}}throw e}function M(e,r,i,a,o){var s=typeof e;(s===`undefined`||s===`boolean`)&&(e=null);var c=!1;if(e===null)c=!0;else switch(s){case`bigint`:case`string`:case`number`:c=!0;break;case`object`:switch(e.$$typeof){case t:case n:c=!0;break;case d:return c=e._init,M(c(e._payload),r,i,a,o)}}if(c)return o=o(e),c=a===``?`.`+A(e,0):a,S(o)?(i=``,c!=null&&(i=c.replace(k,`$&/`)+`/`),M(o,r,i,``,function(e){return e})):o!=null&&(O(o)&&(o=D(o,i+(o.key==null||e&&e.key===o.key?``:(``+o.key).replace(k,`$&/`)+`/`)+c)),r.push(o)),1;c=0;var l=a===``?`.`:a+`:`;if(S(e))for(var u=0;u{t.exports=l()})),d=o((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0>>1,a=e[r];if(0>>1;ri(c,n))li(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(li(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m)if(n(c)!==null)m=!0,S||(S=!0,O());else{var t=n(l);t!==null&&A(x,t.startTime-e)}}var S=!1,C=-1,w=5,T=-1;function E(){return g?!0:!(e.unstable_now()-Tt&&E());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&A(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?O():S=!1}}}var O;if(typeof y==`function`)O=function(){y(D)};else if(typeof MessageChannel<`u`){var ee=new MessageChannel,k=ee.port2;ee.port1.onmessage=D,O=function(){k.postMessage(null)}}else O=function(){_(D,0)};function A(t,n){C=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(C),C=-1):h=!0,A(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,S||(S=!0,O()))),r},e.unstable_shouldYield=E,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),f=o(((e,t)=>{t.exports=d()})),p=o((e=>{var t=u();function n(e){var t=`https://react.dev/errors/`+e;if(1{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=p()})),h=o((e=>{var t=f(),n=u(),r=m();function i(e){var t=`https://react.dev/errors/`+e;if(1ae||(e.current=ie[ae],ie[ae]=null,ae--)}function L(e,t){ae++,ie[ae]=e.current,e.current=t}var oe=F(null),R=F(null),se=F(null),ce=F(null);function le(e,t){switch(L(se,t),L(R,e),L(oe,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Vd(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Vd(t),e=Hd(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}I(oe),L(oe,e)}function ue(){I(oe),I(R),I(se)}function de(e){e.memoizedState!==null&&L(ce,e);var t=oe.current,n=Hd(t,e.type);t!==n&&(L(R,e),L(oe,n))}function fe(e){R.current===e&&(I(oe),I(R)),ce.current===e&&(I(ce),Qf._currentValue=re)}var pe,me;function he(e){if(pe===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);pe=t&&t[1]||``,me=-1)`:-1i||c[r]!==l[i]){var u=` -`+c[r].replace(` at new `,` at `);return e.displayName&&u.includes(``)&&(u=u.replace(``,e.displayName)),u}while(1<=r&&0<=i);break}}}finally{ge=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:``)?he(n):``}function ve(e,t){switch(e.tag){case 26:case 27:case 5:return he(e.type);case 16:return he(`Lazy`);case 13:return e.child!==t&&t!==null?he(`Suspense Fallback`):he(`Suspense`);case 19:return he(`SuspenseList`);case 0:case 15:return _e(e.type,!1);case 11:return _e(e.type.render,!1);case 1:return _e(e.type,!0);case 31:return he(`Activity`);default:return``}}function ye(e){try{var t=``,n=null;do t+=ve(e,n),n=e,e=e.return;while(e);return t}catch(e){return` -Error generating stack: `+e.message+` -`+e.stack}}var be=Object.prototype.hasOwnProperty,xe=t.unstable_scheduleCallback,Se=t.unstable_cancelCallback,Ce=t.unstable_shouldYield,we=t.unstable_requestPaint,Te=t.unstable_now,Ee=t.unstable_getCurrentPriorityLevel,De=t.unstable_ImmediatePriority,Oe=t.unstable_UserBlockingPriority,ke=t.unstable_NormalPriority,Ae=t.unstable_LowPriority,je=t.unstable_IdlePriority,Me=t.log,Ne=t.unstable_setDisableYieldValue,Pe=null,Fe=null;function Ie(e){if(typeof Me==`function`&&Ne(e),Fe&&typeof Fe.setStrictMode==`function`)try{Fe.setStrictMode(Pe,e)}catch{}}var Le=Math.clz32?Math.clz32:Be,Re=Math.log,ze=Math.LN2;function Be(e){return e>>>=0,e===0?32:31-(Re(e)/ze|0)|0}var Ve=256,He=262144,Ue=4194304;function We(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 Ge(e,t,n){var r=e.pendingLanes;if(r===0)return 0;var i=0,a=e.suspendedLanes,o=e.pingedLanes;e=e.warmLanes;var s=r&134217727;return s===0?(s=r&~a,s===0?o===0?n||(n=r&~e,n!==0&&(i=We(n))):i=We(o):i=We(s)):(r=s&~a,r===0?(o&=s,o===0?n||(n=s&~e,n!==0&&(i=We(n))):i=We(o)):i=We(r)),i===0?0:t!==0&&t!==i&&(t&a)===0&&(a=i&-i,n=t&-t,a>=n||a===32&&n&4194048)?t:i}function Ke(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function qe(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 Je(){var e=Ue;return Ue<<=1,!(Ue&62914560)&&(Ue=4194304),e}function Ye(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function Xe(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function Ze(e,t,n,r,i,a){var o=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 s=e.entanglements,c=e.expirationTimes,l=e.hiddenUpdates;for(n=o&~n;0`u`||window.document===void 0||window.document.createElement===void 0),un=!1;if(ln)try{var dn={};Object.defineProperty(dn,`passive`,{get:function(){un=!0}}),window.addEventListener(`test`,dn,dn),window.removeEventListener(`test`,dn,dn)}catch{un=!1}var fn=null,pn=null,mn=null;function hn(){if(mn)return mn;var e,t=pn,n=t.length,r,i=`value`in fn?fn.value:fn.textContent,a=i.length;for(e=0;e=qn),Xn=` `,Zn=!1;function Qn(e,t){switch(e){case`keyup`:return Gn.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function $n(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var er=!1;function tr(e,t){switch(e){case`compositionend`:return $n(t);case`keypress`:return t.which===32?(Zn=!0,Xn):null;case`textInput`:return e=t.data,e===Xn&&Zn?null:e;default:return null}}function nr(e,t){if(er)return e===`compositionend`||!Kn&&Qn(e,t)?(e=hn(),mn=pn=fn=null,er=!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=r}a:{for(;n;){if(n.nextSibling){n=n.nextSibling;break a}n=n.parentNode}n=void 0}n=wr(n)}}function Er(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Er(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Dr(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=It(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=It(e.document)}return t}function Or(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 kr=ln&&`documentMode`in document&&11>=document.documentMode,Ar=null,jr=null,Mr=null,Nr=!1;function Pr(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;Nr||Ar==null||Ar!==It(r)||(r=Ar,`selectionStart`in r&&Or(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Mr&&Cr(Mr,r)||(Mr=r,r=Ed(jr,`onSelect`),0>=o,i-=o,Ei=1<<32-Le(t)+i|n<h?(g=d,d=null):g=d.sibling;var _=p(i,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(i,d),a=o(_,a,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(i,d),B&&Oi(i,h),l;if(d===null){for(;hg?(_=h,h=null):_=h.sibling;var y=p(a,h,v.value,l);if(y===null){h===null&&(h=_);break}e&&h&&y.alternate===null&&t(a,h),s=o(y,s,g),d===null?u=y:d.sibling=y,d=y,h=_}if(v.done)return n(a,h),B&&Oi(a,g),u;if(h===null){for(;!v.done;g++,v=c.next())v=f(a,v.value,l),v!==null&&(s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return B&&Oi(a,g),u}for(h=r(h);!v.done;g++,v=c.next())v=m(h,a,g,v.value,l),v!==null&&(e&&v.alternate!==null&&h.delete(v.key===null?g:v.key),s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return e&&h.forEach(function(e){return t(a,e)}),B&&Oi(a,g),u}function b(e,r,o,c){if(typeof o==`object`&&o&&o.type===y&&o.key===null&&(o=o.props.children),typeof o==`object`&&o){switch(o.$$typeof){case _:a:{for(var l=o.key;r!==null;){if(r.key===l){if(l=o.type,l===y){if(r.tag===7){n(e,r.sibling),c=a(r,o.props.children),c.return=e,e=c;break a}}else if(r.elementType===l||typeof l==`object`&&l&&l.$$typeof===O&&Da(l)===r.type){n(e,r.sibling),c=a(r,o.props),Pa(c,o),c.return=e,e=c;break a}n(e,r);break}else t(e,r);r=r.sibling}o.type===y?(c=pi(o.props.children,e.mode,c,o.key),c.return=e,e=c):(c=fi(o.type,o.key,o.props,null,e.mode,c),Pa(c,o),c.return=e,e=c)}return s(e);case v:a:{for(l=o.key;r!==null;){if(r.key===l)if(r.tag===4&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),c=a(r,o.children||[]),c.return=e,e=c;break a}else{n(e,r);break}else t(e,r);r=r.sibling}c=gi(o,e.mode,c),c.return=e,e=c}return s(e);case O:return o=Da(o),b(e,r,o,c)}if(ne(o))return h(e,r,o,c);if(j(o)){if(l=j(o),typeof l!=`function`)throw Error(i(150));return o=l.call(o),g(e,r,o,c)}if(typeof o.then==`function`)return b(e,r,Na(o),c);if(o.$$typeof===C)return b(e,r,ta(e,o),c);Fa(e,o)}return typeof o==`string`&&o!==``||typeof o==`number`||typeof o==`bigint`?(o=``+o,r!==null&&r.tag===6?(n(e,r.sibling),c=a(r,o),c.return=e,e=c):(n(e,r),c=mi(o,e.mode,c),c.return=e,e=c),s(e)):n(e,r)}return function(e,t,n,r){try{Ma=0;var i=b(e,t,n,r);return ja=null,i}catch(t){if(t===xa||t===Ca)throw t;var a=ci(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var La=Ia(!0),Ra=Ia(!1),za=!1;function Ba(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Va(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 Ha(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function Ua(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,K&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,t=ai(e),ii(e,null,n),t}return ti(e,r,t,n),ai(e)}function Wa(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194048)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,$e(e,n)}}function Ga(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,a=null;if(n=n.firstBaseUpdate,n!==null){do{var o={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};a===null?i=a=o:a=a.next=o,n=n.next}while(n!==null);a===null?i=a=t:a=a.next=t}else i=a=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:a,shared:r.shared,callbacks:r.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var Ka=!1;function qa(){if(Ka){var e=fa;if(e!==null)throw e}}function Ja(e,t,n,r){Ka=!1;var i=e.updateQueue;za=!1;var a=i.firstBaseUpdate,o=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var c=s,l=c.next;c.next=null,o===null?a=l:o.next=l,o=c;var u=e.alternate;u!==null&&(u=u.updateQueue,s=u.lastBaseUpdate,s!==o&&(s===null?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(a!==null){var d=i.baseState;o=0,u=l=c=null,s=a;do{var f=s.lane&-536870913,p=f!==s.lane;if(p?(Y&f)===f:(r&f)===f){f!==0&&f===da&&(Ka=!0),u!==null&&(u=u.next={lane:0,tag:s.tag,payload:s.payload,callback:null,next:null});a:{var m=e,g=s;f=t;var _=n;switch(g.tag){case 1:if(m=g.payload,typeof m==`function`){d=m.call(_,d,f);break a}d=m;break a;case 3:m.flags=m.flags&-65537|128;case 0:if(m=g.payload,f=typeof m==`function`?m.call(_,d,f):m,f==null)break a;d=h({},d,f);break a;case 2:za=!0}}f=s.callback,f!==null&&(e.flags|=64,p&&(e.flags|=8192),p=i.callbacks,p===null?i.callbacks=[f]:p.push(f))}else p={lane:f,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=p,c=d):u=u.next=p,o|=f;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;p=s,s=p.next,p.next=null,i.lastBaseUpdate=p,i.shared.pending=null}}while(1);u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,a===null&&(i.shared.lanes=0),Gl|=o,e.lanes=o,e.memoizedState=d}}function Ya(e,t){if(typeof e!=`function`)throw Error(i(191,e));e.call(t)}function Xa(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ea?a:8;var o=N.T,s={};N.T=s,Ps(e,!1,t,n);try{var c=i(),l=N.S;l!==null&&l(s,c),typeof c==`object`&&c&&typeof c.then==`function`?Ns(e,t,ha(c,r),pu(e)):Ns(e,t,r,pu(e))}catch(n){Ns(e,t,{then:function(){},status:`rejected`,reason:n},pu())}finally{P.p=a,o!==null&&s.types!==null&&(o.types=s.types),N.T=o}}function Cs(){}function ws(e,t,n,r){if(e.tag!==5)throw Error(i(476));var a=Ts(e).queue;Ss(e,a,t,re,n===null?Cs:function(){return Es(e),n(r)})}function Ts(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:re,baseState:re,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Fo,lastRenderedState:re},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Fo,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function Es(e){var t=Ts(e);t.next===null&&(t=e.alternate.memoizedState),Ns(e,t.next.queue,{},pu())}function Ds(){return ea(Qf)}function Os(){return Ao().memoizedState}function ks(){return Ao().memoizedState}function As(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=pu();e=Ha(n);var r=Ua(t,e,n);r!==null&&(hu(r,t,n),Wa(r,t,n)),t={cache:sa()},e.payload=t;return}t=t.return}}function js(e,t,n){var r=pu();n={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},Fs(e)?Is(t,n):(n=ni(e,t,n,r),n!==null&&(hu(n,e,r),Ls(n,t,r)))}function Ms(e,t,n){Ns(e,t,n,pu())}function Ns(e,t,n,r){var i={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(Fs(e))Is(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var o=t.lastRenderedState,s=a(o,n);if(i.hasEagerState=!0,i.eagerState=s,Sr(s,o))return ti(e,t,i,0),q===null&&ei(),!1}catch{}if(n=ni(e,t,i,r),n!==null)return hu(n,e,r),Ls(n,t,r),!0}return!1}function Ps(e,t,n,r){if(r={lane:2,revertLane:dd(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},Fs(e)){if(t)throw Error(i(479))}else t=ni(e,n,r,2),t!==null&&hu(t,e,2)}function Fs(e){var t=e.alternate;return e===V||t!==null&&t===V}function Is(e,t){ho=mo=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Ls(e,t,n){if(n&4194048){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,$e(e,n)}}var Rs={readContext:ea,use:No,useCallback:U,useContext:U,useEffect:U,useImperativeHandle:U,useLayoutEffect:U,useInsertionEffect:U,useMemo:U,useReducer:U,useRef:U,useState:U,useDebugValue:U,useDeferredValue:U,useTransition:U,useSyncExternalStore:U,useId:U,useHostTransitionStatus:U,useFormState:U,useActionState:U,useOptimistic:U,useMemoCache:U,useCacheRefresh:U};Rs.useEffectEvent=U;var zs={readContext:ea,use:No,useCallback:function(e,t){return ko().memoizedState=[e,t===void 0?null:t],e},useContext:ea,useEffect:ls,useImperativeHandle:function(e,t,n){n=n==null?null:n.concat([e]),ss(4194308,4,hs.bind(null,t,e),n)},useLayoutEffect:function(e,t){return ss(4194308,4,e,t)},useInsertionEffect:function(e,t){ss(4,2,e,t)},useMemo:function(e,t){var n=ko();t=t===void 0?null:t;var r=e();if(go){Ie(!0);try{e()}finally{Ie(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=ko();if(n!==void 0){var i=n(t);if(go){Ie(!0);try{n(t)}finally{Ie(!1)}}}else i=t;return r.memoizedState=r.baseState=i,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:i},r.queue=e,e=e.dispatch=js.bind(null,V,e),[r.memoizedState,e]},useRef:function(e){var t=ko();return e={current:e},t.memoizedState=e},useState:function(e){e=Go(e);var t=e.queue,n=Ms.bind(null,V,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:_s,useDeferredValue:function(e,t){return bs(ko(),e,t)},useTransition:function(){var e=Go(!1);return e=Ss.bind(null,V,e.queue,!0,!1),ko().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=V,a=ko();if(B){if(n===void 0)throw Error(i(407));n=n()}else{if(n=t(),q===null)throw Error(i(349));Y&127||Bo(r,t,n)}a.memoizedState=n;var o={value:n,getSnapshot:t};return a.queue=o,ls(Ho.bind(null,r,o,e),[e]),r.flags|=2048,as(9,{destroy:void 0},Vo.bind(null,r,o,n,t),null),n},useId:function(){var e=ko(),t=q.identifierPrefix;if(B){var n=Di,r=Ei;n=(r&~(1<<32-Le(r)-1)).toString(32)+n,t=`_`+t+`R_`+n,n=_o++,0<\/script>`,o=o.removeChild(o.firstChild);break;case`select`:o=typeof r.is==`string`?s.createElement(`select`,{is:r.is}):s.createElement(`select`),r.multiple?o.multiple=!0:r.size&&(o.size=r.size);break;default:o=typeof r.is==`string`?s.createElement(a,{is:r.is}):s.createElement(a)}}o[ot]=t,o[st]=r;a:for(s=t.child;s!==null;){if(s.tag===5||s.tag===6)o.appendChild(s.stateNode);else if(s.tag!==4&&s.tag!==27&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===t)break a;for(;s.sibling===null;){if(s.return===null||s.return===t)break a;s=s.return}s.sibling.return=s.return,s=s.sibling}t.stateNode=o;a:switch(Pd(o,a,r),a){case`button`:case`input`:case`select`:case`textarea`:r=!!r.autoFocus;break a;case`img`:r=!0;break a;default:r=!1}r&&Nc(t)}}return W(t),Pc(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==r&&Nc(t);else{if(typeof r!=`string`&&t.stateNode===null)throw Error(i(166));if(e=se.current,Bi(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,a=Ni,a!==null)switch(a.tag){case 27:case 5:r=a.memoizedProps}e[ot]=t,e=!!(e.nodeValue===n||r!==null&&!0===r.suppressHydrationWarning||Md(e.nodeValue,n)),e||Li(t,!0)}else e=Bd(e).createTextNode(r),e[ot]=t,t.stateNode=e}return W(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(r=Bi(t),n!==null){if(e===null){if(!r)throw Error(i(318));if(e=t.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(i(557));e[ot]=t}else Vi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;W(t),e=!1}else n=Hi(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(co(t),t):(co(t),null);if(t.flags&128)throw Error(i(558))}return W(t),null;case 13:if(r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(a=Bi(t),r!==null&&r.dehydrated!==null){if(e===null){if(!a)throw Error(i(318));if(a=t.memoizedState,a=a===null?null:a.dehydrated,!a)throw Error(i(317));a[ot]=t}else Vi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;W(t),a=!1}else a=Hi(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=a),a=!0;if(!a)return t.flags&256?(co(t),t):(co(t),null)}return co(t),t.flags&128?(t.lanes=n,t):(n=r!==null,e=e!==null&&e.memoizedState!==null,n&&(r=t.child,a=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(a=r.alternate.memoizedState.cachePool.pool),o=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(o=r.memoizedState.cachePool.pool),o!==a&&(r.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),Ic(t,t.updateQueue),W(t),null);case 4:return ue(),e===null&&Sd(t.stateNode.containerInfo),W(t),null;case 10:return Ji(t.type),W(t),null;case 19:if(I(lo),r=t.memoizedState,r===null)return W(t),null;if(a=(t.flags&128)!=0,o=r.rendering,o===null)if(a)Lc(r,!1);else{if(Wl!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(o=uo(e),o!==null){for(t.flags|=128,Lc(r,!1),e=o.updateQueue,t.updateQueue=e,Ic(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)di(n,e),n=n.sibling;return L(lo,lo.current&1|2),B&&Oi(t,r.treeForkCount),t.child}e=e.sibling}r.tail!==null&&Te()>tu&&(t.flags|=128,a=!0,Lc(r,!1),t.lanes=4194304)}else{if(!a)if(e=uo(o),e!==null){if(t.flags|=128,a=!0,e=e.updateQueue,t.updateQueue=e,Ic(t,e),Lc(r,!0),r.tail===null&&r.tailMode===`hidden`&&!o.alternate&&!B)return W(t),null}else 2*Te()-r.renderingStartTime>tu&&n!==536870912&&(t.flags|=128,a=!0,Lc(r,!1),t.lanes=4194304);r.isBackwards?(o.sibling=t.child,t.child=o):(e=r.last,e===null?t.child=o:e.sibling=o,r.last=o)}return r.tail===null?(W(t),null):(e=r.tail,r.rendering=e,r.tail=e.sibling,r.renderingStartTime=Te(),e.sibling=null,n=lo.current,L(lo,a?n&1|2:n&1),B&&Oi(t,r.treeForkCount),e);case 22:case 23:return co(t),to(),r=t.memoizedState!==null,e===null?r&&(t.flags|=8192):e.memoizedState!==null!==r&&(t.flags|=8192),r?n&536870912&&!(t.flags&128)&&(W(t),t.subtreeFlags&6&&(t.flags|=8192)):W(t),n=t.updateQueue,n!==null&&Ic(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),r=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),e!==null&&I(_a),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),Ji(oa),W(t),null;case 25:return null;case 30:return null}throw Error(i(156,t.tag))}function zc(e,t){switch(ji(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Ji(oa),ue(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return fe(t),null;case 31:if(t.memoizedState!==null){if(co(t),t.alternate===null)throw Error(i(340));Vi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(co(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(i(340));Vi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return I(lo),null;case 4:return ue(),null;case 10:return Ji(t.type),null;case 22:case 23:return co(t),to(),e!==null&&I(_a),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return Ji(oa),null;case 25:return null;default:return null}}function Bc(e,t){switch(ji(t),t.tag){case 3:Ji(oa),ue();break;case 26:case 27:case 5:fe(t);break;case 4:ue();break;case 31:t.memoizedState!==null&&co(t);break;case 13:co(t);break;case 19:I(lo);break;case 10:Ji(t.type);break;case 22:case 23:co(t),to(),e!==null&&I(_a);break;case 24:Ji(oa)}}function Vc(e,t){try{var n=t.updateQueue,r=n===null?null:n.lastEffect;if(r!==null){var i=r.next;n=i;do{if((n.tag&e)===e){r=void 0;var a=n.create,o=n.inst;r=a(),o.destroy=r}n=n.next}while(n!==i)}}catch(e){Z(t,t.return,e)}}function Hc(e,t,n){try{var r=t.updateQueue,i=r===null?null:r.lastEffect;if(i!==null){var a=i.next;r=a;do{if((r.tag&e)===e){var o=r.inst,s=o.destroy;if(s!==void 0){o.destroy=void 0,i=t;var c=n,l=s;try{l()}catch(e){Z(i,c,e)}}}r=r.next}while(r!==a)}}catch(e){Z(t,t.return,e)}}function Uc(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{Xa(t,n)}catch(t){Z(e,e.return,t)}}}function Wc(e,t,n){n.props=Ks(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(n){Z(e,t,n)}}function Gc(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;case 30:r=e.stateNode;break;default:r=e.stateNode}typeof n==`function`?e.refCleanup=n(r):n.current=r}}catch(n){Z(e,t,n)}}function Kc(e,t){var n=e.ref,r=e.refCleanup;if(n!==null)if(typeof r==`function`)try{r()}catch(n){Z(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n==`function`)try{n(null)}catch(n){Z(e,t,n)}else n.current=null}function qc(e){var t=e.type,n=e.memoizedProps,r=e.stateNode;try{a:switch(t){case`button`:case`input`:case`select`:case`textarea`:n.autoFocus&&r.focus();break a;case`img`:n.src?r.src=n.src:n.srcSet&&(r.srcset=n.srcSet)}}catch(t){Z(e,e.return,t)}}function Jc(e,t,n){try{var r=e.stateNode;Fd(r,e.type,n,t),r[st]=t}catch(t){Z(e,e.return,t)}}function Yc(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&Zd(e.type)||e.tag===4}function Xc(e){a:for(;;){for(;e.sibling===null;){if(e.return===null||Yc(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&&Zd(e.type)||e.flags&2||e.child===null||e.tag===4)continue a;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Zc(e,t,n){var r=e.tag;if(r===5||r===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=$t));else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode,t=null),e=e.child,e!==null))for(Zc(e,t,n),e=e.sibling;e!==null;)Zc(e,t,n),e=e.sibling}function Qc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode),e=e.child,e!==null))for(Qc(e,t,n),e=e.sibling;e!==null;)Qc(e,t,n),e=e.sibling}function $c(e){var t=e.stateNode,n=e.memoizedProps;try{for(var r=e.type,i=t.attributes;i.length;)t.removeAttributeNode(i[0]);Pd(t,r,n),t[ot]=e,t[st]=n}catch(t){Z(e,e.return,t)}}var el=!1,tl=!1,nl=!1,rl=typeof WeakSet==`function`?WeakSet:Set,il=null;function al(e,t){if(e=e.containerInfo,Rd=sp,e=Dr(e),Or(e)){if(`selectionStart`in e)var n={start:e.selectionStart,end:e.selectionEnd};else a:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var a=r.anchorOffset,o=r.focusNode;r=r.focusOffset;try{n.nodeType,o.nodeType}catch{n=null;break a}var s=0,c=-1,l=-1,u=0,d=0,f=e,p=null;b:for(;;){for(var m;f!==n||a!==0&&f.nodeType!==3||(c=s+a),f!==o||r!==0&&f.nodeType!==3||(l=s+r),f.nodeType===3&&(s+=f.nodeValue.length),(m=f.firstChild)!==null;)p=f,f=m;for(;;){if(f===e)break b;if(p===n&&++u===a&&(c=s),p===o&&++d===r&&(l=s),(m=f.nextSibling)!==null)break;f=p,p=f.parentNode}f=m}n=c===-1||l===-1?null:{start:c,end:l}}else n=null}n||={start:0,end:0}}else n=null;for(zd={focusedElem:e,selectionRange:n},sp=!1,il=t;il!==null;)if(t=il,e=t.child,t.subtreeFlags&1028&&e!==null)e.return=t,il=e;else for(;il!==null;){switch(t=il,o=t.alternate,e=t.flags,t.tag){case 0:if(e&4&&(e=t.updateQueue,e=e===null?null:e.events,e!==null))for(n=0;n title`))),Pd(o,r,n),o[ot]=e,yt(o),r=o;break a;case`link`:var s=Vf(`link`,`href`,a).get(r+(n.href||``));if(s){for(var c=0;cg&&(o=g,g=h,h=o);var _=Tr(s,h),v=Tr(s,g);if(_&&v&&(p.rangeCount!==1||p.anchorNode!==_.node||p.anchorOffset!==_.offset||p.focusNode!==v.node||p.focusOffset!==v.offset)){var y=d.createRange();y.setStart(_.node,_.offset),p.removeAllRanges(),h>g?(p.addRange(y),p.extend(v.node,v.offset)):(y.setEnd(v.node,v.offset),p.addRange(y))}}}}for(d=[],p=s;p=p.parentNode;)p.nodeType===1&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for(typeof s.focus==`function`&&s.focus(),s=0;sn?32:n,N.T=null,n=lu,lu=null;var o=au,s=su;if(iu=0,ou=au=null,su=0,K&6)throw Error(i(331));var c=K;if(K|=4,Pl(o.current),El(o,o.current,s,n),K=c,id(0,!1),Fe&&typeof Fe.onPostCommitFiberRoot==`function`)try{Fe.onPostCommitFiberRoot(Pe,o)}catch{}return!0}finally{P.p=a,N.T=r,Vu(e,t)}}function Wu(e,t,n){t=vi(n,t),t=Qs(e.stateNode,t,2),e=Ua(e,t,2),e!==null&&(Xe(e,2),rd(e))}function Z(e,t,n){if(e.tag===3)Wu(e,e,n);else for(;t!==null;){if(t.tag===3){Wu(t,e,n);break}else if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError==`function`||typeof r.componentDidCatch==`function`&&(ru===null||!ru.has(r))){e=vi(n,e),n=$s(2),r=Ua(t,n,2),r!==null&&(ec(n,r,t,e),Xe(r,2),rd(r));break}}t=t.return}}function Gu(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new Rl;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(Hl=!0,i.add(n),e=Ku.bind(null,e,t,n),t.then(e,e))}function Ku(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,q===e&&(Y&n)===n&&(Wl===4||Wl===3&&(Y&62914560)===Y&&300>Te()-$l?!(K&2)&&Su(e,0):ql|=n,Yl===Y&&(Yl=0)),rd(e)}function qu(e,t){t===0&&(t=Je()),e=ri(e,t),e!==null&&(Xe(e,t),rd(e))}function Ju(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),qu(e,n)}function Yu(e,t){var n=0;switch(e.tag){case 31:case 13:var r=e.stateNode,a=e.memoizedState;a!==null&&(n=a.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(i(314))}r!==null&&r.delete(t),qu(e,n)}function Xu(e,t){return xe(e,t)}var Zu=null,Qu=null,$u=!1,ed=!1,td=!1,nd=0;function rd(e){e!==Qu&&e.next===null&&(Qu===null?Zu=Qu=e:Qu=Qu.next=e),ed=!0,$u||($u=!0,ud())}function id(e,t){if(!td&&ed){td=!0;do for(var n=!1,r=Zu;r!==null;){if(!t)if(e!==0){var i=r.pendingLanes;if(i===0)var a=0;else{var o=r.suspendedLanes,s=r.pingedLanes;a=(1<<31-Le(42|e)+1)-1,a&=i&~(o&~s),a=a&201326741?a&201326741|1:a?a|2:0}a!==0&&(n=!0,ld(r,a))}else a=Y,a=Ge(r,r===q?a:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),!(a&3)||Ke(r,a)||(n=!0,ld(r,a));r=r.next}while(n);td=!1}}function ad(){od()}function od(){ed=$u=!1;var e=0;nd!==0&&Gd()&&(e=nd);for(var t=Te(),n=null,r=Zu;r!==null;){var i=r.next,a=sd(r,t);a===0?(r.next=null,n===null?Zu=i:n.next=i,i===null&&(Qu=n)):(n=r,(e!==0||a&3)&&(ed=!0)),r=i}iu!==0&&iu!==5||id(e,!1),nd!==0&&(nd=0)}function sd(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,i=e.expirationTimes,a=e.pendingLanes&-62914561;0s)break;var u=c.transferSize,d=c.initiatorType;u&&Id(d)&&(c=c.responseEnd,o+=u*(c`u`?null:document;function xf(e,t,n){var r=bf;if(r&&typeof t==`string`&&t){var i=Rt(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),hf.has(i)||(hf.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),Pd(t,`link`,e),yt(t),r.head.appendChild(t)))}}function Sf(e){_f.D(e),xf(`dns-prefetch`,e,null)}function Cf(e,t){_f.C(e,t),xf(`preconnect`,e,t)}function wf(e,t,n){_f.L(e,t,n);var r=bf;if(r&&e&&t){var i=`link[rel="preload"][as="`+Rt(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+Rt(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+Rt(n.imageSizes)+`"]`)):i+=`[href="`+Rt(e)+`"]`;var a=i;switch(t){case`style`:a=Af(e);break;case`script`:a=Pf(e)}mf.has(a)||(e=h({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),mf.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(jf(a))||t===`script`&&r.querySelector(Ff(a))||(t=r.createElement(`link`),Pd(t,`link`,e),yt(t),r.head.appendChild(t)))}}function Tf(e,t){_f.m(e,t);var n=bf;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+Rt(r)+`"][href="`+Rt(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=Pf(e)}if(!mf.has(a)&&(e=h({rel:`modulepreload`,href:e},t),mf.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(Ff(a)))return}r=n.createElement(`link`),Pd(r,`link`,e),yt(r),n.head.appendChild(r)}}}function Ef(e,t,n){_f.S(e,t,n);var r=bf;if(r&&e){var i=vt(r).hoistableStyles,a=Af(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(jf(a)))s.loading=5;else{e=h({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=mf.get(a))&&Rf(e,n);var c=o=r.createElement(`link`);yt(c),Pd(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Lf(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function Df(e,t){_f.X(e,t);var n=bf;if(n&&e){var r=vt(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=h({src:e,async:!0},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),yt(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Of(e,t){_f.M(e,t);var n=bf;if(n&&e){var r=vt(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=h({src:e,async:!0,type:`module`},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),yt(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function kf(e,t,n,r){var a=(a=se.current)?gf(a):null;if(!a)throw Error(i(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(t=Af(n.href),n=vt(a).hoistableStyles,r=n.get(t),r||(r={type:`style`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=Af(n.href);var o=vt(a).hoistableStyles,s=o.get(e);if(s||(a=a.ownerDocument||a,s={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},o.set(e,s),(o=a.querySelector(jf(e)))&&!o._p&&(s.instance=o,s.state.loading=5),mf.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},mf.set(e,n),o||Nf(a,e,n,s.state))),t&&r===null)throw Error(i(528,``));return s}if(t&&r!==null)throw Error(i(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(t=Pf(n),n=vt(a).hoistableScripts,r=n.get(t),r||(r={type:`script`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(i(444,e))}}function Af(e){return`href="`+Rt(e)+`"`}function jf(e){return`link[rel="stylesheet"][`+e+`]`}function Mf(e){return h({},e,{"data-precedence":e.precedence,precedence:null})}function Nf(e,t,n,r){e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)?r.loading=1:(t=e.createElement(`link`),r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2}),Pd(t,`link`,n),yt(t),e.head.appendChild(t))}function Pf(e){return`[src="`+Rt(e)+`"]`}function Ff(e){return`script[async]`+e}function If(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+Rt(n.href)+`"]`);if(r)return t.instance=r,yt(r),r;var a=h({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),yt(r),Pd(r,`style`,a),Lf(r,n.precedence,e),t.instance=r;case`stylesheet`:a=Af(n.href);var o=e.querySelector(jf(a));if(o)return t.state.loading|=4,t.instance=o,yt(o),o;r=Mf(n),(a=mf.get(a))&&Rf(r,a),o=(e.ownerDocument||e).createElement(`link`),yt(o);var s=o;return s._p=new Promise(function(e,t){s.onload=e,s.onerror=t}),Pd(o,`link`,r),t.state.loading|=4,Lf(o,n.precedence,e),t.instance=o;case`script`:return o=Pf(n.src),(a=e.querySelector(Ff(o)))?(t.instance=a,yt(a),a):(r=n,(a=mf.get(o))&&(r=h({},n),zf(r,a)),e=e.ownerDocument||e,a=e.createElement(`script`),yt(a),Pd(a,`link`,r),e.head.appendChild(a),t.instance=a);case`void`:return null;default:throw Error(i(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Lf(r,n.precedence,e));return t.instance}function Lf(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o title`):null)}function Uf(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 Wf(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function Gf(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=Af(r.href),a=t.querySelector(jf(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=Jf.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,yt(a);return}a=t.ownerDocument||t,r=Mf(r),(i=mf.get(i))&&Rf(r,i),a=a.createElement(`link`),yt(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),Pd(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=Jf.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var Kf=0;function qf(e,t){return e.stylesheets&&e.count===0&&Xf(e,e.stylesheets),0Kf?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function Jf(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Xf(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var Yf=null;function Xf(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,Yf=new Map,t.forEach(Zf,e),Yf=null,Jf.call(e))}function Zf(e,t){if(!(t.state.loading&4)){var n=Yf.get(e);if(n)var r=n.get(null);else{n=new Map,Yf.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=h()})),_=e=>{let t,n=new Set,r=(e,r)=>{let i=typeof e==`function`?e(t):e;if(!Object.is(i,t)){let e=t;t=r??(typeof i!=`object`||!i)?i:Object.assign({},t,i),n.forEach(n=>n(t,e))}},i=()=>t,a={setState:r,getState:i,getInitialState:()=>o,subscribe:e=>(n.add(e),()=>n.delete(e))},o=t=e(r,i,a);return a},v=(e=>e?_(e):_),y=c(u(),1),b=e=>e;function x(e,t=b){let n=y.useSyncExternalStore(e.subscribe,y.useCallback(()=>t(e.getState()),[e,t]),y.useCallback(()=>t(e.getInitialState()),[e,t]));return y.useDebugValue(n),n}var S=e=>{let t=v(e),n=e=>x(t,e);return Object.assign(n,t),n},C=(e=>e?S(e):S),w=g(),T=`/api`;async function E(e,t){let n=await fetch(`${T}${e}`,{...t,headers:{"Content-Type":`application/json`,...t?.headers}});if(!n.ok){let e=await n.json().catch(()=>({detail:n.statusText}));throw Error(e.detail??`HTTP ${n.status}`)}if(n.status!==204)return n.json()}var D={getVersion:()=>E(`/version`),getAccounts:()=>E(`/accounts`),getAccount:e=>E(`/accounts/${e}`),createAccount:e=>E(`/accounts`,{method:`POST`,body:JSON.stringify(e)}),updateAccount:(e,t)=>E(`/accounts/${e}`,{method:`PUT`,body:JSON.stringify(t)}),deleteAccount:e=>E(`/accounts/${e}`,{method:`DELETE`}),deleteBulk:e=>E(`/accounts/delete-bulk`,{method:`POST`,body:JSON.stringify({ids:e})}),assignProxies:()=>E(`/accounts/assign-proxies`,{method:`POST`}),reassignProxies:()=>E(`/accounts/reassign-proxies`,{method:`POST`}),clearProxies:()=>E(`/accounts/clear-proxies`,{method:`POST`}),importAccounts:e=>{let t=new FormData;return t.append(`file`,e),fetch(`${T}/accounts/import`,{method:`POST`,body:t}).then(async e=>{if(!e.ok)throw Error((await e.json().catch(()=>({}))).detail??e.statusText);return e.json()})},executeAction:e=>E(`/actions`,{method:`POST`,body:JSON.stringify(e)}),respondToPrompt:(e,t,n)=>E(`/tasks/${e}/respond`,{method:`POST`,body:JSON.stringify({value:t,login:n||``})}),generate2FA:e=>E(`/actions/generate-2fa`,{method:`POST`,body:JSON.stringify({shared_secret:e})}),generate2FAByAccount:e=>E(`/actions/generate-2fa-by-account`,{method:`POST`,body:JSON.stringify({account_id:e})}),getConfirmations:e=>E(`/actions/confirmations/${e}`),respondConfirmations:(e,t,n,r)=>E(`/actions/confirmations/${e}/respond`,{method:`POST`,body:JSON.stringify({ids:t,nonces:n,accept:r})}),getProxies:()=>E(`/proxies`),addProxy:(e,t=`http`)=>E(`/proxies`,{method:`POST`,body:JSON.stringify({address:e,protocol:t})}),deleteProxy:e=>E(`/proxies/${e}`,{method:`DELETE`}),deleteAllProxies:()=>E(`/proxies/all`,{method:`DELETE`}),bulkAddProxies:e=>E(`/proxies/bulk`,{method:`POST`,body:JSON.stringify(e)}),checkProxies:()=>E(`/proxies/check`,{method:`POST`}),getTasks:()=>E(`/tasks`),getTask:e=>E(`/tasks/${e}`),cancelTask:e=>E(`/tasks/${e}`,{method:`DELETE`}),getMafiles:()=>E(`/mafiles`),uploadMafiles:e=>{let t=new FormData;return e.forEach(e=>t.append(`files`,e)),fetch(`${T}/mafiles/upload`,{method:`POST`,body:t}).then(async e=>{if(!e.ok)throw Error((await e.json().catch(()=>({}))).detail??e.statusText);return e.json()})},deleteMafile:e=>E(`/mafiles/${encodeURIComponent(e)}`,{method:`DELETE`}),exportSecrets:()=>E(`/mafiles/export/all`),exportZip:e=>fetch(`${T}/mafiles/export/zip`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)}).then(e=>{if(!e.ok)throw Error(`Export failed: ${e.status}`);return e.blob()}),getValidationSettings:()=>E(`/settings/validation`),updateValidationSettings:e=>E(`/settings/validation`,{method:`PUT`,body:JSON.stringify(e)}),getDisplaySettings:()=>E(`/settings/display`),updateDisplaySettings:e=>E(`/settings/display`,{method:`PUT`,body:JSON.stringify(e)}),getColumnSettings:()=>E(`/settings/columns`),updateColumnSettings:e=>E(`/settings/columns`,{method:`PUT`,body:JSON.stringify(e)}),getLogpassColumnSettings:()=>E(`/settings/logpass-columns`),updateLogpassColumnSettings:e=>E(`/settings/logpass-columns`,{method:`PUT`,body:JSON.stringify(e)}),getLogs:()=>E(`/logs`),startAutoAccept:e=>E(`/auto-accept/start`,{method:`POST`,body:JSON.stringify({account_ids:e})}),stopAutoAccept:e=>E(`/auto-accept/stop`,{method:`POST`,body:JSON.stringify({account_ids:e})}),getAutoAcceptStatus:()=>E(`/auto-accept/status`),openBrowser:e=>E(`/accounts/${e}/browser`,{method:`POST`}),getLogpassAccounts:()=>E(`/logpass`),createLogpassAccount:e=>E(`/logpass`,{method:`POST`,body:JSON.stringify(e)}),updateLogpassAccount:(e,t)=>E(`/logpass/${e}`,{method:`PUT`,body:JSON.stringify(t)}),deleteLogpassAccount:e=>E(`/logpass/${e}`,{method:`DELETE`}),deleteLogpassBulk:e=>E(`/logpass/delete-bulk`,{method:`POST`,body:JSON.stringify({ids:e})}),importLogpass:e=>E(`/logpass/import`,{method:`POST`,body:JSON.stringify({lines:e})}),validateLogpass:e=>E(`/logpass/validate`,{method:`POST`,body:JSON.stringify({account_ids:e})}),fullParseLogpass:e=>E(`/logpass/full-parse`,{method:`POST`,body:JSON.stringify({account_ids:e})}),assignLogpassProxies:()=>E(`/logpass/assign-proxies`,{method:`POST`}),reassignLogpassProxies:()=>E(`/logpass/reassign-proxies`,{method:`POST`}),clearLogpassProxies:()=>E(`/logpass/clear-proxies`,{method:`POST`}),openLogpassBrowser:e=>E(`/logpass/${e}/browser`,{method:`POST`}),getTokenAccounts:()=>E(`/token-accounts`),createTokenAccount:e=>E(`/token-accounts`,{method:`POST`,body:JSON.stringify(e)}),deleteTokenAccount:e=>E(`/token-accounts/${e}`,{method:`DELETE`}),deleteTokenBulk:e=>E(`/token-accounts/delete-bulk`,{method:`POST`,body:JSON.stringify({ids:e})}),importTokens:e=>E(`/token-accounts/import`,{method:`POST`,body:JSON.stringify({lines:e})}),validateTokens:e=>E(`/token-accounts/validate`,{method:`POST`,body:JSON.stringify({account_ids:e})}),openTokenBrowser:e=>E(`/token-accounts/${e}/browser`,{method:`POST`}),assignTokenProxies:()=>E(`/token-accounts/assign-proxies`,{method:`POST`}),reassignTokenProxies:()=>E(`/token-accounts/reassign-proxies`,{method:`POST`}),clearTokenProxies:()=>E(`/token-accounts/clear-proxies`,{method:`POST`}),getTokenColumnSettings:()=>E(`/settings/token-columns`),updateTokenColumnSettings:e=>E(`/settings/token-columns`,{method:`PUT`,body:JSON.stringify(e)})},O=0,ee={browser:!0,profile:!0,steam_id:!0,login:!0,password:!0,login_pass:!0,email:!0,email_pass:!1,email_login_pass:!1,phone:!0,status:!0,ban:!0,twofa:!0,mafile:!0,proxy:!0,notes:!0,actions:!0,last_online:!0},k={browser:!0,profile:!0,steam_id:!0,login:!0,password:!0,login_pass:!0,status:!0,ban:!0,prime:!0,trophy:!0,behavior:!0,license:!0,proxy:!0,notes:!0,actions:!0,last_online:!0},A={browser:!0,profile:!0,last_online:!0,steam_id:!0,login:!0,token:!0,status:!0,proxy:!0,notes:!0,actions:!0},j=C((e,t)=>({activeTab:`accounts`,setTab:t=>e({activeTab:t}),accountSection:`mafile`,setAccountSection:t=>e({accountSection:t}),toasts:[],addToast:(t,n)=>{let r=++O;e(e=>({toasts:[...e.toasts,{id:r,type:t,message:n}]})),setTimeout(()=>{e(e=>({toasts:e.toasts.filter(e=>e.id!==r)}))},4e3)},removeToast:t=>e(e=>({toasts:e.toasts.filter(e=>e.id!==t)})),hidePasswords:!1,setHidePasswords:t=>{e({hidePasswords:t}),D.updateDisplaySettings({hide_passwords:t}).catch(()=>{})},loadDisplaySettings:async()=>{try{e({hidePasswords:(await D.getDisplaySettings()).hide_passwords})}catch{}},columnVisibility:{...ee},setColumnVisibility:t=>e({columnVisibility:t}),toggleColumn:n=>{let r={...t().columnVisibility,[n]:!t().columnVisibility[n]};e({columnVisibility:r}),D.updateColumnSettings(r).catch(()=>{})},loadColumnSettings:async()=>{try{let t=await D.getColumnSettings();e({columnVisibility:{...ee,...t}})}catch{}},logpassColumnVisibility:{...k},toggleLogpassColumn:n=>{let r={...t().logpassColumnVisibility,[n]:!t().logpassColumnVisibility[n]};e({logpassColumnVisibility:r}),D.updateLogpassColumnSettings(r).catch(()=>{})},loadLogpassColumnSettings:async()=>{try{let t=await D.getLogpassColumnSettings();e({logpassColumnVisibility:{...k,...t}})}catch{}},tokenColumnVisibility:{...A},toggleTokenColumn:n=>{let r={...t().tokenColumnVisibility,[n]:!t().tokenColumnVisibility[n]};e({tokenColumnVisibility:r}),D.updateTokenColumnSettings(r).catch(()=>{})},loadTokenColumnSettings:async()=>{try{let t=await D.getTokenColumnSettings();e({tokenColumnVisibility:{...A,...t}})}catch{}}})),M=`steampanel_locale`,te=localStorage.getItem(M)||`ru`,ne=new Set;function N(){ne.forEach(e=>e())}function P(e){te=e,localStorage.setItem(M,e),N()}function re(){return[(0,y.useSyncExternalStore)(e=>(ne.add(e),()=>ne.delete(e)),()=>te),P]}var ie={ru:{"header.accounts":`Аккаунтов`,"tab.accounts":`Аккаунты`,"tab.mafiles":`Mafile Management`,"tab.tools":`Настройки`,"tab.logs":`Логи`,"section.dataType":`Тип данных`,"col.browser":`Войти`,"col.profile":`Профиль`,"col.lastOnline":`Отлега`,"col.steamId":`Steam ID`,"col.login":`Логин`,"col.password":`Пароль`,"col.loginPass":`Login:Pass`,"col.email":`Email`,"col.emailPass":`Email Pass`,"col.emailLoginPass":`Email:Pass`,"col.phone":`Телефон`,"col.status":`Статус`,"col.ban":`Бан`,"col.twofa":`2FA`,"col.mafile":`Mafile`,"col.proxy":`Прокси`,"col.notes":`Заметки`,"col.actions":`Действия`,"col.prime":`Prime`,"col.trophy":`Trophy`,"col.behavior":`Behavior`,"col.license":`Лицензии`,"col.token":`Токен`,"action.selectAction":`— Действие`,"action.validate":`Валидация`,"action.changePassword":`Сменить пароль`,"action.randomPassword":`Случайный пароль`,"action.changeEmail":`Сменить email`,"action.changePhone":`Сменить телефон`,"action.removePhone":`Удалить телефон`,"action.removeGuard":`Удалить Guard`,"action.noRevocationCode":`Нет revocation_code в mafile`,"action.enableAutoAccept":`Вкл. автопринятие`,"action.disableAutoAccept":`Выкл. авто-принятие входа`,"action.enableAutoAcceptLogin":`Вкл. авто-принятие входа`,"action.generate2fa":`Сгенерировать 2FA код`,"action.confirmations":`Подтверждения`,"prompt.newPassword":`Введите новый пароль`,"prompt.newEmail":`Введите новый email`,"prompt.newPhone":`Введите новый номер телефона`,"prompt.removePhone":`Введите номер телефона (на который переставится старый)`,"prompt.enterValue":`Введите значение...`,"confirm.removeGuard":`Удалить Steam Guard для этого аккаунта?`,"confirm.deleteAccount":`Удалить аккаунт?`,"confirm.deleteSelected":`Удалить {count} выбранных аккаунтов?`,"confirm.deleteAll":`Удалить ВСЕ {count} аккаунтов? Это необратимо!`,"confirm.deleteLogpassSelected":`Удалить {count} аккаунт(ов)?`,"confirm.deleteLogpassAll":`Удалить все {count} аккаунтов?`,"confirm.deleteTokenSelected":`Удалить {count} токен(ов)?`,"confirm.deleteTokenAll":`Удалить все {count} токенов?`,"confirm.deleteToken":`Удалить токен {name}?`,"confirm.deleteLogpass":`Удалить {name}?`,"confirm.assignProxies":`Назначить прокси аккаунтам без прокси?`,"confirm.reassignProxies":`Переназначить прокси на все аккаунты?`,"confirm.reassignProxiesAll":`Переназначить прокси всем аккаунтам?`,"confirm.clearProxies":`Очистить прокси у всех аккаунтов?`,"confirm.executeBulk":`Выполнить «{action}» для {count} аккаунтов?`,"confirm.yes":`Да`,"confirm.title":`Подтверждения`,"confirm.loading":`Загрузка подтверждений...`,"confirm.empty":`Нет ожидающих подтверждений`,"confirm.acceptAll":`Принять все`,"confirm.denyAll":`Отклонить все`,"confirm.refresh":`Обновить`,"confirm.accepted":`Принято`,"confirm.denied":`Отклонено`,"confirm.respondFailed":`Не удалось обработать подтверждение`,"btn.import":`Импорт`,"btn.add":`Добавить`,"btn.save":`Сохранить`,"btn.cancel":`Отмена`,"btn.execute":`Выполнить`,"btn.deleteSelected":`Удалить выбранные`,"btn.deleteAll":`Удалить все`,"btn.assignProxies":`Назначить прокси`,"btn.reassign":`Переназначить`,"btn.clearProxies":`Очистить прокси`,"btn.validate":`Валидировать`,"btn.fullParse":`Полный парс`,"btn.generate":`Сгенерировать`,"toast.copied":`Скопировано`,"toast.copyFailed":`Не удалось скопировать`,"toast.noteSaved":`Заметка сохранена`,"toast.noteSaveError":`Ошибка сохранения`,"toast.accountDeleted":`Аккаунт удален`,"toast.accountAdded":`Аккаунт добавлен`,"toast.saved":`Сохранено`,"toast.done":`Готово`,"toast.error":`Ошибка`,"toast.selectAction":`Выберите действие`,"toast.selectAccounts":`Выберите аккаунты`,"toast.noAccounts":`Нет аккаунтов`,"toast.autoAcceptEnabled":`Автопринятие включено для {count} акк.`,"toast.autoAcceptOn":`Авто-принятие входа включено`,"toast.autoAcceptOff":`Авто-принятие входа выключено`,"toast.taskCancelled":`Задача отменена`,"toast.browserOpening":`Браузер открывается...`,"toast.cookiesExpiredRevalidating":`Куки устарели. Запущена повторная валидация...`,"toast.cookiesExpired":`Куки устарели. Провалидируйте аккаунт заново.`,"toast.proxyCleared":`Прокси убран у {name}`,"toast.proxiesReassigned":`Переназначено {used} прокси на {count} акк.`,"toast.proxiesAssigned":`Назначено {used} прокси на {count} аккаунтов`,"toast.proxiesAssignedShort":`Назначено {count} аккаунтам`,"toast.proxiesReassignedShort":`Переназначено {count} аккаунтам`,"toast.proxiesClearedCount":`Очищено прокси у {count} аккаунтов`,"toast.proxiesClearedShort":`Очищено у {count} аккаунтов`,"toast.deleted":`Удалено: {count}`,"toast.sentToMafile":`{count} акк. отправлено в Mafile Management`,"toast.settingsSaved":`Настройки сохранены`,"toast.proxyFormatError":`Не удалось распознать прокси. Проверьте формат.`,"toast.proxiesAdded":`Добавлено {count} прокси`,"toast.proxiesDeleted":`Удалено {count} прокси`,"toast.exportDone":`Экспорт завершён`,"toast.uploaded":`Загружено: {count}`,"toast.uploadedWithErrors":`Загружено: {uploaded}, ошибок: {errors}`,"toast.importResult":`Импортировано: {imported}, Пропущено: {skipped}`,"toast.fileEmpty":`Файл пуст`,"task.validate":`Валидация`,"task.changePassword":`Смена пароля`,"task.randomPassword":`Случ. пароль`,"task.changeEmail":`Смена email`,"task.changePhone":`Смена телефона`,"task.removePhone":`Удал. телефона`,"task.removeGuard":`Удал. Guard`,"status.unknown":`Неизвестен`,"status.valid":`Валидный`,"status.invalid":`Невалидный`,"status.locked":`Заблокирован`,"status.limited":`Ограничен`,"status.banned":`БАН`,"status.ok":`ОК`,"tip.openBrowser":`Открыть Steam в браузере`,"tip.copyPassword":`Копировать пароль`,"tip.copyLoginPass":`Копировать login:pass`,"tip.copyEmailPass":`Копировать пароль email`,"tip.copyEmailLoginPass":`Копировать email:pass`,"tip.show":`Показать`,"tip.hide":`Скрыть`,"tip.gen2fa":`Сгенерировать и скопировать 2FA код`,"tip.code":`Код`,"tip.addNote":`Нажмите чтобы добавить заметку`,"tip.edit":`Редактировать`,"tip.delete":`Удалить`,"tip.autoAcceptActive":`Авто-принятие входа`,"tip.validate":`Валидировать`,"tip.columnSettings":`Настройки столбцов`,"tip.deleteProxy":`Удалить прокси`,"tip.clickToCopy":`Клик для копирования`,"tip.proxyError":`Ошибка прокси: {error}`,"ph.search":`Поиск: логин / Steam ID / заметка / lvl>10`,"ph.searchLogpass":`Поиск: логин / Steam ID / заметка / игра / lvl>10`,"ph.login":`Логин`,"ph.password":`Пароль`,"ph.proxy":`Прокси`,"ph.proxyOptional":`Прокси (необязательно)`,"ph.notes":`Заметки`,"ph.notesOptional":`Заметки (необязательно)`,"ph.loginOptional":`Логин (необязательно)`,"ph.emailPassword":`Пароль от email`,"empty.accounts":`Нет аккаунтов. Импортируйте файл`,"empty.logpass":`Аккаунтов нет. Импортируйте файл.`,"empty.tokens":`Токенов нет. Импортируйте или добавьте токены.`,"empty.logs":`Нет логов`,"empty.tasks":`Нет задач`,"modal.addAccount":`Добавить аккаунт`,"modal.editAccount":`Редактировать аккаунт`,"modal.importAccounts":`Импорт аккаунтов`,"modal.addToken":`Добавить токен`,"modal.importTokens":`Импорт токенов`,"import.formats":`Форматы`,"import.formatsColon":`Форматы:`,"import.delimiter":`разделитель`,"import.or":`или`,"import.dragTxt":`Перетащите .txt файл или нажмите для выбора`,"import.dragTxtCsv":`Перетащите .txt / .csv файл или нажмите для выбора`,"import.dragMafile":`Перетащите .mafile файлы или нажмите для выбора`,"import.attachMafile":`Прикрепить .mafile (необязательно)`,"import.selected":`Выбран: {name}`,"import.uploading":`Загрузка...`,"import.importBtn":`Импортировать`,"import.tokenFormat":`refresh_token (по одному на строку)`,"paging.shown":`Показано {visible} из {total}…`,"proxy.label":`Прокси {num}`,"proxy.title":`Прокси`,"proxy.count":`{count} шт.`,"proxy.protocol":`Протокол:`,"proxy.format":`Формат:`,"proxy.customFormat":`Свой формат...`,"proxy.formatConstructor":`Конструктор формата:`,"proxy.preview":`Предпросмотр:`,"proxy.dragFile":`Перетащите .txt файл с прокси или нажмите для выбора`,"proxy.addBtn":`Добавить`,"proxy.checking":`Проверка...`,"proxy.checkAll":`Проверить все`,"proxy.deleteAllBtn":`Удалить все прокси`,"proxy.confirmDeleteAll":`Удалить все прокси? Это действие нельзя отменить.`,"proxy.checkResult":`Всего: {total} | Живых: {alive} | Мёртвых: {dead}`,"proxy.removeProxy":`Убрать прокси`,"proxy.reassignProxy":`Переназначить прокси`,"proxy.perLine":`Прокси по одному на строку ({format})`,"proxy.deleteProxy":`Удалить прокси`,"tools.2faGenerator":`Генератор 2FA кода`,"tools.validationSettings":`Настройки валидации`,"tools.loadProfile":`Загружать профиль (никнейм, аватар)`,"tools.checkBans":`Проверять баны`,"tools.maxThreads":`Макс. потоков:`,"tools.autoRevalidateBrowser":`Автовалидация при мёртвых куках (браузер)`,"tools.clickCopy":`Клик для копирования`,"tools.genErrorStr":`Ошибка`,"logs.title":`Лог`,"logs.clear":`Очистить`,"logs.activeTasks":`Активные задачи`,"mafile.upload":`Загрузка Mafile`,"mafile.exportSettings":`Настройки экспорта`,"mafile.exportFormat":`Формат:`,"mafile.flatFiles":`Плоские файлы (.mafile)`,"mafile.perAccountFolder":`Папка на аккаунт`,"mafile.singleFile":`Одним файлом`,"mafile.variables":`Переменные:`,"mafile.folderName":`Название папки:`,"mafile.mafileName":`Название .mafile:`,"mafile.txtSettings":`Настройки .txt`,"mafile.addGlobalTxt":`Добавить общий`,"mafile.withAllAccounts":`со всеми аккаунтами`,"mafile.addTxtPerFolder":`Добавить .txt в каждую папку`,"mafile.skipFolders":`Не создавать папку для каждого аккаунта`,"mafile.txtFolderName":`Название .txt в папке:`,"mafile.txtLineFormat":`Формат строки .txt:`,"mafile.mafileFields":`Поля Mafile`,"mafile.sessionFields":`Поля Session`,"mafile.export":`Экспорт`,"mafile.noAccounts":`нет аккаунтов`,"mafile.sentAccounts":`Отправленные аккаунты`,"mafile.clearBtn":`Очистить`,"mafile.insert":`Вставить {value}`,"mafile.emptyTitle":`Нет выбранных аккаунтов`,"mafile.emptyHint":`Выберите аккаунты в таблице и отправьте сюда для экспорта mafile`,"mafile.accountsCount":`акк.`,"mafile.withMafile":`с mafile`,"mafile.namingSection":`Шаблоны имён`,"mafile.flat_mafiles":`Файлы`,"mafile.per_account_folder":`Папки`,"mafile.single_file":`Один файл`,"settings.display":`Отображение`,"settings.hidePasswords":`Скрывать пароли (спойлер)`,"token.disclaimerTitle":`Вкладка в разработке`,"token.disclaimerBody1":`Функциональность вкладки Token не завершена и находится в стадии разработки.`,"token.disclaimerBody2":`⚠ Валидация токенов может привести к их инвалидации (убить токены). Используйте на свой страх и риск.`,"token.disclaimerBody3":`Импорт, редактирование и любые действия с токенами могут работать некорректно.`,"token.acceptRisk":`Я понимаю риски и хочу продолжить`,"twofa.copied":`2FA: {code} (скопировано)`,"twofa.error":`Ошибка 2FA: {error}`,"misc.task":`Задача {id}`,"misc.taskAction":`Задача {id} - {action} ({login})`,"misc.taskCount":`Задача {id} ({count} акк.)`,"misc.error":`Ошибка: {error}`,"misc.proxyErrorCheck":`Ошибка проверки: {error}`,"misc.exportError":`Ошибка экспорта: {error}`,"misc.genError":`Ошибка генерации: {error}`,"misc.errorStr":`Ошибка`,"misc.insert":`Вставить`},en:{"header.accounts":`Accounts`,"tab.accounts":`Accounts`,"tab.mafiles":`Mafile Management`,"tab.tools":`Settings`,"tab.logs":`Logs`,"section.dataType":`Data Type`,"col.browser":`Login`,"col.profile":`Profile`,"col.lastOnline":`Last Online`,"col.steamId":`Steam ID`,"col.login":`Login`,"col.password":`Password`,"col.loginPass":`Login:Pass`,"col.email":`Email`,"col.emailPass":`Email Pass`,"col.emailLoginPass":`Email:Pass`,"col.phone":`Phone`,"col.status":`Status`,"col.ban":`Ban`,"col.twofa":`2FA`,"col.mafile":`Mafile`,"col.proxy":`Proxy`,"col.notes":`Notes`,"col.actions":`Actions`,"col.prime":`Prime`,"col.trophy":`Trophy`,"col.behavior":`Behavior`,"col.license":`Licenses`,"col.token":`Token`,"action.selectAction":`— Action`,"action.validate":`Validate`,"action.changePassword":`Change password`,"action.randomPassword":`Random password`,"action.changeEmail":`Change email`,"action.changePhone":`Change phone`,"action.removePhone":`Remove phone`,"action.removeGuard":`Remove Guard`,"action.noRevocationCode":`No revocation_code in mafile`,"action.enableAutoAccept":`Enable auto-accept`,"action.disableAutoAccept":`Disable login auto-accept`,"action.enableAutoAcceptLogin":`Enable login auto-accept`,"action.generate2fa":`Generate 2FA code`,"action.confirmations":`Confirmations`,"prompt.newPassword":`Enter new password`,"prompt.newEmail":`Enter new email`,"prompt.newPhone":`Enter new phone number`,"prompt.removePhone":`Enter phone number (old number will be transferred to it)`,"prompt.enterValue":`Enter value...`,"confirm.removeGuard":`Remove Steam Guard for this account?`,"confirm.deleteAccount":`Delete account?`,"confirm.deleteSelected":`Delete {count} selected accounts?`,"confirm.deleteAll":`Delete ALL {count} accounts? This is irreversible!`,"confirm.deleteLogpassSelected":`Delete {count} account(s)?`,"confirm.deleteLogpassAll":`Delete all {count} accounts?`,"confirm.deleteTokenSelected":`Delete {count} token(s)?`,"confirm.deleteTokenAll":`Delete all {count} tokens?`,"confirm.deleteToken":`Delete token {name}?`,"confirm.deleteLogpass":`Delete {name}?`,"confirm.assignProxies":`Assign proxies to accounts without proxies?`,"confirm.reassignProxies":`Reassign proxies to all accounts?`,"confirm.reassignProxiesAll":`Reassign proxies to all accounts?`,"confirm.clearProxies":`Clear proxies from all accounts?`,"confirm.executeBulk":`Execute «{action}» for {count} accounts?`,"confirm.yes":`Yes`,"confirm.title":`Confirmations`,"confirm.loading":`Loading confirmations...`,"confirm.empty":`No pending confirmations`,"confirm.acceptAll":`Accept all`,"confirm.denyAll":`Deny all`,"confirm.refresh":`Refresh`,"confirm.accepted":`Accepted`,"confirm.denied":`Denied`,"confirm.respondFailed":`Failed to process confirmation`,"btn.import":`Import`,"btn.add":`Add`,"btn.save":`Save`,"btn.cancel":`Cancel`,"btn.execute":`Execute`,"btn.deleteSelected":`Delete selected`,"btn.deleteAll":`Delete all`,"btn.assignProxies":`Assign proxies`,"btn.reassign":`Reassign`,"btn.clearProxies":`Clear proxies`,"btn.validate":`Validate`,"btn.fullParse":`Full parse`,"btn.generate":`Generate`,"toast.copied":`Copied`,"toast.copyFailed":`Failed to copy`,"toast.noteSaved":`Note saved`,"toast.noteSaveError":`Error saving`,"toast.accountDeleted":`Account deleted`,"toast.accountAdded":`Account added`,"toast.saved":`Saved`,"toast.done":`Done`,"toast.error":`Error`,"toast.selectAction":`Select an action`,"toast.selectAccounts":`Select accounts`,"toast.noAccounts":`No accounts`,"toast.autoAcceptEnabled":`Auto-accept enabled for {count} accounts`,"toast.autoAcceptOn":`Login auto-accept enabled`,"toast.autoAcceptOff":`Login auto-accept disabled`,"toast.taskCancelled":`Task cancelled`,"toast.browserOpening":`Opening browser...`,"toast.cookiesExpiredRevalidating":`Cookies expired. Re-validating...`,"toast.cookiesExpired":`Cookies expired. Re-validate the account.`,"toast.proxyCleared":`Proxy removed from {name}`,"toast.proxiesReassigned":`Reassigned {used} proxies to {count} accounts`,"toast.proxiesAssigned":`Assigned {used} proxies to {count} accounts`,"toast.proxiesAssignedShort":`Assigned to {count} accounts`,"toast.proxiesReassignedShort":`Reassigned to {count} accounts`,"toast.proxiesClearedCount":`Cleared proxies from {count} accounts`,"toast.proxiesClearedShort":`Cleared from {count} accounts`,"toast.deleted":`Deleted: {count}`,"toast.sentToMafile":`{count} accounts sent to Mafile Management`,"toast.settingsSaved":`Settings saved`,"toast.proxyFormatError":`Failed to parse proxies. Check the format.`,"toast.proxiesAdded":`Added {count} proxies`,"toast.proxiesDeleted":`Deleted {count} proxies`,"toast.exportDone":`Export complete`,"toast.uploaded":`Uploaded: {count}`,"toast.uploadedWithErrors":`Uploaded: {uploaded}, errors: {errors}`,"toast.importResult":`Imported: {imported}, Skipped: {skipped}`,"toast.fileEmpty":`File is empty`,"task.validate":`Validation`,"task.changePassword":`Password change`,"task.randomPassword":`Random password`,"task.changeEmail":`Email change`,"task.changePhone":`Phone change`,"task.removePhone":`Phone removal`,"task.removeGuard":`Guard removal`,"status.unknown":`Unknown`,"status.valid":`Valid`,"status.invalid":`Invalid`,"status.locked":`Locked`,"status.limited":`Limited`,"status.banned":`BANNED`,"status.ok":`OK`,"tip.openBrowser":`Open Steam in browser`,"tip.copyPassword":`Copy password`,"tip.copyLoginPass":`Copy login:pass`,"tip.copyEmailPass":`Copy email password`,"tip.copyEmailLoginPass":`Copy email:pass`,"tip.show":`Show`,"tip.hide":`Hide`,"tip.gen2fa":`Generate and copy 2FA code`,"tip.code":`Code`,"tip.addNote":`Click to add a note`,"tip.edit":`Edit`,"tip.delete":`Delete`,"tip.autoAcceptActive":`Login auto-accept`,"tip.validate":`Validate`,"tip.columnSettings":`Column settings`,"tip.deleteProxy":`Delete proxy`,"tip.clickToCopy":`Click to copy`,"tip.proxyError":`Proxy error: {error}`,"ph.search":`Search: login / Steam ID / notes / lvl>10`,"ph.searchLogpass":`Search: login / Steam ID / notes / game / lvl>10`,"ph.login":`Login`,"ph.password":`Password`,"ph.proxy":`Proxy`,"ph.proxyOptional":`Proxy (optional)`,"ph.notes":`Notes`,"ph.notesOptional":`Notes (optional)`,"ph.loginOptional":`Login (optional)`,"ph.emailPassword":`Email password`,"empty.accounts":`No accounts. Import a file`,"empty.logpass":`No accounts. Import a file.`,"empty.tokens":`No tokens. Import or add tokens.`,"empty.logs":`No logs`,"empty.tasks":`No tasks`,"modal.addAccount":`Add account`,"modal.editAccount":`Edit account`,"modal.importAccounts":`Import accounts`,"modal.addToken":`Add token`,"modal.importTokens":`Import tokens`,"import.formats":`Formats`,"import.formatsColon":`Formats:`,"import.delimiter":`delimiter`,"import.or":`or`,"import.dragTxt":`Drag a .txt file or click to select`,"import.dragTxtCsv":`Drag a .txt / .csv file or click to select`,"import.dragMafile":`Drag .mafile files or click to select`,"import.attachMafile":`Attach .mafile (optional)`,"import.selected":`Selected: {name}`,"import.uploading":`Uploading...`,"import.importBtn":`Import`,"import.tokenFormat":`refresh_token (one per line)`,"paging.shown":`Showing {visible} of {total}…`,"proxy.label":`Proxy {num}`,"proxy.title":`Proxies`,"proxy.count":`{count} total`,"proxy.protocol":`Protocol:`,"proxy.format":`Format:`,"proxy.customFormat":`Custom format...`,"proxy.formatConstructor":`Format constructor:`,"proxy.preview":`Preview:`,"proxy.dragFile":`Drag a .txt file with proxies or click to select`,"proxy.addBtn":`Add`,"proxy.checking":`Checking...`,"proxy.checkAll":`Check all`,"proxy.deleteAllBtn":`Delete all proxies`,"proxy.confirmDeleteAll":`Delete all proxies? This cannot be undone.`,"proxy.checkResult":`Total: {total} | Alive: {alive} | Dead: {dead}`,"proxy.removeProxy":`Remove proxy`,"proxy.reassignProxy":`Reassign proxy`,"proxy.perLine":`Proxies one per line ({format})`,"proxy.deleteProxy":`Delete proxy`,"tools.2faGenerator":`2FA Code Generator`,"tools.validationSettings":`Validation Settings`,"tools.loadProfile":`Load profile (nickname, avatar)`,"tools.checkBans":`Check bans`,"tools.maxThreads":`Max threads:`,"tools.autoRevalidateBrowser":`Auto-revalidate on dead cookies (browser)`,"tools.clickCopy":`Click to copy`,"tools.genErrorStr":`Error`,"logs.title":`Log`,"logs.clear":`Clear`,"logs.activeTasks":`Active Tasks`,"mafile.upload":`Upload Mafile`,"mafile.exportSettings":`Export Settings`,"mafile.exportFormat":`Format:`,"mafile.flatFiles":`Flat files (.mafile)`,"mafile.perAccountFolder":`Folder per account`,"mafile.singleFile":`Single file`,"mafile.variables":`Variables:`,"mafile.folderName":`Folder name:`,"mafile.mafileName":`.mafile name:`,"mafile.txtSettings":`.txt Settings`,"mafile.addGlobalTxt":`Add global`,"mafile.withAllAccounts":`with all accounts`,"mafile.addTxtPerFolder":`Add .txt to each folder`,"mafile.skipFolders":`Don't create folder for each account`,"mafile.txtFolderName":`.txt name in folder:`,"mafile.txtLineFormat":`.txt line format:`,"mafile.mafileFields":`Mafile Fields`,"mafile.sessionFields":`Session Fields`,"mafile.export":`Export`,"mafile.noAccounts":`no accounts`,"mafile.sentAccounts":`Sent Accounts`,"mafile.clearBtn":`Clear`,"mafile.insert":`Insert {value}`,"mafile.emptyTitle":`No accounts selected`,"mafile.emptyHint":`Select accounts in the table and send them here for mafile export`,"mafile.accountsCount":`accs`,"mafile.withMafile":`with mafile`,"mafile.namingSection":`Naming templates`,"mafile.flat_mafiles":`Files`,"mafile.per_account_folder":`Folders`,"mafile.single_file":`Single file`,"settings.display":`Display`,"settings.hidePasswords":`Hide passwords (spoiler)`,"token.disclaimerTitle":`Tab under development`,"token.disclaimerBody1":`Token tab functionality is not complete and is under development.`,"token.disclaimerBody2":`⚠ Token validation may invalidate (kill) tokens. Use at your own risk.`,"token.disclaimerBody3":`Import, editing and any actions with tokens may work incorrectly.`,"token.acceptRisk":`I understand the risks and want to continue`,"twofa.copied":`2FA: {code} (copied)`,"twofa.error":`2FA Error: {error}`,"misc.task":`Task {id}`,"misc.taskAction":`Task {id} - {action} ({login})`,"misc.taskCount":`Task {id} ({count} accounts)`,"misc.error":`Error: {error}`,"misc.proxyErrorCheck":`Check error: {error}`,"misc.exportError":`Export error: {error}`,"misc.genError":`Generation error: {error}`,"misc.errorStr":`Error`,"misc.insert":`Insert`}};function ae(e,t){let n=(ie[te]||ie.ru)[e]??ie.ru[e]??e;if(t)for(let[e,r]of Object.entries(t))n=n.replace(`{${e}}`,String(r));return n}function F(){return(0,y.useSyncExternalStore)(e=>(ne.add(e),()=>ne.delete(e)),()=>te),ae}var I=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),L=o(((e,t)=>{t.exports=I()}))();function oe(){let[e,t]=re(),[n,r]=(0,y.useState)(``);return(0,y.useEffect)(()=>{D.getVersion().then(e=>r(e.version)).catch(()=>{})},[]),(0,L.jsxs)(`header`,{className:`bg-dark-800 border-b border-dark-600 px-4 py-3 flex items-center justify-between`,children:[(0,L.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5 cursor-pointer`,onClick:()=>window.location.reload(),children:[(0,L.jsx)(`svg`,{viewBox:`0 0 24 24`,xmlns:`http://www.w3.org/2000/svg`,className:`w-7 h-7 shrink-0 fill-white`,children:(0,L.jsx)(`path`,{d:`M11.979 0C5.678 0 0.511 4.86 0.022 11.037l6.432 2.658c0.545 -0.371 1.203 -0.59 1.912 -0.59 0.063 0 0.125 0.004 0.188 0.006l2.861 -4.142V8.91c0 -2.495 2.028 -4.524 4.524 -4.524 2.494 0 4.524 2.031 4.524 4.527s-2.03 4.525 -4.524 4.525h-0.105l-4.076 2.911c0 0.052 0.004 0.105 0.004 0.159 0 1.875 -1.515 3.396 -3.39 3.396 -1.635 0 -3.016 -1.173 -3.331 -2.727L0.436 15.27C1.862 20.307 6.486 24 11.979 24c6.627 0 11.999 -5.373 11.999 -12S18.605 0 11.979 0zM7.54 18.21l-1.473 -0.61c0.262 0.543 0.714 0.999 1.314 1.25 1.297 0.539 2.793 -0.076 3.332 -1.375 0.263 -0.63 0.264 -1.319 0.005 -1.949s-0.75 -1.121 -1.377 -1.383c-0.624 -0.26 -1.29 -0.249 -1.878 -0.03l1.523 0.63c0.956 0.4 1.409 1.5 1.009 2.455 -0.397 0.957 -1.497 1.41 -2.454 1.012H7.54zm11.415 -9.303c0 -1.662 -1.353 -3.015 -3.015 -3.015 -1.665 0 -3.015 1.353 -3.015 3.015 0 1.665 1.35 3.015 3.015 3.015 1.663 0 3.015 -1.35 3.015 -3.015zm-5.273 -0.005c0 -1.252 1.013 -2.266 2.265 -2.266 1.249 0 2.266 1.014 2.266 2.266 0 1.251 -1.017 2.265 -2.266 2.265 -1.253 0 -2.265 -1.014 -2.265 -2.265z`})}),(0,L.jsx)(`h1`,{className:`text-lg font-bold text-white tracking-wide`,children:`SteamPanel`})]}),(0,L.jsx)(`span`,{className:`text-xs text-gray-500`,children:n&&`v${n}`}),(0,L.jsxs)(`span`,{className:`text-xs text-gray-500`,children:[`by`,` `,(0,L.jsx)(`a`,{href:`https://t.me/lolzdm`,target:`_blank`,rel:`noopener noreferrer`,className:`hover:text-accent transition`,children:`@lolzdm`})]})]}),(0,L.jsx)(`div`,{className:`flex items-center gap-4`,children:(0,L.jsxs)(`button`,{onClick:()=>t(e===`ru`?`en`:`ru`),className:`flex items-center gap-1.5 text-xs text-gray-400 hover:text-gray-200 transition px-2 py-1 border border-dark-500 hover:border-gray-500 rounded`,children:[(0,L.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:`13`,height:`13`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`1.8`,strokeLinecap:`round`,strokeLinejoin:`round`,className:`opacity-80`,children:[(0,L.jsx)(`circle`,{cx:`12`,cy:`12`,r:`10`}),(0,L.jsx)(`path`,{d:`M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z`})]}),e===`ru`?`EN`:`RU`]})})]})}var R=(e=16)=>({width:e,height:e,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`}),se=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`}),(0,L.jsx)(`polyline`,{points:`7 10 12 15 17 10`}),(0,L.jsx)(`line`,{x1:`12`,y1:`15`,x2:`12`,y2:`3`})]}),ce=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`}),(0,L.jsx)(`polyline`,{points:`17 8 12 3 7 8`}),(0,L.jsx)(`line`,{x1:`12`,y1:`3`,x2:`12`,y2:`15`})]}),le=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`line`,{x1:`12`,y1:`5`,x2:`12`,y2:`19`}),(0,L.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`})]}),ue=({size:e=16,...t})=>(0,L.jsx)(`svg`,{...R(e),...t,children:(0,L.jsx)(`polyline`,{points:`20 6 9 17 4 12`})}),de=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`line`,{x1:`18`,y1:`6`,x2:`6`,y2:`18`}),(0,L.jsx)(`line`,{x1:`6`,y1:`6`,x2:`18`,y2:`18`})]}),fe=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`path`,{d:`M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z`}),(0,L.jsx)(`line`,{x1:`12`,y1:`9`,x2:`12`,y2:`13`}),(0,L.jsx)(`line`,{x1:`12`,y1:`17`,x2:`12.01`,y2:`17`})]}),pe=({size:e=16,...t})=>(0,L.jsx)(`svg`,{...R(e),...t,children:(0,L.jsx)(`path`,{d:`m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2`})}),me=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`circle`,{cx:`12`,cy:`12`,r:`10`}),(0,L.jsx)(`line`,{x1:`2`,y1:`12`,x2:`22`,y2:`12`}),(0,L.jsx)(`path`,{d:`M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z`})]}),he=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`polyline`,{points:`23 4 23 10 17 10`}),(0,L.jsx)(`path`,{d:`M20.49 15a9 9 0 1 1-2.12-9.36L23 10`})]}),ge=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`circle`,{cx:`12`,cy:`12`,r:`10`}),(0,L.jsx)(`line`,{x1:`4.93`,y1:`4.93`,x2:`19.07`,y2:`19.07`})]}),_e=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`path`,{d:`M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z`}),(0,L.jsx)(`circle`,{cx:`12`,cy:`12`,r:`3`})]}),ve=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`path`,{d:`M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94`}),(0,L.jsx)(`path`,{d:`M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19`}),(0,L.jsx)(`line`,{x1:`1`,y1:`1`,x2:`23`,y2:`23`}),(0,L.jsx)(`path`,{d:`M14.12 14.12a3 3 0 1 1-4.24-4.24`})]}),ye=({size:e=16,...t})=>(0,L.jsx)(`svg`,{...R(e),...t,children:(0,L.jsx)(`path`,{d:`M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.78 7.78 5.5 5.5 0 0 1 7.78-7.78zm0 0L15.5 7.5m0 0 3 3L22 7l-3-3m-3.5 3.5L19 4`})}),be=({size:e=16,...t})=>(0,L.jsx)(`svg`,{...R(e),...t,children:(0,L.jsx)(`polygon`,{points:`13 2 3 14 12 14 11 22 21 10 12 10 13 2`})}),xe=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`circle`,{cx:`12`,cy:`12`,r:`3`}),(0,L.jsx)(`path`,{d:`M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z`})]}),Se=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`path`,{d:`M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7`}),(0,L.jsx)(`path`,{d:`M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z`})]}),Ce=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`polyline`,{points:`3 6 5 6 21 6`}),(0,L.jsx)(`path`,{d:`M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2`})]}),we=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`rect`,{x:`3`,y:`11`,width:`18`,height:`11`,rx:`2`,ry:`2`}),(0,L.jsx)(`path`,{d:`M7 11V7a5 5 0 0 1 10 0v4`})]}),Te=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`line`,{x1:`16.5`,y1:`9.4`,x2:`7.5`,y2:`4.21`}),(0,L.jsx)(`path`,{d:`M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z`}),(0,L.jsx)(`polyline`,{points:`3.27 6.96 12 12.01 20.73 6.96`}),(0,L.jsx)(`line`,{x1:`12`,y1:`22.08`,x2:`12`,y2:`12`})]}),Ee=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`path`,{d:`M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z`}),(0,L.jsx)(`polyline`,{points:`14 2 14 8 20 8`}),(0,L.jsx)(`line`,{x1:`16`,y1:`13`,x2:`8`,y2:`13`}),(0,L.jsx)(`line`,{x1:`16`,y1:`17`,x2:`8`,y2:`17`}),(0,L.jsx)(`polyline`,{points:`10 9 9 9 8 9`})]}),De=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`path`,{d:`M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2`}),(0,L.jsx)(`rect`,{x:`8`,y:`2`,width:`8`,height:`4`,rx:`1`,ry:`1`})]}),Oe=({size:e=16,...t})=>(0,L.jsx)(`svg`,{...R(e),...t,children:(0,L.jsx)(`polygon`,{points:`5 3 19 12 5 21 5 3`})}),ke=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`circle`,{cx:`12`,cy:`12`,r:`10`}),(0,L.jsx)(`line`,{x1:`15`,y1:`9`,x2:`9`,y2:`15`}),(0,L.jsx)(`line`,{x1:`9`,y1:`9`,x2:`15`,y2:`15`})]}),Ae=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`path`,{d:`M22 11.08V12a10 10 0 1 1-5.93-9.14`}),(0,L.jsx)(`polyline`,{points:`22 4 12 14.01 9 11.01`})]}),je=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`path`,{d:`M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2`}),(0,L.jsx)(`circle`,{cx:`9`,cy:`7`,r:`4`}),(0,L.jsx)(`path`,{d:`M22 21v-2a4 4 0 0 0-3-3.87`}),(0,L.jsx)(`path`,{d:`M16 3.13a4 4 0 0 1 0 7.75`})]}),Me=({size:e=16,...t})=>(0,L.jsx)(`svg`,{...R(e),...t,children:(0,L.jsx)(`path`,{d:`m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2`})}),Ne=({size:e=16,...t})=>(0,L.jsx)(`svg`,{...R(e),...t,children:(0,L.jsx)(`path`,{d:`M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z`})}),Pe=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`path`,{d:`M15 12h-5`}),(0,L.jsx)(`path`,{d:`M15 8h-5`}),(0,L.jsx)(`path`,{d:`M19 17V5a2 2 0 0 0-2-2H4`}),(0,L.jsx)(`path`,{d:`M8 21h12a2 2 0 0 0 2-2v-1a1 1 0 0 0-1-1H11a1 1 0 0 0-1 1v1a2 2 0 1 1-4 0V5a2 2 0 1 0-4 0v2`})]}),Fe=({size:e=16,...t})=>(0,L.jsx)(`svg`,{...R(e),...t,children:(0,L.jsx)(`polyline`,{points:`9 18 15 12 9 6`})}),Ie=[{id:`accounts`,labelKey:`tab.accounts`,icon:je},{id:`mafiles`,labelKey:`tab.mafiles`,icon:Me},{id:`tools`,labelKey:`tab.tools`,icon:Ne},{id:`logs`,labelKey:`tab.logs`,icon:Pe}];function Le(){let e=j(e=>e.activeTab),t=j(e=>e.setTab),n=F();return(0,L.jsx)(`nav`,{className:`bg-dark-800 border-b border-dark-600 flex gap-1 px-4 overflow-x-auto`,children:Ie.map(({id:r,labelKey:i,icon:a})=>(0,L.jsxs)(`button`,{onClick:()=>t(r),className:`flex items-center gap-1.5 px-4 py-2.5 text-sm font-medium transition-colors border-b-2 -mb-px ${e===r?`border-accent text-accent`:`border-transparent text-gray-400 hover:text-gray-200`}`,children:[(0,L.jsx)(a,{size:14}),n(i)]},r))})}function Re(){let e=j(e=>e.toasts),t=j(e=>e.removeToast);return e.length===0?null:(0,L.jsx)(`div`,{className:`toast-container`,children:e.map(e=>(0,L.jsx)(`div`,{className:`toast toast-${e.type}`,onClick:()=>t(e.id),children:e.message},e.id))})}var ze=C(e=>({accounts:[],selectedIds:new Set,loading:!1,loadAccounts:async()=>{e({loading:!0});try{e({accounts:await D.getAccounts()})}finally{e({loading:!1})}},toggleSelect:t=>e(e=>{let n=new Set(e.selectedIds);return n.has(t)?n.delete(t):n.add(t),{selectedIds:n}}),selectAll:()=>e(e=>({selectedIds:new Set(e.accounts.map(e=>e.id))})),clearSelection:()=>e({selectedIds:new Set}),setSelectedIds:t=>e({selectedIds:t}),mafileManagerIds:new Set,sendToMafileManager:t=>e(e=>{let n=new Set(e.mafileManagerIds);return t.forEach(e=>n.add(e)),{mafileManagerIds:n}}),clearMafileManager:()=>e({mafileManagerIds:new Set})})),Be=C(e=>({tasks:[],hasRunning:!1,loadTasks:async()=>{let t=await D.getTasks();e({tasks:t,hasRunning:t.some(e=>e.status===`running`||e.status===`pending`)})}})),Ve=C(e=>({accounts:[],selectedIds:new Set,loading:!1,loadAccounts:async()=>{e({loading:!0});try{e({accounts:await D.getLogpassAccounts()})}finally{e({loading:!1})}},toggleSelect:t=>e(e=>{let n=new Set(e.selectedIds);return n.has(t)?n.delete(t):n.add(t),{selectedIds:n}}),selectAll:()=>e(e=>({selectedIds:new Set(e.accounts.map(e=>e.id))})),clearSelection:()=>e({selectedIds:new Set})})),He=C(e=>({accounts:[],selectedIds:new Set,loading:!1,loadAccounts:async()=>{e({loading:!0});try{e({accounts:await D.getTokenAccounts()})}finally{e({loading:!1})}},toggleSelect:t=>e(e=>{let n=new Set(e.selectedIds);return n.has(t)?n.delete(t):n.add(t),{selectedIds:n}}),selectAll:()=>e(e=>({selectedIds:new Set(e.accounts.map(e=>e.id))})),clearSelection:()=>e({selectedIds:new Set})}));async function Ue(e){try{return await navigator.clipboard.writeText(e),!0}catch{return!1}}var We={unknown:[`badge-unknown`,`status.unknown`],valid:[`badge-ok`,`status.valid`],invalid:[`badge-error`,`status.invalid`],locked:[`badge-error`,`status.locked`],limited:[`badge-running`,`status.limited`]};function Ge({status:e}){let t=We[e],[n,r]=t?[t[0],ae(t[1])]:[`badge-unknown`,e];return(0,L.jsx)(`span`,{className:`badge ${n}`,children:r})}function Ke({status:e}){return e===`BANNED`?(0,L.jsx)(`span`,{className:`badge badge-error`,children:ae(`status.banned`)}):e===`NO BAN`?(0,L.jsx)(`span`,{className:`badge badge-ok`,children:ae(`status.ok`)}):(0,L.jsx)(`span`,{className:`badge badge-unknown`,children:`—`})}function qe({hasMafile:e}){return e?(0,L.jsx)(`span`,{className:`badge badge-ok`,children:`✓`}):(0,L.jsx)(`span`,{className:`badge badge-unknown`,children:`—`})}var Je=m(),Ye={0:`❓`,1:`🧪`,2:`🔄`,3:`🏪`,4:`⚙️`,5:`📱`,6:`🔑`};function Xe({account:e,onClose:t}){let n=F(),r=j(e=>e.addToast),[i,a]=(0,y.useState)([]),[o,s]=(0,y.useState)(!0),[c,l]=(0,y.useState)(new Set),[u,d]=(0,y.useState)(null),f=(0,y.useCallback)(async()=>{s(!0),d(null);try{a((await D.getConfirmations(e.id)).confirmations)}catch(e){d(e instanceof Error?e.message:String(e))}finally{s(!1)}},[e.id]);(0,y.useEffect)(()=>{f()},[f]);let p=async(t,i,o)=>{let s=new Set(c);t.forEach(e=>s.add(e)),l(s);try{let{success:s}=await D.respondConfirmations(e.id,t,i,o);s?(r(`success`,`${n(o?`confirm.accepted`:`confirm.denied`)} (${t.length})`),a(e=>e.filter(e=>!t.includes(e.id)))):r(`error`,n(`confirm.respondFailed`))}catch(e){r(`error`,e instanceof Error?e.message:String(e))}finally{l(e=>{let n=new Set(e);return t.forEach(e=>n.delete(e)),n})}};return(0,L.jsx)(`div`,{className:`confirm-overlay`,onMouseDown:t,children:(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-lg shadow-xl p-5 w-[560px] max-h-[80vh] flex flex-col`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsxs)(`div`,{className:`flex items-center justify-between mb-4`,children:[(0,L.jsxs)(`h2`,{className:`text-base font-semibold text-gray-200`,children:[n(`confirm.title`),` — `,e.login]}),(0,L.jsx)(`button`,{onClick:t,className:`text-gray-500 hover:text-gray-300 transition-colors`,children:(0,L.jsx)(de,{})})]}),o&&(0,L.jsxs)(`div`,{className:`flex items-center justify-center py-8 text-gray-400 text-sm`,children:[(0,L.jsx)(he,{className:`animate-spin mr-2 w-4 h-4`}),n(`confirm.loading`)]}),u&&(0,L.jsx)(`div`,{className:`bg-red-900/30 border border-red-700 rounded p-3 text-sm text-red-300 mb-3`,children:u}),!o&&!u&&i.length===0&&(0,L.jsx)(`p`,{className:`text-gray-400 text-sm text-center py-8`,children:n(`confirm.empty`)}),!o&&i.length>0&&(0,L.jsxs)(L.Fragment,{children:[(0,L.jsxs)(`div`,{className:`flex gap-2 mb-3`,children:[(0,L.jsxs)(`button`,{onClick:()=>{i.length!==0&&p(i.map(e=>e.id),i.map(e=>e.nonce),!0)},className:`btn-primary text-xs flex items-center gap-1`,children:[(0,L.jsx)(ue,{className:`w-3 h-3`}),n(`confirm.acceptAll`),` (`,i.length,`)`]}),(0,L.jsxs)(`button`,{onClick:()=>{i.length!==0&&p(i.map(e=>e.id),i.map(e=>e.nonce),!1)},className:`btn-secondary text-xs flex items-center gap-1`,children:[(0,L.jsx)(de,{className:`w-3 h-3`}),n(`confirm.denyAll`)]}),(0,L.jsxs)(`button`,{onClick:f,className:`btn-secondary text-xs flex items-center gap-1 ml-auto`,children:[(0,L.jsx)(he,{className:`w-3 h-3`}),n(`confirm.refresh`)]})]}),(0,L.jsx)(`div`,{className:`overflow-y-auto space-y-2 flex-1 min-h-0`,children:i.map(e=>{let t=c.has(e.id);return(0,L.jsxs)(`div`,{className:`bg-dark-700 border border-dark-600 rounded p-3 flex items-start gap-3 ${t?`opacity-50`:``}`,children:[e.icon?(0,L.jsx)(`img`,{src:e.icon,alt:``,className:`w-8 h-8 rounded flex-shrink-0 mt-0.5`}):(0,L.jsx)(`span`,{className:`text-xl flex-shrink-0 mt-0.5`,children:Ye[e.type]??`❓`}),(0,L.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,L.jsxs)(`div`,{className:`flex items-center gap-2 mb-1`,children:[(0,L.jsx)(`span`,{className:`text-xs px-1.5 py-0.5 rounded bg-dark-600 text-gray-400`,children:e.type_name}),(0,L.jsx)(`span`,{className:`text-sm text-gray-200 truncate`,children:e.headline})]}),e.summary.length>0&&(0,L.jsx)(`p`,{className:`text-xs text-gray-400 truncate`,children:e.summary.join(` • `)})]}),(0,L.jsxs)(`div`,{className:`flex gap-1 flex-shrink-0`,children:[(0,L.jsx)(`button`,{disabled:t,onClick:()=>p([e.id],[e.nonce],!0),className:`p-1.5 rounded bg-green-700/60 hover:bg-green-600/80 text-green-200 transition-colors`,title:e.accept,children:(0,L.jsx)(ue,{className:`w-3.5 h-3.5`})}),(0,L.jsx)(`button`,{disabled:t,onClick:()=>p([e.id],[e.nonce],!1),className:`p-1.5 rounded bg-red-700/60 hover:bg-red-600/80 text-red-200 transition-colors`,title:e.cancel,children:(0,L.jsx)(de,{className:`w-3.5 h-3.5`})})]})]},e.id)})})]})]})})}var Ze=[{action:`validate`,labelKey:`action.validate`},{action:`change_password`,labelKey:`action.changePassword`},{action:`random_password`,labelKey:`action.randomPassword`},{action:`change_email`,labelKey:`action.changeEmail`},{action:`change_phone`,labelKey:`action.changePhone`},{action:`remove_guard`,labelKey:`action.removeGuard`}],Qe={change_password:`prompt.newPassword`,change_email:`prompt.newEmail`,change_phone:`prompt.newPhone`},$e={change_password:`new_password`,change_email:`new_email`,change_phone:`new_phone`},et={remove_guard:`confirm.removeGuard`};function tt({account:e,onAction:t,onToggleAutoAccept:n}){let[r,i]=(0,y.useState)(!1),[a,o]=(0,y.useState)(null),[s,c]=(0,y.useState)(``),[l,u]=(0,y.useState)(null),[d,f]=(0,y.useState)(!1),[p,m]=(0,y.useState)(null),h=(0,y.useRef)(null),g=(0,y.useRef)(null),_=j(e=>e.addToast),v=ze(e=>e.loadAccounts),b=F(),x=(0,y.useCallback)(()=>{if(!g.current)return;let e=g.current.getBoundingClientRect();m({top:window.innerHeight-e.bottom<320?Math.max(4,e.top-320):e.bottom+4,left:Math.max(4,e.right-180)})},[]);(0,y.useEffect)(()=>{if(!r)return;x();function e(e){h.current&&!h.current.contains(e.target)&&g.current&&!g.current.contains(e.target)&&i(!1)}function t(){i(!1)}return document.addEventListener(`mousedown`,e),window.addEventListener(`scroll`,t,!0),()=>{document.removeEventListener(`mousedown`,e),window.removeEventListener(`scroll`,t,!0)}},[r,x]);let S=(n,r)=>{i(!1);let a=et[n];if(a){u({action:n,title:b(a)});return}let s=Qe[n];s?(o({action:n,title:b(s)}),c(``)):t(e.id,n,{})},C=()=>{if(!a||!s)return;let n=$e[a.action]||`value`;t(e.id,a.action,{[n]:s}),o(null)},w=e.auto_accept?b(`action.disableAutoAccept`):b(`action.enableAutoAcceptLogin`);return(0,L.jsxs)(L.Fragment,{children:[(0,L.jsxs)(`div`,{className:`relative inline-block`,children:[(0,L.jsx)(`button`,{ref:g,onClick:()=>i(!r),className:`btn-secondary px-2 py-1 text-xs`,children:(0,L.jsx)(be,{size:12})}),r&&p&&(0,Je.createPortal)((0,L.jsxs)(`div`,{ref:h,className:`action-menu-dropdown`,style:{position:`fixed`,top:p.top,left:p.left},children:[Ze.map(({action:t,labelKey:n})=>t===`remove_guard`&&!e.has_revocation_code?(0,L.jsx)(`span`,{"data-tooltip":b(`action.noRevocationCode`),className:`block`,children:(0,L.jsx)(`button`,{className:`action-menu-item opacity-40 cursor-not-allowed`,disabled:!0,children:b(n)})},t):(0,L.jsx)(`button`,{onClick:()=>S(t,b(n)),className:`action-menu-item`,children:b(n)},t)),(0,L.jsx)(`hr`,{className:`border-dark-600 my-1`}),(0,L.jsx)(`button`,{onClick:async()=>{if(i(!1),!e.shared_secret){_(`error`,b(`twofa.error`,{error:`No shared_secret`}));return}try{let{code:t}=await D.generate2FA(e.shared_secret);await Ue(t),_(`success`,b(`twofa.copied`,{code:t}))}catch(e){_(`error`,b(`twofa.error`,{error:e instanceof Error?e.message:String(e)}))}},disabled:!e.shared_secret,className:`action-menu-item ${e.shared_secret?``:`opacity-40 cursor-not-allowed`}`,children:b(`action.generate2fa`)}),(0,L.jsx)(`button`,{onClick:()=>{i(!1),f(!0)},disabled:!e.identity_secret,className:`action-menu-item ${e.identity_secret?``:`opacity-40 cursor-not-allowed`}`,children:b(`action.confirmations`)}),(0,L.jsx)(`hr`,{className:`border-dark-600 my-1`}),(0,L.jsx)(`button`,{onClick:async()=>{i(!1);try{await D.updateAccount(e.id,{proxy:``}),_(`success`,b(`toast.proxyCleared`,{name:e.login})),await v()}catch(e){_(`error`,b(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}},className:`action-menu-item`,children:b(`proxy.removeProxy`)}),(0,L.jsx)(`button`,{onClick:async()=>{i(!1);try{let e=await D.reassignProxies();_(`success`,b(`toast.proxiesReassigned`,{used:e.proxies_used,count:e.assigned})),await v()}catch(e){_(`error`,b(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}},className:`action-menu-item`,children:b(`proxy.reassignProxy`)}),(0,L.jsx)(`hr`,{className:`border-dark-600 my-1`}),(0,L.jsx)(`button`,{onClick:()=>{i(!1),n(e.id)},className:`action-menu-item`,children:w})]}),document.body)]}),a&&(0,L.jsx)(`div`,{className:`confirm-overlay`,onMouseDown:()=>o(null),children:(0,L.jsxs)(`div`,{className:`confirm-box`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`p`,{className:`text-sm text-gray-300 mb-3`,children:a.title}),(0,L.jsx)(`input`,{autoFocus:!0,value:s,onChange:e=>c(e.target.value),onKeyDown:e=>e.key===`Enter`&&C(),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm mb-3`,placeholder:a.action.includes(`phone`)?`+7 9123456789`:void 0}),(0,L.jsxs)(`div`,{className:`flex gap-2`,children:[(0,L.jsx)(`button`,{onClick:C,className:`btn-primary flex-1`,children:`OK`}),(0,L.jsx)(`button`,{onClick:()=>o(null),className:`btn-secondary flex-1`,children:b(`btn.cancel`)})]})]})}),l&&(0,L.jsx)(`div`,{className:`confirm-overlay`,onMouseDown:()=>u(null),children:(0,L.jsxs)(`div`,{className:`confirm-box`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`p`,{className:`text-sm text-gray-300 mb-3`,children:l.title}),(0,L.jsxs)(`div`,{className:`flex gap-2`,children:[(0,L.jsx)(`button`,{autoFocus:!0,onClick:()=>{t(e.id,l.action,{}),u(null)},className:`btn-primary flex-1`,children:b(`confirm.yes`)}),(0,L.jsx)(`button`,{onClick:()=>u(null),className:`btn-secondary flex-1`,children:b(`btn.cancel`)})]})]})}),d&&(0,L.jsx)(Xe,{account:e,onClose:()=>f(!1)})]})}function nt({level:e}){return e>=100?(0,L.jsx)(`div`,{className:`steam-lvl l100p img-${Math.floor(e/100)*100}`,title:`Level ${e}`,children:(0,L.jsx)(`span`,{children:e})}):(0,L.jsx)(`div`,{className:`steam-lvl l${Math.floor(e/10)*10}`,title:`Level ${e}`,children:(0,L.jsx)(`span`,{children:e})})}function rt({account:e,visibleColumns:t,proxyLabel:n,isProcessing:r,accountResult:i,accountStep:a,onEdit:o,onDelete:s,onAction:c,onToggleAutoAccept:l,onOpenBrowser:u}){let d=ze(e=>e.selectedIds),f=ze(e=>e.toggleSelect),p=j(e=>e.addToast),m=j(e=>e.hidePasswords),[h,g]=(0,y.useState)(!1),[_,v]=(0,y.useState)(!1),[b,x]=(0,y.useState)(e.notes||``),S=F(),C=async e=>{let t=await Ue(e);p(t?`success`:`error`,S(t?`toast.copied`:`toast.copyFailed`))},w=m&&!h,T=`••••••••`;return(0,L.jsxs)(`tr`,{className:`hover:bg-dark-700/50 transition`,children:[(0,L.jsx)(`td`,{className:`px-3 py-2`,children:(0,L.jsx)(`input`,{type:`checkbox`,checked:d.has(e.id),onChange:()=>f(e.id)})}),(0,L.jsx)(`td`,{className:`px-1 py-2 w-5`,children:r?(0,L.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,L.jsx)(`div`,{className:`w-4 h-4 border-2 border-accent border-t-transparent rounded-full animate-spin shrink-0`}),a&&(0,L.jsxs)(`span`,{className:`text-[10px] text-gray-500 whitespace-nowrap`,children:[`[`,a.step,`/`,a.total,`]`]})]}):i?.status===`ok`?(0,L.jsx)(ue,{size:16,className:`text-gray-400`}):i?.status===`error`?(0,L.jsx)(`span`,{title:i.error?.toLowerCase().includes(`proxy`)||i.error?.toLowerCase().includes(`network`)||i.error?.includes(`WinError`)?S(`tip.proxyError`,{error:i.error}):i.error,children:(0,L.jsx)(fe,{size:16,className:`text-red-400`})}):null}),t.browser&&(0,L.jsx)(`td`,{className:`px-3 py-2 whitespace-nowrap text-center`,children:e.has_cookies?(0,L.jsx)(`button`,{onClick:()=>u(e.id),className:`px-2 py-0.5 text-xs font-medium rounded bg-blue-600/20 text-blue-400 border border-blue-500/30 hover:bg-blue-600/40 hover:text-blue-300 active:scale-95 transition`,title:S(`tip.openBrowser`),children:S(`col.browser`)}):(0,L.jsx)(`span`,{className:`text-gray-600 text-xs`,children:`—`})}),t.profile&&(0,L.jsx)(`td`,{className:`px-3 py-2 whitespace-nowrap`,children:(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[e.avatar_url&&(0,L.jsx)(`img`,{src:e.avatar_url,className:`avatar-sm`,alt:``}),(0,L.jsx)(`span`,{className:`text-xs`,children:e.nickname||`—`}),e.steam_level!=null&&(0,L.jsx)(nt,{level:e.steam_level})]})}),t.last_online&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs text-gray-400 whitespace-nowrap`,children:e.last_online||`—`}),t.steam_id&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs`,children:e.steam_id?(0,L.jsx)(`a`,{href:`https://steamcommunity.com/profiles/${encodeURIComponent(e.steam_id)}/`,target:`_blank`,rel:`noopener noreferrer`,className:`text-blue-400 hover:text-blue-300 hover:underline`,children:e.steam_id}):`—`}),t.login&&(0,L.jsx)(`td`,{className:`px-3 py-2 font-medium`,children:e.login}),t.password&&(0,L.jsxs)(`td`,{className:`px-3 py-2 text-gray-400 select-none whitespace-nowrap`,children:[(0,L.jsx)(`span`,{className:`cell-copy cursor-pointer`,onClick:()=>C(e.password),title:S(`tip.copyPassword`),children:w?T:e.password}),(0,L.jsx)(`button`,{onClick:e=>{e.stopPropagation(),g(!h)},className:`ml-1.5 text-gray-500 hover:text-gray-300 inline-flex align-middle`,title:S(w?`tip.show`:`tip.hide`),children:w?(0,L.jsx)(_e,{size:14}):(0,L.jsx)(ve,{size:14})})]}),t.login_pass&&(0,L.jsxs)(`td`,{className:`px-3 py-2 text-gray-400 text-xs select-none whitespace-nowrap`,children:[(0,L.jsx)(`span`,{className:`cell-copy cursor-pointer`,onClick:()=>C(`${e.login}:${e.password}`),title:S(`tip.copyLoginPass`),children:w?`${e.login}:${T}`:`${e.login}:${e.password}`}),(0,L.jsx)(`button`,{onClick:e=>{e.stopPropagation(),g(!h)},className:`ml-1.5 text-gray-500 hover:text-gray-300 inline-flex align-middle`,title:S(w?`tip.show`:`tip.hide`),children:w?(0,L.jsx)(_e,{size:14}):(0,L.jsx)(ve,{size:14})})]}),t.email&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-gray-400 text-xs`,children:e.email||`—`}),t.email_pass&&(0,L.jsxs)(`td`,{className:`px-3 py-2 text-gray-400 text-xs select-none whitespace-nowrap`,children:[(0,L.jsx)(`span`,{className:`cell-copy cursor-pointer`,onClick:()=>{e.email_password&&C(e.email_password)},title:e.email_password?S(`tip.copyEmailPass`):``,children:e.email_password?w?T:e.email_password:`—`}),e.email_password&&(0,L.jsx)(`button`,{onClick:e=>{e.stopPropagation(),g(!h)},className:`ml-1.5 text-gray-500 hover:text-gray-300 inline-flex align-middle`,title:S(w?`tip.show`:`tip.hide`),children:w?(0,L.jsx)(_e,{size:14}):(0,L.jsx)(ve,{size:14})})]}),t.email_login_pass&&(0,L.jsxs)(`td`,{className:`px-3 py-2 text-gray-400 text-xs select-none whitespace-nowrap`,children:[(0,L.jsx)(`span`,{className:`cell-copy cursor-pointer`,onClick:()=>{e.email&&e.email_password&&C(`${e.email}:${e.email_password}`)},title:e.email&&e.email_password?S(`tip.copyEmailLoginPass`):``,children:e.email&&e.email_password?w?`${e.email}:${T}`:`${e.email}:${e.email_password}`:`—`}),e.email&&e.email_password&&(0,L.jsx)(`button`,{onClick:e=>{e.stopPropagation(),g(!h)},className:`ml-1.5 text-gray-500 hover:text-gray-300 inline-flex align-middle`,title:S(w?`tip.show`:`tip.hide`),children:w?(0,L.jsx)(_e,{size:14}):(0,L.jsx)(ve,{size:14})})]}),t.phone&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-gray-400 text-xs`,children:e.phone||`—`}),t.status&&(0,L.jsx)(`td`,{className:`px-3 py-2`,children:(0,L.jsx)(Ge,{status:e.status})}),t.ban&&(0,L.jsx)(`td`,{className:`px-3 py-2`,children:(0,L.jsx)(Ke,{status:e.ban_status})}),t.twofa&&(0,L.jsx)(`td`,{className:`px-3 py-2 whitespace-nowrap`,children:e.shared_secret?(0,L.jsxs)(`button`,{onClick:async()=>{try{let{code:t}=await D.generate2FA(e.shared_secret);await Ue(t),p(`success`,S(`twofa.copied`,{code:t}))}catch(e){p(`error`,S(`twofa.error`,{error:e instanceof Error?e.message:String(e)}))}},className:`text-accent hover:underline text-xs`,title:S(`tip.gen2fa`),children:[(0,L.jsx)(ye,{size:12,className:`inline mr-0.5`}),` `,S(`tip.code`)]}):(0,L.jsx)(`span`,{className:`text-gray-600 text-xs`,children:`—`})}),t.mafile&&(0,L.jsx)(`td`,{className:`px-3 py-2`,children:(0,L.jsx)(qe,{hasMafile:!!e.mafile_path})}),t.proxy&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs`,children:e.proxy?(0,L.jsx)(`span`,{className:`text-blue-400 cursor-pointer hover:underline`,onClick:()=>C(e.proxy),title:e.proxy,children:n||e.proxy}):`—`}),t.notes&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs max-w-[180px]`,children:_?(0,L.jsx)(`input`,{autoFocus:!0,className:`w-full bg-dark-600 border border-dark-500 rounded px-1.5 py-0.5 text-xs text-gray-200 outline-none focus:border-accent`,value:b,onChange:e=>x(e.target.value),onBlur:async()=>{if(v(!1),b!==(e.notes||``))try{await D.updateAccount(e.id,{notes:b}),p(`success`,S(`toast.noteSaved`)),ze.getState().loadAccounts()}catch{p(`error`,S(`toast.noteSaveError`))}},onKeyDown:t=>{t.key===`Enter`&&t.target.blur(),t.key===`Escape`&&(x(e.notes||``),v(!1))}}):(0,L.jsx)(`span`,{className:`cursor-pointer text-gray-400 hover:text-gray-200 truncate block`,onClick:()=>{x(e.notes||``),v(!0)},title:e.notes||S(`tip.addNote`),children:e.notes||`—`})}),t.actions&&(0,L.jsx)(`td`,{className:`px-3 py-2 whitespace-nowrap`,children:(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,L.jsx)(tt,{account:e,onAction:c,onToggleAutoAccept:l}),(0,L.jsx)(`button`,{onClick:()=>o(e.id),className:`text-gray-400 hover:text-accent`,title:S(`tip.edit`),children:(0,L.jsx)(Se,{size:14})}),(0,L.jsx)(`button`,{onClick:()=>s(e.id),className:`text-gray-400 hover:text-red-400`,title:S(`tip.delete`),children:(0,L.jsx)(Ce,{size:14})}),e.auto_accept?(0,L.jsx)(`span`,{title:S(`tip.autoAcceptActive`),children:(0,L.jsx)(he,{size:14,className:`text-accent`})}):null]})})]})}var it=[`browser`,`profile`,`last_online`,`steam_id`,`login`,`password`,`login_pass`,`email`,`email_pass`,`email_login_pass`,`phone`,`status`,`ban`,`twofa`,`mafile`,`proxy`,`notes`,`actions`],at={browser:`col.browser`,profile:`col.profile`,last_online:`col.lastOnline`,steam_id:`col.steamId`,login:`col.login`,password:`col.password`,login_pass:`col.loginPass`,email:`col.email`,email_pass:`col.emailPass`,email_login_pass:`col.emailLoginPass`,phone:`col.phone`,status:`col.status`,ban:`col.ban`,twofa:`col.twofa`,mafile:`col.mafile`,proxy:`col.proxy`,notes:`col.notes`,actions:`col.actions`};function ot({accounts:e,processingIds:t,accountResults:n,accountSteps:r,onEdit:i,onDelete:a,onAction:o,onToggleAutoAccept:s,onOpenBrowser:c}){let l=ze(e=>e.selectAll),u=ze(e=>e.clearSelection),d=ze(e=>e.selectedIds),f=j(e=>e.columnVisibility),p=F(),m=e.length>0&&d.size===e.length,h=it.filter(e=>f[e]),[g,_]=(0,y.useState)(100),v=(0,y.useRef)(null),[b,x]=(0,y.useState)(null),[S,C]=(0,y.useState)(`asc`),w=e=>{b===e?S===`asc`?C(`desc`):(x(null),C(`asc`)):(x(e),C(`asc`))},T=(0,y.useMemo)(()=>{if(!b)return e;let t=S===`asc`?1:-1,n=Symbol();return[...e].sort((e,r)=>{let i=e=>{if(!e||e===`—`)return n;if(e===`online`)return-1;let t=e.match(/^(\d+)([mhd])$/i);if(!t)return n;let r=parseInt(t[1],10);return t[2]===`m`?r:t[2]===`h`?r*60:r*1440},a=i(e.last_online),o=i(r.last_online);return a===n&&o===n?0:a===n?1:o===n?-1:a===o?0:(a{_(100)},[e,b,S]);let E=(0,y.useMemo)(()=>T.slice(0,g),[T,g]);(0,y.useEffect)(()=>{let e=v.current;if(!e)return;let t=new IntersectionObserver(e=>{e[0].isIntersecting&&_(e=>Math.min(e+100,T.length))},{rootMargin:`400px`});return t.observe(e),()=>t.disconnect()},[T.length,g]);let D=(0,y.useMemo)(()=>{let t=new Map,n=[];for(let t of e)t.proxy&&!n.includes(t.proxy)&&n.push(t.proxy);let r=new Map;n.forEach((e,t)=>r.set(e,t+1));for(let n of e)if(n.proxy){let e=r.get(n.proxy);t.set(n.id,e?p(`proxy.label`,{num:e}):n.proxy)}return t},[e]);return e.length?(0,L.jsx)(`div`,{className:`overflow-x-auto`,children:(0,L.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,L.jsx)(`thead`,{className:`sticky top-0 bg-dark-800 z-10`,children:(0,L.jsxs)(`tr`,{className:`text-left text-xs text-gray-500 border-b border-dark-600`,children:[(0,L.jsx)(`th`,{className:`px-3 py-2`,children:(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,L.jsx)(`input`,{type:`checkbox`,checked:m,onChange:()=>m?u():l()}),d.size>0&&(0,L.jsx)(`span`,{className:`text-accent font-medium`,children:d.size})]})}),(0,L.jsx)(`th`,{className:`w-5`}),h.map(e=>e===`last_online`?(0,L.jsxs)(`th`,{className:`px-3 py-2 cursor-pointer select-none hover:text-gray-300`,onClick:()=>w(`last_online`),children:[p(at[e]),b===`last_online`?S===`asc`?` ▲`:` ▼`:``]},e):(0,L.jsx)(`th`,{className:`px-3 py-2${e===`browser`?` text-center`:``}`,children:p(at[e])},e))]})}),(0,L.jsxs)(`tbody`,{children:[E.map(e=>(0,L.jsx)(rt,{account:e,visibleColumns:f,proxyLabel:D.get(e.id)??null,isProcessing:t.has(e.id),accountResult:n[String(e.id)],accountStep:r[String(e.id)],onEdit:i,onDelete:a,onAction:o,onToggleAutoAccept:s,onOpenBrowser:c},e.id)),g{m.current?.focus()},[]),(0,L.jsx)(`div`,{className:`confirm-overlay`,onMouseDown:n,children:(0,L.jsxs)(`div`,{className:`confirm-box max-w-md`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`h3`,{className:`text-lg font-semibold mb-4`,children:r(`modal.editAccount`)}),(0,L.jsxs)(`div`,{className:`space-y-3`,children:[(0,L.jsx)(`input`,{ref:m,value:i,onChange:e=>a(e.target.value),placeholder:r(`ph.login`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:o,onChange:e=>s(e.target.value),placeholder:r(`ph.password`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:c,onChange:e=>l(e.target.value),placeholder:`Email`,className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:u,onChange:e=>d(e.target.value),placeholder:r(`ph.proxy`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:f,onChange:e=>p(e.target.value),placeholder:r(`ph.notes`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`button`,{onClick:()=>{t(e.id,{login:i,password:o,email:c||void 0,proxy:u||void 0,notes:f||void 0})},className:`btn-primary w-full`,children:r(`btn.save`)})]})]})})}function ct({onClose:e}){let t=F(),[n,r]=(0,y.useState)(null),[i,a]=(0,y.useState)(``),[o,s]=(0,y.useState)(!1),c=(0,y.useRef)(null),l=j(e=>e.addToast),u=ze(e=>e.loadAccounts);return(0,L.jsx)(`div`,{className:`confirm-overlay`,onMouseDown:e,children:(0,L.jsxs)(`div`,{className:`confirm-box max-w-lg w-full`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`h3`,{className:`text-lg font-semibold mb-4`,children:t(`modal.importAccounts`)}),(0,L.jsxs)(`div`,{className:`text-sm text-gray-400 mb-3 space-y-1`,children:[(0,L.jsxs)(`p`,{className:`font-medium text-gray-300`,children:[t(`import.formats`),` `,(0,L.jsxs)(`span`,{className:`text-gray-500 font-normal`,children:[`(`,t(`import.delimiter`),` `,(0,L.jsx)(`code`,{className:`text-accent`,children:`:`}),` `,t(`import.or`),` `,(0,L.jsx)(`code`,{className:`text-accent`,children:`|`}),`)`]})]}),(0,L.jsxs)(`p`,{className:`font-mono text-xs`,children:[`login:pass:`,`{`,`mafile`,`}`]}),(0,L.jsxs)(`p`,{className:`font-mono text-xs`,children:[`login:pass:email:email_pass:`,`{`,`mafile`,`}`]}),(0,L.jsxs)(`p`,{className:`font-mono text-xs`,children:[`login:pass:email:email_pass:`,`{`,`mafile`,`}`,`:notes`]}),(0,L.jsx)(`p`,{className:`font-mono text-xs`,children:`login:pass:email:email_pass`}),(0,L.jsx)(`p`,{className:`font-mono text-xs`,children:`login:pass:email:email_pass:notes`})]}),(0,L.jsxs)(`div`,{onDragOver:e=>e.preventDefault(),onDrop:e=>{e.preventDefault();let t=e.dataTransfer.files[0];t&&r(t)},onClick:()=>c.current?.click(),className:`border-2 border-dashed border-dark-500 rounded-lg p-6 mb-3 text-center cursor-pointer transition-colors hover:border-accent`,children:[(0,L.jsx)(ce,{size:32,className:`mx-auto mb-2 text-gray-500`}),(0,L.jsx)(`p`,{className:`text-sm text-gray-400`,children:n?t(`import.selected`,{name:n.name}):t(`import.dragTxt`)})]}),(0,L.jsx)(`input`,{ref:c,type:`file`,accept:`.txt`,className:`hidden`,onChange:e=>{let t=e.target.files?.[0];t&&r(t)}}),(0,L.jsx)(`button`,{onClick:async()=>{if(n){s(!0);try{let e=await D.importAccounts(n);a(t(`toast.importResult`,{imported:e.imported,skipped:e.skipped})),l(`success`,`${e.imported} ok, ${e.skipped} skip`),await u()}catch(e){a(e instanceof Error?e.message:t(`misc.errorStr`))}finally{s(!1)}}},disabled:!n||o,className:`btn-primary w-full`,children:t(o?`import.uploading`:`import.importBtn`)}),i&&(0,L.jsx)(`p`,{className:`mt-3 text-sm text-gray-300`,children:i})]})})}function lt({onSave:e,onClose:t}){let n=F(),r=j(e=>e.addToast);ze(e=>e.loadAccounts);let[i,a]=(0,y.useState)(``),[o,s]=(0,y.useState)(``),[c,l]=(0,y.useState)(``),[u,d]=(0,y.useState)(``),[f,p]=(0,y.useState)(``),[m,h]=(0,y.useState)(``),[g,_]=(0,y.useState)(null),[v,b]=(0,y.useState)(!1),x=(0,y.useRef)(null),S=e=>{let t=e.includes(`|`)?`|`:`:`,n=e.split(t);n.length>=2?(a(n[0]),s(n[1]),n.length>=3&&l(n[2]),n.length>=4&&d(n[3])):a(e)};return(0,L.jsx)(`div`,{className:`confirm-overlay`,onMouseDown:t,children:(0,L.jsxs)(`div`,{className:`confirm-box max-w-md`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`h3`,{className:`text-lg font-semibold mb-4`,children:n(`modal.addAccount`)}),(0,L.jsxs)(`div`,{className:`space-y-3`,children:[(0,L.jsx)(`input`,{autoFocus:!0,value:i,onChange:e=>a(e.target.value),onPaste:e=>{let t=e.clipboardData.getData(`text`).trim();(t.includes(`:`)||t.includes(`|`))&&(e.preventDefault(),S(t))},placeholder:n(`ph.login`)+` (login:pass)`,className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:o,onChange:e=>s(e.target.value),placeholder:n(`ph.password`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsxs)(`div`,{className:`grid grid-cols-2 gap-2`,children:[(0,L.jsx)(`input`,{value:c,onChange:e=>l(e.target.value),placeholder:`Email`,className:`bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:u,onChange:e=>d(e.target.value),placeholder:n(`ph.emailPassword`),className:`bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`})]}),(0,L.jsxs)(`div`,{className:`grid grid-cols-2 gap-2`,children:[(0,L.jsx)(`input`,{value:f,onChange:e=>p(e.target.value),placeholder:n(`ph.proxyOptional`),className:`bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:m,onChange:e=>h(e.target.value),placeholder:n(`ph.notesOptional`),className:`bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`})]}),(0,L.jsxs)(`div`,{onClick:()=>x.current?.click(),className:`border border-dashed border-dark-500 rounded p-3 text-center cursor-pointer transition-colors hover:border-accent flex items-center justify-center gap-2`,children:[(0,L.jsx)(ce,{size:14,className:`text-gray-500`}),(0,L.jsx)(`span`,{className:`text-xs text-gray-400`,children:g?g.name:n(`import.attachMafile`)}),g&&(0,L.jsx)(`button`,{onClick:e=>{e.stopPropagation(),_(null)},className:`text-xs text-red-400 hover:text-red-300 ml-1`,children:`✕`})]}),(0,L.jsx)(`input`,{ref:x,type:`file`,accept:`.mafile`,className:`hidden`,onChange:e=>{let t=e.target.files?.[0];t&&_(t)}}),(0,L.jsx)(`button`,{onClick:async()=>{if(!(!i||!o)){b(!0);try{e({login:i,password:o,email:c||void 0,email_password:u||void 0,proxy:f||void 0,notes:m||void 0}),g&&await D.uploadMafiles([g])}catch(e){r(`error`,e instanceof Error?e.message:String(e))}finally{b(!1)}}},disabled:!i||!o||v,className:`btn-primary w-full`,children:n(v?`import.uploading`:`btn.add`)})]})]})})}function ut({message:e,onConfirm:t,onCancel:n}){let r=F();return(0,L.jsx)(`div`,{className:`confirm-overlay`,onMouseDown:n,children:(0,L.jsxs)(`div`,{className:`confirm-box`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`p`,{className:`text-sm text-gray-300 mb-4`,children:e}),(0,L.jsxs)(`div`,{className:`flex gap-2`,children:[(0,L.jsx)(`button`,{onClick:t,className:`btn-primary flex-1`,children:r(`confirm.yes`)}),(0,L.jsx)(`button`,{onClick:n,className:`btn-secondary flex-1`,children:r(`btn.cancel`)})]})]})})}var dt={browser:`col.browser`,profile:`col.profile`,last_online:`col.lastOnline`,steam_id:`col.steamId`,login:`col.login`,password:`col.password`,login_pass:`col.loginPass`,email:`col.email`,email_pass:`col.emailPass`,email_login_pass:`col.emailLoginPass`,phone:`col.phone`,status:`col.status`,ban:`col.ban`,twofa:`col.twofa`,mafile:`col.mafile`,proxy:`col.proxy`,notes:`col.notes`,actions:`col.actions`};function ft(){let[e,t]=(0,y.useState)(!1),n=j(e=>e.columnVisibility),r=j(e=>e.toggleColumn),i=(0,y.useRef)(null),a=F();return(0,y.useEffect)(()=>{let e=e=>{i.current&&!i.current.contains(e.target)&&t(!1)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[]),(0,L.jsxs)(`div`,{className:`relative`,ref:i,children:[(0,L.jsx)(`button`,{onClick:()=>t(!e),className:`btn-secondary text-sm px-2 py-2`,title:a(`tip.columnSettings`),children:(0,L.jsx)(xe,{size:14})}),e&&(0,L.jsx)(`div`,{className:`absolute right-0 top-full mt-1 bg-dark-700 border border-dark-600 rounded-lg shadow-xl z-50 p-2 min-w-[160px]`,children:Object.keys(dt).map(e=>(0,L.jsxs)(`label`,{className:`flex items-center gap-2 px-2 py-1 hover:bg-dark-600 rounded cursor-pointer text-sm`,children:[(0,L.jsx)(`input`,{type:`checkbox`,checked:n[e],onChange:()=>r(e)}),a(dt[e])]},e))})]})}function pt({onClose:e}){let t=F(),[n,r]=(0,y.useState)(null),[i,a]=(0,y.useState)(``),[o,s]=(0,y.useState)(!1),c=(0,y.useRef)(null),l=j(e=>e.addToast),u=Ve(e=>e.loadAccounts);return(0,L.jsx)(`div`,{className:`confirm-overlay`,onMouseDown:e,children:(0,L.jsxs)(`div`,{className:`confirm-box max-w-lg w-full`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`h3`,{className:`text-lg font-semibold mb-4`,children:t(`modal.importAccounts`)}),(0,L.jsxs)(`div`,{className:`text-sm text-gray-400 mb-3 space-y-1`,children:[(0,L.jsx)(`p`,{className:`font-medium text-gray-300`,children:t(`import.formatsColon`)}),(0,L.jsx)(`p`,{className:`font-mono text-xs`,children:`login:pass`}),(0,L.jsx)(`p`,{className:`font-mono text-xs`,children:`login|pass`}),(0,L.jsx)(`p`,{className:`font-mono text-xs`,children:`CSV: login,password,steam_id,ban,prime,trophy,behavior,license`}),(0,L.jsx)(`p`,{className:`text-xs text-yellow-500/80 mt-1`,children:`⚠ Mafile-файлы и JSON не принимаются. Только log:pass / log|pass.`})]}),(0,L.jsxs)(`div`,{onDragOver:e=>e.preventDefault(),onDrop:e=>{e.preventDefault();let t=e.dataTransfer.files[0];t&&r(t)},onClick:()=>c.current?.click(),className:`border-2 border-dashed border-dark-500 rounded-lg p-6 mb-3 text-center cursor-pointer transition-colors hover:border-accent`,children:[(0,L.jsx)(ce,{size:32,className:`mx-auto mb-2 text-gray-500`}),(0,L.jsx)(`p`,{className:`text-sm text-gray-400`,children:n?t(`import.selected`,{name:n.name}):t(`import.dragTxtCsv`)})]}),(0,L.jsx)(`input`,{ref:c,type:`file`,accept:`.txt,.csv`,className:`hidden`,onChange:e=>{let t=e.target.files?.[0];t&&r(t)}}),(0,L.jsx)(`button`,{onClick:async()=>{if(n){s(!0);try{let e=(await n.text()).split(` -`).map(e=>e.trim()).filter(Boolean);if(!e.length){a(t(`toast.fileEmpty`)),s(!1);return}let r=await D.importLogpass(e);a(t(`toast.importResult`,{imported:r.imported,skipped:r.skipped})),l(`success`,`${r.imported} ok, ${r.skipped} skip`),await u()}catch(e){a(e instanceof Error?e.message:t(`misc.errorStr`))}finally{s(!1)}}},disabled:!n||o,className:`btn-primary w-full`,children:t(o?`import.uploading`:`import.importBtn`)}),i&&(0,L.jsx)(`p`,{className:`mt-3 text-sm text-gray-300`,children:i})]})})}function mt({onClose:e}){let t=F(),[n,r]=(0,y.useState)(``),[i,a]=(0,y.useState)(``),[o,s]=(0,y.useState)(``),c=Ve(e=>e.loadAccounts);return(0,L.jsx)(`div`,{className:`confirm-overlay`,onMouseDown:e,children:(0,L.jsxs)(`div`,{className:`confirm-box max-w-md`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`h3`,{className:`text-lg font-semibold mb-4`,children:t(`modal.addAccount`)}),(0,L.jsxs)(`div`,{className:`space-y-3`,children:[(0,L.jsx)(`input`,{autoFocus:!0,value:n,onChange:e=>r(e.target.value),placeholder:t(`ph.login`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:i,onChange:e=>a(e.target.value),placeholder:t(`ph.password`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:o,onChange:e=>s(e.target.value),placeholder:t(`ph.proxyOptional`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`button`,{onClick:async()=>{if(!n||!i)return;let t={login:n,password:i,proxy:o||void 0};await D.createLogpassAccount(t),await c(),e()},className:`btn-primary w-full`,children:t(`btn.add`)})]})]})})}function ht({account:e,onClose:t}){let n=F(),[r,i]=(0,y.useState)(e.login),[a,o]=(0,y.useState)(e.password),[s,c]=(0,y.useState)(e.proxy??``),[l,u]=(0,y.useState)(e.notes??``),d=Ve(e=>e.loadAccounts);return(0,L.jsx)(`div`,{className:`confirm-overlay`,onMouseDown:t,children:(0,L.jsxs)(`div`,{className:`confirm-box max-w-md`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`h3`,{className:`text-lg font-semibold mb-4`,children:n(`modal.editAccount`)}),(0,L.jsxs)(`div`,{className:`space-y-3`,children:[(0,L.jsx)(`input`,{autoFocus:!0,value:r,onChange:e=>i(e.target.value),placeholder:n(`ph.login`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:a,onChange:e=>o(e.target.value),placeholder:n(`ph.password`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:s,onChange:e=>c(e.target.value),placeholder:n(`ph.proxyOptional`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:l,onChange:e=>u(e.target.value),placeholder:n(`ph.notes`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsxs)(`div`,{className:`flex gap-2`,children:[(0,L.jsx)(`button`,{onClick:async()=>{!r||!a||(await D.updateLogpassAccount(e.id,{login:r,password:a,proxy:s||void 0,notes:l||void 0}),await d(),t())},className:`btn-primary flex-1`,children:n(`btn.save`)}),(0,L.jsx)(`button`,{onClick:t,className:`btn-secondary flex-1`,children:n(`btn.cancel`)})]})]})]})})}var gt={browser:`col.browser`,profile:`col.profile`,last_online:`col.lastOnline`,steam_id:`col.steamId`,login:`col.login`,password:`col.password`,login_pass:`col.loginPass`,status:`col.status`,ban:`col.ban`,prime:`col.prime`,trophy:`col.trophy`,behavior:`col.behavior`,license:`col.license`,proxy:`col.proxy`,notes:`col.notes`,actions:`col.actions`};function _t(){let[e,t]=(0,y.useState)(!1),n=j(e=>e.logpassColumnVisibility),r=j(e=>e.toggleLogpassColumn),i=(0,y.useRef)(null),a=F();return(0,y.useEffect)(()=>{let e=e=>{i.current&&!i.current.contains(e.target)&&t(!1)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[]),(0,L.jsxs)(`div`,{className:`relative`,ref:i,children:[(0,L.jsx)(`button`,{onClick:()=>t(!e),className:`btn-secondary text-sm px-2 py-2`,title:a(`tip.columnSettings`),children:(0,L.jsx)(xe,{size:14})}),e&&(0,L.jsx)(`div`,{className:`absolute right-0 top-full mt-1 bg-dark-700 border border-dark-600 rounded-lg shadow-xl z-50 p-2 min-w-[160px]`,children:Object.keys(gt).map(e=>(0,L.jsxs)(`label`,{className:`flex items-center gap-2 px-2 py-1 hover:bg-dark-600 rounded cursor-pointer text-sm`,children:[(0,L.jsx)(`input`,{type:`checkbox`,checked:n[e],onChange:()=>r(e)}),a(gt[e])]},e))})]})}function vt(e){if(!e)return null;if(typeof e==`string`)try{return JSON.parse(e)}catch{return null}return e}function yt(){let e=Ve(e=>e.accounts),t=Ve(e=>e.selectedIds),n=Ve(e=>e.loadAccounts),r=Ve(e=>e.selectAll),i=Ve(e=>e.clearSelection),a=j(e=>e.addToast),o=j(e=>e.logpassColumnVisibility),s=F(),[c,l]=(0,y.useState)(``),[u,d]=(0,y.useState)(!1),[f,p]=(0,y.useState)(!1),[m,h]=(0,y.useState)(null),[g,_]=(0,y.useState)({open:!1,message:``,onConfirm:()=>{}}),[v,b]=(0,y.useState)(new Set),[x,S]=(0,y.useState)({}),[C,w]=(0,y.useState)({}),[T,E]=(0,y.useState)(null),[O,ee]=(0,y.useState)(100),[k,A]=(0,y.useState)(null),[M,te]=(0,y.useState)(`asc`),ne=e=>{k===e?M===`asc`?te(`desc`):(A(null),te(`asc`)):(A(e),te(`asc`))},N=(0,y.useRef)(null);(0,y.useEffect)(()=>{n()},[n]);let P=(e,t)=>_({open:!0,message:e,onConfirm:t}),re=(0,y.useCallback)(e=>{let t=new EventSource(`/api/tasks/${e}/stream`);t.onmessage=e=>{try{let r=JSON.parse(e.data);if(E(r),r.account_results){let e=vt(r.account_results);e&&S(e)}r.account_steps&&w(r.account_steps),r.status!==`running`&&(t.close(),b(new Set),E(null),n())}catch{}},t.onerror=()=>t.close()},[n]),ie=(0,y.useCallback)(async()=>{let e=[...t];if(e.length){i(),b(new Set(e)),S({}),w({});try{let{task_id:t}=await D.validateLogpass(e);E({id:t,type:`logpass_validate`,status:`running`,progress:0,total:e.length,result:null,error:null,created_at:``,updated_at:``}),re(t)}catch(e){b(new Set),a(`error`,String(e))}}},[t,i,re,a]),ae=(0,y.useCallback)(async e=>{b(new Set([e])),S(t=>{let n={...t};return delete n[String(e)],n}),w(t=>{let n={...t};return delete n[String(e)],n});try{let{task_id:t}=await D.validateLogpass([e]);E({id:t,type:`logpass_validate`,status:`running`,progress:0,total:1,result:null,error:null,created_at:``,updated_at:``}),re(t)}catch(e){b(new Set),a(`error`,String(e))}},[re,a]),I=(0,y.useCallback)(async()=>{let e=[...t];if(e.length){i(),b(new Set(e)),S({}),w({});try{let{task_id:t}=await D.fullParseLogpass(e);E({id:t,type:`logpass_full_parse`,status:`running`,progress:0,total:e.length,result:null,error:null,created_at:``,updated_at:``}),re(t)}catch(e){b(new Set),a(`error`,String(e))}}},[t,i,re,a]),oe=()=>{let e=[...t];e.length&&P(s(`confirm.deleteLogpassSelected`,{count:e.length}),async()=>{await D.deleteLogpassBulk(e),i(),n()})},R=()=>{P(s(`confirm.deleteLogpassAll`,{count:e.length}),async()=>{await D.deleteLogpassBulk(e.map(e=>e.id)),i(),n()})},ce=()=>{P(s(`confirm.assignProxies`),async()=>{try{a(`success`,s(`toast.proxiesAssignedShort`,{count:(await D.assignLogpassProxies()).assigned})),n()}catch(e){a(`error`,e instanceof Error?e.message:String(e))}})},ue=()=>{P(s(`confirm.reassignProxiesAll`),async()=>{try{a(`success`,s(`toast.proxiesReassignedShort`,{count:(await D.reassignLogpassProxies()).assigned})),n()}catch(e){a(`error`,e instanceof Error?e.message:String(e))}})},de=()=>{P(s(`confirm.clearProxies`),async()=>{try{a(`success`,s(`toast.proxiesClearedShort`,{count:(await D.clearLogpassProxies()).cleared})),n()}catch(e){a(`error`,e instanceof Error?e.message:String(e))}})},fe=e.length>0&&t.size===e.length,pe=(0,y.useMemo)(()=>{if(!c.trim())return e;let t=c.trim(),n=t.match(/^lvl\s*(>=|<=|>|<|=)\s*(\d+)$/i);if(n){let t=n[1],r=parseInt(n[2],10);return e.filter(e=>{let n=e.steam_level;return n==null?!1:t===`>`?n>r:t===`>=`?n>=r:t===`<`?ne.login.toLowerCase().includes(r)||(e.steam_id??``).toLowerCase().includes(r)||(e.nickname??``).toLowerCase().includes(r)||(e.notes??``).toLowerCase().includes(r)||(e.license??``).toLowerCase().includes(r))},[e,c]),_e=(0,y.useMemo)(()=>{if(!k)return pe;let e=M===`asc`?1:-1,t=Symbol();return[...pe].sort((n,r)=>{let i=t,a=t;if(k===`last_online`){let e=e=>{if(!e||e===`—`)return t;if(e===`online`)return-1;let n=e.match(/^(\d+)([mhd])$/i);if(!n)return t;let r=parseInt(n[1],10);return n[2]===`m`?r:n[2]===`h`?r*60:r*1440};i=e(n.last_online),a=e(r.last_online)}else k===`prime`?(i=n.prime===`Enabled`?0:n.prime===`Disabled`?1:t,a=r.prime===`Enabled`?0:r.prime===`Disabled`?1:t):k===`trophy`?(i=n.trophy!=null&&n.trophy!==`—`?parseInt(n.trophy,10)||0:t,a=r.trophy!=null&&r.trophy!==`—`?parseInt(r.trophy,10)||0:t):k===`behavior`&&(i=n.behavior!=null&&n.behavior!==`—`?parseInt(n.behavior,10)||0:t,a=r.behavior!=null&&r.behavior!==`—`?parseInt(r.behavior,10)||0:t);return i===t&&a===t?0:i===t?1:a===t?-1:i===a?0:(i{ee(100)},[c,k,M]);let ve=(0,y.useMemo)(()=>_e.slice(0,O),[_e,O]);(0,y.useEffect)(()=>{let e=N.current;if(!e)return;let t=new IntersectionObserver(e=>{e[0].isIntersecting&&ee(e=>Math.min(e+100,_e.length))},{rootMargin:`400px`});return t.observe(e),()=>t.disconnect()},[_e.length,O]);let ye=(0,y.useMemo)(()=>{let t=new Map,n=[];for(let t of e)t.proxy&&!n.includes(t.proxy)&&n.push(t.proxy);let r=new Map;n.forEach((e,t)=>r.set(e,t+1));for(let n of e)n.proxy&&t.set(n.id,s(`proxy.label`,{num:r.get(n.proxy)??0}));return t},[e]),be=async e=>{try{let t=await D.openLogpassBrowser(e);t.status===`revalidating`?(a(`warn`,s(`toast.cookiesExpiredRevalidating`)),t.task_id&&(b(new Set([e])),E({id:t.task_id,type:`logpass_validate`,status:`running`,progress:0,total:1,result:null,error:null,created_at:``,updated_at:``}),re(t.task_id))):a(`success`,s(`toast.browserOpening`))}catch(e){a(`error`,e instanceof Error?e.message:String(e))}};return(0,L.jsxs)(`div`,{className:`flex flex-col gap-4 h-full min-h-0`,children:[(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-lg px-3 py-2 flex flex-wrap items-center gap-2 shrink-0`,children:[(0,L.jsxs)(`button`,{onClick:()=>d(!0),className:`btn-primary`,children:[(0,L.jsx)(se,{size:14,className:`inline mr-1`}),s(`btn.import`)]}),(0,L.jsxs)(`button`,{onClick:()=>p(!0),className:`btn-secondary`,children:[(0,L.jsx)(le,{size:14,className:`inline mr-1`}),s(`btn.add`)]}),T&&(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(`div`,{className:`h-5 border-l border-dark-500`}),(0,L.jsxs)(`div`,{className:`flex items-center gap-2 min-w-0`,children:[(0,L.jsx)(`span`,{className:`text-xs text-gray-400 whitespace-nowrap`,children:s(`task.validate`)}),(0,L.jsx)(`div`,{className:`w-28 bg-dark-600 rounded-full h-2.5 shrink-0`,children:(0,L.jsx)(`div`,{className:`h-2.5 rounded-full transition-all duration-300 ${T.status===`completed`?`bg-green-500`:T.status===`failed`?`bg-red-500`:`bg-accent`}`,style:{width:`${T.total>1?T.total>0?Math.round(T.progress/T.total*100):0:T.total_steps?Math.round((T.step??0)/T.total_steps*100):0}%`}})}),(0,L.jsxs)(`span`,{className:`text-xs text-gray-500 whitespace-nowrap`,children:[T.total>1?`${T.progress}/${T.total}${T.active_count?` (${T.active_count})`:``}`:T.step_label||`${T.progress}/${T.total}`,T.total>1?` (${T.total>0?Math.round(T.progress/T.total*100):0}%)`:T.total_steps?` (${T.step}/${T.total_steps})`:``]}),T.status===`completed`&&(0,L.jsx)(Ae,{size:14,className:`text-green-400`}),T.status===`failed`&&(0,L.jsx)(`span`,{title:T.error||``,children:(0,L.jsx)(ke,{size:14,className:`text-red-400`})})]})]}),(0,L.jsxs)(`div`,{className:`ml-auto flex items-center gap-2`,children:[(0,L.jsx)(_t,{}),(0,L.jsx)(`div`,{className:`h-5 border-l border-dark-500`}),(0,L.jsx)(`button`,{onClick:oe,className:`btn-danger-outline text-xs`,children:s(`btn.deleteSelected`)}),(0,L.jsx)(`button`,{onClick:R,className:`btn-danger text-xs`,children:s(`btn.deleteAll`)})]})]}),(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-lg overflow-hidden flex-1 min-h-0 flex flex-col`,children:[(0,L.jsxs)(`div`,{className:`px-3 py-2 flex items-center gap-2 border-b border-dark-600 shrink-0 bg-dark-800`,children:[(0,L.jsxs)(`button`,{onClick:ie,disabled:t.size===0||v.size>0,className:`btn-accent text-sm disabled:opacity-40`,children:[(0,L.jsx)(Oe,{size:12,className:`inline mr-1`}),s(`btn.validate`)]}),(0,L.jsxs)(`button`,{onClick:I,disabled:t.size===0||v.size>0,className:`btn-secondary text-sm disabled:opacity-40`,children:[(0,L.jsx)(Oe,{size:12,className:`inline mr-1`}),s(`btn.fullParse`)]}),T&&T.status===`running`&&(0,L.jsxs)(`button`,{onClick:async()=>{try{await D.cancelTask(T.id)}catch{}},className:`btn-danger text-sm`,children:[(0,L.jsx)(ke,{size:12,className:`inline mr-1`}),s(`btn.cancel`)]}),(0,L.jsx)(`div`,{className:`h-5 border-l border-dark-500`}),(0,L.jsxs)(`button`,{onClick:ce,className:`btn-secondary text-sm`,children:[(0,L.jsx)(me,{size:14,className:`inline mr-1`}),s(`btn.assignProxies`)]}),(0,L.jsxs)(`button`,{onClick:ue,className:`btn-secondary text-sm`,children:[(0,L.jsx)(he,{size:14,className:`inline mr-1`}),s(`btn.reassign`)]}),(0,L.jsxs)(`button`,{onClick:de,className:`btn-danger-outline text-sm`,children:[(0,L.jsx)(ge,{size:14,className:`inline mr-1`}),s(`btn.clearProxies`)]}),(0,L.jsx)(`div`,{className:`ml-auto`,children:(0,L.jsx)(`input`,{type:`text`,value:c,onChange:e=>l(e.target.value),placeholder:s(`ph.searchLogpass`),className:`bg-dark-700 border border-dark-600 rounded px-2 py-1.5 text-xs w-80 placeholder:text-gray-500 outline-none focus:border-accent`})})]}),(0,L.jsx)(`div`,{className:`overflow-auto flex-1 min-h-0`,children:(0,L.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,L.jsx)(`thead`,{className:`sticky top-0 bg-dark-800 z-10`,children:(0,L.jsxs)(`tr`,{className:`text-left text-xs text-gray-500 border-b border-dark-600`,children:[(0,L.jsx)(`th`,{className:`px-3 py-2`,children:(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,L.jsx)(`input`,{type:`checkbox`,checked:fe,onChange:()=>fe?i():r()}),t.size>0&&(0,L.jsx)(`span`,{className:`text-accent font-medium`,children:t.size})]})}),(0,L.jsx)(`th`,{className:`w-5`}),o.browser&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:s(`col.browser`)}),o.profile&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:s(`col.profile`)}),o.last_online&&(0,L.jsxs)(`th`,{className:`px-3 py-2 cursor-pointer select-none hover:text-gray-300`,onClick:()=>ne(`last_online`),children:[s(`col.lastOnline`),k===`last_online`?M===`asc`?` ▲`:` ▼`:``]}),o.steam_id&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:`Steam ID`}),o.login&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:s(`col.login`)}),o.password&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:s(`col.password`)}),o.login_pass&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:`Login:Pass`}),o.status&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:s(`col.status`)}),o.ban&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:s(`col.ban`)}),o.prime&&(0,L.jsxs)(`th`,{className:`px-3 py-2 cursor-pointer select-none hover:text-gray-300`,onClick:()=>ne(`prime`),children:[`Prime`,k===`prime`?M===`asc`?` ▲`:` ▼`:``]}),o.trophy&&(0,L.jsxs)(`th`,{className:`px-3 py-2 cursor-pointer select-none hover:text-gray-300`,onClick:()=>ne(`trophy`),children:[`Trophy`,k===`trophy`?M===`asc`?` ▲`:` ▼`:``]}),o.behavior&&(0,L.jsxs)(`th`,{className:`px-3 py-2 cursor-pointer select-none hover:text-gray-300`,onClick:()=>ne(`behavior`),children:[`Behavior`,k===`behavior`?M===`asc`?` ▲`:` ▼`:``]}),o.license&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:s(`col.license`)}),o.proxy&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:s(`col.proxy`)}),o.notes&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:s(`col.notes`)}),o.actions&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:s(`col.actions`)})]})}),(0,L.jsx)(`tbody`,{children:pe.length===0?(0,L.jsx)(`tr`,{children:(0,L.jsx)(`td`,{colSpan:16,className:`text-center py-12 text-gray-500`,children:s(`empty.logpass`)})}):(0,L.jsxs)(L.Fragment,{children:[ve.map(e=>(0,L.jsx)(bt,{account:e,cols:o,isProcessing:v.has(e.id),accountResult:x[String(e.id)],accountStep:C[String(e.id)],proxyLabel:ye.get(e.id)??null,onDelete:t=>P(s(`confirm.deleteLogpass`,{name:e.login}),async()=>{await D.deleteLogpassAccount(t),n()}),onOpenBrowser:be,onValidate:ae,onEdit:e=>h(e)},e.id)),O{let t=e.find(e=>e.id===m);return t?(0,L.jsx)(ht,{account:t,onClose:()=>h(null)}):null})(),u&&(0,L.jsx)(pt,{onClose:()=>d(!1)}),f&&(0,L.jsx)(mt,{onClose:()=>p(!1)}),g.open&&(0,L.jsx)(ut,{message:g.message,onConfirm:()=>{g.onConfirm(),_(e=>({...e,open:!1}))},onCancel:()=>_(e=>({...e,open:!1}))})]})}function bt({account:e,cols:t,isProcessing:n,accountResult:r,accountStep:i,proxyLabel:a,onDelete:o,onOpenBrowser:s,onValidate:c,onEdit:l}){let u=Ve(e=>e.selectedIds),d=Ve(e=>e.toggleSelect),f=j(e=>e.addToast),p=j(e=>e.hidePasswords),m=Ve(e=>e.loadAccounts),[h,g]=(0,y.useState)(!1),[_,v]=(0,y.useState)(!1),[b,x]=(0,y.useState)(e.notes||``),[S,C]=(0,y.useState)(!1),w=F(),T=p&&!h,E=`••••••••`,O=async e=>{let t=await Ue(e);f(t?`success`:`error`,w(t?`toast.copied`:`toast.copyFailed`))};return(0,L.jsxs)(`tr`,{className:`hover:bg-dark-700/50 transition`,children:[(0,L.jsx)(`td`,{className:`px-3 py-2`,children:(0,L.jsx)(`input`,{type:`checkbox`,checked:u.has(e.id),onChange:()=>d(e.id)})}),(0,L.jsx)(`td`,{className:`px-1 py-2 w-5`,children:n?(0,L.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,L.jsx)(`div`,{className:`w-4 h-4 border-2 border-accent border-t-transparent rounded-full animate-spin shrink-0`}),i&&(0,L.jsxs)(`span`,{className:`text-[10px] text-gray-500 whitespace-nowrap`,children:[`[`,i.step,`/`,i.total,`]`]})]}):r?.status===`ok`?(0,L.jsx)(ue,{size:16,className:`text-gray-400`}):r?.status===`error`?(0,L.jsx)(`span`,{title:r.error,children:(0,L.jsx)(fe,{size:16,className:`text-red-400`})}):null}),t.browser&&(0,L.jsx)(`td`,{className:`px-3 py-2 whitespace-nowrap text-center`,children:e.has_cookies?(0,L.jsx)(`button`,{onClick:()=>s(e.id),className:`px-2 py-0.5 text-xs font-medium rounded bg-blue-600/20 text-blue-400 border border-blue-500/30 hover:bg-blue-600/40 hover:text-blue-300 active:scale-95 transition`,title:w(`tip.openBrowser`),children:w(`col.browser`)}):(0,L.jsx)(`span`,{className:`text-gray-600 text-xs`,children:`—`})}),t.profile&&(0,L.jsx)(`td`,{className:`px-3 py-2 whitespace-nowrap`,children:(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[e.avatar_url&&(0,L.jsx)(`img`,{src:e.avatar_url,className:`avatar-sm`,alt:``}),(0,L.jsx)(`span`,{className:`text-xs`,children:e.nickname||`—`}),e.steam_level!=null&&(0,L.jsx)(nt,{level:e.steam_level})]})}),t.last_online&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs text-gray-400 whitespace-nowrap`,children:e.last_online||`—`}),t.steam_id&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs`,children:e.steam_id?(0,L.jsx)(`a`,{href:`https://steamcommunity.com/profiles/${encodeURIComponent(e.steam_id)}/`,target:`_blank`,rel:`noopener noreferrer`,className:`text-blue-400 hover:text-blue-300 hover:underline`,children:e.steam_id}):`—`}),t.login&&(0,L.jsx)(`td`,{className:`px-3 py-2 font-medium`,children:e.login}),t.password&&(0,L.jsxs)(`td`,{className:`px-3 py-2 text-gray-400 select-none whitespace-nowrap`,children:[(0,L.jsx)(`span`,{className:`cursor-pointer`,onClick:()=>O(e.password),title:w(`tip.copyPassword`),children:T?E:e.password}),(0,L.jsx)(`button`,{onClick:e=>{e.stopPropagation(),g(!h)},className:`ml-1.5 text-gray-500 hover:text-gray-300 inline-flex align-middle`,title:w(T?`tip.show`:`tip.hide`),children:T?(0,L.jsx)(_e,{size:14}):(0,L.jsx)(ve,{size:14})})]}),t.login_pass&&(0,L.jsxs)(`td`,{className:`px-3 py-2 text-gray-400 text-xs select-none whitespace-nowrap`,children:[(0,L.jsx)(`span`,{className:`cursor-pointer`,onClick:()=>O(`${e.login}:${e.password}`),title:w(`tip.copyLoginPass`),children:T?`${e.login}:${E}`:`${e.login}:${e.password}`}),(0,L.jsx)(`button`,{onClick:e=>{e.stopPropagation(),g(!h)},className:`ml-1.5 text-gray-500 hover:text-gray-300 inline-flex align-middle`,title:w(T?`tip.show`:`tip.hide`),children:T?(0,L.jsx)(_e,{size:14}):(0,L.jsx)(ve,{size:14})})]}),t.status&&(0,L.jsx)(`td`,{className:`px-3 py-2`,children:(0,L.jsx)(Ge,{status:e.status})}),t.ban&&(0,L.jsx)(`td`,{className:`px-3 py-2`,children:(0,L.jsx)(Ke,{status:e.ban_status})}),t.prime&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs text-gray-400`,children:e.prime??`—`}),t.trophy&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs text-gray-400`,children:e.trophy??`—`}),t.behavior&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs text-gray-400`,children:e.behavior??`—`}),t.license&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs text-gray-400 cursor-pointer select-none ${S?`max-w-none whitespace-normal break-words`:`truncate max-w-[200px] whitespace-nowrap`}`,title:S?void 0:e.license??``,onClick:()=>C(e=>!e),children:e.license??`—`}),t.proxy&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs`,children:e.proxy?(0,L.jsx)(`span`,{className:`text-blue-400 cursor-pointer hover:underline`,onClick:()=>O(e.proxy),title:e.proxy,children:a||e.proxy}):`—`}),t.notes&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs max-w-[180px]`,children:_?(0,L.jsx)(`input`,{autoFocus:!0,className:`w-full bg-dark-600 border border-dark-500 rounded px-1.5 py-0.5 text-xs text-gray-200 outline-none focus:border-accent`,value:b,onChange:e=>x(e.target.value),onBlur:async()=>{if(v(!1),b!==(e.notes||``))try{await D.updateLogpassAccount(e.id,{notes:b}),f(`success`,w(`toast.noteSaved`)),m()}catch{f(`error`,w(`toast.noteSaveError`))}},onKeyDown:t=>{t.key===`Enter`&&t.target.blur(),t.key===`Escape`&&(x(e.notes||``),v(!1))}}):(0,L.jsx)(`span`,{className:`cursor-pointer text-gray-400 hover:text-gray-200 truncate block`,onClick:()=>{x(e.notes||``),v(!0)},title:e.notes||w(`tip.addNote`),children:e.notes||`—`})}),t.actions&&(0,L.jsx)(`td`,{className:`px-3 py-2 whitespace-nowrap`,children:(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,L.jsx)(`button`,{onClick:()=>c(e.id),disabled:n,className:`text-gray-400 hover:text-accent disabled:opacity-40`,title:w(`tip.validate`),children:(0,L.jsx)(Oe,{size:14})}),(0,L.jsx)(`button`,{onClick:()=>l(e.id),className:`text-gray-400 hover:text-accent`,title:w(`tip.edit`),children:(0,L.jsx)(Se,{size:14})}),(0,L.jsx)(`button`,{onClick:()=>o(e.id),className:`text-gray-400 hover:text-red-400`,title:w(`tip.delete`),children:(0,L.jsx)(Ce,{size:14})})]})})]})}function xt({onClose:e}){let t=F(),[n,r]=(0,y.useState)(null),[i,a]=(0,y.useState)(``),[o,s]=(0,y.useState)(!1),c=(0,y.useRef)(null),l=j(e=>e.addToast),u=He(e=>e.loadAccounts);return(0,L.jsx)(`div`,{className:`confirm-overlay`,onMouseDown:e,children:(0,L.jsxs)(`div`,{className:`confirm-box max-w-lg w-full`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`h3`,{className:`text-lg font-semibold mb-4`,children:t(`modal.importTokens`)}),(0,L.jsxs)(`div`,{className:`text-sm text-gray-400 mb-3 space-y-1`,children:[(0,L.jsx)(`p`,{className:`font-medium text-gray-300`,children:t(`import.formatsColon`)}),(0,L.jsx)(`p`,{className:`font-mono text-xs`,children:t(`import.tokenFormat`)})]}),(0,L.jsxs)(`div`,{onDragOver:e=>e.preventDefault(),onDrop:e=>{e.preventDefault();let t=e.dataTransfer.files[0];t&&r(t)},onClick:()=>c.current?.click(),className:`border-2 border-dashed border-dark-500 rounded-lg p-6 mb-3 text-center cursor-pointer transition-colors hover:border-accent`,children:[(0,L.jsx)(ce,{size:32,className:`mx-auto mb-2 text-gray-500`}),(0,L.jsx)(`p`,{className:`text-sm text-gray-400`,children:n?t(`import.selected`,{name:n.name}):t(`import.dragTxt`)})]}),(0,L.jsx)(`input`,{ref:c,type:`file`,accept:`.txt`,className:`hidden`,onChange:e=>{let t=e.target.files?.[0];t&&r(t)}}),(0,L.jsx)(`button`,{onClick:async()=>{if(n){s(!0);try{let e=(await n.text()).split(` -`).map(e=>e.trim()).filter(Boolean);if(!e.length){a(t(`toast.fileEmpty`)),s(!1);return}let r=await D.importTokens(e);a(t(`toast.importResult`,{imported:r.imported,skipped:r.skipped})),l(`success`,`${r.imported} ok, ${r.skipped} skip`),await u()}catch(e){a(e instanceof Error?e.message:t(`misc.errorStr`))}finally{s(!1)}}},disabled:!n||o,className:`btn-primary w-full`,children:t(o?`import.uploading`:`import.importBtn`)}),i&&(0,L.jsx)(`p`,{className:`mt-3 text-sm text-gray-300`,children:i})]})})}function St({onClose:e}){let t=F(),[n,r]=(0,y.useState)(``),[i,a]=(0,y.useState)(``),[o,s]=(0,y.useState)(``),[c,l]=(0,y.useState)(``),u=He(e=>e.loadAccounts);return(0,L.jsx)(`div`,{className:`confirm-overlay`,onMouseDown:e,children:(0,L.jsxs)(`div`,{className:`confirm-box max-w-md`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`h3`,{className:`text-lg font-semibold mb-4`,children:t(`modal.addToken`)}),(0,L.jsxs)(`div`,{className:`space-y-3`,children:[(0,L.jsx)(`textarea`,{autoFocus:!0,value:n,onChange:e=>r(e.target.value),placeholder:`Refresh token`,rows:3,className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm font-mono resize-none`}),(0,L.jsx)(`input`,{value:i,onChange:e=>a(e.target.value),placeholder:t(`ph.loginOptional`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:o,onChange:e=>s(e.target.value),placeholder:t(`ph.proxyOptional`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:c,onChange:e=>l(e.target.value),placeholder:t(`ph.notesOptional`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`button`,{onClick:async()=>{if(!n.trim())return;let t={token:n.trim(),login:i.trim()||void 0,proxy:o.trim()||void 0,notes:c.trim()||void 0};await D.createTokenAccount(t),await u(),e()},disabled:!n.trim(),className:`btn-primary w-full disabled:opacity-40`,children:t(`btn.add`)})]})]})})}var Ct={browser:`col.browser`,profile:`col.profile`,last_online:`col.lastOnline`,steam_id:`col.steamId`,login:`col.login`,token:`col.token`,status:`col.status`,proxy:`col.proxy`,notes:`col.notes`,actions:`col.actions`};function wt(){let[e,t]=(0,y.useState)(!1),n=j(e=>e.tokenColumnVisibility),r=j(e=>e.toggleTokenColumn),i=(0,y.useRef)(null),a=F();return(0,y.useEffect)(()=>{let e=e=>{i.current&&!i.current.contains(e.target)&&t(!1)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[]),(0,L.jsxs)(`div`,{className:`relative`,ref:i,children:[(0,L.jsx)(`button`,{onClick:()=>t(!e),className:`btn-secondary text-sm px-2 py-2`,title:a(`tip.columnSettings`),children:(0,L.jsx)(xe,{size:14})}),e&&(0,L.jsx)(`div`,{className:`absolute right-0 top-full mt-1 bg-dark-700 border border-dark-600 rounded-lg shadow-xl z-50 p-2 min-w-[160px]`,children:Object.keys(Ct).map(e=>(0,L.jsxs)(`label`,{className:`flex items-center gap-2 px-2 py-1 hover:bg-dark-600 rounded cursor-pointer text-sm`,children:[(0,L.jsx)(`input`,{type:`checkbox`,checked:n[e],onChange:()=>r(e)}),a(Ct[e])]},e))})]})}function Tt(e){if(!e)return null;if(typeof e==`string`)try{return JSON.parse(e)}catch{return null}return e}function Et(){let e=He(e=>e.accounts),t=He(e=>e.selectedIds),n=He(e=>e.loadAccounts),r=He(e=>e.toggleSelect),i=He(e=>e.selectAll),a=He(e=>e.clearSelection),o=j(e=>e.addToast),s=j(e=>e.tokenColumnVisibility),c=j(e=>e.loadTokenColumnSettings),l=F(),[u,d]=(0,y.useState)(!1),[f,p]=(0,y.useState)(``),[m,h]=(0,y.useState)(!1),[g,_]=(0,y.useState)(!1),[v,b]=(0,y.useState)({open:!1,message:``,onConfirm:()=>{}}),[x,S]=(0,y.useState)(new Set),[C,w]=(0,y.useState)({}),[T,E]=(0,y.useState)({}),[O,ee]=(0,y.useState)(null);(0,y.useEffect)(()=>{n(),c()},[n,c]);let k=(e,t)=>b({open:!0,message:e,onConfirm:t}),A=(0,y.useCallback)(e=>{let t=new EventSource(`/api/tasks/${e}/stream`);t.onmessage=e=>{try{let r=JSON.parse(e.data);if(ee(r),r.account_results){let e=Tt(r.account_results);e&&w(e)}r.account_steps&&E(r.account_steps),r.status!==`running`&&(t.close(),S(new Set),n())}catch{}},t.onerror=()=>t.close()},[n]),M=(0,y.useCallback)(async()=>{let e=[...t];if(e.length){a(),S(new Set(e)),w({}),E({});try{let{task_id:t}=await D.validateTokens(e);ee({id:t,type:`token_validate`,status:`running`,progress:0,total:e.length,result:null,error:null,created_at:``,updated_at:``}),A(t)}catch(e){S(new Set),o(`error`,String(e))}}},[t,a,A,o]),te=(0,y.useCallback)(async e=>{S(new Set([e])),w(t=>{let n={...t};return delete n[String(e)],n}),E(t=>{let n={...t};return delete n[String(e)],n});try{let{task_id:t}=await D.validateTokens([e]);ee({id:t,type:`token_validate`,status:`running`,progress:0,total:1,result:null,error:null,created_at:``,updated_at:``}),A(t)}catch(e){S(new Set),o(`error`,String(e))}},[A,o]),ne=()=>{let e=[...t];e.length&&k(l(`confirm.deleteTokenSelected`,{count:e.length}),async()=>{await D.deleteTokenBulk(e),a(),n()})},N=()=>{k(l(`confirm.deleteTokenAll`,{count:e.length}),async()=>{await D.deleteTokenBulk(e.map(e=>e.id)),a(),n()})},P=()=>{k(l(`confirm.assignProxies`),async()=>{try{o(`success`,l(`toast.proxiesAssignedShort`,{count:(await D.assignTokenProxies()).assigned})),n()}catch(e){o(`error`,e instanceof Error?e.message:String(e))}})},re=()=>{k(l(`confirm.reassignProxiesAll`),async()=>{try{o(`success`,l(`toast.proxiesReassignedShort`,{count:(await D.reassignTokenProxies()).assigned})),n()}catch(e){o(`error`,e instanceof Error?e.message:String(e))}})},ie=()=>{k(l(`confirm.clearProxies`),async()=>{try{o(`success`,l(`toast.proxiesClearedShort`,{count:(await D.clearTokenProxies()).cleared})),n()}catch(e){o(`error`,e instanceof Error?e.message:String(e))}})},ae=async e=>{try{let t=await D.openTokenBrowser(e);t.status===`revalidating`?(o(`warn`,l(`toast.cookiesExpiredRevalidating`)),t.task_id&&(S(new Set([e])),ee({id:t.task_id,type:`token_validate`,status:`running`,progress:0,total:1,result:null,error:null,created_at:``,updated_at:``}),A(t.task_id))):o(`success`,l(`toast.browserOpening`))}catch(e){o(`error`,e instanceof Error?e.message:String(e))}},I=e.length>0&&t.size===e.length,oe=(0,y.useMemo)(()=>{if(!f.trim())return e;let t=f.trim(),n=t.match(/^lvl\s*(>=|<=|>|<|=)\s*(\d+)$/i);if(n){let t=n[1],r=parseInt(n[2],10);return e.filter(e=>{let n=e.steam_level;return n==null?!1:t===`>`?n>r:t===`>=`?n>=r:t===`<`?n(e.login??``).toLowerCase().includes(r)||(e.steam_id??``).toLowerCase().includes(r)||(e.nickname??``).toLowerCase().includes(r)||(e.notes??``).toLowerCase().includes(r))},[e,f]),R=(0,y.useMemo)(()=>{let t=new Map,n=[];for(let t of e)t.proxy&&!n.includes(t.proxy)&&n.push(t.proxy);let r=new Map;n.forEach((e,t)=>r.set(e,t+1));for(let n of e)n.proxy&&t.set(n.id,l(`proxy.label`,{num:r.get(n.proxy)??0}));return t},[e,l]);return(0,L.jsxs)(`div`,{className:`relative flex flex-col gap-4 h-full min-h-0`,children:[!u&&(0,L.jsx)(`div`,{className:`absolute inset-0 z-50 bg-dark-900/80 backdrop-blur-sm flex items-center justify-center`,children:(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-yellow-500/40 rounded-xl p-6 max-w-lg mx-4 shadow-2xl`,children:[(0,L.jsxs)(`div`,{className:`flex items-center gap-3 mb-4`,children:[(0,L.jsx)(fe,{size:28,className:`text-yellow-400 shrink-0`}),(0,L.jsx)(`h3`,{className:`text-lg font-semibold text-yellow-400`,children:l(`token.disclaimerTitle`)})]}),(0,L.jsxs)(`div`,{className:`text-sm text-gray-300 space-y-2 mb-5`,children:[(0,L.jsx)(`p`,{dangerouslySetInnerHTML:{__html:l(`token.disclaimerBody1`)}}),(0,L.jsx)(`p`,{className:`text-red-400 font-medium`,dangerouslySetInnerHTML:{__html:l(`token.disclaimerBody2`)}}),(0,L.jsx)(`p`,{dangerouslySetInnerHTML:{__html:l(`token.disclaimerBody3`)}})]}),(0,L.jsxs)(`label`,{className:`flex items-center gap-2 cursor-pointer select-none group`,children:[(0,L.jsx)(`input`,{type:`checkbox`,checked:u,onChange:e=>d(e.target.checked),className:`w-4 h-4 rounded border-yellow-500/50 accent-yellow-500`}),(0,L.jsx)(`span`,{className:`text-sm text-gray-400 group-hover:text-gray-300 transition`,children:l(`token.acceptRisk`)})]})]})}),(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-lg px-3 py-2 flex flex-wrap items-center gap-2 shrink-0`,children:[(0,L.jsxs)(`button`,{onClick:()=>h(!0),className:`btn-primary`,children:[(0,L.jsx)(se,{size:14,className:`inline mr-1`}),l(`btn.import`)]}),(0,L.jsxs)(`button`,{onClick:()=>_(!0),className:`btn-secondary`,children:[(0,L.jsx)(le,{size:14,className:`inline mr-1`}),l(`btn.add`)]}),O&&(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(`div`,{className:`h-5 border-l border-dark-500`}),(0,L.jsxs)(`div`,{className:`flex items-center gap-2 min-w-0`,children:[(0,L.jsx)(`span`,{className:`text-xs text-gray-400 whitespace-nowrap`,children:l(`task.validate`)}),(0,L.jsx)(`div`,{className:`w-28 bg-dark-600 rounded-full h-2.5 shrink-0`,children:(0,L.jsx)(`div`,{className:`h-2.5 rounded-full transition-all duration-300 ${O.status===`completed`?`bg-green-500`:O.status===`failed`?`bg-red-500`:`bg-accent`}`,style:{width:`${O.total>1?O.total>0?Math.round(O.progress/O.total*100):0:O.total_steps?Math.round((O.step??0)/O.total_steps*100):0}%`}})}),(0,L.jsxs)(`span`,{className:`text-xs text-gray-500 whitespace-nowrap`,children:[O.total>1?`${O.progress}/${O.total}${O.active_count?` (${O.active_count})`:``}`:O.step_label||`${O.progress}/${O.total}`,O.total>1?` (${O.total>0?Math.round(O.progress/O.total*100):0}%)`:O.total_steps?` (${O.step}/${O.total_steps})`:``]}),O.status===`completed`&&(0,L.jsx)(Ae,{size:14,className:`text-green-400`}),O.status===`failed`&&(0,L.jsx)(`span`,{title:O.error||``,children:(0,L.jsx)(ke,{size:14,className:`text-red-400`})})]})]}),(0,L.jsxs)(`div`,{className:`ml-auto flex items-center gap-2`,children:[(0,L.jsx)(wt,{}),(0,L.jsx)(`div`,{className:`h-5 border-l border-dark-500`}),(0,L.jsx)(`button`,{onClick:ne,className:`btn-danger-outline text-xs`,children:l(`btn.deleteSelected`)}),(0,L.jsx)(`button`,{onClick:N,className:`btn-danger text-xs`,children:l(`btn.deleteAll`)})]})]}),(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-lg overflow-hidden flex-1 min-h-0 flex flex-col`,children:[(0,L.jsxs)(`div`,{className:`px-3 py-2 flex items-center gap-2 border-b border-dark-600 shrink-0 bg-dark-800`,children:[(0,L.jsxs)(`button`,{onClick:M,disabled:t.size===0||x.size>0,className:`btn-accent text-sm disabled:opacity-40`,children:[(0,L.jsx)(Oe,{size:12,className:`inline mr-1`}),l(`btn.validate`)]}),(0,L.jsx)(`div`,{className:`h-5 border-l border-dark-500`}),(0,L.jsxs)(`button`,{onClick:P,className:`btn-secondary text-sm`,children:[(0,L.jsx)(me,{size:14,className:`inline mr-1`}),l(`btn.assignProxies`)]}),(0,L.jsxs)(`button`,{onClick:re,className:`btn-secondary text-sm`,children:[(0,L.jsx)(he,{size:14,className:`inline mr-1`}),l(`btn.reassign`)]}),(0,L.jsxs)(`button`,{onClick:ie,className:`btn-danger-outline text-sm`,children:[(0,L.jsx)(ge,{size:14,className:`inline mr-1`}),l(`btn.clearProxies`)]}),(0,L.jsx)(`div`,{className:`ml-auto`,children:(0,L.jsx)(`input`,{type:`text`,value:f,onChange:e=>p(e.target.value),placeholder:l(`ph.search`),className:`bg-dark-700 border border-dark-600 rounded px-2 py-1.5 text-xs w-80 placeholder:text-gray-500 outline-none focus:border-accent`})})]}),(0,L.jsx)(`div`,{className:`overflow-auto flex-1 min-h-0`,children:(0,L.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,L.jsx)(`thead`,{className:`sticky top-0 bg-dark-800 z-10`,children:(0,L.jsxs)(`tr`,{className:`text-left text-xs text-gray-500 border-b border-dark-600`,children:[(0,L.jsx)(`th`,{className:`px-3 py-2`,children:(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,L.jsx)(`input`,{type:`checkbox`,checked:I,onChange:()=>I?a():i()}),t.size>0&&(0,L.jsx)(`span`,{className:`text-accent font-medium`,children:t.size})]})}),(0,L.jsx)(`th`,{className:`w-5`}),s.browser&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:l(`col.browser`)}),s.profile&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:l(`col.profile`)}),s.last_online&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:l(`col.lastOnline`)}),s.steam_id&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:`Steam ID`}),s.login&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:l(`col.login`)}),s.token&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:l(`col.token`)}),s.status&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:l(`col.status`)}),s.proxy&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:l(`col.proxy`)}),s.notes&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:l(`col.notes`)}),s.actions&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:l(`col.actions`)})]})}),(0,L.jsx)(`tbody`,{children:oe.length===0?(0,L.jsx)(`tr`,{children:(0,L.jsx)(`td`,{colSpan:12,className:`text-center py-12 text-gray-500`,children:l(`empty.tokens`)})}):oe.map(e=>{let i=x.has(e.id),a=C[String(e.id)],o=T[String(e.id)];return(0,L.jsxs)(`tr`,{className:`hover:bg-dark-700/50 transition border-t border-dark-700`,children:[(0,L.jsx)(`td`,{className:`px-3 py-2`,children:(0,L.jsx)(`input`,{type:`checkbox`,checked:t.has(e.id),onChange:()=>r(e.id)})}),(0,L.jsx)(`td`,{className:`px-1 py-2 w-5`,children:i?(0,L.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,L.jsx)(`div`,{className:`w-4 h-4 border-2 border-accent border-t-transparent rounded-full animate-spin shrink-0`}),o&&(0,L.jsxs)(`span`,{className:`text-[10px] text-gray-500 whitespace-nowrap`,children:[`[`,o.step,`/`,o.total,`]`]})]}):a?.status===`ok`?(0,L.jsx)(ue,{size:16,className:`text-gray-400`}):a?.status===`error`?(0,L.jsx)(`span`,{title:a.error,children:(0,L.jsx)(fe,{size:16,className:`text-red-400`})}):null}),s.browser&&(0,L.jsx)(`td`,{className:`px-3 py-2 whitespace-nowrap text-center`,children:e.has_cookies?(0,L.jsx)(`button`,{onClick:()=>ae(e.id),className:`px-2 py-0.5 text-xs font-medium rounded bg-blue-600/20 text-blue-400 border border-blue-500/30 hover:bg-blue-600/40 hover:text-blue-300 active:scale-95 transition`,title:l(`tip.openBrowser`),children:l(`col.browser`)}):(0,L.jsx)(`span`,{className:`text-gray-600 text-xs`,children:`—`})}),s.profile&&(0,L.jsx)(`td`,{className:`px-3 py-2 whitespace-nowrap`,children:(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[e.avatar_url&&(0,L.jsx)(`img`,{src:e.avatar_url,className:`avatar-sm`,alt:``}),(0,L.jsx)(`span`,{className:`text-xs`,children:e.nickname||`—`}),e.steam_level!=null&&(0,L.jsx)(nt,{level:e.steam_level})]})}),s.last_online&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs text-gray-400 whitespace-nowrap`,children:e.last_online||`—`}),s.steam_id&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs`,children:e.steam_id?(0,L.jsx)(`a`,{href:`https://steamcommunity.com/profiles/${encodeURIComponent(e.steam_id)}/`,target:`_blank`,rel:`noopener noreferrer`,className:`text-blue-400 hover:text-blue-300 hover:underline`,children:e.steam_id}):`—`}),s.login&&(0,L.jsx)(`td`,{className:`px-3 py-2 font-medium`,children:e.login??`—`}),s.token&&(0,L.jsxs)(`td`,{className:`px-3 py-2 font-mono text-gray-400 truncate max-w-[180px]`,title:e.token,children:[e.token.slice(0,24),`…`]}),s.status&&(0,L.jsx)(`td`,{className:`px-3 py-2`,children:(0,L.jsx)(Ge,{status:e.status})}),s.proxy&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs text-gray-500 whitespace-nowrap`,children:R.get(e.id)??`—`}),s.notes&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs text-gray-500`,children:e.notes??`—`}),s.actions&&(0,L.jsx)(`td`,{className:`px-3 py-2 whitespace-nowrap`,children:(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,L.jsx)(`button`,{onClick:()=>te(e.id),disabled:i,className:`text-gray-400 hover:text-accent disabled:opacity-40 transition`,title:l(`tip.validate`),children:(0,L.jsx)(Oe,{size:14})}),(0,L.jsx)(`button`,{onClick:()=>k(l(`confirm.deleteToken`,{name:e.login??e.token.slice(0,16)}),async()=>{await D.deleteTokenAccount(e.id),n()}),className:`text-gray-400 hover:text-red-400 transition`,title:l(`tip.delete`),children:(0,L.jsx)(Ce,{size:14})})]})})]},e.id)})})]})})]}),m&&(0,L.jsx)(xt,{onClose:()=>h(!1)}),g&&(0,L.jsx)(St,{onClose:()=>_(!1)}),v.open&&(0,L.jsx)(ut,{message:v.message,onConfirm:()=>{v.onConfirm(),b(e=>({...e,open:!1}))},onCancel:()=>b(e=>({...e,open:!1}))})]})}function Dt(e){if(!e)return null;if(typeof e==`string`)try{return JSON.parse(e)}catch{return null}return e}function Ot(e){if(!e)return[];try{return JSON.parse(e)}catch{return[]}}var kt=[{value:``,labelKey:`action.selectAction`},{value:`validate`,labelKey:`action.validate`},{value:`change_password`,labelKey:`action.changePassword`},{value:`random_password`,labelKey:`action.randomPassword`},{value:`change_email`,labelKey:`action.changeEmail`},{value:`remove_guard`,labelKey:`action.removeGuard`},{value:`enable_auto_accept`,labelKey:`action.enableAutoAccept`}];function At({value:e,onChange:t,disabledActions:n}){let r=F(),[i,a]=(0,y.useState)(!1),o=(0,y.useRef)(null);return(0,y.useEffect)(()=>{if(!i)return;let e=e=>{o.current&&!o.current.contains(e.target)&&a(!1)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[i]),(0,L.jsxs)(`div`,{ref:o,className:`relative`,children:[(0,L.jsxs)(`button`,{type:`button`,onClick:()=>a(e=>!e),className:`bg-dark-700 border border-dark-600 rounded px-2 py-1.5 text-sm flex items-center gap-1 min-w-[170px] justify-between hover:border-dark-500 transition-colors`,children:[(0,L.jsx)(`span`,{className:`truncate`,children:r(kt.find(t=>t.value===e)?.labelKey||`action.selectAction`)}),(0,L.jsx)(`svg`,{width:`12`,height:`12`,viewBox:`0 0 12 12`,fill:`none`,className:`shrink-0 transition-transform ${i?`rotate-180`:``}`,children:(0,L.jsx)(`path`,{d:`M3 4.5L6 7.5L9 4.5`,stroke:`currentColor`,strokeWidth:`1.5`,strokeLinecap:`round`,strokeLinejoin:`round`})})]}),i&&(0,L.jsx)(`div`,{className:`absolute top-full left-0 mt-1 z-50 bg-dark-700 border border-dark-600 rounded shadow-lg min-w-[100px] py-1 max-h-[320px] overflow-y-auto`,children:kt.map(i=>{let o=!!(i.value&&n?.has(i.value));return(0,L.jsx)(`button`,{type:`button`,onClick:()=>{o||(t(i.value),a(!1))},disabled:o,title:o?r(`action.noRevocationCode`):void 0,className:`w-full text-left px-3 py-2 text-sm transition-colors ${o?`opacity-40 cursor-not-allowed`:`hover:bg-dark-600`} ${i.value===e?`text-accent bg-dark-600/50`:``} ${i.value?``:`text-gray-500`}`,children:r(i.labelKey)},i.value)})})]})}function jt(){let e=j(e=>e.accountSection),t=ze(e=>e.accounts.length),n=Ve(e=>e.accounts.length),r=He(e=>e.accounts.length),i=Ve(e=>e.loadAccounts),a=He(e=>e.loadAccounts),[o,s]=(0,y.useState)(0),c=(0,y.useRef)(0),l=(0,y.useRef)(0),u=(0,y.useRef)(e);(0,y.useEffect)(()=>{e===`logpass`&&n===0&&i(),e===`token`&&r===0&&a()},[e]);let d=e===`logpass`?n:e===`token`?r:t;return(0,y.useEffect)(()=>{cancelAnimationFrame(c.current);let t=u.current!==e;if(u.current=e,t){l.current=d,s(d);return}let n=l.current,r=d-n;if(r===0)return;let i=Math.min(400,Math.max(150,Math.abs(r)*2)),a=performance.now(),o=e=>{let t=e-a,u=Math.min(t/i,1),d=1-(1-u)**3,f=Math.max(0,Math.round(n+r*d));l.current=f,s(f),u<1&&(c.current=requestAnimationFrame(o))};return c.current=requestAnimationFrame(o),()=>cancelAnimationFrame(c.current)},[d,e]),(0,L.jsxs)(`div`,{className:`mt-1 px-3 py-2 border-t border-dark-600 flex items-center gap-2`,children:[(0,L.jsxs)(`div`,{className:`relative shrink-0`,style:{width:14,height:14},children:[(0,L.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:`14`,height:`14`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,className:`text-gray-400`,children:[(0,L.jsx)(`path`,{d:`M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2`}),(0,L.jsx)(`circle`,{cx:`9`,cy:`7`,r:`4`}),(0,L.jsx)(`path`,{d:`M22 21v-2a4 4 0 0 0-3-3.87`}),(0,L.jsx)(`path`,{d:`M16 3.13a4 4 0 0 1 0 7.75`})]}),(0,L.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:`14`,height:`14`,viewBox:`0 0 24 24`,fill:`none`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,className:`icon-shimmer absolute inset-0`,style:{pointerEvents:`none`},children:[(0,L.jsx)(`path`,{d:`M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2`}),(0,L.jsx)(`circle`,{cx:`9`,cy:`7`,r:`4`}),(0,L.jsx)(`path`,{d:`M22 21v-2a4 4 0 0 0-3-3.87`}),(0,L.jsx)(`path`,{d:`M16 3.13a4 4 0 0 1 0 7.75`})]})]}),(0,L.jsx)(`span`,{className:`text-sm text-gray-300 font-medium tabular-nums`,children:o})]})}function Mt(){let e=ze(e=>e.accounts),t=ze(e=>e.selectedIds),n=ze(e=>e.loadAccounts),r=ze(e=>e.clearSelection),i=ze(e=>e.sendToMafileManager),a=j(e=>e.setTab),o=j(e=>e.addToast),s=Be(e=>e.loadTasks),c=F(),[l,u]=(0,y.useState)(null),[d,f]=(0,y.useState)(!1),[p,m]=(0,y.useState)(!1),[h,g]=(0,y.useState)(null),[_,v]=(0,y.useState)(null),[b,x]=(0,y.useState)(``),S=j(e=>e.accountSection),C=j(e=>e.setAccountSection),[w,T]=(0,y.useState)(null),[E,O]=(0,y.useState)(new Set),[ee,k]=(0,y.useState)(``),[A,M]=(0,y.useState)(null),[te,ne]=(0,y.useState)(``),[N,P]=(0,y.useState)({}),[re,ie]=(0,y.useState)({}),ae=(0,y.useMemo)(()=>{if(!ee.trim())return e;let t=ee.trim(),n=t.match(/^lvl\s*(>=|<=|>|<|=)\s*(\d+)$/i);if(n){let t=n[1],r=parseInt(n[2],10);return e.filter(e=>{let n=e.steam_level;return n==null?!1:t===`>`?n>r:t===`>=`?n>=r:t===`<`?n{if(e.login.toLowerCase().includes(r)||e.steam_id&&e.steam_id.toLowerCase().includes(r))return!0;if(e.notes){let t=e.notes.toLowerCase();return i.some(e=>t.includes(e))}return!1})},[e,ee]),I=(0,y.useMemo)(()=>{let n=new Set;return e.filter(e=>t.has(e.id)).some(e=>e.has_revocation_code)||n.add(`remove_guard`),n},[e,t]);(0,y.useEffect)(()=>{n()},[]);let oe=(e,t)=>{g(e),v(()=>t)},R=(0,y.useCallback)((e,t=[],r=!0)=>{r&&P(e=>{let n={...e};return t.forEach(e=>delete n[String(e)]),n});let i=new EventSource(`/api/tasks/${e}/stream`);i.onmessage=r=>{try{let a=JSON.parse(r.data);T(a);let l=Dt(a.account_results);l&&P(e=>({...e,...l})),a.account_steps&&ie(e=>({...e,...a.account_steps})),a.prompt&&(M({taskId:e,message:a.prompt,login:a.prompt_login}),ne(``)),(a.status===`completed`||a.status===`failed`||a.status===`cancelled`)&&(a.status===`completed`?o(`success`,`${a.type}: ${a.result||c(`toast.done`)}`):a.status===`cancelled`?o(`info`,c(`toast.taskCancelled`)):o(`error`,`${a.type}: ${a.error||c(`toast.error`)}`),O(e=>{let n=new Set(e);return t.forEach(e=>n.delete(e)),n}),M(null),n(),s(),i.close(),setTimeout(()=>T(null),3e3))}catch{}},i.onerror=()=>i.close()},[o,n,s]);(0,y.useEffect)(()=>{let e=!1;return(async()=>{try{let t=await D.getTasks();if(e)return;let n=t.find(e=>e.status===`running`);if(n){let e=Ot(n.account_ids);T(n),O(new Set(e));let t=Dt(n.account_results);t&&P(t),R(n.id,e,!1);return}let r=t.find(e=>e.status===`completed`||e.status===`failed`);if(r){let e=Dt(r.account_results);e&&Object.keys(e).length>0&&P(e)}}catch{}})(),()=>{e=!0}},[R]);let ce=async(t,n,r)=>{let i=e.find(e=>e.id===t)?.login??`#${t}`;try{O(e=>new Set(e).add(t));let e=await D.executeAction({account_ids:[t],action:n,params:r});o(`info`,c(`misc.taskAction`,{id:e.task_id,action:n,login:i})),R(e.task_id,[t])}catch(e){O(e=>{let n=new Set(e);return n.delete(t),n}),o(`error`,c(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}},ue=async()=>{if(!(!A||!te))try{await D.respondToPrompt(A.taskId,te,A.login),M(null)}catch(e){o(`error`,c(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}},de=async()=>{if(A)try{await D.cancelTask(A.taskId)}catch{}M(null)},fe=()=>{if(!b)return o(`warn`,c(`toast.selectAction`));if(!t.size)return o(`warn`,c(`toast.selectAccounts`));if(b===`enable_auto_accept`){let e=[...t];r(),D.startAutoAccept(e).then(()=>{o(`success`,c(`toast.autoAcceptEnabled`,{count:e.length})),n()}).catch(e=>o(`error`,c(`misc.error`,{error:e instanceof Error?e.message:String(e)})));return}let e=[...t],i=b;oe(c(`confirm.executeBulk`,{action:c(kt.find(e=>e.value===i)?.labelKey||`action.selectAction`),count:e.length}),async()=>{try{let t=await D.executeAction({account_ids:e,action:i});r(),O(t=>{let n=new Set(t);return e.forEach(e=>n.add(e)),n}),o(`info`,c(`misc.taskCount`,{id:t.task_id,count:t.accounts_count})),R(t.task_id,e)}catch(e){o(`error`,c(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}})},_e=async t=>{let r=e.find(e=>e.id===t);if(!r)return;let i=!r.auto_accept;try{i?await D.startAutoAccept([t]):await D.stopAutoAccept([t]),o(`info`,c(i?`toast.autoAcceptOn`:`toast.autoAcceptOff`)),await n()}catch(e){o(`error`,c(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}},ve=e=>u(e),xe=async(e,t)=>{try{await D.updateAccount(e,t),u(null),o(`success`,c(`toast.saved`)),await n()}catch(e){o(`error`,c(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}},Se=e=>{oe(c(`confirm.deleteAccount`),async()=>{try{await D.deleteAccount(e),o(`success`,c(`toast.accountDeleted`)),await n()}catch(e){o(`error`,c(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}})},Ce=()=>{if(!t.size)return o(`warn`,c(`toast.selectAccounts`));oe(c(`confirm.deleteSelected`,{count:t.size}),async()=>{try{let e=await D.deleteBulk([...t]);r(),o(`success`,c(`toast.deleted`,{count:e.deleted})),await n()}catch(e){o(`error`,c(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}})},Te=()=>{if(!e.length)return o(`warn`,c(`toast.noAccounts`));oe(c(`confirm.deleteAll`,{count:e.length}),async()=>{try{let e=await D.deleteBulk([]);r(),o(`success`,c(`toast.deleted`,{count:e.deleted})),await n()}catch(e){o(`error`,c(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}})},Ee=async e=>{try{await D.createAccount(e),m(!1),o(`success`,c(`toast.accountAdded`)),await n()}catch(e){o(`error`,c(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}},De=()=>{if(!t.size)return o(`warn`,c(`toast.selectAccounts`));i([...t]),a(`mafiles`),o(`info`,c(`toast.sentToMafile`,{count:t.size}))},je=async e=>{try{let t=await D.openBrowser(e);t.status===`revalidating`?(o(`warn`,c(`toast.cookiesExpiredRevalidating`)),t.task_id&&(O(t=>new Set(t).add(e)),R(t.task_id,[e]))):o(`info`,c(`toast.browserOpening`))}catch(e){o(`error`,c(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}},Me=async()=>{oe(c(`confirm.assignProxies`),async()=>{try{let e=await D.assignProxies();o(`success`,c(`toast.proxiesAssigned`,{used:e.proxies_used,count:e.assigned})),await n()}catch(e){o(`error`,c(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}})},Ne=async()=>{oe(c(`confirm.reassignProxies`),async()=>{try{let e=await D.reassignProxies();o(`success`,c(`toast.proxiesReassigned`,{used:e.proxies_used,count:e.assigned})),await n()}catch(e){o(`error`,c(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}})},Pe=async()=>{oe(c(`confirm.clearProxies`),async()=>{try{o(`success`,c(`toast.proxiesClearedCount`,{count:(await D.clearProxies()).cleared})),await n()}catch(e){o(`error`,c(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}})},Fe=l?e.find(e=>e.id===l):null,Ie=[{id:`mafile`,label:`Mafile`,icon:(0,L.jsx)(we,{size:14})},{id:`logpass`,label:`Log:Pass`,icon:(0,L.jsx)(ye,{size:14})},{id:`token`,label:`Token`,icon:(0,L.jsx)(be,{size:14})}];return(0,L.jsxs)(`div`,{className:`flex gap-3 h-full min-h-0 overflow-hidden`,children:[(0,L.jsxs)(`div`,{className:`w-36 shrink-0 flex flex-col gap-1 bg-dark-800 border border-dark-600 rounded-lg p-2 self-start`,children:[(0,L.jsx)(`p`,{className:`text-xs font-medium text-gray-500 px-2 py-1 uppercase tracking-wider`,children:c(`section.dataType`)}),Ie.map(e=>(0,L.jsxs)(`button`,{onClick:()=>C(e.id),className:`flex items-center gap-2 px-3 py-2 rounded text-sm text-left w-full transition-colors ${S===e.id?`bg-accent/20 text-accent`:`text-gray-400 hover:text-gray-200 hover:bg-dark-700`}`,children:[e.icon,e.label]},e.id)),(0,L.jsx)(jt,{})]}),S===`logpass`&&(0,L.jsx)(`div`,{className:`flex-1 min-w-0 min-h-0`,children:(0,L.jsx)(yt,{})}),S===`token`&&(0,L.jsx)(`div`,{className:`flex-1 min-w-0 min-h-0`,children:(0,L.jsx)(Et,{})}),S===`mafile`&&(0,L.jsxs)(`div`,{className:`flex flex-col gap-4 flex-1 min-w-0 min-h-0 overflow-hidden`,children:[(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-lg px-3 py-2 flex flex-wrap items-center gap-2 shrink-0`,children:[(0,L.jsxs)(`button`,{onClick:()=>f(!0),className:`btn-primary`,children:[(0,L.jsx)(se,{size:14,className:`inline mr-1`}),c(`btn.import`)]}),(0,L.jsxs)(`button`,{onClick:()=>m(!0),className:`btn-secondary`,children:[(0,L.jsx)(le,{size:14,className:`inline mr-1`}),c(`btn.add`)]}),w&&(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(`div`,{className:`h-5 border-l border-dark-500`}),(0,L.jsxs)(`div`,{className:`flex items-center gap-2 min-w-0`,children:[(0,L.jsx)(`span`,{className:`text-xs text-gray-400 whitespace-nowrap`,children:w.type===`validate`?c(`task.validate`):w.type===`change_password`?c(`task.changePassword`):w.type===`random_password`?c(`task.randomPassword`):w.type===`change_email`?c(`task.changeEmail`):w.type===`change_phone`?c(`task.changePhone`):w.type===`remove_guard`?c(`task.removeGuard`):w.type}),(0,L.jsx)(`div`,{className:`w-28 bg-dark-600 rounded-full h-2.5 shrink-0`,children:(0,L.jsx)(`div`,{className:`h-2.5 rounded-full transition-all duration-300 ${w.status===`completed`?`bg-green-500`:w.status===`failed`?`bg-red-500`:`bg-accent`}`,style:{width:`${w.total>1?w.total>0?Math.round(w.progress/w.total*100):0:w.total_steps?Math.round((w.step??0)/w.total_steps*100):0}%`}})}),(0,L.jsxs)(`span`,{className:`text-xs text-gray-500 whitespace-nowrap`,children:[w.total>1?`${w.progress}/${w.total}${w.active_count?` (${w.active_count})`:``}`:w.step_label||`${w.progress}/${w.total}`,w.total>1?` (${w.total>0?Math.round(w.progress/w.total*100):0}%)`:w.total_steps?` (${w.step}/${w.total_steps})`:``]}),w.status===`completed`&&(0,L.jsx)(Ae,{size:14,className:`text-green-400`}),w.status===`failed`&&(0,L.jsx)(`span`,{title:w.error||``,children:(0,L.jsx)(ke,{size:14,className:`text-red-400`})})]})]}),(0,L.jsxs)(`div`,{className:`ml-auto flex items-center gap-2`,children:[(0,L.jsx)(ft,{}),(0,L.jsx)(`div`,{className:`h-5 border-l border-dark-500`}),(0,L.jsx)(`button`,{onClick:Ce,className:`btn-danger-outline text-xs`,children:c(`btn.deleteSelected`)}),(0,L.jsx)(`button`,{onClick:Te,className:`btn-danger text-xs`,children:c(`btn.deleteAll`)})]})]}),(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-lg overflow-hidden flex-1 min-h-0 flex flex-col`,children:[(0,L.jsxs)(`div`,{className:`px-3 py-2 flex items-center gap-2 border-b border-dark-600 shrink-0 bg-dark-800`,children:[(0,L.jsx)(At,{value:b,onChange:x,disabledActions:I}),(0,L.jsxs)(`button`,{onClick:fe,disabled:!!w||E.size>0,className:`btn-accent text-sm disabled:opacity-40 disabled:cursor-not-allowed`,children:[(0,L.jsx)(Oe,{size:12,className:`inline mr-1`}),c(`btn.execute`)]}),w&&w.status===`running`&&(0,L.jsxs)(`button`,{onClick:async()=>{try{await D.cancelTask(w.id)}catch{}},className:`btn-danger text-sm`,children:[(0,L.jsx)(ke,{size:12,className:`inline mr-1`}),c(`btn.cancel`)]}),(0,L.jsx)(`div`,{className:`h-5 border-l border-dark-500`}),(0,L.jsxs)(`button`,{onClick:De,className:`btn-secondary text-sm`,children:[(0,L.jsx)(pe,{size:14,className:`inline mr-1`}),`В Mafile Manager`]}),(0,L.jsx)(`div`,{className:`h-5 border-l border-dark-500`}),(0,L.jsxs)(`button`,{onClick:Me,className:`btn-secondary text-sm`,children:[(0,L.jsx)(me,{size:14,className:`inline mr-1`}),c(`btn.assignProxies`)]}),(0,L.jsxs)(`button`,{onClick:Ne,className:`btn-secondary text-sm`,children:[(0,L.jsx)(he,{size:14,className:`inline mr-1`}),c(`btn.reassign`)]}),(0,L.jsxs)(`button`,{onClick:Pe,className:`btn-danger-outline text-sm`,children:[(0,L.jsx)(ge,{size:14,className:`inline mr-1`}),c(`btn.clearProxies`)]}),(0,L.jsx)(`div`,{className:`ml-auto`,children:(0,L.jsx)(`input`,{type:`text`,value:ee,onChange:e=>k(e.target.value),placeholder:c(`ph.search`),className:`bg-dark-700 border border-dark-600 rounded px-2 py-1.5 text-xs w-80 placeholder:text-gray-500 outline-none focus:border-accent`})})]}),(0,L.jsx)(`div`,{className:`overflow-auto flex-1 min-h-0`,children:(0,L.jsx)(ot,{accounts:ae,processingIds:E,accountResults:N,accountSteps:re,onEdit:ve,onDelete:Se,onAction:ce,onToggleAutoAccept:_e,onOpenBrowser:je})})]})]}),Fe&&(0,L.jsx)(st,{account:Fe,onSave:xe,onClose:()=>u(null)}),d&&(0,L.jsx)(ct,{onClose:()=>f(!1)}),p&&(0,L.jsx)(lt,{onSave:Ee,onClose:()=>m(!1)}),h&&_&&(0,L.jsx)(ut,{message:h,onConfirm:()=>{_(),g(null),v(null)},onCancel:()=>{g(null),v(null)}}),A&&(0,L.jsx)(`div`,{className:`fixed inset-0 bg-black/60 flex items-center justify-center z-50`,onMouseDown:de,children:(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-lg p-5 w-96 shadow-xl`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`p`,{className:`text-sm text-gray-300 mb-3`,children:A.message}),(0,L.jsx)(`input`,{autoFocus:!0,value:te,onChange:e=>ne(e.target.value),onKeyDown:e=>e.key===`Enter`&&ue(),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm mb-3`,placeholder:c(`prompt.enterValue`)}),(0,L.jsxs)(`div`,{className:`flex gap-2`,children:[(0,L.jsx)(`button`,{onClick:ue,className:`btn-primary flex-1`,children:`OK`}),(0,L.jsx)(`button`,{onClick:de,className:`btn-secondary flex-1`,children:c(`btn.cancel`)})]})]})})]})}function Nt(){let e=F(),[t,n]=(0,y.useState)(`secret`),[r,i]=(0,y.useState)(``),[a,o]=(0,y.useState)(``),[s,c]=(0,y.useState)(``),[l,u]=(0,y.useState)(null),[d,f]=(0,y.useState)(!1),p=(0,y.useRef)(null),m=j(e=>e.addToast),h=ze(e=>e.accounts),g=ze(e=>e.loadAccounts);(0,y.useEffect)(()=>{t===`account`&&h.length===0&&g()},[t]),(0,y.useEffect)(()=>{let e=e=>{p.current&&!p.current.contains(e.target)&&f(!1)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[]);let _=h.filter(e=>{let t=s.toLowerCase();return!t||e.login.toLowerCase().includes(t)||(e.steam_id??``).includes(t)}).slice(0,12),v=async()=>{try{if(t===`secret`){if(!r.trim())return;o((await D.generate2FA(r.trim())).code)}else{if(!l)return;o((await D.generate2FAByAccount(l.id)).code)}}catch(t){o(e(`tools.genErrorStr`)),m(`error`,e(`misc.genError`,{error:t instanceof Error?t.message:String(t)}))}},b=async()=>{if(!a||a===e(`tools.genErrorStr`))return;let t=await Ue(a);m(t?`success`:`error`,e(t?`toast.copied`:`toast.copyFailed`))},x=e=>`flex-1 py-1.5 text-xs font-medium rounded transition-colors ${t===e?`bg-dark-600 text-gray-100`:`text-gray-500 hover:text-gray-300`}`;return(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-xl overflow-hidden flex flex-col`,children:[(0,L.jsxs)(`div`,{className:`px-4 py-3 border-b border-dark-600 flex items-center gap-2`,children:[(0,L.jsx)(ye,{size:14,className:`text-accent shrink-0`}),(0,L.jsx)(`span`,{className:`text-sm font-semibold text-gray-100`,children:e(`tools.2faGenerator`)})]}),(0,L.jsxs)(`div`,{className:`px-4 pt-3 pb-2`,children:[(0,L.jsxs)(`div`,{className:`flex gap-1 bg-dark-900 rounded p-0.5 mb-3`,children:[(0,L.jsx)(`button`,{type:`button`,className:x(`secret`),onClick:()=>n(`secret`),children:`Shared secret`}),(0,L.jsx)(`button`,{type:`button`,className:x(`account`),onClick:()=>n(`account`),children:`Из Mafile`})]}),t===`secret`?(0,L.jsxs)(`div`,{className:`flex gap-2`,children:[(0,L.jsx)(`input`,{value:r,onChange:e=>i(e.target.value),onKeyDown:e=>e.key===`Enter`&&v(),placeholder:`shared_secret`,className:`flex-1 bg-dark-700 border border-dark-600 rounded px-3 py-1.5 text-sm`}),(0,L.jsx)(`button`,{type:`button`,onClick:v,className:`btn-primary text-sm px-3 py-1.5`,children:e(`btn.generate`)})]}):(0,L.jsxs)(`div`,{className:`flex gap-2`,children:[(0,L.jsxs)(`div`,{className:`relative flex-1`,ref:p,children:[(0,L.jsx)(`input`,{value:l?`${l.login}${l.steam_id?` · `+l.steam_id:``}`:s,onChange:e=>{c(e.target.value),u(null),f(!0)},onFocus:()=>f(!0),placeholder:`Логин или SteamID...`,className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-1.5 text-sm`}),d&&_.length>0&&(0,L.jsx)(`div`,{className:`absolute top-full mt-1 left-0 right-0 bg-dark-800 border border-dark-600 rounded-lg shadow-xl z-50 max-h-48 overflow-y-auto`,children:_.map(e=>(0,L.jsxs)(`button`,{type:`button`,className:`w-full text-left px-3 py-1.5 text-sm hover:bg-dark-600 transition-colors flex items-center justify-between gap-2`,onMouseDown:()=>{u(e),c(``),f(!1)},children:[(0,L.jsx)(`span`,{className:`text-gray-200 truncate`,children:e.login}),e.steam_id&&(0,L.jsx)(`span`,{className:`text-gray-500 text-xs shrink-0`,children:e.steam_id})]},e.id))})]}),(0,L.jsx)(`button`,{type:`button`,onClick:v,disabled:!l,className:`btn-primary text-sm px-3 py-1.5 disabled:opacity-40 disabled:cursor-not-allowed`,children:e(`btn.generate`)})]}),a&&(0,L.jsx)(`div`,{className:`mt-3 text-2xl font-mono text-accent cursor-pointer tabular-nums tracking-widest`,onClick:b,title:e(`tools.clickCopy`),children:a})]})]})}var Pt=[{value:`login:pass@ip:port`,label:`login:pass@ip:port`},{value:`login:pass:ip:port`,label:`login:pass:ip:port`},{value:`ip:port@login:pass`,label:`ip:port@login:pass`},{value:`ip:port:login:pass`,label:`ip:port:login:pass`}];function Ft(e,t,n,r){let i=e.trim();if(!i)return null;let a=n;for(let e of[`socks5://`,`socks4://`,`http://`,`https://`])if(i.toLowerCase().startsWith(e)){a=e.replace(`://`,``),i=i.slice(e.length);break}if(!i.includes(`@`)&&i.split(`:`).length===2)return{address:i,protocol:a};let o=``,s=``,c=``,l=``;if(t===`custom`&&r&&r.length>=4){let e=It(i,r);if(!e)return null;({ip:o,port:s,login:c,pass:l}=e)}else if(t===`login:pass@ip:port`){let e=i.indexOf(`@`);if(e===-1)return null;let t=i.slice(0,e),n=i.slice(e+1),r=t.split(`:`),a=n.split(`:`);if(r.length<2||a.length<2)return null;c=r[0],l=r.slice(1).join(`:`),o=a[0],s=a[1]}else if(t===`login:pass:ip:port`){let e=i.split(`:`);if(e.length<4)return null;c=e[0],l=e[1],o=e[2],s=e[3]}else if(t===`ip:port@login:pass`){let e=i.indexOf(`@`);if(e===-1)return null;let t=i.slice(0,e),n=i.slice(e+1),r=t.split(`:`),a=n.split(`:`);if(r.length<2||a.length<2)return null;o=r[0],s=r[1],c=a[0],l=a.slice(1).join(`:`)}else if(t===`ip:port:login:pass`){let e=i.split(`:`);if(e.length<4)return null;o=e[0],s=e[1],c=e[2],l=e[3]}return!o||!s?null:{address:c&&l?`${c}:${l}@${o}:${s}`:`${o}:${s}`,protocol:a}}function It(e,t){let n=[],r=[];for(let e=0;ee.addToast),x=F(),S=async()=>{try{t(await D.getProxies())}catch{}};(0,y.useEffect)(()=>{S()},[]);let C=async e=>{let t=e.split(` -`).filter(e=>e.trim());if(!t.length)return;let n=f?`custom`:c,i=[];for(let e of t){let t=Ft(e,n,u,f?m:void 0);t&&i.push(t)}if(!i.length){b(`error`,x(`toast.proxyFormatError`));return}try{b(`success`,x(`toast.proxiesAdded`,{count:(await D.bulkAddProxies(i)).added})),r(``),await S()}catch(e){b(`error`,x(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}},w=()=>C(n),T=async e=>{e.preventDefault(),_(!1);let t=e.dataTransfer.files[0];t&&await C(await t.text())},E=async e=>{let t=e.target.files?.[0];t&&(await C(await t.text()),e.target.value=``)},O=async e=>{try{await D.deleteProxy(e),await S()}catch(e){b(`error`,x(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}},ee=async()=>{if(e.length&&window.confirm(x(`proxy.confirmDeleteAll`)))try{b(`success`,x(`toast.proxiesDeleted`,{count:(await D.deleteAllProxies()).deleted})),s(``),await S()}catch(e){b(`error`,x(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}},k=async()=>{a(!0),s(``);try{let e=await D.checkProxies();s(x(`proxy.checkResult`,{total:e.total,alive:e.alive,dead:e.dead})),await S()}catch(e){b(`error`,x(`misc.proxyErrorCheck`,{error:e instanceof Error?e.message:String(e)}))}finally{a(!1)}},A=(e,t)=>{let n=[...m];n[e]=t,h(n)},M=m.join(``);return(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-lg p-4`,children:[(0,L.jsxs)(`h3`,{className:`font-semibold mb-3`,children:[(0,L.jsx)(me,{size:14,className:`inline mr-1`}),x(`proxy.title`),` `,(0,L.jsx)(`span`,{className:`text-xs text-gray-500 ml-2`,children:x(`proxy.count`,{count:e.length})})]}),(0,L.jsxs)(`div`,{className:`mb-3 space-y-2`,children:[(0,L.jsxs)(`div`,{className:`flex items-center gap-3 flex-wrap`,children:[(0,L.jsx)(`span`,{className:`text-xs text-gray-400`,children:x(`proxy.protocol`)}),(0,L.jsxs)(`select`,{value:u,onChange:e=>d(e.target.value),className:`bg-dark-700 border border-dark-600 rounded px-2 py-1 text-xs`,children:[(0,L.jsx)(`option`,{value:`http`,children:`HTTP`}),(0,L.jsx)(`option`,{value:`socks5`,children:`SOCKS5`})]}),(0,L.jsx)(`span`,{className:`text-xs text-gray-400`,children:x(`proxy.format`)}),(0,L.jsxs)(`select`,{value:f?`__custom__`:c,onChange:e=>{e.target.value===`__custom__`?p(!0):(p(!1),l(e.target.value))},className:`bg-dark-700 border border-dark-600 rounded px-2 py-1 text-xs`,children:[Pt.map(e=>(0,L.jsx)(`option`,{value:e.value,children:e.label},e.value)),(0,L.jsx)(`option`,{value:`__custom__`,children:x(`proxy.customFormat`)})]})]}),f&&(0,L.jsxs)(`div`,{className:`bg-dark-700 border border-dark-600 rounded p-3 space-y-2`,children:[(0,L.jsx)(`p`,{className:`text-xs text-gray-400`,children:x(`proxy.formatConstructor`)}),(0,L.jsx)(`div`,{className:`flex items-center gap-1 flex-wrap`,children:m.map((e,t)=>t%2==0?(0,L.jsx)(`select`,{value:e,onChange:e=>A(t,e.target.value),className:`bg-dark-600 border border-dark-500 rounded px-2 py-1 text-xs text-accent`,children:Lt.map(e=>(0,L.jsx)(`option`,{value:e,children:e},e))},t):(0,L.jsx)(`select`,{value:e,onChange:e=>A(t,e.target.value),className:`bg-dark-600 border border-dark-500 rounded px-1 py-1 text-xs text-yellow-400 w-10 text-center`,children:Rt.map(e=>(0,L.jsx)(`option`,{value:e,children:e},e))},t))}),(0,L.jsxs)(`p`,{className:`text-xs text-gray-500`,children:[x(`proxy.preview`),` `,(0,L.jsx)(`span`,{className:`text-gray-300`,children:M})]})]})]}),(0,L.jsxs)(`div`,{onDragOver:e=>{e.preventDefault(),_(!0)},onDragLeave:()=>_(!1),onDrop:T,onClick:()=>v.current?.click(),className:`border-2 border-dashed rounded-lg p-4 mb-2 text-center cursor-pointer transition-colors ${g?`border-accent bg-accent/10`:`border-dark-500 hover:border-accent`}`,children:[(0,L.jsx)(ce,{size:24,className:`mx-auto mb-1 text-gray-500`}),(0,L.jsx)(`p`,{className:`text-xs text-gray-400`,children:x(`proxy.dragFile`)})]}),(0,L.jsx)(`input`,{ref:v,type:`file`,accept:`.txt`,className:`hidden`,onChange:E}),(0,L.jsx)(`textarea`,{value:n,onChange:e=>r(e.target.value),rows:4,placeholder:x(`proxy.perLine`,{format:f?M:c}),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm mb-2 resize-y`}),(0,L.jsxs)(`div`,{className:`flex gap-2 mb-3 flex-wrap`,children:[(0,L.jsx)(`button`,{onClick:w,className:`btn-primary`,children:x(`proxy.addBtn`)}),(0,L.jsx)(`button`,{onClick:k,disabled:i,className:`btn-secondary`,children:x(i?`proxy.checking`:`proxy.checkAll`)}),e.length>0&&(0,L.jsx)(`button`,{onClick:ee,className:`btn-danger text-xs`,children:x(`proxy.deleteAllBtn`)})]}),o&&(0,L.jsx)(`p`,{className:`text-xs text-gray-300 mb-3`,children:o}),e.length>0&&(()=>{let t=e.filter(e=>e.is_alive).length,n=e.length-t;return(0,L.jsxs)(`p`,{className:`text-xs text-gray-400 mb-3`,children:[(0,L.jsxs)(`span`,{className:`text-green-400`,children:[`● `,t]}),(0,L.jsx)(`span`,{className:`mx-2`,children:`/`}),(0,L.jsxs)(`span`,{className:`text-red-400`,children:[`● `,n]}),(0,L.jsx)(`span`,{className:`mx-2`,children:`/`}),(0,L.jsx)(`span`,{children:e.length})]})})(),(0,L.jsx)(`div`,{className:`max-h-48 overflow-y-auto space-y-1`,children:e.map(e=>(0,L.jsxs)(`div`,{className:`flex items-center justify-between text-xs gap-2 group px-2 py-1 rounded hover:bg-dark-700`,children:[(0,L.jsxs)(`span`,{className:`${e.is_alive?`text-green-400`:`text-red-400`} min-w-0 truncate`,children:[e.protocol,`://`,e.address]}),(0,L.jsx)(`button`,{onClick:()=>O(e.id),className:`text-red-400 hover:bg-red-400/20 rounded px-2 py-0.5 text-sm font-medium shrink-0 transition`,title:x(`proxy.deleteProxy`),children:`✕`})]},e.id))})]})}function Bt({checked:e,onChange:t}){return(0,L.jsxs)(`label`,{className:`toggle-switch`,children:[(0,L.jsx)(`input`,{type:`checkbox`,checked:e,onChange:e=>t(e.target.checked)}),(0,L.jsx)(`span`,{className:`toggle-track`})]})}function Vt({label:e,desc:t,checked:n,onChange:r}){return(0,L.jsxs)(`div`,{className:`flex items-center justify-between gap-4 py-2.5`,children:[(0,L.jsxs)(`div`,{className:`min-w-0`,children:[(0,L.jsx)(`p`,{className:`text-sm text-gray-200 leading-tight`,children:e}),t&&(0,L.jsx)(`p`,{className:`text-xs text-gray-500 mt-0.5`,children:t})]}),(0,L.jsx)(Bt,{checked:n,onChange:r})]})}function Ht({value:e,onChange:t}){let[n,r]=(0,y.useState)(!1),[i,a]=(0,y.useState)(``),o=(0,y.useRef)(null),s=e=>Math.max(1,e),c=()=>{t(s(parseInt(i)||e)),r(!1)},l=`h-6 px-1.5 rounded bg-dark-700 border border-dark-600 text-gray-300 hover:bg-dark-600 text-xs flex items-center justify-center select-none leading-none`;return(0,L.jsxs)(`div`,{className:`flex items-center gap-3 pt-3 mt-0.5`,children:[(0,L.jsx)(`span`,{className:`text-sm text-gray-400 flex-1`,title:`Двойной клик на числе для ручного ввода`,children:`Max threads`}),(0,L.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,L.jsx)(`button`,{type:`button`,className:l,onClick:()=>t(s(e-10)),children:`-10`}),(0,L.jsx)(`button`,{type:`button`,className:l,onClick:()=>t(s(e-1)),children:`-1`}),n?(0,L.jsx)(`input`,{ref:o,autoFocus:!0,value:i,onChange:e=>a(e.target.value),onBlur:c,onKeyDown:e=>{e.key===`Enter`&&c(),e.key===`Escape`&&r(!1)},className:`w-10 text-center text-sm font-mono bg-dark-900 border border-accent rounded outline-none text-gray-100 py-0.5`}):(0,L.jsx)(`span`,{className:`w-10 text-center text-sm font-mono text-gray-100 cursor-pointer select-none`,onDoubleClick:()=>{a(String(e)),r(!0)},title:`Двойной клик для ручного ввода`,children:e}),(0,L.jsx)(`button`,{type:`button`,className:l,onClick:()=>t(s(e+1)),children:`+1`}),(0,L.jsx)(`button`,{type:`button`,className:l,onClick:()=>t(s(e+10)),children:`+10`})]})]})}function Ut(){let e=F(),[t,n]=(0,y.useState)({fetch_profile:!0,check_ban:!0,max_threads:5,auto_revalidate_browser:!0}),r=j(e=>e.hidePasswords),i=j(e=>e.setHidePasswords),a=j(e=>e.addToast);return(0,y.useEffect)(()=>{D.getValidationSettings().then(n).catch(()=>{})},[]),(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-xl overflow-hidden flex flex-col`,children:[(0,L.jsxs)(`div`,{className:`px-5 py-3.5 border-b border-dark-600 flex items-center gap-2.5`,children:[(0,L.jsx)(xe,{size:15,className:`text-accent shrink-0`}),(0,L.jsx)(`span`,{className:`text-sm font-semibold text-gray-100`,children:`Settings`})]}),(0,L.jsxs)(`div`,{className:`px-5 pt-4 pb-3 border-b border-dark-600`,children:[(0,L.jsx)(`p`,{className:`text-[10px] font-semibold text-gray-500 uppercase tracking-widest mb-0.5`,children:e(`tools.validationSettings`)}),(0,L.jsxs)(`div`,{className:`divide-y divide-dark-600/60`,children:[(0,L.jsx)(Vt,{label:e(`tools.loadProfile`),checked:t.fetch_profile,onChange:e=>n({...t,fetch_profile:e})}),(0,L.jsx)(Vt,{label:e(`tools.checkBans`),checked:t.check_ban,onChange:e=>n({...t,check_ban:e})}),(0,L.jsx)(Vt,{label:e(`tools.autoRevalidateBrowser`),checked:t.auto_revalidate_browser,onChange:e=>n({...t,auto_revalidate_browser:e})})]}),(0,L.jsx)(Ht,{value:t.max_threads,onChange:e=>n(t=>({...t,max_threads:e}))})]}),(0,L.jsxs)(`div`,{className:`px-5 pt-4 pb-3`,children:[(0,L.jsx)(`p`,{className:`text-[10px] font-semibold text-gray-500 uppercase tracking-widest mb-0.5`,children:e(`settings.display`)}),(0,L.jsx)(Vt,{label:e(`settings.hidePasswords`),checked:r,onChange:i})]}),(0,L.jsx)(`div`,{className:`px-5 py-3 border-t border-dark-600 flex justify-end`,children:(0,L.jsx)(`button`,{onClick:async()=>{try{await D.updateValidationSettings(t),a(`success`,e(`toast.settingsSaved`))}catch(t){a(`error`,e(`misc.error`,{error:t instanceof Error?t.message:String(t)}))}},className:`btn-primary`,children:e(`btn.save`)})})]})}function Wt(){return(0,L.jsxs)(`div`,{className:`max-w-5xl mx-auto flex flex-col gap-4`,children:[(0,L.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-4`,children:[(0,L.jsx)(Nt,{}),(0,L.jsx)(Ut,{})]}),(0,L.jsx)(zt,{})]})}var Gt=[`shared_secret`,`serial_number`,`revocation_code`,`uri`,`account_name`,`token_gid`,`identity_secret`,`secret_1`,`device_id`,`server_time`,`fully_enrolled`],Kt=[`SessionID`,`AccessToken`,`RefreshToken`,`SteamID`,`SteamLoginSecure`],qt=[{value:`{username}`,label:`username`},{value:`{steamid}`,label:`steamid`}],Jt=[{value:`flat_mafiles`,icon:`📄`},{value:`per_account_folder`,icon:`📁`},{value:`single_file`,icon:`📦`}];function Yt({accountIds:e,onExport:t}){let n=F(),[r,i]=(0,y.useState)(new Set(Gt)),[a,o]=(0,y.useState)(new Set(Kt)),[s,c]=(0,y.useState)(`per_account_folder`),[l,u]=(0,y.useState)(`{username}`),[d,f]=(0,y.useState)(`{steamid}.mafile`),[p,m]=(0,y.useState)(`{username}.txt`),[h,g]=(0,y.useState)(!1),[_,v]=(0,y.useState)(!1),[b,x]=(0,y.useState)(!1),[S,C]=(0,y.useState)(`{login}:{password}:{email}:{email_password}`),w=(e,t,n)=>{let r=new Set(e);r.has(t)?r.delete(t):r.add(t),n(r)},T=(e,t)=>{e(e=>e+t)};return(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-xl overflow-hidden`,children:[(0,L.jsxs)(`div`,{className:`px-4 py-3 border-b border-dark-600 flex items-center gap-2`,children:[(0,L.jsx)(Te,{size:14,className:`text-accent`}),(0,L.jsx)(`h4`,{className:`font-semibold text-sm`,children:n(`mafile.exportSettings`)})]}),(0,L.jsxs)(`div`,{className:`p-4 space-y-4`,children:[(0,L.jsxs)(`div`,{children:[(0,L.jsx)(`p`,{className:`text-xs text-gray-400 mb-2`,children:n(`mafile.exportFormat`)}),(0,L.jsx)(`div`,{className:`grid grid-cols-3 gap-2`,children:Jt.map(e=>(0,L.jsxs)(`button`,{onClick:()=>{c(e.value),e.value===`single_file`&&(v(!1),x(!1))},className:`flex flex-col items-center gap-1 p-3 rounded-lg border text-xs transition-all cursor-pointer ${s===e.value?`border-accent bg-accent/10 text-white`:`border-dark-600 bg-dark-700 text-gray-400 hover:border-dark-500 hover:text-gray-300`}`,children:[(0,L.jsx)(`span`,{className:`text-base`,children:e.icon}),(0,L.jsx)(`span`,{children:n(`mafile.${e.value}`)})]},e.value))})]}),s!==`single_file`&&(0,L.jsxs)(`details`,{className:`group`,open:!0,children:[(0,L.jsxs)(`summary`,{className:`text-xs text-gray-400 cursor-pointer hover:text-gray-300 transition-colors flex items-center gap-1.5 select-none`,children:[(0,L.jsx)(Fe,{size:12,className:`transition-transform group-open:rotate-90`}),n(`mafile.namingSection`),(0,L.jsxs)(`span`,{className:`text-gray-500 ml-1`,children:[(0,L.jsx)(`code`,{className:`text-accent/70`,children:`{username}`}),` `,(0,L.jsx)(`code`,{className:`text-accent/70`,children:`{steamid}`})]})]}),(0,L.jsxs)(`div`,{className:`mt-3 space-y-3 pl-4 border-l border-dark-600`,children:[s===`per_account_folder`&&(0,L.jsx)(Xt,{label:n(`mafile.folderName`),value:l,onChange:u,vars:qt,insertVar:T}),(0,L.jsx)(Xt,{label:n(`mafile.mafileName`),value:d,onChange:f,vars:qt,insertVar:T})]})]}),(0,L.jsxs)(`details`,{className:`group`,children:[(0,L.jsxs)(`summary`,{className:`text-xs text-gray-400 cursor-pointer hover:text-gray-300 transition-colors flex items-center gap-1.5 select-none`,children:[(0,L.jsx)(Fe,{size:12,className:`transition-transform group-open:rotate-90`}),(0,L.jsx)(Ee,{size:12,className:`inline`}),n(`mafile.txtSettings`)]}),(0,L.jsxs)(`div`,{className:`mt-3 space-y-2.5 pl-4 border-l border-dark-600`,children:[s!==`single_file`&&(0,L.jsxs)(L.Fragment,{children:[(0,L.jsxs)(Zt,{checked:_,onChange:e=>{v(e),e||x(!1)},children:[n(`mafile.addGlobalTxt`),` `,(0,L.jsx)(`code`,{className:`text-accent text-xs`,children:`accounts.txt`})]}),s===`per_account_folder`&&(0,L.jsx)(Zt,{checked:h,onChange:g,children:n(`mafile.addTxtPerFolder`)}),(0,L.jsx)(Zt,{checked:b,onChange:x,disabled:!_,children:n(`mafile.skipFolders`)})]}),(_||h||s===`single_file`)&&(0,L.jsxs)(`div`,{className:`space-y-3 pt-1`,children:[s===`per_account_folder`&&h&&(0,L.jsx)(Xt,{label:n(`mafile.txtFolderName`),value:p,onChange:m,vars:qt,insertVar:T}),(0,L.jsxs)(`div`,{children:[(0,L.jsx)(`label`,{className:`text-xs text-gray-400 block mb-1`,children:n(`mafile.txtLineFormat`)}),(0,L.jsx)(`input`,{value:S,onChange:e=>C(e.target.value),className:`w-full bg-dark-700 border border-dark-600 rounded-lg px-3 py-1.5 text-sm font-mono focus:border-accent/50 focus:outline-none transition-colors`}),(0,L.jsxs)(`p`,{className:`text-[11px] text-gray-500 mt-1.5 leading-relaxed`,children:[n(`mafile.variables`),` `,(0,L.jsx)(`code`,{className:`text-accent/70`,children:`{login}`}),` `,(0,L.jsx)(`code`,{className:`text-accent/70`,children:`{password}`}),` `,(0,L.jsx)(`code`,{className:`text-accent/70`,children:`{email}`}),` `,(0,L.jsx)(`code`,{className:`text-accent/70`,children:`{email_password}`}),` `,(0,L.jsx)(`code`,{className:`text-accent/70`,children:`{steam_id}`}),` `,(0,L.jsx)(`code`,{className:`text-accent/70`,children:`{proxy}`}),` `,(0,L.jsx)(`code`,{className:`text-accent/70`,children:`{mafile}`})]})]})]})]})]}),(0,L.jsxs)(`details`,{className:`group`,children:[(0,L.jsxs)(`summary`,{className:`text-xs text-gray-400 cursor-pointer hover:text-gray-300 transition-colors flex items-center gap-1.5 select-none`,children:[(0,L.jsx)(Fe,{size:12,className:`transition-transform group-open:rotate-90`}),n(`mafile.mafileFields`),(0,L.jsxs)(`span`,{className:`text-gray-500 text-[11px]`,children:[r.size,`/`,Gt.length]})]}),(0,L.jsx)(`div`,{className:`flex flex-wrap gap-x-3 gap-y-1.5 mt-2 pl-4`,children:Gt.map(e=>(0,L.jsxs)(`label`,{className:`flex items-center gap-1.5 text-xs cursor-pointer hover:text-gray-200 transition-colors`,children:[(0,L.jsx)(`input`,{type:`checkbox`,checked:r.has(e),onChange:()=>w(r,e,i),className:`accent-accent`}),(0,L.jsx)(`span`,{className:`font-mono text-[11px]`,children:e})]},e))})]}),(0,L.jsxs)(`details`,{className:`group`,children:[(0,L.jsxs)(`summary`,{className:`text-xs text-gray-400 cursor-pointer hover:text-gray-300 transition-colors flex items-center gap-1.5 select-none`,children:[(0,L.jsx)(Fe,{size:12,className:`transition-transform group-open:rotate-90`}),n(`mafile.sessionFields`),(0,L.jsxs)(`span`,{className:`text-gray-500 text-[11px]`,children:[a.size,`/`,Kt.length]})]}),(0,L.jsx)(`div`,{className:`flex flex-wrap gap-x-3 gap-y-1.5 mt-2 pl-4`,children:Kt.map(e=>(0,L.jsxs)(`label`,{className:`flex items-center gap-1.5 text-xs cursor-pointer hover:text-gray-200 transition-colors`,children:[(0,L.jsx)(`input`,{type:`checkbox`,checked:a.has(e),onChange:()=>w(a,e,o),className:`accent-accent`}),(0,L.jsx)(`span`,{className:`font-mono text-[11px]`,children:e})]},e))})]}),(0,L.jsxs)(`button`,{onClick:()=>{t({fields:[...r],session_fields:[...a],format:s,account_ids:e,folder_name_template:l,mafile_name_template:d,txt_name_template:p,include_txt_per_folder:h,include_global_txt:_,skip_folders:b,txt_format:S})},disabled:e.length===0,className:`w-full flex items-center justify-center gap-2 py-2.5 rounded-lg font-medium text-sm transition-all ${e.length===0?`bg-dark-700 text-gray-500 cursor-not-allowed`:`bg-accent hover:bg-accent-hover text-white cursor-pointer`}`,children:[(0,L.jsx)(se,{size:14}),n(`mafile.export`),` (`,e.length>0?e.length:n(`mafile.noAccounts`),`)`]})]})]})}function Xt({label:e,value:t,onChange:n,vars:r,insertVar:i}){return(0,L.jsxs)(`div`,{children:[(0,L.jsx)(`label`,{className:`text-xs text-gray-400 block mb-1`,children:e}),(0,L.jsxs)(`div`,{className:`flex gap-1.5`,children:[(0,L.jsx)(`input`,{value:t,onChange:e=>n(e.target.value),className:`flex-1 bg-dark-700 border border-dark-600 rounded-lg px-3 py-1.5 text-sm font-mono focus:border-accent/50 focus:outline-none transition-colors`}),r.map(e=>(0,L.jsx)(`button`,{onClick:()=>i(e=>n(e(t)),e.value),className:`px-2 py-1 text-[11px] rounded bg-dark-700 border border-dark-600 text-gray-400 hover:text-accent hover:border-accent/30 transition-colors cursor-pointer`,children:e.label},e.value))]})]})}function Zt({checked:e,onChange:t,disabled:n,children:r}){return(0,L.jsxs)(`label`,{className:`flex items-center gap-2.5 text-sm cursor-pointer select-none ${n?`opacity-40 cursor-not-allowed`:`hover:text-gray-200`} transition-colors`,children:[(0,L.jsx)(`input`,{type:`checkbox`,checked:e,disabled:n,onChange:e=>t(e.target.checked),className:`accent-accent`}),(0,L.jsx)(`span`,{className:`text-xs`,children:r})]})}function Qt(){let e=F(),t=ze(e=>e.accounts),n=ze(e=>e.mafileManagerIds),r=ze(e=>e.clearMafileManager),i=j(e=>e.addToast),a=t.filter(e=>n.has(e.id)),o=async t=>{try{let n=await D.exportZip(t),r=URL.createObjectURL(n),a=document.createElement(`a`);a.href=r,a.download=`mafiles_export.zip`,a.click(),URL.revokeObjectURL(r),i(`success`,e(`toast.exportDone`))}catch(t){i(`error`,e(`misc.exportError`,{error:t instanceof Error?t.message:String(t)}))}},s=a.filter(e=>e.mafile_path).length;return(0,L.jsx)(`div`,{className:`h-full overflow-y-auto pr-1`,children:(0,L.jsxs)(`div`,{className:`max-w-2xl mx-auto space-y-5 py-2`,children:[a.length===0&&(0,L.jsxs)(`div`,{className:`flex flex-col items-center justify-center py-16 text-center`,children:[(0,L.jsx)(`div`,{className:`w-14 h-14 rounded-2xl bg-dark-700 flex items-center justify-center mb-4`,children:(0,L.jsx)(Te,{size:24,className:`text-gray-500`})}),(0,L.jsx)(`p`,{className:`text-gray-400 text-sm mb-1`,children:e(`mafile.emptyTitle`)}),(0,L.jsx)(`p`,{className:`text-gray-500 text-xs max-w-xs`,children:e(`mafile.emptyHint`)})]}),a.length>0&&(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-xl overflow-hidden`,children:[(0,L.jsxs)(`div`,{className:`flex items-center justify-between px-4 py-3 border-b border-dark-600`,children:[(0,L.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,L.jsx)(De,{size:14,className:`text-accent`}),(0,L.jsx)(`h3`,{className:`font-semibold text-sm`,children:e(`mafile.sentAccounts`)}),(0,L.jsxs)(`span`,{className:`text-xs text-gray-500`,children:[a.length,` `,e(`mafile.accountsCount`),` · `,s,` `,e(`mafile.withMafile`)]})]}),(0,L.jsx)(`button`,{onClick:r,className:`text-xs text-red-400 hover:text-red-300 transition-colors cursor-pointer`,children:e(`mafile.clearBtn`)})]}),(0,L.jsx)(`div`,{className:`max-h-56 overflow-y-auto divide-y divide-dark-700`,children:a.map(e=>(0,L.jsxs)(`div`,{className:`flex items-center gap-3 px-4 py-2 hover:bg-dark-700/50 transition-colors`,children:[e.avatar_url?(0,L.jsx)(`img`,{src:e.avatar_url,className:`avatar-sm shrink-0`,alt:``}):(0,L.jsx)(`div`,{className:`w-6 h-6 rounded bg-dark-600 shrink-0`}),(0,L.jsx)(`span`,{className:`text-sm truncate flex-1 min-w-0`,children:e.login}),e.steam_id&&(0,L.jsx)(`span`,{className:`text-xs text-gray-500 font-mono hidden sm:block`,children:e.steam_id}),(0,L.jsx)(`span`,{className:`text-xs px-1.5 py-0.5 rounded ${e.mafile_path?`bg-green-500/10 text-green-400`:`bg-dark-600 text-gray-500`}`,children:e.mafile_path?`mafile`:`—`})]},e.id))})]}),a.length>0&&(0,L.jsx)(Yt,{accountIds:[...n],onExport:o})]})})}function $t(e,t,n=!0){let r=(0,y.useRef)(t);r.current=t,(0,y.useEffect)(()=>{if(!n)return;let t=new EventSource(e);return t.onmessage=e=>{try{r.current(JSON.parse(e.data))}catch{}},t.onerror=()=>{t.close()},()=>t.close()},[e,n])}function en(){let[e,t]=(0,y.useState)([]),n=(0,y.useRef)(null),r=(0,y.useRef)(!0);(0,y.useEffect)(()=>{D.getLogs().then(t).catch(()=>{})},[]),$t(`/api/logs/stream`,e=>{t(t=>{let n=[...t,e];return n.length>500&&n.splice(0,n.length-500),n})}),(0,y.useEffect)(()=>{r.current&&n.current&&(n.current.scrollTop=n.current.scrollHeight)},[e]);let i=()=>{if(!n.current)return;let{scrollTop:e,scrollHeight:t,clientHeight:i}=n.current;r.current=t-e-i<40},a=e=>{switch(e){case`error`:case`critical`:return`text-red-400`;case`warning`:return`text-yellow-400`;case`success`:return`text-green-400`;case`debug`:return`text-gray-500`;default:return`text-gray-300`}};return(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-lg flex flex-col`,style:{maxHeight:`calc(100vh - 200px)`},children:[(0,L.jsxs)(`div`,{className:`px-3 py-2 border-b border-dark-600 flex items-center justify-between shrink-0`,children:[(0,L.jsx)(`h3`,{className:`font-semibold text-sm`,children:`📜 Лог`}),(0,L.jsx)(`button`,{onClick:()=>t([]),className:`text-xs text-gray-500 hover:text-gray-300 transition-colors`,children:`Очистить`})]}),(0,L.jsxs)(`div`,{ref:n,onScroll:i,className:`flex-1 overflow-y-auto min-h-0 p-2 font-mono text-xs space-y-px`,children:[e.map((e,t)=>(0,L.jsxs)(`div`,{className:`flex gap-2`,children:[(0,L.jsx)(`span`,{className:`text-gray-600 shrink-0`,children:e.ts}),(0,L.jsx)(`span`,{className:`shrink-0 w-3 text-center ${a(e.level)}`,children:e.icon}),(0,L.jsx)(`span`,{className:`${a(e.level)} break-all min-w-0`,children:e.msg})]},t)),e.length===0&&(0,L.jsx)(`p`,{className:`text-gray-600 text-center py-4`,children:`Нет логов`})]})]})}function tn(){return(0,L.jsx)(en,{})}function nn(){let e=j(e=>e.activeTab),t=j(e=>e.loadDisplaySettings),n=j(e=>e.loadColumnSettings),r=j(e=>e.loadLogpassColumnSettings);return(0,y.useEffect)(()=>{t(),n(),r()},[]),(0,L.jsxs)(`div`,{className:`h-dvh bg-dark-900 text-gray-300 flex flex-col overflow-hidden`,children:[(0,L.jsx)(oe,{}),(0,L.jsx)(Le,{}),(0,L.jsxs)(`main`,{className:`flex-1 min-h-0 p-4 w-full overflow-y-auto`,children:[e===`accounts`&&(0,L.jsx)(Mt,{}),e===`tools`&&(0,L.jsx)(Wt,{}),e===`mafiles`&&(0,L.jsx)(Qt,{}),e===`logs`&&(0,L.jsx)(tn,{})]}),(0,L.jsx)(Re,{})]})}var rn=class extends y.Component{state={error:null};static getDerivedStateFromError(e){return{error:e}}componentDidCatch(e,t){console.error(`React crash:`,e,t)}render(){let{error:e}=this.state;return e?(0,L.jsxs)(`div`,{style:{padding:32,fontFamily:`monospace`,background:`#0f0f0f`,color:`#f87171`,minHeight:`100vh`},children:[(0,L.jsx)(`h2`,{style:{fontSize:18,marginBottom:12},children:`⚠ SteamPanel failed to start`}),(0,L.jsxs)(`pre`,{style:{whiteSpace:`pre-wrap`,fontSize:13,color:`#fca5a5`},children:[e.message,` - -`,e.stack]}),(0,L.jsx)(`p`,{style:{marginTop:16,color:`#9ca3af`,fontSize:12},children:`Open browser console (F12) for more details, or report this error.`})]}):this.props.children}};(0,w.createRoot)(document.getElementById(`root`)).render((0,L.jsx)(y.StrictMode,{children:(0,L.jsx)(rn,{children:(0,L.jsx)(nn,{})})})); \ No newline at end of file diff --git a/app/static/assets/index-_9agmVKx.js b/app/static/assets/index-_9agmVKx.js new file mode 100644 index 0000000..d7babbc --- /dev/null +++ b/app/static/assets/index-_9agmVKx.js @@ -0,0 +1,14 @@ +var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),s=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;li[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},c=(n,r,a)=>(a=n==null?{}:e(i(n)),s(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var l=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.portal`),r=Symbol.for(`react.fragment`),i=Symbol.for(`react.strict_mode`),a=Symbol.for(`react.profiler`),o=Symbol.for(`react.consumer`),s=Symbol.for(`react.context`),c=Symbol.for(`react.forward_ref`),l=Symbol.for(`react.suspense`),u=Symbol.for(`react.memo`),d=Symbol.for(`react.lazy`),f=Symbol.for(`react.activity`),p=Symbol.iterator;function m(e){return typeof e!=`object`||!e?null:(e=p&&e[p]||e[`@@iterator`],typeof e==`function`?e:null)}var h={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},g=Object.assign,_={};function v(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}v.prototype.isReactComponent={},v.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=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,e,t,`setState`)},v.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function y(){}y.prototype=v.prototype;function b(e,t,n){this.props=e,this.context=t,this.refs=_,this.updater=n||h}var x=b.prototype=new y;x.constructor=b,g(x,v.prototype),x.isPureReactComponent=!0;var S=Array.isArray;function C(){}var w={H:null,A:null,T:null,S:null},T=Object.prototype.hasOwnProperty;function E(e,n,r){var i=r.ref;return{$$typeof:t,type:e,key:n,ref:i===void 0?null:i,props:r}}function D(e,t){return E(e.type,t,e.props)}function O(e){return typeof e==`object`&&!!e&&e.$$typeof===t}function k(e){var t={"=":`=0`,":":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var ee=/\/+/g;function te(e,t){return typeof e==`object`&&e&&e.key!=null?k(``+e.key):t.toString(36)}function A(e){switch(e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason;default:switch(typeof e.status==`string`?e.then(C,C):(e.status=`pending`,e.then(function(t){e.status===`pending`&&(e.status=`fulfilled`,e.value=t)},function(t){e.status===`pending`&&(e.status=`rejected`,e.reason=t)})),e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason}}throw e}function j(e,r,i,a,o){var s=typeof e;(s===`undefined`||s===`boolean`)&&(e=null);var c=!1;if(e===null)c=!0;else switch(s){case`bigint`:case`string`:case`number`:c=!0;break;case`object`:switch(e.$$typeof){case t:case n:c=!0;break;case d:return c=e._init,j(c(e._payload),r,i,a,o)}}if(c)return o=o(e),c=a===``?`.`+te(e,0):a,S(o)?(i=``,c!=null&&(i=c.replace(ee,`$&/`)+`/`),j(o,r,i,``,function(e){return e})):o!=null&&(O(o)&&(o=D(o,i+(o.key==null||e&&e.key===o.key?``:(``+o.key).replace(ee,`$&/`)+`/`)+c)),r.push(o)),1;c=0;var l=a===``?`.`:a+`:`;if(S(e))for(var u=0;u{t.exports=l()})),d=o((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0>>1,a=e[r];if(0>>1;ri(c,n))li(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(li(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m)if(n(c)!==null)m=!0,S||(S=!0,O());else{var t=n(l);t!==null&&te(x,t.startTime-e)}}var S=!1,C=-1,w=5,T=-1;function E(){return g?!0:!(e.unstable_now()-Tt&&E());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&te(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?O():S=!1}}}var O;if(typeof y==`function`)O=function(){y(D)};else if(typeof MessageChannel<`u`){var k=new MessageChannel,ee=k.port2;k.port1.onmessage=D,O=function(){ee.postMessage(null)}}else O=function(){_(D,0)};function te(t,n){C=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(C),C=-1):h=!0,te(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,S||(S=!0,O()))),r},e.unstable_shouldYield=E,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),f=o(((e,t)=>{t.exports=d()})),p=o((e=>{var t=u();function n(e){var t=`https://react.dev/errors/`+e;if(1{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=p()})),h=o((e=>{var t=f(),n=u(),r=m();function i(e){var t=`https://react.dev/errors/`+e;if(1ie||(e.current=re[ie],re[ie]=null,ie--)}function L(e,t){ie++,re[ie]=e.current,e.current=t}var oe=I(null),R=I(null),se=I(null),ce=I(null);function le(e,t){switch(L(se,t),L(R,e),L(oe,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Vd(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Vd(t),e=Hd(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}ae(oe),L(oe,e)}function ue(){ae(oe),ae(R),ae(se)}function de(e){e.memoizedState!==null&&L(ce,e);var t=oe.current,n=Hd(t,e.type);t!==n&&(L(R,e),L(oe,n))}function fe(e){R.current===e&&(ae(oe),ae(R)),ce.current===e&&(ae(ce),Qf._currentValue=ne)}var pe,me;function he(e){if(pe===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);pe=t&&t[1]||``,me=-1)`:-1i||c[r]!==l[i]){var u=` +`+c[r].replace(` at new `,` at `);return e.displayName&&u.includes(``)&&(u=u.replace(``,e.displayName)),u}while(1<=r&&0<=i);break}}}finally{ge=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:``)?he(n):``}function _e(e,t){switch(e.tag){case 26:case 27:case 5:return he(e.type);case 16:return he(`Lazy`);case 13:return e.child!==t&&t!==null?he(`Suspense Fallback`):he(`Suspense`);case 19:return he(`SuspenseList`);case 0:case 15:return z(e.type,!1);case 11:return z(e.type.render,!1);case 1:return z(e.type,!0);case 31:return he(`Activity`);default:return``}}function ve(e){try{var t=``,n=null;do t+=_e(e,n),n=e,e=e.return;while(e);return t}catch(e){return` +Error generating stack: `+e.message+` +`+e.stack}}var ye=Object.prototype.hasOwnProperty,be=t.unstable_scheduleCallback,xe=t.unstable_cancelCallback,Se=t.unstable_shouldYield,Ce=t.unstable_requestPaint,we=t.unstable_now,Te=t.unstable_getCurrentPriorityLevel,Ee=t.unstable_ImmediatePriority,De=t.unstable_UserBlockingPriority,Oe=t.unstable_NormalPriority,ke=t.unstable_LowPriority,Ae=t.unstable_IdlePriority,je=t.log,Me=t.unstable_setDisableYieldValue,Ne=null,Pe=null;function Fe(e){if(typeof je==`function`&&Me(e),Pe&&typeof Pe.setStrictMode==`function`)try{Pe.setStrictMode(Ne,e)}catch{}}var Ie=Math.clz32?Math.clz32:ze,Le=Math.log,Re=Math.LN2;function ze(e){return e>>>=0,e===0?32:31-(Le(e)/Re|0)|0}var Be=256,Ve=262144,He=4194304;function Ue(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 We(e,t,n){var r=e.pendingLanes;if(r===0)return 0;var i=0,a=e.suspendedLanes,o=e.pingedLanes;e=e.warmLanes;var s=r&134217727;return s===0?(s=r&~a,s===0?o===0?n||(n=r&~e,n!==0&&(i=Ue(n))):i=Ue(o):i=Ue(s)):(r=s&~a,r===0?(o&=s,o===0?n||(n=s&~e,n!==0&&(i=Ue(n))):i=Ue(o)):i=Ue(r)),i===0?0:t!==0&&t!==i&&(t&a)===0&&(a=i&-i,n=t&-t,a>=n||a===32&&n&4194048)?t:i}function Ge(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function Ke(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 qe(){var e=He;return He<<=1,!(He&62914560)&&(He=4194304),e}function Je(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function Ye(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function Xe(e,t,n,r,i,a){var o=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 s=e.entanglements,c=e.expirationTimes,l=e.hiddenUpdates;for(n=o&~n;0`u`||window.document===void 0||window.document.createElement===void 0),ln=!1;if(cn)try{var un={};Object.defineProperty(un,`passive`,{get:function(){ln=!0}}),window.addEventListener(`test`,un,un),window.removeEventListener(`test`,un,un)}catch{ln=!1}var dn=null,fn=null,pn=null;function mn(){if(pn)return pn;var e,t=fn,n=t.length,r,i=`value`in dn?dn.value:dn.textContent,a=i.length;for(e=0;e=Kn),Yn=` `,Xn=!1;function Zn(e,t){switch(e){case`keyup`:return Wn.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function Qn(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var $n=!1;function er(e,t){switch(e){case`compositionend`:return Qn(t);case`keypress`:return t.which===32?(Xn=!0,Yn):null;case`textInput`:return e=t.data,e===Yn&&Xn?null:e;default:return null}}function tr(e,t){if($n)return e===`compositionend`||!Gn&&Zn(e,t)?(e=mn(),pn=fn=dn=null,$n=!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=r}a:{for(;n;){if(n.nextSibling){n=n.nextSibling;break a}n=n.parentNode}n=void 0}n=Cr(n)}}function Tr(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Tr(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Er(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=Ft(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=Ft(e.document)}return t}function Dr(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 Or=cn&&`documentMode`in document&&11>=document.documentMode,kr=null,Ar=null,jr=null,Mr=!1;function Nr(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;Mr||kr==null||kr!==Ft(r)||(r=kr,`selectionStart`in r&&Dr(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),jr&&Sr(jr,r)||(jr=r,r=Ed(Ar,`onSelect`),0>=o,i-=o,Ti=1<<32-Ie(t)+i|n<h?(g=d,d=null):g=d.sibling;var _=p(i,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(i,d),a=o(_,a,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(i,d),V&&Di(i,h),l;if(d===null){for(;hg?(_=h,h=null):_=h.sibling;var y=p(a,h,v.value,l);if(y===null){h===null&&(h=_);break}e&&h&&y.alternate===null&&t(a,h),s=o(y,s,g),d===null?u=y:d.sibling=y,d=y,h=_}if(v.done)return n(a,h),V&&Di(a,g),u;if(h===null){for(;!v.done;g++,v=c.next())v=f(a,v.value,l),v!==null&&(s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return V&&Di(a,g),u}for(h=r(h);!v.done;g++,v=c.next())v=m(h,a,g,v.value,l),v!==null&&(e&&v.alternate!==null&&h.delete(v.key===null?g:v.key),s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return e&&h.forEach(function(e){return t(a,e)}),V&&Di(a,g),u}function b(e,r,o,c){if(typeof o==`object`&&o&&o.type===y&&o.key===null&&(o=o.props.children),typeof o==`object`&&o){switch(o.$$typeof){case _:a:{for(var l=o.key;r!==null;){if(r.key===l){if(l=o.type,l===y){if(r.tag===7){n(e,r.sibling),c=a(r,o.props.children),c.return=e,e=c;break a}}else if(r.elementType===l||typeof l==`object`&&l&&l.$$typeof===O&&Ea(l)===r.type){n(e,r.sibling),c=a(r,o.props),Na(c,o),c.return=e,e=c;break a}n(e,r);break}else t(e,r);r=r.sibling}o.type===y?(c=fi(o.props.children,e.mode,c,o.key),c.return=e,e=c):(c=di(o.type,o.key,o.props,null,e.mode,c),Na(c,o),c.return=e,e=c)}return s(e);case v:a:{for(l=o.key;r!==null;){if(r.key===l)if(r.tag===4&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),c=a(r,o.children||[]),c.return=e,e=c;break a}else{n(e,r);break}else t(e,r);r=r.sibling}c=hi(o,e.mode,c),c.return=e,e=c}return s(e);case O:return o=Ea(o),b(e,r,o,c)}if(N(o))return h(e,r,o,c);if(A(o)){if(l=A(o),typeof l!=`function`)throw Error(i(150));return o=l.call(o),g(e,r,o,c)}if(typeof o.then==`function`)return b(e,r,Ma(o),c);if(o.$$typeof===C)return b(e,r,ea(e,o),c);Pa(e,o)}return typeof o==`string`&&o!==``||typeof o==`number`||typeof o==`bigint`?(o=``+o,r!==null&&r.tag===6?(n(e,r.sibling),c=a(r,o),c.return=e,e=c):(n(e,r),c=pi(o,e.mode,c),c.return=e,e=c),s(e)):n(e,r)}return function(e,t,n,r){try{ja=0;var i=b(e,t,n,r);return Aa=null,i}catch(t){if(t===ba||t===Sa)throw t;var a=si(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var Ia=Fa(!0),La=Fa(!1),Ra=!1;function za(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Ba(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 Va(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function Ha(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,K&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,t=ii(e),ri(e,null,n),t}return ei(e,r,t,n),ii(e)}function Ua(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194048)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Qe(e,n)}}function Wa(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,a=null;if(n=n.firstBaseUpdate,n!==null){do{var o={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};a===null?i=a=o:a=a.next=o,n=n.next}while(n!==null);a===null?i=a=t:a=a.next=t}else i=a=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:a,shared:r.shared,callbacks:r.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var Ga=!1;function Ka(){if(Ga){var e=da;if(e!==null)throw e}}function qa(e,t,n,r){Ga=!1;var i=e.updateQueue;Ra=!1;var a=i.firstBaseUpdate,o=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var c=s,l=c.next;c.next=null,o===null?a=l:o.next=l,o=c;var u=e.alternate;u!==null&&(u=u.updateQueue,s=u.lastBaseUpdate,s!==o&&(s===null?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(a!==null){var d=i.baseState;o=0,u=l=c=null,s=a;do{var f=s.lane&-536870913,p=f!==s.lane;if(p?(Y&f)===f:(r&f)===f){f!==0&&f===ua&&(Ga=!0),u!==null&&(u=u.next={lane:0,tag:s.tag,payload:s.payload,callback:null,next:null});a:{var m=e,g=s;f=t;var _=n;switch(g.tag){case 1:if(m=g.payload,typeof m==`function`){d=m.call(_,d,f);break a}d=m;break a;case 3:m.flags=m.flags&-65537|128;case 0:if(m=g.payload,f=typeof m==`function`?m.call(_,d,f):m,f==null)break a;d=h({},d,f);break a;case 2:Ra=!0}}f=s.callback,f!==null&&(e.flags|=64,p&&(e.flags|=8192),p=i.callbacks,p===null?i.callbacks=[f]:p.push(f))}else p={lane:f,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=p,c=d):u=u.next=p,o|=f;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;p=s,s=p.next,p.next=null,i.lastBaseUpdate=p,i.shared.pending=null}}while(1);u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,a===null&&(i.shared.lanes=0),Gl|=o,e.lanes=o,e.memoizedState=d}}function Ja(e,t){if(typeof e!=`function`)throw Error(i(191,e));e.call(t)}function Ya(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ea?a:8;var o=P.T,s={};P.T=s,Ps(e,!1,t,n);try{var c=i(),l=P.S;l!==null&&l(s,c),typeof c==`object`&&c&&typeof c.then==`function`?Ns(e,t,ma(c,r),pu(e)):Ns(e,t,r,pu(e))}catch(n){Ns(e,t,{then:function(){},status:`rejected`,reason:n},pu())}finally{F.p=a,o!==null&&s.types!==null&&(o.types=s.types),P.T=o}}function Cs(){}function ws(e,t,n,r){if(e.tag!==5)throw Error(i(476));var a=Ts(e).queue;Ss(e,a,t,ne,n===null?Cs:function(){return Es(e),n(r)})}function Ts(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:ne,baseState:ne,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Fo,lastRenderedState:ne},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Fo,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function Es(e){var t=Ts(e);t.next===null&&(t=e.alternate.memoizedState),Ns(e,t.next.queue,{},pu())}function Ds(){return $i(Qf)}function Os(){return Ao().memoizedState}function ks(){return Ao().memoizedState}function As(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=pu();e=Va(n);var r=Ha(t,e,n);r!==null&&(hu(r,t,n),Ua(r,t,n)),t={cache:oa()},e.payload=t;return}t=t.return}}function js(e,t,n){var r=pu();n={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},Fs(e)?Is(t,n):(n=ti(e,t,n,r),n!==null&&(hu(n,e,r),Ls(n,t,r)))}function Ms(e,t,n){Ns(e,t,n,pu())}function Ns(e,t,n,r){var i={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(Fs(e))Is(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var o=t.lastRenderedState,s=a(o,n);if(i.hasEagerState=!0,i.eagerState=s,xr(s,o))return ei(e,t,i,0),q===null&&$r(),!1}catch{}if(n=ti(e,t,i,r),n!==null)return hu(n,e,r),Ls(n,t,r),!0}return!1}function Ps(e,t,n,r){if(r={lane:2,revertLane:dd(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},Fs(e)){if(t)throw Error(i(479))}else t=ti(e,n,r,2),t!==null&&hu(t,e,2)}function Fs(e){var t=e.alternate;return e===H||t!==null&&t===H}function Is(e,t){mo=po=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Ls(e,t,n){if(n&4194048){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Qe(e,n)}}var Rs={readContext:$i,use:No,useCallback:bo,useContext:bo,useEffect:bo,useImperativeHandle:bo,useLayoutEffect:bo,useInsertionEffect:bo,useMemo:bo,useReducer:bo,useRef:bo,useState:bo,useDebugValue:bo,useDeferredValue:bo,useTransition:bo,useSyncExternalStore:bo,useId:bo,useHostTransitionStatus:bo,useFormState:bo,useActionState:bo,useOptimistic:bo,useMemoCache:bo,useCacheRefresh:bo};Rs.useEffectEvent=bo;var zs={readContext:$i,use:No,useCallback:function(e,t){return ko().memoizedState=[e,t===void 0?null:t],e},useContext:$i,useEffect:ls,useImperativeHandle:function(e,t,n){n=n==null?null:n.concat([e]),ss(4194308,4,hs.bind(null,t,e),n)},useLayoutEffect:function(e,t){return ss(4194308,4,e,t)},useInsertionEffect:function(e,t){ss(4,2,e,t)},useMemo:function(e,t){var n=ko();t=t===void 0?null:t;var r=e();if(ho){Fe(!0);try{e()}finally{Fe(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=ko();if(n!==void 0){var i=n(t);if(ho){Fe(!0);try{n(t)}finally{Fe(!1)}}}else i=t;return r.memoizedState=r.baseState=i,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:i},r.queue=e,e=e.dispatch=js.bind(null,H,e),[r.memoizedState,e]},useRef:function(e){var t=ko();return e={current:e},t.memoizedState=e},useState:function(e){e=Go(e);var t=e.queue,n=Ms.bind(null,H,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:_s,useDeferredValue:function(e,t){return bs(ko(),e,t)},useTransition:function(){var e=Go(!1);return e=Ss.bind(null,H,e.queue,!0,!1),ko().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=H,a=ko();if(V){if(n===void 0)throw Error(i(407));n=n()}else{if(n=t(),q===null)throw Error(i(349));Y&127||Bo(r,t,n)}a.memoizedState=n;var o={value:n,getSnapshot:t};return a.queue=o,ls(Ho.bind(null,r,o,e),[e]),r.flags|=2048,as(9,{destroy:void 0},Vo.bind(null,r,o,n,t),null),n},useId:function(){var e=ko(),t=q.identifierPrefix;if(V){var n=Ei,r=Ti;n=(r&~(1<<32-Ie(r)-1)).toString(32)+n,t=`_`+t+`R_`+n,n=go++,0<\/script>`,o=o.removeChild(o.firstChild);break;case`select`:o=typeof r.is==`string`?s.createElement(`select`,{is:r.is}):s.createElement(`select`),r.multiple?o.multiple=!0:r.size&&(o.size=r.size);break;default:o=typeof r.is==`string`?s.createElement(a,{is:r.is}):s.createElement(a)}}o[at]=t,o[ot]=r;a:for(s=t.child;s!==null;){if(s.tag===5||s.tag===6)o.appendChild(s.stateNode);else if(s.tag!==4&&s.tag!==27&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===t)break a;for(;s.sibling===null;){if(s.return===null||s.return===t)break a;s=s.return}s.sibling.return=s.return,s=s.sibling}t.stateNode=o;a:switch(Pd(o,a,r),a){case`button`:case`input`:case`select`:case`textarea`:r=!!r.autoFocus;break a;case`img`:r=!0;break a;default:r=!1}r&&Nc(t)}}return W(t),Pc(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==r&&Nc(t);else{if(typeof r!=`string`&&t.stateNode===null)throw Error(i(166));if(e=se.current,zi(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,a=Mi,a!==null)switch(a.tag){case 27:case 5:r=a.memoizedProps}e[at]=t,e=!!(e.nodeValue===n||r!==null&&!0===r.suppressHydrationWarning||Md(e.nodeValue,n)),e||Ii(t,!0)}else e=Bd(e).createTextNode(r),e[at]=t,t.stateNode=e}return W(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(r=zi(t),n!==null){if(e===null){if(!r)throw Error(i(318));if(e=t.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(i(557));e[at]=t}else Bi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;W(t),e=!1}else n=Vi(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(so(t),t):(so(t),null);if(t.flags&128)throw Error(i(558))}return W(t),null;case 13:if(r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(a=zi(t),r!==null&&r.dehydrated!==null){if(e===null){if(!a)throw Error(i(318));if(a=t.memoizedState,a=a===null?null:a.dehydrated,!a)throw Error(i(317));a[at]=t}else Bi(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;W(t),a=!1}else a=Vi(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=a),a=!0;if(!a)return t.flags&256?(so(t),t):(so(t),null)}return so(t),t.flags&128?(t.lanes=n,t):(n=r!==null,e=e!==null&&e.memoizedState!==null,n&&(r=t.child,a=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(a=r.alternate.memoizedState.cachePool.pool),o=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(o=r.memoizedState.cachePool.pool),o!==a&&(r.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),Ic(t,t.updateQueue),W(t),null);case 4:return ue(),e===null&&Sd(t.stateNode.containerInfo),W(t),null;case 10:return qi(t.type),W(t),null;case 19:if(ae(co),r=t.memoizedState,r===null)return W(t),null;if(a=(t.flags&128)!=0,o=r.rendering,o===null)if(a)Lc(r,!1);else{if(Wl!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(o=lo(e),o!==null){for(t.flags|=128,Lc(r,!1),e=o.updateQueue,t.updateQueue=e,Ic(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)ui(n,e),n=n.sibling;return L(co,co.current&1|2),V&&Di(t,r.treeForkCount),t.child}e=e.sibling}r.tail!==null&&we()>tu&&(t.flags|=128,a=!0,Lc(r,!1),t.lanes=4194304)}else{if(!a)if(e=lo(o),e!==null){if(t.flags|=128,a=!0,e=e.updateQueue,t.updateQueue=e,Ic(t,e),Lc(r,!0),r.tail===null&&r.tailMode===`hidden`&&!o.alternate&&!V)return W(t),null}else 2*we()-r.renderingStartTime>tu&&n!==536870912&&(t.flags|=128,a=!0,Lc(r,!1),t.lanes=4194304);r.isBackwards?(o.sibling=t.child,t.child=o):(e=r.last,e===null?t.child=o:e.sibling=o,r.last=o)}return r.tail===null?(W(t),null):(e=r.tail,r.rendering=e,r.tail=e.sibling,r.renderingStartTime=we(),e.sibling=null,n=co.current,L(co,a?n&1|2:n&1),V&&Di(t,r.treeForkCount),e);case 22:case 23:return so(t),eo(),r=t.memoizedState!==null,e===null?r&&(t.flags|=8192):e.memoizedState!==null!==r&&(t.flags|=8192),r?n&536870912&&!(t.flags&128)&&(W(t),t.subtreeFlags&6&&(t.flags|=8192)):W(t),n=t.updateQueue,n!==null&&Ic(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),r=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),e!==null&&ae(ga),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),qi(aa),W(t),null;case 25:return null;case 30:return null}throw Error(i(156,t.tag))}function zc(e,t){switch(Ai(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return qi(aa),ue(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return fe(t),null;case 31:if(t.memoizedState!==null){if(so(t),t.alternate===null)throw Error(i(340));Bi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(so(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(i(340));Bi()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return ae(co),null;case 4:return ue(),null;case 10:return qi(t.type),null;case 22:case 23:return so(t),eo(),e!==null&&ae(ga),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return qi(aa),null;case 25:return null;default:return null}}function Bc(e,t){switch(Ai(t),t.tag){case 3:qi(aa),ue();break;case 26:case 27:case 5:fe(t);break;case 4:ue();break;case 31:t.memoizedState!==null&&so(t);break;case 13:so(t);break;case 19:ae(co);break;case 10:qi(t.type);break;case 22:case 23:so(t),eo(),e!==null&&ae(ga);break;case 24:qi(aa)}}function Vc(e,t){try{var n=t.updateQueue,r=n===null?null:n.lastEffect;if(r!==null){var i=r.next;n=i;do{if((n.tag&e)===e){r=void 0;var a=n.create,o=n.inst;r=a(),o.destroy=r}n=n.next}while(n!==i)}}catch(e){Z(t,t.return,e)}}function Hc(e,t,n){try{var r=t.updateQueue,i=r===null?null:r.lastEffect;if(i!==null){var a=i.next;r=a;do{if((r.tag&e)===e){var o=r.inst,s=o.destroy;if(s!==void 0){o.destroy=void 0,i=t;var c=n,l=s;try{l()}catch(e){Z(i,c,e)}}}r=r.next}while(r!==a)}}catch(e){Z(t,t.return,e)}}function Uc(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{Ya(t,n)}catch(t){Z(e,e.return,t)}}}function Wc(e,t,n){n.props=Ks(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(n){Z(e,t,n)}}function Gc(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;case 30:r=e.stateNode;break;default:r=e.stateNode}typeof n==`function`?e.refCleanup=n(r):n.current=r}}catch(n){Z(e,t,n)}}function Kc(e,t){var n=e.ref,r=e.refCleanup;if(n!==null)if(typeof r==`function`)try{r()}catch(n){Z(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n==`function`)try{n(null)}catch(n){Z(e,t,n)}else n.current=null}function qc(e){var t=e.type,n=e.memoizedProps,r=e.stateNode;try{a:switch(t){case`button`:case`input`:case`select`:case`textarea`:n.autoFocus&&r.focus();break a;case`img`:n.src?r.src=n.src:n.srcSet&&(r.srcset=n.srcSet)}}catch(t){Z(e,e.return,t)}}function Jc(e,t,n){try{var r=e.stateNode;Fd(r,e.type,n,t),r[ot]=t}catch(t){Z(e,e.return,t)}}function Yc(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&Zd(e.type)||e.tag===4}function Xc(e){a:for(;;){for(;e.sibling===null;){if(e.return===null||Yc(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&&Zd(e.type)||e.flags&2||e.child===null||e.tag===4)continue a;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Zc(e,t,n){var r=e.tag;if(r===5||r===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=Qt));else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode,t=null),e=e.child,e!==null))for(Zc(e,t,n),e=e.sibling;e!==null;)Zc(e,t,n),e=e.sibling}function Qc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode),e=e.child,e!==null))for(Qc(e,t,n),e=e.sibling;e!==null;)Qc(e,t,n),e=e.sibling}function $c(e){var t=e.stateNode,n=e.memoizedProps;try{for(var r=e.type,i=t.attributes;i.length;)t.removeAttributeNode(i[0]);Pd(t,r,n),t[at]=e,t[ot]=n}catch(t){Z(e,e.return,t)}}var el=!1,tl=!1,nl=!1,rl=typeof WeakSet==`function`?WeakSet:Set,il=null;function al(e,t){if(e=e.containerInfo,Rd=sp,e=Er(e),Dr(e)){if(`selectionStart`in e)var n={start:e.selectionStart,end:e.selectionEnd};else a:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var a=r.anchorOffset,o=r.focusNode;r=r.focusOffset;try{n.nodeType,o.nodeType}catch{n=null;break a}var s=0,c=-1,l=-1,u=0,d=0,f=e,p=null;b:for(;;){for(var m;f!==n||a!==0&&f.nodeType!==3||(c=s+a),f!==o||r!==0&&f.nodeType!==3||(l=s+r),f.nodeType===3&&(s+=f.nodeValue.length),(m=f.firstChild)!==null;)p=f,f=m;for(;;){if(f===e)break b;if(p===n&&++u===a&&(c=s),p===o&&++d===r&&(l=s),(m=f.nextSibling)!==null)break;f=p,p=f.parentNode}f=m}n=c===-1||l===-1?null:{start:c,end:l}}else n=null}n||={start:0,end:0}}else n=null;for(zd={focusedElem:e,selectionRange:n},sp=!1,il=t;il!==null;)if(t=il,e=t.child,t.subtreeFlags&1028&&e!==null)e.return=t,il=e;else for(;il!==null;){switch(t=il,o=t.alternate,e=t.flags,t.tag){case 0:if(e&4&&(e=t.updateQueue,e=e===null?null:e.events,e!==null))for(n=0;n title`))),Pd(o,r,n),o[at]=e,vt(o),r=o;break a;case`link`:var s=Vf(`link`,`href`,a).get(r+(n.href||``));if(s){for(var c=0;cg&&(o=g,g=h,h=o);var _=wr(s,h),v=wr(s,g);if(_&&v&&(p.rangeCount!==1||p.anchorNode!==_.node||p.anchorOffset!==_.offset||p.focusNode!==v.node||p.focusOffset!==v.offset)){var y=d.createRange();y.setStart(_.node,_.offset),p.removeAllRanges(),h>g?(p.addRange(y),p.extend(v.node,v.offset)):(y.setEnd(v.node,v.offset),p.addRange(y))}}}}for(d=[],p=s;p=p.parentNode;)p.nodeType===1&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for(typeof s.focus==`function`&&s.focus(),s=0;sn?32:n,P.T=null,n=lu,lu=null;var o=au,s=su;if(iu=0,ou=au=null,su=0,K&6)throw Error(i(331));var c=K;if(K|=4,Pl(o.current),El(o,o.current,s,n),K=c,id(0,!1),Pe&&typeof Pe.onPostCommitFiberRoot==`function`)try{Pe.onPostCommitFiberRoot(Ne,o)}catch{}return!0}finally{F.p=a,P.T=r,Vu(e,t)}}function Wu(e,t,n){t=_i(n,t),t=Qs(e.stateNode,t,2),e=Ha(e,t,2),e!==null&&(Ye(e,2),rd(e))}function Z(e,t,n){if(e.tag===3)Wu(e,e,n);else for(;t!==null;){if(t.tag===3){Wu(t,e,n);break}else if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError==`function`||typeof r.componentDidCatch==`function`&&(ru===null||!ru.has(r))){e=_i(n,e),n=$s(2),r=Ha(t,n,2),r!==null&&(ec(n,r,t,e),Ye(r,2),rd(r));break}}t=t.return}}function Gu(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new Rl;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(Hl=!0,i.add(n),e=Ku.bind(null,e,t,n),t.then(e,e))}function Ku(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,q===e&&(Y&n)===n&&(Wl===4||Wl===3&&(Y&62914560)===Y&&300>we()-$l?!(K&2)&&Su(e,0):ql|=n,Yl===Y&&(Yl=0)),rd(e)}function qu(e,t){t===0&&(t=qe()),e=ni(e,t),e!==null&&(Ye(e,t),rd(e))}function Ju(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),qu(e,n)}function Yu(e,t){var n=0;switch(e.tag){case 31:case 13:var r=e.stateNode,a=e.memoizedState;a!==null&&(n=a.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(i(314))}r!==null&&r.delete(t),qu(e,n)}function Xu(e,t){return be(e,t)}var Zu=null,Qu=null,$u=!1,ed=!1,td=!1,nd=0;function rd(e){e!==Qu&&e.next===null&&(Qu===null?Zu=Qu=e:Qu=Qu.next=e),ed=!0,$u||($u=!0,ud())}function id(e,t){if(!td&&ed){td=!0;do for(var n=!1,r=Zu;r!==null;){if(!t)if(e!==0){var i=r.pendingLanes;if(i===0)var a=0;else{var o=r.suspendedLanes,s=r.pingedLanes;a=(1<<31-Ie(42|e)+1)-1,a&=i&~(o&~s),a=a&201326741?a&201326741|1:a?a|2:0}a!==0&&(n=!0,ld(r,a))}else a=Y,a=We(r,r===q?a:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),!(a&3)||Ge(r,a)||(n=!0,ld(r,a));r=r.next}while(n);td=!1}}function ad(){od()}function od(){ed=$u=!1;var e=0;nd!==0&&Gd()&&(e=nd);for(var t=we(),n=null,r=Zu;r!==null;){var i=r.next,a=sd(r,t);a===0?(r.next=null,n===null?Zu=i:n.next=i,i===null&&(Qu=n)):(n=r,(e!==0||a&3)&&(ed=!0)),r=i}iu!==0&&iu!==5||id(e,!1),nd!==0&&(nd=0)}function sd(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,i=e.expirationTimes,a=e.pendingLanes&-62914561;0s)break;var u=c.transferSize,d=c.initiatorType;u&&Id(d)&&(c=c.responseEnd,o+=u*(c`u`?null:document;function xf(e,t,n){var r=bf;if(r&&typeof t==`string`&&t){var i=Lt(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),hf.has(i)||(hf.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),Pd(t,`link`,e),vt(t),r.head.appendChild(t)))}}function Sf(e){_f.D(e),xf(`dns-prefetch`,e,null)}function Cf(e,t){_f.C(e,t),xf(`preconnect`,e,t)}function wf(e,t,n){_f.L(e,t,n);var r=bf;if(r&&e&&t){var i=`link[rel="preload"][as="`+Lt(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+Lt(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+Lt(n.imageSizes)+`"]`)):i+=`[href="`+Lt(e)+`"]`;var a=i;switch(t){case`style`:a=Af(e);break;case`script`:a=Pf(e)}mf.has(a)||(e=h({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),mf.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(jf(a))||t===`script`&&r.querySelector(Ff(a))||(t=r.createElement(`link`),Pd(t,`link`,e),vt(t),r.head.appendChild(t)))}}function Tf(e,t){_f.m(e,t);var n=bf;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+Lt(r)+`"][href="`+Lt(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=Pf(e)}if(!mf.has(a)&&(e=h({rel:`modulepreload`,href:e},t),mf.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(Ff(a)))return}r=n.createElement(`link`),Pd(r,`link`,e),vt(r),n.head.appendChild(r)}}}function Ef(e,t,n){_f.S(e,t,n);var r=bf;if(r&&e){var i=_t(r).hoistableStyles,a=Af(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(jf(a)))s.loading=5;else{e=h({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=mf.get(a))&&Rf(e,n);var c=o=r.createElement(`link`);vt(c),Pd(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Lf(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function Df(e,t){_f.X(e,t);var n=bf;if(n&&e){var r=_t(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=h({src:e,async:!0},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),vt(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Of(e,t){_f.M(e,t);var n=bf;if(n&&e){var r=_t(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=h({src:e,async:!0,type:`module`},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),vt(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function kf(e,t,n,r){var a=(a=se.current)?gf(a):null;if(!a)throw Error(i(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(t=Af(n.href),n=_t(a).hoistableStyles,r=n.get(t),r||(r={type:`style`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=Af(n.href);var o=_t(a).hoistableStyles,s=o.get(e);if(s||(a=a.ownerDocument||a,s={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},o.set(e,s),(o=a.querySelector(jf(e)))&&!o._p&&(s.instance=o,s.state.loading=5),mf.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},mf.set(e,n),o||Nf(a,e,n,s.state))),t&&r===null)throw Error(i(528,``));return s}if(t&&r!==null)throw Error(i(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(t=Pf(n),n=_t(a).hoistableScripts,r=n.get(t),r||(r={type:`script`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(i(444,e))}}function Af(e){return`href="`+Lt(e)+`"`}function jf(e){return`link[rel="stylesheet"][`+e+`]`}function Mf(e){return h({},e,{"data-precedence":e.precedence,precedence:null})}function Nf(e,t,n,r){e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)?r.loading=1:(t=e.createElement(`link`),r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2}),Pd(t,`link`,n),vt(t),e.head.appendChild(t))}function Pf(e){return`[src="`+Lt(e)+`"]`}function Ff(e){return`script[async]`+e}function If(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+Lt(n.href)+`"]`);if(r)return t.instance=r,vt(r),r;var a=h({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),vt(r),Pd(r,`style`,a),Lf(r,n.precedence,e),t.instance=r;case`stylesheet`:a=Af(n.href);var o=e.querySelector(jf(a));if(o)return t.state.loading|=4,t.instance=o,vt(o),o;r=Mf(n),(a=mf.get(a))&&Rf(r,a),o=(e.ownerDocument||e).createElement(`link`),vt(o);var s=o;return s._p=new Promise(function(e,t){s.onload=e,s.onerror=t}),Pd(o,`link`,r),t.state.loading|=4,Lf(o,n.precedence,e),t.instance=o;case`script`:return o=Pf(n.src),(a=e.querySelector(Ff(o)))?(t.instance=a,vt(a),a):(r=n,(a=mf.get(o))&&(r=h({},n),zf(r,a)),e=e.ownerDocument||e,a=e.createElement(`script`),vt(a),Pd(a,`link`,r),e.head.appendChild(a),t.instance=a);case`void`:return null;default:throw Error(i(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Lf(r,n.precedence,e));return t.instance}function Lf(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o title`):null)}function Uf(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 Wf(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function Gf(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=Af(r.href),a=t.querySelector(jf(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=Jf.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,vt(a);return}a=t.ownerDocument||t,r=Mf(r),(i=mf.get(i))&&Rf(r,i),a=a.createElement(`link`),vt(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),Pd(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=Jf.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var Kf=0;function qf(e,t){return e.stylesheets&&e.count===0&&Xf(e,e.stylesheets),0Kf?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function Jf(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Xf(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var Yf=null;function Xf(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,Yf=new Map,t.forEach(Zf,e),Yf=null,Jf.call(e))}function Zf(e,t){if(!(t.state.loading&4)){var n=Yf.get(e);if(n)var r=n.get(null);else{n=new Map,Yf.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=h()})),_=e=>{let t,n=new Set,r=(e,r)=>{let i=typeof e==`function`?e(t):e;if(!Object.is(i,t)){let e=t;t=r??(typeof i!=`object`||!i)?i:Object.assign({},t,i),n.forEach(n=>n(t,e))}},i=()=>t,a={setState:r,getState:i,getInitialState:()=>o,subscribe:e=>(n.add(e),()=>n.delete(e))},o=t=e(r,i,a);return a},v=(e=>e?_(e):_),y=c(u(),1),b=e=>e;function x(e,t=b){let n=y.useSyncExternalStore(e.subscribe,y.useCallback(()=>t(e.getState()),[e,t]),y.useCallback(()=>t(e.getInitialState()),[e,t]));return y.useDebugValue(n),n}var S=e=>{let t=v(e),n=e=>x(t,e);return Object.assign(n,t),n},C=(e=>e?S(e):S),w=g(),T=`/api`;async function E(e,t){let n=await fetch(`${T}${e}`,{...t,headers:{"Content-Type":`application/json`,...t?.headers}});if(!n.ok){let e=await n.json().catch(()=>({detail:n.statusText}));throw Error(e.detail??`HTTP ${n.status}`)}if(n.status!==204)return n.json()}var D={getVersion:()=>E(`/version`),getAccounts:()=>E(`/accounts`),getAccount:e=>E(`/accounts/${e}`),createAccount:e=>E(`/accounts`,{method:`POST`,body:JSON.stringify(e)}),updateAccount:(e,t)=>E(`/accounts/${e}`,{method:`PUT`,body:JSON.stringify(t)}),deleteAccount:e=>E(`/accounts/${e}`,{method:`DELETE`}),deleteBulk:e=>E(`/accounts/delete-bulk`,{method:`POST`,body:JSON.stringify({ids:e})}),assignProxies:()=>E(`/accounts/assign-proxies`,{method:`POST`}),reassignProxies:()=>E(`/accounts/reassign-proxies`,{method:`POST`}),clearProxies:()=>E(`/accounts/clear-proxies`,{method:`POST`}),importAccounts:e=>{let t=new FormData;return t.append(`file`,e),fetch(`${T}/accounts/import`,{method:`POST`,body:t}).then(async e=>{if(!e.ok)throw Error((await e.json().catch(()=>({}))).detail??e.statusText);return e.json()})},executeAction:e=>E(`/actions`,{method:`POST`,body:JSON.stringify(e)}),respondToPrompt:(e,t,n)=>E(`/tasks/${e}/respond`,{method:`POST`,body:JSON.stringify({value:t,login:n||``})}),generate2FA:e=>E(`/actions/generate-2fa`,{method:`POST`,body:JSON.stringify({shared_secret:e})}),generate2FAByAccount:e=>E(`/actions/generate-2fa-by-account`,{method:`POST`,body:JSON.stringify({account_id:e})}),getConfirmations:e=>E(`/actions/confirmations/${e}`),respondConfirmations:(e,t,n,r)=>E(`/actions/confirmations/${e}/respond`,{method:`POST`,body:JSON.stringify({ids:t,nonces:n,accept:r})}),getProxies:()=>E(`/proxies`),addProxy:(e,t=`http`)=>E(`/proxies`,{method:`POST`,body:JSON.stringify({address:e,protocol:t})}),deleteProxy:e=>E(`/proxies/${e}`,{method:`DELETE`}),deleteAllProxies:()=>E(`/proxies/all`,{method:`DELETE`}),bulkAddProxies:e=>E(`/proxies/bulk`,{method:`POST`,body:JSON.stringify(e)}),checkProxies:()=>E(`/proxies/check`,{method:`POST`}),getTasks:()=>E(`/tasks`),getTask:e=>E(`/tasks/${e}`),cancelTask:e=>E(`/tasks/${e}`,{method:`DELETE`}),getMafiles:()=>E(`/mafiles`),uploadMafiles:e=>{let t=new FormData;return e.forEach(e=>t.append(`files`,e)),fetch(`${T}/mafiles/upload`,{method:`POST`,body:t}).then(async e=>{if(!e.ok)throw Error((await e.json().catch(()=>({}))).detail??e.statusText);return e.json()})},deleteMafile:e=>E(`/mafiles/${encodeURIComponent(e)}`,{method:`DELETE`}),exportSecrets:()=>E(`/mafiles/export/all`),exportZip:e=>fetch(`${T}/mafiles/export/zip`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)}).then(e=>{if(!e.ok)throw Error(`Export failed: ${e.status}`);return e.blob()}),getValidationSettings:()=>E(`/settings/validation`),updateValidationSettings:e=>E(`/settings/validation`,{method:`PUT`,body:JSON.stringify(e)}),getDisplaySettings:()=>E(`/settings/display`),updateDisplaySettings:e=>E(`/settings/display`,{method:`PUT`,body:JSON.stringify(e)}),getColumnSettings:()=>E(`/settings/columns`),updateColumnSettings:e=>E(`/settings/columns`,{method:`PUT`,body:JSON.stringify(e)}),getLogpassColumnSettings:()=>E(`/settings/logpass-columns`),updateLogpassColumnSettings:e=>E(`/settings/logpass-columns`,{method:`PUT`,body:JSON.stringify(e)}),getLogs:()=>E(`/logs`),startAutoAccept:e=>E(`/auto-accept/start`,{method:`POST`,body:JSON.stringify({account_ids:e})}),stopAutoAccept:e=>E(`/auto-accept/stop`,{method:`POST`,body:JSON.stringify({account_ids:e})}),getAutoAcceptStatus:()=>E(`/auto-accept/status`),openBrowser:e=>E(`/accounts/${e}/browser`,{method:`POST`}),getLogpassAccounts:()=>E(`/logpass`),createLogpassAccount:e=>E(`/logpass`,{method:`POST`,body:JSON.stringify(e)}),updateLogpassAccount:(e,t)=>E(`/logpass/${e}`,{method:`PUT`,body:JSON.stringify(t)}),deleteLogpassAccount:e=>E(`/logpass/${e}`,{method:`DELETE`}),deleteLogpassBulk:e=>E(`/logpass/delete-bulk`,{method:`POST`,body:JSON.stringify({ids:e})}),importLogpass:e=>E(`/logpass/import`,{method:`POST`,body:JSON.stringify({lines:e})}),validateLogpass:e=>E(`/logpass/validate`,{method:`POST`,body:JSON.stringify({account_ids:e})}),fullParseLogpass:e=>E(`/logpass/full-parse`,{method:`POST`,body:JSON.stringify({account_ids:e})}),assignLogpassProxies:()=>E(`/logpass/assign-proxies`,{method:`POST`}),reassignLogpassProxies:()=>E(`/logpass/reassign-proxies`,{method:`POST`}),clearLogpassProxies:()=>E(`/logpass/clear-proxies`,{method:`POST`}),openLogpassBrowser:e=>E(`/logpass/${e}/browser`,{method:`POST`}),getTokenAccounts:()=>E(`/token-accounts`),createTokenAccount:e=>E(`/token-accounts`,{method:`POST`,body:JSON.stringify(e)}),deleteTokenAccount:e=>E(`/token-accounts/${e}`,{method:`DELETE`}),deleteTokenBulk:e=>E(`/token-accounts/delete-bulk`,{method:`POST`,body:JSON.stringify({ids:e})}),importTokens:e=>E(`/token-accounts/import`,{method:`POST`,body:JSON.stringify({lines:e})}),validateTokens:e=>E(`/token-accounts/validate`,{method:`POST`,body:JSON.stringify({account_ids:e})}),openTokenBrowser:e=>E(`/token-accounts/${e}/browser`,{method:`POST`}),assignTokenProxies:()=>E(`/token-accounts/assign-proxies`,{method:`POST`}),reassignTokenProxies:()=>E(`/token-accounts/reassign-proxies`,{method:`POST`}),clearTokenProxies:()=>E(`/token-accounts/clear-proxies`,{method:`POST`}),getTokenColumnSettings:()=>E(`/settings/token-columns`),updateTokenColumnSettings:e=>E(`/settings/token-columns`,{method:`PUT`,body:JSON.stringify(e)}),fullCheckTokens:e=>E(`/token-accounts/full-check`,{method:`POST`,body:JSON.stringify({account_ids:e})}),getTokenCheckData:e=>E(`/token-accounts/${e}/check-data`),downloadTokenCookies:e=>{let t=document.createElement(`a`);t.href=`${T}/token-accounts/${e}/cookies`,t.download=``,t.click()}},O=0,k={browser:!0,profile:!0,steam_id:!0,login:!0,password:!0,login_pass:!0,email:!0,email_pass:!1,email_login_pass:!1,phone:!0,status:!0,ban:!0,twofa:!0,mafile:!0,proxy:!0,notes:!0,actions:!0,last_online:!0},ee={browser:!0,profile:!0,steam_id:!0,login:!0,password:!0,login_pass:!0,status:!0,ban:!0,prime:!0,trophy:!0,behavior:!0,license:!0,proxy:!0,notes:!0,actions:!0,last_online:!0},te={browser:!0,profile:!0,last_online:!0,steam_id:!0,login:!0,token:!0,status:!0,proxy:!0,notes:!0,actions:!0},A=C((e,t)=>({activeTab:`accounts`,setTab:t=>e({activeTab:t}),accountSection:`mafile`,setAccountSection:t=>e({accountSection:t}),toasts:[],addToast:(t,n)=>{let r=++O;e(e=>({toasts:[...e.toasts,{id:r,type:t,message:n}]})),setTimeout(()=>{e(e=>({toasts:e.toasts.filter(e=>e.id!==r)}))},4e3)},removeToast:t=>e(e=>({toasts:e.toasts.filter(e=>e.id!==t)})),hidePasswords:!1,setHidePasswords:t=>{e({hidePasswords:t}),D.updateDisplaySettings({hide_passwords:t}).catch(()=>{})},loadDisplaySettings:async()=>{try{e({hidePasswords:(await D.getDisplaySettings()).hide_passwords})}catch{}},columnVisibility:{...k},setColumnVisibility:t=>e({columnVisibility:t}),toggleColumn:n=>{let r={...t().columnVisibility,[n]:!t().columnVisibility[n]};e({columnVisibility:r}),D.updateColumnSettings(r).catch(()=>{})},loadColumnSettings:async()=>{try{let t=await D.getColumnSettings();e({columnVisibility:{...k,...t}})}catch{}},logpassColumnVisibility:{...ee},toggleLogpassColumn:n=>{let r={...t().logpassColumnVisibility,[n]:!t().logpassColumnVisibility[n]};e({logpassColumnVisibility:r}),D.updateLogpassColumnSettings(r).catch(()=>{})},loadLogpassColumnSettings:async()=>{try{let t=await D.getLogpassColumnSettings();e({logpassColumnVisibility:{...ee,...t}})}catch{}},autoProxyOnImport:!1,autoValidateOnImport:!1,autoProxyOnImportMafile:!0,autoProxyOnImportLogpass:!0,autoProxyOnImportToken:!0,autoValidateOnImportMafile:!0,autoValidateOnImportLogpass:!0,autoValidateOnImportToken:!0,loadImportSettings:async()=>{try{let t=await D.getValidationSettings();e({autoProxyOnImport:t.auto_proxy_on_import,autoValidateOnImport:t.auto_validate_on_import,autoProxyOnImportMafile:t.auto_proxy_on_import_mafile,autoProxyOnImportLogpass:t.auto_proxy_on_import_logpass,autoProxyOnImportToken:t.auto_proxy_on_import_token,autoValidateOnImportMafile:t.auto_validate_on_import_mafile,autoValidateOnImportLogpass:t.auto_validate_on_import_logpass,autoValidateOnImportToken:t.auto_validate_on_import_token})}catch{}},tokenColumnVisibility:{...te},toggleTokenColumn:n=>{let r={...t().tokenColumnVisibility,[n]:!t().tokenColumnVisibility[n]};e({tokenColumnVisibility:r}),D.updateTokenColumnSettings(r).catch(()=>{})},loadTokenColumnSettings:async()=>{try{let t=await D.getTokenColumnSettings();e({tokenColumnVisibility:{...te,...t}})}catch{}}})),j=`steampanel_locale`,M=localStorage.getItem(j)||`ru`,N=new Set;function P(){N.forEach(e=>e())}function F(e){M=e,localStorage.setItem(j,e),P()}function ne(){return[(0,y.useSyncExternalStore)(e=>(N.add(e),()=>N.delete(e)),()=>M),F]}var re={ru:{"header.accounts":`Аккаунтов`,"tab.accounts":`Аккаунты`,"tab.mafiles":`Mafile Management`,"tab.tools":`Настройки`,"tab.logs":`Логи`,"section.dataType":`Тип данных`,"col.browser":`Войти`,"col.profile":`Профиль`,"col.lastOnline":`Отлега`,"col.steamId":`Steam ID`,"col.login":`Логин`,"col.password":`Пароль`,"col.loginPass":`Login:Pass`,"col.email":`Email`,"col.emailPass":`Email Pass`,"col.emailLoginPass":`Email:Pass`,"col.phone":`Телефон`,"col.status":`Статус`,"col.ban":`Бан`,"col.twofa":`2FA`,"col.mafile":`Mafile`,"col.proxy":`Прокси`,"col.notes":`Заметки`,"col.actions":`Действия`,"col.prime":`Prime`,"col.trophy":`Trophy`,"col.behavior":`Behavior`,"col.license":`Лицензии`,"col.token":`Токен`,"action.selectAction":`— Действие`,"action.validate":`Валидация`,"action.changePassword":`Сменить пароль`,"action.randomPassword":`Случайный пароль`,"action.changeEmail":`Сменить email`,"action.changePhone":`Сменить телефон`,"action.removePhone":`Удалить телефон`,"action.removeGuard":`Удалить Guard`,"action.noRevocationCode":`Нет revocation_code в mafile`,"action.enableAutoAccept":`Вкл. автопринятие`,"action.disableAutoAccept":`Выкл. авто-принятие входа`,"action.enableAutoAcceptLogin":`Вкл. авто-принятие входа`,"action.generate2fa":`Сгенерировать 2FA код`,"action.confirmations":`Подтверждения`,"prompt.newPassword":`Введите новый пароль`,"prompt.newEmail":`Введите новый email`,"prompt.newPhone":`Введите новый номер телефона`,"prompt.removePhone":`Введите номер телефона (на который переставится старый)`,"prompt.enterValue":`Введите значение...`,"confirm.removeGuard":`Удалить Steam Guard для этого аккаунта?`,"confirm.deleteAccount":`Удалить аккаунт?`,"confirm.deleteSelected":`Удалить {count} выбранных аккаунтов?`,"confirm.deleteAll":`Удалить ВСЕ {count} аккаунтов? Это необратимо!`,"confirm.deleteLogpassSelected":`Удалить {count} аккаунт(ов)?`,"confirm.deleteLogpassAll":`Удалить все {count} аккаунтов?`,"confirm.deleteTokenSelected":`Удалить {count} токен(ов)?`,"confirm.deleteTokenAll":`Удалить все {count} токенов?`,"confirm.deleteToken":`Удалить токен {name}?`,"confirm.deleteLogpass":`Удалить {name}?`,"confirm.assignProxies":`Назначить прокси аккаунтам без прокси?`,"confirm.reassignProxies":`Переназначить прокси на все аккаунты?`,"confirm.reassignProxiesAll":`Переназначить прокси всем аккаунтам?`,"confirm.clearProxies":`Очистить прокси у всех аккаунтов?`,"confirm.executeBulk":`Выполнить «{action}» для {count} аккаунтов?`,"confirm.yes":`Да`,"confirm.title":`Подтверждения`,"confirm.loading":`Загрузка подтверждений...`,"confirm.empty":`Нет ожидающих подтверждений`,"confirm.acceptAll":`Принять все`,"confirm.denyAll":`Отклонить все`,"confirm.refresh":`Обновить`,"confirm.accepted":`Принято`,"confirm.denied":`Отклонено`,"confirm.respondFailed":`Не удалось обработать подтверждение`,"btn.import":`Импорт`,"btn.add":`Добавить`,"btn.save":`Сохранить`,"btn.cancel":`Отмена`,"btn.execute":`Выполнить`,"btn.deleteSelected":`Удалить выбранные`,"btn.deleteAll":`Удалить все`,"btn.assignProxies":`Назначить прокси`,"btn.reassign":`Переназначить`,"btn.clearProxies":`Очистить прокси`,"btn.validate":`Валидировать`,"btn.fullParse":`Полный парс`,"btn.fullCheck":`Полная проверка`,"btn.generate":`Сгенерировать`,"toast.copied":`Скопировано`,"toast.copyFailed":`Не удалось скопировать`,"toast.noteSaved":`Заметка сохранена`,"toast.noteSaveError":`Ошибка сохранения`,"toast.accountDeleted":`Аккаунт удален`,"toast.accountAdded":`Аккаунт добавлен`,"toast.saved":`Сохранено`,"toast.done":`Готово`,"toast.error":`Ошибка`,"toast.selectAction":`Выберите действие`,"toast.selectAccounts":`Выберите аккаунты`,"toast.noAccounts":`Нет аккаунтов`,"toast.autoAcceptEnabled":`Автопринятие включено для {count} акк.`,"toast.autoAcceptOn":`Авто-принятие входа включено`,"toast.autoAcceptOff":`Авто-принятие входа выключено`,"toast.taskCancelled":`Задача отменена`,"toast.browserOpening":`Браузер открывается...`,"toast.cookiesExpiredRevalidating":`Куки устарели. Запущена повторная валидация...`,"toast.cookiesExpired":`Куки устарели. Провалидируйте аккаунт заново.`,"toast.proxyCleared":`Прокси убран у {name}`,"toast.proxiesReassigned":`Переназначено {used} прокси на {count} акк.`,"toast.proxiesAssigned":`Назначено {used} прокси на {count} аккаунтов`,"toast.proxiesAssignedShort":`Назначено {count} аккаунтам`,"toast.proxiesReassignedShort":`Переназначено {count} аккаунтам`,"toast.proxiesClearedCount":`Очищено прокси у {count} аккаунтов`,"toast.proxiesClearedShort":`Очищено у {count} аккаунтов`,"toast.deleted":`Удалено: {count}`,"toast.sentToMafile":`{count} акк. отправлено в Mafile Management`,"toast.settingsSaved":`Настройки сохранены`,"toast.proxyFormatError":`Не удалось распознать прокси. Проверьте формат.`,"toast.proxiesAdded":`Добавлено {count} прокси`,"toast.proxiesDeleted":`Удалено {count} прокси`,"toast.exportDone":`Экспорт завершён`,"toast.uploaded":`Загружено: {count}`,"toast.uploadedWithErrors":`Загружено: {uploaded}, ошибок: {errors}`,"toast.importResult":`Импортировано: {imported}, Пропущено: {skipped}`,"toast.fileEmpty":`Файл пуст`,"task.validate":`Валидация`,"task.changePassword":`Смена пароля`,"task.randomPassword":`Случ. пароль`,"task.changeEmail":`Смена email`,"task.changePhone":`Смена телефона`,"task.removePhone":`Удал. телефона`,"task.removeGuard":`Удал. Guard`,"status.unknown":`Неизвестен`,"status.valid":`Валидный`,"status.invalid":`Невалидный`,"status.locked":`Заблокирован`,"status.limited":`Ограничен`,"status.banned":`БАН`,"status.ok":`ОК`,"tip.openBrowser":`Открыть Steam в браузере`,"tip.copyPassword":`Копировать пароль`,"tip.copyLoginPass":`Копировать login:pass`,"tip.copyEmailPass":`Копировать пароль email`,"tip.copyEmailLoginPass":`Копировать email:pass`,"tip.show":`Показать`,"tip.hide":`Скрыть`,"tip.gen2fa":`Сгенерировать и скопировать 2FA код`,"tip.code":`Код`,"tip.addNote":`Нажмите чтобы добавить заметку`,"tip.edit":`Редактировать`,"tip.delete":`Удалить`,"tip.autoAcceptActive":`Авто-принятие входа`,"tip.validate":`Валидировать`,"tip.columnSettings":`Настройки столбцов`,"tip.deleteProxy":`Удалить прокси`,"tip.clickToCopy":`Клик для копирования`,"tip.proxyError":`Ошибка прокси: {error}`,"ph.search":`Поиск: логин / Steam ID / заметка / lvl>10`,"ph.searchLogpass":`Поиск: логин / Steam ID / заметка / игра / lvl>10`,"ph.login":`Логин`,"ph.password":`Пароль`,"ph.proxy":`Прокси`,"ph.proxyOptional":`Прокси (необязательно)`,"ph.notes":`Заметки`,"ph.notesOptional":`Заметки (необязательно)`,"ph.loginOptional":`Логин (необязательно)`,"ph.emailPassword":`Пароль от email`,"empty.accounts":`Нет аккаунтов. Импортируйте файл`,"empty.logpass":`Аккаунтов нет. Импортируйте файл.`,"empty.tokens":`Токенов нет. Импортируйте или добавьте токены.`,"empty.logs":`Нет логов`,"empty.tasks":`Нет задач`,"modal.addAccount":`Добавить аккаунт`,"modal.editAccount":`Редактировать аккаунт`,"modal.importAccounts":`Импорт аккаунтов`,"modal.addToken":`Добавить токен`,"modal.importTokens":`Импорт токенов`,"import.formats":`Форматы`,"import.formatsColon":`Форматы:`,"import.delimiter":`разделитель`,"import.or":`или`,"import.dragTxt":`Перетащите .txt файл или нажмите для выбора`,"import.dragTxtCsv":`Перетащите .txt / .csv файл или нажмите для выбора`,"import.dragMafile":`Перетащите .mafile файлы или нажмите для выбора`,"import.attachMafile":`Прикрепить .mafile (необязательно)`,"import.selected":`Выбран: {name}`,"import.uploading":`Загрузка...`,"import.importBtn":`Импортировать`,"import.tokenFormat":`refresh_token (по одному на строку)`,"paging.shown":`Показано {visible} из {total}…`,"proxy.label":`Прокси {num}`,"proxy.title":`Прокси`,"proxy.count":`{count} шт.`,"proxy.protocol":`Протокол:`,"proxy.format":`Формат:`,"proxy.customFormat":`Свой формат...`,"proxy.formatConstructor":`Конструктор формата:`,"proxy.preview":`Предпросмотр:`,"proxy.dragFile":`Перетащите .txt файл с прокси или нажмите для выбора`,"proxy.addBtn":`Добавить`,"proxy.checking":`Проверка...`,"proxy.checkAll":`Проверить все`,"proxy.deleteAllBtn":`Удалить все прокси`,"proxy.confirmDeleteAll":`Удалить все прокси? Это действие нельзя отменить.`,"proxy.checkResult":`Всего: {total} | Живых: {alive} | Мёртвых: {dead}`,"proxy.removeProxy":`Убрать прокси`,"proxy.reassignProxy":`Переназначить прокси`,"proxy.perLine":`Прокси по одному на строку ({format})`,"proxy.deleteProxy":`Удалить прокси`,"tools.2faGenerator":`Генератор 2FA кода`,"tools.validationSettings":`Настройки валидации`,"tools.loadProfile":`Загружать профиль (никнейм, аватар)`,"tools.checkBans":`Проверять баны`,"tools.maxThreads":`Макс. потоков:`,"tools.autoRevalidateBrowser":`Автовалидация при мёртвых куках (браузер)`,"tools.autoProxyOnImport":`Авто-назначение прокси при импорте`,"tools.autoValidateOnImport":`Авто-валидация при импорте`,"tools.importSettings":`Настройки импорта`,"tools.autoProxyOnImportDesc":`Авто-назначить прокси сразу после импорта`,"tools.autoValidateOnImportDesc":`Авто-валидировать аккаунты сразу после импорта`,"tools.importTabMafile":`Mafile`,"tools.importTabLogpass":`Log:Pass`,"tools.importTabToken":`Token`,"tools.clickCopy":`Клик для копирования`,"tools.genErrorStr":`Ошибка`,"logs.title":`Лог`,"logs.clear":`Очистить`,"logs.activeTasks":`Активные задачи`,"mafile.upload":`Загрузка Mafile`,"mafile.exportSettings":`Настройки экспорта`,"mafile.exportFormat":`Формат:`,"mafile.flatFiles":`Плоские файлы (.mafile)`,"mafile.perAccountFolder":`Папка на аккаунт`,"mafile.singleFile":`Одним файлом`,"mafile.variables":`Переменные:`,"mafile.folderName":`Название папки:`,"mafile.mafileName":`Название .mafile:`,"mafile.txtSettings":`Настройки .txt`,"mafile.addGlobalTxt":`Добавить общий`,"mafile.withAllAccounts":`со всеми аккаунтами`,"mafile.addTxtPerFolder":`Добавить .txt в каждую папку`,"mafile.skipFolders":`Не создавать папку для каждого аккаунта`,"mafile.txtFolderName":`Название .txt в папке:`,"mafile.txtLineFormat":`Формат строки .txt:`,"mafile.mafileFields":`Поля Mafile`,"mafile.sessionFields":`Поля Session`,"mafile.export":`Экспорт`,"mafile.noAccounts":`нет аккаунтов`,"mafile.sentAccounts":`Отправленные аккаунты`,"mafile.clearBtn":`Очистить`,"mafile.insert":`Вставить {value}`,"mafile.emptyTitle":`Нет выбранных аккаунтов`,"mafile.emptyHint":`Выберите аккаунты в таблице и отправьте сюда для экспорта mafile`,"mafile.accountsCount":`акк.`,"mafile.withMafile":`с mafile`,"mafile.namingSection":`Шаблоны имён`,"mafile.flat_mafiles":`Файлы`,"mafile.per_account_folder":`Папки`,"mafile.single_file":`Один файл`,"settings.display":`Отображение`,"settings.hidePasswords":`Скрывать пароли (спойлер)`,"token.disclaimerTitle":`Вкладка в разработке`,"token.disclaimerBody1":`Функциональность вкладки Token не завершена и находится в стадии разработки.`,"token.disclaimerBody2":`⚠ Валидация токенов может привести к их инвалидации (убить токены). Используйте на свой страх и риск.`,"token.disclaimerBody3":`Импорт, редактирование и любые действия с токенами могут работать некорректно.`,"token.acceptRisk":`Я понимаю риски и хочу продолжить`,"twofa.copied":`2FA: {code} (скопировано)`,"twofa.error":`Ошибка 2FA: {error}`,"misc.task":`Задача {id}`,"misc.taskAction":`Задача {id} - {action} ({login})`,"misc.taskCount":`Задача {id} ({count} акк.)`,"misc.error":`Ошибка: {error}`,"misc.proxyErrorCheck":`Ошибка проверки: {error}`,"misc.exportError":`Ошибка экспорта: {error}`,"misc.genError":`Ошибка генерации: {error}`,"misc.errorStr":`Ошибка`,"misc.insert":`Вставить`},en:{"header.accounts":`Accounts`,"tab.accounts":`Accounts`,"tab.mafiles":`Mafile Management`,"tab.tools":`Settings`,"tab.logs":`Logs`,"section.dataType":`Data Type`,"col.browser":`Login`,"col.profile":`Profile`,"col.lastOnline":`Last Online`,"col.steamId":`Steam ID`,"col.login":`Login`,"col.password":`Password`,"col.loginPass":`Login:Pass`,"col.email":`Email`,"col.emailPass":`Email Pass`,"col.emailLoginPass":`Email:Pass`,"col.phone":`Phone`,"col.status":`Status`,"col.ban":`Ban`,"col.twofa":`2FA`,"col.mafile":`Mafile`,"col.proxy":`Proxy`,"col.notes":`Notes`,"col.actions":`Actions`,"col.prime":`Prime`,"col.trophy":`Trophy`,"col.behavior":`Behavior`,"col.license":`Licenses`,"col.token":`Token`,"action.selectAction":`— Action`,"action.validate":`Validate`,"action.changePassword":`Change password`,"action.randomPassword":`Random password`,"action.changeEmail":`Change email`,"action.changePhone":`Change phone`,"action.removePhone":`Remove phone`,"action.removeGuard":`Remove Guard`,"action.noRevocationCode":`No revocation_code in mafile`,"action.enableAutoAccept":`Enable auto-accept`,"action.disableAutoAccept":`Disable login auto-accept`,"action.enableAutoAcceptLogin":`Enable login auto-accept`,"action.generate2fa":`Generate 2FA code`,"action.confirmations":`Confirmations`,"prompt.newPassword":`Enter new password`,"prompt.newEmail":`Enter new email`,"prompt.newPhone":`Enter new phone number`,"prompt.removePhone":`Enter phone number (old number will be transferred to it)`,"prompt.enterValue":`Enter value...`,"confirm.removeGuard":`Remove Steam Guard for this account?`,"confirm.deleteAccount":`Delete account?`,"confirm.deleteSelected":`Delete {count} selected accounts?`,"confirm.deleteAll":`Delete ALL {count} accounts? This is irreversible!`,"confirm.deleteLogpassSelected":`Delete {count} account(s)?`,"confirm.deleteLogpassAll":`Delete all {count} accounts?`,"confirm.deleteTokenSelected":`Delete {count} token(s)?`,"confirm.deleteTokenAll":`Delete all {count} tokens?`,"confirm.deleteToken":`Delete token {name}?`,"confirm.deleteLogpass":`Delete {name}?`,"confirm.assignProxies":`Assign proxies to accounts without proxies?`,"confirm.reassignProxies":`Reassign proxies to all accounts?`,"confirm.reassignProxiesAll":`Reassign proxies to all accounts?`,"confirm.clearProxies":`Clear proxies from all accounts?`,"confirm.executeBulk":`Execute «{action}» for {count} accounts?`,"confirm.yes":`Yes`,"confirm.title":`Confirmations`,"confirm.loading":`Loading confirmations...`,"confirm.empty":`No pending confirmations`,"confirm.acceptAll":`Accept all`,"confirm.denyAll":`Deny all`,"confirm.refresh":`Refresh`,"confirm.accepted":`Accepted`,"confirm.denied":`Denied`,"confirm.respondFailed":`Failed to process confirmation`,"btn.import":`Import`,"btn.add":`Add`,"btn.save":`Save`,"btn.cancel":`Cancel`,"btn.execute":`Execute`,"btn.deleteSelected":`Delete selected`,"btn.deleteAll":`Delete all`,"btn.assignProxies":`Assign proxies`,"btn.reassign":`Reassign`,"btn.clearProxies":`Clear proxies`,"btn.validate":`Validate`,"btn.fullParse":`Full parse`,"btn.fullCheck":`Full Check`,"btn.generate":`Generate`,"toast.copied":`Copied`,"toast.copyFailed":`Failed to copy`,"toast.noteSaved":`Note saved`,"toast.noteSaveError":`Error saving`,"toast.accountDeleted":`Account deleted`,"toast.accountAdded":`Account added`,"toast.saved":`Saved`,"toast.done":`Done`,"toast.error":`Error`,"toast.selectAction":`Select an action`,"toast.selectAccounts":`Select accounts`,"toast.noAccounts":`No accounts`,"toast.autoAcceptEnabled":`Auto-accept enabled for {count} accounts`,"toast.autoAcceptOn":`Login auto-accept enabled`,"toast.autoAcceptOff":`Login auto-accept disabled`,"toast.taskCancelled":`Task cancelled`,"toast.browserOpening":`Opening browser...`,"toast.cookiesExpiredRevalidating":`Cookies expired. Re-validating...`,"toast.cookiesExpired":`Cookies expired. Re-validate the account.`,"toast.proxyCleared":`Proxy removed from {name}`,"toast.proxiesReassigned":`Reassigned {used} proxies to {count} accounts`,"toast.proxiesAssigned":`Assigned {used} proxies to {count} accounts`,"toast.proxiesAssignedShort":`Assigned to {count} accounts`,"toast.proxiesReassignedShort":`Reassigned to {count} accounts`,"toast.proxiesClearedCount":`Cleared proxies from {count} accounts`,"toast.proxiesClearedShort":`Cleared from {count} accounts`,"toast.deleted":`Deleted: {count}`,"toast.sentToMafile":`{count} accounts sent to Mafile Management`,"toast.settingsSaved":`Settings saved`,"toast.proxyFormatError":`Failed to parse proxies. Check the format.`,"toast.proxiesAdded":`Added {count} proxies`,"toast.proxiesDeleted":`Deleted {count} proxies`,"toast.exportDone":`Export complete`,"toast.uploaded":`Uploaded: {count}`,"toast.uploadedWithErrors":`Uploaded: {uploaded}, errors: {errors}`,"toast.importResult":`Imported: {imported}, Skipped: {skipped}`,"toast.fileEmpty":`File is empty`,"task.validate":`Validation`,"task.changePassword":`Password change`,"task.randomPassword":`Random password`,"task.changeEmail":`Email change`,"task.changePhone":`Phone change`,"task.removePhone":`Phone removal`,"task.removeGuard":`Guard removal`,"status.unknown":`Unknown`,"status.valid":`Valid`,"status.invalid":`Invalid`,"status.locked":`Locked`,"status.limited":`Limited`,"status.banned":`BANNED`,"status.ok":`OK`,"tip.openBrowser":`Open Steam in browser`,"tip.copyPassword":`Copy password`,"tip.copyLoginPass":`Copy login:pass`,"tip.copyEmailPass":`Copy email password`,"tip.copyEmailLoginPass":`Copy email:pass`,"tip.show":`Show`,"tip.hide":`Hide`,"tip.gen2fa":`Generate and copy 2FA code`,"tip.code":`Code`,"tip.addNote":`Click to add a note`,"tip.edit":`Edit`,"tip.delete":`Delete`,"tip.autoAcceptActive":`Login auto-accept`,"tip.validate":`Validate`,"tip.columnSettings":`Column settings`,"tip.deleteProxy":`Delete proxy`,"tip.clickToCopy":`Click to copy`,"tip.proxyError":`Proxy error: {error}`,"ph.search":`Search: login / Steam ID / notes / lvl>10`,"ph.searchLogpass":`Search: login / Steam ID / notes / game / lvl>10`,"ph.login":`Login`,"ph.password":`Password`,"ph.proxy":`Proxy`,"ph.proxyOptional":`Proxy (optional)`,"ph.notes":`Notes`,"ph.notesOptional":`Notes (optional)`,"ph.loginOptional":`Login (optional)`,"ph.emailPassword":`Email password`,"empty.accounts":`No accounts. Import a file`,"empty.logpass":`No accounts. Import a file.`,"empty.tokens":`No tokens. Import or add tokens.`,"empty.logs":`No logs`,"empty.tasks":`No tasks`,"modal.addAccount":`Add account`,"modal.editAccount":`Edit account`,"modal.importAccounts":`Import accounts`,"modal.addToken":`Add token`,"modal.importTokens":`Import tokens`,"import.formats":`Formats`,"import.formatsColon":`Formats:`,"import.delimiter":`delimiter`,"import.or":`or`,"import.dragTxt":`Drag a .txt file or click to select`,"import.dragTxtCsv":`Drag a .txt / .csv file or click to select`,"import.dragMafile":`Drag .mafile files or click to select`,"import.attachMafile":`Attach .mafile (optional)`,"import.selected":`Selected: {name}`,"import.uploading":`Uploading...`,"import.importBtn":`Import`,"import.tokenFormat":`refresh_token (one per line)`,"paging.shown":`Showing {visible} of {total}…`,"proxy.label":`Proxy {num}`,"proxy.title":`Proxies`,"proxy.count":`{count} total`,"proxy.protocol":`Protocol:`,"proxy.format":`Format:`,"proxy.customFormat":`Custom format...`,"proxy.formatConstructor":`Format constructor:`,"proxy.preview":`Preview:`,"proxy.dragFile":`Drag a .txt file with proxies or click to select`,"proxy.addBtn":`Add`,"proxy.checking":`Checking...`,"proxy.checkAll":`Check all`,"proxy.deleteAllBtn":`Delete all proxies`,"proxy.confirmDeleteAll":`Delete all proxies? This cannot be undone.`,"proxy.checkResult":`Total: {total} | Alive: {alive} | Dead: {dead}`,"proxy.removeProxy":`Remove proxy`,"proxy.reassignProxy":`Reassign proxy`,"proxy.perLine":`Proxies one per line ({format})`,"proxy.deleteProxy":`Delete proxy`,"tools.2faGenerator":`2FA Code Generator`,"tools.validationSettings":`Validation Settings`,"tools.loadProfile":`Load profile (nickname, avatar)`,"tools.checkBans":`Check bans`,"tools.maxThreads":`Max threads:`,"tools.autoRevalidateBrowser":`Auto-revalidate on dead cookies (browser)`,"tools.autoProxyOnImport":`Auto-assign proxies on import`,"tools.autoValidateOnImport":`Auto-validate on import`,"tools.importSettings":`Import Settings`,"tools.autoProxyOnImportDesc":`Auto-assign proxies right after import`,"tools.autoValidateOnImportDesc":`Auto-validate accounts right after import`,"tools.importTabMafile":`Mafile`,"tools.importTabLogpass":`Log:Pass`,"tools.importTabToken":`Token`,"tools.clickCopy":`Click to copy`,"tools.genErrorStr":`Error`,"logs.title":`Log`,"logs.clear":`Clear`,"logs.activeTasks":`Active Tasks`,"mafile.upload":`Upload Mafile`,"mafile.exportSettings":`Export Settings`,"mafile.exportFormat":`Format:`,"mafile.flatFiles":`Flat files (.mafile)`,"mafile.perAccountFolder":`Folder per account`,"mafile.singleFile":`Single file`,"mafile.variables":`Variables:`,"mafile.folderName":`Folder name:`,"mafile.mafileName":`.mafile name:`,"mafile.txtSettings":`.txt Settings`,"mafile.addGlobalTxt":`Add global`,"mafile.withAllAccounts":`with all accounts`,"mafile.addTxtPerFolder":`Add .txt to each folder`,"mafile.skipFolders":`Don't create folder for each account`,"mafile.txtFolderName":`.txt name in folder:`,"mafile.txtLineFormat":`.txt line format:`,"mafile.mafileFields":`Mafile Fields`,"mafile.sessionFields":`Session Fields`,"mafile.export":`Export`,"mafile.noAccounts":`no accounts`,"mafile.sentAccounts":`Sent Accounts`,"mafile.clearBtn":`Clear`,"mafile.insert":`Insert {value}`,"mafile.emptyTitle":`No accounts selected`,"mafile.emptyHint":`Select accounts in the table and send them here for mafile export`,"mafile.accountsCount":`accs`,"mafile.withMafile":`with mafile`,"mafile.namingSection":`Naming templates`,"mafile.flat_mafiles":`Files`,"mafile.per_account_folder":`Folders`,"mafile.single_file":`Single file`,"settings.display":`Display`,"settings.hidePasswords":`Hide passwords (spoiler)`,"token.disclaimerTitle":`Tab under development`,"token.disclaimerBody1":`Token tab functionality is not complete and is under development.`,"token.disclaimerBody2":`⚠ Token validation may invalidate (kill) tokens. Use at your own risk.`,"token.disclaimerBody3":`Import, editing and any actions with tokens may work incorrectly.`,"token.acceptRisk":`I understand the risks and want to continue`,"twofa.copied":`2FA: {code} (copied)`,"twofa.error":`2FA Error: {error}`,"misc.task":`Task {id}`,"misc.taskAction":`Task {id} - {action} ({login})`,"misc.taskCount":`Task {id} ({count} accounts)`,"misc.error":`Error: {error}`,"misc.proxyErrorCheck":`Check error: {error}`,"misc.exportError":`Export error: {error}`,"misc.genError":`Generation error: {error}`,"misc.errorStr":`Error`,"misc.insert":`Insert`}};function ie(e,t){let n=(re[M]||re.ru)[e]??re.ru[e]??e;if(t)for(let[e,r]of Object.entries(t))n=n.replace(`{${e}}`,String(r));return n}function I(){return(0,y.useSyncExternalStore)(e=>(N.add(e),()=>N.delete(e)),()=>M),ie}var ae=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),L=o(((e,t)=>{t.exports=ae()}))();function oe(){let[e,t]=ne(),[n,r]=(0,y.useState)(``);return(0,y.useEffect)(()=>{D.getVersion().then(e=>r(e.version)).catch(()=>{})},[]),(0,L.jsxs)(`header`,{className:`bg-dark-800 border-b border-dark-600 px-4 py-3 flex items-center justify-between`,children:[(0,L.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5 cursor-pointer`,onClick:()=>window.location.reload(),children:[(0,L.jsx)(`svg`,{viewBox:`0 0 24 24`,xmlns:`http://www.w3.org/2000/svg`,className:`w-7 h-7 shrink-0 fill-white`,children:(0,L.jsx)(`path`,{d:`M11.979 0C5.678 0 0.511 4.86 0.022 11.037l6.432 2.658c0.545 -0.371 1.203 -0.59 1.912 -0.59 0.063 0 0.125 0.004 0.188 0.006l2.861 -4.142V8.91c0 -2.495 2.028 -4.524 4.524 -4.524 2.494 0 4.524 2.031 4.524 4.527s-2.03 4.525 -4.524 4.525h-0.105l-4.076 2.911c0 0.052 0.004 0.105 0.004 0.159 0 1.875 -1.515 3.396 -3.39 3.396 -1.635 0 -3.016 -1.173 -3.331 -2.727L0.436 15.27C1.862 20.307 6.486 24 11.979 24c6.627 0 11.999 -5.373 11.999 -12S18.605 0 11.979 0zM7.54 18.21l-1.473 -0.61c0.262 0.543 0.714 0.999 1.314 1.25 1.297 0.539 2.793 -0.076 3.332 -1.375 0.263 -0.63 0.264 -1.319 0.005 -1.949s-0.75 -1.121 -1.377 -1.383c-0.624 -0.26 -1.29 -0.249 -1.878 -0.03l1.523 0.63c0.956 0.4 1.409 1.5 1.009 2.455 -0.397 0.957 -1.497 1.41 -2.454 1.012H7.54zm11.415 -9.303c0 -1.662 -1.353 -3.015 -3.015 -3.015 -1.665 0 -3.015 1.353 -3.015 3.015 0 1.665 1.35 3.015 3.015 3.015 1.663 0 3.015 -1.35 3.015 -3.015zm-5.273 -0.005c0 -1.252 1.013 -2.266 2.265 -2.266 1.249 0 2.266 1.014 2.266 2.266 0 1.251 -1.017 2.265 -2.266 2.265 -1.253 0 -2.265 -1.014 -2.265 -2.265z`})}),(0,L.jsx)(`h1`,{className:`text-lg font-bold text-white tracking-wide`,children:`SteamPanel`})]}),(0,L.jsx)(`span`,{className:`text-xs text-gray-500`,children:n&&`v${n}`}),(0,L.jsxs)(`span`,{className:`text-xs text-gray-500`,children:[`by`,` `,(0,L.jsx)(`a`,{href:`https://t.me/lolzdm`,target:`_blank`,rel:`noopener noreferrer`,className:`hover:text-accent transition`,children:`@lolzdm`})]})]}),(0,L.jsx)(`div`,{className:`flex items-center gap-4`,children:(0,L.jsxs)(`button`,{onClick:()=>t(e===`ru`?`en`:`ru`),className:`flex items-center gap-1.5 text-xs text-gray-400 hover:text-gray-200 transition px-2 py-1 border border-dark-500 hover:border-gray-500 rounded`,children:[(0,L.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:`13`,height:`13`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`1.8`,strokeLinecap:`round`,strokeLinejoin:`round`,className:`opacity-80`,children:[(0,L.jsx)(`circle`,{cx:`12`,cy:`12`,r:`10`}),(0,L.jsx)(`path`,{d:`M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z`})]}),e===`ru`?`EN`:`RU`]})})]})}var R=(e=16)=>({width:e,height:e,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`}),se=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`}),(0,L.jsx)(`polyline`,{points:`7 10 12 15 17 10`}),(0,L.jsx)(`line`,{x1:`12`,y1:`15`,x2:`12`,y2:`3`})]}),ce=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`}),(0,L.jsx)(`polyline`,{points:`17 8 12 3 7 8`}),(0,L.jsx)(`line`,{x1:`12`,y1:`3`,x2:`12`,y2:`15`})]}),le=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`line`,{x1:`12`,y1:`5`,x2:`12`,y2:`19`}),(0,L.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`})]}),ue=({size:e=16,...t})=>(0,L.jsx)(`svg`,{...R(e),...t,children:(0,L.jsx)(`polyline`,{points:`20 6 9 17 4 12`})}),de=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`line`,{x1:`18`,y1:`6`,x2:`6`,y2:`18`}),(0,L.jsx)(`line`,{x1:`6`,y1:`6`,x2:`18`,y2:`18`})]}),fe=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`path`,{d:`M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z`}),(0,L.jsx)(`line`,{x1:`12`,y1:`9`,x2:`12`,y2:`13`}),(0,L.jsx)(`line`,{x1:`12`,y1:`17`,x2:`12.01`,y2:`17`})]}),pe=({size:e=16,...t})=>(0,L.jsx)(`svg`,{...R(e),...t,children:(0,L.jsx)(`path`,{d:`m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2`})}),me=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`circle`,{cx:`12`,cy:`12`,r:`10`}),(0,L.jsx)(`line`,{x1:`2`,y1:`12`,x2:`22`,y2:`12`}),(0,L.jsx)(`path`,{d:`M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z`})]}),he=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`polyline`,{points:`23 4 23 10 17 10`}),(0,L.jsx)(`path`,{d:`M20.49 15a9 9 0 1 1-2.12-9.36L23 10`})]}),ge=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`circle`,{cx:`12`,cy:`12`,r:`10`}),(0,L.jsx)(`line`,{x1:`4.93`,y1:`4.93`,x2:`19.07`,y2:`19.07`})]}),z=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`path`,{d:`M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z`}),(0,L.jsx)(`circle`,{cx:`12`,cy:`12`,r:`3`})]}),_e=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`path`,{d:`M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94`}),(0,L.jsx)(`path`,{d:`M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19`}),(0,L.jsx)(`line`,{x1:`1`,y1:`1`,x2:`23`,y2:`23`}),(0,L.jsx)(`path`,{d:`M14.12 14.12a3 3 0 1 1-4.24-4.24`})]}),ve=({size:e=16,...t})=>(0,L.jsx)(`svg`,{...R(e),...t,children:(0,L.jsx)(`path`,{d:`M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.78 7.78 5.5 5.5 0 0 1 7.78-7.78zm0 0L15.5 7.5m0 0 3 3L22 7l-3-3m-3.5 3.5L19 4`})}),ye=({size:e=16,...t})=>(0,L.jsx)(`svg`,{...R(e),...t,children:(0,L.jsx)(`polygon`,{points:`13 2 3 14 12 14 11 22 21 10 12 10 13 2`})}),be=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`circle`,{cx:`12`,cy:`12`,r:`3`}),(0,L.jsx)(`path`,{d:`M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z`})]}),xe=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`path`,{d:`M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7`}),(0,L.jsx)(`path`,{d:`M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z`})]}),Se=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`polyline`,{points:`3 6 5 6 21 6`}),(0,L.jsx)(`path`,{d:`M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2`})]}),Ce=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`rect`,{x:`3`,y:`11`,width:`18`,height:`11`,rx:`2`,ry:`2`}),(0,L.jsx)(`path`,{d:`M7 11V7a5 5 0 0 1 10 0v4`})]}),we=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`line`,{x1:`16.5`,y1:`9.4`,x2:`7.5`,y2:`4.21`}),(0,L.jsx)(`path`,{d:`M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z`}),(0,L.jsx)(`polyline`,{points:`3.27 6.96 12 12.01 20.73 6.96`}),(0,L.jsx)(`line`,{x1:`12`,y1:`22.08`,x2:`12`,y2:`12`})]}),Te=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`path`,{d:`M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z`}),(0,L.jsx)(`polyline`,{points:`14 2 14 8 20 8`}),(0,L.jsx)(`line`,{x1:`16`,y1:`13`,x2:`8`,y2:`13`}),(0,L.jsx)(`line`,{x1:`16`,y1:`17`,x2:`8`,y2:`17`}),(0,L.jsx)(`polyline`,{points:`10 9 9 9 8 9`})]}),Ee=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`path`,{d:`M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2`}),(0,L.jsx)(`rect`,{x:`8`,y:`2`,width:`8`,height:`4`,rx:`1`,ry:`1`})]}),De=({size:e=16,...t})=>(0,L.jsx)(`svg`,{...R(e),...t,children:(0,L.jsx)(`polygon`,{points:`5 3 19 12 5 21 5 3`})}),Oe=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`circle`,{cx:`12`,cy:`12`,r:`10`}),(0,L.jsx)(`line`,{x1:`15`,y1:`9`,x2:`9`,y2:`15`}),(0,L.jsx)(`line`,{x1:`9`,y1:`9`,x2:`15`,y2:`15`})]}),ke=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`path`,{d:`M22 11.08V12a10 10 0 1 1-5.93-9.14`}),(0,L.jsx)(`polyline`,{points:`22 4 12 14.01 9 11.01`})]}),Ae=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,className:`animate-spin ${t.className??``}`,children:[(0,L.jsx)(`line`,{x1:`12`,y1:`2`,x2:`12`,y2:`6`}),(0,L.jsx)(`line`,{x1:`12`,y1:`18`,x2:`12`,y2:`22`}),(0,L.jsx)(`line`,{x1:`4.93`,y1:`4.93`,x2:`7.76`,y2:`7.76`}),(0,L.jsx)(`line`,{x1:`16.24`,y1:`16.24`,x2:`19.07`,y2:`19.07`}),(0,L.jsx)(`line`,{x1:`2`,y1:`12`,x2:`6`,y2:`12`}),(0,L.jsx)(`line`,{x1:`18`,y1:`12`,x2:`22`,y2:`12`}),(0,L.jsx)(`line`,{x1:`4.93`,y1:`19.07`,x2:`7.76`,y2:`16.24`}),(0,L.jsx)(`line`,{x1:`16.24`,y1:`7.76`,x2:`19.07`,y2:`4.93`})]}),je=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`path`,{d:`M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2`}),(0,L.jsx)(`circle`,{cx:`9`,cy:`7`,r:`4`}),(0,L.jsx)(`path`,{d:`M22 21v-2a4 4 0 0 0-3-3.87`}),(0,L.jsx)(`path`,{d:`M16 3.13a4 4 0 0 1 0 7.75`})]}),Me=({size:e=16,...t})=>(0,L.jsx)(`svg`,{...R(e),...t,children:(0,L.jsx)(`path`,{d:`m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2`})}),Ne=({size:e=16,...t})=>(0,L.jsx)(`svg`,{...R(e),...t,children:(0,L.jsx)(`path`,{d:`M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z`})}),Pe=({size:e=16,...t})=>(0,L.jsxs)(`svg`,{...R(e),...t,children:[(0,L.jsx)(`path`,{d:`M15 12h-5`}),(0,L.jsx)(`path`,{d:`M15 8h-5`}),(0,L.jsx)(`path`,{d:`M19 17V5a2 2 0 0 0-2-2H4`}),(0,L.jsx)(`path`,{d:`M8 21h12a2 2 0 0 0 2-2v-1a1 1 0 0 0-1-1H11a1 1 0 0 0-1 1v1a2 2 0 1 1-4 0V5a2 2 0 1 0-4 0v2`})]}),Fe=({size:e=16,...t})=>(0,L.jsx)(`svg`,{...R(e),...t,children:(0,L.jsx)(`polyline`,{points:`9 18 15 12 9 6`})}),Ie=[{id:`accounts`,labelKey:`tab.accounts`,icon:je},{id:`mafiles`,labelKey:`tab.mafiles`,icon:Me},{id:`tools`,labelKey:`tab.tools`,icon:Ne},{id:`logs`,labelKey:`tab.logs`,icon:Pe}];function Le(){let e=A(e=>e.activeTab),t=A(e=>e.setTab),n=I();return(0,L.jsx)(`nav`,{className:`bg-dark-800 border-b border-dark-600 flex gap-1 px-4 overflow-x-auto`,children:Ie.map(({id:r,labelKey:i,icon:a})=>(0,L.jsxs)(`button`,{onClick:()=>t(r),className:`flex items-center gap-1.5 px-4 py-2.5 text-sm font-medium transition-colors border-b-2 -mb-px ${e===r?`border-accent text-accent`:`border-transparent text-gray-400 hover:text-gray-200`}`,children:[(0,L.jsx)(a,{size:14}),n(i)]},r))})}function Re(){let e=A(e=>e.toasts),t=A(e=>e.removeToast);return e.length===0?null:(0,L.jsx)(`div`,{className:`toast-container`,children:e.map(e=>(0,L.jsx)(`div`,{className:`toast toast-${e.type}`,onClick:()=>t(e.id),children:e.message},e.id))})}var ze=C(e=>({accounts:[],selectedIds:new Set,loading:!1,loadAccounts:async()=>{e({loading:!0});try{e({accounts:await D.getAccounts()})}finally{e({loading:!1})}},toggleSelect:t=>e(e=>{let n=new Set(e.selectedIds);return n.has(t)?n.delete(t):n.add(t),{selectedIds:n}}),selectAll:()=>e(e=>({selectedIds:new Set(e.accounts.map(e=>e.id))})),clearSelection:()=>e({selectedIds:new Set}),setSelectedIds:t=>e({selectedIds:t}),mafileManagerIds:new Set,sendToMafileManager:t=>e(e=>{let n=new Set(e.mafileManagerIds);return t.forEach(e=>n.add(e)),{mafileManagerIds:n}}),clearMafileManager:()=>e({mafileManagerIds:new Set})})),Be=C(e=>({tasks:[],hasRunning:!1,loadTasks:async()=>{let t=await D.getTasks();e({tasks:t,hasRunning:t.some(e=>e.status===`running`||e.status===`pending`)})}})),Ve=C(e=>({accounts:[],selectedIds:new Set,loading:!1,loadAccounts:async()=>{e({loading:!0});try{e({accounts:await D.getLogpassAccounts()})}finally{e({loading:!1})}},toggleSelect:t=>e(e=>{let n=new Set(e.selectedIds);return n.has(t)?n.delete(t):n.add(t),{selectedIds:n}}),selectAll:()=>e(e=>({selectedIds:new Set(e.accounts.map(e=>e.id))})),clearSelection:()=>e({selectedIds:new Set}),setSelectedIds:t=>e({selectedIds:t})})),He=C(e=>({accounts:[],selectedIds:new Set,loading:!1,loadAccounts:async()=>{e({loading:!0});try{e({accounts:await D.getTokenAccounts()})}finally{e({loading:!1})}},toggleSelect:t=>e(e=>{let n=new Set(e.selectedIds);return n.has(t)?n.delete(t):n.add(t),{selectedIds:n}}),selectAll:()=>e(e=>({selectedIds:new Set(e.accounts.map(e=>e.id))})),clearSelection:()=>e({selectedIds:new Set}),setSelectedIds:t=>e({selectedIds:t})}));async function Ue(e){try{return await navigator.clipboard.writeText(e),!0}catch{return!1}}var We={unknown:[`badge-unknown`,`status.unknown`],valid:[`badge-ok`,`status.valid`],invalid:[`badge-error`,`status.invalid`],locked:[`badge-error`,`status.locked`],limited:[`badge-running`,`status.limited`]};function Ge({status:e}){let t=We[e],[n,r]=t?[t[0],ie(t[1])]:[`badge-unknown`,e];return(0,L.jsx)(`span`,{className:`badge ${n}`,children:r})}function Ke({status:e}){return e===`BANNED`?(0,L.jsx)(`span`,{className:`badge badge-error`,children:ie(`status.banned`)}):e===`NO BAN`?(0,L.jsx)(`span`,{className:`badge badge-ok`,children:ie(`status.ok`)}):(0,L.jsx)(`span`,{className:`badge badge-unknown`,children:`—`})}function qe({hasMafile:e}){return e?(0,L.jsx)(`span`,{className:`badge badge-ok`,children:`✓`}):(0,L.jsx)(`span`,{className:`badge badge-unknown`,children:`—`})}var Je=m(),Ye={0:`❓`,1:`🧪`,2:`🔄`,3:`🏪`,4:`⚙️`,5:`📱`,6:`🔑`};function Xe({account:e,onClose:t}){let n=I(),r=A(e=>e.addToast),[i,a]=(0,y.useState)([]),[o,s]=(0,y.useState)(!0),[c,l]=(0,y.useState)(new Set),[u,d]=(0,y.useState)(null),f=(0,y.useCallback)(async()=>{s(!0),d(null);try{a((await D.getConfirmations(e.id)).confirmations)}catch(e){d(e instanceof Error?e.message:String(e))}finally{s(!1)}},[e.id]);(0,y.useEffect)(()=>{f()},[f]);let p=async(t,i,o)=>{let s=new Set(c);t.forEach(e=>s.add(e)),l(s);try{let{success:s}=await D.respondConfirmations(e.id,t,i,o);s?(r(`success`,`${n(o?`confirm.accepted`:`confirm.denied`)} (${t.length})`),a(e=>e.filter(e=>!t.includes(e.id)))):r(`error`,n(`confirm.respondFailed`))}catch(e){r(`error`,e instanceof Error?e.message:String(e))}finally{l(e=>{let n=new Set(e);return t.forEach(e=>n.delete(e)),n})}};return(0,L.jsx)(`div`,{className:`confirm-overlay`,onMouseDown:t,children:(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-lg shadow-xl p-5 w-[560px] max-h-[80vh] flex flex-col`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsxs)(`div`,{className:`flex items-center justify-between mb-4`,children:[(0,L.jsxs)(`h2`,{className:`text-base font-semibold text-gray-200`,children:[n(`confirm.title`),` — `,e.login]}),(0,L.jsx)(`button`,{onClick:t,className:`text-gray-500 hover:text-gray-300 transition-colors`,children:(0,L.jsx)(de,{})})]}),o&&(0,L.jsxs)(`div`,{className:`flex items-center justify-center py-8 text-gray-400 text-sm`,children:[(0,L.jsx)(he,{className:`animate-spin mr-2 w-4 h-4`}),n(`confirm.loading`)]}),u&&(0,L.jsx)(`div`,{className:`bg-red-900/30 border border-red-700 rounded p-3 text-sm text-red-300 mb-3`,children:u}),!o&&!u&&i.length===0&&(0,L.jsx)(`p`,{className:`text-gray-400 text-sm text-center py-8`,children:n(`confirm.empty`)}),!o&&i.length>0&&(0,L.jsxs)(L.Fragment,{children:[(0,L.jsxs)(`div`,{className:`flex gap-2 mb-3`,children:[(0,L.jsxs)(`button`,{onClick:()=>{i.length!==0&&p(i.map(e=>e.id),i.map(e=>e.nonce),!0)},className:`btn-primary text-xs flex items-center gap-1`,children:[(0,L.jsx)(ue,{className:`w-3 h-3`}),n(`confirm.acceptAll`),` (`,i.length,`)`]}),(0,L.jsxs)(`button`,{onClick:()=>{i.length!==0&&p(i.map(e=>e.id),i.map(e=>e.nonce),!1)},className:`btn-secondary text-xs flex items-center gap-1`,children:[(0,L.jsx)(de,{className:`w-3 h-3`}),n(`confirm.denyAll`)]}),(0,L.jsxs)(`button`,{onClick:f,className:`btn-secondary text-xs flex items-center gap-1 ml-auto`,children:[(0,L.jsx)(he,{className:`w-3 h-3`}),n(`confirm.refresh`)]})]}),(0,L.jsx)(`div`,{className:`overflow-y-auto space-y-2 flex-1 min-h-0`,children:i.map(e=>{let t=c.has(e.id);return(0,L.jsxs)(`div`,{className:`bg-dark-700 border border-dark-600 rounded p-3 flex items-start gap-3 ${t?`opacity-50`:``}`,children:[e.icon?(0,L.jsx)(`img`,{src:e.icon,alt:``,className:`w-8 h-8 rounded flex-shrink-0 mt-0.5`}):(0,L.jsx)(`span`,{className:`text-xl flex-shrink-0 mt-0.5`,children:Ye[e.type]??`❓`}),(0,L.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,L.jsxs)(`div`,{className:`flex items-center gap-2 mb-1`,children:[(0,L.jsx)(`span`,{className:`text-xs px-1.5 py-0.5 rounded bg-dark-600 text-gray-400`,children:e.type_name}),(0,L.jsx)(`span`,{className:`text-sm text-gray-200 truncate`,children:e.headline})]}),e.summary.length>0&&(0,L.jsx)(`p`,{className:`text-xs text-gray-400 truncate`,children:e.summary.join(` • `)})]}),(0,L.jsxs)(`div`,{className:`flex gap-1 flex-shrink-0`,children:[(0,L.jsx)(`button`,{disabled:t,onClick:()=>p([e.id],[e.nonce],!0),className:`p-1.5 rounded bg-green-700/60 hover:bg-green-600/80 text-green-200 transition-colors`,title:e.accept,children:(0,L.jsx)(ue,{className:`w-3.5 h-3.5`})}),(0,L.jsx)(`button`,{disabled:t,onClick:()=>p([e.id],[e.nonce],!1),className:`p-1.5 rounded bg-red-700/60 hover:bg-red-600/80 text-red-200 transition-colors`,title:e.cancel,children:(0,L.jsx)(de,{className:`w-3.5 h-3.5`})})]})]},e.id)})})]})]})})}var Ze=[{action:`validate`,labelKey:`action.validate`},{action:`change_password`,labelKey:`action.changePassword`},{action:`random_password`,labelKey:`action.randomPassword`},{action:`change_email`,labelKey:`action.changeEmail`},{action:`change_phone`,labelKey:`action.changePhone`},{action:`remove_guard`,labelKey:`action.removeGuard`}],Qe={change_password:`prompt.newPassword`,change_email:`prompt.newEmail`,change_phone:`prompt.newPhone`},$e={change_password:`new_password`,change_email:`new_email`,change_phone:`new_phone`},et={remove_guard:`confirm.removeGuard`};function tt({account:e,onAction:t,onToggleAutoAccept:n}){let[r,i]=(0,y.useState)(!1),[a,o]=(0,y.useState)(null),[s,c]=(0,y.useState)(``),[l,u]=(0,y.useState)(null),[d,f]=(0,y.useState)(!1),[p,m]=(0,y.useState)(null),h=(0,y.useRef)(null),g=(0,y.useRef)(null),_=A(e=>e.addToast),v=ze(e=>e.loadAccounts),b=I(),x=(0,y.useCallback)(()=>{if(!g.current)return;let e=g.current.getBoundingClientRect();m({top:window.innerHeight-e.bottom<320?Math.max(4,e.top-320):e.bottom+4,left:Math.max(4,e.right-180)})},[]);(0,y.useEffect)(()=>{if(!r)return;x();function e(e){h.current&&!h.current.contains(e.target)&&g.current&&!g.current.contains(e.target)&&i(!1)}function t(){i(!1)}return document.addEventListener(`mousedown`,e),window.addEventListener(`scroll`,t,!0),()=>{document.removeEventListener(`mousedown`,e),window.removeEventListener(`scroll`,t,!0)}},[r,x]);let S=(n,r)=>{i(!1);let a=et[n];if(a){u({action:n,title:b(a)});return}let s=Qe[n];s?(o({action:n,title:b(s)}),c(``)):t(e.id,n,{})},C=()=>{if(!a||!s)return;let n=$e[a.action]||`value`;t(e.id,a.action,{[n]:s}),o(null)},w=e.auto_accept?b(`action.disableAutoAccept`):b(`action.enableAutoAcceptLogin`);return(0,L.jsxs)(L.Fragment,{children:[(0,L.jsxs)(`div`,{className:`relative inline-block`,children:[(0,L.jsx)(`button`,{ref:g,onClick:()=>i(!r),className:`btn-secondary px-2 py-1 text-xs`,children:(0,L.jsx)(ye,{size:12})}),r&&p&&(0,Je.createPortal)((0,L.jsxs)(`div`,{ref:h,className:`action-menu-dropdown`,style:{position:`fixed`,top:p.top,left:p.left},children:[Ze.map(({action:t,labelKey:n})=>t===`remove_guard`&&!e.has_revocation_code?(0,L.jsx)(`span`,{"data-tooltip":b(`action.noRevocationCode`),className:`block`,children:(0,L.jsx)(`button`,{className:`action-menu-item opacity-40 cursor-not-allowed`,disabled:!0,children:b(n)})},t):(0,L.jsx)(`button`,{onClick:()=>S(t,b(n)),className:`action-menu-item`,children:b(n)},t)),(0,L.jsx)(`hr`,{className:`border-dark-600 my-1`}),(0,L.jsx)(`button`,{onClick:async()=>{if(i(!1),!e.shared_secret){_(`error`,b(`twofa.error`,{error:`No shared_secret`}));return}try{let{code:t}=await D.generate2FA(e.shared_secret);await Ue(t),_(`success`,b(`twofa.copied`,{code:t}))}catch(e){_(`error`,b(`twofa.error`,{error:e instanceof Error?e.message:String(e)}))}},disabled:!e.shared_secret,className:`action-menu-item ${e.shared_secret?``:`opacity-40 cursor-not-allowed`}`,children:b(`action.generate2fa`)}),(0,L.jsx)(`button`,{onClick:()=>{i(!1),f(!0)},disabled:!e.identity_secret,className:`action-menu-item ${e.identity_secret?``:`opacity-40 cursor-not-allowed`}`,children:b(`action.confirmations`)}),(0,L.jsx)(`hr`,{className:`border-dark-600 my-1`}),(0,L.jsx)(`button`,{onClick:async()=>{i(!1);try{await D.updateAccount(e.id,{proxy:``}),_(`success`,b(`toast.proxyCleared`,{name:e.login})),await v()}catch(e){_(`error`,b(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}},className:`action-menu-item`,children:b(`proxy.removeProxy`)}),(0,L.jsx)(`button`,{onClick:async()=>{i(!1);try{let e=await D.reassignProxies();_(`success`,b(`toast.proxiesReassigned`,{used:e.proxies_used,count:e.assigned})),await v()}catch(e){_(`error`,b(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}},className:`action-menu-item`,children:b(`proxy.reassignProxy`)}),(0,L.jsx)(`hr`,{className:`border-dark-600 my-1`}),(0,L.jsx)(`button`,{onClick:()=>{i(!1),n(e.id)},className:`action-menu-item`,children:w})]}),document.body)]}),a&&(0,L.jsx)(`div`,{className:`confirm-overlay`,onMouseDown:()=>o(null),children:(0,L.jsxs)(`div`,{className:`confirm-box`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`p`,{className:`text-sm text-gray-300 mb-3`,children:a.title}),(0,L.jsx)(`input`,{autoFocus:!0,value:s,onChange:e=>c(e.target.value),onKeyDown:e=>e.key===`Enter`&&C(),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm mb-3`,placeholder:a.action.includes(`phone`)?`+7 9123456789`:void 0}),(0,L.jsxs)(`div`,{className:`flex gap-2`,children:[(0,L.jsx)(`button`,{onClick:C,className:`btn-primary flex-1`,children:`OK`}),(0,L.jsx)(`button`,{onClick:()=>o(null),className:`btn-secondary flex-1`,children:b(`btn.cancel`)})]})]})}),l&&(0,L.jsx)(`div`,{className:`confirm-overlay`,onMouseDown:()=>u(null),children:(0,L.jsxs)(`div`,{className:`confirm-box`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`p`,{className:`text-sm text-gray-300 mb-3`,children:l.title}),(0,L.jsxs)(`div`,{className:`flex gap-2`,children:[(0,L.jsx)(`button`,{autoFocus:!0,onClick:()=>{t(e.id,l.action,{}),u(null)},className:`btn-primary flex-1`,children:b(`confirm.yes`)}),(0,L.jsx)(`button`,{onClick:()=>u(null),className:`btn-secondary flex-1`,children:b(`btn.cancel`)})]})]})}),d&&(0,L.jsx)(Xe,{account:e,onClose:()=>f(!1)})]})}function nt({level:e}){return e>=100?(0,L.jsx)(`div`,{className:`steam-lvl l100p img-${Math.floor(e/100)*100}`,title:`Level ${e}`,children:(0,L.jsx)(`span`,{children:e})}):(0,L.jsx)(`div`,{className:`steam-lvl l${Math.floor(e/10)*10}`,title:`Level ${e}`,children:(0,L.jsx)(`span`,{children:e})})}function rt({account:e,visibleColumns:t,proxyLabel:n,isProcessing:r,accountResult:i,accountStep:a,onEdit:o,onDelete:s,onAction:c,onToggleAutoAccept:l,onOpenBrowser:u}){let d=ze(e=>e.selectedIds),f=ze(e=>e.toggleSelect),p=A(e=>e.addToast),m=A(e=>e.hidePasswords),[h,g]=(0,y.useState)(!1),[_,v]=(0,y.useState)(!1),[b,x]=(0,y.useState)(e.notes||``),S=I(),C=async e=>{let t=await Ue(e);p(t?`success`:`error`,S(t?`toast.copied`:`toast.copyFailed`))},w=m&&!h,T=`••••••••`;return(0,L.jsxs)(`tr`,{className:`hover:bg-dark-700/50 transition`,children:[(0,L.jsx)(`td`,{className:`px-3 py-2`,children:(0,L.jsx)(`input`,{type:`checkbox`,checked:d.has(e.id),onChange:()=>f(e.id)})}),(0,L.jsx)(`td`,{className:`px-1 py-2 w-5`,children:r?(0,L.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,L.jsx)(`div`,{className:`w-4 h-4 border-2 border-accent border-t-transparent rounded-full animate-spin shrink-0`}),a&&(0,L.jsxs)(`span`,{className:`text-[10px] text-gray-500 whitespace-nowrap`,children:[`[`,a.step,`/`,a.total,`]`]})]}):i?.status===`ok`?(0,L.jsx)(ue,{size:16,className:`text-gray-400`}):i?.status===`error`?(0,L.jsx)(`span`,{title:i.error?.toLowerCase().includes(`proxy`)||i.error?.toLowerCase().includes(`network`)||i.error?.includes(`WinError`)?S(`tip.proxyError`,{error:i.error}):i.error,children:(0,L.jsx)(fe,{size:16,className:`text-red-400`})}):null}),t.browser&&(0,L.jsx)(`td`,{className:`px-3 py-2 whitespace-nowrap text-center`,children:e.has_cookies?(0,L.jsx)(`button`,{onClick:()=>u(e.id),className:`px-2 py-0.5 text-xs font-medium rounded bg-blue-600/20 text-blue-400 border border-blue-500/30 hover:bg-blue-600/40 hover:text-blue-300 active:scale-95 transition`,title:S(`tip.openBrowser`),children:S(`col.browser`)}):(0,L.jsx)(`span`,{className:`text-gray-600 text-xs`,children:`—`})}),t.profile&&(0,L.jsx)(`td`,{className:`px-3 py-2 whitespace-nowrap`,children:(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[e.avatar_url&&(0,L.jsx)(`img`,{src:e.avatar_url,className:`avatar-sm`,alt:``}),(0,L.jsx)(`span`,{className:`text-xs`,children:e.nickname||`—`}),e.steam_level!=null&&(0,L.jsx)(nt,{level:e.steam_level})]})}),t.last_online&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs text-gray-400 whitespace-nowrap`,children:e.last_online||`—`}),t.steam_id&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs`,children:e.steam_id?(0,L.jsx)(`a`,{href:`https://steamcommunity.com/profiles/${encodeURIComponent(e.steam_id)}/`,target:`_blank`,rel:`noopener noreferrer`,className:`text-blue-400 hover:text-blue-300 hover:underline`,children:e.steam_id}):`—`}),t.login&&(0,L.jsx)(`td`,{className:`px-3 py-2 font-medium`,children:e.login}),t.password&&(0,L.jsxs)(`td`,{className:`px-3 py-2 text-gray-400 select-none whitespace-nowrap`,children:[(0,L.jsx)(`span`,{className:`cell-copy cursor-pointer`,onClick:()=>C(e.password),title:S(`tip.copyPassword`),children:w?T:e.password}),(0,L.jsx)(`button`,{onClick:e=>{e.stopPropagation(),g(!h)},className:`ml-1.5 text-gray-500 hover:text-gray-300 inline-flex align-middle`,title:S(w?`tip.show`:`tip.hide`),children:w?(0,L.jsx)(z,{size:14}):(0,L.jsx)(_e,{size:14})})]}),t.login_pass&&(0,L.jsxs)(`td`,{className:`px-3 py-2 text-gray-400 text-xs select-none whitespace-nowrap`,children:[(0,L.jsx)(`span`,{className:`cell-copy cursor-pointer`,onClick:()=>C(`${e.login}:${e.password}`),title:S(`tip.copyLoginPass`),children:w?`${e.login}:${T}`:`${e.login}:${e.password}`}),(0,L.jsx)(`button`,{onClick:e=>{e.stopPropagation(),g(!h)},className:`ml-1.5 text-gray-500 hover:text-gray-300 inline-flex align-middle`,title:S(w?`tip.show`:`tip.hide`),children:w?(0,L.jsx)(z,{size:14}):(0,L.jsx)(_e,{size:14})})]}),t.email&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-gray-400 text-xs`,children:e.email||`—`}),t.email_pass&&(0,L.jsxs)(`td`,{className:`px-3 py-2 text-gray-400 text-xs select-none whitespace-nowrap`,children:[(0,L.jsx)(`span`,{className:`cell-copy cursor-pointer`,onClick:()=>{e.email_password&&C(e.email_password)},title:e.email_password?S(`tip.copyEmailPass`):``,children:e.email_password?w?T:e.email_password:`—`}),e.email_password&&(0,L.jsx)(`button`,{onClick:e=>{e.stopPropagation(),g(!h)},className:`ml-1.5 text-gray-500 hover:text-gray-300 inline-flex align-middle`,title:S(w?`tip.show`:`tip.hide`),children:w?(0,L.jsx)(z,{size:14}):(0,L.jsx)(_e,{size:14})})]}),t.email_login_pass&&(0,L.jsxs)(`td`,{className:`px-3 py-2 text-gray-400 text-xs select-none whitespace-nowrap`,children:[(0,L.jsx)(`span`,{className:`cell-copy cursor-pointer`,onClick:()=>{e.email&&e.email_password&&C(`${e.email}:${e.email_password}`)},title:e.email&&e.email_password?S(`tip.copyEmailLoginPass`):``,children:e.email&&e.email_password?w?`${e.email}:${T}`:`${e.email}:${e.email_password}`:`—`}),e.email&&e.email_password&&(0,L.jsx)(`button`,{onClick:e=>{e.stopPropagation(),g(!h)},className:`ml-1.5 text-gray-500 hover:text-gray-300 inline-flex align-middle`,title:S(w?`tip.show`:`tip.hide`),children:w?(0,L.jsx)(z,{size:14}):(0,L.jsx)(_e,{size:14})})]}),t.phone&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-gray-400 text-xs`,children:e.phone||`—`}),t.status&&(0,L.jsx)(`td`,{className:`px-3 py-2`,children:(0,L.jsx)(Ge,{status:e.status})}),t.ban&&(0,L.jsx)(`td`,{className:`px-3 py-2`,children:(0,L.jsx)(Ke,{status:e.ban_status})}),t.twofa&&(0,L.jsx)(`td`,{className:`px-3 py-2 whitespace-nowrap`,children:e.shared_secret?(0,L.jsxs)(`button`,{onClick:async()=>{try{let{code:t}=await D.generate2FA(e.shared_secret);await Ue(t),p(`success`,S(`twofa.copied`,{code:t}))}catch(e){p(`error`,S(`twofa.error`,{error:e instanceof Error?e.message:String(e)}))}},className:`text-accent hover:underline text-xs`,title:S(`tip.gen2fa`),children:[(0,L.jsx)(ve,{size:12,className:`inline mr-0.5`}),` `,S(`tip.code`)]}):(0,L.jsx)(`span`,{className:`text-gray-600 text-xs`,children:`—`})}),t.mafile&&(0,L.jsx)(`td`,{className:`px-3 py-2`,children:(0,L.jsx)(qe,{hasMafile:!!e.mafile_path})}),t.proxy&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs`,children:e.proxy?(0,L.jsx)(`span`,{className:`text-blue-400 cursor-pointer hover:underline`,onClick:()=>C(e.proxy),title:e.proxy,children:n||e.proxy}):`—`}),t.notes&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs max-w-[180px]`,children:_?(0,L.jsx)(`input`,{autoFocus:!0,className:`w-full bg-dark-600 border border-dark-500 rounded px-1.5 py-0.5 text-xs text-gray-200 outline-none focus:border-accent`,value:b,onChange:e=>x(e.target.value),onBlur:async()=>{if(v(!1),b!==(e.notes||``))try{await D.updateAccount(e.id,{notes:b}),p(`success`,S(`toast.noteSaved`)),ze.getState().loadAccounts()}catch{p(`error`,S(`toast.noteSaveError`))}},onKeyDown:t=>{t.key===`Enter`&&t.target.blur(),t.key===`Escape`&&(x(e.notes||``),v(!1))}}):(0,L.jsx)(`span`,{className:`cursor-pointer text-gray-400 hover:text-gray-200 truncate block`,onClick:()=>{x(e.notes||``),v(!0)},title:e.notes||S(`tip.addNote`),children:e.notes||`—`})}),t.actions&&(0,L.jsx)(`td`,{className:`px-3 py-2 whitespace-nowrap`,children:(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,L.jsx)(tt,{account:e,onAction:c,onToggleAutoAccept:l}),(0,L.jsx)(`button`,{onClick:()=>o(e.id),className:`text-gray-400 hover:text-accent`,title:S(`tip.edit`),children:(0,L.jsx)(xe,{size:14})}),(0,L.jsx)(`button`,{onClick:()=>s(e.id),className:`text-gray-400 hover:text-red-400`,title:S(`tip.delete`),children:(0,L.jsx)(Se,{size:14})}),e.auto_accept?(0,L.jsx)(`span`,{title:S(`tip.autoAcceptActive`),children:(0,L.jsx)(he,{size:14,className:`text-accent`})}):null]})})]})}var it=[`browser`,`profile`,`last_online`,`steam_id`,`login`,`password`,`login_pass`,`email`,`email_pass`,`email_login_pass`,`phone`,`status`,`ban`,`twofa`,`mafile`,`proxy`,`notes`,`actions`],at={browser:`col.browser`,profile:`col.profile`,last_online:`col.lastOnline`,steam_id:`col.steamId`,login:`col.login`,password:`col.password`,login_pass:`col.loginPass`,email:`col.email`,email_pass:`col.emailPass`,email_login_pass:`col.emailLoginPass`,phone:`col.phone`,status:`col.status`,ban:`col.ban`,twofa:`col.twofa`,mafile:`col.mafile`,proxy:`col.proxy`,notes:`col.notes`,actions:`col.actions`};function ot({accounts:e,processingIds:t,accountResults:n,accountSteps:r,onEdit:i,onDelete:a,onAction:o,onToggleAutoAccept:s,onOpenBrowser:c}){let l=ze(e=>e.selectedIds),u=ze(e=>e.setSelectedIds),d=A(e=>e.columnVisibility),f=I(),p=e.length>0&&e.every(e=>l.has(e.id)),m=()=>{if(p){let t=new Set(l);e.forEach(e=>t.delete(e.id)),u(t)}else{let t=new Set(l);e.forEach(e=>t.add(e.id)),u(t)}},h=it.filter(e=>d[e]),[g,_]=(0,y.useState)(100),v=(0,y.useRef)(null),[b,x]=(0,y.useState)(null),[S,C]=(0,y.useState)(`asc`),w=e=>{b===e?S===`asc`?C(`desc`):(x(null),C(`asc`)):(x(e),C(`asc`))},T=(0,y.useMemo)(()=>{if(!b)return e;let t=S===`asc`?1:-1,n=Symbol();return[...e].sort((e,r)=>{let i=e=>{if(!e||e===`—`)return n;if(e===`online`)return-1;let t=e.match(/^(\d+)([mhd])$/i);if(!t)return n;let r=parseInt(t[1],10);return t[2]===`m`?r:t[2]===`h`?r*60:r*1440},a=i(e.last_online),o=i(r.last_online);return a===n&&o===n?0:a===n?1:o===n?-1:a===o?0:(a{_(100)},[e,b,S]);let E=(0,y.useMemo)(()=>T.slice(0,g),[T,g]);(0,y.useEffect)(()=>{let e=v.current;if(!e)return;let t=new IntersectionObserver(e=>{e[0].isIntersecting&&_(e=>Math.min(e+100,T.length))},{rootMargin:`400px`});return t.observe(e),()=>t.disconnect()},[T.length,g]);let D=(0,y.useMemo)(()=>{let t=new Map,n=[];for(let t of e)t.proxy&&!n.includes(t.proxy)&&n.push(t.proxy);let r=new Map;n.forEach((e,t)=>r.set(e,t+1));for(let n of e)if(n.proxy){let e=r.get(n.proxy);t.set(n.id,e?f(`proxy.label`,{num:e}):n.proxy)}return t},[e]);return e.length?(0,L.jsx)(`div`,{className:`overflow-x-auto`,children:(0,L.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,L.jsx)(`thead`,{className:`sticky top-0 bg-dark-800 z-10`,children:(0,L.jsxs)(`tr`,{className:`text-left text-xs text-gray-500 border-b border-dark-600`,children:[(0,L.jsx)(`th`,{className:`px-3 py-2`,children:(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,L.jsx)(`input`,{type:`checkbox`,checked:p,onChange:m}),l.size>0&&(0,L.jsx)(`span`,{className:`text-accent font-medium`,children:l.size})]})}),(0,L.jsx)(`th`,{className:`w-5`}),h.map(e=>e===`last_online`?(0,L.jsxs)(`th`,{className:`px-3 py-2 cursor-pointer select-none hover:text-gray-300`,onClick:()=>w(`last_online`),children:[f(at[e]),b===`last_online`?S===`asc`?` ▲`:` ▼`:``]},e):(0,L.jsx)(`th`,{className:`px-3 py-2${e===`browser`?` text-center`:``}`,children:f(at[e])},e))]})}),(0,L.jsxs)(`tbody`,{children:[E.map(e=>(0,L.jsx)(rt,{account:e,visibleColumns:d,proxyLabel:D.get(e.id)??null,isProcessing:t.has(e.id),accountResult:n[String(e.id)],accountStep:r[String(e.id)],onEdit:i,onDelete:a,onAction:o,onToggleAutoAccept:s,onOpenBrowser:c},e.id)),g{m.current?.focus()},[]),(0,L.jsx)(`div`,{className:`confirm-overlay`,onMouseDown:n,children:(0,L.jsxs)(`div`,{className:`confirm-box max-w-md`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`h3`,{className:`text-lg font-semibold mb-4`,children:r(`modal.editAccount`)}),(0,L.jsxs)(`div`,{className:`space-y-3`,children:[(0,L.jsx)(`input`,{ref:m,value:i,onChange:e=>a(e.target.value),placeholder:r(`ph.login`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:o,onChange:e=>s(e.target.value),placeholder:r(`ph.password`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:c,onChange:e=>l(e.target.value),placeholder:`Email`,className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:u,onChange:e=>d(e.target.value),placeholder:r(`ph.proxy`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:f,onChange:e=>p(e.target.value),placeholder:r(`ph.notes`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`button`,{onClick:()=>{t(e.id,{login:i,password:o,email:c||void 0,proxy:u||void 0,notes:f||void 0})},className:`btn-primary w-full`,children:r(`btn.save`)})]})]})})}function ct({onClose:e,onImportDone:t}){let n=I(),[r,i]=(0,y.useState)(null),[a,o]=(0,y.useState)(``),[s,c]=(0,y.useState)(!1),l=(0,y.useRef)(null),u=A(e=>e.addToast),d=ze(e=>e.loadAccounts);return(0,L.jsx)(`div`,{className:`confirm-overlay`,onMouseDown:e,children:(0,L.jsxs)(`div`,{className:`confirm-box max-w-lg w-full`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`h3`,{className:`text-lg font-semibold mb-4`,children:n(`modal.importAccounts`)}),(0,L.jsxs)(`div`,{className:`text-sm text-gray-400 mb-3 space-y-1`,children:[(0,L.jsxs)(`p`,{className:`font-medium text-gray-300`,children:[n(`import.formats`),` `,(0,L.jsxs)(`span`,{className:`text-gray-500 font-normal`,children:[`(`,n(`import.delimiter`),` `,(0,L.jsx)(`code`,{className:`text-accent`,children:`:`}),` `,n(`import.or`),` `,(0,L.jsx)(`code`,{className:`text-accent`,children:`|`}),`)`]})]}),(0,L.jsxs)(`p`,{className:`font-mono text-xs`,children:[`login:pass:`,`{`,`mafile`,`}`]}),(0,L.jsxs)(`p`,{className:`font-mono text-xs`,children:[`login:pass:email:email_pass:`,`{`,`mafile`,`}`]}),(0,L.jsxs)(`p`,{className:`font-mono text-xs`,children:[`login:pass:email:email_pass:`,`{`,`mafile`,`}`,`:notes`]}),(0,L.jsx)(`p`,{className:`font-mono text-xs`,children:`login:pass:email:email_pass`}),(0,L.jsx)(`p`,{className:`font-mono text-xs`,children:`login:pass:email:email_pass:notes`})]}),(0,L.jsxs)(`div`,{onDragOver:e=>e.preventDefault(),onDrop:e=>{e.preventDefault();let t=e.dataTransfer.files[0];t&&i(t)},onClick:()=>l.current?.click(),className:`border-2 border-dashed border-dark-500 rounded-lg p-6 mb-3 text-center cursor-pointer transition-colors hover:border-accent`,children:[(0,L.jsx)(ce,{size:32,className:`mx-auto mb-2 text-gray-500`}),(0,L.jsx)(`p`,{className:`text-sm text-gray-400`,children:r?n(`import.selected`,{name:r.name}):n(`import.dragTxt`)})]}),(0,L.jsx)(`input`,{ref:l,type:`file`,accept:`.txt`,className:`hidden`,onChange:e=>{let t=e.target.files?.[0];t&&i(t)}}),(0,L.jsx)(`button`,{onClick:async()=>{if(r){c(!0);try{let e=new Set(ze.getState().accounts.map(e=>e.id)),i=await D.importAccounts(r);o(n(`toast.importResult`,{imported:i.imported,skipped:i.skipped})),u(`success`,`${i.imported} ok, ${i.skipped} skip`),await d();let a=ze.getState().accounts.map(e=>e.id).filter(t=>!e.has(t));t?.(a)}catch(e){o(e instanceof Error?e.message:n(`misc.errorStr`))}finally{c(!1)}}},disabled:!r||s,className:`btn-primary w-full`,children:n(s?`import.uploading`:`import.importBtn`)}),a&&(0,L.jsx)(`p`,{className:`mt-3 text-sm text-gray-300`,children:a})]})})}function lt({onSave:e,onClose:t}){let n=I(),r=A(e=>e.addToast),[i,a]=(0,y.useState)(``),[o,s]=(0,y.useState)(``),[c,l]=(0,y.useState)(``),[u,d]=(0,y.useState)(``),[f,p]=(0,y.useState)(``),[m,h]=(0,y.useState)(``),[g,_]=(0,y.useState)(null),[v,b]=(0,y.useState)(!1),x=(0,y.useRef)(null),S=e=>{let t=e.includes(`|`)?`|`:`:`,n=e.split(t);n.length>=2?(a(n[0]),s(n[1]),n.length>=3&&l(n[2]),n.length>=4&&d(n[3])):a(e)};return(0,L.jsx)(`div`,{className:`confirm-overlay`,onMouseDown:t,children:(0,L.jsxs)(`div`,{className:`confirm-box max-w-md`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`h3`,{className:`text-lg font-semibold mb-4`,children:n(`modal.addAccount`)}),(0,L.jsxs)(`div`,{className:`space-y-3`,children:[(0,L.jsx)(`input`,{autoFocus:!0,value:i,onChange:e=>a(e.target.value),onPaste:e=>{let t=e.clipboardData.getData(`text`).trim();(t.includes(`:`)||t.includes(`|`))&&(e.preventDefault(),S(t))},placeholder:n(`ph.login`)+` (login:pass)`,className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:o,onChange:e=>s(e.target.value),placeholder:n(`ph.password`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsxs)(`div`,{className:`grid grid-cols-2 gap-2`,children:[(0,L.jsx)(`input`,{value:c,onChange:e=>l(e.target.value),placeholder:`Email`,className:`bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:u,onChange:e=>d(e.target.value),placeholder:n(`ph.emailPassword`),className:`bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`})]}),(0,L.jsxs)(`div`,{className:`grid grid-cols-2 gap-2`,children:[(0,L.jsx)(`input`,{value:f,onChange:e=>p(e.target.value),placeholder:n(`ph.proxyOptional`),className:`bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:m,onChange:e=>h(e.target.value),placeholder:n(`ph.notesOptional`),className:`bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`})]}),(0,L.jsxs)(`div`,{onClick:()=>x.current?.click(),className:`border border-dashed border-dark-500 rounded p-3 text-center cursor-pointer transition-colors hover:border-accent flex items-center justify-center gap-2`,children:[(0,L.jsx)(ce,{size:14,className:`text-gray-500`}),(0,L.jsx)(`span`,{className:`text-xs text-gray-400`,children:g?g.name:n(`import.attachMafile`)}),g&&(0,L.jsx)(`button`,{onClick:e=>{e.stopPropagation(),_(null)},className:`text-xs text-red-400 hover:text-red-300 ml-1`,children:`✕`})]}),(0,L.jsx)(`input`,{ref:x,type:`file`,accept:`.mafile`,className:`hidden`,onChange:e=>{let t=e.target.files?.[0];t&&_(t)}}),(0,L.jsx)(`button`,{onClick:async()=>{if(!(!i||!o)){b(!0);try{e({login:i,password:o,email:c||void 0,email_password:u||void 0,proxy:f||void 0,notes:m||void 0}),g&&await D.uploadMafiles([g])}catch(e){r(`error`,e instanceof Error?e.message:String(e))}finally{b(!1)}}},disabled:!i||!o||v,className:`btn-primary w-full`,children:n(v?`import.uploading`:`btn.add`)})]})]})})}function ut({message:e,onConfirm:t,onCancel:n}){let r=I();return(0,L.jsx)(`div`,{className:`confirm-overlay`,onMouseDown:n,children:(0,L.jsxs)(`div`,{className:`confirm-box`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`p`,{className:`text-sm text-gray-300 mb-4`,children:e}),(0,L.jsxs)(`div`,{className:`flex gap-2`,children:[(0,L.jsx)(`button`,{onClick:t,className:`btn-primary flex-1`,children:r(`confirm.yes`)}),(0,L.jsx)(`button`,{onClick:n,className:`btn-secondary flex-1`,children:r(`btn.cancel`)})]})]})})}var dt={browser:`col.browser`,profile:`col.profile`,last_online:`col.lastOnline`,steam_id:`col.steamId`,login:`col.login`,password:`col.password`,login_pass:`col.loginPass`,email:`col.email`,email_pass:`col.emailPass`,email_login_pass:`col.emailLoginPass`,phone:`col.phone`,status:`col.status`,ban:`col.ban`,twofa:`col.twofa`,mafile:`col.mafile`,proxy:`col.proxy`,notes:`col.notes`,actions:`col.actions`};function ft(){let[e,t]=(0,y.useState)(!1),n=A(e=>e.columnVisibility),r=A(e=>e.toggleColumn),i=(0,y.useRef)(null),a=I();return(0,y.useEffect)(()=>{let e=e=>{i.current&&!i.current.contains(e.target)&&t(!1)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[]),(0,L.jsxs)(`div`,{className:`relative`,ref:i,children:[(0,L.jsx)(`button`,{onClick:()=>t(!e),className:`btn-secondary text-sm px-2 py-2`,title:a(`tip.columnSettings`),children:(0,L.jsx)(be,{size:14})}),e&&(0,L.jsx)(`div`,{className:`absolute right-0 top-full mt-1 bg-dark-700 border border-dark-600 rounded-lg shadow-xl z-50 p-2 min-w-[160px]`,children:Object.keys(dt).map(e=>(0,L.jsxs)(`label`,{className:`flex items-center gap-2 px-2 py-1 hover:bg-dark-600 rounded cursor-pointer text-sm`,children:[(0,L.jsx)(`input`,{type:`checkbox`,checked:n[e],onChange:()=>r(e)}),a(dt[e])]},e))})]})}function pt({onClose:e,onImportDone:t}){let n=I(),[r,i]=(0,y.useState)(null),[a,o]=(0,y.useState)(``),[s,c]=(0,y.useState)(!1),l=(0,y.useRef)(null),u=A(e=>e.addToast),d=Ve(e=>e.loadAccounts);return(0,L.jsx)(`div`,{className:`confirm-overlay`,onMouseDown:e,children:(0,L.jsxs)(`div`,{className:`confirm-box max-w-lg w-full`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`h3`,{className:`text-lg font-semibold mb-4`,children:n(`modal.importAccounts`)}),(0,L.jsxs)(`div`,{className:`text-sm text-gray-400 mb-3 space-y-1`,children:[(0,L.jsx)(`p`,{className:`font-medium text-gray-300`,children:n(`import.formatsColon`)}),(0,L.jsx)(`p`,{className:`font-mono text-xs`,children:`login:pass`}),(0,L.jsx)(`p`,{className:`font-mono text-xs`,children:`login|pass`}),(0,L.jsx)(`p`,{className:`font-mono text-xs`,children:`CSV: login,password,steam_id,ban,prime,trophy,behavior,license`}),(0,L.jsx)(`p`,{className:`text-xs text-yellow-500/80 mt-1`,children:`⚠ Mafile-файлы и JSON не принимаются. Только log:pass / log|pass.`})]}),(0,L.jsxs)(`div`,{onDragOver:e=>e.preventDefault(),onDrop:e=>{e.preventDefault();let t=e.dataTransfer.files[0];t&&i(t)},onClick:()=>l.current?.click(),className:`border-2 border-dashed border-dark-500 rounded-lg p-6 mb-3 text-center cursor-pointer transition-colors hover:border-accent`,children:[(0,L.jsx)(ce,{size:32,className:`mx-auto mb-2 text-gray-500`}),(0,L.jsx)(`p`,{className:`text-sm text-gray-400`,children:r?n(`import.selected`,{name:r.name}):n(`import.dragTxtCsv`)})]}),(0,L.jsx)(`input`,{ref:l,type:`file`,accept:`.txt,.csv`,className:`hidden`,onChange:e=>{let t=e.target.files?.[0];t&&i(t)}}),(0,L.jsx)(`button`,{onClick:async()=>{if(r){c(!0);try{let e=(await r.text()).split(` +`).map(e=>e.trim()).filter(Boolean);if(!e.length){o(n(`toast.fileEmpty`)),c(!1);return}let i=new Set(Ve.getState().accounts.map(e=>e.id)),a=await D.importLogpass(e);o(n(`toast.importResult`,{imported:a.imported,skipped:a.skipped})),u(`success`,`${a.imported} ok, ${a.skipped} skip`),await d();let s=Ve.getState().accounts.map(e=>e.id).filter(e=>!i.has(e));t?.(s)}catch(e){o(e instanceof Error?e.message:n(`misc.errorStr`))}finally{c(!1)}}},disabled:!r||s,className:`btn-primary w-full`,children:n(s?`import.uploading`:`import.importBtn`)}),a&&(0,L.jsx)(`p`,{className:`mt-3 text-sm text-gray-300`,children:a})]})})}function mt({onClose:e}){let t=I(),[n,r]=(0,y.useState)(``),[i,a]=(0,y.useState)(``),[o,s]=(0,y.useState)(``),c=Ve(e=>e.loadAccounts);return(0,L.jsx)(`div`,{className:`confirm-overlay`,onMouseDown:e,children:(0,L.jsxs)(`div`,{className:`confirm-box max-w-md`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`h3`,{className:`text-lg font-semibold mb-4`,children:t(`modal.addAccount`)}),(0,L.jsxs)(`div`,{className:`space-y-3`,children:[(0,L.jsx)(`input`,{autoFocus:!0,value:n,onChange:e=>r(e.target.value),placeholder:t(`ph.login`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:i,onChange:e=>a(e.target.value),placeholder:t(`ph.password`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:o,onChange:e=>s(e.target.value),placeholder:t(`ph.proxyOptional`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`button`,{onClick:async()=>{if(!n||!i)return;let t={login:n,password:i,proxy:o||void 0};await D.createLogpassAccount(t),await c(),e()},className:`btn-primary w-full`,children:t(`btn.add`)})]})]})})}function ht({account:e,onClose:t}){let n=I(),[r,i]=(0,y.useState)(e.login),[a,o]=(0,y.useState)(e.password),[s,c]=(0,y.useState)(e.proxy??``),[l,u]=(0,y.useState)(e.notes??``),d=Ve(e=>e.loadAccounts);return(0,L.jsx)(`div`,{className:`confirm-overlay`,onMouseDown:t,children:(0,L.jsxs)(`div`,{className:`confirm-box max-w-md`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`h3`,{className:`text-lg font-semibold mb-4`,children:n(`modal.editAccount`)}),(0,L.jsxs)(`div`,{className:`space-y-3`,children:[(0,L.jsx)(`input`,{autoFocus:!0,value:r,onChange:e=>i(e.target.value),placeholder:n(`ph.login`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:a,onChange:e=>o(e.target.value),placeholder:n(`ph.password`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:s,onChange:e=>c(e.target.value),placeholder:n(`ph.proxyOptional`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:l,onChange:e=>u(e.target.value),placeholder:n(`ph.notes`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsxs)(`div`,{className:`flex gap-2`,children:[(0,L.jsx)(`button`,{onClick:async()=>{!r||!a||(await D.updateLogpassAccount(e.id,{login:r,password:a,proxy:s||void 0,notes:l||void 0}),await d(),t())},className:`btn-primary flex-1`,children:n(`btn.save`)}),(0,L.jsx)(`button`,{onClick:t,className:`btn-secondary flex-1`,children:n(`btn.cancel`)})]})]})]})})}var gt={browser:`col.browser`,profile:`col.profile`,last_online:`col.lastOnline`,steam_id:`col.steamId`,login:`col.login`,password:`col.password`,login_pass:`col.loginPass`,status:`col.status`,ban:`col.ban`,prime:`col.prime`,trophy:`col.trophy`,behavior:`col.behavior`,license:`col.license`,proxy:`col.proxy`,notes:`col.notes`,actions:`col.actions`};function _t(){let[e,t]=(0,y.useState)(!1),n=A(e=>e.logpassColumnVisibility),r=A(e=>e.toggleLogpassColumn),i=(0,y.useRef)(null),a=I();return(0,y.useEffect)(()=>{let e=e=>{i.current&&!i.current.contains(e.target)&&t(!1)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[]),(0,L.jsxs)(`div`,{className:`relative`,ref:i,children:[(0,L.jsx)(`button`,{onClick:()=>t(!e),className:`btn-secondary text-sm px-2 py-2`,title:a(`tip.columnSettings`),children:(0,L.jsx)(be,{size:14})}),e&&(0,L.jsx)(`div`,{className:`absolute right-0 top-full mt-1 bg-dark-700 border border-dark-600 rounded-lg shadow-xl z-50 p-2 min-w-[160px]`,children:Object.keys(gt).map(e=>(0,L.jsxs)(`label`,{className:`flex items-center gap-2 px-2 py-1 hover:bg-dark-600 rounded cursor-pointer text-sm`,children:[(0,L.jsx)(`input`,{type:`checkbox`,checked:n[e],onChange:()=>r(e)}),a(gt[e])]},e))})]})}function vt(e){if(!e)return null;if(typeof e==`string`)try{return JSON.parse(e)}catch{return null}return e}function yt(){let e=Ve(e=>e.accounts),t=Ve(e=>e.selectedIds),n=Ve(e=>e.loadAccounts),r=Ve(e=>e.clearSelection),i=Ve(e=>e.setSelectedIds),a=A(e=>e.addToast),o=A(e=>e.autoProxyOnImportLogpass),s=A(e=>e.autoValidateOnImportLogpass),c=A(e=>e.logpassColumnVisibility),l=I(),[u,d]=(0,y.useState)(``),[f,p]=(0,y.useState)(!1),[m,h]=(0,y.useState)(!1),[g,_]=(0,y.useState)(null),[v,b]=(0,y.useState)({open:!1,message:``,onConfirm:()=>{}}),[x,S]=(0,y.useState)(new Set),[C,w]=(0,y.useState)({}),[T,E]=(0,y.useState)({}),[O,k]=(0,y.useState)(null),[ee,te]=(0,y.useState)(100),[j,M]=(0,y.useState)(null),[N,P]=(0,y.useState)(`asc`),F=e=>{j===e?N===`asc`?P(`desc`):(M(null),P(`asc`)):(M(e),P(`asc`))},ne=(0,y.useRef)(null);(0,y.useEffect)(()=>{n()},[n]);let re=(e,t)=>b({open:!0,message:e,onConfirm:t}),ie=(0,y.useCallback)(e=>{let t=new EventSource(`/api/tasks/${e}/stream`);t.onmessage=e=>{try{let r=JSON.parse(e.data);if(k(r),r.account_results){let e=vt(r.account_results);e&&w(e)}r.account_steps&&E(r.account_steps),r.status!==`running`&&(t.close(),S(new Set),k(null),n())}catch{}},t.onerror=()=>t.close()},[n]),ae=(0,y.useCallback)(async()=>{let e=[...t];if(e.length){r(),S(new Set(e)),w({}),E({});try{let{task_id:t}=await D.validateLogpass(e);k({id:t,type:`logpass_validate`,status:`running`,progress:0,total:e.length,result:null,error:null,created_at:``,updated_at:``}),ie(t)}catch(e){S(new Set),a(`error`,String(e))}}},[t,r,ie,a]),oe=(0,y.useCallback)(async e=>{S(new Set([e])),w(t=>{let n={...t};return delete n[String(e)],n}),E(t=>{let n={...t};return delete n[String(e)],n});try{let{task_id:t}=await D.validateLogpass([e]);k({id:t,type:`logpass_validate`,status:`running`,progress:0,total:1,result:null,error:null,created_at:``,updated_at:``}),ie(t)}catch(e){S(new Set),a(`error`,String(e))}},[ie,a]),R=(0,y.useCallback)(async()=>{let e=[...t];if(e.length){r(),S(new Set(e)),w({}),E({});try{let{task_id:t}=await D.fullParseLogpass(e);k({id:t,type:`logpass_full_parse`,status:`running`,progress:0,total:e.length,result:null,error:null,created_at:``,updated_at:``}),ie(t)}catch(e){S(new Set),a(`error`,String(e))}}},[t,r,ie,a]),ce=()=>{let e=[...t];e.length&&re(l(`confirm.deleteLogpassSelected`,{count:e.length}),async()=>{await D.deleteLogpassBulk(e),r(),n()})},ue=()=>{re(l(`confirm.deleteLogpassAll`,{count:e.length}),async()=>{await D.deleteLogpassBulk(e.map(e=>e.id)),r(),n()})},de=()=>{re(l(`confirm.assignProxies`),async()=>{try{a(`success`,l(`toast.proxiesAssignedShort`,{count:(await D.assignLogpassProxies()).assigned})),n()}catch(e){a(`error`,e instanceof Error?e.message:String(e))}})},fe=()=>{re(l(`confirm.reassignProxiesAll`),async()=>{try{a(`success`,l(`toast.proxiesReassignedShort`,{count:(await D.reassignLogpassProxies()).assigned})),n()}catch(e){a(`error`,e instanceof Error?e.message:String(e))}})},pe=()=>{re(l(`confirm.clearProxies`),async()=>{try{a(`success`,l(`toast.proxiesClearedShort`,{count:(await D.clearLogpassProxies()).cleared})),n()}catch(e){a(`error`,e instanceof Error?e.message:String(e))}})},z=(0,y.useMemo)(()=>{if(!u.trim())return e;let t=u.trim(),n=t.match(/^lvl\s*(>=|<=|>|<|=)\s*(\d+)$/i);if(n){let t=n[1],r=parseInt(n[2],10);return e.filter(e=>{let n=e.steam_level;return n==null?!1:t===`>`?n>r:t===`>=`?n>=r:t===`<`?ne.login.toLowerCase().includes(r)||(e.steam_id??``).toLowerCase().includes(r)||(e.nickname??``).toLowerCase().includes(r)||(e.notes??``).toLowerCase().includes(r)||(e.license??``).toLowerCase().includes(r))},[e,u]),_e=z.length>0&&z.every(e=>t.has(e.id)),ve=()=>{if(_e){let e=new Set(t);z.forEach(t=>e.delete(t.id)),i(e)}else{let e=new Set(t);z.forEach(t=>e.add(t.id)),i(e)}},ye=(0,y.useMemo)(()=>{if(!j)return z;let e=N===`asc`?1:-1,t=Symbol();return[...z].sort((n,r)=>{let i=t,a=t;if(j===`last_online`){let e=e=>{if(!e||e===`—`)return t;if(e===`online`)return-1;let n=e.match(/^(\d+)([mhd])$/i);if(!n)return t;let r=parseInt(n[1],10);return n[2]===`m`?r:n[2]===`h`?r*60:r*1440};i=e(n.last_online),a=e(r.last_online)}else j===`prime`?(i=n.prime===`Enabled`?0:n.prime===`Disabled`?1:t,a=r.prime===`Enabled`?0:r.prime===`Disabled`?1:t):j===`trophy`?(i=n.trophy!=null&&n.trophy!==`—`?parseInt(n.trophy,10)||0:t,a=r.trophy!=null&&r.trophy!==`—`?parseInt(r.trophy,10)||0:t):j===`behavior`&&(i=n.behavior!=null&&n.behavior!==`—`?parseInt(n.behavior,10)||0:t,a=r.behavior!=null&&r.behavior!==`—`?parseInt(r.behavior,10)||0:t);return i===t&&a===t?0:i===t?1:a===t?-1:i===a?0:(i{te(100)},[u,j,N]);let be=(0,y.useMemo)(()=>ye.slice(0,ee),[ye,ee]);(0,y.useEffect)(()=>{let e=ne.current;if(!e)return;let t=new IntersectionObserver(e=>{e[0].isIntersecting&&te(e=>Math.min(e+100,ye.length))},{rootMargin:`400px`});return t.observe(e),()=>t.disconnect()},[ye.length,ee]);let xe=(0,y.useMemo)(()=>{let t=new Map,n=[];for(let t of e)t.proxy&&!n.includes(t.proxy)&&n.push(t.proxy);let r=new Map;n.forEach((e,t)=>r.set(e,t+1));for(let n of e)n.proxy&&t.set(n.id,l(`proxy.label`,{num:r.get(n.proxy)??0}));return t},[e]),Se=async e=>{try{let t=await D.openLogpassBrowser(e);t.status===`revalidating`?(a(`warn`,l(`toast.cookiesExpiredRevalidating`)),t.task_id&&(S(new Set([e])),k({id:t.task_id,type:`logpass_validate`,status:`running`,progress:0,total:1,result:null,error:null,created_at:``,updated_at:``}),ie(t.task_id))):a(`success`,l(`toast.browserOpening`))}catch(e){a(`error`,e instanceof Error?e.message:String(e))}},Ce=(0,y.useCallback)(async e=>{let t=o,r=s;try{let e=await D.getValidationSettings();t=e.auto_proxy_on_import_logpass,r=e.auto_validate_on_import_logpass}catch{}if(t)try{a(`success`,l(`toast.proxiesAssignedShort`,{count:(await D.assignLogpassProxies()).assigned})),await n()}catch{}if(r&&e.length)try{let{task_id:t}=await D.validateLogpass(e);k({id:t,type:`logpass_validate`,status:`running`,progress:0,total:e.length,result:null,error:null,created_at:``,updated_at:``}),S(new Set(e)),ie(t)}catch(e){S(new Set),a(`error`,e instanceof Error?e.message:String(e))}},[o,s,a,n,ie,l]);return(0,L.jsxs)(`div`,{className:`flex flex-col gap-4 h-full min-h-0`,children:[(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-lg px-3 py-2 flex flex-wrap items-center gap-2 shrink-0`,children:[(0,L.jsxs)(`button`,{onClick:()=>p(!0),className:`btn-primary`,children:[(0,L.jsx)(se,{size:14,className:`inline mr-1`}),l(`btn.import`)]}),(0,L.jsxs)(`button`,{onClick:()=>h(!0),className:`btn-secondary`,children:[(0,L.jsx)(le,{size:14,className:`inline mr-1`}),l(`btn.add`)]}),O&&(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(`div`,{className:`h-5 border-l border-dark-500`}),(0,L.jsxs)(`div`,{className:`flex items-center gap-2 min-w-0`,children:[(0,L.jsx)(`span`,{className:`text-xs text-gray-400 whitespace-nowrap`,children:l(`task.validate`)}),(0,L.jsx)(`div`,{className:`w-28 bg-dark-600 rounded-full h-2.5 shrink-0`,children:(0,L.jsx)(`div`,{className:`h-2.5 rounded-full transition-all duration-300 ${O.status===`completed`?`bg-green-500`:O.status===`failed`?`bg-red-500`:`bg-accent`}`,style:{width:`${O.total>1?O.total>0?Math.round(O.progress/O.total*100):0:O.total_steps?Math.round((O.step??0)/O.total_steps*100):0}%`}})}),(0,L.jsxs)(`span`,{className:`text-xs text-gray-500 whitespace-nowrap`,children:[O.total>1?`${O.progress}/${O.total}${O.active_count?` (${O.active_count})`:``}`:O.step_label||`${O.progress}/${O.total}`,O.total>1?` (${O.total>0?Math.round(O.progress/O.total*100):0}%)`:O.total_steps?` (${O.step}/${O.total_steps})`:``]}),O.status===`completed`&&(0,L.jsx)(ke,{size:14,className:`text-green-400`}),O.status===`failed`&&(0,L.jsx)(`span`,{title:O.error||``,children:(0,L.jsx)(Oe,{size:14,className:`text-red-400`})})]})]}),(0,L.jsxs)(`div`,{className:`ml-auto flex items-center gap-2`,children:[(0,L.jsx)(_t,{}),(0,L.jsx)(`div`,{className:`h-5 border-l border-dark-500`}),(0,L.jsx)(`button`,{onClick:ce,className:`btn-danger-outline text-xs`,children:l(`btn.deleteSelected`)}),(0,L.jsx)(`button`,{onClick:ue,className:`btn-danger text-xs`,children:l(`btn.deleteAll`)})]})]}),(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-lg overflow-hidden flex-1 min-h-0 flex flex-col`,children:[(0,L.jsxs)(`div`,{className:`px-3 py-2 flex items-center gap-2 border-b border-dark-600 shrink-0 bg-dark-800`,children:[(0,L.jsxs)(`button`,{onClick:ae,disabled:t.size===0||x.size>0,className:`btn-accent text-sm disabled:opacity-40`,children:[(0,L.jsx)(De,{size:12,className:`inline mr-1`}),l(`btn.validate`)]}),(0,L.jsxs)(`button`,{onClick:R,disabled:t.size===0||x.size>0,className:`btn-secondary text-sm disabled:opacity-40`,children:[(0,L.jsx)(De,{size:12,className:`inline mr-1`}),l(`btn.fullParse`)]}),O&&O.status===`running`&&(0,L.jsxs)(`button`,{onClick:async()=>{try{await D.cancelTask(O.id)}catch{}},className:`btn-danger text-sm`,children:[(0,L.jsx)(Oe,{size:12,className:`inline mr-1`}),l(`btn.cancel`)]}),(0,L.jsx)(`div`,{className:`h-5 border-l border-dark-500`}),(0,L.jsxs)(`button`,{onClick:de,className:`btn-secondary text-sm`,children:[(0,L.jsx)(me,{size:14,className:`inline mr-1`}),l(`btn.assignProxies`)]}),(0,L.jsxs)(`button`,{onClick:fe,className:`btn-secondary text-sm`,children:[(0,L.jsx)(he,{size:14,className:`inline mr-1`}),l(`btn.reassign`)]}),(0,L.jsxs)(`button`,{onClick:pe,className:`btn-danger-outline text-sm`,children:[(0,L.jsx)(ge,{size:14,className:`inline mr-1`}),l(`btn.clearProxies`)]}),(0,L.jsx)(`div`,{className:`ml-auto`,children:(0,L.jsx)(`input`,{type:`text`,value:u,onChange:e=>d(e.target.value),placeholder:l(`ph.searchLogpass`),className:`bg-dark-700 border border-dark-600 rounded px-2 py-1.5 text-xs w-80 placeholder:text-gray-500 outline-none focus:border-accent`})})]}),(0,L.jsx)(`div`,{className:`overflow-auto flex-1 min-h-0`,children:(0,L.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,L.jsx)(`thead`,{className:`sticky top-0 bg-dark-800 z-10`,children:(0,L.jsxs)(`tr`,{className:`text-left text-xs text-gray-500 border-b border-dark-600`,children:[(0,L.jsx)(`th`,{className:`px-3 py-2`,children:(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,L.jsx)(`input`,{type:`checkbox`,checked:_e,onChange:ve}),t.size>0&&(0,L.jsx)(`span`,{className:`text-accent font-medium`,children:t.size})]})}),(0,L.jsx)(`th`,{className:`w-5`}),c.browser&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:l(`col.browser`)}),c.profile&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:l(`col.profile`)}),c.last_online&&(0,L.jsxs)(`th`,{className:`px-3 py-2 cursor-pointer select-none hover:text-gray-300`,onClick:()=>F(`last_online`),children:[l(`col.lastOnline`),j===`last_online`?N===`asc`?` ▲`:` ▼`:``]}),c.steam_id&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:`Steam ID`}),c.login&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:l(`col.login`)}),c.password&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:l(`col.password`)}),c.login_pass&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:`Login:Pass`}),c.status&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:l(`col.status`)}),c.ban&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:l(`col.ban`)}),c.prime&&(0,L.jsxs)(`th`,{className:`px-3 py-2 cursor-pointer select-none hover:text-gray-300`,onClick:()=>F(`prime`),children:[`Prime`,j===`prime`?N===`asc`?` ▲`:` ▼`:``]}),c.trophy&&(0,L.jsxs)(`th`,{className:`px-3 py-2 cursor-pointer select-none hover:text-gray-300`,onClick:()=>F(`trophy`),children:[`Trophy`,j===`trophy`?N===`asc`?` ▲`:` ▼`:``]}),c.behavior&&(0,L.jsxs)(`th`,{className:`px-3 py-2 cursor-pointer select-none hover:text-gray-300`,onClick:()=>F(`behavior`),children:[`Behavior`,j===`behavior`?N===`asc`?` ▲`:` ▼`:``]}),c.license&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:l(`col.license`)}),c.proxy&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:l(`col.proxy`)}),c.notes&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:l(`col.notes`)}),c.actions&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:l(`col.actions`)})]})}),(0,L.jsx)(`tbody`,{children:z.length===0?(0,L.jsx)(`tr`,{children:(0,L.jsx)(`td`,{colSpan:16,className:`text-center py-12 text-gray-500`,children:l(`empty.logpass`)})}):(0,L.jsxs)(L.Fragment,{children:[be.map(e=>(0,L.jsx)(bt,{account:e,cols:c,isProcessing:x.has(e.id),accountResult:C[String(e.id)],accountStep:T[String(e.id)],proxyLabel:xe.get(e.id)??null,onDelete:t=>re(l(`confirm.deleteLogpass`,{name:e.login}),async()=>{await D.deleteLogpassAccount(t),n()}),onOpenBrowser:Se,onValidate:oe,onEdit:e=>_(e)},e.id)),ee{let t=e.find(e=>e.id===g);return t?(0,L.jsx)(ht,{account:t,onClose:()=>_(null)}):null})(),f&&(0,L.jsx)(pt,{onClose:()=>p(!1),onImportDone:Ce}),m&&(0,L.jsx)(mt,{onClose:()=>h(!1)}),v.open&&(0,L.jsx)(ut,{message:v.message,onConfirm:()=>{v.onConfirm(),b(e=>({...e,open:!1}))},onCancel:()=>b(e=>({...e,open:!1}))})]})}function bt({account:e,cols:t,isProcessing:n,accountResult:r,accountStep:i,proxyLabel:a,onDelete:o,onOpenBrowser:s,onValidate:c,onEdit:l}){let u=Ve(e=>e.selectedIds),d=Ve(e=>e.toggleSelect),f=A(e=>e.addToast),p=A(e=>e.hidePasswords),m=Ve(e=>e.loadAccounts),[h,g]=(0,y.useState)(!1),[_,v]=(0,y.useState)(!1),[b,x]=(0,y.useState)(e.notes||``),[S,C]=(0,y.useState)(!1),w=I(),T=p&&!h,E=`••••••••`,O=async e=>{let t=await Ue(e);f(t?`success`:`error`,w(t?`toast.copied`:`toast.copyFailed`))};return(0,L.jsxs)(`tr`,{className:`hover:bg-dark-700/50 transition`,children:[(0,L.jsx)(`td`,{className:`px-3 py-2`,children:(0,L.jsx)(`input`,{type:`checkbox`,checked:u.has(e.id),onChange:()=>d(e.id)})}),(0,L.jsx)(`td`,{className:`px-1 py-2 w-5`,children:n?(0,L.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,L.jsx)(`div`,{className:`w-4 h-4 border-2 border-accent border-t-transparent rounded-full animate-spin shrink-0`}),i&&(0,L.jsxs)(`span`,{className:`text-[10px] text-gray-500 whitespace-nowrap`,children:[`[`,i.step,`/`,i.total,`]`]})]}):r?.status===`ok`?(0,L.jsx)(ue,{size:16,className:`text-gray-400`}):r?.status===`error`?(0,L.jsx)(`span`,{title:r.error,children:(0,L.jsx)(fe,{size:16,className:`text-red-400`})}):null}),t.browser&&(0,L.jsx)(`td`,{className:`px-3 py-2 whitespace-nowrap text-center`,children:e.has_cookies?(0,L.jsx)(`button`,{onClick:()=>s(e.id),className:`px-2 py-0.5 text-xs font-medium rounded bg-blue-600/20 text-blue-400 border border-blue-500/30 hover:bg-blue-600/40 hover:text-blue-300 active:scale-95 transition`,title:w(`tip.openBrowser`),children:w(`col.browser`)}):(0,L.jsx)(`span`,{className:`text-gray-600 text-xs`,children:`—`})}),t.profile&&(0,L.jsx)(`td`,{className:`px-3 py-2 whitespace-nowrap`,children:(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[e.avatar_url&&(0,L.jsx)(`img`,{src:e.avatar_url,className:`avatar-sm`,alt:``}),(0,L.jsx)(`span`,{className:`text-xs`,children:e.nickname||`—`}),e.steam_level!=null&&(0,L.jsx)(nt,{level:e.steam_level})]})}),t.last_online&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs text-gray-400 whitespace-nowrap`,children:e.last_online||`—`}),t.steam_id&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs`,children:e.steam_id?(0,L.jsx)(`a`,{href:`https://steamcommunity.com/profiles/${encodeURIComponent(e.steam_id)}/`,target:`_blank`,rel:`noopener noreferrer`,className:`text-blue-400 hover:text-blue-300 hover:underline`,children:e.steam_id}):`—`}),t.login&&(0,L.jsx)(`td`,{className:`px-3 py-2 font-medium`,children:e.login}),t.password&&(0,L.jsxs)(`td`,{className:`px-3 py-2 text-gray-400 select-none whitespace-nowrap`,children:[(0,L.jsx)(`span`,{className:`cursor-pointer`,onClick:()=>O(e.password),title:w(`tip.copyPassword`),children:T?E:e.password}),(0,L.jsx)(`button`,{onClick:e=>{e.stopPropagation(),g(!h)},className:`ml-1.5 text-gray-500 hover:text-gray-300 inline-flex align-middle`,title:w(T?`tip.show`:`tip.hide`),children:T?(0,L.jsx)(z,{size:14}):(0,L.jsx)(_e,{size:14})})]}),t.login_pass&&(0,L.jsxs)(`td`,{className:`px-3 py-2 text-gray-400 text-xs select-none whitespace-nowrap`,children:[(0,L.jsx)(`span`,{className:`cursor-pointer`,onClick:()=>O(`${e.login}:${e.password}`),title:w(`tip.copyLoginPass`),children:T?`${e.login}:${E}`:`${e.login}:${e.password}`}),(0,L.jsx)(`button`,{onClick:e=>{e.stopPropagation(),g(!h)},className:`ml-1.5 text-gray-500 hover:text-gray-300 inline-flex align-middle`,title:w(T?`tip.show`:`tip.hide`),children:T?(0,L.jsx)(z,{size:14}):(0,L.jsx)(_e,{size:14})})]}),t.status&&(0,L.jsx)(`td`,{className:`px-3 py-2`,children:(0,L.jsx)(Ge,{status:e.status})}),t.ban&&(0,L.jsx)(`td`,{className:`px-3 py-2`,children:(0,L.jsx)(Ke,{status:e.ban_status})}),t.prime&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs text-gray-400`,children:e.prime??`—`}),t.trophy&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs text-gray-400`,children:e.trophy??`—`}),t.behavior&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs text-gray-400`,children:e.behavior??`—`}),t.license&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs text-gray-400 cursor-pointer select-none ${S?`max-w-none whitespace-normal break-words`:`truncate max-w-[200px] whitespace-nowrap`}`,title:S?void 0:e.license??``,onClick:()=>C(e=>!e),children:e.license??`—`}),t.proxy&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs`,children:e.proxy?(0,L.jsx)(`span`,{className:`text-blue-400 cursor-pointer hover:underline`,onClick:()=>O(e.proxy),title:e.proxy,children:a||e.proxy}):`—`}),t.notes&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs max-w-[180px]`,children:_?(0,L.jsx)(`input`,{autoFocus:!0,className:`w-full bg-dark-600 border border-dark-500 rounded px-1.5 py-0.5 text-xs text-gray-200 outline-none focus:border-accent`,value:b,onChange:e=>x(e.target.value),onBlur:async()=>{if(v(!1),b!==(e.notes||``))try{await D.updateLogpassAccount(e.id,{notes:b}),f(`success`,w(`toast.noteSaved`)),m()}catch{f(`error`,w(`toast.noteSaveError`))}},onKeyDown:t=>{t.key===`Enter`&&t.target.blur(),t.key===`Escape`&&(x(e.notes||``),v(!1))}}):(0,L.jsx)(`span`,{className:`cursor-pointer text-gray-400 hover:text-gray-200 truncate block`,onClick:()=>{x(e.notes||``),v(!0)},title:e.notes||w(`tip.addNote`),children:e.notes||`—`})}),t.actions&&(0,L.jsx)(`td`,{className:`px-3 py-2 whitespace-nowrap`,children:(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,L.jsx)(`button`,{onClick:()=>c(e.id),disabled:n,className:`text-gray-400 hover:text-accent disabled:opacity-40`,title:w(`tip.validate`),children:(0,L.jsx)(De,{size:14})}),(0,L.jsx)(`button`,{onClick:()=>l(e.id),className:`text-gray-400 hover:text-accent`,title:w(`tip.edit`),children:(0,L.jsx)(xe,{size:14})}),(0,L.jsx)(`button`,{onClick:()=>o(e.id),className:`text-gray-400 hover:text-red-400`,title:w(`tip.delete`),children:(0,L.jsx)(Se,{size:14})})]})})]})}function xt({onClose:e,onImportDone:t}){let n=I(),[r,i]=(0,y.useState)(null),[a,o]=(0,y.useState)(``),[s,c]=(0,y.useState)(!1),l=(0,y.useRef)(null),u=A(e=>e.addToast),d=He(e=>e.loadAccounts);return(0,L.jsx)(`div`,{className:`confirm-overlay`,onMouseDown:e,children:(0,L.jsxs)(`div`,{className:`confirm-box max-w-lg w-full`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`h3`,{className:`text-lg font-semibold mb-4`,children:n(`modal.importTokens`)}),(0,L.jsxs)(`div`,{className:`text-sm text-gray-400 mb-3 space-y-1`,children:[(0,L.jsx)(`p`,{className:`font-medium text-gray-300`,children:n(`import.formatsColon`)}),(0,L.jsx)(`p`,{className:`font-mono text-xs`,children:n(`import.tokenFormat`)})]}),(0,L.jsxs)(`div`,{onDragOver:e=>e.preventDefault(),onDrop:e=>{e.preventDefault();let t=e.dataTransfer.files[0];t&&i(t)},onClick:()=>l.current?.click(),className:`border-2 border-dashed border-dark-500 rounded-lg p-6 mb-3 text-center cursor-pointer transition-colors hover:border-accent`,children:[(0,L.jsx)(ce,{size:32,className:`mx-auto mb-2 text-gray-500`}),(0,L.jsx)(`p`,{className:`text-sm text-gray-400`,children:r?n(`import.selected`,{name:r.name}):n(`import.dragTxt`)})]}),(0,L.jsx)(`input`,{ref:l,type:`file`,accept:`.txt`,className:`hidden`,onChange:e=>{let t=e.target.files?.[0];t&&i(t)}}),(0,L.jsx)(`button`,{onClick:async()=>{if(r){c(!0);try{let e=(await r.text()).split(` +`).map(e=>e.trim()).filter(Boolean);if(!e.length){o(n(`toast.fileEmpty`)),c(!1);return}let i=new Set(He.getState().accounts.map(e=>e.id)),a=await D.importTokens(e);o(n(`toast.importResult`,{imported:a.imported,skipped:a.skipped})),u(`success`,`${a.imported} ok, ${a.skipped} skip`),await d();let s=He.getState().accounts.map(e=>e.id).filter(e=>!i.has(e));t?.(s)}catch(e){o(e instanceof Error?e.message:n(`misc.errorStr`))}finally{c(!1)}}},disabled:!r||s,className:`btn-primary w-full`,children:n(s?`import.uploading`:`import.importBtn`)}),a&&(0,L.jsx)(`p`,{className:`mt-3 text-sm text-gray-300`,children:a})]})})}function St({onClose:e}){let t=I(),[n,r]=(0,y.useState)(``),[i,a]=(0,y.useState)(``),[o,s]=(0,y.useState)(``),[c,l]=(0,y.useState)(``),u=He(e=>e.loadAccounts);return(0,L.jsx)(`div`,{className:`confirm-overlay`,onMouseDown:e,children:(0,L.jsxs)(`div`,{className:`confirm-box max-w-md`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`h3`,{className:`text-lg font-semibold mb-4`,children:t(`modal.addToken`)}),(0,L.jsxs)(`div`,{className:`space-y-3`,children:[(0,L.jsx)(`textarea`,{autoFocus:!0,value:n,onChange:e=>r(e.target.value),placeholder:`Refresh token`,rows:3,className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm font-mono resize-none`}),(0,L.jsx)(`input`,{value:i,onChange:e=>a(e.target.value),placeholder:t(`ph.loginOptional`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:o,onChange:e=>s(e.target.value),placeholder:t(`ph.proxyOptional`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`input`,{value:c,onChange:e=>l(e.target.value),placeholder:t(`ph.notesOptional`),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm`}),(0,L.jsx)(`button`,{onClick:async()=>{if(!n.trim())return;let t={token:n.trim(),login:i.trim()||void 0,proxy:o.trim()||void 0,notes:c.trim()||void 0};await D.createTokenAccount(t),await u(),e()},disabled:!n.trim(),className:`btn-primary w-full disabled:opacity-40`,children:t(`btn.add`)})]})]})})}var Ct={browser:`col.browser`,profile:`col.profile`,last_online:`col.lastOnline`,steam_id:`col.steamId`,login:`col.login`,token:`col.token`,status:`col.status`,proxy:`col.proxy`,notes:`col.notes`,actions:`col.actions`};function wt(){let[e,t]=(0,y.useState)(!1),n=A(e=>e.tokenColumnVisibility),r=A(e=>e.toggleTokenColumn),i=(0,y.useRef)(null),a=I();return(0,y.useEffect)(()=>{let e=e=>{i.current&&!i.current.contains(e.target)&&t(!1)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[]),(0,L.jsxs)(`div`,{className:`relative`,ref:i,children:[(0,L.jsx)(`button`,{onClick:()=>t(!e),className:`btn-secondary text-sm px-2 py-2`,title:a(`tip.columnSettings`),children:(0,L.jsx)(be,{size:14})}),e&&(0,L.jsx)(`div`,{className:`absolute right-0 top-full mt-1 bg-dark-700 border border-dark-600 rounded-lg shadow-xl z-50 p-2 min-w-[160px]`,children:Object.keys(Ct).map(e=>(0,L.jsxs)(`label`,{className:`flex items-center gap-2 px-2 py-1 hover:bg-dark-600 rounded cursor-pointer text-sm`,children:[(0,L.jsx)(`input`,{type:`checkbox`,checked:n[e],onChange:()=>r(e)}),a(Ct[e])]},e))})]})}function Tt({label:e,value:t,good:n,bad:r}){return(0,L.jsxs)(`div`,{className:`flex text-[11px] font-mono leading-[1.7]`,children:[(0,L.jsx)(`span`,{className:`w-[110px] shrink-0 text-gray-500`,children:e}),(0,L.jsx)(`span`,{className:`min-w-0 break-words ${n?`text-green-400`:r?`text-red-400`:`text-gray-200`}`,children:t})]})}function Et({title:e,children:t}){return(0,L.jsxs)(`div`,{className:`rounded-lg border border-dark-600 bg-dark-900/40 px-3 py-2 space-y-0`,children:[(0,L.jsx)(`div`,{className:`text-[9px] font-semibold uppercase tracking-widest text-gray-600 pt-1 pb-0.5`,children:e}),t]})}function Dt(e){return e<=0?`0ч`:`${(e/60).toFixed(1)}ч`}function Ot(e){if(!e)return`—`;try{return new Date(e).toLocaleString()}catch{return e}}function kt({account:e,onClose:t,onRecheck:n}){let[r,i]=(0,y.useState)(null),[a,o]=(0,y.useState)(!0),[s,c]=(0,y.useState)(null);return(0,y.useEffect)(()=>{let t=!1;return D.getTokenCheckData(e.id).then(e=>{t||(i(e),o(!1))}).catch(e=>{t||(c(e instanceof Error?e.message:String(e)),o(!1))}),()=>{t=!0}},[e.id]),(0,y.useEffect)(()=>{let e=e=>{e.key===`Escape`&&t()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[t]),(0,L.jsx)(`div`,{className:`fixed inset-0 bg-black/60 flex items-center justify-center z-50`,onClick:e=>{e.target===e.currentTarget&&t()},children:(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-xl w-full max-w-[640px] max-h-[85vh] flex flex-col shadow-2xl mx-4`,children:[(0,L.jsxs)(`div`,{className:`px-5 pt-4 pb-3 border-b border-dark-600 flex items-start justify-between shrink-0`,children:[(0,L.jsxs)(`div`,{className:`flex items-start gap-3 min-w-0`,children:[(0,L.jsx)(`div`,{className:`h-9 w-9 rounded-lg bg-dark-700 shrink-0 overflow-hidden`,children:r?.avatar_url??e.avatar_url?(0,L.jsx)(`img`,{src:r?.avatar_url??e.avatar_url,alt:``,className:`w-full h-full object-cover`}):(0,L.jsx)(`div`,{className:`w-full h-full bg-dark-600`})}),(0,L.jsxs)(`div`,{className:`min-w-0`,children:[(0,L.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,L.jsx)(`span`,{className:`text-sm font-semibold text-gray-100 truncate`,children:r?.display_name??e.nickname??e.login??`—`}),(r?.steam_level??e.steam_level)!=null&&(0,L.jsxs)(`span`,{className:`rounded bg-accent/15 border border-accent/30 px-1.5 py-0.5 text-[9px] font-bold text-accent`,children:[`Lv.`,r?.steam_level??e.steam_level]})]}),(0,L.jsxs)(`div`,{className:`flex items-center gap-2 mt-0.5 text-[10px] text-gray-500 flex-wrap`,children:[(r?.steam_id??e.steam_id)&&(0,L.jsx)(`button`,{onClick:()=>{r?.steam_id&&Ue(r.steam_id)},className:`font-mono hover:text-gray-300 transition`,title:`Копировать SteamID`,children:r?.steam_id??e.steam_id}),(r?.last_online??e.last_online)&&(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(`span`,{className:`text-gray-700`,children:`·`}),(0,L.jsx)(`span`,{children:r?.last_online??e.last_online})]})]})]})]}),(0,L.jsxs)(`div`,{className:`flex items-center gap-2 shrink-0 ml-3`,children:[(0,L.jsxs)(`button`,{onClick:n,className:`flex items-center gap-1.5 px-2.5 py-1.5 text-xs rounded-lg bg-accent/10 border border-accent/30 text-accent hover:bg-accent/20 transition`,title:`Запустить полную проверку`,children:[(0,L.jsx)(he,{size:12}),`Обновить`]}),(0,L.jsx)(`button`,{onClick:t,className:`text-gray-500 hover:text-gray-300 transition p-1 rounded`,title:`Закрыть`,children:(0,L.jsx)(de,{size:16})})]})]}),(0,L.jsxs)(`div`,{className:`flex-1 overflow-auto min-h-0 px-5 py-4`,children:[a&&(0,L.jsx)(`div`,{className:`flex items-center justify-center py-16`,children:(0,L.jsx)(Ae,{size:28,className:`text-accent`})}),s&&!a&&(0,L.jsx)(`div`,{className:`flex items-center justify-center py-16 text-sm text-red-400`,children:s}),r&&!a&&(0,L.jsxs)(`div`,{className:`grid grid-cols-2 gap-3`,children:[(0,L.jsxs)(Et,{title:`Identity`,children:[e.login&&(0,L.jsx)(Tt,{label:`Логин`,value:e.login}),r.display_name&&(0,L.jsx)(Tt,{label:`Имя`,value:r.display_name}),r.steam_id&&(0,L.jsx)(Tt,{label:`SteamID`,value:r.steam_id}),r.user_country&&(0,L.jsx)(Tt,{label:`Страна`,value:r.user_country}),(0,L.jsx)(Tt,{label:`Телефон`,value:r.phone_digits?`заканч. на ${r.phone_digits}`:`Нет`}),r.created_date&&(0,L.jsx)(Tt,{label:`Создан`,value:r.created_date})]}),(0,L.jsxs)(Et,{title:`Security & Status`,children:[(0,L.jsx)(Tt,{label:`Trade Ban`,value:r.trade_ban&&r.trade_ban!==`None`?r.trade_ban:`Нет`,good:!r.trade_ban||r.trade_ban===`None`,bad:!!r.trade_ban&&r.trade_ban!==`None`}),(0,L.jsx)(Tt,{label:`Alert`,value:r.alert_status&&r.alert_status!==`None`?r.alert_status:`Нет`,good:!r.alert_status||r.alert_status===`None`,bad:!!r.alert_status&&r.alert_status!==`None`}),(0,L.jsx)(Tt,{label:`Market Lim`,value:r.market_limited?`Да`:`Нет`,good:!r.market_limited,bad:r.market_limited}),(0,L.jsx)(Tt,{label:`Family`,value:r.family_group?`Да`:`Нет`})]}),(0,L.jsxs)(Et,{title:`Economy & Activity`,children:[r.balance_raw&&(0,L.jsx)(Tt,{label:`Баланс`,value:r.balance_raw}),r.steam_level!=null&&(0,L.jsx)(Tt,{label:`Уровень`,value:String(r.steam_level)}),r.playtime_2weeks>0&&(0,L.jsx)(Tt,{label:`Время за 2 нед`,value:Dt(r.playtime_2weeks)})]}),(0,L.jsxs)(Et,{title:`Inventory`,children:[(0,L.jsx)(Tt,{label:`CS2`,value:`${r.inventory_cs2} (${r.inventory_cs2_marketable})`}),(0,L.jsx)(Tt,{label:`Dota 2`,value:`${r.inventory_dota2} (${r.inventory_dota2_marketable})`}),(0,L.jsx)(Tt,{label:`TF2`,value:`${r.inventory_tf2} (${r.inventory_tf2_marketable})`}),(0,L.jsx)(Tt,{label:`Rust`,value:`${r.inventory_rust} (${r.inventory_rust_marketable})`})]})]})]}),(0,L.jsx)(`div`,{className:`shrink-0 px-5 py-2 border-t border-dark-600 text-[10px] text-gray-600`,children:r?.checked_at?`Последняя проверка: ${Ot(r.checked_at)}`:`Данные ещё не получены`})]})})}function At(e){if(!e)return null;if(typeof e==`string`)try{return JSON.parse(e)}catch{return null}return e}function jt(){let e=He(e=>e.accounts),t=He(e=>e.selectedIds),n=He(e=>e.loadAccounts),r=He(e=>e.toggleSelect),i=He(e=>e.clearSelection),a=He(e=>e.setSelectedIds),o=A(e=>e.addToast),s=A(e=>e.autoProxyOnImportToken),c=A(e=>e.autoValidateOnImportToken),l=A(e=>e.tokenColumnVisibility),u=A(e=>e.loadTokenColumnSettings),d=I(),[f,p]=(0,y.useState)(``),[m,h]=(0,y.useState)(!1),[g,_]=(0,y.useState)(!1),[v,b]=(0,y.useState)({open:!1,message:``,onConfirm:()=>{}}),[x,S]=(0,y.useState)(new Set),[C,w]=(0,y.useState)({}),[T,E]=(0,y.useState)({}),[O,k]=(0,y.useState)(null),[ee,te]=(0,y.useState)(null);(0,y.useEffect)(()=>{n(),u()},[n,u]);let j=(e,t)=>b({open:!0,message:e,onConfirm:t}),M=(0,y.useCallback)(e=>{let t=new EventSource(`/api/tasks/${e}/stream`);t.onmessage=e=>{try{let r=JSON.parse(e.data);if(k(r),r.account_results){let e=At(r.account_results);e&&w(e)}r.account_steps&&E(r.account_steps),r.status!==`running`&&(t.close(),S(new Set),n())}catch{}},t.onerror=()=>t.close()},[n]),N=(0,y.useCallback)(async()=>{let e=[...t];if(e.length){i(),S(new Set(e)),w({}),E({});try{let{task_id:t}=await D.validateTokens(e);k({id:t,type:`token_validate`,status:`running`,progress:0,total:e.length,result:null,error:null,created_at:``,updated_at:``}),M(t)}catch(e){S(new Set),o(`error`,String(e))}}},[t,i,M,o]),P=(0,y.useCallback)(async e=>{S(new Set([e])),w(t=>{let n={...t};return delete n[String(e)],n}),E(t=>{let n={...t};return delete n[String(e)],n});try{let{task_id:t}=await D.validateTokens([e]);k({id:t,type:`token_validate`,status:`running`,progress:0,total:1,result:null,error:null,created_at:``,updated_at:``}),M(t)}catch(e){S(new Set),o(`error`,String(e))}},[M,o]),F=(0,y.useCallback)(async e=>{S(new Set([e]));try{let{task_id:t}=await D.fullCheckTokens([e]);k({id:t,type:`token_full_check`,status:`running`,progress:0,total:1,result:null,error:null,created_at:``,updated_at:``}),M(t)}catch(e){S(new Set),o(`error`,String(e))}},[M,o]),ne=(0,y.useCallback)(async()=>{let e=[...t];if(e.length){i(),S(new Set(e)),w({}),E({});try{let{task_id:t}=await D.fullCheckTokens(e);k({id:t,type:`token_full_check`,status:`running`,progress:0,total:e.length,result:null,error:null,created_at:``,updated_at:``}),M(t)}catch(e){S(new Set),o(`error`,String(e))}}},[t,i,M,o]),re=(0,y.useCallback)(e=>{if(!e.has_cookies){o(`warn`,`Нет сохранённых куки. Сначала запустите валидацию.`);return}D.downloadTokenCookies(e.id)},[o]),ie=()=>{let e=[...t];e.length&&j(d(`confirm.deleteTokenSelected`,{count:e.length}),async()=>{await D.deleteTokenBulk(e),i(),n()})},ae=()=>{j(d(`confirm.deleteTokenAll`,{count:e.length}),async()=>{await D.deleteTokenBulk(e.map(e=>e.id)),i(),n()})},oe=()=>{j(d(`confirm.assignProxies`),async()=>{try{o(`success`,d(`toast.proxiesAssignedShort`,{count:(await D.assignTokenProxies()).assigned})),n()}catch(e){o(`error`,e instanceof Error?e.message:String(e))}})},R=()=>{j(d(`confirm.reassignProxiesAll`),async()=>{try{o(`success`,d(`toast.proxiesReassignedShort`,{count:(await D.reassignTokenProxies()).assigned})),n()}catch(e){o(`error`,e instanceof Error?e.message:String(e))}})},ce=()=>{j(d(`confirm.clearProxies`),async()=>{try{o(`success`,d(`toast.proxiesClearedShort`,{count:(await D.clearTokenProxies()).cleared})),n()}catch(e){o(`error`,e instanceof Error?e.message:String(e))}})},de=async e=>{try{let t=await D.openTokenBrowser(e);t.status===`revalidating`?(o(`warn`,d(`toast.cookiesExpiredRevalidating`)),t.task_id&&(S(new Set([e])),k({id:t.task_id,type:`token_validate`,status:`running`,progress:0,total:1,result:null,error:null,created_at:``,updated_at:``}),M(t.task_id))):o(`success`,d(`toast.browserOpening`))}catch(e){o(`error`,e instanceof Error?e.message:String(e))}},pe=(0,y.useCallback)(async e=>{let t=s,r=c;try{let e=await D.getValidationSettings();t=e.auto_proxy_on_import_token,r=e.auto_validate_on_import_token}catch{}if(t)try{o(`success`,d(`toast.proxiesAssignedShort`,{count:(await D.assignTokenProxies()).assigned})),await n()}catch{}if(r&&e.length)try{let{task_id:t}=await D.validateTokens(e);k({id:t,type:`token_validate`,status:`running`,progress:0,total:e.length,result:null,error:null,created_at:``,updated_at:``}),S(new Set(e)),M(t)}catch(e){S(new Set),o(`error`,e instanceof Error?e.message:String(e))}},[s,c,o,n,M,d]),z=(0,y.useMemo)(()=>{if(!f.trim())return e;let t=f.trim(),n=t.match(/^lvl\s*(>=|<=|>|<|=)\s*(\d+)$/i);if(n){let t=n[1],r=parseInt(n[2],10);return e.filter(e=>{let n=e.steam_level;return n==null?!1:t===`>`?n>r:t===`>=`?n>=r:t===`<`?n(e.login??``).toLowerCase().includes(r)||(e.steam_id??``).toLowerCase().includes(r)||(e.nickname??``).toLowerCase().includes(r)||(e.notes??``).toLowerCase().includes(r))},[e,f]),_e=z.length>0&&z.every(e=>t.has(e.id)),ve=()=>{if(_e){let e=new Set(t);z.forEach(t=>e.delete(t.id)),a(e)}else{let e=new Set(t);z.forEach(t=>e.add(t.id)),a(e)}},ye=(0,y.useMemo)(()=>{let t=new Map,n=[];for(let t of e)t.proxy&&!n.includes(t.proxy)&&n.push(t.proxy);let r=new Map;n.forEach((e,t)=>r.set(e,t+1));for(let n of e)n.proxy&&t.set(n.id,d(`proxy.label`,{num:r.get(n.proxy)??0}));return t},[e,d]);return(0,L.jsxs)(`div`,{className:`flex flex-col gap-4 h-full min-h-0`,children:[(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-lg px-3 py-2 flex flex-wrap items-center gap-2 shrink-0`,children:[(0,L.jsxs)(`button`,{onClick:()=>h(!0),className:`btn-primary`,children:[(0,L.jsx)(se,{size:14,className:`inline mr-1`}),d(`btn.import`)]}),(0,L.jsxs)(`button`,{onClick:()=>_(!0),className:`btn-secondary`,children:[(0,L.jsx)(le,{size:14,className:`inline mr-1`}),d(`btn.add`)]}),O&&(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(`div`,{className:`h-5 border-l border-dark-500`}),(0,L.jsxs)(`div`,{className:`flex items-center gap-2 min-w-0`,children:[(0,L.jsx)(`span`,{className:`text-xs text-gray-400 whitespace-nowrap`,children:d(`task.validate`)}),(0,L.jsx)(`div`,{className:`w-28 bg-dark-600 rounded-full h-2.5 shrink-0`,children:(0,L.jsx)(`div`,{className:`h-2.5 rounded-full transition-all duration-300 ${O.status===`completed`?`bg-green-500`:O.status===`failed`?`bg-red-500`:`bg-accent`}`,style:{width:`${O.total>1?O.total>0?Math.round(O.progress/O.total*100):0:O.total_steps?Math.round((O.step??0)/O.total_steps*100):0}%`}})}),(0,L.jsxs)(`span`,{className:`text-xs text-gray-500 whitespace-nowrap`,children:[O.total>1?`${O.progress}/${O.total}${O.active_count?` (${O.active_count})`:``}`:O.step_label||`${O.progress}/${O.total}`,O.total>1?` (${O.total>0?Math.round(O.progress/O.total*100):0}%)`:O.total_steps?` (${O.step}/${O.total_steps})`:``]}),O.status===`completed`&&(0,L.jsx)(ke,{size:14,className:`text-green-400`}),O.status===`failed`&&(0,L.jsx)(`span`,{title:O.error||``,children:(0,L.jsx)(Oe,{size:14,className:`text-red-400`})})]})]}),(0,L.jsxs)(`div`,{className:`ml-auto flex items-center gap-2`,children:[(0,L.jsx)(wt,{}),(0,L.jsx)(`div`,{className:`h-5 border-l border-dark-500`}),(0,L.jsx)(`button`,{onClick:ie,className:`btn-danger-outline text-xs`,children:d(`btn.deleteSelected`)}),(0,L.jsx)(`button`,{onClick:ae,className:`btn-danger text-xs`,children:d(`btn.deleteAll`)})]})]}),(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-lg overflow-hidden flex-1 min-h-0 flex flex-col`,children:[(0,L.jsxs)(`div`,{className:`px-3 py-2 flex items-center gap-2 border-b border-dark-600 shrink-0 bg-dark-800`,children:[(0,L.jsxs)(`button`,{onClick:N,disabled:t.size===0||x.size>0,className:`btn-accent text-sm disabled:opacity-40`,children:[(0,L.jsx)(De,{size:12,className:`inline mr-1`}),d(`btn.validate`)]}),(0,L.jsxs)(`button`,{onClick:ne,disabled:t.size===0||x.size>0,className:`btn-secondary text-sm disabled:opacity-40`,children:[(0,L.jsx)(Pe,{size:12,className:`inline mr-1`}),d(`btn.fullCheck`)]}),(0,L.jsx)(`div`,{className:`h-5 border-l border-dark-500`}),(0,L.jsxs)(`button`,{onClick:oe,className:`btn-secondary text-sm`,children:[(0,L.jsx)(me,{size:14,className:`inline mr-1`}),d(`btn.assignProxies`)]}),(0,L.jsxs)(`button`,{onClick:R,className:`btn-secondary text-sm`,children:[(0,L.jsx)(he,{size:14,className:`inline mr-1`}),d(`btn.reassign`)]}),(0,L.jsxs)(`button`,{onClick:ce,className:`btn-danger-outline text-sm`,children:[(0,L.jsx)(ge,{size:14,className:`inline mr-1`}),d(`btn.clearProxies`)]}),(0,L.jsx)(`div`,{className:`ml-auto`,children:(0,L.jsx)(`input`,{type:`text`,value:f,onChange:e=>p(e.target.value),placeholder:d(`ph.search`),className:`bg-dark-700 border border-dark-600 rounded px-2 py-1.5 text-xs w-80 placeholder:text-gray-500 outline-none focus:border-accent`})})]}),(0,L.jsx)(`div`,{className:`overflow-auto flex-1 min-h-0`,children:(0,L.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,L.jsx)(`thead`,{className:`sticky top-0 bg-dark-800 z-10`,children:(0,L.jsxs)(`tr`,{className:`text-left text-xs text-gray-500 border-b border-dark-600`,children:[(0,L.jsx)(`th`,{className:`px-3 py-2`,children:(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,L.jsx)(`input`,{type:`checkbox`,checked:_e,onChange:ve}),t.size>0&&(0,L.jsx)(`span`,{className:`text-accent font-medium`,children:t.size})]})}),(0,L.jsx)(`th`,{className:`w-5`}),l.browser&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:d(`col.browser`)}),l.profile&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:d(`col.profile`)}),l.last_online&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:d(`col.lastOnline`)}),l.steam_id&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:`Steam ID`}),l.login&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:d(`col.login`)}),l.token&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:d(`col.token`)}),l.status&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:d(`col.status`)}),l.proxy&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:d(`col.proxy`)}),l.notes&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:d(`col.notes`)}),l.actions&&(0,L.jsx)(`th`,{className:`px-3 py-2`,children:d(`col.actions`)})]})}),(0,L.jsx)(`tbody`,{children:z.length===0?(0,L.jsx)(`tr`,{children:(0,L.jsx)(`td`,{colSpan:12,className:`text-center py-12 text-gray-500`,children:d(`empty.tokens`)})}):z.map(e=>{let i=x.has(e.id),a=C[String(e.id)],o=T[String(e.id)];return(0,L.jsxs)(`tr`,{className:`hover:bg-dark-700/50 transition border-t border-dark-700`,children:[(0,L.jsx)(`td`,{className:`px-3 py-2`,children:(0,L.jsx)(`input`,{type:`checkbox`,checked:t.has(e.id),onChange:()=>r(e.id)})}),(0,L.jsx)(`td`,{className:`px-1 py-2 w-5`,children:i?(0,L.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,L.jsx)(`div`,{className:`w-4 h-4 border-2 border-accent border-t-transparent rounded-full animate-spin shrink-0`}),o&&(0,L.jsxs)(`span`,{className:`text-[10px] text-gray-500 whitespace-nowrap`,children:[`[`,o.step,`/`,o.total,`]`]})]}):a?.status===`ok`?(0,L.jsx)(ue,{size:16,className:`text-gray-400`}):a?.status===`error`?(0,L.jsx)(`span`,{title:a.error,children:(0,L.jsx)(fe,{size:16,className:`text-red-400`})}):null}),l.browser&&(0,L.jsx)(`td`,{className:`px-3 py-2 whitespace-nowrap text-center`,children:e.has_cookies?(0,L.jsx)(`button`,{onClick:()=>de(e.id),className:`px-2 py-0.5 text-xs font-medium rounded bg-blue-600/20 text-blue-400 border border-blue-500/30 hover:bg-blue-600/40 hover:text-blue-300 active:scale-95 transition`,title:d(`tip.openBrowser`),children:d(`col.browser`)}):(0,L.jsx)(`span`,{className:`text-gray-600 text-xs`,children:`—`})}),l.profile&&(0,L.jsx)(`td`,{className:`px-3 py-2 whitespace-nowrap`,children:(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[e.avatar_url&&(0,L.jsx)(`img`,{src:e.avatar_url,className:`avatar-sm`,alt:``}),(0,L.jsx)(`span`,{className:`text-xs`,children:e.nickname||`—`}),e.steam_level!=null&&(0,L.jsx)(nt,{level:e.steam_level})]})}),l.last_online&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs text-gray-400 whitespace-nowrap`,children:e.last_online||`—`}),l.steam_id&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs`,children:e.steam_id?(0,L.jsx)(`a`,{href:`https://steamcommunity.com/profiles/${encodeURIComponent(e.steam_id)}/`,target:`_blank`,rel:`noopener noreferrer`,className:`text-blue-400 hover:text-blue-300 hover:underline`,children:e.steam_id}):`—`}),l.login&&(0,L.jsx)(`td`,{className:`px-3 py-2 font-medium`,children:e.login??`—`}),l.token&&(0,L.jsxs)(`td`,{className:`px-3 py-2 font-mono text-gray-400 truncate max-w-[180px]`,title:e.token,children:[e.token.slice(0,24),`…`]}),l.status&&(0,L.jsx)(`td`,{className:`px-3 py-2`,children:(0,L.jsx)(Ge,{status:e.status})}),l.proxy&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs text-gray-500 whitespace-nowrap`,children:ye.get(e.id)??`—`}),l.notes&&(0,L.jsx)(`td`,{className:`px-3 py-2 text-xs text-gray-500`,children:e.notes??`—`}),l.actions&&(0,L.jsx)(`td`,{className:`px-3 py-2 whitespace-nowrap`,children:(0,L.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,L.jsx)(`button`,{onClick:()=>P(e.id),disabled:i,className:`text-gray-400 hover:text-accent disabled:opacity-40 transition`,title:d(`tip.validate`),children:(0,L.jsx)(De,{size:14})}),(0,L.jsx)(`button`,{onClick:()=>F(e.id),disabled:i,className:`text-gray-400 hover:text-accent disabled:opacity-40 transition`,title:d(`btn.fullCheck`),children:(0,L.jsx)(Pe,{size:14})}),(0,L.jsx)(`button`,{onClick:()=>te(e.id),className:`text-gray-400 hover:text-blue-400 transition`,title:`Детали проверки`,children:(0,L.jsx)(Te,{size:14})}),(0,L.jsx)(`button`,{onClick:()=>re(e),className:`transition ${e.has_cookies?`text-gray-400 hover:text-green-400`:`text-gray-700 cursor-not-allowed`}`,title:e.has_cookies?`Скачать куки`:`Куки отсутствуют`,children:(0,L.jsx)(se,{size:14})}),(0,L.jsx)(`button`,{onClick:()=>j(d(`confirm.deleteToken`,{name:e.login??e.token.slice(0,16)}),async()=>{await D.deleteTokenAccount(e.id),n()}),className:`text-gray-400 hover:text-red-400 transition`,title:d(`tip.delete`),children:(0,L.jsx)(Se,{size:14})})]})})]},e.id)})})]})})]}),m&&(0,L.jsx)(xt,{onClose:()=>h(!1),onImportDone:pe}),g&&(0,L.jsx)(St,{onClose:()=>_(!1)}),ee!=null&&(()=>{let t=e.find(e=>e.id===ee);return t?(0,L.jsx)(kt,{account:t,onClose:()=>te(null),onRecheck:()=>{te(null),F(t.id)}}):null})(),v.open&&(0,L.jsx)(ut,{message:v.message,onConfirm:()=>{v.onConfirm(),b(e=>({...e,open:!1}))},onCancel:()=>b(e=>({...e,open:!1}))})]})}function Mt(e){if(!e)return null;if(typeof e==`string`)try{return JSON.parse(e)}catch{return null}return e}function Nt(e){if(!e)return[];try{return JSON.parse(e)}catch{return[]}}var Pt=[{value:``,labelKey:`action.selectAction`},{value:`validate`,labelKey:`action.validate`},{value:`change_password`,labelKey:`action.changePassword`},{value:`random_password`,labelKey:`action.randomPassword`},{value:`change_email`,labelKey:`action.changeEmail`},{value:`remove_guard`,labelKey:`action.removeGuard`},{value:`enable_auto_accept`,labelKey:`action.enableAutoAccept`}];function Ft({value:e,onChange:t,disabledActions:n}){let r=I(),[i,a]=(0,y.useState)(!1),o=(0,y.useRef)(null);return(0,y.useEffect)(()=>{if(!i)return;let e=e=>{o.current&&!o.current.contains(e.target)&&a(!1)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[i]),(0,L.jsxs)(`div`,{ref:o,className:`relative`,children:[(0,L.jsxs)(`button`,{type:`button`,onClick:()=>a(e=>!e),className:`bg-dark-700 border border-dark-600 rounded px-2 py-1.5 text-sm flex items-center gap-1 min-w-[170px] justify-between hover:border-dark-500 transition-colors`,children:[(0,L.jsx)(`span`,{className:`truncate`,children:r(Pt.find(t=>t.value===e)?.labelKey||`action.selectAction`)}),(0,L.jsx)(`svg`,{width:`12`,height:`12`,viewBox:`0 0 12 12`,fill:`none`,className:`shrink-0 transition-transform ${i?`rotate-180`:``}`,children:(0,L.jsx)(`path`,{d:`M3 4.5L6 7.5L9 4.5`,stroke:`currentColor`,strokeWidth:`1.5`,strokeLinecap:`round`,strokeLinejoin:`round`})})]}),i&&(0,L.jsx)(`div`,{className:`absolute top-full left-0 mt-1 z-50 bg-dark-700 border border-dark-600 rounded shadow-lg min-w-[100px] py-1 max-h-[320px] overflow-y-auto`,children:Pt.map(i=>{let o=!!(i.value&&n?.has(i.value));return(0,L.jsx)(`button`,{type:`button`,onClick:()=>{o||(t(i.value),a(!1))},disabled:o,title:o?r(`action.noRevocationCode`):void 0,className:`w-full text-left px-3 py-2 text-sm transition-colors ${o?`opacity-40 cursor-not-allowed`:`hover:bg-dark-600`} ${i.value===e?`text-accent bg-dark-600/50`:``} ${i.value?``:`text-gray-500`}`,children:r(i.labelKey)},i.value)})})]})}function It(){let e=A(e=>e.accountSection),t=ze(e=>e.accounts.length),n=Ve(e=>e.accounts.length),r=He(e=>e.accounts.length),i=Ve(e=>e.loadAccounts),a=He(e=>e.loadAccounts),[o,s]=(0,y.useState)(0),c=(0,y.useRef)(0),l=(0,y.useRef)(0),u=(0,y.useRef)(e);(0,y.useEffect)(()=>{e===`logpass`&&n===0&&i(),e===`token`&&r===0&&a()},[e]);let d=e===`logpass`?n:e===`token`?r:t;return(0,y.useEffect)(()=>{cancelAnimationFrame(c.current);let t=u.current!==e;if(u.current=e,t){l.current=d,s(d);return}let n=l.current,r=d-n;if(r===0)return;let i=Math.min(400,Math.max(150,Math.abs(r)*2)),a=performance.now(),o=e=>{let t=e-a,u=Math.min(t/i,1),d=1-(1-u)**3,f=Math.max(0,Math.round(n+r*d));l.current=f,s(f),u<1&&(c.current=requestAnimationFrame(o))};return c.current=requestAnimationFrame(o),()=>cancelAnimationFrame(c.current)},[d,e]),(0,L.jsxs)(`div`,{className:`mt-1 px-3 py-2 border-t border-dark-600 flex items-center gap-2`,children:[(0,L.jsxs)(`div`,{className:`relative shrink-0`,style:{width:14,height:14},children:[(0,L.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:`14`,height:`14`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,className:`text-gray-400`,children:[(0,L.jsx)(`path`,{d:`M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2`}),(0,L.jsx)(`circle`,{cx:`9`,cy:`7`,r:`4`}),(0,L.jsx)(`path`,{d:`M22 21v-2a4 4 0 0 0-3-3.87`}),(0,L.jsx)(`path`,{d:`M16 3.13a4 4 0 0 1 0 7.75`})]}),(0,L.jsxs)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,width:`14`,height:`14`,viewBox:`0 0 24 24`,fill:`none`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,className:`icon-shimmer absolute inset-0`,style:{pointerEvents:`none`},children:[(0,L.jsx)(`path`,{d:`M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2`}),(0,L.jsx)(`circle`,{cx:`9`,cy:`7`,r:`4`}),(0,L.jsx)(`path`,{d:`M22 21v-2a4 4 0 0 0-3-3.87`}),(0,L.jsx)(`path`,{d:`M16 3.13a4 4 0 0 1 0 7.75`})]})]}),(0,L.jsx)(`span`,{className:`text-sm text-gray-300 font-medium tabular-nums`,children:o})]})}function Lt(){let e=ze(e=>e.accounts),t=ze(e=>e.selectedIds),n=ze(e=>e.loadAccounts),r=ze(e=>e.clearSelection),i=ze(e=>e.sendToMafileManager),a=A(e=>e.setTab),o=A(e=>e.addToast),s=A(e=>e.autoProxyOnImportMafile),c=A(e=>e.autoValidateOnImportMafile),l=Be(e=>e.loadTasks),u=I(),[d,f]=(0,y.useState)(null),[p,m]=(0,y.useState)(!1),[h,g]=(0,y.useState)(!1),[_,v]=(0,y.useState)(null),[b,x]=(0,y.useState)(null),[S,C]=(0,y.useState)(``),w=A(e=>e.accountSection),T=A(e=>e.setAccountSection),[E,O]=(0,y.useState)(null),[k,ee]=(0,y.useState)(new Set),[te,j]=(0,y.useState)(``),[M,N]=(0,y.useState)(null),[P,F]=(0,y.useState)(``),[ne,re]=(0,y.useState)({}),[ie,ae]=(0,y.useState)({}),oe=(0,y.useMemo)(()=>{if(!te.trim())return e;let t=te.trim(),n=t.match(/^lvl\s*(>=|<=|>|<|=)\s*(\d+)$/i);if(n){let t=n[1],r=parseInt(n[2],10);return e.filter(e=>{let n=e.steam_level;return n==null?!1:t===`>`?n>r:t===`>=`?n>=r:t===`<`?n{if(e.login.toLowerCase().includes(r)||e.steam_id&&e.steam_id.toLowerCase().includes(r))return!0;if(e.notes){let t=e.notes.toLowerCase();return i.some(e=>t.includes(e))}return!1})},[e,te]),R=(0,y.useMemo)(()=>{let n=new Set;return e.filter(e=>t.has(e.id)).some(e=>e.has_revocation_code)||n.add(`remove_guard`),n},[e,t]);(0,y.useEffect)(()=>{n()},[]);let ce=(e,t)=>{v(e),x(()=>t)},ue=(0,y.useCallback)((e,t=[],r=!0)=>{r&&re(e=>{let n={...e};return t.forEach(e=>delete n[String(e)]),n});let i=new EventSource(`/api/tasks/${e}/stream`);i.onmessage=r=>{try{let a=JSON.parse(r.data);O(a);let s=Mt(a.account_results);s&&re(e=>({...e,...s})),a.account_steps&&ae(e=>({...e,...a.account_steps})),a.prompt&&(N({taskId:e,message:a.prompt,login:a.prompt_login}),F(``)),(a.status===`completed`||a.status===`failed`||a.status===`cancelled`)&&(a.status===`completed`?o(`success`,`${a.type}: ${a.result||u(`toast.done`)}`):a.status===`cancelled`?o(`info`,u(`toast.taskCancelled`)):o(`error`,`${a.type}: ${a.error||u(`toast.error`)}`),ee(e=>{let n=new Set(e);return t.forEach(e=>n.delete(e)),n}),N(null),n(),l(),i.close(),setTimeout(()=>O(null),3e3))}catch{}},i.onerror=()=>i.close()},[o,n,l]);(0,y.useEffect)(()=>{let e=!1;return(async()=>{try{let t=await D.getTasks();if(e)return;let n=t.find(e=>e.status===`running`);if(n){let e=Nt(n.account_ids);O(n),ee(new Set(e));let t=Mt(n.account_results);t&&re(t),ue(n.id,e,!1);return}let r=t.find(e=>e.status===`completed`||e.status===`failed`);if(r){let e=Mt(r.account_results);e&&Object.keys(e).length>0&&re(e)}}catch{}})(),()=>{e=!0}},[ue]);let de=async(t,n,r)=>{let i=e.find(e=>e.id===t)?.login??`#${t}`;try{ee(e=>new Set(e).add(t));let e=await D.executeAction({account_ids:[t],action:n,params:r});o(`info`,u(`misc.taskAction`,{id:e.task_id,action:n,login:i})),ue(e.task_id,[t])}catch(e){ee(e=>{let n=new Set(e);return n.delete(t),n}),o(`error`,u(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}},fe=async()=>{if(!(!M||!P))try{await D.respondToPrompt(M.taskId,P,M.login),N(null)}catch(e){o(`error`,u(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}},z=async()=>{if(M)try{await D.cancelTask(M.taskId)}catch{}N(null)},_e=()=>{if(!S)return o(`warn`,u(`toast.selectAction`));if(!t.size)return o(`warn`,u(`toast.selectAccounts`));if(S===`enable_auto_accept`){let e=[...t];r(),D.startAutoAccept(e).then(()=>{o(`success`,u(`toast.autoAcceptEnabled`,{count:e.length})),n()}).catch(e=>o(`error`,u(`misc.error`,{error:e instanceof Error?e.message:String(e)})));return}let e=[...t],i=S;ce(u(`confirm.executeBulk`,{action:u(Pt.find(e=>e.value===i)?.labelKey||`action.selectAction`),count:e.length}),async()=>{try{let t=await D.executeAction({account_ids:e,action:i});r(),ee(t=>{let n=new Set(t);return e.forEach(e=>n.add(e)),n}),o(`info`,u(`misc.taskCount`,{id:t.task_id,count:t.accounts_count})),ue(t.task_id,e)}catch(e){o(`error`,u(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}})},be=async t=>{let r=e.find(e=>e.id===t);if(!r)return;let i=!r.auto_accept;try{i?await D.startAutoAccept([t]):await D.stopAutoAccept([t]),o(`info`,u(i?`toast.autoAcceptOn`:`toast.autoAcceptOff`)),await n()}catch(e){o(`error`,u(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}},xe=e=>f(e),Se=async(e,t)=>{try{await D.updateAccount(e,t),f(null),o(`success`,u(`toast.saved`)),await n()}catch(e){o(`error`,u(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}},we=e=>{ce(u(`confirm.deleteAccount`),async()=>{try{await D.deleteAccount(e),o(`success`,u(`toast.accountDeleted`)),await n()}catch(e){o(`error`,u(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}})},Te=()=>{if(!t.size)return o(`warn`,u(`toast.selectAccounts`));ce(u(`confirm.deleteSelected`,{count:t.size}),async()=>{try{let e=await D.deleteBulk([...t]);r(),o(`success`,u(`toast.deleted`,{count:e.deleted})),await n()}catch(e){o(`error`,u(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}})},Ee=()=>{if(!e.length)return o(`warn`,u(`toast.noAccounts`));ce(u(`confirm.deleteAll`,{count:e.length}),async()=>{try{let e=await D.deleteBulk([]);r(),o(`success`,u(`toast.deleted`,{count:e.deleted})),await n()}catch(e){o(`error`,u(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}})},Ae=async e=>{try{await D.createAccount(e),g(!1),o(`success`,u(`toast.accountAdded`)),await n()}catch(e){o(`error`,u(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}},je=()=>{if(!t.size)return o(`warn`,u(`toast.selectAccounts`));i([...t]),a(`mafiles`),o(`info`,u(`toast.sentToMafile`,{count:t.size}))},Me=async e=>{try{let t=await D.openBrowser(e);t.status===`revalidating`?(o(`warn`,u(`toast.cookiesExpiredRevalidating`)),t.task_id&&(ee(t=>new Set(t).add(e)),ue(t.task_id,[e]))):o(`info`,u(`toast.browserOpening`))}catch(e){o(`error`,u(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}},Ne=async()=>{ce(u(`confirm.assignProxies`),async()=>{try{let e=await D.assignProxies();o(`success`,u(`toast.proxiesAssigned`,{used:e.proxies_used,count:e.assigned})),await n()}catch(e){o(`error`,u(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}})},Pe=async()=>{ce(u(`confirm.reassignProxies`),async()=>{try{let e=await D.reassignProxies();o(`success`,u(`toast.proxiesReassigned`,{used:e.proxies_used,count:e.assigned})),await n()}catch(e){o(`error`,u(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}})},Fe=async()=>{ce(u(`confirm.clearProxies`),async()=>{try{o(`success`,u(`toast.proxiesClearedCount`,{count:(await D.clearProxies()).cleared})),await n()}catch(e){o(`error`,u(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}})},Ie=(0,y.useCallback)(async e=>{let t=s,r=c;try{let e=await D.getValidationSettings();t=e.auto_proxy_on_import_mafile,r=e.auto_validate_on_import_mafile}catch{}if(t)try{o(`success`,u(`toast.proxiesAssignedShort`,{count:(await D.assignProxies()).assigned})),await n()}catch{}if(r&&e.length)try{ee(new Set(e));let t=await D.executeAction({account_ids:e,action:`validate`});O({id:t.task_id,type:`validate`,status:`running`,progress:0,total:e.length,result:null,error:null,account_ids:null,account_results:null,created_at:``,updated_at:``}),ue(t.task_id,e)}catch(e){ee(new Set),o(`error`,u(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}},[s,c,o,n,ue,u]),Le=d?e.find(e=>e.id===d):null,Re=[{id:`mafile`,label:`Mafile`,icon:(0,L.jsx)(Ce,{size:14})},{id:`logpass`,label:`Log:Pass`,icon:(0,L.jsx)(ve,{size:14})},{id:`token`,label:`Token`,icon:(0,L.jsx)(ye,{size:14})}];return(0,L.jsxs)(`div`,{className:`flex gap-3 h-full min-h-0 overflow-hidden`,children:[(0,L.jsxs)(`div`,{className:`w-36 shrink-0 flex flex-col gap-1 bg-dark-800 border border-dark-600 rounded-lg p-2 self-start`,children:[(0,L.jsx)(`p`,{className:`text-xs font-medium text-gray-500 px-2 py-1 uppercase tracking-wider`,children:u(`section.dataType`)}),Re.map(e=>(0,L.jsxs)(`button`,{onClick:()=>T(e.id),className:`flex items-center gap-2 px-3 py-2 rounded text-sm text-left w-full transition-colors ${w===e.id?`bg-accent/20 text-accent`:`text-gray-400 hover:text-gray-200 hover:bg-dark-700`}`,children:[e.icon,e.label]},e.id)),(0,L.jsx)(It,{})]}),w===`logpass`&&(0,L.jsx)(`div`,{className:`flex-1 min-w-0 min-h-0`,children:(0,L.jsx)(yt,{})}),w===`token`&&(0,L.jsx)(`div`,{className:`flex-1 min-w-0 min-h-0`,children:(0,L.jsx)(jt,{})}),w===`mafile`&&(0,L.jsxs)(`div`,{className:`flex flex-col gap-4 flex-1 min-w-0 min-h-0 overflow-hidden`,children:[(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-lg px-3 py-2 flex flex-wrap items-center gap-2 shrink-0`,children:[(0,L.jsxs)(`button`,{onClick:()=>m(!0),className:`btn-primary`,children:[(0,L.jsx)(se,{size:14,className:`inline mr-1`}),u(`btn.import`)]}),(0,L.jsxs)(`button`,{onClick:()=>g(!0),className:`btn-secondary`,children:[(0,L.jsx)(le,{size:14,className:`inline mr-1`}),u(`btn.add`)]}),E&&(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(`div`,{className:`h-5 border-l border-dark-500`}),(0,L.jsxs)(`div`,{className:`flex items-center gap-2 min-w-0`,children:[(0,L.jsx)(`span`,{className:`text-xs text-gray-400 whitespace-nowrap`,children:E.type===`validate`?u(`task.validate`):E.type===`change_password`?u(`task.changePassword`):E.type===`random_password`?u(`task.randomPassword`):E.type===`change_email`?u(`task.changeEmail`):E.type===`change_phone`?u(`task.changePhone`):E.type===`remove_guard`?u(`task.removeGuard`):E.type}),(0,L.jsx)(`div`,{className:`w-28 bg-dark-600 rounded-full h-2.5 shrink-0`,children:(0,L.jsx)(`div`,{className:`h-2.5 rounded-full transition-all duration-300 ${E.status===`completed`?`bg-green-500`:E.status===`failed`?`bg-red-500`:`bg-accent`}`,style:{width:`${E.total>1?E.total>0?Math.round(E.progress/E.total*100):0:E.total_steps?Math.round((E.step??0)/E.total_steps*100):0}%`}})}),(0,L.jsxs)(`span`,{className:`text-xs text-gray-500 whitespace-nowrap`,children:[E.total>1?`${E.progress}/${E.total}${E.active_count?` (${E.active_count})`:``}`:E.step_label||`${E.progress}/${E.total}`,E.total>1?` (${E.total>0?Math.round(E.progress/E.total*100):0}%)`:E.total_steps?` (${E.step}/${E.total_steps})`:``]}),E.status===`completed`&&(0,L.jsx)(ke,{size:14,className:`text-green-400`}),E.status===`failed`&&(0,L.jsx)(`span`,{title:E.error||``,children:(0,L.jsx)(Oe,{size:14,className:`text-red-400`})})]})]}),(0,L.jsxs)(`div`,{className:`ml-auto flex items-center gap-2`,children:[(0,L.jsx)(ft,{}),(0,L.jsx)(`div`,{className:`h-5 border-l border-dark-500`}),(0,L.jsx)(`button`,{onClick:Te,className:`btn-danger-outline text-xs`,children:u(`btn.deleteSelected`)}),(0,L.jsx)(`button`,{onClick:Ee,className:`btn-danger text-xs`,children:u(`btn.deleteAll`)})]})]}),(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-lg overflow-hidden flex-1 min-h-0 flex flex-col`,children:[(0,L.jsxs)(`div`,{className:`px-3 py-2 flex items-center gap-2 border-b border-dark-600 shrink-0 bg-dark-800`,children:[(0,L.jsx)(Ft,{value:S,onChange:C,disabledActions:R}),(0,L.jsxs)(`button`,{onClick:_e,disabled:!!E||k.size>0,className:`btn-accent text-sm disabled:opacity-40 disabled:cursor-not-allowed`,children:[(0,L.jsx)(De,{size:12,className:`inline mr-1`}),u(`btn.execute`)]}),E&&E.status===`running`&&(0,L.jsxs)(`button`,{onClick:async()=>{try{await D.cancelTask(E.id)}catch{}},className:`btn-danger text-sm`,children:[(0,L.jsx)(Oe,{size:12,className:`inline mr-1`}),u(`btn.cancel`)]}),(0,L.jsx)(`div`,{className:`h-5 border-l border-dark-500`}),(0,L.jsxs)(`button`,{onClick:je,className:`btn-secondary text-sm`,children:[(0,L.jsx)(pe,{size:14,className:`inline mr-1`}),`В Mafile Manager`]}),(0,L.jsx)(`div`,{className:`h-5 border-l border-dark-500`}),(0,L.jsxs)(`button`,{onClick:Ne,className:`btn-secondary text-sm`,children:[(0,L.jsx)(me,{size:14,className:`inline mr-1`}),u(`btn.assignProxies`)]}),(0,L.jsxs)(`button`,{onClick:Pe,className:`btn-secondary text-sm`,children:[(0,L.jsx)(he,{size:14,className:`inline mr-1`}),u(`btn.reassign`)]}),(0,L.jsxs)(`button`,{onClick:Fe,className:`btn-danger-outline text-sm`,children:[(0,L.jsx)(ge,{size:14,className:`inline mr-1`}),u(`btn.clearProxies`)]}),(0,L.jsx)(`div`,{className:`ml-auto`,children:(0,L.jsx)(`input`,{type:`text`,value:te,onChange:e=>j(e.target.value),placeholder:u(`ph.search`),className:`bg-dark-700 border border-dark-600 rounded px-2 py-1.5 text-xs w-80 placeholder:text-gray-500 outline-none focus:border-accent`})})]}),(0,L.jsx)(`div`,{className:`overflow-auto flex-1 min-h-0`,children:(0,L.jsx)(ot,{accounts:oe,processingIds:k,accountResults:ne,accountSteps:ie,onEdit:xe,onDelete:we,onAction:de,onToggleAutoAccept:be,onOpenBrowser:Me})})]})]}),Le&&(0,L.jsx)(st,{account:Le,onSave:Se,onClose:()=>f(null)}),p&&(0,L.jsx)(ct,{onClose:()=>m(!1),onImportDone:Ie}),h&&(0,L.jsx)(lt,{onSave:Ae,onClose:()=>g(!1)}),_&&b&&(0,L.jsx)(ut,{message:_,onConfirm:()=>{b(),v(null),x(null)},onCancel:()=>{v(null),x(null)}}),M&&(0,L.jsx)(`div`,{className:`fixed inset-0 bg-black/60 flex items-center justify-center z-50`,onMouseDown:z,children:(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-lg p-5 w-96 shadow-xl`,onMouseDown:e=>e.stopPropagation(),children:[(0,L.jsx)(`p`,{className:`text-sm text-gray-300 mb-3`,children:M.message}),(0,L.jsx)(`input`,{autoFocus:!0,value:P,onChange:e=>F(e.target.value),onKeyDown:e=>e.key===`Enter`&&fe(),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm mb-3`,placeholder:u(`prompt.enterValue`)}),(0,L.jsxs)(`div`,{className:`flex gap-2`,children:[(0,L.jsx)(`button`,{onClick:fe,className:`btn-primary flex-1`,children:`OK`}),(0,L.jsx)(`button`,{onClick:z,className:`btn-secondary flex-1`,children:u(`btn.cancel`)})]})]})})]})}function Rt(){let e=I(),[t,n]=(0,y.useState)(`secret`),[r,i]=(0,y.useState)(``),[a,o]=(0,y.useState)(``),[s,c]=(0,y.useState)(``),[l,u]=(0,y.useState)(null),[d,f]=(0,y.useState)(!1),p=(0,y.useRef)(null),m=A(e=>e.addToast),h=ze(e=>e.accounts),g=ze(e=>e.loadAccounts);(0,y.useEffect)(()=>{t===`account`&&h.length===0&&g()},[t]),(0,y.useEffect)(()=>{let e=e=>{p.current&&!p.current.contains(e.target)&&f(!1)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[]);let _=h.filter(e=>{let t=s.toLowerCase();return!t||e.login.toLowerCase().includes(t)||(e.steam_id??``).includes(t)}).slice(0,12),v=async()=>{try{if(t===`secret`){if(!r.trim())return;o((await D.generate2FA(r.trim())).code)}else{if(!l)return;o((await D.generate2FAByAccount(l.id)).code)}}catch(t){o(e(`tools.genErrorStr`)),m(`error`,e(`misc.genError`,{error:t instanceof Error?t.message:String(t)}))}},b=async()=>{if(!a||a===e(`tools.genErrorStr`))return;let t=await Ue(a);m(t?`success`:`error`,e(t?`toast.copied`:`toast.copyFailed`))},x=e=>`flex-1 py-1.5 text-xs font-medium rounded transition-colors ${t===e?`bg-dark-600 text-gray-100`:`text-gray-500 hover:text-gray-300`}`;return(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-xl overflow-hidden flex flex-col`,children:[(0,L.jsxs)(`div`,{className:`px-4 py-3 border-b border-dark-600 flex items-center gap-2`,children:[(0,L.jsx)(ve,{size:14,className:`text-accent shrink-0`}),(0,L.jsx)(`span`,{className:`text-sm font-semibold text-gray-100`,children:e(`tools.2faGenerator`)})]}),(0,L.jsxs)(`div`,{className:`px-4 pt-3 pb-2`,children:[(0,L.jsxs)(`div`,{className:`flex gap-1 bg-dark-900 rounded p-0.5 mb-3`,children:[(0,L.jsx)(`button`,{type:`button`,className:x(`secret`),onClick:()=>n(`secret`),children:`Shared secret`}),(0,L.jsx)(`button`,{type:`button`,className:x(`account`),onClick:()=>n(`account`),children:`Из Mafile`})]}),t===`secret`?(0,L.jsxs)(`div`,{className:`flex gap-2`,children:[(0,L.jsx)(`input`,{value:r,onChange:e=>i(e.target.value),onKeyDown:e=>e.key===`Enter`&&v(),placeholder:`shared_secret`,className:`flex-1 bg-dark-700 border border-dark-600 rounded px-3 py-1.5 text-sm`}),(0,L.jsx)(`button`,{type:`button`,onClick:v,className:`btn-primary text-sm px-3 py-1.5`,children:e(`btn.generate`)})]}):(0,L.jsxs)(`div`,{className:`flex gap-2`,children:[(0,L.jsxs)(`div`,{className:`relative flex-1`,ref:p,children:[(0,L.jsx)(`input`,{value:l?`${l.login}${l.steam_id?` · `+l.steam_id:``}`:s,onChange:e=>{c(e.target.value),u(null),f(!0)},onFocus:()=>f(!0),placeholder:`Логин или SteamID...`,className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-1.5 text-sm`}),d&&_.length>0&&(0,L.jsx)(`div`,{className:`absolute top-full mt-1 left-0 right-0 bg-dark-800 border border-dark-600 rounded-lg shadow-xl z-50 max-h-48 overflow-y-auto`,children:_.map(e=>(0,L.jsxs)(`button`,{type:`button`,className:`w-full text-left px-3 py-1.5 text-sm hover:bg-dark-600 transition-colors flex items-center justify-between gap-2`,onMouseDown:()=>{u(e),c(``),f(!1)},children:[(0,L.jsx)(`span`,{className:`text-gray-200 truncate`,children:e.login}),e.steam_id&&(0,L.jsx)(`span`,{className:`text-gray-500 text-xs shrink-0`,children:e.steam_id})]},e.id))})]}),(0,L.jsx)(`button`,{type:`button`,onClick:v,disabled:!l,className:`btn-primary text-sm px-3 py-1.5 disabled:opacity-40 disabled:cursor-not-allowed`,children:e(`btn.generate`)})]}),a&&(0,L.jsx)(`div`,{className:`mt-3 text-2xl font-mono text-accent cursor-pointer tabular-nums tracking-widest`,onClick:b,title:e(`tools.clickCopy`),children:a})]})]})}var zt=[{value:`login:pass@ip:port`,label:`login:pass@ip:port`},{value:`login:pass:ip:port`,label:`login:pass:ip:port`},{value:`ip:port@login:pass`,label:`ip:port@login:pass`},{value:`ip:port:login:pass`,label:`ip:port:login:pass`}];function Bt(e,t,n,r){let i=e.trim();if(!i)return null;let a=n;for(let e of[`socks5://`,`socks4://`,`http://`,`https://`])if(i.toLowerCase().startsWith(e)){a=e.replace(`://`,``),i=i.slice(e.length);break}if(!i.includes(`@`)&&i.split(`:`).length===2)return{address:i,protocol:a};let o=``,s=``,c=``,l=``;if(t===`custom`&&r&&r.length>=4){let e=Vt(i,r);if(!e)return null;({ip:o,port:s,login:c,pass:l}=e)}else if(t===`login:pass@ip:port`){let e=i.indexOf(`@`);if(e===-1)return null;let t=i.slice(0,e),n=i.slice(e+1),r=t.split(`:`),a=n.split(`:`);if(r.length<2||a.length<2)return null;c=r[0],l=r.slice(1).join(`:`),o=a[0],s=a[1]}else if(t===`login:pass:ip:port`){let e=i.split(`:`);if(e.length<4)return null;c=e[0],l=e[1],o=e[2],s=e[3]}else if(t===`ip:port@login:pass`){let e=i.indexOf(`@`);if(e===-1)return null;let t=i.slice(0,e),n=i.slice(e+1),r=t.split(`:`),a=n.split(`:`);if(r.length<2||a.length<2)return null;o=r[0],s=r[1],c=a[0],l=a.slice(1).join(`:`)}else if(t===`ip:port:login:pass`){let e=i.split(`:`);if(e.length<4)return null;o=e[0],s=e[1],c=e[2],l=e[3]}return!o||!s?null:{address:c&&l?`${c}:${l}@${o}:${s}`:`${o}:${s}`,protocol:a}}function Vt(e,t){let n=[],r=[];for(let e=0;ee.addToast),x=I(),S=async()=>{try{t(await D.getProxies())}catch{}};(0,y.useEffect)(()=>{S()},[]);let C=async e=>{let t=e.split(` +`).filter(e=>e.trim());if(!t.length)return;let n=f?`custom`:c,i=[];for(let e of t){let t=Bt(e,n,u,f?m:void 0);t&&i.push(t)}if(!i.length){b(`error`,x(`toast.proxyFormatError`));return}try{b(`success`,x(`toast.proxiesAdded`,{count:(await D.bulkAddProxies(i)).added})),r(``),await S()}catch(e){b(`error`,x(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}},w=()=>C(n),T=async e=>{e.preventDefault(),_(!1);let t=e.dataTransfer.files[0];t&&await C(await t.text())},E=async e=>{let t=e.target.files?.[0];t&&(await C(await t.text()),e.target.value=``)},O=async e=>{try{await D.deleteProxy(e),await S()}catch(e){b(`error`,x(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}},k=async()=>{if(e.length&&window.confirm(x(`proxy.confirmDeleteAll`)))try{b(`success`,x(`toast.proxiesDeleted`,{count:(await D.deleteAllProxies()).deleted})),s(``),await S()}catch(e){b(`error`,x(`misc.error`,{error:e instanceof Error?e.message:String(e)}))}},ee=async()=>{a(!0),s(``);try{let e=await D.checkProxies();s(x(`proxy.checkResult`,{total:e.total,alive:e.alive,dead:e.dead})),await S()}catch(e){b(`error`,x(`misc.proxyErrorCheck`,{error:e instanceof Error?e.message:String(e)}))}finally{a(!1)}},te=(e,t)=>{let n=[...m];n[e]=t,h(n)},j=m.join(``);return(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-lg p-4`,children:[(0,L.jsxs)(`h3`,{className:`font-semibold mb-3`,children:[(0,L.jsx)(me,{size:14,className:`inline mr-1`}),x(`proxy.title`),` `,(0,L.jsx)(`span`,{className:`text-xs text-gray-500 ml-2`,children:x(`proxy.count`,{count:e.length})})]}),(0,L.jsxs)(`div`,{className:`mb-3 space-y-2`,children:[(0,L.jsxs)(`div`,{className:`flex items-center gap-3 flex-wrap`,children:[(0,L.jsx)(`span`,{className:`text-xs text-gray-400`,children:x(`proxy.protocol`)}),(0,L.jsxs)(`select`,{value:u,onChange:e=>d(e.target.value),className:`bg-dark-700 border border-dark-600 rounded px-2 py-1 text-xs`,children:[(0,L.jsx)(`option`,{value:`http`,children:`HTTP`}),(0,L.jsx)(`option`,{value:`socks5`,children:`SOCKS5`})]}),(0,L.jsx)(`span`,{className:`text-xs text-gray-400`,children:x(`proxy.format`)}),(0,L.jsxs)(`select`,{value:f?`__custom__`:c,onChange:e=>{e.target.value===`__custom__`?p(!0):(p(!1),l(e.target.value))},className:`bg-dark-700 border border-dark-600 rounded px-2 py-1 text-xs`,children:[zt.map(e=>(0,L.jsx)(`option`,{value:e.value,children:e.label},e.value)),(0,L.jsx)(`option`,{value:`__custom__`,children:x(`proxy.customFormat`)})]})]}),f&&(0,L.jsxs)(`div`,{className:`bg-dark-700 border border-dark-600 rounded p-3 space-y-2`,children:[(0,L.jsx)(`p`,{className:`text-xs text-gray-400`,children:x(`proxy.formatConstructor`)}),(0,L.jsx)(`div`,{className:`flex items-center gap-1 flex-wrap`,children:m.map((e,t)=>t%2==0?(0,L.jsx)(`select`,{value:e,onChange:e=>te(t,e.target.value),className:`bg-dark-600 border border-dark-500 rounded px-2 py-1 text-xs text-accent`,children:Ht.map(e=>(0,L.jsx)(`option`,{value:e,children:e},e))},t):(0,L.jsx)(`select`,{value:e,onChange:e=>te(t,e.target.value),className:`bg-dark-600 border border-dark-500 rounded px-1 py-1 text-xs text-yellow-400 w-10 text-center`,children:Ut.map(e=>(0,L.jsx)(`option`,{value:e,children:e},e))},t))}),(0,L.jsxs)(`p`,{className:`text-xs text-gray-500`,children:[x(`proxy.preview`),` `,(0,L.jsx)(`span`,{className:`text-gray-300`,children:j})]})]})]}),(0,L.jsxs)(`div`,{onDragOver:e=>{e.preventDefault(),_(!0)},onDragLeave:()=>_(!1),onDrop:T,onClick:()=>v.current?.click(),className:`border-2 border-dashed rounded-lg p-4 mb-2 text-center cursor-pointer transition-colors ${g?`border-accent bg-accent/10`:`border-dark-500 hover:border-accent`}`,children:[(0,L.jsx)(ce,{size:24,className:`mx-auto mb-1 text-gray-500`}),(0,L.jsx)(`p`,{className:`text-xs text-gray-400`,children:x(`proxy.dragFile`)})]}),(0,L.jsx)(`input`,{ref:v,type:`file`,accept:`.txt`,className:`hidden`,onChange:E}),(0,L.jsx)(`textarea`,{value:n,onChange:e=>r(e.target.value),rows:4,placeholder:x(`proxy.perLine`,{format:f?j:c}),className:`w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm mb-2 resize-y`}),(0,L.jsxs)(`div`,{className:`flex gap-2 mb-3 flex-wrap`,children:[(0,L.jsx)(`button`,{onClick:w,className:`btn-primary`,children:x(`proxy.addBtn`)}),(0,L.jsx)(`button`,{onClick:ee,disabled:i,className:`btn-secondary`,children:x(i?`proxy.checking`:`proxy.checkAll`)}),e.length>0&&(0,L.jsx)(`button`,{onClick:k,className:`btn-danger text-xs`,children:x(`proxy.deleteAllBtn`)})]}),o&&(0,L.jsx)(`p`,{className:`text-xs text-gray-300 mb-3`,children:o}),e.length>0&&(()=>{let t=e.filter(e=>e.is_alive).length,n=e.length-t;return(0,L.jsxs)(`p`,{className:`text-xs text-gray-400 mb-3`,children:[(0,L.jsxs)(`span`,{className:`text-green-400`,children:[`● `,t]}),(0,L.jsx)(`span`,{className:`mx-2`,children:`/`}),(0,L.jsxs)(`span`,{className:`text-red-400`,children:[`● `,n]}),(0,L.jsx)(`span`,{className:`mx-2`,children:`/`}),(0,L.jsx)(`span`,{children:e.length})]})})(),(0,L.jsx)(`div`,{className:`max-h-48 overflow-y-auto space-y-1`,children:e.map(e=>(0,L.jsxs)(`div`,{className:`flex items-center justify-between text-xs gap-2 group px-2 py-1 rounded hover:bg-dark-700`,children:[(0,L.jsxs)(`span`,{className:`${e.is_alive?`text-green-400`:`text-red-400`} min-w-0 truncate`,children:[e.protocol,`://`,e.address]}),(0,L.jsx)(`button`,{onClick:()=>O(e.id),className:`text-red-400 hover:bg-red-400/20 rounded px-2 py-0.5 text-sm font-medium shrink-0 transition`,title:x(`proxy.deleteProxy`),children:`✕`})]},e.id))})]})}function Gt({checked:e,onChange:t}){return(0,L.jsxs)(`label`,{className:`toggle-switch`,children:[(0,L.jsx)(`input`,{type:`checkbox`,checked:e,onChange:e=>t(e.target.checked)}),(0,L.jsx)(`span`,{className:`toggle-track`})]})}function Kt({label:e,desc:t,checked:n,onChange:r}){return(0,L.jsxs)(`div`,{className:`flex items-center justify-between gap-4 py-2.5`,children:[(0,L.jsxs)(`div`,{className:`min-w-0`,children:[(0,L.jsx)(`p`,{className:`text-sm text-gray-200 leading-tight`,children:e}),t&&(0,L.jsx)(`p`,{className:`text-xs text-gray-500 mt-0.5`,children:t})]}),(0,L.jsx)(Gt,{checked:n,onChange:r})]})}function qt({value:e,onChange:t}){let[n,r]=(0,y.useState)(!1),[i,a]=(0,y.useState)(``),o=(0,y.useRef)(null),s=e=>Math.max(1,e),c=()=>{t(s(parseInt(i)||e)),r(!1)},l=`h-6 px-1.5 rounded bg-dark-700 border border-dark-600 text-gray-300 hover:bg-dark-600 text-xs flex items-center justify-center select-none leading-none`;return(0,L.jsxs)(`div`,{className:`flex items-center gap-3 pt-3 mt-0.5`,children:[(0,L.jsx)(`span`,{className:`text-sm text-gray-400 flex-1`,title:`Двойной клик на числе для ручного ввода`,children:`Max threads`}),(0,L.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,L.jsx)(`button`,{type:`button`,className:l,onClick:()=>t(s(e-10)),children:`-10`}),(0,L.jsx)(`button`,{type:`button`,className:l,onClick:()=>t(s(e-1)),children:`-1`}),n?(0,L.jsx)(`input`,{ref:o,autoFocus:!0,value:i,onChange:e=>a(e.target.value),onBlur:c,onKeyDown:e=>{e.key===`Enter`&&c(),e.key===`Escape`&&r(!1)},className:`w-10 text-center text-sm font-mono bg-dark-900 border border-accent rounded outline-none text-gray-100 py-0.5`}):(0,L.jsx)(`span`,{className:`w-10 text-center text-sm font-mono text-gray-100 cursor-pointer select-none`,onDoubleClick:()=>{a(String(e)),r(!0)},title:`Двойной клик для ручного ввода`,children:e}),(0,L.jsx)(`button`,{type:`button`,className:l,onClick:()=>t(s(e+1)),children:`+1`}),(0,L.jsx)(`button`,{type:`button`,className:l,onClick:()=>t(s(e+10)),children:`+10`})]})]})}function Jt(){let e=I(),[t,n]=(0,y.useState)({fetch_profile:!0,check_ban:!0,max_threads:5,auto_revalidate_browser:!0,auto_proxy_on_import:!1,auto_validate_on_import:!1,auto_proxy_on_import_mafile:!0,auto_proxy_on_import_logpass:!0,auto_proxy_on_import_token:!0,auto_validate_on_import_mafile:!0,auto_validate_on_import_logpass:!0,auto_validate_on_import_token:!0}),[r,i]=(0,y.useState)(`mafile`),a=A(e=>e.hidePasswords),o=A(e=>e.setHidePasswords),s=A(e=>e.loadImportSettings),c=A(e=>e.addToast);return(0,y.useEffect)(()=>{D.getValidationSettings().then(n).catch(()=>{})},[]),(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-xl overflow-hidden flex flex-col`,children:[(0,L.jsxs)(`div`,{className:`px-5 py-3.5 border-b border-dark-600 flex items-center gap-2.5`,children:[(0,L.jsx)(be,{size:15,className:`text-accent shrink-0`}),(0,L.jsx)(`span`,{className:`text-sm font-semibold text-gray-100`,children:`Settings`})]}),(0,L.jsxs)(`div`,{className:`px-5 pt-4 pb-3 border-b border-dark-600`,children:[(0,L.jsx)(`p`,{className:`text-[10px] font-semibold text-gray-500 uppercase tracking-widest mb-0.5`,children:e(`tools.validationSettings`)}),(0,L.jsxs)(`div`,{className:`divide-y divide-dark-600/60`,children:[(0,L.jsx)(Kt,{label:e(`tools.loadProfile`),checked:t.fetch_profile,onChange:e=>n({...t,fetch_profile:e})}),(0,L.jsx)(Kt,{label:e(`tools.checkBans`),checked:t.check_ban,onChange:e=>n({...t,check_ban:e})}),(0,L.jsx)(Kt,{label:e(`tools.autoRevalidateBrowser`),checked:t.auto_revalidate_browser,onChange:e=>n({...t,auto_revalidate_browser:e})})]}),(0,L.jsx)(qt,{value:t.max_threads,onChange:e=>n(t=>({...t,max_threads:e}))})]}),(0,L.jsxs)(`div`,{className:`px-5 pt-4 pb-3 border-b border-dark-600`,children:[(0,L.jsx)(`p`,{className:`text-[10px] font-semibold text-gray-500 uppercase tracking-widest mb-1.5`,children:e(`tools.importSettings`)}),(0,L.jsx)(`div`,{className:`flex gap-1 mb-3`,children:[`mafile`,`logpass`,`token`].map(t=>(0,L.jsx)(`button`,{type:`button`,onClick:()=>i(t),className:`px-2.5 py-1 rounded text-xs font-medium transition-colors ${r===t?`bg-accent/20 text-accent border border-accent/30`:`text-gray-500 hover:text-gray-300 border border-transparent`}`,children:e(`tools.importTab${t.charAt(0).toUpperCase()+t.slice(1)}`)},t))}),[`mafile`,`logpass`,`token`].map(i=>r===i?(0,L.jsxs)(`div`,{className:`divide-y divide-dark-600/60`,children:[(0,L.jsx)(Kt,{label:e(`tools.autoProxyOnImport`),desc:e(`tools.autoProxyOnImportDesc`),checked:t[`auto_proxy_on_import_${i}`],onChange:e=>n({...t,[`auto_proxy_on_import_${i}`]:e})}),(0,L.jsx)(Kt,{label:e(`tools.autoValidateOnImport`),desc:e(`tools.autoValidateOnImportDesc`),checked:t[`auto_validate_on_import_${i}`],onChange:e=>n({...t,[`auto_validate_on_import_${i}`]:e})})]},i):null)]}),(0,L.jsxs)(`div`,{className:`px-5 pt-4 pb-3`,children:[(0,L.jsx)(`p`,{className:`text-[10px] font-semibold text-gray-500 uppercase tracking-widest mb-0.5`,children:e(`settings.display`)}),(0,L.jsx)(Kt,{label:e(`settings.hidePasswords`),checked:a,onChange:o})]}),(0,L.jsx)(`div`,{className:`px-5 py-3 border-t border-dark-600 flex justify-end`,children:(0,L.jsx)(`button`,{onClick:async()=>{try{await D.updateValidationSettings(t),await s(),c(`success`,e(`toast.settingsSaved`))}catch(t){c(`error`,e(`misc.error`,{error:t instanceof Error?t.message:String(t)}))}},className:`btn-primary`,children:e(`btn.save`)})})]})}function Yt(){return(0,L.jsxs)(`div`,{className:`max-w-5xl mx-auto flex flex-col gap-4`,children:[(0,L.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-2 gap-4`,children:[(0,L.jsx)(Rt,{}),(0,L.jsx)(Jt,{})]}),(0,L.jsx)(Wt,{})]})}var Xt=[`shared_secret`,`serial_number`,`revocation_code`,`uri`,`account_name`,`token_gid`,`identity_secret`,`secret_1`,`device_id`,`server_time`,`fully_enrolled`],Zt=[`SessionID`,`AccessToken`,`RefreshToken`,`SteamID`,`SteamLoginSecure`],Qt=[{value:`{username}`,label:`username`},{value:`{steamid}`,label:`steamid`}],$t=[{value:`flat_mafiles`,icon:`📄`},{value:`per_account_folder`,icon:`📁`},{value:`single_file`,icon:`📦`}];function en({accountIds:e,onExport:t}){let n=I(),[r,i]=(0,y.useState)(new Set(Xt)),[a,o]=(0,y.useState)(new Set(Zt)),[s,c]=(0,y.useState)(`per_account_folder`),[l,u]=(0,y.useState)(`{username}`),[d,f]=(0,y.useState)(`{steamid}.mafile`),[p,m]=(0,y.useState)(`{username}.txt`),[h,g]=(0,y.useState)(!1),[_,v]=(0,y.useState)(!1),[b,x]=(0,y.useState)(!1),[S,C]=(0,y.useState)(`{login}:{password}:{email}:{email_password}`),w=(e,t,n)=>{let r=new Set(e);r.has(t)?r.delete(t):r.add(t),n(r)},T=(e,t)=>{e(e=>e+t)};return(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-xl overflow-hidden`,children:[(0,L.jsxs)(`div`,{className:`px-4 py-3 border-b border-dark-600 flex items-center gap-2`,children:[(0,L.jsx)(we,{size:14,className:`text-accent`}),(0,L.jsx)(`h4`,{className:`font-semibold text-sm`,children:n(`mafile.exportSettings`)})]}),(0,L.jsxs)(`div`,{className:`p-4 space-y-4`,children:[(0,L.jsxs)(`div`,{children:[(0,L.jsx)(`p`,{className:`text-xs text-gray-400 mb-2`,children:n(`mafile.exportFormat`)}),(0,L.jsx)(`div`,{className:`grid grid-cols-3 gap-2`,children:$t.map(e=>(0,L.jsxs)(`button`,{onClick:()=>{c(e.value),e.value===`single_file`&&(v(!1),x(!1))},className:`flex flex-col items-center gap-1 p-3 rounded-lg border text-xs transition-all cursor-pointer ${s===e.value?`border-accent bg-accent/10 text-white`:`border-dark-600 bg-dark-700 text-gray-400 hover:border-dark-500 hover:text-gray-300`}`,children:[(0,L.jsx)(`span`,{className:`text-base`,children:e.icon}),(0,L.jsx)(`span`,{children:n(`mafile.${e.value}`)})]},e.value))})]}),s!==`single_file`&&(0,L.jsxs)(`details`,{className:`group`,open:!0,children:[(0,L.jsxs)(`summary`,{className:`text-xs text-gray-400 cursor-pointer hover:text-gray-300 transition-colors flex items-center gap-1.5 select-none`,children:[(0,L.jsx)(Fe,{size:12,className:`transition-transform group-open:rotate-90`}),n(`mafile.namingSection`),(0,L.jsxs)(`span`,{className:`text-gray-500 ml-1`,children:[(0,L.jsx)(`code`,{className:`text-accent/70`,children:`{username}`}),` `,(0,L.jsx)(`code`,{className:`text-accent/70`,children:`{steamid}`})]})]}),(0,L.jsxs)(`div`,{className:`mt-3 space-y-3 pl-4 border-l border-dark-600`,children:[s===`per_account_folder`&&(0,L.jsx)(tn,{label:n(`mafile.folderName`),value:l,onChange:u,vars:Qt,insertVar:T}),(0,L.jsx)(tn,{label:n(`mafile.mafileName`),value:d,onChange:f,vars:Qt,insertVar:T})]})]}),(0,L.jsxs)(`details`,{className:`group`,children:[(0,L.jsxs)(`summary`,{className:`text-xs text-gray-400 cursor-pointer hover:text-gray-300 transition-colors flex items-center gap-1.5 select-none`,children:[(0,L.jsx)(Fe,{size:12,className:`transition-transform group-open:rotate-90`}),(0,L.jsx)(Te,{size:12,className:`inline`}),n(`mafile.txtSettings`)]}),(0,L.jsxs)(`div`,{className:`mt-3 space-y-2.5 pl-4 border-l border-dark-600`,children:[s!==`single_file`&&(0,L.jsxs)(L.Fragment,{children:[(0,L.jsxs)(nn,{checked:_,onChange:e=>{v(e),e||x(!1)},children:[n(`mafile.addGlobalTxt`),` `,(0,L.jsx)(`code`,{className:`text-accent text-xs`,children:`accounts.txt`})]}),s===`per_account_folder`&&(0,L.jsx)(nn,{checked:h,onChange:g,children:n(`mafile.addTxtPerFolder`)}),(0,L.jsx)(nn,{checked:b,onChange:x,disabled:!_,children:n(`mafile.skipFolders`)})]}),(_||h||s===`single_file`)&&(0,L.jsxs)(`div`,{className:`space-y-3 pt-1`,children:[s===`per_account_folder`&&h&&(0,L.jsx)(tn,{label:n(`mafile.txtFolderName`),value:p,onChange:m,vars:Qt,insertVar:T}),(0,L.jsxs)(`div`,{children:[(0,L.jsx)(`label`,{className:`text-xs text-gray-400 block mb-1`,children:n(`mafile.txtLineFormat`)}),(0,L.jsx)(`input`,{value:S,onChange:e=>C(e.target.value),className:`w-full bg-dark-700 border border-dark-600 rounded-lg px-3 py-1.5 text-sm font-mono focus:border-accent/50 focus:outline-none transition-colors`}),(0,L.jsxs)(`p`,{className:`text-[11px] text-gray-500 mt-1.5 leading-relaxed`,children:[n(`mafile.variables`),` `,(0,L.jsx)(`code`,{className:`text-accent/70`,children:`{login}`}),` `,(0,L.jsx)(`code`,{className:`text-accent/70`,children:`{password}`}),` `,(0,L.jsx)(`code`,{className:`text-accent/70`,children:`{email}`}),` `,(0,L.jsx)(`code`,{className:`text-accent/70`,children:`{email_password}`}),` `,(0,L.jsx)(`code`,{className:`text-accent/70`,children:`{steam_id}`}),` `,(0,L.jsx)(`code`,{className:`text-accent/70`,children:`{proxy}`}),` `,(0,L.jsx)(`code`,{className:`text-accent/70`,children:`{mafile}`})]})]})]})]})]}),(0,L.jsxs)(`details`,{className:`group`,children:[(0,L.jsxs)(`summary`,{className:`text-xs text-gray-400 cursor-pointer hover:text-gray-300 transition-colors flex items-center gap-1.5 select-none`,children:[(0,L.jsx)(Fe,{size:12,className:`transition-transform group-open:rotate-90`}),n(`mafile.mafileFields`),(0,L.jsxs)(`span`,{className:`text-gray-500 text-[11px]`,children:[r.size,`/`,Xt.length]})]}),(0,L.jsx)(`div`,{className:`flex flex-wrap gap-x-3 gap-y-1.5 mt-2 pl-4`,children:Xt.map(e=>(0,L.jsxs)(`label`,{className:`flex items-center gap-1.5 text-xs cursor-pointer hover:text-gray-200 transition-colors`,children:[(0,L.jsx)(`input`,{type:`checkbox`,checked:r.has(e),onChange:()=>w(r,e,i),className:`accent-accent`}),(0,L.jsx)(`span`,{className:`font-mono text-[11px]`,children:e})]},e))})]}),(0,L.jsxs)(`details`,{className:`group`,children:[(0,L.jsxs)(`summary`,{className:`text-xs text-gray-400 cursor-pointer hover:text-gray-300 transition-colors flex items-center gap-1.5 select-none`,children:[(0,L.jsx)(Fe,{size:12,className:`transition-transform group-open:rotate-90`}),n(`mafile.sessionFields`),(0,L.jsxs)(`span`,{className:`text-gray-500 text-[11px]`,children:[a.size,`/`,Zt.length]})]}),(0,L.jsx)(`div`,{className:`flex flex-wrap gap-x-3 gap-y-1.5 mt-2 pl-4`,children:Zt.map(e=>(0,L.jsxs)(`label`,{className:`flex items-center gap-1.5 text-xs cursor-pointer hover:text-gray-200 transition-colors`,children:[(0,L.jsx)(`input`,{type:`checkbox`,checked:a.has(e),onChange:()=>w(a,e,o),className:`accent-accent`}),(0,L.jsx)(`span`,{className:`font-mono text-[11px]`,children:e})]},e))})]}),(0,L.jsxs)(`button`,{onClick:()=>{t({fields:[...r],session_fields:[...a],format:s,account_ids:e,folder_name_template:l,mafile_name_template:d,txt_name_template:p,include_txt_per_folder:h,include_global_txt:_,skip_folders:b,txt_format:S})},disabled:e.length===0,className:`w-full flex items-center justify-center gap-2 py-2.5 rounded-lg font-medium text-sm transition-all ${e.length===0?`bg-dark-700 text-gray-500 cursor-not-allowed`:`bg-accent hover:bg-accent-hover text-white cursor-pointer`}`,children:[(0,L.jsx)(se,{size:14}),n(`mafile.export`),` (`,e.length>0?e.length:n(`mafile.noAccounts`),`)`]})]})]})}function tn({label:e,value:t,onChange:n,vars:r,insertVar:i}){return(0,L.jsxs)(`div`,{children:[(0,L.jsx)(`label`,{className:`text-xs text-gray-400 block mb-1`,children:e}),(0,L.jsxs)(`div`,{className:`flex gap-1.5`,children:[(0,L.jsx)(`input`,{value:t,onChange:e=>n(e.target.value),className:`flex-1 bg-dark-700 border border-dark-600 rounded-lg px-3 py-1.5 text-sm font-mono focus:border-accent/50 focus:outline-none transition-colors`}),r.map(e=>(0,L.jsx)(`button`,{onClick:()=>i(e=>n(e(t)),e.value),className:`px-2 py-1 text-[11px] rounded bg-dark-700 border border-dark-600 text-gray-400 hover:text-accent hover:border-accent/30 transition-colors cursor-pointer`,children:e.label},e.value))]})]})}function nn({checked:e,onChange:t,disabled:n,children:r}){return(0,L.jsxs)(`label`,{className:`flex items-center gap-2.5 text-sm cursor-pointer select-none ${n?`opacity-40 cursor-not-allowed`:`hover:text-gray-200`} transition-colors`,children:[(0,L.jsx)(`input`,{type:`checkbox`,checked:e,disabled:n,onChange:e=>t(e.target.checked),className:`accent-accent`}),(0,L.jsx)(`span`,{className:`text-xs`,children:r})]})}function rn(){let e=I(),t=ze(e=>e.accounts),n=ze(e=>e.mafileManagerIds),r=ze(e=>e.clearMafileManager),i=A(e=>e.addToast),a=t.filter(e=>n.has(e.id)),o=async t=>{try{let n=await D.exportZip(t),r=URL.createObjectURL(n),a=document.createElement(`a`);a.href=r,a.download=`mafiles_export.zip`,a.click(),URL.revokeObjectURL(r),i(`success`,e(`toast.exportDone`))}catch(t){i(`error`,e(`misc.exportError`,{error:t instanceof Error?t.message:String(t)}))}},s=a.filter(e=>e.mafile_path).length;return(0,L.jsx)(`div`,{className:`h-full overflow-y-auto pr-1`,children:(0,L.jsxs)(`div`,{className:`max-w-2xl mx-auto space-y-5 py-2`,children:[a.length===0&&(0,L.jsxs)(`div`,{className:`flex flex-col items-center justify-center py-16 text-center`,children:[(0,L.jsx)(`div`,{className:`w-14 h-14 rounded-2xl bg-dark-700 flex items-center justify-center mb-4`,children:(0,L.jsx)(we,{size:24,className:`text-gray-500`})}),(0,L.jsx)(`p`,{className:`text-gray-400 text-sm mb-1`,children:e(`mafile.emptyTitle`)}),(0,L.jsx)(`p`,{className:`text-gray-500 text-xs max-w-xs`,children:e(`mafile.emptyHint`)})]}),a.length>0&&(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-xl overflow-hidden`,children:[(0,L.jsxs)(`div`,{className:`flex items-center justify-between px-4 py-3 border-b border-dark-600`,children:[(0,L.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,L.jsx)(Ee,{size:14,className:`text-accent`}),(0,L.jsx)(`h3`,{className:`font-semibold text-sm`,children:e(`mafile.sentAccounts`)}),(0,L.jsxs)(`span`,{className:`text-xs text-gray-500`,children:[a.length,` `,e(`mafile.accountsCount`),` · `,s,` `,e(`mafile.withMafile`)]})]}),(0,L.jsx)(`button`,{onClick:r,className:`text-xs text-red-400 hover:text-red-300 transition-colors cursor-pointer`,children:e(`mafile.clearBtn`)})]}),(0,L.jsx)(`div`,{className:`max-h-56 overflow-y-auto divide-y divide-dark-700`,children:a.map(e=>(0,L.jsxs)(`div`,{className:`flex items-center gap-3 px-4 py-2 hover:bg-dark-700/50 transition-colors`,children:[e.avatar_url?(0,L.jsx)(`img`,{src:e.avatar_url,className:`avatar-sm shrink-0`,alt:``}):(0,L.jsx)(`div`,{className:`w-6 h-6 rounded bg-dark-600 shrink-0`}),(0,L.jsx)(`span`,{className:`text-sm truncate flex-1 min-w-0`,children:e.login}),e.steam_id&&(0,L.jsx)(`span`,{className:`text-xs text-gray-500 font-mono hidden sm:block`,children:e.steam_id}),(0,L.jsx)(`span`,{className:`text-xs px-1.5 py-0.5 rounded ${e.mafile_path?`bg-green-500/10 text-green-400`:`bg-dark-600 text-gray-500`}`,children:e.mafile_path?`mafile`:`—`})]},e.id))})]}),a.length>0&&(0,L.jsx)(en,{accountIds:[...n],onExport:o})]})})}function an(e,t,n=!0){let r=(0,y.useRef)(t);r.current=t,(0,y.useEffect)(()=>{if(!n)return;let t=new EventSource(e);return t.onmessage=e=>{try{r.current(JSON.parse(e.data))}catch{}},t.onerror=()=>{t.close()},()=>t.close()},[e,n])}function on(){let[e,t]=(0,y.useState)([]),n=(0,y.useRef)(null),r=(0,y.useRef)(!0);(0,y.useEffect)(()=>{D.getLogs().then(t).catch(()=>{})},[]),an(`/api/logs/stream`,e=>{t(t=>{let n=[...t,e];return n.length>500&&n.splice(0,n.length-500),n})}),(0,y.useEffect)(()=>{r.current&&n.current&&(n.current.scrollTop=n.current.scrollHeight)},[e]);let i=()=>{if(!n.current)return;let{scrollTop:e,scrollHeight:t,clientHeight:i}=n.current;r.current=t-e-i<40},a=e=>{switch(e){case`error`:case`critical`:return`text-red-400`;case`warning`:return`text-yellow-400`;case`success`:return`text-green-400`;case`debug`:return`text-gray-500`;default:return`text-gray-300`}};return(0,L.jsxs)(`div`,{className:`bg-dark-800 border border-dark-600 rounded-lg flex flex-col`,style:{maxHeight:`calc(100vh - 200px)`},children:[(0,L.jsxs)(`div`,{className:`px-3 py-2 border-b border-dark-600 flex items-center justify-between shrink-0`,children:[(0,L.jsx)(`h3`,{className:`font-semibold text-sm`,children:`📜 Лог`}),(0,L.jsx)(`button`,{onClick:()=>t([]),className:`text-xs text-gray-500 hover:text-gray-300 transition-colors`,children:`Очистить`})]}),(0,L.jsxs)(`div`,{ref:n,onScroll:i,className:`flex-1 overflow-y-auto min-h-0 p-2 font-mono text-xs space-y-px`,children:[e.map((e,t)=>(0,L.jsxs)(`div`,{className:`flex gap-2`,children:[(0,L.jsx)(`span`,{className:`text-gray-600 shrink-0`,children:e.ts}),(0,L.jsx)(`span`,{className:`shrink-0 w-3 text-center ${a(e.level)}`,children:e.icon}),(0,L.jsx)(`span`,{className:`${a(e.level)} break-all min-w-0`,children:e.msg})]},t)),e.length===0&&(0,L.jsx)(`p`,{className:`text-gray-600 text-center py-4`,children:`Нет логов`})]})]})}function sn(){return(0,L.jsx)(on,{})}function cn(){let e=A(e=>e.activeTab),t=A(e=>e.loadDisplaySettings),n=A(e=>e.loadColumnSettings),r=A(e=>e.loadLogpassColumnSettings),i=A(e=>e.loadImportSettings);return(0,y.useEffect)(()=>{t(),n(),r(),i()},[]),(0,L.jsxs)(`div`,{className:`h-dvh bg-dark-900 text-gray-300 flex flex-col overflow-hidden`,children:[(0,L.jsx)(oe,{}),(0,L.jsx)(Le,{}),(0,L.jsxs)(`main`,{className:`flex-1 min-h-0 p-4 w-full overflow-y-auto`,children:[e===`accounts`&&(0,L.jsx)(Lt,{}),e===`tools`&&(0,L.jsx)(Yt,{}),e===`mafiles`&&(0,L.jsx)(rn,{}),e===`logs`&&(0,L.jsx)(sn,{})]}),(0,L.jsx)(Re,{})]})}var ln=class extends y.Component{state={error:null};static getDerivedStateFromError(e){return{error:e}}componentDidCatch(e,t){console.error(`React crash:`,e,t)}render(){let{error:e}=this.state;return e?(0,L.jsxs)(`div`,{style:{padding:32,fontFamily:`monospace`,background:`#0f0f0f`,color:`#f87171`,minHeight:`100vh`},children:[(0,L.jsx)(`h2`,{style:{fontSize:18,marginBottom:12},children:`⚠ SteamPanel failed to start`}),(0,L.jsxs)(`pre`,{style:{whiteSpace:`pre-wrap`,fontSize:13,color:`#fca5a5`},children:[e.message,` + +`,e.stack]}),(0,L.jsx)(`p`,{style:{marginTop:16,color:`#9ca3af`,fontSize:12},children:`Open browser console (F12) for more details, or report this error.`})]}):this.props.children}};(0,w.createRoot)(document.getElementById(`root`)).render((0,L.jsx)(y.StrictMode,{children:(0,L.jsx)(ln,{children:(0,L.jsx)(cn,{})})})); \ No newline at end of file diff --git a/app/static/assets/index-aSRiX3qP.css b/app/static/assets/index-aSRiX3qP.css deleted file mode 100644 index f229131..0000000 --- a/app/static/assets/index-aSRiX3qP.css +++ /dev/null @@ -1,2 +0,0 @@ -/*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */ -@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-200:oklch(88.5% .062 18.334);--color-red-300:oklch(80.8% .114 19.571);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-red-900:oklch(39.6% .141 25.723);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-500:oklch(79.5% .184 86.047);--color-green-200:oklch(92.5% .084 155.995);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-green-600:oklch(62.7% .194 149.214);--color-green-700:oklch(52.7% .154 150.069);--color-blue-300:oklch(80.9% .105 251.813);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-md:28rem;--container-lg:32rem;--container-2xl:42rem;--container-5xl:64rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-wide:.025em;--tracking-wider:.05em;--tracking-widest:.1em;--leading-tight:1.25;--leading-relaxed:1.625;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--animate-spin:spin 1s linear infinite;--blur-sm:8px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-dark-900:#0f0f0f;--color-dark-800:#1a1a1a;--color-dark-700:#252525;--color-dark-600:#333;--color-accent:#4f8cff;--color-accent-hover:#6ba0ff;--color-accent-dim:#3a6fd8}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.top-0{top:calc(var(--spacing) * 0)}.top-full{top:100%}.right-0{right:calc(var(--spacing) * 0)}.left-0{left:calc(var(--spacing) * 0)}.z-10{z-index:10}.z-50{z-index:50}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mx-4{margin-inline:calc(var(--spacing) * 4)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing) * 1)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mr-0\.5{margin-right:calc(var(--spacing) * .5)}.mr-1{margin-right:calc(var(--spacing) * 1)}.mr-2{margin-right:calc(var(--spacing) * 2)}.-mb-px{margin-bottom:-1px}.mb-0\.5{margin-bottom:calc(var(--spacing) * .5)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-2\.5{height:calc(var(--spacing) * 2.5)}.h-3{height:calc(var(--spacing) * 3)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-14{height:calc(var(--spacing) * 14)}.h-dvh{height:100dvh}.h-full{height:100%}.max-h-48{max-height:calc(var(--spacing) * 48)}.max-h-56{max-height:calc(var(--spacing) * 56)}.max-h-\[80vh\]{max-height:80vh}.max-h-\[320px\]{max-height:320px}.min-h-0{min-height:calc(var(--spacing) * 0)}.min-h-\[300px\]{min-height:300px}.w-3{width:calc(var(--spacing) * 3)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-10{width:calc(var(--spacing) * 10)}.w-14{width:calc(var(--spacing) * 14)}.w-28{width:calc(var(--spacing) * 28)}.w-36{width:calc(var(--spacing) * 36)}.w-80{width:calc(var(--spacing) * 80)}.w-96{width:calc(var(--spacing) * 96)}.w-\[560px\]{width:560px}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-\[180px\]{max-width:180px}.max-w-\[200px\]{max-width:200px}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-none{max-width:none}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-\[100px\]{min-width:100px}.min-w-\[160px\]{min-width:160px}.min-w-\[170px\]{min-width:170px}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.rotate-180{rotate:180deg}.animate-spin{animation:var(--animate-spin)}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.resize-y{resize:vertical}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-px>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(1px * var(--tw-space-y-reverse));margin-block-end:calc(1px * calc(1 - var(--tw-space-y-reverse)))}.gap-x-3{column-gap:calc(var(--spacing) * 3)}.gap-y-1\.5{row-gap:calc(var(--spacing) * 1.5)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-dark-600\/60>:not(:last-child)){border-color:#3339}@supports (color:color-mix(in lab, red, red)){:where(.divide-dark-600\/60>:not(:last-child)){border-color:color-mix(in oklab, var(--color-dark-600) 60%, transparent)}}:where(.divide-dark-700>:not(:last-child)){border-color:var(--color-dark-700)}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-accent{border-color:var(--color-accent)}.border-blue-500\/30{border-color:#3080ff4d}@supports (color:color-mix(in lab, red, red)){.border-blue-500\/30{border-color:color-mix(in oklab, var(--color-blue-500) 30%, transparent)}}.border-dark-600{border-color:var(--color-dark-600)}.border-dark-700{border-color:var(--color-dark-700)}.border-red-700{border-color:var(--color-red-700)}.border-transparent{border-color:#0000}.border-yellow-500\/40{border-color:#edb20066}@supports (color:color-mix(in lab, red, red)){.border-yellow-500\/40{border-color:color-mix(in oklab, var(--color-yellow-500) 40%, transparent)}}.border-yellow-500\/50{border-color:#edb20080}@supports (color:color-mix(in lab, red, red)){.border-yellow-500\/50{border-color:color-mix(in oklab, var(--color-yellow-500) 50%, transparent)}}.border-t-transparent{border-top-color:#0000}.bg-accent{background-color:var(--color-accent)}.bg-accent\/10{background-color:#4f8cff1a}@supports (color:color-mix(in lab, red, red)){.bg-accent\/10{background-color:color-mix(in oklab, var(--color-accent) 10%, transparent)}}.bg-accent\/20{background-color:#4f8cff33}@supports (color:color-mix(in lab, red, red)){.bg-accent\/20{background-color:color-mix(in oklab, var(--color-accent) 20%, transparent)}}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab, red, red)){.bg-black\/60{background-color:color-mix(in oklab, var(--color-black) 60%, transparent)}}.bg-blue-600\/20{background-color:#155dfc33}@supports (color:color-mix(in lab, red, red)){.bg-blue-600\/20{background-color:color-mix(in oklab, var(--color-blue-600) 20%, transparent)}}.bg-dark-600{background-color:var(--color-dark-600)}.bg-dark-600\/50{background-color:#33333380}@supports (color:color-mix(in lab, red, red)){.bg-dark-600\/50{background-color:color-mix(in oklab, var(--color-dark-600) 50%, transparent)}}.bg-dark-700{background-color:var(--color-dark-700)}.bg-dark-800{background-color:var(--color-dark-800)}.bg-dark-900{background-color:var(--color-dark-900)}.bg-dark-900\/80{background-color:#0f0f0fcc}@supports (color:color-mix(in lab, red, red)){.bg-dark-900\/80{background-color:color-mix(in oklab, var(--color-dark-900) 80%, transparent)}}.bg-green-500{background-color:var(--color-green-500)}.bg-green-500\/10{background-color:#00c7581a}@supports (color:color-mix(in lab, red, red)){.bg-green-500\/10{background-color:color-mix(in oklab, var(--color-green-500) 10%, transparent)}}.bg-green-700\/60{background-color:#00813899}@supports (color:color-mix(in lab, red, red)){.bg-green-700\/60{background-color:color-mix(in oklab, var(--color-green-700) 60%, transparent)}}.bg-red-500{background-color:var(--color-red-500)}.bg-red-700\/60{background-color:#bf000f99}@supports (color:color-mix(in lab, red, red)){.bg-red-700\/60{background-color:color-mix(in oklab, var(--color-red-700) 60%, transparent)}}.bg-red-900\/30{background-color:#82181a4d}@supports (color:color-mix(in lab, red, red)){.bg-red-900\/30{background-color:color-mix(in oklab, var(--color-red-900) 30%, transparent)}}.fill-white{fill:var(--color-white)}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-12{padding-block:calc(var(--spacing) * 12)}.py-16{padding-block:calc(var(--spacing) * 16)}.pt-1{padding-top:calc(var(--spacing) * 1)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pr-1{padding-right:calc(var(--spacing) * 1)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pl-4{padding-left:calc(var(--spacing) * 4)}.text-center{text-align:center}.text-left{text-align:left}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-normal{white-space:normal}.whitespace-nowrap{white-space:nowrap}.text-accent{color:var(--color-accent)}.text-accent\/70{color:#4f8cffb3}@supports (color:color-mix(in lab, red, red)){.text-accent\/70{color:color-mix(in oklab, var(--color-accent) 70%, transparent)}}.text-blue-400{color:var(--color-blue-400)}.text-gray-100{color:var(--color-gray-100)}.text-gray-200{color:var(--color-gray-200)}.text-gray-300{color:var(--color-gray-300)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-green-200{color:var(--color-green-200)}.text-green-400{color:var(--color-green-400)}.text-red-200{color:var(--color-red-200)}.text-red-300{color:var(--color-red-300)}.text-red-400{color:var(--color-red-400)}.text-white{color:var(--color-white)}.text-yellow-400{color:var(--color-yellow-400)}.text-yellow-500\/80{color:#edb200cc}@supports (color:color-mix(in lab, red, red)){.text-yellow-500\/80{color:color-mix(in oklab, var(--color-yellow-500) 80%, transparent)}}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.accent-accent{accent-color:var(--color-accent)}.accent-yellow-500{accent-color:var(--color-yellow-500)}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-80{opacity:.8}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-300{--tw-duration:.3s;transition-duration:.3s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.group-open\:rotate-90:is(:where(.group):is([open],:popover-open,:open) *){rotate:90deg}@media (hover:hover){.group-hover\:text-gray-300:is(:where(.group):hover *){color:var(--color-gray-300)}}.placeholder\:text-gray-500::placeholder{color:var(--color-gray-500)}@media (hover:hover){.hover\:border-accent:hover{border-color:var(--color-accent)}.hover\:border-accent\/30:hover{border-color:#4f8cff4d}@supports (color:color-mix(in lab, red, red)){.hover\:border-accent\/30:hover{border-color:color-mix(in oklab, var(--color-accent) 30%, transparent)}}.hover\:border-gray-500:hover{border-color:var(--color-gray-500)}.hover\:bg-accent-hover:hover{background-color:var(--color-accent-hover)}.hover\:bg-blue-600\/40:hover{background-color:#155dfc66}@supports (color:color-mix(in lab, red, red)){.hover\:bg-blue-600\/40:hover{background-color:color-mix(in oklab, var(--color-blue-600) 40%, transparent)}}.hover\:bg-dark-600:hover{background-color:var(--color-dark-600)}.hover\:bg-dark-700:hover{background-color:var(--color-dark-700)}.hover\:bg-dark-700\/50:hover{background-color:#25252580}@supports (color:color-mix(in lab, red, red)){.hover\:bg-dark-700\/50:hover{background-color:color-mix(in oklab, var(--color-dark-700) 50%, transparent)}}.hover\:bg-green-600\/80:hover{background-color:#00a544cc}@supports (color:color-mix(in lab, red, red)){.hover\:bg-green-600\/80:hover{background-color:color-mix(in oklab, var(--color-green-600) 80%, transparent)}}.hover\:bg-red-400\/20:hover{background-color:#ff656833}@supports (color:color-mix(in lab, red, red)){.hover\:bg-red-400\/20:hover{background-color:color-mix(in oklab, var(--color-red-400) 20%, transparent)}}.hover\:bg-red-600\/80:hover{background-color:#e40014cc}@supports (color:color-mix(in lab, red, red)){.hover\:bg-red-600\/80:hover{background-color:color-mix(in oklab, var(--color-red-600) 80%, transparent)}}.hover\:text-accent:hover{color:var(--color-accent)}.hover\:text-blue-300:hover{color:var(--color-blue-300)}.hover\:text-gray-200:hover{color:var(--color-gray-200)}.hover\:text-gray-300:hover{color:var(--color-gray-300)}.hover\:text-red-300:hover{color:var(--color-red-300)}.hover\:text-red-400:hover{color:var(--color-red-400)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:border-accent:focus{border-color:var(--color-accent)}.focus\:border-accent\/50:focus{border-color:#4f8cff80}@supports (color:color-mix(in lab, red, red)){.focus\:border-accent\/50:focus{border-color:color-mix(in oklab, var(--color-accent) 50%, transparent)}}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.active\:scale-95:active{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-40:disabled{opacity:.4}@media (width>=40rem){.sm\:block{display:block}}@media (width>=48rem){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}}.avatar-sm{object-fit:cover;border-radius:3px;flex-shrink:0;width:24px;height:24px}.steam-lvl{color:#e5e5e5;border:1.5px solid #9b9b9b;border-radius:10px;flex-shrink:0;justify-content:center;align-items:center;width:18px;height:18px;font-size:10px;font-weight:600;display:inline-flex}.steam-lvl.l10{border-color:#c02942}.steam-lvl.l20{border-color:#d95b43}.steam-lvl.l30{border-color:#fecc23}.steam-lvl.l40{border-color:#467a3c}.steam-lvl.l50{border-color:#4e8ddb}.steam-lvl.l60{border-color:#7652c9}.steam-lvl.l70{border-color:#c252c9}.steam-lvl.l80{border-color:#542437}.steam-lvl.l90{border-color:#997c52}.steam-lvl.l100p{text-shadow:1px 1px #1a1a1a;background-position:0 0;background-repeat:no-repeat;background-size:contain;border:none;border-radius:0;width:20px;height:20px;font-size:9px}.steam-lvl.l100p.img-100{background-image:url(https://community.fastly.steamstatic.com/public/shared/images/community/levels_hexagons.png)}.steam-lvl.l100p.img-200{background-image:url(https://community.fastly.steamstatic.com/public/shared/images/community/levels_shields.png)}.steam-lvl.l100p.img-300{background-image:url(https://community.fastly.steamstatic.com/public/shared/images/community/levels_books.png)}.steam-lvl.l100p.img-400{background-image:url(https://community.fastly.steamstatic.com/public/shared/images/community/levels_chevrons.png)}.steam-lvl.l100p.img-500{background-image:url(https://community.fastly.steamstatic.com/public/shared/images/community/levels_circle2.png)}.steam-lvl.l100p.img-600{background-image:url(https://community.fastly.steamstatic.com/public/shared/images/community/levels_angle.png)}.steam-lvl.l100p.img-700{background-image:url(https://community.fastly.steamstatic.com/public/shared/images/community/levels_flag.png)}.steam-lvl.l100p.img-800{background-image:url(https://community.fastly.steamstatic.com/public/shared/images/community/levels_wings.png)}.steam-lvl.l100p.img-900{background-image:url(https://community.fastly.steamstatic.com/public/shared/images/community/levels_arrows.png)}.btn-primary{cursor:pointer;background-color:var(--color-accent);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--color-white);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));border-radius:.25rem}@media (hover:hover){.btn-primary:hover{background-color:var(--color-accent-hover)}}.btn-secondary{cursor:pointer;border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-dark-600);background-color:var(--color-dark-700);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--color-gray-300);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));border-radius:.25rem}@media (hover:hover){.btn-secondary:hover{background-color:var(--color-dark-600)}}.btn-accent{cursor:pointer;background-color:var(--color-accent-dim);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--color-white);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));border-radius:.25rem}@media (hover:hover){.btn-accent:hover{background-color:var(--color-accent)}}.btn-danger{cursor:pointer;border-style:var(--tw-border-style);border-width:1px;border-color:#e400144d;border-radius:.25rem}@supports (color:color-mix(in lab, red, red)){.btn-danger{border-color:color-mix(in oklab, var(--color-red-600) 30%, transparent)}}.btn-danger{background-color:#e4001433}@supports (color:color-mix(in lab, red, red)){.btn-danger{background-color:color-mix(in oklab, var(--color-red-600) 20%, transparent)}}.btn-danger{padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--color-red-400);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media (hover:hover){.btn-danger:hover{background-color:#e400144d}@supports (color:color-mix(in lab, red, red)){.btn-danger:hover{background-color:color-mix(in oklab, var(--color-red-600) 30%, transparent)}}}.btn-danger-outline{cursor:pointer;border-style:var(--tw-border-style);border-width:1px;border-color:#e400144d;border-radius:.25rem}@supports (color:color-mix(in lab, red, red)){.btn-danger-outline{border-color:color-mix(in oklab, var(--color-red-600) 30%, transparent)}}.btn-danger-outline{padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--color-red-400);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));background-color:#0000}@media (hover:hover){.btn-danger-outline:hover{background-color:#e400141a}@supports (color:color-mix(in lab, red, red)){.btn-danger-outline:hover{background-color:color-mix(in oklab, var(--color-red-600) 10%, transparent)}}}.badge{padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * .5);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);border-radius:.25rem;display:inline-block}.badge-ok{background-color:#00c75833}@supports (color:color-mix(in lab, red, red)){.badge-ok{background-color:color-mix(in oklab, var(--color-green-500) 20%, transparent)}}.badge-ok{color:var(--color-green-400)}.badge-error{background-color:#fb2c3633}@supports (color:color-mix(in lab, red, red)){.badge-error{background-color:color-mix(in oklab, var(--color-red-500) 20%, transparent)}}.badge-error{color:var(--color-red-400)}.badge-running{background-color:#3080ff33}@supports (color:color-mix(in lab, red, red)){.badge-running{background-color:color-mix(in oklab, var(--color-blue-500) 20%, transparent)}}.badge-running{color:var(--color-blue-400)}.badge-unknown{background-color:#6a728233}@supports (color:color-mix(in lab, red, red)){.badge-unknown{background-color:color-mix(in oklab, var(--color-gray-500) 20%, transparent)}}.badge-unknown{color:var(--color-gray-500)}.progress-bar{height:calc(var(--spacing) * 1.5);background-color:var(--color-dark-600);border-radius:3.40282e38px;width:100%;overflow:hidden}.progress-fill{background-color:var(--color-accent);height:100%;transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.3s;border-radius:3.40282e38px;transition-duration:.3s}.cell-copy{cursor:pointer;transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));-webkit-user-select:all;user-select:all}@media (hover:hover){.cell-copy:hover{color:var(--color-gray-200)}}.copy-tooltip{color:#fff;pointer-events:none;z-index:9999;background:#333;border-radius:4px;padding:2px 8px;font-size:11px;transition:opacity .2s;position:fixed;transform:translate(-50%,-100%)}[data-tooltip]{position:relative}button[disabled][data-tooltip]{pointer-events:auto}[data-tooltip]:after{content:attr(data-tooltip);color:#f0f0f8;white-space:nowrap;pointer-events:none;opacity:0;z-index:9999;background:#0f0f1a;border:1px solid #6b6b8a;border-radius:5px;padding:5px 10px;font-size:12px;font-weight:500;transition:opacity .15s;position:absolute;bottom:calc(100% + 6px);left:50%;transform:translate(-50%);box-shadow:0 4px 12px #0009}[data-tooltip]:hover:after{opacity:1}.popup-2fa{z-index:100;background:var(--color-dark-700);border:1px solid var(--color-dark-600);border-radius:8px;padding:8px 14px;position:fixed;box-shadow:0 4px 16px #0006}.popup-2fa-code{color:var(--color-accent);cursor:pointer;-webkit-user-select:all;user-select:all;font-family:monospace;font-size:1.5rem}.action-menu-dropdown{z-index:50;border-radius:var(--radius-lg);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-dark-600);background-color:var(--color-dark-700);min-width:180px;padding-block:calc(var(--spacing) * 1);--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.action-menu-item{cursor:pointer;width:100%;padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 1.5);text-align:left;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--color-gray-300);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));display:block}@media (hover:hover){.action-menu-item:hover{background-color:var(--color-dark-600);color:var(--color-white)}}.confirm-overlay{inset:calc(var(--spacing) * 0);z-index:50;background-color:#0009;justify-content:center;align-items:center;display:flex;position:fixed}@supports (color:color-mix(in lab, red, red)){.confirm-overlay{background-color:color-mix(in oklab, var(--color-black) 60%, transparent)}}.confirm-box{width:100%;max-width:var(--container-md);border-radius:var(--radius-lg);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-dark-600);background-color:var(--color-dark-800);padding:calc(var(--spacing) * 6);--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);overflow-wrap:break-word;word-break:break-word}.toast-container{z-index:9999;pointer-events:none;flex-direction:column-reverse;gap:.5rem;display:flex;position:fixed;bottom:1rem;left:1rem}.toast{pointer-events:auto;color:#fff;border-radius:.375rem;padding:.5rem 1rem;font-size:.8rem;transition:opacity .3s;animation:.25s ease-out toastIn;box-shadow:0 2px 8px #0000004d}.toast-info{background:#2563eb}.toast-success{background:#16a34a}.toast-error{background:#dc2626}.toast-warn{background:#d97706}@keyframes toastIn{0%{opacity:0;transform:translate(-30px)}to{opacity:1;transform:translate(0)}}@keyframes shimmer{0%{stroke-dashoffset:80px}to{stroke-dashoffset:-80px}}.icon-shimmer{stroke:#ffffff73;stroke-dasharray:8 72;animation:2.5s linear infinite shimmer}.toggle-switch{cursor:pointer;flex-shrink:0;align-items:center;width:38px;height:22px;display:inline-flex;position:relative}.toggle-switch input{opacity:0;width:0;height:0;position:absolute}.toggle-track{background:#2a2a2a;border:1px solid #444;border-radius:999px;transition:background .2s,border-color .2s;position:absolute;inset:0}.toggle-track:before{content:"";background:#666;border-radius:50%;width:16px;height:16px;transition:transform .2s,background .2s;position:absolute;top:2px;left:2px}.toggle-switch input:checked~.toggle-track{background:#4f8cff;border-color:#4f8cff}.toggle-switch input:checked~.toggle-track:before{background:#fff;transform:translate(16px)}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:var(--color-dark-900)}::-webkit-scrollbar-thumb{background:var(--color-dark-600);border-radius:3px}::-webkit-scrollbar-thumb:hover{background:#555}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@keyframes spin{to{transform:rotate(360deg)}} diff --git a/app/static/assets/index-ztmqkldd.css b/app/static/assets/index-ztmqkldd.css new file mode 100644 index 0000000..baae4f1 --- /dev/null +++ b/app/static/assets/index-ztmqkldd.css @@ -0,0 +1,2 @@ +/*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */ +@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-duration:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-200:oklch(88.5% .062 18.334);--color-red-300:oklch(80.8% .114 19.571);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-red-900:oklch(39.6% .141 25.723);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-500:oklch(79.5% .184 86.047);--color-green-200:oklch(92.5% .084 155.995);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-green-600:oklch(62.7% .194 149.214);--color-green-700:oklch(52.7% .154 150.069);--color-blue-300:oklch(80.9% .105 251.813);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-md:28rem;--container-lg:32rem;--container-2xl:42rem;--container-5xl:64rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-wide:.025em;--tracking-wider:.05em;--tracking-widest:.1em;--leading-tight:1.25;--leading-relaxed:1.625;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-dark-900:#0f0f0f;--color-dark-800:#1a1a1a;--color-dark-700:#252525;--color-dark-600:#333;--color-accent:#4f8cff;--color-accent-hover:#6ba0ff;--color-accent-dim:#3a6fd8}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.top-0{top:calc(var(--spacing) * 0)}.top-full{top:100%}.right-0{right:calc(var(--spacing) * 0)}.left-0{left:calc(var(--spacing) * 0)}.z-10{z-index:10}.z-50{z-index:50}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mx-4{margin-inline:calc(var(--spacing) * 4)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing) * 1)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mr-0\.5{margin-right:calc(var(--spacing) * .5)}.mr-1{margin-right:calc(var(--spacing) * 1)}.mr-2{margin-right:calc(var(--spacing) * 2)}.-mb-px{margin-bottom:-1px}.mb-0\.5{margin-bottom:calc(var(--spacing) * .5)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-3{margin-left:calc(var(--spacing) * 3)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-2\.5{height:calc(var(--spacing) * 2.5)}.h-3{height:calc(var(--spacing) * 3)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-14{height:calc(var(--spacing) * 14)}.h-dvh{height:100dvh}.h-full{height:100%}.max-h-48{max-height:calc(var(--spacing) * 48)}.max-h-56{max-height:calc(var(--spacing) * 56)}.max-h-\[80vh\]{max-height:80vh}.max-h-\[85vh\]{max-height:85vh}.max-h-\[320px\]{max-height:320px}.min-h-0{min-height:calc(var(--spacing) * 0)}.min-h-\[300px\]{min-height:300px}.w-3{width:calc(var(--spacing) * 3)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-10{width:calc(var(--spacing) * 10)}.w-14{width:calc(var(--spacing) * 14)}.w-28{width:calc(var(--spacing) * 28)}.w-36{width:calc(var(--spacing) * 36)}.w-80{width:calc(var(--spacing) * 80)}.w-96{width:calc(var(--spacing) * 96)}.w-\[110px\]{width:110px}.w-\[560px\]{width:560px}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-\[180px\]{max-width:180px}.max-w-\[200px\]{max-width:200px}.max-w-\[640px\]{max-width:640px}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-none{max-width:none}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-\[100px\]{min-width:100px}.min-w-\[160px\]{min-width:160px}.min-w-\[170px\]{min-width:170px}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.rotate-180{rotate:180deg}.animate-spin{animation:var(--animate-spin)}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.resize-y{resize:vertical}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}:where(.space-y-0>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 0) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 0) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-px>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(1px * var(--tw-space-y-reverse));margin-block-end:calc(1px * calc(1 - var(--tw-space-y-reverse)))}.gap-x-3{column-gap:calc(var(--spacing) * 3)}.gap-y-1\.5{row-gap:calc(var(--spacing) * 1.5)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-dark-600\/60>:not(:last-child)){border-color:#3339}@supports (color:color-mix(in lab, red, red)){:where(.divide-dark-600\/60>:not(:last-child)){border-color:color-mix(in oklab, var(--color-dark-600) 60%, transparent)}}:where(.divide-dark-700>:not(:last-child)){border-color:var(--color-dark-700)}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-accent{border-color:var(--color-accent)}.border-accent\/30{border-color:#4f8cff4d}@supports (color:color-mix(in lab, red, red)){.border-accent\/30{border-color:color-mix(in oklab, var(--color-accent) 30%, transparent)}}.border-blue-500\/30{border-color:#3080ff4d}@supports (color:color-mix(in lab, red, red)){.border-blue-500\/30{border-color:color-mix(in oklab, var(--color-blue-500) 30%, transparent)}}.border-dark-600{border-color:var(--color-dark-600)}.border-dark-700{border-color:var(--color-dark-700)}.border-red-700{border-color:var(--color-red-700)}.border-transparent{border-color:#0000}.border-t-transparent{border-top-color:#0000}.bg-accent{background-color:var(--color-accent)}.bg-accent\/10{background-color:#4f8cff1a}@supports (color:color-mix(in lab, red, red)){.bg-accent\/10{background-color:color-mix(in oklab, var(--color-accent) 10%, transparent)}}.bg-accent\/15{background-color:#4f8cff26}@supports (color:color-mix(in lab, red, red)){.bg-accent\/15{background-color:color-mix(in oklab, var(--color-accent) 15%, transparent)}}.bg-accent\/20{background-color:#4f8cff33}@supports (color:color-mix(in lab, red, red)){.bg-accent\/20{background-color:color-mix(in oklab, var(--color-accent) 20%, transparent)}}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab, red, red)){.bg-black\/60{background-color:color-mix(in oklab, var(--color-black) 60%, transparent)}}.bg-blue-600\/20{background-color:#155dfc33}@supports (color:color-mix(in lab, red, red)){.bg-blue-600\/20{background-color:color-mix(in oklab, var(--color-blue-600) 20%, transparent)}}.bg-dark-600{background-color:var(--color-dark-600)}.bg-dark-600\/50{background-color:#33333380}@supports (color:color-mix(in lab, red, red)){.bg-dark-600\/50{background-color:color-mix(in oklab, var(--color-dark-600) 50%, transparent)}}.bg-dark-700{background-color:var(--color-dark-700)}.bg-dark-800{background-color:var(--color-dark-800)}.bg-dark-900{background-color:var(--color-dark-900)}.bg-dark-900\/40{background-color:#0f0f0f66}@supports (color:color-mix(in lab, red, red)){.bg-dark-900\/40{background-color:color-mix(in oklab, var(--color-dark-900) 40%, transparent)}}.bg-green-500{background-color:var(--color-green-500)}.bg-green-500\/10{background-color:#00c7581a}@supports (color:color-mix(in lab, red, red)){.bg-green-500\/10{background-color:color-mix(in oklab, var(--color-green-500) 10%, transparent)}}.bg-green-700\/60{background-color:#00813899}@supports (color:color-mix(in lab, red, red)){.bg-green-700\/60{background-color:color-mix(in oklab, var(--color-green-700) 60%, transparent)}}.bg-red-500{background-color:var(--color-red-500)}.bg-red-700\/60{background-color:#bf000f99}@supports (color:color-mix(in lab, red, red)){.bg-red-700\/60{background-color:color-mix(in oklab, var(--color-red-700) 60%, transparent)}}.bg-red-900\/30{background-color:#82181a4d}@supports (color:color-mix(in lab, red, red)){.bg-red-900\/30{background-color:color-mix(in oklab, var(--color-red-900) 30%, transparent)}}.fill-white{fill:var(--color-white)}.object-cover{object-fit:cover}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1{padding:calc(var(--spacing) * 1)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-12{padding-block:calc(var(--spacing) * 12)}.py-16{padding-block:calc(var(--spacing) * 16)}.pt-1{padding-top:calc(var(--spacing) * 1)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pr-1{padding-right:calc(var(--spacing) * 1)}.pb-0\.5{padding-bottom:calc(var(--spacing) * .5)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pl-4{padding-left:calc(var(--spacing) * 4)}.text-center{text-align:center}.text-left{text-align:left}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-\[1\.7\]{--tw-leading:1.7;line-height:1.7}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-normal{white-space:normal}.whitespace-nowrap{white-space:nowrap}.text-accent{color:var(--color-accent)}.text-accent\/70{color:#4f8cffb3}@supports (color:color-mix(in lab, red, red)){.text-accent\/70{color:color-mix(in oklab, var(--color-accent) 70%, transparent)}}.text-blue-400{color:var(--color-blue-400)}.text-gray-100{color:var(--color-gray-100)}.text-gray-200{color:var(--color-gray-200)}.text-gray-300{color:var(--color-gray-300)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-green-200{color:var(--color-green-200)}.text-green-400{color:var(--color-green-400)}.text-red-200{color:var(--color-red-200)}.text-red-300{color:var(--color-red-300)}.text-red-400{color:var(--color-red-400)}.text-white{color:var(--color-white)}.text-yellow-400{color:var(--color-yellow-400)}.text-yellow-500\/80{color:#edb200cc}@supports (color:color-mix(in lab, red, red)){.text-yellow-500\/80{color:color-mix(in oklab, var(--color-yellow-500) 80%, transparent)}}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.accent-accent{accent-color:var(--color-accent)}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-80{opacity:.8}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-300{--tw-duration:.3s;transition-duration:.3s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.group-open\:rotate-90:is(:where(.group):is([open],:popover-open,:open) *){rotate:90deg}.placeholder\:text-gray-500::placeholder{color:var(--color-gray-500)}@media (hover:hover){.hover\:border-accent:hover{border-color:var(--color-accent)}.hover\:border-accent\/30:hover{border-color:#4f8cff4d}@supports (color:color-mix(in lab, red, red)){.hover\:border-accent\/30:hover{border-color:color-mix(in oklab, var(--color-accent) 30%, transparent)}}.hover\:border-gray-500:hover{border-color:var(--color-gray-500)}.hover\:bg-accent-hover:hover{background-color:var(--color-accent-hover)}.hover\:bg-accent\/20:hover{background-color:#4f8cff33}@supports (color:color-mix(in lab, red, red)){.hover\:bg-accent\/20:hover{background-color:color-mix(in oklab, var(--color-accent) 20%, transparent)}}.hover\:bg-blue-600\/40:hover{background-color:#155dfc66}@supports (color:color-mix(in lab, red, red)){.hover\:bg-blue-600\/40:hover{background-color:color-mix(in oklab, var(--color-blue-600) 40%, transparent)}}.hover\:bg-dark-600:hover{background-color:var(--color-dark-600)}.hover\:bg-dark-700:hover{background-color:var(--color-dark-700)}.hover\:bg-dark-700\/50:hover{background-color:#25252580}@supports (color:color-mix(in lab, red, red)){.hover\:bg-dark-700\/50:hover{background-color:color-mix(in oklab, var(--color-dark-700) 50%, transparent)}}.hover\:bg-green-600\/80:hover{background-color:#00a544cc}@supports (color:color-mix(in lab, red, red)){.hover\:bg-green-600\/80:hover{background-color:color-mix(in oklab, var(--color-green-600) 80%, transparent)}}.hover\:bg-red-400\/20:hover{background-color:#ff656833}@supports (color:color-mix(in lab, red, red)){.hover\:bg-red-400\/20:hover{background-color:color-mix(in oklab, var(--color-red-400) 20%, transparent)}}.hover\:bg-red-600\/80:hover{background-color:#e40014cc}@supports (color:color-mix(in lab, red, red)){.hover\:bg-red-600\/80:hover{background-color:color-mix(in oklab, var(--color-red-600) 80%, transparent)}}.hover\:text-accent:hover{color:var(--color-accent)}.hover\:text-blue-300:hover{color:var(--color-blue-300)}.hover\:text-blue-400:hover{color:var(--color-blue-400)}.hover\:text-gray-200:hover{color:var(--color-gray-200)}.hover\:text-gray-300:hover{color:var(--color-gray-300)}.hover\:text-green-400:hover{color:var(--color-green-400)}.hover\:text-red-300:hover{color:var(--color-red-300)}.hover\:text-red-400:hover{color:var(--color-red-400)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:border-accent:focus{border-color:var(--color-accent)}.focus\:border-accent\/50:focus{border-color:#4f8cff80}@supports (color:color-mix(in lab, red, red)){.focus\:border-accent\/50:focus{border-color:color-mix(in oklab, var(--color-accent) 50%, transparent)}}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.active\:scale-95:active{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-40:disabled{opacity:.4}@media (width>=40rem){.sm\:block{display:block}}@media (width>=48rem){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}}.avatar-sm{object-fit:cover;border-radius:3px;flex-shrink:0;width:24px;height:24px}.steam-lvl{color:#e5e5e5;border:1.5px solid #9b9b9b;border-radius:10px;flex-shrink:0;justify-content:center;align-items:center;width:18px;height:18px;font-size:10px;font-weight:600;display:inline-flex}.steam-lvl.l10{border-color:#c02942}.steam-lvl.l20{border-color:#d95b43}.steam-lvl.l30{border-color:#fecc23}.steam-lvl.l40{border-color:#467a3c}.steam-lvl.l50{border-color:#4e8ddb}.steam-lvl.l60{border-color:#7652c9}.steam-lvl.l70{border-color:#c252c9}.steam-lvl.l80{border-color:#542437}.steam-lvl.l90{border-color:#997c52}.steam-lvl.l100p{text-shadow:1px 1px #1a1a1a;background-position:0 0;background-repeat:no-repeat;background-size:contain;border:none;border-radius:0;width:20px;height:20px;font-size:9px}.steam-lvl.l100p.img-100{background-image:url(https://community.fastly.steamstatic.com/public/shared/images/community/levels_hexagons.png)}.steam-lvl.l100p.img-200{background-image:url(https://community.fastly.steamstatic.com/public/shared/images/community/levels_shields.png)}.steam-lvl.l100p.img-300{background-image:url(https://community.fastly.steamstatic.com/public/shared/images/community/levels_books.png)}.steam-lvl.l100p.img-400{background-image:url(https://community.fastly.steamstatic.com/public/shared/images/community/levels_chevrons.png)}.steam-lvl.l100p.img-500{background-image:url(https://community.fastly.steamstatic.com/public/shared/images/community/levels_circle2.png)}.steam-lvl.l100p.img-600{background-image:url(https://community.fastly.steamstatic.com/public/shared/images/community/levels_angle.png)}.steam-lvl.l100p.img-700{background-image:url(https://community.fastly.steamstatic.com/public/shared/images/community/levels_flag.png)}.steam-lvl.l100p.img-800{background-image:url(https://community.fastly.steamstatic.com/public/shared/images/community/levels_wings.png)}.steam-lvl.l100p.img-900{background-image:url(https://community.fastly.steamstatic.com/public/shared/images/community/levels_arrows.png)}.btn-primary{cursor:pointer;background-color:var(--color-accent);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--color-white);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));border-radius:.25rem}@media (hover:hover){.btn-primary:hover{background-color:var(--color-accent-hover)}}.btn-secondary{cursor:pointer;border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-dark-600);background-color:var(--color-dark-700);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--color-gray-300);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));border-radius:.25rem}@media (hover:hover){.btn-secondary:hover{background-color:var(--color-dark-600)}}.btn-accent{cursor:pointer;background-color:var(--color-accent-dim);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--color-white);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));border-radius:.25rem}@media (hover:hover){.btn-accent:hover{background-color:var(--color-accent)}}.btn-danger{cursor:pointer;border-style:var(--tw-border-style);border-width:1px;border-color:#e400144d;border-radius:.25rem}@supports (color:color-mix(in lab, red, red)){.btn-danger{border-color:color-mix(in oklab, var(--color-red-600) 30%, transparent)}}.btn-danger{background-color:#e4001433}@supports (color:color-mix(in lab, red, red)){.btn-danger{background-color:color-mix(in oklab, var(--color-red-600) 20%, transparent)}}.btn-danger{padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--color-red-400);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media (hover:hover){.btn-danger:hover{background-color:#e400144d}@supports (color:color-mix(in lab, red, red)){.btn-danger:hover{background-color:color-mix(in oklab, var(--color-red-600) 30%, transparent)}}}.btn-danger-outline{cursor:pointer;border-style:var(--tw-border-style);border-width:1px;border-color:#e400144d;border-radius:.25rem}@supports (color:color-mix(in lab, red, red)){.btn-danger-outline{border-color:color-mix(in oklab, var(--color-red-600) 30%, transparent)}}.btn-danger-outline{padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--color-red-400);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));background-color:#0000}@media (hover:hover){.btn-danger-outline:hover{background-color:#e400141a}@supports (color:color-mix(in lab, red, red)){.btn-danger-outline:hover{background-color:color-mix(in oklab, var(--color-red-600) 10%, transparent)}}}.badge{padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * .5);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);border-radius:.25rem;display:inline-block}.badge-ok{background-color:#00c75833}@supports (color:color-mix(in lab, red, red)){.badge-ok{background-color:color-mix(in oklab, var(--color-green-500) 20%, transparent)}}.badge-ok{color:var(--color-green-400)}.badge-error{background-color:#fb2c3633}@supports (color:color-mix(in lab, red, red)){.badge-error{background-color:color-mix(in oklab, var(--color-red-500) 20%, transparent)}}.badge-error{color:var(--color-red-400)}.badge-running{background-color:#3080ff33}@supports (color:color-mix(in lab, red, red)){.badge-running{background-color:color-mix(in oklab, var(--color-blue-500) 20%, transparent)}}.badge-running{color:var(--color-blue-400)}.badge-unknown{background-color:#6a728233}@supports (color:color-mix(in lab, red, red)){.badge-unknown{background-color:color-mix(in oklab, var(--color-gray-500) 20%, transparent)}}.badge-unknown{color:var(--color-gray-500)}.progress-bar{height:calc(var(--spacing) * 1.5);background-color:var(--color-dark-600);border-radius:3.40282e38px;width:100%;overflow:hidden}.progress-fill{background-color:var(--color-accent);height:100%;transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.3s;border-radius:3.40282e38px;transition-duration:.3s}.cell-copy{cursor:pointer;transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));-webkit-user-select:all;user-select:all}@media (hover:hover){.cell-copy:hover{color:var(--color-gray-200)}}.copy-tooltip{color:#fff;pointer-events:none;z-index:9999;background:#333;border-radius:4px;padding:2px 8px;font-size:11px;transition:opacity .2s;position:fixed;transform:translate(-50%,-100%)}[data-tooltip]{position:relative}button[disabled][data-tooltip]{pointer-events:auto}[data-tooltip]:after{content:attr(data-tooltip);color:#f0f0f8;white-space:nowrap;pointer-events:none;opacity:0;z-index:9999;background:#0f0f1a;border:1px solid #6b6b8a;border-radius:5px;padding:5px 10px;font-size:12px;font-weight:500;transition:opacity .15s;position:absolute;bottom:calc(100% + 6px);left:50%;transform:translate(-50%);box-shadow:0 4px 12px #0009}[data-tooltip]:hover:after{opacity:1}.popup-2fa{z-index:100;background:var(--color-dark-700);border:1px solid var(--color-dark-600);border-radius:8px;padding:8px 14px;position:fixed;box-shadow:0 4px 16px #0006}.popup-2fa-code{color:var(--color-accent);cursor:pointer;-webkit-user-select:all;user-select:all;font-family:monospace;font-size:1.5rem}.action-menu-dropdown{z-index:50;border-radius:var(--radius-lg);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-dark-600);background-color:var(--color-dark-700);min-width:180px;padding-block:calc(var(--spacing) * 1);--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.action-menu-item{cursor:pointer;width:100%;padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 1.5);text-align:left;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--color-gray-300);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));display:block}@media (hover:hover){.action-menu-item:hover{background-color:var(--color-dark-600);color:var(--color-white)}}.confirm-overlay{inset:calc(var(--spacing) * 0);z-index:50;background-color:#0009;justify-content:center;align-items:center;display:flex;position:fixed}@supports (color:color-mix(in lab, red, red)){.confirm-overlay{background-color:color-mix(in oklab, var(--color-black) 60%, transparent)}}.confirm-box{width:100%;max-width:var(--container-md);border-radius:var(--radius-lg);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-dark-600);background-color:var(--color-dark-800);padding:calc(var(--spacing) * 6);--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);overflow-wrap:break-word;word-break:break-word}.toast-container{z-index:9999;pointer-events:none;flex-direction:column-reverse;gap:.5rem;display:flex;position:fixed;bottom:1rem;left:1rem}.toast{pointer-events:auto;color:#fff;border-radius:.375rem;padding:.5rem 1rem;font-size:.8rem;transition:opacity .3s;animation:.25s ease-out toastIn;box-shadow:0 2px 8px #0000004d}.toast-info{background:#2563eb}.toast-success{background:#16a34a}.toast-error{background:#dc2626}.toast-warn{background:#d97706}@keyframes toastIn{0%{opacity:0;transform:translate(-30px)}to{opacity:1;transform:translate(0)}}@keyframes shimmer{0%{stroke-dashoffset:80px}to{stroke-dashoffset:-80px}}.icon-shimmer{stroke:#ffffff73;stroke-dasharray:8 72;animation:2.5s linear infinite shimmer}.toggle-switch{cursor:pointer;flex-shrink:0;align-items:center;width:38px;height:22px;display:inline-flex;position:relative}.toggle-switch input{opacity:0;width:0;height:0;position:absolute}.toggle-track{background:#2a2a2a;border:1px solid #444;border-radius:999px;transition:background .2s,border-color .2s;position:absolute;inset:0}.toggle-track:before{content:"";background:#666;border-radius:50%;width:16px;height:16px;transition:transform .2s,background .2s;position:absolute;top:2px;left:2px}.toggle-switch input:checked~.toggle-track{background:#4f8cff;border-color:#4f8cff}.toggle-switch input:checked~.toggle-track:before{background:#fff;transform:translate(16px)}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:var(--color-dark-900)}::-webkit-scrollbar-thumb{background:var(--color-dark-600);border-radius:3px}::-webkit-scrollbar-thumb:hover{background:#555}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-duration{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@keyframes spin{to{transform:rotate(360deg)}} diff --git a/app/static/index.html b/app/static/index.html index 05c8fb3..0ba86c7 100644 --- a/app/static/index.html +++ b/app/static/index.html @@ -1,14 +1,14 @@ - - - - - - - SteamPanel - - - - -
- - + + + + + + + SteamPanel + + + + +
+ + diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 23c770c..0aeae37 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -12,12 +12,16 @@ export default function App() { const activeTab = useUiStore((s) => s.activeTab); const loadDisplaySettings = useUiStore((s) => s.loadDisplaySettings); const loadColumnSettings = useUiStore((s) => s.loadColumnSettings); - const loadLogpassColumnSettings = useUiStore((s) => s.loadLogpassColumnSettings); + const loadLogpassColumnSettings = useUiStore( + (s) => s.loadLogpassColumnSettings, + ); + const loadImportSettings = useUiStore((s) => s.loadImportSettings); useEffect(() => { loadDisplaySettings(); loadColumnSettings(); loadLogpassColumnSettings(); + loadImportSettings(); }, []); return ( diff --git a/frontend/src/api/client.ts b/frontend/src/api/client.ts index 33c73d0..01ef08a 100644 --- a/frontend/src/api/client.ts +++ b/frontend/src/api/client.ts @@ -1,9 +1,24 @@ import type { - Account, AccountCreate, AccountUpdate, BulkImportResult, - Proxy, Task, MafileInfo, MafileExportRequest, - ActionRequest, ValidationSettings, DisplaySettings, ColumnSettings, LogpassColumnSettings, LogEntry, - LogpassAccount, LogpassAccountCreate, LogpassAccountUpdate, - TokenAccount, TokenAccountCreate, TokenColumnSettings, + Account, + AccountCreate, + AccountUpdate, + BulkImportResult, + Proxy, + Task, + MafileInfo, + MafileExportRequest, + ActionRequest, + ValidationSettings, + DisplaySettings, + ColumnSettings, + LogpassColumnSettings, + LogEntry, + LogpassAccount, + LogpassAccountCreate, + LogpassAccountUpdate, + TokenAccount, + TokenAccountCreate, + TokenColumnSettings, } from "./types"; const BASE = "/api"; @@ -29,76 +44,144 @@ export const api = { getAccounts: () => request("/accounts"), getAccount: (id: number) => request(`/accounts/${id}`), createAccount: (data: AccountCreate) => - request("/accounts", { method: "POST", body: JSON.stringify(data) }), + request("/accounts", { + method: "POST", + body: JSON.stringify(data), + }), updateAccount: (id: number, data: AccountUpdate) => - request(`/accounts/${id}`, { method: "PUT", body: JSON.stringify(data) }), + request(`/accounts/${id}`, { + method: "PUT", + body: JSON.stringify(data), + }), deleteAccount: (id: number) => request(`/accounts/${id}`, { method: "DELETE" }), deleteBulk: (ids: number[]) => - request<{ deleted: number }>("/accounts/delete-bulk", { method: "POST", body: JSON.stringify({ ids }) }), + request<{ deleted: number }>("/accounts/delete-bulk", { + method: "POST", + body: JSON.stringify({ ids }), + }), assignProxies: () => - request<{ assigned: number; proxies_used: number }>("/accounts/assign-proxies", { method: "POST" }), + request<{ assigned: number; proxies_used: number }>( + "/accounts/assign-proxies", + { method: "POST" }, + ), reassignProxies: () => - request<{ assigned: number; proxies_used: number }>("/accounts/reassign-proxies", { method: "POST" }), + request<{ assigned: number; proxies_used: number }>( + "/accounts/reassign-proxies", + { method: "POST" }, + ), clearProxies: () => request<{ cleared: number }>("/accounts/clear-proxies", { method: "POST" }), importAccounts: (file: File) => { const form = new FormData(); form.append("file", file); - return fetch(`${BASE}/accounts/import`, { method: "POST", body: form }).then(async (r) => { - if (!r.ok) throw new Error((await r.json().catch(() => ({}))).detail ?? r.statusText); + return fetch(`${BASE}/accounts/import`, { + method: "POST", + body: form, + }).then(async (r) => { + if (!r.ok) + throw new Error( + (await r.json().catch(() => ({}))).detail ?? r.statusText, + ); return r.json() as Promise; }); }, // Actions executeAction: (data: ActionRequest) => - request<{ task_id: string; accounts_count: number }>("/actions", { method: "POST", body: JSON.stringify(data) }), - respondToPrompt: (taskId: string, value: string, login?: string) => - request<{ status: string }>(`/tasks/${taskId}/respond`, { method: "POST", body: JSON.stringify({ value, login: login || "" }) }), - generate2FA: (shared_secret: string) => - request<{ code: string }>("/actions/generate-2fa", { method: "POST", body: JSON.stringify({ shared_secret }) }), - generate2FAByAccount: (account_id: number) => - request<{ code: string }>("/actions/generate-2fa-by-account", { method: "POST", body: JSON.stringify({ account_id }) }), - getConfirmations: (account_id: number) => - request<{ success: boolean; confirmations: import("./types").SteamConfirmation[] }>(`/actions/confirmations/${account_id}`), - respondConfirmations: (account_id: number, ids: string[], nonces: string[], accept: boolean) => - request<{ success: boolean }>(`/actions/confirmations/${account_id}/respond`, { + request<{ task_id: string; accounts_count: number }>("/actions", { method: "POST", - body: JSON.stringify({ ids, nonces, accept }), + body: JSON.stringify(data), }), + respondToPrompt: (taskId: string, value: string, login?: string) => + request<{ status: string }>(`/tasks/${taskId}/respond`, { + method: "POST", + body: JSON.stringify({ value, login: login || "" }), + }), + generate2FA: (shared_secret: string) => + request<{ code: string }>("/actions/generate-2fa", { + method: "POST", + body: JSON.stringify({ shared_secret }), + }), + generate2FAByAccount: (account_id: number) => + request<{ code: string }>("/actions/generate-2fa-by-account", { + method: "POST", + body: JSON.stringify({ account_id }), + }), + getConfirmations: (account_id: number) => + request<{ + success: boolean; + confirmations: import("./types").SteamConfirmation[]; + }>(`/actions/confirmations/${account_id}`), + respondConfirmations: ( + account_id: number, + ids: string[], + nonces: string[], + accept: boolean, + ) => + request<{ success: boolean }>( + `/actions/confirmations/${account_id}/respond`, + { + method: "POST", + body: JSON.stringify({ ids, nonces, accept }), + }, + ), // Proxies getProxies: () => request("/proxies"), addProxy: (address: string, protocol = "http") => - request("/proxies", { method: "POST", body: JSON.stringify({ address, protocol }) }), + request("/proxies", { + method: "POST", + body: JSON.stringify({ address, protocol }), + }), deleteProxy: (id: number) => request(`/proxies/${id}`, { method: "DELETE" }), deleteAllProxies: () => request<{ deleted: number }>("/proxies/all", { method: "DELETE" }), bulkAddProxies: (proxies: { address: string; protocol: string }[]) => - request<{ added: number }>("/proxies/bulk", { method: "POST", body: JSON.stringify(proxies) }), + request<{ added: number }>("/proxies/bulk", { + method: "POST", + body: JSON.stringify(proxies), + }), checkProxies: () => - request<{ total: number; alive: number; dead: number }>("/proxies/check", { method: "POST" }), + request<{ total: number; alive: number; dead: number }>("/proxies/check", { + method: "POST", + }), // Tasks getTasks: () => request("/tasks"), getTask: (id: string) => request(`/tasks/${id}`), - cancelTask: (id: string) => request(`/tasks/${id}`, { method: "DELETE" }), + cancelTask: (id: string) => + request(`/tasks/${id}`, { method: "DELETE" }), // Mafiles getMafiles: () => request("/mafiles"), uploadMafiles: (files: File[]) => { const form = new FormData(); files.forEach((f) => form.append("files", f)); - return fetch(`${BASE}/mafiles/upload`, { method: "POST", body: form }).then(async (r) => { - if (!r.ok) throw new Error((await r.json().catch(() => ({}))).detail ?? r.statusText); - return r.json() as Promise<{ uploaded: number; errors: string[] }>; - }); + return fetch(`${BASE}/mafiles/upload`, { method: "POST", body: form }).then( + async (r) => { + if (!r.ok) + throw new Error( + (await r.json().catch(() => ({}))).detail ?? r.statusText, + ); + return r.json() as Promise<{ uploaded: number; errors: string[] }>; + }, + ); }, deleteMafile: (filename: string) => - request(`/mafiles/${encodeURIComponent(filename)}`, { method: "DELETE" }), - exportSecrets: () => request<{ account_name: string; shared_secret: string; identity_secret: string; steam_id: string }[]>("/mafiles/export/all"), + request(`/mafiles/${encodeURIComponent(filename)}`, { + method: "DELETE", + }), + exportSecrets: () => + request< + { + account_name: string; + shared_secret: string; + identity_secret: string; + steam_id: string; + }[] + >("/mafiles/export/all"), exportZip: (body: MafileExportRequest) => fetch(`${BASE}/mafiles/export/zip`, { method: "POST", @@ -110,80 +193,175 @@ export const api = { }), // Settings - getValidationSettings: () => request("/settings/validation"), + getValidationSettings: () => + request("/settings/validation"), updateValidationSettings: (data: ValidationSettings) => - request("/settings/validation", { method: "PUT", body: JSON.stringify(data) }), + request("/settings/validation", { + method: "PUT", + body: JSON.stringify(data), + }), getDisplaySettings: () => request("/settings/display"), updateDisplaySettings: (data: DisplaySettings) => - request("/settings/display", { method: "PUT", body: JSON.stringify(data) }), + request("/settings/display", { + method: "PUT", + body: JSON.stringify(data), + }), getColumnSettings: () => request("/settings/columns"), updateColumnSettings: (data: ColumnSettings) => - request("/settings/columns", { method: "PUT", body: JSON.stringify(data) }), - getLogpassColumnSettings: () => request("/settings/logpass-columns"), + request("/settings/columns", { + method: "PUT", + body: JSON.stringify(data), + }), + getLogpassColumnSettings: () => + request("/settings/logpass-columns"), updateLogpassColumnSettings: (data: LogpassColumnSettings) => - request("/settings/logpass-columns", { method: "PUT", body: JSON.stringify(data) }), + request("/settings/logpass-columns", { + method: "PUT", + body: JSON.stringify(data), + }), // Logs getLogs: () => request("/logs"), // Auto-accept startAutoAccept: (ids: number[]) => - request<{ started: number[] }>("/auto-accept/start", { method: "POST", body: JSON.stringify({ account_ids: ids }) }), + request<{ started: number[] }>("/auto-accept/start", { + method: "POST", + body: JSON.stringify({ account_ids: ids }), + }), stopAutoAccept: (ids: number[]) => - request<{ stopped: number[] }>("/auto-accept/stop", { method: "POST", body: JSON.stringify({ account_ids: ids }) }), + request<{ stopped: number[] }>("/auto-accept/stop", { + method: "POST", + body: JSON.stringify({ account_ids: ids }), + }), getAutoAcceptStatus: () => request<{ running: number[] }>("/auto-accept/status"), // Browser openBrowser: (id: number) => - request<{ status: string; message: string; task_id?: string }>(`/accounts/${id}/browser`, { method: "POST" }), + request<{ status: string; message: string; task_id?: string }>( + `/accounts/${id}/browser`, + { method: "POST" }, + ), // Logpass accounts getLogpassAccounts: () => request("/logpass"), createLogpassAccount: (data: LogpassAccountCreate) => - request("/logpass", { method: "POST", body: JSON.stringify(data) }), + request("/logpass", { + method: "POST", + body: JSON.stringify(data), + }), updateLogpassAccount: (id: number, data: LogpassAccountUpdate) => - request(`/logpass/${id}`, { method: "PUT", body: JSON.stringify(data) }), + request(`/logpass/${id}`, { + method: "PUT", + body: JSON.stringify(data), + }), deleteLogpassAccount: (id: number) => request(`/logpass/${id}`, { method: "DELETE" }), deleteLogpassBulk: (ids: number[]) => - request<{ deleted: number }>("/logpass/delete-bulk", { method: "POST", body: JSON.stringify({ ids }) }), + request<{ deleted: number }>("/logpass/delete-bulk", { + method: "POST", + body: JSON.stringify({ ids }), + }), importLogpass: (lines: string[]) => - request("/logpass/import", { method: "POST", body: JSON.stringify({ lines }) }), + request("/logpass/import", { + method: "POST", + body: JSON.stringify({ lines }), + }), validateLogpass: (account_ids: number[]) => - request<{ task_id: string; accounts_count: number }>("/logpass/validate", { method: "POST", body: JSON.stringify({ account_ids }) }), + request<{ task_id: string; accounts_count: number }>("/logpass/validate", { + method: "POST", + body: JSON.stringify({ account_ids }), + }), fullParseLogpass: (account_ids: number[]) => - request<{ task_id: string; accounts_count: number }>("/logpass/full-parse", { method: "POST", body: JSON.stringify({ account_ids }) }), + request<{ task_id: string; accounts_count: number }>( + "/logpass/full-parse", + { method: "POST", body: JSON.stringify({ account_ids }) }, + ), assignLogpassProxies: () => - request<{ assigned: number; proxies_used: number }>("/logpass/assign-proxies", { method: "POST" }), + request<{ assigned: number; proxies_used: number }>( + "/logpass/assign-proxies", + { method: "POST" }, + ), reassignLogpassProxies: () => - request<{ assigned: number; proxies_used: number }>("/logpass/reassign-proxies", { method: "POST" }), + request<{ assigned: number; proxies_used: number }>( + "/logpass/reassign-proxies", + { method: "POST" }, + ), clearLogpassProxies: () => request<{ cleared: number }>("/logpass/clear-proxies", { method: "POST" }), openLogpassBrowser: (id: number) => - request<{ status: string; message: string; task_id?: string }>(`/logpass/${id}/browser`, { method: "POST" }), + request<{ status: string; message: string; task_id?: string }>( + `/logpass/${id}/browser`, + { method: "POST" }, + ), // Token accounts getTokenAccounts: () => request("/token-accounts"), createTokenAccount: (data: TokenAccountCreate) => - request("/token-accounts", { method: "POST", body: JSON.stringify(data) }), + request("/token-accounts", { + method: "POST", + body: JSON.stringify(data), + }), deleteTokenAccount: (id: number) => request(`/token-accounts/${id}`, { method: "DELETE" }), deleteTokenBulk: (ids: number[]) => - request<{ deleted: number }>("/token-accounts/delete-bulk", { method: "POST", body: JSON.stringify({ ids }) }), + request<{ deleted: number }>("/token-accounts/delete-bulk", { + method: "POST", + body: JSON.stringify({ ids }), + }), importTokens: (lines: string[]) => - request("/token-accounts/import", { method: "POST", body: JSON.stringify({ lines }) }), + request("/token-accounts/import", { + method: "POST", + body: JSON.stringify({ lines }), + }), validateTokens: (ids: number[]) => - request<{ task_id: string; accounts_count: number }>("/token-accounts/validate", { method: "POST", body: JSON.stringify({ account_ids: ids }) }), + request<{ task_id: string; accounts_count: number }>( + "/token-accounts/validate", + { method: "POST", body: JSON.stringify({ account_ids: ids }) }, + ), openTokenBrowser: (id: number) => - request<{ status: string; message: string; task_id?: string }>(`/token-accounts/${id}/browser`, { method: "POST" }), + request<{ status: string; message: string; task_id?: string }>( + `/token-accounts/${id}/browser`, + { method: "POST" }, + ), assignTokenProxies: () => - request<{ assigned: number; proxies_used: number }>("/token-accounts/assign-proxies", { method: "POST" }), + request<{ assigned: number; proxies_used: number }>( + "/token-accounts/assign-proxies", + { method: "POST" }, + ), reassignTokenProxies: () => - request<{ assigned: number; proxies_used: number }>("/token-accounts/reassign-proxies", { method: "POST" }), + request<{ assigned: number; proxies_used: number }>( + "/token-accounts/reassign-proxies", + { method: "POST" }, + ), clearTokenProxies: () => - request<{ cleared: number }>("/token-accounts/clear-proxies", { method: "POST" }), - getTokenColumnSettings: () => request("/settings/token-columns"), + request<{ cleared: number }>("/token-accounts/clear-proxies", { + method: "POST", + }), + getTokenColumnSettings: () => + request("/settings/token-columns"), updateTokenColumnSettings: (data: TokenColumnSettings) => - request("/settings/token-columns", { method: "PUT", body: JSON.stringify(data) }), + request("/settings/token-columns", { + method: "PUT", + body: JSON.stringify(data), + }), + fullCheckTokens: (ids: number[]) => + request<{ task_id: string; accounts_count: number }>( + "/token-accounts/full-check", + { + method: "POST", + body: JSON.stringify({ account_ids: ids }), + }, + ), + getTokenCheckData: (id: number) => + request( + `/token-accounts/${id}/check-data`, + ), + downloadTokenCookies: (id: number) => { + const a = document.createElement("a"); + a.href = `${BASE}/token-accounts/${id}/cookies`; + a.download = ""; + a.click(); + }, }; diff --git a/frontend/src/api/types.ts b/frontend/src/api/types.ts index 012a410..67b700f 100644 --- a/frontend/src/api/types.ts +++ b/frontend/src/api/types.ts @@ -71,7 +71,10 @@ export interface Task { step_label?: string; active_count?: number; account_ids?: string | null; - account_results?: Record | string | null; + account_results?: + | Record + | string + | null; account_steps?: Record; created_at: string; updated_at: string; @@ -118,6 +121,14 @@ export interface ValidationSettings { check_ban: boolean; max_threads: number; auto_revalidate_browser: boolean; + auto_proxy_on_import: boolean; + auto_validate_on_import: boolean; + auto_proxy_on_import_mafile: boolean; + auto_proxy_on_import_logpass: boolean; + auto_proxy_on_import_token: boolean; + auto_validate_on_import_mafile: boolean; + auto_validate_on_import_logpass: boolean; + auto_validate_on_import_token: boolean; } export interface DisplaySettings { @@ -259,6 +270,32 @@ export interface Toast { message: string; } +export interface TokenCheckData { + steam_id: string | null; + display_name: string | null; + avatar_url: string | null; + steam_level: number | null; + last_online: string | null; + balance_raw: string | null; + user_country: string | null; + family_group: boolean; + playtime_2weeks: number; + inventory_cs2: number; + inventory_dota2: number; + inventory_tf2: number; + inventory_rust: number; + inventory_cs2_marketable: number; + inventory_dota2_marketable: number; + inventory_tf2_marketable: number; + inventory_rust_marketable: number; + trade_ban: string | null; + created_date: string | null; + phone_digits: string | null; + alert_status: string; + market_limited: boolean; + checked_at: string | null; +} + export interface SteamConfirmation { id: string; nonce: string; diff --git a/frontend/src/components/accounts/AccountTable.tsx b/frontend/src/components/accounts/AccountTable.tsx index 7d34762..9a73d23 100644 --- a/frontend/src/components/accounts/AccountTable.tsx +++ b/frontend/src/components/accounts/AccountTable.tsx @@ -6,17 +6,45 @@ import { AccountRow } from "./AccountRow"; import { useT } from "@/lib/i18n"; const COLUMN_KEYS: (keyof ColumnSettings)[] = [ - "browser", "profile", "last_online", "steam_id", "login", "password", "login_pass", - "email", "email_pass", "email_login_pass", "phone", "status", "ban", "twofa", "mafile", "proxy", "notes", "actions", + "browser", + "profile", + "last_online", + "steam_id", + "login", + "password", + "login_pass", + "email", + "email_pass", + "email_login_pass", + "phone", + "status", + "ban", + "twofa", + "mafile", + "proxy", + "notes", + "actions", ]; const COL_LABEL_KEYS: Record = { - browser: "col.browser", profile: "col.profile", last_online: "col.lastOnline", - steam_id: "col.steamId", login: "col.login", password: "col.password", - login_pass: "col.loginPass", email: "col.email", email_pass: "col.emailPass", - email_login_pass: "col.emailLoginPass", phone: "col.phone", status: "col.status", - ban: "col.ban", twofa: "col.twofa", mafile: "col.mafile", proxy: "col.proxy", - notes: "col.notes", actions: "col.actions", + browser: "col.browser", + profile: "col.profile", + last_online: "col.lastOnline", + steam_id: "col.steamId", + login: "col.login", + password: "col.password", + login_pass: "col.loginPass", + email: "col.email", + email_pass: "col.emailPass", + email_login_pass: "col.emailLoginPass", + phone: "col.phone", + status: "col.status", + ban: "col.ban", + twofa: "col.twofa", + mafile: "col.mafile", + proxy: "col.proxy", + notes: "col.notes", + actions: "col.actions", }; interface Props { @@ -26,19 +54,47 @@ interface Props { accountSteps: Record; onEdit: (id: number) => void; onDelete: (id: number) => void; - onAction: (id: number, action: string, params: Record) => void; + onAction: ( + id: number, + action: string, + params: Record, + ) => void; onToggleAutoAccept: (id: number) => void; onOpenBrowser: (id: number) => void; } -export function AccountTable({ accounts, processingIds, accountResults, accountSteps, onEdit, onDelete, onAction, onToggleAutoAccept, onOpenBrowser }: Props) { - const selectAll = useAccountStore((s) => s.selectAll); - const clearSelection = useAccountStore((s) => s.clearSelection); +export function AccountTable({ + accounts, + processingIds, + accountResults, + accountSteps, + onEdit, + onDelete, + onAction, + onToggleAutoAccept, + onOpenBrowser, +}: Props) { const selectedIds = useAccountStore((s) => s.selectedIds); + const setSelectedIds = useAccountStore((s) => s.setSelectedIds); const cols = useUiStore((s) => s.columnVisibility); const t = useT(); - const allSelected = accounts.length > 0 && selectedIds.size === accounts.length; + const allFilteredSelected = + accounts.length > 0 && accounts.every((a) => selectedIds.has(a.id)); + + const toggleSelectAllFiltered = () => { + if (allFilteredSelected) { + // Deselect only the filtered accounts, keep others selected + const next = new Set(selectedIds); + accounts.forEach((a) => next.delete(a.id)); + setSelectedIds(next); + } else { + // Add all filtered accounts to selection + const next = new Set(selectedIds); + accounts.forEach((a) => next.add(a.id)); + setSelectedIds(next); + } + }; const visibleKeys = COLUMN_KEYS.filter((k) => cols[k]); const BATCH = 100; @@ -52,7 +108,10 @@ export function AccountTable({ accounts, processingIds, accountResults, accountS const toggleSort = (field: SortField) => { if (sortField === field) { if (sortDir === "asc") setSortDir("desc"); - else { setSortField(null); setSortDir("asc"); } + else { + setSortField(null); + setSortDir("asc"); + } } else { setSortField(field); setSortDir("asc"); @@ -64,7 +123,9 @@ export function AccountTable({ accounts, processingIds, accountResults, accountS const dir = sortDir === "asc" ? 1 : -1; const EMPTY = Symbol(); return [...accounts].sort((a, b) => { - const parseOnline = (v: string | null | undefined): number | typeof EMPTY => { + const parseOnline = ( + v: string | null | undefined, + ): number | typeof EMPTY => { if (!v || v === "\u2014") return EMPTY; if (v === "online") return -1; const m = v.match(/^(\d+)([mhd])$/i); @@ -84,16 +145,25 @@ export function AccountTable({ accounts, processingIds, accountResults, accountS }); }, [accounts, sortField, sortDir]); - useEffect(() => { setVisibleCount(BATCH); }, [accounts, sortField, sortDir]); + useEffect(() => { + setVisibleCount(BATCH); + }, [accounts, sortField, sortDir]); - const visible = useMemo(() => sorted.slice(0, visibleCount), [sorted, visibleCount]); + const visible = useMemo( + () => sorted.slice(0, visibleCount), + [sorted, visibleCount], + ); useEffect(() => { const el = sentinelRef.current; if (!el) return; - const obs = new IntersectionObserver((entries) => { - if (entries[0].isIntersecting) setVisibleCount((c) => Math.min(c + BATCH, sorted.length)); - }, { rootMargin: "400px" }); + const obs = new IntersectionObserver( + (entries) => { + if (entries[0].isIntersecting) + setVisibleCount((c) => Math.min(c + BATCH, sorted.length)); + }, + { rootMargin: "400px" }, + ); obs.observe(el); return () => obs.disconnect(); }, [sorted.length, visibleCount]); @@ -135,11 +205,13 @@ export function AccountTable({ accounts, processingIds, accountResults, accountS
allSelected ? clearSelection() : selectAll()} + checked={allFilteredSelected} + onChange={toggleSelectAllFiltered} /> {selectedIds.size > 0 && ( - {selectedIds.size} + + {selectedIds.size} + )}
@@ -147,12 +219,28 @@ export function AccountTable({ accounts, processingIds, accountResults, accountS {visibleKeys.map((k) => { if (k === "last_online") { return ( - toggleSort("last_online")}> - {t(COL_LABEL_KEYS[k])}{sortField === "last_online" ? (sortDir === "asc" ? " ▲" : " ▼") : ""} + toggleSort("last_online")} + > + {t(COL_LABEL_KEYS[k])} + {sortField === "last_online" + ? sortDir === "asc" + ? " ▲" + : " ▼" + : ""} ); } - return {t(COL_LABEL_KEYS[k])}; + return ( + + {t(COL_LABEL_KEYS[k])} + + ); })} @@ -174,7 +262,17 @@ export function AccountTable({ accounts, processingIds, accountResults, accountS /> ))} {visibleCount < accounts.length && ( - {t("paging.shown", { visible: visibleCount, total: accounts.length })} + + + {t("paging.shown", { + visible: visibleCount, + total: accounts.length, + })} + + )} diff --git a/frontend/src/components/accounts/AccountsTab.tsx b/frontend/src/components/accounts/AccountsTab.tsx index 25dd4e4..51f662f 100644 --- a/frontend/src/components/accounts/AccountsTab.tsx +++ b/frontend/src/components/accounts/AccountsTab.tsx @@ -12,9 +12,18 @@ import { AddModal } from "./AddModal"; import { ConfirmModal } from "@/components/shared/Modals"; import { ColumnSettingsDropdown } from "./ColumnSettingsDropdown"; import { - IconDownload, IconPlus, IconCheckCircle, IconXCircle, - IconFolder, IconGlobe, IconRefresh, IconBan, - IconPlay, IconLock, IconKey, IconZap, + IconDownload, + IconPlus, + IconCheckCircle, + IconXCircle, + IconFolder, + IconGlobe, + IconRefresh, + IconBan, + IconPlay, + IconLock, + IconKey, + IconZap, } from "@/components/shared/Icons"; import { LogpassTab } from "./LogpassTab"; import { TokenTab } from "./TokenTab"; @@ -28,14 +37,22 @@ type AccResults = Record; function parseAccResults(raw: Task["account_results"]): AccResults | null { if (!raw) return null; if (typeof raw === "string") { - try { return JSON.parse(raw) as AccResults; } catch { return null; } + try { + return JSON.parse(raw) as AccResults; + } catch { + return null; + } } return raw; } function parseIds(raw: Task["account_ids"]): number[] { if (!raw) return []; - try { return JSON.parse(raw) as number[]; } catch { return []; } + try { + return JSON.parse(raw) as number[]; + } catch { + return []; + } } const BULK_ACTIONS = [ @@ -48,7 +65,15 @@ const BULK_ACTIONS = [ { value: "enable_auto_accept", labelKey: "action.enableAutoAccept" }, ] as const; -function BulkActionDropdown({ value, onChange, disabledActions }: { value: string; onChange: (v: string) => void; disabledActions?: Set }) { +function BulkActionDropdown({ + value, + onChange, + disabledActions, +}: { + value: string; + onChange: (v: string) => void; + disabledActions?: Set; +}) { const t = useT(); const [open, setOpen] = useState(false); const ref = useRef(null); @@ -56,13 +81,17 @@ function BulkActionDropdown({ value, onChange, disabledActions }: { value: strin useEffect(() => { if (!open) return; const handler = (e: MouseEvent) => { - if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false); + if (ref.current && !ref.current.contains(e.target as Node)) + setOpen(false); }; document.addEventListener("mousedown", handler); return () => document.removeEventListener("mousedown", handler); }, [open]); - const label = t(BULK_ACTIONS.find((a) => a.value === value)?.labelKey || "action.selectAction"); + const label = t( + BULK_ACTIONS.find((a) => a.value === value)?.labelKey || + "action.selectAction", + ); return (
@@ -72,8 +101,20 @@ function BulkActionDropdown({ value, onChange, disabledActions }: { value: strin className="bg-dark-700 border border-dark-600 rounded px-2 py-1.5 text-sm flex items-center gap-1 min-w-[170px] justify-between hover:border-dark-500 transition-colors" > {label} - - + + {open && ( @@ -84,7 +125,12 @@ function BulkActionDropdown({ value, onChange, disabledActions }: { value: strin
- - + + + + + - - + + + + +
- {displayCount} + + {displayCount} +
); } @@ -174,6 +255,8 @@ export function AccountsTab() { const sendToMafileManager = useAccountStore((s) => s.sendToMafileManager); const setTab = useUiStore((s) => s.setTab); const addToast = useUiStore((s) => s.addToast); + const autoProxyOnImport = useUiStore((s) => s.autoProxyOnImportMafile); + const autoValidateOnImport = useUiStore((s) => s.autoValidateOnImportMafile); const loadTasks = useTaskStore((s) => s.loadTasks); const t = useT(); @@ -181,17 +264,27 @@ export function AccountsTab() { const [showImport, setShowImport] = useState(false); const [showAdd, setShowAdd] = useState(false); const [confirmMsg, setConfirmMsg] = useState(null); - const [onConfirmAction, setOnConfirmAction] = useState<(() => void) | null>(null); + const [onConfirmAction, setOnConfirmAction] = useState<(() => void) | null>( + null, + ); const [bulkAction, setBulkAction] = useState(""); const section = useUiStore((s) => s.accountSection); const setSection = useUiStore((s) => s.setAccountSection); const [activeTask, setActiveTask] = useState(null); const [processingIds, setProcessingIds] = useState>(new Set()); const [searchQuery, setSearchQuery] = useState(""); - const [promptData, setPromptData] = useState<{ taskId: string; message: string; login?: string } | null>(null); + const [promptData, setPromptData] = useState<{ + taskId: string; + message: string; + login?: string; + } | null>(null); const [promptValue, setPromptValue] = useState(""); - const [accountResults, setAccountResults] = useState>({}); - const [accountSteps, setAccountSteps] = useState>({}); + const [accountResults, setAccountResults] = useState< + Record + >({}); + const [accountSteps, setAccountSteps] = useState< + Record + >({}); const filteredAccounts = useMemo(() => { if (!searchQuery.trim()) return accounts; @@ -235,60 +328,81 @@ export function AccountsTab() { return disabled; }, [accounts, selectedIds]); - useEffect(() => { loadAccounts(); }, []); + useEffect(() => { + loadAccounts(); + }, []); const confirm = (msg: string, action: () => void) => { setConfirmMsg(msg); setOnConfirmAction(() => action); }; - const watchTask = useCallback((taskId: string, accountIds: number[] = [], clearResults = true) => { - if (clearResults) { - setAccountResults((prev) => { - const next = { ...prev }; - accountIds.forEach((id) => delete next[String(id)]); - return next; - }); - } - const es = new EventSource(`/api/tasks/${taskId}/stream`); - es.onmessage = (e) => { - try { - const data = JSON.parse(e.data) as Task; - setActiveTask(data); - const parsed = parseAccResults(data.account_results); - if (parsed) { - setAccountResults((prev) => ({ ...prev, ...parsed })); - } - if (data.account_steps) { - setAccountSteps((prev) => ({ ...prev, ...data.account_steps })); - } - if (data.prompt) { - setPromptData({ taskId, message: data.prompt, login: data.prompt_login }); - setPromptValue(""); - } - if (data.status === "completed" || data.status === "failed" || data.status === "cancelled") { - if (data.status === "completed") { - addToast("success", `${data.type}: ${data.result || t("toast.done")}`); - } else if (data.status === "cancelled") { - addToast("info", t("toast.taskCancelled")); - } else { - addToast("error", `${data.type}: ${data.error || t("toast.error")}`); + const watchTask = useCallback( + (taskId: string, accountIds: number[] = [], clearResults = true) => { + if (clearResults) { + setAccountResults((prev) => { + const next = { ...prev }; + accountIds.forEach((id) => delete next[String(id)]); + return next; + }); + } + const es = new EventSource(`/api/tasks/${taskId}/stream`); + es.onmessage = (e) => { + try { + const data = JSON.parse(e.data) as Task; + setActiveTask(data); + const parsed = parseAccResults(data.account_results); + if (parsed) { + setAccountResults((prev) => ({ ...prev, ...parsed })); } - setProcessingIds((prev) => { - const s = new Set(prev); - accountIds.forEach((id) => s.delete(id)); - return s; - }); - setPromptData(null); - loadAccounts(); - loadTasks(); - es.close(); - setTimeout(() => setActiveTask(null), 3000); + if (data.account_steps) { + setAccountSteps((prev) => ({ ...prev, ...data.account_steps })); + } + if (data.prompt) { + setPromptData({ + taskId, + message: data.prompt, + login: data.prompt_login, + }); + setPromptValue(""); + } + if ( + data.status === "completed" || + data.status === "failed" || + data.status === "cancelled" + ) { + if (data.status === "completed") { + addToast( + "success", + `${data.type}: ${data.result || t("toast.done")}`, + ); + } else if (data.status === "cancelled") { + addToast("info", t("toast.taskCancelled")); + } else { + addToast( + "error", + `${data.type}: ${data.error || t("toast.error")}`, + ); + } + setProcessingIds((prev) => { + const s = new Set(prev); + accountIds.forEach((id) => s.delete(id)); + return s; + }); + setPromptData(null); + loadAccounts(); + loadTasks(); + es.close(); + setTimeout(() => setActiveTask(null), 3000); + } + } catch { + /* ignore */ } - } catch { /* ignore */ } - }; - es.onerror = () => es.close(); - }, [addToast, loadAccounts, loadTasks]); + }; + es.onerror = () => es.close(); + }, + [addToast, loadAccounts, loadTasks], + ); // Restore running/completed task state on page load useEffect(() => { @@ -309,45 +423,80 @@ export function AccountsTab() { return; } - const recent = tasks.find((t) => t.status === "completed" || t.status === "failed"); + const recent = tasks.find( + (t) => t.status === "completed" || t.status === "failed", + ); if (recent) { const restored = parseAccResults(recent.account_results); if (restored && Object.keys(restored).length > 0) { setAccountResults(restored); } } - } catch { /* ignore */ } + } catch { + /* ignore */ + } })(); - return () => { cancelled = true; }; + return () => { + cancelled = true; + }; }, [watchTask]); - const handleAction = async (id: number, action: string, params: Record) => { + const handleAction = async ( + id: number, + action: string, + params: Record, + ) => { const acc = accounts.find((a) => a.id === id); const login = acc?.login ?? `#${id}`; try { setProcessingIds((prev) => new Set(prev).add(id)); - const result = await api.executeAction({ account_ids: [id], action, params }); - addToast("info", t("misc.taskAction", { id: result.task_id, action, login })); + const result = await api.executeAction({ + account_ids: [id], + action, + params, + }); + addToast( + "info", + t("misc.taskAction", { id: result.task_id, action, login }), + ); watchTask(result.task_id, [id]); } catch (e: unknown) { - setProcessingIds((prev) => { const s = new Set(prev); s.delete(id); return s; }); - addToast("error", t("misc.error", { error: e instanceof Error ? e.message : String(e) })); + setProcessingIds((prev) => { + const s = new Set(prev); + s.delete(id); + return s; + }); + addToast( + "error", + t("misc.error", { error: e instanceof Error ? e.message : String(e) }), + ); } }; const handlePromptSubmit = async () => { if (!promptData || !promptValue) return; try { - await api.respondToPrompt(promptData.taskId, promptValue, promptData.login); + await api.respondToPrompt( + promptData.taskId, + promptValue, + promptData.login, + ); setPromptData(null); } catch (e: unknown) { - addToast("error", t("misc.error", { error: e instanceof Error ? e.message : String(e) })); + addToast( + "error", + t("misc.error", { error: e instanceof Error ? e.message : String(e) }), + ); } }; const handlePromptCancel = async () => { if (promptData) { - try { await api.cancelTask(promptData.taskId); } catch { /* task may already be done */ } + try { + await api.cancelTask(promptData.taskId); + } catch { + /* task may already be done */ + } } setPromptData(null); }; @@ -359,26 +508,64 @@ export function AccountsTab() { if (bulkAction === "enable_auto_accept") { const ids = [...selectedIds]; clearSelection(); - api.startAutoAccept(ids) - .then(() => { addToast("success", t("toast.autoAcceptEnabled", { count: ids.length })); loadAccounts(); }) - .catch((e: unknown) => addToast("error", t("misc.error", { error: e instanceof Error ? e.message : String(e) }))); + api + .startAutoAccept(ids) + .then(() => { + addToast( + "success", + t("toast.autoAcceptEnabled", { count: ids.length }), + ); + loadAccounts(); + }) + .catch((e: unknown) => + addToast( + "error", + t("misc.error", { + error: e instanceof Error ? e.message : String(e), + }), + ), + ); return; } const capturedIds = [...selectedIds]; const capturedAction = bulkAction; - const actionLabel = t(BULK_ACTIONS.find((a) => a.value === capturedAction)?.labelKey || "action.selectAction"); + const actionLabel = t( + BULK_ACTIONS.find((a) => a.value === capturedAction)?.labelKey || + "action.selectAction", + ); confirm( - t("confirm.executeBulk", { action: actionLabel, count: capturedIds.length }), + t("confirm.executeBulk", { + action: actionLabel, + count: capturedIds.length, + }), async () => { try { - const result = await api.executeAction({ account_ids: capturedIds, action: capturedAction }); + const result = await api.executeAction({ + account_ids: capturedIds, + action: capturedAction, + }); clearSelection(); - setProcessingIds((prev) => { const s = new Set(prev); capturedIds.forEach((id) => s.add(id)); return s; }); - addToast("info", t("misc.taskCount", { id: result.task_id, count: result.accounts_count })); + setProcessingIds((prev) => { + const s = new Set(prev); + capturedIds.forEach((id) => s.add(id)); + return s; + }); + addToast( + "info", + t("misc.taskCount", { + id: result.task_id, + count: result.accounts_count, + }), + ); watchTask(result.task_id, capturedIds); } catch (e: unknown) { - addToast("error", t("misc.error", { error: e instanceof Error ? e.message : String(e) })); + addToast( + "error", + t("misc.error", { + error: e instanceof Error ? e.message : String(e), + }), + ); } }, ); @@ -391,10 +578,16 @@ export function AccountsTab() { try { if (enable) await api.startAutoAccept([id]); else await api.stopAutoAccept([id]); - addToast("info", enable ? t("toast.autoAcceptOn") : t("toast.autoAcceptOff")); + addToast( + "info", + enable ? t("toast.autoAcceptOn") : t("toast.autoAcceptOff"), + ); await loadAccounts(); } catch (e: unknown) { - addToast("error", t("misc.error", { error: e instanceof Error ? e.message : String(e) })); + addToast( + "error", + t("misc.error", { error: e instanceof Error ? e.message : String(e) }), + ); } }; @@ -407,7 +600,10 @@ export function AccountsTab() { addToast("success", t("toast.saved")); await loadAccounts(); } catch (e: unknown) { - addToast("error", t("misc.error", { error: e instanceof Error ? e.message : String(e) })); + addToast( + "error", + t("misc.error", { error: e instanceof Error ? e.message : String(e) }), + ); } }; @@ -418,23 +614,36 @@ export function AccountsTab() { addToast("success", t("toast.accountDeleted")); await loadAccounts(); } catch (e: unknown) { - addToast("error", t("misc.error", { error: e instanceof Error ? e.message : String(e) })); + addToast( + "error", + t("misc.error", { + error: e instanceof Error ? e.message : String(e), + }), + ); } }); }; const handleDeleteSelected = () => { if (!selectedIds.size) return addToast("warn", t("toast.selectAccounts")); - confirm(t("confirm.deleteSelected", { count: selectedIds.size }), async () => { - try { - const result = await api.deleteBulk([...selectedIds]); - clearSelection(); - addToast("success", t("toast.deleted", { count: result.deleted })); - await loadAccounts(); - } catch (e: unknown) { - addToast("error", t("misc.error", { error: e instanceof Error ? e.message : String(e) })); - } - }); + confirm( + t("confirm.deleteSelected", { count: selectedIds.size }), + async () => { + try { + const result = await api.deleteBulk([...selectedIds]); + clearSelection(); + addToast("success", t("toast.deleted", { count: result.deleted })); + await loadAccounts(); + } catch (e: unknown) { + addToast( + "error", + t("misc.error", { + error: e instanceof Error ? e.message : String(e), + }), + ); + } + }, + ); }; const handleDeleteAll = () => { @@ -446,7 +655,12 @@ export function AccountsTab() { addToast("success", t("toast.deleted", { count: result.deleted })); await loadAccounts(); } catch (e: unknown) { - addToast("error", t("misc.error", { error: e instanceof Error ? e.message : String(e) })); + addToast( + "error", + t("misc.error", { + error: e instanceof Error ? e.message : String(e), + }), + ); } }); }; @@ -458,7 +672,10 @@ export function AccountsTab() { addToast("success", t("toast.accountAdded")); await loadAccounts(); } catch (e: unknown) { - addToast("error", t("misc.error", { error: e instanceof Error ? e.message : String(e) })); + addToast( + "error", + t("misc.error", { error: e instanceof Error ? e.message : String(e) }), + ); } }; @@ -482,7 +699,10 @@ export function AccountsTab() { addToast("info", t("toast.browserOpening")); } } catch (e: unknown) { - addToast("error", t("misc.error", { error: e instanceof Error ? e.message : String(e) })); + addToast( + "error", + t("misc.error", { error: e instanceof Error ? e.message : String(e) }), + ); } }; @@ -490,10 +710,21 @@ export function AccountsTab() { confirm(t("confirm.assignProxies"), async () => { try { const r = await api.assignProxies(); - addToast("success", t("toast.proxiesAssigned", { used: r.proxies_used, count: r.assigned })); + addToast( + "success", + t("toast.proxiesAssigned", { + used: r.proxies_used, + count: r.assigned, + }), + ); await loadAccounts(); } catch (e: unknown) { - addToast("error", t("misc.error", { error: e instanceof Error ? e.message : String(e) })); + addToast( + "error", + t("misc.error", { + error: e instanceof Error ? e.message : String(e), + }), + ); } }); }; @@ -502,10 +733,21 @@ export function AccountsTab() { confirm(t("confirm.reassignProxies"), async () => { try { const r = await api.reassignProxies(); - addToast("success", t("toast.proxiesReassigned", { used: r.proxies_used, count: r.assigned })); + addToast( + "success", + t("toast.proxiesReassigned", { + used: r.proxies_used, + count: r.assigned, + }), + ); await loadAccounts(); } catch (e: unknown) { - addToast("error", t("misc.error", { error: e instanceof Error ? e.message : String(e) })); + addToast( + "error", + t("misc.error", { + error: e instanceof Error ? e.message : String(e), + }), + ); } }); }; @@ -514,17 +756,95 @@ export function AccountsTab() { confirm(t("confirm.clearProxies"), async () => { try { const r = await api.clearProxies(); - addToast("success", t("toast.proxiesClearedCount", { count: r.cleared })); + addToast( + "success", + t("toast.proxiesClearedCount", { count: r.cleared }), + ); await loadAccounts(); } catch (e: unknown) { - addToast("error", t("misc.error", { error: e instanceof Error ? e.message : String(e) })); + addToast( + "error", + t("misc.error", { + error: e instanceof Error ? e.message : String(e), + }), + ); } }); }; + const handleAfterImport = useCallback( + async (newIds: number[]) => { + let proxyOn = autoProxyOnImport; + let validateOn = autoValidateOnImport; + try { + const fresh = await api.getValidationSettings(); + proxyOn = fresh.auto_proxy_on_import_mafile; + validateOn = fresh.auto_validate_on_import_mafile; + } catch { + /* fall back to stale store values */ + } + + if (proxyOn) { + try { + const r = await api.assignProxies(); + addToast( + "success", + t("toast.proxiesAssignedShort", { count: r.assigned }), + ); + await loadAccounts(); + } catch { + /* ignore */ + } + } + if (validateOn && newIds.length) { + try { + setProcessingIds(new Set(newIds)); + const result = await api.executeAction({ + account_ids: newIds, + action: "validate", + }); + setActiveTask({ + id: result.task_id, + type: "validate", + status: "running", + progress: 0, + total: newIds.length, + result: null, + error: null, + account_ids: null, + account_results: null, + created_at: "", + updated_at: "", + }); + watchTask(result.task_id, newIds); + } catch (e: unknown) { + setProcessingIds(new Set()); + addToast( + "error", + t("misc.error", { + error: e instanceof Error ? e.message : String(e), + }), + ); + } + } + }, + [ + autoProxyOnImport, + autoValidateOnImport, + addToast, + loadAccounts, + watchTask, + t, + ], + ); + const editAccount = editId ? accounts.find((a) => a.id === editId) : null; - const SECTIONS: { id: AccountSection; label: string; icon: React.ReactNode }[] = [ + const SECTIONS: { + id: AccountSection; + label: string; + icon: React.ReactNode; + }[] = [ { id: "mafile", label: "Mafile", icon: }, { id: "logpass", label: "Log:Pass", icon: }, { id: "token", label: "Token", icon: }, @@ -534,140 +854,263 @@ export function AccountsTab() {
{/* Section sidebar */}
-

{t("section.dataType")}

+

+ {t("section.dataType")} +

{SECTIONS.map((s) => ( ))}
- {section === "logpass" &&
} - {section === "token" &&
} - {section === "mafile" &&
- {/* Toolbar */} -
- - + {section === "logpass" && ( +
+ +
+ )} + {section === "token" && ( +
+ +
+ )} + {section === "mafile" && ( +
+ {/* Toolbar */} +
+ + - {/* Inline progress indicator */} - {activeTask && ( - <> -
-
- - {activeTask.type === "validate" ? t("task.validate") : - activeTask.type === "change_password" ? t("task.changePassword") : - activeTask.type === "random_password" ? t("task.randomPassword") : - activeTask.type === "change_email" ? t("task.changeEmail") : - activeTask.type === "change_phone" ? t("task.changePhone") : - activeTask.type === "remove_guard" ? t("task.removeGuard") : - activeTask.type} - -
-
1 - ? (activeTask.total > 0 ? Math.round((activeTask.progress / activeTask.total) * 100) : 0) - : (activeTask.total_steps ? Math.round(((activeTask.step ?? 0) / activeTask.total_steps) * 100) : 0)}%` }} + {/* Inline progress indicator */} + {activeTask && ( + <> +
+
+ + {activeTask.type === "validate" + ? t("task.validate") + : activeTask.type === "change_password" + ? t("task.changePassword") + : activeTask.type === "random_password" + ? t("task.randomPassword") + : activeTask.type === "change_email" + ? t("task.changeEmail") + : activeTask.type === "change_phone" + ? t("task.changePhone") + : activeTask.type === "remove_guard" + ? t("task.removeGuard") + : activeTask.type} + +
+
1 + ? activeTask.total > 0 + ? Math.round( + (activeTask.progress / activeTask.total) * + 100, + ) + : 0 + : activeTask.total_steps + ? Math.round( + ((activeTask.step ?? 0) / + activeTask.total_steps) * + 100, + ) + : 0 + }%`, + }} + /> +
+ + {activeTask.total > 1 + ? `${activeTask.progress}/${activeTask.total}${activeTask.active_count ? ` (${activeTask.active_count})` : ""}` + : activeTask.step_label || + `${activeTask.progress}/${activeTask.total}`} + {activeTask.total > 1 + ? ` (${activeTask.total > 0 ? Math.round((activeTask.progress / activeTask.total) * 100) : 0}%)` + : activeTask.total_steps + ? ` (${activeTask.step}/${activeTask.total_steps})` + : ""} + + {activeTask.status === "completed" && ( + + )} + {activeTask.status === "failed" && ( + + + + )} +
+ + )} + +
+ +
+ + +
+
+ + {/* Table with action bar */} +
+ {/* Action bar (table header panel) */} +
+ + + {activeTask && activeTask.status === "running" && ( + + )} +
+ +
+ + + +
+ setSearchQuery(e.target.value)} + placeholder={t("ph.search")} + className="bg-dark-700 border border-dark-600 rounded px-2 py-1.5 text-xs w-80 placeholder:text-gray-500 outline-none focus:border-accent" />
- - {activeTask.total > 1 - ? `${activeTask.progress}/${activeTask.total}${activeTask.active_count ? ` (${activeTask.active_count})` : ""}` - : (activeTask.step_label || `${activeTask.progress}/${activeTask.total}`)} - {activeTask.total > 1 - ? ` (${activeTask.total > 0 ? Math.round((activeTask.progress / activeTask.total) * 100) : 0}%)` - : (activeTask.total_steps ? ` (${activeTask.step}/${activeTask.total_steps})` : "")} - - {activeTask.status === "completed" && } - {activeTask.status === "failed" && }
- - )} - -
- -
- - -
-
- - {/* Table with action bar */} -
- {/* Action bar (table header panel) */} -
- - - {activeTask && activeTask.status === "running" && ( - - )} -
- -
- - - -
- setSearchQuery(e.target.value)} - placeholder={t("ph.search")} - className="bg-dark-700 border border-dark-600 rounded px-2 py-1.5 text-xs w-80 placeholder:text-gray-500 outline-none focus:border-accent" - /> + {/* Table */} +
+ +
- {/* Table */} -
- -
-
-
} + )} {/* Modals */} {editAccount && ( - setEditId(null)} /> + setEditId(null)} + /> + )} + {showImport && ( + setShowImport(false)} + onImportDone={handleAfterImport} + /> + )} + {showAdd && ( + setShowAdd(false)} /> )} - {showImport && setShowImport(false)} />} - {showAdd && setShowAdd(false)} />} {confirmMsg && onConfirmAction && ( { onConfirmAction(); setConfirmMsg(null); setOnConfirmAction(null); }} - onCancel={() => { setConfirmMsg(null); setOnConfirmAction(null); }} + onConfirm={() => { + onConfirmAction(); + setConfirmMsg(null); + setOnConfirmAction(null); + }} + onCancel={() => { + setConfirmMsg(null); + setOnConfirmAction(null); + }} /> )} {promptData && ( -
-
e.stopPropagation()}> +
+
e.stopPropagation()} + >

{promptData.message}

- - + +
diff --git a/frontend/src/components/accounts/AddModal.tsx b/frontend/src/components/accounts/AddModal.tsx index a7f9ea2..21cc534 100644 --- a/frontend/src/components/accounts/AddModal.tsx +++ b/frontend/src/components/accounts/AddModal.tsx @@ -2,7 +2,7 @@ import { useState, useRef } from "react"; import type { AccountCreate } from "@/api/types"; import { api } from "@/api/client"; import { useUiStore } from "@/stores/uiStore"; -import { useAccountStore } from "@/stores/accountStore"; + import { IconUpload } from "@/components/shared/Icons"; import { useT } from "@/lib/i18n"; @@ -14,7 +14,7 @@ interface Props { export function AddModal({ onSave, onClose }: Props) { const t = useT(); const addToast = useUiStore((s) => s.addToast); - const loadAccounts = useAccountStore((s) => s.loadAccounts); + const [login, setLogin] = useState(""); const [password, setPassword] = useState(""); const [email, setEmail] = useState(""); @@ -63,7 +63,10 @@ export function AddModal({ onSave, onClose }: Props) { return (
-
e.stopPropagation()}> +
e.stopPropagation()} + >

{t("modal.addAccount")}

- setPassword(e.target.value)} placeholder={t("ph.password")} className="w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm" /> + setPassword(e.target.value)} + placeholder={t("ph.password")} + className="w-full bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm" + />
- setEmail(e.target.value)} placeholder="Email" className="bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm" /> - setEmailPassword(e.target.value)} placeholder={t("ph.emailPassword")} className="bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm" /> + setEmail(e.target.value)} + placeholder="Email" + className="bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm" + /> + setEmailPassword(e.target.value)} + placeholder={t("ph.emailPassword")} + className="bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm" + />
- setProxy(e.target.value)} placeholder={t("ph.proxyOptional")} className="bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm" /> - setNotes(e.target.value)} placeholder={t("ph.notesOptional")} className="bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm" /> + setProxy(e.target.value)} + placeholder={t("ph.proxyOptional")} + className="bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm" + /> + setNotes(e.target.value)} + placeholder={t("ph.notesOptional")} + className="bg-dark-700 border border-dark-600 rounded px-3 py-2 text-sm" + />
{mafile && ( )}
- { - const f = e.target.files?.[0]; - if (f) setMafile(f); - }} /> + { + const f = e.target.files?.[0]; + if (f) setMafile(f); + }} + /> -
diff --git a/frontend/src/components/accounts/ImportModal.tsx b/frontend/src/components/accounts/ImportModal.tsx index 57a0f67..7f0a33a 100644 --- a/frontend/src/components/accounts/ImportModal.tsx +++ b/frontend/src/components/accounts/ImportModal.tsx @@ -7,9 +7,10 @@ import { useT } from "@/lib/i18n"; interface Props { onClose: () => void; + onImportDone?: (newIds: number[]) => void; } -export function ImportModal({ onClose }: Props) { +export function ImportModal({ onClose, onImportDone }: Props) { const t = useT(); const [file, setFile] = useState(null); const [result, setResult] = useState(""); @@ -28,10 +29,23 @@ export function ImportModal({ onClose }: Props) { if (!file) return; setUploading(true); try { + const idsBefore = new Set( + useAccountStore.getState().accounts.map((a) => a.id), + ); const res = await api.importAccounts(file); - setResult(t("toast.importResult", { imported: res.imported, skipped: res.skipped })); + setResult( + t("toast.importResult", { + imported: res.imported, + skipped: res.skipped, + }), + ); addToast("success", `${res.imported} ok, ${res.skipped} skip`); await loadAccounts(); + const newIds = useAccountStore + .getState() + .accounts.map((a) => a.id) + .filter((id) => !idsBefore.has(id)); + onImportDone?.(newIds); } catch (e: unknown) { setResult(e instanceof Error ? e.message : t("misc.errorStr")); } finally { @@ -41,13 +55,30 @@ export function ImportModal({ onClose }: Props) { return (
-
e.stopPropagation()}> -

{t("modal.importAccounts")}

+
e.stopPropagation()} + > +

+ {t("modal.importAccounts")} +

-

{t("import.formats")} ({t("import.delimiter")} : {t("import.or")} |)

-

login:pass:{"{"}mafile{"}"}

-

login:pass:email:email_pass:{"{"}mafile{"}"}

-

login:pass:email:email_pass:{"{"}mafile{"}"}:notes

+

+ {t("import.formats")}{" "} + + ({t("import.delimiter")} :{" "} + {t("import.or")} |) + +

+

+ login:pass:{"{"}mafile{"}"} +

+

+ login:pass:email:email_pass:{"{"}mafile{"}"} +

+

+ login:pass:email:email_pass:{"{"}mafile{"}"}:notes +

login:pass:email:email_pass

login:pass:email:email_pass:notes

@@ -59,14 +90,26 @@ export function ImportModal({ onClose }: Props) { >

- {file ? t("import.selected", { name: file.name }) : t("import.dragTxt")} + {file + ? t("import.selected", { name: file.name }) + : t("import.dragTxt")}

- { - const f = e.target.files?.[0]; - if (f) setFile(f); - }} /> - {result &&

{result}

} diff --git a/frontend/src/components/accounts/LogpassImportModal.tsx b/frontend/src/components/accounts/LogpassImportModal.tsx index 792e8c8..a2e4a11 100644 --- a/frontend/src/components/accounts/LogpassImportModal.tsx +++ b/frontend/src/components/accounts/LogpassImportModal.tsx @@ -7,9 +7,10 @@ import { useT } from "@/lib/i18n"; interface Props { onClose: () => void; + onImportDone?: (newIds: number[]) => void; } -export function LogpassImportModal({ onClose }: Props) { +export function LogpassImportModal({ onClose, onImportDone }: Props) { const t = useT(); const [file, setFile] = useState(null); const [result, setResult] = useState(""); @@ -29,12 +30,33 @@ export function LogpassImportModal({ onClose }: Props) { setUploading(true); try { const text = await file.text(); - const lines = text.split("\n").map((l) => l.trim()).filter(Boolean); - if (!lines.length) { setResult(t("toast.fileEmpty")); setUploading(false); return; } + const lines = text + .split("\n") + .map((l) => l.trim()) + .filter(Boolean); + if (!lines.length) { + setResult(t("toast.fileEmpty")); + setUploading(false); + return; + } + // Snapshot IDs before import to detect new ones + const idsBefore = new Set( + useLogpassStore.getState().accounts.map((a) => a.id), + ); const res = await api.importLogpass(lines); - setResult(t("toast.importResult", { imported: res.imported, skipped: res.skipped })); + setResult( + t("toast.importResult", { + imported: res.imported, + skipped: res.skipped, + }), + ); addToast("success", `${res.imported} ok, ${res.skipped} skip`); await loadAccounts(); + const newIds = useLogpassStore + .getState() + .accounts.map((a) => a.id) + .filter((id) => !idsBefore.has(id)); + onImportDone?.(newIds); } catch (e: unknown) { setResult(e instanceof Error ? e.message : t("misc.errorStr")); } finally { @@ -44,14 +66,25 @@ export function LogpassImportModal({ onClose }: Props) { return (
-
e.stopPropagation()}> -

{t("modal.importAccounts")}

+
e.stopPropagation()} + > +

+ {t("modal.importAccounts")} +

-

{t("import.formatsColon")}

+

+ {t("import.formatsColon")} +

login:pass

login|pass

-

CSV: login,password,steam_id,ban,prime,trophy,behavior,license

-

⚠ Mafile-файлы и JSON не принимаются. Только log:pass / log|pass.

+

+ CSV: login,password,steam_id,ban,prime,trophy,behavior,license +

+

+ ⚠ Mafile-файлы и JSON не принимаются. Только log:pass / log|pass. +

e.preventDefault()} @@ -61,14 +94,26 @@ export function LogpassImportModal({ onClose }: Props) { >

- {file ? t("import.selected", { name: file.name }) : t("import.dragTxtCsv")} + {file + ? t("import.selected", { name: file.name }) + : t("import.dragTxtCsv")}

- { - const f = e.target.files?.[0]; - if (f) setFile(f); - }} /> - {result &&

{result}

} diff --git a/frontend/src/components/accounts/LogpassTab.tsx b/frontend/src/components/accounts/LogpassTab.tsx index cc0546a..f8be296 100644 --- a/frontend/src/components/accounts/LogpassTab.tsx +++ b/frontend/src/components/accounts/LogpassTab.tsx @@ -11,9 +11,20 @@ import { StatusBadge, BanBadge } from "./Badges"; import { SteamLevelBadge } from "./SteamLevelBadge"; import { copyText } from "@/lib/clipboard"; import { - IconDownload, IconPlus, IconPlay, IconTrash, IconCheckCircle, IconXCircle, - IconEye, IconEyeOff, IconGlobe, IconRefresh, IconBan, - IconCheck, IconAlertTriangle, IconEdit, + IconDownload, + IconPlus, + IconPlay, + IconTrash, + IconCheckCircle, + IconXCircle, + IconEye, + IconEyeOff, + IconGlobe, + IconRefresh, + IconBan, + IconCheck, + IconAlertTriangle, + IconEdit, } from "@/components/shared/Icons"; import type { Task, LogpassColumnSettings } from "@/api/types"; import { useT } from "@/lib/i18n"; @@ -24,7 +35,11 @@ type AccSteps = Record; function parseAccResults(raw: Task["account_results"]): AccResults | null { if (!raw) return null; if (typeof raw === "string") { - try { return JSON.parse(raw) as AccResults; } catch { return null; } + try { + return JSON.parse(raw) as AccResults; + } catch { + return null; + } } return raw; } @@ -33,9 +48,11 @@ export function LogpassTab() { const accounts = useLogpassStore((s) => s.accounts); const selectedIds = useLogpassStore((s) => s.selectedIds); const loadAccounts = useLogpassStore((s) => s.loadAccounts); - const selectAll = useLogpassStore((s) => s.selectAll); const clearSelection = useLogpassStore((s) => s.clearSelection); + const setSelectedIds = useLogpassStore((s) => s.setSelectedIds); const addToast = useUiStore((s) => s.addToast); + const autoProxyOnImport = useUiStore((s) => s.autoProxyOnImportLogpass); + const autoValidateOnImport = useUiStore((s) => s.autoValidateOnImportLogpass); const cols = useUiStore((s) => s.logpassColumnVisibility); const t = useT(); @@ -43,7 +60,11 @@ export function LogpassTab() { const [showImport, setShowImport] = useState(false); const [showAdd, setShowAdd] = useState(false); const [editAccountId, setEditAccountId] = useState(null); - const [confirmModal, setConfirmModal] = useState<{ open: boolean; message: string; onConfirm: () => void }>({ open: false, message: "", onConfirm: () => {} }); + const [confirmModal, setConfirmModal] = useState<{ + open: boolean; + message: string; + onConfirm: () => void; + }>({ open: false, message: "", onConfirm: () => {} }); const [processingIds, setProcessingIds] = useState>(new Set()); const [accountResults, setAccountResults] = useState({}); const [accountSteps, setAccountSteps] = useState({}); @@ -58,7 +79,10 @@ export function LogpassTab() { const toggleSort = (field: SortField) => { if (sortField === field) { if (sortDir === "asc") setSortDir("desc"); - else { setSortField(null); setSortDir("asc"); } + else { + setSortField(null); + setSortDir("asc"); + } } else { setSortField(field); setSortDir("asc"); @@ -66,32 +90,41 @@ export function LogpassTab() { }; const sentinelRef = useRef(null); - useEffect(() => { loadAccounts(); }, [loadAccounts]); - - const confirm = (msg: string, fn: () => void) => setConfirmModal({ open: true, message: msg, onConfirm: fn }); - - const watchTask = useCallback((taskId: string) => { - const es = new EventSource(`/api/tasks/${taskId}/stream`); - es.onmessage = (ev) => { - try { - const data = JSON.parse(ev.data) as Task; - setActiveTask(data); - if (data.account_results) { - const r = parseAccResults(data.account_results); - if (r) setAccountResults(r); - } - if (data.account_steps) setAccountSteps(data.account_steps as AccSteps); - if (data.status !== "running") { - es.close(); - setProcessingIds(new Set()); - setActiveTask(null); - loadAccounts(); - } - } catch { /* ignore */ } - }; - es.onerror = () => es.close(); + useEffect(() => { + loadAccounts(); }, [loadAccounts]); + const confirm = (msg: string, fn: () => void) => + setConfirmModal({ open: true, message: msg, onConfirm: fn }); + + const watchTask = useCallback( + (taskId: string) => { + const es = new EventSource(`/api/tasks/${taskId}/stream`); + es.onmessage = (ev) => { + try { + const data = JSON.parse(ev.data) as Task; + setActiveTask(data); + if (data.account_results) { + const r = parseAccResults(data.account_results); + if (r) setAccountResults(r); + } + if (data.account_steps) + setAccountSteps(data.account_steps as AccSteps); + if (data.status !== "running") { + es.close(); + setProcessingIds(new Set()); + setActiveTask(null); + loadAccounts(); + } + } catch { + /* ignore */ + } + }; + es.onerror = () => es.close(); + }, + [loadAccounts], + ); + const handleValidate = useCallback(async () => { const ids = [...selectedIds]; if (!ids.length) return; @@ -101,7 +134,17 @@ export function LogpassTab() { setAccountSteps({}); try { const { task_id } = await api.validateLogpass(ids); - setActiveTask({ id: task_id, type: "logpass_validate", status: "running", progress: 0, total: ids.length, result: null, error: null, created_at: "", updated_at: "" }); + setActiveTask({ + id: task_id, + type: "logpass_validate", + status: "running", + progress: 0, + total: ids.length, + result: null, + error: null, + created_at: "", + updated_at: "", + }); watchTask(task_id); } catch (err) { setProcessingIds(new Set()); @@ -109,19 +152,40 @@ export function LogpassTab() { } }, [selectedIds, clearSelection, watchTask, addToast]); - const handleValidateSingle = useCallback(async (id: number) => { - setProcessingIds(new Set([id])); - setAccountResults((r) => { const n = { ...r }; delete n[String(id)]; return n; }); - setAccountSteps((s) => { const n = { ...s }; delete n[String(id)]; return n; }); - try { - const { task_id } = await api.validateLogpass([id]); - setActiveTask({ id: task_id, type: "logpass_validate", status: "running", progress: 0, total: 1, result: null, error: null, created_at: "", updated_at: "" }); - watchTask(task_id); - } catch (err) { - setProcessingIds(new Set()); - addToast("error", String(err)); - } - }, [watchTask, addToast]); + const handleValidateSingle = useCallback( + async (id: number) => { + setProcessingIds(new Set([id])); + setAccountResults((r) => { + const n = { ...r }; + delete n[String(id)]; + return n; + }); + setAccountSteps((s) => { + const n = { ...s }; + delete n[String(id)]; + return n; + }); + try { + const { task_id } = await api.validateLogpass([id]); + setActiveTask({ + id: task_id, + type: "logpass_validate", + status: "running", + progress: 0, + total: 1, + result: null, + error: null, + created_at: "", + updated_at: "", + }); + watchTask(task_id); + } catch (err) { + setProcessingIds(new Set()); + addToast("error", String(err)); + } + }, + [watchTask, addToast], + ); const handleFullParse = useCallback(async () => { const ids = [...selectedIds]; @@ -132,7 +196,17 @@ export function LogpassTab() { setAccountSteps({}); try { const { task_id } = await api.fullParseLogpass(ids); - setActiveTask({ id: task_id, type: "logpass_full_parse", status: "running", progress: 0, total: ids.length, result: null, error: null, created_at: "", updated_at: "" }); + setActiveTask({ + id: task_id, + type: "logpass_full_parse", + status: "running", + progress: 0, + total: ids.length, + result: null, + error: null, + created_at: "", + updated_at: "", + }); watchTask(task_id); } catch (err) { setProcessingIds(new Set()); @@ -143,28 +217,39 @@ export function LogpassTab() { const handleDeleteSelected = () => { const ids = [...selectedIds]; if (!ids.length) return; - confirm(t("confirm.deleteLogpassSelected", { count: ids.length }), async () => { - await api.deleteLogpassBulk(ids); - clearSelection(); - loadAccounts(); - }); + confirm( + t("confirm.deleteLogpassSelected", { count: ids.length }), + async () => { + await api.deleteLogpassBulk(ids); + clearSelection(); + loadAccounts(); + }, + ); }; const handleDeleteAll = () => { - confirm(t("confirm.deleteLogpassAll", { count: accounts.length }), async () => { - await api.deleteLogpassBulk(accounts.map((a) => a.id)); - clearSelection(); - loadAccounts(); - }); + confirm( + t("confirm.deleteLogpassAll", { count: accounts.length }), + async () => { + await api.deleteLogpassBulk(accounts.map((a) => a.id)); + clearSelection(); + loadAccounts(); + }, + ); }; const handleAssignProxies = () => { confirm(t("confirm.assignProxies"), async () => { try { const r = await api.assignLogpassProxies(); - addToast("success", t("toast.proxiesAssignedShort", { count: r.assigned })); + addToast( + "success", + t("toast.proxiesAssignedShort", { count: r.assigned }), + ); loadAccounts(); - } catch (e: unknown) { addToast("error", e instanceof Error ? e.message : String(e)); } + } catch (e: unknown) { + addToast("error", e instanceof Error ? e.message : String(e)); + } }); }; @@ -172,9 +257,14 @@ export function LogpassTab() { confirm(t("confirm.reassignProxiesAll"), async () => { try { const r = await api.reassignLogpassProxies(); - addToast("success", t("toast.proxiesReassignedShort", { count: r.assigned })); + addToast( + "success", + t("toast.proxiesReassignedShort", { count: r.assigned }), + ); loadAccounts(); - } catch (e: unknown) { addToast("error", e instanceof Error ? e.message : String(e)); } + } catch (e: unknown) { + addToast("error", e instanceof Error ? e.message : String(e)); + } }); }; @@ -182,13 +272,17 @@ export function LogpassTab() { confirm(t("confirm.clearProxies"), async () => { try { const r = await api.clearLogpassProxies(); - addToast("success", t("toast.proxiesClearedShort", { count: r.cleared })); + addToast( + "success", + t("toast.proxiesClearedShort", { count: r.cleared }), + ); loadAccounts(); - } catch (e: unknown) { addToast("error", e instanceof Error ? e.message : String(e)); } + } catch (e: unknown) { + addToast("error", e instanceof Error ? e.message : String(e)); + } }); }; - const allSelected = accounts.length > 0 && selectedIds.size === accounts.length; const filtered = useMemo(() => { if (!searchQuery.trim()) return accounts; const q = searchQuery.trim(); @@ -210,15 +304,30 @@ export function LogpassTab() { } const ql = q.toLowerCase(); - return accounts.filter((a) => - a.login.toLowerCase().includes(ql) || - (a.steam_id ?? "").toLowerCase().includes(ql) || - (a.nickname ?? "").toLowerCase().includes(ql) || - (a.notes ?? "").toLowerCase().includes(ql) || - (a.license ?? "").toLowerCase().includes(ql) + return accounts.filter( + (a) => + a.login.toLowerCase().includes(ql) || + (a.steam_id ?? "").toLowerCase().includes(ql) || + (a.nickname ?? "").toLowerCase().includes(ql) || + (a.notes ?? "").toLowerCase().includes(ql) || + (a.license ?? "").toLowerCase().includes(ql), ); }, [accounts, searchQuery]); + const allFilteredSelected = + filtered.length > 0 && filtered.every((a) => selectedIds.has(a.id)); + const toggleSelectAllFiltered = () => { + if (allFilteredSelected) { + const next = new Set(selectedIds); + filtered.forEach((a) => next.delete(a.id)); + setSelectedIds(next); + } else { + const next = new Set(selectedIds); + filtered.forEach((a) => next.add(a.id)); + setSelectedIds(next); + } + }; + const sorted = useMemo(() => { if (!sortField) return filtered; const dir = sortDir === "asc" ? 1 : -1; @@ -227,7 +336,9 @@ export function LogpassTab() { let va: number | typeof EMPTY = EMPTY; let vb: number | typeof EMPTY = EMPTY; if (sortField === "last_online") { - const parseOnline = (v: string | null | undefined): number | typeof EMPTY => { + const parseOnline = ( + v: string | null | undefined, + ): number | typeof EMPTY => { if (!v || v === "\u2014") return EMPTY; if (v === "online") return -1; const m = v.match(/^(\d+)([mhd])$/i); @@ -243,11 +354,23 @@ export function LogpassTab() { va = a.prime === "Enabled" ? 0 : a.prime === "Disabled" ? 1 : EMPTY; vb = b.prime === "Enabled" ? 0 : b.prime === "Disabled" ? 1 : EMPTY; } else if (sortField === "trophy") { - va = a.trophy != null && a.trophy !== "\u2014" ? parseInt(a.trophy, 10) || 0 : EMPTY; - vb = b.trophy != null && b.trophy !== "\u2014" ? parseInt(b.trophy, 10) || 0 : EMPTY; + va = + a.trophy != null && a.trophy !== "\u2014" + ? parseInt(a.trophy, 10) || 0 + : EMPTY; + vb = + b.trophy != null && b.trophy !== "\u2014" + ? parseInt(b.trophy, 10) || 0 + : EMPTY; } else if (sortField === "behavior") { - va = a.behavior != null && a.behavior !== "\u2014" ? parseInt(a.behavior, 10) || 0 : EMPTY; - vb = b.behavior != null && b.behavior !== "\u2014" ? parseInt(b.behavior, 10) || 0 : EMPTY; + va = + a.behavior != null && a.behavior !== "\u2014" + ? parseInt(a.behavior, 10) || 0 + : EMPTY; + vb = + b.behavior != null && b.behavior !== "\u2014" + ? parseInt(b.behavior, 10) || 0 + : EMPTY; } // Empty values always sink to the bottom if (va === EMPTY && vb === EMPTY) return 0; @@ -258,16 +381,25 @@ export function LogpassTab() { }); }, [filtered, sortField, sortDir]); - useEffect(() => { setVisibleCount(BATCH); }, [searchQuery, sortField, sortDir]); + useEffect(() => { + setVisibleCount(BATCH); + }, [searchQuery, sortField, sortDir]); - const visible = useMemo(() => sorted.slice(0, visibleCount), [sorted, visibleCount]); + const visible = useMemo( + () => sorted.slice(0, visibleCount), + [sorted, visibleCount], + ); useEffect(() => { const el = sentinelRef.current; if (!el) return; - const obs = new IntersectionObserver((entries) => { - if (entries[0].isIntersecting) setVisibleCount((c) => Math.min(c + BATCH, sorted.length)); - }, { rootMargin: "400px" }); + const obs = new IntersectionObserver( + (entries) => { + if (entries[0].isIntersecting) + setVisibleCount((c) => Math.min(c + BATCH, sorted.length)); + }, + { rootMargin: "400px" }, + ); obs.observe(el); return () => obs.disconnect(); }, [sorted.length, visibleCount]); @@ -281,7 +413,8 @@ export function LogpassTab() { const proxyToNum = new Map(); unique.forEach((p, i) => proxyToNum.set(p, i + 1)); for (const a of accounts) { - if (a.proxy) map.set(a.id, t("proxy.label", { num: proxyToNum.get(a.proxy) ?? 0 })); + if (a.proxy) + map.set(a.id, t("proxy.label", { num: proxyToNum.get(a.proxy) ?? 0 })); } return map; }, [accounts]); @@ -293,7 +426,17 @@ export function LogpassTab() { addToast("warn", t("toast.cookiesExpiredRevalidating")); if (result.task_id) { setProcessingIds(new Set([id])); - setActiveTask({ id: result.task_id, type: "logpass_validate", status: "running", progress: 0, total: 1, result: null, error: null, created_at: "", updated_at: "" }); + setActiveTask({ + id: result.task_id, + type: "logpass_validate", + status: "running", + progress: 0, + total: 1, + result: null, + error: null, + created_at: "", + updated_at: "", + }); watchTask(result.task_id); } } else { @@ -304,40 +447,130 @@ export function LogpassTab() { } }; + const handleAfterLogpassImport = useCallback( + async (newIds: number[]) => { + let proxyOn = autoProxyOnImport; + let validateOn = autoValidateOnImport; + try { + const fresh = await api.getValidationSettings(); + proxyOn = fresh.auto_proxy_on_import_logpass; + validateOn = fresh.auto_validate_on_import_logpass; + } catch { + /* fall back to stale store values */ + } + + if (proxyOn) { + try { + const r = await api.assignLogpassProxies(); + addToast( + "success", + t("toast.proxiesAssignedShort", { count: r.assigned }), + ); + await loadAccounts(); + } catch { + /* ignore */ + } + } + if (validateOn && newIds.length) { + try { + const { task_id } = await api.validateLogpass(newIds); + setActiveTask({ + id: task_id, + type: "logpass_validate", + status: "running", + progress: 0, + total: newIds.length, + result: null, + error: null, + created_at: "", + updated_at: "", + }); + setProcessingIds(new Set(newIds)); + watchTask(task_id); + } catch (e: unknown) { + setProcessingIds(new Set()); + addToast("error", e instanceof Error ? e.message : String(e)); + } + } + }, + [ + autoProxyOnImport, + autoValidateOnImport, + addToast, + loadAccounts, + watchTask, + t, + ], + ); + return (
{/* Toolbar */}
- - + + {/* Progress indicator — exact match to AccountsTab */} {activeTask && ( <>
- {t("task.validate")} + + {t("task.validate")} +
1 - ? (activeTask.total > 0 ? Math.round((activeTask.progress / activeTask.total) * 100) : 0) - : (activeTask.total_steps ? Math.round(((activeTask.step ?? 0) / activeTask.total_steps) * 100) : 0)}%` }} + style={{ + width: `${ + activeTask.total > 1 + ? activeTask.total > 0 + ? Math.round( + (activeTask.progress / activeTask.total) * 100, + ) + : 0 + : activeTask.total_steps + ? Math.round( + ((activeTask.step ?? 0) / + activeTask.total_steps) * + 100, + ) + : 0 + }%`, + }} />
{activeTask.total > 1 ? `${activeTask.progress}/${activeTask.total}${activeTask.active_count ? ` (${activeTask.active_count})` : ""}` - : (activeTask.step_label || `${activeTask.progress}/${activeTask.total}`)} + : activeTask.step_label || + `${activeTask.progress}/${activeTask.total}`} {activeTask.total > 1 ? ` (${activeTask.total > 0 ? Math.round((activeTask.progress / activeTask.total) * 100) : 0}%)` - : (activeTask.total_steps ? ` (${activeTask.step}/${activeTask.total_steps})` : "")} + : activeTask.total_steps + ? ` (${activeTask.step}/${activeTask.total_steps})` + : ""} - {activeTask.status === "completed" && } - {activeTask.status === "failed" && } + {activeTask.status === "completed" && ( + + )} + {activeTask.status === "failed" && ( + + + + )}
)} @@ -345,8 +578,15 @@ export function LogpassTab() {
- - + +
@@ -359,27 +599,52 @@ export function LogpassTab() { disabled={selectedIds.size === 0 || processingIds.size > 0} className="btn-accent text-sm disabled:opacity-40" > - {t("btn.validate")} + + {t("btn.validate")} {activeTask && activeTask.status === "running" && ( )}
- - - + + +
- allSelected ? clearSelection() : selectAll()} /> - {selectedIds.size > 0 && {selectedIds.size}} + + {selectedIds.size > 0 && ( + + {selectedIds.size} + + )}
- {cols.browser && {t("col.browser")}} - {cols.profile && {t("col.profile")}} - {cols.last_online && toggleSort("last_online")}>{t("col.lastOnline")}{sortField === "last_online" ? (sortDir === "asc" ? " ▲" : " ▼") : ""}} + {cols.browser && ( + {t("col.browser")} + )} + {cols.profile && ( + {t("col.profile")} + )} + {cols.last_online && ( + toggleSort("last_online")} + > + {t("col.lastOnline")} + {sortField === "last_online" + ? sortDir === "asc" + ? " ▲" + : " ▼" + : ""} + + )} {cols.steam_id && Steam ID} {cols.login && {t("col.login")}} - {cols.password && {t("col.password")}} + {cols.password && ( + {t("col.password")} + )} {cols.login_pass && Login:Pass} - {cols.status && {t("col.status")}} + {cols.status && ( + {t("col.status")} + )} {cols.ban && {t("col.ban")}} - {cols.prime && toggleSort("prime")}>Prime{sortField === "prime" ? (sortDir === "asc" ? " ▲" : " ▼") : ""}} - {cols.trophy && toggleSort("trophy")}>Trophy{sortField === "trophy" ? (sortDir === "asc" ? " ▲" : " ▼") : ""}} - {cols.behavior && toggleSort("behavior")}>Behavior{sortField === "behavior" ? (sortDir === "asc" ? " ▲" : " ▼") : ""}} - {cols.license && {t("col.license")}} + {cols.prime && ( + toggleSort("prime")} + > + Prime + {sortField === "prime" + ? sortDir === "asc" + ? " ▲" + : " ▼" + : ""} + + )} + {cols.trophy && ( + toggleSort("trophy")} + > + Trophy + {sortField === "trophy" + ? sortDir === "asc" + ? " ▲" + : " ▼" + : ""} + + )} + {cols.behavior && ( + toggleSort("behavior")} + > + Behavior + {sortField === "behavior" + ? sortDir === "asc" + ? " ▲" + : " ▼" + : ""} + + )} + {cols.license && ( + {t("col.license")} + )} {cols.proxy && {t("col.proxy")}} {cols.notes && {t("col.notes")}} - {cols.actions && {t("col.actions")}} + {cols.actions && ( + {t("col.actions")} + )} {filtered.length === 0 ? ( - {t("empty.logpass")} + + + {t("empty.logpass")} + + ) : ( <> - {visible.map((a) => ( - confirm(t("confirm.deleteLogpass", { name: a.login }), async () => { await api.deleteLogpassAccount(id); loadAccounts(); })} - onOpenBrowser={handleOpenBrowser} - onValidate={handleValidateSingle} - onEdit={(id) => setEditAccountId(id)} - /> - ))} - {visibleCount < filtered.length && ( - {t("paging.shown", { visible: visibleCount, total: filtered.length })} - )} + {visible.map((a) => ( + + confirm( + t("confirm.deleteLogpass", { name: a.login }), + async () => { + await api.deleteLogpassAccount(id); + loadAccounts(); + }, + ) + } + onOpenBrowser={handleOpenBrowser} + onValidate={handleValidateSingle} + onEdit={(id) => setEditAccountId(id)} + /> + ))} + {visibleCount < filtered.length && ( + + + {t("paging.shown", { + visible: visibleCount, + total: filtered.length, + })} + + + )} )} @@ -451,16 +806,30 @@ export function LogpassTab() {
- {editAccountId != null && (() => { - const acc = accounts.find((a) => a.id === editAccountId); - return acc ? setEditAccountId(null)} /> : null; - })()} - {showImport && setShowImport(false)} />} + {editAccountId != null && + (() => { + const acc = accounts.find((a) => a.id === editAccountId); + return acc ? ( + setEditAccountId(null)} + /> + ) : null; + })()} + {showImport && ( + setShowImport(false)} + onImportDone={handleAfterLogpassImport} + /> + )} {showAdd && setShowAdd(false)} />} {confirmModal.open && ( { confirmModal.onConfirm(); setConfirmModal((p) => ({ ...p, open: false })); }} + onConfirm={() => { + confirmModal.onConfirm(); + setConfirmModal((p) => ({ ...p, open: false })); + }} onCancel={() => setConfirmModal((p) => ({ ...p, open: false }))} /> )} @@ -470,7 +839,18 @@ export function LogpassTab() { /* ─── Row component ─── */ -function LogpassRow({ account: a, cols, isProcessing, accountResult, accountStep, proxyLabel, onDelete, onOpenBrowser, onValidate, onEdit }: { +function LogpassRow({ + account: a, + cols, + isProcessing, + accountResult, + accountStep, + proxyLabel, + onDelete, + onOpenBrowser, + onValidate, + onEdit, +}: { account: import("@/api/types").LogpassAccount; cols: LogpassColumnSettings; isProcessing: boolean; @@ -498,25 +878,38 @@ function LogpassRow({ account: a, cols, isProcessing, accountResult, accountStep const handleCopy = async (text: string) => { const ok = await copyText(text); - addToast(ok ? "success" : "error", ok ? t("toast.copied") : t("toast.copyFailed")); + addToast( + ok ? "success" : "error", + ok ? t("toast.copied") : t("toast.copyFailed"), + ); }; return ( - toggleSelect(a.id)} /> + toggleSelect(a.id)} + /> {/* Progress/status icon */} {isProcessing ? (
- {accountStep && [{accountStep.step}/{accountStep.total}]} + {accountStep && ( + + [{accountStep.step}/{accountStep.total}] + + )}
) : accountResult?.status === "ok" ? ( ) : accountResult?.status === "error" ? ( - + + + ) : null} {/* Browser login button */} @@ -527,7 +920,9 @@ function LogpassRow({ account: a, cols, isProcessing, accountResult, accountStep onClick={() => onOpenBrowser(a.id)} className="px-2 py-0.5 text-xs font-medium rounded bg-blue-600/20 text-blue-400 border border-blue-500/30 hover:bg-blue-600/40 hover:text-blue-300 active:scale-95 transition" title={t("tip.openBrowser")} - >{t("col.browser")} + > + {t("col.browser")} + ) : ( )} @@ -535,13 +930,15 @@ function LogpassRow({ account: a, cols, isProcessing, accountResult, accountStep )} {/* Profile — avatar + nickname + level */} {cols.profile && ( - -
- {a.avatar_url && } - {a.nickname || "—"} - {a.steam_level != null && } -
- + +
+ {a.avatar_url && ( + + )} + {a.nickname || "—"} + {a.steam_level != null && } +
+ )} {/* Last online */} {cols.last_online && ( @@ -551,46 +948,89 @@ function LogpassRow({ account: a, cols, isProcessing, accountResult, accountStep )} {/* Steam ID */} {cols.steam_id && ( - - {a.steam_id ? ( - - {a.steam_id} - - ) : "—"} - + + {a.steam_id ? ( + + {a.steam_id} + + ) : ( + "—" + )} + )} {/* Login */} {cols.login && {a.login}} {/* Password */} {cols.password && ( - - handleCopy(a.password)} title={t("tip.copyPassword")}> - {masked ? dots : a.password} - - - + + handleCopy(a.password)} + title={t("tip.copyPassword")} + > + {masked ? dots : a.password} + + + )} {/* Login:Pass */} {cols.login_pass && ( - - handleCopy(`${a.login}:${a.password}`)} title={t("tip.copyLoginPass")}> - {masked ? `${a.login}:${dots}` : `${a.login}:${a.password}`} - - - + + handleCopy(`${a.login}:${a.password}`)} + title={t("tip.copyLoginPass")} + > + {masked ? `${a.login}:${dots}` : `${a.login}:${a.password}`} + + + )} {/* Status */} - {cols.status && } + {cols.status && ( + + + + )} {/* Ban */} - {cols.ban && } + {cols.ban && ( + + + + )} {/* Prime, Trophy, Behavior */} - {cols.prime && {a.prime ?? "—"}} - {cols.trophy && {a.trophy ?? "—"}} - {cols.behavior && {a.behavior ?? "—"}} + {cols.prime && ( + {a.prime ?? "—"} + )} + {cols.trophy && ( + {a.trophy ?? "—"} + )} + {cols.behavior && ( + {a.behavior ?? "—"} + )} {/* License — expandable on click */} {cols.license && ( - {a.proxy ? ( - handleCopy(a.proxy!)} title={a.proxy}> - {proxyLabel || a.proxy} - - ) : "—"} - + + {a.proxy ? ( + handleCopy(a.proxy!)} + title={a.proxy} + > + {proxyLabel || a.proxy} + + ) : ( + "—" + )} + )} {/* Notes — inline editable */} {cols.notes && ( - - {editingNotes ? ( - setNotesValue(e.target.value)} - onBlur={async () => { - setEditingNotes(false); - if (notesValue !== (a.notes || "")) { - try { - await api.updateLogpassAccount(a.id, { notes: notesValue }); - addToast("success", t("toast.noteSaved")); - loadAccounts(); - } catch { addToast("error", t("toast.noteSaveError")); } - } - }} - onKeyDown={(e) => { if (e.key === "Enter") (e.target as HTMLInputElement).blur(); if (e.key === "Escape") { setNotesValue(a.notes || ""); setEditingNotes(false); } }} - /> - ) : ( - { setNotesValue(a.notes || ""); setEditingNotes(true); }} - title={a.notes || t("tip.addNote")} - > - {a.notes || "—"} - - )} - + + {editingNotes ? ( + setNotesValue(e.target.value)} + onBlur={async () => { + setEditingNotes(false); + if (notesValue !== (a.notes || "")) { + try { + await api.updateLogpassAccount(a.id, { notes: notesValue }); + addToast("success", t("toast.noteSaved")); + loadAccounts(); + } catch { + addToast("error", t("toast.noteSaveError")); + } + } + }} + onKeyDown={(e) => { + if (e.key === "Enter") (e.target as HTMLInputElement).blur(); + if (e.key === "Escape") { + setNotesValue(a.notes || ""); + setEditingNotes(false); + } + }} + /> + ) : ( + { + setNotesValue(a.notes || ""); + setEditingNotes(true); + }} + title={a.notes || t("tip.addNote")} + > + {a.notes || "—"} + + )} + )} {/* Actions */} {cols.actions && ( - -
- - - -
- + +
+ + + +
+ )} ); -} \ No newline at end of file +} diff --git a/frontend/src/components/accounts/TokenCheckModal.tsx b/frontend/src/components/accounts/TokenCheckModal.tsx new file mode 100644 index 0000000..df81ea5 --- /dev/null +++ b/frontend/src/components/accounts/TokenCheckModal.tsx @@ -0,0 +1,307 @@ +import { useEffect, useState } from "react"; +import { api } from "@/api/client"; +import type { TokenAccount, TokenCheckData } from "@/api/types"; +import { copyText } from "@/lib/clipboard"; +import { IconX, IconRefresh, IconLoader } from "@/components/shared/Icons"; + +interface Props { + account: TokenAccount; + onClose: () => void; + onRecheck: () => void; +} + +function Row({ + label, + value, + good, + bad, +}: { + label: string; + value: string; + good?: boolean; + bad?: boolean; +}) { + return ( +
+ {label} + + {value} + +
+ ); +} + +function Card({ + title, + children, +}: { + title: string; + children: React.ReactNode; +}) { + return ( +
+
+ {title} +
+ {children} +
+ ); +} + +function fmtPlaytime(minutes: number): string { + if (minutes <= 0) return "0ч"; + const h = (minutes / 60).toFixed(1); + return `${h}ч`; +} + +function fmtCheckedAt(iso: string | null): string { + if (!iso) return "—"; + try { + return new Date(iso).toLocaleString(); + } catch { + return iso; + } +} + +export function TokenCheckModal({ account, onClose, onRecheck }: Props) { + const [data, setData] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + let cancelled = false; + api + .getTokenCheckData(account.id) + .then((d) => { + if (!cancelled) { + setData(d); + setLoading(false); + } + }) + .catch((e: unknown) => { + if (!cancelled) { + setError(e instanceof Error ? e.message : String(e)); + setLoading(false); + } + }); + return () => { + cancelled = true; + }; + }, [account.id]); + + const handleCopySteamId = () => { + if (data?.steam_id) copyText(data.steam_id); + }; + + // Close on backdrop click + const handleBackdrop = (e: React.MouseEvent) => { + if (e.target === e.currentTarget) onClose(); + }; + + // Close on Escape + useEffect(() => { + const handler = (e: KeyboardEvent) => { + if (e.key === "Escape") onClose(); + }; + window.addEventListener("keydown", handler); + return () => window.removeEventListener("keydown", handler); + }, [onClose]); + + return ( +
+
+ {/* Header */} +
+
+ {/* Avatar */} +
+ {(data?.avatar_url ?? account.avatar_url) ? ( + + ) : ( +
+ )} +
+ + {/* Name + meta */} +
+
+ + {data?.display_name ?? + account.nickname ?? + account.login ?? + "—"} + + {(data?.steam_level ?? account.steam_level) != null && ( + + Lv.{data?.steam_level ?? account.steam_level} + + )} +
+
+ {(data?.steam_id ?? account.steam_id) && ( + + )} + {(data?.last_online ?? account.last_online) && ( + <> + · + {data?.last_online ?? account.last_online} + + )} +
+
+
+ + {/* Actions */} +
+ + +
+
+ + {/* Body */} +
+ {loading && ( +
+ +
+ )} + {error && !loading && ( +
+ {error} +
+ )} + {data && !loading && ( +
+ {/* Identity */} + + {account.login && } + {data.display_name && ( + + )} + {data.steam_id && } + {data.user_country && ( + + )} + + {data.created_date && ( + + )} + + + {/* Security & Status */} + + + + + + + + {/* Economy & Activity */} + + {data.balance_raw && ( + + )} + {data.steam_level != null && ( + + )} + {data.playtime_2weeks > 0 && ( + + )} + + + {/* Inventory */} + + + + + + +
+ )} +
+ + {/* Footer */} +
+ {data?.checked_at + ? `Последняя проверка: ${fmtCheckedAt(data.checked_at)}` + : "Данные ещё не получены"} +
+
+
+ ); +} diff --git a/frontend/src/components/accounts/TokenImportModal.tsx b/frontend/src/components/accounts/TokenImportModal.tsx index e514034..6138bbc 100644 --- a/frontend/src/components/accounts/TokenImportModal.tsx +++ b/frontend/src/components/accounts/TokenImportModal.tsx @@ -7,9 +7,10 @@ import { useT } from "@/lib/i18n"; interface Props { onClose: () => void; + onImportDone?: (newIds: number[]) => void; } -export function TokenImportModal({ onClose }: Props) { +export function TokenImportModal({ onClose, onImportDone }: Props) { const t = useT(); const [file, setFile] = useState(null); const [result, setResult] = useState(""); @@ -29,12 +30,32 @@ export function TokenImportModal({ onClose }: Props) { setUploading(true); try { const text = await file.text(); - const lines = text.split("\n").map((l) => l.trim()).filter(Boolean); - if (!lines.length) { setResult(t("toast.fileEmpty")); setUploading(false); return; } + const lines = text + .split("\n") + .map((l) => l.trim()) + .filter(Boolean); + if (!lines.length) { + setResult(t("toast.fileEmpty")); + setUploading(false); + return; + } + const idsBefore = new Set( + useTokenStore.getState().accounts.map((a) => a.id), + ); const res = await api.importTokens(lines); - setResult(t("toast.importResult", { imported: res.imported, skipped: res.skipped })); + setResult( + t("toast.importResult", { + imported: res.imported, + skipped: res.skipped, + }), + ); addToast("success", `${res.imported} ok, ${res.skipped} skip`); await loadAccounts(); + const newIds = useTokenStore + .getState() + .accounts.map((a) => a.id) + .filter((id) => !idsBefore.has(id)); + onImportDone?.(newIds); } catch (e: unknown) { setResult(e instanceof Error ? e.message : t("misc.errorStr")); } finally { @@ -44,10 +65,17 @@ export function TokenImportModal({ onClose }: Props) { return (
-
e.stopPropagation()}> -

{t("modal.importTokens")}

+
e.stopPropagation()} + > +

+ {t("modal.importTokens")} +

-

{t("import.formatsColon")}

+

+ {t("import.formatsColon")} +

{t("import.tokenFormat")}

- {file ? t("import.selected", { name: file.name }) : t("import.dragTxt")} + {file + ? t("import.selected", { name: file.name }) + : t("import.dragTxt")}

- { - const f = e.target.files?.[0]; - if (f) setFile(f); - }} /> - {result &&

{result}

} diff --git a/frontend/src/components/accounts/TokenTab.tsx b/frontend/src/components/accounts/TokenTab.tsx index 1f3ea5d..1550bc0 100644 --- a/frontend/src/components/accounts/TokenTab.tsx +++ b/frontend/src/components/accounts/TokenTab.tsx @@ -8,9 +8,21 @@ import { SteamLevelBadge } from "./SteamLevelBadge"; import { TokenImportModal } from "./TokenImportModal"; import { TokenAddModal } from "./TokenAddModal"; import { TokenColumnSettingsDropdown } from "./TokenColumnSettingsDropdown"; +import { TokenCheckModal } from "./TokenCheckModal"; import { - IconDownload, IconPlus, IconTrash, IconPlay, IconGlobe, IconRefresh, IconBan, - IconCheckCircle, IconXCircle, IconCheck, IconAlertTriangle, + IconDownload, + IconPlus, + IconTrash, + IconPlay, + IconGlobe, + IconRefresh, + IconBan, + IconCheckCircle, + IconXCircle, + IconCheck, + IconAlertTriangle, + IconScrollText, + IconFileText, } from "@/components/shared/Icons"; import type { Task } from "@/api/types"; import { useT } from "@/lib/i18n"; @@ -21,7 +33,11 @@ type AccSteps = Record; function parseAccResults(raw: Task["account_results"]): AccResults | null { if (!raw) return null; if (typeof raw === "string") { - try { return JSON.parse(raw) as AccResults; } catch { return null; } + try { + return JSON.parse(raw) as AccResults; + } catch { + return null; + } } return raw; } @@ -31,47 +47,63 @@ export function TokenTab() { const selectedIds = useTokenStore((s) => s.selectedIds); const loadAccounts = useTokenStore((s) => s.loadAccounts); const toggleSelect = useTokenStore((s) => s.toggleSelect); - const selectAll = useTokenStore((s) => s.selectAll); const clearSelection = useTokenStore((s) => s.clearSelection); + const setSelectedIds = useTokenStore((s) => s.setSelectedIds); const addToast = useUiStore((s) => s.addToast); + const autoProxyOnImport = useUiStore((s) => s.autoProxyOnImportToken); + const autoValidateOnImport = useUiStore((s) => s.autoValidateOnImportToken); const cols = useUiStore((s) => s.tokenColumnVisibility); const loadTokenColumnSettings = useUiStore((s) => s.loadTokenColumnSettings); const t = useT(); - const [disclaimerAccepted, setDisclaimerAccepted] = useState(false); const [searchQuery, setSearchQuery] = useState(""); const [showImport, setShowImport] = useState(false); const [showAdd, setShowAdd] = useState(false); - const [confirmModal, setConfirmModal] = useState<{ open: boolean; message: string; onConfirm: () => void }>({ open: false, message: "", onConfirm: () => {} }); + const [confirmModal, setConfirmModal] = useState<{ + open: boolean; + message: string; + onConfirm: () => void; + }>({ open: false, message: "", onConfirm: () => {} }); const [processingIds, setProcessingIds] = useState>(new Set()); const [accountResults, setAccountResults] = useState({}); const [accountSteps, setAccountSteps] = useState({}); const [activeTask, setActiveTask] = useState(null); + const [checkModalId, setCheckModalId] = useState(null); - useEffect(() => { loadAccounts(); loadTokenColumnSettings(); }, [loadAccounts, loadTokenColumnSettings]); + useEffect(() => { + loadAccounts(); + loadTokenColumnSettings(); + }, [loadAccounts, loadTokenColumnSettings]); - const confirm = (msg: string, fn: () => void) => setConfirmModal({ open: true, message: msg, onConfirm: fn }); + const confirm = (msg: string, fn: () => void) => + setConfirmModal({ open: true, message: msg, onConfirm: fn }); - const watchTask = useCallback((taskId: string) => { - const es = new EventSource(`/api/tasks/${taskId}/stream`); - es.onmessage = (ev) => { - try { - const data = JSON.parse(ev.data) as Task; - setActiveTask(data); - if (data.account_results) { - const r = parseAccResults(data.account_results); - if (r) setAccountResults(r); + const watchTask = useCallback( + (taskId: string) => { + const es = new EventSource(`/api/tasks/${taskId}/stream`); + es.onmessage = (ev) => { + try { + const data = JSON.parse(ev.data) as Task; + setActiveTask(data); + if (data.account_results) { + const r = parseAccResults(data.account_results); + if (r) setAccountResults(r); + } + if (data.account_steps) + setAccountSteps(data.account_steps as AccSteps); + if (data.status !== "running") { + es.close(); + setProcessingIds(new Set()); + loadAccounts(); + } + } catch { + /* ignore */ } - if (data.account_steps) setAccountSteps(data.account_steps as AccSteps); - if (data.status !== "running") { - es.close(); - setProcessingIds(new Set()); - loadAccounts(); - } - } catch { /* ignore */ } - }; - es.onerror = () => es.close(); - }, [loadAccounts]); + }; + es.onerror = () => es.close(); + }, + [loadAccounts], + ); const handleValidate = useCallback(async () => { const ids = [...selectedIds]; @@ -82,7 +114,17 @@ export function TokenTab() { setAccountSteps({}); try { const { task_id } = await api.validateTokens(ids); - setActiveTask({ id: task_id, type: "token_validate", status: "running", progress: 0, total: ids.length, result: null, error: null, created_at: "", updated_at: "" }); + setActiveTask({ + id: task_id, + type: "token_validate", + status: "running", + progress: 0, + total: ids.length, + result: null, + error: null, + created_at: "", + updated_at: "", + }); watchTask(task_id); } catch (err) { setProcessingIds(new Set()); @@ -90,45 +132,140 @@ export function TokenTab() { } }, [selectedIds, clearSelection, watchTask, addToast]); - const handleValidateSingle = useCallback(async (id: number) => { - setProcessingIds(new Set([id])); - setAccountResults((r) => { const n = { ...r }; delete n[String(id)]; return n; }); - setAccountSteps((s) => { const n = { ...s }; delete n[String(id)]; return n; }); + const handleValidateSingle = useCallback( + async (id: number) => { + setProcessingIds(new Set([id])); + setAccountResults((r) => { + const n = { ...r }; + delete n[String(id)]; + return n; + }); + setAccountSteps((s) => { + const n = { ...s }; + delete n[String(id)]; + return n; + }); + try { + const { task_id } = await api.validateTokens([id]); + setActiveTask({ + id: task_id, + type: "token_validate", + status: "running", + progress: 0, + total: 1, + result: null, + error: null, + created_at: "", + updated_at: "", + }); + watchTask(task_id); + } catch (err) { + setProcessingIds(new Set()); + addToast("error", String(err)); + } + }, + [watchTask, addToast], + ); + + const handleFullCheckSingle = useCallback( + async (id: number) => { + setProcessingIds(new Set([id])); + try { + const { task_id } = await api.fullCheckTokens([id]); + setActiveTask({ + id: task_id, + type: "token_full_check", + status: "running", + progress: 0, + total: 1, + result: null, + error: null, + created_at: "", + updated_at: "", + }); + watchTask(task_id); + } catch (err) { + setProcessingIds(new Set()); + addToast("error", String(err)); + } + }, + [watchTask, addToast], + ); + + const handleFullCheck = useCallback(async () => { + const ids = [...selectedIds]; + if (!ids.length) return; + clearSelection(); + setProcessingIds(new Set(ids)); + setAccountResults({}); + setAccountSteps({}); try { - const { task_id } = await api.validateTokens([id]); - setActiveTask({ id: task_id, type: "token_validate", status: "running", progress: 0, total: 1, result: null, error: null, created_at: "", updated_at: "" }); + const { task_id } = await api.fullCheckTokens(ids); + setActiveTask({ + id: task_id, + type: "token_full_check", + status: "running", + progress: 0, + total: ids.length, + result: null, + error: null, + created_at: "", + updated_at: "", + }); watchTask(task_id); } catch (err) { setProcessingIds(new Set()); addToast("error", String(err)); } - }, [watchTask, addToast]); + }, [selectedIds, clearSelection, watchTask, addToast]); + + const handleDownloadCookies = useCallback( + (account: (typeof accounts)[number]) => { + if (!account.has_cookies) { + addToast("warn", "Нет сохранённых куки. Сначала запустите валидацию."); + return; + } + api.downloadTokenCookies(account.id); + }, + [addToast], + ); const handleDeleteSelected = () => { const ids = [...selectedIds]; if (!ids.length) return; - confirm(t("confirm.deleteTokenSelected", { count: ids.length }), async () => { - await api.deleteTokenBulk(ids); - clearSelection(); - loadAccounts(); - }); + confirm( + t("confirm.deleteTokenSelected", { count: ids.length }), + async () => { + await api.deleteTokenBulk(ids); + clearSelection(); + loadAccounts(); + }, + ); }; const handleDeleteAll = () => { - confirm(t("confirm.deleteTokenAll", { count: accounts.length }), async () => { - await api.deleteTokenBulk(accounts.map((a) => a.id)); - clearSelection(); - loadAccounts(); - }); + confirm( + t("confirm.deleteTokenAll", { count: accounts.length }), + async () => { + await api.deleteTokenBulk(accounts.map((a) => a.id)); + clearSelection(); + loadAccounts(); + }, + ); }; const handleAssignProxies = () => { confirm(t("confirm.assignProxies"), async () => { try { const r = await api.assignTokenProxies(); - addToast("success", t("toast.proxiesAssignedShort", { count: r.assigned })); + addToast( + "success", + t("toast.proxiesAssignedShort", { count: r.assigned }), + ); loadAccounts(); - } catch (e: unknown) { addToast("error", e instanceof Error ? e.message : String(e)); } + } catch (e: unknown) { + addToast("error", e instanceof Error ? e.message : String(e)); + } }); }; @@ -136,9 +273,14 @@ export function TokenTab() { confirm(t("confirm.reassignProxiesAll"), async () => { try { const r = await api.reassignTokenProxies(); - addToast("success", t("toast.proxiesReassignedShort", { count: r.assigned })); + addToast( + "success", + t("toast.proxiesReassignedShort", { count: r.assigned }), + ); loadAccounts(); - } catch (e: unknown) { addToast("error", e instanceof Error ? e.message : String(e)); } + } catch (e: unknown) { + addToast("error", e instanceof Error ? e.message : String(e)); + } }); }; @@ -146,9 +288,14 @@ export function TokenTab() { confirm(t("confirm.clearProxies"), async () => { try { const r = await api.clearTokenProxies(); - addToast("success", t("toast.proxiesClearedShort", { count: r.cleared })); + addToast( + "success", + t("toast.proxiesClearedShort", { count: r.cleared }), + ); loadAccounts(); - } catch (e: unknown) { addToast("error", e instanceof Error ? e.message : String(e)); } + } catch (e: unknown) { + addToast("error", e instanceof Error ? e.message : String(e)); + } }); }; @@ -159,7 +306,17 @@ export function TokenTab() { addToast("warn", t("toast.cookiesExpiredRevalidating")); if (result.task_id) { setProcessingIds(new Set([id])); - setActiveTask({ id: result.task_id, type: "token_validate", status: "running", progress: 0, total: 1, result: null, error: null, created_at: "", updated_at: "" }); + setActiveTask({ + id: result.task_id, + type: "token_validate", + status: "running", + progress: 0, + total: 1, + result: null, + error: null, + created_at: "", + updated_at: "", + }); watchTask(result.task_id); } } else { @@ -170,7 +327,61 @@ export function TokenTab() { } }; - const allSelected = accounts.length > 0 && selectedIds.size === accounts.length; + const handleAfterTokenImport = useCallback( + async (newIds: number[]) => { + let proxyOn = autoProxyOnImport; + let validateOn = autoValidateOnImport; + try { + const fresh = await api.getValidationSettings(); + proxyOn = fresh.auto_proxy_on_import_token; + validateOn = fresh.auto_validate_on_import_token; + } catch { + /* fall back to stale store values */ + } + + if (proxyOn) { + try { + const r = await api.assignTokenProxies(); + addToast( + "success", + t("toast.proxiesAssignedShort", { count: r.assigned }), + ); + await loadAccounts(); + } catch { + /* ignore */ + } + } + if (validateOn && newIds.length) { + try { + const { task_id } = await api.validateTokens(newIds); + setActiveTask({ + id: task_id, + type: "token_validate", + status: "running", + progress: 0, + total: newIds.length, + result: null, + error: null, + created_at: "", + updated_at: "", + }); + setProcessingIds(new Set(newIds)); + watchTask(task_id); + } catch (e: unknown) { + setProcessingIds(new Set()); + addToast("error", e instanceof Error ? e.message : String(e)); + } + } + }, + [ + autoProxyOnImport, + autoValidateOnImport, + addToast, + loadAccounts, + watchTask, + t, + ], + ); const filtered = useMemo(() => { if (!searchQuery.trim()) return accounts; @@ -192,14 +403,29 @@ export function TokenTab() { } const ql = q.toLowerCase(); - return accounts.filter((a) => - (a.login ?? "").toLowerCase().includes(ql) || - (a.steam_id ?? "").toLowerCase().includes(ql) || - (a.nickname ?? "").toLowerCase().includes(ql) || - (a.notes ?? "").toLowerCase().includes(ql) + return accounts.filter( + (a) => + (a.login ?? "").toLowerCase().includes(ql) || + (a.steam_id ?? "").toLowerCase().includes(ql) || + (a.nickname ?? "").toLowerCase().includes(ql) || + (a.notes ?? "").toLowerCase().includes(ql), ); }, [accounts, searchQuery]); + const allFilteredSelected = + filtered.length > 0 && filtered.every((a) => selectedIds.has(a.id)); + const toggleSelectAllFiltered = () => { + if (allFilteredSelected) { + const next = new Set(selectedIds); + filtered.forEach((a) => next.delete(a.id)); + setSelectedIds(next); + } else { + const next = new Set(selectedIds); + filtered.forEach((a) => next.add(a.id)); + setSelectedIds(next); + } + }; + const proxyLabels = useMemo(() => { const map = new Map(); const unique: string[] = []; @@ -209,71 +435,80 @@ export function TokenTab() { const proxyToNum = new Map(); unique.forEach((p, i) => proxyToNum.set(p, i + 1)); for (const a of accounts) { - if (a.proxy) map.set(a.id, t("proxy.label", { num: proxyToNum.get(a.proxy) ?? 0 })); + if (a.proxy) + map.set(a.id, t("proxy.label", { num: proxyToNum.get(a.proxy) ?? 0 })); } return map; }, [accounts, t]); return ( -
- {/* Development warning gate */} - {!disclaimerAccepted && ( -
-
-
- -

{t("token.disclaimerTitle")}

-
-
-

-

-

-

- -
-
- )} - +
{/* Toolbar */}
- - + + {/* Progress indicator */} {activeTask && ( <>
- {t("task.validate")} + + {t("task.validate")} +
1 - ? (activeTask.total > 0 ? Math.round((activeTask.progress / activeTask.total) * 100) : 0) - : (activeTask.total_steps ? Math.round(((activeTask.step ?? 0) / activeTask.total_steps) * 100) : 0)}%` }} + style={{ + width: `${ + activeTask.total > 1 + ? activeTask.total > 0 + ? Math.round( + (activeTask.progress / activeTask.total) * 100, + ) + : 0 + : activeTask.total_steps + ? Math.round( + ((activeTask.step ?? 0) / + activeTask.total_steps) * + 100, + ) + : 0 + }%`, + }} />
{activeTask.total > 1 ? `${activeTask.progress}/${activeTask.total}${activeTask.active_count ? ` (${activeTask.active_count})` : ""}` - : (activeTask.step_label || `${activeTask.progress}/${activeTask.total}`)} + : activeTask.step_label || + `${activeTask.progress}/${activeTask.total}`} {activeTask.total > 1 ? ` (${activeTask.total > 0 ? Math.round((activeTask.progress / activeTask.total) * 100) : 0}%)` - : (activeTask.total_steps ? ` (${activeTask.step}/${activeTask.total_steps})` : "")} + : activeTask.total_steps + ? ` (${activeTask.step}/${activeTask.total_steps})` + : ""} - {activeTask.status === "completed" && } - {activeTask.status === "failed" && } + {activeTask.status === "completed" && ( + + )} + {activeTask.status === "failed" && ( + + + + )}
)} @@ -281,8 +516,15 @@ export function TokenTab() {
- - + +
@@ -295,12 +537,39 @@ export function TokenTab() { disabled={selectedIds.size === 0 || processingIds.size > 0} className="btn-accent text-sm disabled:opacity-40" > - {t("btn.validate")} + + {t("btn.validate")} + +
- - - + + +
- allSelected ? clearSelection() : selectAll()} /> - {selectedIds.size > 0 && {selectedIds.size}} + + {selectedIds.size > 0 && ( + + {selectedIds.size} + + )}
- {cols.browser && {t("col.browser")}} - {cols.profile && {t("col.profile")}} - {cols.last_online && {t("col.lastOnline")}} + {cols.browser && ( + {t("col.browser")} + )} + {cols.profile && ( + {t("col.profile")} + )} + {cols.last_online && ( + {t("col.lastOnline")} + )} {cols.steam_id && Steam ID} {cols.login && {t("col.login")}} {cols.token && {t("col.token")}} - {cols.status && {t("col.status")}} + {cols.status && ( + {t("col.status")} + )} {cols.proxy && {t("col.proxy")}} {cols.notes && {t("col.notes")}} - {cols.actions && {t("col.actions")}} + {cols.actions && ( + {t("col.actions")} + )} {filtered.length === 0 ? ( - {t("empty.tokens")} + + + {t("empty.tokens")} + + ) : ( filtered.map((a) => { const isProcessing = processingIds.has(a.id); const result = accountResults[String(a.id)]; const step = accountSteps[String(a.id)]; return ( - + - toggleSelect(a.id)} /> + toggleSelect(a.id)} + /> {/* Status icon */} {isProcessing ? (
- {step && [{step.step}/{step.total}]} + {step && ( + + [{step.step}/{step.total}] + + )}
) : result?.status === "ok" ? ( ) : result?.status === "error" ? ( - + + + ) : null} {cols.browser && ( @@ -369,7 +676,9 @@ export function TokenTab() { onClick={() => handleOpenBrowser(a.id)} className="px-2 py-0.5 text-xs font-medium rounded bg-blue-600/20 text-blue-400 border border-blue-500/30 hover:bg-blue-600/40 hover:text-blue-300 active:scale-95 transition" title={t("tip.openBrowser")} - >{t("col.browser")} + > + {t("col.browser")} + ) : ( )} @@ -378,27 +687,69 @@ export function TokenTab() { {cols.profile && (
- {a.avatar_url && } + {a.avatar_url && ( + + )} {a.nickname || "—"} - {a.steam_level != null && } + {a.steam_level != null && ( + + )}
)} - {cols.last_online && {a.last_online || "—"}} + {cols.last_online && ( + + {a.last_online || "—"} + + )} {cols.steam_id && ( {a.steam_id ? ( - + {a.steam_id} - ) : "—"} + ) : ( + "—" + )} + + )} + {cols.login && ( + + {a.login ?? "—"} + + )} + {cols.token && ( + + {a.token.slice(0, 24)}… + + )} + {cols.status && ( + + + + )} + {cols.proxy && ( + + {proxyLabels.get(a.id) ?? "—"} + + )} + {cols.notes && ( + + {a.notes ?? "—"} )} - {cols.login && {a.login ?? "—"}} - {cols.token && {a.token.slice(0, 24)}…} - {cols.status && } - {cols.proxy && {proxyLabels.get(a.id) ?? "—"}} - {cols.notes && {a.notes ?? "—"}} {cols.actions && (
@@ -407,12 +758,56 @@ export function TokenTab() { disabled={isProcessing} className="text-gray-400 hover:text-accent disabled:opacity-40 transition" title={t("tip.validate")} - > + > + + + + + + > + +
)} @@ -425,12 +820,34 @@ export function TokenTab() {
- {showImport && setShowImport(false)} />} + {showImport && ( + setShowImport(false)} + onImportDone={handleAfterTokenImport} + /> + )} {showAdd && setShowAdd(false)} />} + {checkModalId != null && + (() => { + const acc = accounts.find((a) => a.id === checkModalId); + return acc ? ( + setCheckModalId(null)} + onRecheck={() => { + setCheckModalId(null); + handleFullCheckSingle(acc.id); + }} + /> + ) : null; + })()} {confirmModal.open && ( { confirmModal.onConfirm(); setConfirmModal((p) => ({ ...p, open: false })); }} + onConfirm={() => { + confirmModal.onConfirm(); + setConfirmModal((p) => ({ ...p, open: false })); + }} onCancel={() => setConfirmModal((p) => ({ ...p, open: false }))} /> )} diff --git a/frontend/src/components/tools/ValidationSettings.tsx b/frontend/src/components/tools/ValidationSettings.tsx index 6724d77..c626c38 100644 --- a/frontend/src/components/tools/ValidationSettings.tsx +++ b/frontend/src/components/tools/ValidationSettings.tsx @@ -5,16 +5,31 @@ import { useUiStore } from "@/stores/uiStore"; import { useT } from "@/lib/i18n"; import { IconSettings } from "@/components/shared/Icons"; -function Toggle({ checked, onChange }: { checked: boolean; onChange: (v: boolean) => void }) { +function Toggle({ + checked, + onChange, +}: { + checked: boolean; + onChange: (v: boolean) => void; +}) { return ( ); } -function SettingRow({ label, desc, checked, onChange }: { +function SettingRow({ + label, + desc, + checked, + onChange, +}: { label: string; desc?: string; checked: boolean; @@ -31,7 +46,13 @@ function SettingRow({ label, desc, checked, onChange }: { ); } -function ThreadStepper({ value, onChange }: { value: number; onChange: (v: number) => void }) { +function ThreadStepper({ + value, + onChange, +}: { + value: number; + onChange: (v: number) => void; +}) { const [editing, setEditing] = useState(false); const [input, setInput] = useState(""); const inputRef = useRef(null); @@ -42,14 +63,32 @@ function ThreadStepper({ value, onChange }: { value: number; onChange: (v: numbe setEditing(false); }; - const btnCls = "h-6 px-1.5 rounded bg-dark-700 border border-dark-600 text-gray-300 hover:bg-dark-600 text-xs flex items-center justify-center select-none leading-none"; + const btnCls = + "h-6 px-1.5 rounded bg-dark-700 border border-dark-600 text-gray-300 hover:bg-dark-600 text-xs flex items-center justify-center select-none leading-none"; return (
- Max threads + + Max threads +
- - + + {editing ? ( setInput(e.target.value)} onBlur={commit} - onKeyDown={(e) => { if (e.key === "Enter") commit(); if (e.key === "Escape") setEditing(false); }} + onKeyDown={(e) => { + if (e.key === "Enter") commit(); + if (e.key === "Escape") setEditing(false); + }} className="w-10 text-center text-sm font-mono bg-dark-900 border border-accent rounded outline-none text-gray-100 py-0.5" /> ) : ( { setInput(String(value)); setEditing(true); }} + onDoubleClick={() => { + setInput(String(value)); + setEditing(true); + }} title="Двойной клик для ручного ввода" - >{value} + > + {value} + )} - - + +
); @@ -81,21 +140,40 @@ export function ValidationSettings() { check_ban: true, max_threads: 5, auto_revalidate_browser: true, + auto_proxy_on_import: false, + auto_validate_on_import: false, + auto_proxy_on_import_mafile: true, + auto_proxy_on_import_logpass: true, + auto_proxy_on_import_token: true, + auto_validate_on_import_mafile: true, + auto_validate_on_import_logpass: true, + auto_validate_on_import_token: true, }); + const [importTab, setImportTab] = useState<"mafile" | "logpass" | "token">( + "mafile", + ); const hidePasswords = useUiStore((s) => s.hidePasswords); const setHidePasswords = useUiStore((s) => s.setHidePasswords); + const loadImportSettings = useUiStore((s) => s.loadImportSettings); const addToast = useUiStore((s) => s.addToast); useEffect(() => { - api.getValidationSettings().then(setSettings).catch(() => {}); + api + .getValidationSettings() + .then(setSettings) + .catch(() => {}); }, []); const save = async () => { try { await api.updateValidationSettings(settings); + await loadImportSettings(); // sync stale uiStore values addToast("success", t("toast.settingsSaved")); } catch (e: unknown) { - addToast("error", t("misc.error", { error: e instanceof Error ? e.message : String(e) })); + addToast( + "error", + t("misc.error", { error: e instanceof Error ? e.message : String(e) }), + ); } }; @@ -124,10 +202,75 @@ export function ValidationSettings() { setSettings({ ...settings, auto_revalidate_browser: v })} + onChange={(v) => + setSettings({ ...settings, auto_revalidate_browser: v }) + } />
- setSettings((s) => ({ ...s, max_threads: v }))} /> + setSettings((s) => ({ ...s, max_threads: v }))} + /> +
+ +
+

+ {t("tools.importSettings")} +

+ {/* Tab switcher */} +
+ {(["mafile", "logpass", "token"] as const).map((tab) => ( + + ))} +
+ {/* Per-tab toggles */} + {(["mafile", "logpass", "token"] as const).map((tab) => + importTab === tab ? ( +
+ + setSettings({ + ...settings, + [`auto_proxy_on_import_${tab}`]: v, + }) + } + /> + + setSettings({ + ...settings, + [`auto_validate_on_import_${tab}`]: v, + }) + } + /> +
+ ) : null, + )}
@@ -142,7 +285,9 @@ export function ValidationSettings() {
- +
); diff --git a/frontend/src/lib/i18n.ts b/frontend/src/lib/i18n.ts index 855601f..1bca173 100644 --- a/frontend/src/lib/i18n.ts +++ b/frontend/src/lib/i18n.ts @@ -7,9 +7,13 @@ const STORAGE_KEY = "steampanel_locale"; let _locale: Locale = (localStorage.getItem(STORAGE_KEY) as Locale) || "ru"; const _listeners = new Set<() => void>(); -function notify() { _listeners.forEach((l) => l()); } +function notify() { + _listeners.forEach((l) => l()); +} -export function getLocale(): Locale { return _locale; } +export function getLocale(): Locale { + return _locale; +} export function setLocale(l: Locale) { _locale = l; @@ -19,7 +23,10 @@ export function setLocale(l: Locale) { export function useLocale(): [Locale, (l: Locale) => void] { const locale = useSyncExternalStore( - (cb) => { _listeners.add(cb); return () => _listeners.delete(cb); }, + (cb) => { + _listeners.add(cb); + return () => _listeners.delete(cb); + }, () => _locale, ); return [locale, setLocale]; @@ -82,7 +89,8 @@ const translations: Translations = { "prompt.newPassword": "Введите новый пароль", "prompt.newEmail": "Введите новый email", "prompt.newPhone": "Введите новый номер телефона", - "prompt.removePhone": "Введите номер телефона (на который переставится старый)", + "prompt.removePhone": + "Введите номер телефона (на который переставится старый)", "prompt.enterValue": "Введите значение...", // -- Confirm dialogs -- "confirm.removeGuard": "Удалить Steam Guard для этого аккаунта?", @@ -123,6 +131,7 @@ const translations: Translations = { "btn.clearProxies": "Очистить прокси", "btn.validate": "Валидировать", "btn.fullParse": "Полный парс", + "btn.fullCheck": "Полная проверка", "btn.generate": "Сгенерировать", // -- Toast messages -- "toast.copied": "Скопировано", @@ -142,7 +151,8 @@ const translations: Translations = { "toast.autoAcceptOff": "Авто-принятие входа выключено", "toast.taskCancelled": "Задача отменена", "toast.browserOpening": "Браузер открывается...", - "toast.cookiesExpiredRevalidating": "Куки устарели. Запущена повторная валидация...", + "toast.cookiesExpiredRevalidating": + "Куки устарели. Запущена повторная валидация...", "toast.cookiesExpired": "Куки устарели. Провалидируйте аккаунт заново.", "toast.proxyCleared": "Прокси убран у {name}", "toast.proxiesReassigned": "Переназначено {used} прокси на {count} акк.", @@ -249,7 +259,8 @@ const translations: Translations = { "proxy.checking": "Проверка...", "proxy.checkAll": "Проверить все", "proxy.deleteAllBtn": "Удалить все прокси", - "proxy.confirmDeleteAll": "Удалить все прокси? Это действие нельзя отменить.", + "proxy.confirmDeleteAll": + "Удалить все прокси? Это действие нельзя отменить.", "proxy.checkResult": "Всего: {total} | Живых: {alive} | Мёртвых: {dead}", "proxy.removeProxy": "Убрать прокси", "proxy.reassignProxy": "Переназначить прокси", @@ -262,6 +273,15 @@ const translations: Translations = { "tools.checkBans": "Проверять баны", "tools.maxThreads": "Макс. потоков:", "tools.autoRevalidateBrowser": "Автовалидация при мёртвых куках (браузер)", + "tools.autoProxyOnImport": "Авто-назначение прокси при импорте", + "tools.autoValidateOnImport": "Авто-валидация при импорте", + "tools.importSettings": "Настройки импорта", + "tools.autoProxyOnImportDesc": "Авто-назначить прокси сразу после импорта", + "tools.autoValidateOnImportDesc": + "Авто-валидировать аккаунты сразу после импорта", + "tools.importTabMafile": "Mafile", + "tools.importTabLogpass": "Log:Pass", + "tools.importTabToken": "Token", "tools.clickCopy": "Клик для копирования", "tools.genErrorStr": "Ошибка", // -- Logs panel -- @@ -293,7 +313,8 @@ const translations: Translations = { "mafile.clearBtn": "Очистить", "mafile.insert": "Вставить {value}", "mafile.emptyTitle": "Нет выбранных аккаунтов", - "mafile.emptyHint": "Выберите аккаунты в таблице и отправьте сюда для экспорта mafile", + "mafile.emptyHint": + "Выберите аккаунты в таблице и отправьте сюда для экспорта mafile", "mafile.accountsCount": "акк.", "mafile.withMafile": "с mafile", "mafile.namingSection": "Шаблоны имён", @@ -305,9 +326,12 @@ const translations: Translations = { "settings.hidePasswords": "Скрывать пароли (спойлер)", // -- Token disclaimer -- "token.disclaimerTitle": "Вкладка в разработке", - "token.disclaimerBody1": "Функциональность вкладки Token не завершена и находится в стадии разработки.", - "token.disclaimerBody2": "⚠ Валидация токенов может привести к их инвалидации (убить токены). Используйте на свой страх и риск.", - "token.disclaimerBody3": "Импорт, редактирование и любые действия с токенами могут работать некорректно.", + "token.disclaimerBody1": + "Функциональность вкладки Token не завершена и находится в стадии разработки.", + "token.disclaimerBody2": + "⚠ Валидация токенов может привести к их инвалидации (убить токены). Используйте на свой страх и риск.", + "token.disclaimerBody3": + "Импорт, редактирование и любые действия с токенами могут работать некорректно.", "token.acceptRisk": "Я понимаю риски и хочу продолжить", // -- 2FA -- "twofa.copied": "2FA: {code} (скопировано)", @@ -377,7 +401,8 @@ const translations: Translations = { "prompt.newPassword": "Enter new password", "prompt.newEmail": "Enter new email", "prompt.newPhone": "Enter new phone number", - "prompt.removePhone": "Enter phone number (old number will be transferred to it)", + "prompt.removePhone": + "Enter phone number (old number will be transferred to it)", "prompt.enterValue": "Enter value...", // -- Confirm dialogs -- "confirm.removeGuard": "Remove Steam Guard for this account?", @@ -418,6 +443,7 @@ const translations: Translations = { "btn.clearProxies": "Clear proxies", "btn.validate": "Validate", "btn.fullParse": "Full parse", + "btn.fullCheck": "Full Check", "btn.generate": "Generate", // -- Toast messages -- "toast.copied": "Copied", @@ -557,6 +583,15 @@ const translations: Translations = { "tools.checkBans": "Check bans", "tools.maxThreads": "Max threads:", "tools.autoRevalidateBrowser": "Auto-revalidate on dead cookies (browser)", + "tools.autoProxyOnImport": "Auto-assign proxies on import", + "tools.autoValidateOnImport": "Auto-validate on import", + "tools.importSettings": "Import Settings", + "tools.autoProxyOnImportDesc": "Auto-assign proxies right after import", + "tools.autoValidateOnImportDesc": + "Auto-validate accounts right after import", + "tools.importTabMafile": "Mafile", + "tools.importTabLogpass": "Log:Pass", + "tools.importTabToken": "Token", "tools.clickCopy": "Click to copy", "tools.genErrorStr": "Error", // -- Logs panel -- @@ -588,7 +623,8 @@ const translations: Translations = { "mafile.clearBtn": "Clear", "mafile.insert": "Insert {value}", "mafile.emptyTitle": "No accounts selected", - "mafile.emptyHint": "Select accounts in the table and send them here for mafile export", + "mafile.emptyHint": + "Select accounts in the table and send them here for mafile export", "mafile.accountsCount": "accs", "mafile.withMafile": "with mafile", "mafile.namingSection": "Naming templates", @@ -600,9 +636,12 @@ const translations: Translations = { "settings.hidePasswords": "Hide passwords (spoiler)", // -- Token disclaimer -- "token.disclaimerTitle": "Tab under development", - "token.disclaimerBody1": "Token tab functionality is not complete and is under development.", - "token.disclaimerBody2": "⚠ Token validation may invalidate (kill) tokens. Use at your own risk.", - "token.disclaimerBody3": "Import, editing and any actions with tokens may work incorrectly.", + "token.disclaimerBody1": + "Token tab functionality is not complete and is under development.", + "token.disclaimerBody2": + "⚠ Token validation may invalidate (kill) tokens. Use at your own risk.", + "token.disclaimerBody3": + "Import, editing and any actions with tokens may work incorrectly.", "token.acceptRisk": "I understand the risks and want to continue", // -- 2FA -- "twofa.copied": "2FA: {code} (copied)", @@ -620,7 +659,10 @@ const translations: Translations = { }, }; -export function t(key: string, params?: Record): string { +export function t( + key: string, + params?: Record, +): string { const dict = translations[_locale] || translations.ru; let text = dict[key] ?? translations.ru[key] ?? key; if (params) { @@ -633,7 +675,10 @@ export function t(key: string, params?: Record): string export function useT() { useSyncExternalStore( - (cb) => { _listeners.add(cb); return () => _listeners.delete(cb); }, + (cb) => { + _listeners.add(cb); + return () => _listeners.delete(cb); + }, () => _locale, ); return t; diff --git a/frontend/src/stores/logpassStore.ts b/frontend/src/stores/logpassStore.ts index 9fcedc4..6e43774 100644 --- a/frontend/src/stores/logpassStore.ts +++ b/frontend/src/stores/logpassStore.ts @@ -11,6 +11,7 @@ interface LogpassState { toggleSelect: (id: number) => void; selectAll: () => void; clearSelection: () => void; + setSelectedIds: (ids: Set) => void; } export const useLogpassStore = create((set) => ({ @@ -40,4 +41,5 @@ export const useLogpassStore = create((set) => ({ set((s) => ({ selectedIds: new Set(s.accounts.map((a) => a.id)) })), clearSelection: () => set({ selectedIds: new Set() }), + setSelectedIds: (ids) => set({ selectedIds: ids }), })); diff --git a/frontend/src/stores/tokenStore.ts b/frontend/src/stores/tokenStore.ts index e0c2897..26c0a7a 100644 --- a/frontend/src/stores/tokenStore.ts +++ b/frontend/src/stores/tokenStore.ts @@ -11,6 +11,7 @@ interface TokenState { toggleSelect: (id: number) => void; selectAll: () => void; clearSelection: () => void; + setSelectedIds: (ids: Set) => void; } export const useTokenStore = create((set) => ({ @@ -40,4 +41,5 @@ export const useTokenStore = create((set) => ({ set((s) => ({ selectedIds: new Set(s.accounts.map((a) => a.id)) })), clearSelection: () => set({ selectedIds: new Set() }), + setSelectedIds: (ids) => set({ selectedIds: ids }), })); diff --git a/frontend/src/stores/uiStore.ts b/frontend/src/stores/uiStore.ts index 75c9d8a..c71566a 100644 --- a/frontend/src/stores/uiStore.ts +++ b/frontend/src/stores/uiStore.ts @@ -1,26 +1,67 @@ import { create } from "zustand"; -import type { TabId, Toast, ToastType, ColumnSettings, LogpassColumnSettings, TokenColumnSettings } from "@/api/types"; +import type { + TabId, + Toast, + ToastType, + ColumnSettings, + LogpassColumnSettings, + TokenColumnSettings, +} from "@/api/types"; import { api } from "@/api/client"; let _toastId = 0; const DEFAULT_COLUMNS: ColumnSettings = { - browser: true, profile: true, steam_id: true, login: true, password: true, - login_pass: true, email: true, email_pass: false, email_login_pass: false, - phone: true, status: true, - ban: true, twofa: true, mafile: true, proxy: true, notes: true, actions: true, + browser: true, + profile: true, + steam_id: true, + login: true, + password: true, + login_pass: true, + email: true, + email_pass: false, + email_login_pass: false, + phone: true, + status: true, + ban: true, + twofa: true, + mafile: true, + proxy: true, + notes: true, + actions: true, last_online: true, }; const DEFAULT_LOGPASS_COLUMNS: LogpassColumnSettings = { - browser: true, profile: true, steam_id: true, login: true, password: true, login_pass: true, - status: true, ban: true, prime: true, trophy: true, behavior: true, - license: true, proxy: true, notes: true, actions: true, last_online: true, + browser: true, + profile: true, + steam_id: true, + login: true, + password: true, + login_pass: true, + status: true, + ban: true, + prime: true, + trophy: true, + behavior: true, + license: true, + proxy: true, + notes: true, + actions: true, + last_online: true, }; const DEFAULT_TOKEN_COLUMNS: TokenColumnSettings = { - browser: true, profile: true, last_online: true, steam_id: true, login: true, - token: true, status: true, proxy: true, notes: true, actions: true, + browser: true, + profile: true, + last_online: true, + steam_id: true, + login: true, + token: true, + status: true, + proxy: true, + notes: true, + actions: true, }; interface UiState { @@ -41,6 +82,15 @@ interface UiState { logpassColumnVisibility: LogpassColumnSettings; toggleLogpassColumn: (key: keyof LogpassColumnSettings) => void; loadLogpassColumnSettings: () => Promise; + autoProxyOnImport: boolean; + autoValidateOnImport: boolean; + autoProxyOnImportMafile: boolean; + autoProxyOnImportLogpass: boolean; + autoProxyOnImportToken: boolean; + autoValidateOnImportMafile: boolean; + autoValidateOnImportLogpass: boolean; + autoValidateOnImportToken: boolean; + loadImportSettings: () => Promise; tokenColumnVisibility: TokenColumnSettings; toggleTokenColumn: (key: keyof TokenColumnSettings) => void; loadTokenColumnSettings: () => Promise; @@ -59,7 +109,8 @@ export const useUiStore = create((set, get) => ({ set((s) => ({ toasts: s.toasts.filter((t) => t.id !== id) })); }, 4000); }, - removeToast: (id) => set((s) => ({ toasts: s.toasts.filter((t) => t.id !== id) })), + removeToast: (id) => + set((s) => ({ toasts: s.toasts.filter((t) => t.id !== id) })), hidePasswords: false, setHidePasswords: (v) => { @@ -70,13 +121,18 @@ export const useUiStore = create((set, get) => ({ try { const d = await api.getDisplaySettings(); set({ hidePasswords: d.hide_passwords }); - } catch { /* ignore */ } + } catch { + /* ignore */ + } }, columnVisibility: { ...DEFAULT_COLUMNS }, setColumnVisibility: (v) => set({ columnVisibility: v }), toggleColumn: (key) => { - const cols = { ...get().columnVisibility, [key]: !get().columnVisibility[key] }; + const cols = { + ...get().columnVisibility, + [key]: !get().columnVisibility[key], + }; set({ columnVisibility: cols }); api.updateColumnSettings(cols).catch(() => {}); }, @@ -84,12 +140,17 @@ export const useUiStore = create((set, get) => ({ try { const c = await api.getColumnSettings(); set({ columnVisibility: { ...DEFAULT_COLUMNS, ...c } }); - } catch { /* ignore */ } + } catch { + /* ignore */ + } }, logpassColumnVisibility: { ...DEFAULT_LOGPASS_COLUMNS }, toggleLogpassColumn: (key) => { - const cols = { ...get().logpassColumnVisibility, [key]: !get().logpassColumnVisibility[key] }; + const cols = { + ...get().logpassColumnVisibility, + [key]: !get().logpassColumnVisibility[key], + }; set({ logpassColumnVisibility: cols }); api.updateLogpassColumnSettings(cols).catch(() => {}); }, @@ -97,12 +158,43 @@ export const useUiStore = create((set, get) => ({ try { const c = await api.getLogpassColumnSettings(); set({ logpassColumnVisibility: { ...DEFAULT_LOGPASS_COLUMNS, ...c } }); - } catch { /* ignore */ } + } catch { + /* ignore */ + } + }, + + autoProxyOnImport: false, + autoValidateOnImport: false, + autoProxyOnImportMafile: true, + autoProxyOnImportLogpass: true, + autoProxyOnImportToken: true, + autoValidateOnImportMafile: true, + autoValidateOnImportLogpass: true, + autoValidateOnImportToken: true, + loadImportSettings: async () => { + try { + const s = await api.getValidationSettings(); + set({ + autoProxyOnImport: s.auto_proxy_on_import, + autoValidateOnImport: s.auto_validate_on_import, + autoProxyOnImportMafile: s.auto_proxy_on_import_mafile, + autoProxyOnImportLogpass: s.auto_proxy_on_import_logpass, + autoProxyOnImportToken: s.auto_proxy_on_import_token, + autoValidateOnImportMafile: s.auto_validate_on_import_mafile, + autoValidateOnImportLogpass: s.auto_validate_on_import_logpass, + autoValidateOnImportToken: s.auto_validate_on_import_token, + }); + } catch { + /* ignore */ + } }, tokenColumnVisibility: { ...DEFAULT_TOKEN_COLUMNS }, toggleTokenColumn: (key) => { - const cols = { ...get().tokenColumnVisibility, [key]: !get().tokenColumnVisibility[key] }; + const cols = { + ...get().tokenColumnVisibility, + [key]: !get().tokenColumnVisibility[key], + }; set({ tokenColumnVisibility: cols }); api.updateTokenColumnSettings(cols).catch(() => {}); }, @@ -110,6 +202,8 @@ export const useUiStore = create((set, get) => ({ try { const c = await api.getTokenColumnSettings(); set({ tokenColumnVisibility: { ...DEFAULT_TOKEN_COLUMNS, ...c } }); - } catch { /* ignore */ } + } catch { + /* ignore */ + } }, })); diff --git a/main.py b/main.py index 151c6e2..5f93731 100644 --- a/main.py +++ b/main.py @@ -3,31 +3,43 @@ import socket from contextlib import asynccontextmanager from fastapi import FastAPI -from fastapi.staticfiles import StaticFiles from fastapi.responses import FileResponse +from fastapi.staticfiles import StaticFiles +from loguru import logger + +from app.api import ( + accounts, + actions, + auto_accept, + browser, + logpass, + logs, + mafile_tools, + proxies, + tasks, + token_accounts, +) +from app.api import settings as settings_api +from app.config import settings +from app.core.auto_accept import auto_accept_manager +from app.core.logging import setup_logging +from app.core.proxy_manager import proxy_manager +from app.database import close_db, get_db +from app.services.registry import register_all_handlers mimetypes.add_type("application/javascript", ".js") mimetypes.add_type("text/css", ".css") mimetypes.add_type("image/svg+xml", ".svg") -from loguru import logger -VERSION = "0.3.4" -from app.config import settings -from app.core.logging import setup_logging -from app.database import get_db, close_db -from app.core.proxy_manager import proxy_manager -from app.core.auto_accept import auto_accept_manager -from app.services.registry import register_all_handlers -from app.api import accounts, actions, proxies, tasks, mafile_tools, logs, auto_accept, browser -from app.api import settings as settings_api -from app.api import logpass, token_accounts +VERSION = "0.3.5" @asynccontextmanager async def lifespan(app: FastAPI): setup_logging() from app.api.logs import install_log_sink + install_log_sink() db = await get_db() @@ -73,6 +85,7 @@ app = FastAPI( async def get_version(): return {"version": VERSION} + app.include_router(accounts.router) app.include_router(actions.router) app.include_router(proxies.router) @@ -90,6 +103,7 @@ static_dir.mkdir(parents=True, exist_ok=True) _MIME = {".js": "application/javascript", ".css": "text/css", ".svg": "image/svg+xml"} + @app.get("/", include_in_schema=False) async def serve_root(): return FileResponse( @@ -97,16 +111,22 @@ async def serve_root(): headers={"Cache-Control": "no-store, no-cache, must-revalidate"}, ) + @app.get("/assets/{filename:path}", include_in_schema=False) async def serve_asset(filename: str): from fastapi import HTTPException + file_path = static_dir / "assets" / filename if not file_path.exists(): raise HTTPException(status_code=404) ext = "." + filename.rsplit(".", 1)[-1] if "." in filename else "" media_type = _MIME.get(ext, "application/octet-stream") - return FileResponse(str(file_path), media_type=media_type, - headers={"Cache-Control": "public, max-age=31536000, immutable"}) + return FileResponse( + str(file_path), + media_type=media_type, + headers={"Cache-Control": "public, max-age=31536000, immutable"}, + ) + app.mount("/", StaticFiles(directory=str(static_dir), html=True), name="static") @@ -128,6 +148,7 @@ if __name__ == "__main__": import threading import time import webbrowser + import uvicorn # Install log intercept before uvicorn.run() so the first two startup diff --git a/run.bat b/run.bat index 904b2eb..45458ad 100644 --- a/run.bat +++ b/run.bat @@ -40,6 +40,13 @@ if errorlevel 1 ( :launch cls +rem === Patch nodriver/cdp/network.py encoding bug (non-UTF-8 byte \xb1 in comment) === +venv\Scripts\python.exe -c ^ + "import pathlib;^ + p=pathlib.Path('venv/Lib/site-packages/nodriver/cdp/network.py');^ + d=p.read_bytes() if p.exists() else b'';^ + p.write_bytes(d.replace(b'\xb1',b'+-')) if p.exists() and b'\xb1' in d else None" + rem === Check built frontend === if not exist "app\static\assets\" ( echo.