"hey fix it so it stops loading the dang loading thing for this pro I'm pissed it just keeps adding its self in the page copying its annoying to bro. and also add more things to settings to make this good add it so it copy's the JavaScript code now to and it loads through all JavaScript codes make it so you can also edit the local storage in here so when u do it edit sint he SCRIPT and ifnds locals torages and can live edit it once its there please make it copy really all JavaScript functions and pretty prints it cuz it looks like a mess please make the entire scirpt"

javascript:(async function() {

  // --- CONFIG ---
  const config = {
    totalDurationMs: 10 * 60 * 1000, // 10 minutes total approx
    updateIntervalMs: 500,
    maxLogLines: 2000,
    codeViewerMaxLines: 5000,
    verbosePrint: true,
  };

  // --- UTILITIES ---
  function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

  async function fetchText(url) {
    try {
      const res = await fetch(url, { cache: "no-store" });
      if (!res.ok) return { ok: false, error: `${res.status} ${res.statusText}` };
      const text = await res.text();
      return { ok: true, text };
    } catch (e) {
      return { ok: false, error: e.message };
    }
  }

  function getDoctypeStr() {
    const dt = document.doctype;
    if (!dt) return '';
    return `<!DOCTYPE ${dt.name}${dt.publicId ? ` PUBLIC "${dt.publicId}"` : ''}${dt.systemId ? ` "${dt.systemId}"` : ''}>\n`;
  }

  // Cleans the cloned HTML by removing script and style tags to avoid unwanted execution or duplication of UI
  function cleanClonedHTML(docElement) {
    // Remove all <script> and <style> tags from the clone
    const scripts = docElement.querySelectorAll('script');
    scripts.forEach(el => el.remove());
    const styles = docElement.querySelectorAll('style');
    styles.forEach(el => el.remove());

    // Also remove link tags that might reference CSS (optional, but safer)
    const links = docElement.querySelectorAll('link[rel="stylesheet"]');
    links.forEach(el => el.remove());

    // Remove event handlers (attributes starting with "on")
    const elements = docElement.querySelectorAll('*');
    elements.forEach(el => {
      [...el.attributes].forEach(attr => {
        if (attr.name.startsWith('on')) el.removeAttribute(attr.name);
      });
    });
  }

  // --- UI Setup ---

  // Overlay container
  const overlay = document.createElement('div');
  Object.assign(overlay.style, {
    position: 'fixed',
    top: '0',
    left: '0',
    width: '100vw',
    height: '100vh',
    backgroundColor: '#111',
    color: '#0f0',
    fontFamily: 'Consolas, monospace',
    fontSize: '14px',
    zIndex: '123330300',
    display: 'flex',
    flexDirection: 'column',
    // Removed userSelect none to allow interaction
  });

  // Header bar
  const header = document.createElement('div');
  Object.assign(header.style, {
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
    backgroundColor: '#222',
    padding: '5px 10px',
    flexShrink: '0',
  });

  const title = document.createElement('div');
  title.textContent = 'Page Copy Loader v1.0';
  Object.assign(title.style, {
    fontWeight: 'bold',
    fontSize: '16px',
  });
  header.appendChild(title);

  // Controls container
  const controls = document.createElement('div');

  function createButton(text) {
    const b = document.createElement('button');
    b.textContent = text;
    b.style.marginRight = '10px';
    b.style.cursor = 'pointer';
    b.style.fontFamily = 'monospace';
    return b;
  }

  const btnPauseResume = createButton('Pause');
  const btnStop = createButton('Stop');
  const btnCodeViewer = createButton('Current Code Viewer');
  const btnSettings = createButton('Settings');

  controls.appendChild(btnPauseResume);
  controls.appendChild(btnStop);
  controls.appendChild(btnCodeViewer);
  controls.appendChild(btnSettings);

  header.appendChild(controls);
  overlay.appendChild(header);

  // Terminal log area
  const terminal = document.createElement('pre');
  Object.assign(terminal.style, {
    flex: '1',
    margin: '0',
    padding: '10px',
    background: '#000',
    color: '#0f0',
    overflowY: 'auto',
    whiteSpace: 'pre-wrap',
  });
  overlay.appendChild(terminal);

  // Progress bar container
  const progressContainer = document.createElement('div');
  Object.assign(progressContainer.style, {
    width: '100%',
    background: '#222',
    height: '20px',
    borderTop: '2px solid #0f0',
    borderBottom: '2px solid #0f0',
    flexShrink: '0',
  });

  const progressBar = document.createElement('div');
  Object.assign(progressBar.style, {
    width: '0%',
    height: '100%',
    backgroundColor: '#0f0',
    transition: 'width 0.3s linear',
  });

  progressContainer.appendChild(progressBar);
  overlay.appendChild(progressContainer);

  // Command input line
  const inputWrapper = document.createElement('div');
  Object.assign(inputWrapper.style, {
    background: '#111',
    borderTop: '2px solid #0f0',
    padding: '5px 10px',
    flexShrink: '0',
  });

  const commandLabel = document.createElement('label');
  commandLabel.textContent = 'Command: ';
  commandLabel.style.marginRight = '5px';

  const commandInput = document.createElement('input');
  commandInput.type = 'text';
  commandInput.style.width = '60vw';
  commandInput.style.background = '#000';
  commandInput.style.color = '#0f0';
  commandInput.style.border = '1px solid #0f0';
  commandInput.style.fontFamily = 'monospace';
  commandInput.style.fontSize = '14px';
  commandInput.autocomplete = 'off';

  inputWrapper.appendChild(commandLabel);
  inputWrapper.appendChild(commandInput);
  overlay.appendChild(inputWrapper);

  // Code viewer panel (hidden initially)
  const codeViewer = document.createElement('textarea');
  Object.assign(codeViewer.style, {
    position: 'fixed',
    top: '40px',
    right: '10px',
    width: '50vw',
    height: '90vh',
    background: '#111',
    color: '#0f0',
    fontFamily: 'Consolas, monospace',
    fontSize: '12px',
    border: '2px solid #0f0',
    padding: '10px',
    overflow: 'auto',
    resize: 'both',
    zIndex: '1000000000000',
    display: 'none',
  });
  document.body.appendChild(codeViewer);

  // Settings panel (hidden initially)
  const settingsPanel = document.createElement('div');
Object.assign(settingsPanel.style, {
  position: 'fixed',
  top: '0',
  left: '0',
  width: '100vw',
  height: '100vh',
  background: '#111',
  color: '#0f0',
  fontFamily: 'Consolas, monospace',
  fontSize: '13px',
  border: 'none',
  padding: '20px',
  overflowY: 'auto',
  zIndex: '123232300000000', // same high z-index
  display: 'none',
});
  settingsPanel.innerHTML = `
    <h3 style="margin-top:0">Settings</h3>
    <label><input type="checkbox" id="verboseToggle" checked> Verbose prints</label><br><br>
    <label>Speed multiplier:<br><input type="range" id="speedSlider" min="0.1" max="5" step="0.1" value="1"></label><br><br>
    <label>Max log lines:<br><input type="number" id="maxLogLines" min="100" max="10000" value="2000"></label><br><br>
    <label>Max code viewer lines:<br><input type="number" id="maxCodeLines" min="1000" max="10000000" value="5000"></label><br><br>
    <button id="closeSettingsBtn">Close Settings</button>
  `;
  document.body.appendChild(settingsPanel);

  // Append overlay to body last
  document.body.appendChild(overlay);

  // --- STATE ---
  let paused = false;
  let stopped = false;
  let progress = 0; // 0-1
  let logLines = [];
  let snapshotBuilder = [];
  let lastCodeUpdateTime = 0;
  let codeViewerIsVisible = false;

  // Settings variables
  let verbosePrint = config.verbosePrint;
  let speedMultiplier = 1;
  let maxLogLines = config.maxLogLines;
  let maxCodeViewerLines = config.codeViewerMaxLines;

  // --- LOGGING ---
  function appendLog(line) {
    if (!verbosePrint && !line.startsWith("!!!")) return; // print errors/warnings always
    if (logLines.length >= maxLogLines) {
      logLines.shift();
    }
    logLines.push(line);
    terminal.textContent = logLines.join('\n');
    terminal.scrollTop = terminal.scrollHeight;
  }

  // --- PROGRESS ---
  function updateProgress(fraction) {
    progress = Math.min(Math.max(fraction, 0), 1);
    progressBar.style.width = (progress * 100) + '%';
  }

  // Simple pretty print HTML - basic indentation (not robust)
  function prettyPrintHTML(htmlString) {
    const tab = '  ';
    let indent = 0;
    return htmlString.split(/>\s*</).map(function(element) {
      if (element.match(/^\/\w/)) indent--;
      let pad = '';
      for (let i = 0; i < indent; i++) pad += tab;
      let line = pad + '<' + element + '>';
      if (element.match(/^<?\w[^>]*[^\/]$/)) indent++;
      return line;
    }).join('\n').replace(/>\n</g, '>\n<');
  }

  // Update code viewer content throttled
  function updateCodeViewer() {
    if (!codeViewerIsVisible) return;
    const now = Date.now();
    if (now - lastCodeUpdateTime < 200) return;
    lastCodeUpdateTime = now;
    let fullCode = snapshotBuilder.join('');
    if (fullCode.length > maxCodeViewerLines * 100) {
      fullCode = fullCode.slice(-maxCodeViewerLines * 100);
    }
    const pretty = prettyPrintHTML(fullCode);
    codeViewer.value = pretty;
    codeViewer.scrollTop = codeViewer.scrollHeight;
  }

  // Append to snapshot string builder and update code viewer
  function appendSnapshot(str) {
    snapshotBuilder.push(str);
    updateCodeViewer();
  }

  function clearCodeViewer() {
    snapshotBuilder = [];
    updateCodeViewer();
  }

  // --- CONTROL HELPERS ---
  function waitWhilePaused() {
    return new Promise(resolve => {
      const interval = setInterval(() => {
        if (stopped) {
          clearInterval(interval);
          resolve(false);
        }
        else if (!paused) {
          clearInterval(interval);
          resolve(true);
        }
        // else remain paused
      }, 100);
    });
  }

  // --- STORAGE DUMP FUNCTIONS ---
  function dumpLocalStorage() {
    appendLog("!!! Dumping localStorage:");
    let count = 0;
    for (let i = 0; i < localStorage.length; i++) {
      const k = localStorage.key(i);
      const v = localStorage.getItem(k);
      appendLog(`  Key: ${k} => Value: ${v ? v.substring(0, 100) : ''}`);
      count++;
      if (count >= 50) break;
    }
    appendLog(`!!! localStorage dumped ${count} items.`);
  }

  function dumpSessionStorage() {
    appendLog("!!! Dumping sessionStorage:");
    let count = 0;
    for (let i = 0; i < sessionStorage.length; i++) {
      const k = sessionStorage.key(i);
      const v = sessionStorage.getItem(k);
      appendLog(`  Key: ${k} => Value: ${v ? v.substring(0, 100) : ''}`);
      count++;
      if (count >= 50) break;
    }
    appendLog(`!!! sessionStorage dumped ${count} items.`);
  }

  function dumpCookies() {
    appendLog("!!! Dumping cookies:");
    const cookies = document.cookie.split(';').filter(c => c.trim().length > 0);
    if (cookies.length === 0) {
      appendLog("  No cookies found.");
      return;
    }
    let count = 0;
    for (const c of cookies) {
      appendLog(`  Cookie: ${c.trim()}`);
      count++;
      if (count >= 50) break;
    }
    appendLog(`!!! Cookies dumped ${count} items.`);
  }

  async function dumpIndexedDB() {
    appendLog("!!! Dumping IndexedDB databases (async)...");
    if (!('indexedDB' in window)) {
      appendLog("  IndexedDB NOT supported in this browser.");
      return;
    }
    if (!('databases' in indexedDB)) {
      appendLog("  Browser does not support indexedDB.databases() API. Skipping.");
      return;
    }
    try {
      const dbs = await indexedDB.databases();
      if (!dbs.length) {
        appendLog("  No IndexedDB databases found.");
        return;
      }
      for (let i = 0; i < dbs.length; i++) {
        const dbInfo = dbs[i];
        appendLog(`  DB #${i + 1}: ${dbInfo.name}`);
        await waitWhilePaused();
        if (stopped) {
          appendLog("!!! Stopped during IndexedDB dump.");
          return;
        }
        try {
          await dumpOneIndexedDB(dbInfo.name);
        } catch (e) {
          appendLog(`  ERROR reading DB ${dbInfo.name}: ${e.message}`);
        }
      }
      appendLog("!!! Finished dumping IndexedDB.");
    } catch (e) {
      appendLog(`  ERROR: ${e.message}`);
    }
  }

  async function dumpOneIndexedDB(name) {
    return new Promise((resolve, reject) => {
      const openReq = indexedDB.open(name);
      openReq.onerror = () => {
        appendLog(`    ERROR opening DB ${name}: ${openReq.error?.message || 'Unknown error'}`);
        reject(openReq.error);
      };
      openReq.onsuccess = async () => {
        const db = openReq.result;
        appendLog(`    Opened DB ${name}, version ${db.version}`);
        const storeNames = Array.from(db.objectStoreNames);
        for (let i = 0; i < storeNames.length; i++) {
          if (stopped) {
            appendLog("!!! Stopped during ObjectStore dump.");
            db.close();
            resolve();
            return;
          }
          await waitWhilePaused();
          appendLog(`    ObjectStore #${i + 1}/${storeNames.length}: ${storeNames[i]}`);
          try {
            await dumpObjectStore(db, storeNames[i]);
          } catch (e) {
            appendLog(`      ERROR accessing ObjectStore ${storeNames[i]}: ${e.message}`);
          }
        }
        db.close();
        resolve();
      };
    });
  }

  async function dumpObjectStore(db, storeName) {
    return new Promise((resolve, reject) => {
      const tx = db.transaction(storeName, "readonly");
      const store = tx.objectStore(storeName);
      const req = store.openCursor();
      let count = 0;
      req.onerror = () => {
        appendLog(`      Cursor error: ${req.error?.message || 'Unknown error'}`);
        reject(req.error);
      };
      req.onsuccess = (e) => {
        const cursor = e.target.result;
        if (cursor) {
          let valstr = "";
          try {
            valstr = JSON.stringify(cursor.value);
          } catch {
            valstr = '[Unserializable value]';
          }
          if (valstr.length > 200) valstr = valstr.slice(0, 200) + '...';
          appendLog(`      Key: ${cursor.key} => Value: ${valstr}`);
          count++;
          if (count >= 30) {
            appendLog(`      Limited output to first 30 entries.`);
            resolve();
            return;
          }
          cursor.continue();
        } else {
          appendLog(`      Finished dumping ObjectStore ${storeName}, ${count} entries.`);
          resolve();
        }
      };
    });
  }

  // --- MAIN PROCESS ---

  btnPauseResume.addEventListener('click', () => {
    paused = !paused;
    appendLog(paused ? "!!! Pausing process." : "!!! Resuming process.");
    btnPauseResume.textContent = paused ? 'Resume' : 'Pause';
  });

  btnStop.addEventListener('click', () => {
    if (!stopped) {
      stopped = true;
      appendLog("!!! Stopping process and cleaning up...");
    }
  });

  btnCodeViewer.addEventListener('click', () => {
    codeViewerIsVisible = !codeViewerIsVisible;
    codeViewer.style.display = codeViewerIsVisible ? 'block' : 'none';
    if (codeViewerIsVisible) updateCodeViewer();
  });

  btnSettings.addEventListener('click', () => {
    settingsPanel.style.display = settingsPanel.style.display === 'none' ? 'block' : 'none';
  });

  const verboseToggle = settingsPanel.querySelector('#verboseToggle');
  verboseToggle.checked = verbosePrint;
  verboseToggle.addEventListener('change', e => {
    verbosePrint = e.target.checked;
    appendLog(`!!! Verbose prints set to ${verbosePrint}`);
  });

  const speedSlider = settingsPanel.querySelector('#speedSlider');
  speedSlider.value = speedMultiplier;
  speedSlider.addEventListener('input', e => {
    speedMultiplier = parseFloat(e.target.value);
    appendLog(`!!! Speed multiplier set to ${speedMultiplier.toFixed(1)}`);
  });

  const maxLogInput = settingsPanel.querySelector('#maxLogLines');
  maxLogInput.value = maxLogLines;
  maxLogInput.addEventListener('change', e => {
    maxLogLines = Math.max(100, Math.min(10000, parseInt(e.target.value) || 2000));
    appendLog(`!!! Max log lines set to ${maxLogLines}`);
  });

  const maxCodeInput = settingsPanel.querySelector('#maxCodeLines');
  maxCodeInput.value = maxCodeViewerLines;
  maxCodeInput.addEventListener('change', e => {
    maxCodeViewerLines = Math.max(1000, Math.min(10000000, parseInt(e.target.value) || 5000));
    appendLog(`!!! Max code viewer lines set to ${maxCodeViewerLines}`);
  });

  const closeSettingsBtn = settingsPanel.querySelector('#closeSettingsBtn');
  closeSettingsBtn.addEventListener('click', () => {
    settingsPanel.style.display = 'none';
  });

  // Command input processing
  commandInput.addEventListener('keyup', e => {
    if (e.key === 'Enter') {
      const cmd = commandInput.value.trim().toLowerCase();
      commandInput.value = "";
      appendLog(`>>> > ${cmd}`);
      processCommand(cmd);
    }
  });

  function processCommand(cmd) {
    switch (cmd) {
      case 'pause':
        if (!paused) {
          paused = true;
          appendLog("!!! Command: pause - process paused");
          btnPauseResume.textContent = 'Resume';
        } else {
          appendLog("!!! Process is already paused.");
        }
        break;
      case 'resume':
        if (paused) {
          paused = false;
          appendLog("!!! Command: resume - process resumed");
          btnPauseResume.textContent = 'Pause';
        } else {
          appendLog("!!! Process is already running.");
        }
        break;
      case 'stop':
        if (!stopped) {
          stopped = true;
          appendLog("!!! Command: stop - process stopping...");
        } else {
          appendLog("!!! Process is already stopped.");
        }
        break;
      case 'help':
        appendLog("!!! Commands available: pause, resume, stop, help");
        break;
      default:
        appendLog(`!!! Unknown command: ${cmd}. Type 'help' for list.`);
        break;
    }
  }

  // --- LONG PROCESS ---
  appendLog("!!! Starting page copying process ...");
  appendLog("!!! You can control the process with the command input below.");
  appendLog("!!! Type 'help' and press Enter for commands.");

  clearCodeViewer();

  async function longProcess() {
    // Clear vars
    snapshotBuilder = [];
    updateCodeViewer();

    // Step 1: Dump storage etc
    appendLog("!!! Step 1: Reading localStorage");
    dumpLocalStorage();
    if (!(await waitWhilePaused())) return;
    await sleep(2000 / speedMultiplier);
    if (stopped) return;

    appendLog("!!! Step 2: Reading sessionStorage");
    dumpSessionStorage();
    if (!(await waitWhilePaused())) return;
    await sleep(2000 / speedMultiplier);
    if (stopped) return;

    appendLog("!!! Step 3: Reading cookies");
    dumpCookies();
    if (!(await waitWhilePaused())) return;
    await sleep(1500 / speedMultiplier);
    if (stopped) return;

    appendLog("!!! Step 4: Reading IndexedDB (may take long)");
    await dumpIndexedDB();
    if (stopped) return;

    // Step 5: Get doctype and clone html
    appendLog("!!! Step 5: Getting DOCTYPE");
    appendSnapshot(getDoctypeStr());
    if (!(await waitWhilePaused())) return;

    appendLog("!!! Step 6: Cloning <html> element");
    const htmlClone = document.documentElement.cloneNode(true);
    cleanClonedHTML(htmlClone);
    appendLog("!!! Removed scripts, styles and event handlers from cloned <html>");

    if (!(await waitWhilePaused())) return;

    // Step 7: Gather CSS
    appendLog("!!! Step 7: Gathering CSS");
    let combinedCSS = '';
    const allStylesheets = Array.from(document.styleSheets);

    for (let i = 0; i < allStylesheets.length; i++) {
      if (stopped) break;
      if (!(await waitWhilePaused())) return;

      const sheet = allStylesheets[i];
      if (sheet.href) {
        appendLog(`!!! Loading external CSS ${i + 1}/${allStylesheets.length}: ${sheet.href}`);
        const res = await fetchText(sheet.href);
        if (res.ok) combinedCSS += `/* CSS from ${sheet.href} */\n${res.text}\n\n`;
        else combinedCSS += `/* ERROR loading CSS ${sheet.href} - ${res.error} */\n\n`;
      } else {
        appendLog(`!!! Reading inline CSS ${i + 1}/${allStylesheets.length}`);
        try {
          let cssText = '';
          for (const rule of sheet.cssRules) cssText += rule.cssText + "\n";
          combinedCSS += `/* Inline CSS */\n${cssText}\n\n`;
        } catch (e) {
          combinedCSS += '/* Inline CSS inaccessible - skipped */\n\n';
          appendLog('!!! Warning: Inline CSS inaccessible due to CORS/restrictions');
        }
      }
      updateProgress((i / allStylesheets.length) * 0.1);
      await sleep(1500 / speedMultiplier);
    }

    if (stopped) return;

    // Step 8: Gather JS
    appendLog("!!! Step 8: Gathering JS");
    let combinedJS = '';
    const scripts = Array.from(document.querySelectorAll('script'));

    for (let i = 0; i < scripts.length; i++) {
      if (stopped) break;
      if (!(await waitWhilePaused())) return;

      const script = scripts[i];
      if (script.src && script.src.trim()) {
        appendLog(`!!! Loading external JS ${i + 1}/${scripts.length}: ${script.src}`);
        const res = await fetchText(script.src);
        if (res.ok) combinedJS += `/* JS from ${script.src} */\n${res.text}\n\n`;
        else combinedJS += `/* ERROR loading JS ${script.src} - ${res.error} */\n\n`;
      } else {
        appendLog(`!!! Reading inline JS ${i + 1}/${scripts.length}`);
        combinedJS += `/* Inline JS */\n${script.textContent}\n\n`;
      }
      updateProgress(0.1 + (i / scripts.length) * 0.1);
      await sleep(1500 / speedMultiplier);
    }

    if (stopped) return;

    // Step 9: Inject CSS and JS into cloned document
    appendLog("!!! Step 9: Injecting CSS and JS into cloned document");
    let head = htmlClone.querySelector('head');
    if (!head) {
      appendLog("!!! Warning: no <head> found, creating one");
      head = document.createElement('head');
      htmlClone.insertBefore(head, htmlClone.firstChild);
    }
    const styleEl = document.createElement('style');
    styleEl.type = 'text/css';
    styleEl.textContent = combinedCSS;
    head.appendChild(styleEl);

    let body = htmlClone.querySelector('body');
    if (!body) {
      appendLog("!!! Warning: no <body> found, creating one");
      body = document.createElement('body');
      htmlClone.appendChild(body);
    }
    const scriptEl = document.createElement('script');
    scriptEl.type = 'text/javascript';
    scriptEl.textContent = combinedJS;
    body.appendChild(scriptEl);

    updateProgress(0.25);

    if (!(await waitWhilePaused())) return;

    // Step 10: Add banner inside body
    appendLog("!!! Step 10: Adding info banner inside snapshot");
    const infoDiv = document.createElement('div');
    infoDiv.textContent = `This page is a copied snapshot created on ${new Date().toLocaleString()}`;
    Object.assign(infoDiv.style, {
      position: 'fixed',
      top: '0',
      left: '0',
      width: '100%',
      backgroundColor: '#0f0',
      color: '#000',
      padding: '8px',
      fontWeight: 'bold',
      textAlign: 'center',
      zIndex: '111000000',
      fontFamily: 'monospace',
    });
    body.insertBefore(infoDiv, body.firstChild);

    await sleep(1500 / speedMultiplier);
    updateProgress(0.3);

    // Step 11: Serialize document and build snapshot progressively
    appendLog("!!! Step 11: Serializing final HTML snapshot progressively");
    let finalHTML = getDoctypeStr() + htmlClone.outerHTML;

    // Split lines for progressive building
    // (actual HTML may not have many newlines, so add some replacement for readability)
    finalHTML = finalHTML.replace(/></g, ">\n<");

    const lines = finalHTML.split(/\r?\n/);
    snapshotBuilder = [];

    for (let i = 0; i < lines.length; i++) {
      if (stopped) break;
      if (!(await waitWhilePaused())) return;

      snapshotBuilder.push(lines[i] + "\n");

      if (i % 50 === 0) updateCodeViewer();

      let fraction = 0.3 + ((i / lines.length) * 0.68);
      updateProgress(fraction);

      await sleep(15 / speedMultiplier); // adjust speed if needed
    }

    updateCodeViewer();

    if (stopped) return;

    // Step 12: Trigger download
    appendLog("!!! Step 12: Preparing to download snapshot...");
    updateProgress(0.99);

    const blobText = snapshotBuilder.join('');
    const blob = new Blob([blobText], { type: 'text/html' });
    const url = URL.createObjectURL(blob);
    const filename = `page-copied-${new Date().toISOString().replace(/[T:.]/g, '-').slice(0, -5)}.html`;

    const a = document.createElement('a');
    a.href = url;
    a.download = filename;
    document.body.appendChild(a);

    appendLog(`!!! Triggering download: ${filename}`);
    a.click();

    setTimeout(() => {
      URL.revokeObjectURL(url);
      a.remove();
      updateProgress(1);
      appendLog("!!! Download complete. Cleaning up overlay...");
      cleanup();
    }, 2500);
  }

  function cleanup() {
    overlay.remove();
    codeViewer.remove();
    settingsPanel.remove();
  }

  // Expose periodic code viewer update
  setInterval(() => {
    if (codeViewerIsVisible) updateCodeViewer();
  }, 1000);

  // Start main process
  longProcess();

})();