feat(i18n): complete message parity across all 25 locales
Gitea Actions Runner Test / test-job (push) Successful in 1s
CI / check (push) Successful in 37s
CI / tests-unit (push) Successful in 1m49s
CI / tests-integration (push) Successful in 1m50s
CI / tests-ui (push) Successful in 2m29s
CI / preflight (push) Skipped
CI / deploy (push) Failing after 1m37s

The admin.studio.nitroCleanup section (102 keys) only existed in en and
nl, so 23 locales fell back to English for the entire Nitro Cleanup
panel. The referrals and dailyRewards keys were missing from the same
23 locales, and en itself was missing 6 keys that nl had.

Add the missing keys to every locale with translations, so all 25
locales now carry the same 6063 keys.
This commit is contained in:
openhands committed 2026-09-27 18:38:58 +02:00
1 parent 944527e078
commit bc00ecf08c
24 files changed
+4483 -182

No files matched your search

+195 -8
View File
@@ -787,9 +787,9 @@
"enable": "2FA aktivieren",
"rateLimit": "Too many attempts. Please wait before trying again."
},
"title": "Verbundene Konten",
"subtitle": "Verknüpfe ein Social-Media-Konto, damit du dich mit einem Klick anmelden kannst",
"connected": "Verbunden",
"title": "Verknüpfte Konten",
"subtitle": "Verknüpfe ein soziales Konto, um mit einem Klick anzumelden",
"connected": "Verknüpft",
"unavailable": "Nicht verfügbar",
"login": {
"title": "Anmelden",
@@ -852,7 +852,9 @@
"hidePassword": "Hide",
"accountDetails": "Account details",
"credentials": "Credentials & security",
"newestCitizens": "Newest citizens"
"newestCitizens": "Newest citizens",
"ageVerified": "Ich bin 18+ und stimme der Altersanforderung zu.",
"invitedBy": "Eingeladen von {username}"
},
"forgot": {
"title": "Passwort zurücksetzen",
@@ -1018,7 +1020,9 @@
"cmsErrors": "CMS errors",
"themeBuilder": "Theme builder",
"openSidebar": "Open menu",
"closeSidebar": "Close menu"
"closeSidebar": "Close menu",
"referrals": "Empfehlungen",
"dailyRewards": "Tägliche Belohnungen"
},
"dashboard": {
"title": "Dashboard",
@@ -4306,7 +4310,9 @@
"importAudit": "Audit",
"themeBuilder": "Theme Builder",
"studio": "Studio",
"cmsErrors": "CMS errors"
"cmsErrors": "CMS errors",
"referrals": "Empfehlungen",
"dailyRewards": "Tägliche Belohnungen"
},
"events": "Events",
"eventsSubtitle": "Hotel events and event types",
@@ -5813,6 +5819,64 @@
"NoscopescreatedyetAddonebelow": "No scopes created yet. Add one below.",
"Rename": "Rename"
}
},
"referrals": {
"title": "Empfehlungen",
"subtitle": "Einladungssystem",
"referralsToday": "Empfehlungen heute",
"referralsTotal": "Empfehlungen gesamt",
"invitedTotal": "Einladungen gezählt",
"claims": "Belohnungen abgeholt",
"settings": "Belohnungseinstellungen",
"needed": "Benötigte Empfehlungen",
"rewardAmount": "Belohnungsbetrag",
"rewardCurrency": "Belohnungswährung",
"blockSameIp": "Empfehlungen mit der aktuellen IP des Einladenden ablehnen",
"save": "Einstellungen speichern",
"saving": "Speichern…",
"saved": "Empfehlungseinstellungen gespeichert.",
"saveError": "Empfehlungseinstellungen konnten nicht gespeichert werden.",
"recent": "Letzte Empfehlungen",
"unavailable": "Empfehlungsdaten sind vorübergehend nicht verfügbar.",
"empty": "Noch keine Empfehlungen.",
"inviter": "Einladender",
"invitee": "Eingeladener Benutzer",
"ip": "IP",
"date": "Datum"
},
"dailyRewards": {
"title": "Tägliche Login-Belohnungen",
"subtitle": "Täglicher Login-Belohnungsplan",
"enabled": "Funktionsstatus",
"yes": "Aktiviert",
"no": "Deaktiviert",
"scheduleDays": "Planungstage",
"claimsToday": "Abholungen heute",
"claimsTotal": "Abholungen gesamt",
"status": "Funktionsstatus",
"statusHint": "Wenn deaktiviert, wird die Belohnungskarte ausgeblendet und neue Abholungen werden abgelehnt.",
"disable": "Deaktivieren",
"enable": "Aktivieren",
"schedule": "Belohnungsplan",
"day": "Tag {day}",
"reward": "Belohnung",
"amount": "Betrag",
"actions": "Aktionen",
"addDay": "Tag",
"add": "Tag hinzufügen",
"save": "Speichern",
"saving": "Speichern…",
"saved": "Belohnungsplan gespeichert.",
"cancel": "Abbrechen",
"edit": "Bearbeiten",
"delete": "Löschen",
"created": "Belohnungstag hinzugefügt.",
"updated": "Belohnungstag aktualisiert.",
"deleted": "Belohnungstag entfernt.",
"saveError": "Belohnungstag konnte nicht gespeichert werden.",
"deleteError": "Belohnungstag konnte nicht entfernt werden.",
"confirmDeleteTitle": "Belohnungstag entfernen",
"confirmDeleteBody": "Dieser Belohnungstag wird nicht mehr vergeben. Frühere Abholungen bleiben aufgezeichnet."
}
},
"radioRequests": {
@@ -6223,8 +6287,27 @@
"empty": "You're all caught up. No actions waiting.",
"unavailable": "Some actions could not be checked. Available actions are shown above.",
"retry": "Try again",
"rewardUnavailable": "Referral progress is temporarily unavailable. Please try again."
}
"rewardUnavailable": "Referral progress is temporarily unavailable. Please try again.",
"dailyReward": "Deine tägliche Belohnung ist bereit zur Abholung"
},
"dailyClaimed": "Tägliche Belohnung abgeholt — bis morgen!",
"dailyErrors": {
"already_claimed": "Du hast die tägliche Belohnung heute bereits abgeholt.",
"disabled": "Tägliche Belohnungen sind derzeit deaktiviert.",
"bad_config": "Der tägliche Belohnungsplan ist nicht richtig konfiguriert. Kontaktiere das Team.",
"ratelimit": "Zu viele Versuche. Warte einen Moment und versuche es erneut.",
"error": "Die tägliche Belohnung konnte nicht abgeholt werden. Bitte versuche es erneut."
},
"dailyRewardTitle": "Tägliche Belohnungen",
"dailyRewardHint": "Melde dich jeden Tag an und hole deine Belohnung ab — Serien wachsen bis zu den großen Tagen.",
"dailyRewardDay": "Tag {day}",
"dailyRewardStreak": "{count, plural, one {Serie: # Tag} other {Serie: # Tage}}",
"dailyRewardNextClaim": "Nächste Abholung: {amount} {currency}",
"dailyRewardTomorrow": "Morgen: {amount} {currency}",
"dailyRewardClaim": "Tägliche Belohnung abholen",
"dailyRewardClaimedToday": "Heute abgeholt — komm morgen für die nächste Belohnung wieder.",
"dailyRewardDisabled": "Tägliche Belohnungen sind derzeit deaktiviert. Du kannst das Hotel erkunden.",
"dailyRewardUnavailable": "Der tägliche Belohnungsplan konnte nicht geladen werden. Bitte versuche es erneut."
},
"housekeeping": {
"preview": {
@@ -6502,6 +6585,110 @@
},
"admin": {
"studio": {
"nitroCleanup": {
"alreadyRunning": "Ein Scan läuft bereits — an ihn angehängt.",
"ageUnknown": "Alter unbekannt",
"ageBelow": "< 1T",
"scanButton": "Möbel-Assets scannen",
"scanningAssets": "Assets werden gescannt…",
"cancelButton": "Abbrechen",
"deleteSelected": "Ausgewählte löschen ({count})",
"deleting": "Löschen…",
"redownloadBroken": "Beschädigte erneut herunterladen",
"redownloading": "Erneutes Herunterladen…",
"autoClean": "Alte Fakes automatisch bereinigen",
"cleaning": "Bereinigen…",
"exportManifest": "Manifest exportieren",
"exporting": "Exportieren…",
"phaseStems": "Möbel-Stämme werden geladen…",
"phaseReaddir": "Asset-Verzeichnisse werden gelesen…",
"phaseValidate": ".nitro-Pakete werden validiert…",
"phaseScanning": "Scannen…",
"scanProgressFiles": "{count} Dateien",
"repairProgress": "ok {ok}, fehlgeschlagen {failed}",
"attachedNotice": "Der Scan läuft im Hintergrund weiter — die Ergebnisse erscheinen, wenn er fertig ist.",
"sessionCancelled": "Scan abgebrochen.",
"onlyOldLabel": "Nur Dateien älter als anzeigen",
"onlyOldAgeLabel": "Mindestalter in Tagen für Anzeige",
"onlyOldToggle": "Aktuelle Dateien ausblenden",
"daysLabel": "Tage",
"autoAgeLabel": "Mindestalter in Tagen für automatische Bereinigung",
"loadingResult": "Scan-Ergebnis wird geladen…",
"scannedStat": "Asset-Dateien gescannt",
"cachedNotice": "(zwischengespeichert — Verzeichnisse unverändert)",
"fakeStat": "Falsche Nitros (kein passendes Element)",
"brokenStat": "Beschädigte Nicht lesbar)",
"groupEmpty": "Nichts gefunden",
"selectedCount": "{count} ausgewählt",
"copiesBadge": "{count} Kopien",
"groupFakeLabel": "Falsche Nitros",
"groupFakeDescription": "Diese Dateien passen zu keinem Element in items_base — Reste von gelöschten oder umbenannten Möbeln.",
"groupBrokenLabel": "Beschädigte Nitros",
"groupBrokenDescription": "Diese Dateien gehören zu einem Element, können aber nicht als gültiges Nitro-Paket gelesen werden.",
"groupSwfLabel": "Verwaiste SWFs",
"groupSwfDescription": ".swf-Dateien, die zu keinem Element in items_base passen.",
"groupIconLabel": "Verwaiste Icons",
"groupIconDescription": "Icon-Dateien, die zu keinem Element in items_base passen.",
"warningText": "Das Löschen eines beschädigten .nitro lässt sein Element in der Datenbank ohne Paket — laden Sie es erneut herunter oder lassen Sie die Katalog-Prüfung es später beschaffen. Datenbankzeilen werden von diesem Werkzeug niemals entfernt.",
"onlyAssetsTouched": "Nur Asset-Dateien werden verändert — FurnitureData.json und Datenbankzeilen bleiben unberührt.",
"emptyHint": "Scannen Sie jedes Möbel-Asset-Verzeichnis, um falsche und beschädigte Nitro-Pakete sowie verwaiste SWFs und Icons zu finden. Löschen Sie sie, laden Sie die Beschädigten erneut herunter oder bereinigen Sie alte Reste automatisch.",
"noResult": "Noch kein Scan-Ergebnis — führen Sie zuerst einen Möbel-Asset-Scan durch.",
"scanFailed": "Der Scan ist fehlgeschlagen.",
"confirmDeleteTitle": "{count} Asset-Datei(en) löschen?",
"confirmDeleteDescription": "Die Dateien werden aus jedem Verzeichnis entfernt (public + gespiegelte gamedata). Datenbankzeilen werden niemals verändert.",
"confirmDeleteLabel": "Löschen",
"confirmRepairTitle": "{count} beschädigte(s) .nitro-Paket(e) erneut herunterladen?",
"confirmRepairDescription": "Die Pakete werden erneut aus den konfigurierten nitro-Quellen abgerufen und in jedem Verzeichnis überschrieben (public + gespiegelte gamedata).",
"confirmRepairLabel": "Erneut herunterladen",
"confirmAutoCleanTitle": "Falsche Nitros älter als {days} Tag(e) automatisch bereinigen?",
"confirmAutoCleanDescription": "Nur falsche .nitro-Dateien (kein passendes Element) älter als der Schwellenwert werden entfernt. Beschädigte Pakete und aktuelle Dateien werden niemals verändert.",
"confirmAutoCleanLabel": "Automatisch bereinigen",
"toastDeletePartial": "{copies} Kopie(n) gelöscht, aber einige Dateien konnten nicht entfernt werden",
"toastDeleteDone": "{copies} Dateikopie(n) gelöscht ({deleted} Datei(en))",
"toastRepairDone": "{count} .nitro-Paket(e) repariert",
"toastRepairFailed": "Kein Paket konnte beschafft werden ({failed} fehlgeschlagen)",
"toastRepairCancelled": "Reparatur abgebrochen",
"toastAutoCleanDone": "{deleted} alte falsche .nitro-Dateien bereinigt ({copies} Kopien). {recent} aktuelle + {broken} beschädigte übersprungen.",
"toastAutoCleanNothing": "Nichts alt genug zum Entfernen ({recent} aktuelle, {broken} beschädigte übersprungen)",
"toastManifestDownload": "Scan-Manifest heruntergeladen",
"gamedataTitle": "Spieldaten bereinigen",
"gamedataHint": "Zuerst Vorschau: Dies überschreibt FurnitureData.json, FigureMap.json und FigureData.json. Anders als die Asset-Werkzeuge oben entfernt es Zeilen, die auf nichts verweisen — prüfen Sie die Zahlen, bevor Sie es ausführen.",
"gamedataScan": "Spieldaten-Vorschau",
"gamedataScanning": "Scannen…",
"gamedataRun": "Ausgewählte ausführen",
"gamedataRunning": "Bereinigen…",
"gamedataNoResult": "Noch keine Vorschau — scannen Sie zuerst die Spieldaten-JSON-Dateien.",
"gamedataCount_duplicates": "FurnitureData-Duplikate",
"gamedataCount_orphans": "FurnitureData-Waisen",
"gamedataCount_figureMap": "FigureMap-Probleme",
"gamedataCount_figureData": "Unbenutztes FigureData",
"gamedataPass_dedupeFurnitureData": "FurnitureData deduplizieren",
"gamedataPassDesc_dedupeFurnitureData": "Entfernt wiederholte classnames innerhalb eines Abschnitts und behält den Eintrag mit der höchsten Revision.",
"gamedataPass_cleanFurnitureData": "FurnitureData bereinigen",
"gamedataPassDesc_cleanFurnitureData": "Entfernt Einträge, deren .nitro-Paket in keinem Verzeichnis vorhanden ist.",
"gamedataPass_cleanFigureMap": "FigureMap bereinigen",
"gamedataPassDesc_cleanFigureMap": "Entfernt Teile, die auf eine fehlende Menge in FigureData verweisen, sowie exakte Duplikate.",
"gamedataPass_cleanFigureData": "FigureData bereinigen",
"gamedataPassDesc_cleanFigureData": "Entfernt Mengen, auf die kein FigureMap-Teil verweist, dann Paletten, die kein Mengentyp verwendet. Muss nach FigureMap bereinigen laufen.",
"gamedataNothingSelected": "Wählen Sie mindestens einen Bereinigungsschritt",
"gamedataConfirmTitle": "Spieldaten-JSON-Dateien überschreiben?",
"gamedataConfirmDescription": "{passes} Schritt(e) laufen gegen {duplicates} Duplikatgruppen, {orphans} Waisenzeilen, {figureMap} FigureMap-Probleme und {figureData} unbenutzte FigureData-Einträge. Zeilen werden ohne Sicherungskopie entfernt — dies kann nicht rückgängig gemacht werden.",
"gamedataConfirmLabel": "Dateien überschreiben",
"gamedataDifferingWarning": "Mindestens ein Duplikat ist keine exakte Kopie des Eintrags, der behalten wird, also enthielt die gelöschte Zeile Daten, die der Überlebende nicht hat.",
"gamedataCrossSectionNote": "{count} classname(s) existieren sowohl in roomitemtypes als auch in wallitemtypes. Diese werden nur gemeldet — eines zu entfernen würde den Typ eines Elements ändern.",
"gamedataToastDone": "Bereinigung der Spieldaten entfernte {removed} Zeile(n)",
"gamedataToastNothing": "Spieldaten waren bereits sauber",
"gamedataMaxRemovalsLabel": "Max. Zeilen pro Schritt",
"gamedataMaxRemovalsHint": "0 verwendet den Standardwert 500. Ein Schritt, der mehr entfernen würde, stoppt und fragt statt zu schreiben.",
"gamedataLimitTitle": "{pass} würde {wouldRemove} Zeile(n) entfernen, über dem Limit von {maxRemovals}.",
"gamedataLimitDescription": "Dieser Schritt hat nichts geschrieben, also sind die Dateien unverändert. Prüfen Sie zuerst die Asset-Pfade — ein falsches Verzeichnis lässt jede Zeile wie eine Waise aussehen. Das Anheben des Limits ist ein separater, bewusster Lauf.",
"gamedataLimitOverride": "{wouldRemove} Zeile(n) trotzdem entfernen",
"historyTitle": "Verlauf der automatischen Bereinigung",
"historyScheduled": "geplant",
"historyManual": "manuell",
"historyEntry": "{deleted} entfernt ({copies} Kopien); {recent} aktuelle und {broken} beschädigte übersprungen",
"historyErrors": "{count} Fehler"
},
"importDiagnostics": {
"attempts": "Dateidiagnose",
"preliminary": "Vorprüfung der Adressen; der Inhalt wird beim Import geprüft.",