3 Commits

Author SHA1 Message Date
Moritz Utcke
9552a678c3 Style Update 2025-04-09 20:11:57 -04:00
Jens Cornelsen
856c194a02 Dashboard Mockup 2025-04-10 00:18:13 +02:00
Jens Cornelsen
afc561b701 Auto stash before rebase of "main" onto "origin/main" 2025-04-08 13:05:09 +02:00
299 changed files with 24730 additions and 49943 deletions

3
.crontab Normal file
View File

@@ -0,0 +1,3 @@
# Jeden Monat müssen wir die neuen Klimafaktoren vom DWD abholen, der Cronjob läuft immer am 28. für die höchste Wahrscheinlichkeit
# dass die Daten schon da sind, falls der DWD mal später dran ist...
0 12 28 * * bun ./src/cronjobs/update-dwd-klimafaktoren.ts

2
.env
View File

@@ -4,8 +4,6 @@
# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings
SECRET="jg57cya4mrNkGlnb2R85X1gI8LdY7iNZ9MF0Jbn0K5zQBshOxv"
POSTGRES_DB=main
POSTGRES_HOST=localhost
POSTGRES_PORT=5432

View File

@@ -1,8 +1,10 @@
name: Development Pipeline
name: Dev Pipeline
on:
pull_request:
branches: [main]
push:
branches: [dev]
branches: [main]
jobs:
deploy:
@@ -24,8 +26,8 @@ jobs:
export PATH=$HOME/.nvm/versions/node/v22.14.0/bin:$PATH
echo $PATH
cd ~/online-energieausweis
git reset --hard origin/dev
git reset --hard origin/main
git clean -f -d
git pull origin dev
git pull origin main
git status
make prod-no-backup
make prod

View File

@@ -1,18 +0,0 @@
name: Enforce PR Source
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
branches:
- main
jobs:
check-pr-source:
runs-on: ubuntu-latest
steps:
- name: Enforce only staging → main
run: |
if [[ "${{ github.head_ref }}" != "staging" ]]; then
echo "ERROR: Only 'staging' branch may create PRs into 'main'!"
exit 1
fi

View File

@@ -1,28 +0,0 @@
name: PR Rules Enforcement
on:
pull_request:
branches:
- main
- staging
jobs:
check-pr:
runs-on: ubuntu-latest
name: Validate Pull Request Sources
steps:
- name: Prevent dev merges
run: |
if [[ "${{ github.head_ref }}" == "dev" && "${{ github.base_ref }}" == "main" ]]; then
echo "ERROR: Merging 'dev' into 'main' is forbidden!"
exit 1
fi
- name: Allow only staging into main
if: github.base_ref == 'main'
run: |
if [[ "${{ github.head_ref }}" != "staging" ]]; then
echo "ERROR: Only 'staging' branch is allowed to merge into 'main'. Current: '${{ github.head_ref }}'"
exit 1
fi

View File

@@ -1,68 +0,0 @@
name: Production Pipeline
on:
push:
branches: [main]
jobs:
check-migrations:
name: Check for new Prisma migrations
runs-on: ubuntu-latest
outputs:
has_new_migrations: ${{ steps.diff.outputs.has_new_migrations }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # get full history so git diff works properly
- name: Detect new migration files
id: diff
run: |
# Compare the last two commits on main
if git diff --quiet HEAD~1 -- prisma/migrations/; then
echo "✅ No new Prisma migrations detected."
echo "has_new_migrations=false" >> $GITHUB_OUTPUT
else
echo "⚠️ New Prisma migrations detected! Blocking deployment."
echo "has_new_migrations=true" >> $GITHUB_OUTPUT
fi
deploy:
name: Deploy to production
runs-on: ubuntu-latest
needs: check-migrations
if: needs.check-migrations.outputs.has_new_migrations == 'false'
steps:
- uses: actions/checkout@v2
- name: Install Bun
run: |
curl -fsSL https://bun.sh/install | bash
- uses: appleboy/ssh-action@master
with:
host: ${{ secrets.PROD_HOST }}
username: ${{ secrets.PROD_USERNAME }}
password: ${{ secrets.PROD_PASSWORD }}
port: 22
script: |
export PATH=$HOME/.bun/bin:$PATH
export PATH=$HOME/.nvm/versions/node/v22.14.0/bin:$PATH
echo $PATH
cd ~/online-energieausweis
git reset --hard origin/main
git clean -f -d
git pull origin main
git status
make prod
block-deploy:
name: Block deployment (new migrations detected)
runs-on: ubuntu-latest
needs: check-migrations
if: needs.check-migrations.outputs.has_new_migrations == 'true'
steps:
- name: Stop deploy
run: |
echo "🚫 Deployment blocked because new Prisma migrations were detected."
echo "Please apply migrations on staging and verify before deploying to production."
exit 1

4
.gitignore vendored
View File

@@ -15,8 +15,6 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
error.log*
combined.log*
# lockfile
pnpm-lock.yaml
@@ -36,7 +34,7 @@ dbml/schema.dbml
prisma/migrations/20250315143314_/migration.sql
# src/astro-typesafe-api-caller.ts
src/astro-typesafe-api-caller.ts
src/testing/ausweise.csv
src/testing/users.csv

39
.ssh/id_rsa Normal file
View File

@@ -0,0 +1,39 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAzUGXt3GYcT3344iWGGGcgL0zDKhkrieikZ+yqzDpLuEzRwu3epuT
mvmHpT45awHyWr6pgOPpD7MGSDo13BVRAjCapYC23RL87E3ZRaH6aezVtV+tjl6vcCRtQx
4uQWOtGzV8Mi84ErBxt3xKo19ieyVoJnJig9W7oLbf46I0/3Jz31SRQokfoDc7TFHrtVE2
1UZgxNuDfKMhMsBaZcPNP+Rbpcs7s8Bd3Q1PfrbA6bTGGa4DYAR5Hgm+z/FMcu1PSrAA4f
x+YxQrgNC4TNl8T3HSsGnnthNoQMCcl3LcAiy0C1JaWqXWGjYwawnfUdgB2nhb9i5t+yvb
T/UL1+obIhJRx9EaK4CScNraa0ZWmawl/NY6Dumvly8OpeUwMaynsZEFPEZVxdXFUHVRLR
74NGx23sq6qPYZuy5bFhbPJqIXsh2Pl6gvFE6HZcm5U6jgJOaHt98MSFIkILtWeab0cSmC
Aokt8XF+/ezu37mbEvNzCNZpFYG9d6MXuK5HOG0xAAAFqMTKAD/EygA/AAAAB3NzaC1yc2
EAAAGBAM1Bl7dxmHE99+OIlhhhnIC9MwyoZK4nopGfsqsw6S7hM0cLt3qbk5r5h6U+OWsB
8lq+qYDj6Q+zBkg6NdwVUQIwmqWAtt0S/OxN2UWh+mns1bVfrY5er3AkbUMeLkFjrRs1fD
IvOBKwcbd8SqNfYnslaCZyYoPVu6C23+OiNP9yc99UkUKJH6A3O0xR67VRNtVGYMTbg3yj
ITLAWmXDzT/kW6XLO7PAXd0NT362wOm0xhmuA2AEeR4Jvs/xTHLtT0qwAOH8fmMUK4DQuE
zZfE9x0rBp57YTaEDAnJdy3AIstAtSWlql1ho2MGsJ31HYAdp4W/Yubfsr20/1C9fqGyIS
UcfRGiuAknDa2mtGVpmsJfzWOg7pr5cvDqXlMDGsp7GRBTxGVcXVxVB1US0e+DRsdt7Kuq
j2GbsuWxYWzyaiF7Idj5eoLxROh2XJuVOo4CTmh7ffDEhSJCC7Vnmm9HEpggKJLfFxfv3s
7t+5mxLzcwjWaRWBvXejF7iuRzhtMQAAAAMBAAEAAAGAOgLIWPHzlknf1kCDv2dTHrWaiI
DNV8Ve9o5upmCf/v5qCjHfDPmMibftpP/FpZ86unf5mzKO6796zo4ZK9cgeqB3DMCorinQ
Lw8/kaUai7aCngzpFfxf1C+Pa/FLPHLp+W8v51UeIXYZ5bRsuejbAhgL7BXXDxCow178Py
9YkDvuUNfraCUuOY9ypHrgxfGqsDOAZRLvghnu55Oi2PEygNTPLDgY6xA61x+McLFBK6xK
cvaSAKCzBJDXi5jUtQSpqykEpPSQHnD1PvbsLWIJoaolhaew9gv0ADu3iVIWFLeBMAuwQB
N6fWRjJBT3hD9vmQ39OOCDkbpoATugAu3EOvY9pGLzN0Xf1Epc71eHLJj79hDC4H7Brz7A
bOmkUNFtLOZR4ZoHfpm8N3taZ7IdXX/PA3VLCh9qhbFcaUp3uTpXRxTSvHBL03Gl/BQY19
23FevrBH4GobkMpRVCWFFLawC4e9GPPB2QvQAq19W4RvoKmrOZCAa+VoKZKzCsLqG7AAAA
wA9sQSy5+KfXVrkQOaF8OrEBI4g2yd8Q3RNpGMVIWfFtKIL1CCht9UxaOnJC7r/xos9Y6H
LVnMB9tozQTFf0R3S8H90AAyS6uEzuW6BWDwbQBJvmkPL8gG/AszZWJU9JBfiAHvaWM00A
QwzIv2+veCA2TcYIKhyiXg8r6fOQNLYkSYPpasycJy0nFknCC5Ma6XBgdzHm8QGSD4NfTZ
jbO+uK2z5ZzM+BUprj4Af3vOXqiDD66aZbKdcwzcTRLVy/rgAAAMEA8B/4ilNBG7Z/sYGB
zcBz52dkCG4tfsiY1dDYqEsDnLxF39giZj7Q0yLOHf52lt4GVEneCa5v8Q8jnN6zHZHt9A
C4P6DxtD/D28CGF3smMw6ai+W7fsl1OgEIYfSA9iKzh+sA3egSakiqKAk4H9soE9ZgERkx
cFuDljNGk+cekdzizpE2bmHfx4FscBcJxlZAeI35jSV5u6wzIkB2W13bq8nEI8VRu/n+PV
luxwuy6B5bUfuUDxL9W9Wr9P8t9mkHAAAAwQDa03teSRCRU/ymaua+sv3ysIDOUeSb09vf
8wX9xQpFq50CM99S3bGnwWk4A66JlK70rfWb3yoo5+Bmi22VRckQbhFhGBSWjnkKtAz5Mo
dXHOlcfPcXtxpOW4xwCsoNhnwaELt09b2BjkwWl5gdYUPHs2rIhSupK3otFN5j5GuVd6gf
bSuqavru4Xi5sySWyhKX2y+FkCDeNeOkIFeA12NNvoF4w+osLoz4GLdtydEhwSXUP9U+mr
lRqC1/Jc8qggcAAAAxbW9yaXR6QG1vcml0ei1BU1VTLVRVRi1HYW1pbmctQTE1LUZBNTA3
TlYtRkE1MDdOVgEC
-----END OPENSSH PRIVATE KEY-----

1
.ssh/id_rsa.pub Normal file
View File

@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDNQZe3cZhxPffjiJYYYZyAvTMMqGSuJ6KRn7KrMOku4TNHC7d6m5Oa+YelPjlrAfJavqmA4+kPswZIOjXcFVECMJqlgLbdEvzsTdlFofpp7NW1X62OXq9wJG1DHi5BY60bNXwyLzgSsHG3fEqjX2J7JWgmcmKD1bugtt/jojT/cnPfVJFCiR+gNztMUeu1UTbVRmDE24N8oyEywFplw80/5FulyzuzwF3dDU9+tsDptMYZrgNgBHkeCb7P8Uxy7U9KsADh/H5jFCuA0LhM2XxPcdKwaee2E2hAwJyXctwCLLQLUlpapdYaNjBrCd9R2AHaeFv2Lm37K9tP9QvX6hsiElHH0RorgJJw2tprRlaZrCX81joO6a+XLw6l5TAxrKexkQU8RlXF1cVQdVEtHvg0bHbeyrqo9hm7LlsWFs8moheyHY+XqC8UTodlyblTqOAk5oe33wxIUiQgu1Z5pvRxKYICiS3xcX797O7fuZsS83MI1mkVgb13oxe4rkc4bTE= moritz@moritz-ASUS-TUF-Gaming-A15-FA507NV-FA507NV

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
.PHONY: dev online-energieausweis all prod backup run-database build-database install-dependencies wait-for-database prod database prisma-studio backup-database-cronjob update-dwd-klimafaktoren-cron
.PHONY: dev online-energieausweis all prod backup run-database build-database install-dependencies wait-for-database prod database prisma-studio backup-database-cronjob
DB_CONTAINER_NAME := database
DB_NAME := main
@@ -10,7 +10,7 @@ PERSISTENT_DIR := $(HOME)/persistent/$(APP_NAME)
BACKUP_FILENAME := $(HOME)/backups/$(shell date +"%Y-%m-%d_%H-%M-%S").sql.gz
online-energieausweis:
NODE_ENV="development" bun run dev --host
bun run dev --host
dev: database online-energieausweis
@@ -30,10 +30,6 @@ run-database: stop-database
docker volume create $(DB_VOLUME)
docker build -t $(DB_CONTAINER_NAME) .
docker run -d --name $(DB_CONTAINER_NAME) \
--log-driver=json-file \
--log-opt max-size=50m \
--log-opt max-file=3 \
--restart=always \
-e POSTGRES_USER=$(DB_USER) \
-e POSTGRES_PASSWORD=$(DB_PASSWORD) \
-p $(DB_PORT):5432 \
@@ -45,7 +41,7 @@ stop-database:
- docker stop $(DB_CONTAINER_NAME)
- docker rm $(DB_CONTAINER_NAME)
wait-for-database:
wait-fordatabase:
@while ! docker exec $(DB_CONTAINER_NAME) pg_isready -U $(DB_USER) -h localhost -p $(DB_PORT) > /dev/null 2>&1; do \
sleep 1; \
done
@@ -61,13 +57,7 @@ all:
mkdir -p ~/logs
bun run dev 2>&1 | tee ~/logs/`date '+%d-%m-%Y_%H:%M:%S'`.log
update-dwd-klimafaktoren-cron:
- pm2 delete update-dwd-klimafaktoren-cron
pm2 start --no-autorestart bun --name "update-dwd-klimafaktoren-cron" --cron "0 12 28 * *" -- src/cronjobs/update-dwd-klimafaktoren.ts
prod: prod-no-backup backup-database-cronjob
prod-no-backup: install-dependencies prisma-studio update-dwd-klimafaktoren-cron
prod: install-dependencies prisma-studio backup-database-cronjob
bun run build
mkdir -p ~/logs
mkdir -p ~/persistent/online-energieausweis
@@ -78,4 +68,4 @@ prod-no-backup: install-dependencies prisma-studio update-dwd-klimafaktoren-cron
backup-database-cronjob:
- pm2 delete daily-db-backup
pm2 start bash --name "daily-db-backup" --no-autorestart --cron "0 0 * * *" -- backup-database.bash
pm2 start backup-database.bash --name "daily-db-backup" --cron "0 0 * * *"

View File

@@ -5,9 +5,6 @@ import tailwind from "@astrojs/tailwind";
import node from "@astrojs/node";
import mdx from "@astrojs/mdx";
import astroTypesafeAPI from "astro-typesafe-api"
import { logger } from "./src/lib/logger";
logger.info("Astro config loaded");
// https://astro.build/config
export default defineConfig({

View File

@@ -1,33 +1,20 @@
#!/bin/bash
if [[ -z "$prev_restart_delay" && -n "$cron_restart" ]]; then
echo "skipping initial launch...."
exit 0
fi
FILE_NAME=data-dump_`date +%Y-%m-%d"_"%H_%M_%S`.sql.br
FILE_NAME_COMPLETE=full-dump_`date +%Y-%m-%d"_"%H_%M_%S`.sql.br
DATABASE_NAME=database
# Wir exportieren die Datenbank und komprimieren sie.
docker exec -t online-energieausweis-database-1 pg_dump --data-only -U main main | brotli --best > $FILE_NAME
docker exec -t online-energieausweis-database-1 pg_dumpall -c -U main | brotli --best > $FILE_NAME_COMPLETE
# Das wird benötigt für AWS Ionos Kompatibilität.
export AWS_REQUEST_CHECKSUM_CALCULATION=when_required
export AWS_RESPONSE_CHECKSUM_VALIDATION=when_required
# Wir exportieren die Datenbank und komprimieren sie.
# IMPORTANT: Dieser Befehl benötigt das `ionos` Profil, sonst wird er nicht funktionieren.
# Das Profil kann mit `aws configure --profile ionos` erstellt werden.
# Den Key dafür findet man auf https://dcd.ionos.com/latest/?lang=en#/key-management
docker exec -t $DATABASE_NAME pg_dump --data-only -U main main | brotli --quality=3 > $FILE_NAME
aws s3 cp $FILE_NAME s3://ibc-db-backup/ --profile ionos --endpoint-url https://s3.eu-central-3.ionoscloud.com --storage-class STANDARD
echo "Uploaded $FILE_NAME"
docker exec -t $DATABASE_NAME pg_dumpall -c -U main | brotli --quality=3 > $FILE_NAME_COMPLETE
aws s3 cp $FILE_NAME_COMPLETE s3://ibc-db-backup/ --profile ionos --endpoint-url https://s3.eu-central-3.ionoscloud.com --storage-class STANDARD
echo "Uploaded $FILE_NAME_COMPLETE"
aws s3 cp $FILE_NAME s3://ibc-db-backup/ --profile ionos --endpoint-url https://s3-eu-central-1.ionoscloud.com --storage-class STANDARD
aws s3 cp $FILE_NAME_COMPLETE s3://ibc-db-backup/ --profile ionos --endpoint-url https://s3-eu-central-1.ionoscloud.com --storage-class STANDARD
# Wir entfernen das Backup
rm $FILE_NAME

210
bun.lock
View File

@@ -15,11 +15,10 @@
"@pdfme/common": "^5.2.16",
"@pdfme/generator": "^5.2.16",
"@pdfme/ui": "^5.2.16",
"@svelte-plugins/datepicker": "^1.0.11",
"@trpc/client": "^10.45.2",
"@trpc/server": "^10.45.2",
"astro": "^4.16.17",
"astro-typesafe-api": "^0.2.4",
"astro-typesafe-api": "^0.2.2",
"body-scroll-lock": "^4.0.0-beta.0",
"buffer": "^6.0.3",
"bun": "^1.2.5",
@@ -27,8 +26,7 @@
"express": "^4.21.2",
"flag-icons": "^6.15.0",
"fontkit": "^2.0.4",
"handlebars": "^4.7.8",
"heic2any": "^0.0.4",
"highlight.run": "^9.14.0",
"is-base64": "^1.1.0",
"js-cookie": "^3.0.5",
"js-interpolate": "^1.3.2",
@@ -36,18 +34,16 @@
"jwt-decode": "^4.0.0",
"mime": "^4.0.6",
"moment": "^2.30.1",
"moment-timezone": "^0.6.0",
"moment-timezone": "^0.5.46",
"nodemailer": "^6.10.0",
"pdf-lib": "^1.17.1",
"postcss-nested": "^7.0.2",
"puppeteer": "^24.15.0",
"radix-svelte-icons": "^1.0.0",
"sass": "^1.83.4",
"sharp": "^0.33.5",
"siema": "^1.5.1",
"soap": "^1.1.8",
"sqids": "^0.3.0",
"ssh2-sftp-client": "^12.0.0",
"svelte": "^3.59.2",
"svelte-dialogs": "^1.2.2",
"svelte-preprocess": "^5.1.4",
@@ -55,7 +51,6 @@
"tailwindcss": "^3.4.17",
"trpc-openapi": "^1.2.0",
"uuid": "^9.0.1",
"winston": "^3.18.3",
"zod": "^3.24.1",
},
"devDependencies": {
@@ -72,7 +67,6 @@
"@types/nodemailer": "^6.4.17",
"@types/papaparse": "^5.3.15",
"@types/siema": "^1.4.11",
"@types/ssh2-sftp-client": "^9.0.4",
"@types/uuid": "^9.0.8",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
@@ -88,11 +82,11 @@
"postcss-import": "^16.1.0",
"postcss-nesting": "^13.0.1",
"prettier": "^2.8.8",
"prisma": "6.4.1",
"prisma": "^6.4.1",
"prisma-dbml-generator": "^0.12.0",
"prisma-generator-fake-data": "^0.14.3",
"tsx": "^4.19.3",
"typescript": "^5.8.3",
"typescript": "^5",
"zod-prisma": "^0.5.4",
},
},
@@ -257,7 +251,7 @@
"@cfcs/core": ["@cfcs/core@0.0.6", "", { "dependencies": { "@egjs/component": "^3.0.2" } }, "sha512-FxfJMwoLB8MEMConeXUCqtMGqxdtePQxRBOiGip9ULcYYam3WfCgoY6xdnMaSkYvRvmosp5iuG+TiPofm65+Pw=="],
"@colors/colors": ["@colors/colors@1.6.0", "", {}, "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA=="],
"@colors/colors": ["@colors/colors@1.5.0", "", {}, "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ=="],
"@csstools/selector-resolve-nested": ["@csstools/selector-resolve-nested@3.0.0", "", { "peerDependencies": { "postcss-selector-parser": "^7.0.0" } }, "sha512-ZoK24Yku6VJU1gS79a5PFmC8yn3wIapiKmPgun0hZgEI5AOqgH2kiPRsPz1qkGv4HL+wuDLH83yQyk6inMYrJQ=="],
@@ -269,8 +263,6 @@
"@cypress/xvfb": ["@cypress/xvfb@1.2.4", "", { "dependencies": { "debug": "^3.1.0", "lodash.once": "^4.1.1" } }, "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q=="],
"@dabh/diagnostics": ["@dabh/diagnostics@2.0.8", "", { "dependencies": { "@so-ric/colorspace": "^1.1.6", "enabled": "2.0.x", "kuler": "^2.0.0" } }, "sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q=="],
"@daybrush/utils": ["@daybrush/utils@1.13.0", "", {}, "sha512-ALK12C6SQNNHw1enXK+UO8bdyQ+jaWNQ1Af7Z3FNxeAwjYhQT7do+TRE4RASAJ3ObaS2+TJ7TXR3oz2Gzbw0PQ=="],
"@dnd-kit/accessibility": ["@dnd-kit/accessibility@3.1.1", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw=="],
@@ -525,8 +517,6 @@
"@proload/core": ["@proload/core@0.3.3", "", { "dependencies": { "deepmerge": "^4.2.2", "escalade": "^3.1.1" } }, "sha512-7dAFWsIK84C90AMl24+N/ProHKm4iw0akcnoKjRvbfHifJZBLhaDsDus1QJmhG12lXj4e/uB/8mB/0aduCW+NQ=="],
"@puppeteer/browsers": ["@puppeteer/browsers@2.10.6", "", { "dependencies": { "debug": "^4.4.1", "extract-zip": "^2.0.1", "progress": "^2.0.3", "proxy-agent": "^6.5.0", "semver": "^7.7.2", "tar-fs": "^3.1.0", "yargs": "^17.7.2" }, "bin": { "browsers": "lib/cjs/main-cli.js" } }, "sha512-pHUn6ZRt39bP3698HFQlu2ZHCkS/lPcpv7fVQcGBSzNNygw171UXAKrCUhy+TEMw4lEttOKDgNpb04hwUAJeiQ=="],
"@rc-component/async-validator": ["@rc-component/async-validator@5.0.4", "", { "dependencies": { "@babel/runtime": "^7.24.4" } }, "sha512-qgGdcVIF604M9EqjNF0hbUTz42bz/RDtxWdWuU5EQe3hi7M8ob54B6B35rOsvX5eSvIHIzT9iH1R3n+hk3CGfg=="],
"@rc-component/color-picker": ["@rc-component/color-picker@2.0.1", "", { "dependencies": { "@ant-design/fast-color": "^2.0.6", "@babel/runtime": "^7.23.6", "classnames": "^2.2.6", "rc-util": "^5.38.1" }, "peerDependencies": { "react": ">=16.9.0", "react-dom": ">=16.9.0" } }, "sha512-WcZYwAThV/b2GISQ8F+7650r5ZZJ043E57aVBFkQ+kSY4C6wdofXgB0hBx+GPGpIU0Z81eETNoDUJMr7oy/P8Q=="],
@@ -713,10 +703,6 @@
"@smithy/util-waiter": ["@smithy/util-waiter@4.0.2", "", { "dependencies": { "@smithy/abort-controller": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-piUTHyp2Axx3p/kc2CIJkYSv0BAaheBQmbACZgQSSfWUumWNW+R1lL+H9PDBxKJkvOeEX+hKYEFiwO8xagL8AQ=="],
"@so-ric/colorspace": ["@so-ric/colorspace@1.1.6", "", { "dependencies": { "color": "^5.0.2", "text-hex": "1.0.x" } }, "sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw=="],
"@svelte-plugins/datepicker": ["@svelte-plugins/datepicker@1.0.11", "", {}, "sha512-Tqc07QLyRkCpc3Glg6oRLTUApLtCrOh52d6vJ7L32QI17HrwvcDDjaH3LF3X1SBm3CWdMrnqfJp3xjUZmB4wzw=="],
"@sveltejs/vite-plugin-svelte": ["@sveltejs/vite-plugin-svelte@2.5.3", "", { "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^1.0.4", "debug": "^4.3.4", "deepmerge": "^4.3.1", "kleur": "^4.1.5", "magic-string": "^0.30.3", "svelte-hmr": "^0.15.3", "vitefu": "^0.2.4" }, "peerDependencies": { "svelte": "^3.54.0 || ^4.0.0 || ^5.0.0-next.0", "vite": "^4.0.0" } }, "sha512-erhNtXxE5/6xGZz/M9eXsmI7Pxa6MS7jyTy06zN3Ck++ldrppOnOlJwHHTsMC7DHDQdgUp4NAc4cDNQ9eGdB/w=="],
"@sveltejs/vite-plugin-svelte-inspector": ["@sveltejs/vite-plugin-svelte-inspector@1.0.4", "", { "dependencies": { "debug": "^4.3.4" }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^2.2.0", "svelte": "^3.54.0 || ^4.0.0", "vite": "^4.0.0" } }, "sha512-zjiuZ3yydBtwpF3bj0kQNV0YXe+iKE545QGZVTaylW3eAzFr+pJ/cwK8lZEaRp4JtaJXhD5DyWAV4AxLh6DgaQ=="],
@@ -725,8 +711,6 @@
"@tailwindcss/typography": ["@tailwindcss/typography@0.5.16", "", { "dependencies": { "lodash.castarray": "^4.4.0", "lodash.isplainobject": "^4.0.6", "lodash.merge": "^4.6.2", "postcss-selector-parser": "6.0.10" }, "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" } }, "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA=="],
"@tootallnate/quickjs-emscripten": ["@tootallnate/quickjs-emscripten@0.23.0", "", {}, "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA=="],
"@trpc/client": ["@trpc/client@10.45.2", "", { "peerDependencies": { "@trpc/server": "10.45.2" } }, "sha512-ykALM5kYWTLn1zYuUOZ2cPWlVfrXhc18HzBDyRhoPYN0jey4iQHEFSEowfnhg1RvYnrAVjNBgHNeSAXjrDbGwg=="],
"@trpc/server": ["@trpc/server@10.45.2", "", {}, "sha512-wOrSThNNE4HUnuhJG6PfDRp4L2009KDVxsd+2VYH8ro6o/7/jwYZ8Uu5j+VaW+mOmc8EHerHzGcdbGNQSAUPgg=="],
@@ -823,12 +807,6 @@
"@types/sizzle": ["@types/sizzle@2.3.9", "", {}, "sha512-xzLEyKB50yqCUPUJkIsrVvoWNfFUbIZI+RspLWt8u+tIW/BetMBZtgV2LY/2o+tYH8dRvQ+eoPf3NdhQCcLE2w=="],
"@types/ssh2": ["@types/ssh2@1.15.5", "", { "dependencies": { "@types/node": "^18.11.18" } }, "sha512-N1ASjp/nXH3ovBHddRJpli4ozpk6UdDYIX4RJWFa9L1YKnzdhTlVmiGHm4DZnj/jLbqZpes4aeR30EFGQtvhQQ=="],
"@types/ssh2-sftp-client": ["@types/ssh2-sftp-client@9.0.4", "", { "dependencies": { "@types/ssh2": "^1.0.0" } }, "sha512-gnIn56MTB9W3A3hPL/1sHI23t8YwcE3eVYa1O2XjT9vaqimFdtNHxyQiy5Y78+ociQTKazMSD8YyMEO4QjNMrg=="],
"@types/triple-beam": ["@types/triple-beam@1.3.5", "", {}, "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw=="],
"@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="],
"@types/uuid": ["@types/uuid@9.0.8", "", {}, "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA=="],
@@ -925,15 +903,13 @@
"assert-plus": ["assert-plus@1.0.0", "", {}, "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw=="],
"ast-types": ["ast-types@0.13.4", "", { "dependencies": { "tslib": "^2.0.1" } }, "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w=="],
"astral-regex": ["astral-regex@2.0.0", "", {}, "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ=="],
"astring": ["astring@1.9.0", "", { "bin": { "astring": "bin/astring" } }, "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg=="],
"astro": ["astro@4.16.18", "", { "dependencies": { "@astrojs/compiler": "^2.10.3", "@astrojs/internal-helpers": "0.4.1", "@astrojs/markdown-remark": "5.3.0", "@astrojs/telemetry": "3.1.0", "@babel/core": "^7.26.0", "@babel/plugin-transform-react-jsx": "^7.25.9", "@babel/types": "^7.26.0", "@oslojs/encoding": "^1.1.0", "@rollup/pluginutils": "^5.1.3", "@types/babel__core": "^7.20.5", "@types/cookie": "^0.6.0", "acorn": "^8.14.0", "aria-query": "^5.3.2", "axobject-query": "^4.1.0", "boxen": "8.0.1", "ci-info": "^4.1.0", "clsx": "^2.1.1", "common-ancestor-path": "^1.0.1", "cookie": "^0.7.2", "cssesc": "^3.0.0", "debug": "^4.3.7", "deterministic-object-hash": "^2.0.2", "devalue": "^5.1.1", "diff": "^5.2.0", "dlv": "^1.1.3", "dset": "^3.1.4", "es-module-lexer": "^1.5.4", "esbuild": "^0.21.5", "estree-walker": "^3.0.3", "fast-glob": "^3.3.2", "flattie": "^1.1.1", "github-slugger": "^2.0.0", "gray-matter": "^4.0.3", "html-escaper": "^3.0.3", "http-cache-semantics": "^4.1.1", "js-yaml": "^4.1.0", "kleur": "^4.1.5", "magic-string": "^0.30.14", "magicast": "^0.3.5", "micromatch": "^4.0.8", "mrmime": "^2.0.0", "neotraverse": "^0.6.18", "ora": "^8.1.1", "p-limit": "^6.1.0", "p-queue": "^8.0.1", "preferred-pm": "^4.0.0", "prompts": "^2.4.2", "rehype": "^13.0.2", "semver": "^7.6.3", "shiki": "^1.23.1", "tinyexec": "^0.3.1", "tsconfck": "^3.1.4", "unist-util-visit": "^5.0.0", "vfile": "^6.0.3", "vite": "^5.4.11", "vitefu": "^1.0.4", "which-pm": "^3.0.0", "xxhash-wasm": "^1.1.0", "yargs-parser": "^21.1.1", "zod": "^3.23.8", "zod-to-json-schema": "^3.23.5", "zod-to-ts": "^1.2.0" }, "optionalDependencies": { "sharp": "^0.33.3" }, "bin": { "astro": "astro.js" } }, "sha512-G7zfwJt9BDHEZwlaLNvjbInIw2hPryyD654314KV/XT34pJU6SfN1S+mWa8RAkALcZNJnJXCJmT3JXLQStD3Lw=="],
"astro-typesafe-api": ["astro-typesafe-api@0.2.4", "", { "dependencies": { "es-codec": "^0.5.0", "globby": "^14.0.2" }, "peerDependencies": { "astro": "^4.16.17", "typescript": "^5.0.0", "zod": "^3.24.1" }, "bin": { "astro-typesafe-api": "src/cli.ts" } }, "sha512-KiAw7+QJyuzz606GSkeaTdav8vttDUEYVaFAdVRlDuSvUdhcYsJB14zHkMe6ZSMfRNBQRxaMZBgPgEtWb1mf1w=="],
"astro-typesafe-api": ["astro-typesafe-api@0.2.2", "", { "dependencies": { "es-codec": "^0.5.0", "globby": "^14.0.2" }, "peerDependencies": { "astro": "^4.16.17", "typescript": "^5.0.0", "zod": "^3.24.1" }, "bin": { "astro-typesafe-api": "src/cli.ts" } }, "sha512-SEHV2iPyIrdpYdYb0mIN1WmcvC61bvsCQqb/X+R4EOcFjuozJ9fJhSiFGxJMvNoxJ9S3P3GKLyDnxXvFlKq0mw=="],
"async": ["async@3.2.6", "", {}, "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="],
@@ -957,30 +933,16 @@
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
"b4a": ["b4a@1.6.7", "", {}, "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg=="],
"babel-runtime": ["babel-runtime@6.26.0", "", { "dependencies": { "core-js": "^2.4.0", "regenerator-runtime": "^0.11.0" } }, "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g=="],
"bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="],
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"bare-events": ["bare-events@2.5.4", "", {}, "sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA=="],
"bare-fs": ["bare-fs@4.1.3", "", { "dependencies": { "bare-events": "^2.5.4", "bare-path": "^3.0.0", "bare-stream": "^2.6.4" }, "peerDependencies": { "bare-buffer": "*" }, "optionalPeers": ["bare-buffer"] }, "sha512-OeEZYIg+2qepaWLyphaOXHAHKo3xkM8y3BeGAvHdMN8GNWvEAU1Yw6rYpGzu/wDDbKxgEjVeVDpgGhDzaeMpjg=="],
"bare-os": ["bare-os@3.6.1", "", {}, "sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g=="],
"bare-path": ["bare-path@3.0.0", "", { "dependencies": { "bare-os": "^3.0.1" } }, "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw=="],
"bare-stream": ["bare-stream@2.6.5", "", { "dependencies": { "streamx": "^2.21.0" }, "peerDependencies": { "bare-buffer": "*", "bare-events": "*" }, "optionalPeers": ["bare-buffer", "bare-events"] }, "sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA=="],
"base-64": ["base-64@1.0.0", "", {}, "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg=="],
"base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
"basic-ftp": ["basic-ftp@5.0.5", "", {}, "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg=="],
"bcrypt-pbkdf": ["bcrypt-pbkdf@1.0.2", "", { "dependencies": { "tweetnacl": "^0.14.3" } }, "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w=="],
"binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="],
@@ -1013,10 +975,6 @@
"buffer-equal-constant-time": ["buffer-equal-constant-time@1.0.1", "", {}, "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="],
"buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="],
"buildcheck": ["buildcheck@0.0.6", "", {}, "sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A=="],
"bun": ["bun@1.2.5", "", { "optionalDependencies": { "@oven/bun-darwin-aarch64": "1.2.5", "@oven/bun-darwin-x64": "1.2.5", "@oven/bun-darwin-x64-baseline": "1.2.5", "@oven/bun-linux-aarch64": "1.2.5", "@oven/bun-linux-aarch64-musl": "1.2.5", "@oven/bun-linux-x64": "1.2.5", "@oven/bun-linux-x64-baseline": "1.2.5", "@oven/bun-linux-x64-musl": "1.2.5", "@oven/bun-linux-x64-musl-baseline": "1.2.5", "@oven/bun-windows-x64": "1.2.5", "@oven/bun-windows-x64-baseline": "1.2.5" }, "os": [ "linux", "win32", "darwin", ], "cpu": [ "x64", "arm64", ], "bin": { "bun": "bin/bun.exe", "bunx": "bin/bun.exe" } }, "sha512-fbQLt+DPiGUrPKdmsHRRT7cQAlfjdxPVFvLZrsUPmKiTdv+pU50ypdx9yRJluknSbyaZchFVV7Lx2KXikXKX2Q=="],
"bun-types": ["bun-types@1.2.2", "", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" } }, "sha512-RCbMH5elr9gjgDGDhkTTugA21XtJAy/9jkKe/G3WR2q17VPGhcquf9Sir6uay9iW+7P/BV0CAHA1XlHXMAVKHg=="],
@@ -1063,8 +1021,6 @@
"chownr": ["chownr@2.0.0", "", {}, "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="],
"chromium-bidi": ["chromium-bidi@7.2.0", "", { "dependencies": { "mitt": "^3.0.1", "zod": "^3.24.1" }, "peerDependencies": { "devtools-protocol": "*" } }, "sha512-gREyhyBstermK+0RbcJLbFhcQctg92AGgDe/h/taMJEOLRdtSswBAO9KmvltFSQWgM2LrwWu5SIuEUbdm3JsyQ=="],
"ci-info": ["ci-info@4.1.0", "", {}, "sha512-HutrvTNsF48wnxkzERIXOe5/mlcfFcbfCmwcg6CJnizbSue78AbDt+1cgl26zwn61WFxhcPykPfZrbqjGmBb4A=="],
"cjs-module-lexer": ["cjs-module-lexer@1.4.3", "", {}, "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q=="],
@@ -1083,8 +1039,6 @@
"cli-truncate": ["cli-truncate@2.1.0", "", { "dependencies": { "slice-ansi": "^3.0.0", "string-width": "^4.2.0" } }, "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg=="],
"cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="],
"clone": ["clone@2.1.2", "", {}, "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w=="],
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
@@ -1129,8 +1083,6 @@
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
"concat-stream": ["concat-stream@2.0.0", "", { "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.0.2", "typedarray": "^0.0.6" } }, "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A=="],
"consola": ["consola@3.4.0", "", {}, "sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA=="],
"console-control-strings": ["console-control-strings@1.1.0", "", {}, "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="],
@@ -1155,10 +1107,6 @@
"core-util-is": ["core-util-is@1.0.2", "", {}, "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="],
"cosmiconfig": ["cosmiconfig@9.0.0", "", { "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg=="],
"cpu-features": ["cpu-features@0.0.10", "", { "dependencies": { "buildcheck": "~0.0.6", "nan": "^2.19.0" } }, "sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA=="],
"crc-32": ["crc-32@1.2.2", "", { "bin": { "crc32": "bin/crc32.njs" } }, "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ=="],
"crc32-stream": ["crc32-stream@4.0.3", "", { "dependencies": { "crc-32": "^1.2.0", "readable-stream": "^3.4.0" } }, "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw=="],
@@ -1193,8 +1141,6 @@
"dashdash": ["dashdash@1.14.1", "", { "dependencies": { "assert-plus": "^1.0.0" } }, "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g=="],
"data-uri-to-buffer": ["data-uri-to-buffer@6.0.2", "", {}, "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw=="],
"date-fns": ["date-fns@4.1.0", "", {}, "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg=="],
"dayjs": ["dayjs@1.11.13", "", {}, "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="],
@@ -1215,8 +1161,6 @@
"defu": ["defu@6.1.4", "", {}, "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg=="],
"degenerator": ["degenerator@5.0.1", "", { "dependencies": { "ast-types": "^0.13.4", "escodegen": "^2.1.0", "esprima": "^4.0.1" } }, "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ=="],
"del": ["del@6.1.1", "", { "dependencies": { "globby": "^11.0.1", "graceful-fs": "^4.2.4", "is-glob": "^4.0.1", "is-path-cwd": "^2.2.0", "is-path-inside": "^3.0.2", "p-map": "^4.0.0", "rimraf": "^3.0.2", "slash": "^3.0.0" } }, "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg=="],
"delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
@@ -1245,8 +1189,6 @@
"devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="],
"devtools-protocol": ["devtools-protocol@0.0.1464554", "", {}, "sha512-CAoP3lYfwAGQTaAXYvA6JZR0fjGUb7qec1qf4mToyoH2TZgUFeIqYcjh6f9jNuhHfuZiEdH+PONHYrLhRQX6aw=="],
"dezalgo": ["dezalgo@1.0.4", "", { "dependencies": { "asap": "^2.0.0", "wrappy": "1" } }, "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig=="],
"dfa": ["dfa@1.2.0", "", {}, "sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q=="],
@@ -1283,8 +1225,6 @@
"emoji-regex-xs": ["emoji-regex-xs@1.0.0", "", {}, "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg=="],
"enabled": ["enabled@2.0.0", "", {}, "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="],
"encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="],
"end-of-stream": ["end-of-stream@1.4.4", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q=="],
@@ -1323,8 +1263,6 @@
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
"escodegen": ["escodegen@2.1.0", "", { "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0", "esutils": "^2.0.2" }, "optionalDependencies": { "source-map": "~0.6.1" }, "bin": { "esgenerate": "bin/esgenerate.js", "escodegen": "bin/escodegen.js" } }, "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w=="],
"eslint": ["eslint@8.15.0", "", { "dependencies": { "@eslint/eslintrc": "^1.2.3", "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", "espree": "^9.3.2", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", "globals": "^13.6.0", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "bin": { "eslint": "bin/eslint.js" } }, "sha512-GG5USZ1jhCu8HJkzGgeK8/+RGnHaNYZGrGDzUtigK3BsGESW/rs2az23XqE0WVwDxy1VRvvjSSGu5nB0Bu+6SA=="],
"eslint-config-prettier": ["eslint-config-prettier@8.1.0", "", { "peerDependencies": { "eslint": ">=7.0.0" }, "bin": { "eslint-config-prettier": "bin/cli.js" } }, "sha512-oKMhGv3ihGbCIimCAjqkdzx2Q+jthoqnXSP+d86M9tptwugycmTFdVR4IpLgq2c4SHifbwO90z2fQ8/Aio73yw=="],
@@ -1385,8 +1323,6 @@
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
"fast-fifo": ["fast-fifo@1.3.2", "", {}, "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ=="],
"fast-glob": ["fast-glob@3.3.3", "", { "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.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="],
"fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="],
@@ -1401,8 +1337,6 @@
"fd-slicer": ["fd-slicer@1.1.0", "", { "dependencies": { "pend": "~1.2.0" } }, "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g=="],
"fecha": ["fecha@4.2.3", "", {}, "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw=="],
"figures": ["figures@3.2.0", "", { "dependencies": { "escape-string-regexp": "^1.0.5" } }, "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg=="],
"file-entry-cache": ["file-entry-cache@6.0.1", "", { "dependencies": { "flat-cache": "^3.0.4" } }, "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg=="],
@@ -1427,8 +1361,6 @@
"flattie": ["flattie@1.1.1", "", {}, "sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ=="],
"fn.name": ["fn.name@1.1.0", "", {}, "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="],
"follow-redirects": ["follow-redirects@1.15.9", "", {}, "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ=="],
"fontkit": ["fontkit@2.0.4", "", { "dependencies": { "@swc/helpers": "^0.5.12", "brotli": "^1.3.2", "clone": "^2.1.2", "dfa": "^1.2.0", "fast-deep-equal": "^3.1.3", "restructure": "^3.0.0", "tiny-inflate": "^1.0.3", "unicode-properties": "^1.4.0", "unicode-trie": "^2.0.0" } }, "sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g=="],
@@ -1475,8 +1407,6 @@
"gesto": ["gesto@1.19.4", "", { "dependencies": { "@daybrush/utils": "^1.13.0", "@scena/event-emitter": "^1.0.2" } }, "sha512-hfr/0dWwh0Bnbb88s3QVJd1ZRJeOWcgHPPwmiH6NnafDYvhTsxg+SLYu+q/oPNh9JS3V+nlr6fNs8kvPAtcRDQ=="],
"get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
"get-east-asian-width": ["get-east-asian-width@1.3.0", "", {}, "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ=="],
"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=="],
@@ -1489,8 +1419,6 @@
"get-tsconfig": ["get-tsconfig@4.10.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A=="],
"get-uri": ["get-uri@6.0.4", "", { "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", "debug": "^4.3.4" } }, "sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ=="],
"getopts": ["getopts@2.3.0", "", {}, "sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA=="],
"getos": ["getos@3.2.1", "", { "dependencies": { "async": "^3.2.0" } }, "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q=="],
@@ -1519,8 +1447,6 @@
"h3": ["h3@1.14.0", "", { "dependencies": { "cookie-es": "^1.2.2", "crossws": "^0.3.2", "defu": "^6.1.4", "destr": "^2.0.3", "iron-webcrypto": "^1.2.1", "ohash": "^1.1.4", "radix3": "^1.1.2", "ufo": "^1.5.4", "uncrypto": "^0.1.3", "unenv": "^1.10.0" } }, "sha512-ao22eiONdgelqcnknw0iD645qW0s9NnrJHr5OBz4WOMdBdycfSas1EQf1wXRsm+PcB2Yoj43pjBPwqIpJQTeWg=="],
"handlebars": ["handlebars@4.7.8", "", { "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, "optionalDependencies": { "uglify-js": "^3.1.4" }, "bin": { "handlebars": "bin/handlebars" } }, "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ=="],
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
"has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
@@ -1555,10 +1481,10 @@
"hastscript": ["hastscript@9.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-parse-selector": "^4.0.0", "property-information": "^6.0.0", "space-separated-tokens": "^2.0.0" } }, "sha512-jzaLBGavEDKHrc5EfFImKN7nZKKBdSLIdGvCwDZ9TfzbF2ffXiov8CKE445L2Z1Ek2t/m4SKQ2j6Ipv7NyUolw=="],
"heic2any": ["heic2any@0.0.4", "", {}, "sha512-3lLnZiDELfabVH87htnRolZ2iehX9zwpRyGNz22GKXIu0fznlblf0/ftppXKNqS26dqFSeqfIBhAmAj/uSp0cA=="],
"hexoid": ["hexoid@2.0.0", "", {}, "sha512-qlspKUK7IlSQv2o+5I7yhUd7TxlOG2Vr5LTa3ve2XSNVKAL/n/u/7KLvKmFNimomDIKvZFXWHv0T12mv7rT8Aw=="],
"highlight.run": ["highlight.run@9.14.0", "", {}, "sha512-ZR+ZLHlVU8lXqsuto0ZEMAOuvptaTBBf1jradnKDIn9OfAXupcYFbkASDlbsZtyBh2SYJSK50xwrucXujhksRg=="],
"hosted-git-info": ["hosted-git-info@2.8.9", "", {}, "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw=="],
"hotkeys-js": ["hotkeys-js@3.13.9", "", {}, "sha512-3TRCj9u9KUH6cKo25w4KIdBfdBfNRjfUwrljCLDC2XhmPDG0SjAZFcFZekpUZFmXzfYoGhFDcdx2gX/vUVtztQ=="],
@@ -1615,8 +1541,6 @@
"intersection-observer": ["intersection-observer@0.12.2", "", {}, "sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg=="],
"ip-address": ["ip-address@9.0.5", "", { "dependencies": { "jsbn": "1.1.0", "sprintf-js": "^1.1.3" } }, "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g=="],
"ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="],
"iron-webcrypto": ["iron-webcrypto@1.2.1", "", {}, "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg=="],
@@ -1625,7 +1549,7 @@
"is-alphanumerical": ["is-alphanumerical@2.0.1", "", { "dependencies": { "is-alphabetical": "^2.0.0", "is-decimal": "^2.0.0" } }, "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw=="],
"is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="],
"is-arrayish": ["is-arrayish@0.3.2", "", {}, "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="],
"is-base64": ["is-base64@1.1.0", "", { "bin": { "is-base64": "bin/is-base64", "is_base64": "bin/is-base64" } }, "sha512-Nlhg7Z2dVC4/PTvIFkgVVNvPHSO2eR/Yd0XzhGiXCXEvWnptXlXa/clQ8aePPiMuxEGcWfzWbGw2Fe3d+Y3v1g=="],
@@ -1737,8 +1661,6 @@
"knex": ["knex@2.5.1", "", { "dependencies": { "colorette": "2.0.19", "commander": "^10.0.0", "debug": "4.3.4", "escalade": "^3.1.1", "esm": "^3.2.25", "get-package-type": "^0.1.0", "getopts": "2.3.0", "interpret": "^2.2.0", "lodash": "^4.17.21", "pg-connection-string": "2.6.1", "rechoir": "^0.8.0", "resolve-from": "^5.0.0", "tarn": "^3.0.2", "tildify": "2.0.0" }, "bin": { "knex": "bin/cli.js" } }, "sha512-z78DgGKUr4SE/6cm7ku+jHvFT0X97aERh/f0MUKAKgFnwCYBEW4TFBqtHWFYiJFid7fMrtpZ/gxJthvz5mEByA=="],
"kuler": ["kuler@2.0.0", "", {}, "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="],
"lazy-ass": ["lazy-ass@1.6.0", "", {}, "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw=="],
"lazystream": ["lazystream@1.0.1", "", { "dependencies": { "readable-stream": "^2.0.5" } }, "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw=="],
@@ -1791,8 +1713,6 @@
"log-update": ["log-update@4.0.0", "", { "dependencies": { "ansi-escapes": "^4.3.0", "cli-cursor": "^3.1.0", "slice-ansi": "^4.0.0", "wrap-ansi": "^6.2.0" } }, "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg=="],
"logform": ["logform@2.7.0", "", { "dependencies": { "@colors/colors": "1.6.0", "@types/triple-beam": "^1.3.2", "fecha": "^4.2.0", "ms": "^2.1.1", "safe-stable-stringify": "^2.3.1", "triple-beam": "^1.3.0" } }, "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ=="],
"longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="],
"loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="],
@@ -1957,15 +1877,13 @@
"minizlib": ["minizlib@2.1.2", "", { "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="],
"mitt": ["mitt@3.0.1", "", {}, "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="],
"mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="],
"module-details-from-path": ["module-details-from-path@1.0.3", "", {}, "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A=="],
"moment": ["moment@2.30.1", "", {}, "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how=="],
"moment-timezone": ["moment-timezone@0.6.0", "", { "dependencies": { "moment": "^2.29.4" } }, "sha512-ldA5lRNm3iJCWZcBCab4pnNL3HSZYXVb/3TYr75/1WCTWYuTqYUb5f/S384pncYjJ88lbO8Z4uPDvmoluHJc8Q=="],
"moment-timezone": ["moment-timezone@0.5.47", "", { "dependencies": { "moment": "^2.29.4" } }, "sha512-UbNt/JAWS0m/NJOebR0QMRHBk0hu03r5dx9GK8Cs0AS3I81yDcOc9k+DytPItgVvBP7J6Mf6U2n3BPAacAV9oA=="],
"mrmime": ["mrmime@2.0.0", "", {}, "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw=="],
@@ -1983,12 +1901,8 @@
"negotiator": ["negotiator@0.6.3", "", {}, "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="],
"neo-async": ["neo-async@2.6.2", "", {}, "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="],
"neotraverse": ["neotraverse@0.6.18", "", {}, "sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA=="],
"netmask": ["netmask@2.0.2", "", {}, "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg=="],
"new-github-issue-url": ["new-github-issue-url@0.2.1", "", {}, "sha512-md4cGoxuT4T4d/HDOXbrUHkTKrp/vp+m3aOA7XXVYwNsUNMK49g3SQicTSeV5GIz/5QVGAeYRAOlyp9OvlgsYA=="],
"nlcst-to-string": ["nlcst-to-string@4.0.0", "", { "dependencies": { "@types/nlcst": "^2.0.0" } }, "sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA=="],
@@ -2039,8 +1953,6 @@
"once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
"one-time": ["one-time@1.0.0", "", { "dependencies": { "fn.name": "1.x.x" } }, "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g=="],
"onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="],
"oniguruma-to-es": ["oniguruma-to-es@2.3.0", "", { "dependencies": { "emoji-regex-xs": "^1.0.0", "regex": "^5.1.1", "regex-recursion": "^5.1.1" } }, "sha512-bwALDxriqfKGfUufKGGepCzu9x7nJQuoRoAFp4AnwehhC2crqrDIAP/uN2qdlsAvSMpeRC3+Yzhqc7hLmle5+g=="],
@@ -2073,10 +1985,6 @@
"p-try": ["p-try@2.2.0", "", {}, "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="],
"pac-proxy-agent": ["pac-proxy-agent@7.2.0", "", { "dependencies": { "@tootallnate/quickjs-emscripten": "^0.23.0", "agent-base": "^7.1.2", "debug": "^4.3.4", "get-uri": "^6.0.1", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.6", "pac-resolver": "^7.0.1", "socks-proxy-agent": "^8.0.5" } }, "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA=="],
"pac-resolver": ["pac-resolver@7.0.1", "", { "dependencies": { "degenerator": "^5.0.0", "netmask": "^2.0.2" } }, "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg=="],
"package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="],
"pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="],
@@ -2187,18 +2095,12 @@
"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=="],
"proxy-agent": ["proxy-agent@6.5.0", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "http-proxy-agent": "^7.0.1", "https-proxy-agent": "^7.0.6", "lru-cache": "^7.14.1", "pac-proxy-agent": "^7.1.0", "proxy-from-env": "^1.1.0", "socks-proxy-agent": "^8.0.5" } }, "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A=="],
"proxy-from-env": ["proxy-from-env@1.0.0", "", {}, "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A=="],
"pump": ["pump@3.0.2", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw=="],
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
"puppeteer": ["puppeteer@24.15.0", "", { "dependencies": { "@puppeteer/browsers": "2.10.6", "chromium-bidi": "7.2.0", "cosmiconfig": "^9.0.0", "devtools-protocol": "0.0.1464554", "puppeteer-core": "24.15.0", "typed-query-selector": "^2.12.0" }, "bin": { "puppeteer": "lib/cjs/puppeteer/node/cli.js" } }, "sha512-HPSOTw+DFsU/5s2TUUWEum9WjFbyjmvFDuGHtj2X4YUz2AzOzvKMkT3+A3FR+E+ZefiX/h3kyLyXzWJWx/eMLQ=="],
"puppeteer-core": ["puppeteer-core@24.15.0", "", { "dependencies": { "@puppeteer/browsers": "2.10.6", "chromium-bidi": "7.2.0", "debug": "^4.4.1", "devtools-protocol": "0.0.1464554", "typed-query-selector": "^2.12.0", "ws": "^8.18.3" } }, "sha512-2iy0iBeWbNyhgiCGd/wvGrDSo73emNFjSxYOcyAqYiagkYt5q4cPfVXaVDKBsukgc2fIIfLAalBZlaxldxdDYg=="],
"qs": ["qs@6.13.0", "", { "dependencies": { "side-channel": "^1.0.6" } }, "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg=="],
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
@@ -2363,8 +2265,6 @@
"request-progress": ["request-progress@3.0.0", "", { "dependencies": { "throttleit": "^1.0.0" } }, "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg=="],
"require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="],
"require-in-the-middle": ["require-in-the-middle@7.5.2", "", { "dependencies": { "debug": "^4.3.5", "module-details-from-path": "^1.0.3", "resolve": "^1.22.8" } }, "sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ=="],
"resize-observer-polyfill": ["resize-observer-polyfill@1.5.1", "", {}, "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="],
@@ -2407,8 +2307,6 @@
"safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
"safe-stable-stringify": ["safe-stable-stringify@2.5.0", "", {}, "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA=="],
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
"sander": ["sander@0.5.1", "", { "dependencies": { "es6-promise": "^3.1.2", "graceful-fs": "^4.1.3", "mkdirp": "^0.5.1", "rimraf": "^2.5.2" } }, "sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA=="],
@@ -2475,14 +2373,8 @@
"slice-ansi": ["slice-ansi@3.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", "is-fullwidth-code-point": "^3.0.0" } }, "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ=="],
"smart-buffer": ["smart-buffer@4.2.0", "", {}, "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="],
"soap": ["soap@1.1.8", "", { "dependencies": { "axios": "^1.7.9", "axios-ntlm": "^1.4.2", "debug": "^4.4.0", "formidable": "^3.5.2", "get-stream": "^6.0.1", "lodash": "^4.17.21", "sax": "^1.4.1", "strip-bom": "^3.0.0", "whatwg-mimetype": "4.0.0", "xml-crypto": "^6.0.0" } }, "sha512-fDNGyGsPkQP3bZX/366Ud5Kpjo9mCMh7ZKYIc3uipBEPPM2ZqCNkv1Z2/w0qpzpYFLL7do8WWwVUAjAwuUe1AQ=="],
"socks": ["socks@2.8.4", "", { "dependencies": { "ip-address": "^9.0.5", "smart-buffer": "^4.2.0" } }, "sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ=="],
"socks-proxy-agent": ["socks-proxy-agent@8.0.5", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="],
"sorcery": ["sorcery@0.11.1", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.14", "buffer-crc32": "^1.0.0", "minimist": "^1.2.0", "sander": "^0.5.0" }, "bin": { "sorcery": "bin/sorcery" } }, "sha512-o7npfeJE6wi6J9l0/5LKshFzZ2rMatRiCDwYeDQaOzqdzRJwALhX7mk/A/ecg6wjMu7wdZbmXfD2S/vpOg0bdQ=="],
"source-map": ["source-map@0.7.4", "", {}, "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA=="],
@@ -2503,20 +2395,12 @@
"sqids": ["sqids@0.3.0", "", {}, "sha512-lOQK1ucVg+W6n3FhRwwSeUijxe93b51Bfz5PMRMihVf1iVkl82ePQG7V5vwrhzB11v0NtsR25PSZRGiSomJaJw=="],
"ssh2": ["ssh2@1.16.0", "", { "dependencies": { "asn1": "^0.2.6", "bcrypt-pbkdf": "^1.0.2" }, "optionalDependencies": { "cpu-features": "~0.0.10", "nan": "^2.20.0" } }, "sha512-r1X4KsBGedJqo7h8F5c4Ybpcr5RjyP+aWIG007uBPRjmdQWfEiVLzSK71Zji1B9sKxwaCvD8y8cwSkYrlLiRRg=="],
"ssh2-sftp-client": ["ssh2-sftp-client@12.0.0", "", { "dependencies": { "concat-stream": "^2.0.0", "ssh2": "^1.16.0" } }, "sha512-k+ocDsx6N2eDwQlIRwJFa0I1bkQpFPhIc+cv1iplaQaIPXFt9YM1ZnXCJOW4OILS5dzE+12OlhYIF5g0AzgVfg=="],
"sshpk": ["sshpk@1.18.0", "", { "dependencies": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", "bcrypt-pbkdf": "^1.0.0", "dashdash": "^1.12.0", "ecc-jsbn": "~0.1.1", "getpass": "^0.1.1", "jsbn": "~0.1.0", "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" }, "bin": { "sshpk-conv": "bin/sshpk-conv", "sshpk-sign": "bin/sshpk-sign", "sshpk-verify": "bin/sshpk-verify" } }, "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ=="],
"stack-trace": ["stack-trace@0.0.10", "", {}, "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg=="],
"statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="],
"stdin-discarder": ["stdin-discarder@0.2.2", "", {}, "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ=="],
"streamx": ["streamx@2.22.0", "", { "dependencies": { "fast-fifo": "^1.3.2", "text-decoder": "^1.1.0" }, "optionalDependencies": { "bare-events": "^2.2.0" } }, "sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw=="],
"string-convert": ["string-convert@0.2.1", "", {}, "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A=="],
"string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
@@ -2571,8 +2455,6 @@
"tar": ["tar@6.2.1", "", { "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" } }, "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A=="],
"tar-fs": ["tar-fs@3.1.0", "", { "dependencies": { "pump": "^3.0.0", "tar-stream": "^3.1.5" }, "optionalDependencies": { "bare-fs": "^4.0.1", "bare-path": "^3.0.0" } }, "sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w=="],
"tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="],
"tarn": ["tarn@3.0.2", "", {}, "sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ=="],
@@ -2585,10 +2467,6 @@
"terminal-link": ["terminal-link@2.1.1", "", { "dependencies": { "ansi-escapes": "^4.2.1", "supports-hyperlinks": "^2.0.0" } }, "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ=="],
"text-decoder": ["text-decoder@1.2.3", "", { "dependencies": { "b4a": "^1.6.4" } }, "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA=="],
"text-hex": ["text-hex@1.0.0", "", {}, "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg=="],
"text-table": ["text-table@0.2.0", "", {}, "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw=="],
"thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="],
@@ -2633,8 +2511,6 @@
"trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="],
"triple-beam": ["triple-beam@1.4.1", "", {}, "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg=="],
"trough": ["trough@2.2.0", "", {}, "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw=="],
"trpc-openapi": ["trpc-openapi@1.2.0", "", { "dependencies": { "co-body": "^6.1.0", "h3": "^1.6.4", "lodash.clonedeep": "^4.5.0", "node-mocks-http": "^1.12.2", "openapi-types": "^12.1.1", "zod-to-json-schema": "^3.21.1" }, "peerDependencies": { "@trpc/server": "^10.0.0", "zod": "^3.14.4" } }, "sha512-pfYoCd/3KYXWXvUPZBKJw455OOwngKN/6SIcj7Yit19OMLJ+8yVZkEvGEeg5wUSwfsiTdRsKuvqkRPXVSwV7ew=="],
@@ -2663,16 +2539,10 @@
"type-is": ["type-is@1.6.18", "", { "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" } }, "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g=="],
"typed-query-selector": ["typed-query-selector@2.12.0", "", {}, "sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg=="],
"typedarray": ["typedarray@0.0.6", "", {}, "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA=="],
"typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
"ufo": ["ufo@1.5.4", "", {}, "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ=="],
"uglify-js": ["uglify-js@3.19.3", "", { "bin": { "uglifyjs": "bin/uglifyjs" } }, "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ=="],
"uncrypto": ["uncrypto@0.1.3", "", {}, "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q=="],
"undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="],
@@ -2765,36 +2635,24 @@
"widest-line": ["widest-line@5.0.0", "", { "dependencies": { "string-width": "^7.0.0" } }, "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA=="],
"winston": ["winston@3.18.3", "", { "dependencies": { "@colors/colors": "^1.6.0", "@dabh/diagnostics": "^2.0.8", "async": "^3.2.3", "is-stream": "^2.0.0", "logform": "^2.7.0", "one-time": "^1.0.0", "readable-stream": "^3.4.0", "safe-stable-stringify": "^2.3.1", "stack-trace": "0.0.x", "triple-beam": "^1.3.0", "winston-transport": "^4.9.0" } }, "sha512-NoBZauFNNWENgsnC9YpgyYwOVrl2m58PpQ8lNHjV3kosGs7KJ7Npk9pCUE+WJlawVSe8mykWDKWFSVfs3QO9ww=="],
"winston-transport": ["winston-transport@4.9.0", "", { "dependencies": { "logform": "^2.7.0", "readable-stream": "^3.6.2", "triple-beam": "^1.3.0" } }, "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A=="],
"word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
"wordwrap": ["wordwrap@1.0.0", "", {}, "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="],
"wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
"wrap-ansi-cjs": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
"wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
"ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="],
"xml-crypto": ["xml-crypto@6.0.0", "", { "dependencies": { "@xmldom/is-dom-node": "^1.0.1", "@xmldom/xmldom": "^0.8.10", "xpath": "^0.0.33" } }, "sha512-L3RgnkaDrHaYcCnoENv4Idzt1ZRj5U1z1BDH98QdDTQfssScx8adgxhd9qwyYo+E3fXbQZjEQH7aiXHLVgxGvw=="],
"xpath": ["xpath@0.0.33", "", {}, "sha512-NNXnzrkDrAzalLhIUc01jO2mOzXGXh1JwPgkihcLLzw98c0WgYDmmjSh1Kl3wzaxSVWMuA+fe0WTWOBDWCBmNA=="],
"xxhash-wasm": ["xxhash-wasm@1.1.0", "", {}, "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA=="],
"y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
"yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
"yaml": ["yaml@2.7.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA=="],
"yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="],
"yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
"yauzl": ["yauzl@2.10.0", "", { "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } }, "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g=="],
@@ -2879,18 +2737,10 @@
"@prisma/schema-files-loader/fs-extra": ["fs-extra@11.1.1", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ=="],
"@puppeteer/browsers/debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
"@puppeteer/browsers/semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
"@rollup/pluginutils/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
"@so-ric/colorspace/color": ["color@5.0.2", "", { "dependencies": { "color-convert": "^3.0.1", "color-string": "^2.0.0" } }, "sha512-e2hz5BzbUPcYlIRHo8ieAhYgoajrJr+hWoceg6E345TPsATMUKqDgzt8fSXZJJbxfpiPzkWyphz8yn8At7q3fA=="],
"@sveltejs/vite-plugin-svelte/vitefu": ["vitefu@0.2.5", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["vite"] }, "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q=="],
"@types/ssh2/@types/node": ["@types/node@18.19.86", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-fifKayi175wLyKyc5qUfyENhQ1dCNI1UNjp653d8kuYcPQN5JhX3dGuP/XmvPTg/xRBn1VTLpbmi+H/Mr7tLfQ=="],
"@typescript-eslint/typescript-estree/globby": ["globby@11.1.0", "", { "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.2.9", "ignore": "^5.2.0", "merge2": "^1.4.1", "slash": "^3.0.0" } }, "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g=="],
"@typescript-eslint/utils/eslint-scope": ["eslint-scope@5.1.1", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw=="],
@@ -2929,8 +2779,6 @@
"chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
"cli-table3/@colors/colors": ["@colors/colors@1.5.0", "", {}, "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ=="],
"co-body/qs": ["qs@6.14.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w=="],
"csvtojson/strip-bom": ["strip-bom@2.0.0", "", { "dependencies": { "is-utf8": "^0.2.0" } }, "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g=="],
@@ -2945,7 +2793,7 @@
"dir-glob/path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="],
"escodegen/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
"error-ex/is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="],
"eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@2.1.0", "", {}, "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw=="],
@@ -2979,16 +2827,10 @@
"gray-matter/js-yaml": ["js-yaml@3.14.1", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g=="],
"handlebars/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
"hasha/type-fest": ["type-fest@0.8.1", "", {}, "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA=="],
"ignore-walk/minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="],
"ip-address/jsbn": ["jsbn@1.1.0", "", {}, "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A=="],
"ip-address/sprintf-js": ["sprintf-js@1.1.3", "", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="],
"is-wsl/is-docker": ["is-docker@2.2.1", "", { "bin": { "is-docker": "cli.js" } }, "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ=="],
"knex/commander": ["commander@10.0.1", "", {}, "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug=="],
@@ -3047,10 +2889,6 @@
"p-locate/p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
"pac-proxy-agent/http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="],
"pac-proxy-agent/https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="],
"parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="],
"path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
@@ -3071,16 +2909,6 @@
"prop-types/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
"proxy-agent/http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="],
"proxy-agent/https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="],
"proxy-agent/lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="],
"proxy-agent/proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="],
"puppeteer-core/debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
"rc-align/rc-util": ["rc-util@4.21.1", "", { "dependencies": { "add-dom-event-listener": "^1.1.0", "prop-types": "^15.5.10", "react-is": "^16.12.0", "react-lifecycles-compat": "^3.0.4", "shallowequal": "^1.1.0" } }, "sha512-Z+vlkSQVc1l8O2UjR3WQ+XdWlhj5q9BMQNLk2iOBch75CqPfrJyGtcWMcnhRlNuDu0Ndtt4kLVO8JI8BrABobg=="],
"rc-animate/rc-util": ["rc-util@4.21.1", "", { "dependencies": { "add-dom-event-listener": "^1.1.0", "prop-types": "^15.5.10", "react-is": "^16.12.0", "react-lifecycles-compat": "^3.0.4", "shallowequal": "^1.1.0" } }, "sha512-Z+vlkSQVc1l8O2UjR3WQ+XdWlhj5q9BMQNLk2iOBch75CqPfrJyGtcWMcnhRlNuDu0Ndtt4kLVO8JI8BrABobg=="],
@@ -3113,8 +2941,6 @@
"serve-static/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=="],
"simple-swizzle/is-arrayish": ["is-arrayish@0.3.2", "", {}, "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="],
"soap/strip-bom": ["strip-bom@3.0.0", "", {}, "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA=="],
"sorcery/buffer-crc32": ["buffer-crc32@1.0.0", "", {}, "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w=="],
@@ -3133,8 +2959,6 @@
"tar/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="],
"tar-fs/tar-stream": ["tar-stream@3.1.7", "", { "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ=="],
"temp-write/temp-dir": ["temp-dir@1.0.0", "", {}, "sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ=="],
"temp-write/uuid": ["uuid@3.4.0", "", { "bin": { "uuid": "./bin/uuid" } }, "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="],
@@ -3177,12 +3001,6 @@
"@prisma/internals/globby/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
"@so-ric/colorspace/color/color-convert": ["color-convert@3.1.2", "", { "dependencies": { "color-name": "^2.0.0" } }, "sha512-UNqkvCDXstVck3kdowtOTWROIJQwafjOfXSmddoDrXo4cewMKmusCeF22Q24zvjR8nwWib/3S/dfyzPItPEiJg=="],
"@so-ric/colorspace/color/color-string": ["color-string@2.1.2", "", { "dependencies": { "color-name": "^2.0.0" } }, "sha512-RxmjYxbWemV9gKu4zPgiZagUxbH3RQpEIO77XoSSX0ivgABDZ+h8Zuash/EMFLTI4N9QgFPOJ6JQpPZKFxa+dA=="],
"@types/ssh2/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
"@typescript-eslint/typescript-estree/globby/slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
"@typescript-eslint/utils/eslint-scope/estraverse": ["estraverse@4.3.0", "", {}, "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="],
@@ -3347,10 +3165,6 @@
"@prisma/internals/@prisma/debug/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="],
"@so-ric/colorspace/color/color-convert/color-name": ["color-name@2.0.2", "", {}, "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A=="],
"@so-ric/colorspace/color/color-string/color-name": ["color-name@2.0.2", "", {}, "sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A=="],
"boxen/string-width/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="],
"boxen/wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="],

View File

@@ -1,11 +1,7 @@
version: '3'
services:
database:
container_name: database
image: postgres:17.5
build: ./
restart: always
env_file:
- .env
ports:

1
index.ts Normal file
View File

@@ -0,0 +1 @@
console.log("Hello via Bun!");

View File

@@ -29,11 +29,10 @@
"@pdfme/common": "^5.2.16",
"@pdfme/generator": "^5.2.16",
"@pdfme/ui": "^5.2.16",
"@svelte-plugins/datepicker": "^1.0.11",
"@trpc/client": "^10.45.2",
"@trpc/server": "^10.45.2",
"astro": "^4.16.17",
"astro-typesafe-api": "^0.2.4",
"astro-typesafe-api": "^0.2.2",
"body-scroll-lock": "^4.0.0-beta.0",
"buffer": "^6.0.3",
"bun": "^1.2.5",
@@ -41,8 +40,7 @@
"express": "^4.21.2",
"flag-icons": "^6.15.0",
"fontkit": "^2.0.4",
"handlebars": "^4.7.8",
"heic2any": "^0.0.4",
"highlight.run": "^9.14.0",
"is-base64": "^1.1.0",
"js-cookie": "^3.0.5",
"js-interpolate": "^1.3.2",
@@ -50,18 +48,16 @@
"jwt-decode": "^4.0.0",
"mime": "^4.0.6",
"moment": "^2.30.1",
"moment-timezone": "^0.6.0",
"moment-timezone": "^0.5.46",
"nodemailer": "^6.10.0",
"pdf-lib": "^1.17.1",
"postcss-nested": "^7.0.2",
"puppeteer": "^24.15.0",
"radix-svelte-icons": "^1.0.0",
"sass": "^1.83.4",
"sharp": "^0.33.5",
"siema": "^1.5.1",
"soap": "^1.1.8",
"sqids": "^0.3.0",
"ssh2-sftp-client": "^12.0.0",
"svelte": "^3.59.2",
"svelte-dialogs": "^1.2.2",
"svelte-preprocess": "^5.1.4",
@@ -69,7 +65,6 @@
"tailwindcss": "^3.4.17",
"trpc-openapi": "^1.2.0",
"uuid": "^9.0.1",
"winston": "^3.18.3",
"zod": "^3.24.1"
},
"devDependencies": {
@@ -86,7 +81,6 @@
"@types/nodemailer": "^6.4.17",
"@types/papaparse": "^5.3.15",
"@types/siema": "^1.4.11",
"@types/ssh2-sftp-client": "^9.0.4",
"@types/uuid": "^9.0.8",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
@@ -102,7 +96,7 @@
"postcss-import": "^16.1.0",
"postcss-nesting": "^13.0.1",
"prettier": "^2.8.8",
"prisma": "6.4.1",
"prisma": "^6.4.1",
"prisma-dbml-generator": "^0.12.0",
"prisma-generator-fake-data": "^0.14.3",
"tsx": "^4.19.3",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 256 B

View File

@@ -1,17 +0,0 @@
-- AlterTable
ALTER TABLE "BedarfsausweisGewerbe" ADD COLUMN "ausweisart" "Ausweisart" NOT NULL DEFAULT 'BedarfsausweisGewerbe';
-- AlterTable
ALTER TABLE "BedarfsausweisWohnen" ADD COLUMN "ausweisart" "Ausweisart" NOT NULL DEFAULT 'BedarfsausweisWohnen';
-- AlterTable
ALTER TABLE "GEGNachweisGewerbe" ADD COLUMN "ausweisart" "Ausweisart" NOT NULL DEFAULT 'GEGNachweisGewerbe';
-- AlterTable
ALTER TABLE "GEGNachweisWohnen" ADD COLUMN "ausweisart" "Ausweisart" NOT NULL DEFAULT 'GEGNachweisWohnen';
-- AlterTable
ALTER TABLE "VerbrauchsausweisGewerbe" ADD COLUMN "ausweisart" "Ausweisart" NOT NULL DEFAULT 'VerbrauchsausweisGewerbe';
-- AlterTable
ALTER TABLE "VerbrauchsausweisWohnen" ADD COLUMN "ausweisart" "Ausweisart" NOT NULL DEFAULT 'VerbrauchsausweisWohnen';

View File

@@ -1,9 +0,0 @@
-- AlterTable
ALTER TABLE "BedarfsausweisWohnen" ALTER COLUMN "fenster_art_1" SET DATA TYPE TEXT,
ALTER COLUMN "fenster_art_2" SET DATA TYPE TEXT,
ALTER COLUMN "dachfenster_art" SET DATA TYPE TEXT,
ALTER COLUMN "haustuer_art" SET DATA TYPE TEXT,
ALTER COLUMN "dach_daemmung" SET DATA TYPE TEXT,
ALTER COLUMN "decke_daemmung" SET DATA TYPE TEXT,
ALTER COLUMN "aussenwand_daemmung" SET DATA TYPE TEXT,
ALTER COLUMN "boden_daemmung" SET DATA TYPE TEXT;

View File

@@ -1,49 +0,0 @@
/*
Warnings:
- The `fenster_art_1` column on the `BedarfsausweisWohnen` table would be dropped and recreated. This will lead to data loss if there is data in the column.
- The `fenster_art_2` column on the `BedarfsausweisWohnen` table would be dropped and recreated. This will lead to data loss if there is data in the column.
- The `dachfenster_art` column on the `BedarfsausweisWohnen` table would be dropped and recreated. This will lead to data loss if there is data in the column.
- The `haustuer_art` column on the `BedarfsausweisWohnen` table would be dropped and recreated. This will lead to data loss if there is data in the column.
- The `dach_daemmung` column on the `BedarfsausweisWohnen` table would be dropped and recreated. This will lead to data loss if there is data in the column.
- The `decke_daemmung` column on the `BedarfsausweisWohnen` table would be dropped and recreated. This will lead to data loss if there is data in the column.
- The `aussenwand_daemmung` column on the `BedarfsausweisWohnen` table would be dropped and recreated. This will lead to data loss if there is data in the column.
- The `boden_daemmung` column on the `BedarfsausweisWohnen` table would be dropped and recreated. This will lead to data loss if there is data in the column.
*/
-- AlterEnum
ALTER TYPE "BenutzerRolle" ADD VALUE 'RESELLER';
-- AlterTable
ALTER TABLE "BedarfsausweisWohnen" DROP COLUMN "fenster_art_1",
ADD COLUMN "fenster_art_1" DOUBLE PRECISION,
DROP COLUMN "fenster_art_2",
ADD COLUMN "fenster_art_2" DOUBLE PRECISION,
DROP COLUMN "dachfenster_art",
ADD COLUMN "dachfenster_art" DOUBLE PRECISION,
DROP COLUMN "haustuer_art",
ADD COLUMN "haustuer_art" DOUBLE PRECISION,
DROP COLUMN "dach_daemmung",
ADD COLUMN "dach_daemmung" DOUBLE PRECISION,
DROP COLUMN "decke_daemmung",
ADD COLUMN "decke_daemmung" DOUBLE PRECISION,
DROP COLUMN "aussenwand_daemmung",
ADD COLUMN "aussenwand_daemmung" DOUBLE PRECISION,
DROP COLUMN "boden_daemmung",
ADD COLUMN "boden_daemmung" DOUBLE PRECISION;
-- CreateTable
CREATE TABLE "Provisionen" (
"id" TEXT NOT NULL,
"ausweisart" TEXT NOT NULL,
"provision_prozent" DOUBLE PRECISION NOT NULL,
"provision_betrag" DOUBLE PRECISION NOT NULL,
"benutzer_id" VARCHAR(11),
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Provisionen_pkey" PRIMARY KEY ("id")
);
-- AddForeignKey
ALTER TABLE "Provisionen" ADD CONSTRAINT "Provisionen_benutzer_id_fkey" FOREIGN KEY ("benutzer_id") REFERENCES "benutzer"("id") ON DELETE SET NULL ON UPDATE CASCADE;

View File

@@ -1,15 +0,0 @@
/*
Warnings:
- The primary key for the `Provisionen` table will be changed. If it partially fails, the table could be left without primary key constraint.
- The `id` column on the `Provisionen` table would be dropped and recreated. This will lead to data loss if there is data in the column.
- Changed the type of `ausweisart` on the `Provisionen` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required.
*/
-- AlterTable
ALTER TABLE "Provisionen" DROP CONSTRAINT "Provisionen_pkey",
DROP COLUMN "id",
ADD COLUMN "id" SERIAL NOT NULL,
DROP COLUMN "ausweisart",
ADD COLUMN "ausweisart" "Ausweisart" NOT NULL,
ADD CONSTRAINT "Provisionen_pkey" PRIMARY KEY ("id");

View File

@@ -1,2 +0,0 @@
-- AlterTable
ALTER TABLE "benutzer" ADD COLUMN "partner_code" TEXT;

View File

@@ -1,12 +0,0 @@
/*
Warnings:
- Added the required column `ausweistyp` to the `Provisionen` table without a default value. This is not possible if the table is not empty.
*/
-- AlterTable
ALTER TABLE "Aufnahme" ALTER COLUMN "flaeche" SET DATA TYPE DOUBLE PRECISION,
ALTER COLUMN "nutzflaeche" SET DATA TYPE DOUBLE PRECISION;
-- AlterTable
ALTER TABLE "Provisionen" ADD COLUMN "ausweistyp" "AusweisTyp" NOT NULL;

View File

@@ -1,5 +0,0 @@
-- AlterTable
ALTER TABLE "Bild" ADD COLUMN "benutzer_id" TEXT;
-- AddForeignKey
ALTER TABLE "Bild" ADD CONSTRAINT "Bild_benutzer_id_fkey" FOREIGN KEY ("benutzer_id") REFERENCES "benutzer"("id") ON DELETE NO ACTION ON UPDATE NO ACTION;

View File

@@ -1,10 +0,0 @@
/*
Warnings:
- You are about to alter the column `flaeche` on the `Aufnahme` table. The data in that column could be lost. The data in that column will be cast from `DoublePrecision` to `Integer`.
- You are about to alter the column `nutzflaeche` on the `Aufnahme` table. The data in that column could be lost. The data in that column will be cast from `DoublePrecision` to `Integer`.
*/
-- AlterTable
ALTER TABLE "Aufnahme" ALTER COLUMN "flaeche" SET DATA TYPE INTEGER,
ALTER COLUMN "nutzflaeche" SET DATA TYPE INTEGER;

View File

@@ -1,9 +0,0 @@
/*
Warnings:
- You are about to drop the column `anrede` on the `benutzer` table. All the data in the column will be lost.
*/
-- AlterTable
ALTER TABLE "benutzer" DROP COLUMN "anrede",
ADD COLUMN "empfaenger" VARCHAR(100);

View File

@@ -26,7 +26,6 @@ model BedarfsausweisGewerbe {
klimatisierung Boolean? @default(false)
nachweistyp AusweisTyp @default(Standard)
ausweisart Ausweisart @default(BedarfsausweisGewerbe)
created_at DateTime @default(now())
updated_at DateTime @updatedAt @default(now())

View File

@@ -100,7 +100,6 @@ model BedarfsausweisWohnen {
pruefpunkt_fenster Boolean? @default(false)
ausweistyp AusweisTyp @default(Standard)
ausweisart Ausweisart @default(BedarfsausweisWohnen)
benutzer Benutzer? @relation(fields: [benutzer_id], references: [id], onDelete: NoAction, onUpdate: NoAction)

View File

@@ -2,7 +2,6 @@
enum BenutzerRolle {
USER
ADMIN
RESELLER
}
model Benutzer {
@@ -17,11 +16,10 @@ model Benutzer {
ort String? @db.VarChar(50)
adresse String? @db.VarChar(150)
telefon String? @db.VarChar(50)
empfaenger String? @db.VarChar(100)
anrede String? @db.VarChar(50)
rolle BenutzerRolle @default(USER)
firma String?
lex_office_id String?
partner_code String?
verified Boolean @default(false)
@@ -52,8 +50,6 @@ model Benutzer {
events Event[]
@@map("benutzer")
Provisionen Provisionen[]
bilder Bild[]
}

View File

@@ -15,8 +15,6 @@ model Bild {
created_at DateTime @default(now())
updated_at DateTime @updatedAt @default(now())
benutzer_id String?
benutzer Benutzer? @relation(fields: [benutzer_id], references: [id], onDelete: NoAction, onUpdate: NoAction)
aufnahme_id String?
aufnahme Aufnahme? @relation(fields: [aufnahme_id], references: [id], onDelete: NoAction, onUpdate: NoAction)
}

View File

@@ -17,7 +17,6 @@ model GEGNachweisGewerbe {
beschreibung String? @db.Text
nachweistyp AusweisTyp @default(Standard)
ausweisart Ausweisart @default(GEGNachweisGewerbe)
created_at DateTime @default(now())
updated_at DateTime @updatedAt @default(now())

View File

@@ -17,7 +17,6 @@ model GEGNachweisWohnen {
beschreibung String? @db.Text
nachweistyp AusweisTyp @default(Standard)
ausweisart Ausweisart @default(GEGNachweisWohnen)
created_at DateTime @default(now())
updated_at DateTime @updatedAt @default(now())

View File

@@ -1,11 +0,0 @@
model Provisionen {
id Int @id @default(autoincrement())
ausweisart Ausweisart
ausweistyp AusweisTyp
provision_prozent Float
provision_betrag Float
benutzer_id String? @db.VarChar(11)
benutzer Benutzer? @relation(fields: [benutzer_id], references: [id])
created_at DateTime @default(now())
updated_at DateTime @updatedAt
}

View File

@@ -74,7 +74,6 @@ model VerbrauchsausweisGewerbe {
updated_at DateTime @updatedAt @default(now())
ausweistyp AusweisTyp @default(Standard)
ausweisart Ausweisart @default(VerbrauchsausweisGewerbe)
pruefpunkt_heizungsalter Boolean? @default(false)
pruefpunkt_verbrauch_niedrig Boolean? @default(false)

View File

@@ -75,7 +75,6 @@ model VerbrauchsausweisWohnen {
kontrolldatei_angefragt Boolean? @default(false)
ausweistyp AusweisTyp @default(Standard)
ausweisart Ausweisart @default(VerbrauchsausweisWohnen)
created_at DateTime @default(now())
updated_at DateTime @updatedAt @default(now())

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 10 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@@ -1,78 +0,0 @@
#!/bin/bash
# === Configuration ===
BUCKET_NAME="ibc-db-backup"
ENDPOINT_URL="https://s3.eu-central-3.ionoscloud.com"
LOCAL_DOWNLOAD_DIR="./" # Where to save the file
DATABASE_NAME=database
# === Check if a custom file is given as a command line argument ===
if [ $# -eq 1 ]; then
CUSTOM_FILE="$1"
echo "🔍 Using custom file: $CUSTOM_FILE"
# Check if file exists locally
if [ ! -f "$CUSTOM_FILE" ]; then
# Check if the file exists on the remote
if ! aws s3api head-object --bucket "$BUCKET_NAME" --key "$CUSTOM_FILE" --endpoint-url "$ENDPOINT_URL" > /dev/null 2>&1; then
echo "❌ Custom file does not exist in S3 bucket or locally."
exit 1
else
echo "📥 Downloading $CUSTOM_FILE from S3"
aws s3 cp "s3://$BUCKET_NAME/$CUSTOM_FILE" "$LOCAL_DOWNLOAD_DIR" \
--endpoint-url "$ENDPOINT_URL"
fi
fi
LATEST_FILE="$CUSTOM_FILE"
FILENAME=$(basename "$LATEST_FILE")
if [[ "$FILENAME" == *.br ]]; then
echo "🗜️ Detected compressed file: $FILENAME"
# Remove the .br suffix for the SQL file
SQL_FILE="${FILENAME%.br}" # Remove .br suffix
brotli -d "$FILENAME"
else
SQL_FILE=$FILENAME
fi
else
echo "🔍 No custom file provided, searching for latest .sql.br file in S3"
# === Get latest file from IONOS S3 bucket ===
LATEST_FILE=$(aws s3api list-objects-v2 \
--bucket "$BUCKET_NAME" \
--prefix "data-dump" \
--endpoint-url "$ENDPOINT_URL" \
--query 'Contents | sort_by(@, &LastModified) | [-1].Key' \
--output text)
# === Check if file was found ===
if [ "$LATEST_FILE" == "None" ] || [ -z "$LATEST_FILE" ]; then
echo "❌ No matching .sql.br file found."
exit 1
fi
echo "🔍 Latest file found: $LATEST_FILE"
FILENAME=$(basename "$LATEST_FILE")
SQL_FILE="${FILENAME%.br}" # Remove .br suffix
echo "📥 Downloading $LATEST_FILE"
aws s3 cp "s3://$BUCKET_NAME/$LATEST_FILE" "$LOCAL_DOWNLOAD_DIR" \
--endpoint-url "$ENDPOINT_URL"
brotli -d "$FILENAME"
echo "🗜️ Decompressed to $SQL_FILE"
fi
# === Import into Postgres inside Docker ===
echo "🐘 Importing into PostgreSQL ($DATABASE_NAME:main)"
docker exec -i "$DATABASE_NAME" env PGPASSWORD="hHMP8cd^N3SnzGRR" \
psql -v ON_ERROR_STOP=0 -U main -d main < "$SQL_FILE"
echo "✅ Import complete."
# === Optional: Clean up
# If custom file was provided, do not delete it
if [ -z "$CUSTOM_FILE" ]; then
echo "🧹 Cleaning up downloaded files..."
rm "$FILENAME" "$SQL_FILE"
fi

View File

@@ -5,34 +5,33 @@ export const createCaller = createCallerFactory({
"klimafaktoren": await import("../src/pages/api/klimafaktoren.ts"),
"postleitzahlen": await import("../src/pages/api/postleitzahlen.ts"),
"unterlage": await import("../src/pages/api/unterlage.ts"),
"aufnahme": await import("../src/pages/api/aufnahme/index.ts"),
"admin/ausstellen": await import("../src/pages/api/admin/ausstellen.ts"),
"admin/bedarfsausweis-ausstellen": await import("../src/pages/api/admin/bedarfsausweis-ausstellen.ts"),
"admin/bestellbestaetigung": await import("../src/pages/api/admin/bestellbestaetigung.ts"),
"admin/erinnern": await import("../src/pages/api/admin/erinnern.ts"),
"admin/nicht-ausstellen": await import("../src/pages/api/admin/nicht-ausstellen.ts"),
"admin/post-ausstellen": await import("../src/pages/api/admin/post-ausstellen.ts"),
"admin/registriernummer": await import("../src/pages/api/admin/registriernummer.ts"),
"admin/stornieren": await import("../src/pages/api/admin/stornieren.ts"),
"bedarfsausweis-gewerbe/[id]": await import("../src/pages/api/bedarfsausweis-gewerbe/[id].ts"),
"bedarfsausweis-gewerbe": await import("../src/pages/api/bedarfsausweis-gewerbe/index.ts"),
"ausweise": await import("../src/pages/api/ausweise/index.ts"),
"aufnahme": await import("../src/pages/api/aufnahme/index.ts"),
"auth/access-token": await import("../src/pages/api/auth/access-token.ts"),
"auth/passwort-vergessen": await import("../src/pages/api/auth/passwort-vergessen.ts"),
"auth/refresh-token": await import("../src/pages/api/auth/refresh-token.ts"),
"bedarfsausweis-gewerbe/[id]": await import("../src/pages/api/bedarfsausweis-gewerbe/[id].ts"),
"bedarfsausweis-gewerbe": await import("../src/pages/api/bedarfsausweis-gewerbe/index.ts"),
"geg-nachweis-gewerbe/[id]": await import("../src/pages/api/geg-nachweis-gewerbe/[id].ts"),
"geg-nachweis-gewerbe": await import("../src/pages/api/geg-nachweis-gewerbe/index.ts"),
"bilder/[id]": await import("../src/pages/api/bilder/[id].ts"),
"geg-nachweis-wohnen/[id]": await import("../src/pages/api/geg-nachweis-wohnen/[id].ts"),
"geg-nachweis-wohnen": await import("../src/pages/api/geg-nachweis-wohnen/index.ts"),
"bedarfsausweis-wohnen/[id]": await import("../src/pages/api/bedarfsausweis-wohnen/[id].ts"),
"bedarfsausweis-wohnen": await import("../src/pages/api/bedarfsausweis-wohnen/index.ts"),
"bilder/[id]": await import("../src/pages/api/bilder/[id].ts"),
"geg-nachweis-gewerbe/[id]": await import("../src/pages/api/geg-nachweis-gewerbe/[id].ts"),
"geg-nachweis-gewerbe": await import("../src/pages/api/geg-nachweis-gewerbe/index.ts"),
"geg-nachweis-wohnen/[id]": await import("../src/pages/api/geg-nachweis-wohnen/[id].ts"),
"geg-nachweis-wohnen": await import("../src/pages/api/geg-nachweis-wohnen/index.ts"),
"objekt": await import("../src/pages/api/objekt/index.ts"),
"user": await import("../src/pages/api/user/index.ts"),
"user/self": await import("../src/pages/api/user/self.ts"),
"rechnung/[id]": await import("../src/pages/api/rechnung/[id].ts"),
"rechnung/anfordern": await import("../src/pages/api/rechnung/anfordern.ts"),
"rechnung": await import("../src/pages/api/rechnung/index.ts"),
"user/autocreate": await import("../src/pages/api/user/autocreate.ts"),
"user": await import("../src/pages/api/user/index.ts"),
"user/self": await import("../src/pages/api/user/self.ts"),
"ticket": await import("../src/pages/api/ticket/index.ts"),
"verbrauchsausweis-wohnen/[id]": await import("../src/pages/api/verbrauchsausweis-wohnen/[id].ts"),
"verbrauchsausweis-wohnen": await import("../src/pages/api/verbrauchsausweis-wohnen/index.ts"),

View File

@@ -1,12 +1,18 @@
import { api } from "astro-typesafe-api/client";
import { exclude } from "#lib/exclude.js";
import Cookies from "js-cookie";
import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants.js";
import {
Aufnahme,
AufnahmeClient,
BedarfsausweisWohnenClient,
BildClient,
ObjektClient,
VerbrauchsausweisGewerbeClient,
VerbrauchsausweisWohnenClient,
} from "#components/Ausweis/types.js";
import {
BedarfsausweisWohnen,
Bild,
Enums,
Objekt,
Unterlage,
VerbrauchsausweisGewerbe,
VerbrauchsausweisWohnen,
@@ -523,12 +529,12 @@ export async function bedarfsausweisWohnenSpeichern(
export async function ausweisSpeichern(
ausweis:
| VerbrauchsausweisWohnen
| VerbrauchsausweisGewerbe
| BedarfsausweisWohnen,
objekt: Objekt,
aufnahme: Aufnahme,
bilder: Bild[],
| VerbrauchsausweisWohnenClient
| VerbrauchsausweisGewerbeClient
| BedarfsausweisWohnenClient,
objekt: ObjektClient,
aufnahme: AufnahmeClient,
bilder: BildClient[],
unterlagen: Unterlage[],
ausweisart: Enums.Ausweisart
) {
@@ -560,7 +566,7 @@ export async function ausweisSpeichern(
return;
}
aufnahme.id = aufnahme_id as string;
aufnahme.id = aufnahme_id;
if (ausweisart == Enums.Ausweisart.VerbrauchsausweisWohnen) {
const id = await verbrauchsausweisWohnenSpeichern(

View File

@@ -1,15 +0,0 @@
import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants.js";
import { Benutzer } from "#lib/client/prisma.js";
import { api } from "astro-typesafe-api/client";
import Cookies from "js-cookie";
export async function benutzerLesen(benutzerId: string): Promise<Benutzer> {
const benutzer = await api.user.GET.fetch({ id: benutzerId }
, {
headers: {
Authorization: `Bearer ${Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)}`
}
});
return benutzer[0];
}

View File

@@ -0,0 +1,49 @@
import { dialogs } from "../../../svelte-dialogs.config";
import { loginClient } from "#lib/login";
import { addNotification } from "#components/Notifications/shared";
export async function spawnLoginPrompt() {
const result = await dialogs.prompt(
[
{
label: "Email",
type: "email",
required: true,
placeholder: "Email",
name: "email"
},
{
label: "Passwort",
type: "password",
name: "passwort",
required: true,
placeholder: "********",
},
],
{
title: "Login",
submitButtonText: "Einloggen",
cancelButtonText: "Abbrechen",
}
);
if (!result) return false;
const [email, passwort] = result;
const loginResult = await loginClient(email, passwort);
if (loginResult === null) {
addNotification({
type: "error",
message: "Einloggen fehlgeschlagen",
dismissable: true,
subtext: "Bitte überprüfen Sie ihre Eingaben und versuchen es erneut.",
timeout: 5000,
})
return false
}
return true
}

View File

@@ -0,0 +1,67 @@
import { dialogs } from "../../../svelte-dialogs.config.js";
import { addNotification } from "#components/Notifications/shared.js";
import { api } from "astro-typesafe-api/client";
export async function spawnSignupPrompt() {
const result = await dialogs.prompt(
[
{
label: "Vorname",
type: "text",
required: true,
placeholder: "Vorname",
name: "vorname"
},
{
label: "Name",
type: "text",
required: true,
placeholder: "Name",
name: "name"
},
{
label: "Email",
type: "email",
required: true,
placeholder: "Email",
name: "email"
},
{
label: "Passwort",
type: "password",
name: "passwort",
required: true,
placeholder: "********",
},
],
{
title: "Registrieren",
submitButtonText: "Registrieren",
cancelButtonText: "Abbrechen",
}
);
if (!result) return false;
const [vorname, name, email, passwort] = result;
try {
const response = await api.user.PUT.fetch({
email,
passwort,
vorname,
name,
});
return true;
} catch(e) {
addNotification({
type: "error",
message: "Registrieren fehlgeschlagen",
dismissable: true,
subtext: "Ein Fehler ist aufgetreten, vielleicht wird die angegebene Email bereits verwendet.",
timeout: 5000,
})
return false;
}
}

View File

@@ -1,5 +1,5 @@
import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants.js";
import { Aufnahme, Benutzer, Objekt } from "#lib/client/prisma.js";
import { Aufnahme, Objekt } from "#lib/client/prisma.js";
import { api } from "astro-typesafe-api/client";
import Cookies from "js-cookie";
@@ -162,30 +162,3 @@ export async function objektSpeichern(objekt: Objekt & { id?: string }): Promise
return id;
}
}
export async function benutzerSpeichern(benutzer: Partial<Benutzer>): Promise<string> {
const completeBenutzer: Benutzer = {
id: benutzer.id,
name: benutzer.name ?? null,
email: benutzer.email,
passwort: "",
adresse: benutzer.adresse ?? null,
firma: benutzer.firma ?? null,
vorname: benutzer.vorname ?? null,
ort: benutzer.ort ?? null,
plz: benutzer.plz ?? null,
profilbild: benutzer.profilbild ?? null,
telefon: benutzer.telefon ?? null,
updated_at: new Date(),
verified: benutzer.verified ?? false,
};
await api.user.POST.fetch(completeBenutzer
, {
headers: {
Authorization: `Bearer ${Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)}`
}
});
return benutzer.id;
}

View File

@@ -1,133 +0,0 @@
<script lang="ts">
import { Aufnahme, BedarfsausweisWohnen, Enums, Objekt, Provisionen, Rechnung, VerbrauchsausweisGewerbe, VerbrauchsausweisWohnen } from "#lib/server/prisma.js";
import moment from "moment-timezone"
import { DatePicker } from "@svelte-plugins/datepicker"
import { getProvision } from "#lib/provision.js";
export let bestellungen: (Rechnung & {
ausweis: (VerbrauchsausweisWohnen | BedarfsausweisWohnen | VerbrauchsausweisGewerbe) & { aufnahme: Aufnahme & { objekt: Objekt }}
})[];
export let provisionen: Provisionen[];
export let email: string;
export let startdatum: Date;
export let enddatum: Date;
moment.locale("de");
moment.tz.setDefault("Europe/Berlin");
const bestellungenNachMonat: Record<string, (typeof bestellungen)> = {};
for (const bestellung of bestellungen) {
const monat = moment(bestellung.created_at).format("Y-MM");
if (monat in bestellungenNachMonat) {
bestellungenNachMonat[monat].push(bestellung)
} else {
bestellungenNachMonat[monat] = [bestellung]
}
}
// Wir brauchen alle Monate zwischen dem ersten Mal, dass der partner_code benutzt wurde bis zum heutigen Zeitpunkt.
function getMonthlyPeriods(from: Date, to: Date): moment.Moment[] {
const start = moment(from).startOf('month');
const end = moment(to).endOf('month');
const monthsArray: moment.Moment[] = [];
const current = start.clone();
while (current.isBefore(end)) {
monthsArray.push(current.clone());
current.add(1, 'month');
}
return monthsArray.reverse(); // Most recent month first
}
const periods = getMonthlyPeriods(startdatum, enddatum)
let isOpen = false;
$: formatiertesStartDatum = moment(startdatum).format("DD.MM.YYYY");
$: formatiertesEndDatum = moment(enddatum).format("DD.MM.YYYY");
function toggleDatePicker() {
isOpen = !isOpen;
}
const onChange = ({ startDate, endDate }: { startDate: number, endDate: number }) => {
window.location.href = `/dashboard/abrechnung?start=${moment(startDate).format("YYYY-MM-DD")}&end=${moment(endDate).format("YYYY-MM-DD")}`;
};
</script>
<div class="fixed top-0 left-0 right-0 bg-white p-4 shadow z-10">
<div class="flex justify-between items-center">
<DatePicker bind:isOpen bind:startDate={startdatum} bind:endDate={enddatum} enableFutureDates={false} isRange={true} onDateChange={onChange} isMultipane={true}>
<input type="text" class="w-min" readonly value={`${formatiertesStartDatum} - ${formatiertesEndDatum}`} on:click={toggleDatePicker} />
</DatePicker>
<p>Abrechnungsübersicht für <strong>{email}</strong></p>
</div>
</div>
<main class="my-24 flex flex-col justify-center max-w-6xl mx-auto px-4">
{#if !bestellungen || bestellungen.length === 0}
<p class="text-center text-gray-500">Keine Bestellungen gefunden.</p>
{/if}
{#each periods as dt}
{@const jahrMonat = dt.format("Y-MM")}
{#if jahrMonat in bestellungenNachMonat && bestellungenNachMonat[jahrMonat].length > 0}
<!-- Echo dropdown foreach month. -->
{@const provisionMonat = bestellungenNachMonat[jahrMonat].reduce((acc, bestellung) => {
const { provision_prozent, provision_betrag } = getProvision(bestellung.ausweis.ausweisart, bestellung.ausweis.ausweistyp, provisionen);
return acc + provision_betrag;
}, 0)}
<details class="group" open>
<summary class="flex justify-between items-center cursor-pointer p-4 bg-gray-100 hover:bg-gray-200">
<span class="font-semibold">{moment(dt).format("MMMM YYYY")}</span>
<div class="flex flex-row gap-4 items-center">
<a href={`/dashboard/abrechnung/monatlich.pdf?d=${moment(dt).format("YYYY-MM")}`} target="_blank" rel="noreferrer noopener">PDF generieren</a>
<span class="text-gray-500">{provisionMonat.toFixed(2)}</span>
<svg class="w-4 h-4 transition-transform duration-300 group-open:rotate-180" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polyline points="6 9 12 15 18 9"></polyline>
</svg>
</div>
</summary>
<div class="p-4">
<table class="w-full mb-4 border-collapse border border-gray-300">
<thead>
<tr class="bg-primary text-white w-full">
<td class="text-center p-2 font-bold">ID</td>
<td class="text-center p-2 font-bold">Datum</td>
<td class="text-center p-2 font-bold">Ausweis</td>
<td class="text-center p-2 font-bold">Provision in %</td>
<td class="text-center p-2 font-bold">Betrag Netto</td>
</tr>
</thead>
<tbody class="text-sm">
{#each bestellungenNachMonat[jahrMonat] as bestellung}
{@const provisionBestellung = getProvision(bestellung.ausweis.ausweisart, bestellung.ausweis.ausweistyp, provisionen)}
<tr class="border-b border-gray-300 hover:bg-gray-100">
<td class="text-center py-2 px-4 w-24" style="font-family: monospace;">{bestellung.ausweis.id}</td>
<td class="text-center py-2 font-bold w-32">{moment(bestellung.created_at).format("DD.MM.YYYY HH:mm")}</td>
<td class="text-center py-2 w-32">{bestellung.ausweis.ausweisart} {bestellung.ausweis.ausweistyp}</td>
<td class="text-center py-2 w-32">{provisionBestellung?.provision_prozent || 0} %</td>
<td class="text-right py-2 w-24" style="font-family: monospace;">{provisionBestellung?.provision_betrag.toFixed(2)}</td>
</tr>
{/each}
</tbody>
</table>
</div>
</details>
{:else if !bestellungenNachMonat[jahrMonat] || bestellungenNachMonat[jahrMonat].length === 0}
<details class="group">
<summary class="flex justify-between items-center cursor-pointer p-4 bg-gray-100 hover:bg-gray-200">
<span class="font-semibold">{moment(dt).format("MMMM YYYY")}</span>
<div class="flex flex-row gap-4 items-center">
<span class="text-gray-500">Keine Bestellungen gefunden</span>
<svg class="w-4 h-4 transition-transform duration-300 group-open:rotate-180" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polyline points="6 9 12 15 18 9"></polyline>
</svg>
</div>
</summary>
<div class="p-4 border-t border-gray-200">
<p class="text-gray-500">Für diesen Monat liegen uns keine Bestellungen über ihren Resellercode vor.</p>
</div>
</details>
{/if}
{/each}
</main>

View File

@@ -75,7 +75,7 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
>
<option disabled selected value={null}>Bitte auswählen</option>
{#if ausweisart==Enums.Ausweisart.VerbrauchsausweisWohnen || ausweisart === Enums.Ausweisart.GEGNachweisWohnen || ausweisart === Enums.Ausweisart.BedarfsausweisWohnen}
{#if ausweisart==Enums.Ausweisart.VerbrauchsausweisWohnen || ausweisart === Enums.Ausweisart.GEGNachweisWohnen || ausweisart === Enums.Ausweisart.BedarfsausweisWohnen || ausweisart === Enums.Ausweisart.BedarfsausweisGewerbe}
<option value="Einfamilienhaus">Einfamilienhaus</option>
<option value="Freistehendes Einfamilienhaus">Freistehendes Einfamilienhaus</option>
<option value="Freistehendes Zweifamilienhaus">Freistehendes Zweifamilienhaus</option>
@@ -87,7 +87,7 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
<option value="Atrium-Bungalow">Atrium-Bungalow</option>
<option value="Winkelbungalow">Winkelbungalow</option>
{:else if ausweisart==Enums.Ausweisart.VerbrauchsausweisGewerbe || ausweisart=== Enums.Ausweisart.GEGNachweisGewerbe || ausweisart === Enums.Ausweisart.BedarfsausweisGewerbe}
{:else if ausweisart==Enums.Ausweisart.VerbrauchsausweisGewerbe || ausweisart=== Enums.Ausweisart.GEGNachweisGewerbe}
<option value="Verwaltungsgebäude (allgemein)">Verwaltungsgebäude (allgemein)</option>
<option value="Parlaments- und Gerichtsgebäude">Parlaments- und Gerichtsgebäude</option>
<option value="Ministerien u. Ämter u. Behörden">Ministerien u. Ämter u. Behörden</option>
@@ -186,7 +186,6 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
onlyUnique={true}
minlength={4}
maxlength={4}
required={true}
onFocusIn={() => {
addNotification({
message: "Info",
@@ -250,7 +249,6 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
minlength={4}
maxlength={4}
onlyUnique={true}
required={true}
onFocusIn={() => {
addNotification({
message: "Info",
@@ -289,7 +287,6 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
onlyUnique={true}
minlength={4}
maxlength={4}
required={true}
onFocusIn={() => {
addNotification({
message: "Info",

View File

@@ -49,12 +49,6 @@
if (!value && element.required) {
element.setCustomValidity("Eine Auswahl ist verpflichtend.")
element.dataset["isinvalid"] = "true"
element.addEventListener("change", () => {
element.setCustomValidity("")
element.dataset["isinvalid"] = "false"
})
} else {
element.setCustomValidity("")
}
@@ -137,11 +131,11 @@
window.history.pushState(
{},
"",
`${location.pathname}?ausweis_id=${ausweis.id}`
`${location.pathname}?id=${ausweis.id}`
);
blockLocalStorageSync = true;
localStorage.clear()
window.location.href = `/dashboard/objekte/${ausweis.id}`
window.location.href = `/speichern-erfolgreich?id=${ausweis.id}`
}
}
@@ -184,15 +178,7 @@ sm:grid-cols-[1fr_min-content_min-content_min-content] sm:justify-self-end">
<Overlay bind:hidden={loginOverlayHidden}>
<div class="bg-white w-full max-w-screen-sm py-8">
<EmbeddedAuthFlowModule onLogin={loginAction} email={""} route="signup" title={
{
login: "Ausweisdaten speichern",
signup: "Ausweisdaten speichern"
}
} buttonText={{
login: "Speichern",
signup: "Speichern"
}}></EmbeddedAuthFlowModule>
<EmbeddedAuthFlowModule onLogin={loginAction} email={""}></EmbeddedAuthFlowModule>
</div>
</Overlay>
@@ -228,8 +214,8 @@ grid-cols-1 gap-x-2 gap-y-4
/>
<div class="text-center xs:text-left justify-self-stretch">
<b>Selbsteingabe online</b><br>inkl. ausführlicher&nbsp;telefonischer
Beratung!
<b>Verbrauchsausweis online</b><br>inkl. ausführlicher&nbsp;telefonischer
Beratung
</div>
<div class="text-center xs:text-right">
@@ -248,7 +234,7 @@ grid-cols-1 gap-x-2 gap-y-4
/>
<div class="text-center xs:text-left justify-self-stretch">
<b>Wir übernehmen die Eingabe</b><br>Sie übermitteln die nötigen Unterlagen per Upload oder E-Mail.
<b>Verbrauchsausweis offline</b><br>Sie schicken uns 3&nbsp;Verbrauchsabrechnungen&nbsp;zu)
</div>
<div class="text-center xs:text-right">

View File

@@ -1,8 +1,9 @@
<script lang="ts">
import HelpLabel from "#components/labels/HelpLabel.svelte";
import Inputlabel from "#components/labels/InputLabel.svelte";
import PlzSuche from "#components/PlzSuche.svelte";
import ZipSearch from "#components/PlzSuche.svelte";
import { Enums } from "#lib/client/prisma.js";
import { AufnahmeClient, ObjektClient } from "./types.js";
@@ -10,24 +11,6 @@
export let objekt: ObjektClient;
export let ausweisart: Enums.Ausweisart;
function onlyAllowIntegerInput(event: KeyboardEvent) {
const charCode = event.which || event.keyCode;
// Allow only numbers (0-9) and control keys (e.g., backspace)
if (charCode < 48 || charCode > 57) {
event.preventDefault();
}
}
function onlyAllowPastingIntegers(event: ClipboardEvent) {
const clipboardData = event.clipboardData || (window as any).clipboardData;
const pastedData = clipboardData.getData("Text");
if (!/^\d+$/.test(pastedData)) {
event.preventDefault();
}
}
let ortInput: HTMLInputElement;
</script>
<div
@@ -70,12 +53,9 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
<div class="input-noHelp">
<Inputlabel title="PLZ *"></Inputlabel>
<PlzSuche
<ZipSearch
bind:zip={objekt.plz}
bind:city={objekt.ort}
onchange={(e) => {
ortInput.dispatchEvent(new Event('change'));
}}
name="plz"
/>
</div>
@@ -89,7 +69,6 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
readonly={false}
required
bind:value={objekt.ort}
bind:this={ortInput}
type="text"
/>
@@ -118,11 +97,10 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
data-test="flaeche"
maxlength="4"
type="number"
step="1"
required
autocomplete="off"
on:keypress={onlyAllowIntegerInput}
on:paste={onlyAllowPastingIntegers}
data-rule-minlength="2"
data-msg-minlength="min. 2 Zeichen"
bind:value={aufnahme.flaeche}
/>
@@ -146,10 +124,7 @@ xl:grid-cols-3 xl:gap-x-8 xl:gap-y-8
data-test="nutzflaeche"
maxlength="4"
type="number"
step="1"
required
on:keypress={onlyAllowIntegerInput}
on:paste={onlyAllowPastingIntegers}
bind:value={aufnahme.nutzflaeche}
/>

View File

@@ -186,7 +186,7 @@ xl:grid-cols-2 xl:gap-x-8 xl:gap-y-8
>
<option>Bitte auswählen</option>
{#each arrayRange(2.1, 4.5, 0.1) as step}
<option value={step} selected={ausweis.geschosshoehe === step}>{step.toFixed(2)} m</option>
<option value={step}>{step.toFixed(2)} m</option>
{/each}
</select>

View File

@@ -1,4 +1,5 @@
<script lang="ts">
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016.js";
import ThickArrowDown from "radix-svelte-icons/src/lib/icons/ThickArrowDown.svelte";
import {
BedarfsausweisWohnenClient,
@@ -8,9 +9,8 @@
VerbrauchsausweisWohnenClient,
} from "./types.js";
import ThickArrowUp from "radix-svelte-icons/src/lib/icons/ThickArrowUp.svelte";
import { Enums } from "#lib/client/prisma.js";
import { endEnergieVerbrauchVerbrauchsausweis_2016_Client } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016_Client.js";
import { endEnergieVerbrauchVerbrauchsausweisGewerbe_2016_Client } from "#lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016_Client.js";
import { Enums } from "#lib/client/prisma";
import { endEnergieVerbrauchVerbrauchsausweisGewerbe_2016 } from "#lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016.js";
export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbeClient | BedarfsausweisWohnenClient;
export let aufnahme: AufnahmeClient;
@@ -21,9 +21,7 @@
[Enums.Ausweisart.VerbrauchsausweisGewerbe]: 1000,
[Enums.Ausweisart.VerbrauchsausweisWohnen]: 250,
[Enums.Ausweisart.BedarfsausweisWohnen]: 250,
[Enums.Ausweisart.BedarfsausweisGewerbe]: 0,
[Enums.Ausweisart.GEGNachweisGewerbe]: 0,
[Enums.Ausweisart.GEGNachweisWohnen]: 0,
[Enums.Ausweisart.BedarfsausweisGewerbe]: 250
}[ausweisart];
/**
@@ -60,23 +58,20 @@
return centeredValue;
}
let translation_1 = 0;
let translation_2 = 0;
$: {
(async () => {
let result;
if (ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen || ausweisart === Enums.Ausweisart.BedarfsausweisWohnen) {
result = await endEnergieVerbrauchVerbrauchsausweis_2016_Client(ausweis, aufnahme, objekt);
result = await endEnergieVerbrauchVerbrauchsausweis_2016(ausweis, aufnahme, objekt);
} else if (ausweisart === Enums.Ausweisart.VerbrauchsausweisGewerbe) {
result = await endEnergieVerbrauchVerbrauchsausweisGewerbe_2016_Client(ausweis, aufnahme, objekt);
result = await endEnergieVerbrauchVerbrauchsausweisGewerbe_2016(ausweis, aufnahme, objekt);
}
if (!result) {
return;
}
translation_1 = Math.max(
0,
Math.min(

View File

@@ -20,14 +20,10 @@
export let ausweisart: Enums.Ausweisart;
</script>
<!--
{#if ausweisart=="BedarfsausweisWohnen"}
<AngabenZurHeizunganlage bind:ausweis/>
{/if}
-->
<div
id="sanierungszustand"
class="bereich-box grid

View File

@@ -63,15 +63,8 @@
fuelMap[fuel[0]].push(fuel[1]);
}
// Falls der Ausweis bereits einmal gespeichert wurde mit einem Startdatum sollten wir dieses benutzen.
let month: number, year: number;
if (ausweis.startdatum) {
month = moment(ausweis.startdatum).get("month")
year = moment(ausweis.startdatum).get("year")
} else {
month = availableDates[availableDates.length - 1].month;
year = availableDates[availableDates.length - 1].year;
}
let month = moment(ausweis.startdatum).month();
let year = moment(ausweis.startdatum).year();
$: {
if (typeof month === "number" && typeof year === "number") {

View File

@@ -52,7 +52,7 @@ $: {
<!-- % Anteil Warmwasser -->
<div class="input-standard order-2 md:order-2 xl:order-2">
<Inputlabel title="% Anteil Kühlung"></Inputlabel>
<Inputlabel title="% Anteil Warmwasser"></Inputlabel>
<input
name="anteil_kuehlung_1"

View File

@@ -40,15 +40,15 @@
"Dezember",
];
const earlistPossibleStartDate = moment(aufnahme.erstellungsdatum || Date.now())
const startDate = moment(aufnahme.erstellungsdatum || Date.now())
.subtract(4, "years")
.subtract(6, "months");
const lastPossibleEndDate = moment(aufnahme.erstellungsdatum || Date.now()).subtract(
const endDate = moment(aufnahme.erstellungsdatum || Date.now()).subtract(
3,
"years"
);
for (let m = moment(earlistPossibleStartDate); m.isBefore(lastPossibleEndDate); m.add(1, "month")) {
for (let m = moment(startDate); m.isBefore(endDate); m.add(1, "month")) {
availableDates.push({
year: m.year(),
month: m.month(),
@@ -62,15 +62,8 @@
fuelMap[fuel[0]].push(fuel[1]);
}
// Falls der Ausweis bereits einmal gespeichert wurde mit einem Startdatum sollten wir dieses benutzen.
let month: number, year: number;
if (ausweis.startdatum) {
month = moment(ausweis.startdatum).get("month")
year = moment(ausweis.startdatum).get("year")
} else {
month = availableDates[availableDates.length - 1].month;
year = availableDates[availableDates.length - 1].year;
}
let month = availableDates[availableDates.length - 1].month;
let year = availableDates[availableDates.length - 1].year;
$: {
if (typeof month === "number" && typeof year === "number") {

View File

@@ -16,7 +16,7 @@ const brennstoffe: [
["Flüssiggas", "kg", 13.0, 1.1, 0.27],
["Braunkohle", "kg", 5.5, 1.2, 0.43],
["Holzhackschnitzel", "SRm", 650.0, 0.2, 0.02],
["Strommix", "kWh", 1.0, 1.8, 0.56],
["Strommix", "kWh", 1.0, 2.4, 0.56],
["Fernwärme KWK FB", "kWh", 1.0, 0.7, 0.3],
["Nahwärme KWK FB", "kWh", 1.0, 0.7, 0.3],
["Heizöl EL", "kWh", 1.0, 1.1, 0.31],
@@ -41,10 +41,6 @@ const brennstoffe: [
["Fernwärme KWK EB", "kWh", 1.0, 0.0, 0.04],
["Fernwärme HKW FB", "kWh", 1.0, 1.3, 0.4],
["Fernwärme HKW EB", "kWh", 1.0, 0.1, 0.06],
["Fernwärme Hamburg", "kWh", 1.0, 0.33, 0.064],
["Fernwärme Erfurt", "kWh", 1.0, 0.3, 0],
["Fernwärme Neumünster", "kWh", 1.0, 0.28, 0.0133],
["Fernwärme Pforzheim", "kWh", 1.0, 0.25, 0],
["Erdgas", "kWh", 1.0, 1.1, 0.24],
["Heizöl", "kWh", 1.0, 1.1, 0.31],
["Heizöl", "l", 10.0, 1.1, 0.31],

View File

@@ -14,7 +14,6 @@ import {
GEGNachweisWohnen,
BedarfsausweisGewerbe,
GEGNachweisGewerbe,
GEGEinpreisung
} from "#lib/client/prisma.js";
import { z, ZodSchema } from "zod";
@@ -80,8 +79,6 @@ export type BenutzerClient = OmitKeys<Benutzer, "passwort">;
export type RechnungClient = Rechnung
export type GEGEinpreisungClient = GEGEinpreisung
export function ZodOverlap<T, S = z.ZodType<T, z.ZodTypeDef, T>>(arg: S): S {
return arg;
}
@@ -100,7 +97,7 @@ export type OptionalNullable<T> = T extends object ? {
[K in keyof PickNotNullable<T>]: OptionalNullable<T[K]>
} : T;
export const IDWithPrefix = z.string().refine((value) => {
export const UUidWithPrefix = z.string().refine((value) => {
const prefixedUUidRegex = /^([A-Z]{2})[0-9A-Z]{6,9}$/i
const match = value.match(prefixedUUidRegex)
@@ -113,7 +110,7 @@ export const IDWithPrefix = z.string().refine((value) => {
})
export function getAusweisartFromId(id: string): Enums.Ausweisart | null {
if (!IDWithPrefix.safeParse(id).success) {
if (!UUidWithPrefix.safeParse(id).success) {
return null
}

View File

@@ -0,0 +1,939 @@
<script lang="ts">
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016.js";
import moment from "moment";
import {
AufnahmeClient,
getAusweisartFromId,
ObjektClient,
BildClient,
VerbrauchsausweisWohnenClient,
} from "./Ausweis/types.js";
import AusweisPruefenTooltip from "./AusweisPruefenTooltip.svelte";
import { addNotification } from "#components/Notifications/shared.js";
import { CheckCircled, CrossCircled, Image } from "radix-svelte-icons";
import ChevronDown from "radix-svelte-icons/src/lib/icons/ChevronDown.svelte";
import { Event } from "#lib/client/prisma.js";
import { api } from "astro-typesafe-api/client";
import Cookies from "js-cookie";
import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants.js";
import NotificationWrapper from "./Notifications/NotificationWrapper.svelte";
export let ausweis: VerbrauchsausweisWohnenClient;
export let aufnahme: AufnahmeClient;
export let objekt: ObjektClient;
export let bilder: BildClient[]
export let events: Event[]
export let calculations: Awaited<
ReturnType<typeof endEnergieVerbrauchVerbrauchsausweis_2016>
>;
async function ausweisAusstellen(uid: string) {
try {
await api.admin.ausstellen.GET.fetch({
id_ausweis: uid
}, {
headers: {
"Authorization": `Bearer ${Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)}`
}
})
} catch(e) {
addNotification({
message: "Das hat nicht geklappt.",
subtext: e as string,
timeout: 3000,
type: "error",
})
}
}
const ausweisArt = getAusweisartFromId(ausweis.id)
let verbrauchWWGesamt_1 = "";
let verbrauchWWGesamt_2 = "";
var Ausweisbild,
DatenBlattBild,
warmWasser,
anteilWarmwasser,
solarsystemWarmwasser;
let zurueckGestellt: any;
let symbolPruefung: any;
let StatusIcon: any;
let tooltip3Z1: any;
let tooltip3Z2: any;
let tooltip4Z1: any;
let tooltip4Z2: any;
let tooltip5Z1: any;
let tooltip5Z2: any;
let tooltip5Z3: any;
let tooltip6Z1: any;
let tooltip6Z2: any;
let tooltip7Z1: any;
let tooltip7Z2: any;
let tooltip8Z1: any;
let tooltip8Z2: any;
let tooltip9Z1: any;
let tooltip9Z2: any;
let tooltip10Z1: any;
let tooltip10Z2: any;
let tooltip11Z1: any;
let tooltip11Z2: any;
let tooltip12Z1: any;
let tooltip12Z2: any;
let tooltip13Z1: any;
let tooltip13Z2: any;
let tooltip14Z1: any;
let tooltip14Z2: any;
let tooltip15Z1: any;
let tooltip15Z2: any;
let tooltip16Z1: any;
let tooltip16Z2: any;
let table3Z1: any;
let table3Z2: any;
let table4Z1: any;
let table4Z2: any;
let table5Z1: any;
let table5Z2: any;
let table6Z1: any;
let table6Z2: any;
let table7Z1: any;
let table7Z2: any;
let table8Z1: any;
let table8Z2: any;
let table9Z1: any;
let table9Z2: any;
let table10Z1: any;
let table10Z2: any;
let table11Z1: any;
let table11Z2: any;
let table12Z1: any;
let table12Z2: any;
let table13Z1: any;
let table13Z2: any;
let table14Z1: any;
let table14Z2: any;
let table15Z1: any;
let table15Z2: any;
let table16Z1: any;
let table16Z2: any;
let Abgeschlossen: any;
if (ausweis.ausgestellt) {
Ausweisbild = "/images/dashboard/ausweishaken.jpg";
DatenBlattBild = "/images/dashboard/datenblatthaken.jpg";
StatusIcon = "/images/dashboard/erledigt.svg";
Abgeschlossen = 0;
} else if (ausweis.bestellt) {
Ausweisbild = "/images/dashboard/ausweis.jpg";
DatenBlattBild = "/images/dashboard/datenblatt.jpg";
StatusIcon = "/images/dashboard/bestellt.svg";
Abgeschlossen = 1;
} else {
Ausweisbild = "/images/dashboard/ausweiskreuz.jpg";
DatenBlattBild = "/images/dashboard/datenblattkreuz.jpg";
StatusIcon = "/images/dashboard/gespeichert.svg";
Abgeschlossen = 2;
}
if (ausweis.boxpruefung) {
symbolPruefung = "/images/dashboard/kreishaken.png";
} else {
symbolPruefung = "/images/dashboard/kreiskreuz.png";
}
if (ausweis.zurueckgestellt) {
zurueckGestellt =
"<img src='/images/dashboard/zurueckGestellt.svg' alt='Status' width=\"25\" height=\"25\"></img>";
} else {
zurueckGestellt = "";
}
if (ausweis.warmwasser_enthalten) {
warmWasser = "Warmwasser enthalten";
} else {
warmWasser = "Warmwasser nicht enthalten";
}
if (ausweis.warmwasser_anteil_bekannt) {
anteilWarmwasser = "Anteil bekannt";
} else {
anteilWarmwasser = "Anteil unbekannt";
}
if (
ausweis.warmwasser_enthalten &&
ausweis.warmwasser_anteil_bekannt
) {
if (aufnahme.solarsystem_warmwasser) {
// Wenn Warmwasser enthalten und Anteil bekannt und Solarsystem
verbrauchWWGesamt_1 = `${calculations?.energieVerbrauchGesamt_1} kWh x ${(ausweis.anteil_warmwasser_1 || 0) / 100} x 0.6`;
verbrauchWWGesamt_2 = `${calculations?.energieVerbrauchGesamt_2} kWh x ${(ausweis.anteil_warmwasser_2 || 0) / 100} x 0.6`;
solarsystemWarmwasser = "Solarsystem Warmwasser";
} else {
// Wenn Warmwasser enthalten und Anteil bekannt und **kein** Solarsystem
verbrauchWWGesamt_1 = `${calculations?.energieVerbrauchGesamt_1} kWh x ${(ausweis.anteil_warmwasser_1 || 0) / 100} x 0.6`
verbrauchWWGesamt_2 = `${calculations?.energieVerbrauchGesamt_2} kWh x ${(ausweis.anteil_warmwasser_2 || 0) / 100} x 0.6`
solarsystemWarmwasser = "kein Solarsystem Warmwasser";
}
} else {
if (aufnahme.solarsystem_warmwasser) {
// Wenn Warmwasser Anteil unbekannt und Solarsystem
verbrauchWWGesamt_1 =
calculations?.energetischeNutzflaeche +
" m² x 12 kWh/m² x 3 Jahre";
solarsystemWarmwasser = "Solarsystem Warmwasser";
} else {
// Wenn Warmwasser Anteil unbekannt und **kein** Solarsystem
verbrauchWWGesamt_1 =
calculations?.energetischeNutzflaeche +
" m² x 20 kWh/m² x 3 Jahre";
solarsystemWarmwasser = "kein Solarsystem Warmwasser";
}
}
tooltip3Z1 = "Wohnfläche in m²";
tooltip3Z2 =
ausweis.faktorKeller +
" x " +
aufnahme.flaeche +
" m² Energetische Nutzfläche (Keller " +
aufnahme.keller +
" ) in m²";
table3Z1 = aufnahme.flaeche;
table3Z2 = calculations?.energetischeNutzflaeche;
tooltip4Z1 =
"(" +
ausweis.verbrauch_1 +
" " +
ausweis.einheit_1 +
" + " +
ausweis.verbrauch_2 +
" " +
ausweis.einheit_1 +
" + " +
ausweis.verbrauch_3 +
" " +
ausweis.einheit_1 +
") x " +
calculations?.brennstoff_1.umrechnungsfaktor +
" kWh/" +
ausweis.einheit_1 +
" >> Verbrauch 1 " +
ausweis.brennstoff_1 +
" in kWh";
tooltip4Z2 =
"(" +
ausweis.verbrauch_4 +
" " +
ausweis.einheit_2 +
" + " +
ausweis.verbrauch_5 +
" " +
ausweis.einheit_2 +
" + " +
ausweis.verbrauch_6 +
" " +
ausweis.einheit_2 +
") x " +
calculations?.brennstoff_2.umrechnungsfaktor +
" kWh/" +
ausweis.einheit_2 +
" >> Verbrauch 2 " +
ausweis.brennstoff_2 +
" in kWh";
table4Z1 = calculations?.energieVerbrauchGesamt_1;
table4Z2 = calculations?.energieVerbrauchGesamt_2;
tooltip5Z1 =
warmWasser + ", " + anteilWarmwasser + ", " + solarsystemWarmwasser;
tooltip5Z2 = verbrauchWWGesamt_1;
tooltip5Z3 = verbrauchWWGesamt_2;
table5Z1 = calculations?.energieVerbrauchWarmwasser_1;
table5Z2 = calculations?.energieVerbrauchWarmwasser_2;
tooltip6Z1 =
"(" +
calculations?.klimafaktoren[0].klimafaktor +
" + " +
calculations?.klimafaktoren[1].klimafaktor +
" + " +
calculations?.klimafaktoren[2].klimafaktor +
") / 3 >> durchschnittlicher Klimafaktor";
tooltip6Z2 = "";
table6Z1 = calculations?.durchschnittsKlimafaktor;
table6Z2 = "";
tooltip7Z1 =
calculations?.energieVerbrauchHeizung_1 +
" kWh x " +
calculations?.durchschnittsKlimafaktor +
" >> Klimabereinigter Heizverbrauch 1 in kWh";
tooltip7Z2 =
calculations?.energieVerbrauchHeizung_2 +
" kWh x " +
calculations?.durchschnittsKlimafaktor +
" >> Klimabereinigter Heizverbrauch 2 in kWh";
table7Z1 = calculations?.energieVerbrauchHeizungBereinigt_1;
table7Z2 = calculations?.energieVerbrauchHeizungBereinigt_2;
tooltip8Z1 =
calculations?.energetischeNutzflaeche +
" m² x 6 kWh/m² x 3 Jahre >> Kühlungszuschlag in kWh";
tooltip8Z2 = "";
table8Z1 = calculations?.kuehlungsZuschlag;
table8Z2 = "";
tooltip9Z1 =
"-0.0028 x " +
calculations?.durchschnittsEnergieVerbrauchHeizungBereingt +
" + 0.9147 >> Heizungsfaktor";
tooltip9Z2 =
"(" +
calculations?.energieVerbrauchHeizungBereinigt_1 +
" + " +
calculations?.energieVerbrauchHeizungBereinigt_2 +
") / (3 * " +
calculations?.energetischeNutzflaeche +
") >> Durchschnittsverbrauch Heizung in kWh";
table9Z1 =
calculations?.faktorDurchschnittsEnergieVerbrauchHeizungBereinigt;
table9Z2 = calculations?.durchschnittsEnergieVerbrauchHeizungBereingt;
tooltip10Z1 =
calculations[
"faktorDurchschnittsEnergieVerbrauchHeizungBereinigt"
] +
" x " +
calculations?.leerstand +
" x (" +
calculations.energieVerbrauchHeizungBereinigt_1 +
" + " +
calculations.energieVerbrauchHeizungBereinigt_2 +
") >> Leerstandszuschlag Heizung in kWh";
tooltip10Z2 =
calculations?.leerstand +
" x (" +
calculations?.energieVerbrauchWarmwasser_1 +
" + " +
calculations?.energieVerbrauchWarmwasser_2 +
") >> Leerstandszuschlag Warmwasser in kWh";
table10Z1 = calculations?.leerstandsZuschlagHeizung;
table10Z2 = calculations?.leerstandsZuschlagWarmwasser;
tooltip11Z2 =
"(" +
calculations?.energieVerbrauchHeizungBereinigt_2 +
" + " +
calculations?.energieVerbrauchWarmwasser_2 +
") / (3 Jahre x " +
calculations?.energetischeNutzflaeche +
") Endenergieverbrauch 2 in kWh/m²a";
table11Z1 = calculations?.endEnergieVerbrauch_1;
table11Z2 = calculations?.endEnergieVerbrauch_2;
tooltip12Z1 =
"((" +
calculations?.energieVerbrauchHeizungBereinigt_1 +
" x " +
calculations?.primaerfaktor_1 +
") + (" +
calculations?.energieVerbrauchWarmwasser_1 +
" x " +
calculations?.primaerfaktorww +
")) / (3 Jahre x " +
calculations?.energetischeNutzflaeche +
") Primärenergieverbrauch 1 in kWh/m²a";
tooltip12Z2 =
"((" +
calculations?.energieVerbrauchHeizungBereinigt_2 +
" x " +
calculations?.primaerfaktor_1 +
") + (" +
calculations?.energieVerbrauchWarmwasser_2 +
" x " +
calculations?.primaerfaktorww_1 +
")) / (3 Jahre x " +
calculations?.energetischeNutzflaeche +
") Primärenergieverbrauch 2 in kWh/m²a";
table12Z1 = calculations?.primaerEnergieVerbrauch_1;
table12Z2 = calculations?.primaerEnergieVerbrauch_2;
tooltip13Z1 =
"(" +
calculations?.leerstandsZuschlagHeizung +
" + " +
calculations?.leerstandsZuschlagWarmwasser +
") / (3 Jahre x " +
calculations?.energetischeNutzflaeche +
") Endenergieverbrauch Leerstand in kWh/m²a";
tooltip13Z2 =
"(" +
calculations?.kuehlungsZuschlag +
") / (3 Jahre x " +
calculations?.energetischeNutzflaeche +
") Endenergieverbrauch Kühlung in kWh/m²a";
table13Z1 = calculations?.endEnergieVerbrauchLeerstandsZuschlag;
table13Z2 = calculations?.endEnergieVerbrauchKuehlungsZuschlag;
tooltip14Z1 =
calculations?.endEnergieVerbrauchLeerstandsZuschlag +
" x " +
calculations?.primaerfaktor +
" Primärenergieverbrauch Leerstand in kWh/m²a";
tooltip14Z2 =
calculations?.endEnergieVerbrauchKuehlungsZuschlag +
" x 1.8 Primärenergieverbrauch Kühlung in kWh/m²a";
table14Z1 = calculations?.primaerEnergieVerbrauchLeerstandsZuschlag;
table14Z2 = calculations?.primaerEnergieVerbrauchKuehlungsZuschlag;
tooltip15Z1 =
calculations?.endEnergieVerbrauch_1 +
" + " +
calculations?.endEnergieVerbrauch_2 +
" + " +
calculations?.endEnergieVerbrauchLeerstandsZuschlag +
" + " +
calculations?.endEnergieVerbrauchKuehlungsZuschlag +
" Endenergieverbrauch in kWh/m²a";
tooltip15Z2 =
"(" +
calculations?.endEnergieVerbrauch_1 +
" x " +
calculations?.co2Emissionen_1 +
") + (" +
calculations?.endEnergieVerbrauch_2 +
" x " +
calculations?.co2Emissionen_2 +
") + (" +
calculations?.endEnergieVerbrauchLeerstandsZuschlag +
" x " +
calculations?.co2Emissionen_1 +
") + (" +
calculations?.endEnergieVerbrauchKuehlungsZuschlag +
" x " +
calculations?.co2Emissionen_1 +
") CO2-Emissionen in kg/m²a";
table15Z1 = calculations?.endEnergieVerbrauchGesamt;
table15Z2 = calculations?.co2EmissionenGesamt;
tooltip16Z1 =
calculations?.primaerEnergieVerbrauch_1 +
" + " +
calculations?.primaerEnergieVerbrauch_2 +
" + " +
calculations?.primaerEnergieVerbrauchLeerstandsZuschlag +
" x " +
calculations?.primaerEnergieVerbrauchKuehlungsZuschlag +
" Primärenergieverbrauch in kWh/m²a";
tooltip16Z2 = "Effizienzklasse";
table16Z1 = calculations?.primaerEnergieVerbrauchGesamt;
table16Z2 = aufnahme.energieeffizienzklasse;
let imagePreview = "";
// let imageJson = JSON.parse(ausweis.images);
// let imagePreview = "";
// if (typeof imageJson === "object") {
// imagePreview =
// imageJson.daemmung.toString() +
// "," +
// imageJson.general.toString() +
// "," +
// imageJson.fenster.toString() +
// "," +
// imageJson.heizung.toString();
// }
async function stornieren(ausweis: VerbrauchsausweisWohnenClient) {
try {
const response = await api.admin.stornieren.PUT.fetch({
uid_ausweis: ausweis.id
}, {
headers: {
"Authorization": `Bearer ${Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)}`
}
})
addNotification({
message: "Ausweis wurde storniert",
type: "success",
dismissable: true,
timeout: 3000,
})
ausweis.storniert = true;
ausweis = ausweis;
} catch(e) {
addNotification({
message: "Ausweis konnte nicht storniert werden.",
subtext: e as string,
type: "error",
dismissable: true,
timeout: 3000,
})
}
}
let bilderModal: HTMLDialogElement;
let infoVisible = false;
async function registriernummerAnfordern(uid: string) {
try {
const result = await api.admin.registriernummer.GET.fetch({
uid
}, {
headers: {
"Authorization": `Bearer ${Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)}`
}
})
} catch(e) {
addNotification({
message: "Registriernummer anfordern fehlgeschlagen.",
subtext: e as string,
type: "error",
dismissable: true,
timeout: 3000,
})
}
}
</script>
<div class="border rounded-lg bg-base-200">
<table class="">
<tbody>
<tr>
<td><button on:click={() => infoVisible = !infoVisible}><ChevronDown size={22} class="transition-all {infoVisible ? "" : "rotate-180"}"></ChevronDown></button></td>
<td class="w-6 px-2"
>
{#if ausweis.ausgestellt}
<div class="tooltip" data-tip="Ausweis wurde ausgestellt">
<div class="rounded-full w-6 h-6 bg-success"></div>
</div>
{:else if ausweis.bestellt}
<div class="tooltip" data-tip="Ausweis wurde bestellt">
<div class="rounded-full w-6 h-6 bg-warning"></div>
</div>
{:else}
<div class="tooltip" data-tip="Ausweis ist in Bearbeitung">
<div class="rounded-full w-6 h-6 bg-error"></div>
</div>
{/if}
</td
>
<td width="150px"
>
<AusweisPruefenTooltip>
<div slot="tooltip">
<span>{aufnahme.adresse} {aufnahme.plz} {aufnahme.ort}</span>
<br>
<span>{aufnahme.gebaeudetyp}, Einheiten: {aufnahme.einheiten}</span>
</div>
<span>{ausweisArt} - {aufnahme.id}</span>
<span>{moment(aufnahme.erstellungsdatum).format("DD.MM.YYYY")}</span>
</AusweisPruefenTooltip></td
>
<td width="35px"
>
<AusweisPruefenTooltip>
<div slot="tooltip">
<span>Baujahr Gebäude / Baujahr Heizung</span>
</div>
<span>{aufnahme.baujahr_gebaeude.join(", ")}</span>
<span>{aufnahme.baujahr_heizung.join(", ")}</span>
</AusweisPruefenTooltip>
<div class="tooltip" data-tip="">
</div></td
>
<td width="45px"
>
<AusweisPruefenTooltip>
<div slot="tooltip">
<span>Wohnfläche in m²</span>
<br>
<span>{ausweis.faktorKeller} x {aufnahme.flaeche}m² Energetische Nutzfläche (Keller {aufnahme.keller}) in m²</span>
</div>
<span>{aufnahme.flaeche}</span>
<span><strong>{calculations?.energetischeNutzflaeche}</strong></span>
</AusweisPruefenTooltip>
</td
>
<td width="90px"
>
<AusweisPruefenTooltip>
<div slot="tooltip">
<span>{tooltip4Z1}</span>
<br>
<span>{tooltip4Z2}</span>
</div>
<span>{table4Z1}</span>
<span>{table4Z2}</span>
</AusweisPruefenTooltip></td
>
<td width="70px"
>
<AusweisPruefenTooltip>
<div slot="tooltip">
<span>{tooltip5Z1}</span>
<br>
<span>{tooltip5Z2}</span>
<br>
<span>{tooltip5Z3}</span>
</div>
<span>{table5Z1}</span>
<span>{table5Z2}</span>
</AusweisPruefenTooltip>
</td
>
<td width="50px"
>
<AusweisPruefenTooltip>
<div slot="tooltip">
<span>{tooltip6Z1}</span>
<br>
<span>{tooltip6Z2}</span>
</div>
<span><strong>{table6Z1}</strong></span>
<span><strong>{table6Z2}</strong></span>
</AusweisPruefenTooltip></td
>
<td width="90px"
>
<AusweisPruefenTooltip>
<div slot="tooltip">
<span>{tooltip7Z1}</span>
<br>
<span>{tooltip7Z2}</span>
</div>
<span>{table7Z1}</span>
<span>{table7Z2}</span>
</AusweisPruefenTooltip></td
>
<td width="60px"
>
<AusweisPruefenTooltip>
<div slot="tooltip">
<span>{tooltip8Z1}</span>
<br>
<span>{tooltip8Z2}</span>
</div>
<span>{table8Z1}</span>
<span>{table8Z2}</span>
</AusweisPruefenTooltip></td
>
<td width="50px"
>
<AusweisPruefenTooltip>
<div slot="tooltip">
<span>{tooltip9Z1}</span>
<br>
<span>{tooltip9Z2}</span>
</div>
<span>{table9Z1}</span>
<span><strong>{table9Z2}</strong></span>
</AusweisPruefenTooltip></td
>
<td width="100px"
>
<AusweisPruefenTooltip>
<div slot="tooltip">
<span>{tooltip10Z1}</span>
<br>
<span>{tooltip10Z2}</span>
</div>
<span>{table10Z1}</span>
<span>{table10Z2}</span>
</AusweisPruefenTooltip></td
>
<td width="110px"
>
<AusweisPruefenTooltip>
<div slot="tooltip">
<span>({calculations?.energieVerbrauchHeizungBereinigt_1} + {calculations?.energieVerbrauchWarmwasser_1}) / (3 Jahre x {calculations?.energetischeNutzflaeche}) Endenergieverbrauch 1 in kWh/m²a</span>
<br>
<span>{tooltip11Z2}</span>
</div>
<span>{table11Z1}</span>
<span>{table11Z2}</span>
</AusweisPruefenTooltip></td
>
<td width="50px"
>
<AusweisPruefenTooltip>
<div slot="tooltip">
<span>{tooltip12Z1}</span>
<br>
<span>{tooltip12Z2}</span>
</div>
<span>{table12Z1}</span>
<span>{table12Z2}</span>
</AusweisPruefenTooltip>
</td
>
<td width="60px"
>
<AusweisPruefenTooltip>
<div slot="tooltip">
<span>{tooltip13Z1}</span>
<br>
<span>{tooltip13Z2}</span>
</div>
<span>{table13Z1}</span>
<span>{table13Z2}</span>
</AusweisPruefenTooltip>
</td
>
<td width="45px"
>
<AusweisPruefenTooltip>
<div slot="tooltip">
<span>{tooltip14Z1}</span>
<br>
<span>{tooltip14Z2}</span>
</div>
<span>{table14Z1}</span>
<span>{table14Z2}</span>
</AusweisPruefenTooltip>
</td
>
<td width="45px"
>
<AusweisPruefenTooltip>
<div slot="tooltip">
<span>{tooltip15Z1}</span>
<br>
<span>{tooltip15Z2}</span>
</div>
<span><strong>{table15Z1}</strong></span>
<span><strong>{table15Z2}</strong></span>
</AusweisPruefenTooltip>
</td
>
<td width="50px"
>
<AusweisPruefenTooltip>
<div slot="tooltip">
<span>{tooltip16Z1}</span>
<br>
<span>{tooltip16Z2}</span>
</div>
<span><strong>{table16Z1}</strong></span>
<span><strong>{table16Z2}</strong></span>
</AusweisPruefenTooltip>
</td
>
<td title="Gebäudebilder anzeigen"
><!-- Open the modal using ID.showModal() method -->
<button class="btn btn-square" on:click={() => bilderModal.showModal()}><Image size={22}></Image></button>
<dialog bind:this={bilderModal} class="modal p-4 rounded-lg">
<div class="modal-box flex flex-row gap-4 items-center justify-center">
{#if bilder.length === 0}
<div class="flex flex-col gap-4 items-center justify-center">
<p>Für diesen Ausweis sind noch keine Bilder vorhanden.</p>
<button class="button" tabindex="0">Erinnerung Verschicken</button>
</div>
{:else}
{#each bilder as image}
<div>
<h2 class="text-lg mb-4 font-bold">{image.kategorie}</h2>
<img src="/bilder/{image.id}.jpg">
</div>
{/each}
{/if}
</div>
<form method="dialog" class="modal-backdrop">
<button class="button">Close</button>
</form>
</dialog></td
>
<td class="w-[30px]"
>
<AusweisPruefenTooltip>
<div slot="tooltip">
<span>{aufnahme.prueftext}</span>
</div>
{#if ausweis.boxpruefung}
<CheckCircled size={22}></CheckCircled>
{:else}
<CrossCircled size={22}></CrossCircled>
{/if}
</AusweisPruefenTooltip></td
>
<td title="Ausweis anzeigen" class="w-[50px]"
><a
class="energieausweis-img"
href="/pdf/ansichtsausweis?uid={ausweis.id}"
target="_blank"
><img
src="/images/dashboard/ausweis.jpg"
alt="Energieausweis"
class="w-full h-8"
/></a
></td
>
<td title="Datenblatt anzeigen" width="50px"
><a
class="energieausweis-img"
href="/pdf/datenblatt?uid={ausweis.id}"
target="_blank"
><img
src="/images/dashboard/datenblatt.jpg"
alt="Datenblatt"
/></a
></td
>
<td
title="Ausweis stornieren und Zahlung wenn erforderlich automatisch zurückbuchen"
class="w-4 p-1"
><button
class="btn btn-xs btn-ghost"
on:click={() => stornieren(ausweis)}>S</button
></td
>
<td title="Ausweis ausstellen" class="w-4 p-1"
><button
class="btn btn-xs btn-ghost"
on:click={() => ausweisAusstellen(aufnahme.uid)}>A</button
></td
>
<td
title="Ausweis ausstellen und per Post verschicken"
class="w-4 p-1"
><button
class="btn btn-xs btn-ghost"
on:click={() => ausweisAusstellenPost(aufnahme.uid)}>P</button
></td
>
<td
title="E-Mail an Kunden schicken mit Erläuterungen warum der Ausweis noch nicht ausgestellt werden kann."
class="w-4 p-1"
><button
class="btn btn-xs btn-ghost"
on:click={() => ausweisnichtAusstellen(aufnahme.uid)}>N</button
></td
>
<td
title="Bestellbestätigung nochmal schicken (Zahlung nicht erfolgreich)"
class="w-4 p-1"
><button
class="btn btn-xs btn-ghost"
on:click={() => bestellBestaetigung(aufnahme.uid)}>B</button
></td
>
<td
title="E-Mail an Kunden schicken mit Erinnerung die Bestellung abzuschließen."
class="w-4 p-1"
><button
class="btn btn-xs btn-ghost"
on:click={() => erinnern(aufnahme.uid)}
>E</button
></td
>
<td
title="Zum Formular mit allen Eingabedaten."
class="w-4 p-1"
><a
class="btn btn-xs btn-ghost"
target="_blank"
href="/energieausweis-erstellen/gespeichert?id={aufnahme.uid}">F</a
></td
>
{#if aufnahme.kontrolldatei}
<td title="XML-Datei an das DiBT verschicken." class="w-4 p-1"><button class="btn btn-xs btn-ghost" on:click={() => {
xmlAbschicken(aufnahme.uid)
}}>X</button></td>
{/if}
{#if !ausweis.registriernummer}
<td title="Registriernummer vom DiBT anfordern." class="w-4 p-1"><button class="btn btn-xs btn-ghost" on:click={() => {
registriernummerAnfordern(ausweis.id)
}}>R</button></td>
{/if}
</tr>
</tbody>
</table>
<div class:hidden={!infoVisible} class:block={infoVisible} class="py-4 border-t">
<div class="grid grid-cols-[2fr_1fr] prose max-w-full">
<div class="border-r px-8">
<h3 class="mt-0">Wichtige Daten</h3>
<table>
<tbody>
<tr>
<td>Angewendete Berechnungsformel</td>
<td><strong>EnEV 2016</strong></td>
</tr>
<tr>
<td>Berechnungsergebnis</td>
<td>{calculations?.endEnergieVerbrauchGesamt}kWh/m2/A - Energieeffizienzklasse <strong>{calculations?.energieEffizienzKlasse}</strong></td>
</tr>
<tr>
<td>Informationen des Nutzers</td>
<td>{ausweis.boxpruefung}</td>
</tr>
<tr>
<td>UID</td>
<td><strong><pre>{ausweis.id}</pre></strong></td>
</tr>
</tbody>
</table>
</div>
<div class="px-8">
<h3 class="mt-0">Ereignisse</h3>
<ul class="timeline timeline-snap-icon max-md:timeline-compact timeline-vertical">
<li>
<div class="timeline-middle">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="h-5 w-5"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z" clip-rule="evenodd" /></svg>
</div>
<div class="timeline-start md:text-end mb-10">
<time class="font-mono italic">{moment(ausweis.erstellungsdatum).format("DD.MM.YYYY - HH:mm")} Uhr</time>
<div class="text-lg font-black">Ausweis erstellt</div>
</div>
<hr/>
</li>
{#each events as event, i}
<li>
<hr />
<div class="timeline-middle">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="h-5 w-5"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z" clip-rule="evenodd" /></svg>
</div>
<div class="mb-10" class:timeline-end={i % 2 == 0} class:timeline-start={i % 2 == 1}>
<time class="font-mono italic">{moment(event.date).format("DD.MM.YYYY - HH:mm")} Uhr</time>
<div class="text-lg font-black">{event.title}</div>
{event.description || ""}
</div>
<hr />
</li>
{/each}
{#if ausweis.erledigt}
<li>
<hr />
<div class="timeline-middle">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="h-5 w-5"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z" clip-rule="evenodd" /></svg>
</div>
<div class="mb-10 timeline-end">
<time class="font-mono italic">{moment(ausweis.ausstellungsdatum).format("DD.MM.YYYY - HH:mm")} Uhr</time>
<div class="text-lg font-black">Ausweis ausgestellt</div>
{ausweis.registriernummer ? `Registriernummer: ${ausweis.registriernummer}` : ""}
</div>
<hr />
</li>
{/if}
</ul>
</div>
</div>
</div>
</div>
<NotificationWrapper />

View File

@@ -0,0 +1,68 @@
<script lang="ts">
import { getZodBaseType } from "#client/lib/helpers.js";
import { filterAusweise } from "#lib/filters.js";
import { ZodTypeAny } from "astro:schema";
import { Cross1 } from "radix-svelte-icons";
import z, { ZodBoolean, ZodNativeEnum, ZodNumber } from "zod"
export let filters: { name: keyof z.infer<typeof filterAusweise>, type: ZodTypeAny, value: any }[] = []
</script>
{#each filters as filter, i}
{@const type = getZodBaseType(filter.type)}
<div class="flex flex-row bg-white gap-4 px-2 py-2 rounded-lg">
{#if i === 0}
<span class="badge">where</span>
{:else}
<span class="badge">and</span>
{/if}
<select on:change={function(e) {
delete filters[filter.name]
filter.name = e.target.value;
filter.type = filterAusweise._def.shape()[filter.name]
filters = filters.filter(Boolean);
}}>
<option value={filter.name} selected>{filter.name}</option>
{#each Object.keys(filterAusweise._def.shape()) as n}
{#if !filters.find(filter => filter.name === n)}
<option value={n}>{n}</option>
{/if}
{/each}
</select>
<span class="badge">equals</span>
{#if type instanceof ZodNumber}
<input type="number" bind:value={filter.value}>
{:else if type instanceof ZodBoolean}
<select bind:value={filter.value}>
<option value={true}>true</option>
<option value={false}>false</option>
</select>
{:else if type instanceof ZodNativeEnum}
<select bind:value={filter.value}>
{#each Object.entries(type._def.values) as [key, value]}
<option {value}>{key}</option>
{/each}
</select>
{:else}
<input type="text" bind:value={filter.value}>
{/if}
<Cross1 size={24} class="cursor-pointer"></Cross1>
</div>
{/each}
<button on:click={() => {
const entry = Object.entries(filterAusweise._def.shape())[0]
filters.push({
name: entry[0],
type: entry[1],
value: null
})
filters = filters
}}>Filter Hinzufügen</button>
<style>
.badge {
@apply rounded-lg px-2 py-1 bg-gray-500 text-white;
}
</style>

View File

@@ -1,34 +1,28 @@
<script lang="ts">
import { AufnahmeKomplettClient, BedarfsausweisWohnenClient, BenutzerClient, getAusweisartFromId, RechnungClient, GEGEinpreisungClient, VerbrauchsausweisGewerbeClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js";
import { AufnahmeKomplettClient, BedarfsausweisWohnenClient, BenutzerClient, getAusweisartFromId, RechnungClient, VerbrauchsausweisGewerbeClient, VerbrauchsausweisWohnenClient } from "#components/Ausweis/types.js";
import moment from "moment";
import { dialogs } from "svelte-dialogs";
import {
CrossCircled,
DotsVertical,
Download,
Pencil2,
QuestionMarkCircled,
} from "radix-svelte-icons";
import { endEnergieVerbrauchVerbrauchsausweis_2016 } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016.js";
import { api } from "astro-typesafe-api/client";
import Cookies from "js-cookie";
import { API_ACCESS_TOKEN_COOKIE_NAME, AusstellungsTyp } from "#lib/constants.js";
import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants.js";
import { Enums, Objekt } from "#lib/client/prisma.js";
import { addNotification, updateNotification } from "#components/Notifications/shared.js";
import { endEnergieVerbrauchVerbrauchsausweis_2016_Client } from "#lib/Berechnungen/VerbrauchsausweisWohnen/VerbrauchsausweisWohnen_2016_Client.js";
import { endEnergieVerbrauchVerbrauchsausweisGewerbe_2016_Client } from "#lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016_Client.js";
import { endEnergieVerbrauchVerbrauchsausweisGewerbe_2016 } from "#lib/Berechnungen/VerbrauchsausweisGewerbe/VerbrauchsausweisGewerbe_2016.js";
import { addNotification } from "#components/Notifications/shared.js";
import moment from "moment";
export let ausweis: VerbrauchsausweisWohnenClient | VerbrauchsausweisGewerbeClient | BedarfsausweisWohnenClient;
export let aufnahme: AufnahmeKomplettClient;
export let rechnung: RechnungClient | null;
export let einpreisung: GEGEinpreisungClient | null;
export let rechnung: RechnungClient;
export let objekt: Objekt;
export let benutzer: BenutzerClient;
import { FileText } from "radix-svelte-icons";
import NotificationProvider from "#components/NotificationProvider/NotificationProvider.svelte";
import DashboardNotification from "./DashboardNotification.svelte";
import { notifications } from "#components/NotificationProvider/shared.js";
import { Bell } from "radix-svelte-icons";
import mime from "mime"
const progress = ausweis.ausgestellt ? 100 : ausweis.bestellt ? 66 : 33;
const ausweisart = getAusweisartFromId(ausweis.id);
@@ -93,15 +87,15 @@
let calculations = null;
if (ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen) {
calculations = endEnergieVerbrauchVerbrauchsausweis_2016_Client(ausweis as VerbrauchsausweisWohnenClient, aufnahme, objekt);
calculations = endEnergieVerbrauchVerbrauchsausweis_2016(ausweis as VerbrauchsausweisWohnenClient, aufnahme, objekt);
} else if (ausweisart === Enums.Ausweisart.VerbrauchsausweisGewerbe) {
calculations = endEnergieVerbrauchVerbrauchsausweisGewerbe_2016_Client(ausweis as VerbrauchsausweisGewerbeClient, aufnahme, objekt);
calculations = endEnergieVerbrauchVerbrauchsausweisGewerbe_2016(ausweis as VerbrauchsausweisGewerbeClient, aufnahme, objekt);
}
async function registriernummer() {
async function registriernummerAnfordern() {
try {
const result = await api.admin.registriernummer.GET.fetch({
id: ausweis.id
uid: ausweis.id
}, {
headers: {
"Authorization": `Bearer ${Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)}`
@@ -121,7 +115,7 @@
async function stornieren() {
try {
const response = await api.admin.stornieren.PUT.fetch({
ausweis_id: ausweis.id
uid_ausweis: ausweis.id
}, {
headers: {
"Authorization": `Bearer ${Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)}`
@@ -148,104 +142,17 @@
}
}
async function ausstellen(post = false) {
const notification = addNotification({
message: "Ausweis wird ausgestellt.",
subtext: "Der Ausweis wird nun ausgestellt, bitte habe einen Augenblick geduld..",
type: "info",
timeout: 0,
})
if (ausweisart === Enums.Ausweisart.BedarfsausweisWohnen) {
const results: {data: string, name: string, type: "Sonstiges" | "Ausweis"}[] = []
let i = 0
const dateien = [...(bedarfsausweisAdditionalInput.files || []), ...(bedarfsausweisFileInput.files || [])];
if (dateien.length === 0) {
addNotification({
message: "Bitte laden sie vor dem Ausstellen einen Ausweis hoch.",
timeout: 3000,
type: "error",
dismissable: true
})
return;
}
for (const datei of dateien) {
const reader = new FileReader();
reader.onload = async (ev) => {
const result = reader.result;
if (!result) {
addNotification({
message: `Die Datei ${datei.name} konnte nicht verarbeitet werden.`,
timeout: 3000,
type: "error",
dismissable: true
})
}
results.push({
data: result as string,
name: datei.name,
type: i == dateien.length - 1 ? "Ausweis" : "Sonstiges"
})
i++
if (i === dateien.length) {
try {
await api.admin["bedarfsausweis-ausstellen"].POST.fetch({
id_ausweis: ausweis.id,
post,
files: results
}, {
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)}`
}
})
updateNotification(notification, {
message: "Ausweis ausgestellt.",
subtext: "Der Ausweis wurde erfolgreich ausgestellt.",
timeout: 3000,
type: "success",
})
} catch(e) {
updateNotification(notification, {
message: "Das hat nicht geklappt.",
subtext: e as string,
timeout: 3000,
type: "error",
})
}
}
}
reader.readAsDataURL(datei)
}
} else {
async function ausweisAusstellen() {
try {
await api.admin.ausstellen.GET.fetch({
id_ausweis: ausweis.id,
post
id_ausweis: ausweis.id
}, {
headers: {
"Authorization": `Bearer ${Cookies.get(API_ACCESS_TOKEN_COOKIE_NAME)}`
}
})
ausweis.ausgestellt = true;
updateNotification(notification, {
message: "Ausweis ausgestellt.",
subtext: "Der Ausweis wurde erfolgreich ausgestellt.",
timeout: 3000,
type: "success",
})
} catch(e) {
updateNotification(notification, {
addNotification({
message: "Das hat nicht geklappt.",
subtext: e as string,
timeout: 3000,
@@ -253,25 +160,71 @@
})
}
}
}
let bedarfsausweisFileInput: HTMLInputElement;
let bedarfsausweisAdditionalInput: HTMLInputElement;
let dropdownOpen = false;
function toggleDropdown() {
dropdownOpen = !dropdownOpen;
}
</script>
<div class="relative bg-base-200 border border-base-300 rounded-lg p-4 mx-2">
<div class="mx-auto py-6 px-4 box bg-white">
<!-- Obere Zeile: Titel -->
<div class="border-b flex flex-row pb-2">
<div class="text-xl font-bold">
Verbrauchsausweis Wohnen mit Beratung (Post, Same Day)
</div>
<div class="bg-red-600 ml-auto px-2 py-0.5 text-sm font-semibold rounded-lg text-white">Gespeichert</div>
</div>
<!-- Navigation (1/3) -->
<div class="border-b pt-4 mb-4 flex justify-between items-center">
<button class="bg-gray-300 text-gray-700 px-2 py-1 rounded hover:bg-gray-400">
&laquo;
</button>
<p class="text-gray-700 font-medium">
Ausweis 1/3
</p>
<button class="bg-gray-300 text-gray-700 px-2 py-1 rounded hover:bg-gray-400">
&raquo;
</button>
</div>
<!-- Erster Block: Drei Spalten -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-4">
<!-- Linke Spalte: Bild + ID -->
<div class="flex-shrink-0 bg-gray-100 flex flex-col items-center border text-2xl rounded-b-lg pb-2">
<img
src="../../images/placeholder.png"
alt="Gebäudevorschau"
class="rounded-t-lg mb-2"
/>
<div class="grid grid-cols-1 md:grid-cols-2 gap-2 bg-white">
<!-- PDF-Icon / Ausweis -->
<div class="m-4">
<img
src="../../images/dashboard/AusweisKreuz.svg"
alt="PDF Symbol für Verbrauchsausweis"
class="h-auto w-auto p-2 border border-black rounded-lg"
/>
<span class="text-sm font-medium ml-4">Verbrauchsausweis</span>
</div>
<!-- PDF-Icon / Datenblatt -->
<div class="m-4">
<img
src="../../images/dashboard/DatenblattKreuz.svg"
alt="PDF Symbol für Datenblatt"
class="h-auto w-auto p-2 border border-black rounded-lg"
/>
<span class="text-sm font-medium ml-4">Datenblatt</span>
</div>
</div>
<div class="p-4">Ausweis ID: <b>BWWICR32</b></div>
</div>
<div class="relative bg-base-200 border border-base-300 rounded-lg p-4">
{#if ausweis.storniert}
<div
class="absolute top-0 left-0 w-full h-full bg-[rgba(0,0,0,0.4)] z-[5] rounded-lg select-none"
class="absolute top-0 left-0 w-full h-full bg-[rgba(0,0,0,0.7)] z-[5] rounded-lg select-none"
>
<h1
class="absolute -rotate-[25deg] text-xl md:text-xl tracking-wide uppercase text-red-500 border-4 border-red-500 rounded-lg top-[50%] translate-y-[-50%] left-[50%] translate-x-[-50%]"
class="absolute -rotate-[25deg] text-5xl md:text-7xl tracking-wide uppercase text-red-500 border-4 border-red-500 rounded-lg top-[50%] translate-y-[-50%] left-[50%] translate-x-[-50%]"
>
Storniert
</h1>
@@ -279,53 +232,31 @@
{/if}
<div class="card-body">
<div
class="mb-2 dropdown dropdown-bottom absolute top-4 right-4 bg-base-100"
class="flex justify-end mb-2 dropdown dropdown-bottom absolute top-4 right-4"
>
<button class="rounded-full p-2.5 hover:bg-base-100" on:click={toggleDropdown}>
<button class="rounded-full p-2.5 hover:bg-base-100">
<DotsVertical size={15} />
</button>
</div>
{#if dropdownOpen}
<ul
tabindex="-1"
class="z-[1] menu p-2 shadow bg-base-100 rounded-box w-64 gap-2 border"
class="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-64 gap-2"
>
<!-- <div>
<button on:click={ausweisStornieren} class="flex items-center gap-2" disabled
><CrossCircled size={15} />Stornieren</button
<li>
<button on:click={ausweisStornieren}
><CrossCircled size={15} />Ausweis Stornieren</button
>
</div>
<div>
<button class="flex items-center gap-2" disabled
><Pencil2 size={15} /> Als Vorlage</button>
</div>
<div>
<button on:click={() => hilfeModal.showModal()} class="flex items-center gap-2" disabled
</li>
<li>
<button><Pencil2 size={15} /> Als Vorlage benutzen</button>
</li>
<li>
<button on:click={() => hilfeModal.showModal()}
><QuestionMarkCircled size={15} /> Hilfe Erhalten</button
>
</div> -->
{#if ausweis.bestellt && rechnung}
<div>
<a href="/dashboard/rechnung/aendern?rechnungid={rechnung.id}"><button> Adresse ändern</button
></a>
</div>
{/if}
</li>
</ul>
{/if}
</div>
<div class="flex flex-row flex-wrap items-center gap-2">
{#if ausweis.ausgestellt}
<span class="bg-green-600 px-2 py-0.5 text-sm font-semibold rounded-lg text-white">Ausgestellt</span>
{:else if ausweis.bestellt}
<span class="bg-primary px-2 py-0.5 text-sm font-semibold rounded-lg text-white">Bestellt</span>
{:else}
{#if ausweisart === Enums.Ausweisart.BedarfsausweisGewerbe || ausweisart === Enums.Ausweisart.GEGNachweisWohnen || ausweisart === Enums.Ausweisart.GEGNachweisGewerbe}
<span class="bg-red-600 px-2 py-0.5 text-sm font-semibold rounded-lg text-white">Angefordert</span>
{:else}
<span class="bg-red-600 px-2 py-0.5 text-sm font-semibold rounded-lg text-white">Gespeichert</span>
{/if}
{/if}
<div class="text-lg font-semibold">
{#if ausweisart == Enums.Ausweisart.VerbrauchsausweisWohnen}
Verbrauchsausweis Wohnen
@@ -340,35 +271,42 @@
{:else if ausweisart == Enums.Ausweisart.BedarfsausweisGewerbe}
Bedarfsausweis Gewerbe
{/if}
</div>
</div>
<div class="badge badge-accent font-semibold text-black text-m">
{#if ausweis.ausweistyp === Enums.AusweisTyp.Beratung || ausweis.ausweistyp === Enums.AusweisTyp.BeratungXL}
mit Beratung
(Beratung)
{:else if ausweis.ausweistyp === Enums.AusweisTyp.Offline || ausweis.ausweistyp === Enums.AusweisTyp.OfflineXL}
Offline
{/if}
{#if (rechnung?.services ?? []).length > 0}
{#if rechnung}
<span class="text-sm italic">({rechnung.services})</span>
{/if}
(Offline)
{/if}
</div>
{#if ausweis.ausgestellt}
<span class="bg-green-600 px-2 py-0.5 text-sm font-semibold rounded-lg text-white">Ausgestellt</span>
{:else if ausweis.bestellt}
<span class="bg-primary px-2 py-0.5 text-sm font-semibold rounded-lg text-white">Bestellt</span>
{:else}
<span class="bg-red-600 px-2 py-0.5 text-sm font-semibold rounded-lg text-white">Gespeichert</span>
{/if}
</div>
<div class="badge badge-accent font-semibold text-black text-m">{objekt.adresse}</div>
<div class="mb-4 flex flex-row items-center gap-4">
<div class="w-full border rounded-lg my-2">
<div class="bg-green-600 h-4 rounded-lg" class:bg-red-600={progress == 33} class:bg-primary={progress == 66} style="width: {progress}%;"></div>
</div>
</div>
{#await calculations then calculations}
<div class="flex flex-col mb-4">
<div class="flex flex-row justify-between">
<span>Erstellungsdatum</span>
<span class="font-bold text-base-content"
>{moment(aufnahme.erstellungsdatum).format(
"DD.MM.YYYY"
)}</span
<span class="text-sm font-semibold text-base-content"
>{progress}%</span
>
</div>
{#if ausweis.bestellt}
{#if ausweis.ausweistyp === Enums.AusweisTyp.Beratung || ausweis.ausweistyp === Enums.AusweisTyp.BeratungXL}
<p class="text-sm font-semibold">Sie haben Hilfe zu diesem Ausweis angefordert. Sie werden innerhalb der nächsten 48 Stunden über die hinterlegte Telefonnummer vom IB Cornelsen kontaktiert.</p>
{:else if ausweis.ausweistyp === Enums.AusweisTyp.Offline || ausweis.ausweistyp === Enums.AusweisTyp.OfflineXL}
<p class="text-sm font-semibold">Sie haben die offline Variant zu diesem Ausweis angefordert. Bitte übermitteln Sie uns die letzten drei Jahre der Energieabrechnungen Ihres Energieversorgers.</p>
{:else}
<p class="text-sm font-semibold">Der Ausweis wurde von Ihnen freigegeben und befindet sich in Prüfung vom IB Cornelsen</p>
{/if}
{/if}
{#await calculations then calculations}
<div class="flex flex-col gap-2">
<div class="flex flex-row justify-between">
<span>Energieverbrauch</span>
<span class="font-bold text-base-content"
@@ -381,6 +319,14 @@
>{calculations?.co2EmissionenGesamt}Kg/A</span
>
</div>
<div class="flex flex-row justify-between">
<span>Erstellungsdatum</span>
<span class="font-bold text-base-content"
>{moment(aufnahme.erstellungsdatum).format(
"DD.MM.YYYY"
)}</span
>
</div>
<div class="flex flex-row justify-between">
<span>Baujahr</span>
<span
@@ -398,91 +344,16 @@
: "N/A"}</span
>
</div>
<div class="flex flex-row justify-between">
<span>ID</span>
<span class="font-bold text-base-content"
>{id}</span
>
</div>
</div>
{/await}
{#if benutzer.rolle === Enums.BenutzerRolle.ADMIN && ausweisart === Enums.Ausweisart.BedarfsausweisWohnen}
<span>Laden sie hier den Ausweis hoch</span>
<input type="file" bind:this={bedarfsausweisFileInput}>
<span>Laden sie hier zusätzliche Dokumente hoch</span>
<input type="file" bind:this={bedarfsausweisAdditionalInput} multiple>
{/if}
<div class="flex flex-row justify-start items-center mb-4">
<a
class="p-1 rounded-lg hover:bg-gray-200 mr-2 border-2 border-gray-300"
title="PDF Herunterladen"
target="_blank"
href="/pdf/ansichtsausweis?id={ausweis.id}"
>
{#if ausweis.ausgestellt}
<img src="../../images/dashboard/AusweisHaken.svg" width="65" alt="Energieausweis">
{:else}
<img src="../../images/dashboard/AusweisKreuz.svg" width="65" alt="Energieausweis">
{/if}
</a>
<a
class="p-1 rounded-lg hover:bg-gray-200 border-2 border-gray-300"
title="PDF Herunterladen"
target="_blank"
href="/pdf/datenblatt?id={ausweis.id}"
>
{#if ausweis.ausgestellt}
<img src="../../images/dashboard/DatenblattHaken.svg" width="65" alt="Energieausweis">
{:else}
<img src="../../images/dashboard/DatenblattKreuz.svg" width="65" alt="Energieausweis">
{/if}
</a>
<div class="w-1/2 ml-4 text-sm">
{#if ausweis.bestellt}
{#if ausweis.ausweistyp === Enums.AusweisTyp.Beratung || ausweis.ausweistyp === Enums.AusweisTyp.BeratungXL}
Sie haben Hilfe zu diesem Ausweis angefordert. Sie werden <span class="font-bold">innerhalb der nächsten 48 Stunden</span> über die hinterlegte Telefonnummer vom IB Cornelsen kontaktiert.
{:else if ausweis.ausweistyp === Enums.AusweisTyp.Offline || ausweis.ausweistyp === Enums.AusweisTyp.OfflineXL}
Sie haben die offline Variant zu diesem Ausweis angefordert. Bitte <span class="font-bold">übermitteln Sie uns die letzten drei Jahre der Energieabrechnungen</span> Ihres Energieversorgers.
{:else if !ausweis.ausgestellt}
Der Ausweis wurde von Ihnen freigegeben und befindet sich <span class="font-bold">in Prüfung durch IB Cornelsen</span>
{/if}
{:else if ausweis.ausgestellt}
Vorgang erledigt. Ausweis ist <span class="font-bold">geprüft und ausgestellt.</span>
{:else}
Der Ausweis wurde von Ihnen gespeichert <span class="font-bold">und muss noch bestellt werden.</span>
{/if}
</div>
</div>
<div class="text-sm mb-2">
<span class="font-bold">Rechnungsadresse</span><br>
{#if ausweisart == Enums.Ausweisart.GEGNachweisWohnen || ausweisart == Enums.Ausweisart.GEGNachweisGewerbe || ausweisart == Enums.Ausweisart.BedarfsausweisGewerbe}
{einpreisung?.empfaenger},
{#if einpreisung?.zusatzzeile !== null}
{einpreisung?.zusatzzeile},
{/if}
{einpreisung?.strasse}, {einpreisung?.plz} {einpreisung?.ort}
{:else}
{rechnung?.empfaenger},
{#if rechnung?.zusatzzeile !== null}
{rechnung?.zusatzzeile},
{/if}
{rechnung?.strasse}, {rechnung?.plz} {rechnung?.ort}
{/if}
</div>
<div class="text-sm mb-2">
<span class="font-bold">Versandadresse</span><br>
{#if ausweisart == Enums.Ausweisart.GEGNachweisWohnen || ausweisart == Enums.Ausweisart.GEGNachweisGewerbe || ausweisart == Enums.Ausweisart.BedarfsausweisGewerbe}
{einpreisung?.versand_empfaenger},
{#if einpreisung?.versand_zusatzzeile !== null}
{einpreisung?.versand_zusatzzeile},
{/if}
{einpreisung?.versand_strasse}, {einpreisung?.versand_plz} {einpreisung?.versand_ort}
{:else}
{rechnung?.versand_empfaenger},
{#if rechnung?.versand_zusatzzeile !== null}
{rechnung?.versand_zusatzzeile},
{/if}
{rechnung?.versand_strasse}, {rechnung?.versand_plz} {rechnung?.versand_ort}
{/if}
</div>
<div class="flex flex-row gap-2 justify-end items-center mt-4">
<div class="flex flex-row justify-end items-center gap-4 mt-4">
{#if !ausweis.storniert && !ausweis.ausgestellt}
<!--
<a
@@ -501,294 +372,193 @@
{#if ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen}
<a
class="button text-sm"
href="/energieausweis-erstellen/verbrauchsausweis-wohngebaeude?ausweis_id={ausweis.id}&typ={AusstellungsTyp.Speichern}"
href="/energieausweis-erstellen/verbrauchsausweis-wohngebaeude?id={ausweis.id}"
>Bearbeiten</a>
{:else if ausweisart === Enums.Ausweisart.VerbrauchsausweisGewerbe}
<a
class="button text-sm"
href="/energieausweis-erstellen/verbrauchsausweis-gewerbe?ausweis_id={ausweis.id}&typ={AusstellungsTyp.Speichern}"
href="/energieausweis-erstellen/verbrauchsausweis-gewerbe?id={ausweis.id}"
>Bearbeiten</a>
{:else if ausweisart === Enums.Ausweisart.BedarfsausweisWohnen}
<a
class="button text-sm"
href="/energieausweis-erstellen/bedarfsausweis-wohngebaeude?ausweis_id={ausweis.id}&typ={AusstellungsTyp.Speichern}"
href="/energieausweis-erstellen/bedarfsausweis-wohngebaeude?id={ausweis.id}"
>Bearbeiten</a>
{:else if ausweisart === Enums.Ausweisart.GEGNachweisWohnen}
<a
class="button text-sm"
href="/angebot-anfragen/geg-nachweis-wohnen-anfragen?ausweis_id={ausweis.id}&typ={AusstellungsTyp.Speichern}"
href="/angebot-anfragen/geg-nachweis-wohnen-anfragen?id={ausweis.id}"
>Bearbeiten</a>
{:else if ausweisart === Enums.Ausweisart.GEGNachweisGewerbe}
<a
class="button text-sm"
href="/angebot-anfragen/geg-nachweis-gewerbe-anfragen?ausweis_id={ausweis.id}&typ={AusstellungsTyp.Speichern}"
href="/angebot-anfragen/geg-nachweis-gewerbe-anfragen?id={ausweis.id}"
>Bearbeiten</a>
{:else if ausweisart === Enums.Ausweisart.BedarfsausweisGewerbe}
<a
class="button text-sm"
href="/angebot-anfragen/bedarfsausweis-gewerbe-anfragen?ausweis_id={ausweis.id}&typ={AusstellungsTyp.Speichern}"
href="/angebot-anfragen/bedarfsausweis-gewerbe-anfragen?id={ausweis.id}"
>Bearbeiten</a>
{/if}
{#if ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen}
<a
class="button text-sm"
href="/energieausweis-erstellen/verbrauchsausweis-wohngebaeude?id={ausweis.id}"
>Bearbeiten</a>
{:else if ausweisart === Enums.Ausweisart.VerbrauchsausweisGewerbe}
<a
class="button text-sm"
href="/energieausweis-erstellen/verbrauchsausweis-gewerbe?id={ausweis.id}"
>Bearbeiten</a>
{:else if ausweisart === Enums.Ausweisart.BedarfsausweisWohnen}
<a
class="button text-sm"
href="/energieausweis-erstellen/bedarfsausweis-wohngebaeude?id={ausweis.id}"
>Bearbeiten</a>
{:else if ausweisart === Enums.Ausweisart.GEGNachweisWohnen}
<a
class="button text-sm"
href="/angebot-anfragen/geg-nachweis-wohnen-anfragen?id={ausweis.id}"
>Bearbeiten</a>
{:else if ausweisart === Enums.Ausweisart.GEGNachweisGewerbe}
<a
class="button text-sm"
href="/angebot-anfragen/geg-nachweis-gewerbe-anfragen?id={ausweis.id}"
>Bearbeiten</a>
{:else if ausweisart === Enums.Ausweisart.BedarfsausweisGewerbe}
<a
class="button text-sm"
href="/angebot-anfragen/bedarfsausweis-gewerbe-anfragen?id={ausweis.id}"
>Bearbeiten</a>
{/if}
{/if}
{#if benutzer.rolle === Enums.BenutzerRolle.ADMIN}
<!-- TODO -->
{#if ausweisart === Enums.Ausweisart.VerbrauchsausweisWohnen}
<a
class="button text-sm"
href="/energieausweis-erstellen/verbrauchsausweis-wohngebaeude?ausweis_id={ausweis.id}&typ={AusstellungsTyp.Speichern}"
href="/energieausweis-erstellen/verbrauchsausweis-wohngebaeude?id={ausweis.id}"
>Formular</a>
{:else if ausweisart === Enums.Ausweisart.VerbrauchsausweisGewerbe}
<a
class="button text-sm"
href="/energieausweis-erstellen/verbrauchsausweis-gewerbe?ausweis_id={ausweis.id}&typ={AusstellungsTyp.Speichern}"
>Formular</a>
{:else if ausweisart === Enums.Ausweisart.BedarfsausweisWohnen}
<a
class="button text-sm"
href="/energieausweis-erstellen/bedarfsausweis-wohngebaeude?ausweis_id={ausweis.id}&typ={AusstellungsTyp.Speichern}"
href="/energieausweis-erstellen/verbrauchsausweis-gewerbe?id={ausweis.id}"
>Formular</a>
{/if}
{/if}
{#if benutzer.rolle === Enums.BenutzerRolle.ADMIN}
<button class="button text-sm" title="Ausstellen" on:click={() => ausstellen(false)}>A</button>
<button class="button text-sm" title="Ausstellen mit Postversand" on:click={() => ausstellen(true)}>P</button>
<button class="button text-sm" title="Stornieren" on:click={stornieren}>S</button>
<button class="button text-sm" title="Registriernummer anfordern" on:click={registriernummer}>R</button>
{/if}
</div>
</div>
</div>
<div class="relative bg-base-200 border border-base-300 rounded-lg p-4 mx-2">
<div class="card-body">
<div class="flex flex-row flex-wrap items-center gap-2">
<div class="text-lg font-semibold">{aufnahme.gebaeudetyp}
{#if (aufnahme.einheiten > 0 && aufnahme.einheiten !== null)}
mit {aufnahme.einheiten} Wohneinheiten
{/if}
</div>
<div class="text-sm">
<span class="font-bold">Gebäude (Bj {aufnahme.baujahr_gebaeude})</span> mit
{#if aufnahme.flaeche > 0 && aufnahme.flaeche !== null}
{aufnahme.flaeche} m² Wohnfläche
{/if}
{#if aufnahme.nutzflaeche === 0}
. Die energetische Nutzfläche wurde nach §82 GEG aus der Wohnfläche ermittelt.
{:else}
sowie {aufnahme.nutzflaeche} m² energetische Nutzfläche.
{/if}
Als Ausstellgrund wurde {ausweis.ausstellgrund} angegeben.
{aufnahme.gebaeudeteil === "Wohnen"
? "Die eingegebenen Daten beziehen sich auf den Wohnteil eines gemischt genutzten Gebäudes."
: "Die eingegebenen Daten beziehen sich auf das gesamte Gebäude."}
{aufnahme.saniert ? "Das Gebäude ist in saniertem Zustand." : "Das Gebäude ist in unsaniertem Zustand."}
</div>
{#if ausweisart === Enums.Ausweisart.VerbrauchsausweisGewerbe}
<div class="text-sm">
<span class="font-bold">Gebäudestrom</span> der Jahre vom
{moment(ausweis.startdatum).format("MM.YYYY")} bis {moment(ausweis.startdatum).add("3", "years").format("MM.YYYY")} beträgt
{ausweis.strom_1} kWh, {ausweis.strom_2} kWh und {ausweis.strom_3} kWh.
Im Stromverbrauch enthalten sind
{ausweis.stromverbrauch_enthealt_heizung ? "Heizung, " : ""}
{ausweis.stromverbrauch_enthaelt_warmwasser ? "Warmwasser, " : ""}
{ausweis.stromverbrauch_enthaelt_lueftung ? "Lüftung, " : ""}
{ausweis.stromverbrauch_enthaelt_beleuchtung ? "Beleuchtung, " : ""}
{ausweis.stromverbrauch_enthaelt_kuehlung ? "Kühlung, " : ""}
{#if ausweis.stromverbrauch_sonstig !== null}
sowie {ausweis.stromverbrauch_enthaelt_sonstige}.
{/if}
</div>
{/if}
<div class="text-sm">
<span class="font-bold">Heizung (Bj {aufnahme.baujahr_heizung})</span> wird mit
{ausweis.brennstoff_1} betrieben. Die Verbräuche vom
{moment(ausweis.startdatum).format("MM.YYYY")} bis {moment(ausweis.startdatum).add("3", "years").format("MM.YYYY")} betragen
{ausweis.verbrauch_1} {ausweis.einheit_1}, {ausweis.verbrauch_2} {ausweis.einheit_1} und {ausweis.verbrauch_3} {ausweis.einheit_1}.
{#if ausweis.zusaetzliche_heizquelle} -
Eine weitere Heizung wird mit {ausweis.brennstoff_2} betrieben mit den Verbräuchen {ausweis.verbrauch_4} {ausweis.einheit_2}, {ausweis.verbrauch_5}
{ausweis.einheit_2} und {ausweis.verbrauch_6} {ausweis.einheit_2}.
{/if}
</div>
<div class="text-sm">
{#if ausweis.anteil_warmwasser_1 !== null && ausweis.anteil_warmwasser_1 > 0}
{#if aufnahme.solarsystem_warmwasser}
Da ein Solarsystem für Warmwasser vorhanden ist,
wurde ein Warmwasseranteil von {ausweis.anteil_warmwasser_1 * 0.6}% berücksichtigt.
{:else}
Es wurde ein Warmwasseranteil von {ausweis.anteil_warmwasser_1}% berücksichtigt.
{/if}
{:else}
{#if aufnahme.solarsystem_warmwasser}
Da ein Solarsystem für Warmwasser vorhanden ist, wurde ein reduzierter Warmwasserzuschlag von 12 kWh/m²a angesetzt.
{:else}
Es wurde ein Warmwasserzuschlag von 20 kWh/m²a angesetzt.
{/if}
<button class="button text-sm" on:click={ausweisAusstellen}>A</button>
<button class="button text-sm" on:click={stornieren}>S</button>
<button class="button text-sm" on:click={registriernummerAnfordern}>R</button>
{/if}
{#if ausweis.warmwasser_enthalten}
Der Anteil wird vom Gesamtverbrauch abgezogen, um den Heizwärmebedarf zu ermitteln und diesen mit dem
über drei Jahre gemittelten Klimafaktor zu multiplizieren.
{:else}
Der Anteil wird als Zuschlag zum Gesamtverbrauch addiert, und im Ausweis in einer separaten Zeile ausgewiesen.
{/if}
{#if !ausweis.alternative_heizung && !ausweis.alternative_warmwasser && !ausweis.alternative_lueftung && !ausweis.alternative_kuehlung}
Alternative Energieversorgung wird nicht verwendet
{:else}
Alternative Energieversorgung wird verwendet für {ausweis.alternative_heizung ? "Heizung, " : ""}{ausweis.alternative_warmwasser ? "Warmwasser, " : ""}{ausweis.alternative_lueftung ? "Lüftung, " : ""}{ausweis.alternative_kuehlung ? "Kühlung, " : ""}
{/if}.
Der Leerstand beträgt {aufnahme.leerstand}%. Das Gebäude verfügt über eine
{#if aufnahme.lueftung === Enums.Lueftungskonzept.Fensterlueftung}
Fensterlüftung
{:else if aufnahme.lueftung === Enums.Lueftungskonzept.Schachtlueftung}
Schachtlüftung
{:else if aufnahme.lueftung === Enums.Lueftungskonzept.LueftungsanlageMitWaermerueckgewinnung}
Lüftungsanlage mit Wärmerückgewinnung
{:else if aufnahme.lueftung === Enums.Lueftungskonzept.LueftungsanlageOhneWaermerueckgewinnung}
Lüftungsanlage ohne Wärmerückgewinnung
{/if}
{#if ausweis.kuehlung_enthalten && ausweis.kuehlung_entahlten !== null}
und wird thermisch gekühlt.
{:else if aufnahme.kuehlung === "1" && aufnahme.kuhlung !== null}
und wird gekühlt.
{:else}
und wird nicht gekühlt.
{/if}
</div>
<div class="text-sm">
<span class="font-bold">Heizung: </span>
{aufnahme.zentralheizung ? "Zentral/Etagenheizung, " : ""}
{aufnahme.einzelofen ? "Einzelofen, " : ""}
{aufnahme.waermepumpe ? "Wärmepumpe, " : ""}
{aufnahme.niedertemperatur_kessel ? "Niedertemperaturkessel, " : ""}
{aufnahme.standard_kessel ? "Standardkessel, " : ""}
{aufnahme.durchlauf_erhitzer ? "Durchlauferhitzer, " : ""}
{aufnahme.solarsystem_warmwasser ? "Solarsystem für Warmwasser, " : ""}
{aufnahme.brennwert_kessel ? "Brennwertkessel, " : ""}
{aufnahme.standard_kessel ? "Standardkessel, " : ""}
{aufnahme.warmwasser_rohre_gedaemmt ? "Warmwasserrohre gedämmt, " : ""}
{aufnahme.heizungsrohre_gedaemmt ? "Heizungsrohre gedämmt, " : ""}
{aufnahme.photovoltaik ? "Photovoltaik, " : ""}
{aufnahme.raum_temperatur_regler ? "Raumtemperaturregler, " : ""}
{aufnahme.zirkulation ? "Zirkulation, " : ""}
</div>
<div class="text-sm">
<span class="font-bold">Fenster: </span>
{aufnahme.isolier_verglasung ? "Fenster Isolierglas, " : ""}
{aufnahme.dreifach_verglasung ? "Dreifachverglasung, " : ""}
{aufnahme.doppel_verglasung ? "Doppelverglasung, " : ""}
{aufnahme.einfach_verglasung ? "Einfachverglasung, " : ""}
{aufnahme.fenster_dicht ? "Fenster dicht, " : ""}
{aufnahme.fenster_teilweise_undicht ? "Fenster teilweise undicht, " : ""}
{aufnahme.tueren_undicht ? "Türen undicht, " : ""}
{aufnahme.tueren_dicht ? "Türen dicht, " : ""}
{aufnahme.rolllaeden_kaesten_gedaemmt ? "Rollladenkästen gedämmt" : ""}
</div>
<div class="text-sm">
<span class="font-bold">Dämmung: </span>
{aufnahme.dachgeschoss_gedaemmt ? "Dachgeschoss gedämmt, " : ""}
{aufnahme.aussenwand_gedaemmt ? "Außenwand gedämmt, " : ""}
{aufnahme.keller_decke_gedaemmt ? "Kellerdecke gedämmt, " : ""}
{aufnahme.keller_wand_gedaemmt ? "Kellerwand gedämmt, " : ""}
{aufnahme.oberste_geschossdecke_gedaemmt ? "oberste Geschossdecke gedämmt, " : ""}
{aufnahme.oberste_geschossdecke_min_12cm_gedaemmt ? "oberste Geschossdecke min. 12cm gedämmt, " : ""}
{aufnahme.dachgeschoss_min_12cm_gedaemmt ? "Dachgeschoss min. 12cm gedämmt, " : ""}
{aufnahme.aussenwand_min_12cm_gedaemmt ? "Außenwand min. 12cm gedämmt" : ""}
</div>
<div class="text-xs space-y-1 p-2">
<span class="font-semibold">Hiermit bestätige ich {benutzer.vorname} {benutzer.name} als Besteller:</span><br>
{#if ausweis.pruefpunkt_heizungsalter}
<div>Das Heizungsalter ist jünger als 3 Jahre. Es betrifft einen Heizungstausch ohne energetische Verbesserung.</div>
{/if}
{#if ausweis.pruefpunkt_verbrauch_niedrig}
<div>Ich habe die Verbrauchsangaben kontrolliert. Der niedrige Energiekennwert ist korrekt.</div>
{/if}
{#if ausweis.pruefpunkt_verbrauch_hoch}
<div>Ich habe die Verbrauchsangaben kontrolliert. Der hohe Energiekennwert ist korrekt.</div>
{/if}
{#if ausweis.pruefpunkt_verbrauch_null}
<div>Die eingegebenen Heizverbräuche sind korrekt und alle 3 Felder wurden vollständig eingegeben.</div>
{/if}
{#if ausweis.pruefpunkt_verbrauch_abweichung}
<div>Die eingegebenen Heizverbräuche sind korrekt und die Abweichung lässt sich begründen.</div>
{/if}
{#if ausweis.pruefpunkt_wohnflaeche_einheiten}
<div>Die Angabe der Wohnfläche ist korrekt und bezieht sich auf das gesamte Gebäude.</div>
{/if}
{#if ausweis.pruefpunkt_strom_null}
<div>Die eingegebenen Stromverbräuche sind korrekt. Alle 3 Felder wurden vollständig eingegeben.</div>
{/if}
{#if ausweis.pruefpunkt_strom_abweichung}
<div>Die eingegebenen Stromverbräuche sind korrekt und die Abweichung lässt sich begründen.</div>
{/if}
{#if ausweis.pruefpunkt_heizungsanlage}
<div>Das Baujahr der Heizungsanlage ist kleiner als das Baujahr des Gebäudes und begründet.</div>
{/if}
{#if ausweis.pruefpunkt_anteil_warmwasser}
<div>Ich habe den Warmwasseranteil nochmal überprüft. Dieser ist korrekt und begründet.</div>
{/if}
{#if ausweis.pruefpunkt_wohnflaeche}
<div>Ich habe die Wohnfläche nochmal überprüft und bestätige die Richtigkeit. Es handelt sich lediglich um die Wohnfläche innerhalb des Gebäudes.</div>
{/if}
<div>Ich habe die AGB und DSGVO im <a href="/impressum#agb" target="_blank" rel="noopener noreferrer">Impressum</a> gelesen und akzeptiert. Ich bestätige die Richtigkeit der Eingabe.</div>
</div>
</div>
</div>
</div>
<div class="relative bg-base-200 border border-base-300 rounded-lg p-4 mx-2">
<div class="card-body">
<div class="flex flex-col flex-wrap items-left gap-2">
{#if aufnahme.bilder.length > 0}
<h3 class="font-semibold text-lg">Bilder</h3>
<div class="grid grid-cols-[1fr] md:grid-cols-[1fr,1fr,1fr] lg:grid-cols-[1fr,1fr,1fr] justify-start items-center gap-2">
{#each aufnahme.bilder as bild, i (i)}
<img src="/bilder/{bild.id}.jpg" alt={bild.kategorie} loading="lazy" class="max-h-[10vh] h-full w-full object-contain">
{/each}
</div>
<hr>
{/if}
{#if aufnahme.unterlagen.length > 0}
<h3 class="font-semibold text-lg">Unterlagen</h3>
<div class="text-sm">
{#if aufnahme.unterlagen.length > 0}
{#each aufnahme.unterlagen as unterlage}
<a href="/unterlagen/{unterlage.id}.{mime.getExtension(unterlage.mime)}" target="_blank" class="text-black flex flex-row items-center gap-2 bg-base-200 p-2 rounded-lg"><FileText size={32}></FileText> {unterlage.name}</a>
{/each}
{/if}
</div>
{/if}
</div>
<!-- Benachrichtigungen -->
<!-- <div class="dropdown dropdown-top items-end absolute bottom-4 right-4 z-50">
<div class="indicator">
{#if Object.keys($notifications).length > 0}
<span class="indicator-item badge badge-accent text-xs"
>{Object.keys($notifications).length}</span
<a
class="p-2 rounded-lg hover:bg-gray-200"
title="PDF Herunterladen"
target="_blank"
href="/pdf/ansichtsausweis?id={ausweis.id}"
>
{/if}
<button
tabindex="0"
class="hover:bg-gray-200 p-3 rounded-lg"
<img src="/images/ausweis.webp" width="32" alt="Energieausweis">
</a>
<a
class="p-2 rounded-lg hover:bg-gray-200"
title="PDF Herunterladen"
target="_blank"
href="/pdf/datenblatt?id={ausweis.id}"
>
<Bell size={24} />
<img src="/images/datenblatt.webp" width="32" alt="Datenblatt">
</a>
</div>
</div>
</div>
<div class="flex-shrink-0 bg-gray-100 flex flex-col border text-xl rounded-lg p-4">
<h3 class="font-bold">Ausweisdaten</h3>
<table>
<tr>
<td>Anlass</td>
<td>{ausweis.ausstellgrund}</td>
</tr>
<tr>
<td>Gebäudetyp</td>
<td>{aufnahme.gebaeudetyp}</td>
</tr>
<tr>
<td>Anzahl Wohneinheiten</td>
<td>{aufnahme.einheiten}</td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td>Gebäudeteil</td>
<td>{aufnahme.gebaeudeteil}</td>
</tr>
</table>
<h3 class="font-bold">Heizverbräuche ({ausweis.einheit_1}, {ausweis.einheit_2})</h3>
<table>
<tr>
<td>{ausweis.brennstoff_1}<br>{ausweis.brennstoff_2}</td>
<td>{ausweis.verbrauch_1}, {ausweis.verbrauch_2}, {ausweis.verbrauch_3}<br>{ausweis.verbrauch_4}, {ausweis.verbrauch_5}, {ausweis.verbrauch_6}</td>
</tr>
<tr>
<td>{ausweis.warmwasser_enthalten ? "Warmwasser enthalten" : "Warmwasser nicht enthalten"}</td>
<td>{ausweis.anteil_warmwasser}</td>
</tr>
<tr>
<td>Alternative Energieversorgung</td>
<td>{aufnahme.alternative_heizung ? "Heizung" : ""}, {aufnahme.alternative_warmwasser ? "Warmwasser" : ""} {aufnahme.alternative_lueftung ? "Lüftung" : ""} {aufnahme.alternative_kuehlung ? "Kühlung" : ""}</td>
</tr>
<tr>
<td>Leerstand</td>
<td>{aufnahme.leerstand}</td>
</tr>
<!-- <tr>
<td>{aufnahme.lueftung}</td>
<td>{aufnahme.kuehlung}</td>
</tr> -->
<!-- <tr>
<td>Sanierungszustand: Zentralheizung</td>
</tr> -->
</table>
</div>
</div>
<!-- Zweiter Block: Ansprechpartner und Ausweisdaten in zwei Spalten -->
<div class="flex flex-row md:flex-row gap-4 mb-4">
<p class="text-lg text-gray-700 mb-1">
<strong>Besteller:</strong> {benutzer.vorname} {benutzer.name}
</p>
<p class="text-lg text-gray-700">
<strong>Telefon:</strong> {benutzer.telefon}
</p>
<p class="text-lg text-gray-700">
<strong>E-Mail:</strong> {benutzer.email}
</p>
<p class="text-lg text-gray-700">
<strong>Erstelldatum:</strong> {moment(ausweis.created_at).format("DD.MM.YYYY")}
</p>
</div>
<!-- Fußzeile: Navigation (1/3) -->
<div class="border-t pt-4 flex justify-between items-center">
<button class="bg-gray-300 text-gray-700 px-2 py-1 rounded hover:bg-gray-400">
&laquo;
</button>
<p class="text-gray-700 font-medium">
Ausweis 1/3
</p>
<button class="bg-gray-300 text-gray-700 px-2 py-1 rounded hover:bg-gray-400">
&raquo;
</button>
</div>
<ul
class="dropdown-content mb-2 border border-base-300 z-10 menu py-4 px-0 bg-base-200 rounded-box w-80"
>
<NotificationProvider component={DashboardNotification} />
</ul>
</div> -->
</div>
</div>
@@ -829,10 +599,3 @@
</div>
</div>
</dialog>
<style lang="postcss">
*{@apply font-sans
}
</style>

View File

@@ -47,6 +47,19 @@
<div class="text-sm text-center">Energieausweis</div>
</a>
{/if}
{#if objekt.aufnahmen.at(-1)?.bedarfsausweise_wohnen.length}
{@const ausweis = objekt.aufnahmen.at(-1)?.bedarfsausweise_wohnen.at(-1)}
<a href="/pdf/ansichtsausweis?id={ausweis.id}" target="_blank">
<div class="inline-block border rounded-lg bg-white">
{#if ausweis?.ausgestellt}
<img src="/images/dashboard/AusweisHaken.svg" class="h-auto w-auto max-h-[150px] max-w-full object-contain p-1" alt="Energieausweis ausgestellt">
{:else}
<img src="/images/dashboard/AusweisKreuz.svg" class="h-auto w-auto max-h-[150px] max-w-full object-contain p-1" alt="Energieausweis ausgestellt">
{/if}
</div>
<div class="text-sm text-center">Energieausweis</div>
</a>
{/if}
</div>
<div class="flex flex-col gap-4">
{#each objekt.aufnahmen as aufnahme}

View File

@@ -1,235 +1,147 @@
<script lang="ts">
import {
Gear,
LockClosed,
CaretDown,
MagnifyingGlass,
} from "radix-svelte-icons";
import { Benutzer, Enums } from "#lib/client/prisma.js";
import { ripple } from "svelte-ripple-action";
import type { RippleOptions } from "svelte-ripple-action/dist/constants.js";
import { Reader, Bell, Gear, LockClosed, CaretDown } from "radix-svelte-icons"
import NotificationProvider from "#components/NotificationProvider/NotificationProvider.svelte";
import DashboardNotification from "./DashboardNotification.svelte";
import { notifications } from "#components/NotificationProvider/shared.js";
import ThemeController from "#components/ThemeController.svelte";
import { BenutzerClient, ObjektKomplettClient } from "#components/Ausweis/types.js";
export let lightTheme: boolean;
export let benutzer: Benutzer;
export let besteller: Benutzer | null;
export let benutzer: BenutzerClient;
let id: string;
const rippleOptions: RippleOptions = {
center: false,
color: lightTheme ? "rgba(233,233,233,0.1)" : "rgba(113, 128, 150, 0.1)",
};
let dropdownOpen = false;
function toggleDropdown() {
dropdownOpen = !dropdownOpen;
}
let headerOpen = false;
</script>
<aside class="rounded-lg bg-white box px-6 py-5">
<div class="flex flex-row items-center">
<aside class:hidden={!headerOpen} class="fixed left-0 top-16 w-full h-[calc(100%-4rem)] flex md:relative md:h-auto md:w-auto md:top-0 md:flex bg-base-200 border-r border-r-base-300 flex-col py-4">
<div class="flex flex-row items-center px-4">
<div class="flex flex-row mr-6">
<a href="/"
><img
src="/images/header/logo-IBC-big.svg"
class="h-16"
alt="IBCornelsen - Logo"
/></a
>
<a href="/"><img src="/images/header/logo-IBC-big.svg" class="h-16" alt="IBCornelsen - Logo"/></a>
</div>
<div class="flex-col items-end">
<div class="text-base-content font-semibold text-left flex">
{benutzer.vorname}
{benutzer.name}
</div>
<div class="text-base-content font-semibold text-left flex"
>{benutzer.vorname} {benutzer.name}</div>
<div class="text-base-content text-sm flex">{benutzer.email}</div>
{#if benutzer.rolle === Enums.BenutzerRolle.RESELLER}
<div class="text-xs text-gray-500 flex">Reseller</div>
{/if}
{#if benutzer.rolle === Enums.BenutzerRolle.ADMIN}
<div class="text-xs text-gray-500 flex">Admin</div>
{/if}
<a href="/auth/logout" class="text-xs">Logout</a>
</div>
</div>
<div class="flex flex-col gap-2 mt-0 md:mt-8 px-0">
<!-- <a class="button-tab" href="/dashboard">
<a use:ripple={rippleOptions} class="button-tab" href="/dashboard">
<Reader width={22} height={22} />
Ausweise
</a> -->
<div class="flex flex-row gap-2 mb-2">
<input type="text" bind:value={id} placeholder="ID">
<button class="button" on:click={() => {
window.location.href = `/dashboard/objekte/${id}`
}}><MagnifyingGlass size={24}></MagnifyingGlass></button>
</div>
<div class="relative mb-4">
<button class="button flex flex-row rounded-lg gap-2 bg-secondary text-white text-center" on:click={toggleDropdown}>
Energieausweis erstellen +
</button>
{#if dropdownOpen}
<div class="absolute top-15 left-0 mt-2 w-50 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 z-[9999]" on:click|stopPropagation on:keydown|stopPropagation on:keyup|stopPropagation>
<div class="py-1 w-full" role="menu" aria-orientation="vertical" aria-labelledby="options-menu">
<a href="/energieausweis-erstellen/verbrauchsausweis-wohngebaeude" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 w-full text-left" role="menuitem">Verbrauchsausweis<br>Wohnen Erstellen</a>
<a href="/energieausweis-erstellen/verbrauchsausweis-gewerbe" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 w-full text-left" role="menuitem">Verbrauchsausweis<br>Gewerbe Erstellen</a>
<a href="/energieausweis-erstellen/bedarfsausweis-wohngebaeude" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 w-full text-left" role="menuitem">Bedarfsausweis<br>Wohnen Erstellen</a>
</div>
</div>
{/if}
{#if benutzer.rolle === Enums.BenutzerRolle.RESELLER}
<a href="/dashboard/abrechnung" class="button ">Monatliche Abrechnung</a>
{/if}
</div>
<hr class="border-gray-600" />
{#if besteller}
Besteller
<div class="flex flex-row mb-4">
<div class="item-center mr-4">
<img src="../../images/profile-placeholder.svg" alt="profile icon" width="40" height="40" />
</div>
<div>
<div>
{besteller.vorname} {besteller.name}
</div>
<div class="text-xs text-gray-500">
Eigentümer oder im Auftrag
</div>
<div class="text-xs text-gray-500">
<!-- Soll für den Aussteller sichtbar sein -->
Tel. 1: {besteller.telefon}<br>
<!-- Tel. 2: {rechnung.telefon} -->
</div>
</div>
</div>
<hr class="border-gray-600" />
{/if}
Vorgänge
</a>
<a use:ripple={rippleOptions} class="button-tab" href="/dashboard">
<Reader width={22} height={22} />
Inbox
</a>
<hr class="border-gray-600">
<!--
Mitwirkende
<div class="flex flex-row mb-1">
<div class="item-center mr-4">
<img src="../../images/profile-placeholder.svg" alt="profile icon" width="40" height="40" />
<div class="text-base-content text-xl px-4 mt-4">Mitwirkende</div>
<div class="flex flex-col gap-4 px-4">
{#each [
{ name: "Max Mustermann", image: "/images/profile-placeholder.svg", profession: "Architekt" },
{ name: "Erika Musterfrau", image: "/images/profile-placeholder.svg", profession: "Ingenieurin" },
{ name: "Hans Beispiel", image: "/images/profile-placeholder.svg", profession: "Energieberater" },
{ name: "Anna Beispiel", image: "/images/profile-placeholder.svg", profession: "Bauleiterin" }
] as person}
<div class="flex items-center gap-4">
<img src={person.image} alt={person.name} class="w-12 h-12 rounded-full object-cover" />
<div class="flex flex-col">
<span class="text-base-content font-medium">{person.name}</span>
<span class="text-sm text-gray-500">{person.profession}</span>
</div>
<div>
<div>
Ernie Energieberater
<button class="ml-auto btn btn-primary btn-sm">Chat</button>
</div>
<div class="text-xs text-gray-500">
Energieberater
</div>
</div>
</div>
<div class="flex flex-row mb-1">
<div class="item-center mr-4">
<img src="../../images/profile-placeholder.svg" alt="profile icon" width="40" height="40" />
</div>
<div>
<div>
Peter Planer
</div>
<div class="text-xs text-gray-500">
Architekt
</div>
</div>
</div>
<div class="flex flex-row mb-1">
<div class="item-center mr-4">
<img src="../../images/profile-placeholder.svg" alt="profile icon" width="40" height="40" />
</div>
<div>
<div>
Hans Meier
</div>
<div class="text-xs text-gray-500">
Eigentümer
</div>
</div>
</div>
<hr class="border-gray-600" />
Experten in der Nähe
<div class="flex flex-row mb-1">
<div class="item-center mr-4">
<img src="../../images/profile-placeholder.svg" alt="profile icon" width="40" height="40" />
</div>
<div>
<div>
Thorsten Maas
</div>
<div class="text-xs text-gray-500">
Energieberater
</div>
</div>
</div>
<div class="flex flex-row mb-1">
<div class="item-center mr-4">
<img src="../../images/profile-placeholder.svg" alt="profile icon" width="40" height="40" />
</div>
<div>
<div>
Herbert Holm
</div>
<div class="text-xs text-gray-500">
Gutachter
</div>
</div>
</div>
<hr class="border-gray-600" />
<div class="flex justify-end mt-2 mb-2">
<button class="button flex flex-row rounded-lg gap-2 bg-secondary text-white text-center">
Einladen
</button>
{/each}
</div>
-->
{#if benutzer.rolle === "ADMIN"}
<li>
<details class="[&_.caret]:open:rotate-180" open>
<summary
class="button-tab w-full outline-0 hover:outline-0 cursor-pointer"
>
<LockClosed size={22}/>
Admin <CaretDown
size={24}
class="caret ml-auto transition-transform"
></CaretDown></summary
>
<!-- <button use:ripple={rippleOptions} class="button-tab">
<EnvelopeClosed width={22} height={22} />
Kontakt
</button>
<li><details class="[&_.caret]:open:rotate-180">
<summary class="button-tab w-full outline-0 hover:outline-0">
<Cube width={22} height={22} />
Services <CaretDown size={24} class="caret ml-auto transition-transform"></CaretDown></summary>
<ul>
<li>
<a
class="button-tab"
href="/dashboard/admin/impersonate-user"
>
<button use:ripple={rippleOptions} class="button-tab">
Kontakt
</button>
</li>
<li>
<button use:ripple={rippleOptions} class="button-tab">
Kontakt
</button>
</li>
</ul>
</details></li> -->
{#if benutzer.rolle === "ADMIN"}
<li><details class="[&_.caret]:open:rotate-180" open>
<summary class="button-tab w-full outline-0 hover:outline-0 cursor-pointer">
<LockClosed width={22} height={22} />
Admin <CaretDown size={24} class="caret ml-auto transition-transform"></CaretDown></summary>
<ul>
<li>
<a use:ripple={rippleOptions} class="button-tab" href="/dashboard/admin/ausweise-pruefen">
Ausweise Prüfen
</a>
</li>
<li>
<a use:ripple={rippleOptions} class="button-tab" href="/dashboard/admin/impersonate-user">
Impersonate User
</a>
</li>
</ul>
</details>
</li>
</details></li>
{/if}
</div>
<div class="items-end bottom-4 right-4 z-50 mt-4">
<div class="flex flex-row justify-end items-end">
<a
href="/dashboard/einstellungen"
<div class="mt-10 flex flex-col gap-4 px-8">
<div class="flex flex-row justify-between items-center">
<ThemeController bind:lightTheme></ThemeController>
<div class="dropdown dropdown-top">
<div class="indicator">
{#if Object.keys($notifications).length > 0}
<span class="indicator-item badge badge-accent text-xs">{Object.keys($notifications).length}</span>
{/if}
<button tabindex="0" class="hover:bg-gray-200 p-3 rounded-lg">
<Bell size={24} />
</button>
</div>
<ul class="dropdown-content mb-2 border border-base-300 z-10 menu py-4 px-0 bg-base-200 rounded-box w-80">
<NotificationProvider component={DashboardNotification} />
</ul>
</div>
<a href="/dashboard/einstellungen"
class="hover:bg-gray-200 p-3 rounded-lg"
>
<Gear size={24} />
</a>
</div>
</div>
<div class="divider px-8"></div>
<a
href="/dashboard/einstellungen"
use:ripple={rippleOptions}
class="hover:bg-gray-200 no-animation focus:shadow-none justify-start py-4 h-auto px-8 rounded-none w-full flex flex-row gap-4"
>
</a>
</aside>
<style>

View File

@@ -1,10 +1,10 @@
<script lang="ts">
import { BedarfsausweisWohnenClient, ObjektClient, VerbrauchsausweisGewerbeClient, VerbrauchsausweisWohnenClient } from "./Ausweis/types.js";
import { BedarfsausweisWohnenClient, GEGNachweisWohnenClient, ObjektClient, UnterlageClient, VerbrauchsausweisGewerbeClient, VerbrauchsausweisWohnenClient } from "./Ausweis/types.js";
import { Trash, Upload } from "radix-svelte-icons";
import HelpLabel from "#components/labels/HelpLabel.svelte";
export let kategorie: string = "";
export let files: (Unterlage & { preview?: boolean })[] = [];
export let files: Unterlage[] = [];
export let max: number = Infinity;
export let min: number = 1;
export let name: string = "";
@@ -26,8 +26,6 @@
for (let i = 0; i < fileArray.length; i++) {
const file = fileArray[i];
files.push({ preview: true, kategorie, name: file.name, mime: file.type, aufnahme_id: null, id: "" });
files = files;
if (i == max) {
break;
@@ -64,13 +62,7 @@
name: file.name
})
const placeholder = files.find((f) => f.name === fileArray[i].name && f.preview === true && f.kategorie === kategorie);
if (!placeholder) {
return;
}
placeholder!.preview = false;
placeholder!.id = id;
placeholder!.aufnahme_id = ausweis.id;
files.push({ id, kategorie, name: file.name, mime: mimeType, aufnahme_id: null });
files = files;
@@ -118,19 +110,6 @@
<div class="grid grid-cols-2 gap-2">
{#each files as file, i}
{#if file.kategorie == kategorie}
{#if file.preview === true}
<!-- Show loading spinner -->
<div class="relative group">
<div
class="h-full max-h-96 w-full rounded-lg border-2 group-hover:contrast-50 object-cover transition-all text-center items-center justify-center flex p-4 text-opacity-75 text-black"
>
<div class="flex flex-row gap-4">
<span>{file.name}</span>
<span class="loader"></span>
</div>
</div>
</div>
{:else}
<div class="relative group">
<div
class="h-full max-h-96 w-full rounded-lg border-2 group-hover:contrast-50 object-cover transition-all text-center items-center flex p-4 text-opacity-75 text-black"
@@ -149,7 +128,6 @@
</div>
</div>
{/if}
{/if}
{/each}
<!-- Wir zeigen Platzhalter an, damit der Nutzer sieht wie viele Bilder er hochladen soll -->

View File

@@ -7,7 +7,7 @@
import Cookies from "js-cookie";
import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants.js";
export let images: (BildClient & { preview?: boolean })[] = [];
export let images: BildClient[] = [];
export let max: number = Infinity;
export let min: number = 1;
export let name: string = "";
@@ -35,18 +35,6 @@
<div class="grid grid-cols-2 gap-2">
{#each images as image, i}
{#if image.kategorie == kategorie}
{#if image.preview === true}
<!-- Show loading spinner -->
<div class="relative group">
<div
class="h-full max-h-96 w-full rounded-lg border-2 group-hover:contrast-50 object-cover transition-all text-center items-center justify-center flex p-4 text-opacity-75 text-black"
>
<div class="flex flex-row gap-4">
<span class="loader"></span>
</div>
</div>
</div>
{:else}
<div class="relative group">
<img
src="/bilder/{image.id}.jpg"
@@ -63,15 +51,24 @@
>
<Trash size={20} color="#fff"></Trash>
</button>
<!-- <button
type="button"
class="rounded-full w-[30px] h-[30px] flex items-center justify-center p-0 bg-[rgba(0,0,0,0.4)]"
on:click={async () => {
let image = await rotateImage(images[i]);
images[i] = image;
images = images
}}
>
<RotateCounterClockwise size={20} color="#fff"></RotateCounterClockwise>
</button> -->
</div>
</div>
{/if}
{/if}
{/each}
<!-- Wir zeigen Platzhalter an, damit der Nutzer sieht wie viele Bilder er hochladen soll -->
{#each { length: Math.max(0, Math.min(max, 4) - images.filter(image => image.kategorie === kategorie).length) } as _, i}
<div class="relative group">
<img
src="/placeholder.png"

View File

@@ -28,12 +28,6 @@ export function updateNotification(uid: string, updater: Partial<Notification>)
value[uid] = { ...defaults, ...value[uid], ...updater } as Notification;
return value;
})
if (updater.timeout) {
setTimeout(() => {
deleteNotification(uid);
}, updater.timeout);
}
}
export function addNotification(notification: Partial<Notification>): string {

View File

@@ -2,7 +2,6 @@
export let hidden: boolean = true;
export let closeable: boolean = true;
import { disableBodyScroll, enableBodyScroll } from 'body-scroll-lock';
import { Cross1 } from 'radix-svelte-icons';
$: if (globalThis.window) {
if (hidden) {
@@ -13,11 +12,13 @@
}
</script>
<div class="fixed top-0 left-0 w-[100vw] h-[100vh] flex items-center justify-center bg-[rgba(0,0,0,0.8)] z-50" class:hidden={hidden}>
<div class="fixed top-0 left-0 w-[100vw] h-[100vh] flex items-center justify-center bg-[rgba(0,0,0,0.8)] z-50" class:hidden={hidden} on:click|self={() => {
hidden = closeable ? true : hidden;
}}>
{#if closeable}
<button class="absolute top-4 right-4 text-white bg-gray-50 bg-opacity-25 px-4 py-2 rounded-lg" type="button" on:click={() => {
<button class="absolute top-4 left-4 text-white" on:click={() => {
hidden = true;
}}><Cross1 size={20}></Cross1></button>
}}>Schließen</button>
{/if}
<slot></slot>
</div>

View File

@@ -5,7 +5,7 @@
export let readonly: boolean = false;
export let city: string | null | undefined;
export let zip: string | null = "";
export let onchange: (event: Event) => void = () => {};
let hideZipDropdown: boolean = true;
let zipCodes: inferOutput<API["postleitzahlen"]["GET"]> = [];

View File

@@ -19,7 +19,6 @@
export let onFocusIn: () => any = () => {};
export let onFocusOut: () => any = () => {};
export let className: string = "";
export let required: boolean = false;
function addTag(tag: string) {
if ((onlyUnique && tags.indexOf(tag) > -1) || maxTags == tags.length) {
@@ -49,8 +48,6 @@
tag = ""
}
}
$: required = tags.length > 0 ? false : required;
</script>
<div
@@ -86,7 +83,6 @@
class="input input-bordered h-10 px-2 py-1.5 {className}"
{minlength}
{maxlength}
{required}
disabled={disable}
readonly={readonly}
autocomplete="off"

View File

@@ -2,10 +2,9 @@
import { dialogs } from "svelte-dialogs";
import TicketPopup from "./TicketPopup.svelte";
import { addNotification } from "@ibcornelsen/ui";
export let userEmail: string = "";
async function showTicketPopup() {
const success = await dialogs.modal(TicketPopup, { email: userEmail });
const success = await dialogs.modal(TicketPopup);
console.log(success);

View File

@@ -1,7 +1,6 @@
<script lang="ts">
import { api } from "astro-typesafe-api/client";
import { getClose } from "svelte-dialogs";
export let email: string = "";
const close = getClose();
@@ -13,7 +12,7 @@
email: email,
metadata: {
category: category,
telefon: telefon,
phone: phone,
},
titel: title,
})
@@ -28,8 +27,8 @@
let category = "";
let title = "";
let description = "";
//let email = "";
let telefon = "";
let email = "";
let phone = "";
</script>
<form class="max-w-lg" on:submit={createTicket}>
@@ -90,9 +89,9 @@
<input
class="input input-bordered"
type="tel"
placeholder="Ihre Telefonnummer"
name="telefon"
bind:value={telefon}
placeholder="Ihre Telefonnumer"
name="phone"
bind:value={phone}
required
/>
</div>

View File

@@ -1,9 +1,7 @@
<script lang="ts">
import HelpLabel from "#components/labels/HelpLabel.svelte";
import type { Enums } from "#lib/client/prisma.js";
import Cookies from "js-cookie";
import { tryCatch } from "#lib/tryCatch.js";
import heic2any from "heic2any";
export let max: number = 2;
export let min: number = 1;
@@ -19,9 +17,8 @@
} from "./Ausweis/types.js";
import { api } from "astro-typesafe-api/client";
import { addNotification } from "./Notifications/shared.js";
import { API_ACCESS_TOKEN_COOKIE_NAME } from "#lib/constants.js";
export let images: (BildClient & { preview?: boolean })[] = [];
export let images: BildClient[] = [];
export let ausweis:
| VerbrauchsausweisWohnenClient
| VerbrauchsausweisGewerbeClient
@@ -40,7 +37,7 @@
for (let i = 0; i < files.length; i++) {
const file = files[i];
if (file.type !== "image/jpeg" && file.type !== "image/png" && file.type !== "image/webp" && file.type !== "image/heif" && file.type !== "image/heic") {
if (file.type !== "image/jpeg" && file.type !== "image/png") {
continue;
}
@@ -48,12 +45,9 @@
break;
}
images.push({ preview: true, benutzer_id: null, kategorie, created_at: new Date(), updated_at: new Date(), id: "" });
images = images;
const reader = new FileReader();
reader.onload = async () => {
reader.onload = () => {
if (reader.readyState != reader.DONE) {
return;
}
@@ -63,18 +57,6 @@
}
let blob = new Blob([reader.result as ArrayBuffer]);
if (file.type === "image/heif" || file.type === "image/heic") {
// Heic files are not supported by canvas, so we convert them to jpeg first
// using an external library.
// This is a workaround until all browsers support heic natively.
// For more information see: https://caniuse.com/?search=heic
// and https://developer.apple.com/documentation/imageio/reading_heif_and_heic_images_on_ios
// and https://stackoverflow.com/questions/65887402/how-to-convert-heic-to-jpeg-in-javascript
// and https://github.com/mbitsnbites/heic2any
blob = await heic2any({ blob, toType: "image/jpeg", quality: 0.8 });
}
let url = URL.createObjectURL(blob);
let image = new Image();
image.onload = async () => {
@@ -103,12 +85,6 @@
data: dataURL,
kategorie,
name: file.name
}, {
headers: {
"Authorization": `Bearer ${Cookies.get(
API_ACCESS_TOKEN_COOKIE_NAME
)}`
}
}))
if (error) {
@@ -120,19 +96,8 @@
dismissable: true
})
} else {
const index = images.findIndex((img) => img.preview === true);
if (index !== -1) {
delete images[index];
images = images.filter((img) => img);
}
images = [...images, {
benutzer_id: null,
created_at: new Date(),
updated_at: new Date(),
id: result.id,
kategorie
}];
images.push({ id: result.id, kategorie });
images = images;
if (i == Math.min(files.length, max) - 1) {
this.value = "";
@@ -163,7 +128,6 @@
<div class="input-standard">
<input
type="file"
accept="image/*"
class="file-input file-input-ghost h-[38px]"
bind:this={fileUpload}
{name}
@@ -180,7 +144,6 @@
<div class="input-standard">
<input
type="file"
accept="image/*"
class="file-input file-input-ghost h-[38px]"
bind:this={fileUpload}
{name}

View File

@@ -11,7 +11,7 @@ export async function auditEndEnergie(ausweis: VerbrauchsausweisWohnenClient | V
if (aufnahme){
if (aufnahme.flaeche && ausweis.verbrauch_1 && ausweis.verbrauch_2 && ausweis.verbrauch_3) {
try {
const response = await getKlimafaktoren(ausweis.startdatum as Date, objekt.plz as string);
const response = await getKlimafaktoren(ausweis.startdatum, objekt.plz);
// Alle Klimfaktoren konnten abgefragt werden.
const eevva = await endEnergieVerbrauchVerbrauchsausweis_2016(ausweis, aufnahme, objekt);
if (eevva){

View File

@@ -1,170 +1,82 @@
<script>
import { PRICES } from "#lib/constants";
import { Enums } from "#lib/client/prisma";
export let bullets;
export let title;
export let ref = "";
import { Enums } from "#lib/client/prisma";
const bullets = [
[
"Prüfung durch Dipl.&nbsp;Ing.<br>Registrierung beim DiBt<br>rechtssicher nach&nbsp;GEG",
true,
true,
true,
],
[
"Originalausweis als&nbsp;PDF per&nbsp;<span class='text-nowrap'>E-Mail</span><br>Originalausweis per&nbsp;Post (zubuchbar)",
true,
true,
true,
],
[
"Bearbeitung innerhalb 24&nbsp;Stunden<br>Selbsteingabe",
true,
true,
false,
],
bullets = [
["Prüfung durch Dipl.&nbsp;Ing.<br>Registrierung beim DiBt<br>rechtssicher nach&nbsp;GEG",true, true, true],
["Originalausweis als&nbsp;PDF per&nbsp;<span class='text-nowrap'>E-Mail</span><br>Originalausweis per&nbsp;Post (zubuchbar)",true, true, true],
["Bearbeitung innerhalb 24&nbsp;Stunden<br>Selbsteingabe",true, true, false],
["Same&nbsp;day&nbsp;service (zubuchbar)",true, true, false],
["Fotoupload",true, true, true],
[
"automatische Vorprüfung<br>Live&nbsp;Vorschau direkt bei&nbsp;Eingabe<br>Live&nbsp;Vorschauausweis vorab<br>Vorschauausweis per&nbsp;E-Mail<br>dynamische&nbsp;Eingabehilfe",
true,
true,
false,
],
[
"Prüfanmerkungen per&nbsp;<span class='text-nowrap'>E-Mail</span>",
true,
true,
false,
],
["automatische Vorprüfung<br>Live&nbsp;Vorschau direkt bei&nbsp;Eingabe<br>Live&nbsp;Vorschauausweis vorab<br>Vorschauausweis per&nbsp;E-Mail<br>dynamische&nbsp;Eingabehilfe",true, true, false],
["Prüfanmerkungen per&nbsp;<span class='text-nowrap'>E-Mail</span>",true, true, false],
["persönlicher&nbsp;Support",false, true, true],
[
"telefonische&nbsp;Beratung<br>persönlicher&nbsp;Energieberater",
false,
true,
true,
],
["telefonische&nbsp;Beratung<br>persönlicher&nbsp;Energieberater",false, true, true],
["Dokumentenupload (Pläne, Bauunterlagen)",false, false, true],
["Eingabe durch Dipl.&nbsp;Ing.", false, false, true],
];
["Eingabe durch Dipl.&nbsp;Ing.",false, false, true],]
</script>
<h1>
Produktübersicht: <span class="text-secondary"
>Bedarfsausweis Wohngebäude</span
>
</h1>
<h1>Produktübersicht: <span class="text-secondary">Bedarfsausweis Wohngebäude</span></h1>
<h3>Bedarfsausweis Leistungen und Preise in der Übersicht:</h3>
<hr />
<br />
<hr>
<br>
<div id="ProduktUebersichtBedarfssausweisWohnen">
<div
class="w-full sm:w-[90%] sm:mx-auto grid grid-cols-[1fr_max-content_max-content_max-content] sm:grid-cols-[1fr_min-content_min-content_min-content]"
>
<div
class="zeile grid grid-cols-subgrid col-span-4 py-4 border-b-[1px] justify-items-center items-center sm:text-[1.25rem]"
>
<div class="justify-self-start pl-2"><b>Leistung</b></div>
<div><b>online</b></div>
<div><b>premium</b></div>
<div><b>offline</b></div>
<div class="w-full sm:w-[90%] sm:mx-auto grid grid-cols-[1fr_max-content_max-content_max-content] sm:grid-cols-[1fr_min-content_min-content_min-content]">
<div class="zeile grid grid-cols-subgrid col-span-4 py-4 border-b-[1px] justify-items-center items-center sm:text-[1.25rem]">
<div class="justify-self-start pl-2"><b>Leistung</b></div><div><b>online</b></div><div><b>premium</b></div><div><b>offline</b></div>
</div>
{#each bullets as [bullet,online,premium,offline]}
<div
class="bullet grid grid-cols-subgrid col-span-4 py-4 border-b-[1px] justify-items-center items-center"
>
<div class="bullet grid grid-cols-subgrid col-span-4 py-4 border-b-[1px] justify-items-center items-center">
<div class="justify-self-start pl-2">{@html bullet}</div>
<div class:check={online} class:check-no={!online}>
{online ? "✔" : ""}
</div>
<div class:check={premium} class:check-no={!premium}>
{premium ? "✔" : ""}
</div>
<div class:check={offline} class:check-no={!offline}>
{offline ? "✔" : ""}
</div>
<div class:check={online} class:check-no={!online}>{online ? "✔" : ""}</div>
<div class:check={premium} class:check-no={!premium}>{premium ? "✔" : ""}</div>
<div class:check={offline} class:check-no={!offline}>{offline ? "✔" : ""}</div>
</div>
{/each}
<div
class="zeile grid grid-cols-subgrid col-span-4 py-4 border-b-[0px] justify-items-center items-center sm:text-[1.25rem]"
>
<div class="zeile grid grid-cols-subgrid col-span-4 py-4 border-b-[0px] justify-items-center items-center sm:text-[1.25rem]">
<div class="price justify-self-start pl-2">Preis inkl. MwSt.</div>
<div class="price">
<b
>{PRICES.BedarfsausweisWohnen[
Enums.AusweisTyp.Standard
]}&nbsp;</b
>
</div>
<div class="price">
<b
>{PRICES.BedarfsausweisWohnen[
Enums.AusweisTyp.Beratung
]}&nbsp;</b
>
</div>
<div class="price">
<b
>{PRICES.BedarfsausweisWohnen[
Enums.AusweisTyp.Offline
]}&nbsp;</b
>
</div>
<div class="price"><b>{PRICES.BedarfsausweisWohnen[Enums.AusweisTyp.Standard]}&nbsp;</b></div>
<div class="price"><b>{PRICES.BedarfsausweisWohnen[Enums.AusweisTyp.Beratung]}&nbsp;</b></div>
<div class="price"><b>{PRICES.BedarfsausweisWohnen[Enums.AusweisTyp.Offline]}&nbsp;</b></div>
</div>
<div
class="zeile grid grid-cols-subgrid col-span-4 py-4 border-b-[0px] justify-items-center items-center"
>
<div class="zeile grid grid-cols-subgrid col-span-4 py-4 border-b-[0px] justify-items-center items-center">
<div class="justify-self-start pl-2"></div>
<a
href="{ref}/energieausweis-erstellen/bedarfsausweis-wohngebaeude?ausweistyp={Enums
.AusweisTyp.Standard}"
><button class="bestellbutton" type="button"
>sofort<br />bestellen</button
></a
>
<a
href="{ref}/energieausweis-erstellen/bedarfsausweis-wohngebaeude?ausweistyp={Enums
.AusweisTyp.Beratung}"
><button class="bestellbutton" type="button"
>sofort<br />bestellen</button
></a
>
<a
href="{ref}/energieausweis-erstellen/bedarfsausweis-wohngebaeude?ausweistyp={Enums
.AusweisTyp.Offline}"
><button class="bestellbutton" type="button"
>sofort<br />bestellen</button
></a
>
<a href="{ref}/energieausweis-erstellen/bedarfsausweis-wohngebaeude?ausweistyp={Enums.AusweisTyp.Standard}"><button class="bestellbutton" type="button">sofort<br>bestellen</button></a>
<a href="{ref}/energieausweis-erstellen/bedarfsausweis-wohngebaeude?ausweistyp={Enums.AusweisTyp.Beratung}"><button class="bestellbutton" type="button">sofort<br>bestellen</button></a>
<a href="{ref}/energieausweis-erstellen/bedarfsausweis-wohngebaeude?ausweistyp={Enums.AusweisTyp.Offline}"><button class="bestellbutton" type="button">sofort<br>bestellen</button></a>
</div>
</div>
</div>
<style lang="postcss">
.bestellbutton {
@apply px-[2px] sm:px-4 mx-[2px] sm:mx-2 py-2 bg-secondary ring-2 ring-secondary/25 rounded-none xs:rounded-md text-white text-nowrap font-bold
hover:bg-gradient-to-br from-secondary to-secondary-grad hover:shadow-lg transition-all hover:no-underline hover:ring-2 hover:ring-primary;
}
.zeile {
@apply text-[0.6rem] sm:text-[1rem] md:text-[1.5rem];
}
.bullet {
@apply text-[0.75rem] sm:text-[1rem] md:text-[1.25rem];
}
.bullet:nth-child(even) {
@apply bg-blue-100/40;
}
.bullet:nth-child(2) {
@apply !border-t-[6px];
}
.bullet:nth-child(12) {
@apply !border-b-[6px];
}
.bestellbutton{@apply px-[2px] sm:px-4 mx-[2px] sm:mx-2 py-2 bg-secondary ring-2 ring-secondary/25 rounded-none xs:rounded-md text-white text-nowrap font-bold
hover:bg-gradient-to-br from-secondary to-secondary-grad hover:shadow-lg transition-all hover:no-underline hover:ring-2 hover:ring-primary;}
.zeile{@apply text-[0.6rem] sm:text-[1rem] md:text-[1.5rem]}
.bullet{@apply text-[0.75rem] sm:text-[1rem] md:text-[1.25rem]}
.bullet:nth-child(even){@apply bg-blue-100/40}
.bullet:nth-child(2){@apply !border-t-[6px]}
.bullet:nth-child(12){@apply !border-b-[6px]}
.check {
@apply text-[1.25rem] sm:text-[1.5rem] font-bold text-green-700;
@@ -173,7 +85,6 @@
@apply text-[1.25rem] sm:text-[1.5rem] font-bold text-black;
}
.price {
@apply text-[1.25rem] sm:text-[2rem];
}
.price{@apply text-[1.25rem] sm:text-[2rem]}
</style>

View File

@@ -4,167 +4,78 @@
export let ref = "";
const bullets = [
[
"Prüfung durch Dipl.&nbsp;Ing.<br>Registrierung beim DiBt<br>rechtssicher nach&nbsp;GEG",
true,
true,
true,
],
[
"Originalausweis als&nbsp;PDF per&nbsp;<span class='text-nowrap'>E-Mail</span><br>Originalausweis per&nbsp;Post (zubuchbar)",
true,
true,
true,
],
[
"Bearbeitung innerhalb 24&nbsp;Stunden<br>Selbsteingabe",
true,
true,
false,
],
["Prüfung durch Dipl.&nbsp;Ing.<br>Registrierung beim DiBt<br>rechtssicher nach&nbsp;GEG",true, true, true],
["Originalausweis als&nbsp;PDF per&nbsp;<span class='text-nowrap'>E-Mail</span><br>Originalausweis per&nbsp;Post (zubuchbar)",true, true, true],
["Bearbeitung innerhalb 24&nbsp;Stunden<br>Selbsteingabe",true, true, false],
["Same&nbsp;day&nbsp;service (zubuchbar)",true, true, false],
["Fotoupload",true, true, true],
[
"automatische Vorprüfung<br>Live&nbsp;Vorschau direkt bei&nbsp;Eingabe<br>Live&nbsp;Vorschauausweis vorab<br>Vorschauausweis per&nbsp;E-Mail<br>dynamische&nbsp;Eingabehilfe",
true,
true,
false,
],
[
"Prüfanmerkungen per&nbsp;<span class='text-nowrap'>E-Mail</span>",
true,
true,
false,
],
["automatische Vorprüfung<br>Live&nbsp;Vorschau direkt bei&nbsp;Eingabe<br>Live&nbsp;Vorschauausweis vorab<br>Vorschauausweis per&nbsp;E-Mail<br>dynamische&nbsp;Eingabehilfe",true, true, false],
["Prüfanmerkungen per&nbsp;<span class='text-nowrap'>E-Mail</span>",true, true, false],
["persönlicher&nbsp;Support",false, true, true],
[
"telefonische&nbsp;Beratung<br>persönlicher&nbsp;Energieberater",
false,
true,
true,
],
["telefonische&nbsp;Beratung<br>persönlicher&nbsp;Energieberater",false, true, true],
["Dokumentenupload (Verbrauchsabrechnungen)",false, false, true],
["Eingabe durch Dipl.&nbsp;Ing.",false, false, true],
];
]
</script>
<h1>
Produktübersicht: <span class="text-secondary"
>Verbrauchsausweis Gewerbegebäude</span
>
</h1>
<h1>Produktübersicht: <span class="text-secondary">Verbrauchsausweis Gewerbegebäude</span></h1>
<h3>Verbrauchsausweis Leistungen und Preise in der Übersicht:</h3>
<hr />
<br />
<hr>
<br>
<div id="ProduktUebersichtVerbrauchsausweisGewerbe">
<div
class="w-full sm:w-[90%] sm:mx-auto grid grid-cols-[1fr_max-content_max-content_max-content] sm:grid-cols-[1fr_min-content_min-content_min-content]"
>
<div
class="zeile grid grid-cols-subgrid col-span-4 py-4 border-b-[1px] justify-items-center items-center sm:text-[1.25rem]"
>
<div class="justify-self-start pl-2"><b>Leistung</b></div>
<div><b>online</b></div>
<div><b>premium</b></div>
<div><b>offline</b></div>
<div class="w-full sm:w-[90%] sm:mx-auto grid grid-cols-[1fr_max-content_max-content_max-content] sm:grid-cols-[1fr_min-content_min-content_min-content]">
<div class="zeile grid grid-cols-subgrid col-span-4 py-4 border-b-[1px] justify-items-center items-center sm:text-[1.25rem]">
<div class="justify-self-start pl-2"><b>Leistung</b></div><div><b>online</b></div><div><b>premium</b></div><div><b>offline</b></div>
</div>
{#each bullets as [bullet,online,premium,offline]}
<div
class="bullet grid grid-cols-subgrid col-span-4 py-4 border-b-[1px] justify-items-center items-center"
>
<div class="bullet grid grid-cols-subgrid col-span-4 py-4 border-b-[1px] justify-items-center items-center">
<div class="justify-self-start pl-2">{@html bullet}</div>
<div class:check={online} class:check-no={!online}>
{online ? "✔" : ""}
</div>
<div class:check={premium} class:check-no={!premium}>
{premium ? "✔" : ""}
</div>
<div class:check={offline} class:check-no={!offline}>
{offline ? "✔" : ""}
</div>
<div class:check={online} class:check-no={!online}>{online ? "✔" : ""}</div>
<div class:check={premium} class:check-no={!premium}>{premium ? "✔" : ""}</div>
<div class:check={offline} class:check-no={!offline}>{offline ? "✔" : ""}</div>
</div>
{/each}
<div
class="zeile grid grid-cols-subgrid col-span-4 py-4 border-b-[0px] justify-items-center items-center sm:text-[1.25rem]"
>
<div class="zeile grid grid-cols-subgrid col-span-4 py-4 border-b-[0px] justify-items-center items-center sm:text-[1.25rem]">
<div class="price justify-self-start pl-2">Preis inkl. MwSt.</div>
<div class="price">
<b
>{PRICES.VerbrauchsausweisGewerbe[
Enums.AusweisTyp.Standard
]}&nbsp;</b
>
</div>
<div class="price">
<b
>{PRICES.VerbrauchsausweisGewerbe[
Enums.AusweisTyp.Beratung
]}&nbsp;</b
>
</div>
<div class="price">
<b
>{PRICES.VerbrauchsausweisGewerbe[
Enums.AusweisTyp.Offline
]}&nbsp;</b
>
</div>
<div class="price"><b>{PRICES.VerbrauchsausweisGewerbe[Enums.AusweisTyp.Standard]}&nbsp;</b></div>
<div class="price"><b>{PRICES.VerbrauchsausweisGewerbe[Enums.AusweisTyp.Beratung]}&nbsp;</b></div>
<div class="price"><b>{PRICES.VerbrauchsausweisGewerbe[Enums.AusweisTyp.Offline]}&nbsp;</b></div>
</div>
<div
class="zeile grid grid-cols-subgrid col-span-4 py-4 border-b-[0px] justify-items-center items-center"
>
<div class="zeile grid grid-cols-subgrid col-span-4 py-4 border-b-[0px] justify-items-center items-center">
<div class="justify-self-start pl-2"></div>
<a
href="{ref}/energieausweis-erstellen/verbrauchsausweis-gewerbe?ausweistyp={Enums
.AusweisTyp.Standard}"
><button class="bestellbutton" type="button"
>sofort<br />bestellen</button
></a
>
<a
href="{ref}/energieausweis-erstellen/verbrauchsausweis-gewerbe?ausweistyp={Enums
.AusweisTyp.Beratung}"
><button class="bestellbutton" type="button"
>sofort<br />bestellen</button
></a
>
<a
href="{ref}/energieausweis-erstellen/verbrauchsausweis-gewerbe?ausweistyp={Enums
.AusweisTyp.Offline}"
><button class="bestellbutton" type="button"
>sofort<br />bestellen</button
></a
>
<a href="{ref}/energieausweis-erstellen/verbrauchsausweis-gewerbe?ausweistyp={Enums.AusweisTyp.Standard}"><button class="bestellbutton" type="button">sofort<br>bestellen</button></a>
<a href="{ref}/energieausweis-erstellen/verbrauchsausweis-gewerbe?ausweistyp={Enums.AusweisTyp.Beratung}"><button class="bestellbutton" type="button">sofort<br>bestellen</button></a>
<a href="{ref}/energieausweis-erstellen/verbrauchsausweis-gewerbe?ausweistyp={Enums.AusweisTyp.Offline}"><button class="bestellbutton" type="button">sofort<br>bestellen</button></a>
</div>
</div>
</div>
<style lang="postcss">
.bestellbutton {
@apply px-[2px] sm:px-4 mx-[2px] sm:mx-2 py-2 bg-secondary ring-2 ring-secondary/25 rounded-none xs:rounded-md text-white text-nowrap font-bold
hover:bg-gradient-to-br from-secondary to-secondary-grad hover:shadow-lg transition-all hover:no-underline hover:ring-2 hover:ring-primary;
}
.zeile {
@apply text-[0.6rem] sm:text-[1rem] md:text-[1.5rem];
}
.bullet {
@apply text-[0.75rem] sm:text-[1rem] md:text-[1.25rem];
}
.bullet:nth-child(even) {
@apply bg-blue-100/40;
}
.bullet:nth-child(2) {
@apply !border-t-[6px];
}
.bullet:nth-child(12) {
@apply !border-b-[6px];
}
.bestellbutton{@apply px-[2px] sm:px-4 mx-[2px] sm:mx-2 py-2 bg-secondary ring-2 ring-secondary/25 rounded-none xs:rounded-md text-white text-nowrap font-bold
hover:bg-gradient-to-br from-secondary to-secondary-grad hover:shadow-lg transition-all hover:no-underline hover:ring-2 hover:ring-primary;}
.zeile{@apply text-[0.6rem] sm:text-[1rem] md:text-[1.5rem]}
.bullet{@apply text-[0.75rem] sm:text-[1rem] md:text-[1.25rem]}
.bullet:nth-child(even){@apply bg-blue-100/40}
.bullet:nth-child(2){@apply !border-t-[6px]}
.bullet:nth-child(12){@apply !border-b-[6px]}
.check {
@apply text-[1.25rem] sm:text-[1.5rem] font-bold text-green-700;
@@ -173,7 +84,6 @@
@apply text-[1.25rem] sm:text-[1.5rem] font-bold text-black;
}
.price {
@apply text-[1.25rem] sm:text-[2rem];
}
.price{@apply text-[1.25rem] sm:text-[2rem]}
</style>

View File

@@ -1,170 +1,85 @@
<script lang="ts">
import { PRICES } from "#lib/constants.js";
import { Enums } from "#lib/client/prisma.js";
export let bullets;
export let title;
export let ref = "";
const bullets = [
[
"Prüfung durch Dipl.&nbsp;Ing.<br>Registrierung beim DiBt<br>rechtssicher nach&nbsp;GEG",
true,
true,
true,
],
[
"Originalausweis als&nbsp;PDF per&nbsp;<span class='text-nowrap'>E-Mail</span><br>Originalausweis per&nbsp;Post (zubuchbar)",
true,
true,
true,
],
[
"Bearbeitung innerhalb 24&nbsp;Stunden<br>Selbsteingabe",
true,
true,
false,
],
bullets = [
["Prüfung durch Dipl.&nbsp;Ing.<br>Registrierung beim DiBt<br>rechtssicher nach&nbsp;GEG",true, true, true],
["Originalausweis als&nbsp;PDF per&nbsp;<span class='text-nowrap'>E-Mail</span><br>Originalausweis per&nbsp;Post (zubuchbar)",true, true, true],
["Bearbeitung innerhalb 24&nbsp;Stunden<br>Selbsteingabe",true, true, false],
["Same&nbsp;day&nbsp;service (zubuchbar)",true, true, false],
["Fotoupload",true, true, true],
[
"automatische Vorprüfung<br>Live&nbsp;Vorschau direkt bei&nbsp;Eingabe<br>Live&nbsp;Vorschauausweis vorab<br>Vorschauausweis per&nbsp;E-Mail<br>dynamische&nbsp;Eingabehilfe",
true,
true,
false,
],
[
"Prüfanmerkungen per&nbsp;<span class='text-nowrap'>E-Mail</span>",
true,
true,
false,
],
["automatische Vorprüfung<br>Live&nbsp;Vorschau direkt bei&nbsp;Eingabe<br>Live&nbsp;Vorschauausweis vorab<br>Vorschauausweis per&nbsp;E-Mail<br>dynamische&nbsp;Eingabehilfe",true, true, false],
["Prüfanmerkungen per&nbsp;<span class='text-nowrap'>E-Mail</span>",true, true, false],
["persönlicher&nbsp;Support",false, true, true],
[
"telefonische&nbsp;Beratung<br>persönlicher&nbsp;Energieberater",
false,
true,
true,
],
["telefonische&nbsp;Beratung<br>persönlicher&nbsp;Energieberater",false, true, true],
["Dokumentenupload (Verbrauchsabrechnungen)",false, false, true],
["Eingabe durch Dipl.&nbsp;Ing.",false, false, true],
];
]
</script>
<h1>
Produktübersicht: <span class="text-secondary"
>Verbrauchsausweis Wohngebäude</span
>
</h1>
<h1>Produktübersicht: <span class="text-secondary">Verbrauchsausweis Wohngebäude</span></h1>
<h3>Verbrauchsausweis Leistungen und Preise in der Übersicht:</h3>
<hr />
<br />
<hr>
<br>
<div id="ProduktUebersichtVerbrauchsausweisWohnen">
<div
class="w-full sm:w-[90%] sm:mx-auto grid grid-cols-[1fr_max-content_max-content_max-content] sm:grid-cols-[1fr_min-content_min-content_min-content]"
>
<div
class="zeile grid grid-cols-subgrid col-span-4 py-4 border-b-[1px] justify-items-center items-center sm:text-[1.25rem]"
>
<div class="justify-self-start pl-2"><b>Leistung</b></div>
<div><b>online</b></div>
<div><b>premium</b></div>
<div><b>offline</b></div>
<div class="w-full sm:w-[90%] sm:mx-auto grid grid-cols-[1fr_max-content_max-content_max-content] sm:grid-cols-[1fr_min-content_min-content_min-content]">
<div class="zeile grid grid-cols-subgrid col-span-4 py-4 border-b-[1px] justify-items-center items-center sm:text-[1.25rem]">
<div class="justify-self-start pl-2"><b>Leistung</b></div><div><b>online</b></div><div><b>premium</b></div><div><b>offline</b></div>
</div>
{#each bullets as [bullet,online,premium,offline]}
<div
class="bullet grid grid-cols-subgrid col-span-4 py-4 border-b-[1px] justify-items-center items-center"
>
<div class="bullet grid grid-cols-subgrid col-span-4 py-4 border-b-[1px] justify-items-center items-center">
<div class="justify-self-start pl-2">{@html bullet}</div>
<div class:check={online} class:check-no={!online}>
{online ? "✔" : ""}
</div>
<div class:check={premium} class:check-no={!premium}>
{premium ? "✔" : ""}
</div>
<div class:check={offline} class:check-no={!offline}>
{offline ? "✔" : ""}
</div>
<div class:check={online} class:check-no={!online}>{online ? "✔" : ""}</div>
<div class:check={premium} class:check-no={!premium}>{premium ? "✔" : ""}</div>
<div class:check={offline} class:check-no={!offline}>{offline ? "✔" : ""}</div>
</div>
{/each}
<div
class="zeile grid grid-cols-subgrid col-span-4 py-4 border-b-[0px] justify-items-center items-center sm:text-[1.25rem]"
>
<div class="zeile grid grid-cols-subgrid col-span-4 py-4 border-b-[0px] justify-items-center items-center sm:text-[1.25rem]">
<div class="price justify-self-start pl-2">Preis inkl. MwSt.</div>
<div class="price">
<b
>{PRICES.VerbrauchsausweisWohnen[
Enums.AusweisTyp.Standard
]}&nbsp;</b
>
</div>
<div class="price">
<b
>{PRICES.VerbrauchsausweisWohnen[
Enums.AusweisTyp.Beratung
]}&nbsp;</b
>
</div>
<div class="price">
<b
>{PRICES.VerbrauchsausweisWohnen[
Enums.AusweisTyp.Offline
]}&nbsp;</b
>
</div>
<div class="price"><b>{PRICES.VerbrauchsausweisWohnen[Enums.AusweisTyp.Standard]}&nbsp;</b></div>
<div class="price"><b>{PRICES.VerbrauchsausweisWohnen[Enums.AusweisTyp.Beratung]}&nbsp;</b></div>
<div class="price"><b>{PRICES.VerbrauchsausweisWohnen[Enums.AusweisTyp.Offline]}&nbsp;</b></div>
</div>
<div
class="zeile grid grid-cols-subgrid col-span-4 py-4 border-b-[0px] justify-items-center items-center"
>
<div class="zeile grid grid-cols-subgrid col-span-4 py-4 border-b-[0px] justify-items-center items-center">
<div class="justify-self-start pl-2"></div>
<a
href="{ref}/energieausweis-erstellen/verbrauchsausweis-wohngebaeude?ausweistyp={Enums
.AusweisTyp.Standard}"
><button class="bestellbutton" type="button"
>sofort<br />bestellen</button
></a
>
<a
href="{ref}/energieausweis-erstellen/verbrauchsausweis-wohngebaeude?ausweistyp={Enums
.AusweisTyp.Beratung}"
><button class="bestellbutton" type="button"
>sofort<br />bestellen</button
></a
>
<a
href="{ref}/energieausweis-erstellen/verbrauchsausweis-wohngebaeude?ausweistyp={Enums
.AusweisTyp.Offline}"
><button class="bestellbutton" type="button"
>sofort<br />bestellen</button
></a
>
<a href="{ref}/energieausweis-erstellen/verbrauchsausweis-wohngebaeude?ausweistyp={Enums.AusweisTyp.Standard}" ><button class="bestellbutton" type="button">sofort<br>bestellen</button></a>
<a href="{ref}/energieausweis-erstellen/verbrauchsausweis-wohngebaeude?ausweistyp={Enums.AusweisTyp.Beratung}" ><button class="bestellbutton" type="button">sofort<br>bestellen</button></a>
<a href="{ref}/energieausweis-erstellen/verbrauchsausweis-wohngebaeude?ausweistyp={Enums.AusweisTyp.Offline}" ><button class="bestellbutton" type="button">sofort<br>bestellen</button></a>
</div>
</div>
</div>
<style lang="postcss">
.bestellbutton {
@apply px-[2px] sm:px-4 mx-[2px] sm:mx-2 py-2 bg-secondary ring-2 ring-secondary/25 rounded-none xs:rounded-md text-white text-nowrap font-bold
hover:bg-gradient-to-br from-secondary to-secondary-grad hover:shadow-lg transition-all hover:no-underline hover:ring-2 hover:ring-primary;
}
.zeile {
@apply text-[0.6rem] sm:text-[1rem] md:text-[1.5rem];
}
.bullet {
@apply text-[0.75rem] sm:text-[1rem] md:text-[1.25rem];
}
.bullet:nth-child(even) {
@apply bg-blue-100/40;
}
.bullet:nth-child(2) {
@apply !border-t-[6px];
}
.bullet:nth-child(12) {
@apply !border-b-[6px];
}
.bestellbutton{@apply px-[2px] sm:px-4 mx-[2px] sm:mx-2 py-2 bg-secondary ring-2 ring-secondary/25 rounded-none xs:rounded-md text-white text-nowrap font-bold
hover:bg-gradient-to-br from-secondary to-secondary-grad hover:shadow-lg transition-all hover:no-underline hover:ring-2 hover:ring-primary;}
.zeile{@apply text-[0.6rem] sm:text-[1rem] md:text-[1.5rem]}
.bullet{@apply text-[0.75rem] sm:text-[1rem] md:text-[1.25rem]}
.bullet:nth-child(even){@apply bg-blue-100/40}
.bullet:nth-child(2){@apply !border-t-[6px]}
.bullet:nth-child(12){@apply !border-b-[6px]}
.check {
@apply text-[1.25rem] sm:text-[1.5rem] font-bold text-green-700;
@@ -173,7 +88,6 @@
@apply text-[1.25rem] sm:text-[1.5rem] font-bold text-black;
}
.price {
@apply text-[1.25rem] sm:text-[2rem];
}
.price{@apply text-[1.25rem] sm:text-[2rem]}
</style>

View File

@@ -1,184 +0,0 @@
---
export interface Props {
tab: number;
}
const { tab } = Astro.props;
const { params } = Astro;
const partner = params.partner;
const pathname = Astro.url.pathname;
const isVA = pathname.includes("verbrauchsausweis-wohngebaeude");
const isVAG = pathname.includes("verbrauchsausweis-gewerbe");
const isBA = pathname.includes("bedarfsausweis-wohngebaeude");
const isBAG = pathname.includes("bedarfsausweis-gewerbe-anfragen");
const isGGW = pathname.includes("geg-nachweis-wohnen-anfragen");
const isGGG = pathname.includes("geg-nachweis-gewerbe-anfragen");
const isWEA = pathname.includes("welcher-ausweis");
const isWelt = pathname.includes("immowelt");
const isNET = pathname.includes("immonet");
---
<header id="header" class="w-full bg-white h-[81px] sm:pl-8">
<div class="grid grid-cols-[min-content_1fr] items-center">
<div class="w-[150px] h-[80px]">
<div
class="w-full h-full grid grid-col-1 justify-items-center items-center"
>
<img
class={isNET
? "w-[149px]"
: isWelt
? "w-[109px]"
: "w-[109px]"}
src={`/images/partner/${partner}/${partner}.svg`}
alt={partner}
/>
</div>
</div>
<div>
<!-- Navigation als Liste (nur ab sm sichtbar) -->
<ul class="navlist hidden xl:flex">
<li><a href={`/${partner}/energieausweis-erstellen/verbrauchsausweis-wohngebaeude/`}><button class={tab === 0 ? "glow" : ""}>Verbrauchsausweis</button></a></li>
<li><a href={`/${partner}/energieausweis-erstellen/verbrauchsausweis-gewerbe/`}><button class={tab === 1 ? "glow" : ""}>Verbrauchsausweis Gewerbe</button></a></li>
<li><a href={`/${partner}/energieausweis-erstellen/bedarfsausweis-wohngebaeude/`}><button class={tab === 2 ? "glow" : ""}>Bedarfsausweis</button></a></li>
<li><a href={`/${partner}/angebot-anfragen/bedarfsausweis-gewerbe-anfragen/`}><button class={tab === 3 ? "glow" : ""}>Bedarfsausweis Gewerbe</button></a></li>
<li><a href={`/${partner}/angebot-anfragen/geg-nachweis-wohnen-anfragen/`}><button class={tab === 4 ? "glow" : ""}>GEG Nachweis Wohngebäude</button></a></li>
<li><a href={`/${partner}/angebot-anfragen/geg-nachweis-gewerbe-anfragen/`}><button class={tab === 5 ? "glow" : ""}>GEG Nachweis Gewerbe</button></a></li>
<li><a href={`/${partner}/welcher-ausweis/${partner}`}><button class={tab === 6 ? "glow" : ""}>Welcher Ausweis</button></a></li>
</ul>
<!-- Navigation als Dropdown (nur bis sm sichtbar) -->
<select
class="xl:hidden border rounded p-2 w-[calc(100%-2rem)]"
onchange="if (this.value) window.location.href=this.value"
>
<option value="">Auswahl treffen…</option>
<option value={`/${partner}/energieausweis-erstellen/verbrauchsausweis-wohngebaeude/`} selected={tab === 0}>Verbrauchsausweis</option>
<option value={`/${partner}/energieausweis-erstellen/verbrauchsausweis-gewerbe/`} selected={tab === 1}>Verbrauchsausweis Gewerbe</option>
<option value={`/${partner}/energieausweis-erstellen/bedarfsausweis-wohngebaeude/`} selected={tab === 2}>Bedarfsausweis</option>
<option value={`/${partner}/angebot-anfragen/bedarfsausweis-gewerbe-anfragen/`} selected={tab === 3}>Bedarfsausweis Gewerbe</option>
<option value={`/${partner}/angebot-anfragen/geg-nachweis-wohnen-anfragen/`} selected={tab === 4}>GEG Nachweis Wohngebäude</option>
<option value={`/${partner}/angebot-anfragen/geg-nachweis-gewerbe-anfragen/`} selected={tab === 5}>GEG Nachweis Gewerbe</option>
<option value={`/${partner}/welcher-ausweis/${partner}`} selected={tab === 6}>Welcher Ausweis</option>
</select>
</div>
</div>
</header>
<div
id="titel"
class="block w-full lg:h-[270px] bg-cover !px-8 md:px-32 !py-8 md:py-16"
style={`background-image: url('/images/partner/${partner}/hero-energieausweis.jpg');
background-repeat:no-repeat; background-position:right;`}
>
{
isVA ? (
<div>
Hier komfortabel und einfach online den{" "}
<b>Verbrauchsausweis Wohngebäude</b> bestellen
</div>
) : (
""
)
}
{
isVAG ? (
<div>
Hier komfortabel und einfach online den{" "}
<b>Verbrauchsausweis Gewerbe</b> bestellen
</div>
) : (
""
)
}
{
isBA ? (
<div>
Hier komfortabel und einfach online den{" "}
<b>Bedarfsausweis Wohngebäude</b> bestellen
</div>
) : (
""
)
}
{
isBAG ? (
<div>
Hier komfortabel und einfach online den{" "}
<b>Bedarfsausweis Gewerbe</b> anfragen
</div>
) : (
""
)
}
{
isGGW ? (
<div>
Hier komfortabel und einfach online den{" "}
<b>GEG Nachweis Wohngebäude</b> anfragen
</div>
) : (
""
)
}
{
isGGG ? (
<div>
Hier komfortabel und einfach online den{" "}
<b>GEG Nachweis Gewerbe</b> anfragen
</div>
) : (
""
)
}
{
isWEA ? (
<div>
Hier komfortabel und einfach online den richtigen Ausweis finden
</div>
) : (
""
)
}
</div>
<style lang="postcss">
@font-face {
font-family: "immo Sans";
src: url('/fonts/Immo-Sans/immoSans-Regular.eot');
src: url('/fonts/Immo-Sans/immoSans-Regular.eot?#iefix') format('embedded-opentype'),
url('/fonts/Immo-Sans/immoSans-Regular.woff2') format('woff2'),
url('/fonts/Immo-Sans/immoSans-Regular.woff') format('woff');
font-style: normal;
font-weight: 400;
}
#titel{
font-family: "immo Sans";
font-weight:400;
div{@apply w-fit bg-white/75 py-6 px-4 md:px-16 rounded-lg ring-2 ring-black/15 text-[1.45rem];box-shadow:8px 8px 16px rgba(0,0,0,0.5);}
}
.header-button {
@apply px-4 py-2 text-primary-content font-medium text-lg tracking-normal hover:bg-secondary h-full;
}
.navlist {
@apply flex flex-wrap flex-col sm:flex-row pl-[1.75rem] sm:pl-[1.75rem];
}
.navlist li {
@apply pr-0 sm:pr-[6px] pb-1 sm:pb-0;
}
.navlist li button{@apply text-[0.75rem] md:text-[1rem] text-[#646464] sm:p-2 text-left
hover:rounded-[1rem] hover:bg-[rgba(50,50,50,0.1)];
font-family: "immo Sans";
font-weight:400;}
.glow{@apply rounded-[1rem] bg-[rgba(50,50,50,0.1)];}
</style>

View File

@@ -0,0 +1,114 @@
---
import HeaderLogin from "#components/design/header/HeaderLogin.svelte";
const { tabHover1 } = Astro.props;
const { tabHover2 } = Astro.props;
const { tabHover3 } = Astro.props;
const { tabHover4 } = Astro.props;
const { tabHover5 } = Astro.props;
const { tabHover6 } = Astro.props;
const { tabHover7 } = Astro.props;
const { params, url } = Astro;
const partner = params.partner;
const url1 = new URL(Astro.request.url);
const urlPath = url1.pathname;
const isVA = urlPath.includes("verbrauchsausweis-wohngebaeude");
const isVAG = urlPath.includes("verbrauchsausweis-gewerbe");
const isBA = urlPath.includes("bedarfsausweis-wohngebaeude");
const isBAG = urlPath.includes("bedarfsausweis-gewerbe-anfragen");
const isGGW = urlPath.includes("geg-nachweis-wohnen-anfragen");
const isGGG = urlPath.includes("geg-nachweis-gewerbe-anfragen");
const isWEA = urlPath.includes("welcher-ausweis");
const isWelt = urlPath.includes("immowelt");
const isNET = urlPath.includes("immonet");
---
<header id="header" class="w-full bg-white h-[81px] sm:pl-8">
<div class="grid grid-cols-[min-content_1fr] items-center">
<div class="w-[150px] h-[80px]">
<div class="w-full h-full grid grid-col-1 justify-items-center items-center">
<img class={isNET ? "w-[149px]" : isWelt ? "w-[109px]" : "w-[109px]"} src={`/images/partner/${partner}/${partner}.svg`} alt={partner} />
</div>
</div>
<div>
<ul class="navlist">
<li><a href={`/${partner}/energieausweis-erstellen/verbrauchsausweis-wohngebaeude/`}><button class={tabHover1}>Verbrauchsausweis</button></a></li>
<li><a href={`/${partner}/energieausweis-erstellen/verbrauchsausweis-gewerbe/`}><button class={tabHover2}>Verbrauchsausweis Gewerbe</button></a></li>
<li><a href={`/${partner}/energieausweis-erstellen/bedarfsausweis-wohngebaeude/`}><button class={tabHover3}>Bedarfsausweis</button></a></li>
<li><a href={`/${partner}/angebot-anfragen/bedarfsausweis-gewerbe-anfragen/`}><button class={tabHover4}>Bedarfsausweis Gewerbe</button></a></li>
<li><a href={`/${partner}/angebot-anfragen/geg-nachweis-wohnen-anfragen/`}><button class={tabHover5}>GEG Nachweis Wohngebäude</button></a></li>
<li><a href={`/${partner}/angebot-anfragen/geg-nachweis-gewerbe-anfragen/`}><button class={tabHover6}>GEG Nachweis Gewerbe</button></a></li>
<li><a href={`/${partner}/welcher-ausweis/${partner}`}><button class={tabHover7}>Welcher Ausweis</button></a></li>
</ul>
</div>
</div>
</header>
<div id="titel" class="block w-full 2xl:h-[270px] lg:h-[148px] bg-cover px-24 py-20"
style={`background-image: url('/images/partner/${partner}/hero-energieausweis.jpg');
background-repeat:no-repeat; background-position:right;`}>
{isVA ? <div>Hier komfortabel und einfach online den <b>Verbrauchsausweis Wohngebäude</b> bestellen</div> : ""}
{isVAG ? <div>Hier komfortabel und einfach online den <b>Verbrauchsausweis Gewerbe</b> bestellen</div> : ""}
{isBA ? <div>Hier komfortabel und einfach online den <b>Bedarfsausweis Wohngebäude</b> bestellen</div> : ""}
{isBAG ? <div>Hier komfortabel und einfach online den <b>Bedarfsausweis Gewerbe</b> anfragen</div> : ""}
{isGGW ? <div>Hier komfortabel und einfach online den <b>GEG Nachweis Wohngebäude</b> anfragen</div> : ""}
{isGGG ? <div>Hier komfortabel und einfach online den <b>GEG Nachweis Gewerbe</b> anfragen</div> : ""}
{isWEA ? <div>Hier komfortabel und einfach online den richtigen Ausweis finden</div> : ""}
</div>
<style lang="postcss">
@font-face {
font-family: "immo Sans";
src: url('/fonts/Immo-Sans/immoSans-Regular.eot');
src: url('/fonts/Immo-Sans/immoSans-Regular.eot?#iefix') format('embedded-opentype'),
url('/fonts/Immo-Sans/immoSans-Regular.woff2') format('woff2'),
url('/fonts/Immo-Sans/immoSans-Regular.woff') format('woff');
font-style: normal;
font-weight: 400;
}
#titel{
font-family: "immo Sans";
font-weight:400;
div{@apply w-fit bg-white/75 py-6 px-16 rounded-lg ring-2 ring-black/15 text-[1.45rem];box-shadow:8px 8px 16px rgba(0,0,0,0.5);}
}
.header-button {
@apply px-4 py-2 text-primary-content font-medium text-lg tracking-normal hover:bg-secondary h-full;
}
.navlist {
@apply flex flex-wrap flex-col sm:flex-row pl-[1.75rem] sm:pl-[1.75rem];
}
.navlist li {
@apply pr-0 sm:pr-[6px] pb-1 sm:pb-0;
}
.navlist li button{@apply text-[0.75rem] md:text-[1rem] text-[#646464] sm:p-2 text-left
hover:rounded-[1rem] hover:bg-[rgba(50,50,50,0.1)];
font-family: "immo Sans";
font-weight:400;}
.glow{@apply rounded-[1rem] bg-[rgba(50,50,50,0.1)];}
</style>

View File

@@ -0,0 +1,82 @@
---
import HeaderLogin from "#components/design/header/HeaderLogin.svelte";
---
<header id="header">
<div id="header-grid" class="grid relative bg-white items-center gap-x-4 pt-4 px-0
grid-cols-1
sm:grid-cols-1
md:grid-cols-1
lg:grid-cols-[1fr_minmax(450px,450px)] lg:gap-x-3 lg:px-4 lg:py-4
xl:grid-cols-[1fr_minmax(450px,450px)] xl:gap-x-4 xl:px-6 xl:py-4
2xl:grid-cols-[1fr_minmax(450px,450px)] 2xl:gap-x-5 2xl:px-6 2xl:py-4">
<div class="justify-self-center xs:justify-self-start">
<div class="grid grid-cols-1 px-2 gap-2 gap-y-1
xs:grid-cols-[max-content,1fr] xs:gap-x-2 xs:px-4
md:gap-y-4
lg:px-0 lg:gap-x-4">
<div class="self-start justify-self-start">
<a href="/">
<img id="header-logo" class="w-full
xs:max-w-[64px]
sm:max-w-[64px]
md:max-w-[64px] md:ml-6
lg:max-w-[64px] lg:ml-0
xl:max-w-[94px] xl:ml-0
"
src="/images/header/logo-IBC-big.svg" alt="IBCornelsen-Logo"/>
</a>
</div>
<div class="self-center justify-self-center md:justify-self-start xs:mt-[20px] md:mt-[18px]">
<div id="header-text-1"class="text-secondary justify-self-center
xs:[font-size:_clamp(15px,5vw,36px)] xs:justify-self-start xs:leading-[36px]
lg:[font-size:_clamp(15px,3vw,26px)]
lg:leading-[2rem]
xl:[font-size:_clamp(15px,3vw,36px)]
xl:leading-[4.5rem] pt-[0px]">
Energieausweis online erstellen</div>
<div id="header-text-2"class="text-primary justify-self-center
xs:[font-size:_clamp(15px,4vw,28px)] xs:justify-self-start xs:leading-[20px]
lg:[font-size:_clamp(15px,3vw,20px)]
lg:leading-[2rem]
xl:[font-size:_clamp(15px,3vw,24px)]
xl:leading-[0.5rem]">
Energieausweise nach aktuellem GEG</div>
</div>
</div>
</div>
<div class="w-full justify-self-center">
<HeaderLogin client:load />
</div>
</div>
</div>
<div class="col-start-1 col-span-3">
<div id="header-line" class="px-2 flex flex-row w-full justify-end items-center bg-primary
lg:h-[12px] xl:h-[12px]"></div>
</div>
</header>
<style>
.header-button {
@apply px-4 py-2 text-primary-content font-medium text-lg tracking-normal hover:bg-secondary h-full;
}
</style>

View File

@@ -1,22 +1,19 @@
---
import NavigationCard from "#components/design/sidebars/cards/NavigationCard.svelte";
import CardPriceInfo from "#components/design/sidebars/cards/CardPriceInfo.svelte";
import CardPriceiInfo from "#components/design/sidebars/cards/cardPriceiInfo.svelte";
import CardProduktSidebar from "#components/design/sidebars/cards/CardProduktSidebar.svelte";
import { PRICES } from "#lib/constants";
import { Enums } from "#lib/client/prisma";
---
<div class="">
<NavigationCard client:load/>
<CardProduktSidebar
art="Verbrauchsausweis Gewerbe"
price={PRICES.VerbrauchsausweisGewerbe[Enums.AusweisTyp.Standard]}
/>
<CardPriceInfo />
<CardProduktSidebar
art="Bedarfsausweis Wohnen"
price={PRICES.BedarfsausweisWohnen[Enums.AusweisTyp.Standard]}
/>
<CardProduktSidebar art="Verbrauchsausweis Gewerbe" price={PRICES.VerbrauchsausweisGewerbe[Enums.AusweisTyp.Standard]}></CardProduktSidebar>
<CardPriceiInfo />
<CardProduktSidebar art="Bedarfsausweis Wohnen" price={PRICES.BedarfsausweisWohnen[Enums.AusweisTyp.Standard]}></CardProduktSidebar>
</div>

View File

@@ -1,6 +1,6 @@
---
import CardContact from "#components/design/sidebars/cards/ContactCard.svelte";
import CardPriceInfo from "#components/design/sidebars/cards/CardPriceInfo.svelte";
import CardPriceiInfo from "#components/design/sidebars/cards/cardPriceiInfo.svelte";
import CardProduktSidebar from "#components/design/sidebars/cards/CardProduktSidebar.svelte";
import { PRICES } from "#lib/constants";
@@ -8,15 +8,16 @@ import { Enums } from "#lib/client/prisma";
---
<div class="hidden 2xl:block">
<CardContact />
<CardProduktSidebar
art="Verbrauchsausweis Wohnen"
price={PRICES.VerbrauchsausweisWohnen[Enums.AusweisTyp.Standard]}
/>
<CardPriceInfo />
<CardProduktSidebar
art="Bedarfsausweis Gewerbe"
price={PRICES.BedarfsausweisGewerbe[Enums.AusweisTyp.Standard]}
/>
<CardProduktSidebar art="Verbrauchsausweis Wohnen" price={PRICES.VerbrauchsausweisWohnen[Enums.AusweisTyp.Standard]}></CardProduktSidebar>
<CardPriceiInfo />
<CardProduktSidebar art="Bedarfsausweis Gewerbe" price={PRICES.BedarfsausweisGewerbe[Enums.AusweisTyp.Standard]}></CardProduktSidebar>
</div>
</div>

View File

@@ -1,66 +0,0 @@
<script>
import { PRICES } from "#lib/constants";
import { Enums } from "#lib/client/prisma";
</script>
<div id="cardPriceinfo" class="box card hidden lg:block">
<h2>Was wird der Energieausweis kosten?</h2>
<div>Verbrauchsausweis Wohngebäude</div>
<div>
ab&nbsp;<span class="price"
>{PRICES.VerbrauchsausweisWohnen[Enums.AusweisTyp.Standard]}€</span
>&nbsp;inkl.&nbsp;MwSt.
</div>
<hr class="trenner" />
<div>Bedarfsausweis Wohngebäude</div>
<div>
ab&nbsp;<span class="price"
>{PRICES.BedarfsausweisWohnen[Enums.AusweisTyp.Standard]}€</span
>&nbsp;inkl.&nbsp;MwSt.
</div>
<hr class="trenner" />
<div>Verbrauchsausweis Gewerbe</div>
<div>
ab&nbsp;<span class="price"
>{PRICES.VerbrauchsausweisGewerbe[Enums.AusweisTyp.Standard]}€</span
>&nbsp;inkl.&nbsp;MwSt.
</div>
<hr class="trenner" />
<div>Bedarfsausweis Gewerbe</div>
<div>
ab&nbsp;<span class="price"
>{PRICES.BedarfsausweisGewerbe[Enums.AusweisTyp.Standard]}€</span
>&nbsp;inkl.&nbsp;MwSt.
</div>
<hr class="trenner" />
<div>GEG-Nachweis Wohngebäude</div>
<div>
ab&nbsp;<span class="price"
>{PRICES.GEGNachweisWohnen[Enums.AusweisTyp.Standard]}€</span
>&nbsp;inkl.&nbsp;MwSt.
</div>
<hr class="trenner" />
<div>GEG-Nachweis Gewerbe</div>
<div>
ab&nbsp;<span class="price"
>{PRICES.GEGNachweisGewerbe[Enums.AusweisTyp.Standard]}€</span
>&nbsp;inkl.&nbsp;MwSt.
</div>
<hr class="mt-2" />
</div>
<style lang="postcss">
.trenner {
@apply my-2;
}
.price {
@apply font-bold;
}
</style>

View File

@@ -0,0 +1,465 @@
<script lang="ts">
let innerWidth: number;
function dropdown() {
if (innerWidth < 1024) {
const check_element = this.lastChild;
const rotate_list = document.querySelectorAll(".dd-symbol-clone");
const rotate_element = this.childNodes[0].children[0];
var first_check = check_element.classList.contains(
"show-dropdown-content"
);
const nodeList = document.querySelectorAll(".dropdown-content");
if (first_check == true) {
check_element.classList.remove("show-dropdown-content");
rotate_element.classList.toggle("rotate-symbol");
} else {
for (let i = 0; i < nodeList.length; i++) {
const element = nodeList[i];
element.classList.remove("show-dropdown-content");
}
for (let i = 0; i < rotate_list.length; i++) {
const element = rotate_list[i];
element.classList.remove("rotate-symbol");
}
check_element.classList.add("show-dropdown-content");
rotate_element.classList.add("rotate-symbol");
}
}
}
function hover() {
if (innerWidth > 1024) {
const check_element = this.firstChild.lastChild;
check_element.style.visibility = "visible";
}
}
function hoverout() {
if (innerWidth > 1024) {
const check_element = this.firstChild.lastChild;
check_element.style.visibility = "hidden";
}
}
function hamburger() {
const nodeList = document.querySelectorAll(".dropdown-content");
for (let i = 0; i < nodeList.length; i++) {
nodeList[i].classList.remove("show-dropdown-content");
}
var element = document.getElementById("cardNavigation");
element.classList.toggle("hidden");
const spans = this.children;
var first_check = spans[0].classList.contains("hamburger-swing-0");
if (first_check == true) {
for (let i = 0; i < spans.length; i++) {
spans[i].classList.remove("hamburger-swing-" + i);
}
const rotate_list = document.querySelectorAll(".dd-symbol");
for (let i = 0; i < rotate_list.length; i++) {
rotate_list[i].classList.remove("rotate-symbol");
}
} else {
for (let i = 0; i < spans.length; i++) {
spans[i].classList.add("hamburger-swing-" + i);
}
}
}
</script>
<svelte:window bind:innerWidth />
<div
class="hamburger_menu py-1 px-2 bg-secondary
xs:px-4
lg:hidden"
>
<div
id="hamburger"
on:click={hamburger}
on:keydown={hamburger}
class="cursor-pointer"
>
<span></span>
<span></span>
<span></span>
</div>
</div>
<nav
id="cardNavigation"
class="cardNavigation box hidden relative ring-0 md:ring-2 ring-primary/50 rounded-tr-none lg:block mb-0 lg:mb-5"
>
<div class="nav-element bg-secondary/5 py-1 pl-2 text-xs font-bold">
Jetzt bestellen
</div>
<div class="nav-element">
<a class="no-dropdown nav-element-child" href="/welcher-energieausweis/"
>Welcher Energieausweis?</a
>
</div>
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
<div
class="nav-element dropdown lg:dropdown-right"
on:click={dropdown}
on:keydown={dropdown}
on:mouseover={hover}
on:mouseleave={hoverout}
>
{#if innerWidth > 1023}
<a href={undefined} class="nav-element-child"
>Energieausweis erstellen<span class="dd-symbol-clone"></span
><span class="dd-symbol"></span></a
>
{:else}
<a href={undefined} class="nav-element-child"
>Energieausweis erstellen<span class="dd-symbol-clone"></span
><span class="dd-symbol"></span></a
>
{/if}
<ul class="dropdown-content energieasusweis-erstellen">
{#if innerWidth < 1023}
<li>
<a href="/energieausweis-erstellen"
>Energieausweis erstellen</a
>
</li>
{/if}
<li>
<a
href="/energieausweis-erstellen/verbrauchsausweis-wohngebaeude/"
>Verbrauchsausweis erstellen</a
>
</li>
<li>
<a href="/energieausweis-erstellen/bedarfsausweis-wohngebaeude/"
>Bedarfsausweis erstellen</a
>
</li>
<li>
<a href="/energieausweis-erstellen/verbrauchsausweis-gewerbe/"
>Verbrauchsausweis Gewerbe erstellen</a
>
</li>
</ul>
</div>
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
<div
class="nav-element dropdown lg:dropdown-right"
on:click={dropdown}
on:keydown={dropdown}
on:mouseover={hover}
on:mouseleave={hoverout}
>
{#if innerWidth > 1023}
<a href={undefined} class="nav-element-child"
>Angebot anfragen<span class="dd-symbol-clone"></span><span
class="dd-symbol"></span
></a
>
{:else}
<a href={undefined} class="nav-element-child"
>Angebot anfragen<span class="dd-symbol-clone"></span><span
class="dd-symbol"></span
></a
>
{/if}
<ul class="dropdown-content angebot-anfragen">
{#if innerWidth < 1023}
<li>
<a href="/energieausweis-erstellen">Angebot anfragen</a>
</li>
{/if}
<li>
<a
href="/angebot-anfragen/bedarfsausweis-gewerbe-anfragen"
>Bedarfsausweis Gewerbe anfragen</a
>
</li>
<li>
<a href="/angebot-anfragen/geg-nachweis-wohnen-anfragen"
>GEG Nachweis Wohnen anfragen</a
>
</li>
<li>
<a href="/angebot-anfragen/geg-nachweis-gewerbe-anfragen"
>GEG Nachweis Gewerbe anfragen</a
>
</li>
</ul>
</div>
<div class="nav-element">
<a class="no-dropdown nav-element-child" href="/sanierungsfahrplan"
>Sanierungsfahrplan (iSFP)</a
>
</div>
<div class="nav-element bg-secondary/5 py-1 pl-2 text-xs font-bold">
Produkte & Preise
</div>
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
<div
class="nav-element dropdown lg:dropdown-right"
on:click={dropdown}
on:keydown={dropdown}
on:mouseover={hover}
on:mouseleave={hoverout}
>
<a href="/verbrauchsausweis/" class="nav-element-child"
>Verbrauchsausweis<span class="dd-symbol-clone"></span><span
class="dd-symbol"></span
></a
>
<ul class="dropdown-content verbrauchsausweis">
{#if innerWidth < 1023}
<li><a href="index">Verbrauchsausweis</a></li>
{/if}
<li><a href="/verbrauchsausweis/verbrauchsausweis-wohngebaeude/">Verbrauchsausweis Wohngebäude</a></li>
<li><a href="/energieausweis-erstellen/verbrauchsausweis-wohngebaeude/">Verbrauchsausweis online erstellen</a></li>
<li><a href="/verbrauchsausweis/haeufige-fragen-zum-verbrauchsausweis/">Häufige Fragen zum Verbrauchsausweis</a></li>
<li>
<a href="/verbrauchsausweis/statistiken-zum-verbrauchsausweis/">Statistiken zum Verbrauchsausweis Wohngebäude</a
>
</li>
<li><a href="/verbrauchsausweis/verbrauchsausweis-gewerbe/">Verbrauchsausweis Gewerbe</a></li>
<li>
<a href="/energieausweis-erstellen/verbrauchsausweis-gewerbe/">Verbrauchsausweis Gewerbe online erstellen</a>
</li>
<li>
<a href="/verbrauchsausweis/haeufige-fragen-zum-verbrauchsausweis-gewerbe/">Häufige Fragen zum Verbrauchsausweis Gewerbe</a>
</li>
<li>
<a href="/verbrauchsausweis/statistiken-zum-verbrauchsausweis-gewerbe/">Statistiken zum Verbrauchsausweis Gewerbe</a>
</li>
</ul>
</div>
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
<div
class="nav-element dropdown lg:dropdown-right"
on:click={dropdown}
on:keydown={dropdown}
on:mouseover={hover}
on:mouseleave={hoverout}
>
<a href="/bedarfsausweis/" class="nav-element-child"
>Bedarfsausweis<span class="dd-symbol-clone"></span><span
class="dd-symbol"></span
></a
>
<ul class="dropdown-content bedarfsausweis">
{#if innerWidth < 1023}
<li><a href="/bedarfsausweis/">Bedarfsausweis</a></li>
{/if}
<li><a href="/bedarfsausweis/bedarfsausweis-wohngebaeude/">Bedarfsausweis Wohngebäude</a></li>
<li><a href="/energieausweis-erstellen/bedarfsausweis-wohngebaeude/">Bedarfsausweis online erstellen</a></li>
<li><a href="/bedarfsausweis/haeufige-fragen-zum-bedarfsausweis/">Häufige Fragen zum Bedarfsausweis</a></li>
<li>
<a href="/bedarfsausweis/statistiken-zum-bedarfsausweis/">Statistiken zum Bedarfsausweis Wohngebäude</a>
</li>
<li><a href="/bedarfsausweis/bedarfsausweis-gewerbe/">Bedarfsausweis Gewerbe</a></li>
<li><a href="/angebot-anfragen/bedarfsausweis-gewerbe-anfragen">Bedarfsausweis Gewerbe anfragen</a></li>
<li>
<a href="/bedarfsausweis/haeufige-fragen-zum-bedarfsausweis-gewerbe/">Häufige Fragen zum Bedarfsausweis Gewerbe</a>
</ul>
</div>
<div class="nav-element">
<a class="no-dropdown nav-element-child" href="/sanierungsfahrplan"
>Sanierungsfahrplan</a
>
</div>
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
<div
class="nav-element dropdown lg:dropdown-right"
on:click={dropdown}
on:keydown={dropdown}
on:mouseover={hover}
on:mouseleave={hoverout}
>
<a href="/" class="nav-element-child"
>Energieausweis<span class="dd-symbol-clone"></span><span
class="dd-symbol"></span
></a
>
<ul class="dropdown-content energieausweis">
{#if innerWidth < 1023}
<li><a href="/energieausweis/">Energieausweis</a></li>
{/if}
<li><a href="/energieausweis/energieausweis-pflicht/">Energieausweis Pflicht</a></li>
<li><a href="/energieausweis/energieausweis-kosten/">Energieausweis Kosten</a></li>
<li><a href="/energieausweis/energieausweis-haus/">Energieausweis Haus</a></li>
</ul>
</div>
<!-- <div class="nav-element">
<a
class="no-dropdown nav-element-child"
href="/energieausweis-aussteller">Energieberater finden</a
>
</div> -->
<div class="nav-element bg-secondary/5 py-1 pl-2 text-xs font-bold">
FAQ & Hilfe
</div>
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
<div
class="nav-element dropdown lg:dropdown-right"
on:click={dropdown}
on:keydown={dropdown}
on:mouseover={hover}
on:mouseleave={hoverout}
>
{#if innerWidth > 1023}
<a href="/bestellprozess-energieausweis" class="nav-element-child"
>Bestellprozess Energieausweis<span class="dd-symbol-clone"
></span
><span class="dd-symbol"></span></a
>
{:else}
<a href="/bestellprozess-energieausweis" class="nav-element-child"
>Bestellprozess Energieausweis<span class="dd-symbol-clone"
></span
><span class="dd-symbol"></span></a
>
{/if}
<ul class="dropdown-content bestellprozess-energieausweis">
{#if innerWidth < 1023}
<li>
<a href="/bestellprozess-energieausweis"
>Bestellprozess Energieausweis</a
>
</li>
{/if}
<li>
<a
href="/bestellprozess-energieausweis/merkblatt-verbrauchsausweis-wohnen/"
>Merkblatt Verbrauchsausweis Wohnen</a
>
</li>
<li>
<a href="/energieausweis-erstellen/bedarfsausweis-wohngebaeude/"
>Merkblatt Bedarfsausweis Wohnen</a
>
</li>
<li>
<a href="/energieausweis-erstellen/verbrauchsausweis-gewerbe/"
>Merkblatt Verbrauchsausweis Gewerbe</a
>
</li>
</ul>
</div>
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
<div
class="nav-element dropdown lg:dropdown-right"
on:click={dropdown}
on:keydown={dropdown}
on:mouseover={hover}
on:mouseleave={hoverout}
>
<a href="/geg/" class="nav-element-child"
>Gebäudeenergiegesetz (GEG)<span class="dd-symbol-clone"></span><span
class="dd-symbol"></span
></a
>
<ul class="dropdown-content geg">
{#if innerWidth < 1023}
<li><a href="/geg/">Gebäudeenergiegesetz (GEG)</a></li>
{/if}
<li><a href="/geg/geg-2024-volltext/">GEG 2024 Volltext</a></li>
<li><a href="/geg/enev-zusammenfassung">EnEV Zusammenfassung-Archiv</a></li>
</ul>
</div>
<div class="nav-element">
<a class="no-dropdown nav-element-child" href="/faq/">FAQ</a>
</div>
<div class="nav-element">
<a class="no-dropdown nav-element-child" href="/glossar/">Glossar</a>
</div>
<!--<div class="nav-element">
<a class="no-dropdown nav-element-child lg:rounded-b-xl" href="/kundenbewertungen/"
>Kundenbewertungen</a
>
</div>
<div class="nav-element">
<a
class="no-dropdown nav-element-child lg:!rounded-b-lg xl:!rounded-b-xl"
href="/fuer-entwickler/">Für Entwickler</a
>
</div> -->
</nav>
<style lang="scss">
.dd-symbol::before {
content: "";
font-size: 0.95rem;
position: absolute;
top: 0px;
left: -7px;
animation-name: flim;
animation-duration: 2s;
animation-iteration-count: infinite;
}
.dd-symbol {
visibility: hidden;
}
.dd-symbol::after {
content: "";
font-size: 0.95rem;
position: absolute;
top: 0px;
right: -7px;
animation-name: flim;
animation-duration: 2s;
animation-delay: 1s;
animation-iteration-count: infinite;
}
@keyframes flim {
0% {
opacity: 0;
}
16.66% {
opacity: 0.25;
}
33.32% {
opacity: 0.5;
}
49.98% {
opacity: 0.75;
}
66.64% {
opacity: 0.5;
}
83.33% {
opacity: 0.25;
}
100% {
opacity: 0;
}
}
</style>

View File

@@ -0,0 +1,25 @@
<script lang="ts">
import { PRICES } from "#lib/constants.js";
import { Enums } from "#lib/client/prisma";
</script>
<div id ="cardBAGpromo"
class=" box card">
<div class="grid">
<h2>Bedarfssausweis Gewerbe</h2>
<hr class="mb-4">
<img class="w-[70%] justify-self-center !min-w-[100px] mb-[1rem]" src="/images/right-sidebar/UMBE_gewerbegebaeude.svg" alt="Gewerbe Bedarfsausweis"/>
<p class="promo tracking-tighter text-[2rem] text-gray-700 pl-6">ab<span class="promo pl-[0.2rem]">{PRICES.BedarfsausweisGewerbe[Enums.AusweisTyp.Standard]}</span></p>
<a href="./angebot-anfragen/bedarfsausweis-gewerbe-anfragen id="link-BA-promo"
class=" w-[90%] justify-self-center text-center text-white font-[700] bg-secondary rounded-md px-3 py-1 mt-2 no-underline text-[1rem]
hover:bg-primary
" >jetzt Bedarfssausweis anfragen</a>
</div>
</div>
<style lang="scss">
</style>

View File

@@ -0,0 +1,25 @@
<script lang="ts">
import { PRICES } from "#lib/constants.js";
import { Enums } from "#lib/client/prisma";
</script>
<div id ="cardBApromo"
class=" box card">
<div class="grid">
<h2>Bedarfssausweis Wohngebäude</h2>
<hr class="mb-4">
<img class="w-[70%] justify-self-center !min-w-[100px] mb-[1rem]" src="/images/right-sidebar/UMBE_wohngebaeude.svg" alt="Wohnhaus Bedarfsausweis"/>
<p class="promo tracking-tighter text-[2rem] text-gray-700 pl-6">ab<span class="promo pl-[0.2rem]">{PRICES.BedarfsausweisWohnen[Enums.AusweisTyp.Standard]}</span></p>
<a href="/energieausweis-erstellen/bedarfsausweis-wohngebaeude/" id="link-BA-promo"
class=" w-[90%] justify-self-center text-center text-white font-[700] bg-secondary rounded-md px-3 py-1 mt-2 no-underline text-[1rem]
hover:bg-primary
" >jetzt Bedarfssausweis erstellen</a>
</div>
</div>
<style lang="scss">
</style>

View File

@@ -0,0 +1,43 @@
<script>
import { PRICES } from "#lib/constants";
import { Enums } from "#lib/client/prisma";
</script>
<div id ="cardPriceinfo" class="box card hidden lg:block">
<h2>Was wird der Energieausweis kosten?</h2>
<div>Verbrauchsausweis Wohngebäude</div>
<div>ab&nbsp;<span class="price">{PRICES.VerbrauchsausweisWohnen[Enums.AusweisTyp.Standard]}€</span>&nbsp;inkl.&nbsp;MwSt.</div>
<hr class="trenner">
<div>Bedarfsausweis Wohngebäude</div>
<div>ab&nbsp;<span class="price">{PRICES.BedarfsausweisWohnen[Enums.AusweisTyp.Standard]}€</span>&nbsp;inkl.&nbsp;MwSt.</div>
<hr class="trenner">
<div>Verbrauchsausweis Gewerbe</div>
<div>ab&nbsp;<span class="price">{PRICES.VerbrauchsausweisGewerbe[Enums.AusweisTyp.Standard]}€</span>&nbsp;inkl.&nbsp;MwSt.</div>
<hr class="trenner">
<div>Bedarfsausweis Gewerbe</div>
<div>ab&nbsp;<span class="price">{PRICES.BedarfsausweisGewerbe[Enums.AusweisTyp.Standard]}€</span>&nbsp;inkl.&nbsp;MwSt.</div>
<hr class="trenner">
<div>GEG-Nachweis Wohngebäude</div>
<div>ab&nbsp;<span class="price">{PRICES.GEGNachweisWohnen[Enums.AusweisTyp.Standard]}€</span>&nbsp;inkl.&nbsp;MwSt.</div>
<hr class="trenner">
<div>GEG-Nachweis Gewerbe</div>
<div>ab&nbsp;<span class="price">{PRICES.GEGNachweisGewerbe[Enums.AusweisTyp.Standard]}€</span>&nbsp;inkl.&nbsp;MwSt.</div>
<hr class="mt-2">
</div>
<style lang="postcss">
.trenner{@apply my-2}
.price{@apply font-bold}
</style>

View File

@@ -0,0 +1,26 @@
<script lang="ts">
import { PRICES } from "#lib/constants.js";
import { Enums } from "#lib/client/prisma";
</script>
<div id ="cardVAGpromo"
class=" box card">
<div class="grid">
<h2>Verbrauchsausweis Gewerbe</h2>
<hr class="mb-4">
<img class="w-[70%] justify-self-center !min-w-[100px]" src="/images/right-sidebar/UMBE_gewerbegebaeude.svg" alt="Gewerbe Verbrauchsausweis"/>
<p class="promo tracking-tighter text-[2rem] text-gray-700 pl-6">ab<span class="promo pl-2">{PRICES.VerbrauchsausweisGewerbe[Enums.AusweisTyp.Standard]}</span></p>
<a href="./energieausweis-erstellen/verbrauchsausweis-gewerbe/" id="link-VA-promo"
class=" w-[90%] justify-self-center text-center text-white font-[700] bg-gradient-to-br from-secondary to-secondary-grad rounded-md px-3 py-1 mt-2 no-underline text-[1rem]
hover:bg-primary
" >Verbrauchsausweis sofort&nbsp;erstellen</a>
</div>
</div>
<style lang="scss">
</style>

View File

@@ -0,0 +1,34 @@
<script lang="ts">
import { PRICES } from "#lib/constants.js";
import { Enums } from "#lib/client/prisma";
</script>
<div id="card-VA-promo" class="box card">
<div class="grid">
<h2>Verbrauchsausweis Wohngebäude</h2>
<hr class="mb-4" />
<img
class="w-[70%] justify-self-center !min-w-[100px] mb-[1rem]"
src="/images/right-sidebar/UMBE_wohngebaeude.svg"
alt="Wohnhaus Verbrauchsausweis"
/>
<p class="promo tracking-tighter text-[2rem] text-gray-700 pl-6">
ab<span class="promo pl-2">{PRICES.VerbrauchsausweisWohnen[Enums.AusweisTyp.Standard]}</span
>
</p>
<a
href="./energieausweis-erstellen/verbrauchsausweis-wohngebaeude/"
id="link-VA-promo"
class=" w-[90%] justify-self-center text-center text-white font-[700] bg-secondary rounded-md px-3 py-1 mt-2 no-underline text-[1rem]
hover:bg-primary
">jetzt Verbrauchsausweis erstellen</a
>
</div>
</div>
<style lang="scss">
</style>

View File

@@ -177,10 +177,7 @@ $: standardXL =
<WidgetCardTemplate
name="Verbrauchsausweis Wohngebäude"
price = {PRICES.VerbrauchsausweisWohnen[standardXL ? Enums.AusweisTyp.standardXL : Enums.AusweisTyp.Standard]}
price1 = {PRICES.VerbrauchsausweisWohnen[standardXL ? Enums.AusweisTyp.BeratungXL : Enums.AusweisTyp.Beratung]}
price2 = {PRICES.VerbrauchsausweisWohnen[standardXL ? Enums.AusweisTyp.OfflineXL : Enums.AusweisTyp.Offline]}
price={PRICES.VerbrauchsausweisWohnen[Enums.AusweisTyp.Standard] + (standardXL ? 10 : 0)}
src={'https://online-energieausweis.org/images/partner/'+partner+'/wohngebaeude.svg'}
alt="Wohnhaus Verbrauchsausweis"
variant="einfach"
@@ -193,11 +190,8 @@ $: standardXL =
["Ungenau durch individuelles Heizverhalten.", false],
["Wird nicht immer bei den Banken akzeptiert.", false]
]}
href_buy1={`https://online-energieausweis.org/${partner}/energieausweis-erstellen/verbrauchsausweis-wohngebaeude/${standardXL ? '?ausweistyp=standardXL' : ''}`}
href_buy2={`https://online-energieausweis.org/${partner}/energieausweis-erstellen/verbrauchsausweis-wohngebaeude/${standardXL ? '?ausweistyp=BeratungXL' : '?ausweistyp=Beratung'}`}
href_buy3={`https://online-energieausweis.org/${partner}/energieausweis-erstellen/verbrauchsausweis-wohngebaeude/${standardXL ? '?ausweistyp=OfflineXL' : '?ausweistyp=Offline'}`}
href_buy={"https://online-energieausweis.org/"+partner+"/energieausweis-erstellen/verbrauchsausweis-wohngebaeude/"}{standardXL ? '?ausweistyp=standardXL' : ''}
href_overview={"https://online-energieausweis.org/"+partner+"/energieausweis-erstellen/verbrauchsausweis-wohngebaeude/produkt-uebersicht/"}{standardXL ? '?ausweistyp=standardXL' : ''}
></WidgetCardTemplate>
{/if}
@@ -206,9 +200,7 @@ $: standardXL =
<WidgetCardTemplate
name="Bedarfsausweis Wohngebäude"
price = {PRICES.BedarfsausweisWohnen[standardXL ? Enums.AusweisTyp.standardXL : Enums.AusweisTyp.Standard]}
price1 = {PRICES.BedarfsausweisWohnen[standardXL ? Enums.AusweisTyp.BeratungXL : Enums.AusweisTyp.Beratung]}
price2 = {PRICES.BedarfsausweisWohnen[standardXL ? Enums.AusweisTyp.OfflineXL : Enums.AusweisTyp.Offline]}
price={PRICES.BedarfsausweisWohnen[Enums.AusweisTyp.Standard] + (standardXL ? 25 : 0)}
src={'https://online-energieausweis.org/images/partner/'+partner+'/wohngebaeude.svg'}
alt="Wohnhaus Bedarfsausweis"
variant="fundiert"
@@ -221,11 +213,8 @@ $: standardXL =
["Kann als Grundlage für den ISFP dienen.", true],
["Objektivere Berechnungsmethode nach DIN 18599.", true],
]}
href_buy1={`https://online-energieausweis.org/${partner}/energieausweis-erstellen/bedarfsausweis-wohngebaeude/${standardXL ? '?ausweistyp=standardXL' : ''}`}
href_buy2={`https://online-energieausweis.org/${partner}/energieausweis-erstellen/bedarfsausweis-wohngebaeude/${standardXL ? '?ausweistyp=BeratungXL' : '?ausweistyp=Beratung'}`}
href_buy3={`https://online-energieausweis.org/${partner}/energieausweis-erstellen/bedarfsausweis-wohngebaeude/${standardXL ? '?ausweistyp=OfflineXL' : '?ausweistyp=Offline'}`}
href_buy={"https://online-energieausweis.org/"+partner+"/energieausweis-erstellen/bedarfsausweis-wohngebaeude/"}{standardXL ? '?ausweistyp=standardXL' : ''}
href_overview={"https://online-energieausweis.org/"+partner+"/energieausweis-erstellen/bedarfsausweis-wohngebaeude/produkt-uebersicht"}{standardXL ? '?ausweistyp=standardXL' : ''}
></WidgetCardTemplate>
{/if}
@@ -234,9 +223,7 @@ $: standardXL =
<WidgetCardTemplate
name="Verbrauchsausweis Gewerbegebäude"
price = {PRICES.VerbrauchsausweisGewerbe[standardXL ? Enums.AusweisTyp.standardXL : Enums.AusweisTyp.Standard]}
price1 = {PRICES.VerbrauchsausweisGewerbe[standardXL ? Enums.AusweisTyp.BeratungXL : Enums.AusweisTyp.Beratung]}
price2 = {PRICES.VerbrauchsausweisGewerbe[standardXL ? Enums.AusweisTyp.OfflineXL : Enums.AusweisTyp.Offline]}
price={PRICES.VerbrauchsausweisGewerbe[Enums.AusweisTyp.Standard] + (standardXL ? 15 : 0)}
src={'https://online-energieausweis.org/images/partner/'+partner+'/gewerbegebaeude.svg'}
alt="Gewerbe Verbrauchsausweis"
variant="einfach"
@@ -250,10 +237,8 @@ $: standardXL =
["Wird nicht immer bei den Banken akzeptiert.", false],
["Ungenau durch individuelles Heizverhalten", false],
]}
href_buy1={`https://online-energieausweis.org/${partner}/energieausweis-erstellen/verbrauchsausweis-gewerbe/${standardXL ? '?ausweistyp=standardXL' : ''}`}
href_buy2={`https://online-energieausweis.org/${partner}/energieausweis-erstellen/verbrauchsausweis-gewerbe/${standardXL ? '?ausweistyp=BeratungXL' : '?ausweistyp=Beratung'}`}
href_buy3={`https://online-energieausweis.org/${partner}/energieausweis-erstellen/verbrauchsausweis-gewerbe/${standardXL ? '?ausweistyp=OfflineXL' : '?ausweistyp=Offline'}`}
href_buy={"https://online-energieausweis.org/"+partner+"/energieausweis-erstellen/verbrauchsausweis-gewerbe/"}{standardXL ? '?ausweistyp=standardXL' : ''}
href_overview={"https://online-energieausweis.org/"+partner+"/energieausweis-erstellen/verbrauchsausweis-gewerbe/produkt-uebersicht/"}{standardXL ? '?ausweistyp=standardXL' : ''}
></WidgetCardTemplate>
{/if}
@@ -262,9 +247,7 @@ $: standardXL =
<WidgetCardTemplate
name="Bedarfsausweis Gewerbegebäude"
price = {PRICES.BedarfsausweisGewerbe[standardXL ? Enums.AusweisTyp.standardXL : Enums.AusweisTyp.Standard]}
price1 = {PRICES.BedarfsausweisGewerbe[standardXL ? Enums.AusweisTyp.BeratungXL : Enums.AusweisTyp.Beratung]}
price2 = {PRICES.BedarfsausweisGewerbe[standardXL ? Enums.AusweisTyp.OfflineXL : Enums.AusweisTyp.Offline]}
price={PRICES.BedarfsausweisGewerbe[Enums.AusweisTyp.Standard]}
src={'https://online-energieausweis.org/images/partner/'+partner+'/gewerbegebaeude.svg'}
alt="Gewerbe Bedarfsausweis"
variant="fundiert"
@@ -278,10 +261,8 @@ $: standardXL =
["Objektiveres, besser vergleichbares Ergebnis.", true],
["Zulässig bei Leerstand oder fehlenden Verbräuchen", true],
]}
href_buy1={`https://online-energieausweis.org/${partner}/angebot-anfragen/bedarfsausweis-gewerbe-anfragen/${standardXL ? '?ausweistyp=standardXL' : ''}`}
href_buy2={`https://online-energieausweis.org/${partner}/angebot-anfragen/bedarfsausweis-gewerbe-anfragen/${standardXL ? '?ausweistyp=BeratungXL' : '?ausweistyp=Beratung'}`}
href_buy={"https://online-energieausweis.org/"+partner+"/angebot-anfragen/bedarfsausweis-gewerbe-anfragen/"}
href_overview={"https://online-energieausweis.org/"+partner+"/angebot-anfragen/bedarfsausweis-gewerbe-anfragen/produkt-uebersicht/"}
></WidgetCardTemplate>
{/if}
@@ -290,9 +271,7 @@ $: standardXL =
<WidgetCardTemplate
name="GEG-Nachweis Wohngebäude"
price = {PRICES.GEGNachweisWohnen[standardXL ? Enums.AusweisTyp.standardXL : Enums.AusweisTyp.Standard]}
price1 = {PRICES.GEGNachweisWohnen[standardXL ? Enums.AusweisTyp.BeratungXL : Enums.AusweisTyp.Beratung]}
price2 = {PRICES.GEGNachweisWohnen[standardXL ? Enums.AusweisTyp.OfflineXL : Enums.AusweisTyp.Offline]}
price={PRICES.GEGNachweisWohnen[Enums.AusweisTyp.Standard]}
src={'https://online-energieausweis.org/images/partner/'+partner+'/wohngebaeude.svg'}
alt="GEG-Nachweis-Wohnen"
variant="Bauvorlage"
@@ -306,10 +285,8 @@ $: standardXL =
["Berechnung und Bilanzierung nach aktueller DIN 18599.", true],
["Zonierung und Erstellung eines 3D Gebäudemodells.", true],
]}
href_buy1={`https://online-energieausweis.org/${partner}/angebot-anfragen/geg-nachweis-wohnen-anfragen/${standardXL ? '?ausweistyp=standardXL' : ''}`}
href_buy2={`https://online-energieausweis.org/${partner}/angebot-anfragen/geg-nachweis-wohnen-anfragen/${standardXL ? '?ausweistyp=BeratungXL' : '?ausweistyp=Beratung'}`}
href_buy={"https://online-energieausweis.org/"+partner+"/angebot-anfragen/geg-nachweis-wohnen-anfragen/"}
href_overview={"https://online-energieausweis.org/"+partner+"/angebot-anfragen/geg-nachweis-wohnen-anfragen/produkt-uebersicht/"}
></WidgetCardTemplate>
@@ -319,9 +296,7 @@ $: standardXL =
<WidgetCardTemplate
name="GEG-Nachweis Gewerbegebäude"
price = {PRICES.GEGNachweisGewerbe[standardXL ? Enums.AusweisTyp.standardXL : Enums.AusweisTyp.Standard]}
price1 = {PRICES.GEGNachweisGewerbe[standardXL ? Enums.AusweisTyp.BeratungXL : Enums.AusweisTyp.Beratung]}
price2 = {PRICES.GEGNachweisGewerbe[standardXL ? Enums.AusweisTyp.OfflineXL : Enums.AusweisTyp.Offline]}
price={PRICES.GEGNachweisGewerbe[Enums.AusweisTyp.Standard]}
src={'https://online-energieausweis.org/images/partner/'+partner+'/gewerbegebaeude.svg'}
alt="GEG-Nachweis-Gewerbe"
variant="Bauvorlage"
@@ -335,10 +310,8 @@ $: standardXL =
["Berechnung und Bilanzierung nach aktueller DIN 18599.", true],
["Mehrzonenmodell inkl. Erstellung eines 3D Gebäudemodells.", true],
]}
href_buy1={`https://online-energieausweis.org/${partner}/angebot-anfragen/geg-nachweis-gewerbe-anfragen/${standardXL ? '?ausweistyp=standardXL' : ''}`}
href_buy2={`https://online-energieausweis.org/${partner}/angebot-anfragen/geg-nachweis-gewerbe-anfragen/${standardXL ? '?ausweistyp=BeratungXL' : '?ausweistyp=Beratung'}`}
href_buy={"https://online-energieausweis.org/"+partner+"/angebot-anfragen/geg-nachweis-gewerbe-anfragen/"}
href_overview={"https://online-energieausweis.org/"+partner+"/angebot-anfragen/geg-nachweis-gewerbe-anfragen/produkt-uebersicht/"}
></WidgetCardTemplate>
{/if}

View File

@@ -1,34 +1,35 @@
<script lang="ts">
import { fade } from "svelte/transition";
export let price: number;
export let price1: number;
export let price2: number;
export let name: string;
export let variant: string;
export let services: [string, boolean][];
export let href_buy1: string;
export let href_buy2: string;
export let href_buy3: string = "";
export let href_buy: string;
export let href_overview: string;
export let src: string;
export let alt: string;
export let empfehlung: string;
export let cta: string;
</script>
<div class="produktbox" transition:fade={{ duration: 0 }}>
<div
class="produktbox"
transition:fade={{ duration: 0 }}
>
{#if empfehlung === "ja"}
<div class="empfehlung" aria-label="Empfohlenes Produkt">
Empfehlung
</div>
<div class="empfehlung" aria-label="Empfohlenes Produkt">Empfehlung</div>
{/if}
<h2 class="titel sm:mb-2">{name}</h2>
<div class="sumCent">
<div class="variante">{variant}</div>
<img class="image" {src} {alt} />
<img
class="image"
{src}
{alt}
/>
<div class="">
<p class="price">
ab {price}
@@ -37,103 +38,67 @@
</div>
<hr class="col-span-2 w-full md:w-[50%] md:m-auto bg-[#ffcc00] h-[2px]" />
<div class="sumRows forServices">
{#each services as [service, check]}
<div class="services">
<span>{@html service}</span>
<span class={check ? "check" : "check-no"}
>{check ? "✔" : "✘"}</span
>
</div>
{/each}
</div>
<hr class="col-span-2 w-full md:w-[50%] md:m-auto bg-[#ffcc00] h-[2px]" />
<div class="sumCent buttoncols"
class:md:grid-cols-3={href_buy3}
class:md:grid-cols-2={!href_buy3}>
<div class="sumCent buttoncols">
<a
href={href_buy1}
href={href_buy}
class="buttoncol"
aria-label="Jetzt {name} kaufen"
target="_blank"
>mach selbst (<span class="inside-price">{price}</span>&nbsp;€)
>{cta}
</a>
<a
href={href_buy2}
href={href_overview}
class="buttoncol"
aria-label="{name} Produkt-Übersicht"
target="_blank"
>wir helfen (<span class="inside-price">{price1}</span>&nbsp;€)
</a>
>Produkt-Übersicht</a
>
</div>
<div class="sumRows forServices">
{#each services as [service, check]}
<div class="services">
<span>{@html service}</span>
<span class={check ? "check" : "check-no"}>{check ? "✔" : "✘"}</span>
</div>
{/each}
{#if href_buy3}
<a
href={href_buy3}
class="buttoncol"
aria-label="{name} Produkt-Übersicht"
target="_blank"
>wir machen (<span class="inside-price">{price2}</span>&nbsp;€)
</a>
{/if}
</div>
</div>
<style lang="postcss">
.produktbox {
@apply grid grid-cols-subgrid col-span-2 grid-rows-subgrid row-span-3 md:row-span-12 bg-black/5 rounded-lg
.produktbox{@apply grid grid-cols-subgrid col-span-2 grid-rows-subgrid row-span-3 md:row-span-12 bg-black/5 rounded-lg
px-2 py-2 mt-5;
box-shadow:2px 2px 8px rgba(0,0,0,0.25);
.sumCent {
@apply justify-self-center col-span-2;
}
.sumRows {
@apply hidden sm:grid grid-rows-subgrid row-span-5 items-center;
}
.forServices {
@apply grid-rows-subgrid row-span-5 items-center col-span-2 justify-center px-6;
}
.sumCent{@apply justify-self-center col-span-2}
.sumRows{@apply hidden sm:grid grid-rows-subgrid row-span-5 items-center}
.forServices{@apply grid-rows-subgrid row-span-5 items-center col-span-2 justify-center px-6}
.image {
@apply w-[75%] mx-auto
md:w-[75%] md:pl-0;
}
.image{@apply w-[75%] mx-auto
md:w-[75%] md:pl-0}
.buttoncols {
@apply grid grid-cols-1 gap-x-4 w-full my-4
md:grid-cols-3 md:w-[auto];
}
.buttoncols{@apply grid grid-cols-1 gap-x-4 w-full mb-4
md:grid-cols-2 md:w-[auto]}
.buttoncol {
@apply mt-2 md:mt-0 text-center text-black bg-[#ffcc00] rounded-md px-3 py-1 no-underline
hover:bg-[#222222] hover:text-white;
}
.inside-price {
@apply font-bold;
}
.buttoncol{@apply mt-2 md:mt-0 text-center text-black bg-[#ffcc00] rounded-md px-3 py-1 no-underline
hover:bg-[#222222] hover:text-white}
.price {
@apply tracking-tighter text-[2rem] text-[#222222] pl-12 m-0 -mt-7 text-nowrap text-left;
font-family: "Antique Olive Compact bold";
}
.price{@apply tracking-tighter text-[2rem] text-[#222222] pl-12 m-0 -mt-7 text-nowrap text-left;
font-family: "Antique Olive Compact bold";}
.titel {
@apply col-span-2 text-center [font-size:_clamp(20px,2.5vw,28px)];
}
.empfehlung {
@apply -mt-4 absolute justify-self-end rounded-md bg-red-700 text-white w-fit h-fit px-2 py-1 rotate-1 text-[0.65rem] ring-4 ring-white mr-6;
}
.titel {@apply col-span-2 text-center [font-size:_clamp(20px,2.5vw,28px)]}
.empfehlung{@apply -mt-4 absolute justify-self-end rounded-md bg-red-700 text-white w-fit h-fit px-2 py-1 rotate-1 text-[0.65rem] ring-4 ring-white mr-6}
.variante {
@apply w-fit italic col-span-2 -mt-2 -mb-4 text-[1rem] text-[#222222] justify-self-start ring-2 ring-[#ffcc00] rounded-md pl-[4px] pr-[6px] py-[0px];
}
.services {
@apply hidden text-start py-1 md:grid grid-rows-subgrid row-span-1 items-center md:grid-cols-[1fr_50px];
@apply hidden text-start py-1 md:grid grid-rows-subgrid row-span-1 items-center md:grid-cols-[1fr_50px]
}
.services:not(:last-child) {
@apply border-b-[1px] border-gray-200;
@@ -144,5 +109,7 @@ hover:bg-[#222222] hover:text-white;
.check-no {
@apply justify-self-end self-center font-bold text-red-700;
}
}
</style>

View File

@@ -2,11 +2,6 @@ import { prisma } from "#lib/server/prisma.js";
import moment from "moment";
import csv from "csvtojson"
if (!process.env.prev_restart_delay && process.env.cron_restart) {
console.log('skipping initial launch....');
process.exit(0);
}
// Als erstes schauen wir, welches das letzte Jahr ist, für das wir einen Verbrauchsausweis haben.
// Das machen wir, indem wir die Ausweise nach Jahr und Monat sortieren und dann den letzten Eintrag nehmen.
const newestDate = await prisma.klimafaktoren.findFirst({

View File

@@ -26,7 +26,7 @@ describe("Verbrauchsausweis für Wohngebäude bearbeiten", async () => {
}).then((ausweis: VerbrauchsausweisWohnen & { benutzer: Benutzer, aufnahme: Aufnahme & { objekt: Objekt }, rechnung: Rechnung | null }) => {
cy.login("user@ib-cornelsen.de", "passwort");
cy.visit(`/energieausweis-erstellen/verbrauchsausweis-wohngebaeude?ausweis_id=${ausweis.id}`);
cy.visit(`/energieausweis-erstellen/verbrauchsausweis-wohngebaeude?id=${ausweis.id}`);
cy.wait(2000);

View File

@@ -19,7 +19,6 @@ export type Lueftungskonzept = (typeof Lueftungskonzept)[keyof typeof Lueftungsk
export const BenutzerRolle = {
USER: "USER",
ADMIN: "ADMIN",
RESELLER: "RESELLER",
} as const;
export type BenutzerRolle = (typeof BenutzerRolle)[keyof typeof BenutzerRolle];

View File

@@ -1,5 +1,5 @@
import * as z from "zod"
import { Ausstellgrund, AusweisTyp, Ausweisart } from "@prisma/client"
import { Ausstellgrund, AusweisTyp } from "@prisma/client"
export const BedarfsausweisGewerbeSchema = z.object({
id: z.string(),
@@ -20,7 +20,6 @@ export const BedarfsausweisGewerbeSchema = z.object({
bauteilaktivierung: z.boolean().nullish(),
klimatisierung: z.boolean().nullish(),
nachweistyp: z.nativeEnum(AusweisTyp),
ausweisart: z.nativeEnum(Ausweisart),
created_at: z.date(),
updated_at: z.date(),
benutzer_id: z.string().describe("Die ID des Benutzers, welchem dieser Ausweis gehört").nullish(),

View File

@@ -1,5 +1,5 @@
import * as z from "zod"
import { Ausstellgrund, AusweisTyp, Ausweisart } from "@prisma/client"
import { Ausstellgrund, AusweisTyp } from "@prisma/client"
export const BedarfsausweisWohnenSchema = z.object({
id: z.string(),
@@ -86,7 +86,6 @@ export const BedarfsausweisWohnenSchema = z.object({
pruefpunkt_geometrie: z.boolean().nullish(),
pruefpunkt_fenster: z.boolean().nullish(),
ausweistyp: z.nativeEnum(AusweisTyp),
ausweisart: z.nativeEnum(Ausweisart),
rechnung_id: z.string().nullish(),
aufnahme_id: z.string().describe("ID der korrespondierenden Gebäudeaufnahme"),
})

View File

@@ -13,11 +13,10 @@ export const BenutzerSchema = z.object({
ort: z.string().nullish(),
adresse: z.string().nullish(),
telefon: z.string().nullish(),
empfaenger: z.string().nullish(),
anrede: z.string().nullish(),
rolle: z.nativeEnum(BenutzerRolle),
firma: z.string().nullish(),
lex_office_id: z.string().nullish(),
partner_code: z.string().nullish(),
verified: z.boolean(),
created_at: z.date(),
updated_at: z.date(),

Some files were not shown because too many files have changed in this diff Show More