From c9ab4b9c127a3a5355deac078b1e56adec6f33e0 Mon Sep 17 00:00:00 2001 From: OffByOne <40462192+offbyone1@users.noreply.github.com> Date: Thu, 21 May 2026 20:48:16 +0200 Subject: [PATCH] Add German locale support (#2378) --- app/src/components/LanguageSelect.tsx | 1 + app/src/lib/i18n/I18nContext.tsx | 2 + .../lib/i18n/__tests__/I18nContext.test.tsx | 19 + app/src/lib/i18n/__tests__/coverage.test.ts | 2 +- app/src/lib/i18n/chunks/de-1.ts | 439 +++++++++++++++ app/src/lib/i18n/chunks/de-2.ts | 439 +++++++++++++++ app/src/lib/i18n/chunks/de-3.ts | 389 ++++++++++++++ app/src/lib/i18n/chunks/de-4.ts | 401 ++++++++++++++ app/src/lib/i18n/chunks/de-5.ts | 506 ++++++++++++++++++ app/src/lib/i18n/de.ts | 12 + app/src/lib/i18n/types.ts | 1 + app/src/store/localeSlice.test.ts | 7 + app/src/store/localeSlice.ts | 1 + scripts/apply-i18n-translations.ts | 1 + scripts/i18n-coverage.ts | 1 + 15 files changed, 2220 insertions(+), 1 deletion(-) create mode 100644 app/src/lib/i18n/chunks/de-1.ts create mode 100644 app/src/lib/i18n/chunks/de-2.ts create mode 100644 app/src/lib/i18n/chunks/de-3.ts create mode 100644 app/src/lib/i18n/chunks/de-4.ts create mode 100644 app/src/lib/i18n/chunks/de-5.ts create mode 100644 app/src/lib/i18n/de.ts diff --git a/app/src/components/LanguageSelect.tsx b/app/src/components/LanguageSelect.tsx index 396790e5a..ebd6e5405 100644 --- a/app/src/components/LanguageSelect.tsx +++ b/app/src/components/LanguageSelect.tsx @@ -15,6 +15,7 @@ const LOCALE_OPTIONS: Array<{ value: Locale; flag: string; label: string }> = [ { value: 'fr', flag: '🇫🇷', label: 'Français' }, { value: 'bn', flag: '🇧🇩', label: 'বাংলা' }, { value: 'pt', flag: '🇵🇹', label: 'Português' }, + { value: 'de', flag: '🇩🇪', label: 'Deutsch' }, { value: 'ru', flag: '🇷🇺', label: 'Русский' }, { value: 'id', flag: '🇮🇩', label: 'Bahasa Indonesia' }, { value: 'it', flag: '🇮🇹', label: 'Italiano' }, diff --git a/app/src/lib/i18n/I18nContext.tsx b/app/src/lib/i18n/I18nContext.tsx index 022b32f92..52395ba3d 100644 --- a/app/src/lib/i18n/I18nContext.tsx +++ b/app/src/lib/i18n/I18nContext.tsx @@ -3,6 +3,7 @@ import { createContext, type ReactNode, useCallback, useContext, useEffect, useM import { useAppSelector } from '../../store/hooks'; import ar from './ar'; import bn from './bn'; +import de from './de'; import en from './en'; import es from './es'; import fr from './fr'; @@ -30,6 +31,7 @@ const translations: Record> = { fr, bn, pt, + de, ru, id, it, diff --git a/app/src/lib/i18n/__tests__/I18nContext.test.tsx b/app/src/lib/i18n/__tests__/I18nContext.test.tsx index a81e9a697..f52cb2d02 100644 --- a/app/src/lib/i18n/__tests__/I18nContext.test.tsx +++ b/app/src/lib/i18n/__tests__/I18nContext.test.tsx @@ -4,6 +4,7 @@ import { Provider } from 'react-redux'; import { describe, expect, it } from 'vitest'; import localeReducer, { setLocale } from '../../../store/localeSlice'; +import de from '../de'; import en from '../en'; import { I18nProvider, useT } from '../I18nContext'; import type { Locale, TranslationMap } from '../types'; @@ -58,6 +59,15 @@ describe('I18nProvider', () => { expect(screen.getByTestId('missing-key')).toHaveTextContent('this.key.does.not.exist'); }); + it('serves German translations from the registered locale map', () => { + renderWithLocale('de'); + + expect(screen.getByTestId('locale')).toHaveTextContent('de'); + expect(screen.getByText('Sprache')).toBeInTheDocument(); + expect(screen.getByText('App-Daten löschen')).toBeInTheDocument(); + expect(screen.getByText('Beenden')).toBeInTheDocument(); + }); + it('keeps the Simplified Chinese locale complete against English keys', () => { const englishKeys = Object.keys(unwrapTranslationMap(en)); const simplifiedChinese = unwrapTranslationMap(zhCN); @@ -66,4 +76,13 @@ describe('I18nProvider', () => { expect(englishKeys.length).toBeGreaterThan(0); expect(missingKeys).toEqual([]); }); + + it('keeps the German locale complete against English keys', () => { + const englishKeys = Object.keys(unwrapTranslationMap(en)); + const german = unwrapTranslationMap(de); + const missingKeys = englishKeys.filter(key => !(key in german)); + + expect(englishKeys.length).toBeGreaterThan(0); + expect(missingKeys).toEqual([]); + }); }); diff --git a/app/src/lib/i18n/__tests__/coverage.test.ts b/app/src/lib/i18n/__tests__/coverage.test.ts index 2fd786912..43540a66e 100644 --- a/app/src/lib/i18n/__tests__/coverage.test.ts +++ b/app/src/lib/i18n/__tests__/coverage.test.ts @@ -3,7 +3,7 @@ import { describe, expect, it } from 'vitest'; import enAggregate from '../en'; const CHUNK_COUNT = 5; -const LOCALES = ['zh-CN', 'hi', 'es', 'ar', 'fr', 'bn', 'pt', 'ru', 'id', 'it'] as const; +const LOCALES = ['zh-CN', 'hi', 'es', 'ar', 'fr', 'bn', 'pt', 'de', 'ru', 'id', 'it'] as const; interface ChunkModule { default: Record; diff --git a/app/src/lib/i18n/chunks/de-1.ts b/app/src/lib/i18n/chunks/de-1.ts new file mode 100644 index 000000000..eac4aed8c --- /dev/null +++ b/app/src/lib/i18n/chunks/de-1.ts @@ -0,0 +1,439 @@ +import type { TranslationMap } from '../types'; + +// German (Deutsch) translations. Each chunk maps to chunks/en-1.ts. +const de1: TranslationMap = { + 'nav.home': 'Start', + 'nav.human': 'Human', + 'nav.chat': 'Chat', + 'nav.connections': 'Verbindungen', + 'nav.memory': 'Intelligenz', + 'nav.alerts': 'Benachrichtigungen', + 'nav.rewards': 'Belohnungen', + 'nav.settings': 'Einstellungen', + 'common.cancel': 'Abbrechen', + 'common.save': 'Speichern', + 'common.confirm': 'Bestätigen', + 'common.delete': 'Löschen', + 'common.edit': 'Bearbeiten', + 'common.create': 'Erstellen', + 'common.search': 'Suchen', + 'common.loading': 'Laden…', + 'common.error': 'Fehler', + 'common.success': 'Erfolg', + 'common.back': 'Zurück', + 'common.next': 'Weiter', + 'common.finish': 'Fertig', + 'common.close': 'Schließen', + 'common.enabled': 'Aktiviert', + 'common.disabled': 'Deaktiviert', + 'common.on': 'Ein', + 'common.off': 'Aus', + 'common.yes': 'Ja', + 'common.no': 'Nein', + 'common.ok': 'Verstanden', + 'common.retry': 'Erneut versuchen', + 'common.copy': 'Kopieren', + 'common.copied': 'Kopiert', + 'common.learnMore': 'Mehr erfahren', + 'common.seeAll': 'Alle anzeigen', + 'common.dismiss': 'Ausblenden', + 'common.clear': 'Leeren', + 'common.reset': 'Zurücksetzen', + 'common.refresh': 'Aktualisieren', + 'common.export': 'Exportieren', + 'common.import': 'Importieren', + 'common.upload': 'Hochladen', + 'common.download': 'Herunterladen', + 'common.add': 'Hinzufügen', + 'common.remove': 'Entfernen', + 'common.showMore': 'Mehr anzeigen', + 'common.showLess': 'Weniger anzeigen', + 'common.submit': 'Senden', + 'common.continue': 'Weiter', + 'settings.general': 'Allgemein', + 'settings.featuresAndAI': 'Funktionen und KI', + 'settings.billingAndRewards': 'Abrechnung und Prämien', + 'settings.support': 'Unterstützung', + 'settings.advanced': 'Erweitert', + 'settings.dangerZone': 'Gefahrenbereich', + 'settings.account': 'Konto', + 'settings.accountDesc': 'Wiederherstellungsphrase, Team, Verbindungen und Privatsphäre', + 'settings.notifications': 'Benachrichtigungen', + 'settings.notificationsDesc': '„Bitte nicht stören“ und Benachrichtigungskontrollen pro Konto', + 'settings.features': 'Funktionen', + 'settings.featuresDesc': 'Bildschirmbewusstsein, Nachrichten und Tools', + 'settings.aiModels': 'KI & Modelle', + 'settings.aiModelsDesc': 'Lokales KI-Modell-Setup, Downloads und LLM-Anbieter', + 'settings.ai': 'KI-Konfiguration', + 'settings.aiDesc': 'Cloud-Anbieter, lokale Ollama-Modelle und Routing pro Workload', + 'settings.billingUsage': 'Abrechnung und Nutzung', + 'settings.billingUsageDesc': 'Abonnementplan, Guthaben und Zahlungsmethoden', + 'settings.rewards': 'Belohnungen', + 'settings.rewardsDesc': 'Empfehlungen, Gutscheine und verdiente Credits', + 'settings.restartTour': 'Tour neu starten', + 'settings.restartTourDesc': 'Wiederhole die Produktanleitung von Anfang an', + 'settings.about': 'Über', + 'settings.aboutDesc': 'App-Version und Software-Updates', + 'settings.developerOptions': 'Fortgeschritten', + 'settings.developerOptionsDesc': + 'KI-Konfiguration, Nachrichtenkanäle, Tools, Diagnose und Debug-Panels', + 'settings.clearAppData': 'App-Daten löschen', + 'settings.clearAppDataDesc': 'Melde dich ab und lösche alle lokalen App-Daten dauerhaft', + 'settings.logOut': 'Abmelden', + 'settings.logOutDesc': 'Melde dich von deinem Konto ab', + 'settings.language': 'Sprache', + 'settings.languageDesc': 'Anzeigesprache für die App-Oberfläche', + 'settings.alerts': 'Warnungen', + 'settings.alertsDesc': + 'Sieh dir aktuelle Benachrichtigungen und Aktivitäten in deinem Posteingang an', + 'settings.account.recoveryPhrase': 'Wiederherstellungssatz', + 'settings.account.recoveryPhraseDesc': + 'Sieh dir deinen Kontowiederherstellungssatz an und sichere ihn', + 'settings.account.team': 'Team', + 'settings.account.teamDesc': 'Verwalte Teammitglieder und Berechtigungen', + 'settings.account.connections': 'Verbindungen', + 'settings.account.connectionsDesc': 'Verwalte verknüpfte Konten und Dienste', + 'settings.account.privacy': 'Privatsphäre', + 'settings.account.privacyDesc': 'Kontrolliere, welche Daten deinen Computer verlassen', + 'migration.title': 'Von einem anderen Assistenten importieren', + 'migration.description': + 'Speicher und Notizen von einem anderen lokalen Assistenten in diesen Arbeitsbereich migrieren. Beginne mit einer Vorschau, um genau zu sehen, was sich ändern würde, und kopiere dann die Daten mit „Übernehmen“. Dein aktueller Speicher wird zunächst gesichert.', + 'migration.vendorLabel': 'Quellanbieter', + 'migration.sourceLabel': 'Quellarbeitsbereichspfad (optional)', + 'migration.sourcePlaceholder': + 'Zur automatischen Erkennung leer lassen (z. B. ~/.openclaw/workspace)', + 'migration.sourceHint': + 'Wenn leer, wird standardmäßig der Standardspeicherort des Anbieters verwendet. Lege einen expliziten Pfad fest, wenn du den Arbeitsbereich an einen anderen Ort verschoben hast.', + 'migration.previewAction': 'Vorschau', + 'migration.previewRunning': 'Vorschau...', + 'migration.applyAction': 'Import anwenden', + 'migration.applyRunning': 'Importieren…', + 'migration.applyDisclaimer': + '„Anwenden“ wird nach einer erfolgreichen Vorschau derselben Quelle freigeschaltet. Vor jedem Import wird der vorhandene Speicher gesichert.', + 'migration.reportTitlePreview': 'Vorschau – noch nichts importiert', + 'migration.reportTitleApplied': 'Import abgeschlossen', + 'migration.report.source': 'Quellarbeitsbereich', + 'migration.report.target': 'Zielarbeitsbereich', + 'migration.report.fromSqlite': 'Von SQLite (brain.db)', + 'migration.report.fromMarkdown': 'Von Markdown', + 'migration.report.imported': 'Importiert', + 'migration.report.skippedUnchanged': 'Übersprungen (unverändert)', + 'migration.report.renamedConflicts': 'Aufgrund eines Konflikts umbenannt', + 'migration.report.warnings': 'Warnungen', + 'migration.report.previewHint': + 'Es wurden noch keine Daten importiert. Klicke auf Import anwenden, um ihn zu kopieren.', + 'migration.report.appliedHint': + 'Importierte Einträge sind jetzt in deinem Speicher. Führe die Vorschau erneut aus, wenn du noch einmal vergleichen möchtest.', + 'migration.hermesComingSoonPrefix': 'Hermes-Importeur ist auf der Roadmap – siehe ', + 'migration.hermesComingSoonSuffix': + ' für den Kontext. Wähle noch heute OpenClaw für die Migration; Hermes landet in einem Follow-up.', + 'migration.hermesLinkText': '#1440', + 'migration.confirmImport.singular': + 'Eintrag {count} in den aktuellen Arbeitsbereich importieren?\n\nQuelle: {source}\nZiel: {target}\n\nVorhandener Speicher wird gesichert, bevor der Import ausgeführt wird.', + 'migration.confirmImport.plural': + '{count} Einträge in den aktuellen Arbeitsbereich importieren?\n\nQuelle: {source}\nZiel: {target}\n\nVorhandener Speicher wird gesichert, bevor der Import ausgeführt wird.', + 'settings.notifications.doNotDisturb': 'Bitte nicht stören', + 'settings.notifications.doNotDisturbDesc': + 'Pausiere alle Benachrichtigungen für einen festgelegten Zeitraum', + 'settings.notifications.channelControls': 'Steuerung pro Kanal', + 'settings.notifications.channelControlsDesc': + 'Konfiguriere Benachrichtigungseinstellungen für jeden Kanal', + 'settings.features.screenAwareness': 'Bildschirmbewusstsein', + 'settings.features.screenAwarenessDesc': 'Lass den Assistenten dein aktives Fenster sehen', + 'settings.features.messaging': 'Nachrichten', + 'settings.features.messagingDesc': 'Einstellungen für die Kanal- und Messaging-Integration', + 'settings.features.tools': 'Werkzeuge', + 'settings.features.toolsDesc': 'Verwalte verbundene Tools und Integrationen', + 'settings.ai.localSetup': 'Lokales KI-Setup', + 'settings.ai.localSetupDesc': 'Lade lokale KI-Modelle herunter und konfiguriere sie', + 'settings.ai.llmProvider': 'LLM Anbieter', + 'settings.ai.llmProviderDesc': 'Wähle und konfiguriere deinen KI-Anbieter', + 'clearData.title': 'App-Daten löschen', + 'clearData.warning': + 'Dadurch wirst du abgemeldet und lokale App-Daten werden dauerhaft gelöscht, einschließlich:', + 'clearData.bulletSettings': 'App-Einstellungen und Konversationen', + 'clearData.bulletCache': 'Alle Daten des lokalen Integrationscache', + 'clearData.bulletWorkspace': 'Arbeitsbereichsdaten', + 'clearData.bulletOther': 'Alle anderen lokalen Daten', + 'clearData.irreversible': 'Diese Aktion kann nicht rückgängig gemacht werden.', + 'clearData.clearing': 'App-Daten löschen...', + 'clearData.failed': 'Daten löschen und Abmelden fehlgeschlagen. Bitte versuche es erneut.', + 'clearData.failedLogout': 'Abmelden fehlgeschlagen. Bitte versuche es erneut.', + 'clearData.failedPersist': + 'Der persistente App-Status konnte nicht gelöscht werden. Bitte versuche es erneut.', + 'welcome.title': 'Willkommen bei OpenHuman', + 'welcome.subtitle': + 'Deine persönliche KI-Superintelligenz. Privat, einfach und äußerst leistungsstark.', + 'welcome.connectPrompt': 'Konfiguriere RPC URL (Erweitert)', + 'welcome.selectRuntime': 'Wähle eine Laufzeit aus', + 'welcome.urlPlaceholder': 'http://localhost:8089', + 'welcome.invalidUrl': 'Bitte gib einen gültigen HTTP oder HTTPS URL ein.', + 'welcome.connecting': 'Testen', + 'welcome.connect': 'Testen', + 'home.greeting': 'Guten Morgen', + 'home.greetingAfternoon': 'Guten Tag', + 'home.greetingEvening': 'Guten Abend', + 'home.askAssistant': 'Frag deinen Assistenten etwas ...', + 'home.statusOk': + 'Dein Gerät ist verbunden. Lass die App laufen, um die Verbindung aufrechtzuerhalten. Sende deinem Agenten über die Schaltfläche unten eine Nachricht.', + 'home.statusBackendOnly': + 'Verbindung zum Backend wird wiederhergestellt. Dein Agent wird in Kürze wieder verfügbar sein.', + 'home.statusCoreUnreachable': + 'Der lokale Core-Sidecar reagiert nicht. Der Hintergrundprozess OpenHuman ist möglicherweise abgestürzt oder konnte nicht gestartet werden.', + 'home.statusInternetOffline': + 'Dein Gerät ist gerade offline. Prüfe dein Netzwerk oder starte die App neu, um die Verbindung wiederherzustellen.', + 'home.restartCore': 'Starte Core neu', + 'home.restartingCore': 'Kern wird neu gestartet...', + 'home.themeToggle.toLight': 'Wechsle in den Lichtmodus', + 'home.themeToggle.toDark': 'Wechsle in den Dunkelmodus', + 'chat.newThread': 'Neuer Thread', + 'chat.typeMessage': 'Gib eine Nachricht ein...', + 'chat.send': 'Nachricht senden', + 'chat.thinking': 'Denken...', + 'chat.noMessages': 'Noch keine Nachrichten', + 'chat.startConversation': 'Beginne ein Gespräch', + 'chat.regenerate': 'Regenerieren', + 'chat.copyResponse': 'Antwort kopieren', + 'chat.citations': 'Zitate', + 'chat.toolUsed': 'Werkzeug verwendet', + 'scope.legacy': 'Vermächtnis', + 'scope.user': 'Benutzer', + 'scope.project': 'Projekt', + 'skills.title': 'Verbindungen', + 'skills.search': 'Verbindungen suchen...', + 'skills.noResults': 'Keine Verbindungen gefunden', + 'skills.connect': 'Verbinden', + 'skills.disconnect': 'Trennen', + 'skills.configure': 'Verwalten', + 'skills.connected': 'Verbunden', + 'skills.available': 'Verfügbar', + 'skills.addAccount': 'Konto hinzufügen', + 'skills.channels': 'Kanäle', + 'skills.integrations': 'Integrationen', + 'memory.title': 'Erinnerung', + 'memory.search': 'Erinnerungen suchen...', + 'memory.noResults': 'Keine Erinnerungen gefunden', + 'memory.empty': + 'Noch keine Erinnerungen. Erinnerungen werden automatisch erstellt, während du interagierst.', + 'memory.tab.memory': 'Erinnerung', + 'memory.tab.subconscious': 'Unterbewusstsein', + 'memory.tab.dreams': 'Träume', + 'memory.tab.calls': 'Anrufe', + 'memory.tab.settings': 'Einstellungen', + 'memory.analyzeNow': 'Jetzt analysieren', + 'alerts.title': 'Warnungen', + 'alerts.empty': 'Noch keine Benachrichtigungen', + 'alerts.markAllRead': 'Alle als gelesen markieren', + 'alerts.unread': 'ungelesen', + 'rewards.title': 'Belohnungen', + 'rewards.referrals': 'Empfehlungen', + 'rewards.coupons': 'Einlösen', + 'rewards.credits': 'Credits', + 'rewards.referralCode': 'Dein Empfehlungscode', + 'rewards.copyCode': 'Code kopieren', + 'rewards.share': 'Teilen', + 'onboarding.welcome': 'Hallo. Ich bin OpenHuman.', + 'onboarding.welcomeDesc': + 'Dein superintelligenter KI-Assistent, der auf deinem Computer läuft. Privat, einfach und äußerst leistungsstark.', + 'onboarding.context': 'Kontexterfassung', + 'onboarding.contextDesc': 'Verbinde die Tools und Dienste, die du täglich nutzt.', + 'onboarding.localAI': 'Lokale KI', + 'onboarding.localAIDesc': + 'Richte ein lokales KI-Modell ein, das auf deinem Computer ausgeführt wird.', + 'onboarding.chatProvider': 'Chat-Anbieter', + 'onboarding.chatProviderDesc': 'Wähle aus, wie du mit deinem Assistenten interagieren möchtest.', + 'onboarding.referral': 'Empfehlung', + 'onboarding.referralDesc': 'Wende einen Empfehlungscode an, falls du einen hast.', + 'onboarding.finish': 'Schließe die Einrichtung', + 'onboarding.finishDesc': 'Du bist bereit! Beginne mit der Verwendung von OpenHuman.', + 'onboarding.skip': 'Überspringen', + 'onboarding.getStarted': 'Lege los', + 'onboarding.runtimeChoice.title': 'Wie möchtest du OpenHuman starten?', + 'onboarding.runtimeChoice.subtitle': + 'Wähle das Setup, das am besten zu dir passt. Du kannst es später in den Einstellungen ändern.', + 'onboarding.runtimeChoice.cloud.title': 'Einfach', + 'onboarding.runtimeChoice.cloud.tagline': 'Lass OpenHuman alles für dich verwalten.', + 'onboarding.runtimeChoice.cloud.f1': 'Integrierte Sicherheit', + 'onboarding.runtimeChoice.cloud.f2': 'Token-Komprimierung, um deine Nutzung weiter auszudehnen', + 'onboarding.runtimeChoice.cloud.f3': 'Ein Abonnement, jedes Modell inklusive', + 'onboarding.runtimeChoice.cloud.f4': 'Keine API Schlüssel zum Verwalten', + 'onboarding.runtimeChoice.cloud.f5': 'Einfach einzurichten', + 'onboarding.runtimeChoice.custom.title': 'Führe Benutzerdefiniert aus', + 'onboarding.runtimeChoice.custom.tagline': + 'Bring deine eigenen Schlüssel mit. Volle Kontrolle darüber, was du verwendest.', + 'onboarding.runtimeChoice.custom.f1': 'Du brauchst für fast alles API-Schlüssel', + 'onboarding.runtimeChoice.custom.f2': 'Nutzt Dienste wieder, für die du bereits bezahlt hast', + 'onboarding.runtimeChoice.custom.f3': 'Kann kostenlos sein, wenn du alles lokal ausführst', + 'onboarding.runtimeChoice.custom.f4': 'Mehr Setup, mehr Knöpfe', + 'onboarding.runtimeChoice.custom.f5': 'Am besten für Power-User und Entwickler geeignet', + 'onboarding.runtimeChoice.cloud.creditHighlight': '1 $ Gratisguthaben zum Ausprobieren', + 'onboarding.runtimeChoice.continueCloud': 'Fahre mit „Einfach“ fort', + 'onboarding.runtimeChoice.continueCustom': 'Fahre mit Benutzerdefiniert fort', + 'onboarding.runtimeChoice.recommended': 'Empfohlen', + 'onboarding.apiKeys.title': 'Fügen wir deine API-Schlüssel hinzu', + 'onboarding.apiKeys.subtitle': + 'Du kannst sie jetzt einfügen oder überspringen und später unter „Einstellungen“ > „KI“ hinzufügen. Schlüssel werden auf diesem Gerät gespeichert und im Ruhezustand verschlüsselt.', + 'onboarding.apiKeys.openaiLabel': 'OpenAI API Schlüssel', + 'onboarding.apiKeys.openaiPlaceholder': 'sk-...', + 'onboarding.apiKeys.anthropicLabel': 'Anthropic API Schlüssel', + 'onboarding.apiKeys.anthropicPlaceholder': 'sk-ant-...', + 'onboarding.apiKeys.saveError': + 'Der Schlüssel konnte nicht gespeichert werden. Bitte prüfe ihn noch einmal und versuche es erneut.', + 'onboarding.apiKeys.skipForNow': 'Erstmal überspringen', + 'onboarding.apiKeys.continue': 'Speichern und fortfahren', + 'onboarding.apiKeys.saving': 'Sparen…', + 'onboarding.custom.stepperInference': 'Schlussfolgerung', + 'onboarding.custom.stepperVoice': 'Stimme', + 'onboarding.custom.stepperOAuth': 'OAuth', + 'onboarding.custom.stepperSearch': 'Suchen', + 'onboarding.custom.stepperMemory': 'Erinnerung', + 'onboarding.custom.stepCounter': 'Schritt {n} von {total}', + 'onboarding.custom.defaultTitle': 'Standard', + 'onboarding.custom.defaultSubtitle': 'Lass OpenHuman das für dich erledigen.', + 'onboarding.custom.configureTitle': 'Konfigurieren', + 'onboarding.custom.configureSubtitle': 'Ich wähle aus, was ich verwenden möchte.', + 'onboarding.custom.progressAriaLabel': 'Onboarding-Fortschritt', + 'onboarding.custom.continue': 'Weiter', + 'onboarding.custom.back': 'Zurück', + 'onboarding.custom.finish': 'Schließe die Einrichtung', + 'onboarding.custom.configureLater': + 'Du kannst die Verknüpfung nach dem Onboarding abschließen. Sobald du fertig bist, wirst du auf die passende Einstellungsseite weitergeleitet.', + 'onboarding.custom.openSettings': 'In den Einstellungen öffnen', + 'onboarding.custom.inference.title': 'Schlussfolgerung (Text)', + 'onboarding.custom.inference.subtitle': + 'Welches Sprachmodell soll deine Fragen beantworten und deine Agenten betreiben?', + 'onboarding.custom.inference.defaultDesc': + 'OpenHuman leitet jede Arbeitslast an ein sinnvolles Standardmodell weiter. Keine Schlüssel, keine Einrichtung.', + 'onboarding.custom.inference.configureDesc': + 'Bring deinen eigenen OpenAI- oder Anthropic-Schlüssel mit. Wir verwenden ihn für jede textbasierte Arbeitslast.', + 'onboarding.custom.voice.title': 'Stimme', + 'onboarding.custom.voice.subtitle': 'Speech-to-Text und Text-to-Speech für den Sprachmodus.', + 'onboarding.custom.voice.defaultDesc': + 'OpenHuman wird mit verwaltetem STT/TTS geliefert, das einfach funktioniert. Nichts zu verkabeln.', + 'onboarding.custom.voice.configureDesc': + 'Verwende dein eigenes ElevenLabs / OpenAI Whisper / usw. Konfiguriere es in den Einstellungen › Stimme.', + 'onboarding.custom.oauth.title': 'Verbindungen (OAuth)', + 'onboarding.custom.oauth.subtitle': + 'Gmail, Slack, Notion und andere verbundene Dienste, die OAuth benötigen.', + 'onboarding.custom.oauth.defaultDesc': + 'OpenHuman führt einen verwalteten Composio-Arbeitsbereich aus. Ein Klick, um jeden Dienst später zu verbinden.', + 'onboarding.custom.oauth.configureDesc': + 'Bring dein eigenes Composio-Konto / API-Schlüssel mit. Konfiguriere unter Einstellungen › Verbindungen.', + 'onboarding.custom.search.title': 'Websuche', + 'onboarding.custom.search.subtitle': 'Wie OpenHuman das Web in deinem Namen durchsucht.', + 'onboarding.custom.search.defaultDesc': + 'OpenHuman verwendet ein verwaltetes Such-Backend. Keine Schlüssel erforderlich.', + 'onboarding.custom.search.configureDesc': + 'Bring deinen eigenen Suchanbieterschlüssel mit (Tavily, Brave usw.). Konfiguriere unter Einstellungen › Extras.', + 'onboarding.custom.memory.title': 'Erinnerung', + 'onboarding.custom.memory.subtitle': + 'Wie OpenHuman sich deinen Kontext, deine Vorlieben und frühere Gespräche merkt.', + 'onboarding.custom.memory.defaultDesc': + 'OpenHuman verwaltet die Speicherung und den Abruf des Speichers automatisch. Nichts einzurichten.', + 'onboarding.custom.memory.configureDesc': + 'Überprüfe, exportiere oder lösche den Speicher selbst. Konfiguriere in den Einstellungen › Speicher.', + 'accounts.addAccount': 'Konto hinzufügen', + 'accounts.manageAccounts': 'Konten verwalten', + 'accounts.noAccounts': 'Keine Konten verbunden', + 'accounts.connectAccount': 'Verbinde ein Konto, um loszulegen', + 'accounts.agent': 'Agent', + 'accounts.respondQueue': 'Antwortwarteschlange', + 'accounts.disconnect': 'Trennen', + 'accounts.disconnectConfirm': 'Möchtest du dieses Konto wirklich trennen?', + 'accounts.searchAccounts': 'Konten durchsuchen...', + 'channels.title': 'Kanäle', + 'channels.configure': 'Kanal konfigurieren', + 'channels.setup': 'Einrichtung', + 'channels.noChannels': 'Keine Kanäle konfiguriert', + 'channels.addChannel': 'Kanal hinzufügen', + 'channels.status.connected': 'Verbunden', + 'channels.status.disconnected': 'Nicht verbunden', + 'channels.status.error': 'Fehler', + 'channels.status.configuring': 'Konfigurieren', + 'channels.defaultMessaging': 'Standard-Messaging-Kanal', + 'webhooks.title': 'Webhooks', + 'webhooks.create': 'Erstelle einen Webhook', + 'webhooks.noWebhooks': 'Keine Webhooks konfiguriert', + 'webhooks.url': 'URL', + 'webhooks.secret': 'Geheimnis', + 'webhooks.events': 'Veranstaltungen', + 'webhooks.archiveDirectory': 'Archivverzeichnis', + 'webhooks.todayFile': 'Heutige Akte', + 'invites.title': 'Lädt ein', + 'invites.create': 'Einladung erstellen', + 'invites.noInvites': 'Keine ausstehenden Einladungen', + 'invites.code': 'Einladungscode', + 'invites.copyLink': 'Link kopieren', + 'devOptions.title': 'Fortgeschritten', + 'devOptions.diagnostics': 'Diagnose', + 'devOptions.diagnosticsDesc': 'Systemzustand, Protokolle und Leistungsmetriken', + 'devOptions.debugPanels': 'Debug-Panels', + 'devOptions.debugPanelsDesc': 'Feature-Flags, Zustandsprüfung und Debugging-Tools', + 'devOptions.webhooks': 'Webhooks', + 'devOptions.webhooksDesc': 'Konfiguriere und teste Webhook-Integrationen', + 'devOptions.memoryInspection': 'Speicherinspektion', + 'devOptions.memoryInspectionDesc': 'Speichereinträge durchsuchen, abfragen und verwalten', + 'voice.pushToTalk': 'Push-to-Talk', + 'voice.recording': 'Aufnahme...', + 'voice.processing': 'Verarbeitung...', + 'voice.languageHint': 'Sprache', + 'misc.rehydrating': 'Deine Daten werden geladen...', + 'misc.checkingServices': 'Dienste prüfen...', + 'misc.serviceUnavailable': 'Dienst nicht verfügbar', + 'misc.somethingWentWrong': 'Etwas ist schief gelaufen', + 'misc.tryAgainLater': 'Bitte versuche es später noch einmal.', + 'misc.restartApp': 'App neu starten', + 'misc.updateAvailable': 'Update verfügbar', + 'misc.updateNow': 'Jetzt aktualisieren', + 'misc.updateLater': 'Später', + 'misc.downloading': 'Herunterladen...', + 'misc.installing': 'Installieren...', + 'misc.beta': + 'OpenHuman befindet sich in der frühen Betaphase. Teile uns gerne dein Feedback mit oder melde Fehler, auf die du stößt – jede Meldung hilft uns, schneller zu liefern.', + 'misc.betaFeedback': 'Feedback senden', + 'mnemonic.title': 'Wiederherstellungssatz', + 'mnemonic.warning': + 'Schreibe diese Wörter der Reihe nach auf und bewahre sie an einem sicheren Ort auf.', + 'mnemonic.copyWarning': + 'Gib niemals deine Wiederherstellungsphrase weiter. Jeder mit diesen Wörtern kann auf dein Konto zugreifen.', + 'mnemonic.copied': 'Wiederherstellungsphrase in die Zwischenablage kopiert', + 'mnemonic.reveal': 'Satz enthüllen', + 'mnemonic.hidden': 'Die Wiederherstellungsphrase ist ausgeblendet', + 'privacy.title': 'Datenschutz und Sicherheit', + 'privacy.description': 'Transparenzbericht der an externe Dienste gesendeten Daten.', + 'privacy.empty': 'Keine externen Datenübertragungen erkannt.', + 'privacy.whatLeavesComputer': 'Was deinen Computer verlässt', + 'privacy.loading': 'Datenschutzdetails werden geladen...', + 'privacy.loadError': + 'Die Live-Datenschutzliste konnte nicht geladen werden. Die unten aufgeführten Analytics-Steuerelemente funktionieren weiterhin.', + 'privacy.noCapabilities': 'Derzeit geben keine Funktionen Datenbewegungen offen.', + 'privacy.sentTo': 'Gesendet an', + 'privacy.leavesDevice': 'Verlässt das Gerät', + 'privacy.staysLocal': 'Bleibt lokal', + 'privacy.anonymizedAnalytics': 'Anonymisierte Analysen', + 'privacy.shareAnonymizedData': 'Teile anonymisierte Nutzungsdaten', + 'privacy.shareAnonymizedDataDesc': + 'Hilf mit, OpenHuman zu verbessern, indem du anonyme Absturzberichte und Nutzungsanalysen teilst. Alle Daten sind vollständig anonymisiert – es werden niemals persönliche Daten, Nachrichten, Wallet-Schlüssel oder Sitzungsinformationen erfasst.', + 'privacy.meetingFollowUps': 'Nachbereitung von Besprechungen', + 'privacy.autoHandoffMeet': 'Automatische Übergabe Google Meet-Transkripte an den Orchestrator', + 'privacy.autoHandoffMeetDesc': + 'Wenn ein Google Meet-Anruf endet, kann der Orchestrator von OpenHuman das Transkript lesen und Maßnahmen wie das Verfassen von Nachrichten, das Planen von Folgemaßnahmen oder das Veröffentlichen von Zusammenfassungen in deinem verbundenen Slack-Arbeitsbereich ergreifen. Standardmäßig deaktiviert.', + 'privacy.analyticsDisclaimer': + 'Alle Analysen und Fehlerberichte sind vollständig anonymisiert. Wenn diese Option aktiviert ist, erfassen wir nur Absturzinformationen, den Gerätetyp und den Dateispeicherort von Fehlern. Wir greifen niemals auf deine Nachrichten, Sitzungsdaten, Wallet-Schlüssel, API-Schlüssel oder andere persönlich identifizierbare Informationen zu. Du kannst diese Einstellung jederzeit ändern.', + 'settings.about.version': 'Version', + 'settings.about.updateAvailable': 'ist vorhanden', + 'settings.about.softwareUpdates': 'Software-Updates', + 'settings.about.lastChecked': 'Zuletzt überprüft', + 'settings.about.checking': 'Überprüfen...', + 'settings.about.checkForUpdates': 'Nach Updates suchen', + 'settings.about.releases': 'Veröffentlichungen', + 'settings.about.releasesDesc': 'Durchsuche Versionshinweise und frühere Builds auf GitHub.', + 'settings.about.openReleases': 'Öffne GitHub-Releases', + 'settings.ai.overview': 'Übersicht über das KI-System', + 'settings.appearance': 'Aussehen', + 'settings.appearanceDesc': 'Wähle hell, dunkel oder passend zu deinem Systemthema', + 'settings.mascot': 'Maskottchen', + 'settings.mascotDesc': 'Wähle die Maskottchenfarbe aus, die in der gesamten App verwendet wird', +}; + +export default de1; diff --git a/app/src/lib/i18n/chunks/de-2.ts b/app/src/lib/i18n/chunks/de-2.ts new file mode 100644 index 000000000..b0f01ecf8 --- /dev/null +++ b/app/src/lib/i18n/chunks/de-2.ts @@ -0,0 +1,439 @@ +import type { TranslationMap } from '../types'; + +// German (Deutsch) translations. Each chunk maps to chunks/en-2.ts. +const de2: TranslationMap = { + 'settings.ai.configStatus': 'Konfigurationsstatus', + 'settings.ai.fallbackMode': 'Fallback-Modus', + 'settings.ai.loadedFromRuntime': 'Aus Runtime geladen', + 'settings.ai.loadingDuration': 'Ladedauer', + 'settings.ai.localRuntime': 'Lokale Modelllaufzeit', + 'settings.ai.openManager': 'Öffne den Manager', + 'settings.ai.retryDownload': 'Versuche den Download erneut', + 'settings.ai.state': 'Staat', + 'settings.ai.targetModel': 'Zielmodell', + 'settings.ai.download': 'Herunterladen', + 'settings.ai.localModelUnavailable': 'Lokaler Modellstatus nicht verfügbar.', + 'settings.ai.soulConfig': 'SOUL Persona-Konfiguration', + 'settings.ai.refreshing': 'Erfrischend...', + 'settings.ai.refreshSoul': 'SOUL aktualisieren', + 'settings.ai.loadingSoul': 'SOUL-Konfiguration wird geladen...', + 'settings.ai.identity': 'Identität', + 'settings.ai.personality': 'Persönlichkeit', + 'settings.ai.safetyRules': 'Sicherheitsregeln', + 'settings.ai.source': 'Quelle', + 'settings.ai.loaded': 'Geladen', + 'settings.ai.toolsConfig': 'TOOLS Konfiguration', + 'settings.ai.refreshTools': 'TOOLS aktualisieren', + 'settings.ai.toolsAvailable': 'Verfügbare Werkzeuge', + 'settings.ai.tools': 'Werkzeuge', + 'settings.ai.activeSkills': 'Aktive Fähigkeiten', + 'settings.ai.skills': 'Fähigkeiten', + 'settings.ai.skillsOverview': 'Überblick über die Fähigkeiten', + 'settings.ai.refreshingAll': 'Alles erfrischen...', + 'settings.ai.refreshAll': 'Aktualisiere alle AI-Konfigurationen', + 'settings.notifications.suppressAll': 'Alle Benachrichtigungen unterdrücken', + 'settings.notifications.suppressAllDesc': + 'Blockiere alle Betriebssystem-Benachrichtigungs-Toasts von eingebetteten Apps, unabhängig vom Fokusstatus.', + 'settings.notifications.toggleDnd': 'Schalte „Bitte nicht stören“ um', + 'settings.notifications.categories': 'Kategorien', + 'settings.notifications.categoryFooter': + 'Durch das Deaktivieren einer Kategorie wird verhindert, dass neue Benachrichtigungen dieses Typs im Benachrichtigungscenter angezeigt werden. Vorhandene Benachrichtigungen bleiben bestehen, bis sie gelöscht werden.', + 'settings.billing.movedToWeb': 'Die Abrechnung wurde ins Internet verlagert', + 'settings.billing.openDashboard': 'Abrechnungs-Dashboard öffnen', + 'settings.billing.movedToWebDesc': + 'Abonnementänderungen, Zahlungsmethoden, Gutschriften und Rechnungen werden jetzt bei TinyHumans im Internet verwaltet.', + 'settings.billing.backToSettings': 'Zurück zu den Einstellungen', + 'settings.billing.openingBrowser': 'Öffne deinen Browser...', + 'settings.billing.browserNotOpen': + 'Wenn dein Browser nicht geöffnet wurde, verwende die Schaltfläche oben.', + 'settings.billing.browserOpenFailed': + 'Der Browser konnte nicht automatisch geöffnet werden. Nutze den Button oben.', + 'settings.tools.chooseCapabilities': + 'Wähle aus, welche Funktionen OpenHuman in deinem Namen nutzen kann.', + 'settings.tools.saveChanges': 'Änderungen speichern', + 'settings.tools.preferencesSaved': 'Einstellungen gespeichert', + 'settings.tools.saveFailed': + 'Einstellungen konnten nicht gespeichert werden. Versuche es erneut.', + 'settings.screenAwareness.mode': 'Modus', + 'settings.screenAwareness.allExceptBlacklist': 'Alle außer Blacklist', + 'settings.screenAwareness.whitelistOnly': 'Nur Whitelist', + 'settings.screenAwareness.screenMonitoring': 'Bildschirmüberwachung', + 'settings.screenAwareness.saveSettings': 'Einstellungen speichern', + 'settings.screenAwareness.session': 'Sitzung', + 'settings.screenAwareness.status': 'Status', + 'settings.screenAwareness.active': 'Aktiv', + 'settings.screenAwareness.stopped': 'Angehalten', + 'settings.screenAwareness.remaining': 'Übrig', + 'settings.screenAwareness.startSession': 'Sitzung starten', + 'settings.screenAwareness.stopSession': 'Sitzung beenden', + 'settings.screenAwareness.analyzeNow': 'Jetzt analysieren', + 'settings.screenAwareness.macosOnly': + 'Die Desktop-Erfassung und Berechtigungssteuerung von Screen Awareness wird derzeit nur auf macOS unterstützt.', + 'connections.comingSoon': 'Kommt bald', + 'connections.setUp': 'Einrichten', + 'connections.configured': 'Konfiguriert', + 'connections.unavailable': 'Nicht verfügbar', + 'connections.checking': 'Überprüfen…', + 'connections.walletConfigured': + 'Lokale EVM-, BTC-, Solana- und Tron-Identitäten werden anhand deiner Wiederherstellungsphrase konfiguriert.', + 'connections.walletReady': + 'Richte lokale EVM-, BTC-, Solana- und Tron-Identitäten aus einer Wiederherstellungsphrase ein.', + 'connections.walletError': + 'Der Wallet-Status konnte nicht überprüft werden. Tippe im Bedienfeld „Wiederherstellungsphrase“ auf , um es noch einmal zu versuchen.', + 'connections.walletChecking': 'Wallet-Status wird überprüft...', + 'connections.walletIdentities': 'Wallet-Identitäten', + 'connections.walletDerived': + 'Wird lokal von deiner Wiederherstellungsphrase abgeleitet und nur als sichere Metadaten gespeichert.', + 'connections.privacySecurity': 'Datenschutz und Sicherheit', + 'connections.privacySecurityDesc': + 'Alle Daten und Anmeldeinformationen werden lokal mit einer Null-Datenaufbewahrungsrichtlinie gespeichert. Deine Daten werden verschlüsselt und niemals an Dritte weitergegeben.', + 'channels.status.connecting': 'Verbinden', + 'channels.status.notConfigured': 'Nicht konfiguriert', + 'channels.noActiveRoute': 'Keine aktive Route', + 'channels.activeRoute': 'Aktive Route', + 'channels.loadingDefinitions': 'Kanaldefinitionen werden geladen...', + 'channels.channelConnections': 'Kanalverbindungen', + 'channels.configureAuthModes': 'Konfiguriere Authentifizierungsmodi für jeden Nachrichtenkanal.', + 'channels.configNotAvailable': 'Konfiguration für', + 'channels.channel': 'Kanal', + 'devOptions.coreModeNotSet': 'Kernmodus: nicht eingestellt', + 'devOptions.coreModeNotSetDesc': + 'Der Boot-Check-Picker wurde noch nicht bestätigt. Verwende den Umschaltmodus in der Auswahl, um „Lokal“ oder „Cloud“ auszuwählen.', + 'devOptions.local': 'Lokal', + 'devOptions.embeddedCoreSidecar': 'Eingebetteter Core-Sidecar', + 'devOptions.sidecarSpawned': 'Wird prozessintern von der Tauri-Shell beim App-Start erzeugt.', + 'devOptions.cloud': 'Wolke', + 'devOptions.remoteCoreRpc': 'Remote-Kern RPC', + 'devOptions.token': 'Token', + 'devOptions.tokenNotSet': 'nicht gesetzt – RPC wird 401', + 'devOptions.triggerSentryTest': 'Trigger Sentry Test (Staging)', + 'devOptions.triggerSentryTestDesc': + 'Löst einen getaggten Fehler aus, um die Sentry-Pipeline zu überprüfen. Problem Nr. 1072 – nach Überprüfung entfernen.', + 'devOptions.sendTestEvent': 'Testereignis senden', + 'devOptions.sending': 'Senden…', + 'devOptions.eventSent': 'Ereignis gesendet', + 'devOptions.failed': 'Fehlgeschlagen', + 'devOptions.appLogs': 'App-Protokolle', + 'devOptions.appLogsDesc': + 'Öffne den Ordner mit den fortlaufenden täglichen Protokolldateien. Hänge die aktuellste Datei an, wenn du ein Problem meldest.', + 'devOptions.openLogsFolder': 'Öffne den Protokollordner', + 'mnemonic.phraseSaved': 'Wiederherstellungsphrase gespeichert', + 'mnemonic.walletReady': + 'Multi-Chain-Wallet-Identitäten sind bereit. Zurück zu den Einstellungen...', + 'mnemonic.writeDownWords': 'Schreibe diese auf', + 'mnemonic.wordsInOrder': + 'Sortiere die Wörter in der richtigen Reihenfolge und bewahre sie an einem sicheren Ort auf. Dieser Satz sichert deinen lokalen Verschlüsselungsschlüssel und deine EVM-, BTC-, Solana- und Tron-Wallet-Identitäten.', + 'mnemonic.cannotRecover': + 'Dieser Satz kann bei Verlust niemals wiederhergestellt werden und sollte vollständig lokal auf deinem Gerät bleiben.', + 'mnemonic.copyToClipboard': 'In die Zwischenablage kopieren', + 'mnemonic.alreadyHavePhrase': 'Ich habe bereits einen Wiederherstellungssatz', + 'mnemonic.consentSaved': + 'Ich habe diesen Satz gespeichert und bin damit einverstanden, ihn für die lokale Wallet-Einrichtung zu verwenden', + 'mnemonic.enterPhraseToRestore': + 'Gib unten deine Wiederherstellungsphrase ein, um deine lokalen Wallet-Identitäten wiederherzustellen, oder füge die vollständige Phrase in ein beliebiges Feld ein (12 Wörter für neue Backups; 24-Wort-Phrasen aus älteren Versionen funktionieren weiterhin).', + 'mnemonic.words': 'Worte', + 'mnemonic.validPhrase': 'Gültige Wiederherstellungsphrase', + 'mnemonic.generateNewPhrase': 'Generiere stattdessen eine neue Wiederherstellungsphrase', + 'mnemonic.securingData': 'Sicherung deiner Daten...', + 'mnemonic.saveRecoveryPhrase': 'Speichere die Wiederherstellungsphrase', + 'mnemonic.userNotLoaded': + 'Benutzer nicht geladen. Bitte melde dich erneut an oder aktualisiere die Seite.', + 'mnemonic.invalidPhrase': + 'Ungültige Wiederherstellungsphrase. Bitte prüfe deine Wörter und versuche es erneut.', + 'mnemonic.somethingWentWrong': 'Etwas ist schief gelaufen. Bitte versuche es erneut.', + 'team.failedToCreate': 'Team konnte nicht erstellt werden', + 'team.invalidInviteCode': 'Ungültiger oder abgelaufener Einladungscode', + 'team.failedToSwitch': 'Teamwechsel fehlgeschlagen', + 'team.failedToLeave': 'Das Team konnte nicht verlassen werden', + 'team.role.owner': 'Besitzer', + 'team.role.admin': 'Admin', + 'team.role.billingManager': 'Rechnungsmanager', + 'team.role.member': 'Mitglied', + 'team.active': 'Aktiv', + 'team.personalTeam': 'Persönliches Team', + 'team.manageTeam': 'Team verwalten', + 'team.switching': 'Wechsel...', + 'team.switch': 'Wechseln', + 'team.leaving': 'Verlassen...', + 'team.leave': 'Geh', + 'team.yourTeams': 'Deine Teams', + 'team.createNewTeam': 'Neues Team erstellen', + 'team.teamName': 'Teamname', + 'team.creating': 'Erstellen...', + 'team.joinExistingTeam': 'Tritt einem bestehenden Team bei', + 'team.inviteCode': 'Einladungscode', + 'team.joining': 'Beitritt...', + 'team.join': 'Mach mit', + 'team.leaveTeam': 'Verlasse das Team', + 'team.confirmLeave': 'Bist du sicher, dass du gehen möchtest?', + 'team.leaveWarning': + 'Du verlierst den Zugriff auf das Team und alle Teamressourcen. Du brauchst eine neue Einladung, um wieder beizutreten.', + 'team.management': 'Teammanagement', + 'team.notFound': 'Team nicht gefunden', + 'team.accessDenied': 'Zugriff verweigert', + 'team.members': 'Mitglieder', + 'voice.title': 'Sprachdiktat', + 'voice.settings': 'Spracheinstellungen', + 'voice.settingsDesc': + 'Halte den Hotkey gedrückt, um zu diktieren und Text in das aktive Feld einzufügen.', + 'voice.hotkey': 'Hotkey', + 'voice.activationMode': 'Aktivierungsmodus', + 'voice.tapToToggle': 'Zum Umschalten tippen', + 'voice.writingStyle': 'Schreibstil', + 'voice.verbatimTranscription': 'Wörtliche Transkription', + 'voice.naturalCleanup': 'Natürliche Reinigung', + 'voice.autoStart': 'Sprachserver automatisch mit dem Core starten', + 'voice.customDictionary': 'Benutzerdefiniertes Wörterbuch', + 'voice.customDictionaryDesc': + 'Füge Namen, Fachbegriffe und Domänenwörter hinzu, um die Erkennungsgenauigkeit zu verbessern.', + 'voice.addWord': 'Füge ein Wort hinzu...', + 'voice.sttDisabled': + 'Das Sprachdiktieren ist deaktiviert, bis das lokale STT-Modell heruntergeladen und bereit ist.', + 'voice.openLocalAiModel': 'Öffne das lokale KI-Modell', + 'voice.serverRestarted': 'Der Sprachserver wurde mit den neuen Einstellungen neu gestartet.', + 'voice.settingsSaved': 'Spracheinstellungen gespeichert.', + 'voice.serverStarted': 'Sprachserver gestartet.', + 'voice.serverStopped': 'Sprachserver gestoppt.', + 'voice.saveVoiceSettings': 'Spracheinstellungen speichern', + 'voice.startVoiceServer': 'Starte den Sprachserver', + 'voice.stopVoiceServer': 'Sprachserver stoppen', + 'voice.debugTitle': 'Sprach-Debug', + 'autocomplete.title': 'Automatische Vervollständigung', + 'autocomplete.settings': 'Einstellungen', + 'autocomplete.acceptWithTab': 'Mit Tab akzeptieren', + 'autocomplete.stylePreset': 'Stilvoreinstellung', + 'autocomplete.style.balanced': 'Ausgewogen', + 'autocomplete.style.concise': 'Prägnant', + 'autocomplete.style.formal': 'Formell', + 'autocomplete.style.casual': 'Lässig', + 'autocomplete.style.custom': 'Benutzerdefiniert', + 'autocomplete.disabledApps': 'Deaktivierte Apps (ein Bundle/App-Token pro Zeile)', + 'autocomplete.saveSettings': 'Einstellungen speichern', + 'autocomplete.saving': 'Sparen…', + 'autocomplete.runtime': 'Laufzeit', + 'autocomplete.running': 'Laufen', + 'autocomplete.start': 'Starten', + 'autocomplete.stop': 'Stopp', + 'autocomplete.settingsSaved': 'Autovervollständigungseinstellungen gespeichert.', + 'autocomplete.started': 'Die automatische Vervollständigung wurde gestartet.', + 'autocomplete.didNotStart': + 'Die automatische Vervollständigung wurde nicht gestartet. Prüfe, ob es aktiviert ist.', + 'autocomplete.stopped': 'Die automatische Vervollständigung wurde gestoppt.', + 'autocomplete.advancedSettings': 'Erweiterte Einstellungen', + 'autocomplete.debugTitle': 'Autocomplete-Debug', + 'chat.agentChat': 'Agenten-Chat', + 'chat.overrides': 'Überschreibt', + 'chat.model': 'Modell', + 'chat.temperature': 'Temperatur', + 'chat.conversation': 'Gespräch', + 'chat.startAgentConversation': 'Beginne ein Gespräch mit dem Agenten.', + 'chat.you': 'Du', + 'chat.agent': 'Agent', + 'chat.askAgent': 'Frag den Agenten etwas ...', + 'chat.sendMessage': 'Nachricht senden', + 'composio.triageTitle': 'Integrationsauslöser', + 'composio.triageDesc': + 'Wenn er aktiv ist, durchläuft jeder eingehende Composio-Auslöser einen KI-Triage-Schritt, der das Ereignis klassifiziert und möglicherweise automatisierte Aktionen auslöst – eine lokale LLM-Runde pro Auslöser. Deaktiviere die Option global oder pro Integration, wenn du eine manuelle Überprüfung bevorzugst. Wenn die Umgebungsvariable', + 'composio.disableAllTriage': 'Deaktiviere die KI-Triage für alle Auslöser', + 'composio.triggersStillRecorded': + 'Auslöser werden weiterhin im Verlauf aufgezeichnet – es wird kein LLM-Turn ausgeführt.', + 'composio.disableSpecificIntegrations': 'Deaktiviere die KI-Triage für bestimmte Integrationen', + 'composio.settingsSaved': 'Einstellungen gespeichert', + 'composio.saveFailed': 'Speichern fehlgeschlagen. Versuche es erneut.', + 'cron.title': 'Cron-Jobs', + 'cron.scheduledJobs': 'Geplante Jobs', + 'cron.manageCronJobs': 'Verwalte Cron-Jobs über den Kernplaner.', + 'cron.refreshCronJobs': 'Cron-Jobs aktualisieren', + 'localModel.modelStatus': 'Modellstatus', + 'localModel.downloadModels': 'Modelle herunterladen', + 'localModel.usage': 'Nutzung', + 'localModel.usageDesc': + 'Wähle aus, welche Subsysteme auf dem lokalen Modell ausgeführt werden. Alles, was nicht funktioniert, nutzt die Cloud.', + 'localModel.enableRuntime': 'Aktiviere die lokale AI-Laufzeit', + 'localModel.enableRuntimeDesc': + 'Hauptschalter. Standardmäßig deaktiviert – Ollama bleibt inaktiv. Wenn diese Option aktiviert ist, verwenden die Baumzusammenfassung, die Bildschirmintelligenz und die automatische Vervollständigung immer das lokale Modell.', + 'localModel.advancedSettings': 'Erweiterte Einstellungen', + 'localModel.debugTitle': 'Lokales Modell-Debug', + 'localModel.ollamaServer.helperText': 'Beispiel: http://192.168.1.5:11434', + 'localModel.ollamaServer.label': 'Ollama Server URL', + 'localModel.ollamaServer.modelCount': 'Modelle', + 'localModel.ollamaServer.placeholder': 'http://localhost:11434', + 'localModel.ollamaServer.reachable': 'Erreichbar', + 'localModel.ollamaServer.resetButton': 'Auf Standard zurücksetzen', + 'localModel.ollamaServer.saveButton': 'Speichern', + 'localModel.ollamaServer.testButton': 'Testverbindung', + 'localModel.ollamaServer.unreachable': 'Unerreichbar', + 'localModel.ollamaServer.validationError': 'Muss ein gültiges http:// oder https:// sein URL', + 'screenAwareness.debugTitle': 'Debuggen der Bildschirmerkennung', + 'memory.debugTitle': 'Speicher-Debug', + 'webhooks.debugTitle': 'Webhooks-Debug', + 'notifications.routingTitle': 'Benachrichtigungsweiterleitung', + 'common.reload': 'Neu laden', + 'common.skip': 'Überspringen', + 'common.disable': 'Deaktivieren', + 'common.enable': 'Aktivieren', + 'chat.safetyTimeout': + 'Keine Antwort vom Agenten nach 2 Minuten. Versuche es erneut oder prüfe deine Verbindung.', + 'chat.filter.all': 'Alle', + 'chat.filter.work': 'Arbeit', + 'chat.filter.briefing': 'Briefing', + 'chat.filter.notification': 'Benachrichtigung', + 'chat.filter.workers': 'Arbeiter', + 'chat.selectThread': 'Wähle einen Thread aus', + 'chat.threads': 'Themen', + 'chat.noThreads': 'Noch keine Threads', + 'chat.noLabelThreads': 'Keine „{label}“-Threads', + 'chat.noWorkerThreads': 'Noch keine Arbeitsthreads', + 'chat.deleteThread': 'Thread löschen', + 'chat.deleteThreadConfirm': 'Bist du sicher, dass du „{title}“ löschen möchtest?', + 'chat.untitledThread': 'Thread ohne Titel', + 'chat.hideSidebar': 'Seitenleiste ausblenden', + 'chat.showSidebar': 'Seitenleiste anzeigen', + 'chat.newThreadShortcut': 'Neuer Thread (/new)', + 'chat.new': 'Neu', + 'chat.failedToLoadMessages': 'Nachrichten konnten nicht geladen werden', + 'chat.thinkingIteration': 'Denken... ({n})', + 'chat.thinkingDots': 'Denken...', + 'chat.approachingLimit': 'Das Nutzungslimit nähert sich', + 'chat.approachingLimitMsg': 'Du hast {pct} % deines verfügbaren Kontingents verwendet.', + 'chat.upgrade': 'Upgrade', + 'chat.weeklyLimitHit': 'Du hast dein enthaltenes Zyklusbudget aufgebraucht.', + 'chat.resets': 'Zurücksetzen', + 'chat.topUpToContinue': 'Lade Guthaben auf, um fortzufahren.', + 'chat.budgetComplete': + 'Dein enthaltenes Budget ist aufgebraucht. Füge Credits hinzu oder führe ein Upgrade durch, um fortzufahren.', + 'chat.topUp': 'Aufladen', + 'chat.cycle': 'Zyklus', + 'chat.cycleSpent': 'Habe diesen Zyklus verbracht', + 'chat.cycleRemaining': 'Übrig', + 'chat.left': 'links', + 'chat.setup': 'Einrichten', + 'chat.switchToText': 'Wechsle zu Text', + 'chat.transcribing': 'Transkribieren...', + 'chat.stopAndSend': 'Stoppen und senden', + 'chat.startTalking': 'Sprich los', + 'chat.playingVoiceReply': 'Sprachantwort wird abgespielt', + 'chat.voiceHint': 'Nutze das Mikrofon zum Sprechen', + 'chat.micUnavailable': 'Mikrofon nicht verfügbar', + 'chat.turn': 'drehen', + 'chat.turns': 'dreht sich', + 'chat.openWorkerThread': 'Arbeitsthread öffnen', + 'memory.searchAria': 'Speicher durchsuchen', + 'memory.searchPlaceholder': 'Speichereinträge durchsuchen...', + 'memory.sourceFilter.all': 'Alle Quellen', + 'memory.sourceFilter.email': 'E-Mail', + 'memory.sourceFilter.calendar': 'Kalender', + 'memory.sourceFilter.telegram': 'Telegram', + 'memory.sourceFilter.aiInsight': 'KI-Einblick', + 'memory.sourceFilter.system': 'System', + 'memory.sourceFilter.trading': 'Handel', + 'memory.sourceFilter.security': 'Sicherheit', + 'memory.ingestionActivity': 'Einnahmeaktivität', + 'memory.events': 'Ereignisse', + 'memory.event': 'Ereignis', + 'memory.overTheLast': 'im letzten', + 'memory.months': 'Monate', + 'memory.peak': 'Höhepunkt', + 'memory.perDay': '/Tag', + 'memory.less': 'Weniger', + 'memory.more': 'Mehr', + 'memory.on': 'auf', + 'memory.loading': 'Speicher wird geladen', + 'memory.fetching': 'Deine Speichereinträge werden abgerufen...', + 'memory.analyzing': 'Gedächtnis analysieren', + 'memory.analyzingHint': 'Verarbeite deine Erinnerungen, um Erkenntnisse zu gewinnen ...', + 'memory.noMatches': 'Keine Übereinstimmungen gefunden', + 'memory.noMatchesHint': 'Versuche, deine Suchbegriffe oder Filter zu ändern.', + 'memory.allCaughtUp': 'Alles aufgeholt', + 'memory.allCaughtUpHint': 'Es müssen keine neuen Speichereinträge verarbeitet werden.', + 'memory.noAnalysis': 'Noch keine Analyse', + 'memory.noAnalysisHint': + 'Führe eine Analyse durch, um Muster in deinen Erinnerungen zu entdecken.', + 'memory.emptyHint': 'Beginne mit der Interaktion, um deine ersten Erinnerungen zu schaffen.', + 'mic.unavailable': 'Mikrofon ist nicht verfügbar', + 'mic.permissionDenied': 'Mikrofonberechtigung verweigert', + 'mic.failedToStartRecorder': 'Der Rekorder konnte nicht gestartet werden', + 'mic.transcribing': 'Transkribieren...', + 'mic.tapToSend': 'Zum Senden tippen', + 'mic.waitingForAgent': 'Warten auf Agent...', + 'mic.tapAndSpeak': 'Tippen und sprechen', + 'mic.stopRecording': 'Aufnahme stoppen und senden', + 'mic.startRecording': 'Starte die Aufnahme', + 'token.usageLimitReached': 'Nutzungslimit erreicht', + 'token.approachingLimit': 'Annäherung an die Grenze', + 'token.planClickForDetails': 'Plan – klicke für Details', + 'token.sessionTokens': 'In: {in} | Aus: {out} | Turns: {turns}', + 'token.limit': 'Limit erreicht', + 'catalog.noCapabilityBinding': 'Keine Fähigkeitsbindung', + 'catalog.downloadFailed': 'Der Download ist fehlgeschlagen', + 'catalog.active': 'Aktiv', + 'catalog.installed': 'Installiert', + 'catalog.notDownloaded': 'Nicht heruntergeladen', + 'catalog.inUse': 'Im Einsatz', + 'catalog.use': 'Benutzen', + 'catalog.deleteModel': 'Modell löschen', + 'catalog.download': 'Herunterladen', + 'navigator.recent': 'Neu', + 'navigator.today': 'Heute', + 'navigator.thisWeek': 'Diese Woche', + 'navigator.sources': 'Quellen', + 'navigator.email': 'E-Mail', + 'navigator.slack': 'Slack', + 'navigator.chat': 'Chatten', + 'navigator.documents': 'Dokumente', + 'navigator.people': 'Menschen', + 'navigator.topics': 'Themen', + 'dreams.description': + 'Träume sind KI-generierte Reflexionen, die Muster aus deinen Erinnerungen synthetisieren.', + 'dreams.comingSoon': 'Kommt bald', + 'assignment.memoryLlm': 'Speicher LLM', + 'assignment.memoryLlmAria': 'Auswahl des Speichers LLM', + 'assignment.embedder': 'Einbetter', + 'assignment.loaded': 'Geladen', + 'assignment.notDownloaded': 'Nicht heruntergeladen', + 'assignment.usedForExtractSummarise': 'Wird zur Extraktion und Zusammenfassung verwendet', + 'insights.knownFacts': 'Bekannte Fakten', + 'insights.preferences': 'Präferenzen', + 'insights.relationships': 'Beziehungen', + 'insights.skills': 'Fähigkeiten', + 'insights.opinions': 'Meinungen', + 'devOptions.menuAi': 'KI-Konfiguration', + 'devOptions.menuAiDesc': 'Cloud-Anbieter, lokale Ollama-Modelle und Routing pro Workload', + 'devOptions.menuScreenAware': 'Bildschirmbewusstsein', + 'devOptions.menuScreenAwareDesc': + 'Bildschirmaufnahmeberechtigungen, Überwachungsrichtlinien und Sitzungskontrollen', + 'devOptions.menuMessaging': 'Messaging-Kanäle', + 'devOptions.menuMessagingDesc': + 'Konfiguriere die Authentifizierungsmodi Telegram/Discord und das Standardkanalrouting', + 'devOptions.menuTools': 'Werkzeuge', + 'devOptions.menuToolsDesc': + 'Aktiviere oder deaktiviere Funktionen, die OpenHuman in deinem Namen nutzen kann', + 'devOptions.menuAgentChat': 'Agenten-Chat', + 'devOptions.menuAgentChatDesc': + 'Test-Agent-Konversation mit Modell- und Temperaturüberschreibungen', + 'devOptions.menuCronJobs': 'Cron-Jobs', + 'devOptions.menuCronJobsDesc': + 'Zeige geplante Jobs für Laufzeitfähigkeiten an und konfiguriere sie', + 'devOptions.menuLocalModelDebug': 'Lokales Modell-Debug', + 'devOptions.menuLocalModelDebugDesc': + 'Ollama-Konfiguration, Asset-Downloads, Modelltests und Diagnose', + 'devOptions.menuWebhooksDebug': 'Webhooks', + 'devOptions.menuWebhooksDebugDesc': + 'Prüfe Laufzeit-Webhook-Registrierungen und erfasste Anforderungsprotokolle', + 'devOptions.menuIntelligence': 'Intelligenz', + 'devOptions.menuIntelligenceDesc': + 'Gedächtnisarbeitsbereich, Unterbewusstseinsmotor, Träume und Einstellungen', + 'devOptions.menuNotificationRouting': 'Benachrichtigungsweiterleitung', + 'devOptions.menuNotificationRoutingDesc': + 'KI-Wichtigkeitsbewertung und Orchestrator-Eskalation für Integrationswarnungen', + 'devOptions.menuComposeIOTriggers': 'ComposeIO Auslöser', + 'devOptions.menuComposeIOTriggersDesc': 'Sieh dir den ComposeIO-Triggerverlauf und das Archiv an', + 'devOptions.menuComposioRouting': 'Composio Routing (Direktmodus)', + 'devOptions.menuComposioRoutingDesc': + 'Bring deinen eigenen Composio API-Schlüssel mit und leite Anrufe direkt an backend.composio.dev weiter', + 'devOptions.menuComposioTriggers': 'Integrationsauslöser', + 'devOptions.menuComposioTriggersDesc': + 'Konfiguriere KI-Triage-Einstellungen für Composio-Integrationsauslöser', +}; + +export default de2; diff --git a/app/src/lib/i18n/chunks/de-3.ts b/app/src/lib/i18n/chunks/de-3.ts new file mode 100644 index 000000000..8cbb4e8ae --- /dev/null +++ b/app/src/lib/i18n/chunks/de-3.ts @@ -0,0 +1,389 @@ +import type { TranslationMap } from '../types'; + +// German (Deutsch) translations. Each chunk maps to chunks/en-3.ts. +const de3: TranslationMap = { + 'insights.other': 'Andere', + 'insights.title': 'Einblicke', + 'insights.empty': + 'Noch keine Erkenntnisse. Erkenntnisse werden generiert, wenn dein Gedächtnis wächst.', + 'insights.description': 'Basierend auf {count} Beziehungen in deinem Speicherdiagramm.', + 'insights.items': 'Artikel', + 'insights.more': 'mehr', + 'calls.joiningCall': 'Beitrittsgespräch', + 'calls.meetWindowOpening': 'Das Meet-Fenster wird geöffnet...', + 'calls.failedToStart': 'Der Meet-Anruf konnte nicht gestartet werden', + 'calls.couldNotStart': 'Anruf konnte nicht gestartet werden', + 'calls.failedToClose': 'Anruf konnte nicht geschlossen werden', + 'calls.couldNotClose': 'Anruf konnte nicht geschlossen werden', + 'calls.joinMeet': 'Nimm an einem Google Meet-Anruf teil', + 'calls.joinMeetDescription': 'Gib einen Google Meet-Link ein, um beizutreten.', + 'calls.meetLink': 'Meet-Link', + 'calls.displayName': 'Anzeigename', + 'calls.openingMeet': 'Meet wird geöffnet...', + 'calls.joinCall': 'Nimm am Anruf teil', + 'calls.activeCalls': 'Aktive Anrufe', + 'calls.leave': 'Verlassen', + 'workspace.wipeConfirm': + 'Bist du sicher, dass du den gesamten Speicher löschen möchtest? Dies kann nicht rückgängig gemacht werden.', + 'workspace.resetTreeConfirm': 'Bist du sicher, dass du den Speicherbaum neu erstellen möchtest?', + 'workspace.wipeTitle': 'Speicher löschen', + 'workspace.resetting': 'Zurücksetzen...', + 'workspace.resetMemory': 'Speicher zurücksetzen', + 'workspace.resetTreeTitle': 'Speicherbaum neu erstellen', + 'workspace.rebuilding': 'Wiederaufbau...', + 'workspace.resetMemoryTree': 'Speicherbaum zurücksetzen', + 'workspace.building': 'Wird erstellt...', + 'workspace.buildSummaryTrees': 'Erstelle Zusammenfassungsbäume', + 'workspace.viewVault': 'Vault anzeigen', + 'workspace.openingVaultTitle': 'Vault in Obsidian öffnen', + 'workspace.openingVaultMessage': + 'Falls Obsidian nicht geöffnet wird, installiere es von obsidian.md oder nutze „Ordner anzeigen“. Vault-Pfad:', + 'workspace.openVaultFailedTitle': 'Vault konnte nicht in Obsidian geöffnet werden', + 'workspace.openVaultFailedMessage': + 'Nutze „Ordner anzeigen“, um das Vault-Verzeichnis direkt zu öffnen. Vault-Pfad:', + 'workspace.revealVaultFailed': 'Vault-Ordner konnte nicht angezeigt werden', + 'workspace.revealFolder': 'Ordner anzeigen', + 'workspace.graphLoadFailed': 'Speicherdiagramm konnte nicht geladen werden', + 'workspace.loadingGraph': 'Speicherdiagramm wird geladen...', + 'workspace.graphViewMode': 'Speicherdiagramm-Ansichtsmodus', + 'workspace.trees': 'Bäume', + 'workspace.contacts': 'Kontakte', + 'graph.noContactMentions': 'Keine Kontakterwähnungen', + 'graph.noMemory': 'Keine Erinnerung', + 'graph.source': 'Quelle', + 'graph.topic': 'Thema', + 'graph.global': 'Global', + 'graph.document': 'Dokument', + 'graph.contact': 'Kontakt', + 'graph.nodes': 'Knoten', + 'graph.parentChild': 'Eltern-Kind', + 'graph.documentContact': 'Dokumentenkontakt', + 'graph.link': 'Link', + 'graph.links': 'Links', + 'graph.children': 'Kinder', + 'graph.clickToOpenObsidian': 'Klicke hier, um in Obsidian zu öffnen', + 'graph.person': 'Person', + 'modal.dontShowAgain': 'Ähnliche Vorschläge nicht anzeigen', + 'reflections.loading': 'Reflexionen werden geladen...', + 'reflections.empty': 'Noch keine Überlegungen', + 'reflections.title': 'Reflexionen', + 'reflections.proposedAction': 'Vorgeschlagene Aktion', + 'reflections.act': 'Handeln', + 'reflections.dismiss': 'Entlassen', + 'whatsapp.chatsSynced': 'Chats synchronisiert', + 'whatsapp.chatSynced': 'Chat synchronisiert', + 'sync.active': 'Aktiv', + 'sync.recent': 'Neu', + 'sync.idle': 'Leerlauf', + 'sync.memorySources': 'Speicherquellen', + 'sync.noConnectedSources': 'Keine angeschlossenen Quellen', + 'sync.chunks': 'Brocken', + 'sync.lastChunk': 'Letzter Teil:', + 'sync.pending': 'ausstehend', + 'sync.processed': 'verarbeitet', + 'sync.syncing': 'Synchronisierung…', + 'sync.sync': 'Synchronisieren', + 'sync.failedToLoad': 'Der Synchronisierungsstatus konnte nicht geladen werden', + 'sync.noContent': + 'Es wurden noch keine Inhalte in den Speicher synchronisiert. Verbinde eine Integration, um zu beginnen.', + 'backend.aiBackend': 'KI-Backend', + 'backend.cloud': 'Wolke', + 'backend.recommended': 'Empfohlen', + 'backend.cloudDescription': + 'Schnelle, leistungsstarke Modelle, die auf unseren Servern gehostet werden. Sofort einsatzbereit.', + 'backend.privacyNote': + 'Es werden niemals personenbezogene Daten, Nachrichten oder Schlüssel an unsere Server gesendet.', + 'backend.local': 'Lokal', + 'backend.advanced': 'Fortgeschritten', + 'backend.localDescription': + 'Führe Modelle auf deinem eigenen Computer mit Ollama aus. Vollständige Privatsphäre, erfordert eine Einrichtung.', + 'backend.ramRecommended': '16 GB+ RAM empfohlen', + 'subconscious.tasks': 'Aufgaben', + 'subconscious.ticks': 'Zecken', + 'subconscious.last': 'Zuletzt', + 'subconscious.failed': 'gescheitert', + 'subconscious.tickInterval': 'Tick-Intervall', + 'subconscious.runNow': 'Jetzt ausführen', + 'subconscious.approvalNeeded': 'Genehmigung erforderlich', + 'subconscious.requiresApproval': 'Erfordert eine Genehmigung', + 'subconscious.fixInConnections': 'Fix in Verbindungen', + 'subconscious.goAhead': 'Mach weiter', + 'subconscious.activeTasks': 'Aktive Aufgaben', + 'subconscious.noActiveTasks': 'Keine aktiven Aufgaben', + 'subconscious.default': 'Standard', + 'subconscious.addTaskPlaceholder': 'Eine neue Aufgabe hinzufügen...', + 'subconscious.activityLog': 'Aktivitätsprotokoll', + 'subconscious.noActivity': 'Noch keine Aktivität', + 'subconscious.decision.nothingNew': 'Nichts Neues', + 'subconscious.decision.completed': 'Abgeschlossen', + 'subconscious.decision.evaluating': 'Bewerten', + 'subconscious.decision.waitingApproval': 'Warten auf Genehmigung', + 'subconscious.decision.failed': 'Fehlgeschlagen', + 'subconscious.decision.cancelled': 'Abgesagt', + 'subconscious.decision.skipped': 'Übersprungen', + 'actionable.complete': 'Komplett', + 'actionable.dismiss': 'Entlassen', + 'actionable.snooze': 'Schlummern', + 'actionable.new': 'Neu', + 'stats.storage': 'Lagerung', + 'stats.files': 'Dateien', + 'stats.documents': 'Dokumente', + 'stats.today': 'heute', + 'stats.namespaces': 'Namensräume', + 'stats.relations': 'Beziehungen', + 'stats.firstMemory': 'Erste Erinnerung', + 'stats.latest': 'Neueste', + 'stats.sessions': 'Sitzungen', + 'stats.tokens': 'Token', + 'bootCheck.invalidUrl': 'Bitte gib eine Laufzeit URL ein.', + 'bootCheck.urlMustStartWith': 'Der URL muss mit http:// oder https:// beginnen.', + 'bootCheck.validUrlRequired': + 'Das sieht nicht nach einem gültigen URL aus (versuche es mit https://core.example.com/rpc)', + 'bootCheck.tokenRequired': 'Für die Verbindung benötigen wir ein Authentifizierungstoken.', + 'bootCheck.chooseCoreMode': 'Wähle eine Laufzeit aus', + 'bootCheck.connectToCore': 'Stelle eine Verbindung zu deiner Laufzeit her', + 'bootCheck.desktopDescription': + 'OpenHuman benötigt eine Laufzeit zum Nachdenken. Wähle, wo es leben soll.', + 'bootCheck.webDescription': + 'Im Web stellt OpenHuman eine Verbindung zu einer von dir gesteuerten Laufzeit her. Gib unten den URL und das Authentifizierungstoken ein oder greife auf die Desktop-App zu, um eine direkt auf deinem Computer auszuführen.', + 'bootCheck.preferDesktop': 'Möchtest du lieber alles auf deinem eigenen Gerät behalten?', + 'bootCheck.downloadDesktop': 'Hol dir die Desktop-App', + 'bootCheck.localRecommended': 'Lokal ausführen (empfohlen)', + 'bootCheck.localDescription': + 'Läuft direkt hier auf deinem Computer. Am schnellsten, völlig privat, nichts einzurichten.', + 'bootCheck.cloudMode': 'In der Cloud ausführen (komplex)', + 'bootCheck.cloudDescription': + 'Stelle eine Verbindung zu einer Laufzeit her, die du woanders hostest. Die Laufzeit bleibt rund um die Uhr online, sodass du dieses Gerät nicht laufen lassen musst.', + 'bootCheck.coreRpcUrl': 'Laufzeit URL', + 'bootCheck.rpcUrlPlaceholder': 'https://core.example.com/rpc', + 'bootCheck.authToken': 'Authentifizierungstoken', + 'bootCheck.bearerTokenPlaceholder': 'Das Bearer-Token von deiner Remote-Laufzeit', + 'bootCheck.storedLocally': 'Wird nur auf diesem Gerät gespeichert. Gesendet als ', + 'bootCheck.testing': 'Testen…', + 'bootCheck.testConnection': 'Testverbindung', + 'bootCheck.connectedOk': 'Verbunden. Es kann losgehen.', + 'bootCheck.authFailed': + 'Dieser Token hat nicht funktioniert. Prüfe ihn noch einmal und versuche es erneut.', + 'bootCheck.unreachablePrefix': 'Konnte es nicht erreichen:', + 'bootCheck.checkingCore': 'Deine Laufzeit wird aufgeweckt ...', + 'bootCheck.cannotReach': 'Die Laufzeit kann nicht erreicht werden', + 'bootCheck.cannotReachDesc': + 'Wir konnten keine Verbindung zu deiner Laufzeit herstellen. Möchtest du etwas anderes ausprobieren?', + 'bootCheck.switchMode': 'Wähle eine andere Laufzeit', + 'bootCheck.quit': 'Beenden', + 'bootCheck.legacyDetected': 'Legacy-Hintergrundlaufzeit erkannt', + 'bootCheck.legacyDescription': + 'Auf diesem Gerät läuft bereits ein separat installierter OpenHuman-Daemon. Wir müssen es bereinigen, bevor die integrierte Laufzeit übernehmen kann.', + 'bootCheck.removing': 'Entfernen…', + 'bootCheck.removeContinue': 'Entfernen und fortfahren', + 'bootCheck.localNeedsRestart': 'Die lokale Laufzeit erfordert einen Neustart', + 'bootCheck.localNeedsRestartDesc': + 'Deine lokale Laufzeit hat eine andere Version als diese App. Durch einen schnellen Neustart werden sie wieder synchronisiert.', + 'bootCheck.restarting': 'Neustart...', + 'bootCheck.restartCore': 'Starte die Runtime neu', + 'bootCheck.cloudNeedsUpdate': 'Cloud Runtime benötigt ein Update', + 'bootCheck.cloudNeedsUpdateDesc': + 'Deine Cloud-Laufzeitumgebung hat eine andere Version als diese App. Führe den Updater aus, um sie wieder zu synchronisieren.', + 'bootCheck.updating': 'Aktualisierung…', + 'bootCheck.updateCloudCore': 'Aktualisiere Cloud Runtime', + 'bootCheck.versionCheckFailed': 'Laufzeitversionsprüfung fehlgeschlagen', + 'bootCheck.versionCheckFailedDesc': + 'Deine Laufzeit ist aktiv, meldet jedoch nicht ihre Version. Möglicherweise ist es veraltet. Starte es neu oder aktualisiere es, um fortzufahren.', + 'bootCheck.working': 'Arbeiten…', + 'bootCheck.restartUpdateCore': 'Runtime neu starten/aktualisieren', + 'bootCheck.unexpectedError': 'Unerwarteter Boot-Check-Fehler', + 'bootCheck.actionFailed': 'Etwas ist schief gelaufen. Bitte versuche es erneut.', + 'notifications.justNow': 'gerade jetzt', + 'notifications.minAgo': 'Vor {n}m', + 'notifications.hrAgo': 'Vor {n}h', + 'notifications.dayAgo': 'Vor {n}d', + 'notifications.category.messages': 'Nachrichten', + 'notifications.category.agents': 'Agenten', + 'notifications.category.skills': 'Fähigkeiten', + 'notifications.category.system': 'System', + 'notifications.category.meetings': 'Treffen', + 'notifications.category.reminders': 'Erinnerungen', + 'notifications.category.important': 'Wichtig', + 'about.update.status.checking': 'Überprüfen...', + 'about.update.status.available': 'v{version} verfügbar', + 'about.update.status.availableNoVersion': 'Update verfügbar', + 'about.update.status.downloading': 'Herunterladen...', + 'about.update.status.readyToInstall': 'v{version} bereit zur Installation', + 'about.update.status.readyToInstallNoVersion': + 'Eine neue Version ist heruntergeladen und bereit. Starte neu, um das Update anzuwenden.', + 'about.update.status.installing': 'Installieren...', + 'about.update.status.restarting': 'Neustart...', + 'about.update.status.upToDate': 'Du verwendest die neueste Version.', + 'about.update.status.error': 'Die Aktualisierungsprüfung ist fehlgeschlagen', + 'about.update.status.default': 'Nach Updates suchen', + 'welcome.connectionFailed': 'Verbindung fehlgeschlagen: {status} {statusText}', + 'welcome.connectionFailedMsg': 'Verbindung fehlgeschlagen: {message}', + 'chat.agentChatDesc': 'Öffne eine direkte Chat-Sitzung mit dem Agenten.', + 'channels.activeRouteValue': '{channel} über {authMode}', + 'privacy.dataKind.messages': 'Nachrichten', + 'privacy.dataKind.agents': 'Agenten', + 'privacy.dataKind.skills': 'Fähigkeiten', + 'privacy.dataKind.system': 'System', + 'privacy.dataKind.meetings': 'Treffen', + 'privacy.dataKind.reminders': 'Erinnerungen', + 'privacy.dataKind.important': 'Wichtig', + 'onboarding.enableLocalAI': 'Aktiviere lokale KI', + 'onboarding.skills.status.available': 'Verfügbar', + 'onboarding.skills.status.connected': 'Verbunden', + 'onboarding.skills.status.connecting': 'Verbinden', + 'onboarding.skills.status.error': 'Fehler', + 'onboarding.skills.status.unavailable': 'Nicht verfügbar', + 'composio.statusUnavailable': 'Status nicht verfügbar', + 'composio.envVarOverrides': 'festgelegt ist, überschreibt es diese Einstellung.', + 'memory.day.sun': 'Sonne', + 'memory.day.mon': 'Mo', + 'memory.day.tue': 'Di', + 'memory.day.wed': 'Mi', + 'memory.day.thu': 'Do', + 'memory.day.fri': 'Fr', + 'memory.day.sat': 'Sa', + 'memory.ingesting': 'Einnahme', + 'memory.ingestionQueued': 'In der Warteschlange', + 'memory.ingestingTitle': 'Einnahme von {title}', + 'mic.noAudioCaptured': 'Kein Ton aufgenommen', + 'mic.noSpeechDetected': 'Keine Sprache erkannt', + 'mic.failedToStopRecording': 'Aufzeichnung konnte nicht gestoppt werden: {message}', + 'mic.transcriptionFailed': 'Transkription fehlgeschlagen: {message}', + 'reflections.kind.retrospective': 'Retrospektive', + 'reflections.kind.derivedFact': 'Abgeleitete Tatsache', + 'reflections.kind.moodInsight': 'Stimmungseinsicht', + 'reflections.kind.relationshipInsight': 'Beziehungseinblick', + 'graph.tooltip.summary': 'Zusammenfassung', + 'graph.tooltip.contact': 'Kontakt', + 'localModel.usage.never': 'Niemals', + 'localModel.usage.mediumLoad': 'Mittlere Belastung', + 'localModel.usage.lowLoad': 'Geringe Belastung', + 'localModel.usage.idleMode': 'Leerlaufmodus', + 'localModel.rebootstrapComplete': 'Modell-Re-Bootstrap abgeschlossen.', + 'localModel.modelsVerified': 'Lokale Modelle verifiziert.', + 'accounts.addModal.allConnected': 'Alles verbunden', + 'accounts.addModal.title': 'Konto hinzufügen', + 'accounts.respondQueue.empty': 'Leer', + 'accounts.respondQueue.hide': 'Antwortwarteschlange ausblenden', + 'accounts.respondQueue.loadFailed': 'Antwortwarteschlange konnte nicht geladen werden', + 'accounts.respondQueue.loading': 'Warteschlange wird geladen…', + 'accounts.respondQueue.pending': 'Ausstehend', + 'accounts.respondQueue.show': 'Antwortwarteschlange anzeigen', + 'accounts.respondQueue.title': 'Antwortwarteschlange', + 'accounts.webviewHost.almostReady': 'Fast fertig...', + 'accounts.webviewHost.loadTimeout': 'Zeitüberschreitung beim Laden der Webansicht', + 'accounts.webviewHost.loading': 'Laden {providerName}...', + 'accounts.webviewHost.loadingAccount': 'Konto wird geladen', + 'accounts.webviewHost.restoringSession': 'Sitzung wird wiederhergestellt...', + 'accounts.webviewHost.retryLoading': 'Versuche den Ladevorgang erneut', + 'accounts.webviewHost.takingLonger': '{providerName} dauert länger als erwartet.', + 'accounts.webviewHost.timeoutHint': 'Timeout-Hinweis', + 'app.connectionBadge.composio': 'Composio', + 'app.connectionBadge.messaging': 'Nachrichten', + 'app.connectionIndicator.connected': 'Verbunden mit OpenHuman AI 🚀', + 'app.connectionIndicator.connecting': 'Verbinden', + 'app.connectionIndicator.coreOffline': 'Kern offline', + 'app.connectionIndicator.disconnected': 'Nicht verbunden', + 'app.connectionIndicator.offline': 'Offline', + 'app.connectionIndicator.reconnecting': 'Wieder verbinden…', + 'app.errorFallback.componentStack': 'Komponentenstapel', + 'app.errorFallback.downloadLatest': 'Neueste herunterladen', + 'app.errorFallback.heading': 'Überschrift', + 'app.errorFallback.hint': 'Hinweis', + 'app.errorFallback.reloadApp': 'App neu laden', + 'app.errorFallback.subheading': 'Unterüberschrift', + 'app.errorFallback.tryRecover': 'Versuche es mit einer Wiederherstellung', + 'app.localAiDownload.installing': 'Installieren...', + 'app.localAiDownload.preparing': 'Vorbereiten...', + 'app.openhumanLink.accounts.continueWith': 'Fahre mit der Anmeldung bei {label} fort', + 'app.openhumanLink.accounts.done': 'Fertig', + 'app.openhumanLink.accounts.intro': 'Einführung', + 'app.openhumanLink.accounts.webviewNote': 'Webview-Hinweis', + 'app.openhumanLink.billing.openDashboard': 'Dashboard öffnen', + 'app.openhumanLink.billing.stayOnTrial': 'In der Testversion bleiben', + 'app.openhumanLink.billing.trialCredit': 'Probeguthaben', + 'app.openhumanLink.billing.trialDesc': 'Testbeschreibung', + 'app.openhumanLink.defaultBody': + 'Im Popup noch nicht fertig. Öffne bei Bedarf die vollständige Einstellungsseite.', + 'app.openhumanLink.discord.intro': 'Einführung', + 'app.openhumanLink.discord.openInvite': 'Einladung öffnen', + 'app.openhumanLink.discord.perk1': 'Vorteil1', + 'app.openhumanLink.discord.perk2': 'Vorteil2', + 'app.openhumanLink.discord.perk3': 'Vorteil3', + 'app.openhumanLink.discord.perk4': 'Vorteil4', + 'app.openhumanLink.done': 'Fertig', + 'app.openhumanLink.loadingChannelSetup': 'Kanal-Setup wird geladen', + 'app.openhumanLink.maybeLater': 'Vielleicht später', + 'app.openhumanLink.notifications.asking': 'Frag dein Betriebssystem ...', + 'app.openhumanLink.notifications.blocked': 'Blockiert', + 'app.openhumanLink.notifications.blockedStep1': 'Schritt 1 blockiert', + 'app.openhumanLink.notifications.blockedStep2': 'Schritt 2 blockiert', + 'app.openhumanLink.notifications.blockedStep3': 'Schritt 3 blockiert', + 'app.openhumanLink.notifications.intro': 'Einführung', + 'app.openhumanLink.notifications.promptHint': 'Prompter Hinweis', + 'app.openhumanLink.notifications.retry': 'Benachrichtigung zum erneuten Testversuch', + 'app.openhumanLink.notifications.send': 'Testbenachrichtigung senden', + 'app.openhumanLink.notifications.sendFailed': 'Konnte nicht gesendet werden: {error}', + 'app.openhumanLink.notifications.sent': + 'Testbenachrichtigung gesendet. Wenn du sie nicht erhalten hast, gehe zu Systemeinstellungen → Benachrichtigungen → OpenHuman, aktiviere „Benachrichtigungen zulassen“ und stelle den Bannerstil auf „Persistent“ ein.', + 'app.openhumanLink.skipForNow': 'Erstmal überspringen', + 'app.openhumanLink.telegramUnavailable': 'Telegram nicht verfügbar', + 'app.openhumanLink.title.accounts': 'Verbinde deine Apps', + 'app.openhumanLink.title.billing': 'Abrechnung und Gutschriften', + 'app.openhumanLink.title.discord': 'Tritt der Community bei', + 'app.openhumanLink.title.messaging': 'Verbinde einen Chat-Kanal', + 'app.openhumanLink.title.notifications': 'Benachrichtigungen zulassen', + 'app.persistRehydration.body': 'Körper', + 'app.persistRehydration.heading': 'Überschrift', + 'app.persistRehydration.resetCta': 'Zurücksetzen…', + 'app.persistRehydration.resetting': 'Zurücksetzen…', + 'app.routeLoading.initializing': 'OpenHuman wird initialisiert...', + 'app.update.currentlyOn': '{version}', + 'app.update.errorFallback': 'Beim Update ist ein Fehler aufgetreten.', + 'app.update.header.default': 'Aktualisieren', + 'app.update.header.error': 'Update fehlgeschlagen', + 'app.update.header.installing': 'Update installieren', + 'app.update.header.readyToInstall': 'Update zur Installation bereit', + 'app.update.header.restarting': 'Neustart...', + 'app.update.later': 'Später', + 'app.update.newVersionReady': 'Eine neue Version ist zur Installation bereit.', + 'app.update.progress.downloaded': '{amount} heruntergeladen', + 'app.update.progress.installing': 'Installation der neuen Version…', + 'app.update.progress.restarting': 'Neustart der App…', + 'app.update.progress.working': '{percent}%', + 'app.update.restartNote': 'Hinweis zum Neustart', + 'app.update.restartNow': 'Starte jetzt neu', + 'app.update.versionReady': 'Version {newVersion} ist zur Installation bereit.', + 'channels.discord.accountLinked': 'Konto verknüpft', + 'channels.discord.connect': 'Verbinden', + 'channels.discord.linkTokenExpired': 'Link-Token abgelaufen. Bitte versuche es erneut.', + 'channels.discord.linkTokenInstruction': '{token}', + 'channels.discord.linkTokenLabel': 'Link-Token-Label', + 'channels.discord.linkTokenOnce': 'Link-Token einmal', + 'channels.discord.picker.allPermissionsOk': + 'Bot verfügt über alle erforderlichen Berechtigungen in diesem Kanal.', + 'channels.discord.picker.botNotInServers': 'Bot nicht auf Servern', + 'channels.discord.picker.category': 'Kategorie', + 'channels.discord.picker.channel': 'Kanal', + 'channels.discord.picker.checkingPermissions': 'Berechtigungen prüfen', + 'channels.discord.picker.loadingChannels': 'Lade Kanäle...', + 'channels.discord.picker.loadingServers': 'Server werden geladen...', + 'channels.discord.picker.missingPermissions': 'Fehlende Berechtigungen', + 'channels.discord.picker.noChannels': 'Keine Textkanäle gefunden', + 'channels.discord.picker.noServers': 'Keine Server gefunden', + 'channels.discord.picker.selectChannel': 'Wähle einen Kanal aus', + 'channels.discord.picker.selectServer': 'Wähle einen Server aus', + 'channels.discord.picker.server': 'Server', + 'channels.discord.picker.serverChannelSelection': 'Server- und Kanalauswahl', + 'channels.discord.savedRestartRequired': + 'Kanal gespeichert. Starte die App neu, um sie zu aktivieren.', + 'channels.telegram.connect': 'Verbinden', + 'channels.telegram.managedDmConnecting': 'Verwaltete DM-Verbindung', + 'channels.telegram.managedDmTimeout': 'DM-Timeout verwaltet', + 'channels.telegram.reconnect': 'Wieder verbinden', + 'channels.telegram.savedRestartRequired': + 'Kanal gespeichert. Starte die App neu, um sie zu aktivieren.', + 'channels.web.alwaysAvailable': 'Immer verfügbar', +}; + +export default de3; diff --git a/app/src/lib/i18n/chunks/de-4.ts b/app/src/lib/i18n/chunks/de-4.ts new file mode 100644 index 000000000..2fb9ae2ff --- /dev/null +++ b/app/src/lib/i18n/chunks/de-4.ts @@ -0,0 +1,401 @@ +import type { TranslationMap } from '../types'; + +// German (Deutsch) translations. Each chunk maps to chunks/en-4.ts. +const de4: TranslationMap = { + 'chat.unsubscribeApproval.approve': 'Genehmigen und abbestellen', + 'chat.unsubscribeApproval.approved': '✓ Erfolgreich abgemeldet.', + 'chat.unsubscribeApproval.denied': '✕Anfrage abgelehnt.', + 'chat.unsubscribeApproval.deny': 'Leugnen', + 'chat.unsubscribeApproval.processing': 'Verarbeitung...', + 'chat.unsubscribeApproval.title': 'Abmeldeanfrage', + 'commandPalette.ariaLabel': 'Befehlspalette', + 'commandPalette.description': 'Beschreibung', + 'commandPalette.label': 'Befehle', + 'commandPalette.noResults': 'Keine Ergebnisse', + 'commandPalette.placeholder': 'Gib einen Befehl ein oder suche ...', + 'commandPalette.searchAria': 'Suchbefehle', + 'commandPalette.shortcutHint': 'Drücke ? für alle Verknüpfungen', + 'commandPalette.title': 'Befehlspalette', + 'composio.connect.additionalConfigRequired': 'Zusätzliche Konfiguration erforderlich', + 'composio.connect.atlassianSubdomainHint': 'acme', + 'composio.connect.atlassianSubdomainLabel': 'Atlassian-Subdomain-Label', + 'composio.connect.connect': 'Verbinden', + 'composio.connect.connectionFailed': 'Verbindung fehlgeschlagen (Status: {status}).', + 'composio.connect.disconnectFailed': 'Verbindungstrennung fehlgeschlagen: {msg}', + 'composio.connect.disconnecting': 'Verbindung trennen…', + 'composio.connect.idleDescription': 'Verbinde deine', + 'composio.connect.idleDescriptionSuffix': + 'Konto. Wir öffnen ein Browserfenster, du genehmigst dort den Zugriff und diese App erkennt die Verbindung automatisch.', + 'composio.connect.isConnected': 'verbunden ist.', + 'composio.connect.manage': 'Verwalten', + 'composio.connect.needsSubdomain': 'Zum Verbinden', + 'composio.connect.needsSubdomainSuffix': + 'Gib deine Atlassian-Subdomain ein (z. B. acme für acme.atlassian.net) und versuche es erneut.', + 'composio.connect.oauthComplete': 'OAuth zum Abschließen…', + 'composio.connect.oauthTimeout': 'OAuth-Zeitüberschreitung', + 'composio.connect.permissions': 'Berechtigungen', + 'composio.connect.permissionsDefault': 'Lesen + Schreiben ist standardmäßig aktiviert', + 'composio.connect.permissionsNote': 'entlarven kann', + 'composio.connect.permissionsNoteSuffix': + 'Die eigenen Agentenberechtigungen von OpenHuman werden unten als Lese-, Schreib- und Admin-Umschaltung gesteuert.', + 'composio.connect.reopenBrowser': 'Browser erneut öffnen', + 'composio.connect.requestingUrl': 'Verbindung wird angefordert URL…', + 'composio.connect.retryConnection': 'Verbindung erneut versuchen', + 'composio.connect.scopeLoadError': 'Bereichseinstellungen konnten nicht geladen werden: {msg}', + 'composio.connect.scopeSaveError': 'Der Bereich {key} konnte nicht gespeichert werden: {msg}', + 'composio.connect.subdomainInvalid': + 'Gib nur die kurze Subdomain ein (z. B. „acme“), nicht die vollständige URL. Es sollte nur Buchstaben, Zahlen und Bindestriche enthalten.', + 'composio.connect.subdomainRequired': 'Bitte gib deine Atlassian-Subdomain ein, um fortzufahren.', + 'composio.connect.dynamicsOrgNameLabel': 'Name der Dynamics 365-Organisation', + 'composio.connect.dynamicsOrgNameHint': + 'Beispiel: „myorg“ für myorg.crm.dynamics.com. Gib nur den kurzen Organisationsnamen ein, nicht den vollständigen URL.', + 'composio.connect.needsFieldsPrefix': 'Zum Verbinden', + 'composio.connect.needsFieldsSuffix': + 'Wir brauchen ein bisschen mehr Informationen. Fülle die fehlenden Felder unten aus und versuche es erneut.', + 'composio.connect.requiredFieldEmpty': 'Dieses Feld ist erforderlich.', + 'composio.connect.wabaIdHint': + 'Finde es über GET /me/businesses und dann GET /{business_id}/owned_whatsapp_business_accounts mit deinem Meta-Zugriffstoken.', + 'composio.connect.wabaIdLabel': 'Waba-ID-Etikett', + 'composio.connect.wabaIdRequired': + 'Bitte gib deine WhatsApp Geschäftskonto-ID (WABA ID) ein, um fortzufahren.', + 'composio.connect.waitingFor': 'Warten auf', + 'composio.connect.waitingHint': 'Wartender Hinweis', + 'composio.triggers.heading': 'Auslöser', + 'composio.triggers.listenFrom': 'Auf Ereignisse hören von', + 'composio.triggers.loadError': 'Trigger konnten nicht geladen werden', + 'composio.triggers.needsConfiguration': 'Muss konfiguriert werden', + 'composio.triggers.noneAvailable': 'Derzeit sind keine Auslöser verfügbar für', + 'conversations.taskKanban.moveLeft': 'Bewege dich nach links', + 'conversations.taskKanban.moveRight': 'Bewege dich nach rechts', + 'conversations.taskKanban.title': 'Aufgaben', + 'conversations.toolTimeline.turn': 'drehen', + 'conversations.toolTimeline.workerThread': 'Worker-Thread', + 'daemon.serviceBlockingGate.body': 'Körper', + 'daemon.serviceBlockingGate.downloadHint': 'Hinweis herunterladen', + 'daemon.serviceBlockingGate.downloadLatest': 'Lade die neueste Version herunter', + 'daemon.serviceBlockingGate.retryCore': 'Core erneut versuchen', + 'daemon.serviceBlockingGate.retryFailed': + 'Wiederholungsversuch fehlgeschlagen. Lade den neuesten App-Build herunter und versuche es erneut.', + 'daemon.serviceBlockingGate.retrying': 'Erneuter Versuch...', + 'daemon.serviceBlockingGate.title': 'OpenHuman Kern ist nicht verfügbar', + 'home.banners.discordSubtitle': 'Discord Untertitel', + 'home.banners.discordTitle': 'Tritt unserem Discord bei', + 'home.banners.earlyBirdDismiss': 'Frühbucherbanner schließen', + 'home.banners.earlyBirdFirstSub': 'erstes Abonnement.', + 'home.banners.earlyBirdOn': 'Frühaufsteher', + 'home.banners.earlyBirdTitle': 'Die ersten 1.000 Nutzer erhalten 60 % Rabatt.', + 'home.banners.earlyBirdUseCode': 'Frühbucher-Nutzungscode', + 'home.banners.getSubscription': 'Hol dir ein Abonnement', + 'home.banners.promoCreditsBody': 'Probiere OpenHuman aus und wenn du Lust auf mehr hast,', + 'home.banners.promoCreditsTitle': 'Du hast {amount} Werbeguthaben.', + 'home.banners.promoCreditsUsage': 'und erhalte 10x mehr Nutzung.', + 'intelligence.memoryChunk.detail.chunk': 'Brocken', + 'intelligence.memoryChunk.detail.copyChunkId': 'Chunk-ID kopieren', + 'intelligence.memoryChunk.detail.embeddingInfo': 'bge-m3 1024dim', + 'intelligence.memoryChunk.detail.noEmbedding': 'Keine Einbettung', + 'intelligence.memoryChunk.letterhead.from': 'von', + 'intelligence.memoryChunk.letterhead.to': 'zu', + 'intelligence.memoryChunk.mentioned.chunkOne': '1 Stück', + 'intelligence.memoryChunk.mentioned.chunkOther': '{count} Stücke', + 'intelligence.memoryChunk.mentioned.heading': 'm e n t i o n e d', + 'intelligence.memoryChunk.scoreBars.ariaScore': '{name} erzielen einen Wert von {pct} Prozent', + 'intelligence.memoryChunk.scoreBars.atThreshold': 'um {threshold}', + 'intelligence.memoryChunk.scoreBars.dropped': 'fallen gelassen', + 'intelligence.memoryChunk.scoreBars.heading': 'Warum hast du es behalten?', + 'intelligence.memoryChunk.scoreBars.kept': 'gehalten', + 'intelligence.memoryText.entityTypePrefix': 'Entitätstyp', + 'intelligence.screenDebug.active': 'Aktiv', + 'intelligence.screenDebug.app': 'App', + 'intelligence.screenDebug.bounds': 'Grenzen', + 'intelligence.screenDebug.captureAlt': 'Testergebnis erfassen', + 'intelligence.screenDebug.captureFailed': 'Fehlgeschlagen', + 'intelligence.screenDebug.captureSuccess': 'Erfolg', + 'intelligence.screenDebug.captureTest': 'Capture-Test', + 'intelligence.screenDebug.capturing': 'Erfassen', + 'intelligence.screenDebug.frames': 'Rahmen', + 'intelligence.screenDebug.idle': 'Leerlauf', + 'intelligence.screenDebug.lastApp': 'Letzte App', + 'intelligence.screenDebug.mode': 'Modus', + 'intelligence.screenDebug.permAccessibility': 'Zugänglichkeit aufrechterhalten', + 'intelligence.screenDebug.permInput': 'Perm-Eingabe', + 'intelligence.screenDebug.permScreen': 'Barrierefreiheit', + 'intelligence.screenDebug.permissions': 'Berechtigungen', + 'intelligence.screenDebug.platformNotSupported': 'Plattform nicht unterstützt', + 'intelligence.screenDebug.recentVisionSummaries': 'Aktuelle Visionszusammenfassungen', + 'intelligence.screenDebug.session': 'Sitzung', + 'intelligence.screenDebug.size': 'Größe', + 'intelligence.screenDebug.status': 'Status', + 'intelligence.screenDebug.testCapture': 'Testaufnahme', + 'intelligence.screenDebug.time': 'Zeit', + 'intelligence.screenDebug.title': 'Titel', + 'intelligence.screenDebug.unknown': 'Unbekannt', + 'intelligence.screenDebug.visionQueue': 'Vision-Warteschlange', + 'intelligence.screenDebug.visionState': 'Visionszustand', + 'intelligence.tasks.activeBoardOne': '1 aktives Forum für alle Gespräche', + 'intelligence.tasks.activeBoardOther': '{count} aktive Boards in allen Gesprächen', + 'intelligence.tasks.empty': 'Noch keine Agenten-Taskboards', + 'intelligence.tasks.emptyHint': 'Leerer Hinweis', + 'intelligence.tasks.failedToLoad': 'Laden fehlgeschlagen', + 'intelligence.tasks.live': 'leben', + 'intelligence.tasks.loadingBoards': 'Taskboards werden geladen…', + 'intelligence.tasks.threadPrefix': 'Thread {thread}', + 'notifications.card.dismiss': 'Benachrichtigung verwerfen', + 'notifications.card.importanceTitle': 'Wichtigkeit: {pct}%', + 'notifications.center.empty': 'Noch keine Benachrichtigungen', + 'notifications.center.emptyHint': 'Leerer Hinweis', + 'notifications.center.filterAll': 'Alles filtern', + 'notifications.center.markAllRead': 'Alles als gelesen markieren', + 'notifications.center.title': 'Benachrichtigungen', + 'oauth.button.connecting': 'Verbinden...', + 'oauth.login.continueWith': 'Weiter mit', + 'onboarding.contextGathering.buildingDesc': 'Gebäudebeschreibung', + 'onboarding.contextGathering.buildingProfile': 'Erstelle dein Profil...', + 'onboarding.contextGathering.continueToChat': 'Weiter chatten', + 'onboarding.contextGathering.errorDesc': + 'Dein Chat ist fertig. Wir erstellen im Hintergrund weiterhin dein vollständiges Profil, sodass du jetzt fortfahren und es im Laufe der Zeit verfeinern kannst.', + 'onboarding.contextGathering.coreAlive': + 'Der Kern ist erreichbar – der erste Start kann eine Minute dauern.', + 'onboarding.contextGathering.coreAliveProbing': 'Kernverbindung prüfen…', + 'onboarding.contextGathering.coreUnreachable': + 'Der Kern reagiert nicht. Du kannst fortfahren und es später noch einmal versuchen.', + 'onboarding.contextGathering.stillWorkingDesc': + 'Der erste Start kann 30–60 Sekunden dauern, während wir dein lokales Modell und deine Tools aufwärmen. Du kannst jederzeit weiter chatten – die Profilerstellung läuft im Hintergrund weiter.', + 'onboarding.contextGathering.stillWorkingTitle': 'Ich arbeite immer noch an deinem Profil…', + 'onboarding.contextGathering.title': 'Kontexterfassung', + 'openhuman.team_list_teams': 'Teamlisten-Teams', + 'overlay.ariaAttention': 'Achtung-Nachricht', + 'overlay.ariaCompanion': 'Begleiter aktiv', + 'overlay.ariaOrb': 'OpenHuman-Overlay', + 'overlay.ariaVoiceActive': 'Spracheingabe aktiv', + 'overlay.companion.error': 'Fehler', + 'overlay.companion.listening': 'Zuhören…', + 'overlay.companion.pointing': 'Zeigen…', + 'overlay.companion.speaking': 'Apropos…', + 'overlay.companion.thinking': 'Denken…', + 'overlay.orbTitle': 'Zum Verschieben ziehen · Doppelklicken, um die Position zurückzusetzen', + 'pages.settings.account.connections': 'Verbindungen', + 'pages.settings.account.connectionsDesc': 'Überprüfe und verwalte verknüpfte Kontoverbindungen', + 'pages.settings.account.privacy': 'Privatsphäre', + 'pages.settings.account.privacyDesc': + 'Verwalte die Datenfreigabe und anonymisierte Nutzungspräferenzen', + 'pages.settings.account.recoveryPhrase': 'Wiederherstellungssatz', + 'pages.settings.account.recoveryPhraseDesc': + 'Verwalte deine BIP39-Wiederherstellungsphrase für Verschlüsselung und Wallet-Zugriff', + 'pages.settings.account.team': 'Team', + 'pages.settings.account.teamDesc': 'Verwalte dein Team, deine Mitglieder und Einladungen', + 'pages.settings.account.migration': 'Von einem anderen Assistenten importieren', + 'pages.settings.account.migrationDesc': + 'Migriere Speicher und Notizen von OpenClaw (oder bald Hermes) in diesen Arbeitsbereich.', + 'pages.settings.accountSection.description': + 'Wiederherstellungsphrase, Team, Verbindungen und Datenschutzeinstellungen.', + 'pages.settings.accountSection.title': 'Konto', + 'pages.settings.ai.llm': 'Llm', + 'pages.settings.ai.llmDesc': 'Llm absch', + 'pages.settings.ai.voice': 'Stimme', + 'pages.settings.ai.voiceDesc': 'Sprachbeschreibung', + 'pages.settings.aiSection.description': + 'Sprachmodellanbieter, lokal Ollama und Sprache (STT / TTS).', + 'pages.settings.aiSection.title': 'AI', + 'pages.settings.features.desktopCompanion': 'Desktop-Begleiter', + 'pages.settings.features.desktopCompanionDesc': + 'Sprachassistent mit Bildschirmerkennung – hört zu, sieht, spricht, zeigt', + 'pages.settings.features.messagingChannels': 'Messaging-Kanäle', + 'pages.settings.features.messagingChannelsDesc': 'Nachrichtenkanäle, Abschn', + 'pages.settings.features.notifications': 'Benachrichtigungen', + 'pages.settings.features.notificationsDesc': 'Benachrichtigungen absch', + 'pages.settings.features.screenAwareness': 'Bildschirmbewusstsein', + 'pages.settings.features.screenAwarenessDesc': 'Abschn. Bildschirmwahrnehmung', + 'pages.settings.features.tools': 'Werkzeuge', + 'pages.settings.features.toolsDesc': 'Werkzeugbeschr', + 'pages.settings.featuresSection.description': 'Bildschirmbewusstsein, Nachrichten und Tools.', + 'pages.settings.featuresSection.title': 'Funktionen', + 'privacy.dataKind.credentials': 'Anmeldeinformationen', + 'privacy.dataKind.derived': 'Abgeleitet', + 'privacy.dataKind.diagnostics': 'Diagnose', + 'privacy.dataKind.metadata': 'MetaDaten', + 'privacy.dataKind.raw': 'Roh', + 'privacy.whatLeaves.link.label': 'Was verlässt meinen Computer?', + 'rewards.community.achievementsUnlocked': '{unlocked} von {total} Erfolgen freigeschaltet', + 'rewards.community.connectDiscord': 'Verbinde Discord', + 'rewards.community.cumulativeTokens': 'Kumulierte Token', + 'rewards.community.currentStreak': 'Aktuelle Serie', + 'rewards.community.discordLinkedNotInGuild': 'Verlinkt, aber nicht auf dem Server', + 'rewards.community.discordMember': 'Dem Server beigetreten', + 'rewards.community.discordNotLinked': 'Nicht verlinkt', + 'rewards.community.discordServer': 'Discord Server', + 'rewards.community.discordStatusUnavailable': 'Mitgliedschaftsstatus nicht verfügbar', + 'rewards.community.discordWaiting': 'Warten auf Backend-Synchronisierung', + 'rewards.community.heroSubtitle': + 'Schalte exklusive Kanäle, Unterstützerabzeichen und Backend-synchronisierte Belohnungen frei, indem du dein Discord-Konto verknüpfst.', + 'rewards.community.heroTitle': 'Verdiene Belohnungen und Discord Rollen', + 'rewards.community.joinDiscord': 'Tritt Discord bei', + 'rewards.community.loadingRewards': 'Prämien werden geladen…', + 'rewards.community.locked': 'Gesperrt', + 'rewards.community.retrying': 'Erneuter Versuch…', + 'rewards.community.rolesAndRewards': 'Rollen und Belohnungen', + 'rewards.community.streakDays': '{n} Tage', + 'rewards.community.syncPending': 'Synchronisierung der Prämien steht aus', + 'rewards.community.syncPendingDesc': 'Synchronisierung ausstehend', + 'rewards.community.syncUnavailable': 'Synchronisierung nicht verfügbar', + 'rewards.community.tryAgain': 'Erneuter Versuch…', + 'rewards.community.unknown': 'Unbekannt', + 'rewards.community.unlocked': 'Entsperrt', + 'rewards.community.yourProgress': 'Dein Fortschritt', + 'rewards.coupon.colCode': 'Code', + 'rewards.coupon.colRedeemed': 'Eingelöst', + 'rewards.coupon.colReward': 'Belohnung', + 'rewards.coupon.colStatus': 'Status', + 'rewards.coupon.loadingHistory': 'Prämienverlauf wird geladen…', + 'rewards.coupon.noCodes': 'Es wurden noch keine Prämiencodes eingelöst.', + 'rewards.coupon.pending': 'Ausstehend', + 'rewards.coupon.placeholder': 'Gutscheincode', + 'rewards.coupon.promoCredits': 'Promo-Credits', + 'rewards.coupon.recentRedemptions': 'Aktuelle Einlösungen', + 'rewards.coupon.redeemAccepted': + '{code} akzeptiert. {amount} wird entsperrt, nachdem die erforderliche Aktion abgeschlossen ist.', + 'rewards.coupon.redeemButton': 'Code einlösen', + 'rewards.coupon.redeemSuccess': '{code} eingelöst. {amount} wurde zu deinen Credits hinzugefügt.', + 'rewards.coupon.redeemedCodes': 'Eingelöste Codes', + 'rewards.coupon.redeeming': 'Einlösen...', + 'rewards.coupon.statusApplied': 'Angewendet', + 'rewards.coupon.statusPendingAction': 'Ausstehende Maßnahmen', + 'rewards.coupon.statusRedeemed': 'Eingelöst', + 'rewards.coupon.subtitle': 'Untertitel', + 'rewards.coupon.title': 'Gutscheincode einlösen', + 'rewards.referralSection.activity': 'Empfehlungsaktivität', + 'rewards.referralSection.apply': 'Bewerben…', + 'rewards.referralSection.applying': 'Bewerben…', + 'rewards.referralSection.colReferredUser': 'Empfohlener Benutzer', + 'rewards.referralSection.colReward': 'Belohnung', + 'rewards.referralSection.colStatus': 'Status', + 'rewards.referralSection.colUpdated': 'Aktualisiert', + 'rewards.referralSection.completed': 'Abgeschlossen', + 'rewards.referralSection.copyCode': 'Code kopieren', + 'rewards.referralSection.copyFailed': 'Der Kopiervorgang ist fehlgeschlagen', + 'rewards.referralSection.haveCode': 'Hast du einen Empfehlungscode?', + 'rewards.referralSection.haveCodeDesc': 'Habe Codebeschreibung', + 'rewards.referralSection.linked': 'Verlinkt', + 'rewards.referralSection.linkedCode': '(Code {code})', + 'rewards.referralSection.loading': 'Empfehlungsprogramm wird geladen…', + 'rewards.referralSection.noReferrals': 'Keine Empfehlungen', + 'rewards.referralSection.pendingReferrals': 'Ausstehende Empfehlungen', + 'rewards.referralSection.placeholder': 'Empfehlungscode', + 'rewards.referralSection.share': 'Teilen', + 'rewards.referralSection.statusCompleted': 'Status abgeschlossen', + 'rewards.referralSection.statusExpired': 'Status abgelaufen', + 'rewards.referralSection.statusJoined': 'Status beigetreten', + 'rewards.referralSection.subtitle': 'Untertitel', + 'rewards.referralSection.title': 'Freunde einladen, Credits verdienen', + 'rewards.referralSection.totalEarned': 'Insgesamt verdient', + 'rewards.referralSection.yourCode': 'Dein Code', + 'settings.ai.addCloudProvider': 'Cloud-Anbieter hinzufügen', + 'settings.ai.addProvider': 'Sparen…', + 'settings.ai.apiKeyFieldLabel': 'Bezeichnung des API-Schlüsselfelds', + 'settings.ai.apiKeyRequired': 'Bitte füge deinen API-Schlüssel ein, um fortzufahren.', + 'settings.ai.apiKeyStoredEncrypted': 'API-Schlüssel verschlüsselt gespeichert', + 'settings.ai.apiKeysEncrypted': 'auth-profiles.json', + 'settings.ai.clearStoredKey': 'Gespeicherten Schlüssel löschen', + 'settings.ai.connectProvider': 'Anbieter verbinden', + 'settings.ai.customRouting': 'Benutzerdefiniertes Routing', + 'settings.ai.defaultResolvesTo': 'OpenHuman', + 'settings.ai.discard': 'Verwerfen', + 'settings.ai.editProvider': 'Anbieter bearbeiten', + 'settings.ai.llmProviders': 'LLM Anbieter', + 'settings.ai.llmProvidersDesc': 'LLM-Anbieter absch', + 'settings.ai.localOllama': 'Lokal (Ollama)', + 'settings.ai.modelLabel': 'Modell', + 'settings.ai.noCustomProviders': 'Keine benutzerdefinierten Anbieter', + 'settings.ai.providerLabel': 'Anbieter', + 'settings.ai.routing': 'Routenführung', + 'settings.ai.routingCustom': 'Routing benutzerdefiniert', + 'settings.ai.routingDefault': 'Standard', + 'settings.ai.routingDesc': 'Routing-Beschreibung', + 'settings.ai.saveChanges': 'Sparen…', + 'settings.ai.saving': 'Sparen…', + 'settings.ai.unsavedChange': 'nicht gespeicherte Änderung', + 'settings.ai.unsavedChanges': 'nicht gespeicherte Änderungen', + 'settings.ai.workloadGroupBackground': 'Hintergrund der Arbeitslastgruppe', + 'settings.ai.workloadGroupChat': 'Workload-Gruppenchat', + 'settings.autocomplete.appFilter.acceptSuggestion': 'Vorschlag annehmen', + 'settings.autocomplete.appFilter.contextOverride': 'Kontextüberschreibung (optional)', + 'settings.autocomplete.appFilter.debugFocus': 'Debug-Fokus', + 'settings.autocomplete.appFilter.getSuggestion': 'Hol dir einen Vorschlag', + 'settings.autocomplete.appFilter.liveLogs': 'Live-Protokolle', + 'settings.autocomplete.appFilter.noLogs': ') :', + 'settings.autocomplete.appFilter.refreshStatus': 'Erfrischend…', + 'settings.autocomplete.appFilter.refreshing': 'Erfrischend…', + 'settings.autocomplete.appFilter.runtime': 'Laufzeit', + 'settings.autocomplete.appFilter.test': 'Testen', + 'settings.autocomplete.completionStyle.acceptedCompletion': + '{count} akzeptierter Abschluss gespeichert – wird zur Personalisierung zukünftiger Vorschläge verwendet.', + 'settings.autocomplete.completionStyle.acceptedCompletions': + '{count} akzeptierte Vervollständigungen werden gespeichert – werden zur Personalisierung zukünftiger Vorschläge verwendet.', + 'settings.autocomplete.completionStyle.clearHistory': 'Löschen…', + 'settings.autocomplete.completionStyle.clearing': 'Löschen…', + 'settings.autocomplete.completionStyle.debounce': 'Entprellung (ms)', + 'settings.autocomplete.completionStyle.enabled': 'Aktiviert', + 'settings.autocomplete.completionStyle.maxChars': 'Max Chars', + 'settings.autocomplete.completionStyle.noHistory': + 'Noch keine akzeptierten Abschlüsse. Akzeptiere Vorschläge mit der Tabulatortaste, um mit der Personalisierung zu beginnen.', + 'settings.autocomplete.completionStyle.overlayTtl': 'Overlay TTL (ms)', + 'settings.autocomplete.completionStyle.personalizationHistory': 'Personalisierungsverlauf', + 'settings.autocomplete.completionStyle.styleExamples': 'Stilbeispiele (eines pro Zeile)', + 'settings.autocomplete.completionStyle.styleInstructions': 'Stilanweisungen', + 'settings.billing.autoRecharge.addAmount': 'Füge diesen Betrag hinzu', + 'settings.billing.autoRecharge.addCard': 'Karte hinzufügen', + 'settings.billing.autoRecharge.amountHint': 'Betragshinweis', + 'settings.billing.autoRecharge.defaultCard': 'Standardkarte', + 'settings.billing.autoRecharge.lastRechargeFailed': 'Das letzte Aufladen ist fehlgeschlagen', + 'settings.billing.autoRecharge.lastRecharged': 'Zuletzt aufgeladen', + 'settings.billing.autoRecharge.noCards': 'Keine Karten', + 'settings.billing.autoRecharge.paymentMethods': 'Zahlungsmethoden', + 'settings.billing.autoRecharge.rechargeInProgress': 'Aufladen läuft', + 'settings.billing.autoRecharge.rechargeWhen': 'Aufladen, wenn der Saldo darunter fällt', + 'settings.billing.autoRecharge.saveSettings': 'Sparen…', + 'settings.billing.autoRecharge.saving': 'Sparen…', + 'settings.billing.autoRecharge.setDefault': ':', + 'settings.billing.autoRecharge.subtitle': 'Untertitel', + 'settings.billing.autoRecharge.title': 'Aktiviere die automatische Aufladung', + 'settings.billing.autoRecharge.toggleAriaLabel': 'Automatisches Aufladen umschalten', + 'settings.billing.autoRecharge.weeklyLimit': 'Wöchentliches Ausgabenlimit', + 'settings.billing.history.desc': 'Beschr', + 'settings.billing.history.empty': 'Leer', + 'settings.billing.history.openPortal': 'Portal öffnen', + 'settings.billing.history.posted': 'Gepostet', + 'settings.billing.history.title': 'Titel', + 'settings.billing.inferenceBudget.cycleEnds': 'Der Zyklus endet', + 'settings.billing.inferenceBudget.exhausted': 'Erschöpft', + 'settings.billing.inferenceBudget.loadError': 'Ladefehler', + 'settings.billing.inferenceBudget.noBudgetDesc': 'Kein Budgetabzug', + 'settings.billing.inferenceBudget.noRecurringBudget': 'Kein wiederkehrendes Budget', + 'settings.billing.inferenceBudget.remaining': 'Übrig', + 'settings.billing.inferenceBudget.tenHourCap': 'Zehn-Stunden-Kappe', + 'settings.billing.inferenceBudget.title': 'Titel', + 'settings.billing.payAsYouGo.available': 'Verfügbar', + 'settings.billing.payAsYouGo.chargeCustomAmount': 'Wird geöffnet…', + 'settings.billing.payAsYouGo.chooseTopUpDesc': 'Wähle „Aufladepreis“.', + 'settings.billing.payAsYouGo.chooseTopUpTitle': 'Wähle den Aufladetitel', + 'settings.billing.payAsYouGo.creditBalanceDesc': 'Guthabenbez', + 'settings.billing.payAsYouGo.creditBalanceTitle': 'Guthabentitel', + 'settings.billing.payAsYouGo.customAmount': 'Benutzerdefinierter Betrag', + 'settings.billing.payAsYouGo.enterAmount': 'Betrag eingeben', + 'settings.billing.payAsYouGo.opening': '{amount}', + 'settings.billing.payAsYouGo.promotionalCredits': 'Werbegutschriften', + 'settings.billing.payAsYouGo.topUpBalance': 'Aufladeguthaben', + 'settings.billing.payAsYouGo.topUpCredits': 'Guthaben aufladen', + 'settings.billing.payAsYouGo.unableToLoad': 'Der Ladeausgleich kann nicht durchgeführt werden.', + 'settings.billing.subscription.annual': 'Jährlich', + 'settings.billing.subscription.billedAnnually': 'Jährliche Abrechnung', + 'settings.billing.subscription.chooseSubtitle': 'Untertitel wählen', + 'settings.billing.subscription.chooseTitle': 'Titel wählen', + 'settings.billing.subscription.cryptoDesc': 'Krypto-Beschreibung', + 'settings.billing.subscription.cryptoQuestion': 'Krypto-Frage', + 'settings.billing.subscription.current': 'Aktuell', + 'settings.billing.subscription.currentPlan': 'Aktueller Plan', + 'settings.billing.subscription.monthly': 'Monatlich', + 'settings.billing.subscription.paymentConfirmed': 'Zahlung bestätigt', + 'settings.billing.subscription.perMonth': 'Pro Monat', + 'settings.billing.subscription.popular': 'Beliebt', +}; + +export default de4; diff --git a/app/src/lib/i18n/chunks/de-5.ts b/app/src/lib/i18n/chunks/de-5.ts new file mode 100644 index 000000000..c698c292f --- /dev/null +++ b/app/src/lib/i18n/chunks/de-5.ts @@ -0,0 +1,506 @@ +import type { TranslationMap } from '../types'; + +// German (Deutsch) translations. Each chunk maps to chunks/en-5.ts. +const de5: TranslationMap = { + 'settings.billing.subscription.save': '{pct}', + 'settings.billing.subscription.upgrade': 'Upgrade', + 'settings.billing.subscription.waiting': 'Warten', + 'settings.billing.subscription.waitingPayment': 'Warten auf Zahlung', + 'settings.composio.apiKeyDesc': + 'Auf diesem Gerät ist derzeit ein Schlüssel vom Typ Composio API gespeichert.', + 'settings.composio.apiKeyLabel': 'Composio API Schlüssel', + 'settings.composio.apiKeyStored': 'API Schlüssel gespeichert', + 'settings.composio.apiKeyStoredPlaceholder': '•·•······················', + 'settings.composio.clearedToBackend': 'In den Backend-Modus gewechselt', + 'settings.composio.confirmItem1': 'Ein Konto bei app.composio.dev mit einem API-Schlüssel', + 'settings.composio.confirmItem2': + 'Um jede Integration über dein persönliches Composio-Konto erneut zu verknüpfen', + 'settings.composio.confirmItem3': + 'Hinweis: Composio-Trigger (Echtzeit-Webhooks) werden noch nicht im Direktmodus ausgelöst, sondern nur bei synchronen Toolaufrufen', + 'settings.composio.confirmNeedItems': 'Du brauchst:', + 'settings.composio.confirmSwitch': 'Ich verstehe, zu Direct wechseln', + 'settings.composio.confirmTitle': '⚠️ Wechsel in den Direktmodus', + 'settings.composio.confirmWarning': + 'Deine vorhandenen Integrationen (Gmail, Slack, GitHub usw., die über OpenHuman verknüpft sind) sind nicht sichtbar – sie befinden sich im von OpenHuman verwalteten Composio-Mandanten.', + 'settings.composio.intro': + 'Composio integriert mehr als 250 externe Apps als Tools, die dein Agent aufrufen kann. Wähle aus, wie diese Werkzeugaufrufe weitergeleitet werden.', + 'settings.composio.modeDirect': 'Direkt (bring deinen eigenen API-Schlüssel mit)', + 'settings.composio.modeDirectDesc': + 'Anrufe gehen direkt an backend.composio.dev. Souverän / offlinefreundlich. Die Werkzeugausführung erfolgt synchron; Echtzeit-Trigger-Webhooks werden noch nicht im Direktmodus weitergeleitet (Folgeproblem).', + 'settings.composio.modeManaged': 'Verwaltet (OpenHuman erledigt das für dich)', + 'settings.composio.modeManagedDesc': + 'OpenHuman leitet Tool-Aufrufe über unser Backend weiter (empfohlen). Auth wird vermittelt; du fügst niemals einen Composio API-Schlüssel ein. Webhooks werden vollständig weitergeleitet.', + 'settings.composio.routingMode': 'Routing-Modus', + 'settings.composio.saveErrorNoKey': + 'Speichern fehlgeschlagen. Der Direktmodus erfordert einen nicht leeren Schlüssel API.', + 'settings.composio.saving': 'Sparen…', + 'settings.composio.switching': 'Wechseln…', + 'settings.cron.jobs.desc': 'Beschr', + 'settings.cron.jobs.empty': 'Keine zentralen Cron-Jobs gefunden.', + 'settings.cron.jobs.lastStatus': 'Letzter Stand', + 'settings.cron.jobs.loading': 'Cron-Jobs werden geladen...', + 'settings.cron.jobs.loadingRuns': 'Ladeläufe', + 'settings.cron.jobs.nextRun': 'Nächster Lauf', + 'settings.cron.jobs.pause': 'Pause', + 'settings.cron.jobs.paused': 'Aktiviert', + 'settings.cron.jobs.recentRuns': 'Aktuelle Läufe', + 'settings.cron.jobs.removing': 'Entfernen', + 'settings.cron.jobs.resume': 'Lebenslauf', + 'settings.cron.jobs.runningNow': 'Läuft jetzt', + 'settings.cron.jobs.saving': 'Sparen…', + 'settings.cron.jobs.schedule': 'Zeitplan', + 'settings.cron.jobs.title': 'Kern-Cron-Jobs', + 'settings.cron.jobs.viewRuns': 'Läufe ansehen', + 'settings.localModel.deviceCapability.active': 'Aktiv', + 'settings.localModel.deviceCapability.appliedTier': 'Angewandte Stufe', + 'settings.localModel.deviceCapability.applying': 'Bewerben', + 'settings.localModel.deviceCapability.cores': '{count}', + 'settings.localModel.deviceCapability.couldNotLoadPresets': + 'Voreinstellungen konnten nicht geladen werden', + 'settings.localModel.deviceCapability.cpu': 'CPU', + 'settings.localModel.deviceCapability.customModelIds': 'Benutzerdefinierte Modell-IDs', + 'settings.localModel.deviceCapability.detected': 'Erkannt', + 'settings.localModel.deviceCapability.disabled': 'Deaktiviert', + 'settings.localModel.deviceCapability.disabledDesc': + 'Lokale KI ist deaktiviert. Alle Inferenzanfragen laufen über die Cloud.', + 'settings.localModel.deviceCapability.downloadingModels': '(Modelle herunterladen)', + 'settings.localModel.deviceCapability.downloadingSetupDesc': + 'Lade das OllamaSetup-Installationsprogramm (~2 GB) herunter und entpacke es. Dies kann bei der ersten Installation eine Minute dauern.', + 'settings.localModel.deviceCapability.failedToApplyPreset': + 'Voreinstellung konnte nicht angewendet werden', + 'settings.localModel.deviceCapability.gpu': 'GPU', + 'settings.localModel.deviceCapability.installFailed': 'Ollama Installation fehlgeschlagen', + 'settings.localModel.deviceCapability.installFailedDesc': + 'Das Installationsprogramm wurde beendet, bevor Ollama verwendbar war. Klicke auf „Wiederholen“, um es noch einmal zu versuchen, oder installiere es manuell von ollama.com.', + 'settings.localModel.deviceCapability.installFirst': 'Führe zuerst Ollama aus.', + 'settings.localModel.deviceCapability.installFirstDesc': + 'Lokale Ebenen hängen von einem extern verwalteten Ollama-Endpunkt ab. Starte es selbst, rufe die gewünschten Modelle ab und verwende weiterhin „Deaktiviert (Cloud-Fallback)“, bis die Laufzeit erreichbar ist.', + 'settings.localModel.deviceCapability.installOllamaFirst': + 'Führe zuerst Ollama aus, um diese Stufe zu verwenden', + 'settings.localModel.deviceCapability.installingOllama': 'Ollama installieren', + 'settings.localModel.deviceCapability.loadingDeviceInfo': 'Geräteinformationen werden geladen', + 'settings.localModel.deviceCapability.localAiDisabled': + 'Lokale KI deaktiviert – Cloud-Fallback wird verwendet.', + 'settings.localModel.deviceCapability.modelTier': 'Modellebene', + 'settings.localModel.deviceCapability.needsOllama': 'Braucht Ollama', + 'settings.localModel.deviceCapability.notDetected': 'Nicht erkannt', + 'settings.localModel.deviceCapability.ram': 'RAM', + 'settings.localModel.deviceCapability.recommended': 'Empfohlen', + 'settings.localModel.deviceCapability.retryInstall': 'Erneuter Versuch…', + 'settings.localModel.deviceCapability.retrying': 'Erneuter Versuch…', + 'settings.localModel.deviceCapability.starting': 'Beginnend mit …', + 'settings.localModel.download.audioPathPlaceholder': 'Absoluter Pfad zur Audiodatei', + 'settings.localModel.download.capabilityAssets': 'Fähigkeitsressourcen', + 'settings.localModel.download.downloading': 'Herunterladen...', + 'settings.localModel.download.embeddingPlaceholder': 'Eine Eingabezeichenfolge pro Zeile...', + 'settings.localModel.download.noThinkMode': 'Kein Denkmodus', + 'settings.localModel.download.promptPlaceholder': + 'Gib eine beliebige Eingabeaufforderung ein und führe sie für das lokale Modell aus ...', + 'settings.localModel.download.quantizationPref': 'Quantisierungspräferenz', + 'settings.localModel.download.runEmbeddingTest': 'Laufen...', + 'settings.localModel.download.runPromptTest': 'Führe den Prompt-Test durch', + 'settings.localModel.download.runSummaryTest': 'Führe einen Zusammenfassungstest durch', + 'settings.localModel.download.runTranscriptionTest': 'Laufen...', + 'settings.localModel.download.runTtsTest': 'Laufen...', + 'settings.localModel.download.runVisionTest': 'Laufen...', + 'settings.localModel.download.running': 'Laufen...', + 'settings.localModel.download.runningPrompt': 'Laufaufforderung', + 'settings.localModel.download.summarizePlaceholder': + 'Füge Text ein, um ihn mit dem lokalen Modell zusammenzufassen ...', + 'settings.localModel.download.testCustomPrompt': + 'Teste die benutzerdefinierte Eingabeaufforderung', + 'settings.localModel.download.testEmbeddings': 'Einbettungen testen', + 'settings.localModel.download.testSummarization': 'Testzusammenfassung', + 'settings.localModel.download.testVisionPrompt': 'Test-Sehaufforderung', + 'settings.localModel.download.testVoiceInput': 'Spracheingabe testen (STT)', + 'settings.localModel.download.testVoiceOutput': 'Sprachausgabe testen (TTS)', + 'settings.localModel.download.ttsOutputPlaceholder': 'Optionaler Ausgabepfad WAV', + 'settings.localModel.download.ttsPlaceholder': 'Gib den zu synthetisierenden Text ein...', + 'settings.localModel.download.visionImagePlaceholder': + 'Eine Bildreferenz pro Zeile (Daten URI, URL oder lokale Pfadmarkierung)', + 'settings.localModel.download.visionPromptPlaceholder': + 'Gib eine Eingabeaufforderung für das Vision-Modell ein...', + 'settings.localModel.status.allChecksPassed': 'Alle Prüfungen bestanden', + 'settings.localModel.status.artifact': 'Artefakt', + 'settings.localModel.status.backend': 'Backend', + 'settings.localModel.status.binary': 'Binär', + 'settings.localModel.status.bootstrapResume': 'Bootstrap / Fortsetzen', + 'settings.localModel.status.checking': 'Überprüfen...', + 'settings.localModel.status.checkingOllama': 'Ollama wird überprüft', + 'settings.localModel.status.customLocation': 'Benutzerdefinierter Standort', + 'settings.localModel.status.customLocationDesc': 'Benutzerdefinierte Standortbeschreibung', + 'settings.localModel.status.diagnosticsHint': + 'Klicke auf „Diagnose ausführen“, um zu überprüfen, ob Ollama ausgeführt wird und Modelle installiert sind.', + 'settings.localModel.status.downloadingUnknown': 'Wird heruntergeladen (Größe unbekannt)', + 'settings.localModel.status.eta': 'Eta', + 'settings.localModel.status.expectedModels': 'Erwartete Modelle', + 'settings.localModel.status.forceRebootstrap': 'Neustart erzwingen', + 'settings.localModel.status.generationTps': 'Generation TPS', + 'settings.localModel.status.hideErrorDetails': 'Fehlerdetails ausblenden', + 'settings.localModel.status.installManually': 'Manuell installieren', + 'settings.localModel.status.installManuallyFrom': 'Manuell installieren von', + 'settings.localModel.status.installOllama': 'Beginnend mit …', + 'settings.localModel.status.installedModels': 'Installierte Modelle', + 'settings.localModel.status.installing': 'Installieren...', + 'settings.localModel.status.installingOllama': 'Ollama-Laufzeit wird installiert...', + 'settings.localModel.status.issues': 'Probleme', + 'settings.localModel.status.issuesFound': '{count} Problem(e) gefunden', + 'settings.localModel.status.lastLatency': 'Letzte Latenz', + 'settings.localModel.status.model': 'Modell', + 'settings.localModel.status.notFound': 'Nicht gefunden', + 'settings.localModel.status.notRunning': 'Läuft nicht', + 'settings.localModel.status.ollamaBinaryPath': 'Ollama Binärpfad', + 'settings.localModel.status.ollamaDiagnostics': 'Ollama Diagnose', + 'settings.localModel.status.ollamaNotInstalled': 'Ollama Laufzeit nicht verfügbar', + 'settings.localModel.status.ollamaNotInstalledDesc': + 'OpenHuman behandelt jetzt Ollama als externe Inferenzlaufzeit. Starte deinen eigenen Ollama-Server, rufe die gewünschten Modelle ab und richte das Workload-Routing darauf aus.', + 'settings.localModel.status.progress': 'Fortschritt', + 'settings.localModel.status.provider': 'Anbieter', + 'settings.localModel.status.retryBootstrap': 'Versuche Bootstrap erneut', + 'settings.localModel.status.runDiagnostics': 'Überprüfen...', + 'settings.localModel.status.running': 'Laufen', + 'settings.localModel.status.runningExternalProcess': + 'Wird über einen externen Prozess ausgeführt', + 'settings.localModel.status.runtimeStatus': 'Laufzeitstatus', + 'settings.localModel.status.server': 'Server', + 'settings.localModel.status.setPath': 'Einstellung...', + 'settings.localModel.status.setting': 'Einstellung...', + 'settings.localModel.status.showErrorDetails': 'Fehlerdetails ausblenden', + 'settings.localModel.status.showInstallErrorDetails': 'Fehlerdetails ausblenden', + 'settings.localModel.status.suggestedFixes': 'Vorgeschlagene Korrekturen', + 'settings.localModel.status.thenSetPath': 'Dann lege den Pfad fest', + 'settings.localModel.status.triggering': 'Auslösen...', + 'settings.localModel.status.unavailable': 'Nicht verfügbar', + 'settings.localModel.status.working': 'Arbeiten...', + 'settings.developerMenu.ai.title': 'KI-Konfiguration', + 'settings.developerMenu.ai.desc': + 'Cloud-Anbieter, lokale Ollama-Modelle und Routing pro Workload', + 'settings.developerMenu.screenAwareness.title': 'Bildschirmbewusstsein', + 'settings.developerMenu.screenAwareness.desc': + 'Bildschirmaufnahmeberechtigungen, Überwachungsrichtlinien und Sitzungskontrollen', + 'settings.developerMenu.messagingChannels.title': 'Messaging-Kanäle', + 'settings.developerMenu.messagingChannels.desc': + 'Konfiguriere die Authentifizierungsmodi Telegram/Discord und das Standardkanalrouting', + 'settings.developerMenu.tools.title': 'Werkzeuge', + 'settings.developerMenu.tools.desc': + 'Aktiviere oder deaktiviere Funktionen, die OpenHuman in deinem Namen nutzen kann', + 'settings.developerMenu.agentChat.title': 'Agenten-Chat', + 'settings.developerMenu.agentChat.desc': + 'Test-Agent-Konversation mit Modell- und Temperaturüberschreibungen', + 'settings.developerMenu.cronJobs.title': 'Cron-Jobs', + 'settings.developerMenu.cronJobs.desc': + 'Zeige geplante Jobs für Laufzeitfähigkeiten an und konfiguriere sie', + 'settings.developerMenu.localModelDebug.title': 'Lokales Modell-Debug', + 'settings.developerMenu.localModelDebug.desc': + 'Ollama-Konfiguration, Asset-Downloads, Modelltests und Diagnose', + 'settings.developerMenu.webhooks.title': 'Webhooks', + 'settings.developerMenu.webhooks.desc': + 'Prüfe Laufzeit-Webhook-Registrierungen und erfasste Anforderungsprotokolle', + 'settings.developerMenu.intelligence.title': 'Intelligenz', + 'settings.developerMenu.intelligence.desc': + 'Gedächtnisarbeitsbereich, Unterbewusstseinsmotor, Träume und Einstellungen', + 'settings.developerMenu.notificationRouting.title': 'Benachrichtigungsweiterleitung', + 'settings.developerMenu.notificationRouting.desc': + 'KI-Wichtigkeitsbewertung und Orchestrator-Eskalation für Integrationswarnungen', + 'settings.developerMenu.composeioTriggers.title': 'ComposeIO Auslöser', + 'settings.developerMenu.composeioTriggers.desc': + 'Sieh dir den ComposeIO-Triggerverlauf und das Archiv an', + 'settings.developerMenu.composioRouting.title': 'Composio Routing (Direktmodus)', + 'settings.developerMenu.composioRouting.desc': + 'Bring deinen eigenen Composio API-Schlüssel mit und leite Anrufe direkt an backend.composio.dev weiter', + 'settings.developerMenu.integrationTriggers.title': 'Integrationsauslöser', + 'settings.developerMenu.integrationTriggers.desc': + 'Konfiguriere KI-Triage-Einstellungen für Composio-Integrationsauslöser', + 'settings.appearance.menuDesc': 'Wähle hell, dunkel oder passend zu deinem Systemthema', + 'settings.mascot.active': 'Aktiv', + 'settings.mascot.characterDesc': 'Charakterbeschreibung', + 'settings.mascot.characterHeading': 'Zeichenüberschrift', + 'settings.mascot.colorDesc': 'Farbbeschreibung', + 'settings.mascot.colorHeading': 'Farbüberschrift', + 'settings.mascot.loadingLibrary': 'OpenHuman-Bibliothek wird geladen…', + 'settings.mascot.localDefault': 'Lokal OpenHuman (Standard)', + 'settings.mascot.menuTitle': 'Maskottchen', + 'settings.mascot.menuDesc': + 'Wähle die Maskottchenfarbe aus, die in der gesamten App verwendet wird', + 'settings.mascot.noCharacters': 'Es sind noch keine OpenHuman Zeichen verfügbar', + 'settings.mascot.noColorVariants': 'Keine Farbvarianten', + 'settings.mascot.voice.current': 'aktuell', + 'settings.mascot.voice.customDesc': + 'Sprach-IDs findest du unter api.elevenlabs.io/v1/voices oder in deinem ElevenLabs-Dashboard. Es wird nur die ID gespeichert – dein API-Schlüssel bleibt im Backend.', + 'settings.mascot.voice.customHeading': 'Benutzerdefinierte Sprach-ID', + 'settings.mascot.voice.customOption': 'Andere (Sprach-ID einfügen)…', + 'settings.mascot.voice.desc': + 'Wähle die ElevenLabs-Stimme aus, die das Maskottchen für gesprochene Antworten verwendet. Filtere nach Geschlecht, wähle aus der kuratierten Liste aus, füge eine benutzerdefinierte ID ein oder lass die App eine Stimme auswählen, die deiner Benutzeroberflächensprache entspricht.', + 'settings.mascot.voice.genderFemale': 'Weiblich', + 'settings.mascot.voice.genderHeading': 'Stimmgeschlecht', + 'settings.mascot.voice.genderMale': 'Männlich', + 'settings.mascot.voice.heading': 'Stimme', + 'settings.mascot.voice.preset': 'Sprachvoreinstellung', + 'settings.mascot.voice.presetHeading': 'Sprachvoreinstellung', + 'settings.mascot.voice.preview': 'Vorschau der Stimme', + 'settings.mascot.voice.previewError': 'Die Sprachvorschau ist fehlgeschlagen', + 'settings.mascot.voice.previewing': 'Vorschau...', + 'settings.mascot.voice.reset': 'Auf Standard zurücksetzen', + 'settings.mascot.voice.useLocaleDefault': 'Passe die App-Sprache an', + 'settings.mascot.voice.useLocaleDefaultDesc': + 'Wähle automatisch eine Stimme für die aktuelle Schnittstellensprache aus.', + 'settings.memoryWindow.balanced.badge': 'Empfohlen', + 'settings.memoryWindow.balanced.hint': + 'Sinnvolle Standardeinstellung – gute Kontinuität, ohne bei jedem Lauf zusätzliche Token zu verbrennen.', + 'settings.memoryWindow.balanced.label': 'Ausgewogen', + 'settings.memoryWindow.description': + 'Wie viel gespeicherter Kontext OpenHuman in jede neue Agentenausführung eingefügt wird. Bei größeren Fenstern ist man sich früherer Gespräche besser bewusst, verbraucht aber bei jedem Durchlauf mehr Token – und kostet mehr.', + 'settings.memoryWindow.extended.badge': 'Mehr Kontext', + 'settings.memoryWindow.extended.hint': + 'Bei jedem Lauf wird mehr Langzeitgedächtnis injiziert. Höhere Token-Kosten pro Spielzug.', + 'settings.memoryWindow.extended.label': 'Erweitert', + 'settings.memoryWindow.maximum.badge': 'Höchste Kosten', + 'settings.memoryWindow.maximum.hint': + 'Das größte sichere Fenster. Beste Kontinuität, deutlich höhere Token-Rechnung bei jedem Lauf.', + 'settings.memoryWindow.maximum.label': 'Maximal', + 'settings.memoryWindow.minimal.badge': 'Günstigstes', + 'settings.memoryWindow.minimal.hint': + 'Kleinstes Speicherfenster. Günstigstes, schnellstes, geringste Kontinuität zwischen den Läufen.', + 'settings.memoryWindow.minimal.label': 'Minimal', + 'settings.memoryWindow.title': 'Langzeitgedächtnisfenster', + 'settings.screenIntel.permissions.accessibility': 'Barrierefreiheit', + 'settings.screenIntel.permissions.grantHint': 'Grant-Hinweis', + 'settings.screenIntel.permissions.inputMonitoring': 'Eingabeüberwachung', + 'settings.screenIntel.permissions.macosAppliesPrivacy': + 'macOS verwaltet diese Berechtigungen unter Systemeinstellungen → Datenschutz & Sicherheit.', + 'settings.screenIntel.permissions.openInputMonitoring': 'Bitte um …', + 'settings.screenIntel.permissions.refreshStatus': 'Erfrischend…', + 'settings.screenIntel.permissions.refreshing': 'Erfrischend…', + 'settings.screenIntel.permissions.requestAccessibility': 'Bitte um …', + 'settings.screenIntel.permissions.requestScreenRecording': 'Bitte um …', + 'settings.screenIntel.permissions.requesting': 'Bitte um …', + 'settings.screenIntel.permissions.restartRefresh': 'Kern wird neu gestartet...', + 'settings.screenIntel.permissions.restartingCore': 'Kern wird neu gestartet...', + 'settings.screenIntel.permissions.screenRecording': 'Bildschirmaufzeichnung', + 'settings.screenIntel.permissions.title': 'Berechtigungen', + 'skills.card.moreActions': 'Weitere Aktionen', + 'skills.create.allowedTools': 'Erlaubte Werkzeuge', + 'skills.create.author': 'Autor', + 'skills.create.authorPlaceholder': 'Dein Name', + 'skills.create.commaSeparated': '(durch Kommas getrennt)', + 'skills.create.createBtn': 'Fertigkeit schaffen', + 'skills.create.createError': 'Fertigkeit konnte nicht erstellt werden', + 'skills.create.creating': 'Erstellen…', + 'skills.create.description': 'Beschreibung', + 'skills.create.descriptionPlaceholder': 'Was bewirkt diese Fähigkeit?', + 'skills.create.license': 'Lizenz', + 'skills.create.name': 'Name', + 'skills.create.namePlaceholder': 'z.B. Fachzeitschrift', + 'skills.create.scope': 'Umfang', + 'skills.create.scopeProjectHint': '/.openhuman/skills/', + 'skills.create.scopeUserHint': + 'Geschrieben an ~/.openhuman/skills//SKILL.md – verfügbar in allen Arbeitsbereichen.', + 'skills.create.slugLabel': 'Schneckenetikett', + 'skills.create.subtitle': 'SKILL.md', + 'skills.create.tags': 'Schlagworte', + 'skills.create.title': 'Neue Fähigkeit', + 'skills.detail.allowedTools': 'Erlaubte Werkzeuge', + 'skills.detail.author': 'Autor', + 'skills.detail.bundledResources': 'Gebündelte Ressourcen', + 'skills.detail.closeAriaLabel': 'Fertigkeitsdetails schließen', + 'skills.detail.location': 'Standort', + 'skills.detail.noBundledResources': 'Keine gebündelten Ressourcen.', + 'skills.detail.tags': 'Schlagworte', + 'skills.detail.warnings': 'Warnungen', + 'skills.install.fetchLog': 'Protokoll abrufen', + 'skills.install.installBtn': 'Installieren…', + 'skills.install.installComplete': 'Installation abgeschlossen', + 'skills.install.installing': 'Installieren…', + 'skills.install.parseWarnings': 'Warnungen analysieren', + 'skills.install.rawError': 'Roher Fehler', + 'skills.install.timeoutHint': '(Sekunden, optional)', + 'skills.install.timeoutLabel': 'Timeout-Label', + 'skills.install.title': 'Skill von URL installieren', + 'skills.install.urlLabel': 'Fähigkeit URL', + 'skills.meetingBots.bannerDesc': + 'Lege einen Google Meet-Link ab und OpenHuman tritt als Gast bei, spricht, hört zu und winkt zurück.', + 'skills.meetingBots.bannerTitle': 'Sende OpenHuman an eine Besprechung', + 'skills.meetingBots.busyTitle': 'OpenHuman ist beschäftigt', + 'skills.meetingBots.comingSoon': 'Kommt bald', + 'skills.meetingBots.couldNotStartTitle': 'OpenHuman konnte nicht gestartet werden', + 'skills.meetingBots.displayName': 'Anzeigename', + 'skills.meetingBots.failedToStart': 'OpenHuman konnte nicht gestartet werden.', + 'skills.meetingBots.joiningMessage': 'Es sollte in wenigen Sekunden als Teilnehmer erscheinen.', + 'skills.meetingBots.joiningTitle': 'OpenHuman nimmt an der Besprechung teil', + 'skills.meetingBots.meetingLink': 'Link zum Treffen', + 'skills.meetingBots.modalAriaLabel': 'Sende OpenHuman an eine Besprechung', + 'skills.meetingBots.modalDesc': + 'OpenHuman tritt als anonymer Gast bei, streamt sein Video in den Anruf und antwortet über den Agenten.', + 'skills.meetingBots.modalTitle': 'Sende OpenHuman an eine Besprechung', + 'skills.meetingBots.newBadge': 'Neu', + 'skills.meetingBots.sendTo': 'Senden an', + 'skills.meetingBots.starting': 'Beginnend mit …', + 'skills.resource.preview.closeAriaLabel': 'Vorschau schließen', + 'skills.resource.preview.failed': 'Vorschau fehlgeschlagen', + 'skills.resource.preview.loading': 'Vorschau wird geladen…', + 'skills.resource.tree.empty': 'Keine gebündelten Ressourcen.', + 'skills.search.placeholder': 'Platzhalter', + 'skills.setup.autocomplete.acceptKey': 'Schlüssel akzeptieren', + 'skills.setup.autocomplete.activeDesc': 'Inline-Vervollständigungen laufen und sind bereit.', + 'skills.setup.autocomplete.activeTitle': 'Die automatische Vervollständigung ist aktiv', + 'skills.setup.autocomplete.customizeSettings': 'Passe die Einstellungen an', + 'skills.setup.autocomplete.debounce': 'Entprellen', + 'skills.setup.autocomplete.description': 'Beschreibung', + 'skills.setup.autocomplete.enableBtn': 'Aktivieren...', + 'skills.setup.autocomplete.enableError': + 'Die automatische Vervollständigung konnte nicht aktiviert werden', + 'skills.setup.autocomplete.enabling': 'Aktivieren...', + 'skills.setup.autocomplete.notSupported': 'Nicht unterstützt', + 'skills.setup.autocomplete.stepEnable': 'Aktiviere Inline-Vervollständigungen', + 'skills.setup.autocomplete.stepSuccess': 'Bereit zu gehen', + 'skills.setup.autocomplete.stylePreset': 'Stilvoreinstellung', + 'skills.setup.autocomplete.stylePresetValue': 'Ausgewogen (später konfigurierbar)', + 'skills.setup.autocomplete.title': 'Automatische Textvervollständigung', + 'skills.setup.screenIntel.activeDesc': + 'Screen Intelligence läuft und liest dein aktives Fenster.', + 'skills.setup.screenIntel.activeTitle': 'Bildschirmintelligenz ist aktiviert', + 'skills.setup.screenIntel.advancedSettings': 'Erweiterte Einstellungen', + 'skills.setup.screenIntel.allGranted': 'Alle Berechtigungen erteilt', + 'skills.setup.screenIntel.captureMode': 'Aufnahmemodus', + 'skills.setup.screenIntel.captureModeValue': 'Alle Fenster (später konfigurierbar)', + 'skills.setup.screenIntel.deniedHint': + 'Nachdem du in den Systemeinstellungen Berechtigungen erteilt hast, klicke unten, um neu zu starten und die Änderungen zu übernehmen.', + 'skills.setup.screenIntel.enableBtn': 'Aktivieren...', + 'skills.setup.screenIntel.enableDesc': + 'Liest, was auf deinem Bildschirm ist, und gibt deinem Agenten nützlichen Kontext.', + 'skills.setup.screenIntel.enableError': 'Screen Intelligence konnte nicht aktiviert werden', + 'skills.setup.screenIntel.enabling': 'Aktivieren...', + 'skills.setup.screenIntel.grant': 'Öffnen...', + 'skills.setup.screenIntel.granted': 'Erteilt', + 'skills.setup.screenIntel.macosOnly': 'Nur macOS', + 'skills.setup.screenIntel.opening': 'Öffnen...', + 'skills.setup.screenIntel.panicHotkey': 'Panik-Hotkey', + 'skills.setup.screenIntel.permAccessibility': 'Barrierefreiheit', + 'skills.setup.screenIntel.permInputMonitoring': 'Eingabeüberwachung', + 'skills.setup.screenIntel.permScreenRecording': 'Bildschirmaufzeichnung', + 'skills.setup.screenIntel.permissionsDesc': + 'Screen Intelligence benötigt Berechtigungen für Bedienungshilfen, Eingabeüberwachung und Bildschirmaufnahme.', + 'skills.setup.screenIntel.refreshStatus': 'Status aktualisieren', + 'skills.setup.screenIntel.restartRefresh': 'Neustart...', + 'skills.setup.screenIntel.restarting': 'Neustart...', + 'skills.setup.screenIntel.stepEnable': 'Aktiviere den Skill', + 'skills.setup.screenIntel.stepPermissions': 'Berechtigungen erteilen', + 'skills.setup.screenIntel.stepSuccess': 'Bereit zu gehen', + 'skills.setup.screenIntel.title': 'Bildschirmintelligenz', + 'skills.setup.screenIntel.visionModel': 'Vision-Modell', + 'skills.setup.voice.activation': 'Aktivierung', + 'skills.setup.voice.activeDescPrefix': 'Fn', + 'skills.setup.voice.activeDescSuffix': 'Fn', + 'skills.setup.voice.activeTitle': 'Sprachintelligenz ist aktiv', + 'skills.setup.voice.customizeSettings': 'Passe die Einstellungen an', + 'skills.setup.voice.downloadSttBtn': 'STT-Modell herunterladen', + 'skills.setup.voice.enableDesc': 'Diktiere Text freihändig über dein Mikrofon.', + 'skills.setup.voice.hotkey': 'Hotkey', + 'skills.setup.voice.startBtn': 'Starten...', + 'skills.setup.voice.startError': 'Der Sprachserver konnte nicht gestartet werden', + 'skills.setup.voice.starting': 'Startet...', + 'skills.setup.voice.stepEnable': 'Sprachserver starten', + 'skills.setup.voice.stepSetup': 'Modell-Download erforderlich', + 'skills.setup.voice.stepSuccess': 'Bereit zu gehen', + 'skills.setup.voice.sttNotReady': 'Speech-to-Text-Modell nicht bereit', + 'skills.setup.voice.sttNotReadyDesc': + 'Voice Intelligence erfordert für die Transkription ein lokales Whisper-Modell. Lade es aus den lokalen Modelleinstellungen herunter.', + 'skills.setup.voice.sttReady': 'Bereit für das Speech-to-Text-Modell', + 'skills.setup.voice.sttReturnHint': 'Stt-Rückgabehinweis', + 'skills.setup.voice.title': 'Sprachintelligenz', + 'skills.uninstall.couldNotUninstall': 'Konnte nicht deinstalliert werden', + 'skills.uninstall.description': + 'Dadurch werden das Skill-Verzeichnis und alle darin enthaltenen Ressourcen dauerhaft gelöscht. Der Agent wird es in der nächsten Runde nicht mehr sehen.', + 'skills.uninstall.title': 'Deinstallieren', + 'skills.uninstall.uninstallBtn': 'Deinstallieren', + 'skills.uninstall.uninstalling': 'Deinstallation…', + 'upsell.global.limitMessage': 'Aktualisiere deinen Plan oder lade Guthaben auf, um fortzufahren', + 'upsell.global.limitTitle': 'Du', + 'upsell.global.nearLimitMessage': + 'Du hast {pct} % deines Nutzungslimits verwendet. Upgrade für höhere Limits.', + 'upsell.global.nearLimitTitle': 'Das Nutzungslimit nähert sich', + 'upsell.usageLimit.bodyBudget': + 'Du hast dein wöchentliches Limit erreicht.{reset} Aktualisiere deinen Plan oder lade Guthaben auf, um Limits zu vermeiden.', + 'upsell.usageLimit.bodyRate': + 'Du hast dein 10-Stunden-Inferenzratenlimit erreicht.{reset} Führe ein Upgrade durch, um höhere Limits zu erhalten.', + 'upsell.usageLimit.heading': 'Nutzungslimit erreicht', + 'upsell.usageLimit.notNow': 'Nicht jetzt', + 'upsell.usageLimit.perWindow': '{amount}', + 'upsell.usageLimit.planIncludes': '{plan}', + 'upsell.usageLimit.resetsIn': 'Es setzt {time} zurück.', + 'upsell.usageLimit.upgradePlan': 'Upgrade-Plan', + 'upsell.usageLimit.weeklyInference': '{amount}', + 'walkthrough.tooltip.letsGo': 'Lass uns gehen!', + 'walkthrough.tooltip.next': 'Weiter →', + 'walkthrough.tooltip.skip': 'Tour überspringen', + 'walkthrough.tooltip.stepCounter': '{n} von {total}', + 'webhooks.activity.empty': 'Leer', + 'webhooks.activity.title': 'Letzte Aktivität', + 'webhooks.composioHistory.empty': 'Leer', + 'webhooks.composioHistory.metadataId': 'MetaDaten-ID', + 'webhooks.composioHistory.metadataUuid': 'Metadata UUID', + 'webhooks.composioHistory.payload': 'Nutzlast', + 'webhooks.composioHistory.title': 'ComposeIO Trigger-Verlauf', + 'webhooks.tunnels.active': 'Aktiv', + 'webhooks.tunnels.createFailed': 'Tunnel konnte nicht erstellt werden', + 'webhooks.tunnels.creating': 'Erstellen...', + 'webhooks.tunnels.deleteFailed': 'Tunnel konnte nicht gelöscht werden', + 'webhooks.tunnels.descriptionPlaceholder': 'Beschreibung (optional)', + 'webhooks.tunnels.echo': 'Echo', + 'webhooks.tunnels.empty': 'Leer', + 'webhooks.tunnels.enableEcho': 'Echo entfernen', + 'webhooks.tunnels.inactive': 'Aktiv', + 'webhooks.tunnels.namePlaceholder': 'Tunnelname (z. B. Telegram-Bot)', + 'webhooks.tunnels.newTunnel': 'Neuer Tunnel', + 'webhooks.tunnels.removeEcho': 'Echo entfernen', + 'webhooks.tunnels.title': 'Webhook-Tunnel', + 'webhooks.tunnels.toggleFailed': 'Echo konnte nicht umgeschaltet werden', + 'composio.authExpired': 'Authentifizierung abgelaufen', + 'composio.reconnect': 'Wieder verbinden', + 'composio.directModeRequiresKey': + 'Speichern fehlgeschlagen. Der Direktmodus erfordert einen nicht leeren Schlüssel API.', + 'composio.notYetRouted': 'noch nicht geroutet', + 'composio.triggers.loading': 'Laden…', + 'conversations.taskKanban.todo': 'Zu tun', + 'settings.composio.loading': 'Laden…', + 'settings.mascot.noCharactersAvailable': 'Es sind noch keine OpenHuman Zeichen verfügbar', + 'skills.uninstall.confirmTitle': '{name} deinstallieren?', + 'conversations.taskKanban.blocked': 'Blockiert', + 'conversations.taskKanban.done': 'Fertig', + 'conversations.taskKanban.inProgress': 'In Bearbeitung', + 'intelligence.memoryChunk.detail.copiedHint': 'kopiert', + 'settings.composio.notYetRouted': 'noch nicht geroutet', + 'settings.localModel.download.manageExternal': + 'Verwalte dieses Modell in deiner externen Laufzeit.', + 'settings.localModel.status.manageOllamaExternal': + 'Verwalte den Ollama-Prozess und die Modell-Pulls außerhalb von OpenHuman, und führe dann die Diagnose erneut aus.', + 'settings.localModel.status.ollamaDocs': 'Ollama Dokumente', + 'settings.localModel.status.thenRetry': + 'für Setup-Anweisungen, dann versuche es erneut, sobald deine Laufzeit erreichbar ist.', + 'settings.appearance.title': 'Aussehen', + 'settings.appearance.themeHeading': 'Thema', + 'settings.appearance.themeAria': 'Thema', + 'settings.appearance.modeLight': 'Licht', + 'settings.appearance.modeLightDesc': 'Helle Flächen, dunkler Text.', + 'settings.appearance.modeDark': 'Dunkel', + 'settings.appearance.modeDarkDesc': + 'Dunkle Oberflächen, nach Einbruch der Dunkelheit angenehmer für die Augen.', + 'settings.appearance.modeSystem': 'Match-System', + 'settings.appearance.modeSystemDesc': + 'Folgt den Einstellungen für das Erscheinungsbild deines Betriebssystems.', + 'settings.appearance.helperText': + 'Der Dunkelmodus schaltet die gesamte App – Chat, Einstellungen, Bedienfelder – auf eine dunkle Palette um. „Match System“ verfolgt das Erscheinungsbild deines Betriebssystems und aktualisiert es live.', + 'settings.mascot.characterPreview': 'Vorschau', + 'settings.mascot.characterStates': 'Staaten', + 'settings.mascot.characterVisemes': 'Mundbilder', + 'settings.mascot.colorAria': 'OpenHuman Farbe', + 'settings.mascot.colorBlack': 'Schwarz', + 'settings.mascot.colorBurgundy': 'Burgund', + 'settings.mascot.colorGreen': 'Grün', + 'settings.mascot.colorNavy': 'Marine', + 'settings.mascot.colorYellow': 'Gelb', + 'settings.mascot.libraryUnavailable': 'OpenHuman Bibliothek nicht verfügbar', + 'settings.mascot.title': 'OpenHuman', +}; + +export default de5; diff --git a/app/src/lib/i18n/de.ts b/app/src/lib/i18n/de.ts new file mode 100644 index 000000000..7b2432db1 --- /dev/null +++ b/app/src/lib/i18n/de.ts @@ -0,0 +1,12 @@ +import de1 from './chunks/de-1'; +import de2 from './chunks/de-2'; +import de3 from './chunks/de-3'; +import de4 from './chunks/de-4'; +import de5 from './chunks/de-5'; +import type { TranslationMap } from './types'; + +// German (Deutsch) translations. Each chunk maps to chunks/en-N.ts. +// Missing keys fall back to English via I18nContext.resolveEn(). +const de: TranslationMap = { ...de1, ...de2, ...de3, ...de4, ...de5 }; + +export default de; diff --git a/app/src/lib/i18n/types.ts b/app/src/lib/i18n/types.ts index 712621e44..29e94dadb 100644 --- a/app/src/lib/i18n/types.ts +++ b/app/src/lib/i18n/types.ts @@ -7,6 +7,7 @@ export type Locale = | 'fr' | 'bn' | 'pt' + | 'de' | 'ru' | 'id' | 'it' diff --git a/app/src/store/localeSlice.test.ts b/app/src/store/localeSlice.test.ts index df0c0c211..7df5cafd3 100644 --- a/app/src/store/localeSlice.test.ts +++ b/app/src/store/localeSlice.test.ts @@ -18,6 +18,13 @@ describe('localeSlice', () => { expect(reducer(undefined, { type: '@@INIT' }).current).toBe('id'); }); + it('detects German browser locales', async () => { + vi.stubGlobal('navigator', { language: 'de-DE' }); + const reducer = await loadReducer(); + + expect(reducer(undefined, { type: '@@INIT' }).current).toBe('de'); + }); + it('detects the legacy Indonesian browser locale code', async () => { vi.stubGlobal('navigator', { language: 'in-ID' }); const reducer = await loadReducer(); diff --git a/app/src/store/localeSlice.ts b/app/src/store/localeSlice.ts index 2e881203d..b1bf079d4 100644 --- a/app/src/store/localeSlice.ts +++ b/app/src/store/localeSlice.ts @@ -14,6 +14,7 @@ const PREFIX_TO_LOCALE: Array<[string, Locale]> = [ ['fr', 'fr'], ['bn', 'bn'], ['pt', 'pt'], + ['de', 'de'], ['ru', 'ru'], ['id', 'id'], ['in', 'id'], diff --git a/scripts/apply-i18n-translations.ts b/scripts/apply-i18n-translations.ts index ea024220c..1ba990231 100644 --- a/scripts/apply-i18n-translations.ts +++ b/scripts/apply-i18n-translations.ts @@ -35,6 +35,7 @@ const LOCALE_HEADERS: Record = { fr: "French (Français)", bn: "Bengali (বাংলা)", pt: "Portuguese (Português)", + de: "German (Deutsch)", ru: "Russian (Русский)", id: "Indonesian (Bahasa Indonesia)", it: "Italian (Italiano)", diff --git a/scripts/i18n-coverage.ts b/scripts/i18n-coverage.ts index 8dae791c0..1d5c2d8d5 100644 --- a/scripts/i18n-coverage.ts +++ b/scripts/i18n-coverage.ts @@ -42,6 +42,7 @@ const ALL_LOCALES = [ "fr", "bn", "pt", + "de", "ru", "id", "it",