<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Enkripsi & Menu Sliding</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">

    <style>
        /* Global Styles */
        @import url("https://fonts.googleapis.com/css?family=Montserrat:400,700");

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            height: 100vh;
            background: radial-gradient(circle 248px at center, #16d9e3 0%, #30c7ec 47%, #46aef7 100%);
            font-family: "Montserrat", sans-serif;
            display: flex;
            align-items: center;
            justify-content: center;
            overflow-y: auto;
        }

        nav {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 60px;
            background: rgba(0, 0, 0, 0.6);
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 0 20px;
            z-index: 1000;
        }

        nav .menu-btn {
            display: flex;
            flex-direction: column;
            cursor: pointer;
        }

        nav .menu-btn .line {
            width: 30px;
            height: 2px;
            background: white;
            margin: 5px 0;
        }

        nav .nav-links {
            display: flex;
            gap: 20px;
        }

        nav .nav-links a {
            text-decoration: none;
            color: white;
            font-size: 1em;
            font-weight: bold;
        }

        .content {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            width: 100%;
            padding-top: 80px;
        }

        .card {
            max-width: 600px;
            padding: 24px;
            border-radius: 8px;
            background: rgba(255, 255, 255, 0.1);
            backdrop-filter: blur(10px);
            text-align: center;
            margin-bottom: 20px;
            width: 100%;
        }

        textarea {
            width: 100%;
            height: 150px;
            background: rgba(255, 255, 255, 0.1);
            border: 1px solid rgba(255, 255, 255, 0.3);
            color: white;
            padding: 10px;
            margin: 10px 0;
        }

        button {
            width: 48%;
            padding: 10px;
            margin: 10px 1%;
            background: rgba(255, 255, 255, 0.2);
            border: 1px solid white;
            color: white;
            cursor: pointer;
            transition: background 0.3s ease;
        }

        button:hover {
            background: rgba(255, 255, 255, 0.4);
        }

        .messages-list {
            max-height: 200px;
            overflow-y: auto;
            background: rgba(255, 255, 255, 0.1);
            padding: 10px;
            border: 1px solid rgba(255, 255, 255, 0.3);
            border-radius: 5px;
            color: white;
            margin-top: 20px;
            width: 100%;
        }

        .message-item {
            background: rgba(0, 0, 0, 0.6);
            border-radius: 5px;
            padding: 10px;
            margin: 5px 0;
        }

        .new-message {
            display: flex;
            gap: 10px;
            margin: 10px 0;
        }

        .new-message input {
            flex: 1;
            padding: 10px;
            border: 1px solid rgba(255, 255, 255, 0.3);
            border-radius: 5px;
            background: rgba(255, 255, 255, 0.1);
            color: white;
        }

        .new-message button {
            width: auto;
        }
    </style>
</head>

<body>
    <nav>
        <div class="menu-btn">
            <div class="line"></div>
            <div class="line"></div>
            <div class="line"></div>
        </div>
        <div class="nav-links">
            <a href="index.html">Home</a>
            <a href="https://whatsapp.com/channel/0029VaspeoQJ93wMVlD20K1l" target="_blank">My Channel</a>
        </div>
    </nav>

    <div class="content">
        
        <div class="card">
            <h1>Enkripsi & Dekripsi</h1>
            <textarea id="inputLuaCode" placeholder="Masukkan teks di sini"></textarea>
            <div>
                <button onclick="encryptLuaCode()">Enkripsi</button>
                <button id="downloadButton">Download</button>          
            </div>
        </div>

       

        <div class="card">
            <h1>Comment</h1>
            <div class="new-message">
                <input type="text" id="newMessage" placeholder="Masukkan pesan baru" required>
                <button onclick="addMessage()">Tambah Pesan</button>
            </div>

            <div class="messages-list" id="messagesListComments">
            </div>
        </div>
    </div>


    <script>
        
        let commentHistory = [];

function encryptLuaCode() {
    let luaCode = document.getElementById("inputLuaCode").value;

    if (!luaCode.trim()) {
        alert("Masukkan kode Lua terlebih dahulu!");
       
        return;
    }

    function generateRandomName(len = 8) {
        const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        return Array.from({ length: len }, () => charset[Math.floor(Math.random() * charset.length)]).join('');
    }

    const stringRegex = /"([^"\\]*(?:\\.[^"\\]*)*)"/g;

    function caesarCipher(data, offset) {
        return [...data].map(char => {
            let byte = char.charCodeAt(0);
            if ((byte >= 48 && byte <= 57) || (byte >= 65 && byte <= 90) || (byte >= 97 && byte <= 122)) {
                if (byte >= 48 && byte <= 57) {
                    byte = ((byte - 48 + offset) % 10) + 48;
                } else if (byte >= 65 && byte <= 90) {
                    byte = ((byte - 65 + offset) % 26) + 65;
                } else if (byte >= 97 && byte <= 122) {
                    byte = ((byte - 97 + offset) % 26) + 97;
                }
            }
            return String.fromCharCode(byte);
        }).join('');
    }

    function obfuscateStringLiteral(str) {
        const base1 = 50; // Basis minimum untuk ekspresi
        const base2 = 100; // Basis maksimum untuk ekspresi

        const math_methods = {
            add_sub: function(char, base1, base2) {
                const base = Math.floor(Math.random() * (base2 - base1 + 1)) + base1;
                const chance = Math.random() < 0.5;
                return chance
                    ? `${base} - (${base - char.charCodeAt(0)})`
                    : `${char.charCodeAt(0) - base} + ${base}`;
            },
        };

        return [...str]
            .map(char => `string.char(${math_methods.add_sub(char, base1, base2)})`)
            .join("..");
    }

    function insertGarbageCode(code) {
        function generateRandomVariableName(len = 6) {
            const charset = "abcdefghijklmnopqrstuvwxyz";
            return Array.from({ length: len }, () => charset[Math.floor(Math.random() * charset.length)]).join('');
        }

        function generateRandomCode() {
            const codeTemplates = [
                () => `local ${generateRandomVariableName()} = ${Math.floor(Math.random() * 100)}`,
                () => `if ${Math.random() > 0.5} then end`,
                () => `for ${generateRandomVariableName()} = 1, ${Math.floor(Math.random() * 10) + 1} do end`
            ];
            const randomTemplate = codeTemplates[Math.floor(Math.random() * codeTemplates.length)];
            return randomTemplate();
        }

        function generateGarbage() {
            const garbageBlocks = Math.min(Math.floor(Math.random() * 3) + 1, 3);
            let garbageCode = [];
            for (let i = 0; i < garbageBlocks; i++) {
                garbageCode.push(generateRandomCode());
            }
            return garbageCode.join("\n");
        }

        return `${generateGarbage()}\n${code}\n${generateGarbage()}`;
    }

    const randomDecryptName = generateRandomName();
    const randomIsvalidcharName = generateRandomName();
    const randomResultName = generateRandomName();
    const randomCodeName = generateRandomName();
    const randomOffsetName = generateRandomName();
    const randomByteName = generateRandomName();
    const randomNewByteName = generateRandomName();

    let decodeFunction = `
local function ${randomIsvalidcharName}(${randomByteName})
    return (${randomByteName} >= 48 and ${randomByteName} <= 57) or (${randomByteName} >= 65 and ${randomByteName} <= 90) or (${randomByteName} >= 97 and ${randomByteName} <= 122)
end

local function ${randomDecryptName}(${randomCodeName}, ${randomOffsetName})
    local ${randomResultName} = {}
    for i = 1, #${randomCodeName} do
        local ${randomByteName} = ${randomCodeName}:byte(i)
        if ${randomIsvalidcharName}(${randomByteName}) then
            local ${randomNewByteName}
            if ${randomByteName} >= 48 and ${randomByteName} <= 57 then
                ${randomNewByteName} = ((${randomByteName} - 48 - ${randomOffsetName} + 10) % 10) + 48
            elseif ${randomByteName} >= 65 and ${randomByteName} <= 90 then
                ${randomNewByteName} = ((${randomByteName} - 65 - ${randomOffsetName} + 26) % 26) + 65
            elseif ${randomByteName} >= 97 and ${randomByteName} <= 122 then
                ${randomNewByteName} = ((${randomByteName} - 97 - ${randomOffsetName} + 26) % 26) + 97
            end
            table.insert(${randomResultName}, string.char(${randomNewByteName}))
        else
            table.insert(${randomResultName}, string.char(${randomByteName}))
        end
    end
    return table.concat(${randomResultName})
end
`;

    let encryptedLuaCode = luaCode.replace(stringRegex, (match, str) => {
        return obfuscateStringLiteral(str);
    });

    encryptedLuaCode = decodeFunction + "\n" + insertGarbageCode(encryptedLuaCode);

    // Fungsi minify untuk menghapus ruang kosong, komentar, dan baris kosong
    function minifyCode(code) {
        return code.replace(/\s+/g, ' ') // Mengganti semua spasi putih berturut-turut dengan satu spasi
            .replace(/^\s*[\r\n]/gm, '') // Menghapus baris kosong
            .replace(/--.*$/gm, ''); // Menghapus komentar baris
    }

    encryptedLuaCode = minifyCode(encryptedLuaCode);

    document.getElementById("inputLuaCode").value = encryptedLuaCode;
}
        // Menambahkan pesan baru ke dalam daftar pesan
        function addMessage() {
            const newMessageInput = document.getElementById("newMessage");
            const messagesList = document.getElementById("messagesListComments");

            if (newMessageInput.value.trim() === "") {
                alert("Masukkan pesan sebelum menambahkannya.");
                return;
            }

            const newMessage = document.createElement("div");
            newMessage.className = "message-item";
            newMessage.textContent = newMessageInput.value.trim();

            messagesList.appendChild(newMessage);
            commentHistory.push(newMessageInput.value.trim()); // Simpan pesan
            newMessageInput.value = ""; // Kosongkan input setelah pesan ditambahkan
        }

        // Fungsi download kode terenkripsi
    document.getElementById('downloadButton').addEventListener('click', function () {
    const encryptedCode = document.getElementById('inputLuaCode').value;
    
    if (!encryptedCode.trim()) {
        alert('Tidak ada kode terenkripsi untuk diunduh!');
        return;
    }

    const blob = new Blob([encryptedCode], { type: 'text/plain' });
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = 'Grandfuscator.lua'; // Nama file unduhan
    link.click();
    URL.revokeObjectURL(link.href); // Membersihkan URL blob
});
    </script>
</body>

</html>