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>
    </select>
    <label for="prompt">Prompt:</label>
    <textarea id="prompt" rows="4" placeholder="Enter your generation prompt..."></textarea>
    <label for="striction">Striction:</label>
    <textarea id="striction" rows="2" placeholder="What NOT to draw..."></textarea>
    <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 (px):</label>
        <input type="number" id="width" value="768" min="32" max="2048" step="8">
        <label for="height">Height (px):</label>
        <input type="number" 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>
        </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">
      </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 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 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);
        };

        const fetchGeneratedImage = async () => {
          const payload = {
            inputs: promptInput.value.trim(),
            parameters: {
              num_inference_steps: parseInt(stepsInput.value, 10),
              guidance_scale: parseFloat(scaleInput.value),
              width: parseInt(widthInput.value, 10),
              height: parseInt(heightInput.value, 10),
              seed: parseInt(seedInput.value, 10) || Math.floor(Math.random() * 99999),
              sampler: samplerSelect.value,
              negative_prompt: strictionInput.value.trim(),
              clip_guidance_preset: clipGuidancePreset.value,
            },
            options: { wait_for_model: true },
          };
          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";
        });
      });
    })();
  </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.