fix this whole thing its not working no buttons work and stop it from copying the interface of this

javascript:(async function(){
  // --- CONFIG ---
  const config = {
    totalDurationMs: 10*60*1000, // 10 minutes total process duration approx
    updateIntervalMs: 500,       // how often progress updates during waiting
    maxLogLines: 2000,
    codeViewerMaxLines: 5000,
    verbosePrint: true,
  };

  // --- UI SETUP ---

  // Create overlay container
  const overlay = document.createElement('div');
  overlay.style.position = 'fixed';
  overlay.style.top = 0;
  overlay.style.left = 0;
  overlay.style.width = '100vw';
  overlay.style.height = '100vh';
  overlay.style.backgroundColor = '#111';
  overlay.style.color = '#0f0';
  overlay.style.fontFamily = 'Consolas, monospace';
  overlay.style.fontSize = '14px';
  overlay.style.zIndex = 2147483647;
  overlay.style.display = 'flex';
  overlay.style.flexDirection = 'column';
  overlay.style.userSelect = 'none';

  // HEADER BAR with buttons
  const header = document.createElement('div');
  header.style.display = 'flex';
  header.style.justifyContent = 'space-between';
  header.style.alignItems = 'center';
  header.style.backgroundColor = '#222';
  header.style.padding = '5px 10px';

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

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

  // Buttons: pause/resume, stop, show code viewer, show settings
  const btnPauseResume = document.createElement('button');
  btnPauseResume.textContent = 'Pause';
  btnPauseResume.style.marginRight = '10px';

  const btnStop = document.createElement('button');
  btnStop.textContent = 'Stop';
  btnStop.style.marginRight = '10px';

  const btnCodeViewer = document.createElement('button');
  btnCodeViewer.textContent = 'Current Code Viewer';
  btnCodeViewer.style.marginRight = '10px';

  const btnSettings = document.createElement('button');
  btnSettings.textContent = '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');
  terminal.style.flex = '1';
  terminal.style.margin = '0';
  terminal.style.padding = '10px';
  terminal.style.background = '#000';
  terminal.style.color = '#0f0';
  terminal.style.overflowY = 'auto';
  terminal.style.whiteSpace = 'pre-wrap';

  overlay.appendChild(terminal);

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

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

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

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

  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 init)
  const codeViewer = document.createElement('textarea');
  codeViewer.style.position = 'fixed';
  codeViewer.style.top = '40px';
  codeViewer.style.right = '10px';
  codeViewer.style.width = '50vw';
  codeViewer.style.height = '90vh';
  codeViewer.style.background = '#111';
  codeViewer.style.color = '#0f0';
  codeViewer.style.fontFamily = 'Consolas, monospace';
  codeViewer.style.fontSize = '12px';
  codeViewer.style.border = '2px solid #0f0';
  codeViewer.style.padding = '10px';
  codeViewer.style.overflow = 'auto';
  codeViewer.style.resize = 'both';
  codeViewer.style.zIndex = 2147483650;
  codeViewer.style.display = 'none';

  document.body.appendChild(codeViewer);

  // Settings panel (hidden init)
  const settingsPanel = document.createElement('div');
  settingsPanel.style.position = 'fixed';
  settingsPanel.style.top = '50px';
  settingsPanel.style.left = '10px';
  settingsPanel.style.width = '300px';
  settingsPanel.style.height = '400px';
  settingsPanel.style.background = '#111';
  settingsPanel.style.color = '#0f0';
  settingsPanel.style.fontFamily = 'Consolas, monospace';
  settingsPanel.style.fontSize = '13px';
  settingsPanel.style.border = '2px solid #0f0';
  settingsPanel.style.padding = '10px';
  settingsPanel.style.overflow = 'auto';
  settingsPanel.style.zIndex = 2147483650;
  settingsPanel.style.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
  document.body.appendChild(overlay);

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

  // Tweakable variables from settings:
  let verbosePrint = config.verbosePrint;
  let speedMultiplier = 1;
  let maxLogLines = config.maxLogLines;
  let maxCodeViewerLines = config.codeViewerMaxLines;

  // --- Utility Functions ---

  // Append log line, respecting max lines
  function appendLog(line) {
    if (!verbosePrint && !line.startsWith("!!!")) return; // only print errors/warnings
    if (logLines.length >= maxLogLines) {
      logLines.shift();
    }
    logLines.push(line);
    terminal.textContent = logLines.join('\n');
    terminal.scrollTop = terminal.scrollHeight;
  }

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

  // Simple pretty print HTML (basic indent) - for code viewer updates
  function prettyPrintHTML(htmlString) {
    // Simple indent by tags for demonstration only, not full robust HTML parser!
    const tab = '  ';
    let indent = 0;
    return htmlString.split(/>\s*</).map(function(element) {
      if (element.match(/^\/\w/)) indent--;  // closing tag e.g. /div
      let pad = '';
      for(let i = 0; i < indent; i++) pad += tab;
      let line = pad + '<' + element + '>';
      if (element.match(/^<?\w[^>]*[^\/]$/)) indent++;  // opening tag not self-closed
      return line;
    }).join('\n').replace(/>\n</g, '>\n<');
  }

  // Update code viewer content live, limiting size & throttling updates
  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); // limit characters approx
    }
    const pretty = prettyPrintHTML(fullCode);
    codeViewer.value = pretty;
    codeViewer.scrollTop = codeViewer.scrollHeight;
  }

  // Append to current snapshot (HTML string builder)
  function appendSnapshot(str) {
    snapshotBuilder.push(str);
    updateCodeViewer();
  }

  // Clear code viewer content
  function clearCodeViewer() {
    snapshotBuilder = [];
    updateCodeViewer();
  }

  // --- PAUSE / RESUME / STOP MECHANISM ---

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

  // --- STORAGE HANDLERS ---

  // Read localStorage keys + values
  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.substring(0,100)}`);
      count++;
      if(count >= 50) break; // limit output
    }
    appendLog(`!!! localStorage dumped ${count} items.`);
  }
  // Read sessionStorage keys + values
  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.substring(0,100)}`);
      count++;
      if(count >= 50) break;
    }
    appendLog(`!!! sessionStorage dumped ${count} items.`);
  }

  // Read document cookies
  function dumpCookies() {
    appendLog("!!! Dumping cookies:");
    const cookies = document.cookie.split(';');
    if(cookies.length===1 && cookies[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.`);
  }

  // Dump IndexedDB (async, can be very long!)
  async function dumpIndexedDB() {
    appendLog("!!! Dumping IndexedDB databases (async)...");
    if(!('indexedDB' in window)) {
      appendLog("  IndexedDB NOT supported in this browser.");
      return;
    }
    // Get databases
    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;
        }
        // Open DB and list object stores
        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 = e => {
        appendLog(`    ERROR opening DB ${name}: ${openReq.error.message}`);
        reject(openReq.error);
      };
      openReq.onsuccess = async e => {
        const db = openReq.result;
        appendLog(`    Opened DB ${name}, version ${db.version}`);
        const storenameList = Array.from(db.objectStoreNames);

        for(let i=0;i<storenameList.length;i++) {
          let storeName = storenameList[i];
          appendLog(`    ObjectStore #${i+1}/${storenameList.length}: ${storeName}`);
          await waitWhilePaused();
          if(stopped) {
            appendLog("!!! Stopped during ObjectStore dump.");
            db.close();
            resolve();
            return;
          }
          try {
            await dumpObjectStore(db, storeName);
          } catch(e) {
            appendLog(`      ERROR accessing ObjectStore ${storeName}: ${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 = e => {
        appendLog(`      Cursor error: ${req.error.message}`);
        reject(req.error);
      };
      req.onsuccess = e => {
        const cursor = e.target.result;
        if(cursor) {
          let valstr = JSON.stringify(cursor.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();
        }
      };
    });
  }

  // --- PROCESS MANAGEMENT ---

  // Controls
  btnPauseResume.onclick = () => {
    if (paused) {
      paused = false;
      appendLog("!!! Resuming process.");
      btnPauseResume.textContent = 'Pause';
    } else {
      paused = true;
      appendLog("!!! Pausing process.");
      btnPauseResume.textContent = 'Resume';
    }
  };

  btnStop.onclick = () => {
    stopped = true;
    appendLog("!!! Stopping process and cleaning up...");
  };

  btnCodeViewer.onclick = () => {
    if (codeViewer.style.display === 'none') {
      codeViewer.style.display = 'block';
      codeViewerIsVisible = true;
      updateCodeViewer();
    } else {
      codeViewer.style.display = 'none';
      codeViewerIsVisible = false;
    }
  };

  btnSettings.onclick = () => {
    if (settingsPanel.style.display === 'none') {
      settingsPanel.style.display = 'block';
    } else {
      settingsPanel.style.display = 'none';
    }
  };

  // Settings inputs handlers
  const verboseToggle = settingsPanel.querySelector('#verboseToggle');
  verboseToggle.checked = verbosePrint;
  verboseToggle.onchange = e => {
    verbosePrint = e.target.checked;
    appendLog(`!!! Verbose prints set to ${verbosePrint}`);
  };

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

  const maxLogInput = settingsPanel.querySelector('#maxLogLines');
  maxLogInput.value = maxLogLines;
  maxLogInput.onchange = 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.onchange = 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.onclick = e => {
    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);
    }
  });

  // Command processor function
  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;
    }
  }

  // --- MAIN LONG RUNNING 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.");

  codeViewer.value = '';
  codeViewerIsVisible = false;

  // --- WORKER FUNCTION ---

  async function longProcess() {
    const startTime = Date.now();
    const stopAt = startTime + config.totalDurationMs;
    const checkpoints = 200; // Number of update cycles for progress bar smoothing

    // Step 0: Clear snapshot build
    snapshotBuilder = [];
    appendLog("!!! Building page system snapshot...");
    updateCodeViewer();

    // Step 1: Print storages (slowed down a lot)
    appendLog("!!! Step 1: Reading localStorage");
    dumpLocalStorage();
    await waitWhilePaused();
    await sleep(2000 / speedMultiplier);
    if(stopped) return;

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

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

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

    // Step 2: Start building the HTML snapshot progressively

    appendLog("!!! Step 5: Getting DOCTYPE");
    const docTypeStr = getDoctypeStr();
    appendSnapshot(docTypeStr);
    await waitWhilePaused();
    if(stopped) return;

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

    await waitWhilePaused();
    if(stopped) return;

    // Step 7: Collect CSS - heavy loop with progress & delays
    appendLog("!!! Step 7: Gathering CSS");
    let combinedCSS = "";
    const allStylesheets = Array.from(document.styleSheets);
    for(let i=0; i< allStylesheets.length; i++) {
      if(stopped) break;
      await waitWhilePaused();
      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(2000 / speedMultiplier);
    }

    // Step 8: Collect JS - heavy loop with progress & delays
    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;
      await waitWhilePaused();
      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(2000 / speedMultiplier);
    }

    // Step 9: Inject CSS and JS inside clone <head> and <body>
    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);

    await waitWhilePaused();
    if(stopped) return;

    // Step 10: Add snapshot banner info 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: '999999999',
      fontFamily: 'monospace'
    });
    body.insertBefore(infoDiv, body.firstChild);

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

    // Step 11: Serialize document and progressively build snapshotBuilder string
    appendLog("!!! Step 11: Serializing final HTML snapshot progressively");

    let finalHTML = getDoctypeStr() + htmlClone.outerHTML;
    // We'll build snapshotBuilder line-by-line with delays progressively so code viewer can update & process lasts ~10min

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

    for(let i=0; i<lines.length; i++) {
      if(stopped) break;
      await waitWhilePaused();
      snapshotBuilder.push(lines[i] + "\n");
      if(i % 50 === 0) updateCodeViewer();

      // Progress range 0.3 to 0.98 roughly over line count
      let fraction = 0.3 + ((i/lines.length)*0.68);
      updateProgress(fraction);

      await sleep(20 / speedMultiplier); // slow down for large content (tweakable)
    }

    updateCodeViewer();

    // Step 12: Save file & trigger download
    appendLog("!!! Step 12: Preparing to download snapshot...");
    updateProgress(0.99);

    let blobText = snapshotBuilder.join('');
    let 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();
    }, 3000);
  }

  // --- CLEANUP FUNCTION ---
  function cleanup() {
    overlay.remove();
    codeViewer.remove();
    settingsPanel.remove();
  }

  // Start the long process in background
  let codeViewerIsVisible = false;
  longProcess();

  // Expose updateCodeViewer every 1s in case of slower updates
  setInterval(() => { if(codeViewerIsVisible) updateCodeViewer(); }, 1000);

})();