addTask skeleton

This commit is contained in:
Ian Gulliver
2024-12-22 10:23:37 -08:00
parent 721b382e63
commit 3ac8302f11
21 changed files with 381 additions and 99 deletions

56
static/app.css Normal file
View File

@@ -0,0 +1,56 @@
:not(:defined) {
visibility: hidden;
}
:host,
.sl-theme-dark {
--sl-color-primary-50: rgb(254 247 254);
--sl-color-primary-100: rgb(252 229 252);
--sl-color-primary-200: rgb(250 209 250);
--sl-color-primary-300: rgb(247 187 248);
--sl-color-primary-400: rgb(244 154 245);
--sl-color-primary-500: rgb(239 107 240);
--sl-color-primary-600: rgb(226 36 228);
--sl-color-primary-700: rgb(186 30 188);
--sl-color-primary-800: rgb(155 25 156);
--sl-color-primary-900: rgb(111 18 112);
--sl-color-primary-950: rgb(70 11 71);
--sl-input-focus-ring-color: transparent;
}
sl-tab sl-icon {
font-size: 20px;
}
sl-input:focus {
outline: none;
}
sl-input sl-icon {
cursor: pointer;
}
.highlight {
animation: colorFade 1.5s ease forwards;
}
@keyframes colorFade {
0% {
}
5% {
color: var(--sl-color-primary-600);
}
60% {
color: var(--sl-color-primary-600);
}
100% {
}
}
body {
font: 12px var(--sl-font-mono);
display: flex;
flex-direction: column;
align-items: center;
}

View File

@@ -1,28 +1,28 @@
// js/elemwrapper.js
var ElemWrapper = class _ElemWrapper {
elem;
appendChild;
setAttribute;
style;
classList;
addEventListener;
remove;
appendChild;
cloneNode;
contains;
querySelectorAll;
querySelector;
querySelectorAll;
remove;
setAttribute;
constructor(elem) {
this.elem = elem;
this.appendChild = this.elem.appendChild.bind(this.elem);
this.setAttribute = this.elem.setAttribute.bind(this.elem);
this.style = this.elem.style;
this.classList = this.elem.classList;
this.addEventListener = this.elem.addEventListener.bind(this.elem);
this.remove = this.elem.remove.bind(this.elem);
this.appendChild = this.elem.appendChild.bind(this.elem);
this.cloneNode = this.elem.cloneNode.bind(this.elem);
this.contains = this.elem.contains.bind(this.elem);
this.querySelectorAll = this.elem.querySelectorAll.bind(this.elem);
this.querySelector = this.elem.querySelector.bind(this.elem);
this.querySelectorAll = this.elem.querySelectorAll.bind(this.elem);
this.remove = this.elem.remove.bind(this.elem);
this.setAttribute = this.elem.setAttribute.bind(this.elem);
}
static create(tagName) {
return new _ElemWrapper(document.createElement(tagName));
@@ -38,37 +38,88 @@ var ElemWrapper = class _ElemWrapper {
}
return elem;
}
setID(id) {
this.elem.id = id;
}
};
// js/slelem.js
var SLElem = class extends ElemWrapper {
constructor(tagName) {
super(document.createElement(tagName));
}
setSlot(slot) {
this.setAttribute("slot", slot);
}
};
// js/slcard.js
var SLCard = class extends SLElem {
constructor() {
super("sl-card");
}
};
// js/slicon.js
var SLIcon = class extends ElemWrapper {
var SLIcon = class extends SLElem {
constructor(name) {
super(document.createElement("sl-icon"));
super("sl-icon");
this.setAttribute("name", name);
}
};
// js/slinput.js
var SLInput = class extends SLElem {
constructor() {
super("sl-input");
}
addIcon(name, slot) {
const icon = new SLIcon(name);
icon.setSlot(slot);
this.append(icon);
return icon;
}
addPrefixIcon(name) {
return this.addIcon(name, "prefix");
}
addSuffixIcon(name) {
return this.addIcon(name, "suffix");
}
clear() {
this.elem.value = "";
}
getValue() {
return this.elem.value;
}
focus() {
this.elem.focus();
}
setPill() {
this.setAttribute("pill", "");
}
};
// js/sltab.js
var SLTab = class extends ElemWrapper {
var SLTab = class extends SLElem {
constructor(panel) {
super(document.createElement("sl-tab"));
super("sl-tab");
this.setAttribute("panel", panel);
this.setAttribute("slot", "nav");
}
};
// js/sltabpanel.js
var SLTabPanel = class extends ElemWrapper {
var SLTabPanel = class extends SLElem {
constructor(name) {
super(document.createElement("sl-tab-panel"));
super("sl-tab-panel");
this.setAttribute("name", name);
}
};
// js/sltabgroup.js
var SLTabGroup = class extends ElemWrapper {
var SLTabGroup = class extends SLElem {
constructor() {
super(document.createElement("sl-tab-group"));
super("sl-tab-group");
}
addTab(panel) {
const tab = new SLTab(panel);
@@ -94,9 +145,34 @@ async function main() {
const tabGroup = new SLTabGroup();
root.append(tabGroup);
const [tasksTab, tasksPanel] = tabGroup.addTabSet("tasks");
tasksTab.append(new SLIcon("slash-circle"));
tasksTab.append(new SLIcon("list-task"));
const tasksCard = new SLCard();
tasksPanel.append(tasksCard);
const tasksInput = new SLInput();
tasksCard.append(tasksInput);
tasksInput.setPill();
const tasksAddIcon = tasksInput.addSuffixIcon("plus-circle");
const addTask = () => {
const task = tasksInput.getValue();
if (task.length === 0) {
return;
}
tasksInput.clear();
tasksInput.focus();
tasksAddIcon.classList.remove("highlight");
void tasksAddIcon.elem.offsetWidth;
tasksAddIcon.classList.add("highlight");
};
tasksAddIcon.addEventListener("click", () => {
addTask();
});
tasksInput.addEventListener("keydown", (e) => {
if (e.key === "Enter") {
addTask();
}
});
const [tagsTab, tagsPanel] = tabGroup.addTabSet("tags");
tagsTab.append(new SLIcon("tags"));
}
document.addEventListener("DOMContentLoaded", main);
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vdHMvZWxlbXdyYXBwZXIudHMiLCAiLi4vdHMvc2xpY29uLnRzIiwgIi4uL3RzL3NsdGFiLnRzIiwgIi4uL3RzL3NsdGFicGFuZWwudHMiLCAiLi4vdHMvc2x0YWJncm91cC50cyIsICIuLi90cy9tYWluLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogW251bGwsIG51bGwsIG51bGwsIG51bGwsIG51bGwsIG51bGxdLAogICJtYXBwaW5ncyI6ICI7QUFBTSxJQUFPLGNBQVAsTUFBTyxhQUFXO0VBQ2I7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUVQLFlBQVksTUFBaUI7QUFDekIsU0FBSyxPQUFPO0FBQ1osU0FBSyxjQUFjLEtBQUssS0FBSyxZQUFZLEtBQUssS0FBSyxJQUFJO0FBQ3ZELFNBQUssZUFBZSxLQUFLLEtBQUssYUFBYSxLQUFLLEtBQUssSUFBSTtBQUN6RCxTQUFLLFFBQVEsS0FBSyxLQUFLO0FBQ3ZCLFNBQUssWUFBWSxLQUFLLEtBQUs7QUFDM0IsU0FBSyxtQkFBbUIsS0FBSyxLQUFLLGlCQUFpQixLQUFLLEtBQUssSUFBSTtBQUNqRSxTQUFLLFNBQVMsS0FBSyxLQUFLLE9BQU8sS0FBSyxLQUFLLElBQUk7QUFDN0MsU0FBSyxZQUFZLEtBQUssS0FBSyxVQUFVLEtBQUssS0FBSyxJQUFJO0FBQ25ELFNBQUssV0FBVyxLQUFLLEtBQUssU0FBUyxLQUFLLEtBQUssSUFBSTtBQUNqRCxTQUFLLG1CQUFtQixLQUFLLEtBQUssaUJBQWlCLEtBQUssS0FBSyxJQUFJO0FBQ2pFLFNBQUssZ0JBQWdCLEtBQUssS0FBSyxjQUFjLEtBQUssS0FBSyxJQUFJO0VBQy9EO0VBRUEsT0FBTyxPQUFPLFNBQWU7QUFDekIsV0FBTyxJQUFJLGFBQVksU0FBUyxjQUFjLE9BQU8sQ0FBQztFQUMxRDtFQUVBLE9BQU8sTUFBaUI7QUFDcEIsU0FBSyxZQUFZLEtBQUssSUFBSTtFQUM5QjtFQUVBLElBQUksU0FBaUIsT0FBZTtBQUNoQyxVQUFNLE9BQU8sYUFBWSxPQUFPLElBQUk7QUFDcEMsU0FBSyxPQUFPLElBQUk7QUFFaEIsYUFBUyxJQUFJLEdBQUcsSUFBSSxNQUFNLFFBQVEsS0FBSyxHQUFHO0FBQ3RDLFdBQUssYUFBYSxNQUFNLENBQUMsR0FBRyxNQUFNLElBQUksQ0FBQyxDQUFDO0lBQzVDO0FBRUEsV0FBTztFQUNYOzs7O0FDMUNFLElBQU8sU0FBUCxjQUFzQixZQUFXO0VBQ25DLFlBQVksTUFBWTtBQUNwQixVQUFNLFNBQVMsY0FBYyxTQUFTLENBQUM7QUFDdkMsU0FBSyxhQUFhLFFBQVEsSUFBSTtFQUNsQzs7OztBQ0pFLElBQU8sUUFBUCxjQUFxQixZQUFXO0VBQ2xDLFlBQVksT0FBYTtBQUNyQixVQUFNLFNBQVMsY0FBYyxRQUFRLENBQUM7QUFDdEMsU0FBSyxhQUFhLFNBQVMsS0FBSztBQUNoQyxTQUFLLGFBQWEsUUFBUSxLQUFLO0VBQ25DOzs7O0FDTEUsSUFBTyxhQUFQLGNBQTBCLFlBQVc7RUFDdkMsWUFBWSxNQUFZO0FBQ3BCLFVBQU0sU0FBUyxjQUFjLGNBQWMsQ0FBQztBQUM1QyxTQUFLLGFBQWEsUUFBUSxJQUFJO0VBQ2xDOzs7O0FDSEUsSUFBTyxhQUFQLGNBQTBCLFlBQVc7RUFDdkMsY0FBQTtBQUNJLFVBQU0sU0FBUyxjQUFjLGNBQWMsQ0FBQztFQUNoRDtFQUVBLE9BQU8sT0FBYTtBQUNoQixVQUFNLE1BQU0sSUFBSSxNQUFNLEtBQUs7QUFDM0IsU0FBSyxPQUFPLEdBQUc7QUFDZixXQUFPO0VBQ1g7RUFFQSxZQUFZLE1BQVk7QUFDcEIsVUFBTSxXQUFXLElBQUksV0FBVyxJQUFJO0FBQ3BDLFNBQUssT0FBTyxRQUFRO0FBQ3BCLFdBQU87RUFDWDtFQUVBLFVBQVUsTUFBWTtBQUNsQixXQUFPO01BQ0gsS0FBSyxPQUFPLElBQUk7TUFDaEIsS0FBSyxZQUFZLElBQUk7O0VBRTdCOzs7O0FDckJKLGVBQWUsT0FBSTtBQUNmLFFBQU0sT0FBTyxJQUFJLFlBQVksU0FBUyxJQUFJO0FBRTFDLFFBQU0sV0FBVyxJQUFJLFdBQVU7QUFDL0IsT0FBSyxPQUFPLFFBQVE7QUFFcEIsUUFBTSxDQUFDLFVBQVUsVUFBVSxJQUFJLFNBQVMsVUFBVSxPQUFPO0FBQ3pELFdBQVMsT0FBTyxJQUFJLE9BQU8sY0FBYyxDQUFDO0FBRTFDLFFBQU0sQ0FBQyxTQUFTLFNBQVMsSUFBSSxTQUFTLFVBQVUsTUFBTTtBQUN0RCxVQUFRLE9BQU8sSUFBSSxPQUFPLE1BQU0sQ0FBQztBQUNyQztBQUVBLFNBQVMsaUJBQWlCLG9CQUFvQixJQUFJOyIsCiAgIm5hbWVzIjogW10KfQo=
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vdHMvZWxlbXdyYXBwZXIudHMiLCAiLi4vdHMvc2xlbGVtLnRzIiwgIi4uL3RzL3NsY2FyZC50cyIsICIuLi90cy9zbGljb24udHMiLCAiLi4vdHMvc2xpbnB1dC50cyIsICIuLi90cy9zbHRhYi50cyIsICIuLi90cy9zbHRhYnBhbmVsLnRzIiwgIi4uL3RzL3NsdGFiZ3JvdXAudHMiLCAiLi4vdHMvbWFpbi50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFtudWxsLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCBudWxsXSwKICAibWFwcGluZ3MiOiAiO0FBQU0sSUFBTyxjQUFQLE1BQU8sYUFBVztFQUNiO0VBRUE7RUFDQTtFQUVBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFFUCxZQUFZLE1BQWlCO0FBQ3pCLFNBQUssT0FBTztBQUVaLFNBQUssUUFBUSxLQUFLLEtBQUs7QUFDdkIsU0FBSyxZQUFZLEtBQUssS0FBSztBQUUzQixTQUFLLG1CQUFtQixLQUFLLEtBQUssaUJBQWlCLEtBQUssS0FBSyxJQUFJO0FBQ2pFLFNBQUssY0FBYyxLQUFLLEtBQUssWUFBWSxLQUFLLEtBQUssSUFBSTtBQUN2RCxTQUFLLFlBQVksS0FBSyxLQUFLLFVBQVUsS0FBSyxLQUFLLElBQUk7QUFDbkQsU0FBSyxXQUFXLEtBQUssS0FBSyxTQUFTLEtBQUssS0FBSyxJQUFJO0FBQ2pELFNBQUssZ0JBQWdCLEtBQUssS0FBSyxjQUFjLEtBQUssS0FBSyxJQUFJO0FBQzNELFNBQUssbUJBQW1CLEtBQUssS0FBSyxpQkFBaUIsS0FBSyxLQUFLLElBQUk7QUFDakUsU0FBSyxTQUFTLEtBQUssS0FBSyxPQUFPLEtBQUssS0FBSyxJQUFJO0FBQzdDLFNBQUssZUFBZSxLQUFLLEtBQUssYUFBYSxLQUFLLEtBQUssSUFBSTtFQUM3RDtFQUVBLE9BQU8sT0FBTyxTQUFlO0FBQ3pCLFdBQU8sSUFBSSxhQUFZLFNBQVMs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

View File

@@ -14,38 +14,8 @@
href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.18.0/cdn/themes/dark.css"
onload="document.documentElement.classList.add('sl-theme-dark');"
/>
<style>
:not(:defined) {
visibility: hidden;
}
:host,
.sl-theme-dark {
--sl-color-primary-50: rgb(254 247 254);
--sl-color-primary-100: rgb(252 229 252);
--sl-color-primary-200: rgb(250 209 250);
--sl-color-primary-300: rgb(247 187 248);
--sl-color-primary-400: rgb(244 154 245);
--sl-color-primary-500: rgb(239 107 240);
--sl-color-primary-600: rgb(226 36 228);
--sl-color-primary-700: rgb(186 30 188);
--sl-color-primary-800: rgb(155 25 156);
--sl-color-primary-900: rgb(111 18 112);
--sl-color-primary-950: rgb(70 11 71);
}
sl-tab sl-icon {
font-size: 20px;
}
body {
font: 12px var(--sl-font-mono);
display: flex;
flex-direction: column;
align-items: center;
}
</style>
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAACXBIWXMAAAsTAAALEwEAmpwYAAADb2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNi4wLjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4yNTY8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+MjU2PC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5QaXhlbG1hdG9yIFBybyAzLjYuMTQ8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAyNC0xMi0yMVQwNjo1Njo1MS0wODowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHRpZmY6WFJlc29sdXRpb24+NzIwMDAwLzEwMDAwPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpSZXNvbHV0aW9uVW5pdD4yPC90aWZmOlJlc29sdXRpb25Vbml0PgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj43MjAwMDAvMTAwMDA8L3RpZmY6WVJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgqN3zs2AAAEQUlEQVR42u3dsWrbUBSA4UATSItDm46lMcG+wgSTKS+Ql+jzemwHLy0YPKQR0rkyQYGQTE3I4L5DKJZcfR+cXXDOr0mggwMAAAAAAAAAAAAAAAAAAAAAAHiL8rw8Xs/WJ32YxfXi0EZgR5ppc1an/KdOedv1RNr88gIA8QPiB8QPiB8QPyB+QPyA+AHxA+IH8YsfxC9+EL/4QfziB/GLH8QvfhC/+EH84gfxix/EL34Qv/hB/OIH8YsfxA+IHxA/IH5A/ID4AfED4gfED4gfxC9+EL/4QfziB/GLH8QvfhC/+EH84gfxix/EL34Qv/hB/OIH8YsfxC9+EL/4YTdiGmmf41/N21GV8l2V4qXrqVPOyy/LD66K/Yj/Ioq6yK/7HH+kpu3D89cp37fzduSqEL/4QfziB/GLH8QvfhC/+EH84gfxix/EL34Qv/hB/OIH8YsfxC9+EL/4QfziB/GLH8QvfsTffTxFU26vtkfiB/GLH8QvfhC/+EH84gfxix+GFH91WZ2KHwYZ/+NpleJJ/CB+8YP4xQ/iFz+IX/wgfvEjfvGLH/GLX/yIX/ziR/ziFz/iF7/4Eb/4xY/4xS9+xC9+EL/4QfziB/H/2/jrlB/FD+LvcJqn6rI6dVWIf4Dxxzw+uyrEL34Qv/hB/OIH8YsfxD/Q+JdXy6NI+XukHF1PnfJNeV5+UoX4xb+j+OsibnvyncLzZrIZq0L84hc/4he/+BG/+MWP+MUvfsQvfvEjfvGLH/GLX/z01800kvjFL/4BaqbNWZXiWfziF7/4xS9+xC9+8SN+8Ysf8Ytf/Ihf/OJH/OIXP+IXv/gRv/j3J/4omte4iEIV4hf/AOO/nd3OVCF+8Ysf8Ytf/Ihf/OJH/OIXP+IXv/gRv/jFj/jFL37662Hy8LFO+aYPv4uKlH+IX/wgfvGD+MUP4hc/iF/8iF/84mdw8Y8r8YufIVrNV6NIuRW/+BG/+MWP+MUvfsQvfvEjfvGLH/GLX/yIX/ziR/ziB/GLH8QvfhC/+EH84gfxix/EL34Qv/hB/OIH8Ysf/qv48734YaDxt/N2JH4Qv/hB/OIH8YsfxC9+EL/4YUjxb79t30WRf4ofBhh/LX4Qv/hB/OIH8YsfxC9+EL/4Eb/4xY/4xS9+xC9+8SN+8Ysf8Ytf/Ihf/OJH/OIXP+IXv6tC/OIH8Ysfeia+xvtITVQpXrqffLfP8dcpP/+eROGqYAf6Fv9mshnbCogfED8gfkD8gPgB8QPiB8QPiB8QP4hf/CB+8YP4xQ/iFz+IX/wgfvGD+MUP4hc/iF/8IH7xg/jFD+IXP4hf/CB+QPyA+AHxA+IHxA+IHxA/IH5A/CB+8YP4xQ/iFz+IX/wgfvGD+MUP4hc/iF/8IH7xg/jFD+IXP4hf/CB+8YP4gd1YXC8O17P1SR+mPC+PbQQAAAAAAAAAAAAAAAAAAAAAgDf5Cx0DM6ztMrCxAAAAAElFTkSuQmCC">
<link rel="stylesheet" href="app.css" />
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAACXBIWXMAAAsTAAALEwEAmpwYAAADb2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNi4wLjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4yNTY8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+MjU2PC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5QaXhlbG1hdG9yIFBybyAzLjYuMTQ8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAyNC0xMi0yMVQwNjo1Njo1MS0wODowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPHRpZmY6WFJlc29sdXRpb24+NzIwMDAwLzEwMDAwPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpSZXNvbHV0aW9uVW5pdD4yPC90aWZmOlJlc29sdXRpb25Vbml0PgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj43MjAwMDAvMTAwMDA8L3RpZmY6WVJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgqN3zs2AAAEQUlEQVR42u3dsWrbUBSA4UATSItDm46lMcG+wgSTKS+Ql+jzemwHLy0YPKQR0rkyQYGQTE3I4L5DKJZcfR+cXXDOr0mggwMAAAAAAAAAAAAAAAAAAAAAAHiL8rw8Xs/WJ32YxfXi0EZgR5ppc1an/KdOedv1RNr88gIA8QPiB8QPiB8QPyB+QPyA+AHxA+IH8YsfxC9+EL/4QfziB/GLH8QvfhC/+EH84gfxix/EL34Qv/hB/OIH8YsfxA+IHxA/IH5A/ID4AfED4gfED4gfxC9+EL/4QfziB/GLH8QvfhC/+EH84gfxix/EL34Qv/hB/OIH8YsfxC9+EL/4YTdiGmmf41/N21GV8l2V4qXrqVPOyy/LD66K/Yj/Ioq6yK/7HH+kpu3D89cp37fzduSqEL/4QfziB/GLH8QvfhC/+EH84gfxix/EL34Qv/hB/OIH8YsfxC9+EL/4QfziB/GLH8QvfsTffTxFU26vtkfiB/GLH8QvfhC/+EH84gfxix+GFH91WZ2KHwYZ/+NpleJJ/CB+8YP4xQ/iFz+IX/wgfvEjfvGLH/GLX/yIX/ziR/ziFz/iF7/4Eb/4xY/4xS9+xC9+EL/4QfziB/H/2/jrlB/FD+LvcJqn6rI6dVWIf4Dxxzw+uyrEL34Qv/hB/OIH8YsfxD/Q+JdXy6NI+XukHF1PnfJNeV5+UoX4xb+j+OsibnvyncLzZrIZq0L84hc/4he/+BG/+MWP+MUvfsQvfvEjfvGLH/GLX/z01800kvjFL/4BaqbNWZXiWfziF7/4xS9+xC9+8SN+8Ysf8Ytf/Ihf/OJH/OIXP+IXv/gRv/j3J/4omte4iEIV4hf/AOO/nd3OVCF+8Ysf8Ytf/Ihf/OJH/OIXP+IXv/gRv/jFj/jFL37662Hy8LFO+aYPv4uKlH+IX/wgfvGD+MUP4hc/iF/8iF/84mdw8Y8r8YufIVrNV6NIuRW/+BG/+MWP+MUvfsQvfvEjfvGLH/GLX/yIX/ziR/ziB/GLH8QvfhC/+EH84gfxix/EL34Qv/hB/OIH8Ysf/qv48734YaDxt/N2JH4Qv/hB/OIH8YsfxC9+EL/4YUjxb79t30WRf4ofBhh/LX4Qv/hB/OIH8YsfxC9+EL/4Eb/4xY/4xS9+xC9+8SN+8Ysf8Ytf/Ihf/OJH/OIXP+IXv6tC/OIH8Ysfeia+xvtITVQpXrqffLfP8dcpP/+eROGqYAf6Fv9mshnbCogfED8gfkD8gPgB8QPiB8QPiB8QP4hf/CB+8YP4xQ/iFz+IX/wgfvGD+MUP4hc/iF/8IH7xg/jFD+IXP4hf/CB+QPyA+AHxA+IHxA+IHxA/IH5A/CB+8YP4xQ/iFz+IX/wgfvGD+MUP4hc/iF/8IH7xg/jFD+IXP4hf/CB+8YP4gd1YXC8O17P1SR+mPC+PbQQAAAAAAAAAAAAAAAAAAAAAgDf5Cx0DM6ztMrCxAAAAAElFTkSuQmCC" />
<script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.18.0/cdn/shoelace-autoloader.js"></script>
<script type="module" src="app.mjs"></script>
</head>