diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
new file mode 100644
index 0000000..18429a6
--- /dev/null
+++ b/.github/workflows/build.yaml
@@ -0,0 +1,60 @@
+name: Deploy to Pages
+
+on:
+ push:
+ branches:
+ - main
+
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
+# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
+concurrency:
+ group: "pages"
+ cancel-in-progress: false
+
+defaults:
+ run:
+ shell: bash
+
+jobs:
+ # Build job
+ build:
+ runs-on: ubuntu-latest
+ environment: "env"
+ steps:
+ - name: Install bun
+ uses: oven-sh/setup-bun@v2
+ with:
+ bun-version: latest
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ submodules: recursive
+ fetch-depth: 0
+ - name: Setup Pages
+ id: pages
+ uses: actions/configure-pages@v4
+ - name: Install bun dependencies
+ run: "bun install"
+ - name: Build website
+ run: "bun run gen"
+ - name: Upload artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: ./out/
+
+ # Deployment job
+ deploy:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ runs-on: ubuntu-latest
+ needs: build
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 23e0b70..0a5b354 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
-V2/
-node_modules/
\ No newline at end of file
+V3/
+node_modules/
+out
\ No newline at end of file
diff --git a/README.md b/README.md
index c231ea0..1e5b2fd 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,15 @@
-# homepage of wah.su
+# wah-su.github.io
-This repository contains a home page for a wah.su.
+To install dependencies:
-It is made using HTML, JS and Tailwind.
+```bash
+bun install
+```
+
+To run:
+
+```bash
+bun run index.ts
+```
+
+This project was created using `bun init` in bun v1.2.1. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.
diff --git a/bun.lock b/bun.lock
new file mode 100644
index 0000000..98ed96a
--- /dev/null
+++ b/bun.lock
@@ -0,0 +1,328 @@
+{
+ "lockfileVersion": 1,
+ "workspaces": {
+ "": {
+ "name": "wah-su.github.io",
+ "dependencies": {
+ "@tailwindcss/cli": "^4.0.6",
+ "picocolors": "^1.1.1",
+ "react": "^19.0.0",
+ "react-dom": "^19.0.0",
+ "tailwindcss": "^4.0.6",
+ },
+ "devDependencies": {
+ "@types/bun": "latest",
+ "@types/express": "^5.0.0",
+ "@types/react": "^19.0.8",
+ "@types/react-dom": "^19.0.3",
+ "chokidar": "^4.0.3",
+ "express": "^4.21.2",
+ "ws": "^8.18.0",
+ },
+ "peerDependencies": {
+ "typescript": "^5.0.0",
+ },
+ },
+ },
+ "packages": {
+ "@parcel/watcher": ["@parcel/watcher@2.5.1", "", { "dependencies": { "detect-libc": "^1.0.3", "is-glob": "^4.0.3", "micromatch": "^4.0.5", "node-addon-api": "^7.0.0" }, "optionalDependencies": { "@parcel/watcher-android-arm64": "2.5.1", "@parcel/watcher-darwin-arm64": "2.5.1", "@parcel/watcher-darwin-x64": "2.5.1", "@parcel/watcher-freebsd-x64": "2.5.1", "@parcel/watcher-linux-arm-glibc": "2.5.1", "@parcel/watcher-linux-arm-musl": "2.5.1", "@parcel/watcher-linux-arm64-glibc": "2.5.1", "@parcel/watcher-linux-arm64-musl": "2.5.1", "@parcel/watcher-linux-x64-glibc": "2.5.1", "@parcel/watcher-linux-x64-musl": "2.5.1", "@parcel/watcher-win32-arm64": "2.5.1", "@parcel/watcher-win32-ia32": "2.5.1", "@parcel/watcher-win32-x64": "2.5.1" } }, "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg=="],
+
+ "@parcel/watcher-android-arm64": ["@parcel/watcher-android-arm64@2.5.1", "", { "os": "android", "cpu": "arm64" }, "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA=="],
+
+ "@parcel/watcher-darwin-arm64": ["@parcel/watcher-darwin-arm64@2.5.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw=="],
+
+ "@parcel/watcher-darwin-x64": ["@parcel/watcher-darwin-x64@2.5.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg=="],
+
+ "@parcel/watcher-freebsd-x64": ["@parcel/watcher-freebsd-x64@2.5.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ=="],
+
+ "@parcel/watcher-linux-arm-glibc": ["@parcel/watcher-linux-arm-glibc@2.5.1", "", { "os": "linux", "cpu": "arm" }, "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA=="],
+
+ "@parcel/watcher-linux-arm-musl": ["@parcel/watcher-linux-arm-musl@2.5.1", "", { "os": "linux", "cpu": "arm" }, "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q=="],
+
+ "@parcel/watcher-linux-arm64-glibc": ["@parcel/watcher-linux-arm64-glibc@2.5.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w=="],
+
+ "@parcel/watcher-linux-arm64-musl": ["@parcel/watcher-linux-arm64-musl@2.5.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg=="],
+
+ "@parcel/watcher-linux-x64-glibc": ["@parcel/watcher-linux-x64-glibc@2.5.1", "", { "os": "linux", "cpu": "x64" }, "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A=="],
+
+ "@parcel/watcher-linux-x64-musl": ["@parcel/watcher-linux-x64-musl@2.5.1", "", { "os": "linux", "cpu": "x64" }, "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg=="],
+
+ "@parcel/watcher-win32-arm64": ["@parcel/watcher-win32-arm64@2.5.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw=="],
+
+ "@parcel/watcher-win32-ia32": ["@parcel/watcher-win32-ia32@2.5.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ=="],
+
+ "@parcel/watcher-win32-x64": ["@parcel/watcher-win32-x64@2.5.1", "", { "os": "win32", "cpu": "x64" }, "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA=="],
+
+ "@tailwindcss/cli": ["@tailwindcss/cli@4.0.6", "", { "dependencies": { "@parcel/watcher": "^2.5.1", "@tailwindcss/node": "^4.0.6", "@tailwindcss/oxide": "^4.0.6", "enhanced-resolve": "^5.18.0", "lightningcss": "^1.29.1", "mri": "^1.2.0", "picocolors": "^1.1.1", "tailwindcss": "4.0.6" }, "bin": { "tailwindcss": "dist/index.mjs" } }, "sha512-5EybaKjLL6ruuKq4PFMpf60npR6x6MmVlqvXWca7ZcujQd7rj5vckNHi2M7Bn0U7dkWmmOm3s/9USLL7BZuudw=="],
+
+ "@tailwindcss/node": ["@tailwindcss/node@4.0.6", "", { "dependencies": { "enhanced-resolve": "^5.18.0", "jiti": "^2.4.2", "tailwindcss": "4.0.6" } }, "sha512-jb6E0WeSq7OQbVYcIJ6LxnZTeC4HjMvbzFBMCrQff4R50HBlo/obmYNk6V2GCUXDeqiXtvtrQgcIbT+/boB03Q=="],
+
+ "@tailwindcss/oxide": ["@tailwindcss/oxide@4.0.6", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.0.6", "@tailwindcss/oxide-darwin-arm64": "4.0.6", "@tailwindcss/oxide-darwin-x64": "4.0.6", "@tailwindcss/oxide-freebsd-x64": "4.0.6", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.0.6", "@tailwindcss/oxide-linux-arm64-gnu": "4.0.6", "@tailwindcss/oxide-linux-arm64-musl": "4.0.6", "@tailwindcss/oxide-linux-x64-gnu": "4.0.6", "@tailwindcss/oxide-linux-x64-musl": "4.0.6", "@tailwindcss/oxide-win32-arm64-msvc": "4.0.6", "@tailwindcss/oxide-win32-x64-msvc": "4.0.6" } }, "sha512-lVyKV2y58UE9CeKVcYykULe9QaE1dtKdxDEdrTPIdbzRgBk6bdxHNAoDqvcqXbIGXubn3VOl1O/CFF77v/EqSA=="],
+
+ "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.0.6", "", { "os": "android", "cpu": "arm64" }, "sha512-xDbym6bDPW3D2XqQqX3PjqW3CKGe1KXH7Fdkc60sX5ZLVUbzPkFeunQaoP+BuYlLc2cC1FoClrIRYnRzof9Sow=="],
+
+ "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.0.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-1f71/ju/tvyGl5c2bDkchZHy8p8EK/tDHCxlpYJ1hGNvsYihZNurxVpZ0DefpN7cNc9RTT8DjrRoV8xXZKKRjg=="],
+
+ "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.0.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-s/hg/ZPgxFIrGMb0kqyeaqZt505P891buUkSezmrDY6lxv2ixIELAlOcUVTkVh245SeaeEiUVUPiUN37cwoL2g=="],
+
+ "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.0.6", "", { "os": "freebsd", "cpu": "x64" }, "sha512-Z3Wo8FWZnmio8+xlcbb7JUo/hqRMSmhQw8IGIRoRJ7GmLR0C+25Wq+bEX/135xe/yEle2lFkhu9JBHd4wZYiig=="],
+
+ "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.0.6", "", { "os": "linux", "cpu": "arm" }, "sha512-SNSwkkim1myAgmnbHs4EjXsPL7rQbVGtjcok5EaIzkHkCAVK9QBQsWeP2Jm2/JJhq4wdx8tZB9Y7psMzHYWCkA=="],
+
+ "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.0.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-tJ+mevtSDMQhKlwCCuhsFEFg058kBiSy4TkoeBG921EfrHKmexOaCyFKYhVXy4JtkaeeOcjJnCLasEeqml4i+Q=="],
+
+ "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.0.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-IoArz1vfuTR4rALXMUXI/GWWfx2EaO4gFNtBNkDNOYhlTD4NVEwE45nbBoojYiTulajI4c2XH8UmVEVJTOJKxA=="],
+
+ "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.0.6", "", { "os": "linux", "cpu": "x64" }, "sha512-QtsUfLkEAeWAC3Owx9Kg+7JdzE+k9drPhwTAXbXugYB9RZUnEWWx5x3q/au6TvUYcL+n0RBqDEO2gucZRvRFgQ=="],
+
+ "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.0.6", "", { "os": "linux", "cpu": "x64" }, "sha512-QthvJqIji2KlGNwLcK/PPYo7w1Wsi/8NK0wAtRGbv4eOPdZHkQ9KUk+oCoP20oPO7i2a6X1aBAFQEL7i08nNMA=="],
+
+ "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.0.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-+oka+dYX8jy9iP00DJ9Y100XsqvbqR5s0yfMZJuPR1H/lDVtDfsZiSix1UFBQ3X1HWxoEEl6iXNJHWd56TocVw=="],
+
+ "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.0.6", "", { "os": "win32", "cpu": "x64" }, "sha512-+o+juAkik4p8Ue/0LiflQXPmVatl6Av3LEZXpBTfg4qkMIbZdhCGWFzHdt2NjoMiLOJCFDddoV6GYaimvK1Olw=="],
+
+ "@types/body-parser": ["@types/body-parser@1.19.5", "", { "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg=="],
+
+ "@types/bun": ["@types/bun@1.2.2", "", { "dependencies": { "bun-types": "1.2.2" } }, "sha512-tr74gdku+AEDN5ergNiBnplr7hpDp3V1h7fqI2GcR/rsUaM39jpSeKH0TFibRvU0KwniRx5POgaYnaXbk0hU+w=="],
+
+ "@types/connect": ["@types/connect@3.4.38", "", { "dependencies": { "@types/node": "*" } }, "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug=="],
+
+ "@types/express": ["@types/express@5.0.0", "", { "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^5.0.0", "@types/qs": "*", "@types/serve-static": "*" } }, "sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ=="],
+
+ "@types/express-serve-static-core": ["@types/express-serve-static-core@5.0.6", "", { "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*", "@types/send": "*" } }, "sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA=="],
+
+ "@types/http-errors": ["@types/http-errors@2.0.4", "", {}, "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA=="],
+
+ "@types/mime": ["@types/mime@1.3.5", "", {}, "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w=="],
+
+ "@types/node": ["@types/node@22.13.1", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew=="],
+
+ "@types/qs": ["@types/qs@6.9.18", "", {}, "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA=="],
+
+ "@types/range-parser": ["@types/range-parser@1.2.7", "", {}, "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ=="],
+
+ "@types/react": ["@types/react@19.0.8", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-9P/o1IGdfmQxrujGbIMDyYaaCykhLKc0NGCtYcECNUr9UAaDe4gwvV9bR6tvd5Br1SG0j+PBpbKr2UYY8CwqSw=="],
+
+ "@types/react-dom": ["@types/react-dom@19.0.3", "", { "peerDependencies": { "@types/react": "^19.0.0" } }, "sha512-0Knk+HJiMP/qOZgMyNFamlIjw9OFCsyC2ZbigmEEyXXixgre6IQpm/4V+r3qH4GC1JPvRJKInw+on2rV6YZLeA=="],
+
+ "@types/send": ["@types/send@0.17.4", "", { "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA=="],
+
+ "@types/serve-static": ["@types/serve-static@1.15.7", "", { "dependencies": { "@types/http-errors": "*", "@types/node": "*", "@types/send": "*" } }, "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw=="],
+
+ "@types/ws": ["@types/ws@8.5.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw=="],
+
+ "accepts": ["accepts@1.3.8", "", { "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" } }, "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw=="],
+
+ "array-flatten": ["array-flatten@1.1.1", "", {}, "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="],
+
+ "body-parser": ["body-parser@1.20.3", "", { "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" } }, "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g=="],
+
+ "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
+
+ "bun-types": ["bun-types@1.2.2", "", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" } }, "sha512-RCbMH5elr9gjgDGDhkTTugA21XtJAy/9jkKe/G3WR2q17VPGhcquf9Sir6uay9iW+7P/BV0CAHA1XlHXMAVKHg=="],
+
+ "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="],
+
+ "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.1", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g=="],
+
+ "call-bound": ["call-bound@1.0.3", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "get-intrinsic": "^1.2.6" } }, "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA=="],
+
+ "chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="],
+
+ "content-disposition": ["content-disposition@0.5.4", "", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ=="],
+
+ "content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="],
+
+ "cookie": ["cookie@0.7.1", "", {}, "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w=="],
+
+ "cookie-signature": ["cookie-signature@1.0.6", "", {}, "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="],
+
+ "csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
+
+ "debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
+
+ "depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="],
+
+ "destroy": ["destroy@1.2.0", "", {}, "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="],
+
+ "detect-libc": ["detect-libc@1.0.3", "", { "bin": { "detect-libc": "./bin/detect-libc.js" } }, "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg=="],
+
+ "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
+
+ "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="],
+
+ "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="],
+
+ "enhanced-resolve": ["enhanced-resolve@5.18.1", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg=="],
+
+ "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
+
+ "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
+
+ "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
+
+ "escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="],
+
+ "etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="],
+
+ "express": ["express@4.21.2", "", { "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.12", "proxy-addr": "~2.0.7", "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "0.19.0", "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" } }, "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA=="],
+
+ "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
+
+ "finalhandler": ["finalhandler@1.3.1", "", { "dependencies": { "debug": "2.6.9", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", "statuses": "2.0.1", "unpipe": "~1.0.0" } }, "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ=="],
+
+ "forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="],
+
+ "fresh": ["fresh@0.5.2", "", {}, "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="],
+
+ "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
+
+ "get-intrinsic": ["get-intrinsic@1.2.7", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "function-bind": "^1.1.2", "get-proto": "^1.0.0", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA=="],
+
+ "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
+
+ "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
+
+ "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
+
+ "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
+
+ "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
+
+ "http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="],
+
+ "iconv-lite": ["iconv-lite@0.4.24", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3" } }, "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="],
+
+ "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
+
+ "ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="],
+
+ "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
+
+ "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
+
+ "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
+
+ "jiti": ["jiti@2.4.2", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A=="],
+
+ "lightningcss": ["lightningcss@1.29.1", "", { "dependencies": { "detect-libc": "^1.0.3" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.29.1", "lightningcss-darwin-x64": "1.29.1", "lightningcss-freebsd-x64": "1.29.1", "lightningcss-linux-arm-gnueabihf": "1.29.1", "lightningcss-linux-arm64-gnu": "1.29.1", "lightningcss-linux-arm64-musl": "1.29.1", "lightningcss-linux-x64-gnu": "1.29.1", "lightningcss-linux-x64-musl": "1.29.1", "lightningcss-win32-arm64-msvc": "1.29.1", "lightningcss-win32-x64-msvc": "1.29.1" } }, "sha512-FmGoeD4S05ewj+AkhTY+D+myDvXI6eL27FjHIjoyUkO/uw7WZD1fBVs0QxeYWa7E17CUHJaYX/RUGISCtcrG4Q=="],
+
+ "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.29.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-HtR5XJ5A0lvCqYAoSv2QdZZyoHNttBpa5EP9aNuzBQeKGfbyH5+UipLWvVzpP4Uml5ej4BYs5I9Lco9u1fECqw=="],
+
+ "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.29.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-k33G9IzKUpHy/J/3+9MCO4e+PzaFblsgBjSGlpAaFikeBFm8B/CkO3cKU9oI4g+fjS2KlkLM/Bza9K/aw8wsNA=="],
+
+ "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.29.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-0SUW22fv/8kln2LnIdOCmSuXnxgxVC276W5KLTwoehiO0hxkacBxjHOL5EtHD8BAXg2BvuhsJPmVMasvby3LiQ=="],
+
+ "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.29.1", "", { "os": "linux", "cpu": "arm" }, "sha512-sD32pFvlR0kDlqsOZmYqH/68SqUMPNj+0pucGxToXZi4XZgZmqeX/NkxNKCPsswAXU3UeYgDSpGhu05eAufjDg=="],
+
+ "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.29.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-0+vClRIZ6mmJl/dxGuRsE197o1HDEeeRk6nzycSy2GofC2JsY4ifCRnvUWf/CUBQmlrvMzt6SMQNMSEu22csWQ=="],
+
+ "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.29.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-UKMFrG4rL/uHNgelBsDwJcBqVpzNJbzsKkbI3Ja5fg00sgQnHw/VrzUTEc4jhZ+AN2BvQYz/tkHu4vt1kLuJyw=="],
+
+ "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.29.1", "", { "os": "linux", "cpu": "x64" }, "sha512-u1S+xdODy/eEtjADqirA774y3jLcm8RPtYztwReEXoZKdzgsHYPl0s5V52Tst+GKzqjebkULT86XMSxejzfISw=="],
+
+ "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.29.1", "", { "os": "linux", "cpu": "x64" }, "sha512-L0Tx0DtaNUTzXv0lbGCLB/c/qEADanHbu4QdcNOXLIe1i8i22rZRpbT3gpWYsCh9aSL9zFujY/WmEXIatWvXbw=="],
+
+ "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.29.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-QoOVnkIEFfbW4xPi+dpdft/zAKmgLgsRHfJalEPYuJDOWf7cLQzYg0DEh8/sn737FaeMJxHZRc1oBreiwZCjog=="],
+
+ "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.29.1", "", { "os": "win32", "cpu": "x64" }, "sha512-NygcbThNBe4JElP+olyTI/doBNGJvLs3bFCRPdvuCcxZCcCZ71B858IHpdm7L1btZex0FvCmM17FK98Y9MRy1Q=="],
+
+ "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
+
+ "media-typer": ["media-typer@0.3.0", "", {}, "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="],
+
+ "merge-descriptors": ["merge-descriptors@1.0.3", "", {}, "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ=="],
+
+ "methods": ["methods@1.1.2", "", {}, "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="],
+
+ "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
+
+ "mime": ["mime@1.6.0", "", { "bin": { "mime": "cli.js" } }, "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="],
+
+ "mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
+
+ "mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
+
+ "mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="],
+
+ "ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
+
+ "negotiator": ["negotiator@0.6.3", "", {}, "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="],
+
+ "node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="],
+
+ "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="],
+
+ "on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="],
+
+ "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="],
+
+ "path-to-regexp": ["path-to-regexp@0.1.12", "", {}, "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="],
+
+ "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
+
+ "picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
+
+ "proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="],
+
+ "qs": ["qs@6.13.0", "", { "dependencies": { "side-channel": "^1.0.6" } }, "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg=="],
+
+ "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="],
+
+ "raw-body": ["raw-body@2.5.2", "", { "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } }, "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA=="],
+
+ "react": ["react@19.0.0", "", {}, "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ=="],
+
+ "react-dom": ["react-dom@19.0.0", "", { "dependencies": { "scheduler": "^0.25.0" }, "peerDependencies": { "react": "^19.0.0" } }, "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ=="],
+
+ "readdirp": ["readdirp@4.1.1", "", {}, "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw=="],
+
+ "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
+
+ "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
+
+ "scheduler": ["scheduler@0.25.0", "", {}, "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA=="],
+
+ "send": ["send@0.19.0", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "2.4.1", "range-parser": "~1.2.1", "statuses": "2.0.1" } }, "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw=="],
+
+ "serve-static": ["serve-static@1.16.2", "", { "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "0.19.0" } }, "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw=="],
+
+ "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="],
+
+ "side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="],
+
+ "side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="],
+
+ "side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="],
+
+ "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="],
+
+ "statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="],
+
+ "tailwindcss": ["tailwindcss@4.0.6", "", {}, "sha512-mysewHYJKaXgNOW6pp5xon/emCsfAMnO8WMaGKZZ35fomnR/T5gYnRg2/yRTTrtXiEl1tiVkeRt0eMO6HxEZqw=="],
+
+ "tapable": ["tapable@2.2.1", "", {}, "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ=="],
+
+ "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
+
+ "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
+
+ "type-is": ["type-is@1.6.18", "", { "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" } }, "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g=="],
+
+ "typescript": ["typescript@5.7.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw=="],
+
+ "undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="],
+
+ "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="],
+
+ "utils-merge": ["utils-merge@1.0.1", "", {}, "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="],
+
+ "vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="],
+
+ "ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="],
+
+ "send/encodeurl": ["encodeurl@1.0.2", "", {}, "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="],
+
+ "send/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
+ }
+}
diff --git a/index.html b/index.html
deleted file mode 100644
index 80d3969..0000000
--- a/index.html
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
-
-
-
-
- wah.su | Homepage
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
deleted file mode 100644
index ad90541..0000000
--- a/package-lock.json
+++ /dev/null
@@ -1,1272 +0,0 @@
-{
- "name": "wah-su.github.io",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "dependencies": {
- "tailwindcss": "^3.4.15"
- }
- },
- "node_modules/@alloc/quick-lru": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
- "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@isaacs/cliui": {
- "version": "8.0.2",
- "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
- "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
- "dependencies": {
- "string-width": "^5.1.2",
- "string-width-cjs": "npm:string-width@^4.2.0",
- "strip-ansi": "^7.0.1",
- "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
- "wrap-ansi": "^8.1.0",
- "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
- "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
- "dependencies": {
- "@jridgewell/set-array": "^1.2.1",
- "@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.24"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/set-array": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
- "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
- "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.25",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
- "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
- "node_modules/@nodelib/fs.scandir": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
- "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
- "dependencies": {
- "@nodelib/fs.stat": "2.0.5",
- "run-parallel": "^1.1.9"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.stat": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
- "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.walk": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
- "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
- "dependencies": {
- "@nodelib/fs.scandir": "2.1.5",
- "fastq": "^1.6.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@pkgjs/parseargs": {
- "version": "0.11.0",
- "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
- "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
- "optional": true,
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/ansi-regex": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
- "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-regex?sponsor=1"
- }
- },
- "node_modules/ansi-styles": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
- "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/any-promise": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
- "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="
- },
- "node_modules/anymatch": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
- "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
- "dependencies": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/arg": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
- "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="
- },
- "node_modules/balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
- },
- "node_modules/binary-extensions": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
- "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/brace-expansion": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
- "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
- "dependencies": {
- "balanced-match": "^1.0.0"
- }
- },
- "node_modules/braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "dependencies": {
- "fill-range": "^7.1.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/camelcase-css": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
- "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/chokidar": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
- "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
- "dependencies": {
- "anymatch": "~3.1.2",
- "braces": "~3.0.2",
- "glob-parent": "~5.1.2",
- "is-binary-path": "~2.1.0",
- "is-glob": "~4.0.1",
- "normalize-path": "~3.0.0",
- "readdirp": "~3.6.0"
- },
- "engines": {
- "node": ">= 8.10.0"
- },
- "funding": {
- "url": "https://paulmillr.com/funding/"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/chokidar/node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
- },
- "node_modules/commander": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
- "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/cross-spawn": {
- "version": "7.0.6",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
- "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
- "dependencies": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/cssesc": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
- "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
- "bin": {
- "cssesc": "bin/cssesc"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/didyoumean": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
- "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="
- },
- "node_modules/dlv": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
- "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="
- },
- "node_modules/eastasianwidth": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
- "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
- },
- "node_modules/emoji-regex": {
- "version": "9.2.2",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
- "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
- },
- "node_modules/fast-glob": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
- "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
- "dependencies": {
- "@nodelib/fs.stat": "^2.0.2",
- "@nodelib/fs.walk": "^1.2.3",
- "glob-parent": "^5.1.2",
- "merge2": "^1.3.0",
- "micromatch": "^4.0.4"
- },
- "engines": {
- "node": ">=8.6.0"
- }
- },
- "node_modules/fast-glob/node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/fastq": {
- "version": "1.17.1",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
- "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
- "dependencies": {
- "reusify": "^1.0.4"
- }
- },
- "node_modules/fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/foreground-child": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
- "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
- "dependencies": {
- "cross-spawn": "^7.0.0",
- "signal-exit": "^4.0.1"
- },
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "hasInstallScript": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/function-bind": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
- "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/glob": {
- "version": "10.4.5",
- "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
- "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
- "dependencies": {
- "foreground-child": "^3.1.0",
- "jackspeak": "^3.1.2",
- "minimatch": "^9.0.4",
- "minipass": "^7.1.2",
- "package-json-from-dist": "^1.0.0",
- "path-scurry": "^1.11.1"
- },
- "bin": {
- "glob": "dist/esm/bin.mjs"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/glob-parent": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
- "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
- "dependencies": {
- "is-glob": "^4.0.3"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "node_modules/hasown": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
- "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
- "dependencies": {
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/is-binary-path": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
- "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "dependencies": {
- "binary-extensions": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-core-module": {
- "version": "2.15.1",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz",
- "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==",
- "dependencies": {
- "hasown": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
- },
- "node_modules/jackspeak": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
- "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
- "dependencies": {
- "@isaacs/cliui": "^8.0.2"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- },
- "optionalDependencies": {
- "@pkgjs/parseargs": "^0.11.0"
- }
- },
- "node_modules/jiti": {
- "version": "1.21.6",
- "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz",
- "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==",
- "bin": {
- "jiti": "bin/jiti.js"
- }
- },
- "node_modules/lilconfig": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
- "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/lines-and-columns": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
- "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
- },
- "node_modules/lru-cache": {
- "version": "10.4.3",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
- "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
- },
- "node_modules/merge2": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/micromatch": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
- "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
- "dependencies": {
- "braces": "^3.0.3",
- "picomatch": "^2.3.1"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
- "node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/minipass": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
- "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
- "engines": {
- "node": ">=16 || 14 >=14.17"
- }
- },
- "node_modules/mz": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
- "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
- "dependencies": {
- "any-promise": "^1.0.0",
- "object-assign": "^4.0.1",
- "thenify-all": "^1.0.0"
- }
- },
- "node_modules/nanoid": {
- "version": "3.3.8",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
- "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "bin": {
- "nanoid": "bin/nanoid.cjs"
- },
- "engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
- }
- },
- "node_modules/normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/object-hash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
- "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/package-json-from-dist": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
- "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="
- },
- "node_modules/path-key": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
- "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/path-parse": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
- "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
- },
- "node_modules/path-scurry": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
- "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
- "dependencies": {
- "lru-cache": "^10.2.0",
- "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
- },
- "engines": {
- "node": ">=16 || 14 >=14.18"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/picocolors": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
- "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
- },
- "node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/pirates": {
- "version": "4.0.6",
- "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
- "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/postcss": {
- "version": "8.4.49",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
- "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "dependencies": {
- "nanoid": "^3.3.7",
- "picocolors": "^1.1.1",
- "source-map-js": "^1.2.1"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- }
- },
- "node_modules/postcss-import": {
- "version": "15.1.0",
- "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
- "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
- "dependencies": {
- "postcss-value-parser": "^4.0.0",
- "read-cache": "^1.0.0",
- "resolve": "^1.1.7"
- },
- "engines": {
- "node": ">=14.0.0"
- },
- "peerDependencies": {
- "postcss": "^8.0.0"
- }
- },
- "node_modules/postcss-js": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
- "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
- "dependencies": {
- "camelcase-css": "^2.0.1"
- },
- "engines": {
- "node": "^12 || ^14 || >= 16"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- "peerDependencies": {
- "postcss": "^8.4.21"
- }
- },
- "node_modules/postcss-load-config": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
- "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "dependencies": {
- "lilconfig": "^3.0.0",
- "yaml": "^2.3.4"
- },
- "engines": {
- "node": ">= 14"
- },
- "peerDependencies": {
- "postcss": ">=8.0.9",
- "ts-node": ">=9.0.0"
- },
- "peerDependenciesMeta": {
- "postcss": {
- "optional": true
- },
- "ts-node": {
- "optional": true
- }
- }
- },
- "node_modules/postcss-load-config/node_modules/lilconfig": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz",
- "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==",
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/antonk52"
- }
- },
- "node_modules/postcss-nested": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
- "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "dependencies": {
- "postcss-selector-parser": "^6.1.1"
- },
- "engines": {
- "node": ">=12.0"
- },
- "peerDependencies": {
- "postcss": "^8.2.14"
- }
- },
- "node_modules/postcss-selector-parser": {
- "version": "6.1.2",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
- "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
- "dependencies": {
- "cssesc": "^3.0.0",
- "util-deprecate": "^1.0.2"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/postcss-value-parser": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
- "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
- },
- "node_modules/queue-microtask": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
- "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ]
- },
- "node_modules/read-cache": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
- "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
- "dependencies": {
- "pify": "^2.3.0"
- }
- },
- "node_modules/readdirp": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
- "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
- "dependencies": {
- "picomatch": "^2.2.1"
- },
- "engines": {
- "node": ">=8.10.0"
- }
- },
- "node_modules/resolve": {
- "version": "1.22.8",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
- "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
- "dependencies": {
- "is-core-module": "^2.13.0",
- "path-parse": "^1.0.7",
- "supports-preserve-symlinks-flag": "^1.0.0"
- },
- "bin": {
- "resolve": "bin/resolve"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/reusify": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
- "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
- "engines": {
- "iojs": ">=1.0.0",
- "node": ">=0.10.0"
- }
- },
- "node_modules/run-parallel": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
- "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "dependencies": {
- "queue-microtask": "^1.2.2"
- }
- },
- "node_modules/shebang-command": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
- "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
- "dependencies": {
- "shebang-regex": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/shebang-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/signal-exit": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
- "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/source-map-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/string-width": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
- "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
- "dependencies": {
- "eastasianwidth": "^0.2.0",
- "emoji-regex": "^9.2.2",
- "strip-ansi": "^7.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/string-width-cjs": {
- "name": "string-width",
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/string-width-cjs/node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/string-width-cjs/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
- },
- "node_modules/string-width-cjs/node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-ansi": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
- "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
- "dependencies": {
- "ansi-regex": "^6.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/strip-ansi?sponsor=1"
- }
- },
- "node_modules/strip-ansi-cjs": {
- "name": "strip-ansi",
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/sucrase": {
- "version": "3.35.0",
- "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
- "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.2",
- "commander": "^4.0.0",
- "glob": "^10.3.10",
- "lines-and-columns": "^1.1.6",
- "mz": "^2.7.0",
- "pirates": "^4.0.1",
- "ts-interface-checker": "^0.1.9"
- },
- "bin": {
- "sucrase": "bin/sucrase",
- "sucrase-node": "bin/sucrase-node"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- }
- },
- "node_modules/supports-preserve-symlinks-flag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
- "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/tailwindcss": {
- "version": "3.4.15",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.15.tgz",
- "integrity": "sha512-r4MeXnfBmSOuKUWmXe6h2CcyfzJCEk4F0pptO5jlnYSIViUkVmsawj80N5h2lO3gwcmSb4n3PuN+e+GC1Guylw==",
- "dependencies": {
- "@alloc/quick-lru": "^5.2.0",
- "arg": "^5.0.2",
- "chokidar": "^3.6.0",
- "didyoumean": "^1.2.2",
- "dlv": "^1.1.3",
- "fast-glob": "^3.3.2",
- "glob-parent": "^6.0.2",
- "is-glob": "^4.0.3",
- "jiti": "^1.21.6",
- "lilconfig": "^2.1.0",
- "micromatch": "^4.0.8",
- "normalize-path": "^3.0.0",
- "object-hash": "^3.0.0",
- "picocolors": "^1.1.1",
- "postcss": "^8.4.47",
- "postcss-import": "^15.1.0",
- "postcss-js": "^4.0.1",
- "postcss-load-config": "^4.0.2",
- "postcss-nested": "^6.2.0",
- "postcss-selector-parser": "^6.1.2",
- "resolve": "^1.22.8",
- "sucrase": "^3.35.0"
- },
- "bin": {
- "tailwind": "lib/cli.js",
- "tailwindcss": "lib/cli.js"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/thenify": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
- "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
- "dependencies": {
- "any-promise": "^1.0.0"
- }
- },
- "node_modules/thenify-all": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
- "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
- "dependencies": {
- "thenify": ">= 3.1.0 < 4"
- },
- "engines": {
- "node": ">=0.8"
- }
- },
- "node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/ts-interface-checker": {
- "version": "0.1.13",
- "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
- "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="
- },
- "node_modules/util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
- },
- "node_modules/which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "node-which": "bin/node-which"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/wrap-ansi": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
- "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
- "dependencies": {
- "ansi-styles": "^6.1.0",
- "string-width": "^5.0.1",
- "strip-ansi": "^7.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
- }
- },
- "node_modules/wrap-ansi-cjs": {
- "name": "wrap-ansi",
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
- "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
- }
- },
- "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
- },
- "node_modules/wrap-ansi-cjs/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/yaml": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.1.tgz",
- "integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==",
- "bin": {
- "yaml": "bin.mjs"
- },
- "engines": {
- "node": ">= 14"
- }
- }
- }
-}
diff --git a/package.json b/package.json
index 53df816..cad550d 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,25 @@
{
+ "name": "wah-su.github.io",
+ "devDependencies": {
+ "@types/bun": "latest",
+ "@types/react": "^19.0.8",
+ "@types/react-dom": "^19.0.3",
+ "@types/express": "^5.0.0",
+ "chokidar": "^4.0.3",
+ "express": "^4.21.2",
+ "ws": "^8.18.0"
+ },
+ "peerDependencies": {
+ "typescript": "^5.0.0"
+ },
"dependencies": {
- "tailwindcss": "^3.4.15"
+ "@tailwindcss/cli": "^4.0.6",
+ "picocolors": "^1.1.1",
+ "react": "^19.0.0",
+ "react-dom": "^19.0.0"
+ },
+ "scripts": {
+ "dev": "bun run ./src/watch.ts",
+ "gen": "bun run ./src/build.tsx"
}
-}
+}
\ No newline at end of file
diff --git a/privacy.html b/privacy.html
deleted file mode 100644
index 2130bd7..0000000
--- a/privacy.html
+++ /dev/null
@@ -1,200 +0,0 @@
-
-
-
-
-
- wah.su | Privacy Policy
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Privacy Policy for wah.su
-
- At wah.su, accessible from https://wah.su and its subdomains, one of
- our main priorities is the privacy of our visitors. This Privacy
- Policy document contains types of information that is collected and
- recorded by wah.su and how we use it.
-
-
- If you have additional questions or require more information about
- our Privacy Policy, do not hesitate to contact us.
-
-
-
-
-
Log Files
-
- wah.su follows a standard procedure of using log files. These files
- log visitors when they visit websites. All hosting companies do this
- and a part of hosting services' analytics. The information collected
- by log files include internet protocol (IP) addresses, browser type,
- Internet Service Provider (ISP), date and timestamp, referring/exit
- pages, and possibly the number of clicks. These are not linked to
- any information that is personally identifiable. The purpose of the
- information is for analyzing trends, administering the site,
- tracking users' movement on the website, and gathering demographic
- information.
-
-
-
-
-
Cookies and Web Beacons
-
- Like any other website, wah.su uses "cookies". These cookies are
- used to store information including visitors' preferences, and the
- pages on the website that the visitor accessed or visited. The
- information is used to optimize the users' experience by customizing
- our web page content based on visitors' browser type and/or other
- information.
-
-
-
-
-
-
-
Third Party Privacy Policies
-
- wah.su's Privacy Policy does not apply to other advertisers or
- websites. Thus, we are advising you to consult the respective
- Privacy Policies of these third-party ad servers for more detailed
- information. It may include their practices and instructions about
- how to opt-out of certain options.
-
-
- You can choose to disable cookies through your individual browser
- options. To know more detailed information about cookie management
- with specific web browsers, it can be found at the browsers'
- respective websites.
-
-
-
-
-
Children's Information
-
- Another part of our priority is adding protection for children while
- using the internet. We encourage parents and guardians to observe,
- participate in, and/or monitor and guide their online activity.
-
-
- wah.su does not knowingly collect any Personal Identifiable
- Information from children under the age of 13. If you think that
- your child provided this kind of information on our website, we
- strongly encourage you to contact us immediately and we will do our
- best efforts to promptly remove such information from our records.
-
-
-
-
-
Online Privacy Policy Only
-
- This Privacy Policy applies only to our online activities and is
- valid for visitors to our website with regards to the information
- that they shared and/or collect in wah.su. This policy is not
- applicable to any information collected offline or via channels
- other than this website.
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/services.html b/services.html
deleted file mode 100644
index 663d9de..0000000
--- a/services.html
+++ /dev/null
@@ -1,126 +0,0 @@
-
-
-
-
-
-
- wah.su | Services
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
File Sharing
-
-
-
-
-
NextCloud
-
-
Productivity suite, offering file sharing and collaboration tools.
-
-
-
-
-
Zipline
-
-
Image uploading with ShareX compatibility.
-
-
-
-
-
-
Media
-
-
-
-
-
Immich
-
-
Platform for managing and browsing your photos.
-
-
-
-
-
Navidrome
-
-
Self-hosted music library and player with subsonic protocol support.
-
-
-
-
-
-
Security and Privacy
-
-
-
-
-
Vaultwarden
-
-
Unofficial Bitwarden password manager compatible server.
-
-
-
-
-
-
Communication
-
-
-
-
-
Matrix
-
-
An open network for secure, decentralised communication.
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/build.tsx b/src/build.tsx
new file mode 100644
index 0000000..9f02b0c
--- /dev/null
+++ b/src/build.tsx
@@ -0,0 +1,66 @@
+import { Log } from "./utils";
+import { renderToString } from "react-dom/server";
+import fs from "fs";
+import exec from "child_process";
+import Base from "./templates/Base";
+import Title from "./templates/Title";
+import Bento from "./templates/Bento";
+import NotBento from "./templates/NotBento";
+
+const environment: "prod" | "dev" =
+ (process.env.ENVIRONMENT as "prod" | "dev") || "prod";
+const log = new Log();
+
+if (environment == "dev") {
+ log.warn("Running in a dev mode!");
+}
+
+if (!fs.existsSync("out")) fs.mkdirSync("out");
+
+const html = renderToString(
+
+
+
+
+
+);
+fs.cpSync("src/static", "out/static", { recursive: true });
+if (environment == "dev") {
+ fs.cpSync("src/static_dev", "out/static/js", { recursive: true });
+} else {
+ log.info("Minifying resources...");
+ exec.exec(
+ "bun run tailwindcss -i src/input.css -o out/static/css/tailwind.css --build --minify",
+ (error, stdout, stderr) => {
+ if (error) {
+ log.error(error.message);
+ return;
+ }
+ if (stderr) {
+ log.error(stderr);
+ return;
+ }
+ log.info(stdout);
+ }
+ );
+
+ const transpiler = new Bun.Transpiler({
+ loader: "js",
+ target: "browser",
+ minifyWhitespace: true,
+ });
+
+ const files = fs.readdirSync("src/static/js");
+ const minify = files.filter((file) => file.endsWith(".js"));
+
+ minify.forEach((file) => {
+ const ext = file.split(".")[file.split(".").length - 1];
+ const name = file.split(".")[0];
+ const orFile = fs.readFileSync(`src/static/js/${file}`, {
+ encoding: "utf-8",
+ });
+ const minFile = transpiler.transformSync(orFile);
+ fs.writeFileSync(`out/static/js/${name}.${ext}`, minFile);
+ });
+}
+fs.writeFileSync("out/index.html", `${html}`);
diff --git a/src/input.css b/src/input.css
new file mode 100644
index 0000000..eb5e11e
--- /dev/null
+++ b/src/input.css
@@ -0,0 +1,34 @@
+@import "tailwindcss";
+
+.ubuntu-regular {
+ font-family: "Ubuntu", serif;
+ font-weight: 400;
+ font-style: normal;
+}
+
+.ubuntu-mono-regular {
+ font-family: "Ubuntu Mono", serif;
+ font-weight: 400;
+ font-style: normal;
+}
+
+.sometype-mono-regular {
+ font-family: "Sometype Mono", serif;
+ font-optical-sizing: auto;
+ font-weight: 400;
+ font-style: normal;
+}
+
+body {
+ position: relative;
+
+ /* Create the dots */
+ background-image:
+ radial-gradient(circle at 1px 1px, #33333366 1px, transparent 0),
+ linear-gradient(to right, #33333366 1px, transparent 1px),
+ linear-gradient(to bottom, #33333366 1px, transparent 1px);
+
+ background-size: 20px 20px;
+ background-position: 0 0, 0 0, 0 0;
+ background-attachment: fixed;
+}
\ No newline at end of file
diff --git a/src/static/css/tailwind.css b/src/static/css/tailwind.css
new file mode 100644
index 0000000..4df0591
--- /dev/null
+++ b/src/static/css/tailwind.css
@@ -0,0 +1,1199 @@
+/*! tailwindcss v4.0.6 | MIT License | https://tailwindcss.com */
+@layer theme, base, components, utilities;
+@layer theme {
+ :root, :host {
+ --font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji",
+ "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+ --font-serif: ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
+ --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
+ "Courier New", monospace;
+ --color-red-50: oklch(0.971 0.013 17.38);
+ --color-red-100: oklch(0.936 0.032 17.717);
+ --color-red-200: oklch(0.885 0.062 18.334);
+ --color-red-300: oklch(0.808 0.114 19.571);
+ --color-red-400: oklch(0.704 0.191 22.216);
+ --color-red-500: oklch(0.637 0.237 25.331);
+ --color-red-600: oklch(0.577 0.245 27.325);
+ --color-red-700: oklch(0.505 0.213 27.518);
+ --color-red-800: oklch(0.444 0.177 26.899);
+ --color-red-900: oklch(0.396 0.141 25.723);
+ --color-red-950: oklch(0.258 0.092 26.042);
+ --color-orange-50: oklch(0.98 0.016 73.684);
+ --color-orange-100: oklch(0.954 0.038 75.164);
+ --color-orange-200: oklch(0.901 0.076 70.697);
+ --color-orange-300: oklch(0.837 0.128 66.29);
+ --color-orange-400: oklch(0.75 0.183 55.934);
+ --color-orange-500: oklch(0.705 0.213 47.604);
+ --color-orange-600: oklch(0.646 0.222 41.116);
+ --color-orange-700: oklch(0.553 0.195 38.402);
+ --color-orange-800: oklch(0.47 0.157 37.304);
+ --color-orange-900: oklch(0.408 0.123 38.172);
+ --color-orange-950: oklch(0.266 0.079 36.259);
+ --color-amber-50: oklch(0.987 0.022 95.277);
+ --color-amber-100: oklch(0.962 0.059 95.617);
+ --color-amber-200: oklch(0.924 0.12 95.746);
+ --color-amber-300: oklch(0.879 0.169 91.605);
+ --color-amber-400: oklch(0.828 0.189 84.429);
+ --color-amber-500: oklch(0.769 0.188 70.08);
+ --color-amber-600: oklch(0.666 0.179 58.318);
+ --color-amber-700: oklch(0.555 0.163 48.998);
+ --color-amber-800: oklch(0.473 0.137 46.201);
+ --color-amber-900: oklch(0.414 0.112 45.904);
+ --color-amber-950: oklch(0.279 0.077 45.635);
+ --color-yellow-50: oklch(0.987 0.026 102.212);
+ --color-yellow-100: oklch(0.973 0.071 103.193);
+ --color-yellow-200: oklch(0.945 0.129 101.54);
+ --color-yellow-300: oklch(0.905 0.182 98.111);
+ --color-yellow-400: oklch(0.852 0.199 91.936);
+ --color-yellow-500: oklch(0.795 0.184 86.047);
+ --color-yellow-600: oklch(0.681 0.162 75.834);
+ --color-yellow-700: oklch(0.554 0.135 66.442);
+ --color-yellow-800: oklch(0.476 0.114 61.907);
+ --color-yellow-900: oklch(0.421 0.095 57.708);
+ --color-yellow-950: oklch(0.286 0.066 53.813);
+ --color-lime-50: oklch(0.986 0.031 120.757);
+ --color-lime-100: oklch(0.967 0.067 122.328);
+ --color-lime-200: oklch(0.938 0.127 124.321);
+ --color-lime-300: oklch(0.897 0.196 126.665);
+ --color-lime-400: oklch(0.841 0.238 128.85);
+ --color-lime-500: oklch(0.768 0.233 130.85);
+ --color-lime-600: oklch(0.648 0.2 131.684);
+ --color-lime-700: oklch(0.532 0.157 131.589);
+ --color-lime-800: oklch(0.453 0.124 130.933);
+ --color-lime-900: oklch(0.405 0.101 131.063);
+ --color-lime-950: oklch(0.274 0.072 132.109);
+ --color-green-50: oklch(0.982 0.018 155.826);
+ --color-green-100: oklch(0.962 0.044 156.743);
+ --color-green-200: oklch(0.925 0.084 155.995);
+ --color-green-300: oklch(0.871 0.15 154.449);
+ --color-green-400: oklch(0.792 0.209 151.711);
+ --color-green-500: oklch(0.723 0.219 149.579);
+ --color-green-600: oklch(0.627 0.194 149.214);
+ --color-green-700: oklch(0.527 0.154 150.069);
+ --color-green-800: oklch(0.448 0.119 151.328);
+ --color-green-900: oklch(0.393 0.095 152.535);
+ --color-green-950: oklch(0.266 0.065 152.934);
+ --color-emerald-50: oklch(0.979 0.021 166.113);
+ --color-emerald-100: oklch(0.95 0.052 163.051);
+ --color-emerald-200: oklch(0.905 0.093 164.15);
+ --color-emerald-300: oklch(0.845 0.143 164.978);
+ --color-emerald-400: oklch(0.765 0.177 163.223);
+ --color-emerald-500: oklch(0.696 0.17 162.48);
+ --color-emerald-600: oklch(0.596 0.145 163.225);
+ --color-emerald-700: oklch(0.508 0.118 165.612);
+ --color-emerald-800: oklch(0.432 0.095 166.913);
+ --color-emerald-900: oklch(0.378 0.077 168.94);
+ --color-emerald-950: oklch(0.262 0.051 172.552);
+ --color-teal-50: oklch(0.984 0.014 180.72);
+ --color-teal-100: oklch(0.953 0.051 180.801);
+ --color-teal-200: oklch(0.91 0.096 180.426);
+ --color-teal-300: oklch(0.855 0.138 181.071);
+ --color-teal-400: oklch(0.777 0.152 181.912);
+ --color-teal-500: oklch(0.704 0.14 182.503);
+ --color-teal-600: oklch(0.6 0.118 184.704);
+ --color-teal-700: oklch(0.511 0.096 186.391);
+ --color-teal-800: oklch(0.437 0.078 188.216);
+ --color-teal-900: oklch(0.386 0.063 188.416);
+ --color-teal-950: oklch(0.277 0.046 192.524);
+ --color-cyan-50: oklch(0.984 0.019 200.873);
+ --color-cyan-100: oklch(0.956 0.045 203.388);
+ --color-cyan-200: oklch(0.917 0.08 205.041);
+ --color-cyan-300: oklch(0.865 0.127 207.078);
+ --color-cyan-400: oklch(0.789 0.154 211.53);
+ --color-cyan-500: oklch(0.715 0.143 215.221);
+ --color-cyan-600: oklch(0.609 0.126 221.723);
+ --color-cyan-700: oklch(0.52 0.105 223.128);
+ --color-cyan-800: oklch(0.45 0.085 224.283);
+ --color-cyan-900: oklch(0.398 0.07 227.392);
+ --color-cyan-950: oklch(0.302 0.056 229.695);
+ --color-sky-50: oklch(0.977 0.013 236.62);
+ --color-sky-100: oklch(0.951 0.026 236.824);
+ --color-sky-200: oklch(0.901 0.058 230.902);
+ --color-sky-300: oklch(0.828 0.111 230.318);
+ --color-sky-400: oklch(0.746 0.16 232.661);
+ --color-sky-500: oklch(0.685 0.169 237.323);
+ --color-sky-600: oklch(0.588 0.158 241.966);
+ --color-sky-700: oklch(0.5 0.134 242.749);
+ --color-sky-800: oklch(0.443 0.11 240.79);
+ --color-sky-900: oklch(0.391 0.09 240.876);
+ --color-sky-950: oklch(0.293 0.066 243.157);
+ --color-blue-50: oklch(0.97 0.014 254.604);
+ --color-blue-100: oklch(0.932 0.032 255.585);
+ --color-blue-200: oklch(0.882 0.059 254.128);
+ --color-blue-300: oklch(0.809 0.105 251.813);
+ --color-blue-400: oklch(0.707 0.165 254.624);
+ --color-blue-500: oklch(0.623 0.214 259.815);
+ --color-blue-600: oklch(0.546 0.245 262.881);
+ --color-blue-700: oklch(0.488 0.243 264.376);
+ --color-blue-800: oklch(0.424 0.199 265.638);
+ --color-blue-900: oklch(0.379 0.146 265.522);
+ --color-blue-950: oklch(0.282 0.091 267.935);
+ --color-indigo-50: oklch(0.962 0.018 272.314);
+ --color-indigo-100: oklch(0.93 0.034 272.788);
+ --color-indigo-200: oklch(0.87 0.065 274.039);
+ --color-indigo-300: oklch(0.785 0.115 274.713);
+ --color-indigo-400: oklch(0.673 0.182 276.935);
+ --color-indigo-500: oklch(0.585 0.233 277.117);
+ --color-indigo-600: oklch(0.511 0.262 276.966);
+ --color-indigo-700: oklch(0.457 0.24 277.023);
+ --color-indigo-800: oklch(0.398 0.195 277.366);
+ --color-indigo-900: oklch(0.359 0.144 278.697);
+ --color-indigo-950: oklch(0.257 0.09 281.288);
+ --color-violet-50: oklch(0.969 0.016 293.756);
+ --color-violet-100: oklch(0.943 0.029 294.588);
+ --color-violet-200: oklch(0.894 0.057 293.283);
+ --color-violet-300: oklch(0.811 0.111 293.571);
+ --color-violet-400: oklch(0.702 0.183 293.541);
+ --color-violet-500: oklch(0.606 0.25 292.717);
+ --color-violet-600: oklch(0.541 0.281 293.009);
+ --color-violet-700: oklch(0.491 0.27 292.581);
+ --color-violet-800: oklch(0.432 0.232 292.759);
+ --color-violet-900: oklch(0.38 0.189 293.745);
+ --color-violet-950: oklch(0.283 0.141 291.089);
+ --color-purple-50: oklch(0.977 0.014 308.299);
+ --color-purple-100: oklch(0.946 0.033 307.174);
+ --color-purple-200: oklch(0.902 0.063 306.703);
+ --color-purple-300: oklch(0.827 0.119 306.383);
+ --color-purple-400: oklch(0.714 0.203 305.504);
+ --color-purple-500: oklch(0.627 0.265 303.9);
+ --color-purple-600: oklch(0.558 0.288 302.321);
+ --color-purple-700: oklch(0.496 0.265 301.924);
+ --color-purple-800: oklch(0.438 0.218 303.724);
+ --color-purple-900: oklch(0.381 0.176 304.987);
+ --color-purple-950: oklch(0.291 0.149 302.717);
+ --color-fuchsia-50: oklch(0.977 0.017 320.058);
+ --color-fuchsia-100: oklch(0.952 0.037 318.852);
+ --color-fuchsia-200: oklch(0.903 0.076 319.62);
+ --color-fuchsia-300: oklch(0.833 0.145 321.434);
+ --color-fuchsia-400: oklch(0.74 0.238 322.16);
+ --color-fuchsia-500: oklch(0.667 0.295 322.15);
+ --color-fuchsia-600: oklch(0.591 0.293 322.896);
+ --color-fuchsia-700: oklch(0.518 0.253 323.949);
+ --color-fuchsia-800: oklch(0.452 0.211 324.591);
+ --color-fuchsia-900: oklch(0.401 0.17 325.612);
+ --color-fuchsia-950: oklch(0.293 0.136 325.661);
+ --color-pink-50: oklch(0.971 0.014 343.198);
+ --color-pink-100: oklch(0.948 0.028 342.258);
+ --color-pink-200: oklch(0.899 0.061 343.231);
+ --color-pink-300: oklch(0.823 0.12 346.018);
+ --color-pink-400: oklch(0.718 0.202 349.761);
+ --color-pink-500: oklch(0.656 0.241 354.308);
+ --color-pink-600: oklch(0.592 0.249 0.584);
+ --color-pink-700: oklch(0.525 0.223 3.958);
+ --color-pink-800: oklch(0.459 0.187 3.815);
+ --color-pink-900: oklch(0.408 0.153 2.432);
+ --color-pink-950: oklch(0.284 0.109 3.907);
+ --color-rose-50: oklch(0.969 0.015 12.422);
+ --color-rose-100: oklch(0.941 0.03 12.58);
+ --color-rose-200: oklch(0.892 0.058 10.001);
+ --color-rose-300: oklch(0.81 0.117 11.638);
+ --color-rose-400: oklch(0.712 0.194 13.428);
+ --color-rose-500: oklch(0.645 0.246 16.439);
+ --color-rose-600: oklch(0.586 0.253 17.585);
+ --color-rose-700: oklch(0.514 0.222 16.935);
+ --color-rose-800: oklch(0.455 0.188 13.697);
+ --color-rose-900: oklch(0.41 0.159 10.272);
+ --color-rose-950: oklch(0.271 0.105 12.094);
+ --color-slate-50: oklch(0.984 0.003 247.858);
+ --color-slate-100: oklch(0.968 0.007 247.896);
+ --color-slate-200: oklch(0.929 0.013 255.508);
+ --color-slate-300: oklch(0.869 0.022 252.894);
+ --color-slate-400: oklch(0.704 0.04 256.788);
+ --color-slate-500: oklch(0.554 0.046 257.417);
+ --color-slate-600: oklch(0.446 0.043 257.281);
+ --color-slate-700: oklch(0.372 0.044 257.287);
+ --color-slate-800: oklch(0.279 0.041 260.031);
+ --color-slate-900: oklch(0.208 0.042 265.755);
+ --color-slate-950: oklch(0.129 0.042 264.695);
+ --color-gray-50: oklch(0.985 0.002 247.839);
+ --color-gray-100: oklch(0.967 0.003 264.542);
+ --color-gray-200: oklch(0.928 0.006 264.531);
+ --color-gray-300: oklch(0.872 0.01 258.338);
+ --color-gray-400: oklch(0.707 0.022 261.325);
+ --color-gray-500: oklch(0.551 0.027 264.364);
+ --color-gray-600: oklch(0.446 0.03 256.802);
+ --color-gray-700: oklch(0.373 0.034 259.733);
+ --color-gray-800: oklch(0.278 0.033 256.848);
+ --color-gray-900: oklch(0.21 0.034 264.665);
+ --color-gray-950: oklch(0.13 0.028 261.692);
+ --color-zinc-50: oklch(0.985 0 0);
+ --color-zinc-100: oklch(0.967 0.001 286.375);
+ --color-zinc-200: oklch(0.92 0.004 286.32);
+ --color-zinc-300: oklch(0.871 0.006 286.286);
+ --color-zinc-400: oklch(0.705 0.015 286.067);
+ --color-zinc-500: oklch(0.552 0.016 285.938);
+ --color-zinc-600: oklch(0.442 0.017 285.786);
+ --color-zinc-700: oklch(0.37 0.013 285.805);
+ --color-zinc-800: oklch(0.274 0.006 286.033);
+ --color-zinc-900: oklch(0.21 0.006 285.885);
+ --color-zinc-950: oklch(0.141 0.005 285.823);
+ --color-neutral-50: oklch(0.985 0 0);
+ --color-neutral-100: oklch(0.97 0 0);
+ --color-neutral-200: oklch(0.922 0 0);
+ --color-neutral-300: oklch(0.87 0 0);
+ --color-neutral-400: oklch(0.708 0 0);
+ --color-neutral-500: oklch(0.556 0 0);
+ --color-neutral-600: oklch(0.439 0 0);
+ --color-neutral-700: oklch(0.371 0 0);
+ --color-neutral-800: oklch(0.269 0 0);
+ --color-neutral-900: oklch(0.205 0 0);
+ --color-neutral-950: oklch(0.145 0 0);
+ --color-stone-50: oklch(0.985 0.001 106.423);
+ --color-stone-100: oklch(0.97 0.001 106.424);
+ --color-stone-200: oklch(0.923 0.003 48.717);
+ --color-stone-300: oklch(0.869 0.005 56.366);
+ --color-stone-400: oklch(0.709 0.01 56.259);
+ --color-stone-500: oklch(0.553 0.013 58.071);
+ --color-stone-600: oklch(0.444 0.011 73.639);
+ --color-stone-700: oklch(0.374 0.01 67.558);
+ --color-stone-800: oklch(0.268 0.007 34.298);
+ --color-stone-900: oklch(0.216 0.006 56.043);
+ --color-stone-950: oklch(0.147 0.004 49.25);
+ --color-black: #000;
+ --color-white: #fff;
+ --spacing: 0.25rem;
+ --breakpoint-sm: 40rem;
+ --breakpoint-md: 48rem;
+ --breakpoint-lg: 64rem;
+ --breakpoint-xl: 80rem;
+ --breakpoint-2xl: 96rem;
+ --container-3xs: 16rem;
+ --container-2xs: 18rem;
+ --container-xs: 20rem;
+ --container-sm: 24rem;
+ --container-md: 28rem;
+ --container-lg: 32rem;
+ --container-xl: 36rem;
+ --container-2xl: 42rem;
+ --container-3xl: 48rem;
+ --container-4xl: 56rem;
+ --container-5xl: 64rem;
+ --container-6xl: 72rem;
+ --container-7xl: 80rem;
+ --text-xs: 0.75rem;
+ --text-xs--line-height: calc(1 / 0.75);
+ --text-sm: 0.875rem;
+ --text-sm--line-height: calc(1.25 / 0.875);
+ --text-base: 1rem;
+ --text-base--line-height: calc(1.5 / 1);
+ --text-lg: 1.125rem;
+ --text-lg--line-height: calc(1.75 / 1.125);
+ --text-xl: 1.25rem;
+ --text-xl--line-height: calc(1.75 / 1.25);
+ --text-2xl: 1.5rem;
+ --text-2xl--line-height: calc(2 / 1.5);
+ --text-3xl: 1.875rem;
+ --text-3xl--line-height: calc(2.25 / 1.875);
+ --text-4xl: 2.25rem;
+ --text-4xl--line-height: calc(2.5 / 2.25);
+ --text-5xl: 3rem;
+ --text-5xl--line-height: 1;
+ --text-6xl: 3.75rem;
+ --text-6xl--line-height: 1;
+ --text-7xl: 4.5rem;
+ --text-7xl--line-height: 1;
+ --text-8xl: 6rem;
+ --text-8xl--line-height: 1;
+ --text-9xl: 8rem;
+ --text-9xl--line-height: 1;
+ --font-weight-thin: 100;
+ --font-weight-extralight: 200;
+ --font-weight-light: 300;
+ --font-weight-normal: 400;
+ --font-weight-medium: 500;
+ --font-weight-semibold: 600;
+ --font-weight-bold: 700;
+ --font-weight-extrabold: 800;
+ --font-weight-black: 900;
+ --tracking-tighter: -0.05em;
+ --tracking-tight: -0.025em;
+ --tracking-normal: 0em;
+ --tracking-wide: 0.025em;
+ --tracking-wider: 0.05em;
+ --tracking-widest: 0.1em;
+ --leading-tight: 1.25;
+ --leading-snug: 1.375;
+ --leading-normal: 1.5;
+ --leading-relaxed: 1.625;
+ --leading-loose: 2;
+ --radius-xs: 0.125rem;
+ --radius-sm: 0.25rem;
+ --radius-md: 0.375rem;
+ --radius-lg: 0.5rem;
+ --radius-xl: 0.75rem;
+ --radius-2xl: 1rem;
+ --radius-3xl: 1.5rem;
+ --radius-4xl: 2rem;
+ --shadow-2xs: 0 1px rgb(0 0 0 / 0.05);
+ --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.05);
+ --shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
+ --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
+ --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
+ --shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / 0.25);
+ --inset-shadow-2xs: inset 0 1px rgb(0 0 0 / 0.05);
+ --inset-shadow-xs: inset 0 1px 1px rgb(0 0 0 / 0.05);
+ --inset-shadow-sm: inset 0 2px 4px rgb(0 0 0 / 0.05);
+ --drop-shadow-xs: 0 1px 1px rgb(0 0 0 / 0.05);
+ --drop-shadow-sm: 0 1px 2px rgb(0 0 0 / 0.15);
+ --drop-shadow-md: 0 3px 3px rgb(0 0 0 / 0.12);
+ --drop-shadow-lg: 0 4px 4px rgb(0 0 0 / 0.15);
+ --drop-shadow-xl: 0 9px 7px rgb(0 0 0 / 0.1);
+ --drop-shadow-2xl: 0 25px 25px rgb(0 0 0 / 0.15);
+ --ease-in: cubic-bezier(0.4, 0, 1, 1);
+ --ease-out: cubic-bezier(0, 0, 0.2, 1);
+ --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
+ --animate-spin: spin 1s linear infinite;
+ --animate-ping: ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;
+ --animate-pulse: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
+ --animate-bounce: bounce 1s infinite;
+ --blur-xs: 4px;
+ --blur-sm: 8px;
+ --blur-md: 12px;
+ --blur-lg: 16px;
+ --blur-xl: 24px;
+ --blur-2xl: 40px;
+ --blur-3xl: 64px;
+ --perspective-dramatic: 100px;
+ --perspective-near: 300px;
+ --perspective-normal: 500px;
+ --perspective-midrange: 800px;
+ --perspective-distant: 1200px;
+ --aspect-video: 16 / 9;
+ --default-transition-duration: 150ms;
+ --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ --default-font-family: var(--font-sans);
+ --default-font-feature-settings: var(--font-sans--font-feature-settings);
+ --default-font-variation-settings: var(
+ --font-sans--font-variation-settings
+ );
+ --default-mono-font-family: var(--font-mono);
+ --default-mono-font-feature-settings: var(
+ --font-mono--font-feature-settings
+ );
+ --default-mono-font-variation-settings: var(
+ --font-mono--font-variation-settings
+ );
+ }
+}
+@layer base {
+ *, ::after, ::before, ::backdrop, ::file-selector-button {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+ border: 0 solid;
+ }
+ html, :host {
+ line-height: 1.5;
+ -webkit-text-size-adjust: 100%;
+ tab-size: 4;
+ font-family: var( --default-font-family, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" );
+ font-feature-settings: var(--default-font-feature-settings, normal);
+ font-variation-settings: var( --default-font-variation-settings, normal );
+ -webkit-tap-highlight-color: transparent;
+ }
+ body {
+ line-height: inherit;
+ }
+ hr {
+ height: 0;
+ color: inherit;
+ border-top-width: 1px;
+ }
+ abbr:where([title]) {
+ -webkit-text-decoration: underline dotted;
+ text-decoration: underline dotted;
+ }
+ h1, h2, h3, h4, h5, h6 {
+ font-size: inherit;
+ font-weight: inherit;
+ }
+ a {
+ color: inherit;
+ -webkit-text-decoration: inherit;
+ text-decoration: inherit;
+ }
+ b, strong {
+ font-weight: bolder;
+ }
+ code, kbd, samp, pre {
+ font-family: var( --default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace );
+ font-feature-settings: var( --default-mono-font-feature-settings, normal );
+ font-variation-settings: var( --default-mono-font-variation-settings, normal );
+ font-size: 1em;
+ }
+ small {
+ font-size: 80%;
+ }
+ sub, sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+ }
+ sub {
+ bottom: -0.25em;
+ }
+ sup {
+ top: -0.5em;
+ }
+ table {
+ text-indent: 0;
+ border-color: inherit;
+ border-collapse: collapse;
+ }
+ :-moz-focusring {
+ outline: auto;
+ }
+ progress {
+ vertical-align: baseline;
+ }
+ summary {
+ display: list-item;
+ }
+ ol, ul, menu {
+ list-style: none;
+ }
+ img, svg, video, canvas, audio, iframe, embed, object {
+ display: block;
+ vertical-align: middle;
+ }
+ img, video {
+ max-width: 100%;
+ height: auto;
+ }
+ button, input, select, optgroup, textarea, ::file-selector-button {
+ font: inherit;
+ font-feature-settings: inherit;
+ font-variation-settings: inherit;
+ letter-spacing: inherit;
+ color: inherit;
+ border-radius: 0;
+ background-color: transparent;
+ opacity: 1;
+ }
+ :where(select:is([multiple], [size])) optgroup {
+ font-weight: bolder;
+ }
+ :where(select:is([multiple], [size])) optgroup option {
+ padding-inline-start: 20px;
+ }
+ ::file-selector-button {
+ margin-inline-end: 4px;
+ }
+ ::placeholder {
+ opacity: 1;
+ color: color-mix(in oklab, currentColor 50%, transparent);
+ }
+ textarea {
+ resize: vertical;
+ }
+ ::-webkit-search-decoration {
+ -webkit-appearance: none;
+ }
+ ::-webkit-date-and-time-value {
+ min-height: 1lh;
+ text-align: inherit;
+ }
+ ::-webkit-datetime-edit {
+ display: inline-flex;
+ }
+ ::-webkit-datetime-edit-fields-wrapper {
+ padding: 0;
+ }
+ ::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field {
+ padding-block: 0;
+ }
+ :-moz-ui-invalid {
+ box-shadow: none;
+ }
+ button, input:where([type="button"], [type="reset"], [type="submit"]), ::file-selector-button {
+ appearance: button;
+ }
+ ::-webkit-inner-spin-button, ::-webkit-outer-spin-button {
+ height: auto;
+ }
+ [hidden]:where(:not([hidden="until-found"])) {
+ display: none !important;
+ }
+}
+@layer utilities {
+ .invisible {
+ visibility: hidden;
+ }
+ .absolute {
+ position: absolute;
+ }
+ .relative {
+ position: relative;
+ }
+ .static {
+ position: static;
+ }
+ .inset-0 {
+ inset: calc(var(--spacing) * 0);
+ }
+ .top-0 {
+ top: calc(var(--spacing) * 0);
+ }
+ .left-0 {
+ left: calc(var(--spacing) * 0);
+ }
+ .-z-10 {
+ z-index: calc(10 * -1);
+ }
+ .col-\[1\] {
+ grid-column: 1;
+ }
+ .col-span-2 {
+ grid-column: span 2 / span 2;
+ }
+ .col-span-full {
+ grid-column: 1 / -1;
+ }
+ .col-start-2 {
+ grid-column-start: 2;
+ }
+ .row-\[1\] {
+ grid-row: 1;
+ }
+ .row-\[4\] {
+ grid-row: 4;
+ }
+ .row-span-2 {
+ grid-row: span 2 / span 2;
+ }
+ .row-span-3 {
+ grid-row: span 3 / span 3;
+ }
+ .row-start-1 {
+ grid-row-start: 1;
+ }
+ .row-start-2 {
+ grid-row-start: 2;
+ }
+ .container {
+ width: 100%;
+ @media (width >= 40rem) {
+ max-width: 40rem;
+ }
+ @media (width >= 48rem) {
+ max-width: 48rem;
+ }
+ @media (width >= 64rem) {
+ max-width: 64rem;
+ }
+ @media (width >= 80rem) {
+ max-width: 80rem;
+ }
+ @media (width >= 96rem) {
+ max-width: 96rem;
+ }
+ }
+ .mx-auto {
+ margin-inline: auto;
+ }
+ .mt-8 {
+ margin-top: calc(var(--spacing) * 8);
+ }
+ .-ml-1 {
+ margin-left: calc(var(--spacing) * -1);
+ }
+ .ml-1 {
+ margin-left: calc(var(--spacing) * 1);
+ }
+ .ml-auto {
+ margin-left: auto;
+ }
+ .block {
+ display: block;
+ }
+ .flex {
+ display: flex;
+ }
+ .grid {
+ display: grid;
+ }
+ .hidden {
+ display: none;
+ }
+ .inline {
+ display: inline;
+ }
+ .aspect-square {
+ aspect-ratio: 1 / 1;
+ }
+ .aspect-video {
+ aspect-ratio: var(--aspect-video);
+ }
+ .h-4 {
+ height: calc(var(--spacing) * 4);
+ }
+ .h-6 {
+ height: calc(var(--spacing) * 6);
+ }
+ .h-8 {
+ height: calc(var(--spacing) * 8);
+ }
+ .h-12 {
+ height: calc(var(--spacing) * 12);
+ }
+ .h-\[114px\] {
+ height: 114px;
+ }
+ .h-full {
+ height: 100%;
+ }
+ .max-h-\[512px\] {
+ max-height: 512px;
+ }
+ .min-h-\[438px\] {
+ min-height: 438px;
+ }
+ .w-4 {
+ width: calc(var(--spacing) * 4);
+ }
+ .w-6 {
+ width: calc(var(--spacing) * 6);
+ }
+ .w-\[114px\] {
+ width: 114px;
+ }
+ .w-full {
+ width: 100%;
+ }
+ .max-w-\[60\%\] {
+ max-width: 60%;
+ }
+ .max-w-\[75\%\] {
+ max-width: 75%;
+ }
+ .max-w-\[500px\] {
+ max-width: 500px;
+ }
+ .max-w-\[1210px\] {
+ max-width: 1210px;
+ }
+ .flex-shrink-0 {
+ flex-shrink: 0;
+ }
+ .origin-center {
+ transform-origin: center;
+ }
+ .scale-80 {
+ --tw-scale-x: 80%;
+ --tw-scale-y: 80%;
+ --tw-scale-z: 80%;
+ scale: var(--tw-scale-x) var(--tw-scale-y);
+ }
+ .scale-90 {
+ --tw-scale-x: 90%;
+ --tw-scale-y: 90%;
+ --tw-scale-z: 90%;
+ scale: var(--tw-scale-x) var(--tw-scale-y);
+ }
+ .scale-140 {
+ --tw-scale-x: 140%;
+ --tw-scale-y: 140%;
+ --tw-scale-z: 140%;
+ scale: var(--tw-scale-x) var(--tw-scale-y);
+ }
+ .scale-150 {
+ --tw-scale-x: 150%;
+ --tw-scale-y: 150%;
+ --tw-scale-z: 150%;
+ scale: var(--tw-scale-x) var(--tw-scale-y);
+ }
+ .animate-ping {
+ animation: var(--animate-ping);
+ }
+ .grid-cols-1 {
+ grid-template-columns: repeat(1, minmax(0, 1fr));
+ }
+ .grid-cols-\[repeat\(4\,minmax\(0\,280px\)\)\] {
+ grid-template-columns: repeat(4,minmax(0,280px));
+ }
+ .grid-rows-1 {
+ grid-template-rows: repeat(1, minmax(0, 1fr));
+ }
+ .grid-rows-\[repeat\(4\,minmax\(0\,136px\)\)\] {
+ grid-template-rows: repeat(4,minmax(0,136px));
+ }
+ .grid-rows-\[repeat\(7\,210px\)\] {
+ grid-template-rows: repeat(7,210px);
+ }
+ .flex-col {
+ flex-direction: column;
+ }
+ .flex-col-reverse {
+ flex-direction: column-reverse;
+ }
+ .flex-row {
+ flex-direction: row;
+ }
+ .items-center {
+ align-items: center;
+ }
+ .items-end {
+ align-items: flex-end;
+ }
+ .items-start {
+ align-items: flex-start;
+ }
+ .justify-center {
+ justify-content: center;
+ }
+ .justify-end {
+ justify-content: flex-end;
+ }
+ .gap-1 {
+ gap: calc(var(--spacing) * 1);
+ }
+ .gap-2 {
+ gap: calc(var(--spacing) * 2);
+ }
+ .gap-3 {
+ gap: calc(var(--spacing) * 3);
+ }
+ .gap-4 {
+ gap: calc(var(--spacing) * 4);
+ }
+ .gap-8 {
+ gap: calc(var(--spacing) * 8);
+ }
+ .overflow-hidden {
+ overflow: hidden;
+ }
+ .overflow-x-hidden {
+ overflow-x: hidden;
+ }
+ .rounded-full {
+ border-radius: calc(infinity * 1px);
+ }
+ .rounded-xl {
+ border-radius: var(--radius-xl);
+ }
+ .border {
+ border-style: var(--tw-border-style);
+ border-width: 1px;
+ }
+ .border-transparent {
+ border-color: transparent;
+ }
+ .bg-\[\#1A0F05\] {
+ background-color: #1A0F05;
+ }
+ .bg-\[\#3b0d25\] {
+ background-color: #3b0d25;
+ }
+ .bg-\[var\(--color\)\] {
+ background-color: var(--color);
+ }
+ .bg-\[var\(--ping-color\)\] {
+ background-color: var(--ping-color);
+ }
+ .bg-white {
+ background-color: var(--color-white);
+ }
+ .bg-gradient-to-r {
+ --tw-gradient-position: to right in oklab;
+ background-image: linear-gradient(var(--tw-gradient-stops));
+ }
+ .from-\[var\(--color\)\/0\] {
+ --tw-gradient-from: var(--color)/0;
+ --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
+ }
+ .to-\[var\(--color\)\] {
+ --tw-gradient-to: var(--color);
+ --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
+ }
+ .to-\[50\%\] {
+ --tw-gradient-to-position: 50%;
+ }
+ .to-\[75\%\] {
+ --tw-gradient-to-position: 75%;
+ }
+ .object-contain {
+ object-fit: contain;
+ }
+ .object-cover {
+ object-fit: cover;
+ }
+ .object-center {
+ object-position: center;
+ }
+ .p-2 {
+ padding: calc(var(--spacing) * 2);
+ }
+ .p-8 {
+ padding: calc(var(--spacing) * 8);
+ }
+ .px-8 {
+ padding-inline: calc(var(--spacing) * 8);
+ }
+ .py-8 {
+ padding-block: calc(var(--spacing) * 8);
+ }
+ .text-right {
+ text-align: right;
+ }
+ .text-lg {
+ font-size: var(--text-lg);
+ line-height: var(--tw-leading, var(--text-lg--line-height));
+ }
+ .text-xs {
+ font-size: var(--text-xs);
+ line-height: var(--tw-leading, var(--text-xs--line-height));
+ }
+ .text-\[24px\] {
+ font-size: 24px;
+ }
+ .text-\[32px\] {
+ font-size: 32px;
+ }
+ .text-\[64px\] {
+ font-size: 64px;
+ }
+ .leading-none {
+ --tw-leading: 1;
+ line-height: 1;
+ }
+ .tracking-tighter {
+ --tw-tracking: var(--tracking-tighter);
+ letter-spacing: var(--tracking-tighter);
+ }
+ .text-\[\#FF851A\] {
+ color: #FF851A;
+ }
+ .text-black {
+ color: var(--color-black);
+ }
+ .text-white {
+ color: var(--color-white);
+ }
+ .transition {
+ transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter;
+ transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
+ transition-duration: var(--tw-duration, var(--default-transition-duration));
+ }
+ .transition-colors {
+ transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;
+ transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
+ transition-duration: var(--tw-duration, var(--default-transition-duration));
+ }
+ .transition-transform {
+ transition-property: transform, translate, scale, rotate;
+ transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
+ transition-duration: var(--tw-duration, var(--default-transition-duration));
+ }
+ .duration-400 {
+ --tw-duration: 400ms;
+ transition-duration: 400ms;
+ }
+ .ease-in {
+ --tw-ease: var(--ease-in);
+ transition-timing-function: var(--ease-in);
+ }
+ .hover\:-rotate-5 {
+ &:hover {
+ @media (hover: hover) {
+ rotate: calc(5deg * -1);
+ }
+ }
+ }
+ .hover\:border-\[\#FF851A\] {
+ &:hover {
+ @media (hover: hover) {
+ border-color: #FF851A;
+ }
+ }
+ }
+ .hover\:text-\[\#FF851A\] {
+ &:hover {
+ @media (hover: hover) {
+ color: #FF851A;
+ }
+ }
+ }
+ .sm\:ml-0 {
+ @media (width >= 40rem) {
+ margin-left: calc(var(--spacing) * 0);
+ }
+ }
+ .sm\:inline {
+ @media (width >= 40rem) {
+ display: inline;
+ }
+ }
+ .sm\:flex-shrink-1 {
+ @media (width >= 40rem) {
+ flex-shrink: 1;
+ }
+ }
+ .sm\:grid-rows-\[repeat\(7\,144px\)\] {
+ @media (width >= 40rem) {
+ grid-template-rows: repeat(7,144px);
+ }
+ }
+ .sm\:flex-row {
+ @media (width >= 40rem) {
+ flex-direction: row;
+ }
+ }
+ .sm\:gap-2 {
+ @media (width >= 40rem) {
+ gap: calc(var(--spacing) * 2);
+ }
+ }
+ .sm\:gap-8 {
+ @media (width >= 40rem) {
+ gap: calc(var(--spacing) * 8);
+ }
+ }
+ .sm\:py-14 {
+ @media (width >= 40rem) {
+ padding-block: calc(var(--spacing) * 14);
+ }
+ }
+ .sm\:text-base {
+ @media (width >= 40rem) {
+ font-size: var(--text-base);
+ line-height: var(--tw-leading, var(--text-base--line-height));
+ }
+ }
+ .md\:-my-8 {
+ @media (width >= 48rem) {
+ margin-block: calc(var(--spacing) * -8);
+ }
+ }
+ .md\:scale-85 {
+ @media (width >= 48rem) {
+ --tw-scale-x: 85%;
+ --tw-scale-y: 85%;
+ --tw-scale-z: 85%;
+ scale: var(--tw-scale-x) var(--tw-scale-y);
+ }
+ }
+ .md\:scale-90 {
+ @media (width >= 48rem) {
+ --tw-scale-x: 90%;
+ --tw-scale-y: 90%;
+ --tw-scale-z: 90%;
+ scale: var(--tw-scale-x) var(--tw-scale-y);
+ }
+ }
+ .md\:gap-4 {
+ @media (width >= 48rem) {
+ gap: calc(var(--spacing) * 4);
+ }
+ }
+ .md\:py-0 {
+ @media (width >= 48rem) {
+ padding-block: calc(var(--spacing) * 0);
+ }
+ }
+ .md\:text-\[32px\] {
+ @media (width >= 48rem) {
+ font-size: 32px;
+ }
+ }
+ .md\:text-\[48px\] {
+ @media (width >= 48rem) {
+ font-size: 48px;
+ }
+ }
+ .md\:text-\[128px\] {
+ @media (width >= 48rem) {
+ font-size: 128px;
+ }
+ }
+ .md\:tracking-normal {
+ @media (width >= 48rem) {
+ --tw-tracking: var(--tracking-normal);
+ letter-spacing: var(--tracking-normal);
+ }
+ }
+ .lg\:mt-16 {
+ @media (width >= 64rem) {
+ margin-top: calc(var(--spacing) * 16);
+ }
+ }
+ .lg\:grid {
+ @media (width >= 64rem) {
+ display: grid;
+ }
+ }
+ .lg\:hidden {
+ @media (width >= 64rem) {
+ display: none;
+ }
+ }
+ .lg\:scale-95 {
+ @media (width >= 64rem) {
+ --tw-scale-x: 95%;
+ --tw-scale-y: 95%;
+ --tw-scale-z: 95%;
+ scale: var(--tw-scale-x) var(--tw-scale-y);
+ }
+ }
+ .lg\:scale-100 {
+ @media (width >= 64rem) {
+ --tw-scale-x: 100%;
+ --tw-scale-y: 100%;
+ --tw-scale-z: 100%;
+ scale: var(--tw-scale-x) var(--tw-scale-y);
+ }
+ }
+ .lg\:flex-row {
+ @media (width >= 64rem) {
+ flex-direction: row;
+ }
+ }
+ .xl\:my-0 {
+ @media (width >= 80rem) {
+ margin-block: calc(var(--spacing) * 0);
+ }
+ }
+ .xl\:mt-0 {
+ @media (width >= 80rem) {
+ margin-top: calc(var(--spacing) * 0);
+ }
+ }
+ .xl\:max-h-none {
+ @media (width >= 80rem) {
+ max-height: none;
+ }
+ }
+ .xl\:max-w-\[590px\] {
+ @media (width >= 80rem) {
+ max-width: 590px;
+ }
+ }
+}
+.ubuntu-regular {
+ font-family: "Ubuntu", serif;
+ font-weight: 400;
+ font-style: normal;
+}
+.ubuntu-mono-regular {
+ font-family: "Ubuntu Mono", serif;
+ font-weight: 400;
+ font-style: normal;
+}
+.sometype-mono-regular {
+ font-family: "Sometype Mono", serif;
+ font-optical-sizing: auto;
+ font-weight: 400;
+ font-style: normal;
+}
+body {
+ position: relative;
+ background-image: radial-gradient(circle at 1px 1px, #33333366 1px, transparent 0), linear-gradient(to right, #33333366 1px, transparent 1px), linear-gradient(to bottom, #33333366 1px, transparent 1px);
+ background-size: 20px 20px;
+ background-position: 0 0, 0 0, 0 0;
+ background-attachment: fixed;
+}
+@keyframes spin {
+ to {
+ transform: rotate(360deg);
+ }
+}
+@keyframes ping {
+ 75%, 100% {
+ transform: scale(2);
+ opacity: 0;
+ }
+}
+@keyframes pulse {
+ 50% {
+ opacity: 0.5;
+ }
+}
+@keyframes bounce {
+ 0%, 100% {
+ transform: translateY(-25%);
+ animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
+ }
+ 50% {
+ transform: none;
+ animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
+ }
+}
+@property --tw-scale-x {
+ syntax: "*";
+ inherits: false;
+ initial-value: 1;
+}
+@property --tw-scale-y {
+ syntax: "*";
+ inherits: false;
+ initial-value: 1;
+}
+@property --tw-scale-z {
+ syntax: "*";
+ inherits: false;
+ initial-value: 1;
+}
+@property --tw-border-style {
+ syntax: "*";
+ inherits: false;
+ initial-value: solid;
+}
+@property --tw-gradient-position {
+ syntax: "*";
+ inherits: false;
+}
+@property --tw-gradient-from {
+ syntax: "";
+ inherits: false;
+ initial-value: #0000;
+}
+@property --tw-gradient-via {
+ syntax: "";
+ inherits: false;
+ initial-value: #0000;
+}
+@property --tw-gradient-to {
+ syntax: "";
+ inherits: false;
+ initial-value: #0000;
+}
+@property --tw-gradient-stops {
+ syntax: "*";
+ inherits: false;
+}
+@property --tw-gradient-via-stops {
+ syntax: "*";
+ inherits: false;
+}
+@property --tw-gradient-from-position {
+ syntax: "";
+ inherits: false;
+ initial-value: 0%;
+}
+@property --tw-gradient-via-position {
+ syntax: "";
+ inherits: false;
+ initial-value: 50%;
+}
+@property --tw-gradient-to-position {
+ syntax: "";
+ inherits: false;
+ initial-value: 100%;
+}
+@property --tw-leading {
+ syntax: "*";
+ inherits: false;
+}
+@property --tw-tracking {
+ syntax: "*";
+ inherits: false;
+}
+@property --tw-duration {
+ syntax: "*";
+ inherits: false;
+}
+@property --tw-ease {
+ syntax: "*";
+ inherits: false;
+}
diff --git a/favicon/android-chrome-192x192.png b/src/static/favicon/android-chrome-192x192.png
similarity index 100%
rename from favicon/android-chrome-192x192.png
rename to src/static/favicon/android-chrome-192x192.png
diff --git a/favicon/android-chrome-512x512.png b/src/static/favicon/android-chrome-512x512.png
similarity index 100%
rename from favicon/android-chrome-512x512.png
rename to src/static/favicon/android-chrome-512x512.png
diff --git a/favicon/apple-touch-icon.png b/src/static/favicon/apple-touch-icon.png
similarity index 100%
rename from favicon/apple-touch-icon.png
rename to src/static/favicon/apple-touch-icon.png
diff --git a/favicon/favicon-16x16.png b/src/static/favicon/favicon-16x16.png
similarity index 100%
rename from favicon/favicon-16x16.png
rename to src/static/favicon/favicon-16x16.png
diff --git a/favicon/favicon-32x32.png b/src/static/favicon/favicon-32x32.png
similarity index 100%
rename from favicon/favicon-32x32.png
rename to src/static/favicon/favicon-32x32.png
diff --git a/favicon/favicon.ico b/src/static/favicon/favicon.ico
similarity index 100%
rename from favicon/favicon.ico
rename to src/static/favicon/favicon.ico
diff --git a/favicon/site.webmanifest b/src/static/favicon/site.webmanifest
similarity index 63%
rename from favicon/site.webmanifest
rename to src/static/favicon/site.webmanifest
index 7702ac5..bf28ef2 100644
--- a/favicon/site.webmanifest
+++ b/src/static/favicon/site.webmanifest
@@ -3,17 +3,17 @@
"short_name": "",
"icons": [
{
- "src": "/favicon/android-chrome-192x192.png",
+ "src": "/static/favicon/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
- "src": "/favicon/android-chrome-512x512.png",
+ "src": "/static/favicon/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#ffffff",
- "background_color": "#ffffff",
+ "background_color": "#000000",
"display": "standalone"
}
\ No newline at end of file
diff --git a/src/static/images/GitHub_Invertocat_Dark.png b/src/static/images/GitHub_Invertocat_Dark.png
new file mode 100644
index 0000000..10b895f
Binary files /dev/null and b/src/static/images/GitHub_Invertocat_Dark.png differ
diff --git a/src/static/images/Unsplash_Symbol.png b/src/static/images/Unsplash_Symbol.png
new file mode 100644
index 0000000..d9e8333
Binary files /dev/null and b/src/static/images/Unsplash_Symbol.png differ
diff --git a/src/static/images/avatar_48.jpg b/src/static/images/avatar_48.jpg
new file mode 100644
index 0000000..d4aeeb0
Binary files /dev/null and b/src/static/images/avatar_48.jpg differ
diff --git a/src/static/images/card-blur.png b/src/static/images/card-blur.png
new file mode 100644
index 0000000..bfac785
Binary files /dev/null and b/src/static/images/card-blur.png differ
diff --git a/src/static/images/card.png b/src/static/images/card.png
new file mode 100644
index 0000000..0d557ea
Binary files /dev/null and b/src/static/images/card.png differ
diff --git a/src/static/images/cards/immich.png b/src/static/images/cards/immich.png
new file mode 100644
index 0000000..636f061
Binary files /dev/null and b/src/static/images/cards/immich.png differ
diff --git a/src/static/images/cards/linkwarden.png b/src/static/images/cards/linkwarden.png
new file mode 100644
index 0000000..7fc2234
Binary files /dev/null and b/src/static/images/cards/linkwarden.png differ
diff --git a/src/static/images/cards/matrix.png b/src/static/images/cards/matrix.png
new file mode 100644
index 0000000..4e34362
Binary files /dev/null and b/src/static/images/cards/matrix.png differ
diff --git a/src/static/images/cards/nextcloud.png b/src/static/images/cards/nextcloud.png
new file mode 100644
index 0000000..c894a39
Binary files /dev/null and b/src/static/images/cards/nextcloud.png differ
diff --git a/src/static/images/cards/vaultwarden.png b/src/static/images/cards/vaultwarden.png
new file mode 100644
index 0000000..cb064b3
Binary files /dev/null and b/src/static/images/cards/vaultwarden.png differ
diff --git a/src/static/images/cards/xbb.png b/src/static/images/cards/xbb.png
new file mode 100644
index 0000000..c4d4236
Binary files /dev/null and b/src/static/images/cards/xbb.png differ
diff --git a/src/static/images/logos/immich.png b/src/static/images/logos/immich.png
new file mode 100644
index 0000000..2a33a68
Binary files /dev/null and b/src/static/images/logos/immich.png differ
diff --git a/src/static/images/logos/linkwarden.png b/src/static/images/logos/linkwarden.png
new file mode 100644
index 0000000..2790819
Binary files /dev/null and b/src/static/images/logos/linkwarden.png differ
diff --git a/src/static/images/logos/matrix.png b/src/static/images/logos/matrix.png
new file mode 100644
index 0000000..0fdb771
Binary files /dev/null and b/src/static/images/logos/matrix.png differ
diff --git a/src/static/images/logos/nextcloud.png b/src/static/images/logos/nextcloud.png
new file mode 100644
index 0000000..f3f043c
Binary files /dev/null and b/src/static/images/logos/nextcloud.png differ
diff --git a/src/static/images/logos/vaultwarden.png b/src/static/images/logos/vaultwarden.png
new file mode 100644
index 0000000..d44962b
Binary files /dev/null and b/src/static/images/logos/vaultwarden.png differ
diff --git a/src/static/images/logos/xbb.png b/src/static/images/logos/xbb.png
new file mode 100644
index 0000000..ac1ab21
Binary files /dev/null and b/src/static/images/logos/xbb.png differ
diff --git a/src/static/js/checkstatus.js b/src/static/js/checkstatus.js
new file mode 100644
index 0000000..18d8235
--- /dev/null
+++ b/src/static/js/checkstatus.js
@@ -0,0 +1,84 @@
+let statusIcon = null;
+let statusIconPing = null;
+let statusText = null;
+
+const serviceUp = {
+ color: "#05df72",
+ text: "All Services Operational",
+};
+const serviceDegraded = {
+ color: "#fcc800",
+ text: "Degraded Services",
+};
+const serviceDown = {
+ color: "#c10007",
+ text: "All Services Down",
+};
+const serviceUnknown = {
+ color: "#6a7282",
+ text: "Unknown",
+};
+
+async function getServicesHealth() {
+ try {
+ const serviceStatus = await fetch(
+ "https://status.wah.su/api/status-page/heartbeat/services"
+ );
+
+ const services = await serviceStatus.json();
+ const heartbeatDict = services.heartbeatList;
+ let lastHeartbeats = [];
+
+ for (const [key, value] of Object.entries(heartbeatDict)) {
+ lastHeartbeats.push(
+ heartbeatDict[key][heartbeatDict[key].length - 1].status
+ );
+ }
+ const count = lastHeartbeats.reduce((partialSum, a) => partialSum + a, 0);
+
+ switch (count) {
+ case lastHeartbeats.length: {
+ statusIcon.style.setProperty("--ping-color", serviceUp.color);
+ statusIconPing.classList.remove("invisible");
+ statusText.textContent = serviceUp.text;
+ break;
+ }
+ case 0: {
+ statusIcon.style.setProperty("--ping-color", serviceDown.color);
+ statusIconPing.classList.add("invisible");
+ statusText.textContent = serviceDown.text;
+ break;
+ }
+ default: {
+ statusIcon.style.setProperty("--ping-color", serviceDegraded.color);
+ statusIconPing.classList.remove("invisible");
+ statusText.textContent = serviceDegraded.text;
+ break;
+ }
+ }
+ } catch (error) {
+ statusIcon.style.setProperty("--ping-color", serviceUnknown.color);
+ statusIconPing.classList.add("invisible");
+ statusText.textContent = serviceUnknown.text;
+ console.log("Failed to fetch services status: " + error);
+ return;
+ }
+}
+
+window.onload = () => {
+ const footer = document.getElementById("footer");
+ const mobileFooter = document.getElementById("mobile-footer");
+
+ if (footer.checkVisibility() == true) {
+ statusIcon = footer.querySelector("#status-icon");
+ statusIconPing = footer.querySelector("#status-icon-ping");
+ statusText = footer.querySelector("#status-text");
+ } else {
+ statusIcon = mobileFooter.querySelector("#status-icon");
+ statusIconPing = mobileFooter.querySelector("#status-icon-ping");
+ statusText = mobileFooter.querySelector("#status-text");
+ }
+
+ getServicesHealth();
+ setInterval(getServicesHealth, 600000);
+};
diff --git a/src/static/og/opengraph.png b/src/static/og/opengraph.png
new file mode 100644
index 0000000..0ac297c
Binary files /dev/null and b/src/static/og/opengraph.png differ
diff --git a/src/static_dev/hotreload.js b/src/static_dev/hotreload.js
new file mode 100644
index 0000000..bccb7bc
--- /dev/null
+++ b/src/static_dev/hotreload.js
@@ -0,0 +1,11 @@
+let webSocket = new WebSocket(`ws://${window.location.hostname}:3001`);
+webSocket.onmessage = function (e) {
+ if (e.data == "RELOAD") {
+ console.log("Reloading page after build");
+ location.reload();
+ } else if (e.data == "CONNECTED") {
+ console.log("Connected to server");
+ } else {
+ console.warn(`unknown data received: ${e}`);
+ }
+};
diff --git a/src/tailwind.css b/src/tailwind.css
deleted file mode 100644
index 1ea91b4..0000000
--- a/src/tailwind.css
+++ /dev/null
@@ -1,27 +0,0 @@
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
-
-.ubuntu-mono-regular {
- font-family: "Ubuntu Mono", monospace;
- font-weight: 400;
- font-style: normal;
-}
-
-.ubuntu-mono-bold {
- font-family: "Ubuntu Mono", monospace;
- font-weight: 700;
- font-style: normal;
-}
-
-.ubuntu-mono-regular-italic {
- font-family: "Ubuntu Mono", monospace;
- font-weight: 400;
- font-style: italic;
-}
-
-.ubuntu-mono-bold-italic {
- font-family: "Ubuntu Mono", monospace;
- font-weight: 700;
- font-style: italic;
-}
\ No newline at end of file
diff --git a/src/templates/Base.tsx b/src/templates/Base.tsx
new file mode 100644
index 0000000..72b94f6
--- /dev/null
+++ b/src/templates/Base.tsx
@@ -0,0 +1,59 @@
+import React from "react";
+
+interface BaseProps {
+ children: React.ReactNode;
+ isDev?: boolean;
+}
+
+export default function Base({ children, isDev }: BaseProps) {
+ return (
+ <>
+
+
+
+
+ WAH.su
+ {isDev ? : ""}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {children}
+
+
+ >
+ );
+}
diff --git a/src/templates/Bento.tsx b/src/templates/Bento.tsx
new file mode 100644
index 0000000..e3aeda7
--- /dev/null
+++ b/src/templates/Bento.tsx
@@ -0,0 +1,67 @@
+import BentoCard from "./BentoCards/BentoCard";
+import Footer from "./Footer";
+
+export default function Bento() {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/templates/BentoCards/BentoCard.tsx b/src/templates/BentoCards/BentoCard.tsx
new file mode 100644
index 0000000..5192854
--- /dev/null
+++ b/src/templates/BentoCards/BentoCard.tsx
@@ -0,0 +1,31 @@
+import BentoCardSmall from "./Small";
+import BentoCardNormal from "./Normal";
+import BentoCardBig from "./Big";
+import BentoCardLarge from "./Large";
+
+export interface BentoCardProps {
+ type?: "small" | "normal" | "big" | "large";
+ color: string;
+ image?: string;
+ logo: string;
+ title: string;
+ description?: string;
+ className?: string;
+ link?: string;
+}
+
+export default function BentoCard(props: BentoCardProps) {
+ if (!props.type || props.type == "normal") {
+ return ;
+ }
+ if (props.type == "small") {
+ return ;
+ }
+ if (props.type == "big") {
+ return ;
+ }
+ if (props.type == "large") {
+ return ;
+ }
+ return NOTHING
;
+}
diff --git a/src/templates/BentoCards/Big.tsx b/src/templates/BentoCards/Big.tsx
new file mode 100644
index 0000000..9890f62
--- /dev/null
+++ b/src/templates/BentoCards/Big.tsx
@@ -0,0 +1,77 @@
+import type { BentoCardProps } from "./BentoCard";
+
+export default function BentoCardBig({
+ color,
+ image,
+ logo,
+ title,
+ description,
+ className,
+ link,
+}: BentoCardProps) {
+ if (link) {
+ return (
+
+ {image ? (
+ <>
+
+
+ >
+ ) : (
+ ""
+ )}
+
+
+
+
{title}
+
+
+
+ {description}
+
+
+ );
+ }
+ return (
+
+ {image ? (
+ <>
+
+
+ >
+ ) : (
+ ""
+ )}
+
+
+
+
{title}
+
+
+
+ {description}
+
+
+ );
+}
diff --git a/src/templates/BentoCards/Large.tsx b/src/templates/BentoCards/Large.tsx
new file mode 100644
index 0000000..6f09dca
--- /dev/null
+++ b/src/templates/BentoCards/Large.tsx
@@ -0,0 +1,77 @@
+import type { BentoCardProps } from "./BentoCard";
+
+export default function BentoCardLarge({
+ color,
+ image,
+ logo,
+ title,
+ description,
+ className,
+ link,
+}: BentoCardProps) {
+ if (link) {
+ return (
+
+ {image ? (
+ <>
+
+
+ >
+ ) : (
+ ""
+ )}
+
+
+
+
{title}
+
+
+
+ {description}
+
+
+ );
+ }
+ return (
+
+ {image ? (
+ <>
+
+
+ >
+ ) : (
+ ""
+ )}
+
+
+
+
{title}
+
+
+
+ {description}
+
+
+ );
+}
diff --git a/src/templates/BentoCards/Normal.tsx b/src/templates/BentoCards/Normal.tsx
new file mode 100644
index 0000000..150bea1
--- /dev/null
+++ b/src/templates/BentoCards/Normal.tsx
@@ -0,0 +1,77 @@
+import type { BentoCardProps } from "./BentoCard";
+
+export default function BentoCardNormal({
+ color,
+ image,
+ logo,
+ title,
+ description,
+ className,
+ link,
+}: BentoCardProps) {
+ if (link) {
+ return (
+
+ {image ? (
+ <>
+
+
+ >
+ ) : (
+ ""
+ )}
+
+
+
+
+
{title}
+
+
+
{description}
+
+
+ );
+ }
+ return (
+
+ {image ? (
+ <>
+
+
+ >
+ ) : (
+ ""
+ )}
+
+
+
+
+
{title}
+
+
+
{description}
+
+
+ );
+}
diff --git a/src/templates/BentoCards/Small.tsx b/src/templates/BentoCards/Small.tsx
new file mode 100644
index 0000000..39f5974
--- /dev/null
+++ b/src/templates/BentoCards/Small.tsx
@@ -0,0 +1,31 @@
+import type { BentoCardProps } from "./BentoCard";
+
+export default function BentoCardSmall({
+ color,
+ logo,
+ title,
+ className,
+ link
+}: BentoCardProps) {
+ if (link) {
+ return (
+
+
+ {title}
+
+ );
+ }
+ return (
+
+
+
{title}
+
+ );
+}
diff --git a/src/templates/Footer.tsx b/src/templates/Footer.tsx
new file mode 100644
index 0000000..79b1c08
--- /dev/null
+++ b/src/templates/Footer.tsx
@@ -0,0 +1,86 @@
+interface FooterProps {
+ className?: string;
+ id: string;
+}
+
+export default function Footer({ className, id }: FooterProps) {
+ return (
+
+ );
+}
diff --git a/src/templates/NotBento.tsx b/src/templates/NotBento.tsx
new file mode 100644
index 0000000..c13ef54
--- /dev/null
+++ b/src/templates/NotBento.tsx
@@ -0,0 +1,60 @@
+import BentoCard from "./BentoCards/BentoCard";
+import Footer from "./Footer";
+
+export default function NotBento() {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/templates/Title.tsx b/src/templates/Title.tsx
new file mode 100644
index 0000000..4f3f3de
--- /dev/null
+++ b/src/templates/Title.tsx
@@ -0,0 +1,29 @@
+export default function Title() {
+ return (
+
+
+
+ WAH.su(d0)
+
+
+ A tech non-company with a whole lot of wah—100% tech, 200% wah!
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/utils.ts b/src/utils.ts
new file mode 100644
index 0000000..18c8f81
--- /dev/null
+++ b/src/utils.ts
@@ -0,0 +1,75 @@
+import { red, yellow } from "picocolors";
+
+export class Log {
+ _level = 1;
+ _levelText = "INFO";
+
+ constructor(level: "DEBUG" | "INFO" | "WARN" | "ERROR" = "INFO") {
+ let _level = 1;
+ switch (level) {
+ case "DEBUG":
+ _level = 0;
+ break;
+ case "INFO":
+ _level = 1;
+ break;
+ case "WARN":
+ _level = 2;
+ break;
+ case "ERROR":
+ _level = 3;
+ break;
+ }
+ this._level = _level;
+ this._levelText = level;
+ }
+
+ _time() {
+ const date = new Date();
+ return date.toLocaleTimeString();
+ }
+
+ _fmt(time: string, level: string, message: string) {
+ return `${time}:${level} - ${message}`;
+ }
+
+ debug(message: string | any, isConnected = false) {
+ if (this._level == 0) {
+ if (isConnected) {
+ message = `↳ ${message}`;
+ }
+ console.log(this._fmt(this._time(), "DEBUG", message));
+ return this._fmt(this._time(), "DEBUG", message);
+ }
+ }
+
+ info(message: string | any, isConnected = false) {
+ if (this._level <= 1) {
+ if (isConnected) {
+ message = `↳ ${message}`;
+ }
+ console.log(this._fmt(this._time(), "INFO", message));
+ return this._fmt(this._time(), "INFO", message);
+ }
+ }
+
+ warn(message: string | any, isConnected = false) {
+ if (this._level <= 2) {
+ if (isConnected) {
+ message = `↳ ${message}`;
+ }
+ console.log(yellow(this._fmt(this._time(), "WARN", message)));
+ return this._fmt(this._time(), "WARN", message);
+ }
+ }
+
+ error(message: string | any, isConnected = false) {
+ if (this._level <= 3) {
+ if (isConnected) {
+ message = `↳ ${message}`;
+ }
+ console.log(red(this._fmt(this._time(), "ERROR", message)));
+ return this._fmt(this._time(), "ERROR", message);
+ }
+ }
+}
diff --git a/src/watch.ts b/src/watch.ts
new file mode 100644
index 0000000..57b15ee
--- /dev/null
+++ b/src/watch.ts
@@ -0,0 +1,96 @@
+import WebSocket from "ws";
+import fs from "fs";
+import chokidar from "chokidar";
+import exec from "child_process";
+import express from "express";
+import { Log } from "./utils";
+import path from "path";
+import { WebSocketServer } from "ws";
+
+let triggered = 0;
+const delay = 1000;
+
+let WSclients: any[] = [];
+
+const log = new Log();
+
+function onChange() {
+ if (triggered != 0 && Date.now() - triggered < delay) {
+ log.warn(`Rebuild was triggered less than a ${delay}ms ago!`, true);
+ return;
+ }
+ triggered = Date.now();
+
+ exec.exec("bun run ./src/build.tsx", (error, stdout, stderr) => {
+ if (error) {
+ log.error(error.message);
+ return;
+ }
+ if (stderr) {
+ log.error(stderr);
+ return;
+ }
+ log.info(stdout);
+ if (WSclients.length > 0) {
+ log.info("Reloading web page...");
+ WSclients.forEach((ws) => ws.send("RELOAD"));
+ }
+ });
+}
+
+function onExit() {
+ fs.rmdirSync(path.join(__dirname, "../out"), { recursive: true });
+ log.info("Deleted 'out' folder");
+ process.exit(0);
+}
+
+const watcher = chokidar.watch(["./src", "./static"], {
+ ignored: (filePath, stats) => filePath.endsWith("watch.ts"),
+ atomic: true,
+ awaitWriteFinish: true,
+ persistent: true,
+});
+
+function startServerWithRebuild() {
+ const app = express();
+ const folder = path.join(__dirname, "../out");
+ const wss = new WebSocketServer({ port: 3001 });
+
+ process.env.ENVIRONMENT = "dev";
+
+ wss.on("connection", (ws: WebSocket) => {
+ WSclients.push(ws);
+ log.info(`Client ${WSclients.length} connected`);
+ ws.send("CONNECTED");
+ });
+
+ process.on("SIGINT", () => {
+ log.info("Gracefully shutdown and cleanup...");
+ onExit();
+ });
+
+ app.use(express.static(folder));
+ app.listen(3000, () => {
+ log.info(`Serving files from folder ${folder}`);
+ log.info("Express server is running on port 3000: http://127.0.0.1:3000");
+
+ watcher
+ .on("add", (path) => {
+ log.info(`File ${path} has been added, rebuilding...`);
+ onChange();
+ })
+ .on("change", (path) => {
+ log.info(`File ${path} has been changed, rebuilding...`);
+ onChange();
+ })
+ .on("unlink", (path) => {
+ log.info(`File ${path} has been removed, rebuilding...`);
+ onChange();
+ });
+ });
+ app.on("close", () => {
+ log.info("Server closed");
+ });
+}
+
+startServerWithRebuild();
diff --git a/static/js/checkstatus.js b/static/js/checkstatus.js
deleted file mode 100644
index 796e3a9..0000000
--- a/static/js/checkstatus.js
+++ /dev/null
@@ -1,84 +0,0 @@
-const statusIcon = document.getElementById("status-icon");
-const statusText = document.getElementById("status-text");
-
-const serviceUp = {
- color: ["bg-green-500", "dark:bg-green-400"],
- text: "All Services Operational",
-};
-const serviceDegraded = {
- color: ["bg-yellow-400", "dark:bg-yellow-200"],
- text: "Degraded Services",
-};
-const serviceDown = {
- color: ["bg-red-600", "dark:bg-red-500"],
- text: "All Services Down",
-};
-const serviceUnknown = {
- color: ["bg-gray-500", "dark:bg-gray-400"],
- text: "Unknown or Failed to fetch",
-};
-
-async function getServicesHealth() {
- try {
- const serviceStatus = await fetch(
- "https://status.wah.su/api/status-page/heartbeat/services"
- );
-
- const services = await serviceStatus.json();
- const heartbeatDict = services.heartbeatList;
- let lastHeartbeats = [];
-
- for (const [key, value] of Object.entries(heartbeatDict)) {
- lastHeartbeats.push(
- heartbeatDict[key][heartbeatDict[key].length - 1].status
- );
- }
- const count = lastHeartbeats.reduce((partialSum, a) => partialSum + a, 0);
-
- switch (count) {
- case lastHeartbeats.length: {
- statusIcon.classList.add(...serviceUp.color);
- statusIcon.classList.remove(
- ...serviceDegraded.color,
- ...serviceDown.color,
- ...serviceUnknown.color
- );
- statusText.textContent = serviceUp.text;
- break;
- }
- case 0: {
- statusIcon.classList.add(...serviceDown.color);
- statusIcon.classList.remove(
- ...serviceUp.color,
- ...serviceDegraded.color,
- ...serviceUnknown.color
- );
- statusText.textContent = serviceDown.text;
- break;
- }
- default: {
- statusIcon.classList.add(...serviceDegraded.color);
- statusIcon.classList.remove(
- ...serviceUp.color,
- ...serviceDown.color,
- ...serviceUnknown.color
- );
- statusText.textContent = serviceDegraded.text;
- break;
- }
- }
- } catch (error) {
- statusIcon.classList.add(...serviceUnknown.color);
- statusIcon.classList.remove(
- ...serviceUp.color,
- ...serviceDegraded.color,
- ...serviceDown.color
- );
- statusText.textContent = serviceUnknown.text;
- console.log("Failed to fetch services status: " + error);
- return;
- }
-}
-
-getServicesHealth();
-setInterval(getServicesHealth, 600000);
diff --git a/static/logo.svg b/static/logo.svg
deleted file mode 100644
index 0c927dc..0000000
--- a/static/logo.svg
+++ /dev/null
@@ -1,52 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/static/logos/element.svg b/static/logos/element.svg
deleted file mode 100644
index 54a91b7..0000000
--- a/static/logos/element.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/static/logos/immich.png b/static/logos/immich.png
deleted file mode 100644
index 35a6152..0000000
Binary files a/static/logos/immich.png and /dev/null differ
diff --git a/static/logos/navidrome.png b/static/logos/navidrome.png
deleted file mode 100644
index 417a813..0000000
Binary files a/static/logos/navidrome.png and /dev/null differ
diff --git a/static/logos/nextcloud.png b/static/logos/nextcloud.png
deleted file mode 100644
index 5b06c90..0000000
Binary files a/static/logos/nextcloud.png and /dev/null differ
diff --git a/static/logos/vaultwarden.png b/static/logos/vaultwarden.png
deleted file mode 100644
index 19164ae..0000000
Binary files a/static/logos/vaultwarden.png and /dev/null differ
diff --git a/static/logos/zipline.png b/static/logos/zipline.png
deleted file mode 100644
index c52ca4f..0000000
Binary files a/static/logos/zipline.png and /dev/null differ
diff --git a/static/og/index.png b/static/og/index.png
deleted file mode 100644
index c80fa32..0000000
Binary files a/static/og/index.png and /dev/null differ
diff --git a/static/og/privacy.png b/static/og/privacy.png
deleted file mode 100644
index 34ea08a..0000000
Binary files a/static/og/privacy.png and /dev/null differ
diff --git a/static/og/services.png b/static/og/services.png
deleted file mode 100644
index 799f633..0000000
Binary files a/static/og/services.png and /dev/null differ
diff --git a/static/tailwind.css b/static/tailwind.css
deleted file mode 100644
index 04d9b70..0000000
--- a/static/tailwind.css
+++ /dev/null
@@ -1,980 +0,0 @@
-*, ::before, ::after {
- --tw-border-spacing-x: 0;
- --tw-border-spacing-y: 0;
- --tw-translate-x: 0;
- --tw-translate-y: 0;
- --tw-rotate: 0;
- --tw-skew-x: 0;
- --tw-skew-y: 0;
- --tw-scale-x: 1;
- --tw-scale-y: 1;
- --tw-pan-x: ;
- --tw-pan-y: ;
- --tw-pinch-zoom: ;
- --tw-scroll-snap-strictness: proximity;
- --tw-gradient-from-position: ;
- --tw-gradient-via-position: ;
- --tw-gradient-to-position: ;
- --tw-ordinal: ;
- --tw-slashed-zero: ;
- --tw-numeric-figure: ;
- --tw-numeric-spacing: ;
- --tw-numeric-fraction: ;
- --tw-ring-inset: ;
- --tw-ring-offset-width: 0px;
- --tw-ring-offset-color: #fff;
- --tw-ring-color: rgb(59 130 246 / 0.5);
- --tw-ring-offset-shadow: 0 0 #0000;
- --tw-ring-shadow: 0 0 #0000;
- --tw-shadow: 0 0 #0000;
- --tw-shadow-colored: 0 0 #0000;
- --tw-blur: ;
- --tw-brightness: ;
- --tw-contrast: ;
- --tw-grayscale: ;
- --tw-hue-rotate: ;
- --tw-invert: ;
- --tw-saturate: ;
- --tw-sepia: ;
- --tw-drop-shadow: ;
- --tw-backdrop-blur: ;
- --tw-backdrop-brightness: ;
- --tw-backdrop-contrast: ;
- --tw-backdrop-grayscale: ;
- --tw-backdrop-hue-rotate: ;
- --tw-backdrop-invert: ;
- --tw-backdrop-opacity: ;
- --tw-backdrop-saturate: ;
- --tw-backdrop-sepia: ;
- --tw-contain-size: ;
- --tw-contain-layout: ;
- --tw-contain-paint: ;
- --tw-contain-style: ;
-}
-
-::backdrop {
- --tw-border-spacing-x: 0;
- --tw-border-spacing-y: 0;
- --tw-translate-x: 0;
- --tw-translate-y: 0;
- --tw-rotate: 0;
- --tw-skew-x: 0;
- --tw-skew-y: 0;
- --tw-scale-x: 1;
- --tw-scale-y: 1;
- --tw-pan-x: ;
- --tw-pan-y: ;
- --tw-pinch-zoom: ;
- --tw-scroll-snap-strictness: proximity;
- --tw-gradient-from-position: ;
- --tw-gradient-via-position: ;
- --tw-gradient-to-position: ;
- --tw-ordinal: ;
- --tw-slashed-zero: ;
- --tw-numeric-figure: ;
- --tw-numeric-spacing: ;
- --tw-numeric-fraction: ;
- --tw-ring-inset: ;
- --tw-ring-offset-width: 0px;
- --tw-ring-offset-color: #fff;
- --tw-ring-color: rgb(59 130 246 / 0.5);
- --tw-ring-offset-shadow: 0 0 #0000;
- --tw-ring-shadow: 0 0 #0000;
- --tw-shadow: 0 0 #0000;
- --tw-shadow-colored: 0 0 #0000;
- --tw-blur: ;
- --tw-brightness: ;
- --tw-contrast: ;
- --tw-grayscale: ;
- --tw-hue-rotate: ;
- --tw-invert: ;
- --tw-saturate: ;
- --tw-sepia: ;
- --tw-drop-shadow: ;
- --tw-backdrop-blur: ;
- --tw-backdrop-brightness: ;
- --tw-backdrop-contrast: ;
- --tw-backdrop-grayscale: ;
- --tw-backdrop-hue-rotate: ;
- --tw-backdrop-invert: ;
- --tw-backdrop-opacity: ;
- --tw-backdrop-saturate: ;
- --tw-backdrop-sepia: ;
- --tw-contain-size: ;
- --tw-contain-layout: ;
- --tw-contain-paint: ;
- --tw-contain-style: ;
-}
-
-/*
-! tailwindcss v3.4.15 | MIT License | https://tailwindcss.com
-*/
-
-/*
-1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
-2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
-*/
-
-*,
-::before,
-::after {
- box-sizing: border-box;
- /* 1 */
- border-width: 0;
- /* 2 */
- border-style: solid;
- /* 2 */
- border-color: #e5e7eb;
- /* 2 */
-}
-
-::before,
-::after {
- --tw-content: '';
-}
-
-/*
-1. Use a consistent sensible line-height in all browsers.
-2. Prevent adjustments of font size after orientation changes in iOS.
-3. Use a more readable tab size.
-4. Use the user's configured `sans` font-family by default.
-5. Use the user's configured `sans` font-feature-settings by default.
-6. Use the user's configured `sans` font-variation-settings by default.
-7. Disable tap highlights on iOS
-*/
-
-html,
-:host {
- line-height: 1.5;
- /* 1 */
- -webkit-text-size-adjust: 100%;
- /* 2 */
- -moz-tab-size: 4;
- /* 3 */
- -o-tab-size: 4;
- tab-size: 4;
- /* 3 */
- font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
- /* 4 */
- font-feature-settings: normal;
- /* 5 */
- font-variation-settings: normal;
- /* 6 */
- -webkit-tap-highlight-color: transparent;
- /* 7 */
-}
-
-/*
-1. Remove the margin in all browsers.
-2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
-*/
-
-body {
- margin: 0;
- /* 1 */
- line-height: inherit;
- /* 2 */
-}
-
-/*
-1. Add the correct height in Firefox.
-2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
-3. Ensure horizontal rules are visible by default.
-*/
-
-hr {
- height: 0;
- /* 1 */
- color: inherit;
- /* 2 */
- border-top-width: 1px;
- /* 3 */
-}
-
-/*
-Add the correct text decoration in Chrome, Edge, and Safari.
-*/
-
-abbr:where([title]) {
- -webkit-text-decoration: underline dotted;
- text-decoration: underline dotted;
-}
-
-/*
-Remove the default font size and weight for headings.
-*/
-
-h1,
-h2,
-h3,
-h4,
-h5,
-h6 {
- font-size: inherit;
- font-weight: inherit;
-}
-
-/*
-Reset links to optimize for opt-in styling instead of opt-out.
-*/
-
-a {
- color: inherit;
- text-decoration: inherit;
-}
-
-/*
-Add the correct font weight in Edge and Safari.
-*/
-
-b,
-strong {
- font-weight: bolder;
-}
-
-/*
-1. Use the user's configured `mono` font-family by default.
-2. Use the user's configured `mono` font-feature-settings by default.
-3. Use the user's configured `mono` font-variation-settings by default.
-4. Correct the odd `em` font sizing in all browsers.
-*/
-
-code,
-kbd,
-samp,
-pre {
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
- /* 1 */
- font-feature-settings: normal;
- /* 2 */
- font-variation-settings: normal;
- /* 3 */
- font-size: 1em;
- /* 4 */
-}
-
-/*
-Add the correct font size in all browsers.
-*/
-
-small {
- font-size: 80%;
-}
-
-/*
-Prevent `sub` and `sup` elements from affecting the line height in all browsers.
-*/
-
-sub,
-sup {
- font-size: 75%;
- line-height: 0;
- position: relative;
- vertical-align: baseline;
-}
-
-sub {
- bottom: -0.25em;
-}
-
-sup {
- top: -0.5em;
-}
-
-/*
-1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
-2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
-3. Remove gaps between table borders by default.
-*/
-
-table {
- text-indent: 0;
- /* 1 */
- border-color: inherit;
- /* 2 */
- border-collapse: collapse;
- /* 3 */
-}
-
-/*
-1. Change the font styles in all browsers.
-2. Remove the margin in Firefox and Safari.
-3. Remove default padding in all browsers.
-*/
-
-button,
-input,
-optgroup,
-select,
-textarea {
- font-family: inherit;
- /* 1 */
- font-feature-settings: inherit;
- /* 1 */
- font-variation-settings: inherit;
- /* 1 */
- font-size: 100%;
- /* 1 */
- font-weight: inherit;
- /* 1 */
- line-height: inherit;
- /* 1 */
- letter-spacing: inherit;
- /* 1 */
- color: inherit;
- /* 1 */
- margin: 0;
- /* 2 */
- padding: 0;
- /* 3 */
-}
-
-/*
-Remove the inheritance of text transform in Edge and Firefox.
-*/
-
-button,
-select {
- text-transform: none;
-}
-
-/*
-1. Correct the inability to style clickable types in iOS and Safari.
-2. Remove default button styles.
-*/
-
-button,
-input:where([type='button']),
-input:where([type='reset']),
-input:where([type='submit']) {
- -webkit-appearance: button;
- /* 1 */
- background-color: transparent;
- /* 2 */
- background-image: none;
- /* 2 */
-}
-
-/*
-Use the modern Firefox focus style for all focusable elements.
-*/
-
-:-moz-focusring {
- outline: auto;
-}
-
-/*
-Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
-*/
-
-:-moz-ui-invalid {
- box-shadow: none;
-}
-
-/*
-Add the correct vertical alignment in Chrome and Firefox.
-*/
-
-progress {
- vertical-align: baseline;
-}
-
-/*
-Correct the cursor style of increment and decrement buttons in Safari.
-*/
-
-::-webkit-inner-spin-button,
-::-webkit-outer-spin-button {
- height: auto;
-}
-
-/*
-1. Correct the odd appearance in Chrome and Safari.
-2. Correct the outline style in Safari.
-*/
-
-[type='search'] {
- -webkit-appearance: textfield;
- /* 1 */
- outline-offset: -2px;
- /* 2 */
-}
-
-/*
-Remove the inner padding in Chrome and Safari on macOS.
-*/
-
-::-webkit-search-decoration {
- -webkit-appearance: none;
-}
-
-/*
-1. Correct the inability to style clickable types in iOS and Safari.
-2. Change font properties to `inherit` in Safari.
-*/
-
-::-webkit-file-upload-button {
- -webkit-appearance: button;
- /* 1 */
- font: inherit;
- /* 2 */
-}
-
-/*
-Add the correct display in Chrome and Safari.
-*/
-
-summary {
- display: list-item;
-}
-
-/*
-Removes the default spacing and border for appropriate elements.
-*/
-
-blockquote,
-dl,
-dd,
-h1,
-h2,
-h3,
-h4,
-h5,
-h6,
-hr,
-figure,
-p,
-pre {
- margin: 0;
-}
-
-fieldset {
- margin: 0;
- padding: 0;
-}
-
-legend {
- padding: 0;
-}
-
-ol,
-ul,
-menu {
- list-style: none;
- margin: 0;
- padding: 0;
-}
-
-/*
-Reset default styling for dialogs.
-*/
-
-dialog {
- padding: 0;
-}
-
-/*
-Prevent resizing textareas horizontally by default.
-*/
-
-textarea {
- resize: vertical;
-}
-
-/*
-1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
-2. Set the default placeholder color to the user's configured gray 400 color.
-*/
-
-input::-moz-placeholder, textarea::-moz-placeholder {
- opacity: 1;
- /* 1 */
- color: #9ca3af;
- /* 2 */
-}
-
-input::placeholder,
-textarea::placeholder {
- opacity: 1;
- /* 1 */
- color: #9ca3af;
- /* 2 */
-}
-
-/*
-Set the default cursor for buttons.
-*/
-
-button,
-[role="button"] {
- cursor: pointer;
-}
-
-/*
-Make sure disabled buttons don't get the pointer cursor.
-*/
-
-:disabled {
- cursor: default;
-}
-
-/*
-1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
-2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
- This can trigger a poorly considered lint error in some tools but is included by design.
-*/
-
-img,
-svg,
-video,
-canvas,
-audio,
-iframe,
-embed,
-object {
- display: block;
- /* 1 */
- vertical-align: middle;
- /* 2 */
-}
-
-/*
-Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
-*/
-
-img,
-video {
- max-width: 100%;
- height: auto;
-}
-
-/* Make elements with the HTML hidden attribute stay hidden by default */
-
-[hidden]:where(:not([hidden="until-found"])) {
- display: none;
-}
-
-.container {
- width: 100%;
- margin-right: auto;
- margin-left: auto;
-}
-
-@media (min-width: 640px) {
- .container {
- max-width: 640px;
- }
-}
-
-@media (min-width: 768px) {
- .container {
- max-width: 768px;
- }
-}
-
-@media (min-width: 1024px) {
- .container {
- max-width: 1024px;
- }
-}
-
-@media (min-width: 1280px) {
- .container {
- max-width: 1280px;
- }
-}
-
-@media (min-width: 1536px) {
- .container {
- max-width: 1536px;
- }
-}
-
-.absolute {
- position: absolute;
-}
-
-.inset-0 {
- inset: 0px;
-}
-
-.-z-10 {
- z-index: -10;
-}
-
-.mx-auto {
- margin-left: auto;
- margin-right: auto;
-}
-
-.mb-4 {
- margin-bottom: 1rem;
-}
-
-.mb-2 {
- margin-bottom: 0.5rem;
-}
-
-.mb-8 {
- margin-bottom: 2rem;
-}
-
-.block {
- display: block;
-}
-
-.flex {
- display: flex;
-}
-
-.aspect-square {
- aspect-ratio: 1 / 1;
-}
-
-.h-6 {
- height: 1.5rem;
-}
-
-.h-\[100dvh\] {
- height: 100dvh;
-}
-
-.h-auto {
- height: auto;
-}
-
-.h-full {
- height: 100%;
-}
-
-.h-16 {
- height: 4rem;
-}
-
-.w-6 {
- width: 1.5rem;
-}
-
-.w-96 {
- width: 24rem;
-}
-
-.w-full {
- width: 100%;
-}
-
-.w-16 {
- width: 4rem;
-}
-
-.max-w-screen-xl {
- max-width: 1280px;
-}
-
-.max-w-96 {
- max-width: 24rem;
-}
-
-.list-inside {
- list-style-position: inside;
-}
-
-.list-disc {
- list-style-type: disc;
-}
-
-.flex-row {
- flex-direction: row;
-}
-
-.flex-col {
- flex-direction: column;
-}
-
-.flex-col-reverse {
- flex-direction: column-reverse;
-}
-
-.flex-wrap {
- flex-wrap: wrap;
-}
-
-.items-center {
- align-items: center;
-}
-
-.justify-center {
- justify-content: center;
-}
-
-.justify-between {
- justify-content: space-between;
-}
-
-.gap-16 {
- gap: 4rem;
-}
-
-.gap-4 {
- gap: 1rem;
-}
-
-.gap-8 {
- gap: 2rem;
-}
-
-.gap-0 {
- gap: 0px;
-}
-
-.rounded-full {
- border-radius: 9999px;
-}
-
-.bg-\[\#120D0C\] {
- --tw-bg-opacity: 1;
- background-color: rgb(18 13 12 / var(--tw-bg-opacity, 1));
-}
-
-.bg-gray-500 {
- --tw-bg-opacity: 1;
- background-color: rgb(107 114 128 / var(--tw-bg-opacity, 1));
-}
-
-.bg-green-500 {
- --tw-bg-opacity: 1;
- background-color: rgb(34 197 94 / var(--tw-bg-opacity, 1));
-}
-
-.bg-red-600 {
- --tw-bg-opacity: 1;
- background-color: rgb(220 38 38 / var(--tw-bg-opacity, 1));
-}
-
-.bg-yellow-400 {
- --tw-bg-opacity: 1;
- background-color: rgb(250 204 21 / var(--tw-bg-opacity, 1));
-}
-
-.object-cover {
- -o-object-fit: cover;
- object-fit: cover;
-}
-
-.p-8 {
- padding: 2rem;
-}
-
-.p-4 {
- padding: 1rem;
-}
-
-.py-2 {
- padding-top: 0.5rem;
- padding-bottom: 0.5rem;
-}
-
-.py-1 {
- padding-top: 0.25rem;
- padding-bottom: 0.25rem;
-}
-
-.pb-8 {
- padding-bottom: 2rem;
-}
-
-.text-2xl {
- font-size: 1.5rem;
- line-height: 2rem;
-}
-
-.text-4xl {
- font-size: 2.25rem;
- line-height: 2.5rem;
-}
-
-.text-lg {
- font-size: 1.125rem;
- line-height: 1.75rem;
-}
-
-.text-xl {
- font-size: 1.25rem;
- line-height: 1.75rem;
-}
-
-.text-8xl {
- font-size: 6rem;
- line-height: 1;
-}
-
-.text-3xl {
- font-size: 1.875rem;
- line-height: 2.25rem;
-}
-
-.font-bold {
- font-weight: 700;
-}
-
-.font-medium {
- font-weight: 500;
-}
-
-.text-white {
- --tw-text-opacity: 1;
- color: rgb(255 255 255 / var(--tw-text-opacity, 1));
-}
-
-.text-blue-600 {
- --tw-text-opacity: 1;
- color: rgb(37 99 235 / var(--tw-text-opacity, 1));
-}
-
-.underline {
- text-decoration-line: underline;
-}
-
-.blur-sm {
- --tw-blur: blur(4px);
- filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
-}
-
-.transition {
- transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter;
- transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
- transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter;
- transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
- transition-duration: 150ms;
-}
-
-.transition-colors {
- transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
- transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
- transition-duration: 150ms;
-}
-
-.ease-in {
- transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
-}
-
-.ubuntu-mono-regular {
- font-family: "Ubuntu Mono", monospace;
- font-weight: 400;
- font-style: normal;
-}
-
-.ubuntu-mono-bold {
- font-family: "Ubuntu Mono", monospace;
- font-weight: 700;
- font-style: normal;
-}
-
-.ubuntu-mono-regular-italic {
- font-family: "Ubuntu Mono", monospace;
- font-weight: 400;
- font-style: italic;
-}
-
-.ubuntu-mono-bold-italic {
- font-family: "Ubuntu Mono", monospace;
- font-weight: 700;
- font-style: italic;
-}
-
-.hover\:text-\[\#ff851b\]:hover {
- --tw-text-opacity: 1;
- color: rgb(255 133 27 / var(--tw-text-opacity, 1));
-}
-
-.hover\:underline:hover {
- text-decoration-line: underline;
-}
-
-@media (min-width: 640px) {
- .sm\:h-8 {
- height: 2rem;
- }
-
- .sm\:w-8 {
- width: 2rem;
- }
-
- .sm\:flex-row {
- flex-direction: row;
- }
-
- .sm\:items-center {
- align-items: center;
- }
-
- .sm\:text-2xl {
- font-size: 1.5rem;
- line-height: 2rem;
- }
-
- .sm\:text-3xl {
- font-size: 1.875rem;
- line-height: 2.25rem;
- }
-
- .sm\:text-6xl {
- font-size: 3.75rem;
- line-height: 1;
- }
-}
-
-@media (min-width: 768px) {
- .md\:p-16 {
- padding: 4rem;
- }
-}
-
-@media (min-width: 1024px) {
- .lg\:flex-row {
- flex-direction: row;
- }
-
- .lg\:items-end {
- align-items: flex-end;
- }
-
- .lg\:items-center {
- align-items: center;
- }
-
- .lg\:justify-between {
- justify-content: space-between;
- }
-
- .lg\:text-right {
- text-align: right;
- }
-}
-
-@media (prefers-color-scheme: dark) {
- .dark\:bg-gray-400 {
- --tw-bg-opacity: 1;
- background-color: rgb(156 163 175 / var(--tw-bg-opacity, 1));
- }
-
- .dark\:bg-green-400 {
- --tw-bg-opacity: 1;
- background-color: rgb(74 222 128 / var(--tw-bg-opacity, 1));
- }
-
- .dark\:bg-red-500 {
- --tw-bg-opacity: 1;
- background-color: rgb(239 68 68 / var(--tw-bg-opacity, 1));
- }
-
- .dark\:bg-yellow-200 {
- --tw-bg-opacity: 1;
- background-color: rgb(254 240 138 / var(--tw-bg-opacity, 1));
- }
-
- .dark\:text-blue-500 {
- --tw-text-opacity: 1;
- color: rgb(59 130 246 / var(--tw-text-opacity, 1));
- }
-}
\ No newline at end of file
diff --git a/static/will-rust-Vv1E0zcQDCI-unsplash.jpg b/static/will-rust-Vv1E0zcQDCI-unsplash.jpg
deleted file mode 100644
index d87fb88..0000000
Binary files a/static/will-rust-Vv1E0zcQDCI-unsplash.jpg and /dev/null differ
diff --git a/tailwind.config.js b/tailwind.config.js
deleted file mode 100644
index 15edad0..0000000
--- a/tailwind.config.js
+++ /dev/null
@@ -1,13 +0,0 @@
-/** @type {import('tailwindcss').Config} */
-module.exports = {
- content: ["./index.html", "./services.html", "./privacy.html", "./static/js/**/*.js"],
- theme: {
- container: {
- center: true,
- },
- extend: {
- },
- },
- plugins: [],
-}
-
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..238655f
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,27 @@
+{
+ "compilerOptions": {
+ // Enable latest features
+ "lib": ["ESNext", "DOM"],
+ "target": "ESNext",
+ "module": "ESNext",
+ "moduleDetection": "force",
+ "jsx": "react-jsx",
+ "allowJs": true,
+
+ // Bundler mode
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "verbatimModuleSyntax": true,
+ "noEmit": true,
+
+ // Best practices
+ "strict": true,
+ "skipLibCheck": true,
+ "noFallthroughCasesInSwitch": true,
+
+ // Some stricter flags (disabled by default)
+ "noUnusedLocals": false,
+ "noUnusedParameters": false,
+ "noPropertyAccessFromIndexSignature": false
+ }
+}