diff --git a/static/js/script.js b/static/js/script.js deleted file mode 100644 index 3628aa1..0000000 --- a/static/js/script.js +++ /dev/null @@ -1,475 +0,0 @@ -// ===== AES Advanced Encryption ===== -async function encryptAdvanced(message, password) { - const salt = crypto.getRandomValues(new Uint8Array(16)); - const key = await deriveKey(password, salt); - const iv = crypto.getRandomValues(new Uint8Array(12)); - - const encoder = new TextEncoder(); - const encodedMessage = encoder.encode(message); - - const encryptedMessage = await crypto.subtle.encrypt( - { name: 'AES-GCM', iv: iv }, - key, - encodedMessage - ); - - const encryptedArray = new Uint8Array(salt.length + iv.length + encryptedMessage.byteLength); - encryptedArray.set(salt); - encryptedArray.set(iv, salt.length); - encryptedArray.set(new Uint8Array(encryptedMessage), salt.length + iv.length); - - return btoa(String.fromCharCode(...encryptedArray)); -} - -async function deriveKey(password, salt) { - const encoder = new TextEncoder(); - const passwordBuffer = encoder.encode(password); - - const keyMaterial = await crypto.subtle.importKey( - 'raw', - passwordBuffer, - { name: 'PBKDF2' }, - false, - ['deriveKey'] - ); - - return crypto.subtle.deriveKey( - { - name: 'PBKDF2', - salt: salt, - iterations: 200000, - hash: 'SHA-256', - }, - keyMaterial, - { name: 'AES-GCM', length: 256 }, - false, - ['encrypt', 'decrypt'] - ); -} - -async function decryptAdvanced(encryptedData, password) { - const encryptedArray = new Uint8Array(atob(encryptedData).split("").map(c => c.charCodeAt(0))); - - const salt = encryptedArray.slice(0, 16); - const iv = encryptedArray.slice(16, 28); - const encryptedMessage = encryptedArray.slice(28); - - const key = await deriveKey(password, salt); - - const decryptedMessage = await crypto.subtle.decrypt( - { name: 'AES-GCM', iv: iv }, - key, - encryptedMessage - ); - - const decoder = new TextDecoder(); - return decoder.decode(decryptedMessage); -} - -// ===== UI Toggles ===== -function toggleEncryptionOptions() { - const type = document.getElementById("encryption-type").value; - document.getElementById("password-input").style.display = (type === 'advanced') ? 'flex' : 'none'; - - if (type === 'basic') removeFile(); - - toggleInputMode(); - document.getElementById("encrypt-label").textContent = (type === 'basic') ? "Encode" : "Encrypt"; - document.getElementById("decrypt-label").textContent = (type === 'basic') ? "Decode" : "Decrypt"; -} - -function removeFile() { - document.getElementById("file-input").value = ""; - document.getElementById("remove-file-btn").style.display = 'none'; - toggleInputMode(); -} - -function toggleInputMode() { - const textValue = document.getElementById("input-text").value.trim(); - const fileSelected = document.getElementById("file-input").files.length > 0; - const isAdvanced = document.getElementById("encryption-type").value === 'advanced'; - - document.getElementById("text-section").style.display = fileSelected ? 'none' : 'flex'; - document.getElementById("file-section").style.display = (isAdvanced && !textValue) ? 'flex' : 'none'; - document.getElementById("remove-file-btn").style.display = fileSelected ? 'inline-block' : 'none'; - - if (isAdvanced) { - document.getElementById("password-input").style.display = 'flex'; - } -} - -// ===== Form Submission ===== -async function handleSubmit(event) { - event.preventDefault(); - - const password = document.getElementById("password").value; - const encryptionType = document.getElementById("encryption-type").value; - - if (encryptionType === 'advanced' && !password) { - alert("Password is required for advanced encryption."); - return; - } - - const payload = { - "encryption-type": encryptionType, - operation: document.querySelector('input[name="operation"]:checked').value, - message: document.getElementById("input-text").value, - password: password - }; - - const fileInput = document.getElementById("file-input"); - if (fileInput.files.length > 0) { - const op = document.querySelector('input[name="operation"]:checked').value; - if (op === 'encrypt') encryptFile(); - else decryptFile(); - return; - } - - try { - const resp = await fetch("/", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify(payload) - }); - const data = await resp.json(); - document.getElementById("output-text").value = data.result; - } catch (err) { - alert("Error processing request: " + err); - } -} - -// ===== File Encryption / Decryption ===== -function encryptFile() { - const f = document.getElementById("file-input"); - const pwd = document.getElementById("password").value; - if (!pwd) return alert("Please enter a password!"); - if (!f.files.length) return alert("Please select a file!"); - - const reader = new FileReader(); - reader.onload = async (e) => { - const raw = new Uint8Array(e.target.result); - const base64Raw = btoa(String.fromCharCode(...raw)); - const encrypted = await encryptAdvanced(base64Raw, pwd); - downloadFile(encrypted, f.files[0].name + ".enc"); - }; - reader.readAsArrayBuffer(f.files[0]); -} - -function decryptFile() { - const f = document.getElementById("file-input"); - const pwd = document.getElementById("password").value; - if (!pwd) return alert("Please enter a password!"); - if (!f.files.length) return alert("Please select a file!"); - - const reader = new FileReader(); - reader.onload = async (e) => { - try { - const encryptedText = e.target.result; - const decryptedBase64 = await decryptAdvanced(encryptedText, pwd); - const byteString = atob(decryptedBase64); - const byteArray = new Uint8Array([...byteString].map(c => c.charCodeAt(0))); - downloadFileBinary(byteArray, f.files[0].name.replace(/\.enc$/, '')); - } catch (err) { - alert("Decryption failed: wrong password or corrupted file."); - } - }; - reader.readAsText(f.files[0]); -} - -function downloadFile(content, filename) { - const blob = new Blob([content], { type: "application/octet-stream" }); - const url = URL.createObjectURL(blob); - const a = document.createElement("a"); - a.href = url; - a.download = filename; - a.click(); - URL.revokeObjectURL(url); -} - -function downloadFileBinary(byteArray, filename) { - const blob = new Blob([byteArray], { type: "application/octet-stream" }); - const url = URL.createObjectURL(blob); - const a = document.createElement("a"); - a.href = url; - a.download = filename; - a.click(); - URL.revokeObjectURL(url); -} - -// ===== Password Generator ===== -function generateRandomPassword() { - const length = 30; - const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+[]{}|;:,.<>?/~"; - let password = ""; - for (let i = 0; i < length; i++) { - password += charset.charAt(Math.floor(Math.random() * charset.length)); - } - document.getElementById("password-field").value = password; -} - -// ===== Copy to Clipboard ===== -function copyToClipboard(elementId, toastId) { - const copyText = document.getElementById(elementId); - copyText.select(); - copyText.setSelectionRange(0, 99999); - document.execCommand("copy"); - - const toast = document.getElementById(toastId); - toast.classList.add("show"); - setTimeout(() => toast.classList.remove("show"), 2000); -} - -// ===== Pacman Easter Egg ===== -function checkForPacman() { - const val = document.getElementById("input-text").value.trim().toLowerCase(); - const pacSection = document.getElementById("pacman-section"); - const encSection = document.getElementById("encoding-section"); - - if (val.includes('pacman') && pacSection.style.display !== 'block') { - pacSection.style.display = 'block'; - encSection.style.display = 'none'; - startPacman(); - } else if (pacSection.style.display === 'block' && !val.includes('pacman')) { - exitGame(); - } -} - -// ===== Game Exit & Restart ===== -function exitGame() { - stopPacman(); - document.getElementById("input-text").value = ""; - document.getElementById("pacman-section").style.display = 'none'; - document.getElementById("encoding-section").style.display = 'block'; -} - -function resetGame() { - stopPacman(); - startPacman(); -} - -// ===== Clear All ===== -function clearAll() { - document.getElementById("input-text").value = ""; - document.getElementById("output-text").value = ""; - document.getElementById("file-input").value = ""; - document.getElementById("password").value = ""; - - document.getElementById("pacman-section").style.display = "none"; - document.getElementById("encoding-section").style.display = "block"; - - removeFile(); - toggleInputMode(); -} - -// ===== Initialize ===== -document.addEventListener("DOMContentLoaded", () => { - toggleEncryptionOptions(); - toggleInputMode(); - document.getElementById("input-text").addEventListener("input", checkForPacman); -}); - - -// ===== Pacman Game Variables & Logic ===== -let canvas, ctx, pacman, enemy, walls, dots, score; -let pacmanSpeed = 40, enemySpeed = 20, cellSize = 40, dotSize = 5; -let cols, rows, randSeed, gameInterval; - -function startPacman() { - canvas = document.getElementById("pacmanCanvas"); - ctx = canvas.getContext("2d"); - cols = Math.floor(canvas.width / cellSize); - rows = Math.floor(canvas.height / cellSize); - walls = []; dots = []; score = 0; - clearInterval(gameInterval); - - randSeed = Array.from( - document.getElementById("password-field").value - ).reduce((s, c) => s + c.charCodeAt(0), 0); - - generateWalls(); - generateDots(); - - pacman = spawn(); - do { - enemy = spawn(); - } while (enemy.x === pacman.x && enemy.y === pacman.y); - - pacman.dx = pacman.dy = 0; - document.addEventListener("keydown", movePacman); - gameInterval = setInterval(gameLoop, 150); -} - -function stopPacman() { - clearInterval(gameInterval); - if (ctx) ctx.clearRect(0, 0, canvas.width, canvas.height); -} - -function spawn() { - const opts = []; - for (let c = 1; c < cols - 1; c++) { - for (let r = 1; r < rows - 1; r++) { - if (!walls.some(w => w.c === c && w.r === r)) { - const neighbors = [ - { c: c+1, r }, { c: c-1, r }, - { c, r: r+1 }, { c, r: r-1 } - ]; - if (neighbors.some(n => - !walls.some(w => w.c===n.c && w.r===n.r) - )) { - opts.push({ c, r }); - } - } - } - } - const s = opts[Math.floor(rand() * opts.length)]; - return { - x: s.c * cellSize + cellSize/2, - y: s.r * cellSize + cellSize/2, - size: cellSize/2 - 5, - dx: 0, - dy: 0 - }; -} - -function rand() { - const x = Math.sin(randSeed++) * 10000; - return x - Math.floor(x); -} - -function generateWalls() { - for (let c = 0; c < cols; c++) { - for (let r = 0; r < rows; r++) { - if (c===0||r===0||c===cols-1||r===rows-1||rand()<0.2) { - walls.push({ c, r }); - } - } - } -} - -function generateDots() { - dots = []; - for (let c = 1; c < cols - 1; c++) { - for (let r = 1; r < rows - 1; r++) { - if (walls.some(w => w.c===c && w.r===r)) continue; - const isEnclosed = - walls.some(w => w.c===c+1 && w.r===r) && - walls.some(w => w.c===c-1 && w.r===r) && - walls.some(w => w.c===c && w.r===r+1) && - walls.some(w => w.c===c && w.r===r-1); - if (!isEnclosed) dots.push({ c, r }); - } - } -} - -function movePacman(e) { - if (!["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].includes(e.key)) return; - e.preventDefault(); - if (e.key==="ArrowUp") { pacman.dx=0; pacman.dy=-pacmanSpeed; } - if (e.key==="ArrowDown") { pacman.dx=0; pacman.dy=pacmanSpeed; } - if (e.key==="ArrowLeft") { pacman.dx=-pacmanSpeed; pacman.dy=0; } - if (e.key==="ArrowRight") { pacman.dx=pacmanSpeed; pacman.dy=0; } -} - -// ===== Collision Helper ===== -function willCollide(x, y, size) { - const left = x - size, right = x + size; - const top = y - size, bottom = y + size; - for (let w of walls) { - const wx1 = w.c * cellSize, wy1 = w.r * cellSize; - const wx2 = wx1 + cellSize, wy2 = wy1 + cellSize; - if (right > wx1 && left < wx2 && bottom > wy1 && top < wy2) { - return true; - } - } - return false; -} - -function moveChar(ch) { - const nx = ch.x + ch.dx, ny = ch.y + ch.dy; - if (!willCollide(nx, ny, ch.size)) { - ch.x = nx; ch.y = ny; - } -} - -function moveEnemy() { - const options = []; - [[enemySpeed,0],[-enemySpeed,0],[0,enemySpeed],[0,-enemySpeed]].forEach( - ([dx,dy]) => { - const nx = enemy.x + dx, ny = enemy.y + dy; - if (!willCollide(nx, ny, enemy.size)) options.push({dx,dy}); - } - ); - if (!options.length) return; - let best = options[0]; - let bestD = Math.abs(enemy.x+best.dx-pacman.x)+Math.abs(enemy.y+best.dy-pacman.y); - for (let opt of options) { - const d = Math.abs(enemy.x+opt.dx-pacman.x)+Math.abs(enemy.y+opt.dy-pacman.y); - if (d < bestD) { best=opt; bestD=d; } - } - enemy.x += best.dx; enemy.y += best.dy; -} - -function gameLoop() { - ctx.clearRect(0,0,canvas.width,canvas.height); - drawWalls(); - moveChar(pacman); - moveEnemy(); - drawChar(pacman,"yellow"); - drawChar(enemy,"red"); - eatDots(); - drawScore(); - checkGameOver(); -} - -function drawWalls() { - ctx.fillStyle="blue"; - walls.forEach(w=>ctx.fillRect(w.c*cellSize,w.r*cellSize,cellSize,cellSize)); -} - -function drawChar(ch,color) { - ctx.beginPath(); - ctx.arc(ch.x,ch.y,ch.size,0,Math.PI*2); - ctx.fillStyle=color; ctx.fill(); -} - -function eatDots() { - const chompSound = document.getElementById("chomp-sound"); - - dots = dots.filter(d => { - const dx = d.c * cellSize + cellSize / 2; - const dy = d.r * cellSize + cellSize / 2; - if (Math.abs(pacman.x - dx) < pacman.size && Math.abs(pacman.y - dy) < pacman.size) { - score++; - if (chompSound) { - chompSound.currentTime = 0; // Reset sound - chompSound.volume = 0.4; - chompSound.play(); - } - return false; // Remove dot - } - return true; - }); - - ctx.fillStyle = "white"; - dots.forEach(d => { - ctx.beginPath(); - ctx.arc(d.c * cellSize + cellSize / 2, d.r * cellSize + cellSize / 2, dotSize, 0, Math.PI * 2); - ctx.fill(); - }); -} - -function drawScore() { - ctx.fillStyle="white"; - ctx.font="20px Poppins"; - ctx.fillText("Score: "+score,10,25); -} - -function checkGameOver() { - if (Math.abs(pacman.x-enemy.x)