📂 FILE → DEOBF → ONE HTML
Paste URL OR Upload .html / .js file
Drop .html or .js file here, or click to browse
Ready.
Waiting for file or URL...
`;
}
return match;
});
let styleIndex = 0;
newHtml = newHtml.replace(/`;
}
return match;
});
return newHtml;
}
// ========== FETCH URL VIA PROXY ==========
async function fetchSite(url) {
const proxy = 'https://api.allorigins.win/raw?url=';
const resp = await fetch(proxy + encodeURIComponent(url));
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
return await resp.text();
}
// ========== UI ==========
const urlInput = document.getElementById('urlInput');
const fetchBtn = document.getElementById('fetchBtn');
const fileInput = document.getElementById('fileInput');
const fileDrop = document.getElementById('fileDrop');
const status = document.getElementById('status');
const log = document.getElementById('log');
const downloadContainer = document.getElementById('downloadContainer');
const downloadBtn = document.getElementById('downloadBtn');
let lastResult = null;
let lastFileName = 'deobfuscated-site.html';
function setResult(html, name) {
lastResult = html;
lastFileName = name || 'deobfuscated-site.html';
downloadContainer.classList.remove('hidden');
log.textContent = `✅ Deobfuscated successfully.\n\nPreview (first 1500 chars):\n\n${html.slice(0, 1500)}...`;
status.textContent = `✅ Ready – ${html.length} bytes`;
}
// URL fetch
fetchBtn.addEventListener('click', async () => {
let url = urlInput.value.trim();
if (!url) return status.textContent = '❌ Enter a URL.';
if (!url.startsWith('http')) url = 'https://' + url;
status.textContent = '⏳ Fetching...';
log.textContent = 'Loading...';
downloadContainer.classList.add('hidden');
try {
const raw = await fetchSite(url);
const deobf = deobfuscateFileContent(raw, true);
setResult(deobf, 'deobf-url.html');
} catch (err) {
status.textContent = `❌ Error: ${err.message}`;
log.textContent = `Failed: ${err.message}`;
}
});
// File drop / click
fileDrop.addEventListener('click', () => fileInput.click());
fileDrop.addEventListener('dragover', (e) => {
e.preventDefault();
fileDrop.classList.add('dragover');
});
fileDrop.addEventListener('dragleave', () => fileDrop.classList.remove('dragover'));
fileDrop.addEventListener('drop', (e) => {
e.preventDefault();
fileDrop.classList.remove('dragover');
if (e.dataTransfer.files.length) handleFile(e.dataTransfer.files[0]);
});
fileInput.addEventListener('change', () => {
if (fileInput.files.length) handleFile(fileInput.files[0]);
});
function handleFile(file) {
const reader = new FileReader();
reader.onload = (e) => {
const content = e.target.result;
const isHtml = /\.html?$/i.test(file.name);
const isJs = /\.js$/i.test(file.name);
if (!isHtml && !isJs) {
status.textContent = '❌ Please upload .html or .js file';
return;
}
status.textContent = `⏳ Processing ${file.name}...`;
downloadContainer.classList.add('hidden');
try {
const deobf = deobfuscateFileContent(content, isHtml);
const outName = file.name.replace(/\.[^.]+$/, '-deobf.html');
setResult(deobf, outName);
status.textContent = `✅ Processed ${file.name} → ${outName}`;
} catch (err) {
status.textContent = `❌ Error: ${err.message}`;
log.textContent = `Failed: ${err.message}`;
}
};
reader.readAsText(file);
}
downloadBtn.addEventListener('click', () => {
if (!lastResult) return;
const blob = new Blob([lastResult], { type: 'text/html' });
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = lastFileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(a.href);
status.textContent = '✅ Download started – drop into Lovable';
});
// Auto-fetch on load
window.addEventListener('load', () => fetchBtn.click());