LET'S UPGRADE THIS CODE AND INCLUDE 2 MORE MODELS IN MENU. ALSO, ADDITIONAL PARAMETERS WE CAN UTILISE IN THE FOLLOWING EXAMPLE:


"""

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>ProgenerativePregeneratoivePerperegnator</title>
  <style>
    body { font-family: Arial, sans-serif; margin: 0; padding: 0; background-color: #0f1a2b; color: #ffffff; }
    .container { max-width: 900px; margin: 20px auto; background: #182947; padding: 20px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.6); border-radius: 12px; }
    h1 { text-align: center; font-size: 2rem; color: #d5d9f0; }
    label, select, textarea, input, button { font-size: 1rem; width: 100%; padding: 10px; margin-bottom: 10px; border-radius: 6px; }
    textarea { resize: vertical; background: #0f1a2b; color: #fff; border: 1px solid #243a5e; }
    select, input { background: #182947; color: #ffffff; border: 1px solid #243a5e; }
    button { background-color: #3b537a; color: white; font-weight: bold; cursor: pointer; transition: 0.3s ease; }
    button:hover { background-color: #4d6a97; }
    #progress { margin-top: 15px; background-color: #111c33; border-radius: 4px; height: 20px; overflow: hidden; display: block; position: relative; }
    #progress-bar { width: 0%; height: 100%; background-color: #267bd6; text-align: center; line-height: 20px; color: white; font-weight: bold; }
    #loading-placeholder { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 1); transition: opacity 0.3s linear; }
    #settings-container { background-color: #182947; border: 1px solid #243a5e; border-radius: 6px; margin-top: 15px; }
    #settings-header { background-color: #243a5e; display: flex; justify-content: space-between; align-items: center; padding: 10px; cursor: pointer; }
    #settings-content { display: none; padding: 10px; background: #182947; }
    #result { margin-top: 20px; background: #0f1735; border: 2px solid #243a5e; border-radius: 8px; overflow: hidden; width: 100%; max-height: 512px; display: flex; justify-content: center; align-items: center; position: relative; }
    .result-placeholder { color: #d5d9f0; font-size: 1rem; }
    #history { margin-top: 30px; }
    #history h2 { text-align: center; font-size: 1.5rem; color: #d5d9f0; margin-bottom: 15px; }
    .history-item { display: inline-block; margin: 10px; width: 150px; background: #0a1735; border: 1px solid #3b537a; border-radius: 6px; overflow: hidden; text-align: center; }
    .history-item img { width: 100%; height: 120px; object-fit: cover; }
    .history-item p { color: white; font-size: 0.8rem; margin: 5px; }
  </style>
</head>
<body>
  <div class="container">
    <h1>Stable Diffusion Generator</h1>
    <label for="model">Select Model:</label>
    <select id="model">
      <option value="hogiahien/counterfeit-v30-edited">hogiahien/counterfeit-v30-edited</option>
      <option value="digiplay/counterfeitV2525d_tweak">digiplay/counterfeitV2525d_tweak</option>
      <option value="gsdf/Counterfeit-V2.5">gsdf/Counterfeit-V2.5</option>
      <option value="Justin-Choo/epiCRealism-Natural_Sin_RC1_VAE">Justin-Choo/epiCRealism-Natural_Sin_RC1_VAE</option>
      <option value="cagliostrolab/animagine-xl-3.1">cagliostrolab/animagine-xl-3.1</option>
    </select>
    <label for="prompt">Prompt:</label>
    <textarea id="prompt" rows="4" placeholder="Enter your generation prompt..."></textarea>
    
    <!-- Negative prompt hidden initially -->
    <div id="striction-container" style="display: none;">
      <label for="striction">Striction:</label>
      <textarea id="striction" rows="2" placeholder="What NOT to draw..."></textarea>
    </div>
    
    <div id="settings-container">
      <div id="settings-header">Settings ▼</div>
      <div id="settings-content">
        <label for="steps">Inference Steps:</label>
        <input type="number" id="steps" value="55" min="1" max="100">
        <label for="scale">Guidance Scale:</label>
        <input type="number" id="scale" value="7" step="0.1" min="1" max="30">
        
        <label for="width">Width (<output id="widthOutput">768</output> px):</label>
        <input type="range" id="width" value="768" min="32" max="2048" step="8">
        
        <label for="height">Height (<output id="heightOutput">768</output> px):</label>
        <input type="range" id="height" value="768" min="32" max="2048" step="8">
        
        <label for="sampler">Sampler:</label>
        <select id="sampler">
          <option value="ddim">DDIM</option>
          <option value="plms">PLMS</option>
          <option value="k_euler">K-Euler</option>
          <option value="k_euler_ancestral">K-Euler Ancestral</option>
          <option value="k_lms">K-LMS</option>
          <option value="dpm++_2m_karras">DPM++ 2M Karras</option>
          <option value="dpm++_sde_karras">DPM++ SDE Karras</option>
          <option value="dpm++_2m_sde_karras">DPM++ 2M SDE Karras</option>
          <option value="euler">Euler</option>
          <option value="euler_a">Euler a</option>
        </select>
        
        <label for="clip_guidance_preset">Clip Guidance Preset (Test):</label>
        <select id="clip_guidance_preset">
          <option value="none">None</option>
          <option value="low">Low</option>
          <option value="medium">Medium</option>
          <option value="high">High</option>
        </select>
        
        <label for="seed">Seed (0 for random):</label>
        <input type="number" id="seed" value="0">
        
        <label for="sdxl_style">Style Preset:</label>
        <select id="sdxl_style">
          <option value="none">None</option>
          <option value="cinematic">Cinematic</option>
          <option value="photographic">Photographic</option>
          <option value="anime">Anime</option>
          <option value="manga">Manga</option>
          <option value="digital_art">Digital Art</option>
          <option value="pixel_art">Pixel art</option>
          <option value="fantasy_art">Fantasy art</option>
          <option value="neonpunk">Neonpunk</option>
          <option value="3d_model">3D Model</option>
        </select>
        
        <label for="quality_tags">Add Quality Tags:</label>
        <input type="checkbox" id="quality_tags">
        
        <div id="quality_tags_presets_container" style="display: none;">
          <label for="quality_tags_presets">Quality Tags Presets:</label>
          <select id="quality_tags_presets">
            <option value="none">None</option>
            <option value="standard_v3.0">Standard v3.0</option>
            <option value="standard_v3.1">Standard v3.1</option>
            <option value="light_v3.1">Light v3.1</option>
            <option value="heavy_v3.1">Heavy v3.1</option>
          </select>
        </div>
        
        <label for="upscaler">Use Upscaler:</label>
        <input type="checkbox" id="upscaler">
        
        <div id="upscaler_options" style="display:none;">
          <label for="upscale_method">Upscale Method:</label>
          <select id="upscale_method">
            <option value="nearest_exact">Nearest Exact</option>
            <option value="bicubic">Bicubic</option>
            <option value="bilinear">Bilinear</option>
          </select>

          <label for="upscale_strength">Upscaler Strength (0-1):</label>
          <input type="number" id="upscale_strength" value="0.55" min="0" max="1" step="0.01">
          
          <label for="upscale_by">Upscale By:</label>
          <input type="number" id="upscale_by" value="1.5" step="0.01" min="1" max="1.5" style="width: 100%;">
          
          <label>New Resolution:</label>
          <output id="new_resolution">1536 x 1536</output>
        </div>
      </div>
    </div>
    
    <button id="generate">Generate Image</button>
    <div id="progress">
      <div id="loading-placeholder"></div>
      <div id="progress-bar">0%</div>
    </div>
    
    <div id="result"><p class="result-placeholder">Your generated image will appear here.</p></div>
    
    <div id="history">
      <h2>Generated History</h2>
      <div id="history-items"></div>
    </div>
  </div>
  
  <script>
    (function () {
      let isGenerating = false;
      document.addEventListener("DOMContentLoaded", () => {
        const generateButton = document.getElementById("generate");
        const modelSelect = document.getElementById("model");
        const promptInput = document.getElementById("prompt");
        const strictionInput = document.getElementById("striction");
        const stepsInput = document.getElementById("steps");
        const scaleInput = document.getElementById("scale");
        const widthInput = document.getElementById("width");
        const heightInput = document.getElementById("height");
        const samplerSelect = document.getElementById("sampler");
        const clipGuidancePreset = document.getElementById("clip_guidance_preset");
        const seedInput = document.getElementById("seed");
        const sdxlStyleSelect = document.getElementById("sdxl_style");
        const qualityTagsCheckbox = document.getElementById("quality_tags");
        const qualityTagsPresetsSelect = document.getElementById("quality_tags_presets");
        const upscalerCheckbox = document.getElementById("upscaler");
        const upscalerOptionsDiv = document.getElementById("upscaler_options");
        const qualityTagsPresetsContainer = document.getElementById("quality_tags_presets_container");
        const upscaleByInput = document.getElementById("upscale_by");
        const newResolutionOutput = document.getElementById("new_resolution");
        const resultDiv = document.getElementById("result");
        const historyDiv = document.getElementById("history-items");
        const progressBar = document.getElementById("progress-bar");
        const loadingPlaceholder = document.getElementById("loading-placeholder");
        const settingsHeader = document.getElementById("settings-header");
        const settingsContent = document.getElementById("settings-content");
        const widthOutput = document.getElementById("widthOutput");
        const heightOutput = document.getElementById("heightOutput");

        const simulateProgress = (computeTime) => {
          const duration = computeTime ? parseFloat(computeTime) * 1000 : 5000;
          const startTime = Date.now();
          loadingPlaceholder.style.opacity = "1";
          let intervalId = setInterval(() => {
            const elapsed = Date.now() - startTime;
            const progress = Math.min((elapsed / duration) * 100, 100);
            progressBar.style.width = `${progress}%`;
            progressBar.textContent = `${Math.floor(progress)}%`;
            loadingPlaceholder.style.opacity = `${1 - progress / 100}`;
            if (progress >= 100) {
              clearInterval(intervalId);
              loadingPlaceholder.style.opacity = "0";
            }
          }, 100);
        };

        // Function to update the new resolution based on upscaling
        const updateNewResolution = () => {
          const width = parseInt(widthInput.value);
          const height = parseInt(heightInput.value);
          const upscaleFactor = parseFloat(upscaleByInput.value);
          const newWidth = Math.round(width * upscaleFactor);
          const newHeight = Math.round(height * upscaleFactor);
          newResolutionOutput.textContent = `${newWidth} x ${newHeight}`;
          widthOutput.textContent = width;
          heightOutput.textContent = height;
        };

        const fetchGeneratedImage = async () => {
          const payload = {
            inputs: promptInput.value.trim(),
            resolution: `${widthInput.value} x ${heightInput.value}`,
            guidance_scale: parseFloat(scaleInput.value),
            num_inference_steps: parseInt(stepsInput.value, 10),
            seed: parseInt(seedInput.value, 10) || Math.floor(Math.random() * 99999),
            sampler: samplerSelect.value,
            options: { wait_for_model: true }
          };

          // Add negative prompt if it is needed
          if (strictionInput.value.trim()) {
            payload.negative_prompt = strictionInput.value.trim();
          }

          // Include sdxl_style if selected
          if (sdxlStyleSelect.value !== "none") {
            payload.sdxl_style = sdxlStyleSelect.value;
          }

          // Include quality tags if the checkbox is checked
          if (qualityTagsCheckbox.checked) {
            payload.add_quality_tags = true;
            payload.quality_tags = qualityTagsPresetsSelect.value !== "none" ? qualityTagsPresetsSelect.value : undefined;
          }

          // Include upscaling parameters if upscaler is checked
          if (upscalerCheckbox.checked) {
            payload.use_upscaler = {
              upscale_method: document.getElementById("upscale_method").value,
              upscaler_strength: parseFloat(document.getElementById("upscale_strength").value),
              upscale_by: parseFloat(upscaleByInput.value),
            };
          }

          const response = await fetch(
            `https://api-inference.huggingface.co/models/${modelSelect.value}`,
            {
              method: "POST",
              headers: { Authorization: "Bearer <TRUFFLEHOG_REDACTED_HUGGINGFACE>", "Content-Type": "application/json" },
              body: JSON.stringify(payload),
            }
          );

          if (!response.ok) throw new Error(`Error: ${await response.text()}`);
          simulateProgress(response.headers.get("x-compute-time"));
          const blob = await response.blob();
          return URL.createObjectURL(blob);
        };

        const addGeneratedImage = (imageUrl) => {
          const imgElement = document.createElement("img");
          imgElement.src = imageUrl;
          imgElement.style = "width: 100%; display: block; border-radius: 8px;";
          resultDiv.innerHTML = "";
          resultDiv.appendChild(imgElement);
          const historyItem = document.createElement("div");
          historyItem.className = "history-item";
          historyItem.innerHTML = `<img src="${imageUrl}" /><p>${promptInput.value || "No Prompt"}</p>`;
          historyDiv.appendChild(historyItem);
        };

        generateButton.addEventListener("click", async () => {
          if (isGenerating) return;
          isGenerating = true;
          progressBar.textContent = "0%";
          progressBar.style.width = "0%";
          try {
            const imageUrl = await fetchGeneratedImage();
            addGeneratedImage(imageUrl);
          } catch (err) { alert(err.message); }
          isGenerating = false;
        });

        settingsHeader.addEventListener("click", () => {
          settingsContent.style.display = settingsContent.style.display === "block" ? "none" : "block";
        });

        upscalerCheckbox.addEventListener("change", () => {
          upscalerOptionsDiv.style.display = upscalerCheckbox.checked ? "block" : "none";
        });

        qualityTagsCheckbox.addEventListener("change", () => {
          qualityTagsPresetsContainer.style.display = qualityTagsCheckbox.checked ? "block" : "none";
        });

        // Update the new resolution on slider changes
        widthInput.addEventListener("input", updateNewResolution);
        heightInput.addEventListener("input", updateNewResolution);
        upscaleByInput.addEventListener("input", updateNewResolution);

        // Initialize values
        updateNewResolution();
      });
    })();
  </script>
</body>
</html>

""".


SOME THINGS TO CONSIDER FOR UPGRADE:


"""


Justin-Choo/epiCRealism-Natural_Sin_RC1_VAE

cagliostrolab/animagine-xl-3.1




EXAMPLE STRUCTURE:


"""

{
prompt: ""
,
negative_prompt: ""
,
resolution: "1024 x 1024"
,
guidance_scale: 7
,
num_inference_steps: 28
,
seed: 849163782
,
sampler: "Euler a"
,
sdxl_style: "Pixel art"
,
add_quality_tags: true
,
quality_tags: "Heavy v3.1"
,
use_upscaler: {
upscale_method: "nearest-exact"
,
upscaler_strength: 0.55
,
upscale_by: 1.5
,
new_resolution: "1536 x 1536"
}
}

""".



STYLES CAN BE:


"""

Style Preset
(None)
Cinematic
Photographic
Anime
Manga
Digital Art
Pixel art
Fantasy art
Neonpunk
3D Model

""".



Use Upscaler CAN BE:

"""

Strength 0 - 1
Upscale by 1 - 1.5

""".



ADDITIONAL SAMPLERS CAN BE:


"""

DPM++ 2M Karras
DPM++ SDE Karras
DPM++ 2M SDE Karras
Euler
Euler a
DDIM

""".



Add Quality Tags
Quality Tags Presets CAN BE:


"""

(None)
Standard v3.0
Standard v3.1
Light v3.1
Heavy v3.1

""".



NOT SURE BUT THEY SEEM AUTOMATICALLY CALCULATING NEW RESOLUTION BASED ON THESE TWO UPSCALE SLIDERS AND HIDDEN BY DEFAULT UNTIL RADIO BUTTON IS PRESSED.

ALSO, LEAVE ORIGINAL RESOLUTION SELECTORS WITH SLIDERS AND THROUGH 8 STEP FOR WIDTH/HEIGHT.

USERS SHOULD NOT BE ALLOWED TO MANUALLY ENTER NEW AND ACTUAL RESOLUTIONS VALUES, OTHERWISE COULD BE AN ERROR.


ALSO, WE CAN PLACE "<output></output>" IN RESOLUTION INLINE TOGETHER WITH "<label for="width">Width (px):</label>" AS: "<label for="width">Width (<output></output> px):</label>" FOR BOTH WIDTH/HEIGHT ABOVE THEIR CORRESPONDING SLIDERS IN LABELS. BECAUSE THEY CURRENTLY EATING THREE ROWS FOR EACH WHICH IS NOT LOOKING NICE.





PROBABLY "use_upscaler	null" SHOULD NOT BE INCLUDED IN JSON IF RADIO BUTTON UNCHECKED. ALSO, "quality_tags	"none"" AND "sdxl_style	"none"" SHOULD NOT BE INCLUDED IN JSON PAYLOAD IF THEIR RADIO BUTTONS UNCHECKED. BECAUSE THIS IMPROPERLY STRUCTURED JSON PAYLOAD COULD MESS THINGS AND RETURN ERRORS FROM OTHER MODELS IN CONCEPT IF SELECTED. ALSO, "add_quality_tags	false" SHOULD ALSO BE EXCLUDED FROM JSON IF RADIO BUTTON UNCHECKED AND IT SHOULD ACT SIMILARLY AS UPSCALE TO HIDE AND SHOW A SELECTION MENU BASED ON RADIO BUTTON STATE. ALSO, NEED TO HIDE NEGATIVE PROMPT FIELD INSIDE SETTINGS MENU AT ITS TOP.

""".




















SHOULD WE ENWIRE THEN AN NLP AI TO GENERATE A NEGATIVE PROMPT BASED ON STYLES SELECTED AND ACTUAL PROMPT SENT BY USER?
also, need to remove that useless loading range, because it makes no sense without anything returned from their hf inference.
also, all information without any popup alerts should be returned from that "<p class="result-placeholder">Your generated image will appear here.</p>", including all errors, states, and everything else.

original apikey for testing should be included!