Загрузка данных
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<title>PHARAON</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Onest:wght@100..900&family=JetBrains+Mono:wght@400;700&display=swap');
* { margin:0; padding:0; box-sizing:border-box; user-select:none; -webkit-user-drag:none; }
html,body { width:100%; height:100%; overflow:hidden; }
body {
font-family:'Onest', 'Segoe UI', Arial, sans-serif;
background:#070910; color:#e8edf6;
}
::-webkit-scrollbar { display:none; }
* { -ms-overflow-style:none; scrollbar-width:none; }
*:focus { outline:none; }
svg { display:block; }
:root {
--primary:#3b82f6;
--primary-hover:#2b6be0;
--w2:rgba(255,255,255,.05);
--w4:rgba(255,255,255,.09);
--w24:rgba(255,255,255,.16);
--w48:rgba(255,255,255,.38);
--line:rgba(59,130,246,.3);
--panel:rgba(11,15,26,.82);
--text:#e8edf6;
--muted:#8b92a6;
--transition:all .25s cubic-bezier(.4,0,.2,1);
}
/* ---------- фон ---------- */
#bg { position:fixed; inset:0; z-index:0;
background:
radial-gradient(900px 620px at 80% 8%, rgba(47,123,255,.16) 0%, transparent 60%),
radial-gradient(720px 520px at 8% 92%, rgba(90,140,255,.1) 0%, transparent 55%),
radial-gradient(1100px 700px at 50% 125%, rgba(28,56,140,.18) 0%, transparent 60%),
linear-gradient(160deg,#0a1020 0%,#060a16 52%,#04070d 100%);
transition: background-image .6s ease;
}
#bg.hasimg { background-image:
linear-gradient(rgba(5,8,16,.72), rgba(5,8,16,.88)),
url('__BG_DATA_URI__'); background-size:cover; background-position:center; }
.wrap { position:relative; z-index:1; width:100%; height:100%; }
/* ---------- топбар (сворачивание/закрытие) ---------- */
.topbar { position:fixed; top:16px; right:18px; z-index:60; display:flex; gap:8px; }
.tb-btn { border:1px solid var(--w4); background:var(--panel); color:#8a93a9; width:36px; height:30px;
border-radius:10px; cursor:pointer; font-size:14px; font-family:inherit;
backdrop-filter:blur(16px); -webkit-backdrop-filter:blur(16px); transition:var(--transition); }
.tb-btn:hover { color:#fff; border-color:var(--w24); box-shadow:0 4px 14px rgba(0,0,0,.35); }
.tb-btn.tb-close:hover { background:rgba(220,60,60,.16); color:#ff8a8a; border-color:rgba(220,60,60,.45); }
/* ---------- панель настроек ---------- */
.themePanel { position:fixed; top:54px; right:18px; z-index:70; min-width:236px;
background:var(--panel); border:1px solid var(--w4); border-radius:18px; padding:20px;
backdrop-filter:blur(24px); -webkit-backdrop-filter:blur(24px);
box-shadow:0 28px 70px rgba(0,0,0,.6), inset 0 1px 0 var(--w2);
animation:panelIn .25s cubic-bezier(.4,0,.2,1); }
@keyframes panelIn { from { opacity:0; transform:translateY(-8px) scale(.97); } to { opacity:1; transform:none; } }
.tp-ttl { font-size:10px; letter-spacing:2.5px; color:var(--muted); margin-bottom:12px; text-transform:uppercase; font-weight:600; }
.tp-row { display:flex; gap:9px; }
.th-c { width:26px; height:26px; border-radius:50%; background:var(--c); cursor:pointer;
border:2px solid rgba(255,255,255,.14); transition:var(--transition); }
.th-c:hover { transform:scale(1.15); box-shadow:0 0 14px var(--c); }
.th-c.sel { border-color:#fff; box-shadow:0 0 12px var(--c); }
.tp-sep { height:1px; background:var(--w4); margin:14px 0; }
.tp-name { margin-top:12px; font-size:11px; color:#aeb6c8; text-align:center; letter-spacing:1.5px; font-weight:500; }
.tp-out { color:#e06565; font-size:11px; cursor:pointer; text-decoration:none; transition:color .15s; }
.tp-out:hover { color:#ff8a8a; }
.ram-row { display:flex; gap:6px; justify-content:center; }
.ram-b { padding:6px 12px; border-radius:8px; font-size:11px; color:var(--muted); cursor:pointer;
border:1px solid var(--w4); font-weight:600; transition:var(--transition); }
.ram-b.on { background:var(--acc); color:#fff; border-color:var(--acc); box-shadow:0 4px 16px var(--acc-glow); }
.ram-b:hover:not(.on) { background:var(--w4); color:#fff; }
/* ---------- темы (база — чёрно-синяя) ---------- */
body { --acc:#3b82f6; --acc-hover:#2b6be0; --acc-glow:rgba(59,130,246,.16); }
body[data-theme="pharaon"] { --acc:#4d8dff; --acc-hover:#3b78e8; --acc-glow:rgba(77,141,255,.18); }
body[data-theme="emerald"] { --acc:#38b8a8; --acc-hover:#2b9e90; --acc-glow:rgba(56,184,168,.16); }
body[data-theme="ruby"] { --acc:#4a5fd8; --acc-hover:#3c4fc0; --acc-glow:rgba(74,95,216,.16); }
body[data-theme="ice"] { --acc:#5aa7f0; --acc-hover:#4a90d8; --acc-glow:rgba(90,167,240,.16); }
body[data-theme="amethyst"] { --acc:#8f6ff0; --acc-hover:#7d5cd8; --acc-glow:rgba(143,111,240,.16); }
body[data-theme="midnight"] { --acc:#6f86b8; --acc-hover:#5f74a0; --acc-glow:rgba(111,134,184,.14); }
/* ---------- экраны ---------- */
.screen { display:none; position:absolute; inset:0; align-items:center; justify-content:center; }
.screen.active { display:flex; animation:screenIn .35s cubic-bezier(.4,0,.2,1); }
@keyframes screenIn { from{opacity:0; transform:translateY(12px) scale(.99)} to{opacity:1; transform:none} }
/* ---------- boot ---------- */
#boot { flex-direction:column; }
#boot .brandbig { margin-top:18px; font-size:22px; font-weight:600; letter-spacing:5px; color:#fff; }
.spin { width:28px; height:28px; border-radius:50%; margin:24px auto 0;
border:2.5px solid var(--w4); border-top-color:var(--acc);
animation:spin 1s cubic-bezier(.4,0,.2,1) infinite; }
@keyframes spin { to { transform:rotate(360deg); } }
#bootStatus { margin-top:16px; font-size:11.5px; color:var(--muted); letter-spacing:1.5px; font-weight:500; }
#bootErr { margin-top:16px; text-align:center; display:none; }
/* ---------- авторизация / ключ ---------- */
#auth.active, #key.active { display:flex; }
.split { width:100%; height:100%; display:flex; align-items:center; justify-content:center; padding:40px; }
.split-left { display:none; }
.split-right { width:100%; max-width:440px; display:flex; flex-direction:column;
align-items:center; text-align:center;
padding:36px 34px 30px;
background:linear-gradient(180deg, rgba(19,26,48,.72), rgba(12,17,34,.82));
border:1px solid var(--w4); border-radius:24px;
box-shadow:0 30px 80px rgba(0,0,0,.55), 0 0 60px rgba(37,78,255,.08), inset 0 1px 0 rgba(255,255,255,.06);
backdrop-filter:blur(28px); -webkit-backdrop-filter:blur(28px); }
.auth-logo { width:64px; height:64px; border-radius:18px; background:linear-gradient(145deg, var(--acc), var(--acc-hover));
display:flex; align-items:center; justify-content:center; margin-bottom:22px;
box-shadow:0 14px 34px var(--acc-glow), inset 0 1px 0 rgba(255,255,255,.25); }
.auth-logo img { width:40px; height:40px; object-fit:contain; }
.h1 { font-size:21px; font-weight:600; color:#fff; line-height:1.25; }
.sub { margin-top:6px; font-size:13.5px; color:#9aa4bb; font-weight:300; line-height:1.5; }
.form { margin-top:26px; width:100%; display:flex; flex-direction:column; gap:14px; }
.field { position:relative; width:100%; }
.field > svg { position:absolute; left:18px; top:50%; transform:translateY(-50%); color:#77829c; z-index:2; }
.field input { width:100%; padding:14px 20px 14px 48px; background:rgba(6,10,20,.6);
border:1px solid var(--w4); color:#fff;
border-radius:14px; font-size:15px; font-family:inherit; transition:var(--transition);
backdrop-filter:blur(24px); -webkit-backdrop-filter:blur(24px); }
.field input::placeholder { color:#67718a; }
.field input:focus { background:rgba(10,15,30,.8); border-color:var(--w24);
box-shadow:0 0 0 3px var(--acc-glow); }
.field input:focus::placeholder { opacity:0; }
.field input:focus ~ svg { color:var(--acc); }
.eye { position:absolute; right:10px; top:50%; transform:translateY(-50%); background:transparent;
border:none; color:#77829c; cursor:pointer; font-size:13px; font-family:inherit;
padding:8px; transition:color .15s; z-index:3; }
.eye:hover { color:#fff; }
.btnlight { width:100%; padding:14px; background:linear-gradient(145deg, var(--acc), var(--acc-hover));
color:#fff; border:none; border-radius:14px; font-weight:600; font-size:15px; font-family:inherit; cursor:pointer;
display:flex; align-items:center; justify-content:center; gap:8px;
box-shadow:0 14px 30px var(--acc-glow); transition:var(--transition); }
.btnlight:hover { transform:translateY(-1px); box-shadow:0 18px 40px var(--acc-glow); filter:brightness(1.08); }
.btnlight:disabled { opacity:.45; cursor:default; transform:none; box-shadow:none; filter:none; }
.btnlight > span:last-child { transition:transform .2s; }
.btnlight:hover > span:last-child { transform:translateX(3px); }
.err { display:none; margin-top:12px; background:rgba(220,60,60,.12); border:1px solid rgba(220,60,60,.35);
color:#ff9d9d; font-size:12px; padding:10px 13px; border-radius:12px; line-height:1.45; font-weight:500; }
.err.show { display:block; animation:shake .35s cubic-bezier(.4,0,.2,1); }
@keyframes shake { 0%,100%{transform:translateX(0)} 20%{transform:translateX(-6px)} 40%{transform:translateX(6px)} 60%{transform:translateX(-3px)} 80%{transform:translateX(3px)} }
.switchline { margin-top:18px; font-size:14px; color:#9aa4bb; }
.switchline a { color:var(--acc); cursor:pointer; text-decoration:none; transition:color .15s; font-weight:500; }
.switchline a:hover { color:var(--acc-hover); }
.ver { margin-top:28px; font-size:10px; color:var(--muted); letter-spacing:2.5px; font-weight:500; }
.waitbox { margin-top:24px; width:100%; border:1px dashed var(--w24); border-radius:16px;
padding:22px 18px; text-align:center; background:rgba(6,10,20,.4); }
.waitbox .nic { font-size:20px; font-weight:700; color:#fff; margin-top:14px;
font-family:'JetBrains Mono', Consolas, monospace; letter-spacing:1.5px; }
.waitbox .note { font-size:11px; color:var(--muted); margin-top:8px; font-weight:400; }
.manual { margin-top:16px; }
/* ---------- главный экран ---------- */
#main.active { flex-direction:column; align-items:center; padding:24px 40px 20px; gap:14px; }
.main-head { width:100%; max-width:948px; display:flex; align-items:center; gap:12px;
background:linear-gradient(180deg, rgba(19,26,48,.72), rgba(12,17,34,.85));
padding:14px 18px; border-radius:16px; border:1px solid var(--w4);
box-shadow:0 18px 48px rgba(0,0,0,.4), inset 0 1px 0 rgba(255,255,255,.06);
backdrop-filter:blur(28px); -webkit-backdrop-filter:blur(28px); }
.main-head .t { font-size:20px; font-weight:600; color:#fff; margin-left:12px; }
.main-head .logo-img.mini { border:2px solid rgba(255,255,255,.2); box-shadow:0 0 24px var(--acc-glow);
background:var(--acc); }
.cards { display:grid; grid-template-columns:1fr 1fr; gap:14px; margin-top:2px; width:100%; max-width:948px; }
.card { border-radius:16px; overflow:hidden; cursor:pointer; position:relative;
border:1px solid var(--w4); background:linear-gradient(180deg, rgba(19,26,48,.7), rgba(12,17,34,.86));
box-shadow:0 14px 44px rgba(0,0,0,.4), inset 0 1px 0 rgba(255,255,255,.05);
backdrop-filter:blur(24px); -webkit-backdrop-filter:blur(24px);
transition:var(--transition); }
.card:hover { border-color:var(--w24); transform:translateY(-3px) scale(1.005);
box-shadow:0 24px 60px rgba(0,0,0,.5); }
.card.sel { border-color:var(--acc); box-shadow:0 0 30px var(--acc-glow), 0 24px 60px rgba(0,0,0,.5); }
.thumb { height:150px; background-size:cover; background-position:center;
background-image:
linear-gradient(rgba(10,14,28,.2), rgba(10,14,28,.55)),
radial-gradient(460px 240px at 72% 24%, rgba(59,130,246,.14) 0%, transparent 60%),
linear-gradient(160deg,#18233f 0%, #111a30 55%, #0b1322 100%); }
.thumb.img { background-image:
linear-gradient(rgba(8,12,24,.3), rgba(8,12,24,.62)),
url('__THUMB_DATA_URI__'); }
.card.locked .thumb { filter:grayscale(1) brightness(.4); }
.card.locked { cursor:default; opacity:.6; }
.card.locked:hover { transform:none; box-shadow:none; border-color:var(--w4); }
.card.locked .lockov { position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
gap:8px; color:#a7aec0; font-size:12px; font-weight:500; letter-spacing:.5px; }
.card-row { display:flex; align-items:center; justify-content:space-between; padding:14px 16px; }
.cname { display:flex; align-items:center; gap:7px; font-size:14px; font-weight:600; color:#fff; }
.cname .c-ico { border-radius:4px; }
.cdate { display:flex; align-items:center; gap:6px; font-size:11.5px; color:#9aa4bb; font-weight:400; }
.cdate.dis { color:var(--muted); opacity:.5; }
.announce { margin-top:2px; max-width:948px; width:100%; background:linear-gradient(180deg, rgba(19,26,48,.65), rgba(12,17,34,.8));
border:1px solid var(--w4); border-radius:12px; padding:10px 14px; font-size:13px; color:#9aa4bb;
line-height:1.5; user-select:text; max-height:80px; overflow:auto; display:none;
backdrop-filter:blur(24px); font-weight:400; }
.progressWrap { display:none; margin-top:2px; width:100%; max-width:948px; }
.prog-top { display:flex; justify-content:space-between; font-size:11px; color:var(--muted); margin-bottom:6px; font-weight:500; }
#pct { color:#fff; font-weight:700; font-family:'JetBrains Mono', Consolas, monospace; }
.bar { height:6px; border-radius:3px; background:rgba(255,255,255,.08); overflow:hidden;
box-shadow:inset 0 1px 3px rgba(0,0,0,.4); }
.bar > div { height:100%; width:0%; border-radius:3px; background:linear-gradient(90deg, var(--acc), #7ea2ff);
transition:width .4s cubic-bezier(.4,0,.2,1); box-shadow:0 0 12px var(--acc-glow); }
#gameOk { display:none; margin-top:8px; font-size:12px; color:#6fe8a8; font-weight:600; }
#mainErr { display:none; margin-top:8px; font-size:12px; color:#ff9d9d; line-height:1.45; font-weight:500; }
/* нижняя панель */
.bottombar { width:100%; max-width:948px; display:flex; align-items:center; gap:10px; margin-top:auto; }
.bottombar .loading-side { flex:1; display:flex; align-items:center; gap:12px; padding:8px;
background:linear-gradient(180deg, rgba(19,26,48,.72), rgba(12,17,34,.86));
border:1px solid var(--w4); border-radius:16px; height:58px;
box-shadow:0 18px 48px rgba(0,0,0,.4), inset 0 1px 0 rgba(255,255,255,.06);
backdrop-filter:blur(28px); -webkit-backdrop-filter:blur(28px); }
.avatar { flex-shrink:0; width:42px; height:42px; border-radius:12px; background:linear-gradient(145deg, var(--acc), var(--acc-hover));
border:1px solid var(--w24); display:flex; align-items:center; justify-content:center;
box-shadow:0 8px 20px var(--acc-glow); }
.avatar-ico { border-radius:10px; object-fit:cover; }
.uinfo { display:flex; flex-direction:column; gap:2px; min-width:0; }
.unick { font-size:14px; font-weight:600; color:#fff; }
.uid { font-size:11px; color:var(--muted); font-weight:400; }
.uinfo-sub { display:flex; align-items:center; gap:10px; }
.pill { font-size:11.5px; color:#9aa4bb; font-weight:500; }
.loading-bars { flex:1; margin-left:4px; background:rgba(255,255,255,.06); border:1px solid var(--w4);
padding:4px; border-radius:20px; }
.line { height:4px; background:rgba(255,255,255,.06); border-radius:2px; position:relative; overflow:hidden; }
.line::after { content:''; position:absolute; top:0; left:0; height:100%; width:var(--progress-width,70%);
background:linear-gradient(90deg, var(--acc), #7ea2ff); border-radius:2px; transition:var(--transition); }
.bottombar .btns { display:flex; gap:8px; }
.bb-btn { border:1px solid var(--w4); display:flex; align-items:center; justify-content:center; padding:0 20px;
height:58px; border-radius:14px; background:linear-gradient(180deg, rgba(19,26,48,.7), rgba(12,17,34,.85));
color:#9aa4bb; font-size:16px; cursor:pointer; font-family:inherit;
backdrop-filter:blur(24px); -webkit-backdrop-filter:blur(24px); transition:var(--transition); }
.bb-btn:hover { border-color:var(--w24); color:#fff; box-shadow:0 8px 24px rgba(0,0,0,.35); }
.bb-btn img { width:16px; }
.runbtn { border:none; display:flex; align-items:center; justify-content:center; gap:8px;
background:linear-gradient(145deg, var(--acc), var(--acc-hover)); color:#fff; border-radius:14px; padding:0 24px; height:58px;
font-size:15px; font-weight:600; font-family:inherit; cursor:pointer; white-space:nowrap;
box-shadow:0 14px 30px var(--acc-glow); transition:var(--transition); }
.runbtn:hover:not(:disabled) { transform:translateY(-1px); box-shadow:0 18px 40px var(--acc-glow); filter:brightness(1.08); }
.runbtn:disabled { opacity:.45; cursor:default; transform:none; box-shadow:none; filter:none; }
/* ---------- эмблема ---------- */
.emblem-wrap { position:relative; display:flex; align-items:center; justify-content:center; }
.emblem-glow { position:absolute; width:120px; height:120px; border-radius:50%;
background:radial-gradient(circle, var(--acc-glow) 0%, transparent 70%);
filter:blur(30px); animation:emblemPulse 4s ease-in-out infinite; }
@keyframes emblemPulse { 0%,100%{opacity:.3; transform:scale(1)} 50%{opacity:.55; transform:scale(1.06)} }
.emblem-svg { position:relative; z-index:1; }
.logo-img { object-fit:contain; }
.logo-img.mini { border-radius:50%; }
.c-ico { object-fit:cover; }
/* ---------- анимация появления карточек ---------- */
.card { opacity:0; animation:cardIn .4s cubic-bezier(.4,0,.2,1) forwards; }
.card:nth-child(1) { animation-delay:.05s; }
.card:nth-child(2) { animation-delay:.12s; }
.card:nth-child(3) { animation-delay:.19s; }
@keyframes cardIn { from{opacity:0; transform:translateY(10px)} to{opacity:1; transform:none} }
.card.locked { animation:cardIn .4s cubic-bezier(.4,0,.2,1) forwards; }
</style>
</head>
<body>
<div id="bg"></div>
<div class="wrap">
<div class="topbar">
<button class="tb-btn" id="tbTheme" title="Настройки">⚙</button>
<button class="tb-btn" id="tbMin" title="Свернуть">─</button>
<button class="tb-btn tb-close" id="tbClose" title="Закрыть">✕</button>
</div>
<div class="themePanel" id="themePanel" style="display:none;">
<div class="tp-ttl">Тема</div>
<div class="tp-row">
<div class="th-c" data-t="pharaon" style="--c:#4d8dff" title="Фараон"></div>
<div class="th-c" data-t="emerald" style="--c:#38b8a8" title="Изумруд"></div>
<div class="th-c" data-t="ruby" style="--c:#4a5fd8" title="Кровь"></div>
<div class="th-c" data-t="ice" style="--c:#5aa7f0" title="Лёд"></div>
<div class="th-c" data-t="amethyst" style="--c:#8f6ff0" title="Аметист"></div>
<div class="th-c" data-t="midnight" style="--c:#6f86b8" title="Полночь"></div>
</div>
<div class="tp-name" id="tpName">Фараон</div>
<div class="tp-sep"></div>
<div class="tp-ttl">ОЗУ</div>
<div class="ram-row">
<div class="ram-b" data-v="2048">2</div>
<div class="ram-b on" data-v="4096">4</div>
<div class="ram-b" data-v="6144">6</div>
<div class="ram-b" data-v="8192">8</div>
</div>
<div class="tp-sep"></div>
<div style="text-align:center;"><a class="tp-out" onclick="logout()">Выйти</a></div>
</div>
<!-- ЗАГРУЗКА -->
<section id="boot" class="screen active">
<div style="text-align:center;">
<div class="emblem-wrap">
<div class="emblem-glow"></div>
<div class="emblem-svg">
<img class="logo-img" src="__LOGO_DATA_URI__" alt="Pharaon" width="90" height="90">
</div>
</div>
<div class="brandbig">PHARAON</div>
<div class="spin"></div>
<div id="bootStatus">Инициализация...</div>
<div id="bootErr">
<div class="err" id="bootErrMsg" style="max-width:400px; text-align:left;"></div>
<button class="btnlight" style="width:auto; padding:0 30px; margin-top:12px;" onclick="doInit()">Повторить</button>
</div>
</div>
</section>
<!-- АВТОРИЗАЦИЯ -->
<section id="auth" class="screen">
<div class="split">
<div class="split-right">
<div class="auth-logo">
<img class="logo-img" src="__LOGO_DATA_URI__" alt="Pharaon" width="40" height="40">
</div>
<div class="h1" id="authTitle">С возвращением</div>
<div class="sub" id="authSub">Войдите в аккаунт загрузчика.</div>
<div class="form">
<div class="field">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="8" r="4"/><path d="M4 21c1.5-4 5-6 8-6s6.5 2 8 6"/></svg>
<input id="authLogin" maxlength="16" placeholder="Логин" autocomplete="off">
</div>
<div class="field">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="4" y="10" width="16" height="11" rx="2"/><path d="M8 10V7a4 4 0 0 1 8 0v3"/></svg>
<input id="authPass" type="password" placeholder="Пароль" autocomplete="off">
<button class="eye" id="passEye" title="Показать пароль">☼</button>
</div>
<div class="field" id="pass2Field" style="display:none;">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="4" y="10" width="16" height="11" rx="2"/><path d="M8 10V7a4 4 0 0 1 8 0v3"/></svg>
<input id="authPass2" type="password" placeholder="Повтори пароль" autocomplete="off">
</div>
<button class="btnlight" id="authBtn" onclick="authSubmit()"><span id="authBtnText">Вход</span><span>➔</span></button>
<div class="err" id="authErr"></div>
<div class="switchline" id="switchLine">Нет аккаунта? <a id="switchLink" onclick="switchTab('reg')">Создать</a></div>
<div class="ver">LOADER v—</div>
</div>
</div>
</div>
</section>
<!-- ОЖИДАНИЕ КЛЮЧА -->
<section id="key" class="screen">
<div class="split">
<div class="split-right">
<div class="auth-logo">
<img class="logo-img" src="__LOGO_DATA_URI__" alt="Pharaon" width="40" height="40">
</div>
<div class="h1">Доступ к загрузчику</div>
<div class="sub">Ключ пока не выдан. Передай админу свой ник — он откроет доступ.</div>
<div class="waitbox">
<div class="spin" style="margin:0 auto;"></div>
<div class="nic" id="nickShow">—</div>
<div class="note">проверяю автоматически каждые 10 секунд</div>
</div>
<div class="form manual">
<div class="sub" style="margin:0 0 2px;">Или активируй ключ вручную</div>
<div class="field">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 2l-2 2m-7.6 7.6a5.5 5.5 0 1 1-7.8 7.8 5.5 5.5 0 0 1 7.8-7.8zm0 0L19 4m-4 4l2 2"/></svg>
<input id="keyInput" placeholder="PHAR-XXXX-XXXX-XXXX" maxlength="19" autocomplete="off" style="font-family:'JetBrains Mono',Consolas,monospace; letter-spacing:1px; text-transform:uppercase;">
</div>
<button class="btnlight" id="keyBtn" onclick="activate()">Активировать<span>➔</span></button>
<div class="err" id="keyErr"></div>
<div class="ver">LOADER v—</div>
</div>
</div>
</div>
</section>
<!-- ГЛАВНАЯ -->
<section id="main" class="screen">
<div class="main-head">
<div class="emblem-wrap" style="display:inline-flex;">
<div class="emblem-svg">
<img class="logo-img mini" src="__LOGO_DATA_URI__" alt="" width="30" height="30">
</div>
</div>
<div class="t">Выберите версию</div>
</div>
<div class="cards">
<div class="card sel" id="cardMain">
<div class="thumb img"></div>
<div class="card-row">
<span class="cname"><img class="c-ico" src="__LOGO_DATA_URI__" alt="" width="12" height="12"> Pharaon</span>
<span class="cdate"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="5" width="18" height="16" rx="2"/><path d="M3 10h18M8 3v4M16 3v4"/></svg> <span id="cardDate">—</span></span>
</div>
</div>
<div class="card locked" id="cardBeta">
<div class="thumb img" style="filter:grayscale(1) brightness(.5);"></div>
<div class="lockov">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="4" y="10" width="16" height="11" rx="2"/><path d="M8 10V7a4 4 0 0 1 8 0v3"/></svg>
Недоступно
</div>
<div class="card-row">
<span class="cname"><img class="c-ico" src="__LOGO_DATA_URI__" alt="" width="12" height="12"> Pharaon Beta</span>
<span class="cdate dis">Недоступно</span>
</div>
</div>
<div class="card locked">
<div class="thumb img" style="filter:grayscale(1) brightness(.5);"></div>
<div class="lockov">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="4" y="10" width="16" height="11" rx="2"/><path d="M8 10V7a4 4 0 0 1 8 0v3"/></svg>
Недоступно
</div>
<div class="card-row">
<span class="cname"><img class="c-ico" src="__LOGO_DATA_URI__" alt="" width="12" height="12"> Pharaon Dev.</span>
<span class="cdate dis">Недоступно</span>
</div>
</div>
</div>
<div class="announce" id="announce"></div>
<div class="progressWrap" id="progressWrap">
<div class="prog-top"><span id="stage">Подготовка...</span><span id="pct">0%</span></div>
<div class="bar"><div id="barFill"></div></div>
</div>
<div id="gameOk"></div>
<div id="mainErr"></div>
<div class="bottombar">
<div class="loading-side">
<div class="avatar">
<img class="avatar-ico" src="__LOGO_DATA_URI__" alt="" width="34" height="34">
</div>
<div class="uinfo">
<div class="unick" id="mLogin">—</div>
<div class="uinfo-sub">
<div class="uid" id="uidLine">UID: —</div>
<div class="pill" id="cardDatePill">—</div>
</div>
</div>
<div class="loading-bars">
<div class="line" id="subLine"></div>
</div>
</div>
<div class="btns">
<button class="bb-btn" id="tbTheme2" title="Настройки">⚙</button>
<button class="runbtn" id="playBtn" onclick="play()">Запустить <span>▶</span></button>
</div>
</div>
</section>
</div>
<script>
'use strict';
let reqId = 0; const pend = {};
let session = null; let timerInt = null; let pollTimer = null;
let ramMb = 4096; let myHwid = '';
const $ = id => document.getElementById(id);
function show(name){ document.querySelectorAll('.screen').forEach(s=>s.classList.remove('active')); $(name).classList.add('active'); }
function err(id, msg, on){ const e=$(id); e.innerHTML = msg||''; e.classList.toggle('show', !!on); }
function esc(s){ const d=document.createElement('div'); d.textContent = s==null?'':String(s); return d.innerHTML; }
function busy(btn, on, txt){ btn.disabled = on; if (txt) btn.innerHTML = txt; }
$('tbMin').addEventListener('click', ()=>window.chrome.webview.postMessage({type:'window', action:'min'}));
$('tbClose').addEventListener('click', ()=>window.chrome.webview.postMessage({type:'window', action:'close'}));
$('tbTheme').addEventListener('click', ()=>togglePanel());
$('tbTheme2').addEventListener('click', ()=>togglePanel());
function togglePanel(){
const p = $('themePanel');
if (p.style.display === 'none' || p.style.display === '') { p.style.display = 'block'; }
else { p.style.display = 'none'; }
}
document.addEventListener('mousedown', e => {
const p = $('themePanel');
if (p.style.display !== 'none' && !p.contains(e.target) && !e.target.closest('#tbTheme') && !e.target.closest('#tbTheme2')) p.style.display = 'none';
});
const THEME_NAMES = { pharaon:'Фараон', emerald:'Изумруд', ruby:'Кровь', ice:'Лёд', amethyst:'Аметист', midnight:'Полночь' };
function setTheme(t, save){
document.body.dataset.theme = t;
document.querySelectorAll('.th-c').forEach(c => c.classList.toggle('sel', c.dataset.t === t));
$('tpName').textContent = THEME_NAMES[t] || t;
if (save) window.chrome.webview.postMessage({type:'theme', theme:t});
}
document.querySelectorAll('.th-c').forEach(c => c.addEventListener('click', () => setTheme(c.dataset.t, true)));
document.querySelectorAll('.ram-b').forEach(b => b.addEventListener('click', () => {
document.querySelectorAll('.ram-b').forEach(x => x.classList.remove('on'));
b.classList.add('on');
ramMb = parseInt(b.dataset.v) || 4096;
}));
function stopWaiting(){ if (pollTimer){ clearInterval(pollTimer); pollTimer = null; } }
function startWaiting(nick){
$('nickShow').textContent = nick || '—';
show('key');
stopWaiting();
pollTimer = setInterval(async ()=>{
try {
const s = await call('poll');
if (s){ stopWaiting(); applySession(s); show('main'); }
} catch(e){}
}, 10000);
}
function call(type, data={}){
return new Promise((resolve, reject)=>{
const id = ++reqId;
pend[id] = {resolve, reject};
window.chrome.webview.postMessage({id, type, data});
});
}
window.chrome.webview.addEventListener('message', e=>{
const m = e.data;
if (m.event){ onEvent(m); return; }
const p = pend[m.id]; if (!p) return; delete pend[m.id];
m.ok ? p.resolve(m.data) : p.reject(new Error(m.error||'Ошибка'));
});
function onEvent(m){
switch (m.event){
case 'boot_status': $('bootStatus').textContent = m.text; break;
case 'boot_error':
$('bootErr').style.display='block';
err('bootErrMsg', esc(m.message), true);
$('boot').querySelector('.spin').style.display='none';
break;
case 'ready': {
$('bootErr').style.display='none';
$('boot').querySelector('.spin').style.display='';
myHwid = m.hwid || '';
document.querySelectorAll('.ver').forEach(v=>v.textContent = 'LOADER v' + m.version);
if (m.theme) setTheme(m.theme, false);
if (m.bg) $('bg').classList.add('hasimg');
if (m.announcement){ $('announce').style.display='block'; $('announce').textContent = m.announcement; }
if (m.ram){
ramMb = m.ram;
document.querySelectorAll('.ram-b').forEach(x => x.classList.toggle('on', +x.dataset.v === m.ram));
}
applySession(m.session);
if (m.session){ setSubBar(m.session); show('main'); }
else if (m.needKey && $('authLogin').value) startWaiting($('authLogin').value);
else show('auth');
break;
}
case 'session':
if (m.session){ stopWaiting(); applySession(m.session); setSubBar(m.session); show('main'); }
else { stopWaiting(); startWaiting($('authLogin').value || '—'); }
break;
case 'progress': {
if (m.pct != null){
$('progressWrap').style.display='block';
$('barFill').style.width = m.pct + '%';
$('pct').textContent = m.pct + '%';
$('stage').textContent = m.stage || '';
if (m.pct >= 100){ setTimeout(()=>{ $('progressWrap').style.display='none'; }, 1500); }
}
busy($('playBtn'), !(m.pct != null && m.pct < 100));
if (!$('playBtn').disabled) $('playBtn').innerHTML = 'Запустить <span>▶</span>';
break;
}
case 'game_started':
$('gameOk').style.display='block';
$('gameOk').textContent = 'Игра запущена (PID ' + m.pid + ')';
setTimeout(()=>{ $('gameOk').style.display='none'; }, 6000);
busy($('playBtn