---
import Analytics from "@vercel/analytics/astro";
import "@fontsource/roboto/400.css";
import "@fontsource/roboto/500.css";
import "@fontsource/roboto/700.css";

import { profileConfig, siteConfig } from "@/config";
import ConfigCarrier from "@components/ConfigCarrier.astro";
import Sakura from "@components/widget/Sakura.astro";
import EmojiCursor from "@components/widget/EmojiCursor.astro";
import {
  AUTO_MODE,
  BANNER_HEIGHT,
  BANNER_HEIGHT_EXTEND,
  BANNER_HEIGHT_HOME,
  DARK_MODE,
  DEFAULT_THEME,
  LIGHT_MODE,
  PAGE_WIDTH,
} from "../constants/constants";
import { defaultFavicons } from "../constants/icon";
import type { Favicon } from "../types/config";
import { url, pathsEqual } from "../utils/url-utils";
import "katex/dist/katex.css";

interface Props {
  title?: string;
  banner?: string;
  description?: string;
  lang?: string;
  setOGTypeArticle?: boolean;
}

let { title, banner, description, lang, setOGTypeArticle } = Astro.props;

// apply a class to the body element to decide the height of the banner, only used for initial page load
// Swup can update the body for each page visit, but it's after the page transition, causing a delay for banner height change
// so use Swup hooks instead to change the height immediately when a link is clicked
const isHomePage = pathsEqual(Astro.url.pathname, url("/"));

// defines global css variables
// why doing this in Layout instead of GlobalStyles: https://github.com/withastro/astro/issues/6728#issuecomment-1502203757
const configHue = siteConfig.themeColor.hue;
if (!banner || typeof banner !== "string" || banner.trim() === "") {
  banner = siteConfig.banner.src;
}

// TODO don't use post cover as banner for now
banner = siteConfig.banner.src;

const enableBanner = siteConfig.banner.enable;

let pageTitle: string;
if (title) {
  pageTitle = `${title} - ${siteConfig.title}`;
} else {
  if (siteConfig.subtitle && siteConfig.subtitle.trim() !== "") {
    pageTitle = `${siteConfig.title} - ${siteConfig.subtitle}`;
  } else {
    pageTitle = siteConfig.title;
  }
}

// Use siteConfig.description as fallback for meta description when no description is provided
if (!description) {
  description = siteConfig.description || pageTitle;
}

const favicons: Favicon[] =
  siteConfig.favicon.length > 0 ? siteConfig.favicon : defaultFavicons;

// const siteLang = siteConfig.lang.replace('_', '-')
if (!lang) {
  lang = `${siteConfig.lang}`;
}
const siteLang = lang.replace("_", "-");

const bannerOffsetByPosition = {
  top: `${BANNER_HEIGHT_EXTEND}vh`,
  center: `${BANNER_HEIGHT_EXTEND / 2}vh`,
  bottom: "0",
};
const bannerOffset =
  bannerOffsetByPosition[siteConfig.banner.position || "center"];
---

<!doctype html>
<html
  lang={siteLang}
  class="bg-[var(--page-bg)] transition text-[12px] md:text-[16px]"
  data-overlayscrollbars-initialize
>
  <!-- 手机端适配 -->

  <head>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c:wght@400;500;700&display=swap" rel="stylesheet">
    <title>{pageTitle}</title>

    <meta charset="UTF-8" />
    <meta name="description" content={description} />
    <meta name="author" content={profileConfig.name} />
    {
      siteConfig.keywords && (
        <meta name="keywords" content={siteConfig.keywords.join(", ")} />
      )
    }

    <meta property="og:site_name" content={siteConfig.title} />
    <meta property="og:url" content={Astro.url} />
    <meta property="og:title" content={pageTitle} />
    <meta property="og:description" content={description} />
    {
      setOGTypeArticle ? (
        <meta property="og:type" content="article" />
      ) : (
        <meta property="og:type" content="website" />
      )
    }

    <meta name="twitter:card" content="summary_large_image" />
    <meta property="twitter:url" content={Astro.url} />
    <meta name="twitter:title" content={pageTitle} />
    <meta name="twitter:description" content={description} />

    <meta name="viewport" content="width=device-width" />
    <meta name="generator" content={Astro.generator} />
    <!-- <script src="/js/umami-share.js" defer></script> -->
    <!-- <script
      data-swup-ignore-script
      is:inline
      src="https://pic.acofork.com/random.js"></script> -->

    {
      /* <!-- Content Security Policy -->
		<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline' https://giscus.app https://hpic.072103.xyz https://umami.acofork.com https://hm.baidu.com https://www.googletagmanager.com https://www.google-analytics.com https://pagead2.googlesyndication.com https://googleads.g.doubleclick.net https://static.cloudflareinsights.com https://*.adtrafficquality.google; style-src 'self' 'unsafe-inline' https://giscus.app https://fonts.googleapis.com https://api.iconify.design; font-src 'self' https://fonts.gstatic.com https://api.iconify.design; img-src 'self' data: https: http:; connect-src 'self' https://umami.acofork.com https://hm.baidu.com https://www.google-analytics.com https://analytics.google.com https://api.iconify.design https://static.cloudflareinsights.com https://pic.2x.nz https://q2.qlogo.cn https://ep1.adtrafficquality.google https://googleads.g.doubleclick.net; frame-src 'self' https://giscus.app *.bilibili.com https://www.google.com https://googleads.g.doubleclick.net https://support.nodeget.com https://*.adtrafficquality.google; object-src 'none'; base-uri 'self'; form-action 'self';"> */
    }
    {
      favicons.map((favicon) => (
        <link
          rel="icon"
          href={favicon.src.startsWith("/") ? url(favicon.src) : favicon.src}
          sizes={favicon.sizes}
          media={favicon.theme && `(prefers-color-scheme: ${favicon.theme})`}
        />
      ))
    }

    <!-- Set the theme before the page is rendered to avoid a flash -->
    <script
      is:inline
      define:vars={{
        DEFAULT_THEME,
        LIGHT_MODE,
        DARK_MODE,
        AUTO_MODE,
        BANNER_HEIGHT_EXTEND,
        PAGE_WIDTH,
        configHue,
        forceDarkMode: siteConfig.themeColor.forceDarkMode,
      }}
    >
      // Force dark mode if configured
      if (forceDarkMode) {
        document.documentElement.classList.add("dark");
        localStorage.setItem("theme", DARK_MODE);
      } else {
        // Load the theme from local storage
        const theme = localStorage.getItem("theme") || AUTO_MODE;
        switch (theme) {
          case LIGHT_MODE:
            document.documentElement.classList.remove("dark");
            break;
          case DARK_MODE:
            document.documentElement.classList.add("dark");
            break;
          case AUTO_MODE:
            if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
              document.documentElement.classList.add("dark");
            } else {
              document.documentElement.classList.remove("dark");
            }
        }
      }

      // Load the hue from local storage
      const hue = localStorage.getItem("hue") || configHue;
      document.documentElement.style.setProperty("--hue", hue);

      // calculate the --banner-height-extend, which needs to be a multiple of 4 to avoid blurry text
      let offset = Math.floor(
        window.innerHeight * (BANNER_HEIGHT_EXTEND / 100)
      );
      offset = offset - (offset % 4);
      document.documentElement.style.setProperty(
        "--banner-height-extend",
        `${offset}px`
      );

      // Background image loading detection
      const bgUrl = bgConfig.enable && bgConfig.src ? bgConfig.src : '';
      
      if (bgUrl) {
      	const img = new Image();
      	img.onload = function() {
      		// 背景图片完全加载后，显示背景并启用卡片透明效果
      		document.body.classList.add('bg-loaded');
            document.getElementById('bg-box').classList.add('loaded');
      		document.documentElement.style.setProperty('--card-bg', 'var(--card-bg-transparent)');
      		document.documentElement.style.setProperty('--float-panel-bg', 'var(--float-panel-bg-transparent)');
            document.documentElement.style.setProperty('--page-bg', 'transparent');
      	};
      	img.onerror = function() {
      		// Keep cards opaque if background image fails to load
      		console.warn('Background image failed to load, keeping cards opaque');
      	};
      	img.src = bgUrl;
      }
    </script>
    <style
      define:vars={{
        configHue,
        "page-width": `${PAGE_WIDTH}rem`,
        "bg-url": siteConfig.background.src
          ? `url(${siteConfig.background.src})`
          : "none",
        "bg-enable": siteConfig.background.enable ? "1" : "0",
        "bg-position": siteConfig.background.position || "center",
        "bg-size": siteConfig.background.size || "cover",
        "bg-repeat": siteConfig.background.repeat || "no-repeat",
        "bg-attachment": siteConfig.background.attachment || "fixed",
        "bg-opacity": (siteConfig.background.opacity || 0.3).toString(),
      }}
    >
      :root {
        --bg-url: var(--bg-url);
        --bg-enable: var(--bg-enable);
        --bg-position: var(--bg-position);
        --bg-size: var(--bg-size);
        --bg-repeat: var(--bg-repeat);
        --bg-attachment: var(--bg-attachment);
        --bg-opacity: var(--bg-opacity);
      }

      /* Background image configuration */
      body {
        --bg-url: var(--bg-url);
        --bg-enable: var(--bg-enable);
        --bg-position: var(--bg-position);
        --bg-size: var(--bg-size);
        --bg-repeat: var(--bg-repeat);
        --bg-attachment: var(--bg-attachment);
        --bg-opacity: var(--bg-opacity);
      }

      #bg-box {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-image: var(--bg-url);
        background-position: var(--bg-position);
        background-size: var(--bg-size);
        background-repeat: var(--bg-repeat);
        background-attachment: var(--bg-attachment);
        opacity: var(--bg-opacity);
        pointer-events: none;
        z-index: -1;
      }
    </style>

    <slot name="head" />

    <link
      rel="alternate"
      type="application/rss+xml"
      title={profileConfig.name}
      href={`${Astro.site}rss.xml`}
    />
    <!-- Umami分析（自建） -->
    <!-- <script
      defer
      src="https://umami.acofork.com/script.js"
      data-website-id="5d710dbd-3a2e-43e3-a553-97b415090c63"
      data-swup-ignore-script></script> -->
    {
      /* - Umami分析（云-备用） 
		<script defer src="https://cloud.umami.is/script.js" data-website-id="5d710dbd-3a2e-43e3-a553-97b415090c63" data-swup-ignore-script></script> */
    }
    <!-- 超级吊的Umami eop -->
    <!-- <script
      defer
      src="https://eo-umami.acofork.com/script.js"
      data-website-id="3f525363-5e81-4653-9491-1bd205c2a571"></script> -->
    <!-- 百度统计 -->
    <!-- <script data-swup-ignore-script>
      var _hmt = _hmt || [];
      (function () {
        var hm = document.createElement("script");
        hm.src = "https://hm.baidu.com/hm.js?b219eaad631b87d273cfe72148b2138b";
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(hm, s);
      })();
    </script> -->

    <!-- clarity 分析 -->
    <!-- <script type="text/javascript" data-swup-ignore-script>
      (function (c, l, a, r, i, t, y) {
        c[a] =
          c[a] ||
          function () {
            (c[a].q = c[a].q || []).push(arguments);
          };
        t = l.createElement(r);
        t.async = 1;
        t.src = "https://www.clarity.ms/tag/" + i;
        y = l.getElementsByTagName(r)[0];
        y.parentNode.insertBefore(t, y);
      })(window, document, "clarity", "script", "t8f0gmcwtx");
    </script> -->
    <!-- gad -->
    <!-- <script
      async
      src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1683686345039700"
      crossorigin="anonymous"
      data-swup-ignore-script></script>
    <meta name="google-adsense-account" content="ca-pub-1683686345039700" /> -->

    <!-- 谷歌分析 -->
    <!-- <script
      async
      src="https://www.googletagmanager.com/gtag/js?id=G-9Z4LT4H8KH"
      data-swup-ignore-script></script> -->
    <script is:inline>
      window.dataLayer = window.dataLayer || [];
      function gtag() {
        dataLayer.push(arguments);
      }
      gtag("js", new Date());

      gtag("config", "G-9Z4LT4H8KH");
    </script>

    <!-- Cloudflare Web Analytics -->
    <!-- <script
      defer
      src="https://static.cloudflareinsights.com/beacon.min.js"
      data-cf-beacon='{"token": "15fe148e91b34f10a15652e1a74ab26c"}'
      data-swup-ignore-script></script> -->
      <!-- End Cloudflare Web Analytics -->
  </head>
  <body
    class="min-h-screen transition"
    class:list={[{ "lg:is-home": isHomePage, "enable-banner": enableBanner }]}
    data-overlayscrollbars-initialize
  >
    <div id="bg-box"></div>
    <Sakura />
    <EmojiCursor />
    <ConfigCarrier />
    <slot />

    <!-- increase the page height during page transition to prevent the scrolling animation from jumping -->
    <div id="page-height-extend" class="hidden h-[300vh]"></div>

    <!-- 域名检测脚本 -->
    <script
      is:inline
      define:vars={{ officialSites: siteConfig.officialSites || [] }}
    >
      // 域名检测功能
      function checkDomain() {
        try {
          // 获取当前访问的完整URL
          const currentUrl = window.location.href;
          // 获取当前域名
          const currentDomain = window.location.hostname;

          // 获取所有官方域名
          const officialDomains = officialSites
            .map((site) => {
              try {
                const url = typeof site === "string" ? site : site.url;
                return new URL(url).hostname;
              } catch (e) {
                return null;
              }
            })
            .filter((domain) => domain !== null);

          // 检查当前域名是否为官方域名或本地开发环境
          const isOfficialDomain = officialDomains.some(
            (officialDomain) =>
              currentDomain === officialDomain ||
              currentDomain.endsWith("." + officialDomain)
          );
          const isLocalDev =
            currentDomain === "localhost" || currentDomain === "127.0.0.1";

          // 如果当前域名不是官方域名且不是本地开发环境
          if (!isOfficialDomain && !isLocalDev) {
            // 创建警告弹窗
            const shouldRedirect = confirm(
              `⚠️ 域名安全警告\n\n` +
                `您当前访问的域名：${currentDomain}\n` +
                `官方域名：${officialDomains.join(", ")}\n\n` +
                `您可能正在访问非官方网站，存在安全风险！\n\n` +
                `点击"确定"跳转到官方网站\n` +
                `点击"取消"继续访问当前网站（不推荐）`
            );

            // 如果用户选择跳转到官方网站
            if (shouldRedirect) {
              // 构建官方网站的对应页面URL（使用第一个官方网站）
              const currentPath =
                window.location.pathname +
                window.location.search +
                window.location.hash;
              const firstSite = officialSites[0];
              const firstUrl =
                typeof firstSite === "string" ? firstSite : firstSite.url;
              const officialPageUrl = firstUrl + currentPath;
              // 跳转到官方网站
              window.location.href = officialPageUrl;
            }
          }
        } catch (error) {
          // 如果检测过程中出现错误，静默处理，不影响正常访问
          console.warn("域名检测失败:", error);
        }
      }

      // 页面加载完成后执行域名检测
      // if (document.readyState === "loading") {
      //   document.addEventListener("DOMContentLoaded", checkDomain);
      // } else {
      //   checkDomain();
      // }
    </script>
    <Analytics />
  </body>
</html>

<style
  is:global
  define:vars={{
    bannerOffset,
    "banner-height-home": `${BANNER_HEIGHT_HOME}vh`,
    "banner-height": `${BANNER_HEIGHT}vh`,
  }}
>
  @tailwind components;
  @layer components {
    .enable-banner.is-home #banner-wrapper {
      @apply h-[var(--banner-height-home)] translate-y-[var(--banner-height-extend)];
    }
    .enable-banner #banner-wrapper {
      @apply h-[var(--banner-height-home)];
    }

    .enable-banner.is-home #banner {
      @apply h-[var(--banner-height-home)] translate-y-0;
    }
    .enable-banner #banner {
      @apply h-[var(--banner-height-home)] translate-y-[var(--bannerOffset)];
    }
    .enable-banner.is-home #main-grid {
      @apply translate-y-[var(--banner-height-extend)];
    }
    .enable-banner #top-row {
      @apply h-[calc(var(--banner-height-home)_-_4.5rem)] transition-all duration-300;
    }
    .enable-banner.is-home #sidebar-sticky {
      @apply top-[calc(1rem_-_var(--banner-height-extend))];
    }
    .navbar-hidden {
      @apply opacity-0 -translate-y-16;
    }
  }
</style>

<script>
  import "overlayscrollbars/overlayscrollbars.css";
  import {
    OverlayScrollbars,
    // ScrollbarsHidingPlugin,
    // SizeObserverPlugin,
    // ClickScrollPlugin
  } from "overlayscrollbars";
  import {
    getHue,
    getStoredTheme,
    setHue,
    setTheme,
    getBgBlur,
    setBgBlur,
    getHideBg,
    setHideBg,
  } from "../utils/setting-utils";
  import { pathsEqual, url } from "../utils/url-utils";
  import {
    BANNER_HEIGHT,
    BANNER_HEIGHT_HOME,
    BANNER_HEIGHT_EXTEND,
    MAIN_PANEL_OVERLAPS_BANNER_HEIGHT,
  } from "../constants/constants";
  import { siteConfig } from "../config";

  /* Preload fonts */
  // (async function() {
  // 	try {
  // 		await Promise.all([
  // 			document.fonts.load("400 1em Roboto"),
  // 			document.fonts.load("700 1em Roboto"),
  // 		]);
  // 		document.body.classList.remove("hidden");
  // 	} catch (error) {
  // 		console.log("Failed to load fonts:", error);
  // 	}
  // })();

  /* TODO This is a temporary solution for style flicker issue when the transition is activated */
  /* issue link: https://github.com/withastro/astro/issues/8711, the solution get from here too */
  /* update: fixed in Astro 3.2.4 */
  /*
function disableAnimation() {
	const css = document.createElement('style')
	css.appendChild(
		document.createTextNode(
			`*{
              -webkit-transition:none!important;
              -moz-transition:none!important;
              -o-transition:none!important;
              -ms-transition:none!important;
              transition:none!important
              }`
		)
	)
	document.head.appendChild(css)

	return () => {
		// Force restyle
		;(() => window.getComputedStyle(document.body))()

		// Wait for next tick before removing
		setTimeout(() => {
			document.head.removeChild(css)
		}, 1)
	}
}
*/

  const bannerEnabled = !!document.getElementById("banner-wrapper");

  function setClickOutsideToClose(panel: string, ignores: string[]) {
    document.addEventListener("click", (event) => {
      let panelDom = document.getElementById(panel);
      let tDom = event.target;
      if (!(tDom instanceof Node)) return; // Ensure the event target is an HTML Node
      for (let ig of ignores) {
        let ie = document.getElementById(ig);
        if (ie == tDom || ie?.contains(tDom)) {
          return;
        }
      }
      panelDom!.classList.add("float-panel-closed");
    });
  }
  setClickOutsideToClose("display-setting", [
    "display-setting",
    "display-settings-switch",
  ]);
  setClickOutsideToClose("nav-menu-panel", [
    "nav-menu-panel",
    "nav-menu-switch",
  ]);
  setClickOutsideToClose("search-panel", [
    "search-panel",
    "search-bar",
    "search-switch",
  ]);

  function loadTheme() {
    const theme = getStoredTheme();
    setTheme(theme);
  }

  function loadHue() {
    setHue(getHue());
  }

  function loadBgBlur() {
    setBgBlur(getBgBlur());
    setHideBg(getHideBg());
  }

  function initCustomScrollbar() {
    const bodyElement = document.querySelector("body");
    if (!bodyElement) return;
    OverlayScrollbars(
      // docs say that a initialization to the body element would affect native functionality like window.scrollTo
      // but just leave it here for now
      {
        target: bodyElement,
        cancel: {
          nativeScrollbarsOverlaid: true, // don't initialize the overlay scrollbar if there is a native one
        },
      },
      {
        scrollbars: {
          theme: "scrollbar-base scrollbar-auto py-1",
          autoHide: "move",
          autoHideDelay: 500,
          autoHideSuspend: false,
        },
      }
    );

    const katexElements = document.querySelectorAll(
      ".katex-display"
    ) as NodeListOf<HTMLElement>;
    katexElements.forEach((ele) => {
      OverlayScrollbars(ele, {
        scrollbars: {
          theme: "scrollbar-base scrollbar-auto py-1",
        },
      });
    });
  }

  function showBanner() {
    if (!siteConfig.banner.enable) return;

    const banner = document.getElementById("banner");
    if (!banner) {
      console.error("Banner element not found");
      return;
    }

    banner.classList.remove("opacity-0", "scale-105");
  }

  function init() {
    // disableAnimation()()		// TODO
    loadTheme();
    loadHue();
    loadBgBlur();
    initCustomScrollbar();
    showBanner();
  }

  /* Load settings when entering the site */
  init();

  const setup = () => {
    // TODO: temp solution to change the height of the banner
    /*
	window.swup.hooks.on('animation:out:start', () => {
		const path = window.location.pathname
		const body = document.querySelector('body')
		if (path[path.length - 1] === '/' && !body.classList.contains('is-home')) {
			body.classList.add('is-home')
		} else if (path[path.length - 1] !== '/' && body.classList.contains('is-home')) {
			body.classList.remove('is-home')
		}
	})
*/
    window.swup.hooks.on("link:click", () => {
      // Remove the delay for the first time page load
      document.documentElement.style.setProperty("--content-delay", "0ms");

      // prevent elements from overlapping the navbar
      if (!bannerEnabled) {
        return;
      }
      let threshold = window.innerHeight * (BANNER_HEIGHT / 100) - 72 - 16;
      let navbar = document.getElementById("navbar-wrapper");
      if (!navbar || !document.body.classList.contains("lg:is-home")) {
        return;
      }
      if (
        document.body.scrollTop >= threshold ||
        document.documentElement.scrollTop >= threshold
      ) {
        navbar.classList.add("navbar-hidden");
      }
    });
    window.swup.hooks.on("content:replace", initCustomScrollbar);
    window.swup.hooks.on("visit:start", (visit: { to: { url: string } }) => {
      // change banner height immediately when a link is clicked
      const bodyElement = document.querySelector("body");
      if (pathsEqual(visit.to.url, url("/"))) {
        bodyElement!.classList.add("lg:is-home");
      } else {
        bodyElement!.classList.remove("lg:is-home");
      }

      // increase the page height during page transition to prevent the scrolling animation from jumping
      const heightExtend = document.getElementById("page-height-extend");
      if (heightExtend) {
        heightExtend.classList.remove("hidden");
      }

      // Hide the TOC while scrolling back to top
      let toc = document.getElementById("toc-wrapper");
      if (toc) {
        toc.classList.add("toc-not-ready");
      }
    });
    window.swup.hooks.on("page:view", () => {
      // hide the temp high element when the transition is done
      const heightExtend = document.getElementById("page-height-extend");
      if (heightExtend) {
        heightExtend.classList.remove("hidden");
      }
    });
    window.swup.hooks.on("visit:end", (_visit: { to: { url: string } }) => {
      setTimeout(() => {
        const heightExtend = document.getElementById("page-height-extend");
        if (heightExtend) {
          heightExtend.classList.add("hidden");
        }

        // Just make the transition looks better
        const toc = document.getElementById("toc-wrapper");
        if (toc) {
          toc.classList.remove("toc-not-ready");
        }
      }, 200);
    });
  };
  if (window?.swup?.hooks) {
    setup();
  } else {
    document.addEventListener("swup:enable", setup);
  }

  let backToTopBtn = document.getElementById("back-to-top-btn");
  let toc = document.getElementById("toc-wrapper");
  let navbar = document.getElementById("navbar-wrapper");
  function scrollFunction() {
    let bannerHeight = window.innerHeight * (BANNER_HEIGHT / 100);

    if (backToTopBtn) {
      if (
        document.body.scrollTop > bannerHeight ||
        document.documentElement.scrollTop > bannerHeight
      ) {
        backToTopBtn.classList.remove("hide");
      } else {
        backToTopBtn.classList.add("hide");
      }
    }

    if (bannerEnabled && toc) {
      if (
        document.body.scrollTop > bannerHeight ||
        document.documentElement.scrollTop > bannerHeight
      ) {
        toc.classList.remove("toc-hide");
      } else {
        toc.classList.add("toc-hide");
      }
    }

    if (!bannerEnabled) return;
    if (navbar) {
      const NAVBAR_HEIGHT = 72;
      const MAIN_PANEL_EXCESS_HEIGHT = MAIN_PANEL_OVERLAPS_BANNER_HEIGHT * 16; // The height the main panel overlaps the banner

      let bannerHeight = BANNER_HEIGHT;
      if (
        document.body.classList.contains("lg:is-home") &&
        window.innerWidth >= 1024
      ) {
        bannerHeight = BANNER_HEIGHT_HOME;
      }
      let threshold =
        window.innerHeight * (bannerHeight / 100) -
        NAVBAR_HEIGHT -
        MAIN_PANEL_EXCESS_HEIGHT -
        16;
      if (
        document.body.scrollTop >= threshold ||
        document.documentElement.scrollTop >= threshold
      ) {
        navbar.classList.add("navbar-hidden");
      } else {
        navbar.classList.remove("navbar-hidden");
      }
    }
  }
  window.onscroll = scrollFunction;

  window.onresize = () => {
    // calculate the --banner-height-extend, which needs to be a multiple of 4 to avoid blurry text
    let offset = Math.floor(window.innerHeight * (BANNER_HEIGHT_EXTEND / 100));
    offset = offset - (offset % 4);
    document.documentElement.style.setProperty(
      "--banner-height-extend",
      `${offset}px`
    );
  };
</script>

<script>
  import { Fancybox } from "@fancyapps/ui";
  import "@fancyapps/ui/dist/fancybox/fancybox.css";

  const setup = () => {
    Fancybox.bind(".custom-md img, #post-cover img", {
      clickContent: "close",
      dblclickContent: "zoom",
      click: "close",
      dblclick: "zoom",
      Panels: {
        display: ["counter", "zoom"],
      },
      Images: {
        panning: true,
        zoom: true,
        protect: false,
      },
    } as any);

    window.swup.hooks.on("page:view", () => {
      Fancybox.bind(".custom-md img, #post-cover img", {
        clickContent: "close",
        dblclickContent: "zoom",
        click: "close",
        dblclick: "zoom",
        Panels: {
          display: ["counter", "zoom"],
        },
        Images: {
          panning: true,
          zoom: true,
          protect: false,
        },
      } as any);
    });

    window.swup.hooks.on(
      "content:replace",
      () => {
        Fancybox.unbind(".custom-md img, #post-cover img");
      },
      { before: true }
    );
  };

  if (window.swup) {
    setup();
  } else {
    document.addEventListener("swup:enable", setup);
  }
</script>
