diff --git a/Datenbank-Schema.-.md b/Datenbank-Schema.-.md
new file mode 100644
index 0000000..6f20dd9
--- /dev/null
+++ b/Datenbank-Schema.-.md
@@ -0,0 +1,411 @@
+# Datenbank-Schema
+
+← Zurück zur [Übersicht](Datenbank) · Funktionen: [Datenbank-Repositories](Datenbank-Repositories)
+
+Diese Seite beschreibt alle Tabellen und wie sie zusammenhängen.
+
+| Bereich | Tabellen | Angelegt in |
+|---|---|---|
+| Benutzer | `users`, `user_settings` | `schema.ts` |
+| Chats | `chat_sessions`, `chat_messages`, `chat_message_versions`, `chat_memories`, `persona_chat_state` | `schema.ts` |
+| Personas | `personas`, `persona_versions`, `prompt_templates` | `schema.ts` |
+| Marktplatz | `persona_market`, `persona_market_favorites`, `persona_market_ratings`, `persona_market_reports` | `schema.ts` |
+| Anhänge | `attachments`, `message_attachments`, `attachment_vision_analyses`, `upload_deletions` | `attachments.ts` |
+
+---
+
+## Beziehungsdiagramm
+
+**Durchgezogene Linie** = echter Fremdschlüssel (SQLite prüft ihn).
+**Gestrichelte Linie** = nur logische Beziehung (Spalte verweist auf eine andere Tabelle,
+wird aber nicht von der Datenbank geprüft, sondern vom Code).
+
+```mermaid
+erDiagram
+ users ||--o| user_settings : "hat"
+ users ||--o{ chat_memories : "besitzt"
+ users ||--o{ persona_chat_state : "besitzt"
+ users ||--o{ attachments : "lädt hoch"
+ users ||..o{ chat_sessions : "besitzt"
+ users ||..o{ personas : "besitzt"
+ users ||..o{ prompt_templates : "besitzt"
+ users ||..o{ persona_market : "veröffentlicht"
+ users ||..o{ persona_market_favorites : "favorisiert"
+ users ||..o{ persona_market_ratings : "bewertet"
+ users ||..o{ persona_market_reports : "meldet"
+
+ chat_sessions ||--o{ chat_messages : "enthält"
+ chat_sessions ||--o{ chat_memories : "hat"
+ chat_sessions ||--o| persona_chat_state : "hat"
+ chat_sessions |o--o{ chat_sessions : "Abzweigung von"
+ chat_messages |o--o{ chat_sessions : "Abzweigpunkt"
+ chat_messages |o..o{ chat_sessions : "aktives Blatt"
+ chat_messages |o--o{ chat_messages : "Parent"
+ chat_messages ||--o{ chat_message_versions : "Versionen"
+ chat_messages ||--o{ message_attachments : "hat"
+
+ attachments ||--o{ message_attachments : "verwendet in"
+ attachments ||--o{ attachment_vision_analyses : "Analysen"
+ attachments ||..o| upload_deletions : "Trigger"
+
+ personas |o--o{ chat_sessions : "Persona im Chat"
+ personas |o--o{ chat_memories : "bezieht sich auf"
+ personas |o--o{ persona_chat_state : "bezieht sich auf"
+ personas |o--o{ user_settings : "aktive Persona"
+ personas ||--o{ persona_versions : "Versionen"
+ personas |o--o{ prompt_templates : "Vorlagen"
+ personas |o..o{ persona_market : "veröffentlicht als"
+ persona_market |o..o{ personas : "gesammelt als"
+ persona_market ||--o{ persona_market_favorites : "hat"
+ persona_market ||--o{ persona_market_ratings : "hat"
+ persona_market ||--o{ persona_market_reports : "hat"
+```
+
+---
+
+## Lösch- und Umbenennungsverhalten
+
+Aufräumen passiert an **zwei Stellen**: teils automatisch durch Fremdschlüssel in der
+Datenbank, teils von Hand in `repositories.js`.
+
+### Automatisch durch die Datenbank (ON DELETE)
+
+| Wird gelöscht | Folge |
+|---|---|
+| `chat_sessions` | Löscht alle `chat_messages`, `chat_memories` und `persona_chat_state` des Chats. Abzweigungen dieses Chats behalten ihren Inhalt, `source_chat_id` wird `NULL` |
+| `chat_messages` | Löscht `chat_message_versions` und `message_attachments`. Kind-Nachrichten bleiben, ihr `parent_message_id` wird `NULL` |
+| `personas` | Löscht `persona_versions` und `prompt_templates` der Persona. In Chats, Memories, Chat-State und Settings wird der Verweis `NULL` |
+| `persona_market` | Löscht Favoriten, Bewertungen und Meldungen |
+| `attachments` | Löscht `message_attachments` und `attachment_vision_analyses`, trägt die Datei in `upload_deletions` ein (Trigger) |
+| `users` | Löscht `user_settings`, `chat_memories`, `persona_chat_state`, `attachments` |
+
+### Von Hand im Code
+
+| Aktion | Funktion | Was passiert |
+|---|---|---|
+| Benutzer löschen | `deleteUserTransaction` | Löscht nacheinander Marktplatz-Favoriten, -Bewertungen, -Meldungen, veröffentlichte Personas, Vorlagen, Persona-Versionen, Memories, Chat-State, Chats, Settings, Personas und zuletzt den Benutzer. Anhänge werden danach automatisch per CASCADE entfernt |
+| Benutzer umbenennen | `renameUserTransaction` | Ändert den Namen in `users` und in allen Tabellen mit Benutzerbezug. `attachments` wird per `ON UPDATE CASCADE` automatisch angepasst |
+| Persona löschen | `clearPersonaReferences` + `deletePersona` | Entfernt die Persona aus allen Chats und löscht ihren Marktplatz-Eintrag, danach die Persona selbst |
+
+Wird eine **neue Tabelle mit Benutzerbezug** angelegt, muss sie in beiden Transaktionen ergänzt werden.
+
+---
+
+## Tabellen
+
+### Benutzer
+
+#### `users`
+
+| Spalte | Typ | Hinweis |
+|---|---|---|
+| `username` | TEXT | **PK** |
+| `password` | TEXT | Passwort-Hash, nie Klartext |
+| `session_version` | INTEGER | Default `0`. Wird erhöht, um alle Sessions des Benutzers ungültig zu machen (z. B. nach Passwortänderung) |
+
+#### `user_settings` (1:1 zu `users`)
+
+| Spalte | Typ | Hinweis |
+|---|---|---|
+| `username` | TEXT | **PK**, FK → `users` (CASCADE) |
+| `active_persona_id` | INTEGER | FK → `personas` (SET NULL) |
+| `active_user_persona_id` | INTEGER | FK → `personas` (SET NULL), die aktuell gewählte User-Persona |
+
+### Chats
+
+#### `chat_sessions`
+
+| Spalte | Typ | Hinweis |
+|---|---|---|
+| `id` | INTEGER | **PK** |
+| `username` | TEXT | Besitzer (logisch → `users`) |
+| `title` | TEXT | Gespeicherter Titel, siehe Hinweis unten |
+| `assistant_persona_id` | INTEGER | FK → `personas` (SET NULL) |
+| `user_persona_id` | INTEGER | FK → `personas` (SET NULL) |
+| `folder_name` | TEXT | Ordner in der Seitenleiste |
+| `is_pinned` | INTEGER | Boolean |
+| `archived_at` | DATETIME | `NULL` = nicht archiviert |
+| `scenario_prompt`, `scenario_summary` | TEXT | Rollenspiel-Szenario und Kurzfassung |
+| `context_summary` | TEXT | Automatische Zusammenfassung älterer Nachrichten |
+| `context_summary_message_id` | INTEGER | Bis zu dieser Nachricht reicht die Zusammenfassung (logisch → `chat_messages`) |
+| `active_leaf_message_id` | INTEGER | Letzte Nachricht des sichtbaren Zweigs (logisch → `chat_messages`), siehe [Nachrichtenbaum](#nachrichtenbaum) |
+| `source_chat_id` | INTEGER | FK → `chat_sessions` (SET NULL). Gesetzt, wenn dieser Chat eine Abzweigung eines anderen ist |
+| `branched_from_message_id` | INTEGER | FK → `chat_messages` (SET NULL). Nachricht, an der abgezweigt wurde |
+| `preferred_model`, `temperature`, `context_length`, `response_length`, `system_instruction` | | Modell-Einstellungen pro Chat |
+| `created_at`, `updated_at` | DATETIME | `updated_at` bestimmt die Sortierung in der Liste |
+
+**Angezeigter Titel:** Hat ein Chat eine Assistant-Persona und ist keine Abzweigung, wird der
+**Name der Persona** als Titel angezeigt. Der gespeicherte Titel steht dann in `stored_title`.
+Diese Logik steckt in den SELECT-Abfragen in `repositories.js`.
+
+**Hauptchat:** Pro Kombination aus Assistant- und User-Persona gibt es einen Hauptchat
+(`source_chat_id IS NULL`), den `getChatByParticipants` findet.
+
+#### `chat_messages`
+
+| Spalte | Typ | Hinweis |
+|---|---|---|
+| `id` | INTEGER | **PK** |
+| `chat_id` | INTEGER | FK → `chat_sessions` (CASCADE) |
+| `role` | TEXT | `user` oder `bot` |
+| `content` | TEXT | Aktuell angezeigter Text |
+| `thinking` | TEXT | Reasoning-Ausgabe des Modells |
+| `sources` | TEXT | Websuche-Quellen als JSON |
+| `model_name` | TEXT | Modell, das die Antwort erzeugt hat |
+| `retry_variants` | TEXT | JSON-Array aller Antwortvarianten (Kopie aus `chat_message_versions`) |
+| `retry_active_index` | INTEGER | Welche Variante angezeigt wird |
+| `retry_retries_used` | INTEGER | Anzahl genutzter Wiederholungen |
+| `retry_prompt_message_id` | INTEGER | Zugehörige User-Nachricht (logisch → `chat_messages`) |
+| `delivery_status` | TEXT | `complete` (Default), `failed`, sowie ein Zwischenstatus während der Generierung (wird im Chat-Service gesetzt) |
+| `error_message` | TEXT | Fehlertext bei `failed` |
+| `parent_message_id` | INTEGER | FK → `chat_messages` (SET NULL), Vorgänger im Baum |
+| `created_at` | DATETIME | |
+
+#### `chat_message_versions`
+
+Alle Fassungen einer Nachricht (Regenerieren, Bearbeiten).
+
+| Spalte | Typ | Hinweis |
+|---|---|---|
+| `id` | INTEGER | **PK** |
+| `message_id` | INTEGER | FK → `chat_messages` (CASCADE), indiziert |
+| `content`, `thinking`, `sources`, `model_name` | TEXT | Inhalt dieser Fassung |
+| `created_at` | DATETIME | |
+
+#### `chat_memories`
+
+Fakten, die sich das Modell in einem Chat merkt.
+
+| Spalte | Typ | Hinweis |
+|---|---|---|
+| `id` | INTEGER | **PK** |
+| `username` | TEXT | FK → `users` (CASCADE) |
+| `chat_id` | INTEGER | FK → `chat_sessions` (CASCADE) |
+| `assistant_persona_id`, `user_persona_id` | INTEGER | FK → `personas` (SET NULL) |
+| `fact` | TEXT | Der Fakt |
+| `created_at`, `updated_at` | DATETIME | |
+
+#### `persona_chat_state` (1:1 zu `chat_sessions`)
+
+Rollenspiel-Zustand eines Chats. `chat_id` ist `UNIQUE`, Änderungen laufen per Upsert.
+
+| Spalte | Typ | Hinweis |
+|---|---|---|
+| `id` | INTEGER | **PK** |
+| `username` | TEXT | FK → `users` (CASCADE) |
+| `chat_id` | INTEGER | FK → `chat_sessions` (CASCADE), **UNIQUE** |
+| `assistant_persona_id`, `user_persona_id` | INTEGER | FK → `personas` (SET NULL) |
+| `relationship_notes`, `tone`, `current_location`, `goals`, `unresolved_threads`, `boundaries` | TEXT | Zustand der Unterhaltung |
+| `created_at`, `updated_at` | DATETIME | |
+
+### Personas
+
+#### `personas`
+
+| Spalte | Typ | Hinweis |
+|---|---|---|
+| `id` | INTEGER | **PK** |
+| `username` | TEXT | Besitzer (logisch → `users`) |
+| `name` | TEXT | |
+| `pronouns`, `appearance`, `background`, `details`, `example_dialogues` | TEXT | Beschreibung |
+| `custom_fields` | TEXT | Eigene Felder als JSON |
+| `persona_type` | TEXT | `assistant` (Default) oder `user` |
+| `source_market_id` | INTEGER | Gesetzt, wenn aus dem Marktplatz gesammelt (logisch → `persona_market`) |
+| `source_creator_username` | TEXT | Ursprünglicher Ersteller |
+| `created_at`, `updated_at` | DATETIME | |
+
+#### `persona_versions`
+
+Bei jeder Änderung einer Persona wird der **vorherige** Stand als Version gespeichert.
+
+| Spalte | Typ | Hinweis |
+|---|---|---|
+| `id` | INTEGER | **PK** |
+| `persona_id` | INTEGER | FK → `personas` (CASCADE) |
+| `username` | TEXT | |
+| `version_number` | INTEGER | Fortlaufend ab 1 |
+| `snapshot_json` | TEXT | Stand der Persona als JSON (erzeugt von `buildPersonaSnapshot`) |
+| `created_at` | DATETIME | |
+
+#### `prompt_templates`
+
+| Spalte | Typ | Hinweis |
+|---|---|---|
+| `id` | INTEGER | **PK** |
+| `username` | TEXT | Besitzer. **`NULL` = System-Vorlage**, sichtbar für alle, bearbeitbar nur als Benutzer `system` |
+| `persona_id` | INTEGER | FK → `personas` (CASCADE). `NULL` = für alle Personas |
+| `name`, `description`, `category` | TEXT | |
+| `prompt_text` | TEXT | Der Prompt |
+| `starter_text` | TEXT | Optionaler Einstiegstext |
+| `is_shared` | INTEGER | Boolean. Geteilte Vorlagen sehen alle Benutzer |
+| `created_at`, `updated_at` | DATETIME | |
+
+### Marktplatz
+
+#### `persona_market`
+
+Eine **Kopie** der Persona zum Zeitpunkt der Veröffentlichung. Änderungen am Original
+wirken erst nach erneutem Veröffentlichen.
+
+| Spalte | Typ | Hinweis |
+|---|---|---|
+| `id` | INTEGER | **PK** |
+| `persona_id` | INTEGER | Original-Persona (logisch → `personas`) |
+| `creator_username` | TEXT | Ersteller |
+| `name`, `pronouns`, `appearance`, `background`, `details`, `example_dialogues` | TEXT | Kopie der Persona |
+| `persona_type` | TEXT | `assistant` oder `user` |
+| `tags` | TEXT | JSON-Array |
+| `usage_count` | INTEGER | Wie oft gesammelt |
+| `favorite_count` | INTEGER | Zwischengespeicherte Anzahl, wird nach jeder Änderung neu gezählt |
+| `rating_total`, `rating_count` | INTEGER | Summe und Anzahl der Bewertungen. Durchschnitt wird in Abfragen als `rating_average` berechnet |
+| `moderation_status` | TEXT | Default `approved`. `rejected` wird öffentlich ausgeblendet |
+| `moderation_notes` | TEXT | |
+| `soft_deleted_at` | DATETIME | `NULL` = sichtbar |
+| `created_at`, `updated_at` | DATETIME | |
+
+**UNIQUE** (`persona_id`, `creator_username`): Jede Persona kann nur einmal veröffentlicht werden,
+erneutes Veröffentlichen aktualisiert den Eintrag.
+
+#### `persona_market_favorites` · `persona_market_ratings`
+
+| Spalte | Typ | Hinweis |
+|---|---|---|
+| `market_id` | INTEGER | **PK**, FK → `persona_market` (CASCADE) |
+| `username` | TEXT | **PK** |
+| `rating` | INTEGER | nur in `_ratings` |
+| `created_at` (`updated_at`) | DATETIME | |
+
+Zusammengesetzter Primärschlüssel: ein Favorit bzw. eine Bewertung pro Benutzer und Eintrag.
+
+#### `persona_market_reports`
+
+| Spalte | Typ | Hinweis |
+|---|---|---|
+| `id` | INTEGER | **PK** |
+| `market_id` | INTEGER | FK → `persona_market` (CASCADE) |
+| `reporter_username` | TEXT | |
+| `reason`, `details` | TEXT | |
+| `status` | TEXT | Default `open`. Offene Meldungen werden zuerst gelistet |
+| `created_at`, `updated_at` | DATETIME | |
+
+### Anhänge
+
+#### `attachments`
+
+Metadaten hochgeladener Bilder. Die Datei selbst liegt im Upload-Verzeichnis.
+
+| Spalte | Typ | Hinweis |
+|---|---|---|
+| `id` | TEXT | **PK** |
+| `username` | TEXT | FK → `users` (CASCADE, auch ON UPDATE) |
+| `original_name` | TEXT | Ursprünglicher Dateiname |
+| `storage_key` | TEXT | **UNIQUE**, Dateiname im Speicher, **nie ans Frontend geben** |
+| `mime_type` | TEXT | |
+| `size_bytes`, `width`, `height` | INTEGER | |
+| `status` | TEXT | `temporary` (Default) oder `attached`, per `CHECK` erzwungen |
+| `created_at` | TEXT | |
+| `vision_model`, `vision_analysis`, `vision_analyzed_at` | TEXT | Ältere Einzelanalyse, siehe Auffälligkeiten |
+
+#### `message_attachments` (n:m Nachricht ↔ Anhang)
+
+| Spalte | Typ | Hinweis |
+|---|---|---|
+| `message_id` | INTEGER | **PK**, FK → `chat_messages` (CASCADE) |
+| `attachment_id` | TEXT | **PK**, FK → `attachments` (CASCADE), indiziert |
+| `position` | INTEGER | Reihenfolge der Bilder |
+
+#### `attachment_vision_analyses`
+
+Zwischenspeicher für Bildanalysen, damit dasselbe Bild nicht mehrfach analysiert wird.
+
+| Spalte | Typ | Hinweis |
+|---|---|---|
+| `attachment_id` | TEXT | **PK**, FK → `attachments` (CASCADE) |
+| `vision_model` | TEXT | **PK** |
+| `prompt_version` | INTEGER | **PK** |
+| `question` | TEXT | **PK** |
+| `analysis` | TEXT | Ergebnis |
+| `analyzed_at` | TEXT | |
+
+#### `upload_deletions`
+
+Warteschlange für Dateien, die die App vom Speicher löschen muss. Einzige Spalte: `storage_key` (**PK**).
+
+### Lebenszyklus eines Anhangs
+
+```mermaid
+flowchart TD
+ A["Bild hochgeladen"] --> B["attachments
status = temporary"]
+ B -->|"Nachricht gesendet"| C["status = attached
+ Zeile in message_attachments"]
+ C -->|"Nachricht oder Chat gelöscht"| D["message_attachments-Zeile gelöscht"]
+ D -->|"Trigger release_message_attachment
(keine weiteren Verweise)"| E["attachments-Zeile gelöscht"]
+ B -->|"temporärer Upload verworfen"| E
+ E -->|"Trigger queue_attachment_file_delete"| F["storage_key in upload_deletions"]
+ F --> G["App löscht die Datei vom Speicher"]
+```
+
+---
+
+## Nachrichtenbaum
+
+Nachrichten eines Chats sind keine flache Liste, sondern ein **Baum**. Jede Nachricht
+verweist über `parent_message_id` auf ihren Vorgänger. So können aus einer Stelle mehrere
+Verläufe entstehen, z. B. durch Bearbeiten einer Frage.
+
+```mermaid
+flowchart TD
+ M1["1 · user: Hallo"] --> M2["2 · bot: Hi!"]
+ M2 --> M3["3 · user: Erzähl einen Witz"]
+ M3 --> M4["4 · bot: Witz"]
+ M2 --> M5["5 · user: Erzähl ein Rätsel
(bearbeitete Frage)"]
+ M5 --> M6["6 · bot: Rätsel"]
+```
+
+- **Aktiver Zweig:** `chat_sessions.active_leaf_message_id` zeigt auf das sichtbare Ende,
+ z. B. `6`. Die App läuft von dort über die Parents zurück zur Wurzel: `6 → 5 → 2 → 1`.
+ Das machen die rekursiven Abfragen (`WITH RECURSIVE branch ...`) in `repositories.js`.
+- **Geschwister:** Nachrichten mit gleichem Parent und gleicher Rolle (hier `3` und `5`)
+ sind Alternativen, zwischen denen der Benutzer wechseln kann.
+- **Fehlgeschlagene Antworten** (`delivery_status = 'failed'`) bleiben im Baum, werden aber
+ beim Aufbau des Modellkontexts übersprungen.
+
+### Drei Arten von „Alternativen“
+
+| Mechanismus | Wo gespeichert | Wofür |
+|---|---|---|
+| Versionen einer Nachricht | `chat_message_versions` (vollständig) und `retry_variants` (Kopie der Inhalte für die Anzeige) | Regenerieren einer Antwort, Bearbeiten. `saveMessageVersion` hält beide synchron |
+| Zweige im Baum | `parent_message_id` + `active_leaf_message_id` | Verschiedene Gesprächsverläufe im selben Chat |
+| Chat-Abzweigung | neuer Chat mit `source_chat_id` + `branched_from_message_id` | Eigener Chat, der an einer bestimmten Nachricht eines anderen Chats beginnt |
+
+---
+
+## Migrationen
+
+`runMigrations` bringt ältere Datenbanken auf den aktuellen Stand. Die Funktion läuft
+**bei jedem Start**, ändert aber nur, was noch fehlt (idempotent).
+
+| Schritt | Was passiert | Wann aktiv |
+|---|---|---|
+| `chat_message_versions` anlegen | Tabelle + Index | Immer, auch bei neuen DBs (existiert nur hier) |
+| `ensureColumn(...)` | Liest Spalten per `PRAGMA table_info`, führt `ALTER TABLE ... ADD COLUMN` nur bei fehlender Spalte aus | Nur bei alten DBs. **Ausnahme:** `chat_messages.sources` und `thinking` existieren nur hier, werden also auch bei neuen DBs angelegt |
+| `UPDATE ... WHERE ... IS NULL` | Setzt Default-Werte in alten Zeilen | Läuft jedes Mal (liest die ganze Tabelle) |
+| Nachrichtenbaum aufbauen | Verknüpft jede Nachricht mit ihrer Vorgängerin (`LAG`), setzt das aktive Blatt | Einmalig, wenn `parent_message_id` neu angelegt wurde |
+| Alte Tabelle `chats` übernehmen | Pro Benutzer ein Chat „Imported chat“ mit allen alten Nachrichten, in einer Transaktion | Einmalig, wenn `chats` existiert und `chat_messages` leer ist |
+| `chats` löschen | `DROP TABLE chats` | Wenn `dropLegacyChats` (Config `DROP_LEGACY_CHATS`, Default `true`) |
+
+Geplante Verbesserung: versionierte Migrationen mit `PRAGMA user_version`, damit jede
+Migration genau einmal läuft (siehe TODO in `schema.ts`).
+
+---
+
+## Bekannte Auffälligkeiten
+
+| Punkt | Details |
+|---|---|
+| Fehlende Fremdschlüssel auf `users` | `chat_sessions`, `personas`, `prompt_templates`, `persona_versions` und alle Marktplatz-Tabellen verweisen nur logisch auf `users`. Das Aufräumen übernimmt `deleteUserTransaction`. SQLite kann Fremdschlüssel nicht per `ALTER TABLE` nachrüsten, dafür muss die Tabelle neu erstellt werden |
+| Umbenennen trotz Fremdschlüssel (zu prüfen) | `renameUserTransaction` ändert zuerst `users.username`. `user_settings`, `chat_memories` und `persona_chat_state` haben einen Fremdschlüssel auf `users` **ohne** `ON UPDATE CASCADE`. Hat der Benutzer dort Einträge, schlägt das Umbenennen vermutlich mit `FOREIGN KEY constraint failed` fehl. Mit einem Test prüfen |
+| `sources`, `thinking`, `chat_message_versions` | Nur in `runMigrations` definiert, nicht in `initializeSchema` |
+| `user_settings.active_persona_id` | Wird gelesen, aber in `repositories.js` nirgends gesetzt |
+| Zwei Orte für Bildanalysen | `attachments.vision_*` und `attachment_vision_analyses`. Prüfen, ob die Spalten noch verwendet werden |
+| Uneinheitliche Zeitstempel | `DATETIME` in `schema.ts`, `TEXT` in `attachments.ts`. In SQLite gleichwertig, aber inkonsistent |
+| Bewertungen ohne Wertebereich | `persona_market_ratings.rating` hat keinen `CHECK`, der Bereich wird nur im Code geprüft |
\ No newline at end of file