Files
Multi-Hoster-Upload/renderer/i18n.js
T
Sucukdeluxe dc744ec6f3 release: Multi-Hoster-Upload 2.1.1
Add live English and German interface switching, animated navigation and history controls, improved update changelogs, remembered upload folders, reliable repeated hot reloads, and refreshed public documentation.
2026-08-10 18:31:35 +02:00

588 lines
37 KiB
JavaScript

(function (root, factory) {
const api = factory();
if (typeof module === 'object' && module.exports) module.exports = api;
if (root) root.I18n = api;
})(typeof window !== 'undefined' ? window : globalThis, function () {
const pairs = [
['Arbeitsbereich', 'Workspace'],
['Accounts verwalten', 'Manage accounts'],
['Archiv', 'Archive'],
['(aktivieren zum Erzeugen)', '(enable to generate)'],
['-Tab direkt beim jeweiligen Hoster.', ' tab for the relevant host.'],
['127.0.0.1 oder Tunnel-/Tailscale-Adresse', '127.0.0.1 or tunnel/Tailscale address'],
['API-Token', 'API token'],
['Account-Status', 'Account status'],
['Allowlist (IP/CIDR, eine pro Zeile)', 'Allowlist (one IP/CIDR per line)'],
['Aufbewahrung', 'Retention'],
['Ausgabe-Format der kopierten Links', 'Output format for copied links'],
['Auto-Check vor Upload', 'Auto-check before upload'],
['Automatischer Check vor dem Upload', 'Automatic check before upload'],
['Bildschirm und Eingabesteuerung bleiben gesperrt.', 'Screen and input control remain locked.'],
['Bindet nur an', 'Binds only to'],
['Bindet an', 'Binds to'],
['. Nur IPs/CIDRs aus der Allowlist dürfen verbinden (Loopback immer) — zusätzlich zum Token. Über Tailscale: trage deinen Tailnet-Bereich ein (z.B.', '. Only IPs/CIDRs from the allowlist may connect (loopback is always allowed), in addition to the token. For Tailscale, enter your tailnet range, e.g.'],
[') und die Tailscale-IP/MagicDNS oben als Code-Adresse. Transport ist plaintext über den Tunnel — Tailscale/WireGuard verschlüsselt.', ') and enter the Tailscale IP or MagicDNS name above as the code address. Transport is plaintext through the tunnel; Tailscale/WireGuard provides encryption.'],
['Datum', 'Date'],
['Einstellungskategorien', 'Settings categories'],
['Erlaubt', 'Allowed'],
['Erneut versuchen', 'Retry'],
['Exportieren', 'Export'],
['Fehlgeschlagene erneut', 'Retry failed'],
['Fensterverhalten, Drop-Target und Programmupdates.', 'Window behavior, drop target, and application updates.'],
['Gesamt:', 'Total:'],
['Globales Speed-Limit', 'Global speed limit'],
['Hauptbereiche', 'Main sections'],
['Hinweis', 'Notice'],
['Hoster-Limits automatisch hochskalieren', 'Automatically scale host limits'],
['Hoster', 'Host'],
['Importieren', 'Import'],
['In Zwischenablage', 'To clipboard'],
['In diesem Lauf hochgeladen:', 'Uploaded during this run:'],
['Input erlauben', 'Allow input'],
['Installierte Version', 'Installed version'],
['Laufzeit:', 'Runtime:'],
['Letzte 100 Uploads', 'Last 100 uploads'],
['Letzte 1000 Uploads', 'Last 1,000 uploads'],
['Letzte 7 Tage', 'Last 7 days'],
['Letzte 30 Tage', 'Last 30 days'],
['Letzte 90 Tage', 'Last 90 days'],
['Max. parallele Uploads', 'Max. parallel uploads'],
['Maximale parallele Uploads', 'Maximum parallel uploads'],
['Neustart', 'Restart'],
['Noch keine Accounts', 'No accounts yet'],
['Nur lokal (127.0.0.1) — Tunnel/VPN', 'Local only (127.0.0.1) — tunnel/VPN'],
['Parallele Uploads verringern', 'Decrease parallel uploads'],
['Restzeit:', 'Time remaining:'],
['Rest', 'Remaining'],
['Schnell finden', 'Quick find'],
['Schnelleinstellungen', 'Quick settings'],
['Sicherung', 'Backup'],
['Sichtbarkeit', 'Visibility'],
['Sitzung', 'Session'],
['Speicherstatus', 'Save status'],
['Statistik', 'Statistics'],
['Suche Aktualisierungen', 'Checking for updates'],
['Verbleibend:', 'Remaining:'],
['Zuletzt erzeugte Upload-Links', 'Recently generated upload links'],
['User-ID, role:ROLLEN-ID, @here oder @everyone', 'User ID, role:ROLE-ID, @here, or @everyone'],
['https://discord.com/api/webhooks/… oder eigene URL', 'https://discord.com/api/webhooks/… or custom URL'],
['nur lesenden', 'read-only'],
['z. B. Hauptaccount, Premium, Kunde XY', 'e.g. primary account, premium, customer XY'],
['Datei', 'File'],
['Dateien', 'Files'],
['Dateien hinzufügen', 'Add files'],
['Ordner hinzufügen', 'Add folder'],
['Online-Schlüssel erstellen', 'Create online key'],
['Online-Schlüssel importieren', 'Import online key'],
['Einstellungen öffnen', 'Open settings'],
['Geschwindigkeitslimit', 'Speed limit'],
['Hilfe', 'Help'],
['Log-Ordner öffnen', 'Open log folder'],
['Diagnose-Paket exportieren', 'Export diagnostics package'],
['Eine neue Version ist verfügbar', 'A new version is available'],
['Bereit zum Download', 'Ready to download'],
['Abbrechen', 'Cancel'],
['Jetzt installieren', 'Install now'],
['Jetzt updaten', 'Install now'],
['Alle Dateien', 'All files'],
['Aktiv', 'Active'],
['Warteschlange', 'Queue'],
['Fertig', 'Completed'],
['Fehler', 'Failed'],
['Verfügbarkeit', 'Availability'],
['Bereite Accounts', 'Ready accounts'],
['Primär', 'Primary'],
['Nicht geprüft', 'Not checked'],
['Nicht aktiv', 'Inactive'],
['Prüfen', 'Check'],
['Bearbeiten', 'Edit'],
['Keine Upload-Ziele ausgewählt', 'No upload destinations selected'],
['Dateien ablegen, Ziele wählen und Uploads zentral steuern.', 'Drop files, choose destinations, and manage uploads in one place.'],
['Upload-Aufträge', 'Upload jobs'],
['Dateien hinzufügen, Ziele auswählen und Fortschritt verfolgen', 'Add files, choose destinations, and track progress'],
['+ Dateien', '+ Files'],
['+ Ordner', '+ Folder'],
['Dateien hierher ziehen oder klicken', 'Drop files here or click to browse'],
['Dateien und Ordner werden vor dem Upload geprüft.', 'Files and folders are checked before upload.'],
['Dateiname', 'File name'],
['Hoster / Account', 'Host / Account'],
['Hochgeladen / Größe', 'Uploaded / Size'],
['Geschwindigkeit', 'Speed'],
['Fortschritt', 'Progress'],
['Status', 'Status'],
['Aktionen', 'Actions'],
['Alle Links kopieren', 'Copy all links'],
['Alle entfernen', 'Remove all'],
['Entfernen', 'Remove'],
['Dateien in der Warteschlange', 'Files in queue'],
['Läuft:', 'Running:'],
['Fehler:', 'Failed:'],
['Dateigröße in der Warteschlange', 'Queued file size'],
['Upload-Geschwindigkeit:', 'Upload speed:'],
['Zugänge', 'Accounts'],
['Alle Accounts', 'All accounts'],
['Bereit', 'Ready'],
['Aktion nötig', 'Action required'],
['Zugänge prüfen, priorisieren und für Uploads bereitstellen.', 'Check, prioritize, and prepare accounts for uploads.'],
['Hoster-Zugangsdaten verwalten und prüfen', 'Manage and verify host account credentials'],
['Accounts prüfen', 'Check accounts'],
['Account hinzufügen', 'Add account'],
['Füge deinen ersten Hoster-Account hinzu. Die Zugangsdaten werden vor dem Speichern geprüft.', 'Add your first host account. Credentials are verified before saving.'],
['Alle ausklappen', 'Expand all'],
['Alle einklappen', 'Collapse all'],
['Wähle einen Hoster und gib deine Zugangsdaten ein.', 'Choose a host and enter your credentials.'],
['Wähle einen Hoster und gib deine Zugangsdaten ein. Der Account wird vor dem Anlegen geprüft.', 'Choose a host and enter your credentials. The account is checked before it is added.'],
['Prüfen und anlegen', 'Verify and add'],
['Prüfen und speichern', 'Verify and save'],
['Keine Einträge.', 'No entries.'],
['Schließen', 'Close'],
['Account löschen?', 'Delete account?'],
['Account wirklich löschen?', 'Are you sure you want to delete this account?'],
['Löschen', 'Delete'],
['Alle Optionen nach Aufgaben sortiert. Änderungen werden mit dem Speichern-Button übernommen.', 'All options are grouped by task. Changes are applied with the Save button.'],
['Speichern', 'Save'],
['Einstellungen', 'Settings'],
['Allgemein', 'General'],
['Uploads', 'Uploads'],
['Automatik', 'Automation'],
['Benachrichtigungen', 'Notifications'],
['Logs & Support', 'Logs & Support'],
['Fernsteuerung', 'Remote control'],
['Diagnose-Zugriff', 'Diagnostics access'],
['Backup & Übertragen', 'Backup & Transfer'],
['Keine passende Einstellung gefunden.', 'No matching setting found.'],
['Keine ungespeicherten Änderungen', 'No unsaved changes'],
['Oberfläche', 'Interface'],
['Sprache', 'Language'],
['Englisch', 'English'],
['Deutsch', 'German'],
['Immer im Vordergrund', 'Always on top'],
['Drop-Target anzeigen', 'Show drop target'],
['Programmupdate', 'Application update'],
['Nach neuer Version suchen', 'Check for a newer version'],
['Verfügbare Updates werden zusammen mit dem Changelog angezeigt.', 'Available updates are shown together with the changelog.'],
['Neue Version suchen', 'Check for a new version'],
['Nach Updates suchen', 'Check for updates'],
['Upload-Verhalten', 'Upload behavior'],
['Globale Leistung, Warteschlange und Verhalten nach einem erfolgreichen Upload.', 'Global performance, queue, and behavior after a successful upload.'],
['Leistung', 'Performance'],
['Globale parallele Uploads', 'Global parallel uploads'],
['0 = nur die Einstellung des jeweiligen Hosters verwenden', '0 = use the setting of each host'],
['Verteilt die globale Parallelität auf vorhandene Accounts eines Hosters.', 'Distributes global parallelism across the available accounts of a host.'],
['Nach Abschluss', 'After completion'],
['Nach Abschluss aus der Liste entfernen', 'Remove from the list after completion'],
['Erfolgreich hochgeladene Dateien verschwinden automatisch aus der Upload-Liste.', 'Successfully uploaded files are automatically removed from the upload list.'],
['Warteschlange beim Start wiederherstellen', 'Restore queue on startup'],
['Noch nicht abgeschlossene Uploads werden beim nächsten Programmstart erneut angezeigt.', 'Incomplete uploads are shown again the next time the application starts.'],
['Hoster-Einstellungen', 'Host settings'],
['Upload-Einstellungen', 'Upload settings'],
['Erfolgreiche Links in fileuploader.log.', 'Successful links in fileuploader.log.'],
['Verteilt die Dateien reihum auf alle aktiven Accounts dieses Hosters (Datei 1 → Account 1, Datei 2 → Account 2 …). Hält z. B. byse-Accounts aktiv. Nur ein Account = kein Effekt.', 'Distributes files across all active accounts for this host in round-robin order (file 1 → account 1, file 2 → account 2, and so on). Keeps accounts such as byse active. Has no effect with only one account.'],
['Größen-Limit merken', 'Remember size limit'],
['Überspringt nach zwei verdächtigen Ablehnungen auf einem Account größere Dateien dort vorab ("Bekanntes Größen-Limit"). Abschalten = jede Datei wird immer wirklich versucht.', 'After two suspicious rejections on an account, larger files are skipped there in advance ("Known size limit"). When disabled, every file is always attempted.'],
['Einstellungen einzelner Hoster', 'Settings for individual hosts'],
['wie Wiederholungen, Geschwindigkeit, Parallelität, Dateigröße und Logging findest du im', 'such as retries, speed, parallelism, file size, and logging are available in'],
['Accounts-Tab.', 'the Accounts tab.'],
['Wiederholungen und überwachte Ordner für unbeaufsichtigte Uploads.', 'Retries and watched folders for unattended uploads.'],
['Unbeaufsichtigter Betrieb', 'Unattended operation'],
['Automatische Wiederholungsrunden', 'Automatic retry rounds'],
['0 = aus. Nach Batch-Ende werden transiente Fehler (Netzwerk, Hoster-Flake) automatisch bis zu N Runden neu versucht.', '0 = off. After a batch ends, transient errors (network or host issues) are retried automatically for up to N rounds.'],
['Wartezeit zwischen Runden', 'Delay between rounds'],
['Minuten · jede weitere Runde wartet entsprechend länger', 'Minutes · each additional round waits proportionally longer'],
['Ordnerüberwachung', 'Folder monitoring'],
['Inaktiv', 'Inactive'],
['Ordnerpfad', 'Folder path'],
['Wählen', 'Choose'],
['Dateierweiterungen', 'File extensions'],
['Nur diese', 'Only these'],
['Alle außer', 'All except'],
['Verzögerung (Sekunden)', 'Delay (seconds)'],
['Warten bis Datei fertig geschrieben', 'Wait until the file has finished writing'],
['Verhalten', 'Behavior'],
['Aktiviert', 'Enabled'],
['Unterordner einbeziehen', 'Include subfolders'],
['Duplikate überspringen', 'Skip duplicates'],
['Auto-Upload starten', 'Start uploads automatically'],
['Hoster-Vorauswahl', 'Host preselection'],
['Erst Accounts anlegen, dann hier auswählen.', 'Add accounts first, then select them here.'],
['Keine Auswahl = Hoster-Modal bei jeder Datei.', 'No selection = show the host dialog for every file.'],
['Meldungen nach einem abgeschlossenen Upload-Batch versenden.', 'Send notifications after a completed upload batch.'],
['Webhook-Adresse', 'Webhook URL'],
['Test senden', 'Send test'],
['Nach Batch-Ende wird eine Zusammenfassung versendet. Discord wird automatisch erkannt, andere Ziele erhalten JSON.', 'A summary is sent after the batch ends. Discord is detected automatically; other destinations receive JSON.'],
['Discord-Erwähnung', 'Discord mention'],
['Optional · leer lassen, wenn die Nachricht ohne Ping gesendet werden soll', 'Optional · leave blank to send the message without a ping'],
['Protokollierung verwalten, Log-Dateien öffnen und ein bereinigtes Support-Paket erstellen.', 'Manage logging, open log files, and create a sanitized support package.'],
['Ordner wählen', 'Choose folder'],
['Öffnen', 'Open'],
['Log-Datei-Modus', 'Log file mode'],
['Eine Datei', 'Single file'],
['Pro Tag', 'Per day'],
['Pro Session', 'Per session'],
['Pro Session = neue Datei bei jedem App-Start; nach komplettem Schließen + erneutem Öffnen beginnt eine neue Session.', 'Per session = a new file on every application start; a new session begins after fully closing and reopening the application.'],
['DEBUG-Einträge in debug.log schreiben (Performance ↓, Diagnostik ↑)', 'Write DEBUG entries to debug.log (performance ↓, diagnostics ↑)'],
['Diagnose', 'Diagnostics'],
['Log-Dateien', 'Log files'],
['Wird geladen…', 'Loading…'],
['Zeigen', 'Show'],
['Im Explorer zeigen', 'Show in File Explorer'],
['Support-Paket', 'Support package'],
['Eine .txt mit Logs + sanitierter Config; Passwörter/API-Keys werden vor dem Speichern maskiert.', 'A .txt containing logs and sanitized configuration; passwords and API keys are masked before saving.'],
['Upload-Funktionen über einen verbundenen Client steuern.', 'Control upload features through a connected client.'],
['Server', 'Server'],
['Eingaben erlauben', 'Allow input'],
['Kopieren', 'Copy'],
['Neu', 'New'],
['Prüfe...', 'Checking...'],
['Prüfe…', 'Checking…'],
['Zeitlich kontrollierter Lesezugriff für Fehleranalyse und Support.', 'Time-limited read access for troubleshooting and support.'],
['Diagnose-Zugriff (nur lesen)', 'Diagnostics access (read-only)'],
['Zugriff auf Logs, Queue-Status und bereinigte Einstellungen. Passwörter, API-Keys und Tokens werden maskiert.', 'Access to logs, queue status, and sanitized settings. Passwords, API keys, and tokens are masked.'],
['Der Verbindungs-Code ist ein Zugangsschlüssel — nur mit vertrauenswürdigen Stellen teilen; bei Verdacht „Neu" klicken. Standard-Bindung ist', 'The connection code is an access key. Share it only with trusted parties and click “New” if you suspect misuse. The default binding is'],
['und damit nur über einen SSH- oder VPN-Tunnel erreichbar.', 'and is therefore reachable only through an SSH or VPN tunnel.'],
['Im Netzwerk (0.0.0.0) — Allowlist nötig', 'On the network (0.0.0.0) — allowlist required'],
['Adresse für den Code', 'Address for the code'],
['Verbindungs-Code', 'Connection code'],
['. Fernzugriff nur über einen Tunnel (z.B. Tailscale/SSH) — die sicherste Variante.', '. Remote access is available only through a tunnel such as Tailscale or SSH, which is the safest option.'],
['Accounts und Einstellungen sichern oder auf ein anderes Gerät übernehmen.', 'Back up accounts and settings or transfer them to another device.'],
['Der Upload-Verlauf wird nicht übertragen und bleibt auf diesem Gerät.', 'Upload history is not transferred and remains on this device.'],
['Verschlüsseltes Online-Backup', 'Encrypted online backup'],
['Die Verschlüsselung findet ausschließlich auf diesem Gerät statt. Der Server speichert nur verschlüsselte Daten.', 'Encryption takes place only on this device. The server stores encrypted data only.'],
['Neuen Schlüssel erzeugen', 'Generate new key'],
['Jeder Export erzeugt einen neuen Schlüssel. Ältere Schlüssel bleiben gültig.', 'Each export creates a new key. Older keys remain valid.'],
['Dein neuer Schlüssel', 'Your new key'],
['Vorhandenen Schlüssel importieren', 'Import existing key'],
['Online importieren', 'Import online'],
['Behandle den Schlüssel wie ein Passwort. Wer ihn besitzt, kann die verschlüsselten Einstellungen entschlüsseln.', 'Treat the key like a password. Anyone who has it can decrypt the encrypted settings.'],
['Lokales Datei-Backup', 'Local file backup'],
['Datei exportieren', 'Export file'],
['Datei importieren', 'Import file'],
['Alle Uploads', 'All uploads'],
['Erfolgreich', 'Successful'],
['Aktive Regel', 'Active rule'],
['Alles behalten', 'Keep everything'],
['Links wiederfinden, kopieren oder als Datei exportieren.', 'Find links, copy them, or export them as a file.'],
['Upload-Verlauf', 'Upload history'],
['Verlauf exportieren', 'Export history'],
['Verlauf löschen', 'Delete history'],
['Verlauf löschen?', 'Delete history?'],
['Alle Verlaufseinträge werden dauerhaft gelöscht. Dieser Vorgang kann nicht rückgängig gemacht werden.', 'All history entries will be permanently deleted. This action cannot be undone.'],
['Ausgewählte starten', 'Start selected'],
['Upload-Ziele auswählen', 'Choose upload destinations'],
['Dateien wurden hinzugefügt. Wähle jetzt die Hoster für den Upload.', 'Files were added. Now choose the hosts for the upload.'],
['Alle', 'All'],
['Keine', 'None'],
['Keine Hoster mit Zugangsdaten vorhanden. Bitte zuerst in den Accounts einen Login oder API-Key hinterlegen.', 'No hosts with credentials are available. Add a login or API key under Accounts first.'],
['Keine Hoster mit Zugangsdaten für einen Check.', 'No hosts with credentials are available for a check.'],
['Die Auswahl wird für neue Queue-Einträge verwendet.', 'The selection is used for new queue entries.'],
['Nach Aktualisierungen suchen', 'Check for updates'],
['Anwendungsmenüs', 'Application menus'],
['Parallele Uploads erhöhen', 'Increase parallel uploads'],
['Geschwindigkeitslimit aktivieren', 'Enable speed limit'],
['Geschwindigkeitslimit in Megabyte pro Sekunde', 'Speed limit in megabytes per second'],
['Geschwindigkeitslimit erhöhen', 'Increase speed limit'],
['Geschwindigkeitslimit verringern', 'Decrease speed limit'],
['Hilfe und Support', 'Help and support'],
['Update-Fortschritt', 'Update progress'],
['Alle Dateien anzeigen', 'Show all files'],
['Aktive Uploads anzeigen', 'Show active uploads'],
['Wartende Uploads anzeigen', 'Show queued uploads'],
['Fertige Uploads anzeigen', 'Show completed uploads'],
['Fehlgeschlagene Uploads anzeigen', 'Show failed uploads'],
['Alle Uploads starten', 'Start all uploads'],
['Ausgewählte Uploads starten', 'Start selected uploads'],
['Ausgewählte Datei erneut hochladen', 'Upload selected file again'],
['Ausgewählten Upload abbrechen', 'Cancel selected upload'],
['Aktive Uploads beenden und stoppen', 'Stop active uploads'],
['Alle Uploads abbrechen', 'Cancel all uploads'],
['Nach oben', 'Move up'],
['Nach unten', 'Move down'],
['Alle Zeilen als Datei exportieren (Zeit, Hoster, Link, Dateiname)', 'Export all rows as a file (time, host, link, file name)'],
['Alle Links aus diesem Panel entfernen', 'Remove all links from this panel'],
['Alle Accounts anzeigen', 'Show all accounts'],
['Bereite Accounts anzeigen', 'Show ready accounts'],
['Fehlerhafte Accounts anzeigen', 'Show accounts with errors'],
['Einstellungen durchsuchen', 'Search settings'],
['Ordner wählen...', 'Choose folder...'],
['Standardpfad verwenden', 'Use default path'],
['Log-Ordner im Explorer öffnen', 'Open log folder in File Explorer'],
['Sammelt alle Logs + sanitierte Config (Credentials maskiert) + App-Versionen in eine einzelne .txt-Datei zum Teilen.', 'Collects all logs, sanitized configuration with masked credentials, and application versions in a single shareable .txt file.'],
['Neu generieren', 'Generate new'],
['Neu generieren (macht alte Codes ungültig)', 'Generate new (invalidates old codes)'],
['Nach dem Export erscheint hier der 75-stellige Schlüssel', 'The 75-character key appears here after export'],
['Verlaufsübersicht', 'History overview'],
['Verlaufsstatus', 'History status'],
['Gesamten Verlauf anzeigen', 'Show all history'],
['Erfolgreiche Uploads anzeigen', 'Show successful uploads'],
['Fehlgeschlagene Uploads anzeigen', 'Show failed uploads'],
['Gespeichert!', 'Saved!'],
['Speichert…', 'Saving…'],
['Changelog', 'Changelog'],
['— bitte Diagnose-Paket exportieren oder Programm neu starten.', '— please export a diagnostics package or restart the application.'],
['• Bereit', '• Ready'],
['• Fehler', '• Failed'],
['<nicht gesetzt>', '<not set>'],
['Noch keine Uploads.', 'No uploads yet.'],
['Pfade nicht verfügbar.', 'Paths unavailable.'],
['Noch keine Uploads in dieser Session.', 'No uploads in this session yet.'],
['Account bearbeiten', 'Edit account'],
['Account nicht mehr in der Config — wurde extern gelöscht. Modal schließen und neu anlegen.', 'The account is no longer in the configuration because it was deleted externally. Close the dialog and add it again.'],
['Account wurde erfolgreich geprüft und gespeichert.', 'Account verified and saved successfully.'],
['Account wurde mit Warnung geprüft und gespeichert.', 'Account verified and saved with a warning.'],
['Account-Check läuft bereits.', 'An account check is already running.'],
['Account-Löschung konnte nicht persistiert werden — bitte erneut versuchen.', 'The account deletion could not be saved. Please try again.'],
['Account-Übersicht', 'Account overview'],
['Account wurde diese Session als fehlerhaft markiert. Klick = Wieder als aktiv markieren.', 'The account was marked as failed for this session. Click to reactivate it.'],
['Pausiert (Session)', 'Paused (session)'],
['Wieder aktivieren', 'Reactivate'],
['Accounts mit Handlungsbedarf anzeigen', 'Show accounts requiring action'],
['Alle Accounts und Einstellungen wurden übernommen.', 'All accounts and settings were applied.'],
['Anwendung neu starten?', 'Restart application?'],
['API-Key anzeigen', 'Show API key'],
['Automatisch gespeichert', 'Saved automatically'],
['Beenden', 'Quit'],
['Bekanntes Größen-Limit', 'Known size limit'],
['Backup nicht entschlüsselbar', 'Backup could not be decrypted'],
['Bitte mindestens einen Hoster auswählen.', 'Select at least one host.'],
['CSRF token nicht gefunden', 'CSRF token not found'],
['Deaktiviert', 'Disabled'],
['Der Schlüssel muss exakt 75 Zeichen lang sein.', 'The key must be exactly 75 characters long.'],
['Der Schlüssel muss mit MHU2- beginnen und exakt 75 Zeichen lang sein.', 'The key must start with MHU2- and be exactly 75 characters long.'],
['Diagnose-Paket wird erstellt…', 'Creating diagnostics package…'],
['Die Anwendung konnte nach dem fehlgeschlagenen Speichern nicht entsperrt werden', 'The application could not be unlocked after saving failed'],
['Die Anwendung wird gerade beendet', 'The application is shutting down'],
['Download wird geprüft…', 'Verifying download…'],
['Download wird vorbereitet…', 'Preparing download…'],
['Ein Einstellungsimport läuft bereits', 'A settings import is already running'],
['Einstellungen konnten vor dem Beenden nicht gespeichert werden', 'Settings could not be saved before quitting'],
['Einstellungen werden gerade importiert', 'Settings are being imported'],
['Einstellungen werden gespeichert…', 'Saving settings…'],
['Einstellungen wurden durch einen Import ersetzt', 'Settings were replaced by an import'],
['Ganz nach oben', 'Move to top'],
['Ganz nach unten', 'Move to bottom'],
['Hoster entfernen ▸', 'Remove host ▸'],
['Kein gültiger Account', 'No valid account'],
['Kein Update verfügbar', 'No update available'],
['Kein Upload aktiv', 'No active upload'],
['Kein Verlauf zum Exportieren vorhanden.', 'There is no history to export.'],
['Keine Antwort vom Hoster erhalten', 'No response received from the host'],
['Keine Einträge im Log gefunden', 'No log entries found'],
['Keine Einträge zum Exportieren.', 'No entries to export.'],
['Keine Jobs hinzugefuegt', 'No jobs added'],
['Keine Log-Einträge für diesen Job (entweder noch nichts passiert oder aus vorherigem Batch und schon geräumt).', 'No log entries for this job. Nothing has happened yet, or entries from a previous batch were already cleared.'],
['Keine passenden Jobs für Retry gefunden.', 'No matching jobs found for retry.'],
['Keine startbaren Jobs ausgewählt (alle laufen schon oder sind fertig).', 'No startable jobs selected because all are already running or completed.'],
['Keine transienten Fehler', 'No transient errors'],
['Keine URL eingetragen.', 'No URL entered.'],
['Keine Zugangsdaten', 'No credentials'],
['Lade und entschlüssele Einstellungen…', 'Loading and decrypting settings…'],
['Link kopieren', 'Copy link'],
['Links kopieren', 'Copy links'],
['Log anzeigen', 'Show log'],
['Log importieren', 'Import log'],
['Log importieren — bereits hochgeladene aus Queue entfernen', 'Import log — remove already uploaded jobs from queue'],
['Log-Datei', 'Log file'],
['MB/s · 0 = unbegrenzt', 'MB/s · 0 = unlimited'],
['Log-Pfad automatisch auf funktionierenden Ordner gesetzt', 'Log path automatically changed to a writable folder'],
['Neuer Schlüssel erstellt. Ältere Schlüssel bleiben gültig.', 'New key created. Older keys remain valid.'],
['Nicht alle Einstellungen konnten gespeichert werden', 'Not all settings could be saved'],
['Online-Schlüssel erstellt', 'Online key created'],
['Online-Schlüssel kopiert', 'Online key copied'],
['Online-Sicherung konnte nicht erstellt werden', 'Online backup could not be created'],
['Online-Sicherung konnte nicht importiert werden', 'Online backup could not be imported'],
['OTP wird geprüft…', 'Checking OTP…'],
['OTP-Prüfung fehlgeschlagen', 'OTP check failed'],
['Passwort anzeigen', 'Show password'],
['Prüfe Zugangsdaten…', 'Checking credentials…'],
['Prüfen…', 'Checking…'],
['Prüfung fehlgeschlagen', 'Check failed'],
['Prüfung oder Speichern fehlgeschlagen', 'Check or save failed'],
['Speichere aktuelle Einstellungen…', 'Saving current settings…'],
['Speichern vor dem Beenden hat zu lange gedauert', 'Saving before quitting took too long'],
['Stoppt nach aktiven Uploads...', 'Stopping after active uploads...'],
['Suche nach Aktualisierungen…', 'Checking for updates…'],
['Suche nach Updates…', 'Checking for updates…'],
['System wird heruntergefahren in', 'System will shut down in'],
['Übernehmen', 'Apply'],
['Übersprungen', 'Skipped'],
['Ungespeicherte Änderungen', 'Unsaved changes'],
['Update installiert. Die Anwendung startet neu…', 'Update installed. The application is restarting…'],
['Update konnte nicht gestartet werden', 'Update could not be started'],
['Update verfügbar', 'Update available'],
['Update ist bereit. Einstellungen werden gespeichert…', 'The update is ready. Saving settings…'],
['Update wird installiert. Die Anwendung startet neu…', 'Installing update. The application is restarting…'],
['Updateprüfung fehlgeschlagen', 'Update check failed'],
['Upload läuft...', 'Uploading...'],
['Upload-Log', 'Upload log'],
['Upload-Status', 'Upload status'],
['Upload-Übersicht', 'Upload overview'],
['Verlauf als CSV exportieren?\n\nOK = CSV\nAbbrechen = JSON', 'Export history as CSV?\n\nOK = CSV\nCancel = JSON'],
['Verlauf wirklich löschen?', 'Are you sure you want to delete the history?'],
['Verschlüssele und speichere Einstellungen…', 'Encrypting and saving settings…'],
['Zeit', 'Time'],
['Wenn das Backup mit der alten Passwort-Option (vor v3.0) erstellt wurde, hier eingeben.', 'If the backup was created with the legacy password option before v3.0, enter it here.'],
['Verlauf', 'History']
];
const deToEn = new Map(pairs);
const enToDe = new Map(pairs.map(([de, en]) => [en, de]));
function normalizeLanguage(value) {
return value === 'de' ? 'de' : 'en';
}
function translateText(value, language) {
const text = String(value ?? '');
const target = normalizeLanguage(language);
const leading = text.match(/^\s*/)?.[0] || '';
const trailing = text.match(/\s*$/)?.[0] || '';
const core = text.slice(leading.length, text.length - trailing.length);
const exact = target === 'en' ? deToEn.get(core) : enToDe.get(core);
if (exact) return `${leading}${exact}${trailing}`;
const patterns = target === 'en'
? [
[/^Update v(.+) verfügbar$/, 'Update v$1 available'],
[/^Aktives Ziel: (.+)$/, 'Active destination: $1'],
[/^(\d+) Fehler$/, '$1 errors'],
[/^Gesamt (\d+)$/, 'Total $1'],
[/^Verbindungen (\d+)$/, 'Connections $1'],
[/^Verbleibend (\d+)$/, 'Remaining $1'],
[/^(\d+) deaktiviert$/, '$1 disabled'],
[/^(.+) verbergen$/, 'Hide $1'],
[/^(.+) anzeigen$/, 'Show $1'],
[/^(.+) Account wieder aktiv — nächste Batch verwendet ihn$/, '$1 account reactivated — the next batch will use it'],
[/^(.+): Alle Accounts ausgeschöpft$/, '$1: all accounts exhausted'],
[/^(.+): Keine weiteren Fallback-Accounts verfügbar$/, '$1: no additional fallback accounts available'],
[/^(\d+) Ziele aktiv: (.+)$/, '$1 destinations active: $2'],
[/^(\d+) Job\(s\) zum erneuten Upload zurückgesetzt$/, '$1 job(s) reset for upload'],
[/^(\d+) bereits hochgeladene Jobs aus Queue entfernt \((\d+) Log-Einträge gelesen\)$/, '$1 already uploaded jobs removed from the queue ($2 log entries read)'],
[/^(\d+) Einträge exportiert$/, '$1 entries exported'],
[/^(\d+) Verlaufseinträge werden dauerhaft entfernt\.\n\nFortfahren\?$/, '$1 history entries will be permanently removed.\n\nContinue?'],
[/^Account "(.+)" wirklich löschen\?$/, 'Are you sure you want to delete account "$1"?'],
[/^Aktiv auf (.+) \((.+)\) — (\d+) Client\(s\) — Letzter Zugriff: (.+)$/, 'Active at $1 ($2) — $3 client(s) — Last access: $4'],
[/^Aktiv auf Port (\d+) — (\d+) Client\(s\) verbunden$/, 'Active on port $1 — $2 client(s) connected'],
[/^Alle Fehler erneut versuchen \((\d+)\)$/, 'Retry all failed uploads ($1)'],
[/^API: (.+)$/, 'API: $1'],
[/^Ausgewählte starten \((\d+)\)$/, 'Start selected ($1)'],
[/^Auto-Retry Runde (\d+)\/(\d+): (\d+) transiente Fehler werden in (.+) min neu versucht\.$/, 'Auto-retry round $1/$2: $3 transient errors will be retried in $4 min.'],
[/^Backup importiert\. Bitte prüfen: (.+)\.$/, 'Backup imported. Please review: $1.'],
[/^Code erstellt: (.+)$/, 'Code created: $1'],
[/^Diagnose-Paket gespeichert \((.+) KB\)$/, 'Diagnostics package saved ($1 KB)'],
[/^Einstellungen übernommen\. Bitte prüfen: (.+)\.$/, 'Settings applied. Please review: $1.'],
[/^Entfernen \((\d+)\)$/, 'Remove ($1)'],
[/^Fehler (\d+)$/, 'Failed $1'],
[/^Fehler: (.+)$/, 'Error: $1'],
[/^Fertig (\d+)$/, 'Completed $1'],
[/^Fertig:$/, 'Completed:'],
[/^Gespeichert: (.+) \((.+) KB\)$/, 'Saved: $1 ($2 KB)'],
[/^Import übernommen\. Warteschlange konnte nicht vollständig gespeichert werden: (.+)$/, 'Import applied. The queue could not be saved completely: $1'],
[/^Jobs konnten nicht hinzugefuegt werden: (.+)$/, 'Jobs could not be added: $1'],
[/^Links kopieren \((\d+)\)$/, 'Copy links ($1)'],
[/^Log-Pfad nicht beschreibbar — schreibe nach: (.+)$/, 'Log path is not writable — writing to: $1'],
[/^Login: (.+)$/, 'Login: $1'],
[/^Speichern fehlgeschlagen: (.+)$/, 'Saving failed: $1'],
[/^Test erfolgreich gesendet \(HTTP (\d+)\)\.$/, 'Test sent successfully (HTTP $1).'],
[/^Übersprungen: (.+)$/, 'Skipped: $1'],
[/^Update fehlgeschlagen: (.+)$/, 'Update failed: $1'],
[/^Update wird heruntergeladen… (\d+)%$/, 'Downloading update… $1%'],
[/^Verlauf exportiert \((\d+) Zeilen\)$/, 'History exported ($1 rows)'],
[/^Verlauf gekürzt: (\d+) entfernt$/, 'History trimmed: $1 removed'],
[/^Zeige neueste (.+) von (.+) Einträgen\. Der vollständige Verlauf bleibt gespeichert und ist über „Verlauf exportieren“ verfügbar\.$/, 'Showing the newest $1 of $2 entries. The complete history remains saved and is available through “Export history”.'],
[/^Wirklich alle (\d+) Links aus diesem Panel entfernen\?$/, 'Remove all $1 links from this panel?'],
[/^Zugangsdaten für (.+) bearbeiten und prüfen\.$/, 'Edit and verify credentials for $1.'],
[/^Läuft (\d+)$/, 'Running $1'],
[/^Fehler (\d+)$/, 'Failed $1'],
[/^Update v(.+) verfügbar\. Klicken zum Installieren\.$/, 'Update v$1 available. Click to install.']
]
: [
[/^Update v(.+) available$/, 'Update v$1 verfügbar'],
[/^Active destination: (.+)$/, 'Aktives Ziel: $1'],
[/^Running (\d+)$/, 'Läuft $1'],
[/^Failed (\d+)$/, 'Fehler $1'],
[/^Update v(.+) available\. Click to install\.$/, 'Update v$1 verfügbar. Klicken zum Installieren.']
];
for (const [pattern, replacement] of patterns) {
if (pattern.test(core)) return `${leading}${core.replace(pattern, replacement)}${trailing}`;
}
return text;
}
function createDomLocalizer(documentRef) {
const textSources = new WeakMap();
const textRendered = new WeakMap();
const attributeSources = new WeakMap();
const attributes = ['aria-label', 'placeholder', 'title', 'data-tooltip'];
let language = 'en';
let observer = null;
function renderTextNode(node) {
const current = node.nodeValue || '';
if (!textSources.has(node) || current !== textRendered.get(node)) textSources.set(node, current);
const source = textSources.get(node);
const rendered = language === 'de' ? source : translateText(source, language);
textRendered.set(node, rendered);
if (current !== rendered) node.nodeValue = rendered;
}
function renderAttributes(element) {
let sources = attributeSources.get(element);
if (!sources) {
sources = new Map();
attributeSources.set(element, sources);
}
for (const name of attributes) {
if (!element.hasAttribute(name)) continue;
const current = element.getAttribute(name) || '';
const known = sources.get(name);
if (!known || current !== known.rendered) sources.set(name, { source: current, rendered: current });
const entry = sources.get(name);
const rendered = language === 'de' ? entry.source : translateText(entry.source, language);
entry.rendered = rendered;
if (current !== rendered) element.setAttribute(name, rendered);
}
}
function renderNode(node) {
if (!node) return;
if (node.nodeType === 3) {
renderTextNode(node);
return;
}
if (node.nodeType !== 1 && node.nodeType !== 9 && node.nodeType !== 11) return;
if (node.nodeType === 1) renderAttributes(node);
const walker = documentRef.createTreeWalker(node, 5);
let current = walker.nextNode();
while (current) {
if (current.nodeType === 3) renderTextNode(current);
else renderAttributes(current);
current = walker.nextNode();
}
}
function setLanguage(value) {
language = normalizeLanguage(value);
documentRef.documentElement.lang = language;
renderNode(documentRef.body || documentRef.documentElement);
return language;
}
function start(value = 'en') {
setLanguage(value);
if (!observer && documentRef.defaultView?.MutationObserver) {
observer = new documentRef.defaultView.MutationObserver(records => {
for (const record of records) {
if (record.type === 'characterData') renderTextNode(record.target);
else if (record.type === 'attributes') renderAttributes(record.target);
else record.addedNodes.forEach(renderNode);
}
});
observer.observe(documentRef.documentElement, { subtree: true, childList: true, characterData: true, attributes: true, attributeFilter: attributes });
}
return language;
}
return { start, setLanguage, translate: renderNode, getLanguage: () => language };
}
return { normalizeLanguage, translateText, createDomLocalizer };
});