<!doctype html>
<html>
  <head>
    <title>{{ title }}</title>
    <meta name="viewport" content="{{ viewport }}" />
    <meta
      id="nicegui-color-scheme"
      name="color-scheme"
      content="{{ ({'True': 'dark', 'False': 'light'}).get(dark, 'normal') }}"
    />
    <link href="{{ favicon_url }}" rel="shortcut icon" />
    <style>
      @layer theme, base, quasar, nicegui, components, utilities, overrides, quasar_importants;
      @import url("{{ prefix | safe }}/_nicegui/{{version}}/static/fonts.css") layer(base);
      {% if prod_js %}
        @import url("{{ prefix | safe }}/_nicegui/{{version}}/static/quasar.unimportant.prod.css") layer(quasar);
        @import url("{{ prefix | safe }}/_nicegui/{{version}}/static/quasar.important.prod.css") layer(quasar_importants);
      {% else %}
        @import url("{{ prefix | safe }}/_nicegui/{{version}}/static/quasar.unimportant.css") layer(quasar);
        @import url("{{ prefix | safe }}/_nicegui/{{version}}/static/quasar.important.css") layer(quasar_importants);
      {% endif %}
      @import url("{{ prefix | safe }}/_nicegui/{{version}}/static/nicegui.css") layer(nicegui);
      @layer quasar {
        blockquote, dd, dl, figure, h1, h2, h3, h4, h5, h6, hr, p, pre {
          margin: revert-layer; /* HACK: revert Quasar's margin styles */
        }
      }
      @layer overrides {
        {{ headwind_css | safe }}
        .column.inline, .flex.inline, .row.inline {
          display: inline-flex;  /* HACK: re-apply Quasar's inline styles to override Tailwind */
        }
        .nicegui-dialog-open,
        .nicegui-select-popup-open,
        .nicegui-table-fullscreen {
          scroll-behavior: auto !important; /* HACK: avoid smooth-scrolling when dialogs or select popups close */
        }
      }
    </style>
    <script type="importmap">
      {"imports": {{ imports | safe }}}
    </script>
    <script>
      addStyle = (c) => document.head.append(Object.assign(document.createElement("style"), { textContent: c }));
    </script>
    {{ head_html | safe }}
    <!-- prevent Prettier from removing this line -->
    {% for url in js_imports_urls %}
    <link rel="modulepreload" href="{{ url }}" />
    {% endfor %}
    <!-- prevent Prettier from removing this line -->
    {% if tailwind %}
    <style type="text/tailwindcss">
      @custom-variant dark (&:where(body.body--dark, body.body--dark *));
    </style>
    {% endif %}
    <!-- prevent Prettier from removing this line -->
    {% if unocss %}
    <script defer src="{{ prefix | safe }}/_nicegui/{{version}}/static/unocss/preset-{{unocss}}.global.js"></script>
    <script>
      window.__unocss = {
        presets: [
          () => window.__unocss_runtime.presets.preset{{unocss.title()}}({
            dark: {
              light: 'body.body--light',
              dark: 'body.body--dark',
            },
          }),
        ],
        runtime: { ready: () => false },
        outputToCssLayers: {
          cssLayerName: (layer) => {
            if (layer === 'default') return 'utilities';
            if (layer === 'preflights') return 'base';
            return undefined;
          },
        },
      };
    </script>
    <script defer src="{{ prefix | safe }}/_nicegui/{{version}}/static/unocss/core.global.js"></script>
    <style>
      #app.nicegui-unocss-loading {
        visibility: hidden;
      }
    </style>
    {% endif %}
  </head>
  <body>
    <script defer src="{{ prefix | safe }}/_nicegui/{{version}}/static/socket.io.min.js"></script>
    {% if tailwind %}
    <script defer src="{{ prefix | safe }}/_nicegui/{{version}}/static/tailwindcss.min.js"></script>
    {% endif %}
    <script type="module">
      import * as Vue from "vue";
      globalThis.Vue = Vue;
    </script>
    {% if prod_js %}
    <script defer src="{{ prefix | safe }}/_nicegui/{{version}}/static/quasar.umd.prod.js"></script>
    {% else %}
    <script defer src="{{ prefix | safe }}/_nicegui/{{version}}/static/quasar.umd.js"></script>
    {% endif %}
    <script defer src="{{ prefix | safe }}/_nicegui/{{version}}/static/nicegui.js"></script>

    <script defer src="{{ prefix | safe }}/_nicegui/{{version}}/static/lang/{{ language }}.umd.prod.js"></script>
    {{ body_html | safe }}

    <div id="app" {% if unocss %}class="nicegui-unocss-loading" {% endif %}></div>
    <div id="popup" class="nicegui-error-popup" aria-hidden="true">
      <span>{{ translations.connection_lost }}</span>
      <span>{{ translations.trying_to_reconnect }}</span>
    </div>
    <div id="too_long_message_popup" class="nicegui-error-popup" aria-hidden="true">
      <span>{{ translations.message_too_long }}</span>
      <span>{{ translations.message_too_long_body }}</span>
    </div>
    <script type="module">
      // Load DOMPurify for HTML sanitization
      // NOTE: Always use DOMPurify instead of native setHTML because native setHTML strips class attributes.
      import DOMPurify from "dompurify";
      Element.prototype.setHTML = function (html) {
        this.innerHTML = DOMPurify.sanitize(html);
      };

      const app = createApp(parseElements(String.raw`{{ elements | safe }}`), {
        version: "{{ version }}",
        prefix: "{{ prefix | safe }}",
        query: {{ socket_io_js_query_params | safe }},
        extraHeaders: {{ socket_io_js_extra_headers | safe }},
        transports: {{ socket_io_js_transports | safe }},
      });
      const dark = {{ dark }};
      const language = "{{ language }}";
      const vue_config = {{ vue_config | safe }};
      {{ vue_config_script | safe }}

      {{ js_imports | safe }}
      {{ vue_scripts | safe }}

      app.mount("#app");

      // Scroll to fragment after Vue mounts (browser's native scroll may have failed if element wasn't ready)
      if (window.location.hash) {
        Vue.nextTick(() => {
          const fragment = window.location.hash.substring(1);
          (document.getElementById(fragment) || document.querySelector(`a[name="${fragment}"]`))?.scrollIntoView();
        });
      }
    </script>
  </body>
</html>
