function initHashGenerator() { const statusEl = document.getElementById("hashStatus"); const csrfTokenEl = document.getElementById("csrfToken"); const inputEl = document.getElementById("hashInput"); const generateBtn = document.getElementById("hashGenerateBtn"); const copyAllBtn = document.getElementById("hashCopyAllBtn"); const clearBtn = document.getElementById("hashClearBtn"); const algoEls = Array.from(document.querySelectorAll(".hashAlgo")); const copyBtns = Array.from(document.querySelectorAll(".hash-copy-btn")); const outputMap = { md5: document.getElementById("hashMd5"), sha1: document.getElementById("hashSha1"), sha224: document.getElementById("hashSha224"), sha256: document.getElementById("hashSha256"), sha384: document.getElementById("hashSha384"), sha512: document.getElementById("hashSha512"), sha3256: document.getElementById("hashSha3_256"), sha3512: document.getElementById("hashSha3_512"), blake2b: document.getElementById("hashBlake2b"), blake2s: document.getElementById("hashBlake2s"), }; if (!inputEl || !generateBtn) return; function setStatus(text, isError) { if (!statusEl) return; statusEl.textContent = text; statusEl.classList.toggle("status-error", !!isError); statusEl.classList.toggle("status-success", !isError); } function selectedAlgos() { return algoEls .filter((el) => el.checked) .map((el) => el.value.toLowerCase().replace("-", "")); } function hasAnyOutput() { return Object.values(outputMap).some((el) => el && el.value.trim()); } function refreshButtons() { const hasInput = !!inputEl.value.trim(); const selected = selectedAlgos(); generateBtn.disabled = !hasInput || selected.length === 0; clearBtn && (clearBtn.disabled = !hasInput && !hasAnyOutput()); copyAllBtn && (copyAllBtn.disabled = !hasAnyOutput()); copyBtns.forEach((btn) => { const target = document.getElementById(btn.dataset.target); btn.disabled = !(target && target.value.trim()); }); } function clearOutputs() { Object.values(outputMap).forEach((el) => { if (el) el.value = ""; }); } async function generateHashes() { const text = inputEl.value; if (!text.trim()) return; const selected = selectedAlgos(); if (!selected.length) { setStatus("Select at least one hash algorithm.", true); return; } setStatus("Generating hashes...", false); clearOutputs(); try { const formData = new FormData(); formData.append("text", text); selected.forEach((algo) => formData.append("algorithms[]", algo)); const response = await fetch("/api/hash-generate/", { method: "POST", headers: csrfTokenEl?.value ? { "X-CSRFToken": csrfTokenEl.value } : {}, body: formData, }); const data = await response.json(); if (!response.ok) { throw new Error(data.error || "Hash generation failed."); } Object.entries(outputMap).forEach(([algo, el]) => { if (el) el.value = data.hashes?.[algo] || ""; }); setStatus("Hashes generated successfully.", false); } catch (err) { setStatus(err.message || "Hash generation failed.", true); } refreshButtons(); } async function copyAll() { const lines = []; for (const [algo, el] of Object.entries(outputMap)) { if (el && el.value.trim()) lines.push(`${algo}: ${el.value}`); } if (!lines.length) return; await navigator.clipboard.writeText(lines.join("\n")); const original = copyAllBtn.textContent; copyAllBtn.textContent = "Copied"; setStatus("All hashes copied.", false); setTimeout(() => { copyAllBtn.textContent = original; }, 1200); } function clearAll() { inputEl.value = ""; clearOutputs(); setStatus("Enter text and generate hashes.", false); refreshButtons(); } copyBtns.forEach((btn) => { btn.addEventListener("click", async () => { const target = document.getElementById(btn.dataset.target); if (!target || !target.value.trim()) return; await navigator.clipboard.writeText(target.value); const original = btn.textContent; btn.textContent = "Copied"; setStatus(`${btn.dataset.target} copied.`, false); setTimeout(() => { btn.textContent = original; }, 1200); }); }); inputEl.addEventListener("input", refreshButtons); algoEls.forEach((el) => el.addEventListener("change", refreshButtons)); generateBtn.addEventListener("click", () => { void generateHashes(); }); copyAllBtn && copyAllBtn.addEventListener("click", () => { void copyAll(); }); clearBtn && clearBtn.addEventListener("click", clearAll); refreshButtons(); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", initHashGenerator); } else { initHashGenerator(); }