<style>
  .hidden {
    display: none;
  }
  .question-prompt {
    margin-top: 56px;
    margin-bottom: 24px;
    font-style: italic;
  }
  esp-web-install-button {
    display: inline-block;
    margin-bottom: 24px;
  }
  .types label {
    display: flex;
    margin-bottom: 24px;
    align-items: top;
    flex-direction: column;
    position: relative;
    padding-left: 48px;
  }
  .types input {
    position: absolute;
    left: 16px;
  }
  .types .name {
    font-weight: bold;
  }
  .type {
    margin-top: 56px;
  }
  .radios {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
  }
  .radios label {
    padding: 4px;
    cursor: pointer;
    width: calc(33.3% - 16px);
    display: block;
    position: relative;
  }
  .radios input {
    position: absolute;
    top: 12px;
    left: 12px;
  }
  .radios img {
    display: block;
    width: calc(100% - 8px);
    border: 4px solid rgba(0, 0, 0, 0);
    aspect-ratio: 1;
  }
  .radios input:checked + img {
    border-color: #58a6ff;
  }
  @media only screen and (max-width: 450px) {
    .radios label {
      width: calc(50% - 16px);
      max-width: initial;
    }
  }
  .info ol {
    margin-top: 0;
    margin-bottom: 24px;
  }
  .info ol li {
    margin-bottom: 8px;
  }
  .diy::after {
    content: "DIY";
    background-color: #f44336;
    color: #fff;
    padding: 2px 4px;
    border-radius: 4px;
    font-size: 0.8em;
    position: absolute;
    bottom: 12px;
    left: 12px;
  }
  body .diy {
    display: none;
  }
  body.show-diy .diy {
    display: initial;
  }
  .installer-footer {
    margin-top: 56px;
    padding-top: 16px;
    font-size: 0.8em;
    border-top: 1px solid darkgrey;
  }
</style>
<script
  type="module"
  src="https://unpkg.com/esp-web-tools@10/dist/web/install-button.js?module"
></script>

<div class="admonition note unsupported hidden">
  <p class="admonition-title">Note</p>
  <p>
    This page requires a browser that supports WebSerial. Please open this
    website on your desktop using Google Chrome or Microsoft Edge.
  </p>
</div>

<div class="question-prompt">I want to create a:</div>
<div class="types">
  <label>
    <input type="radio" name="type" value="voice" checked />
    <div class="name">Voice assistant</div>
    <div class="description">
      Create a device to control Home Assistant with your voice.
    </div>
  </label>
  <label>
    <input type="radio" name="type" value="bluetooth" />
    <div class="name">Bluetooth proxy</div>
    <div class="description">
      Create a device to allow Home Assistant to control Bluetooth devices.
    </div>
  </label>
  <label>
    <input type="radio" name="type" value="media" />
    <div class="text">
      <div class="name">Media Player</div>
      <div class="description">
        Create an internet connected smart media player.
      </div>
    </div>
  </label>
  <label>
    <input type="radio" name="type" value="empty" />
    <div class="name">Empty ESPHome device</div>
    <div class="description">
      No special features built-in. Ready to make it your own.
    </div>
  </label>
</div>

<div
  class="type type-voice hidden"
  data-manifest-root="https://firmware.esphome.io/wake-word-voice-assistant"
>
  <div class="question-prompt">
    Pick the device you want to turn into a voice assistant:
  </div>
  <div class="radios">
    <label>
      <input
        type="radio"
        name="voice-device"
        class="device-option"
        value="m5stack-atom-echo"
        checked
      />
      <img
        src="/_static/projects/media-player/atom_echo.png"
        alt="M5Stack Atom Echo Development Kit"
      />
    </label>
    <label>
      <input
        type="radio"
        name="voice-device"
        class="device-option"
        value="esp32-s3-box-3"
      />
      <img
        src="/_static/projects/voice-assistant/esp32-s3-box-3.png"
        alt="ESP32-S3-BOX-3"
      />
    </label>
  </div>

  <div class="hidden info esp32-s3-box-3">
    <div class="question-prompt">Select your variant:</div>
    <div class="types">
      <label>
        <input
          type="radio"
          name="esp32-s3-box-3-variant"
          value="esp32-s3-box-3"
          checked
        />
        <div class="name">ESP32-S3-BOX-3</div>
      </label>
    </div>
    <div class="types">
      <label>
        <input
          type="radio"
          name="esp32-s3-box-3-variant"
          value="esp32-s3-box"
        />
        <div class="name">ESP32-S3-BOX</div>
      </label>
    </div>
    <div class="types">
      <label>
        <input
          type="radio"
          name="esp32-s3-box-3-variant"
          value="esp32-s3-box-lite"
        />
        <div class="name">ESP32-S3-BOX-Lite</div>
      </label>
    </div>
  </div>

  <div class="question-prompt">Start the installation:</div>
  <esp-web-install-button></esp-web-install-button>

  <div class="question-prompt">Configure Home Assistant:</div>
  <p>
    Follow
    <a
      href="https://www.home-assistant.io/voice_control/thirteen-usd-voice-remote/"
      target="_blank"
      >this tutorial</a
    >
    to configure Home Assistant to use your new voice assistant.
  </p>

  <div class="hidden info esp32-s3-box-3">
    <h3>ESP32-S3-BOX-3</h3>
    <p>
      The open-source reference design for voice assistants by Espressif. The
      non-3 and lite variant are older versions that are no longer for sale.
    </p>
    <p>Buy ESP32-S3-BOX-3</p>
    <ul>
      <li>
        <a href="https://amzn.to/3u9HIUW">Amazon</a>
      </li>
      <li>
        <a
          href="https://www.aliexpress.us/item/3256805733893224.html?gatewayAdapt=glo2usa4itemAdapt"
          >AliExpress</a
        >
      </li>
    </ul>
  </div>

  <div class="hidden info m5stack-atom-echo">
    <h3>M5Stack Atom Echo Development Kit</h3>
    <p>Tiny ESP32 board with a built-in speaker.</p>
    <p>Buy</p>
    <ul>
      <li>
        <a href="https://amzn.to/47wcAx2">Amazon</a>
      </li>
      <li>
        <a
          href="https://shop.m5stack.com/collections/m5-controllers/products/atom-echo-smart-speaker-dev-kit?ref=NabuCasa"
          >M5Stack Shop</a
        >
      </li>
      <li>
        <a
          href="https://www.aliexpress.com/item/1005003299332198.html?aff_platform=portals-tool&sk=_A8G2YF&aff_trace_key=90326d2a90444b4887632f62dd533ce4-1654058373639-07963-_A8G2YF&terminal_id=c5517a8c9bb44b4fb32147398fbc2576&aff_fcid=90326d2a90444b4887632f62dd533ce4-1654058373639-07963-_A8G2YF&tt=CPS_NORMAL&aff_fsk=_A8G2YF"
          >AliExpress</a
        >
      </li>
    </ul>
  </div>

  <h3>For advanced users</h3>
  <ul>
    <li>
      The device is adoptable in
      <a
        href="https://my.home-assistant.io/redirect/supervisor_addon/?addon=5c53de3b_esphome&amp;repository_url=https%3A%2F%2Fgithub.com%2Fesphome%2Fhome-assistant-addon"
        >the ESPHome dashboard</a
      >
    </li>
    <li>
      The YAML configuration is on
      <a href="https://github.com/esphome/firmware/tree/main/voice-assistant/"
        >GitHub</a
      >
    </li>
  </ul>
</div>

<div
  class="type type-bluetooth"
  data-manifest-root="https://firmware.esphome.io/bluetooth-proxy"
>
  <div class="question-prompt">
    Pick the device you want to turn into a Bluetooth proxy:
  </div>
  <div class="radios">
    <label>
      <input
        type="radio"
        name="bluetooth-device"
        class="device-option"
        value="esp32-generic"
        checked
      />
      <img
        src="/_static/projects/bluetooth-proxy/esp32_generic.png"
        alt="ESP32 Generic"
      />
    </label>
    <label>
      <input
        type="radio"
        name="bluetooth-device"
        class="device-option"
        value="m5stack-atom-lite"
      />
      <img
        src="/_static/projects/bluetooth-proxy/m5stack_atom_lite.png"
        alt="M5Stack Atom Lite"
      />
    </label>
    <label>
      <input
        type="radio"
        name="bluetooth-device"
        class="device-option"
        value="olimex-esp32-poe-iso"
      />
      <img
        src="/_static/projects/bluetooth-proxy/olimex_esp32_poe_iso.png"
        alt="Olimex ESP32 Power-over-Ethernet ISO"
      />
    </label>
    <label class="diy">
      <input
        type="radio"
        name="bluetooth-device"
        class="device-option"
        value="lilygo-t-eth-poe"
      />
      <img
        src="/_static/projects/bluetooth-proxy/lilygo-eth-poe.png"
        alt="LilyGO T-ETH-POE"
      />
    </label>
    <label class="diy">
      <input
        type="radio"
        name="bluetooth-device"
        class="device-option"
        value="gl-s10"
      />
      <img
        src="/_static/projects/bluetooth-proxy/gl-s10.png"
        alt="GL.iNet GL-S10"
      />
    </label>
    <label class="diy">
      <input
        type="radio"
        name="bluetooth-device"
        class="device-option"
        value="wt32-eth01"
      />
      <img
        src="/_static/projects/bluetooth-proxy/wt32-eth01.png"
        alt="Wireless-Tag WT32-ETH01"
      />
    </label>
  </div>

  <div class="question-prompt">Start the installation:</div>
  <esp-web-install-button
    manifest="https://firmware.esphome.io/esphome-web/manifest.json"
  ></esp-web-install-button>

  <div class="hidden info esp32-generic">
    <h3>Generic ESP32</h3>
    <p>
      Turn any ESP32 into a Bluetooth proxy for Home Assistant. This option only
      works for "plain" ESP32 and not for ESP32-C3 or other variants.
    </p>
    <p>Buy</p>
    <ul>
      <li>
        <a
          href="https://www.amazon.com/ESP-WROOM-32-Development-Microcontroller-Integrated-Compatible/dp/B08D5ZD528/?&_encoding=UTF8&tag=homeassista0e-20&linkCode=ur2&linkId=f9087b654cd5735f0761ae5db99e1e1a&camp=1789&creative=9325"
          >Amazon</a
        >
      </li>
    </ul>
  </div>

  <div class="hidden info gl-s10">
    <h3>GL.iNet GL-S10</h3>
    <p>
      ESP32 in a case with external antenna and wired Ethernet connection that
      can also be powered using Power over Ethernet 802.3af. Note that when
      installed via this website, Wi-Fi is disabled and it needs to be connected
      via Ethernet.
    </p>
    <b>Warning: This board requires extra work.</b>
    This device requires you to disassemble the device to be able to install it
    as a Bluetooth proxy. This installation method is for revision 2.X of their
    board. See instructions for the configuration of other revisions.
    <a href="https://blakadder.com/gl-s10/">Read DIY instructions.</a>
    <p>Buy</p>
    <ul>
      <li>
        <a
          href="https://store.gl-inet.com/collections/iot-gateway/products/gl-s10-bluetooth-iot-gateway"
          >GL.iNet Shop</a
        >
      </li>
    </ul>
  </div>

  <div class="hidden info m5stack-atom-lite">
    <h3>M5Stack Atom Lite</h3>
    <p>Small ESP32 board with a case.</p>
    <p>Buy</p>
    <ul>
      <li>
        <a
          href="https://shop.m5stack.com/products/atom-lite-esp32-development-kit?ref=NabuCasa"
          >M5Stack Shop</a
        >
      </li>
      <li>
        <a
          href="https://www.aliexpress.com/item/1005003299215808.html?aff_platform=portals-tool&sk=_A8G2YF&aff_trace_key=90326d2a90444b4887632f62dd533ce4-1654058373639-07963-_A8G2YF&terminal_id=c5517a8c9bb44b4fb32147398fbc2576&aff_fcid=90326d2a90444b4887632f62dd533ce4-1654058373639-07963-_A8G2YF&tt=CPS_NORMAL&aff_fsk=_A8G2YF"
          >AliExpress</a
        >
      </li>
    </ul>
  </div>

  <div class="hidden info olimex-esp32-poe-iso">
    <h3>Olimex ESP32 Power-over-Ethernet ISO</h3>
    <p>
      ESP32 board with wired Ethernet connection that can also be powered using
      Power over Ethernet 802.3af. Note that when installed via this website,
      Wi-Fi is disabled and it needs to be connected via Ethernet. The
      <i>ESP32-POE-ISO-EA</i> variant may provide better Bluetooth range since
      it has an external antennae.

      <a href="https://www.thingiverse.com/thing:3857281"
        >Case on Thingiverse.</a
      >
    </p>
    <p>Buy</p>
    <ul>
      <li>
        <a
          href="https://www.olimex.com/Products/IoT/ESP32/ESP32-POE-ISO-EA/open-source-hardware"
          >Olimex</a
        >
      </li>
      <li>
        <a
          href="https://www.mouser.com/ProductDetail/Olimex-Ltd/ESP32-POE-ISO?qs=sGAEpiMZZMuqBwn8WqcFUj2aNd7i9W7uc087HzBKguU1UBkflb3j3w%3D%3D"
          >Mouser</a
        >
      </li>
    </ul>
  </div>

  <div class="hidden info wt32-eth01">
    <h3>Wireless-Tag WT32-ETH01</h3>
    <p>
      ESP32 board with wired Ethernet connection. Note that when installed via
      this website, Wi-Fi is disabled and it needs to be connected via Ethernet.
      <a href="https://www.thingiverse.com/search?q=WT32-ETH01"
        >Various enclosures on Thingiverse.</a
      >
    </p>
    <p>
      <b>Warning: This board requires extra work.</b>
      This device requires you to create a special flash tool to be able to
      install it as a Bluetooth proxy.
      <a
        href="https://community.home-assistant.io/t/how-i-installed-esphome-on-the-wt32-eth01/359027"
        >Read DIY instructions.</a
      >
    </p>
    <p>Buy</p>
    <ul>
      <li>
        <a href="https://www.aliexpress.com/wholesale?SearchText=WT32-ETH01"
          >AliExpress</a
        >
      </li>
      <li>
        <a
          href="https://eu.mouser.com/ProductDetail/Seeed-Studio/102991455?qs=hd1VzrDQEGjybZ4QAH35DA%3D%3D"
          >Mouser</a
        >
      </li>
      <li>
        <a
          href="https://www.tubeszb.com/product/wt32-eth01-bluetooth-proxy-kit/53"
          >TubesZB - Kit with enlosure and USB-C</a
        >
      </li>
    </ul>
  </div>

  <div class="hidden info lilygo-t-eth-poe">
    <h3>LilyGO T-ETH-POE ESP32-WROOM</h3>
    <p>
      A compact board with an ESP32-WROOM module and wired Ethernet connection.
      Can be powered via Power over Ethernet 802.3af or via the built in USB-C
      port. Note that when installed via this website, Wi-Fi is disabled and it
      needs to be connected via Ethernet.
      <a
        href="https://www.thingiverse.com/search?q=LILYGO TTGO T-Internet-POE ESP32"
        >Various enclosures on Thingiverse.</a
      >
    </p>
    <p>
      <b>Warning: This board requires extra work.</b>
      This device comes with a special "download tool" that needs to be used to
      install it as a Bluetooth proxy.
    </p>
    <p>Buy</p>
    <ul>
      <li>
        <a
          href="https://www.aliexpress.com/item/2255800936677694.html?pdp_ext_f=%7B%22sku_id%22%3A%2210000014557692201%22%7D"
          >AliExpress</a
        >
      </li>
    </ul>
  </div>

  <h3>For advanced users</h3>
  <ul>
    <li>
      The device is adoptable in
      <a
        href="https://my.home-assistant.io/redirect/supervisor_addon/?addon=5c53de3b_esphome&repository_url=https%3A%2F%2Fgithub.com%2Fesphome%2Fhome-assistant-addon"
        >the ESPHome dashboard</a
      >
    </li>
    <li>
      The YAML configuration is on
      <a href="https://github.com/esphome/firmware/tree/main/bluetooth-proxy">GitHub</a>
    </li>
  </ul>
</div>

<div
  class="type type-media hidden"
  data-manifest-root="https://firmware.esphome.io/media-player"
>
  <div class="question-prompt">
    Pick the device you want to turn into a media player:
  </div>
  <div class="radios">
    <label>
      <input
        type="radio"
        name="media-device"
        class="device-option"
        value="raspiaudio-muse-luxe"
        checked
      />
      <img
        src="/_static/projects/media-player/esp_muse_luxe.png"
        alt="Raspiaudio ESP Muse Luxe"
      />
    </label>
    <label>
      <input
        type="radio"
        name="media-device"
        class="device-option"
        value="raspiaudio-muse-proto"
      />
      <img
        src="/_static/projects/media-player/esp_muse_proto.png"
        alt="Raspiaudio ESP Muse Proto"
      />
    </label>
    <label>
      <input
        type="radio"
        name="media-device"
        class="device-option"
        value="m5stack-atom-speaker-kit"
      />
      <img
        src="/_static/projects/media-player/atom_speaker_kit.png"
        alt="M5Stack Atom Speaker Kit"
      />
    </label>
    <label>
      <input
        type="radio"
        name="media-device"
        class="device-option"
        value="m5stack-atom-echo"
      />
      <img
        src="/_static/projects/media-player/atom_echo.png"
        alt="M5Stack Atom Echo Development Kit"
      />
    </label>
  </div>

  <div class="question-prompt">Start the installation:</div>
  <esp-web-install-button></esp-web-install-button>

  <div class="hidden info raspiaudio-muse-luxe">
    <h3>Raspiaudio ESP Muse Luxe</h3>
    <p>
      Portable speaker with two 5 Watt speakers built-in. Can run 4 hours off
      the built-in battery or be powered by a cable.
    </p>
    <p>
      This is a powerful device. If you want to use it solely as a media player,
      we recommend to use the
      <a href="https://raspiaudio.github.io/">Squeezelite-ESP32 firmware</a>.
    </p>
    <p>Buy</p>
    <ul>
      <li>
        <a href="https://raspiaudio.com/produit/esp-muse-luxe">Raspiaudio</a>
      </li>
      <li>
        <a
          href="https://www.amazon.com/gp/product/B09N3S9S29/?&_encoding=UTF8&tag=homeassista0e-20&linkCode=ur2&linkId=71c80756dcd782eba9f1a80dc576c7d3&camp=1789&creative=9325"
          >Amazon</a
        >
      </li>
    </ul>
  </div>

  <div class="hidden info raspiaudio-muse-proto">
    <h3>Raspiaudio ESP Muse Proto</h3>
    <p>Powerful audio prototyping board to create your own smart speakers.</p>
    <p>
      This is a powerful device. If you want to use it solely as a media player,
      we recommend to use the
      <a href="https://raspiaudio.github.io/">Squeezelite-ESP32 firmware</a>.
    </p>
    <p>Buy</p>
    <ul>
      <li>
        <a href="https://raspiaudio.com/produit/muse-proto">Raspiaudio</a>
      </li>
      <li>
        <a
          href="https://www.amazon.com/gp/product/B097F884WL/?&_encoding=UTF8&tag=homeassista0e-20&linkCode=ur2&linkId=71c80756dcd782eba9f1a80dc576c7d3&camp=1789&creative=9325"
          >Amazon</a
        >
      </li>
    </ul>
  </div>

  <div class="hidden info m5stack-atom-speaker-kit">
    <h3>M5Stack Atom Speaker Kit</h3>
    <p>Small ESP32 board with a built-in speaker and a headphone jack.</p>
    <p>Buy</p>
    <ul>
      <li>
        <a
          href="https://shop.m5stack.com/products/atom-speaker-kit-ns4168?ref=NabuCasa"
          >M5Stack Shop</a
        >
      </li>
      <li>
        <a
          href="https://www.aliexpress.com/item/1005003297368240.html?aff_platform=portals-tool&sk=_A8G2YF&aff_trace_key=90326d2a90444b4887632f62dd533ce4-1654058373639-07963-_A8G2YF&terminal_id=c5517a8c9bb44b4fb32147398fbc2576&aff_fcid=90326d2a90444b4887632f62dd533ce4-1654058373639-07963-_A8G2YF&tt=CPS_NORMAL&aff_fsk=_A8G2YF"
          >AliExpress</a
        >
      </li>
    </ul>
  </div>

  <div class="hidden info m5stack-atom-echo">
    <h3>M5Stack Atom Echo Development Kit</h3>
    <p>Tiny ESP32 board with a built-in speaker.</p>
    <p>Buy</p>
    <ul>
      <li>
        <a href="https://amzn.to/47wcAx2">Amazon</a>
      </li>
      <li>
        <a
          href="https://shop.m5stack.com/collections/m5-controllers/products/atom-echo-smart-speaker-dev-kit?ref=NabuCasa"
          >M5Stack Shop</a
        >
      </li>
      <li>
        <a
          href="https://www.aliexpress.com/item/1005003299332198.html?aff_platform=portals-tool&sk=_A8G2YF&aff_trace_key=90326d2a90444b4887632f62dd533ce4-1654058373639-07963-_A8G2YF&terminal_id=c5517a8c9bb44b4fb32147398fbc2576&aff_fcid=90326d2a90444b4887632f62dd533ce4-1654058373639-07963-_A8G2YF&tt=CPS_NORMAL&aff_fsk=_A8G2YF"
          >AliExpress</a
        >
      </li>
    </ul>
  </div>

  <h3>For advanced users</h3>
  <ul>
    <li>
      The device is adoptable in
      <a
        href="https://my.home-assistant.io/redirect/supervisor_addon/?addon=5c53de3b_esphome&amp;repository_url=https%3A%2F%2Fgithub.com%2Fesphome%2Fhome-assistant-addon"
        >the ESPHome dashboard</a
      >
    </li>
    <li>
      The YAML configuration is on
      <a href="https://github.com/esphome/media-players/">GitHub</a>
    </li>
  </ul>
</div>

<div class="type type-empty">
  <div class="question-prompt">
    Pick the manufacturer of the device you want to set up:
  </div>

  <div class="radios">
    <label>
      <input
        type="radio"
        name="esphome-device"
        class="device-option"
        value="espressif"
        checked
      />
      <img src="/_static/projects/empty/espressif.png" alt="Espressif" />
    </label>
    <label>
      <input
        type="radio"
        name="esphome-device"
        class="device-option"
        value="raspberry"
      />
      <img src="/_static/projects/empty/pico-w.png" alt="Raspberry Pi Pico W" />
    </label>
  </div>

  <div class="hidden info espressif">
    <div class="question-prompt">Start the installation:</div>
    <esp-web-install-button
      manifest="https://firmware.esphome.io/esphome-web/manifest.json"
    ></esp-web-install-button>
  </div>

  <div class="hidden info raspberry">
    <div class="question-prompt">Installation instructions:</div>

    <ol>
      <li>Disconnect your Raspberry Pi Pico from your computer</li>
      <li>
        Hold the BOOTSEL button and connect the Pico to your computer. The Pico
        will show up as a USB drive named RPI-RP2
      </li>
      <li>
        Download
        <a
          href="https://firmware.esphome.io/esphome-web/pico-w/esphome-web-rp2040.uf2"
          >ESPHome for Pico</a
        >
      </li>
      <li>
        Drag the downloaded file to the RPI-RP2 USB drive. The installation is
        complete when the drive disappears
      </li>
      <li>
        Connect your Pico to the Wi-Fi network. Once connected, it will
        automatically show up on your ESPHome dashboard.<br />
        <button type="button" onclick="showImprovWifiSerial()">
          Configure Wi-Fi
        </button>
      </li>
    </ol>
  </div>
</div>

<div class="installer-footer">
  ESP installer powered by
  <a href="https://esphome.github.io/esp-web-tools/">ESP Web Tools</a>.
  Affiliated links are used on this website to support ESPHome development. Use
  Coupon code <code>NABUCASA</code> on
  <a href="https://shop.m5stack.com/discount/NABUCASA?ref=NabuCasa">M5Stack</a>
  for 5% off your order.
</div>

<script>
  async function showImprovWifiSerial() {
    import(
      "https://unpkg.com/improv-wifi-serial-sdk@2.5.0/dist/web/serial-launch-button.js?module"
    );
    let port;
    try {
      port = await navigator.serial.requestPort({
        filters: [
          {
            usbProductId: 61450,
            usbVendorId: 11914,
          },
        ],
      });
    } catch (err) {
      if (err.name !== "NotFoundError") {
        alert(`Error: ${err.message}`);
      }
      return;
    }

    try {
      await port.open({ baudRate: 115200 });
    } catch (err) {
      alert(err.message);
      return;
    }

    const improv = document.createElement(
      "improv-wifi-serial-provision-dialog"
    );
    improv.port = port;
    document.body.appendChild(improv);
  }

  // Handle selecting a project type
  document.querySelectorAll('input[name="type"]').forEach((radio) =>
    radio.addEventListener("change", () => {
      document.querySelectorAll(".type").forEach((info) => {
        info.classList.add("hidden");
      });
      document.querySelector(`.type-${radio.value}`).classList.remove("hidden");
    })
  );

  // Handle selecting a device
  document.querySelectorAll("input.device-option").forEach((radio) =>
    radio.addEventListener("change", () => {
      const typeRoot = radio.closest(".type");
      const manifestRoot = typeRoot.dataset.manifestRoot;
      if (manifestRoot) {
        const button = typeRoot.querySelector("esp-web-install-button");

        let device = radio.value;
        const variant = typeRoot.querySelector(
          `input[name="${device}-variant"]:checked`
        );
        if (variant) {
          device = variant.value;
        }

        button.manifest = `${manifestRoot}/${device}/manifest.json`;
      }

      // Show matching info blocks, hide the others
      typeRoot.querySelectorAll(".info").forEach((info) => {
        info.classList.toggle("hidden", !info.classList.contains(radio.value));
      });
    })
  );

  // Handle selecting a variant
  document.querySelectorAll('input[name$="-variant"]').forEach((radio) =>
    radio.addEventListener("change", () => {
      const typeRoot = radio.closest(".type");
      // Selecting a device handles the variant, so just trigger change again
      typeRoot
        .querySelector("input.device-option:checked")
        .dispatchEvent(new Event("change"));
    })
  );

  // Check URL for type
  if (window.location.search) {
    const params = new URLSearchParams(window.location.search);
    const type = params.get("type");
    if (type) {
      document.querySelector(
        `input[name="type"][value="${type}"]`
      ).checked = true;
    }
  }

  // Show current selection on page load
  document
    .querySelector('input[name="type"]:checked')
    .dispatchEvent(new Event("change"));
  document
    .querySelectorAll("input.device-option:checked")
    .forEach((radio) => radio.dispatchEvent(new Event("change")));

  // Check if web installation is supported
  customElements.whenDefined("esp-web-install-button").then((cls) => {
    if (cls.isSupported) {
      return;
    }
    // show unsupported note
    document.querySelector(".unsupported").classList.remove("hidden");
  });
</script>