<!doctype html>
<html class="sl-theme-dark">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
    <meta content="Comet" property="og:title" />
    <meta
      content="Stremio's fastest torrent/debrid search add-on."
      property="og:description"
    />
    <meta content="https://comet.feels.legal" property="og:url" />
    <meta
      content="https://raw.githubusercontent.com/g0ldyy/comet/refs/heads/main/comet/assets/icon.png"
      property="og:image"
    />
    <meta content="#6b6ef8" data-react-helmet="true" name="theme-color" />

    <title>Comet - Stremio's fastest torrent/debrid search add-on.</title>
    <link
      id="favicon"
      rel="icon"
      type="image/x-icon"
      href="https://raw.githubusercontent.com/g0ldyy/comet/refs/heads/main/comet/assets/icon.png"
    />

    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.20.1/cdn/themes/dark.css"
    />
    <script
      type="module"
      src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.20.1/cdn/shoelace-autoloader.js"
    ></script>

    <style>
      :not(:defined) {
        visibility: hidden;
      }

      body {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        min-height: 100vh;
        margin: 0;
        background: radial-gradient(
          ellipse at bottom,
          #25292c 0%,
          #0c0d13 100%
        );
        font-family:
          system-ui,
          -apple-system,
          "Segoe UI",
          Roboto,
          "Helvetica Neue",
          "Noto Sans",
          "Liberation Sans",
          Arial,
          sans-serif,
          "Apple Color Emoji",
          "Segoe UI Emoji",
          "Segoe UI Symbol",
          "Noto Color Emoji";
        font-size: 1rem;
        font-weight: 400;
      }

      ::-webkit-scrollbar {
        overflow: hidden;
      }

      .header {
        text-align: center;
        width: 40%;
        margin-bottom: 20px;
        margin-top: 50px;
      }

      .comet-text {
        font-size: calc(1.375rem + 1.5vw);
        font-weight: 500;
        margin-bottom: 0;
      }

      .emoji {
        width: 1em;
        height: 1em;
        vertical-align: middle;
      }

      .form-container {
        background-color: #1a1d20;
        padding: 2rem;
        border-radius: 0.375rem;
        box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
        width: 80vw;
        max-width: 950px;
        margin-bottom: 50px;
      }

      .form-item {
        margin-bottom: 0.75rem;
      }

      sl-details {
        margin-bottom: 0.75rem;
      }

      .centered-item {
        display: flex;
        justify-content: center;
      }

      .margin-left-install {
        margin-right: 10px;
      }

      .stars {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 120%;
        transform: rotate(-45deg);
        z-index: -1;
      }

      .star {
        --star-color: var(--primary-color);
        --star-tail-length: 6em;
        --star-tail-height: 2px;
        --star-width: calc(var(--star-tail-length) / 6);
        --fall-duration: 9s;
        --tail-fade-duration: var(--fall-duration);
        position: absolute;
        top: var(--top-offset);
        left: 0;
        width: var(--star-tail-length);
        height: var(--star-tail-height);
        color: var(--star-color);
        background: linear-gradient(45deg, currentColor, transparent);
        border-radius: 50%;
        filter: drop-shadow(0 0 6px currentColor);
        transform: translate3d(104em, 0, 0);
        animation:
          fall var(--fall-duration) var(--fall-delay) linear infinite,
          tail-fade var(--tail-fade-duration) var(--fall-delay) ease-out
            infinite;
      }

      @media screen and (max-width: 750px) {
        .star {
          animation: fall var(--fall-duration) var(--fall-delay) linear infinite;
        }
      }

      .star::before,
      .star::after {
        position: absolute;
        content: "";
        top: 0;
        left: calc(var(--star-width) / -2);
        width: var(--star-width);
        height: 100%;
        background: linear-gradient(
          45deg,
          transparent,
          currentColor,
          transparent
        );
        border-radius: inherit;
        animation: blink 2s linear infinite;
      }

      .star::before {
        transform: rotate(45deg);
      }

      .star::after {
        transform: rotate(-45deg);
      }

      @keyframes fall {
        to {
          transform: translate3d(-30em, 0, 0);
        }
      }

      @keyframes tail-fade {
        0%,
        50% {
          width: var(--star-tail-length);
          opacity: 1;
        }

        70%,
        80% {
          width: 0;
          opacity: 0.4;
        }

        100% {
          width: 0;
          opacity: 0;
        }
      }

      @keyframes blink {
        50% {
          opacity: 0.6;
        }
      }

      /* Custom Styles */
      .form-item label {
        display: flex;
        align-items: center;
        margin-bottom: 8px;
        font-weight: 500;
      }

      #apiKeyLink,
      #referralLink {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        background: rgba(255, 255, 255, 0.1);
        backdrop-filter: blur(10px);
        -webkit-backdrop-filter: blur(10px);
        color: white;
        padding: 4px 10px;
        border-radius: 12px;
        text-decoration: none;
        font-size: 0.7rem;
        font-weight: 600;
        margin-left: 8px;
        border: 1px solid rgba(255, 255, 255, 0.25);
        box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        transition: all 0.3s ease;
        line-height: normal;
        height: auto;
      }

      #apiKeyLink:hover,
      #referralLink:hover {
        background: rgba(255, 255, 255, 0.2);
        border-color: rgba(255, 255, 255, 0.4);
        transform: translateY(-1px);
        box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2);
      }

      #apiKeyLink:empty,
      #referralLink:empty {
        display: none;
      }

      .discord-btn::part(base) {
        background-color: #5865f2;
        border-color: #5865f2;
        color: white;
        font-weight: 600;
        display: flex;
        align-items: center;
      }

      .discord-btn::part(base):hover {
        background-color: #4752c4;
        border-color: #4752c4;
      }

      .heart-button {
        position: fixed;
        top: 20px;
        right: 20px;
        z-index: 1000;
        background: rgba(255, 255, 255, 0.1);
        backdrop-filter: blur(10px);
        border: 1px solid rgba(255, 255, 255, 0.2);
        border-radius: 50%;
        width: 45px;
        height: 45px;
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
        transition: all 0.3s ease;
        padding: 0;
      }

      .heart-button:hover {
        background: rgba(255, 255, 255, 0.2);
        transform: scale(1.1);
      }

      .heart-button sl-icon {
        color: #ff4757;
        font-size: 1.4rem;
        display: flex;
      }

      @keyframes heartbeat {
        0% {
          transform: scale(1);
        }

        14% {
          transform: scale(1.1);
        }

        28% {
          transform: scale(1);
        }

        42% {
          transform: scale(1.1);
        }

        70% {
          transform: scale(1);
        }
      }
    </style>
  </head>

  <body>
    <div class="stars"></div>

    <script>
      let hasTouchScreen = false;
      if ("maxTouchPoints" in navigator) {
        hasTouchScreen = navigator.maxTouchPoints > 0;
      } else if ("msMaxTouchPoints" in navigator) {
        hasTouchScreen = navigator.msMaxTouchPoints > 0;
      } else {
        const mQ = matchMedia?.("(pointer:coarse)");
        if (mQ?.media === "(pointer:coarse)") {
          hasTouchScreen = !!mQ.matches;
        } else if ("orientation" in window) {
          hasTouchScreen = true;
        } else {
          const UA = navigator.userAgent;
          hasTouchScreen =
            /\b(BlackBerry|webOS|iPhone|IEMobile)\b/i.test(UA) ||
            /\b(Android|Windows Phone|iPad|iPod)\b/i.test(UA);
        }
      }

      if (!hasTouchScreen) {
        document.addEventListener("DOMContentLoaded", function () {
          const starsContainer = document.querySelector(".stars");
          const starCount = 30;

          for (let i = 0; i < starCount; i++) {
            const star = document.createElement("div");
            star.classList.add("star");

            const randomTopOffset = Math.random() * 100;
            const randomLeftOffset = 80 + Math.random() * 40;
            const randomTailLength = 5 + Math.random() * 2.5;
            const randomFallDuration = 6 + Math.random() * 6;

            star.style.setProperty("--top-offset", `${randomTopOffset}vh`);
            star.style.setProperty(
              "--star-tail-length",
              `${randomTailLength}em`,
            );
            star.style.setProperty("--fall-duration", `${randomFallDuration}s`);
            star.style.setProperty("--fall-delay", "0s");
            star.style.transform = `translate3d(${randomLeftOffset}em, 0, 0)`;

            starsContainer.appendChild(star);
          }
        });
      }
    </script>
    <div class="header">
      <div
        style="
          display: flex;
          align-items: center;
          justify-content: center;
          gap: 15px;
          margin-bottom: 10px;
          height: 50px;
        "
      >
        <p
          class="comet-text"
          style="margin: 0; display: flex; align-items: center; line-height: 1"
        >
          <img
            class="emoji"
            src="https://fonts.gstatic.com/s/e/notoemoji/latest/1f4ab/512.gif"
            style="margin-right: 10px"
          />
          Comet
        </p>
        <sl-button
          href="https://discord.com/invite/UJEqpT42nb"
          target="_blank"
          size="small"
          pill
          class="discord-btn"
          style="display: flex; align-items: center"
        >
          <sl-icon
            slot="prefix"
            name="discord"
            style="font-size: 1rem"
          ></sl-icon>
          Discord
        </sl-button>
      </div>
      {{CUSTOM_HEADER_HTML|safe}}
    </div>

    <div class="form-container">
      <!-- <div class="form-item">
        <sl-select
          id="languages_required"
          multiple
          clearable
          label="Required Languages"
          placeholder="Select required languages"
        ></sl-select>
      </div> -->

      <div class="form-item">
        <sl-select
          id="languages_preferred"
          multiple
          clearable
          label="Preferred Languages"
          placeholder="Select preferred languages"
        ></sl-select>
      </div>

      <div class="form-item">
        <sl-select
          id="languages_excluded"
          multiple
          clearable
          label="Excluded Languages"
          placeholder="Select excluded languages"
        ></sl-select>
      </div>

      <div class="form-item">
        <sl-select
          id="resolutions"
          multiple
          clearable
          label="Resolutions"
          placeholder="Select resolutions"
        >
          <sl-option value="r2160p">4K - 2160p</sl-option>
          <sl-option value="r1080p">Full HD - 1080p</sl-option>
          <sl-option value="r720p">HD - 720p</sl-option>
          <sl-option value="r480p">SD - 480p</sl-option>
          <sl-option value="r360p">LD - 360p</sl-option>
          <sl-option value="unknown">Unknown</sl-option>
        </sl-select>
      </div>

      <div class="form-item">
        <sl-input
          id="maxResultsPerResolution"
          type="number"
          min="0"
          value="0"
          label="Max Results Per Resolution"
          placeholder="Enter max results per resolution"
        ></sl-input>
      </div>

      <div class="form-item">
        <sl-input
          id="maxSize"
          type="number"
          min="0"
          value="0"
          label="Max Size (GB)"
          placeholder="Enter max size in gigabytes"
        ></sl-input>
      </div>

      <div
        class="form-item"
        {%
        if
        not
        proxyDebridStream
        %}style="display: none"
        {%
        endif
        %}
      >
        <sl-input
          id="debridStreamProxyPassword"
          label="Debrid Stream Proxy Password"
          placeholder="Enter password"
          help-text="Debrid Stream Proxying allows you to use your Debrid Service from multiple IPs at same time!"
        ></sl-input>
      </div>

      {% set default_debrid_service = 'realdebrid' if disableTorrentStreams else
      'torrent' %}
      <div class="form-item">
        <sl-select
          id="debridService"
          value="{{ default_debrid_service }}"
          data-default-service="{{ default_debrid_service }}"
          data-disable-torrent="{{ 'true' if disableTorrentStreams else 'false' }}"
          label="Debrid Service"
          placeholder="Select debrid service"
        >
          {% if not disableTorrentStreams %}
          <sl-option value="torrent">Torrent</sl-option>
          {% endif %}
          <sl-option value="torbox">TorBox</sl-option>
          <sl-option value="realdebrid">Real-Debrid</sl-option>
          <sl-option value="alldebrid">All-Debrid</sl-option>
          <sl-option value="debridlink">Debrid-Link</sl-option>
          <sl-option value="premiumize">Premiumize</sl-option>
          <sl-option value="debrider">Debrider</sl-option>
          <sl-option value="easydebrid">EasyDebrid</sl-option>
          <sl-option value="offcloud">Offcloud</sl-option>
          <sl-option value="pikpak">PikPak</sl-option>
        </sl-select>
      </div>

      <div class="form-item">
        <label for="debridService">
          Debrid API Key
          <a id="referralLink" href="" target="_blank"></a>
          <a id="apiKeyLink" href="" target="_blank"></a>
        </label>
        <sl-input id="debridApiKey" placeholder="Enter API key"></sl-input>
      </div>

      <sl-details summary="Advanced Settings">
        <div class="form-item">
          <sl-input
            id="rankThreshold"
            type="number"
            value="-10000000000"
            label="Minimum Rank Threshold"
            placeholder="Enter minimum rank threshold"
            help-text="Torrents ranked below this value will be excluded from results."
          ></sl-input>
          <sl-checkbox
            id="cachedOnly"
            help-text="Show only content that has already been cached."
            >Show Cached Only</sl-checkbox
          >
          <sl-checkbox
            id="sortCachedUncachedTogether"
            help-text="Disable the default behavior of sorting cached results first, and instead mixes cached and uncached results together."
            >Sort Cached and Uncached Together</sl-checkbox
          >
          <sl-checkbox
            id="allowEnglishInLanguages"
            help-text="Allows English language torrents to be included even if you excluded English from your language preferences."
            >Allow English in Languages</sl-checkbox
          >
          <sl-checkbox
            id="removeUnknownLanguages"
            help-text="Exclude torrents that don't have a language in the title."
            >Remove Unknown Languages</sl-checkbox
          >
          <sl-checkbox
            checked
            id="removeTrash"
            help-text="Remove all trash from results (if disabled, your filters will not be applied - Adult Content, CAM, Clean Audio, PDTV, R5, Screener, Size, Telecine and Telesync)"
            >Remove Trash</sl-checkbox
          >
          <sl-select
            id="resultFormat"
            multiple
            label="Result Format"
            placeholder="Select what to show in result title"
            hoist
            max-options-visible="10"
          >
          </sl-select>
        </div>
      </sl-details>

      <script>
        const debridServiceElement = document.getElementById("debridService");
        const torrentDisabled =
          debridServiceElement.dataset.disableTorrent === "true";
        const defaultDebridService =
          debridServiceElement.dataset.defaultService;
        window.disableTorrentStreams = torrentDisabled;
        window.defaultDebridService = defaultDebridService;

        debridServiceElement.addEventListener("sl-change", function (event) {
          const selectedService = event.target.value;
          const apiKeyLink = document.getElementById("apiKeyLink");
          const apiKeyInput = document.getElementById("debridApiKey");

          const referralLink = document.getElementById("referralLink");

          // Reset links
          apiKeyLink.href = "";
          apiKeyLink.textContent = "";
          apiKeyLink.style.display = "none";

          referralLink.href = "";
          referralLink.textContent = "";
          referralLink.style.display = "none";

          if (selectedService === "realdebrid") {
            apiKeyLink.href = "https://real-debrid.com/apitoken";
            apiKeyLink.textContent = "Get it here";
            apiKeyLink.style.display = "inline-block";

            referralLink.href = "http://real-debrid.com/?id=16161532";
            referralLink.textContent = "Sign up here";
            referralLink.style.display = "inline-block";
          } else if (selectedService === "alldebrid") {
            apiKeyLink.href = "https://alldebrid.com/apikeys";
            apiKeyLink.textContent = "Get it here";
            apiKeyLink.style.display = "inline-block";
          } else if (selectedService === "premiumize") {
            apiKeyLink.href = "https://premiumize.me/account";
            apiKeyLink.textContent = "Get it here";
            apiKeyLink.style.display = "inline-block";
          } else if (selectedService === "torbox") {
            apiKeyLink.href = "https://torbox.app/settings";
            apiKeyLink.textContent = "Get it here";
            apiKeyLink.style.display = "inline-block";

            referralLink.href =
              "https://torbox.app/subscription?referral=1ffb2238-1c5f-402e-a2ce-3d7a86c52d02";
            referralLink.textContent = "Sign up here";
            referralLink.style.display = "inline-block";
          } else if (selectedService === "debrider") {
            apiKeyLink.href = "https://debrider.app/dashboard/account";
            apiKeyLink.textContent = "Get it here";
            apiKeyLink.style.display = "inline-block";
          } else if (selectedService === "easydebrid") {
            apiKeyLink.href = "https://paradise-cloud.com/products/easydebrid";
            apiKeyLink.textContent = "Get it here";
            apiKeyLink.style.display = "inline-block";
          } else if (selectedService === "debridlink") {
            apiKeyLink.href = "https://debrid-link.com/webapp/apikey";
            apiKeyLink.textContent = "Get it here";
            apiKeyLink.style.display = "inline-block";

            referralLink.href = "https://debrid-link.fr/id/G7mli";
            referralLink.textContent = "Sign up here";
            referralLink.style.display = "inline-block";
          } else if (selectedService === "offcloud") {
            apiKeyLink.href = "https://offcloud.com";
            apiKeyLink.textContent = "Get it here";
            apiKeyLink.style.display = "inline-block";
          } else if (selectedService === "pikpak") {
            apiKeyLink.href = "https://mypikpak.com";
            apiKeyLink.textContent = "Get it here";
            apiKeyLink.style.display = "inline-block";
          }

          if (selectedService === "offcloud" || selectedService === "pikpak") {
            apiKeyInput.helpText = "Format: `email:password`";
          } else if (!torrentDisabled && selectedService === "torrent") {
            apiKeyInput.helpText = "";
          } else {
            apiKeyInput.helpText = "Format: `api-key`";
          }

          if (!torrentDisabled && selectedService === "torrent") {
            apiKeyInput.disabled = true;
          } else {
            apiKeyInput.disabled = false;
          }
        });
      </script>

      <div class="centered-item">
        <sl-button id="install" variant="neutral" class="margin-left-install"
          >Install</sl-button
        >
        <sl-alert id="installAlert" variant="neutral" duration="3000" closable>
          <sl-icon slot="icon" name="clipboard2-check"></sl-icon>
          <strong>Attempting to add the addon to Stremio...</strong>
        </sl-alert>

        <sl-button id="copy-link" variant="neutral">Copy Link</sl-button>
        <sl-alert id="copyAlert" variant="neutral" duration="3000" closable>
          <sl-icon slot="icon" name="clipboard2-check"></sl-icon>
          <strong>The Stremio addon link has been automatically copied.</strong>
        </sl-alert>

        <script type="module">
          const languagesEmojis = {
            "multi": "🌎",
            "en": "🇬🇧",  // English
            "ja": "🇯🇵",  // Japanese
            "zh": "🇨🇳",  // Chinese
            "ru": "🇷🇺",  // Russian
            "ar": "🇸🇦",  // Arabic
            "pt": "🇵🇹",  // Portuguese
            "es": "🇪🇸",  // Spanish
            "fr": "🇫🇷",  // French
            "de": "🇩🇪",  // German
            "it": "🇮🇹",  // Italian
            "ko": "🇰🇷",  // Korean
            "hi": "🇮🇳",  // Hindi
            "bn": "🇧🇩",  // Bengali
            "pa": "🇵🇰",  // Punjabi
            "mr": "🇮🇳",  // Marathi
            "gu": "🇮🇳",  // Gujarati
            "ta": "🇮🇳",  // Tamil
            "te": "🇮🇳",  // Telugu
            "kn": "🇮🇳",  // Kannada
            "ml": "🇮🇳",  // Malayalam
            "th": "🇹🇭",  // Thai
            "vi": "🇻🇳",  // Vietnamese
            "id": "🇮🇩",  // Indonesian
            "tr": "🇹🇷",  // Turkish
            "he": "🇮🇱",  // Hebrew
            "fa": "🇮🇷",  // Persian
            "uk": "🇺🇦",  // Ukrainian
            "el": "🇬🇷",  // Greek
            "lt": "🇱🇹",  // Lithuanian
            "lv": "🇱🇻",  // Latvian
            "et": "🇪🇪",  // Estonian
            "pl": "🇵🇱",  // Polish
            "cs": "🇨🇿",  // Czech
            "sk": "🇸🇰",  // Slovak
            "hu": "🇭🇺",  // Hungarian
            "ro": "🇷🇴",  // Romanian
            "bg": "🇧🇬",  // Bulgarian
            "sr": "🇷🇸",  // Serbian
            "hr": "🇭🇷",  // Croatian
            "sl": "🇸🇮",  // Slovenian
            "nl": "🇳🇱",  // Dutch
            "da": "🇩🇰",  // Danish
            "fi": "🇫🇮",  // Finnish
            "sv": "🇸🇪",  // Swedish
            "no": "🇳🇴",  // Norwegian
            "ms": "🇲🇾",  // Malay
            "la": "💃🏻",  // Latino
          };
          let defaultResultFormat = [];

          document.addEventListener("DOMContentLoaded", async () => {
            await Promise.allSettled([
              customElements.whenDefined("sl-button"),
              customElements.whenDefined("sl-alert"),
              customElements.whenDefined("sl-select"),
              customElements.whenDefined("sl-input"),
              customElements.whenDefined("sl-option"),
              customElements.whenDefined("sl-icon"),
              customElements.whenDefined("sl-checkbox")
            ]);

            const webConfig = {{ webConfig| tojson }};


          const resolutionsSelect = document.getElementById("resolutions");
          resolutionsSelect.value = ["r2160p", "r1080p", "r720p", "r480p", "r360p", "unknown"];

          populateSelect("resultFormat", webConfig.resultFormat);
          defaultResultFormat = webConfig.resultFormat;
          const resultFormatSelect = document.getElementById("resultFormat");
          resultFormatSelect.value = defaultResultFormat;

          // try populate the form from previous settings
          try {
            const settings = getSettingsFromUrl();
            if (settings != null) { populateFormFromSettings(settings); }
          } catch (error) {
            console.log("Failed to retrieve or parse settings from URL:", error);
          }

          // trigger sl-change event on debridService to set initial state
          const debridServiceSelect = document.getElementById("debridService");
          debridServiceSelect.dispatchEvent(new Event("sl-change"));

          // Populate language selects
          // populateSelect("languages_required", Object.keys(languagesEmojis));
          populateSelect("languages_excluded", Object.keys(languagesEmojis));
          populateSelect("languages_preferred", Object.keys(languagesEmojis));

          document.body.classList.add("ready");
                });

          function populateSelect(selectId, options) {
            const selectElement = document.getElementById(selectId);

            const languageNames = {
              "multi": "Multi",
              "en": "English",
              "ja": "Japanese",
              "zh": "Chinese",
              "ru": "Russian",
              "ar": "Arabic",
              "pt": "Portuguese",
              "es": "Spanish",
              "fr": "French",
              "de": "German",
              "it": "Italian",
              "ko": "Korean",
              "hi": "Hindi",
              "bn": "Bengali",
              "pa": "Punjabi",
              "mr": "Marathi",
              "gu": "Gujarati",
              "ta": "Tamil",
              "te": "Telugu",
              "kn": "Kannada",
              "ml": "Malayalam",
              "th": "Thai",
              "vi": "Vietnamese",
              "id": "Indonesian",
              "tr": "Turkish",
              "he": "Hebrew",
              "fa": "Persian",
              "uk": "Ukrainian",
              "el": "Greek",
              "lt": "Lithuanian",
              "lv": "Latvian",
              "et": "Estonian",
              "pl": "Polish",
              "cs": "Czech",
              "sk": "Slovak",
              "hu": "Hungarian",
              "ro": "Romanian",
              "bg": "Bulgarian",
              "sr": "Serbian",
              "hr": "Croatian",
              "sl": "Slovenian",
              "nl": "Dutch",
              "da": "Danish",
              "fi": "Finnish",
              "sv": "Swedish",
              "no": "Norwegian",
              "ms": "Malay",
              "la": "Latino"
            };

            options.forEach(option => {
              const optionElement = document.createElement("sl-option");
              optionElement.value = option;

              if (selectId.startsWith('languages')) {
                const flag = languagesEmojis[option] || '';
                const fullName = languageNames[option] || option;
                optionElement.textContent = `${flag} ${fullName}`;
              } else {
                optionElement.textContent = option;
              }

              selectElement.appendChild(optionElement);
            });
          }

          const installButton = document.querySelector("#install");
          const installAlert = document.querySelector('#installAlert');
          const copyLinkButton = document.querySelector("#copy-link");
          const copyAlert = document.querySelector('#copyAlert');

          function getSettings() {
            // const languages_required = Array.from(document.getElementById("languages_required").selectedOptions).map(option => option.value);
            const languages_excluded = Array.from(document.getElementById("languages_excluded").selectedOptions).map(option => option.value);
            const languages_preferred = Array.from(document.getElementById("languages_preferred").selectedOptions).map(option => option.value);
            const selectedResolutions = Array.from(document.getElementById("resolutions").selectedOptions).map(option => option.value);
            const allResolutions = ["r2160p", "r1080p", "r720p", "r480p", "r360p", "unknown"];
            const resolutions = allResolutions.reduce((obj, res) => {
              // Only include resolutions that are NOT selected (disabled) as false
              if (!selectedResolutions.includes(res)) {
                obj[res] = false;
              }
              return obj;
            }, {});
            const rankThreshold = document.getElementById("rankThreshold").value;
            const maxResultsPerResolution = document.getElementById("maxResultsPerResolution").value;
            const maxSize = document.getElementById("maxSize").value;
            const cachedOnly = document.getElementById("cachedOnly").checked;
            const sortCachedUncachedTogether = document.getElementById("sortCachedUncachedTogether").checked;
            const removeTrash = document.getElementById("removeTrash").checked;
            const allowEnglishInLanguages = document.getElementById("allowEnglishInLanguages").checked;
            const removeUnknownLanguages = document.getElementById("removeUnknownLanguages").checked;
            const resultFormat = Array.from(document.getElementById("resultFormat").selectedOptions).map(option => option.value);
            let debridService = document.getElementById("debridService").value;
            if (window.disableTorrentStreams && debridService === "torrent") {
              debridService = window.defaultDebridService;
            }
            const debridApiKey = document.getElementById("debridApiKey").value;
            const debridStreamProxyPassword = document.getElementById("debridStreamProxyPassword").value;

            const selectedResultFormat = resultFormat.length === defaultResultFormat.length && resultFormat.every((val, index) => val === defaultResultFormat[index]) ? ["all"] : resultFormat;

            return {
              maxResultsPerResolution: parseInt(maxResultsPerResolution),
              maxSize: parseFloat(maxSize * 1073741824),
              cachedOnly: cachedOnly,
              sortCachedUncachedTogether: sortCachedUncachedTogether,
              removeTrash: removeTrash,
              resultFormat: selectedResultFormat,
              debridService: debridService,
              debridApiKey: debridApiKey,
              debridStreamProxyPassword: debridStreamProxyPassword,
              languages: {
                // required: languages_required,
                exclude: languages_excluded,
                preferred: languages_preferred
              },
              resolutions: resolutions,
              options: {
                remove_ranks_under: parseFloat(rankThreshold),
                allow_english_in_languages: allowEnglishInLanguages,
                remove_unknown_languages: removeUnknownLanguages
              }
            };
          }

          // Check if config matches all default values
          // If so, use /manifest.json instead of /{b64config}/manifest.json for better CDN caching
          function isDefaultConfig(settings) {
            // Must be torrent mode
            if (settings.debridService !== "torrent") {
              return false;
            }

            // Check all filtering fields match defaults
            // maxResultsPerResolution default is 0
            if (settings.maxResultsPerResolution !== 0) {
              return false;
            }

            // maxSize default is 0
            if (settings.maxSize !== 0) {
              return false;
            }

            // cachedOnly default is false
            if (settings.cachedOnly !== false) {
              return false;
            }

            // sortCachedUncachedTogether default is false
            if (settings.sortCachedUncachedTogether !== false) {
              return false;
            }

            // removeTrash default is true
            if (settings.removeTrash !== true) {
              return false;
            }

            // resultFormat default is ["all"]
            if (!settings.resultFormat || 
                settings.resultFormat.length !== 1 || 
                settings.resultFormat[0] !== "all") {
              return false;
            }

            // resolutions: all should be enabled (no false values in the object)
            // An empty object means all are enabled (default)
            for (const [res, enabled] of Object.entries(settings.resolutions || {})) {
              if (enabled === false) {
                return false;
              }
            }

            // languages: no excludes or preferences (empty arrays)
            if (settings.languages) {
              if (settings.languages.exclude && settings.languages.exclude.length > 0) {
                return false;
              }
              if (settings.languages.preferred && settings.languages.preferred.length > 0) {
                return false;
              }
            }

            // options: check defaults
            if (settings.options) {
              // remove_ranks_under default is -10000000000
              if (settings.options.remove_ranks_under !== -10000000000) {
                return false;
              }
              // allow_english_in_languages default is false
              if (settings.options.allow_english_in_languages !== false) {
                return false;
              }
              // remove_unknown_languages default is false
              if (settings.options.remove_unknown_languages !== false) {
                return false;
              }
            }

            return true;
          }

          // Generate the manifest URL - use /manifest.json for default configs
          function getManifestUrl(settings, forInstall = false) {
            const isDefault = isDefaultConfig(settings);
            const protocol = forInstall ? "stremio:" : window.location.protocol;
            const host = window.location.host;

            if (isDefault) {
              // Default config: use public manifest URL (better CDN caching)
              return forInstall
                ? `stremio://${host}/manifest.json`
                : `${window.location.origin}/manifest.json`;
            } else {
              // Custom config: use b64config in URL
              const settingsString = btoa(JSON.stringify(settings));
              return forInstall
                ? `stremio://${host}/${settingsString}/manifest.json`
                : `${window.location.origin}/${settingsString}/manifest.json`;
            }
          }

          copyLinkButton.addEventListener("click", () => {
            const settings = getSettings();
            const manifestUrl = getManifestUrl(settings, false);

            const textArea = document.createElement("textarea");
            textArea.value = manifestUrl;
            document.body.appendChild(textArea);
            textArea.focus();
            textArea.select();
            document.execCommand("copy");
            document.body.removeChild(textArea);

            console.log(isDefaultConfig(settings) ? "Using default manifest URL" : btoa(JSON.stringify(settings)));

            copyAlert.toast();
          });

          installButton.addEventListener("click", () => {
            const settings = getSettings();
            const manifestUrl = getManifestUrl(settings, true);
            window.location.href = manifestUrl;
            console.log(isDefaultConfig(settings) ? "Installing with default manifest" : btoa(JSON.stringify(settings)));
            installAlert.toast();
          });

          function getSettingsFromUrl() {
            const url = window.location.href;
            // Try parse settings from the URL
            if (url.split("/").length < 5) {
              console.log("no previous settings"); return null;
            }
            const settingsString = url.split("/")[3];
            if (typeof settingsString === "undefined") {
              console.log("can't fetch previous settings", settingsString)
              return null;
            }
            const settingsJson = atob(settingsString);
            return JSON.parse(settingsJson);
          }

          function populateFormFromSettings(settings) {
            if (settings.cachedOnly !== null)
              document.getElementById("cachedOnly").checked = settings.cachedOnly;
            if (settings.sortCachedUncachedTogether !== undefined && settings.sortCachedUncachedTogether !== null)
              document.getElementById("sortCachedUncachedTogether").checked = settings.sortCachedUncachedTogether;
            if (settings.removeTrash !== null)
              document.getElementById("removeTrash").checked = settings.removeTrash;
            if (settings.maxResultsPerResolution !== null)
              document.getElementById("maxResultsPerResolution").value = settings.maxResultsPerResolution;
            if (settings.maxSize !== null)
              document.getElementById("maxSize").value = settings.maxSize / 1073741824;
            if (settings.debridService !== null) {
              const debridServiceSelect = document.getElementById("debridService");
              const requestedService = settings.debridService;
              if (window.disableTorrentStreams && requestedService === "torrent") {
                debridServiceSelect.value = window.defaultDebridService;
              } else {
                debridServiceSelect.value = requestedService;
              }
            }
            if (settings.debridApiKey !== null)
              document.getElementById("debridApiKey").value = settings.debridApiKey;
            if (settings.debridStreamProxyPassword !== null)
              document.getElementById("debridStreamProxyPassword").value = settings.debridStreamProxyPassword;
            if (settings.resultFormat !== null && settings.resultFormat != "all")
              document.getElementById("resultFormat").value = settings.resultFormat;
            if (settings.languages) {
              // if (settings.languages.required)
              //     document.getElementById("languages_required").value = settings.languages.required;
              if (settings.languages.exclude)
                document.getElementById("languages_excluded").value = settings.languages.exclude;
              if (settings.languages.preferred)
                document.getElementById("languages_preferred").value = settings.languages.preferred;
            }
            if (settings.resolutions) {
              const allResolutions = ["r2160p", "r1080p", "r720p", "r480p", "r360p", "unknown"];
              const enabledResolutions = allResolutions.filter(res => settings.resolutions[res] !== false);
              document.getElementById("resolutions").value = enabledResolutions;
            }
            if (settings.options?.remove_ranks_under !== undefined)
              document.getElementById("rankThreshold").value = settings.options.remove_ranks_under;
            if (settings.options?.allow_english_in_languages !== undefined)
              document.getElementById("allowEnglishInLanguages").checked = settings.options.allow_english_in_languages;
            if (settings.options?.remove_unknown_languages !== undefined)
              document.getElementById("removeUnknownLanguages").checked = settings.options.remove_unknown_languages;
          }
        </script>
      </div>
    </div>

    <div class="heart-button" id="support-trigger">
      <sl-icon name="heart-fill"></sl-icon>
    </div>

    <sl-dialog label="Support Comet" id="support-dialog" style="--width: 400px">
      <div
        style="
          display: flex;
          flex-direction: column;
          align-items: center;
          text-align: center;
          gap: 0.5rem;
          margin-top: -15px;
        "
      >
        <div
          style="
            font-size: 2.5rem;
            animation: heartbeat 1.5s ease-in-out infinite;
          "
        >
          ❤️
        </div>
        <h3 style="margin: 0">Donate to Me</h3>
        <p
          style="
            color: var(--sl-color-neutral-500);
            margin: 0;
            font-size: 0.9rem;
          "
        >
          Comet is a passion project fueled by late nights and coffee. Your
          support helps keep the lights on and the updates rolling!
        </p>

        <div
          style="
            display: flex;
            flex-direction: column;
            gap: 8px;
            width: 100%;
            margin-top: 10px;
          "
        >
          <sl-button
            href="https://github.com/sponsors/g0ldyy"
            target="_blank"
            outline
            style="width: 100%"
          >
            <sl-icon slot="prefix" name="github"></sl-icon>
            GitHub Sponsors
          </sl-button>
          <sl-button
            href="https://ko-fi.com/g0ldyy"
            target="_blank"
            outline
            style="width: 100%; --sl-color-primary-600: #ff5e5b"
          >
            <sl-icon slot="prefix" name="cup-hot"></sl-icon>
            Ko-fi
          </sl-button>
        </div>
      </div>
    </sl-dialog>

    <script>
      const dialog = document.querySelector("#support-dialog");
      const openButton = document.querySelector("#support-trigger");
      openButton.addEventListener("click", () => dialog.show());
    </script>
  </body>
</html>
