banyaro/backend/static/js/pages/datenschutz.js
rene 9394bab1fb Big Sweep: Security + Race-Conditions + Tests + DSGVO + A11y, SW by-v1095
SECURITY (auth.py, routes/auth.py, database.py, main.py)
- JWT bekommt jti; Logout trägt in neue jwt_blacklist-Tabelle ein,
  decode_token() prüft → server-side Invalidierung
- JWT-Expiry default 30 → 7 Tage (ENV JWT_EXPIRY_DAYS überschreibt)
- Sliding-Refresh-Middleware: erneuert Cookie wenn >50% verbraucht
  (Schwelle via JWT_REFRESH_FRACTION, Default 2)
- Login-Lockout in DB-Tabelle login_attempts (5 Versuche / 15 Min,
  überlebt Container-Restart) — alte In-Memory-Lockouts ersetzt
- SMTP-Versand: alle 'except: pass' durch logger.exception ersetzt;
  Fehlversuche landen in failed_emails-Tabelle für späteres Retry
- Referral-Counter Race gefixt: UPDATE partner_codes SET uses=uses+1
  ... WHERE uses<max_uses RETURNING — atomar statt SELECT+UPDATE

RACE CONDITIONS (routes/invoices.py, database.py)
- Neue invoice_counters-Tabelle für atomare Nummernvergabe
- _next_invoice_number nutzt BEGIN IMMEDIATE + atomares UPDATE
- Funktioniert für RG- und ST-Prefixe (Stornorechnungen)
- Race-Test verifiziert (5 Threads × 20 Calls = 100 eindeutige Nummern)

VERSION + TESTS + ERROR-DIGEST (VERSION, Makefile, tests/, scheduler.py)
- Neue VERSION-Datei (Single Source of Truth) — main.py liest beim
  Startup
- Makefile-Target 'make bump' propagiert in sw.js, app.js, index.html
- Makefile-Target 'make test' setzt venv auf, läuft pytest
- 19 Smoke-Tests in tests/ (health, auth, diary, invoice) — alle grün
- Scheduler: täglicher _job_error_digest um 06:30 → schickt Error-
  Zusammenfassung an ADMIN_EMAIL (still wenn keine Errors)

DSGVO + A11Y + ERSTE-HILFE
- landing.html: 'HTML und ODS' → 'JSON' (tatsächlich implementiert)
- datenschutz.js: Sektion Account-Löschung erweitert (sofort gelöscht /
  anonymisiert / 10 Jahre für Rechnungen)
- erste-hilfe.js: prominentes Warning-Banner oben (ersetzt keine
  Tierarzt-Beratung); Notfallnummern gruppiert nach Land, TODO-Platz-
  halter für AT-Uni-Klinik, CH Tox Info Suisse, CH Tierspital Zürich
- ui.js Modal: ESC schließt, Focus-Trap, Auto-Focus erstes Element,
  Restore Focus auf vorigen Caller
- impressum.js Kontaktformular: Labels mit for=cf-name etc.

NEUE DB-TABELLEN (idempotent via CREATE TABLE IF NOT EXISTS)
- jwt_blacklist, login_attempts, failed_emails, invoice_counters

NEUE ENV-VARS
- JWT_REFRESH_FRACTION (Default 2)
- JWT_EXPIRY_DAYS Default geändert (30 → 7)
2026-05-26 20:12:01 +02:00

356 lines
21 KiB
JavaScript

/* ============================================================
BAN YARO — Datenschutzerklärung
============================================================ */
window.Page_datenschutz = (() => {
const S = {
h2: `font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0 0 var(--space-2)`,
p: `font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:0`,
ul: `font-size:var(--text-sm);color:var(--c-text-secondary);line-height:1.7;margin:var(--space-2) 0 0;padding-left:var(--space-5)`,
a: `color:var(--c-primary)`,
};
function sec(title, body) {
return `
<section style="margin-bottom:var(--space-6)">
<h2 style="${S.h2}">${title}</h2>
${body}
</section>`;
}
function init(container) {
container.innerHTML = `
<div style="max-width:640px;margin:0 auto;padding:var(--space-6) var(--space-4)">
<h1 style="font-size:var(--text-2xl);font-weight:var(--weight-bold);
color:var(--c-text);margin:0 0 var(--space-6)">Datenschutzerklärung</h1>
${sec('Verantwortlicher', `
<p style="${S.p}">
René Degelmann, Ringstr. 26, 85560 Ebersberg<br>
E-Mail: <a href="mailto:hallo@banyaro.app" style="${S.a}">hallo@banyaro.app</a>
</p>`)}
${sec('Hosting &amp; Infrastruktur', `
<p style="${S.p}">
Die App wird auf einem eigenen Server (Synology DiskStation) in Deutschland betrieben.
Alle Daten werden ausschließlich auf diesem Server gespeichert und nicht an externe
Hoster übermittelt.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Für den E-Mail-Versand (Kontobestätigung, Benachrichtigungen, Rechnungen) nutzen wir
<strong>Brevo</strong> (Sendinblue SAS, 55 rue d'Amsterdam, 75008 Paris, Frankreich).
Brevo ist nach EU-Standardvertragsklauseln zertifiziert. Dabei werden E-Mail-Adresse
und Name übermittelt. Datenschutzinformationen:
<a href="https://www.brevo.com/de/legal/privacypolicy/" target="_blank" rel="noopener"
style="${S.a}">brevo.com/de/legal/privacypolicy/</a>.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Für anonymisierte Nutzungsstatistiken betreiben wir <strong>Umami Analytics</strong>
auf unserem eigenen Server. Es werden keine personenbezogenen Daten oder IP-Adressen
gespeichert. Kein Tracking über Sitzungen hinweg.
</p>`)}
${sec('Deine Daten gehören dir', `
<p style="${S.p}">
Ban Yaro ist eine private Community-App. Dein <strong>Tagebuch</strong>, deine
<strong>persönlichen Notizen</strong>, <strong>Gesundheitsdaten</strong> deines Hundes,
<strong>eigene Routen</strong> und dein <strong>Nutzerprofil</strong> sind
ausschließlich für dich sichtbar — sie werden weder an andere Nutzer noch an Dritte
weitergegeben. Öffentlich sichtbar sind nur Inhalte, die du bewusst veröffentlichst
(z. B. Forenbeiträge, Giftköder-Meldungen, öffentliche Gassi-Treffen).
</p>`)}
${sec('Welche Daten wir verarbeiten', `
<p style="${S.p}">Bei der Registrierung und Nutzung von Ban Yaro werden folgende Daten verarbeitet:</p>
<ul style="${S.ul}">
<li><strong>Accountdaten:</strong> Benutzername, E-Mail-Adresse, Passphrase (verschlüsselt gespeichert)</li>
<li><strong>Hundeprofil:</strong> Name, Rasse, Alter, Foto (freiwillig)</li>
<li><strong>Gesundheitsdaten deines Hundes:</strong> Gewicht, Impfungen, Tierarztbesuche, Medikamente (freiwillig, nur für dich sichtbar)</li>
<li><strong>Tagebuch &amp; Notizen:</strong> Texte, Fotos, Stimmungseinträge (privat, nur für dich)</li>
<li><strong>Standortdaten:</strong> Nur nach expliziter Browser-Freigabe — für Karte, Gassi-Treffen,
Giftköder-Meldungen, Nearby-Alerts und Routenaufzeichnung. Standortdaten werden nicht dauerhaft
gespeichert, außer du speicherst selbst eine Route oder Meldung.</li>
<li><strong>Routendaten:</strong> Aufgezeichnete Routen (GPS-Wegpunkte) werden nur gespeichert,
wenn du sie explizit speicherst; sie sind standardmäßig privat.</li>
<li><strong>Fotos &amp; EXIF-Daten:</strong> Beim Hochladen von Bildern können GPS-Koordinaten
in den EXIF-Metadaten enthalten sein. Diese werden serverseitig ausgelesen, um Fotos auf der
Karte zu verorten — sofern vorhanden. Die Rohdaten werden nicht separat gespeichert.</li>
<li><strong>Inhalte:</strong> Forenbeiträge, Chatnachrichten, öffentliche Gassi-Treffen</li>
<li><strong>Technische Daten:</strong> IP-Adresse (für Sicherheit und Rate-Limiting, max. 30 Tage),
Browser-Typ</li>
</ul>`)}
${sec('Rechtsgrundlage', `
<p style="${S.p}">
Die Verarbeitung erfolgt auf Basis von Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung)
für alle zur Bereitstellung des Dienstes notwendigen Daten, sowie Art. 6 Abs. 1 lit. a
DSGVO (Einwilligung) für optionale Funktionen wie Standortfreigabe und
Push-Benachrichtigungen. Einwilligungen können jederzeit mit Wirkung für die Zukunft
widerrufen werden (Art. 7 Abs. 3 DSGVO) — einfach die entsprechende Funktion in den
Einstellungen deaktivieren oder die Browser-Freigabe entziehen.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Impressum und rechtliche Grundlage nach § 5 DDG (Digitale-Dienste-Gesetz).
</p>`)}
${sec('Datenweitergabe', `
<p style="${S.p}">
Deine Daten werden nicht an Dritte verkauft oder zu Werbezwecken weitergegeben.
Öffentliche Inhalte (Forum, Wiki, Giftköder-Karte) sind für alle Nutzer sichtbar.
Profile sind standardmäßig nur für registrierte Nutzer sichtbar.
Admins und Moderatoren können gemeldete Inhalte zur Qualitätssicherung einsehen
(Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO — berechtigtes Interesse an
Plattformsicherheit).
</p>`)}
${sec('Direktnachrichten', `
<p style="${S.p}">
Nachrichten zwischen Nutzern (z. B. zwischen Hundesitter und Hundeeigentümer oder
zwischen Interessenten und Züchtern) werden auf unserem Server gespeichert, bis du
das Gespräch oder deinen Account löschst. Admins können gemeldete Nachrichten zur
Missbrauchsprüfung einsehen (Art. 6 Abs. 1 lit. f DSGVO — berechtigtes Interesse
an Plattformsicherheit). Nachrichten werden nicht an Dritte weitergegeben.
Du kannst Gespräche jederzeit selbst löschen.
</p>`)}
${sec('Moderation &amp; Community', `
<p style="${S.p}">
Zur Sicherstellung der Plattformqualität und Einhaltung unserer Nutzungsregeln können
Moderatoren und automatische Systeme Inhalte prüfen. Rechtsgrundlage ist
Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an sicherer Plattform).
</p>`)}
${sec('KI-Funktionen', `
<p style="${S.p}">
Ban Yaro bietet KI-gestützte Funktionen (Trainingsempfehlungen, Terminvorschläge,
Rassen-Informationen). Diese laufen primär auf einer <strong>lokalen KI auf unserem
eigenen Server in Deutschland</strong> — deine Anfragen verlassen dabei nicht unsere
Infrastruktur.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Als Ausweichlösung bei Nichtverfügbarkeit des lokalen Modells wird
<strong>Claude Sonnet 4.6</strong> von Anthropic, PBC (San Francisco, USA) genutzt.
In diesem Fall wird der Inhalt deiner Anfrage übermittelt. Bei Gesundheits- und
Ernährungsberichten kann dies Hundedaten (Name, Rasse, Gewicht, Impfhistorie,
Medikamente, Allergien) als Teil des Anfragetextes umfassen. Die Übermittlung
in die USA erfolgt auf Basis der EU-Standardvertragsklauseln (Art. 46 Abs. 2 lit. c DSGVO).
Datenschutzerklärung von Anthropic:
<a href="https://www.anthropic.com/privacy" target="_blank" rel="noopener"
style="${S.a}">anthropic.com/privacy</a>.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Die <strong>Rassenerkennung per Foto</strong> sendet das hochgeladene Bild direkt an
Claude von Anthropic (USA) zur Analyse — es gibt hierfür keinen lokalen Fallback.
Das Foto wird nicht dauerhaft bei Anthropic gespeichert. Rechtsgrundlage: Einwilligung
gem. Art. 6 Abs. 1 lit. a DSGVO durch aktive Nutzung der Funktion.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Der <strong>KI-Trainer</strong> analysiert deinen bisherigen Trainingsfortschritt
(Übungshistorie, Erfolgsquoten, Streaks) und gibt personalisierte Empfehlungen.
Diese Analyse läuft auf unserem lokalen Server in Deutschland — deine Trainingsdaten
verlassen dabei nicht unsere Infrastruktur. Es findet kein Training oder Fine-Tuning
von KI-Modellen auf Basis deiner Nutzerdaten statt.
</p>
<p style="${S.p};margin-top:var(--space-3)">
KI-Empfehlungen sind Vorschläge und ersetzen keine tierärztliche Beratung.
Eine automatisierte Entscheidungsfindung mit rechtlicher Wirkung (Art. 22 DSGVO)
findet nicht statt.
</p>
<p style="${S.p};margin-top:var(--space-3)">
KI-Antworten können fehlerhaft oder unvollständig sein und dienen ausschließlich
allgemeinen Informationszwecken. Sie ersetzen keine tierärztliche oder fachliche
Beratung. Trotz EU-Standardvertragsklauseln besteht bei US-Anbietern ein Restrisiko,
dass US-Behörden auf übermittelte Daten zugreifen könnten.
</p>`)}
${sec('Wetterdaten & Kartendienste', `
<p style="${S.p}">
Die Wetter-Funktion übermittelt auf Wunsch deine GPS-Koordinaten serverseitig an
<strong>Open-Meteo</strong> (Österreich, DSGVO-konform) für die Wettervorhersage.
Für Wetter-Kartenlayer (Regenradar, Temperaturen) werden Kacheln von
<strong>OpenWeatherMap</strong> (OpenWeather Ltd., UK/USA) geladen — dabei wird
dein Browser direkt kontaktiert. Es werden keine Account-Daten übermittelt.
Rechtsgrundlage: Einwilligung gem. Art. 6 Abs. 1 lit. a DSGVO.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Für die automatische Ortsnamens-Ermittlung (z. B. im Wetter-Detail) werden deine
GPS-Koordinaten serverseitig an <strong>Nominatim</strong> der OpenStreetMap Foundation
(UK) übermittelt. Es werden ausschließlich Koordinaten weitergegeben — keine
personenbezogenen Daten.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Datenschutzerklärung Open-Meteo:
<a href="https://open-meteo.com/en/terms" target="_blank" rel="noopener"
style="${S.a}">open-meteo.com/en/terms</a> ·
OpenWeatherMap:
<a href="https://openweathermap.org/privacy-policy" target="_blank" rel="noopener"
style="${S.a}">openweathermap.org/privacy-policy</a> ·
OpenStreetMap/Nominatim:
<a href="https://osmfoundation.org/wiki/Privacy_Policy" target="_blank" rel="noopener"
style="${S.a}">osmfoundation.org</a>
</p>`)}
${sec('Routenvorschläge (OpenRouteService)', `
<p style="${S.p}">
Die Funktion <strong>„Routenvorschläge"</strong> berechnet auf Wunsch einen Rundweg
ausgehend von deinem aktuellen Standort. Dazu werden deine GPS-Koordinaten einmalig
an den Dienst <strong>OpenRouteService</strong> übermittelt, der von
<strong>HeiGIT</strong> am Karlsruher Institut für Technologie (KIT), Deutschland,
betrieben wird. Es werden ausschließlich die Koordinaten übertragen —
keine Account- oder Profildaten. OpenRouteService speichert keine
personenbezogenen Daten dauerhaft.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Die Funktion wird nur aktiv, wenn du deinen Standort im Browser freigibst und
bewusst einen Routenvorschlag anforderst (Einwilligung gem. Art. 6 Abs. 1 lit. a DSGVO).
Der Tagesvorschlag auf der Startseite wird nur berechnet, wenn du eingeloggt bist und
Standortzugriff erteilt hast — das Ergebnis wird lokal zwischengespeichert und
maximal einmal täglich neu abgerufen.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Datenschutzerklärung von OpenRouteService:
<a href="https://openrouteservice.org/privacy-policy/" target="_blank" rel="noopener"
style="${S.a}">openrouteservice.org/privacy-policy</a>
</p>`)}
${sec('Technische Speicherung', `
<p style="${S.p}">
Ban Yaro verwendet technisch notwendige Speichermechanismen für den Betrieb der App:
Session-Tokens und Authentifizierungsdaten werden im Local Storage des Browsers
gespeichert. Ein Service Worker speichert App-Inhalte lokal für die Offline-Nutzung
(Cache). Push-Benachrichtigungs-Token werden für die Zustellung von Hinweisen benötigt.
Diese Speicherung ist für die Kernfunktion der App erforderlich; eine Einwilligung ist
nach § 25 Abs. 2 TTDSG nicht erforderlich. Es werden keine Tracking-Cookies eingesetzt.
</p>`)}
${sec('Push-Benachrichtigungen', `
<p style="${S.p}">
Wenn du Push-Benachrichtigungen aktivierst, wird ein Abonnement-Token an den
Push-Dienst deines Browsers übermittelt: bei Android/Chrome an
<strong>Firebase Cloud Messaging</strong> (Google LLC, USA), bei iOS/Safari an
<strong>Apple Push Notification Service</strong> (Apple Inc., USA). Diese Dienste
erhalten lediglich den Token und die Benachrichtigung selbst — keine weiteren
Nutzerdaten. Die Übermittlung erfolgt auf Basis deiner Einwilligung
(Art. 6 Abs. 1 lit. a DSGVO), die du jederzeit in den Geräteeinstellungen widerrufen kannst.
</p>`)}
${sec('Kalender-Abo (Webcal)', `
<p style="${S.p}">
Das Kalender-Abo nutzt einen persönlichen Token-Link. Wenn deine Kalender-App
diesen Link regelmäßig abruft, wird dabei deine IP-Adresse an unseren Server
übermittelt. Es werden keine weiteren Daten an Dritte weitergegeben.
</p>`)}
${sec('Einladungslinks (Referral)', `
<p style="${S.p}">
Wenn du Freunde über deinen persönlichen Einladungslink einlädst, wird erfasst,
wie viele Personen sich darüber registriert haben — ohne personenbezogene Daten
der eingeladenen Personen zu speichern. Dir wird lediglich die Anzahl angezeigt.
</p>`)}
${sec('Nutzungsanalyse (Umami)', `
<p style="${S.p}">
Wir verwenden Umami, ein datenschutzfreundliches Analysetool, das ausschließlich auf
unserem eigenen Server betrieben wird. Es werden keine Cookies gesetzt, keine
personenbezogenen Daten erhoben und keine Daten an Dritte weitergegeben.
Erfasst werden lediglich anonyme Seitenaufrufe zur Verbesserung der App
(Art. 6 Abs. 1 lit. f DSGVO — berechtigtes Interesse).
</p>`)}
${sec('Deine Rechte (DSGVO)', `
<p style="${S.p}">
Du hast das Recht auf <strong>Auskunft</strong> (Art. 15), <strong>Berichtigung</strong>
(Art. 16), <strong>Löschung</strong> (Art. 17), <strong>Einschränkung der Verarbeitung</strong>
(Art. 18) sowie <strong>Datenportabilität</strong> (Art. 20). Erteilte Einwilligungen
kannst du jederzeit mit Wirkung für die Zukunft widerrufen (Art. 7 Abs. 3 DSGVO).
</p>
<p style="${S.p};margin-top:var(--space-3)">
<strong>Datenexport (Art. 20 DSGVO):</strong> Du kannst jederzeit unter
Einstellungen → „Meine Daten exportieren" eine vollständige Kopie deiner
gespeicherten Daten als JSON-Datei herunterladen. Der Export enthält Profildaten,
Hundedaten, Tagebuch (inkl. Medien-URLs), Gesundheitseinträge, Trainingsfortschritt,
Ausgaben, Verhaltensprotokoll, Versicherung, Ernährungsprofil und Futter-Reaktionen,
eigene Routen, Forum-Beiträge sowie Gassi-Teilnahmen und Gassi-Fotos.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Das JSON-Format ist maschinenlesbar und kann z. B. mit jedem Texteditor geöffnet
oder in andere Anwendungen importiert werden. Der Export wird direkt im Browser
erzeugt und nicht dauerhaft auf dem Server gespeichert.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Zur Ausübung weiterer Rechte wende dich per E-Mail an
<a href="mailto:hallo@banyaro.app" style="${S.a}">hallo@banyaro.app</a>.<br><br>
Du hast außerdem das Recht, bei der zuständigen Datenschutz-Aufsichtsbehörde
Beschwerde einzulegen:<br>
<strong>Bayerisches Landesamt für Datenschutzaufsicht (BayLDA)</strong><br>
Promenade 18, 91522 Ansbach<br>
<a href="mailto:poststelle@lda.bayern.de"
style="${S.a}">poststelle@lda.bayern.de</a> ·
<a href="https://www.lda.bayern.de" target="_blank" rel="noopener"
style="${S.a}">www.lda.bayern.de</a>
</p>`)}
${sec('Zahlungsdaten', `
<p style="${S.p}">
Wenn du ein kostenpflichtiges Abonnement abschließt, verarbeiten wir folgende Daten:
Name, E-Mail-Adresse, Rechnungsadresse und den Zahlungseingang. Rechtsgrundlage ist
Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung). Rechnungsdaten werden gemäß
§ 147 AO <strong>10 Jahre</strong> aufbewahrt. Rechnungen werden per E-Mail mit
TLS-Verschlüsselung zugestellt.
</p>
<p style="${S.p};margin-top:var(--space-3)">
Deine Zahlungsdaten (IBAN) werden nur für die Zuordnung des Zahlungseingangs intern
verwendet und nicht an Dritte weitergegeben. Die vertraglichen Bedingungen (Laufzeit,
Kündigung, Erstattung) findest du in unseren
<a href="#agb" style="${S.a}">AGB</a>.
</p>`)}
${sec('Speicherdauer', `
<p style="${S.p}">
Server-Logs werden nach 30 Tagen rotiert. IP-Adressen werden ausschließlich
zur Sicherheit und für Rate-Limiting maximal 30 Tage gespeichert.
</p>`)}
${sec('Account-Löschung', `
<p style="${S.p}">
Wenn du deinen Account löschst, werden deine Daten nach folgendem Schema verarbeitet:
</p>
<ul style="${S.ul}">
<li><strong>Sofort und unwiderruflich gelöscht:</strong> Account, Hundeprofile, Tagebuch
und Tagebuch-Medien, Gesundheitseinträge, Trainingsfortschritt, Ausgaben,
Verhaltensprotokoll, Versicherung, Ernährungsprofil, Futter-Einträge und -Reaktionen,
Forum-Beiträge, eigene Notizen, Direktnachrichten, Freundschaften,
Push-Benachrichtigungen, Einstellungen und Welten-Konfiguration.</li>
<li><strong>Anonymisiert (Urheber-Bezug auf NULL gesetzt):</strong> Eigene Routen,
Forum-Threads sowie von dir angelegte Wiki-Inhalte bleiben zur Verfügbarkeit für
die Community erhalten, sind aber nicht mehr deinem Account zuordenbar.</li>
<li><strong>10 Jahre aufbewahrt (gesetzliche Pflicht):</strong> Rechnungen und
Rechnungspositionen aus kostenpflichtigen Abonnements gemäß § 147 AO. Diese
enthalten Name, E-Mail-Adresse und Rechnungsadresse zum Zeitpunkt der Rechnung
und können vor Ablauf der Frist nicht gelöscht werden.</li>
</ul>
<p style="${S.p};margin-top:var(--space-3)">
Es findet keine anonymisierte Weiterverarbeitung deiner privaten Inhalte
(Tagebuch, Gesundheit, Notizen) zu Trainings- oder Statistikzwecken statt.
</p>`)}
${sec('Mindestalter', `
<p style="${S.p}">
Die Nutzung von Ban Yaro ist nur Personen ab 18 Jahren gestattet. Durch die
Registrierung bestätigt der Nutzer, das 18. Lebensjahr vollendet zu haben.
</p>`)}
<p style="font-size:var(--text-xs);color:var(--c-text-muted);margin:0">
Stand: Mai 2026 · Version 3
</p>
</div>
`;
}
function refresh() {}
return { init, refresh };
})();