2024-11-21 20:01:52 -03:00
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html lang="{{ lang }}" itemscope itemtype="http://schema.org/WebPage">
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="utf-8" />
|
|
|
|
|
<meta content="IE=edge">
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
|
<!-- Favicon -->
|
|
|
|
|
<link rel='icon' type='image/x-icon' href="/favicon.ico">
|
|
|
|
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
|
|
|
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
|
|
|
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
|
|
|
|
<link rel="manifest" href="/site.webmanifest">
|
|
|
|
|
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
|
|
|
|
|
<meta name="msapplication-TileColor" content="#2b5797">
|
|
|
|
|
<meta name="theme-color" content="#ffffff">
|
|
|
|
|
<!-- Site Title, Description, Author -->
|
|
|
|
|
{% block title %}{% endblock %}
|
|
|
|
|
{% if config.extra.author %}
|
|
|
|
|
<meta name="author" content="{{ config.extra.author }}"/>
|
|
|
|
|
{% endif %}
|
|
|
|
|
<!-- SEO -->
|
|
|
|
|
<script type="application/ld+json">
|
|
|
|
|
{
|
|
|
|
|
"@context": "http://schema.org",
|
|
|
|
|
"@type": "WebSite",
|
|
|
|
|
"name": "{{ config.title }}",
|
|
|
|
|
"url": "{{ config.base_url }}"
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
{% block seo %}{% endblock %}
|
|
|
|
|
<!-- Links and stylesheets -->
|
|
|
|
|
<link rel="preload" href="/font/FiraSans-Regular.woff2" as="font" type="font/woff2" crossorigin>
|
|
|
|
|
<link rel="preload" href="/font/FiraSans-Bold.woff2" as="font" type="font/woff2" crossorigin>
|
|
|
|
|
<link rel="preload" href="/font/forkawesome-webfont.woff2" as="font" type="font/woff2" crossorigin>
|
|
|
|
|
<link rel="stylesheet preload" href="{{ get_url(path='main.css') }}" as="style"/>
|
|
|
|
|
<link rel="stylesheet" href="https://unpkg.com/photoswipe@5.3.7/dist/photoswipe.css" integrity="sha384-IfxC36XL/toUyJ939C73PcgMuRzAZuIzZxE38drsmO5p6jD7ei+Zx/1oA/0l8ysE" crossorigin="anonymous">
|
|
|
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.css" integrity="sha384-GvrOXuhMATgEsSwCs4smul74iXGOixntILdUW9XmUC6+HX0sLNAK3q71HotJqlAn" crossorigin="anonymous">
|
|
|
|
|
<!-- Scripts -->
|
|
|
|
|
<script src="{{ get_url(path='main.js') }}" async></script>
|
|
|
|
|
<script type="module">
|
|
|
|
|
import PhotoSwipeLightbox from "https://unpkg.com/photoswipe@5.3.7/dist/photoswipe-lightbox.esm.min.js";
|
|
|
|
|
import PhotoSwipe from "https://unpkg.com/photoswipe@5.3.7/dist/photoswipe.esm.min.js";
|
|
|
|
|
const lightbox = new PhotoSwipeLightbox({
|
|
|
|
|
gallery: 'figure a',
|
|
|
|
|
pswpModule: PhotoSwipe
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// use <picture> instead of <img>
|
|
|
|
|
lightbox.on('contentLoad', (e) => {
|
|
|
|
|
const { content, isLazy } = e;
|
|
|
|
|
|
|
|
|
|
const avifSrc = content.data.element.dataset.pswpAvif;
|
|
|
|
|
const webpSrc = content.data.element.dataset.pswpWebp;
|
|
|
|
|
if (avifSrc || webpSrc) {
|
|
|
|
|
// prevent to stop the default behavior
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
|
|
|
|
|
content.pictureElement = document.createElement('picture');
|
|
|
|
|
|
|
|
|
|
if (avifSrc) {
|
|
|
|
|
const sourceAvif = document.createElement('source');
|
|
|
|
|
sourceAvif.srcset =avifSrc;
|
|
|
|
|
sourceAvif.type = 'image/avif';
|
|
|
|
|
content.pictureElement.appendChild(sourceAvif);
|
|
|
|
|
}
|
|
|
|
|
if (webpSrc) {
|
|
|
|
|
const sourceWebp = document.createElement('source');
|
|
|
|
|
sourceWebp.srcset = webpSrc;
|
|
|
|
|
sourceWebp.type = 'image/webp';
|
|
|
|
|
content.pictureElement.appendChild(sourceWebp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const source = document.createElement('source');
|
|
|
|
|
source.srcset = content.data.src;
|
|
|
|
|
if (/.png$/.test(content.data.src)) {
|
|
|
|
|
source.type = 'image/png';
|
|
|
|
|
} else {
|
|
|
|
|
source.type = 'image/jpeg';
|
|
|
|
|
}
|
|
|
|
|
content.pictureElement.appendChild(source);
|
|
|
|
|
|
|
|
|
|
content.element = document.createElement('img');
|
|
|
|
|
content.element.src = content.data.src;
|
|
|
|
|
content.element.setAttribute('alt', '');
|
|
|
|
|
content.element.className = 'pswp__img';
|
|
|
|
|
content.pictureElement.appendChild(content.element);
|
|
|
|
|
|
|
|
|
|
content.state = 'loading';
|
|
|
|
|
|
|
|
|
|
if (content.element.complete) {
|
|
|
|
|
content.onLoaded();
|
|
|
|
|
} else {
|
|
|
|
|
content.element.onload = () => {
|
|
|
|
|
content.onLoaded();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
content.element.onerror = () => {
|
|
|
|
|
content.onError();
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// by default PhotoSwipe appends <img>,
|
|
|
|
|
// but we want to append <picture>
|
|
|
|
|
lightbox.on('contentAppend', (e) => {
|
|
|
|
|
const { content } = e;
|
|
|
|
|
if (content.pictureElement && !content.pictureElement.parentNode) {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
content.slide.container.appendChild(content.pictureElement);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// for next/prev navigation with <picture>
|
|
|
|
|
// by default PhotoSwipe removes <img>,
|
|
|
|
|
// but we want to remove <picture>
|
|
|
|
|
lightbox.on('contentRemove', (e) => {
|
|
|
|
|
const { content } = e;
|
|
|
|
|
if (content.pictureElement && content.pictureElement.parentNode) {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
content.pictureElement.remove();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
lightbox.init();
|
|
|
|
|
</script>
|
|
|
|
|
{% if config.mode == "serve" %}
|
|
|
|
|
<!-- The loading of KaTeX is deferred to speed up page rendering -->
|
|
|
|
|
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.js" integrity="sha384-cpW21h6RZv/phavutF+AuVYrr+dA8xD9zs6FwLpaCct6O9ctzYFfFr4dgmgccOTx" crossorigin="anonymous"></script>
|
|
|
|
|
<!-- To automatically render math in text elements, include the auto-render extension: -->
|
|
|
|
|
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/contrib/auto-render.min.js" integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous"></script>
|
|
|
|
|
<script>
|
|
|
|
|
document.addEventListener(
|
|
|
|
|
"DOMContentLoaded",
|
|
|
|
|
function() {
|
|
|
|
|
renderMathInElement(document.body, {
|
|
|
|
|
delimiters: [
|
|
|
|
|
{left: "$$", right: "$$", display: true},
|
|
|
|
|
{left: "$", right: "$", display: false},
|
|
|
|
|
{left: "\\(", right: "\\)", display: false},
|
|
|
|
|
{left: "\\[", right: "\\]", display: true}
|
|
|
|
|
]
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
</script>
|
|
|
|
|
{% endif %}
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
<!-- Navigation -->
|
|
|
|
|
<nav class="navigation" role="navigation" aria-label="main navigation">
|
|
|
|
|
<div class="navbar-brand">
|
|
|
|
|
<a class="navbar-item" href="{{ get_url(path='') }}">
|
2024-11-24 23:45:56 -03:00
|
|
|
<img src="{{ get_url(path='img/logo2024.svg') }}" alt="{{ config.title }}">
|
2024-11-21 20:01:52 -03:00
|
|
|
</a>
|
|
|
|
|
<a role="button" class="navbar-burger" aria-label="menu" data-target="navMenu" aria-expanded="false">
|
|
|
|
|
<span class="icon-bar"></span>
|
|
|
|
|
<span class="icon-bar"></span>
|
|
|
|
|
<span class="icon-bar"></span>
|
|
|
|
|
</a>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="navbar-menu" id="navMenu">
|
|
|
|
|
<div class="navbar-start">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="navbar-end">
|
|
|
|
|
{% for item in config.extra.menu[lang] %}
|
|
|
|
|
{% if item.children %}
|
|
|
|
|
<div class="navbar-item has-dropdown is-hoverable">
|
|
|
|
|
<a class="navbar-link">{{ item.name }}</a>
|
|
|
|
|
<div class="navbar-dropdown">
|
|
|
|
|
{% for child in item.children %}
|
|
|
|
|
<a class="navbar-item" href="{{ get_url(path=child.url) }}">{{ child.name }}</a>
|
|
|
|
|
{% endfor %}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{% else %}
|
|
|
|
|
<a class="navbar-item" title="{{ item.name }}" href="{{ get_url(path=item.url) }}">{{ item.name }}</a>
|
|
|
|
|
{% endif %}
|
|
|
|
|
{% endfor %}
|
|
|
|
|
|
|
|
|
|
{% if config.languages | length > 0 %}
|
|
|
|
|
{% if config.languages | length >= 2 %}
|
|
|
|
|
<div class="navbar-item has-dropdown is-hoverable">
|
|
|
|
|
<a class="navbar-link">A/文</a>
|
|
|
|
|
<div class="navbar-dropdown">
|
|
|
|
|
{% for lang,_ in config.languages %}
|
|
|
|
|
<a class="navbar-item" href="/{{ lang }}" lang="{{ lang }}">{{ lang }}</a>
|
|
|
|
|
{% endfor %}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{% else %}
|
|
|
|
|
{% for lang,_ in config.languages %}
|
|
|
|
|
{% set url = get_url(path=lang | replace(from=config.default_language, to="")) %}
|
|
|
|
|
<a class="navbar-item" lang="{{ lang }}" href="{{ url }}">
|
|
|
|
|
{{ lang }}
|
|
|
|
|
</a>
|
|
|
|
|
{% endfor %}
|
|
|
|
|
{% endif %}
|
|
|
|
|
{% endif %}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</nav>
|
|
|
|
|
|
|
|
|
|
<!-- Header -->
|
|
|
|
|
<header class="wrapper">
|
|
|
|
|
{% block header %}{% endblock %}
|
|
|
|
|
</header>
|
|
|
|
|
|
|
|
|
|
<!-- Main -->
|
|
|
|
|
{% block main %}{% endblock %}
|
|
|
|
|
|
|
|
|
|
<!-- Footer -->
|
|
|
|
|
<footer class="footer">
|
|
|
|
|
<div class="footer-links">
|
|
|
|
|
{% for item in config.extra.social %}
|
|
|
|
|
<a
|
|
|
|
|
{% if item.title == "Mastodon" %}rel="me" {% endif %}
|
|
|
|
|
href="{{ item.url }}"
|
|
|
|
|
title="{{ item.title }}">
|
|
|
|
|
<span class="social-stack">
|
|
|
|
|
<span class="social-circle"></span>
|
|
|
|
|
<span class="{{ item.icon }} social-icon"></span>
|
|
|
|
|
</span>
|
|
|
|
|
</a>
|
|
|
|
|
{% endfor %}
|
|
|
|
|
</div>
|
|
|
|
|
<p class="copyright">
|
|
|
|
|
{% if config.extra.author %}
|
|
|
|
|
{{ config.extra.author }}
|
|
|
|
|
{% endif %}
|
|
|
|
|
|
|
|
|
|
•
|
|
|
|
|
|
|
|
|
|
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0</a> {{ trans(key="unlessLicense",lang=lang) }}
|
|
|
|
|
|
|
|
|
|
{% if config.title %}
|
|
|
|
|
•
|
|
|
|
|
<a href="{#{ "" | absLangURL }#}">{{ config.title }}</a>
|
|
|
|
|
{% endif %}
|
|
|
|
|
</p>
|
|
|
|
|
</footer>
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|