<?php
/* ===== رمز پنل را عوض کن ===== */
const ADMIN_PASS = 'AMIRXVX';
/* ============================== */
const MIN_A = 1000;
const MAX_A = 100000000;

/* ---------- ذخیره‌سازی ---------- */
function dataDir() {
    static $d = null;
    if ($d) return $d;
    foreach ([dirname(__DIR__) . '/amirxvx_data', __DIR__ . '/amirxvx_data'] as $p) {
        if (!is_dir($p)) @mkdir($p, 0700, true);
        if (is_dir($p) && is_writable($p)) {
            if (strpos($p, __DIR__) === 0) {
                @file_put_contents($p . '/.htaccess', "<IfModule mod_authz_core.c>\nRequire all denied\n</IfModule>\n<IfModule !mod_authz_core.c>\nDeny from all\n</IfModule>\n");
                @file_put_contents($p . '/index.html', '');
            }
            return $d = $p;
        }
    }
    http_response_code(500);
    exit('پوشه ذخیره‌سازی قابل نوشتن نیست.');
}
function rd($n) { $f = dataDir() . "/$n.json"; if (!is_file($f)) return null; $j = json_decode((string)file_get_contents($f), true); return is_array($j) ? $j : null; }
function wr($n, $v) { file_put_contents(dataDir() . "/$n.json", json_encode($v, JSON_UNESCAPED_UNICODE), LOCK_EX); }
function del($n) { @unlink(dataDir() . "/$n.json"); }
function cfg() {
    static $c = null;
    if ($c !== null) return $c;
    $c = rd('cfg') ?: [];
    $ch = false;
    foreach (['link_secret', 'hook_secret'] as $k) if (empty($c[$k])) { $c[$k] = bin2hex(random_bytes(20)); $ch = true; }
    if ($ch) wr('cfg', $c);
    return $c;
}

/* ---------- ابزار ---------- */
function esc($s) { return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); }
function b64u($b) { return rtrim(strtr(base64_encode($b), '+/', '-_'), '='); }
function hm($m) { return b64u(hash_hmac('sha256', $m, cfg()['link_secret'], true)); }
function signA($a) { return substr(hm("pay:$a"), 0, 24); }
function digits($s) { return strtr((string)$s, ['۰'=>'0','۱'=>'1','۲'=>'2','۳'=>'3','۴'=>'4','۵'=>'5','۶'=>'6','۷'=>'7','۸'=>'8','۹'=>'9','٠'=>'0','١'=>'1','٢'=>'2','٣'=>'3','٤'=>'4','٥'=>'5','٦'=>'6','٧'=>'7','٨'=>'8','٩'=>'9']); }
function toEn($s) { return preg_replace('/\D/', '', digits($s)); }
function fa($n) { return strtr(number_format((float)$n), [','=>'٬','0'=>'۰','1'=>'۱','2'=>'۲','3'=>'۳','4'=>'۴','5'=>'۵','6'=>'۶','7'=>'۷','8'=>'۸','9'=>'۹']); }
function fmtCard($c) { return trim(chunk_split($c, 4, ' ')); }
function luhn($n) { $s = 0; for ($i = 0; $i < 16; $i++) { $d = (int)$n[15 - $i]; if ($i % 2) { $d *= 2; if ($d > 9) $d -= 9; } $s += $d; } return $s % 10 === 0; }
function bankOf($card) {
    static $B = ['603799'=>'ملی','589210'=>'سپه','627648'=>'توسعه صادرات','627961'=>'صنعت و معدن','603770'=>'کشاورزی','639217'=>'کشاورزی','628023'=>'مسکن','627760'=>'پست بانک','502908'=>'توسعه تعاون','627412'=>'اقتصاد نوین','622106'=>'پارسیان','639194'=>'پارسیان','502229'=>'پاسارگاد','639347'=>'پاسارگاد','627488'=>'کارآفرین','621986'=>'سامان','639346'=>'سینا','639607'=>'سرمایه','636214'=>'آینده','502806'=>'شهر','502938'=>'دی','603769'=>'صادرات','610433'=>'ملت','991975'=>'ملت','585983'=>'تجارت','627353'=>'تجارت','589463'=>'رفاه','627381'=>'انصار','639370'=>'مهر اقتصاد','606373'=>'قرض‌الحسنه مهر ایران','628157'=>'اعتباری توسعه','505416'=>'گردشگری','636949'=>'حکمت ایرانیان','505785'=>'ایران زمین','504172'=>'رسالت','507677'=>'نور'];
    return $B[substr($card, 0, 6)] ?? '—';
}
function isHttps() { return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || (($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '') === 'https'); }
function selfUrl() { return (isHttps() ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . strtok($_SERVER['SCRIPT_NAME'], '?'); }
function cardOk($c) { foreach (['brand', 'card', 'holder', 'tg'] as $f) if (empty($c[$f])) return false; return true; }
function linkFor($a) { return selfUrl() . '?p=' . $a . '.' . signA($a); }
function parseTg($t) { $u = preg_replace('~^https?://t\.me/~i', '', trim($t)); $u = ltrim($u, '@'); $u = preg_split('~[/?]~', $u)[0]; return preg_match('/^[A-Za-z][A-Za-z0-9_]{4,31}$/', $u) ? $u : null; }
function jout($o, $c = 200) { http_response_code($c); header('Content-Type: application/json; charset=UTF-8'); header('Cache-Control: no-store'); echo json_encode($o, JSON_UNESCAPED_UNICODE); exit; }
function jsd($o) { return json_encode($o, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_UNESCAPED_UNICODE); }
function pubState() {
    $c = cfg();
    return ['brand' => $c['brand'] ?? '', 'card' => $c['card'] ?? '', 'holder' => $c['holder'] ?? '', 'tg' => $c['tg'] ?? '',
        'hasToken' => !empty($c['token']), 'botUser' => $c['bot_user'] ?? '', 'admins' => array_values($c['admins'] ?? [])];
}

/* ---------- احراز هویت پنل ---------- */
function isAdmin() {
    if (!preg_match('/(?:^|; )adm=(\d+)\.([\w-]+)/', $_SERVER['HTTP_COOKIE'] ?? '', $m)) return false;
    return (int)$m[1] > time() && hash_equals(hm('adm:' . $m[1]), $m[2]);
}
function setAdm($val, $exp) { setcookie('adm', $val, ['expires' => $exp, 'path' => '/', 'secure' => isHttps(), 'httponly' => true, 'samesite' => 'Strict']); }

/* ---------- تلگرام ---------- */
function tg($method, $body = [], $token = null) {
    $token = $token ?: (cfg()['token'] ?? '');
    if (!$token) return ['ok' => false, 'description' => 'no token'];
    $ch = curl_init("https://api.telegram.org/bot$token/$method");
    curl_setopt_array($ch, [CURLOPT_POST => 1, CURLOPT_RETURNTRANSFER => 1, CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
        CURLOPT_POSTFIELDS => json_encode($body, JSON_UNESCAPED_UNICODE), CURLOPT_TIMEOUT => 15, CURLOPT_CONNECTTIMEOUT => 8]);
    $r = curl_exec($ch); $e = curl_error($ch); curl_close($ch);
    return $r ? (json_decode($r, true) ?: ['ok' => false, 'description' => 'bad response']) : ['ok' => false, 'description' => 'عدم اتصال هاست به تلگرام: ' . $e];
}
function send($chat, $text, $kb = null) {
    $b = ['chat_id' => $chat, 'text' => $text, 'parse_mode' => 'HTML', 'disable_web_page_preview' => true];
    if ($kb) $b['reply_markup'] = ['inline_keyboard' => $kb];
    return tg('sendMessage', $b);
}

/* ---------- ربات ---------- */
function isBotAdmin($id) { return in_array((int)$id, array_map('intval', cfg()['admins'] ?? []), true); }
function setState($id, $s) { if ($s) wr("s_$id", ['s' => $s, 't' => time()]); else del("s_$id"); }
function getState($id) { $x = rd("s_$id"); return ($x && time() - $x['t'] < 3600) ? $x['s'] : null; }
function menuKb() { return [[['text' => '🔗 ساخت لینک پرداخت', 'callback_data' => 'link']], [['text' => '💳 مشخصات کارت', 'callback_data' => 'card']]]; }
function showMenu($id, $chat) { setState($id, null); return send($chat, "👋 <b>ربات ساخت لینک پرداخت</b>\nیک گزینه را انتخاب کن 👇", menuKb()); }
function cardText() {
    $c = cfg();
    return "<b>مشخصات کارت</b>\n\n🏷 مجموعه: " . esc($c['brand'] ?? '—') . "\n💳 کارت: " . (!empty($c['card']) ? '<code>' . fmtCard($c['card']) . '</code>' : '—')
        . "\n🏦 بانک: " . esc(!empty($c['card']) ? bankOf($c['card']) : '—') . "\n👤 صاحب کارت: " . esc($c['holder'] ?? '—')
        . "\n📨 آیدی رسید: " . (!empty($c['tg']) ? '@' . $c['tg'] : '—') . "\n\nبرای تغییر، وارد پنل مدیریت شو:\n" . esc(selfUrl()) . '?admin';
}
function sendLink($chat, $a) {
    $url = linkFor($a);
    return send($chat, '✅ لینک پرداخت <b>' . fa($a) . " تومان</b>\n\n<code>" . esc($url) . '</code>',
        [[['text' => '🔗 باز کردن لینک', 'url' => $url]], [['text' => '➕ لینک جدید', 'callback_data' => 'link'], ['text' => '🏠 منو', 'callback_data' => 'menu']]]);
}
function askAmount($id, $chat) {
    if (!cardOk(cfg())) return send($chat, "⚠️ ابتدا مشخصات کارت را در پنل مدیریت کامل کن:\n" . esc(selfUrl()) . '?admin');
    setState($id, 'amount');
    return send($chat, "💰 مبلغ را به <b>تومان</b> بفرست (مثلاً 250000) یا یکی از دکمه‌ها را بزن:", [
        [['text' => '۵۰ هزار', 'callback_data' => 'amt:50000'], ['text' => '۱۰۰ هزار', 'callback_data' => 'amt:100000'], ['text' => '۲۰۰ هزار', 'callback_data' => 'amt:200000']],
        [['text' => '۵۰۰ هزار', 'callback_data' => 'amt:500000'], ['text' => '۱ میلیون', 'callback_data' => 'amt:1000000']],
        [['text' => '❌ انصراف', 'callback_data' => 'cancel']]]);
}
function onText($id, $chat, $text) {
    $t = trim($text);
    if ($t === '/id') return send($chat, 'آیدی عددی شما: <code>' . $id . '</code>');
    if (!isBotAdmin($id)) return send($chat, "⛔ شما دسترسی ندارید.\nآیدی عددی شما: <code>$id</code>\nاین عدد را به مدیر بدهید تا اضافه‌تان کند.");
    if (in_array($t, ['/start', '/menu', '/cancel'], true)) return showMenu($id, $chat);
    if (getState($id) === 'amount') {
        $d = toEn($t);
        $a = $d !== '' ? (int)substr($d, 0, 12) : 0;
        if ($a < MIN_A || $a > MAX_A) return send($chat, '❗ مبلغ باید بین ' . fa(MIN_A) . ' تا ' . fa(MAX_A) . ' تومان باشد.', [[['text' => '❌ انصراف', 'callback_data' => 'cancel']]]);
        setState($id, null);
        return sendLink($chat, $a);
    }
    return showMenu($id, $chat);
}
function onCallback($id, $chat, $d) {
    if (!isBotAdmin($id)) return;
    if ($d === 'menu' || $d === 'cancel') return showMenu($id, $chat);
    if ($d === 'link') return askAmount($id, $chat);
    if ($d === 'card') return send($chat, cardText(), [[['text' => '🏠 منو', 'callback_data' => 'menu']]]);
    if (strpos($d, 'amt:') === 0) {
        $a = (int)substr($d, 4);
        if ($a < MIN_A || $a > MAX_A) return;
        if (!cardOk(cfg())) return askAmount($id, $chat);
        setState($id, null);
        return sendLink($chat, $a);
    }
}
function handleUpdate($u) {
    if (isset($u['callback_query'])) {
        $q = $u['callback_query'];
        tg('answerCallbackQuery', ['callback_query_id' => $q['id']]);
        $chat = $q['message']['chat'] ?? null;
        if (!$chat || ($chat['type'] ?? '') !== 'private') return;
        return onCallback((int)$q['from']['id'], $chat['id'], $q['data'] ?? '');
    }
    $m = $u['message'] ?? null;
    if (!$m || ($m['chat']['type'] ?? '') !== 'private' || !isset($m['text'])) return;
    return onText((int)$m['from']['id'], $m['chat']['id'], $m['text']);
}

/* ---------- ظاهر مشترک ---------- */
const BASE_CSS = <<<'CSS'
:root{--bg:#000;--ink:#f3ecd9;--mute:#8d8570;--gold:#d4af37;--gold2:#f6e08f;--gold3:#7a5f14;--line:rgba(212,175,55,.18)}
*{box-sizing:border-box;margin:0}
body{font-family:Vazirmatn,Vazir,Tahoma,"Segoe UI",sans-serif;background:var(--bg);color:var(--ink);min-height:100vh;display:flex;justify-content:center;align-items:center;padding:34px 16px;overflow-x:hidden;
background-image:radial-gradient(520px 340px at 50% -10%,rgba(212,175,55,.22),transparent 70%),radial-gradient(400px 280px at 0% 110%,rgba(212,175,55,.08),transparent 70%),linear-gradient(rgba(212,175,55,.035) 1px,transparent 1px),linear-gradient(90deg,rgba(212,175,55,.035) 1px,transparent 1px);background-size:auto,auto,40px 40px,40px 40px}
.fx{position:fixed;inset:0;pointer-events:none;overflow:hidden;z-index:0}
.fx span{position:absolute;bottom:-50px;opacity:0;animation:rise linear infinite;filter:drop-shadow(0 0 8px rgba(212,175,55,.5))}
@keyframes rise{10%{opacity:.75}90%{opacity:.6}100%{transform:translateY(-110vh) rotate(360deg);opacity:0}}
.wrap{width:min(440px,100%);position:relative;z-index:1}
.brand{text-align:center;margin-bottom:18px;direction:ltr}
.brand b{display:block;font-size:clamp(20px,7vw,30px);font-weight:900;letter-spacing:.25em;padding-left:.25em;overflow-wrap:anywhere;background:linear-gradient(180deg,var(--gold2),var(--gold) 50%,var(--gold3));-webkit-background-clip:text;background-clip:text;color:transparent;filter:drop-shadow(0 0 18px rgba(212,175,55,.4))}
.brand i{display:block;width:80px;height:2px;margin:12px auto 0;background:linear-gradient(90deg,transparent,var(--gold),transparent)}
h1{text-align:center;font-size:22px;font-weight:800;display:flex;justify-content:center;align-items:center;gap:10px}
.em{display:inline-block}.e1{animation:bob 2.4s ease-in-out infinite}.e3{animation:beat 1.4s ease-in-out infinite}.e4{animation:twk 2s ease-in-out infinite}
@keyframes bob{50%{transform:translateY(-6px) rotate(-10deg)}}@keyframes beat{0%,100%{transform:scale(1)}30%{transform:scale(1.3)}60%{transform:scale(.95)}}
@keyframes twk{0%,100%{transform:scale(.8) rotate(0);opacity:.6}50%{transform:scale(1.25) rotate(25deg);opacity:1}}
.desc{text-align:center;color:var(--mute);line-height:2;font-size:14px;margin:8px auto 20px;max-width:36ch}
.panel{border:1px solid var(--line);border-radius:22px;padding:18px;background:linear-gradient(160deg,rgba(212,175,55,.09),rgba(255,255,255,.01) 55%),#070706;box-shadow:0 30px 80px rgba(0,0,0,.9),inset 0 1px 0 rgba(246,224,143,.2)}
.btn{display:flex;align-items:center;justify-content:center;gap:10px;width:100%;padding:15px;border-radius:14px;cursor:pointer;font:800 15.5px Vazirmatn,Vazir,Tahoma,sans-serif;text-decoration:none;transition:transform .15s,box-shadow .2s,background .2s}
.btn:active{transform:scale(.98)}.btn:disabled{opacity:.5;cursor:wait}
.gold{border:0;color:#110d02;background:linear-gradient(135deg,var(--gold2),var(--gold) 55%,var(--gold3));box-shadow:0 10px 30px rgba(212,175,55,.32)}
.gold:hover{transform:translateY(-2px)}.gold.done{background:linear-gradient(135deg,#7dffcf,#2ee59d)}
.ghost{margin-top:12px;color:var(--gold2);border:1px solid var(--gold);background:rgba(212,175,55,.08)}
.ghost:hover{background:rgba(212,175,55,.2);transform:translateY(-2px)}
.mini{flex:none;border:1px solid var(--gold);background:rgba(212,175,55,.1);color:var(--gold2);border-radius:10px;padding:9px 14px;font:700 13px Vazirmatn,Vazir,Tahoma,sans-serif;cursor:pointer;transition:.2s;text-decoration:none;text-align:center}
.mini:hover{background:rgba(212,175,55,.28)}.mini.done{background:var(--gold);color:#110d02}
.btn:focus-visible,.mini:focus-visible{outline:2px solid var(--gold2);outline-offset:3px}
.foot{text-align:center;margin-top:20px;font-size:12px;color:#5a5440;direction:ltr;letter-spacing:2px;overflow-wrap:anywhere}
.toast{position:fixed;bottom:26px;left:50%;transform:translate(-50%,24px);opacity:0;padding:11px 22px;border-radius:12px;background:var(--gold);color:#110d02;font-weight:800;font-size:14px;transition:.3s;pointer-events:none;z-index:9}
.toast.on{transform:translate(-50%,0);opacity:1}
@media(prefers-reduced-motion:reduce){*{animation:none!important}}
CSS;

const BASE_JS = <<<'JS'
var U=location.pathname;function $(i){return document.getElementById(i)}
var fx=$("fx"),L=["💎","👑","🔥","⚡","✨","💰","🌟","💫"];
for(var i=0;i<14;i++){var s=document.createElement("span");s.textContent=L[i%L.length];s.style.left=(Math.random()*96)+"%";s.style.fontSize=(14+Math.random()*18)+"px";s.style.animationDuration=(9+Math.random()*10)+"s";s.style.animationDelay=(-Math.random()*16)+"s";fx.appendChild(s)}
var toast=$("toast"),tt;
function fb(v){var a=document.createElement("textarea");a.value=v;a.style.cssText="position:fixed;opacity:0";document.body.appendChild(a);a.select();try{document.execCommand("copy")}catch(e){}document.body.removeChild(a)}
function doCopy(v,m){if(navigator.clipboard&&window.isSecureContext){navigator.clipboard.writeText(v).catch(function(){fb(v)})}else{fb(v)}toast.textContent=m;toast.classList.add("on");clearTimeout(tt);tt=setTimeout(function(){toast.classList.remove("on")},1800)}
function flash(b,t,o){b.classList.add("done");b.textContent=t;setTimeout(function(){b.classList.remove("done");b.textContent=o},1800)}
function fa(n){try{return Number(n).toLocaleString("fa-IR")}catch(e){return String(n)}}
JS;

function shell($title, $css, $body, $js) {
    return '<!DOCTYPE html><html lang="fa" dir="rtl"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="robots" content="noindex,nofollow"><title>'
        . $title . '</title><style>' . BASE_CSS . $css . '</style></head><body><div class="fx" id="fx" aria-hidden="true"></div>' . $body
        . '<div class="toast" id="toast">کپی شد ✓</div><script>' . BASE_JS . $js . '</script></body></html>';
}
function page($body, $code = 200, $priv = false) {
    http_response_code($code);
    header('Content-Type: text/html; charset=UTF-8');
    header('X-Content-Type-Options: nosniff');
    header('Referrer-Policy: no-referrer');
    header('X-Robots-Tag: noindex, nofollow');
    if ($priv) { header('Cache-Control: no-store'); header('X-Frame-Options: DENY'); }
    echo $body;
    exit;
}
function simple($icon, $msg) {
    return '<!DOCTYPE html><html lang="fa" dir="rtl"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="robots" content="noindex"><title>پرداخت</title></head><body style="background:#000;color:#f3ecd9;font-family:Tahoma,sans-serif;display:grid;place-items:center;min-height:100vh;margin:0;text-align:center;padding:20px"><div><div style="font-size:48px">' . $icon . '</div><p style="margin-top:12px;line-height:2">' . $msg . '</p></div></body></html>';
}

/* ---------- صفحه پرداخت ---------- */
const PAY_CSS = <<<'CSS'
.clock{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:18px;padding:12px 16px;border-radius:16px;border:1px solid var(--line);background:linear-gradient(160deg,rgba(212,175,55,.1),rgba(255,255,255,.01))}
.clock .d{font-size:13px;color:var(--mute);line-height:1.8}.clock .d b{display:block;color:var(--ink);font-size:14px}
.clock .t{direction:ltr;font-family:ui-monospace,Consolas,monospace;font-weight:800;font-size:24px;letter-spacing:.06em;font-variant-numeric:tabular-nums;background:linear-gradient(180deg,var(--gold2),var(--gold));-webkit-background-clip:text;background-clip:text;color:transparent}
.clock .t .c{animation:blink 1s steps(2,end) infinite}@keyframes blink{50%{opacity:.25}}
.lbl{display:flex;align-items:center;gap:6px;font-size:11.5px;color:var(--mute)}
.amt{margin-bottom:16px;padding:16px;border-radius:16px;border:1px solid rgba(212,175,55,.4);background:linear-gradient(135deg,rgba(212,175,55,.16),rgba(212,175,55,.03));display:flex;align-items:center;justify-content:space-between;gap:10px}
.amt small{display:block;font-size:12px;color:var(--mute)}
.amt b{display:block;margin:4px 0 2px;font-size:26px;font-weight:900;color:var(--gold2);font-variant-numeric:tabular-nums;filter:drop-shadow(0 0 10px rgba(212,175,55,.35))}
.scene{perspective:900px;margin-bottom:6px}
.bc{position:relative;aspect-ratio:1.586;border-radius:18px;padding:18px;cursor:pointer;direction:ltr;overflow:hidden;display:flex;flex-direction:column;justify-content:space-between;transform-style:preserve-3d;transition:transform .15s ease-out,box-shadow .3s;background:radial-gradient(circle at 15% 0%,#2e260f,#090806 62%);border:1px solid rgba(212,175,55,.5);box-shadow:0 24px 50px rgba(0,0,0,.9),0 0 34px rgba(212,175,55,.14)}
.bc::before{content:"";position:absolute;inset:0;background:linear-gradient(115deg,transparent 35%,rgba(246,224,143,.2) 48%,transparent 60%);transform:translateX(-120%);animation:shine 4.5s ease-in-out infinite}
.bc::after{content:attr(data-ini);position:absolute;right:-8px;bottom:-36px;font-size:150px;font-weight:900;color:rgba(212,175,55,.06);letter-spacing:-8px}
@keyframes shine{60%,100%{transform:translateX(120%)}}
.top{display:flex;justify-content:space-between;align-items:center;position:relative;z-index:1;gap:10px}
.chip{flex:none;width:42px;height:32px;border-radius:7px;background:linear-gradient(135deg,var(--gold2),var(--gold3));position:relative}
.chip::after{content:"";position:absolute;inset:6px 10px;border:1px solid rgba(0,0,0,.4);border-radius:3px}
.tag{font-weight:800;letter-spacing:3px;font-size:12px;color:var(--gold);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.num{position:relative;z-index:1;direction:ltr;white-space:nowrap;text-align:center;width:100%;font-family:ui-monospace,Consolas,monospace;font-weight:700;font-variant-numeric:tabular-nums;font-size:clamp(15px,4.9vw,24px);letter-spacing:.09em;line-height:1;background:linear-gradient(180deg,var(--gold2),var(--gold));-webkit-background-clip:text;background-clip:text;color:transparent;transform:translateZ(30px)}
.bot{position:relative;z-index:1;font-size:11.5px;color:var(--mute)}
.bot b{display:block;color:var(--ink);font-size:15px;direction:rtl;margin-top:2px;text-align:left}
.hint{text-align:center;font-size:12px;color:var(--mute);margin:10px 0 6px}
.info{margin:8px 0 14px}
.row{display:flex;justify-content:space-between;align-items:center;gap:10px;padding:12px 2px;border-top:1px solid var(--line);font-size:14px}
.row span{color:var(--mute)}.row b{font-weight:700}
.row .ltr{direction:ltr;font-family:ui-monospace,Consolas,monospace;letter-spacing:.06em;white-space:nowrap;color:var(--gold2)}
.ghost svg{width:22px;height:22px;fill:currentColor}
.ghost small{font:600 12px ui-monospace,Consolas,monospace;color:var(--mute);direction:ltr}
.note{margin-top:14px;text-align:center;font-size:12.5px;color:var(--mute);line-height:1.9}
@media(prefers-reduced-motion:reduce){.bc{transition:none}}

/* ===== خدمات ===== */
.svc{margin-top:18px}
.svc-brand{direction:ltr;text-align:center;font-family:Orbitron,Montserrat,sans-serif;font-weight:900;font-size:clamp(20px,7vw,28px);letter-spacing:.28em;padding-left:.28em;background:linear-gradient(180deg,var(--gold2),var(--gold) 55%,var(--gold3));-webkit-background-clip:text;background-clip:text;color:transparent;filter:drop-shadow(0 0 14px rgba(212,175,55,.4))}
.svc-sub{text-align:center;color:var(--mute);font-size:13px;margin:6px 0 14px}
.sv{position:relative;overflow:hidden;display:flex;align-items:center;gap:12px;padding:13px 14px;margin-bottom:8px;border:1px solid var(--line);border-radius:14px;background:rgba(212,175,55,.05);animation:svin .45s cubic-bezier(.2,.9,.3,1.2) both;transition:border-color .2s,background .2s,transform .2s}
.sv::after{content:"";position:absolute;inset:0;background:linear-gradient(110deg,transparent 35%,rgba(246,224,143,.14) 50%,transparent 65%);transform:translateX(-130%);animation:svsh 5s ease-in-out infinite;pointer-events:none}
.sv:hover{border-color:var(--gold);background:rgba(212,175,55,.12);transform:translateX(-3px)}
.sv .i{display:inline-block;width:36px;height:36px;line-height:36px;text-align:center;font-size:22px;flex:none;border-radius:10px;background:rgba(212,175,55,.1);border:1px solid var(--line)}
.sv .i span{display:inline-block}
.sv b{font-size:14.5px;font-weight:700}
.sv .tick{margin-right:auto;color:var(--gold);font-size:13px;opacity:.7}
@keyframes svin{from{opacity:0;transform:translateY(14px) scale(.96)}}
@keyframes svsh{55%,100%{transform:translateX(130%)}}
/* انیمیشن اختصاصی هر ایموجی */
.a1 span{animation:svBob 2.2s ease-in-out infinite}
.a2 span{animation:svWig 1.6s ease-in-out infinite;transform-origin:30% 70%}
.a3 span{animation:svFly 2s ease-in-out infinite}
.a4 span{animation:svGem 2.4s ease-in-out infinite}
.a5 span{animation:svPop 1.8s ease-in-out infinite;transform-origin:50% 90%}
.a6 span{animation:svBlink 3s ease-in-out infinite}
.a7 span{animation:svBar 1.8s ease-in-out infinite}
@keyframes svBob{0%,100%{transform:translateY(0)}50%{transform:translateY(-5px) scale(1.08)}}
@keyframes svWig{0%,100%{transform:rotate(0)}20%{transform:rotate(-16deg) scale(1.1)}40%{transform:rotate(12deg) scale(1.1)}60%{transform:rotate(-8deg)}80%{transform:rotate(4deg)}}
@keyframes svFly{0%,100%{transform:translate(0,0) rotate(0)}50%{transform:translate(4px,-7px) rotate(-8deg) scale(1.1)}}
@keyframes svGem{0%,100%{transform:scale(1) rotate(0);filter:drop-shadow(0 0 0 rgba(120,220,255,0))}50%{transform:scale(1.25) rotate(14deg);filter:drop-shadow(0 0 8px rgba(120,220,255,.9))}}
@keyframes svPop{0%,60%,100%{transform:scale(1) rotate(0)}70%{transform:scale(1.35) rotate(-14deg)}85%{transform:scale(.95) rotate(4deg)}}
@keyframes svBlink{0%,42%,48%,100%{transform:scaleY(1)}45%{transform:scaleY(.1)}}
@keyframes svBar{0%,100%{transform:scaleY(1)}50%{transform:scaleY(1.25) translateY(-2px)}}
.pg{display:flex;align-items:center;justify-content:center;gap:10px;margin:14px 0 4px}
.pg .mini{padding:8px 14px}.pg .mini:disabled{opacity:.35;cursor:default}
.pg .dots{display:flex;gap:6px}.pg .dots i{width:8px;height:8px;border-radius:50%;background:var(--line);transition:.25s}.pg .dots i.on{background:var(--gold);box-shadow:0 0 8px var(--gold);transform:scale(1.3)}
.pg .num{color:var(--mute);font-size:12px;min-width:48px;text-align:center}
.pulse{animation:pls 1.2s ease 2}@keyframes pls{50%{box-shadow:0 0 0 3px var(--gold),0 0 40px rgba(212,175,55,.5)}}
CSS;

const PAY_JS = <<<'JS'
$("amtShow").textContent=fa(D.amount)+" تومان";
$("amtRial").textContent="معادل "+fa(D.amount*10)+" ریال";
$("receipt").href="https://t.me/"+D.tg+"?text="+encodeURIComponent("سلام، رسید پرداخت مبلغ "+fa(D.amount)+" تومان");
var aB=$("amtCopy");aB.addEventListener("click",function(){doCopy(String(D.amount),"مبلغ کپی شد ✓");flash(aB,"کپی شد ✓","کپی مبلغ")});
var cB=$("copyBtn"),cT=$("copyTxt"),bc=$("bc"),ct;
function cc(){doCopy(D.card,"شماره کارت کپی شد ✓");cB.classList.add("done");cT.textContent="کپی شد ✓";clearTimeout(ct);ct=setTimeout(function(){cB.classList.remove("done");cT.textContent="کپی شماره کارت"},1800)}
cB.addEventListener("click",cc);bc.addEventListener("click",cc);
bc.addEventListener("keydown",function(e){if(e.key==="Enter"||e.key===" "){e.preventDefault();cc()}});
if(!matchMedia("(prefers-reduced-motion:reduce)").matches){
bc.addEventListener("pointermove",function(e){var r=bc.getBoundingClientRect(),x=(e.clientX-r.left)/r.width-.5,y=(e.clientY-r.top)/r.height-.5;bc.style.transform="rotateY("+x*16+"deg) rotateX("+(-y*16)+"deg)"});
bc.addEventListener("pointerleave",function(){bc.style.transform=""})}
var dE=$("date"),tE=$("time"),TZ="Asia/Tehran";
try{var fD=new Intl.DateTimeFormat("fa-IR-u-ca-persian",{timeZone:TZ,weekday:"long",day:"numeric",month:"long",year:"numeric"});
var fT=new Intl.DateTimeFormat("fa-IR",{timeZone:TZ,hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:false});
var tick=function(){var n=new Date();dE.textContent=fD.format(n);tE.innerHTML=fT.format(n).replace(/:/g,'<span class="c">:</span>')};tick();setInterval(tick,1000)}
catch(e){var t2=function(){var d=new Date(new Date().toLocaleString("en-US",{timeZone:TZ}));var z=function(n){return(n<10?"0":"")+n};tE.textContent=z(d.getHours())+":"+z(d.getMinutes())+":"+z(d.getSeconds());dE.textContent=d.toLocaleDateString("fa-IR")};t2();setInterval(t2,1000)}

/* ===== خدمات: [ایموجی، نام، شماره انیمیشن 1 تا 7] ===== */
var SV=[["👥","ممبر گروه تلگرام",1],["📢","ممبر کانال تلگرام",2],["🚀","بوست تلگرام",3],["💎","ریاکشن پریمیوم تلگرام",4],["👍","ریاکشن ساده تلگرام",5],["👁","ویو تلگرام",6],["📊","نظرسنجی تلگرام",7]];
var PS=4,pg=0,PN=Math.ceil(SV.length/PS),sl=$("svList"),dots=$("pgDots");
for(var k=0;k<PN;k++){dots.appendChild(document.createElement("i"))}
function renderSv(){sl.innerHTML="";SV.slice(pg*PS,pg*PS+PS).forEach(function(s,n){var d=document.createElement("div");d.className="sv";d.style.animationDelay=(n*0.08)+"s";
var i=document.createElement("div");i.className="i a"+s[2];var e=document.createElement("span");e.textContent=s[0];i.appendChild(e);
var b=document.createElement("b");b.textContent=s[1];var t=document.createElement("span");t.className="tick";t.textContent="✓";
d.appendChild(i);d.appendChild(b);d.appendChild(t);sl.appendChild(d)});
$("pgPrev").disabled=pg===0;$("pgNext").disabled=pg===PN-1;$("pgNum").textContent=fa(pg+1)+" / "+fa(PN);
Array.prototype.forEach.call(dots.children,function(x,n){x.className=n===pg?"on":""})}
$("pgPrev").addEventListener("click",function(){if(pg>0){pg--;renderSv()}});
$("pgNext").addEventListener("click",function(){if(pg<PN-1){pg++;renderSv()}});
$("payGo").addEventListener("click",function(){var p=$("payBox");p.scrollIntoView({behavior:"smooth",block:"center"});p.classList.remove("pulse");void p.offsetWidth;p.classList.add("pulse")});
renderSv();
JS;

function payPage($c, $amount) {
    $brand = esc($c['brand']); $holder = esc($c['holder']); $card = fmtCard($c['card']);
    $ini = esc(mb_strtoupper(mb_substr($c['brand'], 0, 2)));
    $body = '<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@700;900&display=swap"><main class="wrap"><div class="brand"><b>' . $brand . '</b><i></i></div>'
    . '<div class="clock"><div class="d"><div class="lbl"><span class="em e1">🕒</span> به وقت ایران</div><b id="date">...</b></div><div class="t" id="time">--:--:--</div></div>'
    . '<h1><span class="em e1">💳</span> پرداخت <span class="em e4">✨</span></h1>'
    . '<p class="desc">مبلغ زیر را به کارت واریز کنید و رسید را برای ادمین ارسال کنید.</p><section class="panel" id="payBox">'
    . '<div class="amt"><div><small>💰 مبلغ قابل پرداخت</small><b id="amtShow">—</b><small id="amtRial"></small></div><button class="mini" id="amtCopy" type="button">کپی مبلغ</button></div>'
    . '<div class="scene"><div class="bc" id="bc" data-ini="' . $ini . '" role="button" tabindex="0" aria-label="کپی شماره کارت"><div class="top"><div class="chip"></div><div class="tag">' . $brand . '</div></div>'
    . '<div class="num">' . $card . '</div><div class="bot">Card Holder<b>' . $holder . '</b></div></div></div><div class="hint">برای کپی، روی کارت بزنید</div>'
    . '<div class="info"><div class="row"><span>🏦 بانک</span><b>' . esc(bankOf($c['card'])) . '</b></div><div class="row"><span>👤 به نام</span><b>' . $holder . '</b></div>'
    . '<div class="row"><span>💳 شماره کارت</span><b class="ltr">' . $card . '</b></div></div>'
    . '<button class="btn gold" id="copyBtn" type="button"><span class="em e1">📋</span> <span id="copyTxt">کپی شماره کارت</span></button>'
    . '<a class="btn ghost" id="receipt" href="#" target="_blank" rel="noopener"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9.8 15.3l-.4 4.2c.6 0 .8-.3 1.2-.6l2.8-2.6 5.8 4.2c1.1.6 1.8.3 2.1-1l3.8-17.7c.4-1.6-.6-2.2-1.6-1.8L1.6 10.5c-1.5.6-1.5 1.5-.3 1.9l5.7 1.8L20.3 5.8c.6-.4 1.2-.2.7.2z"/></svg> ارسال رسید <small>@' . esc($c['tg']) . '</small></a>'
    . '<div class="note"><span class="em e3">🔒</span> قبل از واریز، نام صاحب کارت را بررسی کنید.</div>'
    . '</section>'
    . '<section class="panel svc"><div class="svc-brand">AMIRXVX</div><div class="svc-sub">خدمات ما</div>'
    . '<div id="svList"></div><div class="pg"><button class="mini" id="pgPrev" type="button">‹ قبلی</button><div class="dots" id="pgDots"></div><span class="num" id="pgNum"></span><button class="mini" id="pgNext" type="button">بعدی ›</button></div>'
    . '<button class="btn gold" id="payGo" type="button" style="margin-top:12px"><span class="em e1">💳</span> پرداخت</button></section>'
    . '<div class="foot">© ' . $brand . '</div></main>';
    return shell($brand . ' | پرداخت', PAY_CSS, $body, 'var D=' . jsd(['amount' => $amount, 'card' => $c['card'], 'tg' => $c['tg']]) . ';' . PAY_JS);
}

/* ---------- ورود و پنل ---------- */
const FIELD_CSS = <<<'CSS'
.f{width:100%;background:rgba(0,0,0,.5);border:1px solid var(--line);border-radius:12px;padding:13px;color:var(--gold2);font:600 15px ui-monospace,Consolas,monospace;direction:ltr;text-align:left;outline:0;margin-bottom:10px}
.f:focus{border-color:var(--gold);box-shadow:0 0 0 3px rgba(212,175,55,.15)}.f::placeholder{color:#4d4838}
.rtl{direction:rtl;text-align:right;font-family:Vazirmatn,Vazir,Tahoma,sans-serif}
.lb{display:block;font-size:12.5px;color:var(--mute);margin:4px 0 6px}
.err{color:#ff7b7b;text-align:center;font-size:13px;min-height:22px;margin:4px 0 8px}.okm{color:#2ee59d}
CSS;

function loginPage() {
    return shell('ورود | AMIRXVX', FIELD_CSS, '<main class="wrap"><div class="brand"><b>AMIRXVX</b><i></i></div><h1><span class="em e3">🔐</span> پنل مدیریت</h1><p class="desc">برای ورود رمز عبور را وارد کنید.</p>'
    . '<section class="panel"><input class="f" id="pw" type="password" style="text-align:center" placeholder="رمز عبور" autocomplete="current-password"><div class="err" id="err"></div><button class="btn gold" id="go" type="button">ورود</button></section></main>',
    'var pw=$("pw"),err=$("err"),go=$("go");
function login(){err.textContent="";go.disabled=true;
fetch(U+"?login",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({password:pw.value})})
.then(function(r){if(r.ok){location.reload()}else{err.textContent=r.status===429?"تلاش زیاد. کمی بعد دوباره امتحان کنید.":"رمز عبور اشتباه است";go.disabled=false;pw.select()}})
.catch(function(){err.textContent="خطا در ارتباط";go.disabled=false})}
go.addEventListener("click",login);pw.addEventListener("keydown",function(e){if(e.key==="Enter")login()});pw.focus();');
}

const ADMIN_CSS = <<<'CSS'
.tabs{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;margin:18px 0 14px}
.tabs button{border:1px solid var(--line);background:rgba(212,175,55,.04);color:var(--mute);border-radius:12px;padding:10px 4px;font:700 13px Vazirmatn,Vazir,Tahoma,sans-serif;cursor:pointer;transition:.2s}
.tabs button.on{color:#110d02;background:linear-gradient(135deg,var(--gold2),var(--gold));border-color:var(--gold)}
.tab{display:none}.tab.on{display:block}
.field{display:flex;align-items:center;gap:8px;border:1px solid var(--line);border-radius:12px;padding:0 12px;background:rgba(0,0,0,.5)}
.field:focus-within{border-color:var(--gold);box-shadow:0 0 0 3px rgba(212,175,55,.15)}
.field input{flex:1;min-width:0;background:none;border:0;outline:0;color:var(--gold2);padding:13px 0;direction:ltr;text-align:left;font:700 20px ui-monospace,Consolas,monospace}
.field input::placeholder{color:#4d4838}.field span{color:var(--mute);font-size:13px}
.chips{display:flex;flex-wrap:wrap;gap:6px;margin:10px 0 14px}
.chips button{flex:1 1 auto;border:1px solid var(--line);background:rgba(212,175,55,.06);color:var(--gold2);border-radius:10px;padding:8px 6px;font:600 12px Vazirmatn,Vazir,Tahoma,sans-serif;cursor:pointer}
.chips button:hover{background:rgba(212,175,55,.22);border-color:var(--gold)}
.sum{margin-bottom:14px;text-align:center;font-size:20px;font-weight:900;color:var(--gold2);min-height:30px}
.res{margin-top:16px;padding:14px;border-radius:14px;border:1px solid rgba(212,175,55,.4);background:rgba(212,175,55,.06);display:none}
.res .u{direction:ltr;text-align:left;word-break:break-all;font:600 12.5px ui-monospace,Consolas,monospace;color:var(--gold2);margin-bottom:10px}
.res .a{display:flex;gap:8px}.res .a>*{flex:1}
.hist{margin-top:16px;border-top:1px solid var(--line);padding-top:10px;display:none}
.hist h2{font-size:13px;color:var(--mute);font-weight:600;margin-bottom:6px}
.h{display:flex;justify-content:space-between;align-items:center;gap:8px;padding:8px 0;font-size:13px;border-bottom:1px solid rgba(212,175,55,.08)}
.st{padding:12px;border-radius:12px;border:1px solid var(--line);font-size:13.5px;margin-bottom:12px;line-height:1.9}
.help{font-size:12px;color:var(--mute);line-height:1.9;margin:2px 0 10px}
.out{display:block;width:100%;margin-top:16px;background:none;border:0;color:var(--mute);font:600 12.5px Vazirmatn,Vazir,Tahoma,sans-serif;cursor:pointer}
.out:hover{color:#ff7b7b}.danger{margin-top:10px;color:#ff9a9a;border:1px solid rgba(255,123,123,.5);background:rgba(255,123,123,.06);padding:12px}
CSS;

const ADMIN_JS = <<<'JS'
var NL=String.fromCharCode(10);
function api(a,d){d=d||{};d.action=a;return fetch(U+"?api",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(d)}).then(function(r){if(r.status===401){location.reload();return new Promise(function(){})}return r.json().then(function(j){j.__ok=r.ok;return j})}).catch(function(){return{__ok:false,error:"خطا در ارتباط"}})}
function toEn(s){var o="";for(var i=0;i<s.length;i++){var c=s.charCodeAt(i);if(c>=1776&&c<=1785)o+=String(c-1776);else if(c>=1632&&c<=1641)o+=String(c-1632);else if(c>=48&&c<=57)o+=s.charAt(i)}return o}
function en(n){var s=String(n),o="",c=0;for(var i=s.length-1;i>=0;i--){o=s.charAt(i)+o;c++;if(c%3===0&&i>0)o=","+o}return o}
function msg(id,t,ok){var e=$(id);e.textContent=t;e.className="err"+(ok?" okm":"")}
var tabs=document.querySelectorAll("#tabs button");
tabs.forEach(function(b){b.addEventListener("click",function(){tabs.forEach(function(x){x.classList.remove("on")});b.classList.add("on");
document.querySelectorAll(".tab").forEach(function(t){t.classList.remove("on")});$(b.getAttribute("data-t")).classList.add("on")})});
var amount=0,lastUrl="",inp=$("amt");
function upd(){$("sum").textContent=amount>0?fa(amount)+" تومان":"—"}
inp.addEventListener("input",function(){var d=toEn(inp.value).slice(0,9);amount=d?parseInt(d,10):0;inp.value=amount>0?en(amount):"";upd()});
$("chips").addEventListener("click",function(e){var b=e.target.closest("button");if(!b)return;amount=parseInt(b.getAttribute("data-v"),10);inp.value=en(amount);upd()});
$("mk").addEventListener("click",function(){msg("e1","");if(!amount){msg("e1","مبلغ را وارد کنید");return}
if(!(S.brand&&S.card&&S.holder&&S.tg)){msg("e1","ابتدا مشخصات کارت را در تب «کارت» کامل کن");return}
var mk=$("mk");mk.disabled=true;
api("link",{amount:amount}).then(function(j){mk.disabled=false;if(!j.__ok){msg("e1",j.error||"خطا");return}
lastUrl=j.url;$("url").textContent=lastUrl;$("op").href=lastUrl;$("res").style.display="block";
var d=document.createElement("div");d.className="h";var sp=document.createElement("span");sp.textContent=fa(j.amount)+" تومان";
var bt=document.createElement("button");bt.className="mini";bt.textContent="کپی";bt.setAttribute("data-u",lastUrl);d.appendChild(sp);d.appendChild(bt);
$("hl").insertBefore(d,$("hl").firstChild);$("hist").style.display="block"})});
$("cp").addEventListener("click",function(){doCopy(lastUrl,"لینک کپی شد ✓");flash($("cp"),"کپی شد ✓","کپی لینک")});
$("hl").addEventListener("click",function(e){var b=e.target.closest("button");if(!b)return;doCopy(b.getAttribute("data-u"),"لینک کپی شد ✓")});
function renderBot(){$("botSt").textContent=S.hasToken?("✅ ربات متصل است: @"+S.botUser+" | ادمین‌ها: "+S.admins.length):"❌ ربات هنوز متصل نیست";
$("tok").placeholder=S.hasToken?"برای حفظ توکن فعلی خالی بگذار":"123456789:AAxxxxxxxx";
$("adm").value=S.admins.join(NL);$("rmBot").style.display=S.hasToken?"flex":"none"}
renderBot();
$("saveBot").addEventListener("click",function(){msg("e2","");var b=$("saveBot");b.disabled=true;
api("bot",{token:$("tok").value,admins:$("adm").value}).then(function(j){b.disabled=false;
if(!j.__ok){msg("e2",j.error||"خطا");return}S=j.state;$("tok").value="";renderBot();msg("e2","✅ ذخیره شد و ربات متصل است",true)})});
$("rmBot").addEventListener("click",function(){if(!confirm("ربات قطع و توکن حذف شود؟"))return;
api("botRemove").then(function(j){if(!j.__ok){msg("e2",j.error||"خطا");return}S=j.state;renderBot();msg("e2","ربات قطع شد",true)})});
$("brand").value=S.brand;$("card").value=S.card;$("holder").value=S.holder;$("tgid").value=S.tg?"@"+S.tg:"";
$("saveCard").addEventListener("click",function(){msg("e3","");var b=$("saveCard");b.disabled=true;
api("card",{brand:$("brand").value,card:$("card").value,holder:$("holder").value,tg:$("tgid").value}).then(function(j){b.disabled=false;
if(!j.__ok){msg("e3",j.error||"خطا");return}S=j.state;$("card").value=S.card;$("tgid").value="@"+S.tg;msg("e3","✅ ذخیره شد",true)})});
$("out").addEventListener("click",function(){fetch(U+"?logout",{method:"POST"}).then(function(){location.href=U+"?admin"})});
JS;

function adminPage() {
    $st = pubState();
    $body = '<main class="wrap"><div class="brand"><b>' . esc($st['brand'] ?: 'AMIRXVX') . '</b><i></i></div><h1><span class="em e3">⚙️</span> پنل مدیریت</h1>'
    . '<div class="tabs" id="tabs"><button data-t="t1" class="on">🔗 لینک</button><button data-t="t2">🤖 ربات</button><button data-t="t3">💳 کارت</button></div><section class="panel">'
    . '<div class="tab on" id="t1"><span class="lb">💰 مبلغ (تومان)</span><div class="field"><input id="amt" type="text" inputmode="numeric" autocomplete="off" placeholder="مثلاً 250,000" maxlength="13"><span>تومان</span></div>'
    . '<div class="chips" id="chips"><button data-v="50000">۵۰ هزار</button><button data-v="100000">۱۰۰ هزار</button><button data-v="200000">۲۰۰ هزار</button><button data-v="500000">۵۰۰ هزار</button><button data-v="1000000">۱ میلیون</button></div>'
    . '<div class="sum" id="sum">—</div><button class="btn gold" id="mk" type="button"><span class="em e1">🔗</span> ساخت لینک</button><div class="err" id="e1"></div>'
    . '<div class="res" id="res"><div class="u" id="url"></div><div class="a"><button class="mini" id="cp" type="button">کپی لینک</button><a class="mini" id="op" href="#" target="_blank" rel="noopener">باز کردن</a></div></div>'
    . '<div class="hist" id="hist"><h2>لینک‌های ساخته‌شده در این نشست</h2><div id="hl"></div></div></div>'
    . '<div class="tab" id="t2"><div class="st" id="botSt"></div><span class="lb">🔑 توکن ربات (از @BotFather)</span><input class="f" id="tok" type="text" autocomplete="off" placeholder="123456789:AAxxxxxxxx">'
    . '<span class="lb">👥 آیدی عددی ادمین‌ها (هر کدام در یک خط)</span><textarea class="f" id="adm" rows="3" placeholder="123456789"></textarea>'
    . '<div class="help">فقط این افراد می‌توانند از ربات لینک بسازند. آیدی عددی خودت را نمی‌دانی؟ ابتدا توکن را ذخیره کن، بعد در ربات <b>/id</b> بزن و عدد را اینجا بگذار.</div>'
    . '<button class="btn gold" id="saveBot" type="button">ذخیره و اتصال ربات</button><button class="btn danger" id="rmBot" type="button">قطع و حذف ربات</button><div class="err" id="e2"></div></div>'
    . '<div class="tab" id="t3"><span class="lb">🏷 نام مجموعه</span><input class="f rtl" id="brand" maxlength="24" placeholder="AMIRXVX"><span class="lb">💳 شماره کارت (۱۶ رقم)</span><input class="f" id="card" inputmode="numeric" maxlength="24" placeholder="6219 8618 5048 7991">'
    . '<span class="lb">👤 نام صاحب کارت</span><input class="f rtl" id="holder" maxlength="40" placeholder="ایمانی"><span class="lb">📨 آیدی تلگرام برای رسید</span><input class="f" id="tgid" maxlength="40" placeholder="@PV_AMIRXVX">'
    . '<button class="btn gold" id="saveCard" type="button">ذخیره مشخصات</button><div class="err" id="e3"></div></div>'
    . '<button class="out" id="out" type="button">خروج از پنل</button></section><div class="foot">© AMIRXVX</div></main>';
    return shell('پنل | AMIRXVX', FIELD_CSS . ADMIN_CSS, $body, 'var S=' . jsd($st) . ';' . ADMIN_JS);
}

/* ---------- API پنل ---------- */
function adminApi($b) {
    $a = $b['action'] ?? '';
    $c = cfg();
    if ($a === 'link') {
        $amount = (int)($b['amount'] ?? 0);
        if ($amount < MIN_A || $amount > MAX_A) jout(['error' => 'مبلغ باید بین ' . fa(MIN_A) . ' تا ' . fa(MAX_A) . ' تومان باشد'], 400);
        if (!cardOk($c)) jout(['error' => 'ابتدا مشخصات کارت را کامل کن'], 400);
        jout(['url' => linkFor($amount), 'amount' => $amount]);
    }
    if ($a === 'card') {
        $brand = trim((string)($b['brand'] ?? '')); $holder = trim((string)($b['holder'] ?? ''));
        $card = toEn($b['card'] ?? ''); $tgid = parseTg($b['tg'] ?? '');
        if (mb_strlen($brand) < 2 || mb_strlen($brand) > 24) jout(['error' => 'نام مجموعه باید ۲ تا ۲۴ حرف باشد'], 400);
        if (strlen($card) !== 16 || !luhn($card)) jout(['error' => 'شماره کارت معتبر نیست'], 400);
        if (mb_strlen($holder) < 2 || mb_strlen($holder) > 40) jout(['error' => 'نام صاحب کارت باید ۲ تا ۴۰ حرف باشد'], 400);
        if (!$tgid) jout(['error' => 'آیدی تلگرام معتبر نیست (مثلاً @PV_AMIRXVX)'], 400);
        $c = array_merge($c, ['brand' => $brand, 'holder' => $holder, 'card' => $card, 'tg' => $tgid]);
        wr('cfg', $c);
        $GLOBALS['__cfg'] = null;
        jout(['state' => ['brand' => $brand, 'card' => $card, 'holder' => $holder, 'tg' => $tgid, 'hasToken' => !empty($c['token']), 'botUser' => $c['bot_user'] ?? '', 'admins' => array_values($c['admins'] ?? [])]]);
    }
    if ($a === 'bot') {
        $token = trim((string)($b['token'] ?? '')) ?: ($c['token'] ?? '');
        $ids = array_values(array_unique(array_filter(preg_split('/\D+/', digits($b['admins'] ?? '')), function ($x) { return strlen($x) >= 5 && strlen($x) <= 15; })));
        if (!$token) jout(['error' => 'توکن ربات را وارد کن'], 400);
        if (!preg_match('/^\d{6,12}:[A-Za-z0-9_-]{30,50}$/', $token)) jout(['error' => 'فرمت توکن درست نیست'], 400);
        $me = tg('getMe', [], $token);
        if (empty($me['ok'])) jout(['error' => 'توکن نامعتبر است یا هاست به تلگرام وصل نیست: ' . ($me['description'] ?? '')], 400);
        $wh = tg('setWebhook', ['url' => selfUrl(), 'secret_token' => $c['hook_secret'], 'allowed_updates' => ['message', 'callback_query'], 'drop_pending_updates' => true], $token);
        if (empty($wh['ok'])) jout(['error' => 'اتصال وبهوک ناموفق: ' . ($wh['description'] ?? '')], 400);
        $c['token'] = $token; $c['bot_user'] = $me['result']['username'] ?? ''; $c['admins'] = $ids;
        wr('cfg', $c);
        jout(['state' => ['brand' => $c['brand'] ?? '', 'card' => $c['card'] ?? '', 'holder' => $c['holder'] ?? '', 'tg' => $c['tg'] ?? '', 'hasToken' => true, 'botUser' => $c['bot_user'], 'admins' => $ids]]);
    }
    if ($a === 'botRemove') {
        if (!empty($c['token'])) tg('deleteWebhook', ['drop_pending_updates' => true], $c['token']);
        unset($c['token'], $c['bot_user']);
        wr('cfg', $c);
        jout(['state' => ['brand' => $c['brand'] ?? '', 'card' => $c['card'] ?? '', 'holder' => $c['holder'] ?? '', 'tg' => $c['tg'] ?? '', 'hasToken' => false, 'botUser' => '', 'admins' => array_values($c['admins'] ?? [])]]);
    }
    jout(['error' => 'bad action'], 400);
}

/* ---------- مسیریابی ---------- */
$method = $_SERVER['REQUEST_METHOD'];
cfg();

// وبهوک تلگرام
if ($method === 'POST' && isset($_SERVER['HTTP_X_TELEGRAM_BOT_API_SECRET_TOKEN'])) {
    if (!hash_equals(cfg()['hook_secret'], $_SERVER['HTTP_X_TELEGRAM_BOT_API_SECRET_TOKEN'])) { http_response_code(403); exit('forbidden'); }
    $upd = json_decode((string)file_get_contents('php://input'), true);
    http_response_code(200);
    header('Content-Type: text/plain');
    echo 'ok';
    if (function_exists('fastcgi_finish_request')) fastcgi_finish_request();
    ignore_user_abort(true);
    if (is_array($upd)) { try { handleUpdate($upd); } catch (Throwable $e) { error_log('bot: ' . $e->getMessage()); } }
    exit;
}

// ورود
if ($method === 'POST' && isset($_GET['login'])) {
    $rk = 'rl_' . md5($_SERVER['REMOTE_ADDR'] ?? '');
    $rl = rd($rk) ?: ['n' => 0, 't' => 0];
    if ($rl['t'] > time() && $rl['n'] >= 8) jout(['ok' => false], 429);
    if ($rl['t'] <= time()) $rl = ['n' => 0, 't' => time() + 600];
    $b = json_decode((string)file_get_contents('php://input'), true) ?: [];
    if (!hash_equals(hash('sha256', ADMIN_PASS), hash('sha256', (string)($b['password'] ?? '')))) {
        $rl['n']++; wr($rk, $rl);
        usleep(900000);
        jout(['ok' => false], 401);
    }
    del($rk);
    $exp = time() + 8 * 3600;
    setAdm($exp . '.' . hm('adm:' . $exp), $exp);
    jout(['ok' => true]);
}
if ($method === 'POST' && isset($_GET['logout'])) { setAdm('', time() - 3600); jout(['ok' => true]); }

// API پنل
if ($method === 'POST' && isset($_GET['api'])) {
    if (!isAdmin()) jout(['error' => 'unauthorized'], 401);
    adminApi(json_decode((string)file_get_contents('php://input'), true) ?: []);
}

// پنل
if ($method === 'GET' && isset($_GET['admin'])) page(isAdmin() ? adminPage() : loginPage(), 200, true);

// صفحه پرداخت
if ($method === 'GET' && isset($_GET['p'])) {
    $c = cfg();
    if (preg_match('/^(\d{4,9})\.([A-Za-z0-9_-]{24})$/', (string)$_GET['p'], $m)) {
        $amount = (int)$m[1];
        if (cardOk($c) && $amount >= MIN_A && $amount <= MAX_A && hash_equals(signA($amount), $m[2])) page(payPage($c, $amount));
    }
    page(simple('🔒', 'این لینک پرداخت معتبر نیست.<br>از فرستنده لینک جدید بخواهید.'), 404);
}

page(simple('💳', 'صفحه پرداخت'));
