From fdc2349de1d8ceab13ceb21bfbc882772fc7319e Mon Sep 17 00:00:00 2001 From: Dilan Gilluly Date: Fri, 3 Oct 2025 18:02:40 -0400 Subject: [PATCH] some deployments worked out --- api/Dockerfile | 5 +- api/routers/tickets.py | 2 +- db/Dockerfile | 2 +- deployment/client/docker_client-launch.sh | 14 ++ deployment/client/podman_client-launch.sh | 14 ++ deployment/remote_server/compose.yml | 19 +- .../remote_server/docker_generate-key.sh | 5 + deployment/remote_server/docker_list-keys.sh | 1 + .../remote_server/docker_start-server.sh | 8 + .../remote_server/podman_generate-key.sh | 5 + deployment/remote_server/podman_list-keys.sh | 1 + .../remote_server/podman_start-server.sh | 8 + deployment/remote_server_secure/compose.yml | 36 +++ .../docker_generate-key.sh | 5 + .../remote_server_secure/docker_list-keys.sh | 1 + .../docker_start-server.sh | 12 + .../remote_server_secure/nginx/default.conf | 16 ++ .../podman_generate-key.sh | 5 + .../remote_server_secure/podman_list-keys.sh | 1 + .../podman_start-server.sh | 12 + webapp/Dockerfile | 14 +- webapp/package-lock.json | 220 +++++++++--------- webapp/src/app.html | 1 + webapp/static/icons/tam3x192.png | Bin 0 -> 7175 bytes webapp/static/icons/tam3x512.png | Bin 0 -> 20384 bytes webapp/static/manifest.json | 20 ++ 26 files changed, 286 insertions(+), 141 deletions(-) create mode 100644 deployment/client/docker_client-launch.sh create mode 100755 deployment/client/podman_client-launch.sh create mode 100755 deployment/remote_server/docker_generate-key.sh create mode 100755 deployment/remote_server/docker_list-keys.sh create mode 100755 deployment/remote_server/docker_start-server.sh create mode 100755 deployment/remote_server/podman_generate-key.sh create mode 100755 deployment/remote_server/podman_list-keys.sh create mode 100755 deployment/remote_server/podman_start-server.sh create mode 100644 deployment/remote_server_secure/compose.yml create mode 100755 deployment/remote_server_secure/docker_generate-key.sh create mode 100755 deployment/remote_server_secure/docker_list-keys.sh create mode 100755 deployment/remote_server_secure/docker_start-server.sh create mode 100644 deployment/remote_server_secure/nginx/default.conf create mode 100755 deployment/remote_server_secure/podman_generate-key.sh create mode 100755 deployment/remote_server_secure/podman_list-keys.sh create mode 100755 deployment/remote_server_secure/podman_start-server.sh create mode 100644 webapp/static/icons/tam3x192.png create mode 100644 webapp/static/icons/tam3x512.png create mode 100644 webapp/static/manifest.json diff --git a/api/Dockerfile b/api/Dockerfile index 5ae4dfe..c8bd8f5 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3 +FROM docker.io/python:3-slim WORKDIR /app COPY requirements.txt requirements.txt @@ -7,7 +7,4 @@ COPY . . EXPOSE 80 -HEALTHCHECK --interval=10s --timeout=5s --retries=3 --start-period=10s \ - CMD python healthcheck.py http://localhost/api/ || exit 1 - CMD ["fastapi", "run", "main.py", "--port", "80", "--proxy-headers"] \ No newline at end of file diff --git a/api/routers/tickets.py b/api/routers/tickets.py index 6739efa..fcd68ac 100644 --- a/api/routers/tickets.py +++ b/api/routers/tickets.py @@ -23,7 +23,7 @@ def get_prefix_ticket_one(api_key: str, prefix: str, t_id: int) -> Ticket: raise bad_key return TicketRepo().get_prefix_one(prefix, t_id) -@ticket_router.get("/{prefix}/{t_from}/{t_to}") +@ticket_router.get("/{prefix}/{t_from}/{t_to}/") def get_prefix_ticket_range(api_key: str, prefix: str, t_from: int, t_to: int) -> list[Ticket]: if not ApiKeyRepo().check_api(api_key): raise bad_key diff --git a/db/Dockerfile b/db/Dockerfile index cb4ee5b..90b660b 100644 --- a/db/Dockerfile +++ b/db/Dockerfile @@ -1,3 +1,3 @@ -FROM mariadb:lts +FROM docker.io/mariadb:lts COPY schema.sql /docker-entrypoint-initdb.d/tam3-schema.sql \ No newline at end of file diff --git a/deployment/client/docker_client-launch.sh b/deployment/client/docker_client-launch.sh new file mode 100644 index 0000000..148289d --- /dev/null +++ b/deployment/client/docker_client-launch.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +mkdir -p ~/.config/TAM3/data + +read -p "Do you want to connect to a remote server? [y or n] " rmserver +read -p "Enter the short venue name: " venuename + +if [ $rmserver = "y" -o $rmserver = "Y" ]; then +read -p "Enter the protocol, server host/ip, and port like "https://ip_or_host:8443" w/o quotes: " serveraddr +read -p "Paste in (Ctrl + Shift + V on most terminal emulators) or enter the api key you generated for your server: " serverapi +docker run -d --name=tam3-webclient --restart=always -v ~/.config/TAM3/data:/data:rw,z -e TAM3_REMOTE=$serveraddr -e TAM3_REMOTE_KEY=$serverapi -e NODE_TLS_REJECT_UNAUTHORIZED=0 -e PUBLIC_TAM3_VENUE="$venuename" -p 127.0.0.1:8300:3000 docker.io/dbob16/tam3-webclient:0.1.0 +else +docker run -d --name=tam3-webclient --restart=always -v ~/.config/TAM3/data:/data:rw,z -e PUBLIC_TAM3_VENUE="$venuename" -p 127.0.0.1:8300:3000 docker.io/dbob16/tam3-webclient:0.1.0 +fi \ No newline at end of file diff --git a/deployment/client/podman_client-launch.sh b/deployment/client/podman_client-launch.sh new file mode 100755 index 0000000..65613bd --- /dev/null +++ b/deployment/client/podman_client-launch.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +mkdir -p ~/.config/TAM3/data + +read -p "Do you want to connect to a remote server? [y or n] " rmserver +read -p "Enter the short venue name: " venuename + +if [ $rmserver = "y" -o $rmserver = "Y" ]; then +read -p "Enter the protocol, server host/ip, and port like "https://ip_or_host:8443" w/o quotes: " serveraddr +read -p "Paste in (Ctrl + Shift + V on most terminal emulators) or enter the api key you generated for your server: " serverapi +podman run -d --name=tam3-webclient --restart=always -v ~/.config/TAM3/data:/data:rw,z -e TAM3_REMOTE=$serveraddr -e TAM3_REMOTE_KEY=$serverapi -e NODE_TLS_REJECT_UNAUTHORIZED=0 -e PUBLIC_TAM3_VENUE="$venuename" -p 127.0.0.1:8300:3000 docker.io/dbob16/tam3-webclient:0.1.0 +else +podman run -d --name=tam3-webclient --restart=always -v ~/.config/TAM3/data:/data:rw,z -e PUBLIC_TAM3_VENUE="$venuename" -p 127.0.0.1:8300:3000 docker.io/dbob16/tam3-webclient:0.1.0 +fi \ No newline at end of file diff --git a/deployment/remote_server/compose.yml b/deployment/remote_server/compose.yml index b505323..d70f492 100644 --- a/deployment/remote_server/compose.yml +++ b/deployment/remote_server/compose.yml @@ -1,6 +1,6 @@ services: tam3-db: - image: dbob16/tam3-db:0.1.0 + image: docker.io/dbob16/tam3-db:0.1.0 restart: always environment: MARIADB_RANDOM_ROOT_PASSWORD: 1 @@ -8,7 +8,7 @@ services: MARIADB_USER: tam3 MARIADB_PASSWORD: ${DB_PASSWORD} volumes: - - "${DB_LOCATION}:/var/lib/mysql" + - "${DB_LOCATION}:/var/lib/mysql:z" healthcheck: test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] start_period: 10s @@ -16,7 +16,7 @@ services: timeout: 5s retries: 3 tam3-api: - image: dbob16/tam3-api:0.1.0 + image: docker.io/dbob16/tam3-api:0.1.0 restart: always environment: TAM3_DATA_PATH: /data @@ -25,15 +25,4 @@ services: TAM3_DB_USER: tam3 TAM3_DB_PASSWD: ${DB_PASSWORD} ports: - - "8000:80" - autoheal: - deploy: - replicas: 1 - environment: - AUTOHEAL_CONTAINER_LABEL: autoheal-app - image: willfarrell/autoheal:latest - network_mode: none - restart: always - volumes: - - /etc/localtime:/etc/localtime:ro - - /var/run/docker.sock:/var/run/docker.sock \ No newline at end of file + - "8000:80" \ No newline at end of file diff --git a/deployment/remote_server/docker_generate-key.sh b/deployment/remote_server/docker_generate-key.sh new file mode 100755 index 0000000..46cda81 --- /dev/null +++ b/deployment/remote_server/docker_generate-key.sh @@ -0,0 +1,5 @@ +read -p "Enter the name of the computer you plan to use the key on: " pcname + +docker compose exec tam3-api /app/key.py generate $pcname + +echo "Note the key above this line. You can use that for the computer." \ No newline at end of file diff --git a/deployment/remote_server/docker_list-keys.sh b/deployment/remote_server/docker_list-keys.sh new file mode 100755 index 0000000..4b90084 --- /dev/null +++ b/deployment/remote_server/docker_list-keys.sh @@ -0,0 +1 @@ +docker compose exec tam3-api /app/key.py list \ No newline at end of file diff --git a/deployment/remote_server/docker_start-server.sh b/deployment/remote_server/docker_start-server.sh new file mode 100755 index 0000000..b7d726c --- /dev/null +++ b/deployment/remote_server/docker_start-server.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +gen_password=$(cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 32) + +echo "DB_LOCATION=./tam3-db" > .env +echo "DB_PASSWORD=${gen_password}" >> .env + +docker compose up -d \ No newline at end of file diff --git a/deployment/remote_server/podman_generate-key.sh b/deployment/remote_server/podman_generate-key.sh new file mode 100755 index 0000000..d4bdf32 --- /dev/null +++ b/deployment/remote_server/podman_generate-key.sh @@ -0,0 +1,5 @@ +read -p "Enter the name of the computer you plan to use the key on: " pcname + +podman compose exec tam3-api /app/key.py generate $pcname + +echo "Note the key above this line. You can use that for the computer." \ No newline at end of file diff --git a/deployment/remote_server/podman_list-keys.sh b/deployment/remote_server/podman_list-keys.sh new file mode 100755 index 0000000..a1fc2cd --- /dev/null +++ b/deployment/remote_server/podman_list-keys.sh @@ -0,0 +1 @@ +podman compose exec tam3-api /app/key.py list \ No newline at end of file diff --git a/deployment/remote_server/podman_start-server.sh b/deployment/remote_server/podman_start-server.sh new file mode 100755 index 0000000..de76718 --- /dev/null +++ b/deployment/remote_server/podman_start-server.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +gen_password=$(cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 32) + +echo "DB_LOCATION=./tam3-db" > .env +echo "DB_PASSWORD=${gen_password}" >> .env + +podman compose up -d \ No newline at end of file diff --git a/deployment/remote_server_secure/compose.yml b/deployment/remote_server_secure/compose.yml new file mode 100644 index 0000000..2c278fa --- /dev/null +++ b/deployment/remote_server_secure/compose.yml @@ -0,0 +1,36 @@ +services: + tam3-db: + image: docker.io/dbob16/tam3-db:0.1.0 + restart: always + environment: + MARIADB_RANDOM_ROOT_PASSWORD: 1 + MARIADB_DATABASE: tam3 + MARIADB_USER: tam3 + MARIADB_PASSWORD: ${DB_PASSWORD} + volumes: + - "${DB_LOCATION}:/var/lib/mysql:rw,z" + healthcheck: + test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] + start_period: 10s + interval: 10s + timeout: 5s + retries: 3 + tam3-api: + image: docker.io/dbob16/tam3-api:0.1.0 + restart: always + environment: + TAM3_DATA_PATH: /data + TAM3_DB_HOST: tam3-db + TAM3_DB_DATABASE: tam3 + TAM3_DB_USER: tam3 + TAM3_DB_PASSWD: ${DB_PASSWORD} + ports: + - "8000:80" + tam3-rp: + image: docker.io/nginx:stable + restart: always + ports: + - "8443:443" + volumes: + - "./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro,z" + - "./nginx/certs:/certs:ro,z" \ No newline at end of file diff --git a/deployment/remote_server_secure/docker_generate-key.sh b/deployment/remote_server_secure/docker_generate-key.sh new file mode 100755 index 0000000..46cda81 --- /dev/null +++ b/deployment/remote_server_secure/docker_generate-key.sh @@ -0,0 +1,5 @@ +read -p "Enter the name of the computer you plan to use the key on: " pcname + +docker compose exec tam3-api /app/key.py generate $pcname + +echo "Note the key above this line. You can use that for the computer." \ No newline at end of file diff --git a/deployment/remote_server_secure/docker_list-keys.sh b/deployment/remote_server_secure/docker_list-keys.sh new file mode 100755 index 0000000..4b90084 --- /dev/null +++ b/deployment/remote_server_secure/docker_list-keys.sh @@ -0,0 +1 @@ +docker compose exec tam3-api /app/key.py list \ No newline at end of file diff --git a/deployment/remote_server_secure/docker_start-server.sh b/deployment/remote_server_secure/docker_start-server.sh new file mode 100755 index 0000000..2a178f3 --- /dev/null +++ b/deployment/remote_server_secure/docker_start-server.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +mkdir -p nginx/certs +echo "This part will ask you a bunch of questions for the self-signed cert. Answer them, I can't control it. For common name put the name or IP of the server which the clients can access it." +openssl req -x509 -newkey rsa:4096 -keyout nginx/certs/nginx.key -out nginx/certs/nginx.crt -sha256 -days 3650 -nodes + +gen_password=$(cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 32) + +echo "DB_LOCATION=./tam3-db" > .env +echo "DB_PASSWORD=${gen_password}" >> .env + +docker compose up -d \ No newline at end of file diff --git a/deployment/remote_server_secure/nginx/default.conf b/deployment/remote_server_secure/nginx/default.conf new file mode 100644 index 0000000..7213c7a --- /dev/null +++ b/deployment/remote_server_secure/nginx/default.conf @@ -0,0 +1,16 @@ +server { + listen 443 ssl default_server; + + server_name _; + + ssl_certificate /certs/nginx.crt; + ssl_certificate_key /certs/nginx.key; + + location / { + proxy_pass http://tam3-api/; + proxy_set_header Host $host; + proxy_ssl_name $host; + proxy_ssl_server_name on; + proxy_ssl_session_reuse off; + } +} \ No newline at end of file diff --git a/deployment/remote_server_secure/podman_generate-key.sh b/deployment/remote_server_secure/podman_generate-key.sh new file mode 100755 index 0000000..d4bdf32 --- /dev/null +++ b/deployment/remote_server_secure/podman_generate-key.sh @@ -0,0 +1,5 @@ +read -p "Enter the name of the computer you plan to use the key on: " pcname + +podman compose exec tam3-api /app/key.py generate $pcname + +echo "Note the key above this line. You can use that for the computer." \ No newline at end of file diff --git a/deployment/remote_server_secure/podman_list-keys.sh b/deployment/remote_server_secure/podman_list-keys.sh new file mode 100755 index 0000000..a1fc2cd --- /dev/null +++ b/deployment/remote_server_secure/podman_list-keys.sh @@ -0,0 +1 @@ +podman compose exec tam3-api /app/key.py list \ No newline at end of file diff --git a/deployment/remote_server_secure/podman_start-server.sh b/deployment/remote_server_secure/podman_start-server.sh new file mode 100755 index 0000000..7c5aebb --- /dev/null +++ b/deployment/remote_server_secure/podman_start-server.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +mkdir -p nginx/certs +echo "This part will ask you a bunch of questions for the self-signed cert. Answer them, I can't control it. For common name put the name or IP of the server which the clients can access it." +openssl req -x509 -newkey rsa:4096 -keyout nginx/certs/nginx.key -out nginx/certs/nginx.crt -sha256 -days 3650 -nodes + +gen_password=$(cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 32) + +echo "DB_LOCATION=./tam3-db" > .env +echo "DB_PASSWORD=${gen_password}" >> .env + +podman compose up -d \ No newline at end of file diff --git a/webapp/Dockerfile b/webapp/Dockerfile index 559b13e..5ca6975 100644 --- a/webapp/Dockerfile +++ b/webapp/Dockerfile @@ -1,23 +1,15 @@ -FROM node:lts-alpine AS build +FROM docker.io/node:lts-alpine AS build +RUN mkdir /data WORKDIR /app + COPY . . RUN npm install && npm run build -FROM node:lts-alpine AS prod - -WORKDIR /data -WORKDIR /app - ENV DATABASE_URL=file:/data/local.db -COPY --from=build /app/build/. build/. -COPY --from=build /app/package.json /app/drizzle.config.js . -COPY --from=build /app/drizzle drizzle COPY deploy/start-server.sh start-server.sh -RUN npm install --production && npm install drizzle-kit - EXPOSE 3000 CMD ["sh", "start-server.sh"] \ No newline at end of file diff --git a/webapp/package-lock.json b/webapp/package-lock.json index 81621d2..6349ff2 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -8,6 +8,8 @@ "name": "webapp", "version": "0.0.1", "dependencies": { + "@libsql/client": "^0.14.0", + "drizzle-kit": "^0.30.2", "hotkeys-js": "^3.13.15" }, "devDependencies": { @@ -1231,9 +1233,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.0.tgz", - "integrity": "sha512-VxDYCDqOaR7NXzAtvRx7G1u54d2kEHopb28YH/pKzY6y0qmogP3gG7CSiWsq9WvDFxOQMpNEyjVAHZFXfH3o/A==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.3.tgz", + "integrity": "sha512-h6cqHGZ6VdnwliFG1NXvMPTy/9PS3h8oLh7ImwR+kl+oYnQizgjxsONmmPSb2C66RksfkfIxEVtDSEcJiO0tqw==", "cpu": [ "arm" ], @@ -1245,9 +1247,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.0.tgz", - "integrity": "sha512-pqDirm8koABIKvzL59YI9W9DWbRlTX7RWhN+auR8HXJxo89m4mjqbah7nJZjeKNTNYopqL+yGg+0mhCpf3xZtQ==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.3.tgz", + "integrity": "sha512-wd+u7SLT/u6knklV/ifG7gr5Qy4GUbH2hMWcDauPFJzmCZUAJ8L2bTkVXC2niOIxp8lk3iH/QX8kSrUxVZrOVw==", "cpu": [ "arm64" ], @@ -1259,9 +1261,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.0.tgz", - "integrity": "sha512-YCdWlY/8ltN6H78HnMsRHYlPiKvqKagBP1r+D7SSylxX+HnsgXGCmLiV3Y4nSyY9hW8qr8U9LDUx/Lo7M6MfmQ==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.3.tgz", + "integrity": "sha512-lj9ViATR1SsqycwFkJCtYfQTheBdvlWJqzqxwc9f2qrcVrQaF/gCuBRTiTolkRWS6KvNxSk4KHZWG7tDktLgjg==", "cpu": [ "arm64" ], @@ -1273,9 +1275,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.0.tgz", - "integrity": "sha512-z4nw6y1j+OOSGzuVbSWdIp1IUks9qNw4dc7z7lWuWDKojY38VMWBlEN7F9jk5UXOkUcp97vA1N213DF+Lz8BRg==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.3.tgz", + "integrity": "sha512-+Dyo7O1KUmIsbzx1l+4V4tvEVnVQqMOIYtrxK7ncLSknl1xnMHLgn7gddJVrYPNZfEB8CIi3hK8gq8bDhb3h5A==", "cpu": [ "x64" ], @@ -1287,9 +1289,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.0.tgz", - "integrity": "sha512-Q/dv9Yvyr5rKlK8WQJZVrp5g2SOYeZUs9u/t2f9cQ2E0gJjYB/BWoedXfUT0EcDJefi2zzVfhcOj8drWCzTviw==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.3.tgz", + "integrity": "sha512-u9Xg2FavYbD30g3DSfNhxgNrxhi6xVG4Y6i9Ur1C7xUuGDW3banRbXj+qgnIrwRN4KeJ396jchwy9bCIzbyBEQ==", "cpu": [ "arm64" ], @@ -1301,9 +1303,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.0.tgz", - "integrity": "sha512-kdBsLs4Uile/fbjZVvCRcKB4q64R+1mUq0Yd7oU1CMm1Av336ajIFqNFovByipciuUQjBCPMxwJhCgfG2re3rg==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.3.tgz", + "integrity": "sha512-5M8kyi/OX96wtD5qJR89a/3x5x8x5inXBZO04JWhkQb2JWavOWfjgkdvUqibGJeNNaz1/Z1PPza5/tAPXICI6A==", "cpu": [ "x64" ], @@ -1315,9 +1317,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.0.tgz", - "integrity": "sha512-aL6hRwu0k7MTUESgkg7QHY6CoqPgr6gdQXRJI1/VbFlUMwsSzPGSR7sG5d+MCbYnJmJwThc2ol3nixj1fvI/zQ==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.3.tgz", + "integrity": "sha512-IoerZJ4l1wRMopEHRKOO16e04iXRDyZFZnNZKrWeNquh5d6bucjezgd+OxG03mOMTnS1x7hilzb3uURPkJ0OfA==", "cpu": [ "arm" ], @@ -1329,9 +1331,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.0.tgz", - "integrity": "sha512-BTs0M5s1EJejgIBJhCeiFo7GZZ2IXWkFGcyZhxX4+8usnIo5Mti57108vjXFIQmmJaRyDwmV59Tw64Ap1dkwMw==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.3.tgz", + "integrity": "sha512-ZYdtqgHTDfvrJHSh3W22TvjWxwOgc3ThK/XjgcNGP2DIwFIPeAPNsQxrJO5XqleSlgDux2VAoWQ5iJrtaC1TbA==", "cpu": [ "arm" ], @@ -1343,9 +1345,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.0.tgz", - "integrity": "sha512-uj672IVOU9m08DBGvoPKPi/J8jlVgjh12C9GmjjBxCTQc3XtVmRkRKyeHSmIKQpvJ7fIm1EJieBUcnGSzDVFyw==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.3.tgz", + "integrity": "sha512-NcViG7A0YtuFDA6xWSgmFb6iPFzHlf5vcqb2p0lGEbT+gjrEEz8nC/EeDHvx6mnGXnGCC1SeVV+8u+smj0CeGQ==", "cpu": [ "arm64" ], @@ -1357,9 +1359,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.0.tgz", - "integrity": "sha512-/+IVbeDMDCtB/HP/wiWsSzduD10SEGzIZX2945KSgZRNi4TSkjHqRJtNTVtVb8IRwhJ65ssI56krlLik+zFWkw==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.3.tgz", + "integrity": "sha512-d3pY7LWno6SYNXRm6Ebsq0DJGoiLXTb83AIPCXl9fmtIQs/rXoS8SJxxUNtFbJ5MiOvs+7y34np77+9l4nfFMw==", "cpu": [ "arm64" ], @@ -1371,9 +1373,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.0.tgz", - "integrity": "sha512-U1vVzvSWtSMWKKrGoROPBXMh3Vwn93TA9V35PldokHGqiUbF6erSzox/5qrSMKp6SzakvyjcPiVF8yB1xKr9Pg==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.3.tgz", + "integrity": "sha512-3y5GA0JkBuirLqmjwAKwB0keDlI6JfGYduMlJD/Rl7fvb4Ni8iKdQs1eiunMZJhwDWdCvrcqXRY++VEBbvk6Eg==", "cpu": [ "loong64" ], @@ -1385,9 +1387,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.0.tgz", - "integrity": "sha512-X/4WfuBAdQRH8cK3DYl8zC00XEE6aM472W+QCycpQJeLWVnHfkv7RyBFVaTqNUMsTgIX8ihMjCvFF9OUgeABzw==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.3.tgz", + "integrity": "sha512-AUUH65a0p3Q0Yfm5oD2KVgzTKgwPyp9DSXc3UA7DtxhEb/WSPfbG4wqXeSN62OG5gSo18em4xv6dbfcUGXcagw==", "cpu": [ "ppc64" ], @@ -1399,9 +1401,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.0.tgz", - "integrity": "sha512-xIRYc58HfWDBZoLmWfWXg2Sq8VCa2iJ32B7mqfWnkx5mekekl0tMe7FHpY8I72RXEcUkaWawRvl3qA55og+cwQ==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.3.tgz", + "integrity": "sha512-1makPhFFVBqZE+XFg3Dkq+IkQ7JvmUrwwqaYBL2CE+ZpxPaqkGaiWFEWVGyvTwZace6WLJHwjVh/+CXbKDGPmg==", "cpu": [ "riscv64" ], @@ -1413,9 +1415,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.0.tgz", - "integrity": "sha512-mbsoUey05WJIOz8U1WzNdf+6UMYGwE3fZZnQqsM22FZ3wh1N887HT6jAOjXs6CNEK3Ntu2OBsyQDXfIjouI4dw==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.3.tgz", + "integrity": "sha512-OOFJa28dxfl8kLOPMUOQBCO6z3X2SAfzIE276fwT52uXDWUS178KWq0pL7d6p1kz7pkzA0yQwtqL0dEPoVcRWg==", "cpu": [ "riscv64" ], @@ -1427,9 +1429,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.0.tgz", - "integrity": "sha512-qP6aP970bucEi5KKKR4AuPFd8aTx9EF6BvutvYxmZuWLJHmnq4LvBfp0U+yFDMGwJ+AIJEH5sIP+SNypauMWzg==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.3.tgz", + "integrity": "sha512-jMdsML2VI5l+V7cKfZx3ak+SLlJ8fKvLJ0Eoa4b9/vCUrzXKgoKxvHqvJ/mkWhFiyp88nCkM5S2v6nIwRtPcgg==", "cpu": [ "s390x" ], @@ -1441,9 +1443,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.0.tgz", - "integrity": "sha512-nmSVN+F2i1yKZ7rJNKO3G7ZzmxJgoQBQZ/6c4MuS553Grmr7WqR7LLDcYG53Z2m9409z3JLt4sCOhLdbKQ3HmA==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.3.tgz", + "integrity": "sha512-tPgGd6bY2M2LJTA1uGq8fkSPK8ZLYjDjY+ZLK9WHncCnfIz29LIXIqUgzCR0hIefzy6Hpbe8Th5WOSwTM8E7LA==", "cpu": [ "x64" ], @@ -1455,9 +1457,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.0.tgz", - "integrity": "sha512-2d0qRo33G6TfQVjaMR71P+yJVGODrt5V6+T0BDYH4EMfGgdC/2HWDVjSSFw888GSzAZUwuska3+zxNUCDco6rQ==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.3.tgz", + "integrity": "sha512-BCFkJjgk+WFzP+tcSMXq77ymAPIxsX9lFJWs+2JzuZTLtksJ2o5hvgTdIcZ5+oKzUDMwI0PfWzRBYAydAHF2Mw==", "cpu": [ "x64" ], @@ -1469,9 +1471,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.0.tgz", - "integrity": "sha512-A1JalX4MOaFAAyGgpO7XP5khquv/7xKzLIyLmhNrbiCxWpMlnsTYr8dnsWM7sEeotNmxvSOEL7F65j0HXFcFsw==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.3.tgz", + "integrity": "sha512-KTD/EqjZF3yvRaWUJdD1cW+IQBk4fbQaHYJUmP8N4XoKFZilVL8cobFSTDnjTtxWJQ3JYaMgF4nObY/+nYkumA==", "cpu": [ "arm64" ], @@ -1483,9 +1485,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.0.tgz", - "integrity": "sha512-YQugafP/rH0eOOHGjmNgDURrpYHrIX0yuojOI8bwCyXwxC9ZdTd3vYkmddPX0oHONLXu9Rb1dDmT0VNpjkzGGw==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.3.tgz", + "integrity": "sha512-+zteHZdoUYLkyYKObGHieibUFLbttX2r+58l27XZauq0tcWYYuKUwY2wjeCN9oK1Um2YgH2ibd6cnX/wFD7DuA==", "cpu": [ "arm64" ], @@ -1497,9 +1499,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.0.tgz", - "integrity": "sha512-zYdUYhi3Qe2fndujBqL5FjAFzvNeLxtIqfzNEVKD1I7C37/chv1VxhscWSQHTNfjPCrBFQMnynwA3kpZpZ8w4A==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.3.tgz", + "integrity": "sha512-of1iHkTQSo3kr6dTIRX6t81uj/c/b15HXVsPcEElN5sS859qHrOepM5p9G41Hah+CTqSh2r8Bm56dL2z9UQQ7g==", "cpu": [ "ia32" ], @@ -1511,9 +1513,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.0.tgz", - "integrity": "sha512-fGk03kQylNaCOQ96HDMeT7E2n91EqvCDd3RwvT5k+xNdFCeMGnj5b5hEgTGrQuyidqSsD3zJDQ21QIaxXqTBJw==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.3.tgz", + "integrity": "sha512-s0hybmlHb56mWVZQj8ra9048/WZTPLILKxcvcq+8awSZmyiSUZjjem1AhU3Tf4ZKpYhK4mg36HtHDOe8QJS5PQ==", "cpu": [ "x64" ], @@ -1525,9 +1527,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.0.tgz", - "integrity": "sha512-6iKDCVSIUQ8jPMoIV0OytRKniaYyy5EbY/RRydmLW8ZR3cEBhxbWl5ro0rkUNe0ef6sScvhbY79HrjRm8i3vDQ==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.3.tgz", + "integrity": "sha512-zGIbEVVXVtauFgl3MRwGWEN36P5ZGenHRMgNw88X5wEhEBpq0XrMEZwOn07+ICrwM17XO5xfMZqh0OldCH5VTA==", "cpu": [ "x64" ], @@ -1546,9 +1548,9 @@ "license": "MIT" }, "node_modules/@sveltejs/acorn-typescript": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.5.tgz", - "integrity": "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.6.tgz", + "integrity": "sha512-4awhxtMh4cx9blePWl10HRHj8Iivtqj+2QdDCSMDzxG+XKa9+VCNupQuCuvzEhYPzZSrX+0gC+0lHA/0fFKKQQ==", "dev": true, "license": "MIT", "peerDependencies": { @@ -1572,9 +1574,9 @@ } }, "node_modules/@sveltejs/kit": { - "version": "2.42.2", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.42.2.tgz", - "integrity": "sha512-FcNICFvlSYjPiAgk8BpqTEnXkaUj6I6wDwpQBxKMpsYhUc2Q5STgsVpXOG5LqwFpUAoLAXQ4wdWul7EcAG67JQ==", + "version": "2.43.5", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.43.5.tgz", + "integrity": "sha512-44Mm5csR4mesKx2Eyhtk8UVrLJ4c04BT2wMTfYGKJMOkUqpHP5KLL2DPV0hXUA4t4+T3ZYe0aBygd42lVYv2cA==", "dev": true, "license": "MIT", "dependencies": { @@ -1611,9 +1613,9 @@ } }, "node_modules/@sveltejs/vite-plugin-svelte": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-6.2.0.tgz", - "integrity": "sha512-nJsV36+o7rZUDlrnSduMNl11+RoDE1cKqOI0yUEBCcqFoAZOk47TwD3dPKS2WmRutke9StXnzsPBslY7prDM9w==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-6.2.1.tgz", + "integrity": "sha512-YZs/OSKOQAQCnJvM/P+F1URotNnYNeU3P2s4oIpzm1uFaqUEqRxUB0g5ejMjEb5Gjb9/PiBI5Ktrq4rUUF8UVQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1664,9 +1666,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.18.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.6.tgz", - "integrity": "sha512-r8uszLPpeIWbNKtvWRt/DbVi5zbqZyj1PTmhRMqBMvDnaz1QpmSKujUtJLrqGZeoM8v72MfYggDceY4K1itzWQ==", + "version": "22.18.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.7.tgz", + "integrity": "sha512-3E97nlWEVp2V6J7aMkR8eOnw/w0pArPwf/5/W0865f+xzBoGL/ZuHkTAKAGN7cOWNwd+sG+hZOqj+fjzeHS75g==", "dev": true, "license": "MIT", "dependencies": { @@ -2464,9 +2466,9 @@ } }, "node_modules/rollup": { - "version": "4.52.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.0.tgz", - "integrity": "sha512-+IuescNkTJQgX7AkIDtITipZdIGcWF0pnVvZTWStiazUmcGA2ag8dfg0urest2XlXUi9kuhfQ+qmdc5Stc3z7g==", + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.3.tgz", + "integrity": "sha512-RIDh866U8agLgiIcdpB+COKnlCreHJLfIhWC3LVflku5YHfpnsIKigRZeFfMfCc4dVcqNVfQQ5gO/afOck064A==", "dev": true, "license": "MIT", "dependencies": { @@ -2480,28 +2482,28 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.52.0", - "@rollup/rollup-android-arm64": "4.52.0", - "@rollup/rollup-darwin-arm64": "4.52.0", - "@rollup/rollup-darwin-x64": "4.52.0", - "@rollup/rollup-freebsd-arm64": "4.52.0", - "@rollup/rollup-freebsd-x64": "4.52.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.52.0", - "@rollup/rollup-linux-arm-musleabihf": "4.52.0", - "@rollup/rollup-linux-arm64-gnu": "4.52.0", - "@rollup/rollup-linux-arm64-musl": "4.52.0", - "@rollup/rollup-linux-loong64-gnu": "4.52.0", - "@rollup/rollup-linux-ppc64-gnu": "4.52.0", - "@rollup/rollup-linux-riscv64-gnu": "4.52.0", - "@rollup/rollup-linux-riscv64-musl": "4.52.0", - "@rollup/rollup-linux-s390x-gnu": "4.52.0", - "@rollup/rollup-linux-x64-gnu": "4.52.0", - "@rollup/rollup-linux-x64-musl": "4.52.0", - "@rollup/rollup-openharmony-arm64": "4.52.0", - "@rollup/rollup-win32-arm64-msvc": "4.52.0", - "@rollup/rollup-win32-ia32-msvc": "4.52.0", - "@rollup/rollup-win32-x64-gnu": "4.52.0", - "@rollup/rollup-win32-x64-msvc": "4.52.0", + "@rollup/rollup-android-arm-eabi": "4.52.3", + "@rollup/rollup-android-arm64": "4.52.3", + "@rollup/rollup-darwin-arm64": "4.52.3", + "@rollup/rollup-darwin-x64": "4.52.3", + "@rollup/rollup-freebsd-arm64": "4.52.3", + "@rollup/rollup-freebsd-x64": "4.52.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.3", + "@rollup/rollup-linux-arm-musleabihf": "4.52.3", + "@rollup/rollup-linux-arm64-gnu": "4.52.3", + "@rollup/rollup-linux-arm64-musl": "4.52.3", + "@rollup/rollup-linux-loong64-gnu": "4.52.3", + "@rollup/rollup-linux-ppc64-gnu": "4.52.3", + "@rollup/rollup-linux-riscv64-gnu": "4.52.3", + "@rollup/rollup-linux-riscv64-musl": "4.52.3", + "@rollup/rollup-linux-s390x-gnu": "4.52.3", + "@rollup/rollup-linux-x64-gnu": "4.52.3", + "@rollup/rollup-linux-x64-musl": "4.52.3", + "@rollup/rollup-openharmony-arm64": "4.52.3", + "@rollup/rollup-win32-arm64-msvc": "4.52.3", + "@rollup/rollup-win32-ia32-msvc": "4.52.3", + "@rollup/rollup-win32-x64-gnu": "4.52.3", + "@rollup/rollup-win32-x64-msvc": "4.52.3", "fsevents": "~2.3.2" } }, @@ -2611,9 +2613,9 @@ } }, "node_modules/svelte": { - "version": "5.39.3", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.39.3.tgz", - "integrity": "sha512-7Jwus6iXviGZAvhqbeYu3NNHA6LGyQ8EbmjdAhJUDade5rrW6g9VnBbRhUuYX4pMZLHozijsFolt88zvKPfsbQ==", + "version": "5.39.6", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.39.6.tgz", + "integrity": "sha512-bOJXmuwLNaoqPCTWO8mPu/fwxI5peGE5Efe7oo6Cakpz/G60vsnVF6mxbGODaxMUFUKEnjm6XOwHEqOht6cbvw==", "dev": true, "license": "MIT", "dependencies": { @@ -2681,9 +2683,9 @@ "license": "MIT" }, "node_modules/vite": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.6.tgz", - "integrity": "sha512-SRYIB8t/isTwNn8vMB3MR6E+EQZM/WG1aKmmIUCfDXfVvKfc20ZpamngWHKzAmmu9ppsgxsg4b2I7c90JZudIQ==", + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.7.tgz", + "integrity": "sha512-VbA8ScMvAISJNJVbRDTJdCwqQoAareR/wutevKanhR2/1EkoXVZVkkORaYm/tNVCjP/UDTKtcw3bAkwOUdedmA==", "dev": true, "license": "MIT", "dependencies": { diff --git a/webapp/src/app.html b/webapp/src/app.html index f273cc5..6f21893 100644 --- a/webapp/src/app.html +++ b/webapp/src/app.html @@ -3,6 +3,7 @@ + %sveltekit.head% diff --git a/webapp/static/icons/tam3x192.png b/webapp/static/icons/tam3x192.png new file mode 100644 index 0000000000000000000000000000000000000000..3aa4706e607471a146f8cfa6cb5cc9c5fd3b16c3 GIT binary patch literal 7175 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
j@Ov(*7cc9C*#A}%^huw3gW^QdF zkI#eK3GW$AeOs;Km_S>=mzJ9~iAf=Ce|(x4RQl_PcB^JwwD946+{kb8Avwe6D{;q_mHbq(ok7LIgyRSGa}YCj{Yt5L&<5T(olIG9v&=V7u<;S zG|5vwgsVreqd!rNaHJFTfM{(yYq8Dlb!H`nd1Y!b5AV~>TzU+X%QSrHT?moojEKR3 z$WWP^{ScFRXjVqXP%>_(v^ogb8*+?{m=LKogAPcONQCZFwgS>J^g`>gQMrz5q>HiF z)E%xiB{}J9uI~5t8u^8_#2g+Ucl~s8;}W1H3#)lnu(HW*O9G}g@xD}KU`Rd9<>gm{ zWsvB=Sjs@S(%AWN%961oM>1zqElA=y?e2F2mHY?imt}QK8}fa^4)lc%M69!KJVnyJ zogSXP&eQ5v;Zbavg0^zyBIK4Sa;p-HDY_|wtiA44r=yr#rVSv&x3@MnDEQKQ=oF~L z1;BqPeR1vDH87YXC)c~HZThU$o@4DLkG5t*&Az<4$wIY!us)ghWb}%FAULyjd~Hz6 z)B}m}!rG_(a%bZh4=Yj|K_9@nrji*|Hz`IF&)7DZ?Kpbckc*r&zug@fz$U&w#| z{a59JlP)u^C6Uj81-5e)6ckj=qQS%_c;`+?kM%#vv_4tvZa6Q6b`E`FkziZ&Lm%EZ z@eIO5Pk!&~G7%ZndNgS~$o)+2z&>$$a8jh`dKY0vW?Ccqan@;HU*8`7+cht5?}9I1 zWPTgP$0?3$+8!tAFp}HY$c!qc z7fGeu{9gV`?pcnkZwL%|K`VgDB%=<@f%&Xv6_Ny%6gCnGGl{1SV_K9=OikIRPpO5Z zp1;tp&@*!uVw2^k|7tFZs4V)Zs^VEP&6rzPcTafL%oWAQhhamc6>!Z4%dpsX2A+r! zI{xzuu6G8#M9}^FCZi4Fa%>EEK0t@>zb?p6FUtu74>X(&l(KK%zYpKrbEl%ALG8AT zPY_*P?nZmZqCBZ$tcdvV7q4Ev42MT2ZAXE%Gd2=jTt)>=MX*M&C5qBIy(@@ESz-@X z354J5itRb|2pvY;J_3P=B**X!Niv_CwvSw-bVd61;7(4Y&d$!1Mw&QtU?(Rw_(`4B z19V6sah0Gp_sg+o!YQ9dL?^1R4%_w2NA#HM=#Y)`!|W3i6Jrf+YOxnVck6GhIB1aO zBs@6s_5JJDdh&H{>GnsH$PpAiA;^~aeyM?YBvK%91wu@uRffZ%zq`8Tq$)ok9BXq& zhGwunefsq4D>$79Chw+TYwN&#j=AWr1?ZJwi9yST9y8EQ^0m$I^9UqxHOu?tcfQ~w zL2JnwqA~N@mK&h8Cgu5u>I%L@JL$whw|&uwnYSkFW+=4a7L8OzKeSScvEAb{_V%hW z9(D@v`}OnZlz0HWr7;aN#^rm0pHx&nR>vv&4#rZ9MNY_|^yNdbY5$wa+2r@sg*w1R zA%M=G&UqmA8vLHuh$yDY{|6fWFbVpmhe#ty$&BtvmV0qgTJjga`+olZ%BL!R2jX5C zap`1xk1iu3l6HrmLpM-vrk;pslgMyvz7Zq@^k;7m0!9wf^*lOhWUbmg$_r*G}k$S~Xg34!YZJ`r7LDEY);sU~GNNg-`wgbam^aEKejY)sMB^MKA zZO?tA!u;oYliATr!U5e`g_(_2zYojHFuHGJ*|bBDSy;PW?d_l@k-~mzebGFHy+@(I27B~ zf6KtvERp$7owoWjgLJgEx%tm6RCX}bM%66lp7p9ht$0^fI`&6v^E1f;FMe@>wGKb% zQWMh-fNSsMf_H;V8PA1`=TVO@lsmCHQ2Vji>i=^L6}i-K_f&bA?A8tc zqrb}^!OMT?(Xk!6kTfm+t;N=ifNERv{R#409BBCB56jd4Rz6i!zz>chij~TqHHu8h z+w@TU>q|t;4}V}=LnR~r3CVgB<;anb{+&{apR(3@H6*4E#?#*CpJ68XLb!6*-ohB+W};MM2fEKoM@TyKSg|Pg8+B*8b`de49QWmfsz-+7oHt_%rRg_AFl4Z#M0ICjSl>h($ literal 0 HcmV?d00001 diff --git a/webapp/static/icons/tam3x512.png b/webapp/static/icons/tam3x512.png new file mode 100644 index 0000000000000000000000000000000000000000..ff611c86219a235a721550958e9a80c358c58ba6 GIT binary patch literal 20384 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