diff --git a/.prettierrc b/.prettierrc
index e69de29..b63b7ad 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -0,0 +1,5 @@
+{
+ "useTabs": true,
+ "trailingComma": "all",
+ "singleQuote": false
+}
diff --git a/assets/scss/_variables.scss b/assets/scss/_variables.scss
new file mode 100644
index 0000000..f1b0ec3
--- /dev/null
+++ b/assets/scss/_variables.scss
@@ -0,0 +1,19 @@
+:root {
+ --dark-background: #2B303A;
+ --light-background: #F5F5F5;
+
+ --dark-text: #FFFFFF;
+ --light-text: #000000;
+
+ --dark-primary: #087E8B;
+ --light-primary: #67AEB5;
+
+ --dark-secondary: #7C7F85;
+ --light-secondary: #A4A6AA;
+
+ --dark-danger: #D64933;
+ --light-danger: #FF5A5F;
+
+ --dark-success: #4DA167;
+ --light-success: #77B68B;
+}
diff --git a/assets/scss/style.scss b/assets/scss/style.scss
new file mode 100644
index 0000000..806ff8c
--- /dev/null
+++ b/assets/scss/style.scss
@@ -0,0 +1,26 @@
+@use "node_modules/normalize.css/normalize";
+@use "_variables";
+
+body {
+ font-family: sans-serif;
+ background-color: var(--light-background);
+ color: var(--light-text);
+
+ &:dark {
+ background-color: var(--dark-background);
+ color: var(--dark-text);
+ }
+}
+
+.auth {
+ width: 100%;
+ @media (min-width: 640px) {
+ max-width: 520px;
+ }
+ margin: 1rem auto;
+
+ p {
+ display: flex;
+ flex-direction: column;
+ }
+}
diff --git a/cmd/seed/seed.go b/cmd/seed/seed.go
index 0773354..6ea7067 100644
--- a/cmd/seed/seed.go
+++ b/cmd/seed/seed.go
@@ -30,7 +30,10 @@ func run(c *cli.Context) error {
return errors.Wrap(err, "creating postgres database")
}
- a := app.NewApp(cfg, db)
+ a, err := app.NewApp(cfg, db)
+ if err != nil {
+ return errors.Wrap(err, "creating app")
+ }
log.Debug().Msg("Creating account")
acct, err := a.Account().CreateLocal(c.Context, "testington", "no@mercury.example", []byte("password"))
diff --git a/cmd/web/cmd.go b/cmd/web/cmd.go
index 60917d8..e607e7e 100644
--- a/cmd/web/cmd.go
+++ b/cmd/web/cmd.go
@@ -39,7 +39,10 @@ func run(c *cli.Context) error {
return errors.Wrap(err, "creating postgres database")
}
- a := app.NewApp(cfg, db)
+ a, err := app.NewApp(cfg, db)
+ if err != nil {
+ return errors.Wrap(err, "creating app")
+ }
log.Debug().Msg("Mounting routes")
web.Routes(a)
diff --git a/frontend/index.html b/frontend/index.html
index b6c5f0a..09162dc 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -1,13 +1,13 @@
-
-
-
-
- Vite + Svelte + TS
-
-
-
-
-
+
+
+
+
+ Vite + Svelte + TS
+
+
+
+
+
diff --git a/frontend/package.json b/frontend/package.json
index 100004b..9b9d45a 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -1,22 +1,26 @@
{
- "name": "frontend",
- "private": true,
- "version": "0.0.0",
- "type": "module",
- "scripts": {
- "dev": "vite",
- "build": "vite build",
- "preview": "vite preview",
- "check": "svelte-check --tsconfig ./tsconfig.json"
- },
- "devDependencies": {
- "@sveltejs/vite-plugin-svelte": "^2.4.2",
- "@tsconfig/svelte": "^5.0.0",
- "prettier": "^3.0.3",
- "svelte": "^4.0.5",
- "svelte-check": "^3.4.6",
- "tslib": "^2.6.0",
- "typescript": "^5.0.2",
- "vite": "^4.4.5"
- }
+ "name": "frontend",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "preview": "vite preview",
+ "check": "svelte-check --tsconfig ./tsconfig.json"
+ },
+ "devDependencies": {
+ "@sveltejs/vite-plugin-svelte": "^2.4.2",
+ "@tsconfig/svelte": "^5.0.0",
+ "prettier": "^3.0.3",
+ "sass": "^1.66.1",
+ "svelte": "^4.0.5",
+ "svelte-check": "^3.4.6",
+ "tslib": "^2.6.0",
+ "typescript": "^5.0.2",
+ "vite": "^4.4.5"
+ },
+ "dependencies": {
+ "normalize.css": "^8.0.1"
+ }
}
diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml
index 62adf95..43f7a54 100644
--- a/frontend/pnpm-lock.yaml
+++ b/frontend/pnpm-lock.yaml
@@ -1,5 +1,10 @@
lockfileVersion: "6.0"
+dependencies:
+ normalize.css:
+ specifier: ^8.0.1
+ version: 8.0.1
+
devDependencies:
"@sveltejs/vite-plugin-svelte":
specifier: ^2.4.2
@@ -10,12 +15,15 @@ devDependencies:
prettier:
specifier: ^3.0.3
version: 3.0.3
+ sass:
+ specifier: ^1.66.1
+ version: 1.66.1
svelte:
specifier: ^4.0.5
version: 4.0.5
svelte-check:
specifier: ^3.4.6
- version: 3.4.6(svelte@4.0.5)
+ version: 3.4.6(sass@1.66.1)(svelte@4.0.5)
tslib:
specifier: ^2.6.0
version: 2.6.0
@@ -24,7 +32,7 @@ devDependencies:
version: 5.0.2
vite:
specifier: ^4.4.5
- version: 4.4.5
+ version: 4.4.5(sass@1.66.1)
packages:
/@ampproject/remapping@2.2.1:
@@ -391,7 +399,7 @@ packages:
"@sveltejs/vite-plugin-svelte": 2.4.2(svelte@4.0.5)(vite@4.4.5)
debug: 4.3.4
svelte: 4.0.5
- vite: 4.4.5
+ vite: 4.4.5(sass@1.66.1)
transitivePeerDependencies:
- supports-color
dev: true
@@ -413,7 +421,7 @@ packages:
magic-string: 0.30.3
svelte: 4.0.5
svelte-hmr: 0.15.3(svelte@4.0.5)
- vite: 4.4.5
+ vite: 4.4.5(sass@1.66.1)
vitefu: 0.2.4(vite@4.4.5)
transitivePeerDependencies:
- supports-color
@@ -747,6 +755,13 @@ packages:
}
dev: true
+ /immutable@4.3.4:
+ resolution:
+ {
+ integrity: sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==,
+ }
+ dev: true
+
/import-fresh@3.3.0:
resolution:
{
@@ -947,6 +962,13 @@ packages:
engines: { node: ">=0.10.0" }
dev: true
+ /normalize.css@8.0.1:
+ resolution:
+ {
+ integrity: sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==,
+ }
+ dev: false
+
/once@1.4.0:
resolution:
{
@@ -1106,6 +1128,19 @@ packages:
rimraf: 2.7.1
dev: true
+ /sass@1.66.1:
+ resolution:
+ {
+ integrity: sha512-50c+zTsZOJVgFfTgwwEzkjA3/QACgdNsKueWPyAR0mRINIvLAStVQBbPg14iuqEQ74NPDbXzJARJ/O4SI1zftA==,
+ }
+ engines: { node: ">=14.0.0" }
+ hasBin: true
+ dependencies:
+ chokidar: 3.5.3
+ immutable: 4.3.4
+ source-map-js: 1.0.2
+ dev: true
+
/sorcery@0.11.0:
resolution:
{
@@ -1137,7 +1172,7 @@ packages:
min-indent: 1.0.1
dev: true
- /svelte-check@3.4.6(svelte@4.0.5):
+ /svelte-check@3.4.6(sass@1.66.1)(svelte@4.0.5):
resolution:
{
integrity: sha512-OBlY8866Zh1zHQTkBMPS6psPi7o2umTUyj6JWm4SacnIHXpWFm658pG32m3dKvKFL49V4ntAkfFHKo4ztH07og==,
@@ -1153,7 +1188,7 @@ packages:
picocolors: 1.0.0
sade: 1.8.1
svelte: 4.0.5
- svelte-preprocess: 5.0.4(svelte@4.0.5)(typescript@5.2.2)
+ svelte-preprocess: 5.0.4(sass@1.66.1)(svelte@4.0.5)(typescript@5.2.2)
typescript: 5.2.2
transitivePeerDependencies:
- "@babel/core"
@@ -1179,7 +1214,7 @@ packages:
svelte: 4.0.5
dev: true
- /svelte-preprocess@5.0.4(svelte@4.0.5)(typescript@5.2.2):
+ /svelte-preprocess@5.0.4(sass@1.66.1)(svelte@4.0.5)(typescript@5.2.2):
resolution:
{
integrity: sha512-ABia2QegosxOGsVlsSBJvoWeXy1wUKSfF7SWJdTjLAbx/Y3SrVevvvbFNQqrSJw89+lNSsM58SipmZJ5SRi5iw==,
@@ -1223,6 +1258,7 @@ packages:
"@types/pug": 2.0.6
detect-indent: 6.1.0
magic-string: 0.27.0
+ sass: 1.66.1
sorcery: 0.11.0
strip-indent: 3.0.0
svelte: 4.0.5
@@ -1286,7 +1322,7 @@ packages:
hasBin: true
dev: true
- /vite@4.4.5:
+ /vite@4.4.5(sass@1.66.1):
resolution:
{
integrity: sha512-4m5kEtAWHYr0O1Fu7rZp64CfO1PsRGZlD3TAB32UmQlpd7qg15VF7ROqGN5CyqN7HFuwr7ICNM2+fDWRqFEKaA==,
@@ -1320,6 +1356,7 @@ packages:
esbuild: 0.18.20
postcss: 8.4.29
rollup: 3.28.1
+ sass: 1.66.1
optionalDependencies:
fsevents: 2.3.3
dev: true
@@ -1335,7 +1372,7 @@ packages:
vite:
optional: true
dependencies:
- vite: 4.4.5
+ vite: 4.4.5(sass@1.66.1)
dev: true
/wrappy@1.0.2:
diff --git a/frontend/src/app.css b/frontend/src/app.css
index b87aec7..9e908b9 100644
--- a/frontend/src/app.css
+++ b/frontend/src/app.css
@@ -1,80 +1,80 @@
:root {
- font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
- line-height: 1.5;
- font-weight: 400;
+ font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
+ line-height: 1.5;
+ font-weight: 400;
- color-scheme: light dark;
- color: rgba(255, 255, 255, 0.87);
- background-color: #242424;
+ color-scheme: light dark;
+ color: rgba(255, 255, 255, 0.87);
+ background-color: #242424;
- font-synthesis: none;
- text-rendering: optimizeLegibility;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- -webkit-text-size-adjust: 100%;
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-text-size-adjust: 100%;
}
a {
- font-weight: 500;
- color: #646cff;
- text-decoration: inherit;
+ font-weight: 500;
+ color: #646cff;
+ text-decoration: inherit;
}
a:hover {
- color: #535bf2;
+ color: #535bf2;
}
body {
- margin: 0;
- display: flex;
- place-items: center;
- min-width: 320px;
- min-height: 100vh;
+ margin: 0;
+ display: flex;
+ place-items: center;
+ min-width: 320px;
+ min-height: 100vh;
}
h1 {
- font-size: 3.2em;
- line-height: 1.1;
+ font-size: 3.2em;
+ line-height: 1.1;
}
.card {
- padding: 2em;
+ padding: 2em;
}
#app {
- max-width: 1280px;
- margin: 0 auto;
- padding: 2rem;
- text-align: center;
+ max-width: 1280px;
+ margin: 0 auto;
+ padding: 2rem;
+ text-align: center;
}
button {
- border-radius: 8px;
- border: 1px solid transparent;
- padding: 0.6em 1.2em;
- font-size: 1em;
- font-weight: 500;
- font-family: inherit;
- background-color: #1a1a1a;
- cursor: pointer;
- transition: border-color 0.25s;
+ border-radius: 8px;
+ border: 1px solid transparent;
+ padding: 0.6em 1.2em;
+ font-size: 1em;
+ font-weight: 500;
+ font-family: inherit;
+ background-color: #1a1a1a;
+ cursor: pointer;
+ transition: border-color 0.25s;
}
button:hover {
- border-color: #646cff;
+ border-color: #646cff;
}
button:focus,
button:focus-visible {
- outline: 4px auto -webkit-focus-ring-color;
+ outline: 4px auto -webkit-focus-ring-color;
}
@media (prefers-color-scheme: light) {
- :root {
- color: #213547;
- background-color: #ffffff;
- }
- a:hover {
- color: #747bff;
- }
- button {
- background-color: #f9f9f9;
- }
+ :root {
+ color: #213547;
+ background-color: #ffffff;
+ }
+ a:hover {
+ color: #747bff;
+ }
+ button {
+ background-color: #f9f9f9;
+ }
}
diff --git a/frontend/src/main.ts b/frontend/src/main.ts
index 7ece250..b1acd03 100644
--- a/frontend/src/main.ts
+++ b/frontend/src/main.ts
@@ -2,7 +2,7 @@ import "./app.css";
import App from "./App.svelte";
const app = new App({
- target: document.getElementById("app"),
+ target: document.getElementById("app"),
});
export default app;
diff --git a/frontend/svelte.config.js b/frontend/svelte.config.js
index de2ddd6..69d7904 100644
--- a/frontend/svelte.config.js
+++ b/frontend/svelte.config.js
@@ -1,7 +1,7 @@
import { vitePreprocess } from "@sveltejs/vite-plugin-svelte";
export default {
- // Consult https://svelte.dev/docs#compile-time-svelte-preprocess
- // for more information about preprocessors
- preprocess: vitePreprocess(),
+ // Consult https://svelte.dev/docs#compile-time-svelte-preprocess
+ // for more information about preprocessors
+ preprocess: vitePreprocess(),
};
diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json
index c4e1c5f..3941f55 100644
--- a/frontend/tsconfig.json
+++ b/frontend/tsconfig.json
@@ -1,20 +1,20 @@
{
- "extends": "@tsconfig/svelte/tsconfig.json",
- "compilerOptions": {
- "target": "ESNext",
- "useDefineForClassFields": true,
- "module": "ESNext",
- "resolveJsonModule": true,
- /**
- * Typecheck JS in `.svelte` and `.js` files by default.
- * Disable checkJs if you'd like to use dynamic types in JS.
- * Note that setting allowJs false does not prevent the use
- * of JS in `.svelte` files.
- */
- "allowJs": true,
- "checkJs": true,
- "isolatedModules": true
- },
- "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"],
- "references": [{ "path": "./tsconfig.node.json" }]
+ "extends": "@tsconfig/svelte/tsconfig.json",
+ "compilerOptions": {
+ "target": "ESNext",
+ "useDefineForClassFields": true,
+ "module": "ESNext",
+ "resolveJsonModule": true,
+ /**
+ * Typecheck JS in `.svelte` and `.js` files by default.
+ * Disable checkJs if you'd like to use dynamic types in JS.
+ * Note that setting allowJs false does not prevent the use
+ * of JS in `.svelte` files.
+ */
+ "allowJs": true,
+ "checkJs": true,
+ "isolatedModules": true
+ },
+ "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"],
+ "references": [{ "path": "./tsconfig.node.json" }]
}
diff --git a/frontend/tsconfig.node.json b/frontend/tsconfig.node.json
index 494bfe0..5c17c9b 100644
--- a/frontend/tsconfig.node.json
+++ b/frontend/tsconfig.node.json
@@ -1,9 +1,9 @@
{
- "compilerOptions": {
- "composite": true,
- "skipLibCheck": true,
- "module": "ESNext",
- "moduleResolution": "bundler"
- },
- "include": ["vite.config.ts"]
+ "compilerOptions": {
+ "composite": true,
+ "skipLibCheck": true,
+ "module": "ESNext",
+ "moduleResolution": "bundler"
+ },
+ "include": ["vite.config.ts"]
}
diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts
index 73adabc..a49f5af 100644
--- a/frontend/vite.config.ts
+++ b/frontend/vite.config.ts
@@ -3,8 +3,8 @@ import { svelte } from "@sveltejs/vite-plugin-svelte";
// https://vitejs.dev/config/
export default defineConfig({
- plugins: [svelte()],
- build: {
- manifest: "manifest.json",
- },
+ plugins: [svelte()],
+ build: {
+ manifest: "manifest.json",
+ },
});
diff --git a/go.mod b/go.mod
index a3b5b36..c95dc37 100644
--- a/go.mod
+++ b/go.mod
@@ -5,6 +5,7 @@ go 1.19
require (
emperror.dev/errors v0.8.1
github.com/BurntSushi/toml v1.2.1
+ github.com/flosch/pongo2/v6 v6.0.0
github.com/georgysavva/scany/v2 v2.0.0
github.com/go-chi/chi/v5 v5.0.8
github.com/go-chi/render v1.0.2
diff --git a/go.sum b/go.sum
index d26a037..8364a8a 100644
--- a/go.sum
+++ b/go.sum
@@ -102,6 +102,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
+github.com/flosch/pongo2/v6 v6.0.0 h1:lsGru8IAzHgIAw6H2m4PCyleO58I40ow6apih0WprMU=
+github.com/flosch/pongo2/v6 v6.0.0/go.mod h1:CuDpFm47R0uGGE7z13/tTlt1Y6zdxvr2RLT5LJhsHEU=
github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..7613555
--- /dev/null
+++ b/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "mercury",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "watch:style": "sass -I . -w assets/scss/:web/frontend/assets/css/ --style compressed"
+ },
+ "keywords": [],
+ "author": "sam ",
+ "license": "APGL-3.0-only",
+ "devDependencies": {
+ "normalize.css": "^8.0.1",
+ "sass": "^1.66.1"
+ }
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
new file mode 100644
index 0000000..261f401
--- /dev/null
+++ b/pnpm-lock.yaml
@@ -0,0 +1,1028 @@
+lockfileVersion: '6.0'
+
+importers:
+
+ .:
+ devDependencies:
+ normalize.css:
+ specifier: ^8.0.1
+ version: 8.0.1
+ sass:
+ specifier: ^1.66.1
+ version: 1.66.1
+
+ frontend:
+ dependencies:
+ normalize.css:
+ specifier: ^8.0.1
+ version: 8.0.1
+ devDependencies:
+ '@sveltejs/vite-plugin-svelte':
+ specifier: ^2.4.2
+ version: 2.4.2(svelte@4.0.5)(vite@4.4.5)
+ '@tsconfig/svelte':
+ specifier: ^5.0.0
+ version: 5.0.0
+ prettier:
+ specifier: ^3.0.3
+ version: 3.0.3
+ sass:
+ specifier: ^1.66.1
+ version: 1.66.1
+ svelte:
+ specifier: ^4.0.5
+ version: 4.0.5
+ svelte-check:
+ specifier: ^3.4.6
+ version: 3.4.6(sass@1.66.1)(svelte@4.0.5)
+ tslib:
+ specifier: ^2.6.0
+ version: 2.6.0
+ typescript:
+ specifier: ^5.0.2
+ version: 5.0.2
+ vite:
+ specifier: ^4.4.5
+ version: 4.4.5(sass@1.66.1)
+
+packages:
+
+ /@ampproject/remapping@2.2.1:
+ resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==}
+ engines: {node: '>=6.0.0'}
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.3
+ '@jridgewell/trace-mapping': 0.3.19
+ dev: true
+
+ /@esbuild/android-arm64@0.18.20:
+ resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [android]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/android-arm@0.18.20:
+ resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [android]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/android-x64@0.18.20:
+ resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [android]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/darwin-arm64@0.18.20:
+ resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [darwin]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/darwin-x64@0.18.20:
+ resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [darwin]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/freebsd-arm64@0.18.20:
+ resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [freebsd]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/freebsd-x64@0.18.20:
+ resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [freebsd]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-arm64@0.18.20:
+ resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-arm@0.18.20:
+ resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-ia32@0.18.20:
+ resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-loong64@0.18.20:
+ resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==}
+ engines: {node: '>=12'}
+ cpu: [loong64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-mips64el@0.18.20:
+ resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==}
+ engines: {node: '>=12'}
+ cpu: [mips64el]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-ppc64@0.18.20:
+ resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-riscv64@0.18.20:
+ resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==}
+ engines: {node: '>=12'}
+ cpu: [riscv64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-s390x@0.18.20:
+ resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==}
+ engines: {node: '>=12'}
+ cpu: [s390x]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/linux-x64@0.18.20:
+ resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/netbsd-x64@0.18.20:
+ resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [netbsd]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/openbsd-x64@0.18.20:
+ resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [openbsd]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/sunos-x64@0.18.20:
+ resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [sunos]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/win32-arm64@0.18.20:
+ resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [win32]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/win32-ia32@0.18.20:
+ resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [win32]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@esbuild/win32-x64@0.18.20:
+ resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [win32]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /@jridgewell/gen-mapping@0.3.3:
+ resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==}
+ engines: {node: '>=6.0.0'}
+ dependencies:
+ '@jridgewell/set-array': 1.1.2
+ '@jridgewell/sourcemap-codec': 1.4.15
+ '@jridgewell/trace-mapping': 0.3.19
+ dev: true
+
+ /@jridgewell/resolve-uri@3.1.1:
+ resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==}
+ engines: {node: '>=6.0.0'}
+ dev: true
+
+ /@jridgewell/set-array@1.1.2:
+ resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==}
+ engines: {node: '>=6.0.0'}
+ dev: true
+
+ /@jridgewell/sourcemap-codec@1.4.15:
+ resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
+ dev: true
+
+ /@jridgewell/trace-mapping@0.3.19:
+ resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==}
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.1
+ '@jridgewell/sourcemap-codec': 1.4.15
+ dev: true
+
+ /@nodelib/fs.scandir@2.1.5:
+ resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+ engines: {node: '>= 8'}
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ run-parallel: 1.2.0
+ dev: true
+
+ /@nodelib/fs.stat@2.0.5:
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+ engines: {node: '>= 8'}
+ dev: true
+
+ /@nodelib/fs.walk@1.2.8:
+ resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+ engines: {node: '>= 8'}
+ dependencies:
+ '@nodelib/fs.scandir': 2.1.5
+ fastq: 1.15.0
+ dev: true
+
+ /@sveltejs/vite-plugin-svelte-inspector@1.0.4(@sveltejs/vite-plugin-svelte@2.4.2)(svelte@4.0.5)(vite@4.4.5):
+ resolution: {integrity: sha512-zjiuZ3yydBtwpF3bj0kQNV0YXe+iKE545QGZVTaylW3eAzFr+pJ/cwK8lZEaRp4JtaJXhD5DyWAV4AxLh6DgaQ==}
+ engines: {node: ^14.18.0 || >= 16}
+ peerDependencies:
+ '@sveltejs/vite-plugin-svelte': ^2.2.0
+ svelte: ^3.54.0 || ^4.0.0
+ vite: ^4.0.0
+ dependencies:
+ '@sveltejs/vite-plugin-svelte': 2.4.2(svelte@4.0.5)(vite@4.4.5)
+ debug: 4.3.4
+ svelte: 4.0.5
+ vite: 4.4.5(sass@1.66.1)
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@sveltejs/vite-plugin-svelte@2.4.2(svelte@4.0.5)(vite@4.4.5):
+ resolution: {integrity: sha512-ePfcC48ftMKhkT0OFGdOyycYKnnkT6i/buzey+vHRTR/JpQvuPzzhf1PtKqCDQfJRgoPSN2vscXs6gLigx/zGw==}
+ engines: {node: ^14.18.0 || >= 16}
+ peerDependencies:
+ svelte: ^3.54.0 || ^4.0.0
+ vite: ^4.0.0
+ dependencies:
+ '@sveltejs/vite-plugin-svelte-inspector': 1.0.4(@sveltejs/vite-plugin-svelte@2.4.2)(svelte@4.0.5)(vite@4.4.5)
+ debug: 4.3.4
+ deepmerge: 4.3.1
+ kleur: 4.1.5
+ magic-string: 0.30.3
+ svelte: 4.0.5
+ svelte-hmr: 0.15.3(svelte@4.0.5)
+ vite: 4.4.5(sass@1.66.1)
+ vitefu: 0.2.4(vite@4.4.5)
+ transitivePeerDependencies:
+ - supports-color
+ dev: true
+
+ /@tsconfig/svelte@5.0.0:
+ resolution: {integrity: sha512-iu5BqFjU0+OcLTNQp7fHe6Bf6zdNeJ9IZjLZMqWLuGzVFm/xx+lm//Tf6koPyRmxo55/Snm6RRQ990n89cRKFw==}
+ dev: true
+
+ /@types/estree@1.0.1:
+ resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==}
+ dev: true
+
+ /@types/pug@2.0.6:
+ resolution: {integrity: sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==}
+ dev: true
+
+ /acorn@8.10.0:
+ resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+ dev: true
+
+ /anymatch@3.1.3:
+ resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
+ engines: {node: '>= 8'}
+ dependencies:
+ normalize-path: 3.0.0
+ picomatch: 2.3.1
+ dev: true
+
+ /aria-query@5.3.0:
+ resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==}
+ dependencies:
+ dequal: 2.0.3
+ dev: true
+
+ /axobject-query@3.2.1:
+ resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==}
+ dependencies:
+ dequal: 2.0.3
+ dev: true
+
+ /balanced-match@1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+ dev: true
+
+ /binary-extensions@2.2.0:
+ resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /brace-expansion@1.1.11:
+ resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
+ dependencies:
+ balanced-match: 1.0.2
+ concat-map: 0.0.1
+ dev: true
+
+ /braces@3.0.2:
+ resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
+ engines: {node: '>=8'}
+ dependencies:
+ fill-range: 7.0.1
+ dev: true
+
+ /buffer-crc32@0.2.13:
+ resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==}
+ dev: true
+
+ /callsites@3.1.0:
+ resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
+ engines: {node: '>=6'}
+ dev: true
+
+ /chokidar@3.5.3:
+ resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
+ engines: {node: '>= 8.10.0'}
+ dependencies:
+ anymatch: 3.1.3
+ braces: 3.0.2
+ glob-parent: 5.1.2
+ is-binary-path: 2.1.0
+ is-glob: 4.0.3
+ normalize-path: 3.0.0
+ readdirp: 3.6.0
+ optionalDependencies:
+ fsevents: 2.3.3
+ dev: true
+
+ /code-red@1.0.4:
+ resolution: {integrity: sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==}
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.4.15
+ '@types/estree': 1.0.1
+ acorn: 8.10.0
+ estree-walker: 3.0.3
+ periscopic: 3.1.0
+ dev: true
+
+ /concat-map@0.0.1:
+ resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
+ dev: true
+
+ /css-tree@2.3.1:
+ resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==}
+ engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
+ dependencies:
+ mdn-data: 2.0.30
+ source-map-js: 1.0.2
+ dev: true
+
+ /debug@4.3.4:
+ resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+ dependencies:
+ ms: 2.1.2
+ dev: true
+
+ /deepmerge@4.3.1:
+ resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
+ /dequal@2.0.3:
+ resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
+ engines: {node: '>=6'}
+ dev: true
+
+ /detect-indent@6.1.0:
+ resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==}
+ engines: {node: '>=8'}
+ dev: true
+
+ /es6-promise@3.3.1:
+ resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==}
+ dev: true
+
+ /esbuild@0.18.20:
+ resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==}
+ engines: {node: '>=12'}
+ hasBin: true
+ requiresBuild: true
+ optionalDependencies:
+ '@esbuild/android-arm': 0.18.20
+ '@esbuild/android-arm64': 0.18.20
+ '@esbuild/android-x64': 0.18.20
+ '@esbuild/darwin-arm64': 0.18.20
+ '@esbuild/darwin-x64': 0.18.20
+ '@esbuild/freebsd-arm64': 0.18.20
+ '@esbuild/freebsd-x64': 0.18.20
+ '@esbuild/linux-arm': 0.18.20
+ '@esbuild/linux-arm64': 0.18.20
+ '@esbuild/linux-ia32': 0.18.20
+ '@esbuild/linux-loong64': 0.18.20
+ '@esbuild/linux-mips64el': 0.18.20
+ '@esbuild/linux-ppc64': 0.18.20
+ '@esbuild/linux-riscv64': 0.18.20
+ '@esbuild/linux-s390x': 0.18.20
+ '@esbuild/linux-x64': 0.18.20
+ '@esbuild/netbsd-x64': 0.18.20
+ '@esbuild/openbsd-x64': 0.18.20
+ '@esbuild/sunos-x64': 0.18.20
+ '@esbuild/win32-arm64': 0.18.20
+ '@esbuild/win32-ia32': 0.18.20
+ '@esbuild/win32-x64': 0.18.20
+ dev: true
+
+ /estree-walker@3.0.3:
+ resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+ dependencies:
+ '@types/estree': 1.0.1
+ dev: true
+
+ /fast-glob@3.3.1:
+ resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==}
+ engines: {node: '>=8.6.0'}
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.5
+ dev: true
+
+ /fastq@1.15.0:
+ resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==}
+ dependencies:
+ reusify: 1.0.4
+ dev: true
+
+ /fill-range@7.0.1:
+ resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
+ engines: {node: '>=8'}
+ dependencies:
+ to-regex-range: 5.0.1
+ dev: true
+
+ /fs.realpath@1.0.0:
+ resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
+ dev: true
+
+ /fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /glob-parent@5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+ dependencies:
+ is-glob: 4.0.3
+ dev: true
+
+ /glob@7.2.3:
+ resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
+ dependencies:
+ fs.realpath: 1.0.0
+ inflight: 1.0.6
+ inherits: 2.0.4
+ minimatch: 3.1.2
+ once: 1.4.0
+ path-is-absolute: 1.0.1
+ dev: true
+
+ /graceful-fs@4.2.11:
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+ dev: true
+
+ /immutable@4.3.4:
+ resolution: {integrity: sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==}
+ dev: true
+
+ /import-fresh@3.3.0:
+ resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
+ engines: {node: '>=6'}
+ dependencies:
+ parent-module: 1.0.1
+ resolve-from: 4.0.0
+ dev: true
+
+ /inflight@1.0.6:
+ resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
+ dependencies:
+ once: 1.4.0
+ wrappy: 1.0.2
+ dev: true
+
+ /inherits@2.0.4:
+ resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+ dev: true
+
+ /is-binary-path@2.1.0:
+ resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+ engines: {node: '>=8'}
+ dependencies:
+ binary-extensions: 2.2.0
+ dev: true
+
+ /is-extglob@2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
+ /is-glob@4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ is-extglob: 2.1.1
+ dev: true
+
+ /is-number@7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+ dev: true
+
+ /is-reference@3.0.1:
+ resolution: {integrity: sha512-baJJdQLiYaJdvFbJqXrcGv3WU3QCzBlUcI5QhbesIm6/xPsvmO+2CDoi/GMOFBQEQm+PXkwOPrp9KK5ozZsp2w==}
+ dependencies:
+ '@types/estree': 1.0.1
+ dev: true
+
+ /kleur@4.1.5:
+ resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
+ engines: {node: '>=6'}
+ dev: true
+
+ /locate-character@3.0.0:
+ resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==}
+ dev: true
+
+ /magic-string@0.27.0:
+ resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==}
+ engines: {node: '>=12'}
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.4.15
+ dev: true
+
+ /magic-string@0.30.3:
+ resolution: {integrity: sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==}
+ engines: {node: '>=12'}
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.4.15
+ dev: true
+
+ /mdn-data@2.0.30:
+ resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
+ dev: true
+
+ /merge2@1.4.1:
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+ engines: {node: '>= 8'}
+ dev: true
+
+ /micromatch@4.0.5:
+ resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
+ engines: {node: '>=8.6'}
+ dependencies:
+ braces: 3.0.2
+ picomatch: 2.3.1
+ dev: true
+
+ /min-indent@1.0.1:
+ resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
+ engines: {node: '>=4'}
+ dev: true
+
+ /minimatch@3.1.2:
+ resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
+ dependencies:
+ brace-expansion: 1.1.11
+ dev: true
+
+ /minimist@1.2.8:
+ resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+ dev: true
+
+ /mkdirp@0.5.6:
+ resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==}
+ hasBin: true
+ dependencies:
+ minimist: 1.2.8
+ dev: true
+
+ /mri@1.2.0:
+ resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
+ engines: {node: '>=4'}
+ dev: true
+
+ /ms@2.1.2:
+ resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
+ dev: true
+
+ /nanoid@3.3.6:
+ resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+ dev: true
+
+ /normalize-path@3.0.0:
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
+ /normalize.css@8.0.1:
+ resolution: {integrity: sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==}
+
+ /once@1.4.0:
+ resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+ dependencies:
+ wrappy: 1.0.2
+ dev: true
+
+ /parent-module@1.0.1:
+ resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
+ engines: {node: '>=6'}
+ dependencies:
+ callsites: 3.1.0
+ dev: true
+
+ /path-is-absolute@1.0.1:
+ resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
+ /periscopic@3.1.0:
+ resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==}
+ dependencies:
+ '@types/estree': 1.0.1
+ estree-walker: 3.0.3
+ is-reference: 3.0.1
+ dev: true
+
+ /picocolors@1.0.0:
+ resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
+ dev: true
+
+ /picomatch@2.3.1:
+ resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+ engines: {node: '>=8.6'}
+ dev: true
+
+ /postcss@8.4.29:
+ resolution: {integrity: sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==}
+ engines: {node: ^10 || ^12 || >=14}
+ dependencies:
+ nanoid: 3.3.6
+ picocolors: 1.0.0
+ source-map-js: 1.0.2
+ dev: true
+
+ /prettier@3.0.3:
+ resolution: {integrity: sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==}
+ engines: {node: '>=14'}
+ hasBin: true
+ dev: true
+
+ /queue-microtask@1.2.3:
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+ dev: true
+
+ /readdirp@3.6.0:
+ resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
+ engines: {node: '>=8.10.0'}
+ dependencies:
+ picomatch: 2.3.1
+ dev: true
+
+ /resolve-from@4.0.0:
+ resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
+ engines: {node: '>=4'}
+ dev: true
+
+ /reusify@1.0.4:
+ resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+ dev: true
+
+ /rimraf@2.7.1:
+ resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==}
+ hasBin: true
+ dependencies:
+ glob: 7.2.3
+ dev: true
+
+ /rollup@3.28.1:
+ resolution: {integrity: sha512-R9OMQmIHJm9znrU3m3cpE8uhN0fGdXiawME7aZIpQqvpS/85+Vt1Hq1/yVIcYfOmaQiHjvXkQAoJukvLpau6Yw==}
+ engines: {node: '>=14.18.0', npm: '>=8.0.0'}
+ hasBin: true
+ optionalDependencies:
+ fsevents: 2.3.3
+ dev: true
+
+ /run-parallel@1.2.0:
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+ dependencies:
+ queue-microtask: 1.2.3
+ dev: true
+
+ /sade@1.8.1:
+ resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==}
+ engines: {node: '>=6'}
+ dependencies:
+ mri: 1.2.0
+ dev: true
+
+ /sander@0.5.1:
+ resolution: {integrity: sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==}
+ dependencies:
+ es6-promise: 3.3.1
+ graceful-fs: 4.2.11
+ mkdirp: 0.5.6
+ rimraf: 2.7.1
+ dev: true
+
+ /sass@1.66.1:
+ resolution: {integrity: sha512-50c+zTsZOJVgFfTgwwEzkjA3/QACgdNsKueWPyAR0mRINIvLAStVQBbPg14iuqEQ74NPDbXzJARJ/O4SI1zftA==}
+ engines: {node: '>=14.0.0'}
+ hasBin: true
+ dependencies:
+ chokidar: 3.5.3
+ immutable: 4.3.4
+ source-map-js: 1.0.2
+ dev: true
+
+ /sorcery@0.11.0:
+ resolution: {integrity: sha512-J69LQ22xrQB1cIFJhPfgtLuI6BpWRiWu1Y3vSsIwK/eAScqJxd/+CJlUuHQRdX2C9NGFamq+KqNywGgaThwfHw==}
+ hasBin: true
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.4.15
+ buffer-crc32: 0.2.13
+ minimist: 1.2.8
+ sander: 0.5.1
+ dev: true
+
+ /source-map-js@1.0.2:
+ resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
+ engines: {node: '>=0.10.0'}
+ dev: true
+
+ /strip-indent@3.0.0:
+ resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==}
+ engines: {node: '>=8'}
+ dependencies:
+ min-indent: 1.0.1
+ dev: true
+
+ /svelte-check@3.4.6(sass@1.66.1)(svelte@4.0.5):
+ resolution: {integrity: sha512-OBlY8866Zh1zHQTkBMPS6psPi7o2umTUyj6JWm4SacnIHXpWFm658pG32m3dKvKFL49V4ntAkfFHKo4ztH07og==}
+ hasBin: true
+ peerDependencies:
+ svelte: ^3.55.0 || ^4.0.0-next.0 || ^4.0.0
+ dependencies:
+ '@jridgewell/trace-mapping': 0.3.19
+ chokidar: 3.5.3
+ fast-glob: 3.3.1
+ import-fresh: 3.3.0
+ picocolors: 1.0.0
+ sade: 1.8.1
+ svelte: 4.0.5
+ svelte-preprocess: 5.0.4(sass@1.66.1)(svelte@4.0.5)(typescript@5.2.2)
+ typescript: 5.2.2
+ transitivePeerDependencies:
+ - '@babel/core'
+ - coffeescript
+ - less
+ - postcss
+ - postcss-load-config
+ - pug
+ - sass
+ - stylus
+ - sugarss
+ dev: true
+
+ /svelte-hmr@0.15.3(svelte@4.0.5):
+ resolution: {integrity: sha512-41snaPswvSf8TJUhlkoJBekRrABDXDMdpNpT2tfHIv4JuhgvHqLMhEPGtaQn0BmbNSTkuz2Ed20DF2eHw0SmBQ==}
+ engines: {node: ^12.20 || ^14.13.1 || >= 16}
+ peerDependencies:
+ svelte: ^3.19.0 || ^4.0.0
+ dependencies:
+ svelte: 4.0.5
+ dev: true
+
+ /svelte-preprocess@5.0.4(sass@1.66.1)(svelte@4.0.5)(typescript@5.2.2):
+ resolution: {integrity: sha512-ABia2QegosxOGsVlsSBJvoWeXy1wUKSfF7SWJdTjLAbx/Y3SrVevvvbFNQqrSJw89+lNSsM58SipmZJ5SRi5iw==}
+ engines: {node: '>= 14.10.0'}
+ requiresBuild: true
+ peerDependencies:
+ '@babel/core': ^7.10.2
+ coffeescript: ^2.5.1
+ less: ^3.11.3 || ^4.0.0
+ postcss: ^7 || ^8
+ postcss-load-config: ^2.1.0 || ^3.0.0 || ^4.0.0
+ pug: ^3.0.0
+ sass: ^1.26.8
+ stylus: ^0.55.0
+ sugarss: ^2.0.0 || ^3.0.0 || ^4.0.0
+ svelte: ^3.23.0 || ^4.0.0-next.0 || ^4.0.0
+ typescript: '>=3.9.5 || ^4.0.0 || ^5.0.0'
+ peerDependenciesMeta:
+ '@babel/core':
+ optional: true
+ coffeescript:
+ optional: true
+ less:
+ optional: true
+ postcss:
+ optional: true
+ postcss-load-config:
+ optional: true
+ pug:
+ optional: true
+ sass:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ typescript:
+ optional: true
+ dependencies:
+ '@types/pug': 2.0.6
+ detect-indent: 6.1.0
+ magic-string: 0.27.0
+ sass: 1.66.1
+ sorcery: 0.11.0
+ strip-indent: 3.0.0
+ svelte: 4.0.5
+ typescript: 5.2.2
+ dev: true
+
+ /svelte@4.0.5:
+ resolution: {integrity: sha512-PHKPWP1wiWHBtsE57nCb8xiWB3Ht7/3Kvi3jac0XIxUM2rep8alO7YoAtgWeGD7++tFy46krilOrPW0mG3Dx+A==}
+ engines: {node: '>=16'}
+ dependencies:
+ '@ampproject/remapping': 2.2.1
+ '@jridgewell/sourcemap-codec': 1.4.15
+ '@jridgewell/trace-mapping': 0.3.19
+ acorn: 8.10.0
+ aria-query: 5.3.0
+ axobject-query: 3.2.1
+ code-red: 1.0.4
+ css-tree: 2.3.1
+ estree-walker: 3.0.3
+ is-reference: 3.0.1
+ locate-character: 3.0.0
+ magic-string: 0.30.3
+ periscopic: 3.1.0
+ dev: true
+
+ /to-regex-range@5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+ dependencies:
+ is-number: 7.0.0
+ dev: true
+
+ /tslib@2.6.0:
+ resolution: {integrity: sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==}
+ dev: true
+
+ /typescript@5.0.2:
+ resolution: {integrity: sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==}
+ engines: {node: '>=12.20'}
+ hasBin: true
+ dev: true
+
+ /typescript@5.2.2:
+ resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+ dev: true
+
+ /vite@4.4.5(sass@1.66.1):
+ resolution: {integrity: sha512-4m5kEtAWHYr0O1Fu7rZp64CfO1PsRGZlD3TAB32UmQlpd7qg15VF7ROqGN5CyqN7HFuwr7ICNM2+fDWRqFEKaA==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': '>= 14'
+ less: '*'
+ lightningcss: ^1.21.0
+ sass: '*'
+ stylus: '*'
+ sugarss: '*'
+ terser: ^5.4.0
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+ dependencies:
+ esbuild: 0.18.20
+ postcss: 8.4.29
+ rollup: 3.28.1
+ sass: 1.66.1
+ optionalDependencies:
+ fsevents: 2.3.3
+ dev: true
+
+ /vitefu@0.2.4(vite@4.4.5):
+ resolution: {integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==}
+ peerDependencies:
+ vite: ^3.0.0 || ^4.0.0
+ peerDependenciesMeta:
+ vite:
+ optional: true
+ dependencies:
+ vite: 4.4.5(sass@1.66.1)
+ dev: true
+
+ /wrappy@1.0.2:
+ resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+ dev: true
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
new file mode 100644
index 0000000..b66a7c2
--- /dev/null
+++ b/pnpm-workspace.yaml
@@ -0,0 +1,3 @@
+packages:
+ - .
+ - frontend
diff --git a/web/app/app.go b/web/app/app.go
index 876ca0c..bd97e2b 100644
--- a/web/app/app.go
+++ b/web/app/app.go
@@ -1,8 +1,11 @@
package app
import (
+ "emperror.dev/errors"
"git.sleepycat.moe/sam/mercury/config"
"git.sleepycat.moe/sam/mercury/internal/database/sql"
+ "git.sleepycat.moe/sam/mercury/web/templates"
+ "github.com/flosch/pongo2/v6"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
)
@@ -12,19 +15,27 @@ type App struct {
Config config.Config
Database *sql.Base
+
+ tmpl *pongo2.TemplateSet
}
-func NewApp(cfg config.Config, db *sql.Base) *App {
+func NewApp(cfg config.Config, db *sql.Base) (*App, error) {
app := &App{
Router: chi.NewRouter(),
Config: cfg,
Database: db,
}
+ tmpl, err := templates.New(cfg.Core.Dev)
+ if err != nil {
+ return nil, errors.Wrap(err, "creating templates")
+ }
+ app.tmpl = tmpl
+
app.Router.Use(app.Logger)
app.Router.Use(middleware.Recoverer)
- return app
+ return app, nil
}
func (a *App) Account(q ...sql.Querier) *sql.AccountStore {
diff --git a/web/app/template.go b/web/app/template.go
new file mode 100644
index 0000000..cf5d7ec
--- /dev/null
+++ b/web/app/template.go
@@ -0,0 +1,52 @@
+package app
+
+import (
+ "net/http"
+ "time"
+
+ "github.com/flosch/pongo2/v6"
+)
+
+func (app *App) Template(w http.ResponseWriter, r *http.Request, tmplName string, ctx pongo2.Context) error {
+ tmpl, err := app.tmpl.FromCache(tmplName)
+ if err != nil {
+ return err
+ }
+
+ tctx := pongo2.Context{
+ "flash_message": app.getFlash(w, r),
+ }
+ tctx.Update(ctx)
+
+ w.Header().Set("Content-Type", "text/html")
+ return tmpl.ExecuteWriter(tctx, w)
+}
+
+const flashCookieName = "mercury-flash-message"
+
+func (app *App) Flash(w http.ResponseWriter, msg string) {
+ http.SetCookie(w, &http.Cookie{
+ Name: flashCookieName,
+ Value: msg,
+ Path: "/",
+ HttpOnly: true,
+ Expires: time.Now().Add(time.Minute),
+ })
+}
+
+func (app *App) getFlash(w http.ResponseWriter, r *http.Request) string {
+ cookie, err := r.Cookie(flashCookieName)
+ if err != nil {
+ return ""
+ }
+
+ defer http.SetCookie(w, &http.Cookie{
+ Name: flashCookieName,
+ Value: "",
+ Path: "/",
+ HttpOnly: true,
+ Expires: time.Now(),
+ })
+
+ return cookie.Value
+}
diff --git a/web/auth/auth.go b/web/auth/auth.go
new file mode 100644
index 0000000..24de40c
--- /dev/null
+++ b/web/auth/auth.go
@@ -0,0 +1,15 @@
+package auth
+
+import "git.sleepycat.moe/sam/mercury/web/app"
+
+type Auth struct {
+ *app.App
+}
+
+func New(app *app.App) *Auth {
+ auth := &Auth{
+ App: app,
+ }
+
+ return auth
+}
diff --git a/web/auth/login.go b/web/auth/login.go
new file mode 100644
index 0000000..6be1e2f
--- /dev/null
+++ b/web/auth/login.go
@@ -0,0 +1,11 @@
+package auth
+
+import (
+ "net/http"
+
+ "github.com/flosch/pongo2/v6"
+)
+
+func (app *Auth) GetLogin(w http.ResponseWriter, r *http.Request) {
+ app.Template(w, r, "auth/login.tpl", pongo2.Context{})
+}
diff --git a/web/frontend/.gitignore b/web/frontend/.gitignore
new file mode 100644
index 0000000..7e2f179
--- /dev/null
+++ b/web/frontend/.gitignore
@@ -0,0 +1 @@
+assets
diff --git a/web/frontend/app.html b/web/frontend/app.html
index 378c50b..4110bf2 100644
--- a/web/frontend/app.html
+++ b/web/frontend/app.html
@@ -1,13 +1,13 @@
-
+
-
-
-
- {{.Config.Name}}
+
+
+
+ {{.Config.Name}}
- {{.Vue.RenderTags}}
-
-
-
-
+ {{.Vue.RenderTags}}
+
+
+
+
diff --git a/web/frontend/frontend.go b/web/frontend/frontend.go
index 8d67312..fad5cae 100644
--- a/web/frontend/frontend.go
+++ b/web/frontend/frontend.go
@@ -1,22 +1,26 @@
package frontend
import (
+ "embed"
"html/template"
"net/http"
"os"
+ "path/filepath"
"git.sleepycat.moe/sam/mercury/frontend"
"git.sleepycat.moe/sam/mercury/internal/database"
"git.sleepycat.moe/sam/mercury/web/app"
+ "github.com/go-chi/chi/v5"
"github.com/rs/zerolog/log"
vueglue "github.com/torenware/vite-go"
-
- _ "embed"
)
//go:embed app.html
var htmlTemplate string
+//go:embed assets
+var assets embed.FS
+
type Frontend struct {
*app.App
glue *vueglue.VueGlue
@@ -94,3 +98,14 @@ func (app *Frontend) ServeFrontend(w http.ResponseWriter, r *http.Request) {
log.Err(err).Msg("executing frontend template")
}
}
+
+func (app *Frontend) ServeStaticAssets(w http.ResponseWriter, r *http.Request) {
+ if app.Config.Core.Dev {
+ // TODO: this is unsafe
+ path := filepath.Join("web/frontend/assets/", chi.URLParam(r, "*"))
+ http.ServeFile(w, r, path)
+ return
+ }
+
+ _ = assets
+}
diff --git a/web/routes.go b/web/routes.go
index aace349..0f780f3 100644
--- a/web/routes.go
+++ b/web/routes.go
@@ -2,12 +2,23 @@ package web
import (
"git.sleepycat.moe/sam/mercury/web/app"
+ "git.sleepycat.moe/sam/mercury/web/auth"
"git.sleepycat.moe/sam/mercury/web/frontend"
+ "github.com/go-chi/chi/v5"
)
func Routes(app *app.App) {
+ // auth
+ app.Router.Route("/auth", func(r chi.Router) {
+ auth := auth.New(app)
+ r.Get("/login", auth.GetLogin)
+ })
+
+ // web app handlers
+ // also assets
frontend := frontend.New(app)
app.Router.HandleFunc(frontend.AssetsPath(), frontend.ServeAssets)
+ app.Router.HandleFunc("/static/*", frontend.ServeStaticAssets)
app.Router.HandleFunc("/web", frontend.ServeFrontend)
app.Router.HandleFunc("/web/*", frontend.ServeFrontend)
}
diff --git a/web/templates/auth/login.tpl b/web/templates/auth/login.tpl
new file mode 100644
index 0000000..0cc94f3
--- /dev/null
+++ b/web/templates/auth/login.tpl
@@ -0,0 +1,19 @@
+{% extends 'base.tpl' %}
+{% block title %}
+ Log in
+{% endblock %}
+{% block content %}
+
+{% endblock %}
diff --git a/web/templates/base.tpl b/web/templates/base.tpl
new file mode 100644
index 0000000..97d42d8
--- /dev/null
+++ b/web/templates/base.tpl
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ {% block title %}Mercury{% endblock %}
+
+
+ {% block content %}
+ {% endblock %}
+
+
diff --git a/web/templates/templates.go b/web/templates/templates.go
new file mode 100644
index 0000000..f56e318
--- /dev/null
+++ b/web/templates/templates.go
@@ -0,0 +1,28 @@
+package templates
+
+import (
+ "embed"
+
+ "emperror.dev/errors"
+ "github.com/flosch/pongo2/v6"
+)
+
+//go:embed *
+var fs embed.FS
+
+func New(dev bool) (*pongo2.TemplateSet, error) {
+ if dev {
+ loader, err := pongo2.NewLocalFileSystemLoader("web/templates")
+ if err != nil {
+ return nil, errors.Wrap(err, "creating filesystem loader")
+ }
+
+ ts := pongo2.NewSet("web", loader)
+ ts.Debug = true
+ return ts, nil
+ }
+
+ loader := pongo2.NewFSLoader(fs)
+ ts := pongo2.NewSet("web", loader)
+ return ts, nil
+}