here is some code tell me how it works : function injectButton() {
    // Function to inject the button
    const inject = () => {
        // Find the first input or textarea element (the chat input field)
        const chatInput = document.querySelector('input');

        if (!chatInput) {
            console.error('Chat input element not found!');
            return;
        }

        // Check if the folder button is already present
        if (document.querySelector('#folderButtonContainer')) {
            return; // Button is already present, no need to add it
        }

        // Get the parent of the chat input
        const parentContainer = chatInput.parentNode;

        // Ensure the parent container is using flexbox and set to flex-row
        parentContainer.style.display = 'flex';
        parentContainer.style.flexDirection = 'row'; // Set it to row direction

        // Create the folder selection button container
        const buttonContainer = document.createElement('div');
        buttonContainer.setAttribute('id', 'folderButtonContainer');
        buttonContainer.style.display = 'inline-block'; // Make it inline to appear next to the input

        // Create the folder selection input
        const folderButton = document.createElement('input');
        folderButton.setAttribute('type', 'file');
        folderButton.setAttribute('webkitdirectory', 'webkitdirectory');
        folderButton.setAttribute('directory', 'directory');
        folderButton.setAttribute('multiple', 'multiple');
        folderButton.setAttribute('id', 'folderInput');

        // Create a label for the button with the SVG icon
        const label = document.createElement('label');
        label.innerHTML = getSvgIcon(document.documentElement.classList.contains('dark')); // Check <html> for the 'dark' class
        label.setAttribute('for', 'folderInput');
        label.setAttribute('id', 'folderButtonLabel');

        // Append the folder button and label to the container
        buttonContainer.appendChild(folderButton);
        buttonContainer.appendChild(label);

        // Insert the folder input next to the chat input field
        chatInput.parentNode.insertBefore(buttonContainer, chatInput.nextSibling);

        // Handle folder selection
        folderButton.addEventListener('change', async (event) => {
            const files = event.target.files;
            if (files.length === 0) {
                return;
            }

            // Generate the .txt file from the selected files
            const txtFile = await createTxtFile(files);

            // Simulate dragging the generated .txt file onto the website
            simulateDrag(txtFile);

            // Download the generated .txt file
            //downloadFile(txtFile);
        });

        // Fallback: Check periodically if <html> has 'dark' class (polling every second)
        let isDarkMode = document.documentElement.classList.contains('dark');
        setInterval(() => {
            const currentDarkMode = document.documentElement.classList.contains('dark');
            if (currentDarkMode !== isDarkMode) {
                isDarkMode = currentDarkMode;
                label.innerHTML = getSvgIcon(isDarkMode); // Update SVG color
            }
        }, 1000);
    };

    // Function to get the SVG icon based on the dark mode status
    const getSvgIcon = (isDarkMode) => {
        const fillColor = isDarkMode ? '#fff' : '#000'; // White in dark mode, black in light mode
        return `
            <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="${fillColor}">
                <path d="M160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h240l80 80h320q33 0 56.5 23.5T880-640v400q0 33-23.5 56.5T800-160H160Zm0-80h640v-400H447l-80-80H160v480Zm0 0v-480 480Z"/>
            </svg>`;
    };

    // Inject the button when the DOM is ready
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', inject);
    } else {
        inject();
    }

    // Periodically check if the button exists and re-add it if necessary
    setInterval(() => {
        inject();
    }, 500); // Check every 500 milliseconds
}

  
  // Function to process files and generate a .txt file, including full file structure
  async function createTxtFile(files) {
    let fileStructure = 'File Structure:\n';
    let fileContents = '\nFile Contents:\n';
  
    // Build the file structure (just the file names)
    for (let i = 0; i < files.length; i++) {
      const file = files[i];
      fileStructure += `${file.webkitRelativePath}\n`;  // Include the full relative path for each file
    }
  
    // Append the content of each file
    for (let i = 0; i < files.length; i++) {
      const file = files[i];
      const content = await file.text();
      
      // Check if the file is human-readable before appending its content
      if (isHumanReadable(content)) {
        // Append file name and its content
        fileContents += `File: ${file.name}\nContent:\n${content}\n\n`;
      } else {
        fileContents += `File: ${file.name}\nContent is not human-readable.\n\n`;
      }
    }
  
    // Combine file structure and file contents
    const fullContent = `${fileStructure}\n${fileContents}`;
  
    // Create a Blob from the full content
    const txtBlob = new Blob([fullContent], { type: 'text/plain' });
  
    // Create a File object from the Blob
    const txtFile = new File([txtBlob], 'folder.txt', { type: 'text/plain' });
  
    return txtFile;
  }
  
  // Check if a file's content is human-readable (heuristic method)
  function isHumanReadable(content) {
    // Define a threshold for the ratio of printable characters
    const printableCharRatioThreshold = 0.95;

    if (content.length == 0) return false;
  
    // Count total characters and printable characters
    const totalChars = content.length;
    let printableChars = 0;
  
    for (let i = 0; i < content.length; i++) {
      const charCode = content.charCodeAt(i);
      // Check if the character is printable (ASCII range 32 to 126 or tab/newline)
      if ((charCode >= 32 && charCode <= 126) || charCode === 9 || charCode === 10 || charCode === 13) {
        printableChars++;
      }
    }
  
    // Calculate the ratio of printable characters
    const printableCharRatio = printableChars / totalChars;
  
    // Return true if the file is mostly printable (human-readable)
    return printableCharRatio > printableCharRatioThreshold;
  }
  
  // Simulate a drag event with the generated .txt file
  function simulateDrag(txtFile) {
    // Create a new custom DragEvent
    const dragEvent = new DragEvent('drop', {
      bubbles: true,
      cancelable: true,
      dataTransfer: new DataTransfer(),
    });
  
    // Add the .txt file to the dataTransfer object
    dragEvent.dataTransfer.items.add(txtFile);
  
    // Find the drop area on the page (adjust the selector as per your website structure)
    const dropArea = document.querySelector('textarea'); // Update this to your actual drop area element
  
    if (dropArea) {
      // Dispatch the custom drag event on the drop area
      dropArea.dispatchEvent(dragEvent);
    } else {
      console.error('Drop area not found!');
    }
  }
  
  // Function to download the .txt file
  function downloadFile(file) {
    // Create a temporary link element
    const link = document.createElement('a');
  
    // Create an object URL for the file
    const url = URL.createObjectURL(file);
  
    // Set the download attribute and URL
    link.href = url;
    link.download = file.name;
  
    // Append the link to the document and trigger the download
    document.body.appendChild(link);
    link.click();
  
    // Remove the link after triggering the download
    document.body.removeChild(link);
  
    // Revoke the object URL after the download
    URL.revokeObjectURL(url);
  }
  
  // Wait for the ChatGPT page to load fully, then inject the button
  window.addEventListener('load', injectButton);
  

document.getElementById('processButton').addEventListener('click', () => {
    const folderInput = document.getElementById('folderInput');
    const files = folderInput.files;
  
    console.log("click");

    if (files.length === 0) {
      alert('Please select a folder.');
      return;
    }
  
    // Convert FileList to Array
    const filesArray = Array.from(files);
  
    console.log("click");

    console.log(filesArray);

    // Process the files and generate PDF
  });
  
  async function processFiles(files) {
    const { jsPDF } = window.jspdf;
    const doc = new jsPDF();
  
    for (let i = 0; i < files.length; i++) {
      const file = files[i];
      const content = await file.text();

  
      // Add file name as a heading
      doc.setFontSize(16);
      doc.text(file.name, 10, 10 + (i * 20));
  
      // Add file content
      doc.setFontSize(12);
      doc.text(content.substring(0, 500), 10, 20 + (i * 20)); // Limit content for demo
  
      // Add a page break after each file, except the last one
      if (i < files.length - 1) {
        doc.addPage();
      }
    }
  
    // Save the PDF
    doc.save('folder_contents.pdf');
  }