/** * umlaut-dictionary — single source of truth for the ae/oe/ue/ss umlaut * correction in `de.json` and for the `umlaut-guard.spec.ts` regression * guard. * * Why an explicit token list instead of a character rule (`ue` -> `ü`, * `oe` -> `ö`, `ae` -> `ä`): a blanket character substitution destroys * correct German. `Quelle` would become `Qülle`, `manuell` would become * `manüll`, `neuen` would become `nün`, `Erzeugnisse` would become * `Erzügnisse`. Replacement therefore only ever targets a whole token * that is an exact key in `UMLAUT_REPLACEMENTS`. * * `UMLAUT_ALLOWLIST` lists every token that legitimately contains * `ae`/`oe`/`ue`/`ss` and is already correct German — it must never be * replaced. `empfaenger` sits on this list purely because it is part of * the example placeholder address `empfaenger@example.com` * (key `testToPlaceholder`): an umlaut inside a placeholder email address * would wrongly suggest umlaut addresses are the expected format, so that * value is skipped entirely (any string containing `@`) rather than * "corrected". */ /** Wrong substitute spelling -> correct German spelling, exact token match only. */ export const UMLAUT_REPLACEMENTS: Record = { loeschen: 'löschen', Loeschen: 'Löschen', geloescht: 'gelöscht', hinzufuegen: 'hinzufügen', Hinzufuegen: 'Hinzufügen', hinzuzufuegen: 'hinzuzufügen', einfuegen: 'einfügen', fuege: 'füge', Fuege: 'Füge', Fuegen: 'Fügen', fuer: 'für', pruefen: 'prüfen', Pruefen: 'Prüfen', Pruefe: 'Prüfe', Pruefung: 'Prüfung', geprueft: 'geprüft', ueberpruefen: 'überprüfen', Ueberpruefe: 'Überprüfe', Zertifikatspruefung: 'Zertifikatsprüfung', aendern: 'ändern', // Nachtrag 2026-09-07: die grossgeschriebenen Formen fehlten. Der Waechter // hat sie nicht gemeldet, weil sein Verdachtsmuster case-sensitiv war und // "Ae"/"Oe" deshalb durchrutschten — mitbehoben in umlaut-guard.spec.ts. Aenderung: 'Änderung', Aenderungen: 'Änderungen', Oeffnen: 'Öffnen', geaendert: 'geändert', Moechten: 'Möchten', moeglich: 'möglich', moegliche: 'mögliche', koennen: 'können', verfuegbar: 'verfügbar', Verfuegbar: 'Verfügbar', Verfuegbare: 'Verfügbare', Verfuegbarkeit: 'Verfügbarkeit', Zurueck: 'Zurück', Zuruecksetzen: 'Zurücksetzen', zuruecksetzen: 'zurücksetzen', zurueckgesetzt: 'zurückgesetzt', rueckgaengig: 'rückgängig', Zusammenfuehren: 'Zusammenführen', zusammenfuehren: 'zusammenführen', bestaetigen: 'bestätigen', Bestaetigen: 'Bestätigen', Passwoerter: 'Passwörter', spaeter: 'später', ueberein: 'überein', uebersprungen: 'übersprungen', ueber: 'über', ungueltig: 'ungültig', Verschluesselung: 'Verschlüsselung', entschluesselt: 'entschlüsselt', ausgewaehlt: 'ausgewählt', Ausgewaehlt: 'Ausgewählt', ausgewaehlte: 'ausgewählte', Ausgewaehlte: 'Ausgewählte', waehle: 'wähle', benoetigt: 'benötigt', noetig: 'nötig', muessen: 'müssen', Domaene: 'Domäne', Einschraenkung: 'Einschränkung', Empfaenger: 'Empfänger', Oberflaeche: 'Oberfläche', Postfaecher: 'Postfächer', Praefix: 'Präfix', Sicherheitsgruenden: 'Sicherheitsgründen', unterstuetzt: 'unterstützt', vertrauenswuerdigen: 'vertrauenswürdigen', zusaetzlich: 'zusätzlich', zusaetzliche: 'zusätzliche', Groesse: 'Größe', Schliessen: 'Schließen', ausschliessen: 'ausschließen', }; /** * Tokens containing `ae`/`oe`/`ue`/`ss` that are already correct German * and must never be touched by the replacement or flagged by the guard. */ export const UMLAUT_ALLOWLIST: readonly string[] = [ 'manuell', 'Manuell', 'Quelle', 'Quellen', 'Quell', 'Quellportal', 'Kalenderquelle', 'Kalenderquellen', 'Energiequellen', 'neue', 'neuen', 'neuere', 'Neue', 'Neues', 'aktuelle', 'Aktuell', 'Aktuelle', 'Aktuelles', 'zuerst', 'dauerhaft', 'Schauen', 'Taktfrequenz', 'Feuerlösch', 'Bergbauerzeugnisse', 'true', 'guest', 'Passwort', 'Adresse', 'Absenderadresse', 'muss', 'musste', 'müssen', 'lassen', 'vergessen', 'stattdessen', 'Wasser', 'Abwasser', 'Hessen', 'Erzeugnisse', 'Druckerzeugnisse', 'Gummierzeugnisse', 'Mineralölerzeugnisse', 'Ausschreibung', 'Ausschreibungen', 'Ausschreibungs', 'Ausschreibungsdetails', 'erfasst', 'erfasster', 'Erfassung', 'Ergebnisse', 'gedrosselt', 'ausgeschlossen', 'Ausgeschlossen', 'Ausschlussliste', 'Informationssysteme', 'Zeitmessung', 'Tessera', 'Passen', 'Passt', 'Fasst', 'Verschlüsselung', 'empfaenger', 'Passwörter', 'vertrauenswürdigen', 'ausschließen', 'entschlüsselt', // Nachtrag 2026-09-07: Abkuerzungen mit doppeltem S. Sie tauchen erst auf, // seit das Verdachtsmuster case-insensitiv prueft — vorher fiel jedes // grossgeschriebene "SS" durch dasselbe Loch wie "Aenderungen". 'RSS', 'RSSGenerator', 'SSL', // 260914-m97: Fehler-melden-Knopf, Pflichtlabel "Was ist passiert?" 'passiert', ];