Meta Description" name="description" />
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>π Advanced Web Downloader</title>
<link rel="icon" href="https://i.ibb.co/zHXM76SY/favicon.png">
<style>
body {
background: #111;
color: #eee;
padding: 20px;
transition: background 0.5s ease, color 0.5s ease;
overflow-x: hidden;
text-align: center;
}
body.light { background: #f0f0f0; color: #111; }
/* β¨ Fancy Font + Glow */
.fancy-text {
font-size: 22px;
font-weight: bold;
font-family: "Times New Roman", serif;
letter-spacing: 1.5px;
text-shadow: 0 0 10px #fff, 0 0 20px #ff00ff;
transition: color 0.5s ease, text-shadow 0.5s ease;
}
h2.fancy-text { font-size: 28px; margin: 15px 0; }
.topbar { margin-bottom: 20px; }
input, button, select {
padding: 10px;
margin: 6px 0;
width: 100%;
border-radius: 5px;
border: none;
box-sizing: border-box;
font-family: "Times New Roman", serif;
font-weight: bold;
}
button {
background: #0f0;
color: #000;
cursor: pointer;
transition: transform 0.3s ease;
}
button:hover {
transform: scale(1.05);
background: #39ff14;
box-shadow: 0 0 10px #39ff14;
}
textarea {
width: 100%;
height: 150px;
margin-top: 10px;
border-radius: 5px;
border: 1px solid #444;
background: #222;
color: #0f0;
padding: 10px;
font-family: monospace;
overflow-y: auto;
}
progress {
width: 100%;
height: 20px;
margin-top: 10px;
border-radius: 5px;
background: #333;
}
progress::-webkit-progress-bar { background: #333; border-radius: 5px; }
progress::-webkit-progress-value {
background: linear-gradient(270deg, #00ffcc, #00bfff, #ff00ff);
animation: progressAnim 2s linear infinite;
border-radius: 5px;
}
fieldset {
border: 1px solid #555;
padding: 10px;
margin: 12px 0;
border-radius: 8px;
}
legend { padding: 0 8px; }
label {
display: flex;
align-items: center;
justify-content: space-between;
margin: 6px 0;
font-weight: bold;
}
label span { flex: 1; text-align: left; }
/* Toggle switch */
.switch {
position: relative;
display: inline-block;
width: 50px;
height: 24px;
}
.switch input { display:none; }
.slider {
position: absolute;
cursor: pointer;
top: 0; left: 0; right: 0; bottom: 0;
background-color: #444;
transition: .4s;
border-radius: 24px;
}
.slider:before {
position: absolute;
content: "";
height: 18px;
width: 18px;
left: 3px;
bottom: 3px;
background-color: white;
transition: .4s;
border-radius: 50%;
}
input:checked + .slider {
background-color: #0f0;
box-shadow: 0 0 10px #0f0;
}
input:checked + .slider:before { transform: translateX(26px); }
/* Animations */
@keyframes progressAnim { 0%{background-position:0% 50%;} 100%{background-position:200% 50%;} }
</style>
</head>
<body>
<!-- β¨ Top Fancy Text -->
<h2 id="titleText" class="fancy-text"> π±πΎπ½-π· π΅ππ π§πΊπΌπ β‘</h2>
<input type="text" id="url" placeholder="Enter website URL" class="fancy-text">
<input type="text" id="zipName" placeholder="Custom ZIP Name (optional)" class="fancy-text">
<fieldset>
<legend class="fancy-text">Resources</legend>
<!-- ALL Toggle -->
<label>
<span id="allLabel" class="fancy-text">ALL</span>
<label class="switch">
<input type="checkbox" id="allChk" checked>
<span class="slider"></span>
</label>
</label>
<hr style="border:0.5px solid #444;">
<label><span class="fancy-text">HTML</span>
<label class="switch"><input type="checkbox" class="resChk" id="htmlChk" checked><span class="slider"></span></label>
</label>
<label><span class="fancy-text">CSS</span>
<label class="switch"><input type="checkbox" class="resChk" id="cssChk" checked><span class="slider"></span></label>
</label>
<label><span class="fancy-text">JS</span>
<label class="switch"><input type="checkbox" class="resChk" id="jsChk" checked><span class="slider"></span></label>
</label>
<label><span class="fancy-text">Images</span>
<label class="switch"><input type="checkbox" class="resChk" id="imgChk" checked><span class="slider"></span></label>
</label>
<label><span class="fancy-text">Fonts</span>
<label class="switch"><input type="checkbox" class="resChk" id="fontChk" checked><span class="slider"></span></label>
</label>
</fieldset>
<button class="fancy-text" onclick="downloadSite()">β¬οΈ Download Website as ZIP</button>
<progress id="progress" value="0" max="100"></progress>
<textarea id="log" readonly placeholder="Logs appear here..."></textarea>
<div>
<h3 class="fancy-text">Preview (HTML)</h3>
<iframe id="preview" style="width:100%;height:300px;border:2px solid #0072ff;border-radius:8px;"></iframe>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
<script>
const allChk = document.getElementById("allChk");
const resChks = document.querySelectorAll(".resChk");
allChk.addEventListener("change", () => {
resChks.forEach(cb => cb.checked = allChk.checked);
});
resChks.forEach(cb => {
cb.addEventListener("change", () => {
if ([...resChks].every(c => c.checked)) {
allChk.checked = true;
} else if ([...resChks].every(c => !c.checked)) {
allChk.checked = false;
}
});
});
// π₯ Glow Text Color Cycle
const colors = ["#ff0000","#00ff00","#00ffff","#ff00ff","#ffff00","#ff8800","#4ade80","#38bdf8"];
let i = 0;
setInterval(() => {
document.querySelectorAll(".fancy-text").forEach(el => {
el.style.color = colors[i % colors.length];
el.style.textShadow = `0 0 15px ${colors[i % colors.length]}, 0 0 35px ${colors[i % colors.length]}`;
});
i++;
}, 1000);
// Logs
async function logMessage(text, delay=30){
const log = document.getElementById("log");
for(let i=0;i<text.length;i++){
log.value += text[i];
log.scrollTop = log.scrollHeight;
await new Promise(res=>setTimeout(res,delay));
}
log.value += "\n";
}
async function downloadSite(){
const url = document.getElementById("url").value.trim();
const preview = document.getElementById("preview");
const zipCustom = document.getElementById("zipName").value.trim();
const progressBar = document.getElementById("progress");
const log = document.getElementById("log");
log.value=""; progressBar.value=0;
if(!url){ logMessage("β οΈ Enter a valid URL!"); return; }
document.querySelectorAll("input[type='checkbox']").forEach(cb=>cb.disabled=true);
const htmlChk = document.getElementById("htmlChk").checked;
const cssChk = document.getElementById("cssChk").checked;
const jsChk = document.getElementById("jsChk").checked;
const imgChk = document.getElementById("imgChk").checked;
const fontChk = document.getElementById("fontChk").checked;
let domain = url.replace(/https?:\/\//,'').split('/')[0];
let zipName = zipCustom?`nexuxwebxzip-${zipCustom}.zip`:`nexuxwebxzip-${domain}.zip`;
try{
await logMessage("π‘ Fetching HTML...");
const res = await fetch(url);
const htmlText = await res.text();
preview.srcdoc = htmlText;
const zip = new JSZip();
if(htmlChk) zip.file("index.html", htmlText);
const parser = new DOMParser();
const doc = parser.parseFromString(htmlText,"text/html");
let resources=[];
if(cssChk) resources.push(...[...doc.querySelectorAll("link[rel='stylesheet']")].map(l=>l.href));
if(jsChk) resources.push(...[...doc.querySelectorAll("script[src]")].map(s=>s.src));
if(imgChk) resources.push(...[...doc.querySelectorAll("img")].map(i=>i.src));
if(fontChk) resources.push(...[...doc.querySelectorAll("link[rel='stylesheet']")].map(l=>l.href).filter(h=>h.match(/\.(woff2?|ttf|otf)$/)));
await logMessage(`π Found ${resources.length} resources`);
for(let i=0;i<resources.length;i++){
const r=resources[i];
try{
if(!r.startsWith("http")) continue;
await logMessage(`β¬οΈ Fetching ${r}...`);
const rRes=await fetch(r);
const blob=await rRes.blob();
const filename=r.split("/").pop()||"file";
zip.file(filename,blob);
}catch(e){
await logMessage(`β Failed: ${r}`);
}
progressBar.value=((i+1)/resources.length)*100;
}
await logMessage("βοΈ Generating ZIP...");
const content=await zip.generateAsync({type:"blob"});
const a=document.createElement("a");
a.href=URL.createObjectURL(content);
a.download=zipName;
a.click();
await logMessage(`β
Saved as ${zipName} in nexuxwebxzip folder!`);
}catch(e){
await logMessage("π¨ Error: "+e.message);
} finally {
document.querySelectorAll("input[type='checkbox']").forEach(cb=>cb.disabled=false);
}
}
</script>
</body>
</html>
2
2
35KB
105KB
292.0ms
372.0ms
293.0ms