HOME


sh-3ll 1.0
DIR:/opt/cpguard/app/api/public/captcha/
Upload File :
Current File : //opt/cpguard/app/api/public/captcha/http.html
<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <title data-i18n="page_title">Security Check Required</title>
    <meta name="description" content="Security verification required to continue." />
    <style>
        :root {
            /* LIGHT MODE (Default) */
            --bg0: #eef2f7;
            --bg1: #f7f9fc;
            --glass: rgba(255, 255, 255, .58);
            --glass-2: rgba(255, 255, 255, .42);
            --glass-solid: rgba(255, 255, 255, .70);
            --line: rgba(15, 23, 42, .12);
            --line-2: rgba(15, 23, 42, .08);
            --text: #0f172a;
            --muted: #5b667a;
            --accent: #dc2626;
            --card-bg: white;
            --card-side-bg: rgba(255, 255, 255, .38);
            --radius: 10px;
            --radius-sm: 10px;
            --shadow: 0 10px 30px rgba(15, 23, 42, .08);
            --mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
            --sans: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji";
        }

        /* DARK MODE SUPPORT */
        @media (prefers-color-scheme: dark) {
            :root {
                --bg0: #020617;
                --bg1: #0f172a;
                --glass: rgba(15, 23, 42, .60);
                --glass-2: rgba(15, 23, 42, .42);
                --glass-solid: rgba(30, 41, 59, .70);
                --line: rgba(255, 255, 255, .15);
                --line-2: rgba(255, 255, 255, .10);
                --text: #f1f5f9;
                --muted: #94a3b8;
                --accent: #ef4444;
                --card-bg: #1e293b;
                --card-side-bg: rgba(30, 41, 59, .50);
                --shadow: 0 10px 30px rgba(0, 0, 0, .5);
            }

            body:before {
                opacity: .08;
                /* Reduce noise opacity in dark mode */
            }

            .mark {
                background: radial-gradient(90px 60px at 30% 20%, rgba(255, 255, 255, .10), transparent 60%),
                    linear-gradient(180deg, rgba(220, 38, 38, .2), rgba(255, 255, 255, .05)) !important;
            }

            .side h2,
            .side h3,
            .item strong {
                color: #e2e8f0 !important;
            }

            /* Checkbox/Input adjustments for dark mode */
        }

        * {
            box-sizing: border-box;
        }

        html,
        body {
            height: 100%;
        }

        body {
            margin: 0;
            font-family: var(--sans);
            color: var(--text);
            background:
                radial-gradient(900px 500px at 18% 10%, rgba(99, 102, 241, .10), transparent 60%),
                radial-gradient(900px 500px at 80% 0%, rgba(16, 185, 129, .08), transparent 55%),
                radial-gradient(900px 500px at 72% 92%, rgba(220, 38, 38, .06), transparent 60%),
                linear-gradient(180deg, var(--bg1), var(--bg0));
            line-height: 1.35;
            -webkit-font-smoothing: antialiased;
            overflow-x: hidden;
        }

        body:before {
            content: "";
            position: fixed;
            inset: 0;
            pointer-events: none;
            background: repeating-linear-gradient(0deg, rgba(255, 255, 255, .035) 0 1px, transparent 1px 2px);
            opacity: .18;
            mix-blend-mode: overlay;
        }

        .page {
            min-height: 100%;
            display: flex;
            flex-direction: column;
        }

        .topbar {
            position: sticky;
            top: 0;
            z-index: 10;
            background: var(--glass);
            backdrop-filter: blur(14px) saturate(140%);
            -webkit-backdrop-filter: blur(14px) saturate(140%);
            border-bottom: 1px solid var(--line-2);
        }

        .topbar-inner {
            max-width: 1040px;
            margin: 0 auto;
            padding: 16px 20px;
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 16px;
        }

        .brand {
            display: flex;
            align-items: baseline;
            gap: 10px;
            min-width: 0;
        }

        .domain {
            font-weight: 650;
            letter-spacing: -.02em;
            font-size: 16px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            color: var(--text);
        }

        .status {
            font-size: 12px;
            color: var(--muted);
            font-family: var(--mono);
            border: 1px solid var(--line-2);
            padding: 6px 10px;
            border-radius: var(--radius-sm);
            background: rgba(255, 255, 255, .55);
            backdrop-filter: blur(10px);
            -webkit-backdrop-filter: blur(10px);
            white-space: nowrap;
            display: none;
        }

        .status-top {
            font-size: 12px;
            color: var(--muted);
            font-family: var(--mono);
            border: 1px solid var(--line-2);
            padding: 6px 10px;
            border-radius: var(--radius-sm);
            background: rgba(255, 255, 255, .55);
            backdrop-filter: blur(10px);
            -webkit-backdrop-filter: blur(10px);
            white-space: nowrap;
        }

        .main {
            flex: 1;
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 28px 20px 18px;
        }

        .wrap {
            width: 100%;
            max-width: 1040px;
            display: grid;
            grid-template-columns: 1.1fr .9fr;
            gap: 18px;
            align-items: start;
        }

        .card-main {
            border-radius: var(--radius);
            background-color: var(--card-bg);
            overflow: hidden;
        }

        .side {
            outline-offset: -1px;
            padding: 20px 18px;
        }

        .hero {
            padding: 22px 22px 18px;
            display: grid;
            grid-template-columns: 56px 1fr;
            gap: 16px;
            align-items: start;
        }

        .mark {
            width: 56px;
            height: 56px;
            border-radius: 14px;
            background:
                radial-gradient(90px 60px at 30% 20%, rgba(255, 255, 255, .70), transparent 60%),
                linear-gradient(180deg, rgba(220, 38, 38, .14), rgba(255, 255, 255, .02));
            border: 1px solid rgba(220, 38, 38, .18);
            box-shadow: 0 8px 18px rgba(15, 23, 42, .06);
            display: grid;
            place-items: center;
        }

        .mark svg {
            width: 28px;
            height: 28px;
            color: var(--accent);
        }

        h1 {
            margin: 0 0 6px 0;
            font-size: 22px;
            letter-spacing: -.03em;
            font-weight: 720;
            color: var(--text);
        }

        .lead {
            margin: 0;
            color: var(--muted);
            font-size: 13px;
            max-width: 64ch;
        }

        .captcha {
            border-top: 1px solid var(--line-2);
            padding: 16px 22px 20px;
            display: grid;
            gap: 12px;
        }

        .captcha-title h2 {
            margin: 0;
            font-size: 13px;
            font-weight: 700;
            letter-spacing: -.01em;
            color: var(--text);
        }

        .captcha-box {
            background: radial-gradient(230px 140px at 22% 37%, rgba(255, 255, 255, 0.12), transparent 51%),
                linear-gradient(180deg, rgba(255, 255, 255, .14), rgba(255, 255, 255, .08));
            border: 1px solid var(--line-2);
            border-radius: var(--radius-sm);
            padding: 15px;
            backdrop-filter: blur(20px);
            -webkit-backdrop-filter: blur(20px);
            box-shadow: 0 10px 22px rgba(15, 23, 42, .05);
        }

        .captcha-left {
            display: flex;
            align-items: center;
            gap: 8px;
            position: relative;
            float: left
        }

        .side h2 {
            margin: 0 0 10px 0;
            font-size: 18px;
            font-weight: 760;
            letter-spacing: -.01em;
            color: #4e5d7c;
        }

        .side h3 {
            margin: 0 0 10px 0;
            font-size: 14px;
            font-weight: 760;
            letter-spacing: -.01em;
            color: #4e5d7c;
        }

        .side p {
            margin: 0 0 12px 0;
            color: var(--muted);
            font-size: 13px;
        }

        .list {
            margin: 0;
            padding: 0;
            list-style: none;
            display: grid;
            gap: 10px;
        }

        .item {
            margin-left: -10px;
            border-radius: var(--radius-sm);
            padding: 12px;
            background: var(--card-side-bg);
            backdrop-filter: blur(12px);
        }

        .item strong {
            display: block;
            font-size: 13px;
            letter-spacing: -.01em;
            margin-bottom: 2px;
            font-weight: 720;
            color: #4e5d7c;
        }

        .item span {
            font-size: 12px;
            color: var(--muted);
        }

        .actions {
            margin-top: 12px;
            display: flex;
            gap: 10px;
            flex-wrap: wrap;
        }

        .btn {
            appearance: none;
            border: 1px solid var(--line);
            background: var(--glass-solid);
            color: var(--text);
            padding: 10px 12px;
            border-radius: var(--radius-sm);
            font-size: 13px;
            font-weight: 700;
            letter-spacing: -.01em;
            cursor: pointer;
            backdrop-filter: blur(12px);
            transition: all .18s ease;
        }

        .btn:hover {
            border-color: rgba(15, 23, 42, .22);
            box-shadow: 0 10px 22px rgba(15, 23, 42, .06);
            background: var(--bg0);
        }

        @media (prefers-color-scheme: dark) {
            .btn:hover {
                border-color: #fff;
            }
        }

        .btn-primary {
            border-color: rgba(220, 38, 38, .24);
            background: linear-gradient(180deg, rgba(220, 38, 38, .12), rgba(255, 255, 255, .05));
        }

        footer {
            padding: 0 0 14px;
        }

        .footer-inner {
            max-width: 1040px;
            margin: 0 auto;
            padding: 14px 20px;
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 12px;
            color: var(--muted);
            font-size: 12px;
        }

        .footer-left {
            display: flex;
            align-items: center;
            gap: 10px;
            min-width: 0;
        }

        .footer-logo {
            height: 32px;
            width: auto;
            display: block;
            opacity: .95;
        }

        @media (max-width: 900px) {
            .wrap {
                grid-template-columns: 1fr;
            }

            .hero {
                grid-template-columns: 52px 1fr;
                padding: 20px 18px 16px;
            }

            .captcha {
                padding: 14px 18px 18px;
            }

            .side {
                padding: 18px;
            }

            h1 {
                font-size: 20px;
            }
        }
    </style>
</head>

<body>
    <div class="page">
        <header class="topbar">
            <div class="topbar-inner">
                <div class="brand" title="Requested host">
                    <div id="hostname" data-i18n="">Firewall Block</div>
                </div>
                <div class="status-top" data-i18n="status_badge">SECURITY CHECK</div>
            </div>
        </header>
        <main class="main">
            <div class="wrap">
                <section class="card card-main" aria-labelledby="title">
                    <div class="hero">
                        <div class="mark" aria-hidden="true">
                            <svg fill="currentColor" width="32px" height="32px" viewBox="0 0 512 512"
                                xmlns="http://www.w3.org/2000/svg">
                                <path
                                    d="M79.2,211.44h0c15.52-8.82,34.91-2.28,43.31,13.68l41.38,84.41a7,7,0,0,0,8.93,3.43h0a7,7,0,0,0,4.41-6.52V72c0-13.91,12.85-24,26.77-24s26,10.09,26,24V228.64A11.24,11.24,0,0,0,240.79,240,11,11,0,0,0,252,229V24c0-13.91,10.94-24,24.86-24S302,10.09,302,24V228.64A11.24,11.24,0,0,0,312.79,240,11,11,0,0,0,324,229V56c0-13.91,12.08-24,26-24s26,11.09,26,25V244.64A11.24,11.24,0,0,0,386.79,256,11,11,0,0,0,398,245V120c0-13.91,11.08-24,25-24s25.12,10.22,25,24V336c0,117.41-72,176-160,176H272c-88,0-115.71-39.6-136-88L67.33,255C60.67,237,63.69,220.25,79.2,211.44Z" />
                            </svg>
                        </div>

                        <div>
                            <h1 id="title" data-i18n="main_title">Verify you are human</h1>
                            <p class="lead" data-i18n="main_lead">
                                We detected unusual traffic patterns from your network. Please complete the verification
                                to continue.
                            </p>
                        </div>
                    </div>

                    <div class="captcha">
                        <div class="captcha-title">
                            <h2 data-i18n="captcha_title">Human verification</h2>
                        </div>

                        <div class="captcha-box">

                            
                            <style>
    .badge {
        flex: 0 0 auto;
        font-size: 12px;
        color: var(--text);
        background: rgba(255, 255, 255, .45);
        border: 1px solid var(--line);
        padding: 6px 10px;
        border-radius: 999px;
        font-family: var(--mono);
        backdrop-filter: blur(10px);
        float : right;
    }

    .captcha-widget {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 14px;
        padding: 15px 5px;
    }

    /* Container that keeps checkbox/loader in same spot */
    .checkbox-loader-wrapper {
        width: 18px;
        height: 18px;
        position: relative;
        flex: 0 0 auto;
    }

    /* Checkbox styling */
    .check {
        width: 18px;
        height: 18px;
        border-radius: 6px;
        border: 1px solid var(--line);
        background: rgba(255, 255, 255, 0.7);
        box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55);
        position: absolute;
        top: -1px;
        left: 0;
        transition: opacity 0.2s ease;
        z-index: 2;
        cursor: pointer;
    }

    /* Hide checkbox visually */
    .check.hidden {
        opacity: 0;
        pointer-events: none;
    }

    /* Loader styling */
    .loader {
        width: 18px;
        height: 18px;
        border-radius: 50%;
        border: 3px solid var(--line);
        border-top-color: #ffffff;
        position: absolute;
        top: 0;
        left: 0;
        opacity: 0;
        transition: opacity 0.2s ease;
    }

    .loader.active {
        opacity: 1;
        animation: spin 0.8s linear infinite;
    }

    /* Text container */
    .captcha-text {
        display: flex;
        flex-direction: column;
        justify-content: center;
        min-height: 22px;
        /* ensures text never jumps */
    }

    .captcha-text>div {
        transition: opacity 0.25s ease, transform 0.25s ease;
        opacity: 0;
        transform: translateY(4px);
        height: 0;
        overflow: hidden;
    }

    .captcha-text>div.active {
        opacity: 1;
        transform: translateY(0);
        height: auto;
        position: relative;
        left: 3%;
    }

    @keyframes spin {
        to {
            transform: rotate(360deg);
        }
    }

    @media (prefers-color-scheme: dark) {

        .check {
            background: rgba(30, 41, 59, .8) !important;
            border-color: var(--line) !important;
        }

        .status,
        .status-top {
            background: rgb(0 0 0 / 0%) !important;
        }

        .badge {
            background-color: transparent !important;
        }
    }
</style>


<script src="https://cdn.jsdelivr.net/npm/js-sha256@0.11.1/src/sha256.min.js"></script>

<div class="captcha-widget" id="powCaptchaWidget">
    <div class="captcha-left" id="powCaptcha">
        <div class="checkbox-loader-wrapper">
            <input type="checkbox" class="check" id="powCheck">
            <div class="loader" id="powLoader"></div>
        </div>
        <div class="captcha-text">
            <div id="captchaMessage" class="line1 active">I’m not a robot</div>
        </div>
    </div>
    <div class="badge" data-i18n="captcha_badge">VERIFY</div>
</div>
<script>
    let t;
    let captchaHandled = false;
    const $ = id => document.getElementById(id);

    if (!window.name || !window.name.startsWith("redirect:")) {
        const u = document.referrer || window.location.href;
        if (u && u.startsWith(location.origin)) {
            window.name = "redirect:" + new URL(u).pathname + new URL(u).search;
        }
    }

    // behavioural patterns validation
    let behavior = {
        mouseMoves: 0,
        keyPresses: 0,
        timingEntropy: [],
        canvasHash: ""
    };

    window.addEventListener("mousemove", () => behavior.mouseMoves++);
    window.addEventListener("keydown", () => behavior.keyPresses++);

    let last = performance.now();
    setInterval(() => {
        const now = performance.now();
        const diff = Math.abs(now - last);
        behavior.timingEntropy.push(diff);
        if (behavior.timingEntropy.length > 20) behavior.timingEntropy.shift();
        last = now;
    }, 120);

    function getCanvasHash() {
        const c = document.createElement("canvas");
        const ctx = c.getContext("2d");
        ctx.textBaseline = "top";
        ctx.font = "14px 'Arial'";
        ctx.fillStyle = "#f60";
        ctx.fillRect(0, 0, 100, 30);
        ctx.fillStyle = "#069";
        ctx.fillText("OpsShield✓", 2, 15);
        return sha256(c.toDataURL());
    }

    behavior.canvasHash = getCanvasHash();

    async function getBehaviorData() {
        return {
            mouseMoves: behavior.mouseMoves,
            keyPresses: behavior.keyPresses,
            timingEntropy: behavior.timingEntropy,
            canvasHash: behavior.canvasHash
        };
    }

    async function getFingerprint() {
        const data = [
            navigator.userAgent,
            navigator.language,
            screen.width + "x" + screen.height
        ].join("|");
        return sha256(data);
    }

    // browser challenge solving
    function solvePoW(challenge, difficulty) {
        const target = "0".repeat(difficulty);
        let nonce = 0;
        return new Promise(resolve => {
            function step() {
                const start = performance.now();
                while (performance.now() - start < 8) {
                    if (sha256(challenge + nonce).startsWith(target)) { return resolve(nonce); }
                    nonce++;
                } requestAnimationFrame(step);
            } requestAnimationFrame(step);
        });
    }

    // verification success handling and redirection
    async function handleSuccess() {
        showVerified();
        if (captchaHandled) return;
        captchaHandled = true;

        const redirectUrl = window.name.startsWith("redirect:")
            ? window.name.slice(9)
            : '/';

        await new Promise(r => setTimeout(r, 500));

        fetch(redirectUrl, {
            method: 'HEAD',
            mode: 'same-origin',
            cache: 'no-store',
            keepalive: true
        });
        window.location.replace(redirectUrl);
    }

    const captchaMessage = $("captchaMessage");

    function showMessage(text) {
        captchaMessage.textContent = text;
    }

    function showVerifying() {
        $("powCheck").classList.add("hidden");   // hide checkbox
        $("powLoader").classList.add("active");  // show loader
        showMessage("Verifying...");
    }

    function showVerified() {
        $("powCheck").classList.remove("hidden"); // show checkbox
        $("powLoader").classList.remove("active"); // hide loader
        showMessage("Verified. Redirecting...");
    }

    function showFailed() {
        $("powCheck").checked = false;
        $("powCheck").classList.remove("hidden");
        $("powLoader").classList.remove("active");
        showMessage("Verification failed. Reloading...");
    }

    // checkbox check challenge generation and verification handling
    $("powCheck").addEventListener("change", async e => {
        if (!e.target.checked) return;
        showVerifying();

        const fp = await getFingerprint();
        const behaviorData = await getBehaviorData();

        const r = await fetch("/captcha.php", {
            method: "POST",
            headers: { "Content-Type": "application/json", "X-Captcha-Request": "pow" },
            body: JSON.stringify({ fp, behavior: behaviorData })
        });

        const j = await r.json();

        const challenge = atob(j.payload).split("|")[0];
        const difficulty = j.difficulty;
        const payload = j.payload;

        const nonce = await solvePoW(challenge, difficulty);

        const behaviorData2 = await getBehaviorData();
        const r2 = await fetch("/captcha.php", {
            method: "POST",
            headers: { "Content-Type": "application/json", "X-Captcha-Request": "pow" },
            body: JSON.stringify({
                payload,
                nonce,
                difficulty,
                fp,
                behavior: behaviorData2
            })
        });

        const j2 = await r2.json();

        if (j2.success === true) {
            try {
                handleSuccess();
            } catch { }
        } else {
            showFailed();
            setTimeout(() => {
                location.reload();
            }, 1500);

        }
    });
</script>
                            

                        </div>

                        <div class="actions">
                            <button class="btn btn-primary" type="button" onclick="location.reload()"
                                data-i18n="btn_retry">Try
                                again</button>
                        </div>
                    </div>
                </section>
                <aside class="card side" aria-label="Information">
                    <h2 data-i18n="aside_title">What happened?</h2>
                    <p data-i18n="aside_text">
                        We use automated security to prevent abusive traffic. Your IP is currently blocked or has been
                        flagged for unusual activity.
                    </p>

                    <h3 data-i18n="aside_subtitle">What can I do?</h3>
                    <ul class="list">
                        <li class="item">
                            <strong data-i18n="item_visitor_title">If you are a visitor</strong>
                            <span data-i18n="item_visitor_text">Complete the verification above, then retry. If it
                                persists, wait for some time and try again.</span>
                        </li>
                        <li class="item">
                            <strong data-i18n="item_owner_title">If you are the site owner</strong>
                            <span data-i18n="item_owner_text">Review cPGuard firewall/WAF/Fail2Ban activity to identify
                                the trigger. If appropriate, whitelist or remove the IP from temporary blocklist.</span>
                        </li>
                    </ul>
                </aside>
            </div>
        </main>
        <footer>
            <div class="footer-inner">
                <div class="footer-left">
                    <img class="footer-logo" src="https://opsshield.com/images/cpguard-logo.svg" alt="cPGuard" />
                    <div class="footer-text">© <span id="y"></span> cPGuard. <span data-i18n="rights">All rights
                            reserved.</span></div>
                </div>
                <div><span data-i18n="protected_by">Protected by</span> <strong>cPGuard Firewall</strong></div>
            </div>
        </footer>
    </div>
</body>
<script>
    // set dynamic host and year values
    document.getElementById("hostname").textContent = window.location.hostname;
    document.getElementById("y").textContent = new Date().getFullYear();

    // --- LANGUAGE CONFIGURATION ---
    const translations = {
        "en": {
            page_title: "Security Check Required",
            brand: "Firewall Block",
            status_badge: "SECURITY CHECK",
            main_title: "Verify you are human",
            main_lead: "We detected unusual traffic patterns from your network. Please complete the verification to continue.",
            captcha_title: "Human verification",
            msg_verified: "✅ Verified — redirecting…",
            msg_failed: "❌ Verification failed. Please try again.",
            btn_retry: "Try again",
            aside_title: "What happened?",
            aside_text: "We use automated security systems to prevent abusive traffic. Your IP address has been temporarily blocked or flagged for unusual activity.",
            aside_subtitle: "What can I do?",
            item_visitor_title: "If you are a visitor",
            item_visitor_text: "Complete the verification above and try again. If the issue persists, please wait a while and retry.",
            item_owner_title: "If you are the site owner",
            item_owner_text: "Review cPGuard firewall/WAF/Fail2Ban activity logs to identify the trigger. If appropriate, whitelist the IP address.",
            rights: "All rights reserved.",
            protected_by: "Protected by",
            widget_success: "Verified. Redirecting…",
            widget_error: "Verification failed. Reloading…",
            captcha_verifying: "Verifying…",
            captcha_label: "I’m not a robot",
            captcha_badge: "VERIFY"
        },

        "pt-BR": {
            page_title: "Verificação de Segurança Necessária",
            brand: "Bloqueio de Firewall",
            status_badge: "VERIFICAÇÃO DE SEGURANÇA",
            main_title: "Confirme que você é humano",
            main_lead: "Detectamos padrões de tráfego incomuns na sua rede. Conclua a verificação para continuar.",
            captcha_title: "Verificação humana",
            msg_verified: "✅ Verificado — redirecionando…",
            msg_failed: "❌ Falha na verificação. Tente novamente.",
            btn_retry: "Tentar novamente",
            aside_title: "O que aconteceu?",
            aside_text: "Utilizamos sistemas de segurança automatizados para prevenir tráfego abusivo. Seu endereço IP foi temporariamente bloqueado ou sinalizado.",
            aside_subtitle: "O que posso fazer?",
            item_visitor_title: "Se você for um visitante",
            item_visitor_text: "Conclua a verificação acima e tente novamente. Se o problema persistir, aguarde alguns instantes e tente de novo.",
            item_owner_title: "Se você for o proprietário do site",
            item_owner_text: "Verifique os logs do firewall/WAF/Fail2Ban do cPGuard para identificar o motivo. Se necessário, adicione o IP à lista de permissões.",
            rights: "Todos os direitos reservados.",
            protected_by: "Protegido por",
            widget_success: "Verificado. Redirecionando…",
            widget_error: "Falha na verificação. Recarregando…",
            captcha_verifying: "Verificando…",
            captcha_label: "Não sou um robô",
            captcha_badge: "VERIFICAR"
        },

        "es": {
            page_title: "Verificación de Seguridad Requerida",
            brand: "Bloqueo del Firewall",
            status_badge: "CONTROL DE SEGURIDAD",
            main_title: "Verifique que es humano",
            main_lead: "Hemos detectado tráfico inusual desde su red. Por favor, complete la verificación para continuar.",
            captcha_title: "Verificación humana",
            msg_verified: "✅ Verificado — redirigiendo…",
            msg_failed: "❌ La verificación falló. Inténtelo de nuevo.",
            btn_retry: "Intentar de nuevo",
            aside_title: "¿Qué ocurrió?",
            aside_text: "Utilizamos sistemas de seguridad automatizados para prevenir tráfico abusivo. Su dirección IP ha sido bloqueada temporalmente o marcada por actividad inusual.",
            aside_subtitle: "¿Qué puedo hacer?",
            item_visitor_title: "Si es un visitante",
            item_visitor_text: "Complete la verificación anterior y vuelva a intentarlo. Si el problema persiste, espere un momento e inténtelo de nuevo.",
            item_owner_title: "Si es el propietario del sitio",
            item_owner_text: "Revise los registros del firewall/WAF/Fail2Ban de cPGuard para identificar la causa. Si corresponde, agregue el IP a la lista blanca.",
            rights: "Todos los derechos reservados.",
            protected_by: "Protegido por",
            widget_success: "Verificado. Redirigiendo…",
            widget_error: "Falló la verificación. Recargando…",
            captcha_verifying: "Verificando…",
            captcha_label: "No soy un robot",
            captcha_badge: "VERIFICAR"
        },

        "ru": {
            page_title: "Требуется проверка безопасности",
            brand: "Блокировка брандмауэра",
            status_badge: "ПРОВЕРКА БЕЗОПАСНОСТИ",
            main_title: "Подтвердите, что вы человек",
            main_lead: "Мы обнаружили необычный трафик из вашей сети. Пожалуйста, пройдите проверку, чтобы продолжить.",
            captcha_title: "Проверка человека",
            msg_verified: "✅ Проверено — перенаправление…",
            msg_failed: "❌ Проверка не удалась. Попробуйте снова.",
            btn_retry: "Попробовать снова",
            aside_title: "Что произошло?",
            aside_text: "Мы используем автоматические системы защиты для предотвращения вредоносного трафика. Ваш IP-адрес был временно заблокирован или отмечен как подозрительный.",
            aside_subtitle: "Что можно сделать?",
            item_visitor_title: "Если вы посетитель",
            item_visitor_text: "Пройдите проверку выше и повторите попытку. Если проблема сохраняется, подождите некоторое время и попробуйте снова.",
            item_owner_title: "Если вы владелец сайта",
            item_owner_text: "Проверьте журналы firewall/WAF/Fail2Ban в cPGuard, чтобы определить причину. При необходимости добавьте IP в белый список.",
            rights: "Все права защищены.",
            protected_by: "Защищено",
            widget_success: "Проверка пройдена. Перенаправление…",
            widget_error: "Ошибка проверки. Перезагрузка…",
            captcha_verifying: "Проверка…",
            captcha_label: "Я не робот",
            captcha_badge: "ПРОВЕРИТЬ"
        },

        "ko": {
            page_title: "보안 확인이 필요합니다",
            brand: "방화벽 차단",
            status_badge: "보안 검사",
            main_title: "사람인지 확인해 주세요",
            main_lead: "귀하의 네트워크에서 비정상적인 트래픽이 감지되었습니다. 계속하려면 확인을 완료해 주세요.",
            captcha_title: "사람 확인",
            msg_verified: "✅ 확인됨 — 이동 중…",
            msg_failed: "❌ 확인에 실패했습니다. 다시 시도해 주세요.",
            btn_retry: "다시 시도",
            aside_title: "무슨 일이 발생했나요?",
            aside_text: "비정상적인 트래픽을 방지하기 위해 자동 보안 시스템을 사용하고 있습니다. 귀하의 IP 주소가 일시적으로 차단되었거나 의심스러운 활동으로 표시되었습니다.",
            aside_subtitle: "어떻게 하면 되나요?",
            item_visitor_title: "방문자인 경우",
            item_visitor_text: "위의 확인을 완료한 후 다시 시도해 주세요. 문제가 계속되면 잠시 후 다시 시도하십시오.",
            item_owner_title: "사이트 소유자인 경우",
            item_owner_text: "cPGuard 방화벽/WAF/Fail2Ban 로그를 확인하여 원인을 파악하고, 필요 시 IP를 허용 목록에 추가하십시오.",
            rights: "모든 권리 보유.",
            protected_by: "보호 제공:",
            widget_success: "확인됨. 이동 중…",
            widget_error: "확인 실패. 다시 로드 중…",
            captcha_verifying: "확인 중…",
            captcha_label: "로봇이 아닙니다",
            captcha_badge: "확인"
        }
    };


    function applyLanguage() {
        const browserLang = navigator.language || navigator.userLanguage;
        let langKey = 'en'; // Default

        if (translations[browserLang]) {
            langKey = browserLang;
        } else {
            const shortCode = browserLang.split('-')[0];
            if (translations[shortCode]) {
                langKey = shortCode;
            }
        }
        t = translations[langKey];

        document.querySelectorAll('[data-i18n]').forEach(el => {
            const key = el.getAttribute('data-i18n');
            if (t[key]) {
                el.textContent = t[key];
            }
        });

        const widget = document.getElementById('altchaBox');

        if (widget) {
            if (t.widget_success) widget.setAttribute('success-text', t.widget_success);
            if (t.widget_error) widget.setAttribute('error-text', t.widget_error);
        }
        document.documentElement.lang = langKey;
    }

    applyLanguage();

</script>

</html>