moved from svelte -> php with apache
@ -1 +0,0 @@
|
||||
.gitignore
|
23
.gitignore
vendored
@ -1,23 +0,0 @@
|
||||
node_modules
|
||||
|
||||
# Output
|
||||
.output
|
||||
.vercel
|
||||
.netlify
|
||||
.wrangler
|
||||
/.svelte-kit
|
||||
/build
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Env
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
# Vite
|
||||
vite.config.js.timestamp-*
|
||||
vite.config.ts.timestamp-*
|
17
Dockerfile
@ -1,15 +1,6 @@
|
||||
FROM node:18-alpine AS builder
|
||||
FROM php:8.2-apache
|
||||
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN npm install
|
||||
RUN npx vite build
|
||||
COPY www/ /var/www/html/
|
||||
|
||||
FROM nginx:latest
|
||||
|
||||
COPY --from=builder /app/build /usr/share/nginx/html
|
||||
COPY nginx.conf /etc/nginx/nginx.conf
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
RUN chown -R www-data:www-data /var/www/html
|
||||
RUN a2enmod rewrite
|
||||
|
38
README.md
@ -1,38 +0,0 @@
|
||||
# sv
|
||||
|
||||
Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli).
|
||||
|
||||
## Creating a project
|
||||
|
||||
If you're seeing this, you've probably already done this step. Congrats!
|
||||
|
||||
```bash
|
||||
# create a new project in the current directory
|
||||
npx sv create
|
||||
|
||||
# create a new project in my-app
|
||||
npx sv create my-app
|
||||
```
|
||||
|
||||
## Developing
|
||||
|
||||
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
|
||||
# or start the server and open the app in a new browser tab
|
||||
npm run dev -- --open
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
To create a production version of your app:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
You can preview the production build with `npm run preview`.
|
||||
|
||||
> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
|
217
bun.lock
@ -1,217 +0,0 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "lehnert.dev",
|
||||
"dependencies": {
|
||||
"@sveltejs/adapter-static": "^3.0.8",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-auto": "^4.0.0",
|
||||
"@sveltejs/kit": "^2.16.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.0.0",
|
||||
"svelte": "^5.0.0",
|
||||
"svelte-check": "^4.0.0",
|
||||
"typescript": "^5.0.0",
|
||||
"vite": "^6.2.5",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="],
|
||||
|
||||
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag=="],
|
||||
|
||||
"@esbuild/android-arm": ["@esbuild/android-arm@0.25.2", "", { "os": "android", "cpu": "arm" }, "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA=="],
|
||||
|
||||
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.2", "", { "os": "android", "cpu": "arm64" }, "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w=="],
|
||||
|
||||
"@esbuild/android-x64": ["@esbuild/android-x64@0.25.2", "", { "os": "android", "cpu": "x64" }, "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg=="],
|
||||
|
||||
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA=="],
|
||||
|
||||
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA=="],
|
||||
|
||||
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w=="],
|
||||
|
||||
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ=="],
|
||||
|
||||
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.2", "", { "os": "linux", "cpu": "arm" }, "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g=="],
|
||||
|
||||
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g=="],
|
||||
|
||||
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.2", "", { "os": "linux", "cpu": "ia32" }, "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ=="],
|
||||
|
||||
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.2", "", { "os": "linux", "cpu": "none" }, "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w=="],
|
||||
|
||||
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.2", "", { "os": "linux", "cpu": "none" }, "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q=="],
|
||||
|
||||
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g=="],
|
||||
|
||||
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.2", "", { "os": "linux", "cpu": "none" }, "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw=="],
|
||||
|
||||
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q=="],
|
||||
|
||||
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.2", "", { "os": "linux", "cpu": "x64" }, "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg=="],
|
||||
|
||||
"@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.2", "", { "os": "none", "cpu": "arm64" }, "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw=="],
|
||||
|
||||
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.2", "", { "os": "none", "cpu": "x64" }, "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg=="],
|
||||
|
||||
"@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg=="],
|
||||
|
||||
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw=="],
|
||||
|
||||
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA=="],
|
||||
|
||||
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q=="],
|
||||
|
||||
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg=="],
|
||||
|
||||
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.2", "", { "os": "win32", "cpu": "x64" }, "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA=="],
|
||||
|
||||
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.8", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA=="],
|
||||
|
||||
"@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
|
||||
|
||||
"@jridgewell/set-array": ["@jridgewell/set-array@1.2.1", "", {}, "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A=="],
|
||||
|
||||
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="],
|
||||
|
||||
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="],
|
||||
|
||||
"@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="],
|
||||
|
||||
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.40.0", "", { "os": "android", "cpu": "arm" }, "sha512-+Fbls/diZ0RDerhE8kyC6hjADCXA1K4yVNlH0EYfd2XjyH0UGgzaQ8MlT0pCXAThfxv3QUAczHaL+qSv1E4/Cg=="],
|
||||
|
||||
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.40.0", "", { "os": "android", "cpu": "arm64" }, "sha512-PPA6aEEsTPRz+/4xxAmaoWDqh67N7wFbgFUJGMnanCFs0TV99M0M8QhhaSCks+n6EbQoFvLQgYOGXxlMGQe/6w=="],
|
||||
|
||||
"@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.40.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-GwYOcOakYHdfnjjKwqpTGgn5a6cUX7+Ra2HeNj/GdXvO2VJOOXCiYYlRFU4CubFM67EhbmzLOmACKEfvp3J1kQ=="],
|
||||
|
||||
"@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.40.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-CoLEGJ+2eheqD9KBSxmma6ld01czS52Iw0e2qMZNpPDlf7Z9mj8xmMemxEucinev4LgHalDPczMyxzbq+Q+EtA=="],
|
||||
|
||||
"@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.40.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-r7yGiS4HN/kibvESzmrOB/PxKMhPTlz+FcGvoUIKYoTyGd5toHp48g1uZy1o1xQvybwwpqpe010JrcGG2s5nkg=="],
|
||||
|
||||
"@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.40.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-mVDxzlf0oLzV3oZOr0SMJ0lSDd3xC4CmnWJ8Val8isp9jRGl5Dq//LLDSPFrasS7pSm6m5xAcKaw3sHXhBjoRw=="],
|
||||
|
||||
"@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.40.0", "", { "os": "linux", "cpu": "arm" }, "sha512-y/qUMOpJxBMy8xCXD++jeu8t7kzjlOCkoxxajL58G62PJGBZVl/Gwpm7JK9+YvlB701rcQTzjUZ1JgUoPTnoQA=="],
|
||||
|
||||
"@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.40.0", "", { "os": "linux", "cpu": "arm" }, "sha512-GoCsPibtVdJFPv/BOIvBKO/XmwZLwaNWdyD8TKlXuqp0veo2sHE+A/vpMQ5iSArRUz/uaoj4h5S6Pn0+PdhRjg=="],
|
||||
|
||||
"@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.40.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-L5ZLphTjjAD9leJzSLI7rr8fNqJMlGDKlazW2tX4IUF9P7R5TMQPElpH82Q7eNIDQnQlAyiNVfRPfP2vM5Avvg=="],
|
||||
|
||||
"@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.40.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-ATZvCRGCDtv1Y4gpDIXsS+wfFeFuLwVxyUBSLawjgXK2tRE6fnsQEkE4csQQYWlBlsFztRzCnBvWVfcae/1qxQ=="],
|
||||
|
||||
"@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.40.0", "", { "os": "linux", "cpu": "none" }, "sha512-wG9e2XtIhd++QugU5MD9i7OnpaVb08ji3P1y/hNbxrQ3sYEelKJOq1UJ5dXczeo6Hj2rfDEL5GdtkMSVLa/AOg=="],
|
||||
|
||||
"@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.40.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-vgXfWmj0f3jAUvC7TZSU/m/cOE558ILWDzS7jBhiCAFpY2WEBn5jqgbqvmzlMjtp8KlLcBlXVD2mkTSEQE6Ixw=="],
|
||||
|
||||
"@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.40.0", "", { "os": "linux", "cpu": "none" }, "sha512-uJkYTugqtPZBS3Z136arevt/FsKTF/J9dEMTX/cwR7lsAW4bShzI2R0pJVw+hcBTWF4dxVckYh72Hk3/hWNKvA=="],
|
||||
|
||||
"@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.40.0", "", { "os": "linux", "cpu": "none" }, "sha512-rKmSj6EXQRnhSkE22+WvrqOqRtk733x3p5sWpZilhmjnkHkpeCgWsFFo0dGnUGeA+OZjRl3+VYq+HyCOEuwcxQ=="],
|
||||
|
||||
"@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.40.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-SpnYlAfKPOoVsQqmTFJ0usx0z84bzGOS9anAC0AZ3rdSo3snecihbhFTlJZ8XMwzqAcodjFU4+/SM311dqE5Sw=="],
|
||||
|
||||
"@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.40.0", "", { "os": "linux", "cpu": "x64" }, "sha512-RcDGMtqF9EFN8i2RYN2W+64CdHruJ5rPqrlYw+cgM3uOVPSsnAQps7cpjXe9be/yDp8UC7VLoCoKC8J3Kn2FkQ=="],
|
||||
|
||||
"@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.40.0", "", { "os": "linux", "cpu": "x64" }, "sha512-HZvjpiUmSNx5zFgwtQAV1GaGazT2RWvqeDi0hV+AtC8unqqDSsaFjPxfsO6qPtKRRg25SisACWnJ37Yio8ttaw=="],
|
||||
|
||||
"@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.40.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-UtZQQI5k/b8d7d3i9AZmA/t+Q4tk3hOC0tMOMSq2GlMYOfxbesxG4mJSeDp0EHs30N9bsfwUvs3zF4v/RzOeTQ=="],
|
||||
|
||||
"@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.40.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-+m03kvI2f5syIqHXCZLPVYplP8pQch9JHyXKZ3AGMKlg8dCyr2PKHjwRLiW53LTrN/Nc3EqHOKxUxzoSPdKddA=="],
|
||||
|
||||
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.40.0", "", { "os": "win32", "cpu": "x64" }, "sha512-lpPE1cLfP5oPzVjKMx10pgBmKELQnFJXHgvtHCtuJWOv8MxqdEIMNtgHgBFf7Ea2/7EuVwa9fodWUfXAlXZLZQ=="],
|
||||
|
||||
"@sveltejs/acorn-typescript": ["@sveltejs/acorn-typescript@1.0.5", "", { "peerDependencies": { "acorn": "^8.9.0" } }, "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ=="],
|
||||
|
||||
"@sveltejs/adapter-auto": ["@sveltejs/adapter-auto@4.0.0", "", { "dependencies": { "import-meta-resolve": "^4.1.0" }, "peerDependencies": { "@sveltejs/kit": "^2.0.0" } }, "sha512-kmuYSQdD2AwThymQF0haQhM8rE5rhutQXG4LNbnbShwhMO4qQGnKaaTy+88DuNSuoQDi58+thpq8XpHc1+oEKQ=="],
|
||||
|
||||
"@sveltejs/adapter-static": ["@sveltejs/adapter-static@3.0.8", "", { "peerDependencies": { "@sveltejs/kit": "^2.0.0" } }, "sha512-YaDrquRpZwfcXbnlDsSrBQNCChVOT9MGuSg+dMAyfsAa1SmiAhrA5jUYUiIMC59G92kIbY/AaQOWcBdq+lh+zg=="],
|
||||
|
||||
"@sveltejs/kit": ["@sveltejs/kit@2.20.5", "", { "dependencies": { "@types/cookie": "^0.6.0", "cookie": "^0.6.0", "devalue": "^5.1.0", "esm-env": "^1.2.2", "import-meta-resolve": "^4.1.0", "kleur": "^4.1.5", "magic-string": "^0.30.5", "mrmime": "^2.0.0", "sade": "^1.8.1", "set-cookie-parser": "^2.6.0", "sirv": "^3.0.0" }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0", "svelte": "^4.0.0 || ^5.0.0-next.0", "vite": "^5.0.3 || ^6.0.0" }, "bin": { "svelte-kit": "svelte-kit.js" } }, "sha512-zT/97KvVUo19jEGZa972ls7KICjPCB53j54TVxnEFT5VEwL16G+YFqRVwJbfxh7AmS7/Ptr1rKF7Qt4FBMDNlw=="],
|
||||
|
||||
"@sveltejs/vite-plugin-svelte": ["@sveltejs/vite-plugin-svelte@5.0.3", "", { "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^4.0.1", "debug": "^4.4.0", "deepmerge": "^4.3.1", "kleur": "^4.1.5", "magic-string": "^0.30.15", "vitefu": "^1.0.4" }, "peerDependencies": { "svelte": "^5.0.0", "vite": "^6.0.0" } }, "sha512-MCFS6CrQDu1yGwspm4qtli0e63vaPCehf6V7pIMP15AsWgMKrqDGCPFF/0kn4SP0ii4aySu4Pa62+fIRGFMjgw=="],
|
||||
|
||||
"@sveltejs/vite-plugin-svelte-inspector": ["@sveltejs/vite-plugin-svelte-inspector@4.0.1", "", { "dependencies": { "debug": "^4.3.7" }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^5.0.0", "svelte": "^5.0.0", "vite": "^6.0.0" } }, "sha512-J/Nmb2Q2y7mck2hyCX4ckVHcR5tu2J+MtBEQqpDrrgELZ2uvraQcK/ioCV61AqkdXFgriksOKIceDcQmqnGhVw=="],
|
||||
|
||||
"@types/cookie": ["@types/cookie@0.6.0", "", {}, "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="],
|
||||
|
||||
"@types/estree": ["@types/estree@1.0.7", "", {}, "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ=="],
|
||||
|
||||
"acorn": ["acorn@8.14.1", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg=="],
|
||||
|
||||
"aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="],
|
||||
|
||||
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
|
||||
|
||||
"chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="],
|
||||
|
||||
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
|
||||
|
||||
"cookie": ["cookie@0.6.0", "", {}, "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw=="],
|
||||
|
||||
"debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
|
||||
|
||||
"deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="],
|
||||
|
||||
"devalue": ["devalue@5.1.1", "", {}, "sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw=="],
|
||||
|
||||
"esbuild": ["esbuild@0.25.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.2", "@esbuild/android-arm": "0.25.2", "@esbuild/android-arm64": "0.25.2", "@esbuild/android-x64": "0.25.2", "@esbuild/darwin-arm64": "0.25.2", "@esbuild/darwin-x64": "0.25.2", "@esbuild/freebsd-arm64": "0.25.2", "@esbuild/freebsd-x64": "0.25.2", "@esbuild/linux-arm": "0.25.2", "@esbuild/linux-arm64": "0.25.2", "@esbuild/linux-ia32": "0.25.2", "@esbuild/linux-loong64": "0.25.2", "@esbuild/linux-mips64el": "0.25.2", "@esbuild/linux-ppc64": "0.25.2", "@esbuild/linux-riscv64": "0.25.2", "@esbuild/linux-s390x": "0.25.2", "@esbuild/linux-x64": "0.25.2", "@esbuild/netbsd-arm64": "0.25.2", "@esbuild/netbsd-x64": "0.25.2", "@esbuild/openbsd-arm64": "0.25.2", "@esbuild/openbsd-x64": "0.25.2", "@esbuild/sunos-x64": "0.25.2", "@esbuild/win32-arm64": "0.25.2", "@esbuild/win32-ia32": "0.25.2", "@esbuild/win32-x64": "0.25.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ=="],
|
||||
|
||||
"esm-env": ["esm-env@1.2.2", "", {}, "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA=="],
|
||||
|
||||
"esrap": ["esrap@1.4.6", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } }, "sha512-F/D2mADJ9SHY3IwksD4DAXjTt7qt7GWUf3/8RhCNWmC/67tyb55dpimHmy7EplakFaflV0R/PC+fdSPqrRHAQw=="],
|
||||
|
||||
"fdir": ["fdir@6.4.3", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw=="],
|
||||
|
||||
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||
|
||||
"import-meta-resolve": ["import-meta-resolve@4.1.0", "", {}, "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw=="],
|
||||
|
||||
"is-reference": ["is-reference@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.6" } }, "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw=="],
|
||||
|
||||
"kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="],
|
||||
|
||||
"locate-character": ["locate-character@3.0.0", "", {}, "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA=="],
|
||||
|
||||
"magic-string": ["magic-string@0.30.17", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA=="],
|
||||
|
||||
"mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="],
|
||||
|
||||
"mrmime": ["mrmime@2.0.1", "", {}, "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="],
|
||||
|
||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||
|
||||
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
||||
|
||||
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
||||
|
||||
"postcss": ["postcss@8.5.3", "", { "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A=="],
|
||||
|
||||
"readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="],
|
||||
|
||||
"rollup": ["rollup@4.40.0", "", { "dependencies": { "@types/estree": "1.0.7" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.40.0", "@rollup/rollup-android-arm64": "4.40.0", "@rollup/rollup-darwin-arm64": "4.40.0", "@rollup/rollup-darwin-x64": "4.40.0", "@rollup/rollup-freebsd-arm64": "4.40.0", "@rollup/rollup-freebsd-x64": "4.40.0", "@rollup/rollup-linux-arm-gnueabihf": "4.40.0", "@rollup/rollup-linux-arm-musleabihf": "4.40.0", "@rollup/rollup-linux-arm64-gnu": "4.40.0", "@rollup/rollup-linux-arm64-musl": "4.40.0", "@rollup/rollup-linux-loongarch64-gnu": "4.40.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.40.0", "@rollup/rollup-linux-riscv64-gnu": "4.40.0", "@rollup/rollup-linux-riscv64-musl": "4.40.0", "@rollup/rollup-linux-s390x-gnu": "4.40.0", "@rollup/rollup-linux-x64-gnu": "4.40.0", "@rollup/rollup-linux-x64-musl": "4.40.0", "@rollup/rollup-win32-arm64-msvc": "4.40.0", "@rollup/rollup-win32-ia32-msvc": "4.40.0", "@rollup/rollup-win32-x64-msvc": "4.40.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-Noe455xmA96nnqH5piFtLobsGbCij7Tu+tb3c1vYjNbTkfzGqXqQXG3wJaYXkRZuQ0vEYN4bhwg7QnIrqB5B+w=="],
|
||||
|
||||
"sade": ["sade@1.8.1", "", { "dependencies": { "mri": "^1.1.0" } }, "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A=="],
|
||||
|
||||
"set-cookie-parser": ["set-cookie-parser@2.7.1", "", {}, "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ=="],
|
||||
|
||||
"sirv": ["sirv@3.0.1", "", { "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", "totalist": "^3.0.0" } }, "sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A=="],
|
||||
|
||||
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||
|
||||
"svelte": ["svelte@5.26.2", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "acorn": "^8.12.1", "aria-query": "^5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "esm-env": "^1.2.1", "esrap": "^1.4.6", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-e2TEcGK2YKVwDWYy5OsptVclYgDvfY1E/8IzPiOq63uG/GDo/j5VUYTC9EinQNraoZalbMWN+5f5TYC1QlAqOw=="],
|
||||
|
||||
"svelte-check": ["svelte-check@4.1.6", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "chokidar": "^4.0.1", "fdir": "^6.2.0", "picocolors": "^1.0.0", "sade": "^1.7.4" }, "peerDependencies": { "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": ">=5.0.0" }, "bin": { "svelte-check": "bin/svelte-check" } }, "sha512-P7w/6tdSfk3zEVvfsgrp3h3DFC75jCdZjTQvgGJtjPORs1n7/v2VMPIoty3PWv7jnfEm3x0G/p9wH4pecTb0Wg=="],
|
||||
|
||||
"totalist": ["totalist@3.0.1", "", {}, "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ=="],
|
||||
|
||||
"typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
|
||||
|
||||
"vite": ["vite@6.2.6", "", { "dependencies": { "esbuild": "^0.25.0", "postcss": "^8.5.3", "rollup": "^4.30.1" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-9xpjNl3kR4rVDZgPNdTL0/c6ao4km69a/2ihNQbcANz8RuCOK3hQBmLSJf3bRKVQjVMda+YvizNE8AwvogcPbw=="],
|
||||
|
||||
"vitefu": ["vitefu@1.0.6", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" }, "optionalPeers": ["vite"] }, "sha512-+Rex1GlappUyNN6UfwbVZne/9cYC4+R2XDk9xkNXBKMw6HQagdX9PgZ8V2v1WUSK1wfBLp7qbI1+XSNIlB1xmA=="],
|
||||
|
||||
"zimmerframe": ["zimmerframe@1.1.2", "", {}, "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w=="],
|
||||
}
|
||||
}
|
20
nginx.conf
@ -1,20 +0,0 @@
|
||||
worker_processes auto;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
sendfile on;
|
||||
|
||||
server {
|
||||
listen 3000;
|
||||
server_name localhost;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
error_page 404 /404.html;
|
||||
}
|
||||
}
|
26
package.json
@ -1,26 +0,0 @@
|
||||
{
|
||||
"name": "lehnert.dev",
|
||||
"version": "0.0.1",
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-auto": "^4.0.0",
|
||||
"@sveltejs/kit": "^2.16.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.0.0",
|
||||
"svelte": "^5.0.0",
|
||||
"svelte-check": "^4.0.0",
|
||||
"typescript": "^5.0.0",
|
||||
"vite": "^6.2.5"
|
||||
},
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"prepare": "svelte-kit sync || echo ''",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@sveltejs/adapter-static": "^3.0.8"
|
||||
}
|
||||
}
|
13
src/app.d.ts
vendored
@ -1,13 +0,0 @@
|
||||
// See https://svelte.dev/docs/kit/types#app.d.ts
|
||||
// for information about these interfaces
|
||||
declare global {
|
||||
namespace App {
|
||||
// interface Error {}
|
||||
// interface Locals {}
|
||||
// interface PageData {}
|
||||
// interface PageState {}
|
||||
// interface Platform {}
|
||||
}
|
||||
}
|
||||
|
||||
export {};
|
17
src/app.html
@ -1,17 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
%sveltekit.head%
|
||||
|
||||
<title>lehnert.dev</title>
|
||||
</head>
|
||||
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
<div style="display: contents">%sveltekit.body%</div>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -1 +0,0 @@
|
||||
// place files you want to import through the `$lib` alias in this folder.
|
@ -1,26 +0,0 @@
|
||||
<slot />
|
||||
|
||||
<style>
|
||||
:global(html, body) {
|
||||
min-width: 100vw;
|
||||
min-height: max(100%, 100vh);
|
||||
}
|
||||
|
||||
:global(*) {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:global(body) {
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
#1e1e2f 0,
|
||||
#252547 99vh,
|
||||
#252547 100vh
|
||||
);
|
||||
|
||||
max-width: 100vw;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
</style>
|
@ -1 +0,0 @@
|
||||
export const prerender = true;
|
@ -1,342 +0,0 @@
|
||||
<script lang="ts">
|
||||
import EMail from "$lib/assets/email.svg";
|
||||
import Git from "$lib/assets/git.svg";
|
||||
import GitHub from "$lib/assets/github.svg";
|
||||
import Instagram from "$lib/assets/instagram.svg";
|
||||
import LinkedIn from "$lib/assets/linkedin.svg";
|
||||
import Star from "$lib/assets/star.svg";
|
||||
import { onMount } from "svelte";
|
||||
|
||||
$effect(() => {
|
||||
const indices = Array(50)
|
||||
.fill(0)
|
||||
.map((_, i) => i);
|
||||
|
||||
const points: [number, number][] = indices.map(() => [
|
||||
Math.max(0.02, Math.min(0.98, Math.random())),
|
||||
Math.max(0.02, Math.min(0.98, Math.random())),
|
||||
]);
|
||||
const sizes = indices.map(() => Math.max(Math.random(), 0.3) * 2);
|
||||
|
||||
const stars = points.map(([x, y], i) => {
|
||||
const star = document.createElement("img");
|
||||
star.src = Star;
|
||||
star.classList.add("star");
|
||||
|
||||
star.style.width = `max(${sizes[i]}vw, ${sizes[i]}vh)`;
|
||||
star.style.position = "absolute";
|
||||
star.style.left = `${100 * x}vw`;
|
||||
star.style.top = `${100 * y}vh`;
|
||||
|
||||
return star;
|
||||
});
|
||||
|
||||
function chooseRandom<T>(arr: T[]): T {
|
||||
return arr[Math.floor(Math.random() * arr.length)];
|
||||
}
|
||||
|
||||
const distance = (a: [number, number], b: [number, number]) => {
|
||||
return (
|
||||
Math.sqrt(Math.pow(a[0] - b[0], 2) + Math.pow(a[1] - b[1], 2)) /
|
||||
Math.SQRT2
|
||||
);
|
||||
};
|
||||
|
||||
const connections = stars.map((_, i) => {
|
||||
let others: number[] = [];
|
||||
|
||||
const choosable = [...indices]
|
||||
.sort((a, b) => {
|
||||
return (
|
||||
distance(points[i], points[a]) -
|
||||
distance(points[i], points[b])
|
||||
);
|
||||
})
|
||||
.slice(0, 15);
|
||||
|
||||
const otherCount = Math.max(3, Math.floor(Math.random() * 10));
|
||||
for (let i = 0; i < otherCount; i++) {
|
||||
let o = i;
|
||||
|
||||
while (o === i || others.includes(o)) {
|
||||
o = chooseRandom(choosable);
|
||||
}
|
||||
|
||||
others.push(o);
|
||||
}
|
||||
|
||||
return others;
|
||||
});
|
||||
|
||||
let lidx: number = 0;
|
||||
const lineInterval = setInterval(() => {
|
||||
if (Math.random() < 0.3) return;
|
||||
if (Math.random() < 0.05) lidx = chooseRandom(indices);
|
||||
|
||||
let iter = 0;
|
||||
while (iter++ < 300) {
|
||||
const nidx = chooseRandom(indices);
|
||||
if (lidx === nidx) continue;
|
||||
|
||||
const d = distance(points[lidx], points[nidx]);
|
||||
if ((d > 0.4 && Math.random() < 0.8) || d > 0.5) continue;
|
||||
|
||||
const line = document.getElementById(`${lidx}-${nidx}`);
|
||||
if (!line) continue;
|
||||
|
||||
line.setAttribute("opacity", "1");
|
||||
setTimeout(
|
||||
() => line.setAttribute("opacity", "0"),
|
||||
4500 + Math.random() * 2500,
|
||||
);
|
||||
|
||||
lidx = nidx;
|
||||
return;
|
||||
}
|
||||
|
||||
// nothing found -> choose next random
|
||||
lidx = chooseRandom(indices);
|
||||
}, 650);
|
||||
|
||||
document.getElementById("stars")?.append(...stars);
|
||||
|
||||
const linesSVG = document.getElementById("stars-lines");
|
||||
|
||||
stars.forEach((_, i) => {
|
||||
const [x1, y1] = points[i];
|
||||
|
||||
connections[i].forEach((conn) => {
|
||||
const [x2, y2] = points[conn];
|
||||
const line = document.createElementNS(
|
||||
"http://www.w3.org/2000/svg",
|
||||
"line",
|
||||
);
|
||||
|
||||
line.setAttribute("x1", `${x1 * 100}%`);
|
||||
line.setAttribute("y1", `${y1 * 100}%`);
|
||||
line.setAttribute("x2", `${x2 * 100}%`);
|
||||
line.setAttribute("y2", `${y2 * 100}%`);
|
||||
|
||||
line.setAttribute("stroke", "white");
|
||||
line.setAttribute("stroke-width", "1.5");
|
||||
|
||||
line.id = `${i}-${conn}`;
|
||||
|
||||
line.setAttribute("opacity", "0");
|
||||
|
||||
linesSVG?.append(line);
|
||||
});
|
||||
});
|
||||
|
||||
const enterListeners = stars.map((_, i) => () => {
|
||||
connections[i].forEach((conn) => {
|
||||
const line = document.getElementById(`${i}-${conn}`);
|
||||
line?.setAttribute("opacity", "1");
|
||||
});
|
||||
});
|
||||
|
||||
const leaveListeners = stars.map((_, i) => () => {
|
||||
connections[i].forEach((conn) => {
|
||||
const line = document.getElementById(`${i}-${conn}`);
|
||||
line?.setAttribute("opacity", "0");
|
||||
});
|
||||
});
|
||||
|
||||
stars.forEach((star, i) => {
|
||||
star.addEventListener("mouseenter", enterListeners[i]);
|
||||
star.addEventListener("mouseleave", leaveListeners[i]);
|
||||
});
|
||||
|
||||
const svgResizeListener = () => {
|
||||
if (!linesSVG) return;
|
||||
const w = linesSVG.clientWidth;
|
||||
const h = linesSVG.clientHeight;
|
||||
linesSVG.setAttribute("viewBox", `0 0 ${w} ${h}`);
|
||||
};
|
||||
|
||||
svgResizeListener();
|
||||
|
||||
window.addEventListener("resize", svgResizeListener);
|
||||
|
||||
return () => {
|
||||
clearInterval(lineInterval);
|
||||
|
||||
stars.forEach((star, i) => {
|
||||
star.removeEventListener("mouseenter", enterListeners[i]);
|
||||
star.removeEventListener("mouseleave", leaveListeners[i]);
|
||||
});
|
||||
|
||||
window.removeEventListener("resize", svgResizeListener);
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<meta
|
||||
name="keywords"
|
||||
content="Ludwig Lehnert,Nürnberg,Pegnitz,Nuremberg,Informatik,Computer,Copmuter Science"
|
||||
/>
|
||||
</svelte:head>
|
||||
|
||||
<svg
|
||||
id="stars-lines"
|
||||
aria-hidden="true"
|
||||
style="position: absolute; z-index: 0; height: 100vh; width: 100vw;"
|
||||
></svg>
|
||||
|
||||
<div
|
||||
id="stars"
|
||||
style="position: absolute; z-index: 1; height: 100vh; width: 100vw; overflow-x: hidden;"
|
||||
></div>
|
||||
|
||||
<main style="position: relative; z-index: 2;">
|
||||
<h1>Hey, I'm Ludwig 🚀</h1>
|
||||
<p>Welcome to my digital playground.</p>
|
||||
|
||||
<div class="social-links">
|
||||
<a target="_blank" href="https://instagram.com/lehlud">
|
||||
<img src={Instagram} alt="" width="25" />
|
||||
</a>
|
||||
<a target="_blank" href="https://linkedin.com/in/ludwig-lehnert">
|
||||
<img src={LinkedIn} alt="" width="25" />
|
||||
</a>
|
||||
<a target="_blank" href="mailto:info@lehnert.dev">
|
||||
<img src={EMail} alt="" width="25" />
|
||||
</a>
|
||||
<a target="_blank" href="https://gitea.cloud.lehnert.dev/explore/repos">
|
||||
<img src={Git} alt="" width="25" />
|
||||
</a>
|
||||
<a target="_blank" href="https://github.com/lehlud">
|
||||
<img src={GitHub} alt="" width="25" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="legal-links">
|
||||
<a href="/imprint">Imprint</a>
|
||||
<a href="/privacy">Privacy Policy</a>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div style="height: 400px;"></div>
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
font-size: 3.5rem;
|
||||
background: linear-gradient(90deg, #00ffff, #ff00ff);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
animation: glow 3s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes glow {
|
||||
from {
|
||||
text-shadow: 0 0 10px #00ffff;
|
||||
}
|
||||
to {
|
||||
text-shadow: 0 0 20px #ff00ff;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
:global(.star) {
|
||||
animation: fadeIn 1s forwards;
|
||||
transition-duration: 500ms;
|
||||
translate: -50% -50%;
|
||||
}
|
||||
|
||||
/* :global(#stars-lines) {
|
||||
max-width: 100vw;
|
||||
overflow-x: hidden;
|
||||
} */
|
||||
|
||||
:global(#stars-lines line) {
|
||||
transition-duration: 500ms;
|
||||
}
|
||||
|
||||
:global(#stars-lines line[opacity="1"]) {
|
||||
animation: strokeAnim 3s ease-in-out forwards;
|
||||
}
|
||||
|
||||
@keyframes strokeAnim {
|
||||
from {
|
||||
stroke: #00ffff;
|
||||
}
|
||||
to {
|
||||
stroke: #ff00ff;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1.2rem;
|
||||
max-width: 600px;
|
||||
margin-top: 1rem;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.social-links {
|
||||
display: flex;
|
||||
gap: 0.75rem;
|
||||
margin-top: 1.5rem;
|
||||
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.social-links a {
|
||||
padding: 0.75rem;
|
||||
font-size: 1rem;
|
||||
background: #00ffff;
|
||||
color: #1e1e2f;
|
||||
border: none;
|
||||
border-radius: 999px;
|
||||
cursor: pointer;
|
||||
transition: background 0.3s ease;
|
||||
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
.social-links a:hover {
|
||||
background: #ff00ff;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.legal-links {
|
||||
margin-top: 1rem;
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.legal-links a {
|
||||
color: rgb(255, 255, 255);
|
||||
cursor: pointer;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.legal-links a:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 80vh;
|
||||
color: white;
|
||||
font-family: "Inter", sans-serif;
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
|
||||
pointer-events: none;
|
||||
}
|
||||
</style>
|
@ -1,93 +0,0 @@
|
||||
<script lang="ts">
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<h1>404</h1>
|
||||
|
||||
<p>
|
||||
Oops! The page you're looking for doesn't exist. It might have been
|
||||
abducted by aliens 🛸
|
||||
</p>
|
||||
|
||||
<a class="btn" href="/">Beam me back</a>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
background: radial-gradient(
|
||||
ellipse at center,
|
||||
#1e1e2f 0%,
|
||||
#0f0f1a 100%
|
||||
);
|
||||
color: white;
|
||||
text-align: center;
|
||||
font-family: "Inter", sans-serif;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 6rem;
|
||||
margin: 0;
|
||||
background: linear-gradient(90deg, #ff0066, #00ffff);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
animation: glitch 2s infinite;
|
||||
}
|
||||
|
||||
@keyframes glitch {
|
||||
0% {
|
||||
text-shadow:
|
||||
2px 0 #ff00c8,
|
||||
-2px 0 #00fff9;
|
||||
}
|
||||
25% {
|
||||
text-shadow:
|
||||
-2px 0 #ff00c8,
|
||||
2px 0 #00fff9;
|
||||
}
|
||||
50% {
|
||||
text-shadow:
|
||||
2px 0 #00fff9,
|
||||
-2px 0 #ff00c8;
|
||||
}
|
||||
75% {
|
||||
text-shadow:
|
||||
-1px 0 #00fff9,
|
||||
1px 0 #ff00c8;
|
||||
}
|
||||
100% {
|
||||
text-shadow:
|
||||
2px 0 #ff00c8,
|
||||
-2px 0 #00fff9;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1.25rem;
|
||||
margin: 1rem 0 2rem;
|
||||
color: #ccc;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
text-decoration: none;
|
||||
background: #00ffff;
|
||||
border: none;
|
||||
padding: 0.75rem 1.5rem;
|
||||
border-radius: 999px;
|
||||
font-size: 1rem;
|
||||
color: #1e1e2f;
|
||||
cursor: pointer;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background: #ff0066;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
@ -1,92 +0,0 @@
|
||||
<script lang="ts">
|
||||
// Optional: add any TS logic here
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<h1>Impressum<br />Imprint</h1>
|
||||
<div class="legal-section">
|
||||
<p><b>Angaben gemäß § 5 TMG:</b></p>
|
||||
<p>
|
||||
Ludwig Lehnert <br />
|
||||
Zedernstr. 41 <br />
|
||||
90441 Nürnberg <br />
|
||||
Deutschland
|
||||
</p>
|
||||
<p>
|
||||
<b>Kontakt:</b> <br />
|
||||
<!-- Telefon: [Ihre Telefonnummer] <br /> -->
|
||||
E-Mail: info@lehnert.dev
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 80vh;
|
||||
color: white;
|
||||
font-family: "Inter", sans-serif;
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
background: linear-gradient(90deg, #00ffff, #ff00ff);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
margin-bottom: 1rem;
|
||||
animation: glitch 2s infinite;
|
||||
}
|
||||
|
||||
@keyframes glitch {
|
||||
0% {
|
||||
text-shadow:
|
||||
2px 0 #ff00c8,
|
||||
-2px 0 #00fff9;
|
||||
}
|
||||
25% {
|
||||
text-shadow:
|
||||
-2px 0 #ff00c8,
|
||||
2px 0 #00fff9;
|
||||
}
|
||||
50% {
|
||||
text-shadow:
|
||||
2px 0 #00fff9,
|
||||
-2px 0 #ff00c8;
|
||||
}
|
||||
75% {
|
||||
text-shadow:
|
||||
-1px 0 #00fff9,
|
||||
1px 0 #ff00c8;
|
||||
}
|
||||
100% {
|
||||
text-shadow:
|
||||
2px 0 #ff00c8,
|
||||
-2px 0 #00fff9;
|
||||
}
|
||||
}
|
||||
|
||||
.legal-section {
|
||||
text-align: left;
|
||||
max-width: 700px;
|
||||
margin: 2rem auto;
|
||||
padding: 1rem 2rem;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border-left: 4px solid #00ffff;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.legal-section p {
|
||||
font-size: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
color: #ccc;
|
||||
line-height: 1.6;
|
||||
}
|
||||
</style>
|
@ -1,120 +0,0 @@
|
||||
<script lang="ts">
|
||||
// Optional: add any TS logic here
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<h1>Datenschutzerklärung<br />Privacy Policy</h1>
|
||||
<div class="legal-section">
|
||||
<p><strong>Deutsch:</strong></p>
|
||||
<p>
|
||||
Wir nehmen den Schutz Ihrer persönlichen Daten sehr ernst. Beim
|
||||
Besuch dieser Website werden automatisch Server-Logfiles erfasst
|
||||
(z.B. IP-Adresse, Uhrzeit des Zugriffs), die zur Gewährleistung des
|
||||
Betriebs und zur Sicherheit der Website notwendig sind. Diese Daten
|
||||
werden für maximal 90 Tage gespeichert und danach automatisch
|
||||
gelöscht.
|
||||
</p>
|
||||
<p>
|
||||
Diese Website wird über die Hetzner Cloud gehostet. Es gelten
|
||||
zusätzlich die Datenschutzbestimmungen der Hetzner Online GmbH: <a
|
||||
href="https://www.hetzner.com/de/legal/privacy-policy/"
|
||||
target="_blank">Hetzner Datenschutzerklärung</a
|
||||
>.
|
||||
</p>
|
||||
|
||||
<p><strong>English:</strong></p>
|
||||
<p>
|
||||
We take the protection of your personal data very seriously. When
|
||||
visiting this website, server log files (e.g. IP address, access
|
||||
time) are automatically collected for the purpose of operation and
|
||||
security. These logs are stored for a maximum of 90 days and then
|
||||
automatically deleted.
|
||||
</p>
|
||||
<p>
|
||||
This website is hosted via Hetzner Cloud. The privacy policy of
|
||||
Hetzner Online GmbH also applies: <a
|
||||
href="https://www.hetzner.com/legal/privacy-policy"
|
||||
target="_blank">Hetzner Privacy Policy</a
|
||||
>.
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 80vh;
|
||||
color: white;
|
||||
font-family: "Inter", sans-serif;
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
background: linear-gradient(90deg, #00ffff, #ff00ff);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
margin-bottom: 1rem;
|
||||
animation: glitch 2s infinite;
|
||||
}
|
||||
|
||||
@keyframes glitch {
|
||||
0% {
|
||||
text-shadow:
|
||||
2px 0 #ff00c8,
|
||||
-2px 0 #00fff9;
|
||||
}
|
||||
25% {
|
||||
text-shadow:
|
||||
-2px 0 #ff00c8,
|
||||
2px 0 #00fff9;
|
||||
}
|
||||
50% {
|
||||
text-shadow:
|
||||
2px 0 #00fff9,
|
||||
-2px 0 #ff00c8;
|
||||
}
|
||||
75% {
|
||||
text-shadow:
|
||||
-1px 0 #00fff9,
|
||||
1px 0 #ff00c8;
|
||||
}
|
||||
100% {
|
||||
text-shadow:
|
||||
2px 0 #ff00c8,
|
||||
-2px 0 #00fff9;
|
||||
}
|
||||
}
|
||||
|
||||
.legal-section {
|
||||
text-align: left;
|
||||
max-width: 700px;
|
||||
margin: 2rem auto;
|
||||
padding: 1rem 2rem;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border-left: 4px solid #00ffff;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.legal-section p {
|
||||
font-size: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
color: #ccc;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
a {
|
||||
color: white;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
</style>
|
@ -1,18 +0,0 @@
|
||||
import adapter from '@sveltejs/adapter-static';
|
||||
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
// Consult https://svelte.dev/docs/kit/integrations
|
||||
// for more information about preprocessors
|
||||
preprocess: vitePreprocess(),
|
||||
|
||||
kit: {
|
||||
// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
|
||||
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
|
||||
// See https://svelte.dev/docs/kit/adapters for more information about adapters.
|
||||
adapter: adapter()
|
||||
}
|
||||
};
|
||||
|
||||
export default config;
|
@ -1,19 +0,0 @@
|
||||
{
|
||||
"extends": "./.svelte-kit/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"moduleResolution": "bundler"
|
||||
}
|
||||
// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
|
||||
// except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
|
||||
//
|
||||
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
|
||||
// from the referenced tsconfig.json - TypeScript does not merge them in
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
import { sveltekit } from '@sveltejs/kit/vite';
|
||||
import { defineConfig } from 'vite';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [sveltekit()]
|
||||
});
|
38
www/.htaccess
Normal file
@ -0,0 +1,38 @@
|
||||
RewriteEngine On
|
||||
|
||||
# -------------------------------------------
|
||||
# 1. Rewrite /blog/<ID> to /blog.php?id=<ID>
|
||||
# -------------------------------------------
|
||||
RewriteRule ^blog/([^/]+)/?$ /blog.php?id=$1 [L,QSA]
|
||||
|
||||
# ----------------------------------------------------
|
||||
# 2. Rewrite /lib/* or /blog/* to /error.php?code=404
|
||||
# with 404 response code (internal rewriting)
|
||||
# ----------------------------------------------------
|
||||
RewriteCond %{REQUEST_URI} ^/(lib|blog)(/.*)?$
|
||||
RewriteRule ^ - [R=404,L]
|
||||
ErrorDocument 404 /error.php?code=404
|
||||
|
||||
# ----------------------------------------------------
|
||||
# 3. Custom error handler for all other errors
|
||||
# Sends proper status code to client
|
||||
# ----------------------------------------------------
|
||||
ErrorDocument 400 /error.php?code=400
|
||||
ErrorDocument 401 /error.php?code=401
|
||||
ErrorDocument 403 /error.php?code=403
|
||||
ErrorDocument 500 /error.php?code=500
|
||||
ErrorDocument 502 /error.php?code=502
|
||||
ErrorDocument 503 /error.php?code=503
|
||||
|
||||
|
||||
# RewriteEngine On
|
||||
|
||||
# ErrorDocument 404 /404.php
|
||||
|
||||
# RewriteRule ^b/([0-9]+)$ /blog.php?id=$1 [QSA,L]
|
||||
|
||||
# RewriteRule ^/lib - [R=404,L]
|
||||
|
||||
# RewriteCond %{REQUEST_FILENAME} !-f
|
||||
# RewriteCond %{REQUEST_FILENAME} !-d
|
||||
# RewriteRule ^.*$ - [R=404,L]
|
Before Width: | Height: | Size: 192 B After Width: | Height: | Size: 192 B |
Before Width: | Height: | Size: 604 B After Width: | Height: | Size: 604 B |
Before Width: | Height: | Size: 826 B After Width: | Height: | Size: 826 B |
Before Width: | Height: | Size: 544 B After Width: | Height: | Size: 544 B |
Before Width: | Height: | Size: 483 B After Width: | Height: | Size: 483 B |
Before Width: | Height: | Size: 146 B After Width: | Height: | Size: 146 B |
70
www/blog.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/lib/_index.php';
|
||||
|
||||
$id = (int) $_GET['id'];
|
||||
$path = __DIR__ . "/blog/$id.svg";
|
||||
if (!file_exists($path)) {
|
||||
http_response_code(404);
|
||||
require __DIR__ . '/404.php';
|
||||
exit;
|
||||
}
|
||||
|
||||
$svg = file_get_contents($path);
|
||||
if (str_starts_with($svg, '<?xml')) {
|
||||
$svg = preg_replace('/^\s*<\?xml[^>]+>\s*/', '', $svg);
|
||||
}
|
||||
|
||||
?><!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link rel="shortcut icon" href="/favicon.svg" type="image/x-icon">
|
||||
|
||||
<base target="_blank">
|
||||
|
||||
<title>Blog</title>
|
||||
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
min-height: max(100%, 100vh);
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
main {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
main>svg {
|
||||
width: min(95vw, 1000px);
|
||||
height: auto;
|
||||
}
|
||||
|
||||
main>svg a {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
main>svg a:hover {
|
||||
opacity: 0.7;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main>
|
||||
<?= $svg ?>
|
||||
</main>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
7
www/blog/0.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"links": {
|
||||
"google": "https://google.com",
|
||||
"handwritten.blog": "https://handwritten.blog",
|
||||
"blog-lehnert.dev": "mailto:blog@lehnert.dev"
|
||||
}
|
||||
}
|
20490
www/blog/0.svg
Normal file
After Width: | Height: | Size: 1.6 MiB |
135
www/error.php
Normal file
@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/lib/_index.php';
|
||||
|
||||
$code = 500;
|
||||
|
||||
if (isset($_GET['code'])) {
|
||||
$code = (int) $_GET['code'];
|
||||
}
|
||||
|
||||
$msg = '🪐 Unknown error! Something went wrong in the fabric of spacetime.';
|
||||
$action = 'Stabilize systems';
|
||||
|
||||
$dest = $_SERVER['REQUEST_URI'] ?? '/';
|
||||
|
||||
|
||||
switch ($code) {
|
||||
case 400:
|
||||
$msg = '🛰️ Bad request! Your signal got scrambled mid-transmission—packet lost in space.';
|
||||
$action = 'Resend request';
|
||||
break;
|
||||
|
||||
case 401:
|
||||
$msg = '🔒 Unauthorized! You need proper credentials to dock with this system.';
|
||||
$action = 'Initiate login';
|
||||
$dest = '/login';
|
||||
break;
|
||||
|
||||
case 403:
|
||||
$msg = '🚫 Forbidden! This space sector is read-only for your clearance level.';
|
||||
$action = 'Return to ship';
|
||||
$dest = '/';
|
||||
break;
|
||||
|
||||
case 404:
|
||||
$msg = '🛸 Page not found! It might’ve been abducted or deleted by rogue AIs.';
|
||||
$action = 'Beam me back';
|
||||
$dest = '/';
|
||||
break;
|
||||
|
||||
case 500:
|
||||
$msg = '💥 System failure! The mainframe just had a meltdown and is crying in binary 😢 (01001100...).';
|
||||
$action = 'Reboot core';
|
||||
break;
|
||||
|
||||
case 501:
|
||||
$msg = '🧪 Not implemented! This function is still in alpha testing on Mars.';
|
||||
$action = 'Go back safely';
|
||||
break;
|
||||
|
||||
case 502:
|
||||
$msg = '🌐 Bad gateway! The relay between galaxies misrouted your request.';
|
||||
$action = 'Retry transmission';
|
||||
break;
|
||||
|
||||
case 503:
|
||||
$msg = '☕ Offline! Our servers are recharging on the dark side of the moon.';
|
||||
$action = 'Check back soon';
|
||||
break;
|
||||
}
|
||||
|
||||
?><!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link rel="shortcut icon" href="/favicon.svg" type="image/x-icon">
|
||||
|
||||
<title>Oops!</title>
|
||||
|
||||
<style>
|
||||
<?= default_styles() ?>
|
||||
<?= common_styles() ?>
|
||||
|
||||
main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 80vh;
|
||||
color: white;
|
||||
text-align: center;
|
||||
font-family: "Inter", sans-serif;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 6rem;
|
||||
margin: 0;
|
||||
background: linear-gradient(90deg, #ff0066, #00ffff);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
animation: glitch 2s infinite;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1.25rem;
|
||||
margin: 1rem 0 2rem;
|
||||
color: #ccc;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
text-decoration: none;
|
||||
background: #00ffff;
|
||||
border: none;
|
||||
padding: 0.75rem 1.5rem;
|
||||
border-radius: 999px;
|
||||
font-size: 1rem;
|
||||
color: #1e1e2f;
|
||||
cursor: pointer;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background: #ff0066;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main>
|
||||
<h1><?= $code ?></h1>
|
||||
|
||||
<p><?= $msg ?></p>
|
||||
|
||||
<a class="btn" href="<?= $dest ?>"><?= $action ?></a>
|
||||
</main>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
82
www/imprint/index.php
Normal file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../lib/_index.php';
|
||||
|
||||
?><!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link rel="shortcut icon" href="/favicon.svg" type="image/x-icon">
|
||||
|
||||
<title>Privacy Policy</title>
|
||||
|
||||
<style>
|
||||
<?= default_styles() ?>
|
||||
<?= common_styles() ?>
|
||||
|
||||
main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 80vh;
|
||||
color: white;
|
||||
font-family: "Inter", sans-serif;
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
background: linear-gradient(90deg, #00ffff, #ff00ff);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
margin-bottom: 1rem;
|
||||
animation: glitch 2s infinite;
|
||||
}
|
||||
|
||||
.legal-section {
|
||||
text-align: left;
|
||||
max-width: 700px;
|
||||
margin: 2rem auto;
|
||||
padding: 1rem 2rem;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border-left: 4px solid #00ffff;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.legal-section p {
|
||||
font-size: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
color: #ccc;
|
||||
line-height: 1.6;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main>
|
||||
<h1>Impressum<br />Imprint</h1>
|
||||
<div class="legal-section">
|
||||
<p><b>Angaben gemäß § 5 TMG:</b></p>
|
||||
<p>
|
||||
Ludwig Lehnert <br />
|
||||
Zedernstr. 41 <br />
|
||||
90441 Nürnberg <br />
|
||||
Deutschland
|
||||
</p>
|
||||
<p>
|
||||
<b>Kontakt:</b> <br />
|
||||
<!-- Telefon: [Ihre Telefonnummer] <br /> -->
|
||||
E-Mail: info@lehnert.dev
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
159
www/index.php
Normal file
@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . "/lib/_index.php";
|
||||
|
||||
[$points, $edges, $sizes] = stars_random();
|
||||
|
||||
?><!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link rel="shortcut icon" href="/favicon.svg" type="image/x-icon">
|
||||
|
||||
<title>lehnert.dev</title>
|
||||
|
||||
<meta name="description" content="Welcome to my digital playground.">
|
||||
<meta name="keywords" content="Ludwig Lehnert,Nürnberg,Pegnitz,Nuremberg,Informatik,Computer,Copmuter Science" />
|
||||
|
||||
<style>
|
||||
<?= default_styles() ?>
|
||||
<?= common_styles() ?>
|
||||
<?= stars_styles() ?>
|
||||
|
||||
#stars-edges {
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
#stars-container {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 80vh;
|
||||
color: white;
|
||||
font-family: "Inter", sans-serif;
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.5rem;
|
||||
background: linear-gradient(90deg, #00ffff, #ff00ff);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
animation: glow 3s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1.2rem;
|
||||
max-width: 600px;
|
||||
margin-top: 1rem;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.social-links {
|
||||
display: flex;
|
||||
gap: 0.75rem;
|
||||
margin-top: 1.5rem;
|
||||
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.social-links a {
|
||||
padding: 0.75rem;
|
||||
font-size: 1rem;
|
||||
background: #00ffff;
|
||||
color: #1e1e2f;
|
||||
border: none;
|
||||
border-radius: 999px;
|
||||
cursor: pointer;
|
||||
transition: background 0.3s ease;
|
||||
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
.social-links a:hover {
|
||||
background: #ff00ff;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.legal-links {
|
||||
margin-top: 1rem;
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.legal-links a {
|
||||
color: rgb(255, 255, 255);
|
||||
cursor: pointer;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.legal-links a:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
|
||||
@keyframes glow {
|
||||
from {
|
||||
text-shadow: 0 0 10px #00ffff;
|
||||
}
|
||||
|
||||
to {
|
||||
text-shadow: 0 0 20px #ff00ff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<?= stars_edges_svg($points, $edges) ?>
|
||||
|
||||
<?= stars_container($points, $sizes) ?>
|
||||
|
||||
<script>
|
||||
<?= stars_script($points, $edges, $sizes) ?>
|
||||
</script>
|
||||
|
||||
<main style="position: relative; z-index: 2;">
|
||||
<h1>Hey, I'm Ludwig 🚀</h1>
|
||||
<p>Welcome to my digital playground.</p>
|
||||
|
||||
<div class="social-links">
|
||||
<a target="_blank" href="https://instagram.com/lehlud">
|
||||
<img src="/assets/instagram.svg" alt="" width="25" />
|
||||
</a>
|
||||
<a target="_blank" href="https://linkedin.com/in/ludwig-lehnert">
|
||||
<img src="/assets/linkedin.svg" alt="" width="25" />
|
||||
</a>
|
||||
<a target="_blank" href="mailto:info@lehnert.dev">
|
||||
<img src="/assets/email.svg" alt="" width="25" />
|
||||
</a>
|
||||
<a target="_blank" href="https://gitea.cloud.lehnert.dev/explore/repos">
|
||||
<img src="/assets/git.svg" alt="" width="25" />
|
||||
</a>
|
||||
<a target="_blank" href="https://github.com/lehlud">
|
||||
<img src="/assets/github.svg" alt="" width="25" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="legal-links">
|
||||
<a href="/imprint">Imprint</a>
|
||||
<a href="/privacy">Privacy Policy</a>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
|
||||
</html>
|
5
www/lib/_index.php
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/style.php';
|
||||
require_once __DIR__ . '/stars.php';
|
||||
require_once __DIR__ . '/fill.php';
|
41
www/lib/css/common.css
Normal file
@ -0,0 +1,41 @@
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes glitch {
|
||||
0% {
|
||||
text-shadow:
|
||||
2px 0 #ff00c8,
|
||||
-2px 0 #00fff9;
|
||||
}
|
||||
|
||||
25% {
|
||||
text-shadow:
|
||||
-2px 0 #ff00c8,
|
||||
2px 0 #00fff9;
|
||||
}
|
||||
|
||||
50% {
|
||||
text-shadow:
|
||||
2px 0 #00fff9,
|
||||
-2px 0 #ff00c8;
|
||||
}
|
||||
|
||||
75% {
|
||||
text-shadow:
|
||||
-1px 0 #00fff9,
|
||||
1px 0 #ff00c8;
|
||||
}
|
||||
|
||||
100% {
|
||||
text-shadow:
|
||||
2px 0 #ff00c8,
|
||||
-2px 0 #00fff9;
|
||||
}
|
||||
}
|
21
www/lib/css/default.css
Normal file
@ -0,0 +1,21 @@
|
||||
html,
|
||||
body {
|
||||
/* min-width: 100vw; */
|
||||
min-height: max(100%, 100vh);
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
background: linear-gradient(135deg,
|
||||
#1e1e2f 0,
|
||||
#252547 99vh,
|
||||
#252547 100vh);
|
||||
|
||||
max-width: 100vw;
|
||||
overflow-x: hidden;
|
||||
}
|
37
www/lib/css/stars.css
Normal file
@ -0,0 +1,37 @@
|
||||
#stars-edges {
|
||||
position: absolute;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
#stars-edges>* {
|
||||
transition-duration: 500ms;
|
||||
}
|
||||
|
||||
#stars-edges>*[opacity="1"] {
|
||||
animation: edgesStrokeColor 3s ease-in-out forwards;
|
||||
}
|
||||
|
||||
#stars-container {
|
||||
position: absolute;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
#stars-container>* {
|
||||
animation: fadeIn 1s forwards;
|
||||
transition-duration: 500ms;
|
||||
}
|
||||
|
||||
|
||||
@keyframes edgesStrokeColor {
|
||||
from {
|
||||
stroke: #00ffff;
|
||||
}
|
||||
|
||||
to {
|
||||
stroke: #ff00ff;
|
||||
}
|
||||
}
|
10
www/lib/fill.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
function fill_js(string $js, array $params = []): string
|
||||
{
|
||||
foreach ($params as $key => $value) {
|
||||
$js = str_replace('__' . $key . '__()', $value, $js);
|
||||
}
|
||||
|
||||
return $js;
|
||||
}
|
74
www/lib/js/stars.js
Normal file
@ -0,0 +1,74 @@
|
||||
const indices = __INDICES__();
|
||||
const points = __POINTS__();
|
||||
const edges = __EDGES__();
|
||||
const sizes = __SIZES__();
|
||||
|
||||
|
||||
const starsEdges = document.getElementById('stars-edges');
|
||||
const starsEdgesResize = () => {
|
||||
const w = starsEdges.clientWidth;
|
||||
const h = starsEdges.clientHeight;
|
||||
starsEdges.setAttribute('viewBox', `0 0 ${w} ${h}`);
|
||||
};
|
||||
starsEdgesResize();
|
||||
window.addEventListener('resize', starsEdgesResize);
|
||||
|
||||
const stars = [...indices];
|
||||
|
||||
document.querySelectorAll('#stars-container>*').forEach((star, i) => {
|
||||
const currEdges = indices.map((o) => {
|
||||
const [x, y] = (i > o) ? [o, i] : [i, o];
|
||||
return [document.getElementById(`${x}-${y}`), o];
|
||||
}).filter(([e]) => !!e);
|
||||
|
||||
stars[i] = [star, currEdges];
|
||||
});
|
||||
|
||||
stars.forEach(([star, edges]) => {
|
||||
star.addEventListener('mouseenter', () => {
|
||||
edges.forEach(([edge]) => {
|
||||
edge.setAttribute('opacity', '1');
|
||||
});
|
||||
});
|
||||
|
||||
star.addEventListener('mouseleave', () => {
|
||||
edges.forEach(([edge]) => {
|
||||
edge.setAttribute('opacity', '0');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function chooseRandom(arr) {
|
||||
return arr[Math.floor(Math.random() * arr.length)];
|
||||
}
|
||||
|
||||
|
||||
let lidx = 0;
|
||||
const activeEdges = [];
|
||||
setInterval(() => {
|
||||
if (Math.random() < 0.3) return;
|
||||
if (Math.random() < 0.03) lidx = chooseRandom(indices);
|
||||
|
||||
let iter = 0;
|
||||
while (iter++ < 300) {
|
||||
const [, ledges] = stars[lidx];
|
||||
|
||||
let edge, nidx, iter2 = 0;
|
||||
do {
|
||||
[edge, nidx] = chooseRandom(ledges);
|
||||
} while ((edge === undefined || activeEdges.includes(edge)) && iter2++ < 100);
|
||||
|
||||
activeEdges.push(edge);
|
||||
|
||||
edge.setAttribute("opacity", "1");
|
||||
setTimeout(() => {
|
||||
edge.setAttribute("opacity", "0");
|
||||
activeEdges.splice(activeEdges.indexOf(edge), 1);
|
||||
}, 4500 + Math.random() * 2500);
|
||||
|
||||
lidx = nidx;
|
||||
return;
|
||||
}
|
||||
}, 650);
|
||||
|
||||
|
155
www/lib/stars.php
Normal file
@ -0,0 +1,155 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/_index.php';
|
||||
|
||||
function random_float()
|
||||
{
|
||||
return mt_rand() / mt_getrandmax();
|
||||
}
|
||||
|
||||
function choose_random(array $a)
|
||||
{
|
||||
return $a[mt_rand() % count($a)];
|
||||
}
|
||||
|
||||
|
||||
function new_edges()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
function has_edge(array $edges, array $edge)
|
||||
{
|
||||
foreach ($edges as $e) {
|
||||
if ($e[0] === $edge[0] && $e[1] === $edge[1])
|
||||
return true;
|
||||
if ($e[1] === $edge[0] && $e[0] === $edge[1])
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function add_edge(array &$edges, array $edge)
|
||||
{
|
||||
if (has_edge($edges, $edge))
|
||||
return;
|
||||
|
||||
array_push($edges, $edge);
|
||||
}
|
||||
|
||||
|
||||
function stars_distance(array $a, array $b)
|
||||
{
|
||||
return sqrt(pow($a[0] - $b[0], 2) + pow($a[1] - $b[1], 2)) / sqrt(2);
|
||||
}
|
||||
|
||||
function stars_random(int $amount = 50)
|
||||
{
|
||||
$indices = range(0, $amount - 1);
|
||||
|
||||
$points = array_map(function () {
|
||||
return [
|
||||
round(max(0.02, min(0.98, random_float())), 3),
|
||||
round(max(0.02, min(0.98, random_float())), 3),
|
||||
];
|
||||
}, $indices);
|
||||
|
||||
$sizes = array_map(function () {
|
||||
return round(0.5 + random_float() * 1.2, 3);
|
||||
}, $indices);
|
||||
|
||||
$edges = new_edges();
|
||||
|
||||
foreach ($indices as $i) {
|
||||
$choosable = $indices;
|
||||
usort($choosable, function ($a, $b) use ($points, $i) {
|
||||
$cmp = stars_distance($points[$i], $points[$a]) - stars_distance($points[$i], $points[$b]);
|
||||
if ($cmp < 0)
|
||||
return -1;
|
||||
if ($cmp > 0)
|
||||
return 1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
$choosable = array_slice($choosable, 0, 10);
|
||||
|
||||
$max = 2 + mt_rand() % 2;
|
||||
for ($j = 0; $j < $max; $j++) {
|
||||
$o = $i;
|
||||
|
||||
$iter = 0;
|
||||
while ($o === $i || has_edge($edges, [$i, $o])) {
|
||||
$o = choose_random($choosable);
|
||||
if ($iter++ > 100)
|
||||
break;
|
||||
}
|
||||
|
||||
if ($iter <= 100)
|
||||
add_edge($edges, [$i, $o]);
|
||||
}
|
||||
}
|
||||
|
||||
return [$points, $edges, $sizes];
|
||||
}
|
||||
|
||||
function stars_container(array $points, array $sizes)
|
||||
{
|
||||
$html = '<div id="stars-container" aria-hidden="true">';
|
||||
|
||||
$count = count($points);
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$width = 'max(' . $sizes[$i] . 'vw, ' . $sizes[$i] . 'vh)';
|
||||
$left = ($points[$i][0] * 100) . 'vw';
|
||||
$top = ($points[$i][1] * 100) . 'vh';
|
||||
$html .= "<img src=\"/assets/star.svg\" style=\"position: absolute; width: $width; left: $left; top: $top; translate: -50% -50%;\" />";
|
||||
}
|
||||
|
||||
$html .= '</div>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
function stars_edges_svg(array $points, array $edges)
|
||||
{
|
||||
$html = '<svg id="stars-edges" aria-hidden="true">';
|
||||
|
||||
foreach ($edges as [$a, $b]) {
|
||||
if ($a > $b) {
|
||||
$tmp = $a;
|
||||
$a = $b;
|
||||
$b = $tmp;
|
||||
}
|
||||
|
||||
[$x1, $y1] = $points[$a];
|
||||
[$x2, $y2] = $points[$b];
|
||||
|
||||
$x1 *= 100;
|
||||
$y1 *= 100;
|
||||
$x2 *= 100;
|
||||
$y2 *= 100;
|
||||
|
||||
$html .= "<line id=\"$a-$b\" x1=\"$x1%\" y1=\"$y1%\" x2=\"$x2%\" y2=\"$y2%\" stroke=\"white\" stroke-width=\"1.5\" opacity=\"0\" />";
|
||||
}
|
||||
|
||||
$html .= '</svg>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function stars_script(array $points, array $edges, array $sizes)
|
||||
{
|
||||
$js = file_get_contents(__DIR__ . '/js/stars.js');
|
||||
|
||||
return fill_js($js, [
|
||||
'INDICES' => json_encode(range(0, count($points) - 1)),
|
||||
'POINTS' => json_encode($points),
|
||||
'EDGES' => json_encode($edges),
|
||||
'SIZES' => json_encode($sizes),
|
||||
]);
|
||||
}
|
||||
|
||||
function stars_styles()
|
||||
{
|
||||
return file_get_contents(__DIR__ . '/css/stars.css');
|
||||
}
|
11
www/lib/style.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
function default_styles()
|
||||
{
|
||||
return file_get_contents(__DIR__ . '/css/default.css');
|
||||
}
|
||||
|
||||
function common_styles()
|
||||
{
|
||||
return file_get_contents(__DIR__ . '/css/common.css');
|
||||
}
|
108
www/privacy/index.php
Normal file
@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../lib/_index.php';
|
||||
|
||||
?><!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link rel="shortcut icon" href="/favicon.svg" type="image/x-icon">
|
||||
|
||||
<title>Privacy Policy</title>
|
||||
|
||||
<style>
|
||||
<?= default_styles() ?>
|
||||
<?= common_styles() ?>
|
||||
|
||||
main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 80vh;
|
||||
color: white;
|
||||
font-family: "Inter", sans-serif;
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
background: linear-gradient(90deg, #00ffff, #ff00ff);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
margin-bottom: 1rem;
|
||||
animation: glitch 2s infinite;
|
||||
}
|
||||
|
||||
.legal-section {
|
||||
text-align: left;
|
||||
max-width: 700px;
|
||||
margin: 2rem auto;
|
||||
padding: 1rem 2rem;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border-left: 4px solid #00ffff;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.legal-section p {
|
||||
font-size: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
color: #ccc;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
a {
|
||||
color: white;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main>
|
||||
<h1>Datenschutzerklärung<br />Privacy Policy</h1>
|
||||
<div class="legal-section">
|
||||
<p><strong>Deutsch:</strong></p>
|
||||
<p>
|
||||
Wir nehmen den Schutz Ihrer persönlichen Daten sehr ernst. Beim
|
||||
Besuch dieser Website werden automatisch Server-Logfiles erfasst
|
||||
(z.B. IP-Adresse, Uhrzeit des Zugriffs), die zur Gewährleistung des
|
||||
Betriebs und zur Sicherheit der Website notwendig sind. Diese Daten
|
||||
werden für maximal 90 Tage gespeichert und danach automatisch
|
||||
gelöscht.
|
||||
</p>
|
||||
<p>
|
||||
Diese Website wird über die Hetzner Cloud gehostet. Es gelten
|
||||
zusätzlich die Datenschutzbestimmungen der Hetzner Online GmbH: <a
|
||||
href="https://www.hetzner.com/de/legal/privacy-policy/" target="_blank">Hetzner
|
||||
Datenschutzerklärung</a>.
|
||||
</p>
|
||||
|
||||
<p><strong>English:</strong></p>
|
||||
<p>
|
||||
We take the protection of your personal data very seriously. When
|
||||
visiting this website, server log files (e.g. IP address, access
|
||||
time) are automatically collected for the purpose of operation and
|
||||
security. These logs are stored for a maximum of 90 days and then
|
||||
automatically deleted.
|
||||
</p>
|
||||
<p>
|
||||
This website is hosted via Hetzner Cloud. The privacy policy of
|
||||
Hetzner Online GmbH also applies: <a href="https://www.hetzner.com/legal/privacy-policy"
|
||||
target="_blank">Hetzner Privacy Policy</a>.
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|