diff --git a/Casks/termix.rb b/Casks/termix.rb index c8c8e6f05..59b39e9fa 100644 --- a/Casks/termix.rb +++ b/Casks/termix.rb @@ -1,6 +1,6 @@ cask "termix" do - version "2.8.0" - sha256 "e4030d648055650c682a451038814d4463230d2673457c2e337105458f84ce3d" + version "2.9.0" + sha256 "db37ee3eaf76b6a30d04dec064a516c3e02ffc5a14d7c1627178c0de230374e9" url "https://github.com/Termix-SSH/Termix/releases/download/release-#{version}-tag/termix_macos_universal_dmg.dmg" name "Termix" diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index ddec3063a..62dd4b63b 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,6 +1,6 @@ -A new plugin system powering every feature, a dedicated sync page with more control over what syncs, one inbox for all alerts, a redesigned split screen, admin, user and folder host defaults, host maintenance mode, and a large batch of file manager, terminal, and remote desktop fixes. +A patch for 2.9.0 that fixes OIDC sign-in after upgrading, Docker and Host Metrics logins, memory and CPU use, file downloads, tmux sessions, user data export and more. Also adds predefined host tags. @@ -12,90 +12,35 @@ https://youtu.be/lngaePO96tM -- Rebuilt Termix around a plugin system, with features like the terminal, file manager, tunnels, Docker, Proxmox, remote desktop, metrics, automations, AI and every login method now shipped as signed plugins on a shared SDK -- Moved desktop sync to its own page in the sidebar, with options to choose what syncs, keep single hosts or folders on the device only, and resolve conflicts -- Added a recent servers list when linking the desktop app -- Combined all alerts into one inbox with popups, Termix announcements and a new email channel -- Redesigned split screen with free-form panes and a pane picker -- Redesigned host defaults so they can be set at the admin, user or folder level and are inherited by hosts unless overridden -- Added per-host maintenance mode and recurring schedules to automations -- Added optional auto reconnect for dropped SSH sessions and a button to reconnect all disconnected terminal tabs -- Added a duplicate tab action and a reconnect session keybinding -- Added a host click setting to either focus an existing tab or always open a new one -- Added keyboard type-ahead search to the host list -- Added tighter compact host rows with inline tags -- Added an option to show tab numbers -- Added an option to hide folder paths above nested folders -- Added a list of the fixed app shortcuts to the keyboard shortcuts screen -- Added terminal toolbar position, start state and fade settings per host -- Added a host setting to turn off password prompt auto-fill -- Added the option to apply a saved custom theme in connection defaults -- Added FortiToken push 2FA support for SSH -- Added a unified multi-host tmux monitor view and a per-host tmux mouse toggle -- Added fleet sharing -- Added a list view to Docker management and support for the OrbStack Docker socket on macOS -- Added network graph sync between the desktop app and the server -- Added homepage canvas layout sync across devices -- Added RDP display zoom controls -- Added an option to skip the move to trash confirmation in the file manager -- Made the file manager open in the remote login directory by default -- Added add host and copy IP actions for Tailscale devices -- Added inline credential sharing in the sidebar, matching host sharing -- Made the Windows desktop shortcut optional in the installer -- Redesigned the snippets panel to match the host list -- Redesigned the session log player controls -- Host status now shows online once the port answers and only warns when a login fails -- Faster SFTP downloads -- Faster UI loading with less jitter and lag across tabs, the dashboard and the network graph +- Added predefined host tags that admins can set, with suggestions in the host editor +- Kept compact host row actions on the same line as the host name +- Added a reload button when a sign-in verification method fails to load +- Admins can now merge a duplicate SSO account made by 2.9.0 back into the original account +- Hosts behind the same jump hosts now share one connection for status checks +- Completed the Simplified Chinese translation +- Documented cookie and API key sign-in in the API docs -- TOTP not being prompted for jump hosts in the terminal, file manager, metrics and client tunnels -- SSH host names resolving to IPv6 when IPv4 was available -- Host key updates not syncing between devices -- Host metrics returning 404 on the first connect -- Host metrics using too much CPU on the backend -- Host metrics showing image and firmware filesystems -- Sudo password not auto-filling -- Tunnels failing with shared credentials -- Imported jump host references breaking -- Hard to read terminal selection with the light theme -- Terminal input arriving out of order with local echo on -- Terminal image uploads failing when the image library was unavailable -- File manager saves failing or corrupting files, with no sudo prompt on protected files -- Sending a single file between servers failing -- Disk usage showing the wrong mount or not refreshing with the directory -- File uploads not cancelling and continuing to write on the server -- Ctrl/Cmd+F file search not working in the file manager -- File drops from the OS not working over existing rows -- No download progress in file viewers -- Text in Markdown previews not being selectable -- Inline rename, compact mode and narrow list layout issues in the file manager -- Remote desktop not using the host's saved guacd endpoint -- Remote desktop asking for clipboard access unprompted -- Remote desktop keys staying held after switching windows -- Session share links on desktop pointing at the local app instead of the server -- Shared terminal sizes and participant presence not syncing in session sharing -- Meeting guests not being shown to members, and guests seeing the full roster -- Session sharing not handing over cleanly after a takeover -- AI responses getting cut off mid stream -- AI provider settings not syncing to linked devices -- Proxmox guest sync and startup snippet sync not working -- LDAP logins losing the bind DN from the directory -- Homepage service checks failing for allowed private addresses -- Sidebar search showing overlapping hosts when grouped by tags -- Sidebar rows not resizing after changing density, and compact rows hiding host addresses -- Split screen layouts failing to create over plain HTTP -- Double Shift opening the command palette by accident -- Fleet detail buttons overflowing the sidebar -- Recent activity cutting off host names too early -- Docker container logs using the wrong background color -- Version number missing on desktop when the server was offline -- Desktop app not starting reliably, not quitting with active connections, and the Linux tray icon failing to load -- Mac App Store builds being blocked by the single instance lock -- Untranslated text in toasts and other parts of the UI -- Several dependency security advisories +- OIDC accounts from 2.8 not being able to sign in, or getting a new empty account, after upgrading +- Downloading a file in the file manager turning the whole screen black +- tmux sessions not resuming and new sessions being created instead +- Connections through two or more jump hosts failing +- Docker and Host Metrics failing to sign in while the terminal worked +- Fleets, Proxmox and automations not getting the host sudo password +- Server running out of memory on start and when importing hosts +- High CPU use after the app was first opened +- User data export freezing the server +- 1Password and other secret references being rejected as SSH keys +- Slow file deletes in the file manager +- Mac App Store app failing to start its local server +- Snippets failing to sync on older databases +- GitHub sign in failing +- RDP showing scrollbars and jittering near the edges +- Status checks triggering Fail2Ban bans while a session was open +- Too many database writes from session activity +- Host editor tabs being hidden when they did not fit diff --git a/packaging/build/after-pack.cjs b/packaging/build/after-pack.cjs index 170731252..869b04c35 100644 --- a/packaging/build/after-pack.cjs +++ b/packaging/build/after-pack.cjs @@ -30,6 +30,20 @@ function copyPluginSdk(resourcesDir, sdkDir = path.join(repoRoot, "packages", "p exports.copyPluginSdk = copyPluginSdk; +/** Mac App Store builds report "mas", not "darwin", but are still .app bundles. */ +function resourcesDirFor({ electronPlatformName, appOutDir, packager }) { + return ["darwin", "mas"].includes(electronPlatformName) + ? path.join( + appOutDir, + `${packager.appInfo.productFilename}.app`, + "Contents", + "Resources", + ) + : path.join(appOutDir, "resources"); +} + +exports.resourcesDirFor = resourcesDirFor; + exports.default = async function afterPack(context) { const { targets, appOutDir } = context; @@ -39,15 +53,7 @@ exports.default = async function afterPack(context) { fs.writeFileSync(markerPath, ""); } - const resourcesDir = - context.electronPlatformName === "darwin" - ? path.join( - appOutDir, - `${context.packager.appInfo.productFilename}.app`, - "Contents", - "Resources", - ) - : path.join(appOutDir, "resources"); + const resourcesDir = resourcesDirFor(context); copyPluginSdk(resourcesDir); diff --git a/plugins/acme-ssl/locales/en.json b/plugins/acme-ssl/locales/en.json index 5c0aaa55b..cc7e8300a 100644 --- a/plugins/acme-ssl/locales/en.json +++ b/plugins/acme-ssl/locales/en.json @@ -54,5 +54,8 @@ "request": "Request certificate now", "requesting": "Requesting certificate...", "issued": "Certificate issued and installed" + }, + "plugin": { + "name": "ACME Certificates" } } diff --git a/plugins/acme-ssl/locales/translated/af_ZA.json b/plugins/acme-ssl/locales/translated/af_ZA.json index 88c629b45..771b7deee 100644 --- a/plugins/acme-ssl/locales/translated/af_ZA.json +++ b/plugins/acme-ssl/locales/translated/af_ZA.json @@ -1,17 +1,41 @@ { + "permissions": { + "manage": { + "title": "Bestuur ACME-sertifikate", + "description": "Sien die sertifikaatstatus en versoek nou 'n nuwe sertifikaat." + } + }, "settings": { + "autoRenew": { + "label": "Hernu outomaties", + "description": "Kontroleer twee keer per dag en kry 'n nuwe sertifikaat wanneer daar geen is nie, dit nie die domein dek nie, of dit binne 30 dae verval." + }, "domain": { "label": "Domein", - "placeholder": "termix.voorbeeld.com", - "description": "Die publieke domeinnaam vir die sertifikaat." + "description": "Die publieke domeinnaam vir die sertifikaat.", + "placeholder": "termix.voorbeeld.com" }, "email": { "label": "E-pos", + "description": "Kontak-e-posadres vir die ACME-rekening en vervalkennisgewings.", "placeholder": "admin@voorbeeld.com" }, + "provider": { + "label": "Sertifikaatowerheid", + "description": "Waar om die sertifikaat te kry. Gebruik staging om te toets sonder om Let's Encrypt-tarieflimiete te bereik.", + "letsencrypt": "Kom ons enkripteer", + "letsencryptStaging": "Kom ons enkripteer (opvoering)", + "custom": "Pasgemaakte ACME-gids" + }, + "directoryUrl": { + "label": "ACME-gids-URL", + "description": "Slegs vir 'n persoonlike sertifikaatowerheid. Moet 'n https-URL wees." + }, "challengeType": { "label": "Uitdagingsoort", - "cloudflare": "DNS (Cloudflare) - vereis 'n Cloudflare API-token" + "description": "Hoe om te bewys dat jy die domein besit.", + "http": "HTTP - benodig poort 80 wat vanaf die internet bereikbaar is", + "cloudflare": "DNS (Cloudflare) - benodig 'n Cloudflare API-token" }, "cloudflareToken": { "label": "Cloudflare API-token", @@ -21,9 +45,14 @@ "status": { "title": "Sertifikaatstatus", "none": "Geen sertifikaat nie", + "names": "Omslae {{names}}", + "issuer": "Uitgereik deur {{issuer}}", "expires": "Vervaldatum {{date}}", "lastIssued": "Laas uitgereik {{date}}", - "request": "Uitreik / Hernu Sertifikaat", - "requesting": "Versoek sertifikaat..." + "lastError": "Laaste poging het misluk: {{error}}", + "missing": "Stel die domein, e-posadres en die velde wat jou uitdagingsoort benodig, en stoor dit dan voordat jy 'n sertifikaat aanvra.", + "request": "Versoek nou 'n sertifikaat", + "requesting": "Versoek sertifikaat...", + "issued": "Sertifikaat uitgereik en geïnstalleer" } } diff --git a/plugins/acme-ssl/locales/translated/ar_SA.json b/plugins/acme-ssl/locales/translated/ar_SA.json index a80917cd8..7b6e732e6 100644 --- a/plugins/acme-ssl/locales/translated/ar_SA.json +++ b/plugins/acme-ssl/locales/translated/ar_SA.json @@ -1,29 +1,58 @@ { + "permissions": { + "manage": { + "title": "إدارة شهادات ACME", + "description": "اطلع على حالة الشهادة واطلب شهادة جديدة الآن." + } + }, "settings": { + "autoRenew": { + "label": "يتم التجديد تلقائياً", + "description": "تحقق مرتين في اليوم واحصل على شهادة جديدة عندما لا تكون هناك شهادة، أو عندما لا تغطي النطاق، أو عندما تنتهي صلاحيتها في غضون 30 يومًا." + }, "domain": { "label": "النطاق", - "placeholder": "termix.example.com", - "description": "اسم النطاق العام للشهادة." + "description": "اسم النطاق العام للشهادة.", + "placeholder": "termix.example.com" }, "email": { "label": "البريد الإلكتروني", + "description": "البريد الإلكتروني للتواصل بخصوص حساب ACME وإشعارات انتهاء الصلاحية.", "placeholder": "admin@example.com" }, + "provider": { + "label": "المرجع المصدق (CA)", + "description": "من أين أحصل على الشهادة؟ استخدم بيئة الاختبار لإجراء الاختبارات دون تجاوز حدود معدل Let's Encrypt.", + "letsencrypt": "Let's Encrypt", + "letsencryptStaging": "Let's Encrypt (مرحلة تجريبية)", + "custom": "دليل ACME مخصص" + }, + "directoryUrl": { + "label": "رابط دليل ACME", + "description": "مخصص فقط لهيئة إصدار شهادات مخصصة. يجب أن يكون عنوان URL من نوع https." + }, "challengeType": { "label": "نوع التحدي", - "cloudflare": "DNS (Cloudflare) - يتطلب رمز Cloudflare API" + "description": "كيفية إثبات ملكيتك للنطاق.", + "http": "بروتوكول HTTP - يتطلب منفذ 80 يمكن الوصول إليه من الإنترنت", + "cloudflare": "نظام أسماء النطاقات (Cloudflare) - يتطلب رمز API من Cloudflare" }, "cloudflareToken": { - "label": "رمز Cloudflare API", + "label": "رمز واجهة برمجة تطبيقات Cloudflare", "description": "رمز مقيد بصلاحية Zone:DNS:Edit للنطاق الخاص بك." } }, "status": { "title": "حالة الشهادة", "none": "لا توجد شهادة", + "names": "يغطي {{names}}", + "issuer": "صادر عن {{issuer}}", "expires": "تنتهي في {{date}}", "lastIssued": "آخر إصدار {{date}}", - "request": "إصدار / تجديد الشهادة", - "requesting": "جارٍ طلب الشهادة..." + "lastError": "فشلت المحاولة الأخيرة: {{error}}", + "missing": "قم بتعيين النطاق والبريد الإلكتروني والحقول التي يحتاجها نوع التحدي الخاص بك، ثم احفظ التغييرات قبل طلب الشهادة.", + "request": "اطلب الشهادة الآن", + "requesting": "جارٍ طلب الشهادة...", + "issued": "تم إصدار الشهادة وتركيبها" } } diff --git a/plugins/acme-ssl/locales/translated/bg_BG.json b/plugins/acme-ssl/locales/translated/bg_BG.json index 81b062aad..28007ffb7 100644 --- a/plugins/acme-ssl/locales/translated/bg_BG.json +++ b/plugins/acme-ssl/locales/translated/bg_BG.json @@ -1,29 +1,58 @@ { + "permissions": { + "manage": { + "title": "Управление на ACME сертификати", + "description": "Вижте състоянието на сертификата и заявете нов сертификат сега." + } + }, "settings": { + "autoRenew": { + "label": "Подновяване автоматично", + "description": "Проверявайте два пъти на ден и получавайте нов сертификат, когато няма такъв, не покрива домейна или изтича в рамките на 30 дни." + }, "domain": { "label": "Домейн", - "placeholder": "termix.example.com", - "description": "Публичното име на домейна за сертификата." + "description": "Публичното домейн име за сертификата.", + "placeholder": "termix.example.com" }, "email": { "label": "Имейл", + "description": "Контактен имейл за ACME акаунта и известия за изтичане.", "placeholder": "admin@example.com" }, + "provider": { + "label": "Сертифициращ орган", + "description": "Къде да взема сертификата. Използвайте етапно тестване, за да не се достигат ограниченията на скоростта на Let's Encrypt.", + "letsencrypt": "Нека криптираме", + "letsencryptStaging": "Нека криптираме (подготовка)", + "custom": "Персонализирана ACME директория" + }, + "directoryUrl": { + "label": "URL адрес на директорията на ACME", + "description": "Само за персонализиран сертифициращ орган. Трябва да е https URL адрес." + }, "challengeType": { "label": "Тип предизвикателство", + "description": "Как да докажете, че притежавате домейна.", + "http": "HTTP - изисква порт 80, достъпен от интернет", "cloudflare": "DNS (Cloudflare) - изисква Cloudflare API токен" }, "cloudflareToken": { - "label": "API токен на Cloudflare", + "label": "Cloudflare API токен", "description": "Ограничен токен с разрешение Zone:DNS:Edit за вашия домейн." } }, "status": { - "title": "Статус на сертификата", + "title": "Състояние на сертификата", "none": "Няма сертификат", + "names": "Обхваща {{names}}", + "issuer": "Издадено от {{issuer}}", "expires": "Изтича {{date}}", "lastIssued": "Последно издадено {{date}}", - "request": "Издаване / Подновяване на сертификат", - "requesting": "Заявка за сертификат..." + "lastError": "Последният опит не беше успешен: {{error}}", + "missing": "Задайте домейна, имейла и полетата, необходими за вашия тип предизвикателство, след което ги запазете, преди да заявите сертификат.", + "request": "Заявете сертификат сега", + "requesting": "Заявка за сертификат...", + "issued": "Сертификат издаден и инсталиран" } } diff --git a/plugins/acme-ssl/locales/translated/bn_BD.json b/plugins/acme-ssl/locales/translated/bn_BD.json index db2c9a7d3..5c0aaa55b 100644 --- a/plugins/acme-ssl/locales/translated/bn_BD.json +++ b/plugins/acme-ssl/locales/translated/bn_BD.json @@ -1,29 +1,58 @@ { + "permissions": { + "manage": { + "title": "Manage ACME certificates", + "description": "See the certificate status and request a new certificate now." + } + }, "settings": { + "autoRenew": { + "label": "Renew automatically", + "description": "Check twice a day and get a new certificate when there is none, it does not cover the domain, or it expires within 30 days." + }, "domain": { - "label": "ডোমেইন", - "placeholder": "termix.example.com", - "description": "সার্টিফিকেটটির পাবলিক ডোমেইন নাম।" + "label": "Domain", + "description": "The public domain name for the certificate.", + "placeholder": "termix.example.com" }, "email": { - "label": "ইমেল", + "label": "Email", + "description": "Contact email for the ACME account and expiry notices.", "placeholder": "admin@example.com" }, + "provider": { + "label": "Certificate authority", + "description": "Where to get the certificate. Use staging to test without hitting Let's Encrypt rate limits.", + "letsencrypt": "Let's Encrypt", + "letsencryptStaging": "Let's Encrypt (staging)", + "custom": "Custom ACME directory" + }, + "directoryUrl": { + "label": "ACME directory URL", + "description": "Only for a custom certificate authority. Must be an https URL." + }, "challengeType": { - "label": "চ্যালেঞ্জের ধরণ", - "cloudflare": "ডিএনএস (ক্লাউডফ্লেয়ার) - এর জন্য একটি ক্লাউডফ্লেয়ার এপিআই টোকেন প্রয়োজন।" + "label": "Challenge type", + "description": "How to prove you own the domain.", + "http": "HTTP - needs port 80 reachable from the internet", + "cloudflare": "DNS (Cloudflare) - needs a Cloudflare API token" }, "cloudflareToken": { - "label": "ক্লাউডফ্লেয়ার এপিআই টোকেন", - "description": "আপনার ডোমেনের জন্য Zone:DNS:Edit অনুমতিসহ স্কোপড টোকেন।" + "label": "Cloudflare API token", + "description": "Scoped token with Zone:DNS:Edit permission for your domain." } }, "status": { - "title": "সার্টিফিকেটের অবস্থা", - "none": "কোন সার্টিফিকেট নেই", - "expires": "মেয়াদ শেষ হবে {{date}}", - "lastIssued": "সর্বশেষ প্রকাশিত {{date}}", - "request": "সার্টিফিকেট ইস্যু / নবায়ন করুন", - "requesting": "সার্টিফিকেটের জন্য অনুরোধ..." + "title": "Certificate status", + "none": "No certificate", + "names": "Covers {{names}}", + "issuer": "Issued by {{issuer}}", + "expires": "Expires {{date}}", + "lastIssued": "Last issued {{date}}", + "lastError": "Last attempt failed: {{error}}", + "missing": "Set the domain, email and the fields your challenge type needs, then save, before requesting a certificate.", + "request": "Request certificate now", + "requesting": "Requesting certificate...", + "issued": "Certificate issued and installed" } } diff --git a/plugins/acme-ssl/locales/translated/ca_ES.json b/plugins/acme-ssl/locales/translated/ca_ES.json index 60db3c04e..691ee75e8 100644 --- a/plugins/acme-ssl/locales/translated/ca_ES.json +++ b/plugins/acme-ssl/locales/translated/ca_ES.json @@ -1,17 +1,41 @@ { + "permissions": { + "manage": { + "title": "Gestionar certificats ACME", + "description": "Consulta l'estat del certificat i sol·licita'n un de nou ara." + } + }, "settings": { + "autoRenew": { + "label": "Renovar automàticament", + "description": "Revisa dues vegades al dia i aconsegueix un certificat nou quan no n'hi ha cap, no cobreix el domini o caduca en 30 dies." + }, "domain": { "label": "Domini", - "placeholder": "termix.example.com", - "description": "El nom de domini públic del certificat." + "description": "El nom de domini públic del certificat.", + "placeholder": "termix.example.com" }, "email": { "label": "Correu electrònic", + "description": "Correu electrònic de contacte per al compte ACME i avisos de caducitat.", "placeholder": "admin@example.com" }, + "provider": { + "label": "Autoritat de certificació", + "description": "On s'obté el certificat. Utilitzeu la configuració estadística per fer proves sense arribar als límits de velocitat de Let's Encrypt.", + "letsencrypt": "Xifrem", + "letsencryptStaging": "Xifrem (posada en escena)", + "custom": "Directori ACME personalitzat" + }, + "directoryUrl": { + "label": "URL del directori ACME", + "description": "Només per a una autoritat de certificació personalitzada. Ha de ser una URL https." + }, "challengeType": { "label": "Tipus de repte", - "cloudflare": "DNS (Cloudflare): requereix un token d'API de Cloudflare" + "description": "Com demostrar que ets el propietari del domini.", + "http": "HTTP: necessita que el port 80 sigui accessible des d'Internet", + "cloudflare": "DNS (Cloudflare): necessita un token d'API de Cloudflare" }, "cloudflareToken": { "label": "Token de l'API de Cloudflare", @@ -21,9 +45,14 @@ "status": { "title": "Estat del certificat", "none": "Sense certificat", + "names": "Cobertes {{names}}", + "issuer": "Publicat per {{issuer}}", "expires": "Caduca {{date}}", "lastIssued": "Última emissió {{date}}", - "request": "Emetre / Renovar el certificat", - "requesting": "Sol·licitant certificat..." + "lastError": "Últim intent fallit: {{error}}", + "missing": "Definiu el domini, el correu electrònic i els camps que necessita el vostre tipus de repte i, a continuació, deseu-ho abans de sol·licitar un certificat.", + "request": "Sol·licita el certificat ara", + "requesting": "Sol·licitant certificat...", + "issued": "Certificat emès i instal·lat" } } diff --git a/plugins/acme-ssl/locales/translated/cs_CZ.json b/plugins/acme-ssl/locales/translated/cs_CZ.json index 19cd8e36a..16487134c 100644 --- a/plugins/acme-ssl/locales/translated/cs_CZ.json +++ b/plugins/acme-ssl/locales/translated/cs_CZ.json @@ -1,16 +1,40 @@ { + "permissions": { + "manage": { + "title": "Správa certifikátů ACME", + "description": "Zkontrolujte stav certifikátu a požádejte o nový certifikát." + } + }, "settings": { + "autoRenew": { + "label": "Automaticky obnovit", + "description": "Kontrolujte dvakrát denně a požádejte o nový certifikát, pokud žádný neexistuje, pokud se nevztahuje na danou doménu nebo pokud jeho platnost vyprší do 30 dnů." + }, "domain": { "label": "Doména", - "placeholder": "termix.example.com", - "description": "Název veřejné domény pro certifikát." + "description": "Název veřejné domény pro certifikát.", + "placeholder": "termix.example.com" }, "email": { "label": "E-mail", + "description": "Kontaktní e-mail pro účet ACME a oznámení o vypršení platnosti.", "placeholder": "admin@example.com" }, + "provider": { + "label": "Certifikační autorita", + "description": "Kde získat certifikát. Použijte staging k testování bez překročení limitů rychlosti Let's Encrypt.", + "letsencrypt": "Pojďme šifrovat", + "letsencryptStaging": "Pojďme šifrovat (příprava)", + "custom": "Vlastní adresář ACME" + }, + "directoryUrl": { + "label": "URL adresáře ACME", + "description": "Pouze pro vlastní certifikační autoritu. Musí se jednat o URL adresu typu https." + }, "challengeType": { "label": "Typ výzvy", + "description": "Jak prokázat, že jste vlastníkem domény.", + "http": "HTTP - vyžaduje dostupnost portu 80 z internetu", "cloudflare": "DNS (Cloudflare) – vyžaduje token Cloudflare API" }, "cloudflareToken": { @@ -21,9 +45,14 @@ "status": { "title": "Stav certifikátu", "none": "Žádný certifikát", + "names": "Kryty {{names}}", + "issuer": "Vydáno uživatelem {{issuer}}", "expires": "Platnost vyprší {{date}}", "lastIssued": "Naposledy vydáno {{date}}", - "request": "Vydání / Obnova certifikátu", - "requesting": "Žádost o certifikát..." + "lastError": "Poslední pokus se nezdařil: {{error}}", + "missing": "Před vyžádáním certifikátu nastavte doménu, e-mail a pole, která váš typ výzvy vyžaduje, a poté je uložte.", + "request": "Vyžádejte si certifikát nyní", + "requesting": "Žádost o certifikát...", + "issued": "Certifikát vydán a nainstalován" } } diff --git a/plugins/acme-ssl/locales/translated/da_DK.json b/plugins/acme-ssl/locales/translated/da_DK.json index 8914d4894..e3b371479 100644 --- a/plugins/acme-ssl/locales/translated/da_DK.json +++ b/plugins/acme-ssl/locales/translated/da_DK.json @@ -1,16 +1,40 @@ { + "permissions": { + "manage": { + "title": "Administrer ACME-certifikater", + "description": "Se certifikatstatussen, og anmod om et nyt certifikat nu." + } + }, "settings": { + "autoRenew": { + "label": "Forny automatisk", + "description": "Tjek to gange om dagen, og få et nyt certifikat, hvis der ikke er noget, det ikke dækker domænet, eller det udløber inden for 30 dage." + }, "domain": { "label": "Domæne", - "placeholder": "termix.example.com", - "description": "Det offentlige domænenavn for certifikatet." + "description": "Det offentlige domænenavn for certifikatet.", + "placeholder": "termix.example.com" }, "email": { "label": "E-mail", + "description": "Kontakt-e-mailadresse for ACME-kontoen og udløbsmeddelelser.", "placeholder": "admin@eksempel.com" }, + "provider": { + "label": "Certifikatmyndighed", + "description": "Hvor kan man få certifikatet? Brug staging til at teste uden at nå Let's Encrypt-hastighedsgrænserne.", + "letsencrypt": "Lad os kryptere", + "letsencryptStaging": "Lad os kryptere (staging)", + "custom": "Brugerdefineret ACME-mappe" + }, + "directoryUrl": { + "label": "ACME-katalogets URL", + "description": "Kun for en brugerdefineret certifikatmyndighed. Skal være en https-URL." + }, "challengeType": { "label": "Udfordringstype", + "description": "Sådan beviser du, at du ejer domænet.", + "http": "HTTP - kræver port 80, der kan nås fra internettet", "cloudflare": "DNS (Cloudflare) - kræver et Cloudflare API-token" }, "cloudflareToken": { @@ -21,9 +45,14 @@ "status": { "title": "Certifikatstatus", "none": "Intet certifikat", + "names": "Dækker {{names}}", + "issuer": "Udstedt af {{issuer}}", "expires": "Udløber {{date}}", "lastIssued": "Sidst udstedt {{date}}", - "request": "Udstede/forny certifikat", - "requesting": "Anmoder om certifikat..." + "lastError": "Sidste forsøg mislykkedes: {{error}}", + "missing": "Angiv domæne, e-mail og de felter, som din udfordringstype kræver, og gem derefter, før du anmoder om et certifikat.", + "request": "Anmod om certifikat nu", + "requesting": "Anmoder om certifikat...", + "issued": "Certifikat udstedt og installeret" } } diff --git a/plugins/acme-ssl/locales/translated/de_DE.json b/plugins/acme-ssl/locales/translated/de_DE.json index 9ecf51a82..cececddff 100644 --- a/plugins/acme-ssl/locales/translated/de_DE.json +++ b/plugins/acme-ssl/locales/translated/de_DE.json @@ -1,29 +1,58 @@ { + "permissions": { + "manage": { + "title": "ACME-Zertifikate verwalten", + "description": "Prüfen Sie den Zertifikatsstatus und fordern Sie jetzt ein neues Zertifikat an." + } + }, "settings": { + "autoRenew": { + "label": "Automatische Verlängerung", + "description": "Prüfen Sie zweimal täglich, ob ein Zertifikat vorhanden ist, ob das aktuelle Zertifikat die Domain nicht abdeckt oder ob es innerhalb von 30 Tagen abläuft." + }, "domain": { "label": "Domain", - "placeholder": "termix.example.com", - "description": "Der öffentliche Domainname für das Zertifikat." + "description": "Der öffentliche Domainname für das Zertifikat.", + "placeholder": "termix.example.com" }, "email": { "label": "E-Mail", + "description": "Kontakt-E-Mail-Adresse für das ACME-Konto und Benachrichtigungen zum Ablaufdatum.", "placeholder": "admin@example.com" }, + "provider": { + "label": "Zertifizierungsstelle", + "description": "Wo Sie das Zertifikat erhalten. Nutzen Sie die Staging-Umgebung, um zu testen, ohne die Ratenbegrenzungen von Let's Encrypt zu erreichen.", + "letsencrypt": "Let's Encrypt", + "letsencryptStaging": "Let's Encrypt (Staging)", + "custom": "Benutzerdefiniertes ACME-Verzeichnis" + }, + "directoryUrl": { + "label": "ACME-Verzeichnis-URL", + "description": "Nur für eine benutzerdefinierte Zertifizierungsstelle. Muss eine HTTPS-URL sein." + }, "challengeType": { - "label": "Challenge-Typ", - "cloudflare": "DNS (Cloudflare) – erfordert einen Cloudflare-API-Token" + "label": "Herausforderungstyp", + "description": "Wie Sie nachweisen, dass Sie die Domain besitzen.", + "http": "HTTP – benötigt Port 80, der aus dem Internet erreichbar sein muss.", + "cloudflare": "DNS (Cloudflare) – benötigt ein Cloudflare-API-Token" }, "cloudflareToken": { - "label": "Cloudflare-API-Token", + "label": "Cloudflare API-Token", "description": "Bereichsbezogener Token mit Zone:DNS:Edit-Berechtigung für Ihre Domain." } }, "status": { "title": "Zertifikatsstatus", "none": "Kein Zertifikat", + "names": "Cover {{names}}", + "issuer": "Herausgegeben von {{issuer}}", "expires": "Läuft ab {{date}}", "lastIssued": "Zuletzt ausgestellt {{date}}", - "request": "Zertifikat ausstellen / erneuern", - "requesting": "Zertifikat wird angefordert..." + "lastError": "Letzter Versuch fehlgeschlagen: {{error}}", + "missing": "Legen Sie die Domain, die E-Mail-Adresse und die Felder fest, die Ihr Herausforderungstyp benötigt, und speichern Sie die Einstellungen, bevor Sie ein Zertifikat anfordern.", + "request": "Zertifikat jetzt anfordern", + "requesting": "Zertifikat wird angefordert...", + "issued": "Zertifikat ausgestellt und installiert" } } diff --git a/plugins/acme-ssl/locales/translated/el_GR.json b/plugins/acme-ssl/locales/translated/el_GR.json index f05f2c3a2..0f29bcca3 100644 --- a/plugins/acme-ssl/locales/translated/el_GR.json +++ b/plugins/acme-ssl/locales/translated/el_GR.json @@ -1,17 +1,41 @@ { + "permissions": { + "manage": { + "title": "Διαχείριση πιστοποιητικών ACME", + "description": "Δείτε την κατάσταση του πιστοποιητικού και ζητήστε ένα νέο πιστοποιητικό τώρα." + } + }, "settings": { + "autoRenew": { + "label": "Αυτόματη ανανέωση", + "description": "Ελέγχετε δύο φορές την ημέρα και λαμβάνετε ένα νέο πιστοποιητικό όταν δεν υπάρχει, δεν καλύπτει τον τομέα ή λήγει εντός 30 ημερών." + }, "domain": { "label": "Πεδίο ορισμού", - "placeholder": "termix.example.com", - "description": "Το όνομα δημόσιου τομέα για το πιστοποιητικό." + "description": "Το όνομα δημόσιου τομέα για το πιστοποιητικό.", + "placeholder": "termix.example.com" }, "email": { "label": "E-mail", + "description": "Ηλεκτρονική διεύθυνση ηλεκτρονικού ταχυδρομείου επικοινωνίας για τον λογαριασμό ACME και τις ειδοποιήσεις λήξης.", "placeholder": "admin@example.com" }, + "provider": { + "label": "Αρχή έκδοσης πιστοποιητικών", + "description": "Πού να λάβετε το πιστοποιητικό. Χρησιμοποιήστε τη σταδιακή επεξεργασία για να δοκιμάσετε χωρίς να υπερβείτε τα όρια ρυθμού του Let's Encrypt.", + "letsencrypt": "Ας κρυπτογραφήσουμε", + "letsencryptStaging": "Ας κρυπτογραφήσουμε (σταδιοποίηση)", + "custom": "Προσαρμοσμένος κατάλογος ACME" + }, + "directoryUrl": { + "label": "URL καταλόγου ACME", + "description": "Μόνο για μια προσαρμοσμένη αρχή έκδοσης πιστοποιητικών. Πρέπει να είναι μια διεύθυνση URL https." + }, "challengeType": { "label": "Τύπος πρόκλησης", - "cloudflare": "DNS (Cloudflare) - απαιτεί διακριτικό API Cloudflare" + "description": "Πώς να αποδείξετε ότι είστε ο κάτοχος του domain.", + "http": "HTTP - χρειάζεται θύρα 80 προσβάσιμη από το διαδίκτυο", + "cloudflare": "DNS (Cloudflare) - χρειάζεται ένα διακριτικό API Cloudflare" }, "cloudflareToken": { "label": "Διακριτικό API Cloudflare", @@ -21,9 +45,14 @@ "status": { "title": "Κατάσταση πιστοποιητικού", "none": "Δεν υπάρχει πιστοποιητικό", + "names": "Καλύμματα {{names}}", + "issuer": "Εκδόθηκε από {{issuer}}", "expires": "Λήγει {{date}}", "lastIssued": "Τελευταία έκδοση {{date}}", - "request": "Έκδοση / Ανανέωση Πιστοποιητικού", - "requesting": "Αίτημα πιστοποιητικού..." + "lastError": "Η τελευταία προσπάθεια απέτυχε: {{error}}", + "missing": "Ορίστε τον τομέα, το email και τα πεδία που χρειάζεται ο τύπος της πρόκλησής σας και, στη συνέχεια, αποθηκεύστε το, πριν ζητήσετε πιστοποιητικό.", + "request": "Ζητήστε πιστοποιητικό τώρα", + "requesting": "Αίτημα πιστοποιητικού...", + "issued": "Έκδοση και εγκατάσταση πιστοποιητικού" } } diff --git a/plugins/acme-ssl/locales/translated/es_ES.json b/plugins/acme-ssl/locales/translated/es_ES.json index 026db9a97..16a863d76 100644 --- a/plugins/acme-ssl/locales/translated/es_ES.json +++ b/plugins/acme-ssl/locales/translated/es_ES.json @@ -1,17 +1,41 @@ { + "permissions": { + "manage": { + "title": "Gestionar certificados ACME", + "description": "Consulte el estado del certificado y solicite uno nuevo ahora." + } + }, "settings": { + "autoRenew": { + "label": "Renovación automática", + "description": "Compruebe dos veces al día y obtenga un nuevo certificado si no tiene ninguno, si no cubre el dominio o si caduca en los próximos 30 días." + }, "domain": { "label": "Dominio", - "placeholder": "termix.example.com", - "description": "El nombre de dominio público para el certificado." + "description": "El nombre de dominio público para el certificado.", + "placeholder": "termix.example.com" }, "email": { "label": "Correo electrónico", + "description": "Correo electrónico de contacto para la cuenta ACME y avisos de vencimiento.", "placeholder": "admin@example.com" }, + "provider": { + "label": "Autoridad de certificación", + "description": "Dónde obtener el certificado. Utilice el entorno de pruebas para realizar pruebas sin alcanzar los límites de uso de Let's Encrypt.", + "letsencrypt": "Let's Encrypt", + "letsencryptStaging": "Let's Encrypt (en fase de pruebas)", + "custom": "Directorio ACME personalizado" + }, + "directoryUrl": { + "label": "URL del directorio ACME", + "description": "Solo para una autoridad de certificación personalizada. Debe ser una URL HTTPS." + }, "challengeType": { "label": "Tipo de desafío", - "cloudflare": "DNS (Cloudflare) - requiere un token de API de Cloudflare" + "description": "Cómo demostrar que usted es el propietario del dominio.", + "http": "HTTP: necesita que el puerto 80 sea accesible desde Internet.", + "cloudflare": "DNS (Cloudflare): requiere un token de API de Cloudflare." }, "cloudflareToken": { "label": "Token de API de Cloudflare", @@ -21,9 +45,14 @@ "status": { "title": "Estado del certificado", "none": "Sin certificado", + "names": "Portadas {{names}}", + "issuer": "Emitido por {{issuer}}", "expires": "Caduca {{date}}", "lastIssued": "Última emisión {{date}}", - "request": "Emitir / Renovar certificado", - "requesting": "Solicitando certificado..." + "lastError": "Último intento fallido: {{error}}", + "missing": "Configure el dominio, el correo electrónico y los campos que requiere su tipo de desafío, luego guarde los cambios y, a continuación, solicite un certificado.", + "request": "Solicita tu certificado ahora", + "requesting": "Solicitando certificado...", + "issued": "Certificado emitido e instalado" } } diff --git a/plugins/acme-ssl/locales/translated/fi_FI.json b/plugins/acme-ssl/locales/translated/fi_FI.json index 4efc7187d..4fa05bdaa 100644 --- a/plugins/acme-ssl/locales/translated/fi_FI.json +++ b/plugins/acme-ssl/locales/translated/fi_FI.json @@ -1,29 +1,58 @@ { + "permissions": { + "manage": { + "title": "Hallinnoi ACME-sertifikaatteja", + "description": "Tarkista varmenteen tila ja pyydä uusi varmenne nyt." + } + }, "settings": { + "autoRenew": { + "label": "Uudista automaattisesti", + "description": "Tarkista kahdesti päivässä ja hanki uusi varmenne, jos sitä ei ole, se ei kata verkkotunnusta tai se vanhenee 30 päivän kuluessa." + }, "domain": { "label": "Verkkotunnus", - "placeholder": "termix.esimerkki.com", - "description": "Varmenteen julkinen verkkotunnus." + "description": "Varmenteen julkinen verkkotunnus.", + "placeholder": "termix.esimerkki.com" }, "email": { "label": "Sähköposti", + "description": "ACME-tilin yhteystiedot ja vanhenemisilmoitukset.", "placeholder": "admin@esimerkki.com" }, + "provider": { + "label": "Varmentaja", + "description": "Mistä varmenteen saa? Käytä testausympäristöä Let's Encrypt -nopeusrajoitusten ylittämättä.", + "letsencrypt": "Salataanpa", + "letsencryptStaging": "Let's Encrypt (vaiheistus)", + "custom": "Mukautettu ACME-hakemisto" + }, + "directoryUrl": { + "label": "ACME-hakemiston URL-osoite", + "description": "Vain mukautetulle varmentajalle. URL-osoitteen on oltava https." + }, "challengeType": { "label": "Haasteen tyyppi", + "description": "Kuinka todistaa omistavasi verkkotunnuksen.", + "http": "HTTP - vaatii portin 80, johon internetistä voi päästä käsiksi", "cloudflare": "DNS (Cloudflare) – vaatii Cloudflare API -tunnuksen" }, "cloudflareToken": { - "label": "Cloudflare API-tunnus", + "label": "Cloudflare API -tunnus", "description": "Laajuusaluetunnus, jolla on Zone:DNS:Edit-käyttöoikeus verkkotunnuksellesi." } }, "status": { "title": "Sertifikaatin tila", "none": "Ei todistusta", + "names": "Kannet {{names}}", + "issuer": "Myöntäjä {{issuer}}", "expires": "Vanhenee {{date}}", "lastIssued": "Viimeksi myönnetty {{date}}", - "request": "Myönnä / Uudista sertifikaatti", - "requesting": "Pyydetään varmennetta..." + "lastError": "Viimeisin yritys epäonnistui: {{error}}", + "missing": "Aseta verkkotunnus, sähköpostiosoite ja haastetyyppisi tarvitsemat kentät ja tallenna ne ennen varmenteen pyytämistä.", + "request": "Pyydä todistus nyt", + "requesting": "Pyydetään varmennetta...", + "issued": "Sertifikaatti myönnetty ja asennettu" } } diff --git a/plugins/acme-ssl/locales/translated/fr_FR.json b/plugins/acme-ssl/locales/translated/fr_FR.json index 12fc3d7aa..b54c8552a 100644 --- a/plugins/acme-ssl/locales/translated/fr_FR.json +++ b/plugins/acme-ssl/locales/translated/fr_FR.json @@ -1,29 +1,58 @@ { + "permissions": { + "manage": { + "title": "Gérer les certificats ACME", + "description": "Consultez l'état du certificat et demandez un nouveau certificat dès maintenant." + } + }, "settings": { + "autoRenew": { + "label": "Renouvellement automatique", + "description": "Vérifiez deux fois par jour et obtenez un nouveau certificat s'il n'y en a pas, s'il ne couvre pas le domaine ou s'il expire dans les 30 jours." + }, "domain": { "label": "Domaine", - "placeholder": "termix.example.com", - "description": "Le nom de domaine public pour le certificat." + "description": "Le nom de domaine public pour le certificat.", + "placeholder": "termix.example.com" }, "email": { "label": "E-mail", + "description": "Adresse électronique de contact pour le compte ACME et les avis d'expiration.", "placeholder": "admin@example.com" }, + "provider": { + "label": "Autorité de certification", + "description": "Où obtenir le certificat ? Utilisez un environnement de test pour effectuer des tests sans atteindre les limites de requêtes de Let's Encrypt.", + "letsencrypt": "Let's Encrypt", + "letsencryptStaging": "Let's Encrypt (phase de test)", + "custom": "Répertoire ACME personnalisé" + }, + "directoryUrl": { + "label": "URL du répertoire ACME", + "description": "Uniquement pour une autorité de certification personnalisée. Doit être une URL HTTPS." + }, "challengeType": { - "label": "Type de challenge", - "cloudflare": "DNS (Cloudflare) - nécessite un jeton API Cloudflare" + "label": "Type de défi", + "description": "Comment prouver que vous êtes propriétaire du domaine.", + "http": "HTTP – nécessite que le port 80 soit accessible depuis Internet", + "cloudflare": "DNS (Cloudflare) - nécessite un jeton d'API Cloudflare" }, "cloudflareToken": { - "label": "Jeton API Cloudflare", + "label": "Jeton d'API Cloudflare", "description": "Jeton limité avec l'autorisation Zone:DNS:Edit pour votre domaine." } }, "status": { "title": "Statut du certificat", "none": "Aucun certificat", + "names": "Couvertures {{names}}", + "issuer": "Émis par {{issuer}}", "expires": "Expire le {{date}}", "lastIssued": "Dernière émission le {{date}}", - "request": "Émettre / Renouveler le certificat", - "requesting": "Demande de certificat en cours..." + "lastError": "Dernière tentative échouée : {{error}}", + "missing": "Configurez le domaine, l'adresse e-mail et les champs requis par votre type de défi, puis enregistrez, avant de demander un certificat.", + "request": "Demandez votre certificat dès maintenant", + "requesting": "Demande de certificat en cours...", + "issued": "Certificat délivré et installé" } } diff --git a/plugins/acme-ssl/locales/translated/he_IL.json b/plugins/acme-ssl/locales/translated/he_IL.json index cdac7502d..fdbc2e9d6 100644 --- a/plugins/acme-ssl/locales/translated/he_IL.json +++ b/plugins/acme-ssl/locales/translated/he_IL.json @@ -1,16 +1,40 @@ { + "permissions": { + "manage": { + "title": "ניהול אישורי ACME", + "description": "ראה את סטטוס האישור ובקש אישור חדש כעת." + } + }, "settings": { + "autoRenew": { + "label": "חידוש אוטומטי", + "description": "בדקו פעמיים ביום וקבלו תעודה חדשה אם אין, אם היא לא מכסה את הדומיין, או אם היא פגה תוך 30 יום." + }, "domain": { "label": "תְחוּם", - "placeholder": "termix.example.com", - "description": "שם התחום הציבורי עבור התעודה." + "description": "שם התחום הציבורי עבור התעודה.", + "placeholder": "termix.example.com" }, "email": { "label": "אֶלֶקטרוֹנִי", + "description": "כתובת דוא\"ל ליצירת קשר עבור חשבון ACME והודעות תפוגה.", "placeholder": "admin@example.com" }, + "provider": { + "label": "רשות אישורים", + "description": "היכן ניתן להשיג את האישור. השתמשו ב-staging כדי לבדוק מבלי להגיע למגבלות התעריף של Let's Encrypt.", + "letsencrypt": "בואו נצפין", + "letsencryptStaging": "בואו נצפין (שלבי)", + "custom": "ספריית ACME מותאמת אישית" + }, + "directoryUrl": { + "label": "כתובת אתר של ספריית ACME", + "description": "רק עבור רשות אישורים מותאמת אישית. חייבת להיות כתובת URL מסוג https." + }, "challengeType": { "label": "סוג האתגר", + "description": "איך להוכיח שאתה הבעלים של הדומיין.", + "http": "HTTP - דורש גישה לפורט 80 מהאינטרנט", "cloudflare": "DNS (Cloudflare) - דורש אסימון API של Cloudflare" }, "cloudflareToken": { @@ -21,9 +45,14 @@ "status": { "title": "סטטוס התעודה", "none": "אין תעודה", + "names": "כריכות {{names}}", + "issuer": "הונפק על ידי {{issuer}}", "expires": "פג תוקף {{date}}", "lastIssued": "הוצאה אחרונה {{date}}", - "request": "הנפקה / חידוש תעודה", - "requesting": "מבקש תעודה..." + "lastError": "ניסיון אחרון נכשל: {{error}}", + "missing": "הגדר את הדומיין, האימייל והשדות הנדרשים עבור סוג האתגר שלך, ולאחר מכן שמור, לפני בקשת האישור.", + "request": "בקשת תעודה עכשיו", + "requesting": "מבקש תעודה...", + "issued": "תעודה הונפקה והותקנה" } } diff --git a/plugins/acme-ssl/locales/translated/hi_IN.json b/plugins/acme-ssl/locales/translated/hi_IN.json index ed1ec0219..774d505b9 100644 --- a/plugins/acme-ssl/locales/translated/hi_IN.json +++ b/plugins/acme-ssl/locales/translated/hi_IN.json @@ -1,29 +1,58 @@ { + "permissions": { + "manage": { + "title": "Manage ACME certificates", + "description": "See the certificate status and request a new certificate now." + } + }, "settings": { + "autoRenew": { + "label": "Renew automatically", + "description": "Check twice a day and get a new certificate when there is none, it does not cover the domain, or it expires within 30 days." + }, "domain": { "label": "डोमेन", - "placeholder": "termix.example.com", - "description": "प्रमाणपत्र के लिए सार्वजनिक डोमेन नाम।" + "description": "प्रमाणपत्र के लिए सार्वजनिक डोमेन नाम।", + "placeholder": "termix.example.com" }, "email": { "label": "ईमेल", + "description": "Contact email for the ACME account and expiry notices.", "placeholder": "admin@example.com" }, + "provider": { + "label": "प्रमाणपत्र प्राधिकरण", + "description": "Where to get the certificate. Use staging to test without hitting Let's Encrypt rate limits.", + "letsencrypt": "Let's Encrypt", + "letsencryptStaging": "Let's Encrypt (staging)", + "custom": "Custom ACME directory" + }, + "directoryUrl": { + "label": "ACME directory URL", + "description": "Only for a custom certificate authority. Must be an https URL." + }, "challengeType": { - "label": "चुनौती प्रकार", - "cloudflare": "DNS (Cloudflare) - Cloudflare API टोकन आवश्यक है" + "label": "Challenge type", + "description": "How to prove you own the domain.", + "http": "HTTP - needs port 80 reachable from the internet", + "cloudflare": "DNS (Cloudflare) - needs a Cloudflare API token" }, "cloudflareToken": { - "label": "Cloudflare API टोकन", + "label": "Cloudflare API token", "description": "आपके डोमेन के लिए Zone:DNS:Edit अनुमति वाला स्कोप्ड टोकन।" } }, "status": { - "title": "प्रमाणपत्र स्थिति", + "title": "Certificate status", "none": "कोई प्रमाणपत्र नहीं", + "names": "Covers {{names}}", + "issuer": "Issued by {{issuer}}", "expires": "{{date}} को समाप्त होगा", "lastIssued": "अंतिम जारी: {{date}}", - "request": "प्रमाणपत्र जारी करें / नवीनीकरण करें", - "requesting": "प्रमाणपत्र अनुरोध किया जा रहा है..." + "lastError": "Last attempt failed: {{error}}", + "missing": "Set the domain, email and the fields your challenge type needs, then save, before requesting a certificate.", + "request": "Request certificate now", + "requesting": "प्रमाणपत्र अनुरोध किया जा रहा है...", + "issued": "Certificate issued and installed" } } diff --git a/plugins/acme-ssl/locales/translated/hu_HU.json b/plugins/acme-ssl/locales/translated/hu_HU.json index 6d02ec417..1eb71c5b7 100644 --- a/plugins/acme-ssl/locales/translated/hu_HU.json +++ b/plugins/acme-ssl/locales/translated/hu_HU.json @@ -1,17 +1,41 @@ { + "permissions": { + "manage": { + "title": "ACME tanúsítványok kezelése", + "description": "Tekintse meg a tanúsítvány állapotát, és igényeljen új tanúsítványt most." + } + }, "settings": { + "autoRenew": { + "label": "Automatikus megújítás", + "description": "Naponta kétszer ellenőrizd, és szerezz be új tanúsítványt, ha nincs még tanúsítvány, ha nem fedi le a domaint, vagy ha 30 napon belül lejár." + }, "domain": { "label": "Domain", - "placeholder": "termix.example.com", - "description": "A tanúsítvány nyilvános domainneve." + "description": "A tanúsítvány nyilvános domainneve.", + "placeholder": "termix.example.com" }, "email": { "label": "Email", + "description": "Az ACME fiókkal és a lejárati értesítésekkel kapcsolatos elérhetőségi e-mail cím.", "placeholder": "admin@example.com" }, + "provider": { + "label": "Tanúsítványkibocsátó", + "description": "Hol lehet beszerezni a tanúsítványt? Használjon előzetes tesztelést a Let's Encrypt sebességkorlátainak elérése nélkül.", + "letsencrypt": "Titkosítsunk", + "letsencryptStaging": "Titkosítsuk (előkészítés)", + "custom": "Egyéni ACME címtár" + }, + "directoryUrl": { + "label": "ACME könyvtár URL-címe", + "description": "Csak egyéni hitelesítésszolgáltató esetén. Https URL-címnek kell lennie." + }, "challengeType": { "label": "Kihívás típusa", - "cloudflare": "DNS (Cloudflare) – Cloudflare API tokent igényel" + "description": "Hogyan bizonyíthatod, hogy te vagy a domain tulajdonosa?", + "http": "HTTP – internetről elérhető 80-as port szükséges", + "cloudflare": "DNS (Cloudflare) – Cloudflare API token szükséges" }, "cloudflareToken": { "label": "Cloudflare API token", @@ -21,9 +45,14 @@ "status": { "title": "Tanúsítvány állapota", "none": "Nincs tanúsítvány", + "names": "Borítók {{names}}", + "issuer": "Kibocsátó: {{issuer}}", "expires": "Lejár {{date}}", "lastIssued": "Utolsó kiadás {{date}}", - "request": "Tanúsítvány kiállítása / megújítása", - "requesting": "Tanúsítvány kérése..." + "lastError": "Utolsó kísérlet sikertelen: {{error}}", + "missing": "Állítsa be a domaint, az e-mail címet és a kihívástípushoz szükséges mezőket, majd mentse el a beállításokat a tanúsítvány igénylése előtt.", + "request": "Igényeljen tanúsítványt most", + "requesting": "Tanúsítvány kérése...", + "issued": "Tanúsítvány kiállítva és telepítve" } } diff --git a/plugins/acme-ssl/locales/translated/id_ID.json b/plugins/acme-ssl/locales/translated/id_ID.json index 809bc146f..5c0aaa55b 100644 --- a/plugins/acme-ssl/locales/translated/id_ID.json +++ b/plugins/acme-ssl/locales/translated/id_ID.json @@ -1,29 +1,58 @@ { + "permissions": { + "manage": { + "title": "Manage ACME certificates", + "description": "See the certificate status and request a new certificate now." + } + }, "settings": { + "autoRenew": { + "label": "Renew automatically", + "description": "Check twice a day and get a new certificate when there is none, it does not cover the domain, or it expires within 30 days." + }, "domain": { "label": "Domain", - "placeholder": "termix.example.com", - "description": "Nama domain publik untuk sertifikat tersebut." + "description": "The public domain name for the certificate.", + "placeholder": "termix.example.com" }, "email": { - "label": "E-mail", + "label": "Email", + "description": "Contact email for the ACME account and expiry notices.", "placeholder": "admin@example.com" }, + "provider": { + "label": "Certificate authority", + "description": "Where to get the certificate. Use staging to test without hitting Let's Encrypt rate limits.", + "letsencrypt": "Let's Encrypt", + "letsencryptStaging": "Let's Encrypt (staging)", + "custom": "Custom ACME directory" + }, + "directoryUrl": { + "label": "ACME directory URL", + "description": "Only for a custom certificate authority. Must be an https URL." + }, "challengeType": { - "label": "Jenis Tantangan", - "cloudflare": "DNS (Cloudflare) - memerlukan token API Cloudflare" + "label": "Challenge type", + "description": "How to prove you own the domain.", + "http": "HTTP - needs port 80 reachable from the internet", + "cloudflare": "DNS (Cloudflare) - needs a Cloudflare API token" }, "cloudflareToken": { - "label": "Token API Cloudflare", - "description": "Token terlingkup dengan izin Zone:DNS:Edit untuk domain Anda." + "label": "Cloudflare API token", + "description": "Scoped token with Zone:DNS:Edit permission for your domain." } }, "status": { - "title": "Status Sertifikat", - "none": "Tidak ada sertifikat", - "expires": "Berakhir {{date}}", - "lastIssued": "Terakhir diterbitkan {{date}}", - "request": "Menerbitkan/Memperpanjang Sertifikat", - "requesting": "Meminta sertifikat..." + "title": "Certificate status", + "none": "No certificate", + "names": "Covers {{names}}", + "issuer": "Issued by {{issuer}}", + "expires": "Expires {{date}}", + "lastIssued": "Last issued {{date}}", + "lastError": "Last attempt failed: {{error}}", + "missing": "Set the domain, email and the fields your challenge type needs, then save, before requesting a certificate.", + "request": "Request certificate now", + "requesting": "Requesting certificate...", + "issued": "Certificate issued and installed" } } diff --git a/plugins/acme-ssl/locales/translated/it_IT.json b/plugins/acme-ssl/locales/translated/it_IT.json index a1bddb487..8993ef364 100644 --- a/plugins/acme-ssl/locales/translated/it_IT.json +++ b/plugins/acme-ssl/locales/translated/it_IT.json @@ -1,29 +1,58 @@ { + "permissions": { + "manage": { + "title": "Gestire i certificati ACME", + "description": "Verifica lo stato del certificato e richiedine uno nuovo ora." + } + }, "settings": { + "autoRenew": { + "label": "Rinnovo automatico", + "description": "Controlla due volte al giorno e richiedi un nuovo certificato se non ne trovi uno, se non copre il dominio o se scade entro 30 giorni." + }, "domain": { "label": "Dominio", - "placeholder": "termix.example.com", - "description": "Il nome di dominio pubblico per il certificato." + "description": "Il nome di dominio pubblico per il certificato.", + "placeholder": "termix.example.com" }, "email": { "label": "Email", + "description": "Indirizzo email per contattare l'account ACME e per ricevere avvisi di scadenza.", "placeholder": "admin@example.com" }, + "provider": { + "label": "Autorità di certificazione", + "description": "Dove ottenere il certificato. Utilizza un ambiente di staging per effettuare dei test senza superare i limiti di frequenza di Let's Encrypt.", + "letsencrypt": "Let's Encrypt", + "letsencryptStaging": "Let's Encrypt (staging)", + "custom": "Elenco personalizzato ACME" + }, + "directoryUrl": { + "label": "URL della directory ACME", + "description": "Solo per un'autorità di certificazione personalizzata. Deve essere un URL HTTPS." + }, "challengeType": { - "label": "Tipo di challenge", - "cloudflare": "DNS (Cloudflare) - richiede un token API Cloudflare" + "label": "Tipo di sfida", + "description": "Come dimostrare di essere il proprietario del dominio.", + "http": "HTTP - richiede che la porta 80 sia raggiungibile da Internet", + "cloudflare": "DNS (Cloudflare) - richiede un token API di Cloudflare" }, "cloudflareToken": { - "label": "Token API Cloudflare", + "label": "Token API di Cloudflare", "description": "Token con autorizzazione Zone:DNS:Edit per il tuo dominio." } }, "status": { "title": "Stato del certificato", "none": "Nessun certificato", + "names": "Copertine {{names}}", + "issuer": "Emesso da {{issuer}}", "expires": "Scade il {{date}}", "lastIssued": "Ultimo rilascio il {{date}}", - "request": "Emetti / Rinnova certificato", - "requesting": "Richiesta certificato in corso..." + "lastError": "Ultimo tentativo fallito: {{error}}", + "missing": "Imposta il dominio, l'indirizzo email e i campi richiesti dal tuo tipo di sfida, quindi salva prima di richiedere un certificato.", + "request": "Richiedi subito il certificato", + "requesting": "Richiesta certificato in corso...", + "issued": "Certificato rilasciato e installato" } } diff --git a/plugins/acme-ssl/locales/translated/ja_JP.json b/plugins/acme-ssl/locales/translated/ja_JP.json index e1f65ed9c..668b8c0cf 100644 --- a/plugins/acme-ssl/locales/translated/ja_JP.json +++ b/plugins/acme-ssl/locales/translated/ja_JP.json @@ -1,17 +1,41 @@ { + "permissions": { + "manage": { + "title": "ACME証明書を管理する", + "description": "証明書のステータスを確認し、新しい証明書を今すぐリクエストしてください。" + } + }, "settings": { + "autoRenew": { + "label": "自動更新", + "description": "1日に2回確認し、証明書がない場合、ドメインをカバーしていない場合、または有効期限が30日以内に切れる場合は、新しい証明書を取得してください。" + }, "domain": { "label": "ドメイン", - "placeholder": "termix.example.com", - "description": "証明書の公開ドメイン名。" + "description": "証明書の公開ドメイン名。", + "placeholder": "termix.example.com" }, "email": { "label": "メールアドレス", + "description": "ACMEアカウントおよび有効期限通知に関する連絡先メールアドレス。", "placeholder": "admin@example.com" }, + "provider": { + "label": "認証局", + "description": "証明書の入手方法。Let's Encryptのレート制限に抵触しないよう、ステージング環境を使用してテストしてください。", + "letsencrypt": "レッツ・エンクリプト", + "letsencryptStaging": "Let's Encrypt(ステージング環境)", + "custom": "カスタムACMEディレクトリ" + }, + "directoryUrl": { + "label": "ACMEディレクトリURL", + "description": "カスタム認証局のみ対象です。URLはhttpsでなければなりません。" + }, "challengeType": { - "label": "チャレンジタイプ", - "cloudflare": "DNS(Cloudflare)- Cloudflare APIトークンが必要です" + "label": "チャレンジの種類", + "description": "ドメインの所有権を証明する方法。", + "http": "HTTP - インターネットからアクセス可能なポート80が必要です", + "cloudflare": "DNS(Cloudflare) - Cloudflare APIトークンが必要です" }, "cloudflareToken": { "label": "Cloudflare APIトークン", @@ -19,11 +43,16 @@ } }, "status": { - "title": "証明書ステータス", + "title": "証明書のステータス", "none": "証明書なし", + "names": "カバー {{names}}", + "issuer": "{{issuer}} によって発行されました", "expires": "有効期限 {{date}}", "lastIssued": "最終発行日 {{date}}", - "request": "証明書を発行/更新", - "requesting": "証明書をリクエスト中..." + "lastError": "最後の試行が失敗しました: {{error}}", + "missing": "証明書をリクエストする前に、ドメイン、メールアドレス、およびチャレンジタイプに必要なフィールドを設定して保存してください。", + "request": "今すぐ証明書を申請する", + "requesting": "証明書をリクエスト中...", + "issued": "証明書が発行され、インストールされました。" } } diff --git a/plugins/acme-ssl/locales/translated/ko_KR.json b/plugins/acme-ssl/locales/translated/ko_KR.json index 98789500e..3e5d9ed89 100644 --- a/plugins/acme-ssl/locales/translated/ko_KR.json +++ b/plugins/acme-ssl/locales/translated/ko_KR.json @@ -1,29 +1,58 @@ { + "permissions": { + "manage": { + "title": "ACME 인증서를 관리하세요", + "description": "인증서 상태를 확인하고 지금 바로 새 인증서를 신청하세요." + } + }, "settings": { + "autoRenew": { + "label": "자동으로 갱신됩니다", + "description": "하루에 두 번 확인하고, 인증서가 없거나, 도메인을 포함하지 않거나, 30일 이내에 만료되는 경우 새 인증서를 발급받으세요." + }, "domain": { "label": "도메인", - "placeholder": "termix.example.com", - "description": "인증서에 사용할 공개 도메인 이름입니다." + "description": "인증서에 사용할 공개 도메인 이름입니다.", + "placeholder": "termix.example.com" }, "email": { "label": "이메일", + "description": "ACME 계정 및 만료 알림을 받을 수 있는 이메일 주소입니다.", "placeholder": "admin@example.com" }, + "provider": { + "label": "인증 기관", + "description": "인증서는 어디서 발급받나요? Let's Encrypt의 사용량 제한에 걸리지 않고 테스트하려면 스테이징 환경을 사용하세요.", + "letsencrypt": "렛츠인크립트", + "letsencryptStaging": "렛츠인크립트(스테이징)", + "custom": "사용자 지정 ACME 디렉토리" + }, + "directoryUrl": { + "label": "ACME 디렉토리 URL", + "description": "사용자 지정 인증 기관에만 해당됩니다. URL은 HTTPS여야 합니다." + }, "challengeType": { - "label": "인증 방식", - "cloudflare": "DNS(Cloudflare) - Cloudflare API 토큰 필요" + "label": "도전 유형", + "description": "도메인 소유권을 증명하는 방법.", + "http": "HTTP - 인터넷에서 접근 가능한 80번 포트가 필요합니다.", + "cloudflare": "DNS(클라우드플레어) - 클라우드플레어 API 토큰이 필요합니다." }, "cloudflareToken": { - "label": "Cloudflare API 토큰", + "label": "클라우드플레어 API 토큰", "description": "도메인에 대한 Zone:DNS:Edit 권한이 있는 범위 지정 토큰입니다." } }, "status": { "title": "인증서 상태", "none": "인증서 없음", + "names": "{{names}}을 덮습니다.", + "issuer": "{{issuer}}에서 발행함", "expires": "만료일: {{date}}", "lastIssued": "마지막 발급일: {{date}}", - "request": "인증서 발급 / 갱신", - "requesting": "인증서 요청 중..." + "lastError": "마지막 시도가 실패했습니다: {{error}}", + "missing": "인증서를 요청하기 전에 도메인, 이메일 및 인증 유형에 필요한 필드를 설정하고 저장하세요.", + "request": "지금 인증서를 요청하세요", + "requesting": "인증서 요청 중...", + "issued": "인증서가 발급 및 설치되었습니다." } } diff --git a/plugins/acme-ssl/locales/translated/nl_NL.json b/plugins/acme-ssl/locales/translated/nl_NL.json index 03587b9c6..bd5230214 100644 --- a/plugins/acme-ssl/locales/translated/nl_NL.json +++ b/plugins/acme-ssl/locales/translated/nl_NL.json @@ -1,16 +1,40 @@ { + "permissions": { + "manage": { + "title": "Beheer ACME-certificaten", + "description": "Bekijk de certificaatstatus en vraag nu een nieuw certificaat aan." + } + }, "settings": { + "autoRenew": { + "label": "Automatisch verlengen", + "description": "Controleer tweemaal per dag en vraag een nieuw certificaat aan als er geen certificaat is, het huidige certificaat het domein niet dekt of het huidige certificaat binnen 30 dagen verloopt." + }, "domain": { "label": "Domein", - "placeholder": "termix.example.com", - "description": "De publieke domeinnaam voor het certificaat." + "description": "De publieke domeinnaam voor het certificaat.", + "placeholder": "termix.example.com" }, "email": { "label": "E-mail", + "description": "Contact-e-mailadres voor het ACME-account en meldingen over vervaldatums.", "placeholder": "admin@example.com" }, + "provider": { + "label": "Certificeringsinstantie", + "description": "Waar kan ik het certificaat verkrijgen? Gebruik een testomgeving om te testen zonder de limieten van Let's Encrypt te overschrijden.", + "letsencrypt": "Let's Encrypt", + "letsencryptStaging": "Let's Encrypt (testomgeving)", + "custom": "Aangepaste ACME-directory" + }, + "directoryUrl": { + "label": "ACME-directory-URL", + "description": "Alleen voor een aangepaste certificeringsinstantie. Moet een https-URL zijn." + }, "challengeType": { "label": "Uitdagingstype", + "description": "Hoe bewijs je dat je de domeinnaam bezit?", + "http": "HTTP - vereist poort 80 die bereikbaar is vanaf internet.", "cloudflare": "DNS (Cloudflare) - vereist een Cloudflare API-token" }, "cloudflareToken": { @@ -21,9 +45,14 @@ "status": { "title": "Certificaatstatus", "none": "Geen certificaat", + "names": "Omslagen {{names}}", + "issuer": "Uitgegeven door {{issuer}}", "expires": "Verloopt {{date}}", "lastIssued": "Laatst uitgegeven {{date}}", - "request": "Certificaat aanvragen/verlengen", - "requesting": "Certificaat aanvragen..." + "lastError": "Laatste poging mislukt: {{error}}", + "missing": "Stel het domein, het e-mailadres en de velden in die uw uitdagingstype vereist, sla de wijzigingen op en vraag vervolgens een certificaat aan.", + "request": "Vraag nu uw certificaat aan", + "requesting": "Certificaat aanvragen...", + "issued": "Certificaat afgegeven en geïnstalleerd" } } diff --git a/plugins/acme-ssl/locales/translated/no_NO.json b/plugins/acme-ssl/locales/translated/no_NO.json index 9a98f175e..158b763a8 100644 --- a/plugins/acme-ssl/locales/translated/no_NO.json +++ b/plugins/acme-ssl/locales/translated/no_NO.json @@ -1,29 +1,58 @@ { + "permissions": { + "manage": { + "title": "Manage ACME certificates", + "description": "See the certificate status and request a new certificate now." + } + }, "settings": { + "autoRenew": { + "label": "Renew automatically", + "description": "Check twice a day and get a new certificate when there is none, it does not cover the domain, or it expires within 30 days." + }, "domain": { - "label": "Domene", - "placeholder": "termix.example.com", - "description": "Det offentlige domenenavnet for sertifikatet." + "label": "Domain", + "description": "The public domain name for the certificate.", + "placeholder": "termix.example.com" }, "email": { "label": "E-post", + "description": "Contact email for the ACME account and expiry notices.", "placeholder": "admin@example.com" }, + "provider": { + "label": "Certificate authority", + "description": "Where to get the certificate. Use staging to test without hitting Let's Encrypt rate limits.", + "letsencrypt": "Let's Encrypt", + "letsencryptStaging": "Let's Encrypt (staging)", + "custom": "Custom ACME directory" + }, + "directoryUrl": { + "label": "ACME directory URL", + "description": "Only for a custom certificate authority. Must be an https URL." + }, "challengeType": { - "label": "Utfordringstype", - "cloudflare": "DNS (Cloudflare) – krever et Cloudflare API-token" + "label": "Challenge type", + "description": "How to prove you own the domain.", + "http": "HTTP - needs port 80 reachable from the internet", + "cloudflare": "DNS (Cloudflare) - needs a Cloudflare API token" }, "cloudflareToken": { - "label": "Cloudflare API-token", - "description": "Scope-token med Zone:DNS:Rediger-tillatelse for domenet ditt." + "label": "Cloudflare API token", + "description": "Scoped token with Zone:DNS:Edit permission for your domain." } }, "status": { - "title": "Sertifikatstatus", - "none": "Ingen sertifikat", - "expires": "Utløper {{date}}", - "lastIssued": "Sist utstedt {{date}}", - "request": "Utstede/fornye sertifikat", - "requesting": "Be om sertifikat..." + "title": "Certificate status", + "none": "No certificate", + "names": "Covers {{names}}", + "issuer": "Issued by {{issuer}}", + "expires": "Expires {{date}}", + "lastIssued": "Last issued {{date}}", + "lastError": "Last attempt failed: {{error}}", + "missing": "Set the domain, email and the fields your challenge type needs, then save, before requesting a certificate.", + "request": "Request certificate now", + "requesting": "Requesting certificate...", + "issued": "Certificate issued and installed" } } diff --git a/plugins/acme-ssl/locales/translated/pl_PL.json b/plugins/acme-ssl/locales/translated/pl_PL.json index 8da4f3301..6d01a8b64 100644 --- a/plugins/acme-ssl/locales/translated/pl_PL.json +++ b/plugins/acme-ssl/locales/translated/pl_PL.json @@ -1,29 +1,58 @@ { + "permissions": { + "manage": { + "title": "Manage ACME certificates", + "description": "See the certificate status and request a new certificate now." + } + }, "settings": { + "autoRenew": { + "label": "Renew automatically", + "description": "Check twice a day and get a new certificate when there is none, it does not cover the domain, or it expires within 30 days." + }, "domain": { "label": "Domena", - "placeholder": "termix.example.com", - "description": "Publiczna nazwa domeny certyfikatu." + "description": "Publiczna nazwa domeny certyfikatu.", + "placeholder": "termix.example.com" }, "email": { "label": "E-mail", + "description": "Contact email for the ACME account and expiry notices.", "placeholder": "admin@example.com" }, + "provider": { + "label": "Urząd certyfikacji (CA)", + "description": "Where to get the certificate. Use staging to test without hitting Let's Encrypt rate limits.", + "letsencrypt": "Let's Encrypt", + "letsencryptStaging": "Let's Encrypt (staging)", + "custom": "Custom ACME directory" + }, + "directoryUrl": { + "label": "ACME directory URL", + "description": "Only for a custom certificate authority. Must be an https URL." + }, "challengeType": { - "label": "Typ wyzwania", - "cloudflare": "DNS (Cloudflare) - wymaga tokenu API Cloudflare" + "label": "Challenge type", + "description": "How to prove you own the domain.", + "http": "HTTP - needs port 80 reachable from the internet", + "cloudflare": "DNS (Cloudflare) - needs a Cloudflare API token" }, "cloudflareToken": { - "label": "Token API Cloudflare", + "label": "Cloudflare API token", "description": "Token zakresowy z uprawnieniem Zone:DNS:Edit dla Twojej domeny." } }, "status": { - "title": "Status certyfikatu", + "title": "Certificate status", "none": "Brak certyfikatu", + "names": "Covers {{names}}", + "issuer": "Issued by {{issuer}}", "expires": "Wygasa {{date}}", "lastIssued": "Ostatnio wystawiono {{date}}", - "request": "Wystaw / odnów certyfikat", - "requesting": "Żądanie certyfikatu..." + "lastError": "Last attempt failed: {{error}}", + "missing": "Set the domain, email and the fields your challenge type needs, then save, before requesting a certificate.", + "request": "Request certificate now", + "requesting": "Żądanie certyfikatu...", + "issued": "Certificate issued and installed" } } diff --git a/plugins/acme-ssl/locales/translated/pt_BR.json b/plugins/acme-ssl/locales/translated/pt_BR.json index 0006b239b..5c0aaa55b 100644 --- a/plugins/acme-ssl/locales/translated/pt_BR.json +++ b/plugins/acme-ssl/locales/translated/pt_BR.json @@ -1,29 +1,58 @@ { + "permissions": { + "manage": { + "title": "Manage ACME certificates", + "description": "See the certificate status and request a new certificate now." + } + }, "settings": { + "autoRenew": { + "label": "Renew automatically", + "description": "Check twice a day and get a new certificate when there is none, it does not cover the domain, or it expires within 30 days." + }, "domain": { - "label": "Domínio", - "placeholder": "termix.example.com", - "description": "O nome de domínio público do certificado." + "label": "Domain", + "description": "The public domain name for the certificate.", + "placeholder": "termix.example.com" }, "email": { - "label": "E-mail", + "label": "Email", + "description": "Contact email for the ACME account and expiry notices.", "placeholder": "admin@example.com" }, + "provider": { + "label": "Certificate authority", + "description": "Where to get the certificate. Use staging to test without hitting Let's Encrypt rate limits.", + "letsencrypt": "Let's Encrypt", + "letsencryptStaging": "Let's Encrypt (staging)", + "custom": "Custom ACME directory" + }, + "directoryUrl": { + "label": "ACME directory URL", + "description": "Only for a custom certificate authority. Must be an https URL." + }, "challengeType": { - "label": "Tipo de desafio", - "cloudflare": "DNS (Cloudflare) - requer um token de API do Cloudflare" + "label": "Challenge type", + "description": "How to prove you own the domain.", + "http": "HTTP - needs port 80 reachable from the internet", + "cloudflare": "DNS (Cloudflare) - needs a Cloudflare API token" }, "cloudflareToken": { - "label": "Token da API do Cloudflare", - "description": "Token com escopo definido e permissão Zone:DNS:Edit para o seu domínio." + "label": "Cloudflare API token", + "description": "Scoped token with Zone:DNS:Edit permission for your domain." } }, "status": { - "title": "Status do certificado", - "none": "Sem certificado", - "expires": "Expira em {{date}}", - "lastIssued": "Última edição {{date}}", - "request": "Emitir/Renovar Certificado", - "requesting": "Solicitar certificado..." + "title": "Certificate status", + "none": "No certificate", + "names": "Covers {{names}}", + "issuer": "Issued by {{issuer}}", + "expires": "Expires {{date}}", + "lastIssued": "Last issued {{date}}", + "lastError": "Last attempt failed: {{error}}", + "missing": "Set the domain, email and the fields your challenge type needs, then save, before requesting a certificate.", + "request": "Request certificate now", + "requesting": "Requesting certificate...", + "issued": "Certificate issued and installed" } } diff --git a/plugins/acme-ssl/locales/translated/pt_PT.json b/plugins/acme-ssl/locales/translated/pt_PT.json index e1381cad6..103eded8b 100644 --- a/plugins/acme-ssl/locales/translated/pt_PT.json +++ b/plugins/acme-ssl/locales/translated/pt_PT.json @@ -1,29 +1,58 @@ { + "permissions": { + "manage": { + "title": "Manage ACME certificates", + "description": "See the certificate status and request a new certificate now." + } + }, "settings": { + "autoRenew": { + "label": "Renew automatically", + "description": "Check twice a day and get a new certificate when there is none, it does not cover the domain, or it expires within 30 days." + }, "domain": { "label": "Domínio", - "placeholder": "termix.example.com", - "description": "O nome de domínio público para o certificado." + "description": "O nome de domínio público para o certificado.", + "placeholder": "termix.example.com" }, "email": { "label": "E-mail", + "description": "Contact email for the ACME account and expiry notices.", "placeholder": "admin@example.com" }, + "provider": { + "label": "Autoridade de certificação", + "description": "Where to get the certificate. Use staging to test without hitting Let's Encrypt rate limits.", + "letsencrypt": "Let's Encrypt", + "letsencryptStaging": "Let's Encrypt (staging)", + "custom": "Custom ACME directory" + }, + "directoryUrl": { + "label": "ACME directory URL", + "description": "Only for a custom certificate authority. Must be an https URL." + }, "challengeType": { - "label": "Tipo de desafio", - "cloudflare": "DNS (Cloudflare) - requer um token de API da Cloudflare" + "label": "Challenge type", + "description": "How to prove you own the domain.", + "http": "HTTP - needs port 80 reachable from the internet", + "cloudflare": "DNS (Cloudflare) - needs a Cloudflare API token" }, "cloudflareToken": { - "label": "Token de API da Cloudflare", + "label": "Cloudflare API token", "description": "Token com âmbito e permissão Zone:DNS:Edit para o seu domínio." } }, "status": { - "title": "Estado do certificado", + "title": "Certificate status", "none": "Sem certificado", + "names": "Covers {{names}}", + "issuer": "Issued by {{issuer}}", "expires": "Expira a {{date}}", "lastIssued": "Última emissão a {{date}}", - "request": "Emitir / Renovar certificado", - "requesting": "A solicitar certificado..." + "lastError": "Last attempt failed: {{error}}", + "missing": "Set the domain, email and the fields your challenge type needs, then save, before requesting a certificate.", + "request": "Request certificate now", + "requesting": "A solicitar certificado...", + "issued": "Certificate issued and installed" } } diff --git a/plugins/acme-ssl/locales/translated/ro_RO.json b/plugins/acme-ssl/locales/translated/ro_RO.json index fb081884c..99b2c3151 100644 --- a/plugins/acme-ssl/locales/translated/ro_RO.json +++ b/plugins/acme-ssl/locales/translated/ro_RO.json @@ -1,16 +1,40 @@ { + "permissions": { + "manage": { + "title": "Gestionați certificatele ACME", + "description": "Vedeți starea certificatului și solicitați un certificat nou acum." + } + }, "settings": { + "autoRenew": { + "label": "Reînnoire automată", + "description": "Verificați de două ori pe zi și obțineți un certificat nou atunci când nu există, nu acoperă domeniul sau expiră în termen de 30 de zile." + }, "domain": { "label": "Domeniu", - "placeholder": "termix.example.com", - "description": "Numele de domeniu public pentru certificat." + "description": "Numele de domeniu public pentru certificat.", + "placeholder": "termix.example.com" }, "email": { "label": "E-mail", + "description": "Adresă de e-mail de contact pentru contul ACME și notificări de expirare.", "placeholder": "admin@example.com" }, + "provider": { + "label": "Autoritatea de certificare", + "description": "Unde se obține certificatul. Folosește staging-ul pentru a testa fără a atinge limitele de rată Let's Encrypt.", + "letsencrypt": "Să criptăm", + "letsencryptStaging": "Să criptăm (punct în scenă)", + "custom": "Director ACME personalizat" + }, + "directoryUrl": { + "label": "URL-ul directorului ACME", + "description": "Numai pentru o autoritate de certificare personalizată. Trebuie să fie o adresă URL https." + }, "challengeType": { - "label": "Tipul provocării", + "label": "Tipul de provocare", + "description": "Cum să dovedești că deții domeniul.", + "http": "HTTP - necesită ca portul 80 să fie accesibil de pe internet", "cloudflare": "DNS (Cloudflare) - necesită un token API Cloudflare" }, "cloudflareToken": { @@ -21,9 +45,14 @@ "status": { "title": "Starea certificatului", "none": "Fără certificat", + "names": "Acoperă {{names}}", + "issuer": "Emis de {{issuer}}", "expires": "Expiră la {{date}}", "lastIssued": "Ultima emisiune {{date}}", - "request": "Emitere / Reînnoire certificat", - "requesting": "Se solicită certificatul..." + "lastError": "Ultima încercare a eșuat: {{error}}", + "missing": "Setați domeniul, adresa de e-mail și câmpurile necesare tipului dvs. de provocare, apoi salvați, înainte de a solicita un certificat.", + "request": "Solicitați certificatul acum", + "requesting": "Se solicită certificatul...", + "issued": "Certificat emis și instalat" } } diff --git a/plugins/acme-ssl/locales/translated/ru_RU.json b/plugins/acme-ssl/locales/translated/ru_RU.json index 9f6b02d22..a398a4fdd 100644 --- a/plugins/acme-ssl/locales/translated/ru_RU.json +++ b/plugins/acme-ssl/locales/translated/ru_RU.json @@ -1,29 +1,58 @@ { + "permissions": { + "manage": { + "title": "Manage ACME certificates", + "description": "See the certificate status and request a new certificate now." + } + }, "settings": { + "autoRenew": { + "label": "Renew automatically", + "description": "Check twice a day and get a new certificate when there is none, it does not cover the domain, or it expires within 30 days." + }, "domain": { "label": "Домен", - "placeholder": "termix.example.com", - "description": "Общедоступное доменное имя для сертификата." + "description": "Общедоступное доменное имя для сертификата.", + "placeholder": "termix.example.com" }, "email": { "label": "Email", + "description": "Contact email for the ACME account and expiry notices.", "placeholder": "admin@example.com" }, + "provider": { + "label": "Центр сертификации", + "description": "Where to get the certificate. Use staging to test without hitting Let's Encrypt rate limits.", + "letsencrypt": "Let's Encrypt", + "letsencryptStaging": "Let's Encrypt (staging)", + "custom": "Custom ACME directory" + }, + "directoryUrl": { + "label": "ACME directory URL", + "description": "Only for a custom certificate authority. Must be an https URL." + }, "challengeType": { - "label": "Тип проверки", - "cloudflare": "DNS (Cloudflare) — требуется API-токен Cloudflare" + "label": "Challenge type", + "description": "How to prove you own the domain.", + "http": "HTTP - needs port 80 reachable from the internet", + "cloudflare": "DNS (Cloudflare) - needs a Cloudflare API token" }, "cloudflareToken": { - "label": "API-токен Cloudflare", + "label": "Cloudflare API token", "description": "Токен с ограниченной областью действия и разрешением Zone:DNS:Edit для вашего домена." } }, "status": { - "title": "Статус сертификата", + "title": "Certificate status", "none": "Сертификат отсутствует", + "names": "Covers {{names}}", + "issuer": "Issued by {{issuer}}", "expires": "Истекает {{date}}", "lastIssued": "Последний выпуск {{date}}", - "request": "Выпустить / Обновить сертификат", - "requesting": "Запрос сертификата..." + "lastError": "Last attempt failed: {{error}}", + "missing": "Set the domain, email and the fields your challenge type needs, then save, before requesting a certificate.", + "request": "Request certificate now", + "requesting": "Запрос сертификата...", + "issued": "Certificate issued and installed" } } diff --git a/plugins/acme-ssl/locales/translated/sr_SP.json b/plugins/acme-ssl/locales/translated/sr_SP.json index 126cf510a..5c0aaa55b 100644 --- a/plugins/acme-ssl/locales/translated/sr_SP.json +++ b/plugins/acme-ssl/locales/translated/sr_SP.json @@ -1,29 +1,58 @@ { + "permissions": { + "manage": { + "title": "Manage ACME certificates", + "description": "See the certificate status and request a new certificate now." + } + }, "settings": { + "autoRenew": { + "label": "Renew automatically", + "description": "Check twice a day and get a new certificate when there is none, it does not cover the domain, or it expires within 30 days." + }, "domain": { - "label": "Домен", - "placeholder": "termix.example.com", - "description": "Јавно име домена за сертификат." + "label": "Domain", + "description": "The public domain name for the certificate.", + "placeholder": "termix.example.com" }, "email": { - "label": "Е-пошта", + "label": "Email", + "description": "Contact email for the ACME account and expiry notices.", "placeholder": "admin@example.com" }, + "provider": { + "label": "Certificate authority", + "description": "Where to get the certificate. Use staging to test without hitting Let's Encrypt rate limits.", + "letsencrypt": "Let's Encrypt", + "letsencryptStaging": "Let's Encrypt (staging)", + "custom": "Custom ACME directory" + }, + "directoryUrl": { + "label": "ACME directory URL", + "description": "Only for a custom certificate authority. Must be an https URL." + }, "challengeType": { - "label": "Тип изазова", - "cloudflare": "DNS (Cloudflare) - захтева Cloudflare API токен" + "label": "Challenge type", + "description": "How to prove you own the domain.", + "http": "HTTP - needs port 80 reachable from the internet", + "cloudflare": "DNS (Cloudflare) - needs a Cloudflare API token" }, "cloudflareToken": { - "label": "Клаудфлејр АПИ токен", - "description": "Ограничени токен са дозволом Zone:DNS:Edit за ваш домен." + "label": "Cloudflare API token", + "description": "Scoped token with Zone:DNS:Edit permission for your domain." } }, "status": { - "title": "Статус сертификата", - "none": "Без сертификата", - "expires": "Истиче {{date}}", - "lastIssued": "Последње издање {{date}}", - "request": "Издавање / обнављање сертификата", - "requesting": "Захтева се сертификат..." + "title": "Certificate status", + "none": "No certificate", + "names": "Covers {{names}}", + "issuer": "Issued by {{issuer}}", + "expires": "Expires {{date}}", + "lastIssued": "Last issued {{date}}", + "lastError": "Last attempt failed: {{error}}", + "missing": "Set the domain, email and the fields your challenge type needs, then save, before requesting a certificate.", + "request": "Request certificate now", + "requesting": "Requesting certificate...", + "issued": "Certificate issued and installed" } } diff --git a/plugins/acme-ssl/locales/translated/sv_SE.json b/plugins/acme-ssl/locales/translated/sv_SE.json index 4a7e50ac4..5c0aaa55b 100644 --- a/plugins/acme-ssl/locales/translated/sv_SE.json +++ b/plugins/acme-ssl/locales/translated/sv_SE.json @@ -1,29 +1,58 @@ { + "permissions": { + "manage": { + "title": "Manage ACME certificates", + "description": "See the certificate status and request a new certificate now." + } + }, "settings": { + "autoRenew": { + "label": "Renew automatically", + "description": "Check twice a day and get a new certificate when there is none, it does not cover the domain, or it expires within 30 days." + }, "domain": { - "label": "Domän", - "placeholder": "termix.example.com", - "description": "Det offentliga domännamnet för certifikatet." + "label": "Domain", + "description": "The public domain name for the certificate.", + "placeholder": "termix.example.com" }, "email": { - "label": "E-post", + "label": "Email", + "description": "Contact email for the ACME account and expiry notices.", "placeholder": "admin@example.com" }, + "provider": { + "label": "Certificate authority", + "description": "Where to get the certificate. Use staging to test without hitting Let's Encrypt rate limits.", + "letsencrypt": "Let's Encrypt", + "letsencryptStaging": "Let's Encrypt (staging)", + "custom": "Custom ACME directory" + }, + "directoryUrl": { + "label": "ACME directory URL", + "description": "Only for a custom certificate authority. Must be an https URL." + }, "challengeType": { - "label": "Utmaningstyp", - "cloudflare": "DNS (Cloudflare) – kräver en Cloudflare API-token" + "label": "Challenge type", + "description": "How to prove you own the domain.", + "http": "HTTP - needs port 80 reachable from the internet", + "cloudflare": "DNS (Cloudflare) - needs a Cloudflare API token" }, "cloudflareToken": { - "label": "Cloudflare API-token", - "description": "Scoped-token med Zone:DNS:Edit-behörighet för din domän." + "label": "Cloudflare API token", + "description": "Scoped token with Zone:DNS:Edit permission for your domain." } }, "status": { - "title": "Certifikatstatus", - "none": "Inget certifikat", - "expires": "Utgångsdatum {{date}}", - "lastIssued": "Senast utfärdad {{date}}", - "request": "Utfärda/förnya certifikat", - "requesting": "Begär certifikat..." + "title": "Certificate status", + "none": "No certificate", + "names": "Covers {{names}}", + "issuer": "Issued by {{issuer}}", + "expires": "Expires {{date}}", + "lastIssued": "Last issued {{date}}", + "lastError": "Last attempt failed: {{error}}", + "missing": "Set the domain, email and the fields your challenge type needs, then save, before requesting a certificate.", + "request": "Request certificate now", + "requesting": "Requesting certificate...", + "issued": "Certificate issued and installed" } } diff --git a/plugins/acme-ssl/locales/translated/th_TH.json b/plugins/acme-ssl/locales/translated/th_TH.json index 11cc7ca05..5c0aaa55b 100644 --- a/plugins/acme-ssl/locales/translated/th_TH.json +++ b/plugins/acme-ssl/locales/translated/th_TH.json @@ -1,29 +1,58 @@ { + "permissions": { + "manage": { + "title": "Manage ACME certificates", + "description": "See the certificate status and request a new certificate now." + } + }, "settings": { + "autoRenew": { + "label": "Renew automatically", + "description": "Check twice a day and get a new certificate when there is none, it does not cover the domain, or it expires within 30 days." + }, "domain": { - "label": "โดเมน", - "placeholder": "เทอร์มิกซ์.ตัวอย่าง.com", - "description": "ชื่อโดเมนสาธารณะสำหรับใบรับรอง" + "label": "Domain", + "description": "The public domain name for the certificate.", + "placeholder": "termix.example.com" }, "email": { - "label": "อีเมล", + "label": "Email", + "description": "Contact email for the ACME account and expiry notices.", "placeholder": "admin@example.com" }, + "provider": { + "label": "Certificate authority", + "description": "Where to get the certificate. Use staging to test without hitting Let's Encrypt rate limits.", + "letsencrypt": "Let's Encrypt", + "letsencryptStaging": "Let's Encrypt (staging)", + "custom": "Custom ACME directory" + }, + "directoryUrl": { + "label": "ACME directory URL", + "description": "Only for a custom certificate authority. Must be an https URL." + }, "challengeType": { - "label": "ประเภทความท้าทาย", - "cloudflare": "DNS (Cloudflare) - ต้องใช้โทเค็น API ของ Cloudflare" + "label": "Challenge type", + "description": "How to prove you own the domain.", + "http": "HTTP - needs port 80 reachable from the internet", + "cloudflare": "DNS (Cloudflare) - needs a Cloudflare API token" }, "cloudflareToken": { - "label": "โทเค็น API ของ Cloudflare", - "description": "โทเค็นแบบจำกัดขอบเขตพร้อมสิทธิ์ Zone:DNS:Edit สำหรับโดเมนของคุณ" + "label": "Cloudflare API token", + "description": "Scoped token with Zone:DNS:Edit permission for your domain." } }, "status": { - "title": "สถานะใบรับรอง", - "none": "ไม่มีใบรับรอง", - "expires": "หมดอายุ {{date}}", - "lastIssued": "ออกครั้งล่าสุด {{date}}", - "request": "ออก/ต่ออายุใบรับรอง", - "requesting": "ขอใบรับรอง..." + "title": "Certificate status", + "none": "No certificate", + "names": "Covers {{names}}", + "issuer": "Issued by {{issuer}}", + "expires": "Expires {{date}}", + "lastIssued": "Last issued {{date}}", + "lastError": "Last attempt failed: {{error}}", + "missing": "Set the domain, email and the fields your challenge type needs, then save, before requesting a certificate.", + "request": "Request certificate now", + "requesting": "Requesting certificate...", + "issued": "Certificate issued and installed" } } diff --git a/plugins/acme-ssl/locales/translated/tr_TR.json b/plugins/acme-ssl/locales/translated/tr_TR.json index 7f1cc2154..031945ccc 100644 --- a/plugins/acme-ssl/locales/translated/tr_TR.json +++ b/plugins/acme-ssl/locales/translated/tr_TR.json @@ -1,29 +1,58 @@ { + "permissions": { + "manage": { + "title": "Manage ACME certificates", + "description": "See the certificate status and request a new certificate now." + } + }, "settings": { + "autoRenew": { + "label": "Renew automatically", + "description": "Check twice a day and get a new certificate when there is none, it does not cover the domain, or it expires within 30 days." + }, "domain": { "label": "Alan Adı", - "placeholder": "termix.example.com", - "description": "Sertifika için genel alan adı." + "description": "Sertifika için genel alan adı.", + "placeholder": "termix.example.com" }, "email": { "label": "E-posta", + "description": "Contact email for the ACME account and expiry notices.", "placeholder": "admin@example.com" }, + "provider": { + "label": "Sertifika yetkilisi", + "description": "Where to get the certificate. Use staging to test without hitting Let's Encrypt rate limits.", + "letsencrypt": "Let's Encrypt", + "letsencryptStaging": "Let's Encrypt (staging)", + "custom": "Custom ACME directory" + }, + "directoryUrl": { + "label": "ACME directory URL", + "description": "Only for a custom certificate authority. Must be an https URL." + }, "challengeType": { - "label": "Doğrulama Türü", - "cloudflare": "DNS (Cloudflare) - bir Cloudflare API belirteci gerektirir" + "label": "Challenge type", + "description": "How to prove you own the domain.", + "http": "HTTP - needs port 80 reachable from the internet", + "cloudflare": "DNS (Cloudflare) - needs a Cloudflare API token" }, "cloudflareToken": { - "label": "Cloudflare API Belirteci", + "label": "Cloudflare API token", "description": "Alan adınız için Zone:DNS:Edit iznine sahip kapsamlı belirteç." } }, "status": { - "title": "Sertifika Durumu", + "title": "Certificate status", "none": "Sertifika yok", + "names": "Covers {{names}}", + "issuer": "Issued by {{issuer}}", "expires": "Son kullanma: {{date}}", "lastIssued": "Son veriliş: {{date}}", - "request": "Sertifika Ver / Yenile", - "requesting": "Sertifika isteniyor..." + "lastError": "Last attempt failed: {{error}}", + "missing": "Set the domain, email and the fields your challenge type needs, then save, before requesting a certificate.", + "request": "Request certificate now", + "requesting": "Sertifika isteniyor...", + "issued": "Certificate issued and installed" } } diff --git a/plugins/acme-ssl/locales/translated/uk_UA.json b/plugins/acme-ssl/locales/translated/uk_UA.json index 0b3d891b6..5c0aaa55b 100644 --- a/plugins/acme-ssl/locales/translated/uk_UA.json +++ b/plugins/acme-ssl/locales/translated/uk_UA.json @@ -1,29 +1,58 @@ { + "permissions": { + "manage": { + "title": "Manage ACME certificates", + "description": "See the certificate status and request a new certificate now." + } + }, "settings": { + "autoRenew": { + "label": "Renew automatically", + "description": "Check twice a day and get a new certificate when there is none, it does not cover the domain, or it expires within 30 days." + }, "domain": { - "label": "Домен", - "placeholder": "termix.example.com", - "description": "Ім'я публічного домену для сертифіката." + "label": "Domain", + "description": "The public domain name for the certificate.", + "placeholder": "termix.example.com" }, "email": { - "label": "Електронна пошта", + "label": "Email", + "description": "Contact email for the ACME account and expiry notices.", "placeholder": "admin@example.com" }, + "provider": { + "label": "Certificate authority", + "description": "Where to get the certificate. Use staging to test without hitting Let's Encrypt rate limits.", + "letsencrypt": "Let's Encrypt", + "letsencryptStaging": "Let's Encrypt (staging)", + "custom": "Custom ACME directory" + }, + "directoryUrl": { + "label": "ACME directory URL", + "description": "Only for a custom certificate authority. Must be an https URL." + }, "challengeType": { - "label": "Тип виклику", - "cloudflare": "DNS (Cloudflare) – потрібен токен API Cloudflare" + "label": "Challenge type", + "description": "How to prove you own the domain.", + "http": "HTTP - needs port 80 reachable from the internet", + "cloudflare": "DNS (Cloudflare) - needs a Cloudflare API token" }, "cloudflareToken": { - "label": "Токен API Cloudflare", - "description": "Токен з обмеженою областю дії та дозволом Zone:DNS:Edit для вашого домену." + "label": "Cloudflare API token", + "description": "Scoped token with Zone:DNS:Edit permission for your domain." } }, "status": { - "title": "Статус сертифіката", - "none": "Без сертифіката", - "expires": "Термін дії закінчується {{date}}", - "lastIssued": "Останній виданий {{date}}", - "request": "Видача / поновлення сертифіката", - "requesting": "Запит сертифіката..." + "title": "Certificate status", + "none": "No certificate", + "names": "Covers {{names}}", + "issuer": "Issued by {{issuer}}", + "expires": "Expires {{date}}", + "lastIssued": "Last issued {{date}}", + "lastError": "Last attempt failed: {{error}}", + "missing": "Set the domain, email and the fields your challenge type needs, then save, before requesting a certificate.", + "request": "Request certificate now", + "requesting": "Requesting certificate...", + "issued": "Certificate issued and installed" } } diff --git a/plugins/acme-ssl/locales/translated/vi_VN.json b/plugins/acme-ssl/locales/translated/vi_VN.json index 6958f65e9..90cf7aa4a 100644 --- a/plugins/acme-ssl/locales/translated/vi_VN.json +++ b/plugins/acme-ssl/locales/translated/vi_VN.json @@ -1,29 +1,58 @@ { + "permissions": { + "manage": { + "title": "Manage ACME certificates", + "description": "See the certificate status and request a new certificate now." + } + }, "settings": { + "autoRenew": { + "label": "Renew automatically", + "description": "Check twice a day and get a new certificate when there is none, it does not cover the domain, or it expires within 30 days." + }, "domain": { "label": "Tên miền", - "placeholder": "termix.example.com", - "description": "Tên miền công khai để cấp chứng chỉ." + "description": "Tên miền công khai để cấp chứng chỉ.", + "placeholder": "termix.example.com" }, "email": { "label": "Email", + "description": "Contact email for the ACME account and expiry notices.", "placeholder": "admin@example.com" }, + "provider": { + "label": "Cơ quan chứng thực", + "description": "Where to get the certificate. Use staging to test without hitting Let's Encrypt rate limits.", + "letsencrypt": "Let's Encrypt", + "letsencryptStaging": "Let's Encrypt (staging)", + "custom": "Custom ACME directory" + }, + "directoryUrl": { + "label": "ACME directory URL", + "description": "Only for a custom certificate authority. Must be an https URL." + }, "challengeType": { - "label": "Loại thử thách", - "cloudflare": "DNS (Cloudflare) - yêu cầu Token API Cloudflare" + "label": "Challenge type", + "description": "How to prove you own the domain.", + "http": "HTTP - needs port 80 reachable from the internet", + "cloudflare": "DNS (Cloudflare) - needs a Cloudflare API token" }, "cloudflareToken": { - "label": "Token API Cloudflare", + "label": "Cloudflare API token", "description": "Token có phạm vi với quyền Zone:DNS:Edit cho tên miền của bạn." } }, "status": { - "title": "Trạng thái chứng chỉ", + "title": "Certificate status", "none": "Không có chứng chỉ", + "names": "Covers {{names}}", + "issuer": "Issued by {{issuer}}", "expires": "Hết hạn {{date}}", "lastIssued": "Cấp lần cuối {{date}}", - "request": "Cấp / Gia hạn chứng chỉ", - "requesting": "Đang yêu cầu chứng chỉ..." + "lastError": "Last attempt failed: {{error}}", + "missing": "Set the domain, email and the fields your challenge type needs, then save, before requesting a certificate.", + "request": "Request certificate now", + "requesting": "Đang yêu cầu chứng chỉ...", + "issued": "Certificate issued and installed" } } diff --git a/plugins/acme-ssl/locales/translated/zh_CN.json b/plugins/acme-ssl/locales/translated/zh_CN.json index fc5e64cd5..a9646254c 100644 --- a/plugins/acme-ssl/locales/translated/zh_CN.json +++ b/plugins/acme-ssl/locales/translated/zh_CN.json @@ -1,17 +1,41 @@ { + "permissions": { + "manage": { + "title": "管理 ACME 证书", + "description": "查看证书状态并立即申请新证书。" + } + }, "settings": { + "autoRenew": { + "label": "自动续期", + "description": "每天检查两次。在没有证书、证书未覆盖域名或将在 30 天内过期时申请新证书。" + }, "domain": { "label": "域名", - "placeholder": "termix.example.com", - "description": "证书的公共域名。" + "description": "证书的公共域名。", + "placeholder": "termix.example.com" }, "email": { "label": "邮箱", + "description": "用于 ACME 账户和到期通知的联系邮箱。", "placeholder": "admin@example.com" }, + "provider": { + "label": "证书颁发机构", + "description": "证书申请来源。测试时使用测试环境,以免触发 Let's Encrypt 频率限制。", + "letsencrypt": "Let's Encrypt", + "letsencryptStaging": "Let's Encrypt(测试环境)", + "custom": "自定义 ACME 目录" + }, + "directoryUrl": { + "label": "ACME 目录 URL", + "description": "仅用于自定义证书颁发机构,必须为 HTTPS URL。" + }, "challengeType": { "label": "验证类型", - "cloudflare": "DNS (Cloudflare) - 需要 Cloudflare API 令牌" + "description": "用于证明域名所有权的方式。", + "http": "HTTP:需要互联网能够访问端口 80", + "cloudflare": "DNS(Cloudflare):需要 Cloudflare API 令牌" }, "cloudflareToken": { "label": "Cloudflare API 令牌", @@ -21,9 +45,17 @@ "status": { "title": "证书状态", "none": "无证书", + "names": "覆盖域名:{{names}}", + "issuer": "签发者:{{issuer}}", "expires": "过期于 {{date}}", "lastIssued": "上次签发于 {{date}}", - "request": "签发 / 续期证书", - "requesting": "正在请求证书..." + "lastError": "上次尝试失败:{{error}}", + "missing": "请先设置域名、邮箱及所选验证方式需要的字段,保存后再申请证书。", + "request": "立即申请证书", + "requesting": "正在请求证书...", + "issued": "证书已签发并安装" + }, + "plugin": { + "name": "ACME 证书" } } diff --git a/plugins/acme-ssl/locales/translated/zh_TW.json b/plugins/acme-ssl/locales/translated/zh_TW.json index 49367bc7b..ec27c0005 100644 --- a/plugins/acme-ssl/locales/translated/zh_TW.json +++ b/plugins/acme-ssl/locales/translated/zh_TW.json @@ -1,29 +1,58 @@ { + "permissions": { + "manage": { + "title": "Manage ACME certificates", + "description": "See the certificate status and request a new certificate now." + } + }, "settings": { + "autoRenew": { + "label": "Renew automatically", + "description": "Check twice a day and get a new certificate when there is none, it does not cover the domain, or it expires within 30 days." + }, "domain": { "label": "網域", - "placeholder": "termix.example.com", - "description": "憑證使用的公開網域名稱。" + "description": "憑證使用的公開網域名稱。", + "placeholder": "termix.example.com" }, "email": { "label": "電子郵件", + "description": "Contact email for the ACME account and expiry notices.", "placeholder": "admin@example.com" }, + "provider": { + "label": "憑證授權中心", + "description": "Where to get the certificate. Use staging to test without hitting Let's Encrypt rate limits.", + "letsencrypt": "Let's Encrypt", + "letsencryptStaging": "Let's Encrypt (staging)", + "custom": "Custom ACME directory" + }, + "directoryUrl": { + "label": "ACME directory URL", + "description": "Only for a custom certificate authority. Must be an https URL." + }, "challengeType": { - "label": "驗證類型", - "cloudflare": "DNS (Cloudflare) - 需要 Cloudflare API 權杖" + "label": "Challenge type", + "description": "How to prove you own the domain.", + "http": "HTTP - needs port 80 reachable from the internet", + "cloudflare": "DNS (Cloudflare) - needs a Cloudflare API token" }, "cloudflareToken": { - "label": "Cloudflare API 權杖", + "label": "Cloudflare API token", "description": "具有您網域 Zone:DNS:Edit 權限的限定範圍權杖。" } }, "status": { - "title": "憑證狀態", + "title": "Certificate status", "none": "無憑證", + "names": "Covers {{names}}", + "issuer": "Issued by {{issuer}}", "expires": "到期日 {{date}}", "lastIssued": "上次簽發日期 {{date}}", - "request": "簽發 / 續期憑證", - "requesting": "請求憑證中..." + "lastError": "Last attempt failed: {{error}}", + "missing": "Set the domain, email and the fields your challenge type needs, then save, before requesting a certificate.", + "request": "Request certificate now", + "requesting": "請求憑證中...", + "issued": "Certificate issued and installed" } } diff --git a/plugins/ai/locales/en.json b/plugins/ai/locales/en.json index 7b5758ffa..25ac9b8bb 100644 --- a/plugins/ai/locales/en.json +++ b/plugins/ai/locales/en.json @@ -115,5 +115,8 @@ }, "hosts": { "docsLink": "View docs" + }, + "plugin": { + "name": "AI Assistant" } } diff --git a/plugins/ai/locales/translated/af_ZA.json b/plugins/ai/locales/translated/af_ZA.json index dd52664ca..339bb3883 100644 --- a/plugins/ai/locales/translated/af_ZA.json +++ b/plugins/ai/locales/translated/af_ZA.json @@ -1,4 +1,46 @@ { + "permissions": { + "use": { + "title": "Gebruik die assistent", + "description": "Maak die assistent oop en vra dit dinge." + }, + "manage_providers": { + "title": "Bestuur verskaffers", + "description": "Voeg die KI-verskaffers en hul API-sleutels by, wysig en verwyder hulle." + }, + "apply_proposals": { + "title": "Pas voorstelle toe", + "description": "Laat die assistent die veranderinge wat dit voorstel, uitvoer." + }, + "services.use": { + "title": "Gebruik KI van ander funksies", + "description": "Ander funksies kan die assistent namens jou skakel." + }, + "secrets.share": { + "title": "Deel die API-sleutel", + "description": "Ander funksies mag die gestoorde KI API-sleutel gebruik sonder om dit te sien." + } + }, + "settings": { + "assistantUnavailable": "Die KI-assistent is afgeskakel op hierdie bediener.", + "providersNeedOptIn": "Skakel die KI-assistent hierbo aan om verskaffers by te voeg.", + "admin": { + "globallyEnabled": { + "label": "KI-assistent", + "description": "Laat gebruikers die KI-assistent aanskakel. Terwyl dit af is, is die assistent vir almal versteek en geblokkeer." + }, + "privateEndpoints": { + "label": "Toegelate private KI-gashere", + "description": "Gashere op jou privaat netwerk waarna gebruikers 'n verskaffer kan verwys, soos 'n self-gehoste Ollama. Plaas een gasheer op elke lyn." + } + }, + "host": { + "enableAiAssistant": { + "label": "Aktiveer KI-assistent", + "description": "Laat die KI-assistent toe om in hierdie gasheer se terminaal te help. Standaard afgeskakel, en KI moet steeds vir jou rekening geaktiveer word." + } + } + }, "ai": { "title": "Assistent", "send": "Stuur", @@ -53,7 +95,11 @@ "terminalPanelPlaceholder": "Vra oor hierdie gasheer...", "noProvidersConfigured": "Geen KI-verskaffer is nog gekonfigureer nie. Voeg een by in die KI-assistent-oortjie.", "runsInOpenTerminal": "Loop in jou oop terminaalsessie.", - "runInTerminal": "Hardloop" + "runInTerminal": "Hardloop", + "terminalContextPrefill": "Hier is my terminaaluitvoer:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Laat ander funksies jou KI-verskaffer API-sleutel vir hul eie versoeke gebruik. Die sleutel word nooit gekopieer nie, en jy kan dit te eniger tyd herroep." + } }, "nav": { "ai": "KI" @@ -67,23 +113,6 @@ "aiEnableDesc": "Voeg 'n assistent by wat jou opstelling lees en veranderinge voorstel wat jy goedkeur. Benodig 'n verskaffer wat jy verskaf, soos 'n plaaslike Ollama.", "aiNote": "Niks word êrens heen gestuur totdat jy 'n verskaffer byvoeg en 'n boodskap stuur nie." }, - "settings": { - "admin": { - "globallyEnabled": { - "label": "KI-assistent", - "description": "Laat gebruikers die KI-assistent aanskakel. Terwyl dit af is, is die assistent vir almal versteek en geblokkeer." - }, - "privateEndpoints": { - "label": "Toegelate private KI-gashere" - } - }, - "host": { - "enableAiAssistant": { - "label": "Aktiveer KI-assistent", - "description": "Laat die KI-assistent toe om in hierdie gasheer se terminaal te help. Standaard afgeskakel, en KI moet steeds vir jou rekening geaktiveer word." - } - } - }, "hosts": { "docsLink": "Bekyk dokumente" } diff --git a/plugins/ai/locales/translated/ar_SA.json b/plugins/ai/locales/translated/ar_SA.json index 037576844..9be5b2dea 100644 --- a/plugins/ai/locales/translated/ar_SA.json +++ b/plugins/ai/locales/translated/ar_SA.json @@ -1,11 +1,53 @@ { + "permissions": { + "use": { + "title": "استخدم المساعد", + "description": "افتح المساعد واسأله ما تريد." + }, + "manage_providers": { + "title": "إدارة الموفر", + "description": "أضف، عدّل، واحذف مزودي خدمات الذكاء الاصطناعي ومفاتيح واجهة برمجة التطبيقات الخاصة بهم." + }, + "apply_proposals": { + "title": "تقديم المقترحات", + "description": "دع المساعد يقوم بتنفيذ التغييرات التي يقترحها." + }, + "services.use": { + "title": "استخدم الذكاء الاصطناعي من ميزات أخرى", + "description": "قد تقوم ميزات أخرى بالاتصال بالمساعد نيابةً عنك." + }, + "secrets.share": { + "title": "شارك مفتاح API", + "description": "قد تستخدم ميزات أخرى مفتاح واجهة برمجة تطبيقات الذكاء الاصطناعي المخزن دون رؤيته." + } + }, + "settings": { + "assistantUnavailable": "تم إيقاف تشغيل مساعد الذكاء الاصطناعي على هذا الخادم.", + "providersNeedOptIn": "قم بتشغيل مساعد الذكاء الاصطناعي أعلاه لإضافة مزودي الخدمة.", + "admin": { + "globallyEnabled": { + "label": "مساعد الذكاء الاصطناعي", + "description": "اسمح للمستخدمين بتفعيل مساعد الذكاء الاصطناعي. عند إيقاف تشغيله، يكون المساعد مخفيًا ومحظورًا عن الجميع." + }, + "privateEndpoints": { + "label": "المضيفون الخاصون المسموح بهم للذكاء الاصطناعي", + "description": "المضيفون على شبكتك الخاصة الذين يمكن للمستخدمين توجيه مزود الخدمة إليهم، مثل Ollama المُستضاف ذاتيًا. ضع مضيفًا واحدًا على كل سطر." + } + }, + "host": { + "enableAiAssistant": { + "label": "تفعيل مساعد الذكاء الاصطناعي", + "description": "اسمح للمساعد الذكي بالمساعدة في طرفية هذا المضيف. هذه الميزة معطلة افتراضيًا، ولا يزال يتعين تفعيلها لحسابك." + } + } + }, "ai": { "title": "مساعد", "send": "يرسل", - "stop": "قف", - "save": "يحفظ", - "cancel": "يلغي", - "running": "جري", + "stop": "التوقف", + "save": "حفظ", + "cancel": "إلغاء", + "running": "قيد التشغيل", "approve": "يعتمد", "reject": "يرفض", "inputPlaceholder": "استفسر عن خوادمك، أو صف تغييرًا ترغب في اقتراحه.", @@ -15,7 +57,7 @@ "editProvider": "موفر التحرير", "removeProvider": "إزالة الموفر", "providerType": "مزود", - "providerLabel": "اسم", + "providerLabel": "الاسم", "providerLabelPlaceholder": "على سبيل المثال: أولاما المحلي", "baseUrl": "عنوان الخادم", "apiKey": "مفتاح API", @@ -31,7 +73,7 @@ "providerOpenai": "أوبن إيه آي", "providerGemini": "جوجل جيميني", "providerOpenaiCompatible": "متوافق مع OpenAI", - "toolArguments": "مدخل", + "toolArguments": "إدخال", "toolResult": "نتيجة", "statusApplied": "مُطبَّق", "statusRejected": "مرفوض", @@ -53,7 +95,11 @@ "terminalPanelPlaceholder": "اسأل عن هذا المضيف...", "noProvidersConfigured": "لم يتم إعداد أي موفر للذكاء الاصطناعي حتى الآن. أضف واحداً في علامة تبويب مساعد الذكاء الاصطناعي.", "runsInOpenTerminal": "يتم تشغيله في جلسة الطرفية المفتوحة لديك.", - "runInTerminal": "يجري" + "runInTerminal": "تشغيل", + "terminalContextPrefill": "هذا هو ناتج الطرفية الخاص بي:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "اسمح للميزات الأخرى باستخدام مفتاح واجهة برمجة التطبيقات (API) الخاص بمزود الذكاء الاصطناعي لطلباتها الخاصة. لا يتم نسخ المفتاح مطلقًا، ويمكنك إلغاء هذا في أي وقت." + } }, "nav": { "ai": "الذكاء الاصطناعي" @@ -67,23 +113,6 @@ "aiEnableDesc": "يُضيف هذا البرنامج مساعدًا يقرأ إعداداتك ويقترح تغييرات توافق عليها. يتطلب ذلك مزود خدمة تُحدده بنفسك، مثل مزود خدمة Ollama محلي.", "aiNote": "لن يتم إرسال أي شيء إلى أي مكان حتى تقوم بإضافة مزود خدمة وإرسال رسالة." }, - "settings": { - "admin": { - "globallyEnabled": { - "label": "مساعد الذكاء الاصطناعي", - "description": "اسمح للمستخدمين بتفعيل مساعد الذكاء الاصطناعي. عند إيقاف تشغيله، يكون المساعد مخفيًا ومحظورًا عن الجميع." - }, - "privateEndpoints": { - "label": "المضيفون الخاصون المسموح بهم للذكاء الاصطناعي" - } - }, - "host": { - "enableAiAssistant": { - "label": "تفعيل مساعد الذكاء الاصطناعي", - "description": "اسمح للمساعد الذكي بالمساعدة في طرفية هذا المضيف. هذه الميزة معطلة افتراضيًا، ولا يزال يتعين تفعيلها لحسابك." - } - } - }, "hosts": { "docsLink": "عرض المستندات" } diff --git a/plugins/ai/locales/translated/bg_BG.json b/plugins/ai/locales/translated/bg_BG.json index 0d43bc3d4..07231463b 100644 --- a/plugins/ai/locales/translated/bg_BG.json +++ b/plugins/ai/locales/translated/bg_BG.json @@ -1,4 +1,46 @@ { + "permissions": { + "use": { + "title": "Използвайте асистента", + "description": "Отворете асистента и го попитайте нещо." + }, + "manage_providers": { + "title": "Управление на доставчици", + "description": "Добавяне, редактиране и премахване на доставчици на изкуствен интелект и техните API ключове." + }, + "apply_proposals": { + "title": "Прилагане на предложения", + "description": "Нека асистентът извърши предложените от него промени." + }, + "services.use": { + "title": "Използвайте изкуствен интелект от други функции", + "description": "Други функции може да извикат асистента от ваше име." + }, + "secrets.share": { + "title": "Споделете API ключа", + "description": "Други функции могат да използват съхранения AI API ключ, без да го виждат." + } + }, + "settings": { + "assistantUnavailable": "Асистентът с изкуствен интелект е изключен на този сървър.", + "providersNeedOptIn": "Включете AI асистента по-горе, за да добавите доставчици.", + "admin": { + "globallyEnabled": { + "label": "Асистент с изкуствен интелект", + "description": "Позволете на потребителите да включат асистента с изкуствен интелект. Докато това е изключено, асистентът е скрит и блокиран за всички." + }, + "privateEndpoints": { + "label": "Разрешени частни хостове с изкуствен интелект", + "description": "Хостове във вашата частна мрежа, към които потребителите могат да насочат доставчик, като например самостоятелно хостван Ollama. Поставете по един хост на всеки ред." + } + }, + "host": { + "enableAiAssistant": { + "label": "Активиране на AI асистент", + "description": "Разрешете на AI асистента да помага в терминала на този хост. Изключено по подразбиране и все още изисква AI да е активиран за вашия акаунт." + } + } + }, "ai": { "title": "Асистент", "send": "Изпрати", @@ -53,7 +95,11 @@ "terminalPanelPlaceholder": "Попитайте за този домакин...", "noProvidersConfigured": "Все още не е конфигуриран доставчик на ИИ. Добавете такъв в раздела „Асистент за ИИ“.", "runsInOpenTerminal": "Изпълнява се във вашата отворена терминална сесия.", - "runInTerminal": "Бягане" + "runInTerminal": "Бягане", + "terminalContextPrefill": "Ето изхода на моя терминал:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Позволете на други функции да използват вашия API ключ на доставчика на изкуствен интелект за свои собствени заявки. Ключът никога не се копира и можете да го отмените по всяко време." + } }, "nav": { "ai": "Изкуствен интелект" @@ -67,23 +113,6 @@ "aiEnableDesc": "Добавя асистент, който чете настройките ви и предлага промени, които одобрявате. Необходим е доставчик, когото вие предоставяте, например местен Ollama.", "aiNote": "Нищо не се изпраща никъде, докато не добавите доставчик и не изпратите съобщение." }, - "settings": { - "admin": { - "globallyEnabled": { - "label": "Асистент с изкуствен интелект", - "description": "Позволете на потребителите да включат асистента с изкуствен интелект. Докато това е изключено, асистентът е скрит и блокиран за всички." - }, - "privateEndpoints": { - "label": "Разрешени частни хостове с изкуствен интелект" - } - }, - "host": { - "enableAiAssistant": { - "label": "Активиране на AI асистент", - "description": "Разрешете на AI асистента да помага в терминала на този хост. Изключено по подразбиране и все още изисква AI да е активиран за вашия акаунт." - } - } - }, "hosts": { "docsLink": "Преглед на документи" } diff --git a/plugins/ai/locales/translated/bn_BD.json b/plugins/ai/locales/translated/bn_BD.json index b9cd9691c..7b5758ffa 100644 --- a/plugins/ai/locales/translated/bn_BD.json +++ b/plugins/ai/locales/translated/bn_BD.json @@ -1,90 +1,119 @@ { - "ai": { - "title": "সহকারী", - "send": "পাঠান", - "stop": "থামুন", - "save": "সংরক্ষণ করুন", - "cancel": "বাতিল করুন", - "running": "দৌড়ানো", - "approve": "অনুমোদন করুন", - "reject": "প্রত্যাখ্যান করুন", - "inputPlaceholder": "আপনার সার্ভারগুলো সম্পর্কে জিজ্ঞাসা করুন, অথবা কোনো পরিবর্তনের প্রস্তাব বর্ণনা করুন।", - "selectProvider": "একজন সরবরাহকারী নির্বাচন করুন", - "providerSettings": "প্রদানকারীর সেটিংস", - "addProvider": "প্রদানকারী যোগ করুন", - "editProvider": "সম্পাদনা প্রদানকারী", - "removeProvider": "প্রদানকারীকে অপসারণ করুন", - "providerType": "সরবরাহকারী", - "providerLabel": "নাম", - "providerLabelPlaceholder": "উদাহরণস্বরূপ: স্থানীয় ওলামা", - "baseUrl": "সার্ভারের ঠিকানা", - "apiKey": "এপিআই কী", - "defaultModel": "ডিফল্ট মডেল", - "defaultModelPlaceholder": "উদাহরণস্বরূপ: llama3.1 অথবা claude-opus-5", - "labelRequired": "এই সরবরাহকারীকে একটি নাম দিন", - "providerSaveFailed": "প্রদানকারীকে সংরক্ষণ করা যায়নি", - "providerUpdated": "প্রদানকারী আপডেট করেছেন", - "providerDeleteFailed": "প্রদানকারীকে সরানো যায়নি", - "privateEndpointHint": "আপনার ব্যক্তিগত নেটওয়ার্কের অ্যাড্রেসগুলো ব্যবহার করার জন্য প্রথমে একজন অ্যাডমিনিস্ট্রেটরের কাছ থেকে হোস্টটিকে অনুমতি নিতে হয়।", - "providerOllama": "ওল্লামা", - "providerAnthropic": "অ্যানথ্রোপিক", - "providerOpenai": "ওপেনএআই", - "providerGemini": "গুগল জেমিনি", - "providerOpenaiCompatible": "ওপেনএআই সামঞ্জস্যপূর্ণ", - "toolArguments": "ইনপুট", - "toolResult": "ফলাফল", - "statusApplied": "প্রয়োগ করা হয়েছে", - "statusRejected": "প্রত্যাখ্যাত", - "proposalApplied": "পরিবর্তন প্রয়োগ করা হয়েছে", - "proposalApplyFailed": "পরিবর্তনটি প্রয়োগ করা যায়নি।", - "proposalRejectFailed": "পরিবর্তনটি প্রত্যাখ্যান করা যায়নি", - "enableTitle": "এআই অ্যাসিস্ট্যান্ট সক্রিয় করুন", - "enableDescription": "সহকারীকে আপনার সেটআপটি পড়তে দিন এবং আপনার অনুমোদনের জন্য পরিবর্তনের পরামর্শ দিতে দিন।", - "readOnlyCommands": "শুধুমাত্র পঠনযোগ্য ডায়াগনস্টিক কমান্ডের অনুমতি দিন", - "readOnlyCommandsDescription": "সহকারী প্রতিবার অনুমতি না নিয়েই df এবং uptime-এর মতো কয়েকটি নিরাপদ কমান্ড চালাতে পারে। সার্ভার পরিবর্তন করে এমন যেকোনো কিছু সর্বদা প্রথমে প্রস্তাব করা হয়।", - "modelDetectFailed": "সরবরাহকারীর সাথে যোগাযোগ করা সম্ভব হয়নি, তাই এটি একটি সাধারণ তালিকা। আপনি যেকোনো মডেলের নাম টাইপ করতে পারেন।", - "modelCustom": "একটি মডেলের নাম লিখুন", - "modelRefresh": "তালিকা রিফ্রেশ করুন", - "modelPlaceholder": "একটি মডেল বেছে নিন বা টাইপ করুন", - "attachHint": "কোনো হোস্ট, স্নিপেট বা অটোমেশন উল্লেখ করতে @ টাইপ করুন। আপনার অনুমোদনের জন্য পরিবর্তনগুলো প্রস্তাব করা হবে।", - "runCommandTitle": "রান কমান্ড", - "assistant": "এআই সহকারী", - "terminalPanelEmpty": "এই হোস্ট সম্পর্কে অ্যাসিস্ট্যান্টকে জিজ্ঞাসা করুন। অবস্থা পরিবর্তনের জন্য প্রথমে আপনার অনুমোদন প্রয়োজন।", - "terminalPanelPlaceholder": "এই হোস্ট সম্পর্কে জিজ্ঞাসা করুন...", - "noProvidersConfigured": "এখনো কোনো এআই প্রোভাইডার কনফিগার করা হয়নি। এআই অ্যাসিস্ট্যান্ট ট্যাবে একটি যোগ করুন।", - "runsInOpenTerminal": "আপনার খোলা টার্মিনাল সেশনে চলে।", - "runInTerminal": "দৌড়" - }, - "nav": { - "ai": "এআই" - }, - "onboarding": { - "aiTitle": "এআই সহকারী", - "aiIntro": "টারমিক্সে একটি ঐচ্ছিক এআই অ্যাসিস্ট্যান্ট অন্তর্ভুক্ত থাকতে পারে। আপনি পরবর্তীতে আপনার সেটিংসে এটি পরিবর্তন করতে পারবেন।", - "aiSkipTitle": "এটা ছেড়ে দাও", - "aiSkipDesc": "টারমিক্স এখন যেমন কাজ করে, তেমনই কাজ করে। অ্যাসিস্ট্যান্টটি লুকানো থাকে।", - "aiEnableTitle": "এটা চালু করুন", - "aiEnableDesc": "একজন সহকারী যোগ করে যে আপনার সেটআপ পড়ে এবং আপনার অনুমোদিত পরিবর্তনের পরামর্শ দেয়। এর জন্য আপনার সরবরাহ করা একজন প্রদানকারীর প্রয়োজন, যেমন একজন স্থানীয় ওলামা।", - "aiNote": "আপনি একজন প্রোভাইডার যোগ করে মেসেজ না পাঠানো পর্যন্ত কোথাও কিছু পাঠানো হয় না।" + "permissions": { + "use": { + "title": "Use the assistant", + "description": "Open the assistant and ask it things." + }, + "manage_providers": { + "title": "Manage providers", + "description": "Add, edit and remove the AI providers and their API keys." + }, + "apply_proposals": { + "title": "Apply proposals", + "description": "Let the assistant carry out the changes it suggests." + }, + "services.use": { + "title": "Use AI from other features", + "description": "Other features may call the assistant on your behalf." + }, + "secrets.share": { + "title": "Share the API key", + "description": "Other features may use the stored AI API key without seeing it." + } }, "settings": { + "assistantUnavailable": "The AI assistant is turned off on this server.", + "providersNeedOptIn": "Turn on the AI assistant above to add providers.", "admin": { "globallyEnabled": { - "label": "এআই সহকারী", - "description": "ব্যবহারকারীদের এআই অ্যাসিস্ট্যান্ট চালু করার সুযোগ দিন। এটি বন্ধ থাকা অবস্থায়, অ্যাসিস্ট্যান্টটি সকলের জন্য লুকানো এবং ব্লক করা থাকবে।" + "label": "AI assistant", + "description": "Let users turn on the AI assistant. While this is off, the assistant is hidden and blocked for everyone." }, "privateEndpoints": { - "label": "ব্যক্তিগত এআই হোস্ট অনুমোদিত" + "label": "Allowed private AI hosts", + "description": "Hosts on your private network that users may point a provider at, such as a self-hosted Ollama. Put one host on each line." } }, "host": { "enableAiAssistant": { - "label": "এআই অ্যাসিস্ট্যান্ট সক্রিয় করুন", - "description": "এই হোস্টের টার্মিনালে সাহায্য করার জন্য এআই অ্যাসিস্ট্যান্টকে অনুমতি দিন। এটি ডিফল্টরূপে বন্ধ থাকে এবং আপনার অ্যাকাউন্টের জন্য এআই চালু করা প্রয়োজন।" + "label": "Enable AI Assistant", + "description": "Allow the AI assistant to help in this host's terminal. Off by default, and still needs AI enabled for your account." } } }, + "ai": { + "title": "Assistant", + "send": "Send", + "stop": "Stop", + "save": "Save", + "cancel": "Cancel", + "running": "running", + "approve": "Approve", + "reject": "Reject", + "inputPlaceholder": "Ask about your servers, or describe a change to propose", + "selectProvider": "Select a provider", + "providerSettings": "Provider settings", + "addProvider": "Add provider", + "editProvider": "Edit provider", + "removeProvider": "Remove provider", + "providerType": "Provider", + "providerLabel": "Name", + "providerLabelPlaceholder": "For example: Local Ollama", + "baseUrl": "Server address", + "apiKey": "API key", + "defaultModel": "Default model", + "defaultModelPlaceholder": "For example: llama3.1 or claude-opus-5", + "labelRequired": "Give this provider a name", + "providerSaveFailed": "Could not save the provider", + "providerUpdated": "Provider updated", + "providerDeleteFailed": "Could not remove the provider", + "privateEndpointHint": "Addresses on your private network need an administrator to allow the host first.", + "providerOllama": "Ollama", + "providerAnthropic": "Anthropic", + "providerOpenai": "OpenAI", + "providerGemini": "Google Gemini", + "providerOpenaiCompatible": "OpenAI compatible", + "toolArguments": "Input", + "toolResult": "Result", + "statusApplied": "Applied", + "statusRejected": "Rejected", + "proposalApplied": "Change applied", + "proposalApplyFailed": "Could not apply the change", + "proposalRejectFailed": "Could not reject the change", + "enableTitle": "Enable the AI assistant", + "enableDescription": "Let the assistant read your setup and suggest changes for you to approve.", + "readOnlyCommands": "Allow read-only diagnostic commands", + "readOnlyCommandsDescription": "The assistant may run a short list of safe commands like df and uptime without asking each time. Anything that changes a server is always proposed first.", + "modelDetectFailed": "Could not reach the provider, so this is a general list. You can type any model name.", + "modelCustom": "Enter a model name", + "modelRefresh": "Refresh list", + "modelPlaceholder": "Choose or type a model", + "attachHint": "Type @ to reference a host, snippet or automation. Changes are proposed for you to approve.", + "runCommandTitle": "Run command", + "assistant": "AI Assistant", + "terminalPanelEmpty": "Ask the assistant about this host. Anything that changes state needs your approval first.", + "terminalPanelPlaceholder": "Ask about this host...", + "noProvidersConfigured": "No AI provider is configured yet. Add one in the AI assistant tab.", + "runsInOpenTerminal": "Runs in your open terminal session.", + "runInTerminal": "Run", + "terminalContextPrefill": "Here is my terminal output:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Let other features use your AI provider API key for their own requests. The key is never copied, and you can revoke this at any time." + } + }, + "nav": { + "ai": "AI" + }, + "onboarding": { + "aiTitle": "AI assistant", + "aiIntro": "Termix can include an optional AI assistant. You can change this later in your settings.", + "aiSkipTitle": "Leave it off", + "aiSkipDesc": "Termix works as it does now. The assistant stays hidden.", + "aiEnableTitle": "Turn it on", + "aiEnableDesc": "Adds an assistant that reads your setup and suggests changes you approve. Needs a provider you supply, such as a local Ollama.", + "aiNote": "Nothing is sent anywhere until you add a provider and send a message." + }, "hosts": { - "docsLink": "নথি দেখুন" + "docsLink": "View docs" } } diff --git a/plugins/ai/locales/translated/ca_ES.json b/plugins/ai/locales/translated/ca_ES.json index 975dfddb6..a9184d446 100644 --- a/plugins/ai/locales/translated/ca_ES.json +++ b/plugins/ai/locales/translated/ca_ES.json @@ -1,4 +1,46 @@ { + "permissions": { + "use": { + "title": "Utilitza l'assistent", + "description": "Obre l'assistent i fes-li preguntes." + }, + "manage_providers": { + "title": "Gestiona els proveïdors", + "description": "Afegiu, editeu i elimineu els proveïdors d'IA i les seves claus API." + }, + "apply_proposals": { + "title": "Aplicar propostes", + "description": "Deixa que l'assistent dugui a terme els canvis que suggereixi." + }, + "services.use": { + "title": "Utilitza la IA d'altres funcions", + "description": "Altres funcions poden trucar a l'assistent en nom teu." + }, + "secrets.share": { + "title": "Comparteix la clau de l'API", + "description": "Altres funcions poden utilitzar la clau de l'API d'IA emmagatzemada sense veure-la." + } + }, + "settings": { + "assistantUnavailable": "L'assistent d'IA està desactivat en aquest servidor.", + "providersNeedOptIn": "Activa l'assistent d'IA que hi ha a sobre per afegir proveïdors.", + "admin": { + "globallyEnabled": { + "label": "Assistent d'IA", + "description": "Permet que els usuaris activin l'assistent d'IA. Mentre estigui desactivat, l'assistent està ocult i bloquejat per a tothom." + }, + "privateEndpoints": { + "label": "Amfitrions d'IA privats permesos", + "description": "Amfitrions de la vostra xarxa privada als quals els usuaris poden dirigir un proveïdor, com ara un Ollama autoallotjat. Poseu un amfitrió a cada línia." + } + }, + "host": { + "enableAiAssistant": { + "label": "Activa l'Assistent d'IA", + "description": "Permet que l'assistent d'IA ajudi al terminal d'aquest amfitrió. Desactivat per defecte, però encara cal que la IA estigui activada per al teu compte." + } + } + }, "ai": { "title": "Assistent", "send": "Enviar", @@ -53,7 +95,11 @@ "terminalPanelPlaceholder": "Pregunta per aquest amfitrió...", "noProvidersConfigured": "Encara no hi ha cap proveïdor d'IA configurat. Afegeix-ne un a la pestanya Assistent d'IA.", "runsInOpenTerminal": "S'executa a la sessió de terminal oberta.", - "runInTerminal": "Corre" + "runInTerminal": "Corre", + "terminalContextPrefill": "Aquí teniu la sortida del meu terminal:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Permet que altres funcions utilitzin la clau de l'API del proveïdor d'IA per a les seves pròpies sol·licituds. La clau no es copia mai i pots revocar-la en qualsevol moment." + } }, "nav": { "ai": "IA" @@ -67,23 +113,6 @@ "aiEnableDesc": "Afegeix un assistent que llegeix la configuració i suggereix els canvis que aproveu. Necessita un proveïdor que subministreu, com ara un Ollama local.", "aiNote": "No s'envia res enlloc fins que no afegiu un proveïdor i envieu un missatge." }, - "settings": { - "admin": { - "globallyEnabled": { - "label": "Assistent d'IA", - "description": "Permet que els usuaris activin l'assistent d'IA. Mentre estigui desactivat, l'assistent està ocult i bloquejat per a tothom." - }, - "privateEndpoints": { - "label": "Amfitrions d'IA privats permesos" - } - }, - "host": { - "enableAiAssistant": { - "label": "Activa l'Assistent d'IA", - "description": "Permet que l'assistent d'IA ajudi al terminal d'aquest amfitrió. Desactivat per defecte, però encara cal que la IA estigui activada per al teu compte." - } - } - }, "hosts": { "docsLink": "Veure documents" } diff --git a/plugins/ai/locales/translated/cs_CZ.json b/plugins/ai/locales/translated/cs_CZ.json index fd86bd263..9a47a96ec 100644 --- a/plugins/ai/locales/translated/cs_CZ.json +++ b/plugins/ai/locales/translated/cs_CZ.json @@ -1,4 +1,46 @@ { + "permissions": { + "use": { + "title": "Použijte asistenta", + "description": "Otevřete asistenta a zeptejte se ho na něco." + }, + "manage_providers": { + "title": "Spravovat poskytovatele", + "description": "Přidávejte, upravujte a odebírejte poskytovatele umělé inteligence a jejich klíče API." + }, + "apply_proposals": { + "title": "Použít návrhy", + "description": "Nechte asistenta provést změny, které navrhuje." + }, + "services.use": { + "title": "Používejte umělou inteligenci z jiných funkcí", + "description": "Jiné funkce mohou zavolat asistenta za vás." + }, + "secrets.share": { + "title": "Sdílení klíče API", + "description": "Jiné funkce mohou používat uložený klíč API AI, aniž by ho viděly." + } + }, + "settings": { + "assistantUnavailable": "Asistent s umělou inteligencí je na tomto serveru vypnutý.", + "providersNeedOptIn": "Zapněte výše uvedeného asistenta s umělou inteligencí a přidejte poskytovatele.", + "admin": { + "globallyEnabled": { + "label": "Asistent s umělou inteligencí", + "description": "Umožněte uživatelům zapnout asistenta s umělou inteligencí. Pokud je tato funkce vypnutá, asistent je skrytý a blokovaný pro všechny." + }, + "privateEndpoints": { + "label": "Povolení soukromí hostitelé s umělou inteligencí", + "description": "Hostitelé ve vaší privátní síti, na které mohou uživatelé odkazovat poskytovatele, například Ollama hostovaná na vlastním serveru. Na každý řádek uveďte jednoho hostitele." + } + }, + "host": { + "enableAiAssistant": { + "label": "Povolit asistenta s umělou inteligencí", + "description": "Povolit asistentovi s umělou inteligencí pomáhat v terminálu tohoto hostitele. Ve výchozím nastavení vypnuto, ale stále vyžaduje, aby byla pro váš účet povolena umělá inteligence." + } + } + }, "ai": { "title": "Asistent", "send": "Poslat", @@ -34,7 +76,7 @@ "toolArguments": "Vstup", "toolResult": "Výsledek", "statusApplied": "Aplikovaný", - "statusRejected": "Zamítnuto", + "statusRejected": "Odmítnuto", "proposalApplied": "Změna použita", "proposalApplyFailed": "Změnu se nepodařilo použít", "proposalRejectFailed": "Změnu se nepodařilo odmítnout", @@ -53,7 +95,11 @@ "terminalPanelPlaceholder": "Zeptejte se na tohoto hostitele...", "noProvidersConfigured": "Zatím není nakonfigurován žádný poskytovatel AI. Přidejte ho na kartě Asistent AI.", "runsInOpenTerminal": "Spustí se ve vaší otevřené terminálové relaci.", - "runInTerminal": "Běh" + "runInTerminal": "Běh", + "terminalContextPrefill": "Zde je můj terminálový výstup:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Umožněte ostatním funkcím používat váš klíč API poskytovatele AI pro jejich vlastní požadavky. Klíč se nikdy nekopíruje a jeho použití můžete kdykoli zrušit." + } }, "nav": { "ai": "Umělá inteligence" @@ -67,23 +113,6 @@ "aiEnableDesc": "Přidá asistenta, který si přečte vaše nastavení a navrhne změny, které schválíte. Vyžaduje poskytovatele, kterého dodáte, například místní Ollamu.", "aiNote": "Nic se nikam neodesílá, dokud nepřidáte poskytovatele a neodešlete zprávu." }, - "settings": { - "admin": { - "globallyEnabled": { - "label": "Asistent s umělou inteligencí", - "description": "Umožněte uživatelům zapnout asistenta s umělou inteligencí. Pokud je tato funkce vypnutá, asistent je skrytý a blokovaný pro všechny." - }, - "privateEndpoints": { - "label": "Povolení soukromí hostitelé s umělou inteligencí" - } - }, - "host": { - "enableAiAssistant": { - "label": "Povolit asistenta s umělou inteligencí", - "description": "Povolit asistentovi s umělou inteligencí pomáhat v terminálu tohoto hostitele. Ve výchozím nastavení vypnuto, ale stále vyžaduje, aby byla pro váš účet povolena umělá inteligence." - } - } - }, "hosts": { "docsLink": "Zobrazit dokumenty" } diff --git a/plugins/ai/locales/translated/da_DK.json b/plugins/ai/locales/translated/da_DK.json index bc1406446..72dc289ba 100644 --- a/plugins/ai/locales/translated/da_DK.json +++ b/plugins/ai/locales/translated/da_DK.json @@ -1,4 +1,46 @@ { + "permissions": { + "use": { + "title": "Brug assistenten", + "description": "Åbn assistenten og stil den spørgsmål." + }, + "manage_providers": { + "title": "Administrer udbydere", + "description": "Tilføj, rediger og fjern AI-udbyderne og deres API-nøgler." + }, + "apply_proposals": { + "title": "Anvend forslag", + "description": "Lad assistenten udføre de foreslåede ændringer." + }, + "services.use": { + "title": "Brug AI fra andre funktioner", + "description": "Andre funktioner kan ringe til assistenten på dine vegne." + }, + "secrets.share": { + "title": "Del API-nøglen", + "description": "Andre funktioner kan bruge den gemte AI API-nøgle uden at se den." + } + }, + "settings": { + "assistantUnavailable": "AI-assistenten er slået fra på denne server.", + "providersNeedOptIn": "Slå AI-assistenten ovenfor til for at tilføje udbydere.", + "admin": { + "globallyEnabled": { + "label": "AI-assistent", + "description": "Lad brugerne aktivere AI-assistenten. Når dette er slået fra, er assistenten skjult og blokeret for alle." + }, + "privateEndpoints": { + "label": "Tilladte private AI-værter", + "description": "Værter på dit private netværk, som brugerne kan henvise en udbyder til, f.eks. en selvhostet Ollama. Sæt én vært på hver linje." + } + }, + "host": { + "enableAiAssistant": { + "label": "Aktivér AI-assistent", + "description": "Tillad AI-assistenten at hjælpe i denne værts terminal. Deaktiveret som standard, og kræver stadig, at AI er aktiveret for din konto." + } + } + }, "ai": { "title": "Assistent", "send": "Sende", @@ -53,7 +95,11 @@ "terminalPanelPlaceholder": "Spørg om denne vært...", "noProvidersConfigured": "Der er endnu ikke konfigureret nogen AI-udbyder. Tilføj en i fanen AI-assistent.", "runsInOpenTerminal": "Kører i din åbne terminalsession.", - "runInTerminal": "Løbe" + "runInTerminal": "Løbe", + "terminalContextPrefill": "Her er mit terminaloutput:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Lad andre funktioner bruge din AI-udbyders API-nøgle til deres egne anmodninger. Nøglen kopieres aldrig, og du kan til enhver tid tilbagekalde den." + } }, "nav": { "ai": "AI" @@ -67,23 +113,6 @@ "aiEnableDesc": "Tilføjer en assistent, der læser din opsætning og foreslår ændringer, du godkender. Kræver en udbyder, du angiver, f.eks. en lokal Ollama.", "aiNote": "Intet sendes nogen steder, før du tilføjer en udbyder og sender en besked." }, - "settings": { - "admin": { - "globallyEnabled": { - "label": "AI-assistent", - "description": "Lad brugerne aktivere AI-assistenten. Når dette er slået fra, er assistenten skjult og blokeret for alle." - }, - "privateEndpoints": { - "label": "Tilladte private AI-værter" - } - }, - "host": { - "enableAiAssistant": { - "label": "Aktivér AI-assistent", - "description": "Tillad AI-assistenten at hjælpe i denne værts terminal. Deaktiveret som standard, og kræver stadig, at AI er aktiveret for din konto." - } - } - }, "hosts": { "docsLink": "Se dokumenter" } diff --git a/plugins/ai/locales/translated/de_DE.json b/plugins/ai/locales/translated/de_DE.json index 538102fc8..e6d6d4ef0 100644 --- a/plugins/ai/locales/translated/de_DE.json +++ b/plugins/ai/locales/translated/de_DE.json @@ -1,11 +1,53 @@ { + "permissions": { + "use": { + "title": "Nutzen Sie den Assistenten", + "description": "Öffne den Assistenten und stelle ihm Fragen." + }, + "manage_providers": { + "title": "Anbieter verwalten", + "description": "KI-Anbieter und ihre API-Schlüssel hinzufügen, bearbeiten und entfernen." + }, + "apply_proposals": { + "title": "Vorschläge einreichen", + "description": "Lassen Sie den Assistenten die von ihm vorgeschlagenen Änderungen durchführen." + }, + "services.use": { + "title": "Nutzen Sie KI aus anderen Funktionen", + "description": "Andere Funktionen rufen möglicherweise in Ihrem Namen den Assistenten auf." + }, + "secrets.share": { + "title": "Teilen Sie den API-Schlüssel", + "description": "Andere Funktionen verwenden möglicherweise den gespeicherten KI-API-Schlüssel, ohne ihn anzuzeigen." + } + }, + "settings": { + "assistantUnavailable": "Der KI-Assistent ist auf diesem Server deaktiviert.", + "providersNeedOptIn": "Aktivieren Sie den obenstehenden KI-Assistenten, um Anbieter hinzuzufügen.", + "admin": { + "globallyEnabled": { + "label": "KI-Assistent", + "description": "Ermöglichen Sie den Nutzern, den KI-Assistenten zu aktivieren. Solange diese Option deaktiviert ist, ist der Assistent für alle ausgeblendet und gesperrt." + }, + "privateEndpoints": { + "label": "Zulässige private KI-Hosts", + "description": "Hosts in Ihrem privaten Netzwerk, auf die Benutzer einen Provider verweisen können, wie z. B. ein selbst gehostetes Ollama. Fügen Sie in jede Zeile einen Host ein." + } + }, + "host": { + "enableAiAssistant": { + "label": "KI-Assistent aktivieren", + "description": "Erlauben Sie dem KI-Assistenten, im Terminal dieses Hosts Hilfe zu leisten. Standardmäßig deaktiviert; die KI muss weiterhin für Ihr Konto aktiviert sein." + } + } + }, "ai": { "title": "Assistent", "send": "Schicken", "stop": "Stoppen", "save": "Speichern", - "cancel": "Stornieren", - "running": "läuft", + "cancel": "Abbrechen", + "running": "laufend", "approve": "Genehmigen", "reject": "Ablehnen", "inputPlaceholder": "Erkundigen Sie sich nach Ihren Servern oder beschreiben Sie einen Änderungsvorschlag.", @@ -31,7 +73,7 @@ "providerOpenai": "OpenAI", "providerGemini": "Google Gemini", "providerOpenaiCompatible": "OpenAI-kompatibel", - "toolArguments": "Eingang", + "toolArguments": "Eingabe", "toolResult": "Ergebnis", "statusApplied": "Angewandt", "statusRejected": "Abgelehnt", @@ -53,7 +95,11 @@ "terminalPanelPlaceholder": "Erkundigen Sie sich nach diesem Gastgeber...", "noProvidersConfigured": "Es ist noch kein KI-Anbieter konfiguriert. Fügen Sie einen im Tab „KI-Assistent“ hinzu.", "runsInOpenTerminal": "Wird in Ihrer geöffneten Terminal-Sitzung ausgeführt.", - "runInTerminal": "Laufen" + "runInTerminal": "Ausführen", + "terminalContextPrefill": "Hier ist meine Terminalausgabe:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Erlauben Sie anderen Funktionen, Ihren API-Schlüssel Ihres KI-Anbieters für ihre eigenen Anfragen zu verwenden. Der Schlüssel wird niemals kopiert, und Sie können diese Berechtigung jederzeit widerrufen." + } }, "nav": { "ai": "KI" @@ -67,23 +113,6 @@ "aiEnableDesc": "Fügt einen Assistenten hinzu, der Ihre Einstellungen analysiert und Ihnen von Ihnen genehmigte Änderungen vorschlägt. Benötigt einen von Ihnen angegebenen Anbieter, z. B. einen lokalen Ollama-Händler.", "aiNote": "Es wird nichts gesendet, bis Sie einen Anbieter hinzufügen und eine Nachricht senden." }, - "settings": { - "admin": { - "globallyEnabled": { - "label": "KI-Assistent", - "description": "Ermöglichen Sie den Nutzern, den KI-Assistenten zu aktivieren. Solange diese Option deaktiviert ist, ist der Assistent für alle ausgeblendet und gesperrt." - }, - "privateEndpoints": { - "label": "Zulässige private KI-Hosts" - } - }, - "host": { - "enableAiAssistant": { - "label": "KI-Assistent aktivieren", - "description": "Erlauben Sie dem KI-Assistenten, im Terminal dieses Hosts Hilfe zu leisten. Standardmäßig deaktiviert; die KI muss weiterhin für Ihr Konto aktiviert sein." - } - } - }, "hosts": { "docsLink": "Dokumentation anzeigen" } diff --git a/plugins/ai/locales/translated/el_GR.json b/plugins/ai/locales/translated/el_GR.json index ca0178afb..cb2ddde53 100644 --- a/plugins/ai/locales/translated/el_GR.json +++ b/plugins/ai/locales/translated/el_GR.json @@ -1,4 +1,46 @@ { + "permissions": { + "use": { + "title": "Χρησιμοποιήστε τον βοηθό", + "description": "Άνοιξε τον βοηθό και ρώτα τον πράγματα." + }, + "manage_providers": { + "title": "Διαχείριση παρόχων", + "description": "Προσθήκη, επεξεργασία και κατάργηση των παρόχων τεχνητής νοημοσύνης και των κλειδιών API τους." + }, + "apply_proposals": { + "title": "Εφαρμογή προτάσεων", + "description": "Αφήστε τον βοηθό να εκτελέσει τις αλλαγές που προτείνει." + }, + "services.use": { + "title": "Χρησιμοποιήστε την Τεχνητή Νοημοσύνη από άλλες λειτουργίες", + "description": "Άλλες λειτουργίες ενδέχεται να καλούν τον βοηθό εκ μέρους σας." + }, + "secrets.share": { + "title": "Κοινή χρήση του κλειδιού API", + "description": "Άλλες λειτουργίες ενδέχεται να χρησιμοποιούν το αποθηκευμένο κλειδί API AI χωρίς να το βλέπουν." + } + }, + "settings": { + "assistantUnavailable": "Ο βοηθός τεχνητής νοημοσύνης είναι απενεργοποιημένος σε αυτόν τον διακομιστή.", + "providersNeedOptIn": "Ενεργοποιήστε τον βοηθό τεχνητής νοημοσύνης παραπάνω για να προσθέσετε παρόχους.", + "admin": { + "globallyEnabled": { + "label": "Βοηθός Τεχνητής Νοημοσύνης", + "description": "Επιτρέψτε στους χρήστες να ενεργοποιήσουν τον βοηθό τεχνητής νοημοσύνης. Όσο είναι απενεργοποιημένος, ο βοηθός είναι κρυφός και αποκλεισμένος για όλους." + }, + "privateEndpoints": { + "label": "Επιτρεπόμενοι ιδιωτικοί κεντρικοί υπολογιστές τεχνητής νοημοσύνης", + "description": "Κεντρικοί υπολογιστές στο ιδιωτικό σας δίκτυο στους οποίους οι χρήστες μπορούν να υποδείξουν έναν πάροχο, όπως ένα αυτο-φιλοξενούμενο Ollama. Τοποθετήστε έναν κεντρικό υπολογιστή σε κάθε γραμμή." + } + }, + "host": { + "enableAiAssistant": { + "label": "Ενεργοποίηση Βοηθού Τεχνητής Νοημοσύνης", + "description": "Επιτρέψτε στον βοηθό τεχνητής νοημοσύνης να βοηθά στο τερματικό αυτού του κεντρικού υπολογιστή. Απενεργοποιημένο από προεπιλογή και εξακολουθεί να χρειάζεται ενεργοποιημένη την τεχνητή νοημοσύνη για τον λογαριασμό σας." + } + } + }, "ai": { "title": "Βοηθός", "send": "Στέλνω", @@ -53,7 +95,11 @@ "terminalPanelPlaceholder": "Ρωτήστε για αυτόν τον οικοδεσπότη...", "noProvidersConfigured": "Δεν έχει διαμορφωθεί ακόμη πάροχος τεχνητής νοημοσύνης. Προσθέστε έναν στην καρτέλα βοηθού τεχνητής νοημοσύνης.", "runsInOpenTerminal": "Εκτελείται στην ανοιχτή συνεδρία τερματικού σας.", - "runInTerminal": "Τρέξιμο" + "runInTerminal": "Τρέξιμο", + "terminalContextPrefill": "Εδώ είναι η έξοδος του τερματικού μου:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Επιτρέψτε σε άλλες λειτουργίες να χρησιμοποιούν το κλειδί API του παρόχου τεχνητής νοημοσύνης για τα δικά τους αιτήματα. Το κλειδί δεν αντιγράφεται ποτέ και μπορείτε να το ανακαλέσετε ανά πάσα στιγμή." + } }, "nav": { "ai": "Όλα συμπεριλαμβάνονται" @@ -67,23 +113,6 @@ "aiEnableDesc": "Προσθέτει έναν βοηθό που διαβάζει τη ρύθμισή σας και προτείνει αλλαγές που εγκρίνετε. Χρειάζεται έναν πάροχο που παρέχετε, όπως ένα τοπικό Ollama.", "aiNote": "Τίποτα δεν αποστέλλεται πουθενά μέχρι να προσθέσετε έναν πάροχο και να στείλετε ένα μήνυμα." }, - "settings": { - "admin": { - "globallyEnabled": { - "label": "Βοηθός Τεχνητής Νοημοσύνης", - "description": "Επιτρέψτε στους χρήστες να ενεργοποιήσουν τον βοηθό τεχνητής νοημοσύνης. Όσο είναι απενεργοποιημένος, ο βοηθός είναι κρυφός και αποκλεισμένος για όλους." - }, - "privateEndpoints": { - "label": "Επιτρεπόμενοι ιδιωτικοί κεντρικοί υπολογιστές τεχνητής νοημοσύνης" - } - }, - "host": { - "enableAiAssistant": { - "label": "Ενεργοποίηση Βοηθού Τεχνητής Νοημοσύνης", - "description": "Επιτρέψτε στον βοηθό τεχνητής νοημοσύνης να βοηθά στο τερματικό αυτού του κεντρικού υπολογιστή. Απενεργοποιημένο από προεπιλογή και εξακολουθεί να χρειάζεται ενεργοποιημένη την τεχνητή νοημοσύνη για τον λογαριασμό σας." - } - } - }, "hosts": { "docsLink": "Προβολή εγγράφων" } diff --git a/plugins/ai/locales/translated/es_ES.json b/plugins/ai/locales/translated/es_ES.json index c3ffb8803..14430a48d 100644 --- a/plugins/ai/locales/translated/es_ES.json +++ b/plugins/ai/locales/translated/es_ES.json @@ -1,11 +1,53 @@ { + "permissions": { + "use": { + "title": "Utilice el asistente", + "description": "Abre el asistente y hazle preguntas." + }, + "manage_providers": { + "title": "Gestionar proveedores", + "description": "Agregue, edite y elimine los proveedores de IA y sus claves API." + }, + "apply_proposals": { + "title": "Presentar propuestas", + "description": "Deja que el asistente realice los cambios que sugiere." + }, + "services.use": { + "title": "Utilizar la IA de otras funciones", + "description": "Otras funciones pueden llamar al asistente en tu nombre." + }, + "secrets.share": { + "title": "Comparta la clave API", + "description": "Es posible que otras funciones utilicen la clave API de IA almacenada sin tenerla en cuenta." + } + }, + "settings": { + "assistantUnavailable": "El asistente de IA está desactivado en este servidor.", + "providersNeedOptIn": "Activa el asistente de IA que aparece arriba para añadir proveedores.", + "admin": { + "globallyEnabled": { + "label": "Asistente de IA", + "description": "Permita que los usuarios activen el asistente de IA. Mientras esté desactivado, el asistente permanecerá oculto y bloqueado para todos." + }, + "privateEndpoints": { + "label": "Hosts de IA privados permitidos", + "description": "Hosts en tu red privada a los que los usuarios pueden dirigir un proveedor, como por ejemplo un servidor Ollama autogestionado. Coloca un host en cada línea." + } + }, + "host": { + "enableAiAssistant": { + "label": "Habilitar el asistente de IA", + "description": "Permite que el asistente de IA te ayude en la terminal de este host. Está desactivado por defecto y aún así necesitas tener la IA habilitada para tu cuenta." + } + } + }, "ai": { "title": "Asistente", "send": "Enviar", - "stop": "Detener", - "save": "Ahorrar", + "stop": "Parada", + "save": "Guardar", "cancel": "Cancelar", - "running": "correr", + "running": "en ejecución", "approve": "Aprobar", "reject": "Rechazar", "inputPlaceholder": "Pregunte sobre sus servidores o describa un cambio para proponer.", @@ -31,7 +73,7 @@ "providerOpenai": "OpenAI", "providerGemini": "Google Gemini", "providerOpenaiCompatible": "Compatible con OpenAI", - "toolArguments": "Aporte", + "toolArguments": "Entrada", "toolResult": "Resultado", "statusApplied": "Aplicado", "statusRejected": "Rechazado", @@ -53,7 +95,11 @@ "terminalPanelPlaceholder": "Pregunta por este anfitrión...", "noProvidersConfigured": "Aún no hay ningún proveedor de IA configurado. Añada uno en la pestaña del asistente de IA.", "runsInOpenTerminal": "Se ejecuta en tu sesión de terminal abierta.", - "runInTerminal": "Correr" + "runInTerminal": "Ejecutar", + "terminalContextPrefill": "Aquí está la salida de mi terminal:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Permite que otras funciones utilicen la clave API de tu proveedor de IA para sus propias solicitudes. La clave nunca se copia y puedes revocarla en cualquier momento." + } }, "nav": { "ai": "AI" @@ -67,23 +113,6 @@ "aiEnableDesc": "Agrega un asistente que lee tu configuración y sugiere cambios que apruebas. Requiere un proveedor que tú proporciones, como un Ollama local.", "aiNote": "No se envía nada a ningún sitio hasta que añadas un proveedor y envíes un mensaje." }, - "settings": { - "admin": { - "globallyEnabled": { - "label": "Asistente de IA", - "description": "Permita que los usuarios activen el asistente de IA. Mientras esté desactivado, el asistente permanecerá oculto y bloqueado para todos." - }, - "privateEndpoints": { - "label": "Hosts de IA privados permitidos" - } - }, - "host": { - "enableAiAssistant": { - "label": "Habilitar el asistente de IA", - "description": "Permite que el asistente de IA te ayude en la terminal de este host. Está desactivado por defecto y aún así necesitas tener la IA habilitada para tu cuenta." - } - } - }, "hosts": { "docsLink": "Ver documentación" } diff --git a/plugins/ai/locales/translated/fi_FI.json b/plugins/ai/locales/translated/fi_FI.json index abbd525e4..1145b28d3 100644 --- a/plugins/ai/locales/translated/fi_FI.json +++ b/plugins/ai/locales/translated/fi_FI.json @@ -1,4 +1,46 @@ { + "permissions": { + "use": { + "title": "Käytä avustajaa", + "description": "Avaa avustaja ja kysy siltä asioita." + }, + "manage_providers": { + "title": "Hallinnoi palveluntarjoajia", + "description": "Lisää, muokkaa ja poista tekoälypalveluntarjoajia ja niiden API-avaimia." + }, + "apply_proposals": { + "title": "Käytä ehdotuksia", + "description": "Anna avustajan suorittaa ehdottamansa muutokset." + }, + "services.use": { + "title": "Käytä tekoälyä muista ominaisuuksista", + "description": "Muut ominaisuudet saattavat soittaa avustajalle puolestasi." + }, + "secrets.share": { + "title": "Jaa API-avain", + "description": "Muut ominaisuudet saattavat käyttää tallennettua tekoälyn API-avainta näkemättä sitä." + } + }, + "settings": { + "assistantUnavailable": "Tekoälyavustaja on pois päältä tällä palvelimella.", + "providersNeedOptIn": "Ota yllä oleva tekoälyavustaja käyttöön lisätäksesi palveluntarjoajia.", + "admin": { + "globallyEnabled": { + "label": "Tekoälyavustaja", + "description": "Salli käyttäjien ottaa tekoälyavustaja käyttöön. Kun tämä on pois päältä, avustaja on piilotettu ja estetty kaikilta." + }, + "privateEndpoints": { + "label": "Sallitut yksityiset tekoälyisännät", + "description": "Yksityisen verkon isännät, joihin käyttäjät voivat ohjata palveluntarjoajan, kuten itse isännöity Ollama. Aseta yksi isäntä kullekin riville." + } + }, + "host": { + "enableAiAssistant": { + "label": "Ota tekoälyavustaja käyttöön", + "description": "Salli tekoälyavustaja auttaa tämän isännän terminaalissa. Oletusarvoisesti pois päältä, mutta tekoälyn on silti oltava käytössä tililläsi." + } + } + }, "ai": { "title": "Assistentti", "send": "Lähetä", @@ -53,7 +95,11 @@ "terminalPanelPlaceholder": "Kysy tästä isännöitsijästä...", "noProvidersConfigured": "Tekoälypalveluntarjoajaa ei ole vielä määritetty. Lisää sellainen tekoälyavustaja-välilehdellä.", "runsInOpenTerminal": "Suoritetaan avoimessa pääteistunnossa.", - "runInTerminal": "Juokse" + "runInTerminal": "Juokse", + "terminalContextPrefill": "Tässä on päätteen tuloste:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Anna muiden ominaisuuksien käyttää tekoälypalveluntarjoajasi API-avainta omiin pyyntöihinsä. Avainta ei koskaan kopioida, ja voit peruuttaa tämän milloin tahansa." + } }, "nav": { "ai": "Tekoäly" @@ -67,23 +113,6 @@ "aiEnableDesc": "Lisää avustajan, joka lukee asetuksesi ja ehdottaa hyväksymiäsi muutoksia. Edellyttää toimittamaasi palveluntarjoajaa, kuten paikallisen Ollaman.", "aiNote": "Mitään ei lähetetä mihinkään ennen kuin lisäät palveluntarjoajan ja lähetät viestin." }, - "settings": { - "admin": { - "globallyEnabled": { - "label": "Tekoälyavustaja", - "description": "Salli käyttäjien ottaa tekoälyavustaja käyttöön. Kun tämä on pois päältä, avustaja on piilotettu ja estetty kaikilta." - }, - "privateEndpoints": { - "label": "Sallitut yksityiset tekoälyisännät" - } - }, - "host": { - "enableAiAssistant": { - "label": "Ota tekoälyavustaja käyttöön", - "description": "Salli tekoälyavustaja auttaa tämän isännän terminaalissa. Oletusarvoisesti pois päältä, mutta tekoälyn on silti oltava käytössä tililläsi." - } - } - }, "hosts": { "docsLink": "Näytä dokumentit" } diff --git a/plugins/ai/locales/translated/fr_FR.json b/plugins/ai/locales/translated/fr_FR.json index 7192d287f..ef5361462 100644 --- a/plugins/ai/locales/translated/fr_FR.json +++ b/plugins/ai/locales/translated/fr_FR.json @@ -1,11 +1,53 @@ { + "permissions": { + "use": { + "title": "Utilisez l'assistant", + "description": "Ouvrez l'assistant et posez-lui des questions." + }, + "manage_providers": { + "title": "Gérer les fournisseurs", + "description": "Ajoutez, modifiez et supprimez les fournisseurs d'IA et leurs clés API." + }, + "apply_proposals": { + "title": "Soumettre les propositions", + "description": "Laissez l'assistant effectuer les modifications qu'il suggère." + }, + "services.use": { + "title": "Utiliser l'IA d'autres fonctionnalités", + "description": "D'autres fonctionnalités peuvent appeler l'assistant en votre nom." + }, + "secrets.share": { + "title": "Partagez la clé API", + "description": "D'autres fonctionnalités peuvent utiliser la clé API IA stockée sans la voir." + } + }, + "settings": { + "assistantUnavailable": "L'assistant IA est désactivé sur ce serveur.", + "providersNeedOptIn": "Activez l'assistant IA ci-dessus pour ajouter des fournisseurs.", + "admin": { + "globallyEnabled": { + "label": "Assistant IA", + "description": "Autoriser les utilisateurs à activer l'assistant IA. Lorsqu'il est désactivé, l'assistant est masqué et inaccessible à tous." + }, + "privateEndpoints": { + "label": "Hôtes d'IA privés autorisés", + "description": "Sur votre réseau privé, configurez des hôtes vers lesquels les utilisateurs peuvent orienter un fournisseur, comme un serveur Ollama auto-hébergé. Placez un hôte sur chaque ligne." + } + }, + "host": { + "enableAiAssistant": { + "label": "Activer l'assistant IA", + "description": "Autoriser l'assistant IA à vous aider dans le terminal de cet hôte. Désactivé par défaut ; l'IA doit être activée pour votre compte." + } + } + }, "ai": { "title": "Assistant", "send": "Envoyer", - "stop": "Arrêt", - "save": "Sauvegarder", + "stop": "Stop", + "save": "Enregistrer", "cancel": "Annuler", - "running": "en cours d'exécution", + "running": "en cours", "approve": "Approuver", "reject": "Rejeter", "inputPlaceholder": "Renseignez-vous sur vos serveurs ou décrivez un changement à proposer.", @@ -31,7 +73,7 @@ "providerOpenai": "OpenAI", "providerGemini": "Google Gemini", "providerOpenaiCompatible": "Compatible avec OpenAI", - "toolArguments": "Saisir", + "toolArguments": "Entrée", "toolResult": "Résultat", "statusApplied": "Appliqué", "statusRejected": "Rejeté", @@ -53,7 +95,11 @@ "terminalPanelPlaceholder": "Renseignez-vous sur cet hôte...", "noProvidersConfigured": "Aucun fournisseur d'IA n'est encore configuré. Ajoutez-en un dans l'onglet Assistant IA.", "runsInOpenTerminal": "S'exécute dans votre session de terminal ouverte.", - "runInTerminal": "Courir" + "runInTerminal": "Exécuter", + "terminalContextPrefill": "Voici la sortie de mon terminal :\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Autorisez d'autres fonctionnalités à utiliser votre clé API de fournisseur d'IA pour leurs propres requêtes. Cette clé n'est jamais copiée et vous pouvez la révoquer à tout moment." + } }, "nav": { "ai": "IA" @@ -67,23 +113,6 @@ "aiEnableDesc": "Ajoute un assistant qui analyse votre configuration et suggère des modifications que vous approuvez. Nécessite un fournisseur que vous désignez, comme un Ollama local.", "aiNote": "Aucun message n'est envoyé tant que vous n'avez pas ajouté de fournisseur et envoyé un message." }, - "settings": { - "admin": { - "globallyEnabled": { - "label": "Assistant IA", - "description": "Autoriser les utilisateurs à activer l'assistant IA. Lorsqu'il est désactivé, l'assistant est masqué et inaccessible à tous." - }, - "privateEndpoints": { - "label": "Hôtes d'IA privés autorisés" - } - }, - "host": { - "enableAiAssistant": { - "label": "Activer l'assistant IA", - "description": "Autoriser l'assistant IA à vous aider dans le terminal de cet hôte. Désactivé par défaut ; l'IA doit être activée pour votre compte." - } - } - }, "hosts": { "docsLink": "Voir la documentation" } diff --git a/plugins/ai/locales/translated/he_IL.json b/plugins/ai/locales/translated/he_IL.json index 34237734f..f5e2c4e34 100644 --- a/plugins/ai/locales/translated/he_IL.json +++ b/plugins/ai/locales/translated/he_IL.json @@ -1,4 +1,46 @@ { + "permissions": { + "use": { + "title": "השתמש בעוזר", + "description": "פתח את העוזר ושאל אותו דברים." + }, + "manage_providers": { + "title": "ניהול ספקים", + "description": "הוספה, עריכה והסרה של ספקי הבינה המלאכותית ואת מפתחות ה-API שלהם." + }, + "apply_proposals": { + "title": "החלת הצעות", + "description": "תן לעוזר לבצע את השינויים שהוא מציע." + }, + "services.use": { + "title": "השתמש בבינה מלאכותית מתכונות אחרות", + "description": "ייתכן שתכונות אחרות יתקשרו לעוזר בשמך." + }, + "secrets.share": { + "title": "שתף את מפתח ה-API", + "description": "תכונות אחרות עשויות להשתמש במפתח ה-API של בינה מלאכותית המאוחסן מבלי לראות אותו." + } + }, + "settings": { + "assistantUnavailable": "עוזר הבינה המלאכותית כבוי בשרת הזה.", + "providersNeedOptIn": "הפעל את עוזר הבינה המלאכותית למעלה כדי להוסיף ספקים.", + "admin": { + "globallyEnabled": { + "label": "עוזר בינה מלאכותית", + "description": "אפשר למשתמשים להפעיל את עוזר הבינה המלאכותית. כאשר זה כבוי, העוזר מוסתר וחסום עבור כולם." + }, + "privateEndpoints": { + "label": "מארחים פרטיים של בינה מלאכותית מורשים", + "description": "מארחים ברשת הפרטית שלך שמשתמשים יכולים להפנות אליהם ספק, כגון Ollama המאוחסן בעצמו. שים מארח אחד בכל שורה." + } + }, + "host": { + "enableAiAssistant": { + "label": "הפעל את עוזר הבינה המלאכותית", + "description": "אפשר לעוזר הבינה המלאכותית לסייע במסוף של מארח זה. כבוי כברירת מחדל, ועדיין נדרשת הפעלת בינה מלאכותית עבור חשבונך." + } + } + }, "ai": { "title": "עוֹזֵר", "send": "לִשְׁלוֹחַ", @@ -53,7 +95,11 @@ "terminalPanelPlaceholder": "שאל על המארח הזה...", "noProvidersConfigured": "עדיין לא הוגדר ספק בינה מלאכותית. הוסף אחד בכרטיסייה עוזר בינה מלאכותית.", "runsInOpenTerminal": "פועל בסשן הטרמינל הפתוח שלך.", - "runInTerminal": "לָרוּץ" + "runInTerminal": "לָרוּץ", + "terminalContextPrefill": "הנה פלט הטרמינל שלי:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "אפשרו לתכונות אחרות להשתמש במפתח ה-API של ספק הבינה המלאכותית שלכם עבור בקשות משלהן. המפתח לעולם לא יועתק, ותוכלו לבטל אותו בכל עת." + } }, "nav": { "ai": "בינה מלאכותית" @@ -67,23 +113,6 @@ "aiEnableDesc": "מוסיף עוזר שקורא את ההגדרות שלך ומציע שינויים שאתה מאשר. נדרש ספק שאתה מספק, כגון אולמה מקומי.", "aiNote": "שום דבר לא נשלח לשום מקום עד שתוסיף ספק ותשלח הודעה." }, - "settings": { - "admin": { - "globallyEnabled": { - "label": "עוזר בינה מלאכותית", - "description": "אפשר למשתמשים להפעיל את עוזר הבינה המלאכותית. כאשר זה כבוי, העוזר מוסתר וחסום עבור כולם." - }, - "privateEndpoints": { - "label": "מארחים פרטיים של בינה מלאכותית מורשים" - } - }, - "host": { - "enableAiAssistant": { - "label": "הפעל את עוזר הבינה המלאכותית", - "description": "אפשר לעוזר הבינה המלאכותית לסייע במסוף של מארח זה. כבוי כברירת מחדל, ועדיין נדרשת הפעלת בינה מלאכותית עבור חשבונך." - } - } - }, "hosts": { "docsLink": "הצג מסמכים" } diff --git a/plugins/ai/locales/translated/hi_IN.json b/plugins/ai/locales/translated/hi_IN.json index fc6603d21..e75d94f64 100644 --- a/plugins/ai/locales/translated/hi_IN.json +++ b/plugins/ai/locales/translated/hi_IN.json @@ -1,89 +1,118 @@ { - "ai": { - "title": "सहायक", - "send": "भेजना", - "stop": "रुकना", - "save": "बचाना", - "cancel": "रद्द करना", - "running": "दौड़ना", - "approve": "मंज़ूरी देना", - "reject": "अस्वीकार करना", - "inputPlaceholder": "अपने सर्वरों के बारे में पूछें, या प्रस्तावित परिवर्तन का वर्णन करें।", - "selectProvider": "एक प्रदाता का चयन करें", - "providerSettings": "प्रदाता सेटिंग्स", - "addProvider": "प्रदाता जोड़ें", - "editProvider": "प्रदाता संपादित करें", - "removeProvider": "प्रदाता को हटाएँ", - "providerType": "प्रदाता", - "providerLabel": "नाम", - "providerLabelPlaceholder": "उदाहरण के लिए: स्थानीय ओलामा", - "baseUrl": "सर्वर पता", - "apiKey": "एपीआई कुंजी", - "defaultModel": "डिफ़ॉल्ट मॉडल", - "defaultModelPlaceholder": "उदाहरण के लिए: llama3.1 या claude-opus-5", - "labelRequired": "इस प्रदाता को एक नाम दें", - "providerSaveFailed": "प्रदाता को बचाया नहीं जा सका", - "providerUpdated": "प्रदाता ने अपडेट किया", - "providerDeleteFailed": "प्रदाता को हटाया नहीं जा सका", - "privateEndpointHint": "आपके निजी नेटवर्क पर मौजूद पतों के लिए पहले एक प्रशासक द्वारा होस्ट को अनुमति देना आवश्यक है।", - "providerOllama": "ओलामा", - "providerAnthropic": "anthropic", - "providerOpenai": "ओपनएआई", - "providerGemini": "गूगल जेमिनी", - "providerOpenaiCompatible": "OpenAI संगत", - "toolArguments": "इनपुट", - "toolResult": "परिणाम", - "statusApplied": "लागू किया गया", - "statusRejected": "अस्वीकार कर दिया", - "proposalApplied": "परिवर्तन लागू हो गया", - "proposalApplyFailed": "परिवर्तन लागू नहीं हो सका", - "proposalRejectFailed": "परिवर्तन को अस्वीकार नहीं किया जा सका", - "enableTitle": "एआई सहायक को सक्रिय करें", - "enableDescription": "सहायक को आपकी सेटअप प्रक्रिया पढ़ने दें और वह आपके अनुमोदन के लिए परिवर्तन सुझाएगा।", - "readOnlyCommands": "केवल पढ़ने योग्य डायग्नोस्टिक कमांड की अनुमति दें", - "readOnlyCommandsDescription": "सहायक बिना पूछे ही df और uptime जैसे कुछ सुरक्षित कमांड चला सकता है। सर्वर में कोई भी बदलाव करने का प्रस्ताव हमेशा पहले दिया जाता है।", - "modelDetectFailed": "प्रदाता से संपर्क नहीं हो सका, इसलिए यह एक सामान्य सूची है। आप किसी भी मॉडल का नाम टाइप कर सकते हैं।", - "modelCustom": "मॉडल का नाम दर्ज करें", - "modelRefresh": "सूची रीफ़्रेश करें", - "modelPlaceholder": "कोई मॉडल चुनें या टाइप करें", - "attachHint": "किसी होस्ट, स्निपेट या ऑटोमेशन को संदर्भित करने के लिए @ टाइप करें। आपके अनुमोदन के लिए परिवर्तन प्रस्तावित किए जा रहे हैं।", - "runCommandTitle": "कमांड चलाएँ", - "assistant": "एआई सहायक", - "terminalPanelEmpty": "इस होस्ट के बारे में असिस्टेंट से पूछें। किसी भी स्थिति में बदलाव के लिए पहले आपकी स्वीकृति आवश्यक है।", - "terminalPanelPlaceholder": "इस होस्ट के बारे में पूछें...", - "noProvidersConfigured": "अभी तक कोई एआई प्रदाता कॉन्फ़िगर नहीं किया गया है। एआई सहायक टैब में एक जोड़ें।", - "runsInOpenTerminal": "यह आपके खुले टर्मिनल सत्र में चलता है।", - "runInTerminal": "दौड़ना" - }, - "nav": { - "ai": "ऐ" - }, - "onboarding": { - "aiTitle": "एआई सहायक", - "aiIntro": "टर्मिक्स में एक वैकल्पिक एआई सहायक शामिल हो सकता है। आप इसे बाद में अपनी सेटिंग्स में बदल सकते हैं।", - "aiSkipTitle": "इसे बंद कर दो", - "aiSkipDesc": "टर्मिक्स अभी की तरह ही काम करता है। असिस्टेंट छिपा रहता है।", - "aiEnableTitle": "इसे चालू करें", - "aiEnableDesc": "यह एक सहायक सुविधा जोड़ता है जो आपके सेटअप को पढ़ता है और आपके द्वारा स्वीकृत किए जाने वाले परिवर्तनों का सुझाव देता है। इसके लिए आपको एक प्रदाता उपलब्ध कराना होगा, जैसे कि स्थानीय ओलामा।", - "aiNote": "जब तक आप कोई प्रदाता नहीं जोड़ते और संदेश नहीं भेजते, तब तक कुछ भी कहीं नहीं भेजा जाता।" + "permissions": { + "use": { + "title": "Use the assistant", + "description": "Open the assistant and ask it things." + }, + "manage_providers": { + "title": "Manage providers", + "description": "Add, edit and remove the AI providers and their API keys." + }, + "apply_proposals": { + "title": "Apply proposals", + "description": "Let the assistant carry out the changes it suggests." + }, + "services.use": { + "title": "Use AI from other features", + "description": "Other features may call the assistant on your behalf." + }, + "secrets.share": { + "title": "Share the API key", + "description": "Other features may use the stored AI API key without seeing it." + } }, "settings": { + "assistantUnavailable": "The AI assistant is turned off on this server.", + "providersNeedOptIn": "Turn on the AI assistant above to add providers.", "admin": { "globallyEnabled": { - "label": "एआई सहायक", - "description": "उपयोगकर्ताओं को एआई सहायक चालू करने की अनुमति दें। जब यह बंद होगा, तो सहायक सभी के लिए छिपा हुआ और अवरुद्ध रहेगा।" + "label": "AI assistant", + "description": "Let users turn on the AI assistant. While this is off, the assistant is hidden and blocked for everyone." }, "privateEndpoints": { - "label": "निजी एआई होस्ट की अनुमति दी गई" + "label": "Allowed private AI hosts", + "description": "Hosts on your private network that users may point a provider at, such as a self-hosted Ollama. Put one host on each line." } }, "host": { "enableAiAssistant": { - "label": "एआई असिस्टेंट को सक्षम करें", - "description": "इस होस्ट के टर्मिनल में एआई सहायक को मदद करने की अनुमति दें। यह डिफ़ॉल्ट रूप से बंद है, लेकिन आपके खाते के लिए एआई को सक्षम करना आवश्यक है।" + "label": "Enable AI Assistant", + "description": "Allow the AI assistant to help in this host's terminal. Off by default, and still needs AI enabled for your account." } } }, + "ai": { + "title": "Assistant", + "send": "Send", + "stop": "स्टॉप", + "save": "सहेजें", + "cancel": "रद्द करें", + "running": "चल रहे", + "approve": "Approve", + "reject": "Reject", + "inputPlaceholder": "Ask about your servers, or describe a change to propose", + "selectProvider": "Select a provider", + "providerSettings": "Provider settings", + "addProvider": "Add provider", + "editProvider": "Edit provider", + "removeProvider": "Remove provider", + "providerType": "Provider", + "providerLabel": "नाम", + "providerLabelPlaceholder": "For example: Local Ollama", + "baseUrl": "Server address", + "apiKey": "API key", + "defaultModel": "Default model", + "defaultModelPlaceholder": "For example: llama3.1 or claude-opus-5", + "labelRequired": "Give this provider a name", + "providerSaveFailed": "Could not save the provider", + "providerUpdated": "Provider updated", + "providerDeleteFailed": "Could not remove the provider", + "privateEndpointHint": "Addresses on your private network need an administrator to allow the host first.", + "providerOllama": "Ollama", + "providerAnthropic": "Anthropic", + "providerOpenai": "OpenAI", + "providerGemini": "Google Gemini", + "providerOpenaiCompatible": "OpenAI compatible", + "toolArguments": "इनपुट", + "toolResult": "Result", + "statusApplied": "Applied", + "statusRejected": "Rejected", + "proposalApplied": "Change applied", + "proposalApplyFailed": "Could not apply the change", + "proposalRejectFailed": "Could not reject the change", + "enableTitle": "Enable the AI assistant", + "enableDescription": "Let the assistant read your setup and suggest changes for you to approve.", + "readOnlyCommands": "Allow read-only diagnostic commands", + "readOnlyCommandsDescription": "The assistant may run a short list of safe commands like df and uptime without asking each time. Anything that changes a server is always proposed first.", + "modelDetectFailed": "Could not reach the provider, so this is a general list. You can type any model name.", + "modelCustom": "Enter a model name", + "modelRefresh": "Refresh list", + "modelPlaceholder": "Choose or type a model", + "attachHint": "Type @ to reference a host, snippet or automation. Changes are proposed for you to approve.", + "runCommandTitle": "Run command", + "assistant": "AI Assistant", + "terminalPanelEmpty": "Ask the assistant about this host. Anything that changes state needs your approval first.", + "terminalPanelPlaceholder": "Ask about this host...", + "noProvidersConfigured": "No AI provider is configured yet. Add one in the AI assistant tab.", + "runsInOpenTerminal": "Runs in your open terminal session.", + "runInTerminal": "चलाएं", + "terminalContextPrefill": "Here is my terminal output:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Let other features use your AI provider API key for their own requests. The key is never copied, and you can revoke this at any time." + } + }, + "nav": { + "ai": "AI" + }, + "onboarding": { + "aiTitle": "AI assistant", + "aiIntro": "Termix can include an optional AI assistant. You can change this later in your settings.", + "aiSkipTitle": "Leave it off", + "aiSkipDesc": "Termix works as it does now. The assistant stays hidden.", + "aiEnableTitle": "Turn it on", + "aiEnableDesc": "Adds an assistant that reads your setup and suggests changes you approve. Needs a provider you supply, such as a local Ollama.", + "aiNote": "Nothing is sent anywhere until you add a provider and send a message." + }, "hosts": { "docsLink": "दस्तावेज़ देखें" } diff --git a/plugins/ai/locales/translated/hu_HU.json b/plugins/ai/locales/translated/hu_HU.json index 43b9b6b70..29f3df4a5 100644 --- a/plugins/ai/locales/translated/hu_HU.json +++ b/plugins/ai/locales/translated/hu_HU.json @@ -1,4 +1,46 @@ { + "permissions": { + "use": { + "title": "Használja az asszisztenst", + "description": "Nyisd meg az asszisztenst, és kérdezz tőle dolgokat." + }, + "manage_providers": { + "title": "Szolgáltatók kezelése", + "description": "MI-szolgáltatók és API-kulcsaik hozzáadása, szerkesztése és eltávolítása." + }, + "apply_proposals": { + "title": "Javaslatok alkalmazása", + "description": "Hagyd, hogy az asszisztens végrehajtsa a javasolt módosításokat." + }, + "services.use": { + "title": "Használja a mesterséges intelligenciát más funkciókból", + "description": "Más funkciók felhívhatják az asszisztenst az Ön nevében." + }, + "secrets.share": { + "title": "API-kulcs megosztása", + "description": "Más funkciók használhatják a tárolt AI API-kulcsot anélkül, hogy látnák azt." + } + }, + "settings": { + "assistantUnavailable": "A mesterséges intelligencia asszisztens ki van kapcsolva ezen a szerveren.", + "providersNeedOptIn": "Kapcsolja be a fenti AI asszisztenst a szolgáltatók hozzáadásához.", + "admin": { + "globallyEnabled": { + "label": "MI asszisztens", + "description": "Engedélyezheti a felhasználóknak a mesterséges intelligencia asszisztens bekapcsolását. Amíg ez ki van kapcsolva, az asszisztens rejtett és blokkolt mindenki számára." + }, + "privateEndpoints": { + "label": "Engedélyezett privát AI-gazdagépek", + "description": "Privát hálózatán található hosztok, amelyekre a felhasználók szolgáltatót irányíthatnak, például egy saját hosztot futtató Ollama. Minden sorba egy hosztot írjon be." + } + }, + "host": { + "enableAiAssistant": { + "label": "AI asszisztens engedélyezése", + "description": "Engedélyezi a mesterséges intelligencia asszisztensének a gazdagép terminálján való segítséget. Alapértelmezés szerint ki van kapcsolva, de továbbra is engedélyeznie kell a mesterséges intelligenciát a fiókjában." + } + } + }, "ai": { "title": "Helyettes", "send": "Elküld", @@ -53,7 +95,11 @@ "terminalPanelPlaceholder": "Kérdezz rá erre a házigazdára...", "noProvidersConfigured": "Még nincs konfigurálva AI-szolgáltató. Adjon hozzá egyet az AI-asszisztens fülön.", "runsInOpenTerminal": "A megnyitott terminál munkamenetben fut.", - "runInTerminal": "Fut" + "runInTerminal": "Fut", + "terminalContextPrefill": "Itt a terminál kimenete:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Engedélyezd más funkcióknak a mesterséges intelligencia szolgáltató API-kulcsának használatát a saját kéréseikhez. A kulcs soha nem kerül másolásra, és ezt bármikor visszavonhatod." + } }, "nav": { "ai": "MI" @@ -67,23 +113,6 @@ "aiEnableDesc": "Hozzáad egy asszisztenst, amely beolvassa a beállításait, és javaslatokat tesz az Ön által jóváhagyott módosításokra. Szükség van egy Ön által biztosított szolgáltatóra, például egy helyi Ollama szakemberre.", "aiNote": "Semmi sem kerül sehova, amíg nem adsz hozzá egy szolgáltatót és nem küldesz üzenetet." }, - "settings": { - "admin": { - "globallyEnabled": { - "label": "MI asszisztens", - "description": "Engedélyezheti a felhasználóknak a mesterséges intelligencia asszisztens bekapcsolását. Amíg ez ki van kapcsolva, az asszisztens rejtett és blokkolt mindenki számára." - }, - "privateEndpoints": { - "label": "Engedélyezett privát AI-gazdagépek" - } - }, - "host": { - "enableAiAssistant": { - "label": "AI asszisztens engedélyezése", - "description": "Engedélyezi a mesterséges intelligencia asszisztensének a gazdagép terminálján való segítséget. Alapértelmezés szerint ki van kapcsolva, de továbbra is engedélyeznie kell a mesterséges intelligenciát a fiókjában." - } - } - }, "hosts": { "docsLink": "Dokumentumok megtekintése" } diff --git a/plugins/ai/locales/translated/id_ID.json b/plugins/ai/locales/translated/id_ID.json index d88244757..7b5758ffa 100644 --- a/plugins/ai/locales/translated/id_ID.json +++ b/plugins/ai/locales/translated/id_ID.json @@ -1,90 +1,119 @@ { + "permissions": { + "use": { + "title": "Use the assistant", + "description": "Open the assistant and ask it things." + }, + "manage_providers": { + "title": "Manage providers", + "description": "Add, edit and remove the AI providers and their API keys." + }, + "apply_proposals": { + "title": "Apply proposals", + "description": "Let the assistant carry out the changes it suggests." + }, + "services.use": { + "title": "Use AI from other features", + "description": "Other features may call the assistant on your behalf." + }, + "secrets.share": { + "title": "Share the API key", + "description": "Other features may use the stored AI API key without seeing it." + } + }, + "settings": { + "assistantUnavailable": "The AI assistant is turned off on this server.", + "providersNeedOptIn": "Turn on the AI assistant above to add providers.", + "admin": { + "globallyEnabled": { + "label": "AI assistant", + "description": "Let users turn on the AI assistant. While this is off, the assistant is hidden and blocked for everyone." + }, + "privateEndpoints": { + "label": "Allowed private AI hosts", + "description": "Hosts on your private network that users may point a provider at, such as a self-hosted Ollama. Put one host on each line." + } + }, + "host": { + "enableAiAssistant": { + "label": "Enable AI Assistant", + "description": "Allow the AI assistant to help in this host's terminal. Off by default, and still needs AI enabled for your account." + } + } + }, "ai": { - "title": "Asisten", - "send": "Mengirim", - "stop": "Berhenti", - "save": "Menyimpan", - "cancel": "Membatalkan", - "running": "berlari", - "approve": "Menyetujui", - "reject": "Menolak", - "inputPlaceholder": "Tanyakan tentang server Anda, atau jelaskan perubahan yang ingin Anda usulkan.", - "selectProvider": "Pilih penyedia", - "providerSettings": "Pengaturan penyedia", - "addProvider": "Tambahkan penyedia", - "editProvider": "Penyedia pengeditan", - "removeProvider": "Hapus penyedia", - "providerType": "Penyedia", - "providerLabel": "Nama", - "providerLabelPlaceholder": "Contohnya: Ollama setempat", - "baseUrl": "Alamat server", - "apiKey": "Kunci API", - "defaultModel": "Model default", - "defaultModelPlaceholder": "Misalnya: llama3.1 atau claude-opus-5", - "labelRequired": "Beri nama penyedia ini", - "providerSaveFailed": "Penyedia layanan tidak dapat disimpan.", - "providerUpdated": "Penyedia diperbarui", - "providerDeleteFailed": "Penyedia layanan tidak dapat dihapus.", - "privateEndpointHint": "Alamat-alamat di jaringan pribadi Anda memerlukan izin administrator terlebih dahulu untuk host tersebut.", + "title": "Assistant", + "send": "Send", + "stop": "Stop", + "save": "Save", + "cancel": "Cancel", + "running": "running", + "approve": "Approve", + "reject": "Reject", + "inputPlaceholder": "Ask about your servers, or describe a change to propose", + "selectProvider": "Select a provider", + "providerSettings": "Provider settings", + "addProvider": "Add provider", + "editProvider": "Edit provider", + "removeProvider": "Remove provider", + "providerType": "Provider", + "providerLabel": "Name", + "providerLabelPlaceholder": "For example: Local Ollama", + "baseUrl": "Server address", + "apiKey": "API key", + "defaultModel": "Default model", + "defaultModelPlaceholder": "For example: llama3.1 or claude-opus-5", + "labelRequired": "Give this provider a name", + "providerSaveFailed": "Could not save the provider", + "providerUpdated": "Provider updated", + "providerDeleteFailed": "Could not remove the provider", + "privateEndpointHint": "Addresses on your private network need an administrator to allow the host first.", "providerOllama": "Ollama", - "providerAnthropic": "Antropis", + "providerAnthropic": "Anthropic", "providerOpenai": "OpenAI", "providerGemini": "Google Gemini", - "providerOpenaiCompatible": "Kompatibel dengan OpenAI", - "toolArguments": "Masukan", - "toolResult": "Hasil", - "statusApplied": "Terapan", - "statusRejected": "Ditolak", - "proposalApplied": "Perubahan diterapkan", - "proposalApplyFailed": "Perubahan tidak dapat diterapkan.", - "proposalRejectFailed": "Tidak bisa menolak perubahan tersebut", - "enableTitle": "Aktifkan asisten AI", - "enableDescription": "Biarkan asisten membaca pengaturan Anda dan menyarankan perubahan yang perlu Anda setujui.", - "readOnlyCommands": "Izinkan perintah diagnostik hanya baca.", - "readOnlyCommandsDescription": "Asisten dapat menjalankan daftar singkat perintah aman seperti df dan uptime tanpa bertanya setiap kali. Apa pun yang mengubah server selalu diusulkan terlebih dahulu.", - "modelDetectFailed": "Tidak dapat menghubungi penyedia, jadi ini adalah daftar umum. Anda dapat mengetikkan nama model apa pun.", - "modelCustom": "Masukkan nama model", - "modelRefresh": "Perbarui daftar", - "modelPlaceholder": "Pilih atau ketik model", - "attachHint": "Ketik @ untuk merujuk ke host, cuplikan kode, atau otomatisasi. Perubahan diajukan untuk Anda setujui.", - "runCommandTitle": "Jalankan perintah", - "assistant": "Asisten AI", - "terminalPanelEmpty": "Tanyakan kepada asisten tentang tuan rumah ini. Segala sesuatu yang berubah status memerlukan persetujuan Anda terlebih dahulu.", - "terminalPanelPlaceholder": "Tanyakan tentang tuan rumah ini...", - "noProvidersConfigured": "Belum ada penyedia AI yang dikonfigurasi. Tambahkan satu di tab asisten AI.", - "runsInOpenTerminal": "Berjalan di sesi terminal Anda yang sedang terbuka.", - "runInTerminal": "Berlari" + "providerOpenaiCompatible": "OpenAI compatible", + "toolArguments": "Input", + "toolResult": "Result", + "statusApplied": "Applied", + "statusRejected": "Rejected", + "proposalApplied": "Change applied", + "proposalApplyFailed": "Could not apply the change", + "proposalRejectFailed": "Could not reject the change", + "enableTitle": "Enable the AI assistant", + "enableDescription": "Let the assistant read your setup and suggest changes for you to approve.", + "readOnlyCommands": "Allow read-only diagnostic commands", + "readOnlyCommandsDescription": "The assistant may run a short list of safe commands like df and uptime without asking each time. Anything that changes a server is always proposed first.", + "modelDetectFailed": "Could not reach the provider, so this is a general list. You can type any model name.", + "modelCustom": "Enter a model name", + "modelRefresh": "Refresh list", + "modelPlaceholder": "Choose or type a model", + "attachHint": "Type @ to reference a host, snippet or automation. Changes are proposed for you to approve.", + "runCommandTitle": "Run command", + "assistant": "AI Assistant", + "terminalPanelEmpty": "Ask the assistant about this host. Anything that changes state needs your approval first.", + "terminalPanelPlaceholder": "Ask about this host...", + "noProvidersConfigured": "No AI provider is configured yet. Add one in the AI assistant tab.", + "runsInOpenTerminal": "Runs in your open terminal session.", + "runInTerminal": "Run", + "terminalContextPrefill": "Here is my terminal output:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Let other features use your AI provider API key for their own requests. The key is never copied, and you can revoke this at any time." + } }, "nav": { "ai": "AI" }, "onboarding": { - "aiTitle": "Asisten AI", - "aiIntro": "Termix dapat menyertakan asisten AI opsional. Anda dapat mengubahnya nanti di pengaturan Anda.", - "aiSkipTitle": "Biarkan saja", - "aiSkipDesc": "Termix berfungsi seperti sekarang. Asisten tetap tersembunyi.", - "aiEnableTitle": "Nyalakan", - "aiEnableDesc": "Menambahkan asisten yang membaca pengaturan Anda dan menyarankan perubahan yang Anda setujui. Membutuhkan penyedia yang Anda berikan, seperti Ollama lokal.", - "aiNote": "Tidak ada data yang dikirim ke mana pun sampai Anda menambahkan penyedia dan mengirim pesan." - }, - "settings": { - "admin": { - "globallyEnabled": { - "label": "Asisten AI", - "description": "Izinkan pengguna untuk mengaktifkan asisten AI. Saat dinonaktifkan, asisten akan disembunyikan dan diblokir untuk semua orang." - }, - "privateEndpoints": { - "label": "Host AI pribadi yang diizinkan" - } - }, - "host": { - "enableAiAssistant": { - "label": "Aktifkan Asisten AI", - "description": "Izinkan asisten AI untuk membantu di terminal host ini. Secara default dinonaktifkan, dan AI tetap perlu diaktifkan untuk akun Anda." - } - } + "aiTitle": "AI assistant", + "aiIntro": "Termix can include an optional AI assistant. You can change this later in your settings.", + "aiSkipTitle": "Leave it off", + "aiSkipDesc": "Termix works as it does now. The assistant stays hidden.", + "aiEnableTitle": "Turn it on", + "aiEnableDesc": "Adds an assistant that reads your setup and suggests changes you approve. Needs a provider you supply, such as a local Ollama.", + "aiNote": "Nothing is sent anywhere until you add a provider and send a message." }, "hosts": { - "docsLink": "Lihat dokumen" + "docsLink": "View docs" } } diff --git a/plugins/ai/locales/translated/it_IT.json b/plugins/ai/locales/translated/it_IT.json index 860f734f9..5a0a51a67 100644 --- a/plugins/ai/locales/translated/it_IT.json +++ b/plugins/ai/locales/translated/it_IT.json @@ -1,11 +1,53 @@ { + "permissions": { + "use": { + "title": "Utilizzare l'assistente", + "description": "Apri l'assistente e ponigli delle domande." + }, + "manage_providers": { + "title": "Gestire i fornitori", + "description": "Aggiungi, modifica e rimuovi i provider di intelligenza artificiale e le relative chiavi API." + }, + "apply_proposals": { + "title": "Presentare proposte", + "description": "Lascia che l'assistente esegua le modifiche suggerite." + }, + "services.use": { + "title": "Utilizzare l'intelligenza artificiale da altre funzionalità", + "description": "Altre funzioni potrebbero attivare l'assistente per tuo conto." + }, + "secrets.share": { + "title": "Condividi la chiave API", + "description": "Altre funzionalità potrebbero utilizzare la chiave API AI memorizzata senza visualizzarla." + } + }, + "settings": { + "assistantUnavailable": "L'assistente IA è disattivato su questo server.", + "providersNeedOptIn": "Attiva l'assistente AI qui sopra per aggiungere i fornitori.", + "admin": { + "globallyEnabled": { + "label": "Assistente basato sull'intelligenza artificiale", + "description": "Consenti agli utenti di attivare l'assistente AI. Quando è disattivato, l'assistente è nascosto e bloccato per tutti." + }, + "privateEndpoints": { + "label": "Host di IA privati consentiti", + "description": "Host sulla tua rete privata a cui gli utenti possono indirizzare un provider, come ad esempio un'installazione self-hosted di Ollama. Assegna un host a ciascuna linea." + } + }, + "host": { + "enableAiAssistant": { + "label": "Assistente AI per l'innovazione", + "description": "Consenti all'assistente IA di fornire assistenza nel terminale di questo host. Disattivato per impostazione predefinita, ma è necessario abilitare l'IA per il tuo account." + } + } + }, "ai": { "title": "Assistente", "send": "Inviare", - "stop": "Fermare", + "stop": "Stop", "save": "Salva", - "cancel": "Cancellare", - "running": "corsa", + "cancel": "Annulla", + "running": "in esecuzione", "approve": "Approvare", "reject": "Rifiutare", "inputPlaceholder": "Chiedi informazioni sui tuoi server o descrivi una modifica da proporre", @@ -31,7 +73,7 @@ "providerOpenai": "OpenAI", "providerGemini": "Google Gemini", "providerOpenaiCompatible": "Compatibile con OpenAI", - "toolArguments": "Ingresso", + "toolArguments": "Input", "toolResult": "Risultato", "statusApplied": "Applicato", "statusRejected": "Respinto", @@ -53,7 +95,11 @@ "terminalPanelPlaceholder": "Chiedi informazioni su questo host...", "noProvidersConfigured": "Non è ancora configurato alcun provider di IA. Aggiungine uno nella scheda Assistente IA.", "runsInOpenTerminal": "Viene eseguito nella sessione del terminale aperta.", - "runInTerminal": "Correre" + "runInTerminal": "Esegui", + "terminalContextPrefill": "Ecco l'output del mio terminale:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Consenti ad altre funzionalità di utilizzare la tua chiave API del provider AI per le proprie richieste. La chiave non viene mai copiata e puoi revocarla in qualsiasi momento." + } }, "nav": { "ai": "IA" @@ -67,23 +113,6 @@ "aiEnableDesc": "Aggiunge un assistente che legge la tua configurazione e suggerisce modifiche che approvi. Richiede un provider che tu fornisca, come ad esempio un Ollama locale.", "aiNote": "Non viene inviato nulla finché non si aggiunge un provider e si invia un messaggio." }, - "settings": { - "admin": { - "globallyEnabled": { - "label": "Assistente basato sull'intelligenza artificiale", - "description": "Consenti agli utenti di attivare l'assistente AI. Quando è disattivato, l'assistente è nascosto e bloccato per tutti." - }, - "privateEndpoints": { - "label": "Host di IA privati consentiti" - } - }, - "host": { - "enableAiAssistant": { - "label": "Assistente AI per l'innovazione", - "description": "Consenti all'assistente IA di fornire assistenza nel terminale di questo host. Disattivato per impostazione predefinita, ma è necessario abilitare l'IA per il tuo account." - } - } - }, "hosts": { "docsLink": "Visualizza documentazione" } diff --git a/plugins/ai/locales/translated/ja_JP.json b/plugins/ai/locales/translated/ja_JP.json index 312788b6e..16c7460dd 100644 --- a/plugins/ai/locales/translated/ja_JP.json +++ b/plugins/ai/locales/translated/ja_JP.json @@ -1,11 +1,53 @@ { + "permissions": { + "use": { + "title": "アシスタントを使用する", + "description": "アシスタントを開いて、いろいろ質問してみてください。" + }, + "manage_providers": { + "title": "プロバイダーを管理する", + "description": "AIプロバイダーとそのAPIキーを追加、編集、削除できます。" + }, + "apply_proposals": { + "title": "提案を適用する", + "description": "アシスタントに提案された変更を実行させましょう。" + }, + "services.use": { + "title": "他の機能からAIを活用する", + "description": "その他の機能によっては、あなたに代わってアシスタントを呼び出す場合があります。" + }, + "secrets.share": { + "title": "APIキーを共有する", + "description": "他の機能は、保存されたAI APIキーを認識せずに使用する場合があります。" + } + }, + "settings": { + "assistantUnavailable": "このサーバーではAIアシスタントは無効になっています。", + "providersNeedOptIn": "上記のAIアシスタントをオンにして、プロバイダーを追加してください。", + "admin": { + "globallyEnabled": { + "label": "AIアシスタント", + "description": "ユーザーがAIアシスタントをオンにできるようにします。オフになっている間は、アシスタントは非表示になり、誰からも利用できなくなります。" + }, + "privateEndpoints": { + "label": "プライベートAIホストを許可", + "description": "ユーザーがプロバイダに指定できる、プライベートネットワーク上のホスト(自己ホスト型のOllamaなど)。各行にホストを1つずつ記述してください。" + } + }, + "host": { + "enableAiAssistant": { + "label": "AIアシスタントを有効にする", + "description": "このホストのターミナルでAIアシスタントによる支援を許可します。デフォルトでは無効になっており、アカウントでAIを有効にする必要があります。" + } + } + }, "ai": { "title": "アシスタント", "send": "送信", - "stop": "停止", + "stop": "ストップ", "save": "保存", "cancel": "キャンセル", - "running": "ランニング", + "running": "実行中", "approve": "承認する", "reject": "拒否する", "inputPlaceholder": "サーバーについて質問するか、変更案を説明する", @@ -31,7 +73,7 @@ "providerOpenai": "OpenAI", "providerGemini": "Google Gemini", "providerOpenaiCompatible": "OpenAI対応", - "toolArguments": "入力", + "toolArguments": "受信", "toolResult": "結果", "statusApplied": "適用済み", "statusRejected": "拒否されました", @@ -53,7 +95,11 @@ "terminalPanelPlaceholder": "このホストについて質問する...", "noProvidersConfigured": "AIプロバイダーがまだ設定されていません。AIアシスタントタブで追加してください。", "runsInOpenTerminal": "開いているターミナルセッションで実行されます。", - "runInTerminal": "走る" + "runInTerminal": "実行", + "terminalContextPrefill": "これが私のターミナル出力です:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "他の機能が、独自の要求にあなたのAIプロバイダーAPIキーを使用できるようにします。キーは決して複製されず、いつでも取り消すことができます。" + } }, "nav": { "ai": "AI" @@ -64,26 +110,9 @@ "aiSkipTitle": "オフにしておく", "aiSkipDesc": "Termixは現状のまま動作します。アシスタントは非表示のままです。", "aiEnableTitle": "電源を入れる", - "aiEnableDesc": "設定内容を読み取り、承認した上で変更案を提案するアシスタント機能を追加します。ローカルのOllamaなど、お客様ご自身で手配するプロバイダーが必要です。", + "aiEnableDesc": "設定を読み取り、承認した変更を提案するアシスタント機能を追加します。ローカルのOllamaなど、お客様ご自身で手配するプロバイダーが必要です。", "aiNote": "プロバイダーを追加してメッセージを送信するまで、データはどこにも送信されません。" }, - "settings": { - "admin": { - "globallyEnabled": { - "label": "AIアシスタント", - "description": "ユーザーがAIアシスタントをオンにできるようにします。オフになっている間は、アシスタントは非表示になり、誰からも利用できなくなります。" - }, - "privateEndpoints": { - "label": "プライベートAIホストを許可" - } - }, - "host": { - "enableAiAssistant": { - "label": "AIアシスタントを有効にする", - "description": "このホストのターミナルでAIアシスタントによる支援を許可します。デフォルトでは無効になっており、アカウントでAIを有効にする必要があります。" - } - } - }, "hosts": { "docsLink": "ドキュメントを表示" } diff --git a/plugins/ai/locales/translated/ko_KR.json b/plugins/ai/locales/translated/ko_KR.json index 96d6865bf..c95fc4f25 100644 --- a/plugins/ai/locales/translated/ko_KR.json +++ b/plugins/ai/locales/translated/ko_KR.json @@ -1,11 +1,53 @@ { + "permissions": { + "use": { + "title": "도우미를 사용하세요", + "description": "어시스턴트를 열고 질문을 해보세요." + }, + "manage_providers": { + "title": "공급자 관리", + "description": "AI 제공업체와 해당 API 키를 추가, 편집 및 삭제할 수 있습니다." + }, + "apply_proposals": { + "title": "제안서를 제출하세요", + "description": "도우미가 제안하는 변경 사항을 실행하도록 하세요." + }, + "services.use": { + "title": "다른 기능의 AI를 활용하세요", + "description": "다른 기능들이 사용자를 대신하여 어시스턴트에게 전화를 걸 수도 있습니다." + }, + "secrets.share": { + "title": "API 키를 공유하세요", + "description": "다른 기능들이 저장된 AI API 키를 직접 보지 않고도 사용할 수 있습니다." + } + }, + "settings": { + "assistantUnavailable": "이 서버에서는 AI 비서 기능이 꺼져 있습니다.", + "providersNeedOptIn": "위의 AI 도우미를 켜서 제공업체를 추가하세요.", + "admin": { + "globallyEnabled": { + "label": "AI 비서", + "description": "사용자가 AI 비서를 켜고 끌 수 있도록 하세요. AI 비서가 꺼져 있으면 모든 사용자에게 비서 기능이 숨겨지고 차단됩니다." + }, + "privateEndpoints": { + "label": "개인 AI 호스트 허용", + "description": "사용자가 공급자를 지정할 수 있는 개인 네트워크의 호스트(예: 자체 호스팅 Ollama)를 입력합니다. 각 줄에 호스트를 하나씩 입력하십시오." + } + }, + "host": { + "enableAiAssistant": { + "label": "AI 어시스턴트 활성화", + "description": "이 호스트의 터미널에서 AI 도우미의 도움을 받을 수 있도록 허용합니다. 기본적으로 비활성화되어 있으며, 계정에 AI 기능이 활성화되어 있어야 합니다." + } + } + }, "ai": { "title": "어시스턴트", "send": "보내다", - "stop": "멈추다", - "save": "구하다", + "stop": "스톱", + "save": "저장", "cancel": "취소", - "running": "달리기", + "running": "실행 중", "approve": "승인하다", "reject": "거부하다", "inputPlaceholder": "서버에 대해 문의하거나, 변경 사항을 제안해 보세요.", @@ -53,7 +95,11 @@ "terminalPanelPlaceholder": "이 호스트에 대해 문의해 보세요...", "noProvidersConfigured": "아직 AI 제공업체가 구성되지 않았습니다. AI 도우미 탭에서 추가하세요.", "runsInOpenTerminal": "열려 있는 터미널 세션에서 실행됩니다.", - "runInTerminal": "달리다" + "runInTerminal": "실행", + "terminalContextPrefill": "다음은 제 터미널 출력 결과입니다:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "다른 기능에서 AI 제공업체 API 키를 사용하여 자체 요청을 처리할 수 있도록 허용합니다. 키는 절대 복사되지 않으며 언제든지 취소할 수 있습니다." + } }, "nav": { "ai": "일체 포함" @@ -67,23 +113,6 @@ "aiEnableDesc": "설정을 읽고 사용자가 승인하는 변경 사항을 제안하는 도우미를 추가합니다. 사용자가 제공하는 공급업체(예: 지역 Ollama)가 필요합니다.", "aiNote": "공급자를 추가하고 메시지를 보내기 전까지는 아무것도 전송되지 않습니다." }, - "settings": { - "admin": { - "globallyEnabled": { - "label": "AI 비서", - "description": "사용자가 AI 비서를 켜고 끌 수 있도록 하세요. AI 비서가 꺼져 있으면 모든 사용자에게 비서 기능이 숨겨지고 차단됩니다." - }, - "privateEndpoints": { - "label": "개인 AI 호스트 허용" - } - }, - "host": { - "enableAiAssistant": { - "label": "AI 어시스턴트 활성화", - "description": "이 호스트의 터미널에서 AI 도우미의 도움을 받을 수 있도록 허용합니다. 기본적으로 비활성화되어 있으며, 계정에 AI 기능이 활성화되어 있어야 합니다." - } - } - }, "hosts": { "docsLink": "문서 보기" } diff --git a/plugins/ai/locales/translated/nl_NL.json b/plugins/ai/locales/translated/nl_NL.json index 0e37ce183..c601bcef6 100644 --- a/plugins/ai/locales/translated/nl_NL.json +++ b/plugins/ai/locales/translated/nl_NL.json @@ -1,4 +1,46 @@ { + "permissions": { + "use": { + "title": "Gebruik de assistent", + "description": "Open de assistent en stel er vragen aan." + }, + "manage_providers": { + "title": "Beheer aanbieders", + "description": "AI-providers en hun API-sleutels toevoegen, bewerken en verwijderen." + }, + "apply_proposals": { + "title": "Dien voorstellen in", + "description": "Laat de assistent de voorgestelde wijzigingen doorvoeren." + }, + "services.use": { + "title": "Gebruik AI van andere functies", + "description": "Andere functies kunnen de assistent namens u inschakelen." + }, + "secrets.share": { + "title": "Deel de API-sleutel", + "description": "Andere functies kunnen de opgeslagen AI API-sleutel gebruiken zonder deze te zien." + } + }, + "settings": { + "assistantUnavailable": "De AI-assistent is op deze server uitgeschakeld.", + "providersNeedOptIn": "Schakel de AI-assistent hierboven in om aanbieders toe te voegen.", + "admin": { + "globallyEnabled": { + "label": "AI-assistent", + "description": "Gebruikers kunnen de AI-assistent inschakelen. Wanneer deze is uitgeschakeld, is de assistent verborgen en voor iedereen geblokkeerd." + }, + "privateEndpoints": { + "label": "Toegestane privé-AI-hosts", + "description": "Hosts op uw privénetwerk waarnaar gebruikers een provider kunnen verwijzen, zoals een zelfgehoste Ollama. Plaats één host per lijn." + } + }, + "host": { + "enableAiAssistant": { + "label": "AI-assistent inschakelen", + "description": "Sta de AI-assistent toe om te helpen in de terminal van deze host. Standaard uitgeschakeld, maar AI moet nog steeds voor uw account zijn ingeschakeld." + } + } + }, "ai": { "title": "Assistent", "send": "Versturen", @@ -53,7 +95,11 @@ "terminalPanelPlaceholder": "Vraag naar deze host...", "noProvidersConfigured": "Er is nog geen AI-provider geconfigureerd. Voeg er een toe via het tabblad AI-assistent.", "runsInOpenTerminal": "Wordt uitgevoerd in uw geopende terminalsessie.", - "runInTerminal": "Loop" + "runInTerminal": "Loop", + "terminalContextPrefill": "Hier is mijn terminaluitvoer:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Laat andere functies uw API-sleutel van de AI-provider gebruiken voor hun eigen verzoeken. De sleutel wordt nooit gekopieerd en u kunt deze op elk moment intrekken." + } }, "nav": { "ai": "AI" @@ -67,23 +113,6 @@ "aiEnableDesc": "Voegt een assistent toe die je instellingen leest en wijzigingen voorstelt die je kunt goedkeuren. Vereist een leverancier die je zelf aanlevert, zoals een lokale Ollama.", "aiNote": "Er wordt niets verzonden totdat je een provider toevoegt en een bericht verstuurt." }, - "settings": { - "admin": { - "globallyEnabled": { - "label": "AI-assistent", - "description": "Gebruikers kunnen de AI-assistent inschakelen. Wanneer deze is uitgeschakeld, is de assistent verborgen en voor iedereen geblokkeerd." - }, - "privateEndpoints": { - "label": "Toegestane privé-AI-hosts" - } - }, - "host": { - "enableAiAssistant": { - "label": "AI-assistent inschakelen", - "description": "Sta de AI-assistent toe om te helpen in de terminal van deze host. Standaard uitgeschakeld, maar AI moet nog steeds voor uw account zijn ingeschakeld." - } - } - }, "hosts": { "docsLink": "Documenten bekijken" } diff --git a/plugins/ai/locales/translated/no_NO.json b/plugins/ai/locales/translated/no_NO.json index 62affb69f..3dd895392 100644 --- a/plugins/ai/locales/translated/no_NO.json +++ b/plugins/ai/locales/translated/no_NO.json @@ -1,90 +1,119 @@ { + "permissions": { + "use": { + "title": "Use the assistant", + "description": "Open the assistant and ask it things." + }, + "manage_providers": { + "title": "Manage providers", + "description": "Add, edit and remove the AI providers and their API keys." + }, + "apply_proposals": { + "title": "Apply proposals", + "description": "Let the assistant carry out the changes it suggests." + }, + "services.use": { + "title": "Use AI from other features", + "description": "Other features may call the assistant on your behalf." + }, + "secrets.share": { + "title": "Share the API key", + "description": "Other features may use the stored AI API key without seeing it." + } + }, + "settings": { + "assistantUnavailable": "The AI assistant is turned off on this server.", + "providersNeedOptIn": "Turn on the AI assistant above to add providers.", + "admin": { + "globallyEnabled": { + "label": "AI assistant", + "description": "Let users turn on the AI assistant. While this is off, the assistant is hidden and blocked for everyone." + }, + "privateEndpoints": { + "label": "Allowed private AI hosts", + "description": "Hosts on your private network that users may point a provider at, such as a self-hosted Ollama. Put one host on each line." + } + }, + "host": { + "enableAiAssistant": { + "label": "Enable AI Assistant", + "description": "Allow the AI assistant to help in this host's terminal. Off by default, and still needs AI enabled for your account." + } + } + }, "ai": { - "title": "Assistent", - "send": "Sende", - "stop": "Stoppe", - "save": "Spare", - "cancel": "Kansellere", - "running": "løping", - "approve": "Vedta", - "reject": "Avvis", - "inputPlaceholder": "Spør om servitørene dine, eller beskriv en endring du vil foreslå", - "selectProvider": "Velg en leverandør", - "providerSettings": "Leverandørinnstillinger", - "addProvider": "Legg til leverandør", - "editProvider": "Rediger leverandør", - "removeProvider": "Fjern leverandør", - "providerType": "Leverandør", + "title": "Assistant", + "send": "Send", + "stop": "Stopp", + "save": "Lagre", + "cancel": "Avbryt", + "running": "kjører", + "approve": "Approve", + "reject": "Reject", + "inputPlaceholder": "Ask about your servers, or describe a change to propose", + "selectProvider": "Select a provider", + "providerSettings": "Provider settings", + "addProvider": "Add provider", + "editProvider": "Edit provider", + "removeProvider": "Remove provider", + "providerType": "Provider", "providerLabel": "Navn", - "providerLabelPlaceholder": "For eksempel: Lokal Ollama", - "baseUrl": "Serveradresse", - "apiKey": "API-nøkkel", - "defaultModel": "Standardmodell", - "defaultModelPlaceholder": "For eksempel: llama3.1 eller claude-opus-5", - "labelRequired": "Gi denne leverandøren et navn", - "providerSaveFailed": "Kunne ikke lagre leverandøren", - "providerUpdated": "Leverandøren er oppdatert", - "providerDeleteFailed": "Kunne ikke fjerne leverandøren", - "privateEndpointHint": "Adresser på ditt private nettverk krever at en administrator tillater verten først.", + "providerLabelPlaceholder": "For example: Local Ollama", + "baseUrl": "Server address", + "apiKey": "API key", + "defaultModel": "Default model", + "defaultModelPlaceholder": "For example: llama3.1 or claude-opus-5", + "labelRequired": "Give this provider a name", + "providerSaveFailed": "Could not save the provider", + "providerUpdated": "Provider updated", + "providerDeleteFailed": "Could not remove the provider", + "privateEndpointHint": "Addresses on your private network need an administrator to allow the host first.", "providerOllama": "Ollama", - "providerAnthropic": "Antropisk", - "providerOpenai": "Åpen kunstig intelligens", + "providerAnthropic": "Anthropic", + "providerOpenai": "OpenAI", "providerGemini": "Google Gemini", - "providerOpenaiCompatible": "OpenAI-kompatibel", - "toolArguments": "Inndata", - "toolResult": "Resultat", - "statusApplied": "Anvendt", - "statusRejected": "Avvist", - "proposalApplied": "Endringen er brukt", - "proposalApplyFailed": "Kunne ikke bruke endringen", - "proposalRejectFailed": "Kunne ikke avvise endringen", - "enableTitle": "Aktiver AI-assistenten", - "enableDescription": "La assistenten lese oppsettet ditt og foreslå endringer du kan godkjenne.", - "readOnlyCommands": "Tillat skrivebeskyttede diagnostiske kommandoer", - "readOnlyCommandsDescription": "Assistenten kan kjøre en kort liste med sikre kommandoer som df og uptime uten å spørre hver gang. Alt som endrer en server blir alltid foreslått først.", - "modelDetectFailed": "Kunne ikke nå leverandøren, så dette er en generell liste. Du kan skrive inn et hvilket som helst modellnavn.", - "modelCustom": "Skriv inn et modellnavn", - "modelRefresh": "Oppdater listen", - "modelPlaceholder": "Velg eller skriv inn en modell", - "attachHint": "Skriv inn @ for å referere til en vert, et kodeutdrag eller en automatisering. Endringer foreslås som du kan godkjenne.", - "runCommandTitle": "Kjør kommandoen", - "assistant": "AI-assistent", - "terminalPanelEmpty": "Spør assistenten om denne verten. Alt som endrer status trenger din godkjenning først.", - "terminalPanelPlaceholder": "Spør om denne verten...", - "noProvidersConfigured": "Ingen AI-leverandør er konfigurert ennå. Legg til en i AI-assistent-fanen.", - "runsInOpenTerminal": "Kjører i din åpne terminaløkt.", - "runInTerminal": "Løp" + "providerOpenaiCompatible": "OpenAI compatible", + "toolArguments": "Input", + "toolResult": "Result", + "statusApplied": "Applied", + "statusRejected": "Rejected", + "proposalApplied": "Change applied", + "proposalApplyFailed": "Could not apply the change", + "proposalRejectFailed": "Could not reject the change", + "enableTitle": "Enable the AI assistant", + "enableDescription": "Let the assistant read your setup and suggest changes for you to approve.", + "readOnlyCommands": "Allow read-only diagnostic commands", + "readOnlyCommandsDescription": "The assistant may run a short list of safe commands like df and uptime without asking each time. Anything that changes a server is always proposed first.", + "modelDetectFailed": "Could not reach the provider, so this is a general list. You can type any model name.", + "modelCustom": "Enter a model name", + "modelRefresh": "Refresh list", + "modelPlaceholder": "Choose or type a model", + "attachHint": "Type @ to reference a host, snippet or automation. Changes are proposed for you to approve.", + "runCommandTitle": "Run command", + "assistant": "AI Assistant", + "terminalPanelEmpty": "Ask the assistant about this host. Anything that changes state needs your approval first.", + "terminalPanelPlaceholder": "Ask about this host...", + "noProvidersConfigured": "No AI provider is configured yet. Add one in the AI assistant tab.", + "runsInOpenTerminal": "Runs in your open terminal session.", + "runInTerminal": "Kjør", + "terminalContextPrefill": "Here is my terminal output:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Let other features use your AI provider API key for their own requests. The key is never copied, and you can revoke this at any time." + } }, "nav": { "ai": "AI" }, "onboarding": { - "aiTitle": "AI-assistent", - "aiIntro": "Termix kan inkludere en valgfri AI-assistent. Du kan endre dette senere i innstillingene dine.", - "aiSkipTitle": "La det være av", - "aiSkipDesc": "Termix fungerer som den gjør nå. Assistenten forblir skjult.", - "aiEnableTitle": "Slå den på", - "aiEnableDesc": "Legger til en assistent som leser oppsettet ditt og foreslår endringer du godkjenner. Krever en leverandør du oppgir, for eksempel en lokal Ollama.", - "aiNote": "Ingenting sendes noe sted før du legger til en leverandør og sender en melding." - }, - "settings": { - "admin": { - "globallyEnabled": { - "label": "AI-assistent", - "description": "La brukere slå på AI-assistenten. Mens dette er av, er assistenten skjult og blokkert for alle." - }, - "privateEndpoints": { - "label": "Tillatte private AI-verter" - } - }, - "host": { - "enableAiAssistant": { - "label": "Aktiver AI-assistent", - "description": "Tillat at AI-assistenten hjelper til i denne vertens terminal. Av som standard, og krever fortsatt at AI er aktivert for kontoen din." - } - } + "aiTitle": "AI assistant", + "aiIntro": "Termix can include an optional AI assistant. You can change this later in your settings.", + "aiSkipTitle": "Leave it off", + "aiSkipDesc": "Termix works as it does now. The assistant stays hidden.", + "aiEnableTitle": "Turn it on", + "aiEnableDesc": "Adds an assistant that reads your setup and suggests changes you approve. Needs a provider you supply, such as a local Ollama.", + "aiNote": "Nothing is sent anywhere until you add a provider and send a message." }, "hosts": { - "docsLink": "Vis dokumenter" + "docsLink": "View docs" } } diff --git a/plugins/ai/locales/translated/pl_PL.json b/plugins/ai/locales/translated/pl_PL.json index 946e537be..a1fd9c256 100644 --- a/plugins/ai/locales/translated/pl_PL.json +++ b/plugins/ai/locales/translated/pl_PL.json @@ -1,4 +1,46 @@ { + "permissions": { + "use": { + "title": "Use the assistant", + "description": "Open the assistant and ask it things." + }, + "manage_providers": { + "title": "Manage providers", + "description": "Add, edit and remove the AI providers and their API keys." + }, + "apply_proposals": { + "title": "Apply proposals", + "description": "Let the assistant carry out the changes it suggests." + }, + "services.use": { + "title": "Use AI from other features", + "description": "Other features may call the assistant on your behalf." + }, + "secrets.share": { + "title": "Share the API key", + "description": "Other features may use the stored AI API key without seeing it." + } + }, + "settings": { + "assistantUnavailable": "The AI assistant is turned off on this server.", + "providersNeedOptIn": "Turn on the AI assistant above to add providers.", + "admin": { + "globallyEnabled": { + "label": "Asystent AI", + "description": "Pozwól użytkownikom włączyć asystenta AI. Gdy ta opcja jest wyłączona, asystent jest ukryty i zablokowany dla wszystkich." + }, + "privateEndpoints": { + "label": "Dozwolone prywatne hosty AI", + "description": "Hosts on your private network that users may point a provider at, such as a self-hosted Ollama. Put one host on each line." + } + }, + "host": { + "enableAiAssistant": { + "label": "Enable AI Assistant", + "description": "Allow the AI assistant to help in this host's terminal. Off by default, and still needs AI enabled for your account." + } + } + }, "ai": { "title": "Asystent", "send": "Wyślij", @@ -48,12 +90,16 @@ "modelPlaceholder": "Wybierz lub wpisz model", "attachHint": "Wpisz @, aby odwołać się do hosta, snippetu lub automatyzacji. Zmiany są proponowane do Twojego zatwierdzenia.", "runCommandTitle": "Uruchom polecenie", - "assistant": "Asystent AI", - "terminalPanelEmpty": "Zapytaj asystenta o tego hosta. Każda zmiana stanu wymaga Twojej zgody.", - "terminalPanelPlaceholder": "Zapytaj o tego gospodarza...", - "noProvidersConfigured": "Nie skonfigurowano jeszcze żadnego dostawcy AI. Dodaj go w zakładce Asystent AI.", - "runsInOpenTerminal": "Działa w otwartej sesji terminalowej.", - "runInTerminal": "Uruchomić" + "assistant": "AI Assistant", + "terminalPanelEmpty": "Ask the assistant about this host. Anything that changes state needs your approval first.", + "terminalPanelPlaceholder": "Ask about this host...", + "noProvidersConfigured": "No AI provider is configured yet. Add one in the AI assistant tab.", + "runsInOpenTerminal": "Runs in your open terminal session.", + "runInTerminal": "Uruchom", + "terminalContextPrefill": "Here is my terminal output:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Let other features use your AI provider API key for their own requests. The key is never copied, and you can revoke this at any time." + } }, "nav": { "ai": "AI" @@ -67,23 +113,6 @@ "aiEnableDesc": "Dodaje asystenta, który odczytuje Twoją konfigurację i sugeruje zmiany, które zatwierdzasz. Wymaga wskazanego przez Ciebie dostawcy, np. lokalnej Ollamy.", "aiNote": "Dopóki nie dodasz dostawcy i nie wyślesz wiadomości, nic nie zostanie wysłane." }, - "settings": { - "admin": { - "globallyEnabled": { - "label": "Asystent AI", - "description": "Pozwól użytkownikom włączyć asystenta AI. Gdy ta opcja jest wyłączona, asystent jest ukryty i zablokowany dla wszystkich." - }, - "privateEndpoints": { - "label": "Dozwolone prywatne hosty AI" - } - }, - "host": { - "enableAiAssistant": { - "label": "Włącz asystenta AI", - "description": "Zezwól asystentowi AI na pomoc w terminalu tego hosta. Domyślnie wyłączone, ale nadal wymaga włączenia AI na Twoim koncie." - } - } - }, "hosts": { "docsLink": "Zobacz dokumentację" } diff --git a/plugins/ai/locales/translated/pt_BR.json b/plugins/ai/locales/translated/pt_BR.json index b56f6208e..9cc13f482 100644 --- a/plugins/ai/locales/translated/pt_BR.json +++ b/plugins/ai/locales/translated/pt_BR.json @@ -1,90 +1,119 @@ { - "ai": { - "title": "Assistente", - "send": "Enviar", - "stop": "Parar", - "save": "Salvar", - "cancel": "Cancelar", - "running": "correndo", - "approve": "Aprovar", - "reject": "Rejeitar", - "inputPlaceholder": "Pergunte sobre seus servidores ou descreva uma alteração que você gostaria de propor.", - "selectProvider": "Selecione um fornecedor", - "providerSettings": "Configurações do provedor", - "addProvider": "Adicionar provedor", - "editProvider": "Editar provedor", - "removeProvider": "Remover provedor", - "providerType": "Fornecedor", - "providerLabel": "Nome", - "providerLabelPlaceholder": "Por exemplo: Ollama local", - "baseUrl": "Endereço do servidor", - "apiKey": "Chave de API", - "defaultModel": "Modelo padrão", - "defaultModelPlaceholder": "Por exemplo: llama3.1 ou claude-opus-5", - "labelRequired": "Dê um nome a este fornecedor.", - "providerSaveFailed": "Não foi possível salvar o provedor.", - "providerUpdated": "Fornecedor atualizado", - "providerDeleteFailed": "Não foi possível remover o provedor.", - "privateEndpointHint": "Os endereços na sua rede privada precisam que um administrador autorize o host primeiro.", - "providerOllama": "Ollama", - "providerAnthropic": "Antrópico", - "providerOpenai": "OpenAI", - "providerGemini": "Google Gemini", - "providerOpenaiCompatible": "Compatível com OpenAI", - "toolArguments": "Entrada", - "toolResult": "Resultado", - "statusApplied": "Aplicado", - "statusRejected": "Rejeitado", - "proposalApplied": "Alteração aplicada", - "proposalApplyFailed": "Não foi possível aplicar a alteração.", - "proposalRejectFailed": "Não foi possível rejeitar a alteração.", - "enableTitle": "Ative o assistente de IA", - "enableDescription": "Deixe o assistente ler sua configuração e sugerir alterações para você aprovar.", - "readOnlyCommands": "Permitir comandos de diagnóstico somente leitura", - "readOnlyCommandsDescription": "O assistente pode executar uma pequena lista de comandos seguros, como `df` e `uptime`, sem perguntar a cada vez. Qualquer alteração que faça no servidor será sempre sugerida primeiro.", - "modelDetectFailed": "Não foi possível contatar o fornecedor, portanto esta é uma lista genérica. Você pode digitar o nome de qualquer modelo.", - "modelCustom": "Insira o nome do modelo", - "modelRefresh": "Atualizar lista", - "modelPlaceholder": "Selecione ou digite um modelo", - "attachHint": "Digite @ para fazer referência a um host, snippet ou automação. As alterações são propostas para sua aprovação.", - "runCommandTitle": "Executar comando", - "assistant": "Assistente de IA", - "terminalPanelEmpty": "Pergunte ao assistente sobre este anfitrião. Qualquer alteração de estado precisa da sua aprovação prévia.", - "terminalPanelPlaceholder": "Pergunte sobre este anfitrião...", - "noProvidersConfigured": "Nenhum provedor de IA está configurado ainda. Adicione um na aba do assistente de IA.", - "runsInOpenTerminal": "Executa na sua sessão de terminal aberta.", - "runInTerminal": "Correr" - }, - "nav": { - "ai": "IA" - }, - "onboarding": { - "aiTitle": "assistente de IA", - "aiIntro": "O Termix pode incluir um assistente de IA opcional. Você pode alterar isso posteriormente nas suas configurações.", - "aiSkipTitle": "Deixe desligado", - "aiSkipDesc": "O Termix funciona como está agora. O assistente permanece oculto.", - "aiEnableTitle": "Ligue-o", - "aiEnableDesc": "Adiciona um assistente que lê sua configuração e sugere alterações que você aprova. Requer um provedor fornecido por você, como um Ollama local.", - "aiNote": "Nada será enviado até que você adicione um provedor e envie uma mensagem." + "permissions": { + "use": { + "title": "Use the assistant", + "description": "Open the assistant and ask it things." + }, + "manage_providers": { + "title": "Manage providers", + "description": "Add, edit and remove the AI providers and their API keys." + }, + "apply_proposals": { + "title": "Apply proposals", + "description": "Let the assistant carry out the changes it suggests." + }, + "services.use": { + "title": "Use AI from other features", + "description": "Other features may call the assistant on your behalf." + }, + "secrets.share": { + "title": "Share the API key", + "description": "Other features may use the stored AI API key without seeing it." + } }, "settings": { + "assistantUnavailable": "The AI assistant is turned off on this server.", + "providersNeedOptIn": "Turn on the AI assistant above to add providers.", "admin": { "globallyEnabled": { - "label": "assistente de IA", - "description": "Permita que os usuários ativem o assistente de IA. Quando estiver desativado, o assistente ficará oculto e bloqueado para todos." + "label": "AI assistant", + "description": "Let users turn on the AI assistant. While this is off, the assistant is hidden and blocked for everyone." }, "privateEndpoints": { - "label": "Hosts de IA privados permitidos" + "label": "Allowed private AI hosts", + "description": "Hosts on your private network that users may point a provider at, such as a self-hosted Ollama. Put one host on each line." } }, "host": { "enableAiAssistant": { - "label": "Ativar o assistente de IA", - "description": "Permita que o assistente de IA ajude no terminal deste host. Desativado por padrão, mas ainda precisa que a IA esteja ativada para sua conta." + "label": "Enable AI Assistant", + "description": "Allow the AI assistant to help in this host's terminal. Off by default, and still needs AI enabled for your account." } } }, + "ai": { + "title": "Assistant", + "send": "Send", + "stop": "Stop", + "save": "Salvar", + "cancel": "Cancelar", + "running": "running", + "approve": "Approve", + "reject": "Reject", + "inputPlaceholder": "Ask about your servers, or describe a change to propose", + "selectProvider": "Select a provider", + "providerSettings": "Provider settings", + "addProvider": "Add provider", + "editProvider": "Edit provider", + "removeProvider": "Remove provider", + "providerType": "Provider", + "providerLabel": "Name", + "providerLabelPlaceholder": "For example: Local Ollama", + "baseUrl": "Server address", + "apiKey": "API key", + "defaultModel": "Default model", + "defaultModelPlaceholder": "For example: llama3.1 or claude-opus-5", + "labelRequired": "Give this provider a name", + "providerSaveFailed": "Could not save the provider", + "providerUpdated": "Provider updated", + "providerDeleteFailed": "Could not remove the provider", + "privateEndpointHint": "Addresses on your private network need an administrator to allow the host first.", + "providerOllama": "Ollama", + "providerAnthropic": "Anthropic", + "providerOpenai": "OpenAI", + "providerGemini": "Google Gemini", + "providerOpenaiCompatible": "OpenAI compatible", + "toolArguments": "Entrada", + "toolResult": "Result", + "statusApplied": "Applied", + "statusRejected": "Rejected", + "proposalApplied": "Change applied", + "proposalApplyFailed": "Could not apply the change", + "proposalRejectFailed": "Could not reject the change", + "enableTitle": "Enable the AI assistant", + "enableDescription": "Let the assistant read your setup and suggest changes for you to approve.", + "readOnlyCommands": "Allow read-only diagnostic commands", + "readOnlyCommandsDescription": "The assistant may run a short list of safe commands like df and uptime without asking each time. Anything that changes a server is always proposed first.", + "modelDetectFailed": "Could not reach the provider, so this is a general list. You can type any model name.", + "modelCustom": "Enter a model name", + "modelRefresh": "Refresh list", + "modelPlaceholder": "Choose or type a model", + "attachHint": "Type @ to reference a host, snippet or automation. Changes are proposed for you to approve.", + "runCommandTitle": "Run command", + "assistant": "AI Assistant", + "terminalPanelEmpty": "Ask the assistant about this host. Anything that changes state needs your approval first.", + "terminalPanelPlaceholder": "Ask about this host...", + "noProvidersConfigured": "No AI provider is configured yet. Add one in the AI assistant tab.", + "runsInOpenTerminal": "Runs in your open terminal session.", + "runInTerminal": "Run", + "terminalContextPrefill": "Here is my terminal output:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Let other features use your AI provider API key for their own requests. The key is never copied, and you can revoke this at any time." + } + }, + "nav": { + "ai": "AI" + }, + "onboarding": { + "aiTitle": "AI assistant", + "aiIntro": "Termix can include an optional AI assistant. You can change this later in your settings.", + "aiSkipTitle": "Leave it off", + "aiSkipDesc": "Termix works as it does now. The assistant stays hidden.", + "aiEnableTitle": "Turn it on", + "aiEnableDesc": "Adds an assistant that reads your setup and suggests changes you approve. Needs a provider you supply, such as a local Ollama.", + "aiNote": "Nothing is sent anywhere until you add a provider and send a message." + }, "hosts": { - "docsLink": "Ver documentos" + "docsLink": "Documentação" } } diff --git a/plugins/ai/locales/translated/pt_PT.json b/plugins/ai/locales/translated/pt_PT.json index b4c6149b4..6c9aee940 100644 --- a/plugins/ai/locales/translated/pt_PT.json +++ b/plugins/ai/locales/translated/pt_PT.json @@ -1,89 +1,118 @@ { - "ai": { - "title": "Assistente", - "send": "Enviar", - "stop": "Parar", - "save": "Guardar", - "cancel": "Cancelar", - "running": "corrida", - "approve": "Aprovar", - "reject": "Rejeitar", - "inputPlaceholder": "Pergunte pelos seus servidores ou descreva uma alteração que gostaria de propor.", - "selectProvider": "Selecione um fornecedor", - "providerSettings": "Configurações do fornecedor", - "addProvider": "Adicionar provedor", - "editProvider": "Editar provedor", - "removeProvider": "Remover fornecedor", - "providerType": "Fornecedor", - "providerLabel": "Nome", - "providerLabelPlaceholder": "Por exemplo: Ollama local", - "baseUrl": "Endereço do servidor", - "apiKey": "Chave API", - "defaultModel": "Modelo padrão", - "defaultModelPlaceholder": "Por exemplo: llama3.1 ou claude-opus-5", - "labelRequired": "Dê um nome a este fornecedor.", - "providerSaveFailed": "Não foi possível guardar o fornecedor.", - "providerUpdated": "Fornecedor atualizado", - "providerDeleteFailed": "Não foi possível remover o fornecedor.", - "privateEndpointHint": "Os endereços na sua rede privada necessitam que um administrador autorize primeiro o host.", - "providerOllama": "Ollama", - "providerAnthropic": "Antrópico", - "providerOpenai": "OpenAI", - "providerGemini": "Google Gemini", - "providerOpenaiCompatible": "Compatível com OpenAI", - "toolArguments": "Entrada", - "toolResult": "Resultado", - "statusApplied": "Aplicado", - "statusRejected": "Rejeitado", - "proposalApplied": "Alteração aplicada", - "proposalApplyFailed": "Não foi possível aplicar a alteração.", - "proposalRejectFailed": "Não foi possível rejeitar a alteração.", - "enableTitle": "Ative o assistente de IA", - "enableDescription": "Deixe o assistente ler a sua configuração e sugerir alterações para que a aprove.", - "readOnlyCommands": "Permitir comandos de diagnóstico de leitura apenas", - "readOnlyCommandsDescription": "O assistente pode executar uma pequena lista de comandos seguros, como `df` e `uptime`, sem perguntar de cada vez. Qualquer alteração que faça no servidor será sempre sugerida em primeiro lugar.", - "modelDetectFailed": "Não foi possível contactar o fornecedor, pelo que esta é uma lista genérica. Pode digitar o nome de qualquer modelo.", - "modelCustom": "Introduza o nome do modelo", - "modelRefresh": "Atualizar lista", - "modelPlaceholder": "Selecione ou introduza um modelo", - "attachHint": "Digite @ para fazer referência a um host, snippet ou automação. As alterações são propostas para a sua aprovação.", - "runCommandTitle": "Executar comando", - "assistant": "Assistente de IA", - "terminalPanelEmpty": "Pergunte ao assistente sobre este anfitrião. Qualquer alteração de estado necessita da sua aprovação prévia.", - "terminalPanelPlaceholder": "Pergunte sobre este anfitrião...", - "noProvidersConfigured": "Nenhum fornecedor de IA está configurado ainda. Adicione um no separador do assistente de IA.", - "runsInOpenTerminal": "Executa na sua sessão de terminal aberta.", - "runInTerminal": "Correr" - }, - "nav": { - "ai": "IA" - }, - "onboarding": { - "aiTitle": "assistente de IA", - "aiIntro": "O Termix pode incluir um assistente de IA opcional. Pode alterar isso posteriormente nas suas definições.", - "aiSkipTitle": "Deixe desligado", - "aiSkipDesc": "O Termix funciona como está agora. O assistente permanece oculto.", - "aiEnableTitle": "Ligue-o", - "aiEnableDesc": "Adiciona um assistente que lê a sua configuração e sugere alterações que aprova. Requer um fornecedor fornecido por si, como um Ollama local.", - "aiNote": "Nada será enviado até que adicione um fornecedor e envie uma mensagem." + "permissions": { + "use": { + "title": "Use the assistant", + "description": "Open the assistant and ask it things." + }, + "manage_providers": { + "title": "Manage providers", + "description": "Add, edit and remove the AI providers and their API keys." + }, + "apply_proposals": { + "title": "Apply proposals", + "description": "Let the assistant carry out the changes it suggests." + }, + "services.use": { + "title": "Use AI from other features", + "description": "Other features may call the assistant on your behalf." + }, + "secrets.share": { + "title": "Share the API key", + "description": "Other features may use the stored AI API key without seeing it." + } }, "settings": { + "assistantUnavailable": "The AI assistant is turned off on this server.", + "providersNeedOptIn": "Turn on the AI assistant above to add providers.", "admin": { "globallyEnabled": { - "label": "assistente de IA", - "description": "Permita que os utilizadores ativem o assistente de IA. Quando estiver desativado, o assistente ficará oculto e bloqueado para todos." + "label": "AI assistant", + "description": "Let users turn on the AI assistant. While this is off, the assistant is hidden and blocked for everyone." }, "privateEndpoints": { - "label": "Hosts de IA privados permitidos" + "label": "Allowed private AI hosts", + "description": "Hosts on your private network that users may point a provider at, such as a self-hosted Ollama. Put one host on each line." } }, "host": { "enableAiAssistant": { - "label": "Ativar o assistente de IA", - "description": "Permita que o assistente de IA ajude no terminal deste host. Desativado por defeito, mas ainda precisa que a IA esteja ativada para a sua conta." + "label": "Enable AI Assistant", + "description": "Allow the AI assistant to help in this host's terminal. Off by default, and still needs AI enabled for your account." } } }, + "ai": { + "title": "Assistant", + "send": "Send", + "stop": "Stop", + "save": "Guardar", + "cancel": "Cancelar", + "running": "em execução", + "approve": "Approve", + "reject": "Reject", + "inputPlaceholder": "Ask about your servers, or describe a change to propose", + "selectProvider": "Select a provider", + "providerSettings": "Provider settings", + "addProvider": "Add provider", + "editProvider": "Edit provider", + "removeProvider": "Remove provider", + "providerType": "Provider", + "providerLabel": "Nome", + "providerLabelPlaceholder": "For example: Local Ollama", + "baseUrl": "Server address", + "apiKey": "API key", + "defaultModel": "Default model", + "defaultModelPlaceholder": "For example: llama3.1 or claude-opus-5", + "labelRequired": "Give this provider a name", + "providerSaveFailed": "Could not save the provider", + "providerUpdated": "Provider updated", + "providerDeleteFailed": "Could not remove the provider", + "privateEndpointHint": "Addresses on your private network need an administrator to allow the host first.", + "providerOllama": "Ollama", + "providerAnthropic": "Anthropic", + "providerOpenai": "OpenAI", + "providerGemini": "Google Gemini", + "providerOpenaiCompatible": "OpenAI compatible", + "toolArguments": "Entrada", + "toolResult": "Result", + "statusApplied": "Applied", + "statusRejected": "Rejected", + "proposalApplied": "Change applied", + "proposalApplyFailed": "Could not apply the change", + "proposalRejectFailed": "Could not reject the change", + "enableTitle": "Enable the AI assistant", + "enableDescription": "Let the assistant read your setup and suggest changes for you to approve.", + "readOnlyCommands": "Allow read-only diagnostic commands", + "readOnlyCommandsDescription": "The assistant may run a short list of safe commands like df and uptime without asking each time. Anything that changes a server is always proposed first.", + "modelDetectFailed": "Could not reach the provider, so this is a general list. You can type any model name.", + "modelCustom": "Enter a model name", + "modelRefresh": "Refresh list", + "modelPlaceholder": "Choose or type a model", + "attachHint": "Type @ to reference a host, snippet or automation. Changes are proposed for you to approve.", + "runCommandTitle": "Run command", + "assistant": "AI Assistant", + "terminalPanelEmpty": "Ask the assistant about this host. Anything that changes state needs your approval first.", + "terminalPanelPlaceholder": "Ask about this host...", + "noProvidersConfigured": "No AI provider is configured yet. Add one in the AI assistant tab.", + "runsInOpenTerminal": "Runs in your open terminal session.", + "runInTerminal": "Executar", + "terminalContextPrefill": "Here is my terminal output:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Let other features use your AI provider API key for their own requests. The key is never copied, and you can revoke this at any time." + } + }, + "nav": { + "ai": "AI" + }, + "onboarding": { + "aiTitle": "AI assistant", + "aiIntro": "Termix can include an optional AI assistant. You can change this later in your settings.", + "aiSkipTitle": "Leave it off", + "aiSkipDesc": "Termix works as it does now. The assistant stays hidden.", + "aiEnableTitle": "Turn it on", + "aiEnableDesc": "Adds an assistant that reads your setup and suggests changes you approve. Needs a provider you supply, such as a local Ollama.", + "aiNote": "Nothing is sent anywhere until you add a provider and send a message." + }, "hosts": { "docsLink": "Ver documentação" } diff --git a/plugins/ai/locales/translated/ro_RO.json b/plugins/ai/locales/translated/ro_RO.json index 1486173fd..9aa460137 100644 --- a/plugins/ai/locales/translated/ro_RO.json +++ b/plugins/ai/locales/translated/ro_RO.json @@ -1,4 +1,46 @@ { + "permissions": { + "use": { + "title": "Folosește asistentul", + "description": "Deschide asistentul și pune-i întrebări." + }, + "manage_providers": { + "title": "Gestionați furnizorii", + "description": "Adăugați, editați și eliminați furnizorii de inteligență artificială și cheile API ale acestora." + }, + "apply_proposals": { + "title": "Aplicați propunerile", + "description": "Lăsați asistentul să efectueze modificările sugerate de acesta." + }, + "services.use": { + "title": "Folosește inteligența artificială din alte funcții", + "description": "Alte funcții pot apela asistentul în numele tău." + }, + "secrets.share": { + "title": "Partajați cheia API", + "description": "Alte funcții pot utiliza cheia API AI stocată fără a o vedea." + } + }, + "settings": { + "assistantUnavailable": "Asistentul AI este dezactivat pe acest server.", + "providersNeedOptIn": "Activează asistentul AI de mai sus pentru a adăuga furnizori.", + "admin": { + "globallyEnabled": { + "label": "Asistent AI", + "description": "Permiteți utilizatorilor să activeze asistentul AI. Cât timp această opțiune este dezactivată, asistentul este ascuns și blocat pentru toată lumea." + }, + "privateEndpoints": { + "label": "Gazde private AI permise", + "description": "Gazde din rețeaua ta privată către care utilizatorii pot direcționa un furnizor, cum ar fi un Ollama auto-găzduit. Pune câte o gazdă pe fiecare linie." + } + }, + "host": { + "enableAiAssistant": { + "label": "Activează Asistentul AI", + "description": "Permiteți asistentului AI să vă ajute în terminalul acestei gazde. Dezactivat în mod implicit, dar este nevoie ca AI să fie activat pentru contul dvs." + } + } + }, "ai": { "title": "Asistent", "send": "Trimite", @@ -53,7 +95,11 @@ "terminalPanelPlaceholder": "Întreabă despre această gazdă...", "noProvidersConfigured": "Încă nu este configurat niciun furnizor de inteligență artificială. Adăugați unul în fila Asistent de inteligență artificială.", "runsInOpenTerminal": "Rulează în sesiunea de terminal deschisă.", - "runInTerminal": "Aleargă" + "runInTerminal": "Aleargă", + "terminalContextPrefill": "Iată ieșirea terminalului meu:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Permiteți altor funcții să utilizeze cheia API a furnizorului dvs. de inteligență artificială pentru propriile solicitări. Cheia nu este niciodată copiată și puteți revoca această opțiune oricând." + } }, "nav": { "ai": "IA" @@ -67,23 +113,6 @@ "aiEnableDesc": "Adaugă un asistent care citește configurația și sugerează modificări pe care le aprobi. Necesită un furnizor furnizat de tine, cum ar fi un Ollama local.", "aiNote": "Nimic nu este trimis nicăieri până nu adăugați un furnizor și nu trimiteți un mesaj." }, - "settings": { - "admin": { - "globallyEnabled": { - "label": "Asistent AI", - "description": "Permiteți utilizatorilor să activeze asistentul AI. Cât timp este dezactivat, asistentul este ascuns și blocat pentru toată lumea." - }, - "privateEndpoints": { - "label": "Gazde private AI permise" - } - }, - "host": { - "enableAiAssistant": { - "label": "Activează Asistentul AI", - "description": "Permiteți asistentului AI să vă ajute în terminalul acestei gazde. Dezactivat în mod implicit, dar este nevoie ca AI să fie activat pentru contul dvs." - } - } - }, "hosts": { "docsLink": "Vizualizați documentele" } diff --git a/plugins/ai/locales/translated/ru_RU.json b/plugins/ai/locales/translated/ru_RU.json index 17b8968b1..bb9ef6af6 100644 --- a/plugins/ai/locales/translated/ru_RU.json +++ b/plugins/ai/locales/translated/ru_RU.json @@ -1,89 +1,118 @@ { - "ai": { - "title": "Помощник", - "send": "Отправлять", - "stop": "Останавливаться", - "save": "Сохранять", - "cancel": "Отмена", - "running": "бег", - "approve": "Утвердить", - "reject": "Отклонять", - "inputPlaceholder": "Поинтересуйтесь состоянием ваших серверов или предложите внести изменения.", - "selectProvider": "Выберите поставщика", - "providerSettings": "Настройки поставщика", - "addProvider": "Добавить поставщика", - "editProvider": "Поставщик редактирования", - "removeProvider": "Удалить поставщика", - "providerType": "Поставщик", - "providerLabel": "Имя", - "providerLabelPlaceholder": "Например: Местная лама", - "baseUrl": "Адрес сервера", - "apiKey": "ключ API", - "defaultModel": "Модель по умолчанию", - "defaultModelPlaceholder": "Например: llama3.1 или claude-opus-5", - "labelRequired": "Укажите имя этого поставщика услуг.", - "providerSaveFailed": "Не удалось сохранить поставщика услуг.", - "providerUpdated": "Поставщик обновлен", - "providerDeleteFailed": "Не удалось удалить поставщика услуг.", - "privateEndpointHint": "Для доступа к адресам в вашей частной сети необходимо предварительное разрешение администратора.", - "providerOllama": "оллама", - "providerAnthropic": "Антропический", - "providerOpenai": "OpenAI", - "providerGemini": "Google Gemini", - "providerOpenaiCompatible": "Совместимость с OpenAI", - "toolArguments": "Вход", - "toolResult": "Результат", - "statusApplied": "Применяемый", - "statusRejected": "Отклоненный", - "proposalApplied": "Внесены изменения.", - "proposalApplyFailed": "Не удалось применить изменения.", - "proposalRejectFailed": "Не мог отклонить изменение.", - "enableTitle": "Включите ИИ-помощника", - "enableDescription": "Позвольте ассистенту ознакомиться с вашими настройками и предложить изменения для утверждения.", - "readOnlyCommands": "Разрешить диагностические команды только для чтения", - "readOnlyCommandsDescription": "Ассистент может выполнить короткий список безопасных команд, таких как df и uptime, не запрашивая подтверждения каждый раз. Любая команда, изменяющая состояние сервера, всегда предлагается в первую очередь.", - "modelDetectFailed": "Не удалось связаться с поставщиком, поэтому это общий список. Вы можете ввести любое название модели.", - "modelCustom": "Введите название модели", - "modelRefresh": "Обновить список", - "modelPlaceholder": "Выберите или введите модель", - "attachHint": "Введите @ для ссылки на хост, фрагмент кода или автоматизацию. Предлагаются изменения для вашего утверждения.", - "runCommandTitle": "Выполните команду", - "assistant": "ИИ-помощник", - "terminalPanelEmpty": "Спросите помощника об этом хосте. Любое изменение состояния требует вашего предварительного одобрения.", - "terminalPanelPlaceholder": "Спросите об этом хостинге...", - "noProvidersConfigured": "Поставщик ИИ пока не настроен. Добавьте его на вкладке «Помощник ИИ».", - "runsInOpenTerminal": "Запускается в открытой терминальной сессии.", - "runInTerminal": "Бегать" - }, - "nav": { - "ai": "ИИ" - }, - "onboarding": { - "aiTitle": "ИИ-помощник", - "aiIntro": "В Termix можно добавить опционального ИИ-помощника. Это можно изменить позже в настройках.", - "aiSkipTitle": "Оставьте это выключенным.", - "aiSkipDesc": "Termix работает так, как сейчас. Ассистент остается скрытым.", - "aiEnableTitle": "Включите его", - "aiEnableDesc": "Добавляет помощника, который считывает ваши настройки и предлагает изменения, которые вы одобряете. Требуется поставщик, которого вы предоставляете, например, локальный Ollama.", - "aiNote": "Ничего никуда не отправляется, пока вы не добавите поставщика услуг и не отправите сообщение." + "permissions": { + "use": { + "title": "Use the assistant", + "description": "Open the assistant and ask it things." + }, + "manage_providers": { + "title": "Manage providers", + "description": "Add, edit and remove the AI providers and their API keys." + }, + "apply_proposals": { + "title": "Apply proposals", + "description": "Let the assistant carry out the changes it suggests." + }, + "services.use": { + "title": "Use AI from other features", + "description": "Other features may call the assistant on your behalf." + }, + "secrets.share": { + "title": "Share the API key", + "description": "Other features may use the stored AI API key without seeing it." + } }, "settings": { + "assistantUnavailable": "The AI assistant is turned off on this server.", + "providersNeedOptIn": "Turn on the AI assistant above to add providers.", "admin": { "globallyEnabled": { - "label": "ИИ-помощник", - "description": "Разрешите пользователям включить голосового помощника. Если он выключен, помощник скрыт и заблокирован для всех." + "label": "AI assistant", + "description": "Let users turn on the AI assistant. While this is off, the assistant is hidden and blocked for everyone." }, "privateEndpoints": { - "label": "Разрешены частные хосты ИИ" + "label": "Allowed private AI hosts", + "description": "Hosts on your private network that users may point a provider at, such as a self-hosted Ollama. Put one host on each line." } }, "host": { "enableAiAssistant": { - "label": "Включить ИИ-помощника", - "description": "Разрешите помощнику с искусственным интеллектом помогать на терминале этого хоста. По умолчанию отключено, но для вашей учетной записи ИИ все равно должен быть включен." + "label": "Enable AI Assistant", + "description": "Allow the AI assistant to help in this host's terminal. Off by default, and still needs AI enabled for your account." } } }, + "ai": { + "title": "Assistant", + "send": "Send", + "stop": "Остановить", + "save": "Сохранить", + "cancel": "Отмена", + "running": "выполняется", + "approve": "Approve", + "reject": "Reject", + "inputPlaceholder": "Ask about your servers, or describe a change to propose", + "selectProvider": "Select a provider", + "providerSettings": "Provider settings", + "addProvider": "Add provider", + "editProvider": "Edit provider", + "removeProvider": "Remove provider", + "providerType": "Provider", + "providerLabel": "Название", + "providerLabelPlaceholder": "For example: Local Ollama", + "baseUrl": "Server address", + "apiKey": "API key", + "defaultModel": "Default model", + "defaultModelPlaceholder": "For example: llama3.1 or claude-opus-5", + "labelRequired": "Give this provider a name", + "providerSaveFailed": "Could not save the provider", + "providerUpdated": "Provider updated", + "providerDeleteFailed": "Could not remove the provider", + "privateEndpointHint": "Addresses on your private network need an administrator to allow the host first.", + "providerOllama": "Ollama", + "providerAnthropic": "Anthropic", + "providerOpenai": "OpenAI", + "providerGemini": "Google Gemini", + "providerOpenaiCompatible": "OpenAI compatible", + "toolArguments": "Ввод", + "toolResult": "Result", + "statusApplied": "Applied", + "statusRejected": "Rejected", + "proposalApplied": "Change applied", + "proposalApplyFailed": "Could not apply the change", + "proposalRejectFailed": "Could not reject the change", + "enableTitle": "Enable the AI assistant", + "enableDescription": "Let the assistant read your setup and suggest changes for you to approve.", + "readOnlyCommands": "Allow read-only diagnostic commands", + "readOnlyCommandsDescription": "The assistant may run a short list of safe commands like df and uptime without asking each time. Anything that changes a server is always proposed first.", + "modelDetectFailed": "Could not reach the provider, so this is a general list. You can type any model name.", + "modelCustom": "Enter a model name", + "modelRefresh": "Refresh list", + "modelPlaceholder": "Choose or type a model", + "attachHint": "Type @ to reference a host, snippet or automation. Changes are proposed for you to approve.", + "runCommandTitle": "Run command", + "assistant": "AI Assistant", + "terminalPanelEmpty": "Ask the assistant about this host. Anything that changes state needs your approval first.", + "terminalPanelPlaceholder": "Ask about this host...", + "noProvidersConfigured": "No AI provider is configured yet. Add one in the AI assistant tab.", + "runsInOpenTerminal": "Runs in your open terminal session.", + "runInTerminal": "Запустить", + "terminalContextPrefill": "Here is my terminal output:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Let other features use your AI provider API key for their own requests. The key is never copied, and you can revoke this at any time." + } + }, + "nav": { + "ai": "AI" + }, + "onboarding": { + "aiTitle": "AI assistant", + "aiIntro": "Termix can include an optional AI assistant. You can change this later in your settings.", + "aiSkipTitle": "Leave it off", + "aiSkipDesc": "Termix works as it does now. The assistant stays hidden.", + "aiEnableTitle": "Turn it on", + "aiEnableDesc": "Adds an assistant that reads your setup and suggests changes you approve. Needs a provider you supply, such as a local Ollama.", + "aiNote": "Nothing is sent anywhere until you add a provider and send a message." + }, "hosts": { "docsLink": "Документация" } diff --git a/plugins/ai/locales/translated/sr_SP.json b/plugins/ai/locales/translated/sr_SP.json index 793577f0f..7b5758ffa 100644 --- a/plugins/ai/locales/translated/sr_SP.json +++ b/plugins/ai/locales/translated/sr_SP.json @@ -1,90 +1,119 @@ { - "ai": { - "title": "Асистент", - "send": "Пошаљи", - "stop": "Заустави", - "save": "Сачувај", - "cancel": "Откажи", - "running": "трчање", - "approve": "Одобри", - "reject": "Одбиј", - "inputPlaceholder": "Питајте о својим серверима или опишите промену коју желите да предложите", - "selectProvider": "Изаберите добављача", - "providerSettings": "Подешавања добављача", - "addProvider": "Додај добављача", - "editProvider": "Измени добављача", - "removeProvider": "Уклони добављача", - "providerType": "Провајдер", - "providerLabel": "Име", - "providerLabelPlaceholder": "На пример: Локална Олама", - "baseUrl": "Адреса сервера", - "apiKey": "API кључ", - "defaultModel": "Подразумевани модел", - "defaultModelPlaceholder": "На пример: llama3.1 или claude-opus-5", - "labelRequired": "Дајте име овом добављачу", - "providerSaveFailed": "Није могуће сачувати добављача", - "providerUpdated": "Провајдер је ажуриран", - "providerDeleteFailed": "Није могуће уклонити добављача", - "privateEndpointHint": "Адресе на вашој приватној мрежи прво треба да дозволе администратору хоста.", - "providerOllama": "Олама", - "providerAnthropic": "Антропски", - "providerOpenai": "OpenAI", - "providerGemini": "Гугл Џемини", - "providerOpenaiCompatible": "Компатибилно са OpenAI-ом", - "toolArguments": "Унос", - "toolResult": "Резултат", - "statusApplied": "Примењено", - "statusRejected": "Одбијено", - "proposalApplied": "Промена је примењена", - "proposalApplyFailed": "Није могуће применити промену", - "proposalRejectFailed": "Није могуће одбити промену", - "enableTitle": "Омогућите вештачку интелигенцију (AI) асистента", - "enableDescription": "Нека асистент прочита ваша подешавања и предложи измене које ћете одобрити.", - "readOnlyCommands": "Дозволи дијагностичке команде само за читање", - "readOnlyCommandsDescription": "Асистент може да покрене кратку листу безбедних команди као што су df и uptime без сваког питања. Све што мења сервер се увек прво предлаже.", - "modelDetectFailed": "Нисмо могли да контактирамо добављача, тако да је ово општа листа. Можете да унесете било који назив модела.", - "modelCustom": "Унесите назив модела", - "modelRefresh": "Освежи листу", - "modelPlaceholder": "Изаберите или унесите модел", - "attachHint": "Унесите @ да бисте референцирали хост, исечак кода или аутоматизацију. Промене се предлажу да бисте их одобрили.", - "runCommandTitle": "Покрени команду", - "assistant": "АИ асистент", - "terminalPanelEmpty": "Питајте асистента о овом домаћину. Све што мења стање прво захтева ваше одобрење.", - "terminalPanelPlaceholder": "Питајте о овом домаћину...", - "noProvidersConfigured": "Још увек није конфигурисан ниједан добављач вештачке интелигенције. Додајте га на картици помоћника за вештачку интелигенцију.", - "runsInOpenTerminal": "Покреће се у вашој отвореној терминалној сесији.", - "runInTerminal": "Трчи" - }, - "nav": { - "ai": "Вештачка интелигенција" - }, - "onboarding": { - "aiTitle": "Асистент за вештачку интелигенцију", - "aiIntro": "Termix може да укључи опционог AI асистента. Ово можете касније променити у подешавањима.", - "aiSkipTitle": "Остави то искључено", - "aiSkipDesc": "Термикс ради као и сада. Асистент остаје скривен.", - "aiEnableTitle": "Укључи га", - "aiEnableDesc": "Додаје асистента који чита ваша подешавања и предлаже измене које одобравате. Потребан је добављач кога ви обезбедите, као што је локални Олама.", - "aiNote": "Ништа се не шаље нигде док не додате провајдера и не пошаљете поруку." + "permissions": { + "use": { + "title": "Use the assistant", + "description": "Open the assistant and ask it things." + }, + "manage_providers": { + "title": "Manage providers", + "description": "Add, edit and remove the AI providers and their API keys." + }, + "apply_proposals": { + "title": "Apply proposals", + "description": "Let the assistant carry out the changes it suggests." + }, + "services.use": { + "title": "Use AI from other features", + "description": "Other features may call the assistant on your behalf." + }, + "secrets.share": { + "title": "Share the API key", + "description": "Other features may use the stored AI API key without seeing it." + } }, "settings": { + "assistantUnavailable": "The AI assistant is turned off on this server.", + "providersNeedOptIn": "Turn on the AI assistant above to add providers.", "admin": { "globallyEnabled": { - "label": "Асистент за вештачку интелигенцију", - "description": "Дозволите корисницима да укључе вештачку интелигенцију асистента. Док је ово искључено, асистент је скривен и блокиран за све." + "label": "AI assistant", + "description": "Let users turn on the AI assistant. While this is off, the assistant is hidden and blocked for everyone." }, "privateEndpoints": { - "label": "Дозвољени приватни AI хостови" + "label": "Allowed private AI hosts", + "description": "Hosts on your private network that users may point a provider at, such as a self-hosted Ollama. Put one host on each line." } }, "host": { "enableAiAssistant": { - "label": "Омогући AI асистент", - "description": "Дозволите вештачкој интелигенцији да помогне у терминалу овог хоста. Искључено је подразумевано, а и даље је потребно да вештачка интелигенција буде омогућена за ваш налог." + "label": "Enable AI Assistant", + "description": "Allow the AI assistant to help in this host's terminal. Off by default, and still needs AI enabled for your account." } } }, + "ai": { + "title": "Assistant", + "send": "Send", + "stop": "Stop", + "save": "Save", + "cancel": "Cancel", + "running": "running", + "approve": "Approve", + "reject": "Reject", + "inputPlaceholder": "Ask about your servers, or describe a change to propose", + "selectProvider": "Select a provider", + "providerSettings": "Provider settings", + "addProvider": "Add provider", + "editProvider": "Edit provider", + "removeProvider": "Remove provider", + "providerType": "Provider", + "providerLabel": "Name", + "providerLabelPlaceholder": "For example: Local Ollama", + "baseUrl": "Server address", + "apiKey": "API key", + "defaultModel": "Default model", + "defaultModelPlaceholder": "For example: llama3.1 or claude-opus-5", + "labelRequired": "Give this provider a name", + "providerSaveFailed": "Could not save the provider", + "providerUpdated": "Provider updated", + "providerDeleteFailed": "Could not remove the provider", + "privateEndpointHint": "Addresses on your private network need an administrator to allow the host first.", + "providerOllama": "Ollama", + "providerAnthropic": "Anthropic", + "providerOpenai": "OpenAI", + "providerGemini": "Google Gemini", + "providerOpenaiCompatible": "OpenAI compatible", + "toolArguments": "Input", + "toolResult": "Result", + "statusApplied": "Applied", + "statusRejected": "Rejected", + "proposalApplied": "Change applied", + "proposalApplyFailed": "Could not apply the change", + "proposalRejectFailed": "Could not reject the change", + "enableTitle": "Enable the AI assistant", + "enableDescription": "Let the assistant read your setup and suggest changes for you to approve.", + "readOnlyCommands": "Allow read-only diagnostic commands", + "readOnlyCommandsDescription": "The assistant may run a short list of safe commands like df and uptime without asking each time. Anything that changes a server is always proposed first.", + "modelDetectFailed": "Could not reach the provider, so this is a general list. You can type any model name.", + "modelCustom": "Enter a model name", + "modelRefresh": "Refresh list", + "modelPlaceholder": "Choose or type a model", + "attachHint": "Type @ to reference a host, snippet or automation. Changes are proposed for you to approve.", + "runCommandTitle": "Run command", + "assistant": "AI Assistant", + "terminalPanelEmpty": "Ask the assistant about this host. Anything that changes state needs your approval first.", + "terminalPanelPlaceholder": "Ask about this host...", + "noProvidersConfigured": "No AI provider is configured yet. Add one in the AI assistant tab.", + "runsInOpenTerminal": "Runs in your open terminal session.", + "runInTerminal": "Run", + "terminalContextPrefill": "Here is my terminal output:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Let other features use your AI provider API key for their own requests. The key is never copied, and you can revoke this at any time." + } + }, + "nav": { + "ai": "AI" + }, + "onboarding": { + "aiTitle": "AI assistant", + "aiIntro": "Termix can include an optional AI assistant. You can change this later in your settings.", + "aiSkipTitle": "Leave it off", + "aiSkipDesc": "Termix works as it does now. The assistant stays hidden.", + "aiEnableTitle": "Turn it on", + "aiEnableDesc": "Adds an assistant that reads your setup and suggests changes you approve. Needs a provider you supply, such as a local Ollama.", + "aiNote": "Nothing is sent anywhere until you add a provider and send a message." + }, "hosts": { - "docsLink": "Прикажи документе" + "docsLink": "View docs" } } diff --git a/plugins/ai/locales/translated/sv_SE.json b/plugins/ai/locales/translated/sv_SE.json index 2671da31f..7b5758ffa 100644 --- a/plugins/ai/locales/translated/sv_SE.json +++ b/plugins/ai/locales/translated/sv_SE.json @@ -1,90 +1,119 @@ { + "permissions": { + "use": { + "title": "Use the assistant", + "description": "Open the assistant and ask it things." + }, + "manage_providers": { + "title": "Manage providers", + "description": "Add, edit and remove the AI providers and their API keys." + }, + "apply_proposals": { + "title": "Apply proposals", + "description": "Let the assistant carry out the changes it suggests." + }, + "services.use": { + "title": "Use AI from other features", + "description": "Other features may call the assistant on your behalf." + }, + "secrets.share": { + "title": "Share the API key", + "description": "Other features may use the stored AI API key without seeing it." + } + }, + "settings": { + "assistantUnavailable": "The AI assistant is turned off on this server.", + "providersNeedOptIn": "Turn on the AI assistant above to add providers.", + "admin": { + "globallyEnabled": { + "label": "AI assistant", + "description": "Let users turn on the AI assistant. While this is off, the assistant is hidden and blocked for everyone." + }, + "privateEndpoints": { + "label": "Allowed private AI hosts", + "description": "Hosts on your private network that users may point a provider at, such as a self-hosted Ollama. Put one host on each line." + } + }, + "host": { + "enableAiAssistant": { + "label": "Enable AI Assistant", + "description": "Allow the AI assistant to help in this host's terminal. Off by default, and still needs AI enabled for your account." + } + } + }, "ai": { - "title": "Assistent", - "send": "Skicka", - "stop": "Stopp", - "save": "Spara", - "cancel": "Avboka", - "running": "spring", - "approve": "Godkänna", - "reject": "Avvisa", - "inputPlaceholder": "Fråga om era servrar, eller beskriv en förändring att föreslå", - "selectProvider": "Välj en leverantör", - "providerSettings": "Leverantörsinställningar", - "addProvider": "Lägg till leverantör", - "editProvider": "Redigera leverantör", - "removeProvider": "Ta bort leverantör", - "providerType": "Leverantör", - "providerLabel": "Namn", - "providerLabelPlaceholder": "Till exempel: Lokal Ollama", - "baseUrl": "Serveradress", - "apiKey": "API-nyckel", - "defaultModel": "Standardmodell", - "defaultModelPlaceholder": "Till exempel: llama3.1 eller claude-opus-5", - "labelRequired": "Ge den här leverantören ett namn", - "providerSaveFailed": "Kunde inte spara leverantören", - "providerUpdated": "Leverantören uppdaterad", - "providerDeleteFailed": "Kunde inte ta bort leverantören", - "privateEndpointHint": "Adresser i ditt privata nätverk behöver en administratör som först tillåter värden.", + "title": "Assistant", + "send": "Send", + "stop": "Stop", + "save": "Save", + "cancel": "Cancel", + "running": "running", + "approve": "Approve", + "reject": "Reject", + "inputPlaceholder": "Ask about your servers, or describe a change to propose", + "selectProvider": "Select a provider", + "providerSettings": "Provider settings", + "addProvider": "Add provider", + "editProvider": "Edit provider", + "removeProvider": "Remove provider", + "providerType": "Provider", + "providerLabel": "Name", + "providerLabelPlaceholder": "For example: Local Ollama", + "baseUrl": "Server address", + "apiKey": "API key", + "defaultModel": "Default model", + "defaultModelPlaceholder": "For example: llama3.1 or claude-opus-5", + "labelRequired": "Give this provider a name", + "providerSaveFailed": "Could not save the provider", + "providerUpdated": "Provider updated", + "providerDeleteFailed": "Could not remove the provider", + "privateEndpointHint": "Addresses on your private network need an administrator to allow the host first.", "providerOllama": "Ollama", - "providerAnthropic": "Antropisk", - "providerOpenai": "Öppen AI", + "providerAnthropic": "Anthropic", + "providerOpenai": "OpenAI", "providerGemini": "Google Gemini", - "providerOpenaiCompatible": "OpenAI-kompatibel", + "providerOpenaiCompatible": "OpenAI compatible", "toolArguments": "Input", - "toolResult": "Resultat", - "statusApplied": "Tillämpad", - "statusRejected": "Avvisad", - "proposalApplied": "Ändring tillämpad", - "proposalApplyFailed": "Kunde inte tillämpa ändringen", - "proposalRejectFailed": "Kunde inte avvisa ändringen", - "enableTitle": "Aktivera AI-assistenten", - "enableDescription": "Låt assistenten läsa dina inställningar och föreslå ändringar som du kan godkänna.", - "readOnlyCommands": "Tillåt skrivskyddade diagnostikkommandon", - "readOnlyCommandsDescription": "Assistenten kan köra en kort lista med säkra kommandon som df och uptime utan att fråga varje gång. Allt som ändrar en server föreslås alltid först.", - "modelDetectFailed": "Kunde inte nå leverantören, så detta är en allmän lista. Du kan skriva in vilket modellnamn som helst.", - "modelCustom": "Ange ett modellnamn", - "modelRefresh": "Uppdatera listan", - "modelPlaceholder": "Välj eller skriv en modell", - "attachHint": "Skriv @ för att referera till en värd, ett kodavsnitt eller en automatisering. Ändringar föreslås för dig att godkänna.", - "runCommandTitle": "Kör kommando", - "assistant": "AI-assistent", - "terminalPanelEmpty": "Fråga assistenten om den här värden. Allt som ändras kräver ditt godkännande först.", - "terminalPanelPlaceholder": "Fråga om den här värden...", - "noProvidersConfigured": "Ingen AI-leverantör är konfigurerad ännu. Lägg till en på fliken AI-assistent.", - "runsInOpenTerminal": "Körs i din öppna terminalsession.", - "runInTerminal": "Sikt" + "toolResult": "Result", + "statusApplied": "Applied", + "statusRejected": "Rejected", + "proposalApplied": "Change applied", + "proposalApplyFailed": "Could not apply the change", + "proposalRejectFailed": "Could not reject the change", + "enableTitle": "Enable the AI assistant", + "enableDescription": "Let the assistant read your setup and suggest changes for you to approve.", + "readOnlyCommands": "Allow read-only diagnostic commands", + "readOnlyCommandsDescription": "The assistant may run a short list of safe commands like df and uptime without asking each time. Anything that changes a server is always proposed first.", + "modelDetectFailed": "Could not reach the provider, so this is a general list. You can type any model name.", + "modelCustom": "Enter a model name", + "modelRefresh": "Refresh list", + "modelPlaceholder": "Choose or type a model", + "attachHint": "Type @ to reference a host, snippet or automation. Changes are proposed for you to approve.", + "runCommandTitle": "Run command", + "assistant": "AI Assistant", + "terminalPanelEmpty": "Ask the assistant about this host. Anything that changes state needs your approval first.", + "terminalPanelPlaceholder": "Ask about this host...", + "noProvidersConfigured": "No AI provider is configured yet. Add one in the AI assistant tab.", + "runsInOpenTerminal": "Runs in your open terminal session.", + "runInTerminal": "Run", + "terminalContextPrefill": "Here is my terminal output:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Let other features use your AI provider API key for their own requests. The key is never copied, and you can revoke this at any time." + } }, "nav": { "ai": "AI" }, "onboarding": { - "aiTitle": "AI-assistent", - "aiIntro": "Termix kan inkludera en valfri AI-assistent. Du kan ändra detta senare i dina inställningar.", - "aiSkipTitle": "Lämna den av", - "aiSkipDesc": "Termix fungerar som den gör nu. Assistenten förblir dold.", - "aiEnableTitle": "Slå på den", - "aiEnableDesc": "Lägger till en assistent som läser din installation och föreslår ändringar som du godkänner. Kräver en leverantör som du tillhandahåller, till exempel en lokal Ollama.", - "aiNote": "Ingenting skickas någonstans förrän du lägger till en leverantör och skickar ett meddelande." - }, - "settings": { - "admin": { - "globallyEnabled": { - "label": "AI-assistent", - "description": "Låt användare aktivera AI-assistenten. Medan detta är avstängt är assistenten dold och blockerad för alla." - }, - "privateEndpoints": { - "label": "Tillåtna privata AI-värdar" - } - }, - "host": { - "enableAiAssistant": { - "label": "Aktivera AI-assistenten", - "description": "Tillåt AI-assistenten att hjälpa till i den här värdens terminal. Av som standard och kräver fortfarande att AI är aktiverat för ditt konto." - } - } + "aiTitle": "AI assistant", + "aiIntro": "Termix can include an optional AI assistant. You can change this later in your settings.", + "aiSkipTitle": "Leave it off", + "aiSkipDesc": "Termix works as it does now. The assistant stays hidden.", + "aiEnableTitle": "Turn it on", + "aiEnableDesc": "Adds an assistant that reads your setup and suggests changes you approve. Needs a provider you supply, such as a local Ollama.", + "aiNote": "Nothing is sent anywhere until you add a provider and send a message." }, "hosts": { - "docsLink": "Visa dokument" + "docsLink": "View docs" } } diff --git a/plugins/ai/locales/translated/th_TH.json b/plugins/ai/locales/translated/th_TH.json index 451db02ba..7b5758ffa 100644 --- a/plugins/ai/locales/translated/th_TH.json +++ b/plugins/ai/locales/translated/th_TH.json @@ -1,90 +1,119 @@ { + "permissions": { + "use": { + "title": "Use the assistant", + "description": "Open the assistant and ask it things." + }, + "manage_providers": { + "title": "Manage providers", + "description": "Add, edit and remove the AI providers and their API keys." + }, + "apply_proposals": { + "title": "Apply proposals", + "description": "Let the assistant carry out the changes it suggests." + }, + "services.use": { + "title": "Use AI from other features", + "description": "Other features may call the assistant on your behalf." + }, + "secrets.share": { + "title": "Share the API key", + "description": "Other features may use the stored AI API key without seeing it." + } + }, + "settings": { + "assistantUnavailable": "The AI assistant is turned off on this server.", + "providersNeedOptIn": "Turn on the AI assistant above to add providers.", + "admin": { + "globallyEnabled": { + "label": "AI assistant", + "description": "Let users turn on the AI assistant. While this is off, the assistant is hidden and blocked for everyone." + }, + "privateEndpoints": { + "label": "Allowed private AI hosts", + "description": "Hosts on your private network that users may point a provider at, such as a self-hosted Ollama. Put one host on each line." + } + }, + "host": { + "enableAiAssistant": { + "label": "Enable AI Assistant", + "description": "Allow the AI assistant to help in this host's terminal. Off by default, and still needs AI enabled for your account." + } + } + }, "ai": { - "title": "ผู้ช่วย", - "send": "ส่ง", - "stop": "หยุด", - "save": "บันทึก", - "cancel": "ยกเลิก", - "running": "วิ่ง", - "approve": "อนุมัติ", - "reject": "ปฏิเสธ", - "inputPlaceholder": "สอบถามเกี่ยวกับเซิร์ฟเวอร์ของคุณ หรืออธิบายการเปลี่ยนแปลงที่คุณต้องการเสนอแนะ", - "selectProvider": "เลือกผู้ให้บริการ", - "providerSettings": "การตั้งค่าผู้ให้บริการ", - "addProvider": "เพิ่มผู้ให้บริการ", - "editProvider": "แก้ไขผู้ให้บริการ", - "removeProvider": "ลบผู้ให้บริการ", - "providerType": "ผู้ให้บริการ", - "providerLabel": "ชื่อ", - "providerLabelPlaceholder": "ตัวอย่างเช่น: Ollama ท้องถิ่น", - "baseUrl": "ที่อยู่เซิร์ฟเวอร์", - "apiKey": "คีย์ API", - "defaultModel": "โมเดลเริ่มต้น", - "defaultModelPlaceholder": "ตัวอย่างเช่น: llama3.1 หรือ claude-opus-5", - "labelRequired": "ตั้งชื่อให้ผู้ให้บริการรายนี้", - "providerSaveFailed": "ไม่สามารถบันทึกผู้ให้บริการได้", - "providerUpdated": "ผู้ให้บริการได้รับการอัปเดตแล้ว", - "providerDeleteFailed": "ไม่สามารถลบผู้ให้บริการได้", - "privateEndpointHint": "การเข้าถึงที่อยู่บนเครือข่ายส่วนตัวของคุณนั้น จำเป็นต้องให้ผู้ดูแลระบบอนุญาตก่อน", - "providerOllama": "โอลาม่า", - "providerAnthropic": "แอนโทรปิก", - "providerOpenai": "โอเพ่นไอ", - "providerGemini": "กูเกิล เจมินี", - "providerOpenaiCompatible": "เข้ากันได้กับ OpenAI", - "toolArguments": "ป้อนข้อมูล", - "toolResult": "ผลลัพธ์", - "statusApplied": "สมัครแล้ว", - "statusRejected": "ถูกปฏิเสธ", - "proposalApplied": "มีการเปลี่ยนแปลงเกิดขึ้น", - "proposalApplyFailed": "ไม่สามารถทำการเปลี่ยนแปลงได้", - "proposalRejectFailed": "ไม่สามารถปฏิเสธการเปลี่ยนแปลงได้", - "enableTitle": "เปิดใช้งานผู้ช่วย AI", - "enableDescription": "ให้ผู้ช่วยอ่านการตั้งค่าของคุณและแนะนำการเปลี่ยนแปลงเพื่อให้คุณอนุมัติ", - "readOnlyCommands": "อนุญาตคำสั่งวินิจฉัยแบบอ่านอย่างเดียว", - "readOnlyCommandsDescription": "ผู้ช่วยอาจเรียกใช้คำสั่งที่ปลอดภัยเพียงไม่กี่คำสั่ง เช่น df และ uptime โดยไม่ต้องถามทุกครั้ง คำสั่งใดๆ ที่เปลี่ยนแปลงสถานะของเซิร์ฟเวอร์จะถูกเสนอให้ดำเนินการก่อนเสมอ", - "modelDetectFailed": "ไม่สามารถติดต่อผู้ให้บริการได้ ดังนั้นนี่จึงเป็นรายการทั่วไป คุณสามารถพิมพ์ชื่อรุ่นใดก็ได้", - "modelCustom": "ป้อนชื่อรุ่น", - "modelRefresh": "รีเฟรชรายการ", - "modelPlaceholder": "เลือกหรือพิมพ์แบบจำลอง", - "attachHint": "พิมพ์ @ เพื่ออ้างอิงถึงโฮสต์ สนิปเป็ต หรือระบบอัตโนมัติ การเปลี่ยนแปลงที่เสนอจะถูกนำมาให้คุณอนุมัติ", - "runCommandTitle": "เรียกใช้คำสั่ง", - "assistant": "ผู้ช่วย AI", - "terminalPanelEmpty": "สอบถามผู้ช่วยเกี่ยวกับโฮสต์นี้ การเปลี่ยนแปลงสถานะใดๆ ต้องได้รับการอนุมัติจากคุณก่อน", - "terminalPanelPlaceholder": "สอบถามเกี่ยวกับโฮสต์รายนี้...", - "noProvidersConfigured": "ยังไม่ได้ตั้งค่าผู้ให้บริการ AI เพิ่มผู้ให้บริการในแท็บผู้ช่วย AI", - "runsInOpenTerminal": "ทำงานในเซสชันเทอร์มินัลที่เปิดอยู่ของคุณ", - "runInTerminal": "วิ่ง" + "title": "Assistant", + "send": "Send", + "stop": "Stop", + "save": "Save", + "cancel": "Cancel", + "running": "running", + "approve": "Approve", + "reject": "Reject", + "inputPlaceholder": "Ask about your servers, or describe a change to propose", + "selectProvider": "Select a provider", + "providerSettings": "Provider settings", + "addProvider": "Add provider", + "editProvider": "Edit provider", + "removeProvider": "Remove provider", + "providerType": "Provider", + "providerLabel": "Name", + "providerLabelPlaceholder": "For example: Local Ollama", + "baseUrl": "Server address", + "apiKey": "API key", + "defaultModel": "Default model", + "defaultModelPlaceholder": "For example: llama3.1 or claude-opus-5", + "labelRequired": "Give this provider a name", + "providerSaveFailed": "Could not save the provider", + "providerUpdated": "Provider updated", + "providerDeleteFailed": "Could not remove the provider", + "privateEndpointHint": "Addresses on your private network need an administrator to allow the host first.", + "providerOllama": "Ollama", + "providerAnthropic": "Anthropic", + "providerOpenai": "OpenAI", + "providerGemini": "Google Gemini", + "providerOpenaiCompatible": "OpenAI compatible", + "toolArguments": "Input", + "toolResult": "Result", + "statusApplied": "Applied", + "statusRejected": "Rejected", + "proposalApplied": "Change applied", + "proposalApplyFailed": "Could not apply the change", + "proposalRejectFailed": "Could not reject the change", + "enableTitle": "Enable the AI assistant", + "enableDescription": "Let the assistant read your setup and suggest changes for you to approve.", + "readOnlyCommands": "Allow read-only diagnostic commands", + "readOnlyCommandsDescription": "The assistant may run a short list of safe commands like df and uptime without asking each time. Anything that changes a server is always proposed first.", + "modelDetectFailed": "Could not reach the provider, so this is a general list. You can type any model name.", + "modelCustom": "Enter a model name", + "modelRefresh": "Refresh list", + "modelPlaceholder": "Choose or type a model", + "attachHint": "Type @ to reference a host, snippet or automation. Changes are proposed for you to approve.", + "runCommandTitle": "Run command", + "assistant": "AI Assistant", + "terminalPanelEmpty": "Ask the assistant about this host. Anything that changes state needs your approval first.", + "terminalPanelPlaceholder": "Ask about this host...", + "noProvidersConfigured": "No AI provider is configured yet. Add one in the AI assistant tab.", + "runsInOpenTerminal": "Runs in your open terminal session.", + "runInTerminal": "Run", + "terminalContextPrefill": "Here is my terminal output:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Let other features use your AI provider API key for their own requests. The key is never copied, and you can revoke this at any time." + } }, "nav": { "ai": "AI" }, "onboarding": { - "aiTitle": "ผู้ช่วย AI", - "aiIntro": "Termix อาจมีผู้ช่วย AI เสริม คุณสามารถเปลี่ยนการตั้งค่าได้ในภายหลัง", - "aiSkipTitle": "ปิดมันไว้", - "aiSkipDesc": "Termix ทำงานเหมือนเดิมทุกประการ ตัวช่วยยังคงซ่อนอยู่", - "aiEnableTitle": "เปิดใช้งาน", - "aiEnableDesc": "เพิ่มผู้ช่วยที่จะอ่านการตั้งค่าของคุณและแนะนำการเปลี่ยนแปลงที่คุณต้องอนุมัติ จำเป็นต้องมีผู้ให้บริการที่คุณจัดหาให้ เช่น Ollama ในพื้นที่ของคุณ", - "aiNote": "จะไม่มีการส่งข้อมูลใดๆ จนกว่าคุณจะเพิ่มผู้ให้บริการและส่งข้อความ" - }, - "settings": { - "admin": { - "globallyEnabled": { - "label": "ผู้ช่วย AI", - "description": "อนุญาตให้ผู้ใช้เปิดใช้งานผู้ช่วย AI ได้ เมื่อปิดใช้งานอยู่ ผู้ช่วยจะถูกซ่อนและบล็อกไม่ให้ใครเห็น" - }, - "privateEndpoints": { - "label": "อนุญาตให้โฮสต์ AI ส่วนตัว" - } - }, - "host": { - "enableAiAssistant": { - "label": "เปิดใช้งานผู้ช่วย AI", - "description": "อนุญาตให้ผู้ช่วย AI ช่วยเหลือในเทอร์มินัลของโฮสต์นี้ โดยค่าเริ่มต้นจะปิดอยู่ และยังคงต้องเปิดใช้งาน AI สำหรับบัญชีของคุณก่อน" - } - } + "aiTitle": "AI assistant", + "aiIntro": "Termix can include an optional AI assistant. You can change this later in your settings.", + "aiSkipTitle": "Leave it off", + "aiSkipDesc": "Termix works as it does now. The assistant stays hidden.", + "aiEnableTitle": "Turn it on", + "aiEnableDesc": "Adds an assistant that reads your setup and suggests changes you approve. Needs a provider you supply, such as a local Ollama.", + "aiNote": "Nothing is sent anywhere until you add a provider and send a message." }, "hosts": { - "docsLink": "ดูเอกสาร" + "docsLink": "View docs" } } diff --git a/plugins/ai/locales/translated/tr_TR.json b/plugins/ai/locales/translated/tr_TR.json index 8d22abf89..e2c58918d 100644 --- a/plugins/ai/locales/translated/tr_TR.json +++ b/plugins/ai/locales/translated/tr_TR.json @@ -1,89 +1,118 @@ { - "ai": { - "title": "Asistan", - "send": "Göndermek", - "stop": "Durmak", - "save": "Kaydetmek", - "cancel": "İptal etmek", - "running": "koşma", - "approve": "Onaylamak", - "reject": "Reddetmek", - "inputPlaceholder": "Sunucularınız hakkında bilgi isteyin veya önereceğiniz bir değişikliği açıklayın.", - "selectProvider": "Bir sağlayıcı seçin", - "providerSettings": "Sağlayıcı ayarları", - "addProvider": "Sağlayıcı ekle", - "editProvider": "Sağlayıcıyı düzenle", - "removeProvider": "Sağlayıcıyı kaldır", - "providerType": "Sağlayıcı", - "providerLabel": "İsim", - "providerLabelPlaceholder": "Örneğin: Yerel Ollama", - "baseUrl": "Sunucu adresi", - "apiKey": "API anahtarı", - "defaultModel": "Varsayılan model", - "defaultModelPlaceholder": "Örneğin: llama3.1 veya claude-opus-5", - "labelRequired": "Bu sağlayıcıya bir isim verin.", - "providerSaveFailed": "Sağlayıcı kaydedilemedi.", - "providerUpdated": "Sağlayıcı güncellendi.", - "providerDeleteFailed": "Sağlayıcı kaldırılamadı.", - "privateEndpointHint": "Özel ağınızdaki adreslerin kullanılabilmesi için öncelikle yöneticinin sunucuya izin vermesi gerekmektedir.", - "providerOllama": "Ollama", - "providerAnthropic": "Antropik", - "providerOpenai": "OpenAI", - "providerGemini": "Google Gemini", - "providerOpenaiCompatible": "OpenAI uyumlu", - "toolArguments": "Giriş", - "toolResult": "Sonuç", - "statusApplied": "Uygulandı", - "statusRejected": "Reddedilmiş", - "proposalApplied": "Değişiklik uygulandı.", - "proposalApplyFailed": "Değişiklik uygulanamadı.", - "proposalRejectFailed": "Değişikliği reddedemedim.", - "enableTitle": "Yapay zekâ asistanını etkinleştirin", - "enableDescription": "Asistanın ayarlarınızı okumasını ve onaylamanız için değişiklik önerileri sunmasını sağlayın.", - "readOnlyCommands": "Yalnızca okuma amaçlı tanı komutlarına izin ver", - "readOnlyCommandsDescription": "Yardımcı program, her seferinde sormadan df ve uptime gibi kısa bir güvenli komut listesini çalıştırabilir. Sunucuda değişiklik yapan her şey her zaman önce önerilir.", - "modelDetectFailed": "Sağlayıcıya ulaşılamadı, bu nedenle bu genel bir listedir. İstediğiniz model adını yazabilirsiniz.", - "modelCustom": "Bir model adı girin", - "modelRefresh": "Listeyi yenile", - "modelPlaceholder": "Bir model seçin veya yazın.", - "attachHint": "Bir sunucuya, kod parçasına veya otomasyona referans vermek için @ işaretini kullanın. Onaylamanız için değişiklikler öneriliyor.", - "runCommandTitle": "Çalıştır komutu", - "assistant": "Yapay Zeka Asistanı", - "terminalPanelEmpty": "Bu ev sahibi hakkında asistana danışın. Durum değişikliği gerektiren her şey önce sizin onayınızı gerektirir.", - "terminalPanelPlaceholder": "Bu ev sahibi hakkında bilgi isteyin...", - "noProvidersConfigured": "Henüz hiçbir yapay zeka sağlayıcısı yapılandırılmadı. Yapay zeka asistanı sekmesinden bir tane ekleyin.", - "runsInOpenTerminal": "Açık terminal oturumunuzda çalışır.", - "runInTerminal": "Koşmak" - }, - "nav": { - "ai": "Yapay zeka" - }, - "onboarding": { - "aiTitle": "Yapay zeka asistanı", - "aiIntro": "Termix isteğe bağlı bir yapay zeka asistanı içerebilir. Bunu daha sonra ayarlarınızdan değiştirebilirsiniz.", - "aiSkipTitle": "Kapalı bırakın", - "aiSkipDesc": "Termix şu anki haliyle çalışıyor. Asistan gizli kalıyor.", - "aiEnableTitle": "Açın", - "aiEnableDesc": "Ayarlarınızı okuyan ve onaylamanız halinde değişiklikler öneren bir asistan ekler. Yerel bir Ollama gibi, sizin sağladığınız bir sağlayıcıya ihtiyaç duyar.", - "aiNote": "Bir sağlayıcı ekleyip mesaj gönderene kadar hiçbir şey hiçbir yere gönderilmez." + "permissions": { + "use": { + "title": "Use the assistant", + "description": "Open the assistant and ask it things." + }, + "manage_providers": { + "title": "Manage providers", + "description": "Add, edit and remove the AI providers and their API keys." + }, + "apply_proposals": { + "title": "Apply proposals", + "description": "Let the assistant carry out the changes it suggests." + }, + "services.use": { + "title": "Use AI from other features", + "description": "Other features may call the assistant on your behalf." + }, + "secrets.share": { + "title": "Share the API key", + "description": "Other features may use the stored AI API key without seeing it." + } }, "settings": { + "assistantUnavailable": "The AI assistant is turned off on this server.", + "providersNeedOptIn": "Turn on the AI assistant above to add providers.", "admin": { "globallyEnabled": { - "label": "Yapay zeka asistanı", - "description": "Kullanıcıların yapay zeka asistanını açmasına izin verin. Bu özellik kapalıyken, asistan gizlenir ve herkes için engellenir." + "label": "AI assistant", + "description": "Let users turn on the AI assistant. While this is off, the assistant is hidden and blocked for everyone." }, "privateEndpoints": { - "label": "Özel yapay zeka sunucularına izin verildi." + "label": "Allowed private AI hosts", + "description": "Hosts on your private network that users may point a provider at, such as a self-hosted Ollama. Put one host on each line." } }, "host": { "enableAiAssistant": { - "label": "Yapay Zeka Asistanını Etkinleştir", - "description": "Bu sunucunun terminalinde yapay zeka asistanının yardımcı olmasına izin verin. Varsayılan olarak kapalıdır ve hesabınız için yapay zekanın etkinleştirilmiş olması gerekir." + "label": "Enable AI Assistant", + "description": "Allow the AI assistant to help in this host's terminal. Off by default, and still needs AI enabled for your account." } } }, + "ai": { + "title": "Assistant", + "send": "Send", + "stop": "Durdurma", + "save": "Kaydet", + "cancel": "İptal", + "running": "çalışan", + "approve": "Approve", + "reject": "Reject", + "inputPlaceholder": "Ask about your servers, or describe a change to propose", + "selectProvider": "Select a provider", + "providerSettings": "Provider settings", + "addProvider": "Add provider", + "editProvider": "Edit provider", + "removeProvider": "Remove provider", + "providerType": "Provider", + "providerLabel": "Ad", + "providerLabelPlaceholder": "For example: Local Ollama", + "baseUrl": "Server address", + "apiKey": "API key", + "defaultModel": "Default model", + "defaultModelPlaceholder": "For example: llama3.1 or claude-opus-5", + "labelRequired": "Give this provider a name", + "providerSaveFailed": "Could not save the provider", + "providerUpdated": "Provider updated", + "providerDeleteFailed": "Could not remove the provider", + "privateEndpointHint": "Addresses on your private network need an administrator to allow the host first.", + "providerOllama": "Ollama", + "providerAnthropic": "Anthropic", + "providerOpenai": "OpenAI", + "providerGemini": "Google Gemini", + "providerOpenaiCompatible": "OpenAI compatible", + "toolArguments": "Giriş", + "toolResult": "Result", + "statusApplied": "Applied", + "statusRejected": "Rejected", + "proposalApplied": "Change applied", + "proposalApplyFailed": "Could not apply the change", + "proposalRejectFailed": "Could not reject the change", + "enableTitle": "Enable the AI assistant", + "enableDescription": "Let the assistant read your setup and suggest changes for you to approve.", + "readOnlyCommands": "Allow read-only diagnostic commands", + "readOnlyCommandsDescription": "The assistant may run a short list of safe commands like df and uptime without asking each time. Anything that changes a server is always proposed first.", + "modelDetectFailed": "Could not reach the provider, so this is a general list. You can type any model name.", + "modelCustom": "Enter a model name", + "modelRefresh": "Refresh list", + "modelPlaceholder": "Choose or type a model", + "attachHint": "Type @ to reference a host, snippet or automation. Changes are proposed for you to approve.", + "runCommandTitle": "Run command", + "assistant": "AI Assistant", + "terminalPanelEmpty": "Ask the assistant about this host. Anything that changes state needs your approval first.", + "terminalPanelPlaceholder": "Ask about this host...", + "noProvidersConfigured": "No AI provider is configured yet. Add one in the AI assistant tab.", + "runsInOpenTerminal": "Runs in your open terminal session.", + "runInTerminal": "Çalıştır", + "terminalContextPrefill": "Here is my terminal output:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Let other features use your AI provider API key for their own requests. The key is never copied, and you can revoke this at any time." + } + }, + "nav": { + "ai": "AI" + }, + "onboarding": { + "aiTitle": "AI assistant", + "aiIntro": "Termix can include an optional AI assistant. You can change this later in your settings.", + "aiSkipTitle": "Leave it off", + "aiSkipDesc": "Termix works as it does now. The assistant stays hidden.", + "aiEnableTitle": "Turn it on", + "aiEnableDesc": "Adds an assistant that reads your setup and suggests changes you approve. Needs a provider you supply, such as a local Ollama.", + "aiNote": "Nothing is sent anywhere until you add a provider and send a message." + }, "hosts": { "docsLink": "Dokümanları görüntüle" } diff --git a/plugins/ai/locales/translated/uk_UA.json b/plugins/ai/locales/translated/uk_UA.json index afbc7f59b..7b5758ffa 100644 --- a/plugins/ai/locales/translated/uk_UA.json +++ b/plugins/ai/locales/translated/uk_UA.json @@ -1,90 +1,119 @@ { - "ai": { - "title": "Помічник", - "send": "Надіслати", - "stop": "СТІЙ", - "save": "Зберегти", - "cancel": "Скасувати", - "running": "біг", - "approve": "Схвалити", - "reject": "Відхилити", - "inputPlaceholder": "Запитайте про ваші сервери або опишіть зміну, яку ви хочете запропонувати", - "selectProvider": "Виберіть постачальника", - "providerSettings": "Налаштування постачальника", - "addProvider": "Додати постачальника", - "editProvider": "Редагувати постачальника", - "removeProvider": "Видалити постачальника", - "providerType": "Постачальник", - "providerLabel": "Ім'я", - "providerLabelPlaceholder": "Наприклад: Місцевий Оллама", - "baseUrl": "Адреса сервера", - "apiKey": "Ключ API", - "defaultModel": "Модель за замовчуванням", - "defaultModelPlaceholder": "Наприклад: llama3.1 або claude-opus-5", - "labelRequired": "Введіть назву цього постачальника", - "providerSaveFailed": "Не вдалося зберегти постачальника", - "providerUpdated": "Постачальника оновлено", - "providerDeleteFailed": "Не вдалося видалити постачальника", - "privateEndpointHint": "Адреси у вашій приватній мережі спочатку потребують дозволу адміністратора хоста.", - "providerOllama": "Оллама", - "providerAnthropic": "Антропний", - "providerOpenai": "OpenAI", - "providerGemini": "Google Близнюки", - "providerOpenaiCompatible": "Сумісний з OpenAI", - "toolArguments": "Вхід", - "toolResult": "Результат", - "statusApplied": "Застосовано", - "statusRejected": "Відхилено", - "proposalApplied": "Зміну застосовано", - "proposalApplyFailed": "Не вдалося застосувати зміну", - "proposalRejectFailed": "Не вдалося відхилити зміну", - "enableTitle": "Увімкнути помічника зі штучним інтелектом", - "enableDescription": "Дозвольте асистенту прочитати ваші налаштування та запропонувати зміни для вашого схвалення.", - "readOnlyCommands": "Дозволити діагностичні команди лише для читання", - "readOnlyCommandsDescription": "Помічник може виконувати короткий список безпечних команд, таких як df та uptime, не запитуючи щоразу. Будь-які зміни на сервері завжди пропонуються першими.", - "modelDetectFailed": "Не вдалося зв’язатися з постачальником, тому це загальний список. Ви можете ввести будь-яку назву моделі.", - "modelCustom": "Введіть назву моделі", - "modelRefresh": "Оновити список", - "modelPlaceholder": "Виберіть або введіть модель", - "attachHint": "Введіть @, щоб посилатися на хост, фрагмент або автоматизацію. Зміни пропонуються для вашого схвалення.", - "runCommandTitle": "Виконати команду", - "assistant": "Помічник зі штучним інтелектом", - "terminalPanelEmpty": "Запитайте асистента про цього хоста. Будь-яка зміна стану потребує вашого попереднього схвалення.", - "terminalPanelPlaceholder": "Запитайте про цього хоста...", - "noProvidersConfigured": "Постачальника штучного інтелекту ще не налаштовано. Додайте його на вкладці помічника штучного інтелекту.", - "runsInOpenTerminal": "Працює у вашому відкритому термінальному сеансі.", - "runInTerminal": "Бігти" - }, - "nav": { - "ai": "Штучний інтелект" - }, - "onboarding": { - "aiTitle": "Асистент зі штучним інтелектом", - "aiIntro": "Termix може включати додатковий помічник зі штучним інтелектом. Ви можете змінити це пізніше в налаштуваннях.", - "aiSkipTitle": "Залиште це вимкненим", - "aiSkipDesc": "Termix працює як і зараз. Помічник залишається прихованим.", - "aiEnableTitle": "Увімкніть це", - "aiEnableDesc": "Додає помічника, який читає ваші налаштування та пропонує зміни, які ви схвалюєте. Потрібен постачальник, якого ви надаєте, наприклад, місцевий Ollama.", - "aiNote": "Нічого нікуди не надсилається, доки ви не додасте постачальника та не надішлете повідомлення." + "permissions": { + "use": { + "title": "Use the assistant", + "description": "Open the assistant and ask it things." + }, + "manage_providers": { + "title": "Manage providers", + "description": "Add, edit and remove the AI providers and their API keys." + }, + "apply_proposals": { + "title": "Apply proposals", + "description": "Let the assistant carry out the changes it suggests." + }, + "services.use": { + "title": "Use AI from other features", + "description": "Other features may call the assistant on your behalf." + }, + "secrets.share": { + "title": "Share the API key", + "description": "Other features may use the stored AI API key without seeing it." + } }, "settings": { + "assistantUnavailable": "The AI assistant is turned off on this server.", + "providersNeedOptIn": "Turn on the AI assistant above to add providers.", "admin": { "globallyEnabled": { - "label": "Асистент зі штучним інтелектом", - "description": "Дозвольте користувачам увімкнути помічника зі штучним інтелектом. Коли це вимкнено, помічник прихований і заблокований для всіх." + "label": "AI assistant", + "description": "Let users turn on the AI assistant. While this is off, the assistant is hidden and blocked for everyone." }, "privateEndpoints": { - "label": "Дозволені приватні хости ШІ" + "label": "Allowed private AI hosts", + "description": "Hosts on your private network that users may point a provider at, such as a self-hosted Ollama. Put one host on each line." } }, "host": { "enableAiAssistant": { - "label": "Увімкнути помічника зі штучним інтелектом", - "description": "Дозволити помічнику зі штучним інтелектом допомагати в терміналі цього хоста. Вимкнено за замовчуванням, але все одно потребує ввімкнення штучного інтелекту для вашого облікового запису." + "label": "Enable AI Assistant", + "description": "Allow the AI assistant to help in this host's terminal. Off by default, and still needs AI enabled for your account." } } }, + "ai": { + "title": "Assistant", + "send": "Send", + "stop": "Stop", + "save": "Save", + "cancel": "Cancel", + "running": "running", + "approve": "Approve", + "reject": "Reject", + "inputPlaceholder": "Ask about your servers, or describe a change to propose", + "selectProvider": "Select a provider", + "providerSettings": "Provider settings", + "addProvider": "Add provider", + "editProvider": "Edit provider", + "removeProvider": "Remove provider", + "providerType": "Provider", + "providerLabel": "Name", + "providerLabelPlaceholder": "For example: Local Ollama", + "baseUrl": "Server address", + "apiKey": "API key", + "defaultModel": "Default model", + "defaultModelPlaceholder": "For example: llama3.1 or claude-opus-5", + "labelRequired": "Give this provider a name", + "providerSaveFailed": "Could not save the provider", + "providerUpdated": "Provider updated", + "providerDeleteFailed": "Could not remove the provider", + "privateEndpointHint": "Addresses on your private network need an administrator to allow the host first.", + "providerOllama": "Ollama", + "providerAnthropic": "Anthropic", + "providerOpenai": "OpenAI", + "providerGemini": "Google Gemini", + "providerOpenaiCompatible": "OpenAI compatible", + "toolArguments": "Input", + "toolResult": "Result", + "statusApplied": "Applied", + "statusRejected": "Rejected", + "proposalApplied": "Change applied", + "proposalApplyFailed": "Could not apply the change", + "proposalRejectFailed": "Could not reject the change", + "enableTitle": "Enable the AI assistant", + "enableDescription": "Let the assistant read your setup and suggest changes for you to approve.", + "readOnlyCommands": "Allow read-only diagnostic commands", + "readOnlyCommandsDescription": "The assistant may run a short list of safe commands like df and uptime without asking each time. Anything that changes a server is always proposed first.", + "modelDetectFailed": "Could not reach the provider, so this is a general list. You can type any model name.", + "modelCustom": "Enter a model name", + "modelRefresh": "Refresh list", + "modelPlaceholder": "Choose or type a model", + "attachHint": "Type @ to reference a host, snippet or automation. Changes are proposed for you to approve.", + "runCommandTitle": "Run command", + "assistant": "AI Assistant", + "terminalPanelEmpty": "Ask the assistant about this host. Anything that changes state needs your approval first.", + "terminalPanelPlaceholder": "Ask about this host...", + "noProvidersConfigured": "No AI provider is configured yet. Add one in the AI assistant tab.", + "runsInOpenTerminal": "Runs in your open terminal session.", + "runInTerminal": "Run", + "terminalContextPrefill": "Here is my terminal output:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Let other features use your AI provider API key for their own requests. The key is never copied, and you can revoke this at any time." + } + }, + "nav": { + "ai": "AI" + }, + "onboarding": { + "aiTitle": "AI assistant", + "aiIntro": "Termix can include an optional AI assistant. You can change this later in your settings.", + "aiSkipTitle": "Leave it off", + "aiSkipDesc": "Termix works as it does now. The assistant stays hidden.", + "aiEnableTitle": "Turn it on", + "aiEnableDesc": "Adds an assistant that reads your setup and suggests changes you approve. Needs a provider you supply, such as a local Ollama.", + "aiNote": "Nothing is sent anywhere until you add a provider and send a message." + }, "hosts": { - "docsLink": "Переглянути документи" + "docsLink": "View docs" } } diff --git a/plugins/ai/locales/translated/vi_VN.json b/plugins/ai/locales/translated/vi_VN.json index f96e93f71..e73b28930 100644 --- a/plugins/ai/locales/translated/vi_VN.json +++ b/plugins/ai/locales/translated/vi_VN.json @@ -1,89 +1,118 @@ { - "ai": { - "title": "Trợ lý", - "send": "Gửi", - "stop": "Dừng lại", - "save": "Cứu", - "cancel": "Hủy bỏ", - "running": "đang chạy", - "approve": "Chấp thuận", - "reject": "Từ chối", - "inputPlaceholder": "Hãy hỏi về máy chủ của bạn, hoặc mô tả một thay đổi mà bạn muốn đề xuất.", - "selectProvider": "Chọn nhà cung cấp", - "providerSettings": "Cài đặt nhà cung cấp", - "addProvider": "Thêm nhà cung cấp", - "editProvider": "Chỉnh sửa nhà cung cấp", - "removeProvider": "Xóa nhà cung cấp", - "providerType": "Nhà cung cấp", - "providerLabel": "Tên", - "providerLabelPlaceholder": "Ví dụ: Ollama địa phương", - "baseUrl": "Địa chỉ máy chủ", - "apiKey": "Khóa API", - "defaultModel": "Mô hình mặc định", - "defaultModelPlaceholder": "Ví dụ: llama3.1 hoặc claude-opus-5", - "labelRequired": "Đặt tên cho nhà cung cấp này", - "providerSaveFailed": "Không thể lưu nhà cung cấp", - "providerUpdated": "Nhà cung cấp đã cập nhật", - "providerDeleteFailed": "Không thể xóa nhà cung cấp", - "privateEndpointHint": "Các địa chỉ trên mạng riêng của bạn cần được quản trị viên cho phép truy cập trước.", - "providerOllama": "Ollama", - "providerAnthropic": "Nhân loại", - "providerOpenai": "OpenAI", - "providerGemini": "Google Gemini", - "providerOpenaiCompatible": "Tương thích với OpenAI", - "toolArguments": "Đầu vào", - "toolResult": "Kết quả", - "statusApplied": "Đã áp dụng", - "statusRejected": "Vật bị loại bỏ", - "proposalApplied": "Thay đổi đã được áp dụng", - "proposalApplyFailed": "Không thể áp dụng thay đổi", - "proposalRejectFailed": "Không thể từ chối thay đổi", - "enableTitle": "Kích hoạt trợ lý AI", - "enableDescription": "Hãy để trợ lý đọc cấu hình của bạn và đề xuất các thay đổi để bạn phê duyệt.", - "readOnlyCommands": "Cho phép các lệnh chẩn đoán chỉ đọc", - "readOnlyCommandsDescription": "Trợ lý có thể chạy một danh sách ngắn các lệnh an toàn như df và uptime mà không cần hỏi mỗi lần. Bất kỳ lệnh nào thay đổi máy chủ đều được đề xuất trước tiên.", - "modelDetectFailed": "Không thể liên lạc được với nhà cung cấp, vì vậy đây là danh sách chung. Bạn có thể nhập bất kỳ tên mẫu nào.", - "modelCustom": "Nhập tên mẫu", - "modelRefresh": "Làm mới danh sách", - "modelPlaceholder": "Chọn hoặc nhập mô hình", - "attachHint": "Nhập @ để tham chiếu đến máy chủ, đoạn mã hoặc quy trình tự động hóa. Các thay đổi được đề xuất để bạn phê duyệt.", - "runCommandTitle": "Chạy lệnh", - "assistant": "Trợ lý AI", - "terminalPanelEmpty": "Hãy hỏi trợ lý về máy chủ này. Bất cứ thay đổi nào về trạng thái đều cần sự chấp thuận của bạn trước.", - "terminalPanelPlaceholder": "Hãy hỏi về chủ nhà này...", - "noProvidersConfigured": "Chưa có nhà cung cấp AI nào được cấu hình. Hãy thêm một nhà cung cấp trong tab trợ lý AI.", - "runsInOpenTerminal": "Chương trình này chạy trong cửa sổ dòng lệnh đang mở của bạn.", - "runInTerminal": "Chạy" - }, - "nav": { - "ai": "Trí tuệ nhân tạo" - }, - "onboarding": { - "aiTitle": "Trợ lý AI", - "aiIntro": "Termix có thể bao gồm trợ lý AI tùy chọn. Bạn có thể thay đổi điều này sau trong phần cài đặt.", - "aiSkipTitle": "Đừng làm vậy", - "aiSkipDesc": "Termix vẫn hoạt động như hiện tại. Trợ lý ảo vẫn ẩn mình.", - "aiEnableTitle": "Bật nó lên", - "aiEnableDesc": "Thêm một trợ lý đọc cấu hình của bạn và đề xuất các thay đổi mà bạn chấp thuận. Cần có nhà cung cấp do bạn chỉ định, chẳng hạn như Ollama địa phương.", - "aiNote": "Không có dữ liệu nào được gửi đi cho đến khi bạn thêm nhà cung cấp và gửi tin nhắn." + "permissions": { + "use": { + "title": "Use the assistant", + "description": "Open the assistant and ask it things." + }, + "manage_providers": { + "title": "Manage providers", + "description": "Add, edit and remove the AI providers and their API keys." + }, + "apply_proposals": { + "title": "Apply proposals", + "description": "Let the assistant carry out the changes it suggests." + }, + "services.use": { + "title": "Use AI from other features", + "description": "Other features may call the assistant on your behalf." + }, + "secrets.share": { + "title": "Share the API key", + "description": "Other features may use the stored AI API key without seeing it." + } }, "settings": { + "assistantUnavailable": "The AI assistant is turned off on this server.", + "providersNeedOptIn": "Turn on the AI assistant above to add providers.", "admin": { "globallyEnabled": { - "label": "Trợ lý AI", - "description": "Cho phép người dùng bật trợ lý AI. Khi trợ lý này tắt, nó sẽ bị ẩn và chặn đối với tất cả mọi người." + "label": "AI assistant", + "description": "Let users turn on the AI assistant. While this is off, the assistant is hidden and blocked for everyone." }, "privateEndpoints": { - "label": "Cho phép máy chủ AI riêng" + "label": "Allowed private AI hosts", + "description": "Hosts on your private network that users may point a provider at, such as a self-hosted Ollama. Put one host on each line." } }, "host": { "enableAiAssistant": { - "label": "Kích hoạt Trợ lý AI", - "description": "Cho phép trợ lý AI hỗ trợ trong thiết bị đầu cuối của máy chủ này. Mặc định là tắt, nhưng bạn vẫn cần bật AI cho tài khoản của mình." + "label": "Enable AI Assistant", + "description": "Allow the AI assistant to help in this host's terminal. Off by default, and still needs AI enabled for your account." } } }, + "ai": { + "title": "Assistant", + "send": "Send", + "stop": "Bit dừng", + "save": "Lưu", + "cancel": "Hủy", + "running": "đang chạy", + "approve": "Approve", + "reject": "Reject", + "inputPlaceholder": "Ask about your servers, or describe a change to propose", + "selectProvider": "Select a provider", + "providerSettings": "Provider settings", + "addProvider": "Add provider", + "editProvider": "Edit provider", + "removeProvider": "Remove provider", + "providerType": "Provider", + "providerLabel": "Tên", + "providerLabelPlaceholder": "For example: Local Ollama", + "baseUrl": "Server address", + "apiKey": "API key", + "defaultModel": "Default model", + "defaultModelPlaceholder": "For example: llama3.1 or claude-opus-5", + "labelRequired": "Give this provider a name", + "providerSaveFailed": "Could not save the provider", + "providerUpdated": "Provider updated", + "providerDeleteFailed": "Could not remove the provider", + "privateEndpointHint": "Addresses on your private network need an administrator to allow the host first.", + "providerOllama": "Ollama", + "providerAnthropic": "Anthropic", + "providerOpenai": "OpenAI", + "providerGemini": "Google Gemini", + "providerOpenaiCompatible": "OpenAI compatible", + "toolArguments": "Nhập", + "toolResult": "Result", + "statusApplied": "Applied", + "statusRejected": "Rejected", + "proposalApplied": "Change applied", + "proposalApplyFailed": "Could not apply the change", + "proposalRejectFailed": "Could not reject the change", + "enableTitle": "Enable the AI assistant", + "enableDescription": "Let the assistant read your setup and suggest changes for you to approve.", + "readOnlyCommands": "Allow read-only diagnostic commands", + "readOnlyCommandsDescription": "The assistant may run a short list of safe commands like df and uptime without asking each time. Anything that changes a server is always proposed first.", + "modelDetectFailed": "Could not reach the provider, so this is a general list. You can type any model name.", + "modelCustom": "Enter a model name", + "modelRefresh": "Refresh list", + "modelPlaceholder": "Choose or type a model", + "attachHint": "Type @ to reference a host, snippet or automation. Changes are proposed for you to approve.", + "runCommandTitle": "Run command", + "assistant": "AI Assistant", + "terminalPanelEmpty": "Ask the assistant about this host. Anything that changes state needs your approval first.", + "terminalPanelPlaceholder": "Ask about this host...", + "noProvidersConfigured": "No AI provider is configured yet. Add one in the AI assistant tab.", + "runsInOpenTerminal": "Runs in your open terminal session.", + "runInTerminal": "Chạy", + "terminalContextPrefill": "Here is my terminal output:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Let other features use your AI provider API key for their own requests. The key is never copied, and you can revoke this at any time." + } + }, + "nav": { + "ai": "AI" + }, + "onboarding": { + "aiTitle": "AI assistant", + "aiIntro": "Termix can include an optional AI assistant. You can change this later in your settings.", + "aiSkipTitle": "Leave it off", + "aiSkipDesc": "Termix works as it does now. The assistant stays hidden.", + "aiEnableTitle": "Turn it on", + "aiEnableDesc": "Adds an assistant that reads your setup and suggests changes you approve. Needs a provider you supply, such as a local Ollama.", + "aiNote": "Nothing is sent anywhere until you add a provider and send a message." + }, "hosts": { "docsLink": "Xem tài liệu" } diff --git a/plugins/ai/locales/translated/zh_CN.json b/plugins/ai/locales/translated/zh_CN.json index c22094096..cc88ec8f6 100644 --- a/plugins/ai/locales/translated/zh_CN.json +++ b/plugins/ai/locales/translated/zh_CN.json @@ -1,4 +1,46 @@ { + "permissions": { + "use": { + "title": "使用助手", + "description": "打开助手并向其提问。" + }, + "manage_providers": { + "title": "管理服务提供商", + "description": "添加、编辑和移除 AI 服务提供商及其 API 密钥。" + }, + "apply_proposals": { + "title": "应用建议", + "description": "允许助手执行其建议的更改。" + }, + "services.use": { + "title": "在其他功能中使用 AI", + "description": "其他功能可以代表你调用助手。" + }, + "secrets.share": { + "title": "共享 API 密钥", + "description": "其他功能可以使用已保存的 AI API 密钥,但无法查看其内容。" + } + }, + "settings": { + "assistantUnavailable": "此服务器已关闭 AI 助手。", + "providersNeedOptIn": "请先在上方启用 AI 助手,再添加服务提供商。", + "admin": { + "globallyEnabled": { + "label": "AI 助手", + "description": "允许用户开启 AI 助手。关闭此功能后,助手将被隐藏,所有用户均无法使用。" + }, + "privateEndpoints": { + "label": "允许的私有 AI 主机", + "description": "允许用户将服务提供商指向的内网主机,例如自托管的 Ollama。每行填写一台主机。" + } + }, + "host": { + "enableAiAssistant": { + "label": "启用 AI 助手", + "description": "允许 AI 助手在此主机的终端中提供帮助。默认关闭,且你的账户也必须启用 AI。" + } + } + }, "ai": { "title": "助手", "send": "发送", @@ -8,24 +50,24 @@ "running": "运行中", "approve": "批准", "reject": "拒绝", - "inputPlaceholder": "询问服务器相关情况,或描述要提出的变更建议", + "inputPlaceholder": "询问服务器相关问题,或描述你想进行的更改", "selectProvider": "选择服务提供商", - "providerSettings": "提供商设置", - "addProvider": "添加提供商", + "providerSettings": "服务提供商设置", + "addProvider": "添加服务提供商", "editProvider": "编辑提供商", - "removeProvider": "移除提供者", + "removeProvider": "移除服务提供商", "providerType": "提供商", "providerLabel": "名称", "providerLabelPlaceholder": "例如:本地 Ollama", "baseUrl": "服务器地址", "apiKey": "API 密钥", "defaultModel": "默认模型", - "defaultModelPlaceholder": "例如:llama3.1 或 claude-opus-5", + "defaultModelPlaceholder": "例如 llama3.1 或 claude-opus-5", "labelRequired": "给此提供商起个名字", - "providerSaveFailed": "无法保存提供商", - "providerUpdated": "提供商已更新", - "providerDeleteFailed": "无法移除提供商", - "privateEndpointHint": "您私有网络上的地址需要管理员先允许主机访问。", + "providerSaveFailed": "无法保存服务提供商", + "providerUpdated": "服务提供商已更新", + "providerDeleteFailed": "无法移除服务提供商", + "privateEndpointHint": "使用内网地址前,需要管理员先允许该主机。", "providerOllama": "Ollama", "providerAnthropic": "Anthropic", "providerOpenai": "OpenAI", @@ -35,56 +77,46 @@ "toolResult": "结果", "statusApplied": "已应用", "statusRejected": "已拒绝", - "proposalApplied": "变更已生效", + "proposalApplied": "更改已应用", "proposalApplyFailed": "无法应用更改", "proposalRejectFailed": "无法拒绝更改", "enableTitle": "启用 AI 助手", - "enableDescription": "让助手读取您的设置并提出更改建议,供您批准。", + "enableDescription": "允许助手读取你的配置并提出更改建议,由你批准后执行。", "readOnlyCommands": "允许只读诊断命令", - "readOnlyCommandsDescription": "助手可能会在不每次都询问的情况下运行一些安全的命令,例如 `df` 和 `uptime`。任何会更改服务器的操作都会优先被提出。", + "readOnlyCommandsDescription": "助手可以执行 df、uptime 等少量安全命令,无需每次询问。任何会修改服务器的操作都会先提交建议。", "modelDetectFailed": "无法联系到提供商,所以这里提供的是通用列表。您可以输入任何模型名称。", "modelCustom": "请输入模型名称", "modelRefresh": "刷新列表", "modelPlaceholder": "选择或输入模型", - "attachHint": "输入 @ 符号可引用主机、代码片段或自动化流程。系统会提出更改建议,供您批准。", - "runCommandTitle": "运行命令", - "assistant": "人工智能助手", - "terminalPanelEmpty": "向助理询问有关此房东的信息。任何状态变更都需要您先批准。", - "terminalPanelPlaceholder": "询问一下这位房东的情况……", - "noProvidersConfigured": "尚未配置任何 AI 提供商。请在 AI 助手选项卡中添加。", - "runsInOpenTerminal": "在打开的终端会话中运行。", - "runInTerminal": "跑步" + "attachHint": "输入 @ 引用主机、代码片段或自动化。更改会先提交给你批准。", + "runCommandTitle": "执行命令", + "assistant": "AI 助手", + "terminalPanelEmpty": "向助手询问此主机的相关问题。任何会改变状态的操作都需要先获得你的批准。", + "terminalPanelPlaceholder": "询问此主机的相关问题……", + "noProvidersConfigured": "尚未配置 AI 服务提供商,请在 AI 助手标签页中添加。", + "runsInOpenTerminal": "在你已打开的终端会话中执行。", + "runInTerminal": "运行", + "terminalContextPrefill": "以下是我的终端输出:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "允许其他功能使用你的 AI 服务提供商 API 密钥发起请求。密钥不会被复制,你可以随时撤销授权。" + } }, "nav": { "ai": "AI" }, "onboarding": { "aiTitle": "AI 助手", - "aiIntro": "Termix 可以包含一个可选的 AI 助手。您可以稍后在设置中更改此选项。", + "aiIntro": "Termix 提供可选的 AI 助手,你可以稍后在设置中更改。", "aiSkipTitle": "禁用", "aiSkipDesc": "Termix 正常工作,AI 助手将保持隐藏状态。", "aiEnableTitle": "启用", "aiEnableDesc": "启用 AI 助手,它将分析您的配置并提供优化建议。需自行配置服务商,例如本地运行的 Ollama。", "aiNote": "在您配置服务商并主动发送消息之前,绝不会向外发送任何数据。" }, - "settings": { - "admin": { - "globallyEnabled": { - "label": "AI 助手", - "description": "允许用户开启 AI 助手。关闭此功能后,助手将被隐藏,所有用户均无法使用。" - }, - "privateEndpoints": { - "label": "允许的私有 AI 主机" - } - }, - "host": { - "enableAiAssistant": { - "label": "启用人工智能助手", - "description": "允许 AI 助手在此主机的终端上提供帮助。默认情况下处于关闭状态,但仍需在您的帐户中启用 AI 功能。" - } - } - }, "hosts": { "docsLink": "查看文档" + }, + "plugin": { + "name": "AI 助手" } } diff --git a/plugins/ai/locales/translated/zh_TW.json b/plugins/ai/locales/translated/zh_TW.json index 1f56ed0e6..57535668c 100644 --- a/plugins/ai/locales/translated/zh_TW.json +++ b/plugins/ai/locales/translated/zh_TW.json @@ -1,89 +1,118 @@ { - "ai": { - "title": "助理", - "send": "傳送", - "stop": "停止", - "save": "節省", - "cancel": "取消", - "running": "跑步", - "approve": "核准", - "reject": "拒絕", - "inputPlaceholder": "詢問伺服器相關情況,或描述要提出的變更建議", - "selectProvider": "選擇服務提供者", - "providerSettings": "提供者設定", - "addProvider": "新增提供者", - "editProvider": "編輯提供者", - "removeProvider": "移除提供者", - "providerType": "提供者", - "providerLabel": "姓名", - "providerLabelPlaceholder": "例如:本地奧拉馬", - "baseUrl": "伺服器位址", - "apiKey": "API金鑰", - "defaultModel": "預設模型", - "defaultModelPlaceholder": "例如:llama3.1 或 claude-opus-5", - "labelRequired": "給這家服務提供者取個名字", - "providerSaveFailed": "無法儲存提供者", - "providerUpdated": "提供者已更新", - "providerDeleteFailed": "無法移除提供者", - "privateEndpointHint": "您私有網路上的位址需要管理員先允許主機存取。", - "providerOllama": "奧拉瑪", - "providerAnthropic": "人類學", - "providerOpenai": "OpenAI", - "providerGemini": "Google Gemini", - "providerOpenaiCompatible": "相容 OpenAI", - "toolArguments": "輸入", - "toolResult": "結果", - "statusApplied": "應用", - "statusRejected": "已拒絕", - "proposalApplied": "變更已生效", - "proposalApplyFailed": "無法套用變更", - "proposalRejectFailed": "無法拒絕更改", - "enableTitle": "啟用人工智慧助手", - "enableDescription": "請助手讀取您的設定並提出更改建議,供您批准。", - "readOnlyCommands": "允許只讀診斷命令", - "readOnlyCommandsDescription": "助手可能會在不每次都詢問的情況下執行一些安全的命令,例如 `df` 和 `uptime`。任何會更改伺服器的操作都會優先被提出。", - "modelDetectFailed": "無法聯繫到供應商,所以這裡提供的是通用清單。您可以輸入任何型號名稱。", - "modelCustom": "請輸入型號名稱", - "modelRefresh": "重新整理清單", - "modelPlaceholder": "選擇或輸入型號", - "attachHint": "輸入 @ 符號可引用主機、程式碼片段或自動化流程。系統會提出更改建議,供您批准。", - "runCommandTitle": "運行命令", - "assistant": "人工智慧助手", - "terminalPanelEmpty": "向助理詢問有關此房東的資訊。任何狀態變更都需要您先批准。", - "terminalPanelPlaceholder": "詢問一下這位房東的狀況…", - "noProvidersConfigured": "尚未配置任何 AI 提供者。請在 AI 助理標籤中新增。", - "runsInOpenTerminal": "在開啟的終端機會話中運行。", - "runInTerminal": "跑步" - }, - "nav": { - "ai": "人工智慧" - }, - "onboarding": { - "aiTitle": "人工智慧助手", - "aiIntro": "Termix 可以包含一個可選的 AI 助手。您可以稍後在設定中變更此選項。", - "aiSkipTitle": "丟開", - "aiSkipDesc": "Termix 的運作方式與現在相同。助手保持隱藏狀態。", - "aiEnableTitle": "打開它", - "aiEnableDesc": "添加一個助手,它可以讀取您的設定並提出您批准的更改建議。需要您提供服務提供者,例如當地的 Ollama 服務提供者。", - "aiNote": "在您新增服務提供者並發送訊息之前,任何內容都不會發送到任何地方。" + "permissions": { + "use": { + "title": "Use the assistant", + "description": "Open the assistant and ask it things." + }, + "manage_providers": { + "title": "Manage providers", + "description": "Add, edit and remove the AI providers and their API keys." + }, + "apply_proposals": { + "title": "Apply proposals", + "description": "Let the assistant carry out the changes it suggests." + }, + "services.use": { + "title": "Use AI from other features", + "description": "Other features may call the assistant on your behalf." + }, + "secrets.share": { + "title": "Share the API key", + "description": "Other features may use the stored AI API key without seeing it." + } }, "settings": { + "assistantUnavailable": "The AI assistant is turned off on this server.", + "providersNeedOptIn": "Turn on the AI assistant above to add providers.", "admin": { "globallyEnabled": { - "label": "人工智慧助手", - "description": "允許用戶開啟AI助理。關閉此功能後,助手將被隱藏,所有使用者均無法使用。" + "label": "AI assistant", + "description": "Let users turn on the AI assistant. While this is off, the assistant is hidden and blocked for everyone." }, "privateEndpoints": { - "label": "允許的私有人工智慧主機" + "label": "Allowed private AI hosts", + "description": "Hosts on your private network that users may point a provider at, such as a self-hosted Ollama. Put one host on each line." } }, "host": { "enableAiAssistant": { - "label": "啟用人工智慧助手", - "description": "允許 AI 助理在此主機的終端機上提供協助。預設為關閉狀態,但仍需在您的帳戶中啟用 AI 功能。" + "label": "Enable AI Assistant", + "description": "Allow the AI assistant to help in this host's terminal. Off by default, and still needs AI enabled for your account." } } }, + "ai": { + "title": "Assistant", + "send": "Send", + "stop": "停止位元", + "save": "儲存", + "cancel": "取消", + "running": "執行中", + "approve": "Approve", + "reject": "Reject", + "inputPlaceholder": "Ask about your servers, or describe a change to propose", + "selectProvider": "Select a provider", + "providerSettings": "Provider settings", + "addProvider": "Add provider", + "editProvider": "Edit provider", + "removeProvider": "Remove provider", + "providerType": "Provider", + "providerLabel": "名稱", + "providerLabelPlaceholder": "For example: Local Ollama", + "baseUrl": "Server address", + "apiKey": "API key", + "defaultModel": "Default model", + "defaultModelPlaceholder": "For example: llama3.1 or claude-opus-5", + "labelRequired": "Give this provider a name", + "providerSaveFailed": "Could not save the provider", + "providerUpdated": "Provider updated", + "providerDeleteFailed": "Could not remove the provider", + "privateEndpointHint": "Addresses on your private network need an administrator to allow the host first.", + "providerOllama": "Ollama", + "providerAnthropic": "Anthropic", + "providerOpenai": "OpenAI", + "providerGemini": "Google Gemini", + "providerOpenaiCompatible": "OpenAI compatible", + "toolArguments": "輸入", + "toolResult": "Result", + "statusApplied": "Applied", + "statusRejected": "Rejected", + "proposalApplied": "Change applied", + "proposalApplyFailed": "Could not apply the change", + "proposalRejectFailed": "Could not reject the change", + "enableTitle": "Enable the AI assistant", + "enableDescription": "Let the assistant read your setup and suggest changes for you to approve.", + "readOnlyCommands": "Allow read-only diagnostic commands", + "readOnlyCommandsDescription": "The assistant may run a short list of safe commands like df and uptime without asking each time. Anything that changes a server is always proposed first.", + "modelDetectFailed": "Could not reach the provider, so this is a general list. You can type any model name.", + "modelCustom": "Enter a model name", + "modelRefresh": "Refresh list", + "modelPlaceholder": "Choose or type a model", + "attachHint": "Type @ to reference a host, snippet or automation. Changes are proposed for you to approve.", + "runCommandTitle": "Run command", + "assistant": "AI Assistant", + "terminalPanelEmpty": "Ask the assistant about this host. Anything that changes state needs your approval first.", + "terminalPanelPlaceholder": "Ask about this host...", + "noProvidersConfigured": "No AI provider is configured yet. Add one in the AI assistant tab.", + "runsInOpenTerminal": "Runs in your open terminal session.", + "runInTerminal": "執行", + "terminalContextPrefill": "Here is my terminal output:\n\n{{output}}\n\n", + "secrets": { + "shareApiKey": "Let other features use your AI provider API key for their own requests. The key is never copied, and you can revoke this at any time." + } + }, + "nav": { + "ai": "AI" + }, + "onboarding": { + "aiTitle": "AI assistant", + "aiIntro": "Termix can include an optional AI assistant. You can change this later in your settings.", + "aiSkipTitle": "Leave it off", + "aiSkipDesc": "Termix works as it does now. The assistant stays hidden.", + "aiEnableTitle": "Turn it on", + "aiEnableDesc": "Adds an assistant that reads your setup and suggests changes you approve. Needs a provider you supply, such as a local Ollama.", + "aiNote": "Nothing is sent anywhere until you add a provider and send a message." + }, "hosts": { "docsLink": "檢視文件" } diff --git a/plugins/alerts/locales/en.json b/plugins/alerts/locales/en.json index 9d7514f0d..b3203e591 100644 --- a/plugins/alerts/locales/en.json +++ b/plugins/alerts/locales/en.json @@ -168,5 +168,8 @@ "showRead": "Show read alerts", "allClear": "All clear", "loading": "Loading..." + }, + "plugin": { + "name": "Alerts" } } diff --git a/plugins/alerts/locales/translated/af_ZA.json b/plugins/alerts/locales/translated/af_ZA.json new file mode 100644 index 000000000..d2a22d477 --- /dev/null +++ b/plugins/alerts/locales/translated/af_ZA.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Waarskuwings" + }, + "permissions": { + "use": { + "title": "Gebruik waarskuwings", + "description": "Kry waarskuwings in die inboks en stuur dit na jou eie kanale." + } + }, + "onboarding": { + "feature": "Waarskuwings", + "featureDesc": "Elke waarskuwing in een inboks, gestuur na Discord, ntfy, e-pos of 'n webhook as jy wil." + }, + "settings": { + "group": { + "general": "Algemeen", + "email": "E-pos" + }, + "admin": { + "announcements": { + "label": "Termix-aankondigings", + "description": "Wys nuus van die Termix-span, soos sekuriteitskennisgewings en vrystellings, in almal se inboks." + }, + "retentionDays": { + "label": "Hou waarskuwings vir (dae)", + "description": "Ouer waarskuwings word uit elke inboks verwyder." + }, + "smtpHost": { + "label": "SMTP-bediener", + "description": "Nodig vir e-poskanale. Los leeg om e-pos af te skakel.", + "placeholder": "smtp.voorbeeld.com" + }, + "smtpPort": { + "label": "SMTP-poort", + "description": "Gewoonlik 587 met STARTTLS of 465 met TLS." + }, + "smtpSecure": { + "label": "Gebruik TLS van die begin af", + "description": "Skakel aan vir poort 465. Los af vir poort 587, wat op sy eie na TLS opgradeer." + }, + "smtpUser": { + "label": "SMTP-gebruikersnaam", + "description": "Los leeg as die bediener nie 'n aanmelding benodig nie." + }, + "smtpPassword": { + "label": "SMTP-wagwoord", + "description": "Geënkripteer gestoor." + }, + "smtpFrom": { + "label": "Van adres", + "description": "Die senderwaarskuwings kom vandaan.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "Waarskuwings-opspringvensters", + "description": "Watter nuwe waarskuwings verskyn terwyl jy Termix gebruik? Hulle beland altyd in die inboks.", + "all": "Alle waarskuwings", + "warning": "Waarskuwings en kritieke", + "critical": "Slegs krities", + "off": "Geen" + } + } + }, + "sections": { + "inbox": "Inboks", + "channels": "Kanale", + "rules": "Afleweringsreëls" + }, + "severity": { + "info": "Inligting", + "success": "Sukses", + "warning": "Waarskuwing", + "critical": "Krities" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "Oop", + "view": "Bekyk", + "unread": "Ongelees", + "deliveryFailed_one": "{{count}} kanaal het misluk", + "deliveryFailed_other": "{{count}} kanale het misluk", + "markRead": "Merk as gelees", + "markUnread": "Merk as ongelees", + "markAllRead": "Merk alles as gelees", + "delete": "Vee uit", + "clearRead": "Vee leeswaarskuwings uit", + "cleared_one": "Verwyderde {{count}} waarskuwing", + "cleared_other": "Verwyderde {{count}} waarskuwings", + "filterAll": "Alles", + "filterUnread": "Ongelees", + "anySeverity": "Enige erns", + "anySource": "Enige bron", + "openAll": "Maak oop in 'n oortjie", + "empty": "Geen waarskuwings nog nie.", + "emptyUnread": "Julle is almal ingehaal.", + "loadMore": "Laai meer" + }, + "channels": { + "intro": "Kanale is waar waarskuwings buite Termix kan gaan. Afleweringsreëls kies watter waarskuwings dit gebruik.", + "add": "Voeg kanaal by", + "edit": "Wysig kanaal", + "test": "Stuur 'n toets", + "testSent": "Toetswaarskuwing gestuur", + "testFailed": "Toets het misluk: {{error}}", + "deleteConfirm": "Vee die kanaal \"{{name}} \" uit?", + "deleted": "Kanaal uitgevee", + "empty": "Geen kanale nog nie.", + "enabled": "Geaktiveer", + "needsSave": "Hierdie kanaal moet weer oopgemaak en gestoor word voordat dit kan stuur.", + "name": "Naam", + "nameRequired": "Naam word vereis", + "type": "Tipe", + "types": { + "webhook": "Webhaak", + "ntfy": "ntfy", + "discord": "Disharmonie", + "email": "E-pos" + }, + "emailUnavailable": "E-pos benodig 'n SMTP-bediener, wat 'n administrateur in die Waarskuwingsinstellings opstel.", + "webhookUrl": "URL", + "webhookHint": "Kry 'n JSON-liggaam vir elke waarskuwing.", + "method": "Metode", + "headers": "Koptekste", + "headersHint": "Een per lyn, soos Naam: waarde.", + "ntfyServer": "Bediener-URL", + "ntfyTopic": "Onderwerp", + "ntfyToken": "Toegangstoken (opsioneel)", + "discordUrl": "Discord webhook URL", + "discordHint": "Van die kanaal se instellings in Discord, onder Integrasies.", + "discordUsername": "Vertoonnaam (opsioneel)", + "discordAvatar": "Avatar-URL (opsioneel)", + "emailTo": "Stuur na", + "emailHint": "Skei meer as een adres met kommas.", + "privateNetwork": "Laat 'n privaat netwerkadres toe", + "privateNetworkHint": "Werk slegs vir gashere wat 'n administrateur toelaat in die privaat eindpuntlys." + }, + "rules": { + "intro": "'n Afleweringsreël stuur ooreenstemmende waarskuwings na jou kanale. Waarskuwings bly ook altyd in die inboks.", + "add": "Voeg reël by", + "edit": "Wysig reël", + "empty": "Geen reëls nog nie, so waarskuwings verskyn slegs in die inboks.", + "needChannel": "Voeg eers 'n kanaal by.", + "enabled": "Geaktiveer", + "name": "Naam", + "nameRequired": "Naam word vereis", + "match": "Waarskuwings om te stuur", + "matchHint": "* vir alles, outomatisasies.* vir alles van outomatisasies, of een presiese soort.", + "minSeverity": "Ten minste", + "channels": "Stuur na", + "channelRequired": "Kies ten minste een kanaal", + "deleteConfirm": "Vee die reël \"{{name}} \" uit?", + "everything": "Alles", + "summary": "{{match}}, {{severity}} of hoër, na {{channels}}" + }, + "actions": { + "cancel": "Kanselleer", + "save": "Stoor", + "saving": "Stoor...", + "delete": "Vee uit" + }, + "widget": { + "name": "Waarskuwingsvoer", + "description": "Jou nuutste waarskuwings, met 'n vinnige manier om hulle gelees te merk", + "maxItems": "Maksimum items", + "showRead": "Wys leeswaarskuwings", + "allClear": "Alles duidelik", + "loading": "Laai tans..." + } +} diff --git a/plugins/alerts/locales/translated/ar_SA.json b/plugins/alerts/locales/translated/ar_SA.json new file mode 100644 index 000000000..cec6ba30e --- /dev/null +++ b/plugins/alerts/locales/translated/ar_SA.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "التنبيهات" + }, + "permissions": { + "use": { + "title": "استخدم التنبيهات", + "description": "احصل على التنبيهات في صندوق الوارد وأرسلها إلى قنواتك الخاصة." + } + }, + "onboarding": { + "feature": "التنبيهات", + "featureDesc": "يتم إرسال جميع التنبيهات في صندوق وارد واحد، إلى Discord أو ntfy أو البريد الإلكتروني أو webhook إذا كنت ترغب في ذلك." + }, + "settings": { + "group": { + "general": "عام", + "email": "البريد الإلكتروني" + }, + "admin": { + "announcements": { + "label": "إعلانات تيرميكس", + "description": "اعرض الأخبار من فريق Termix، مثل الإشعارات الأمنية والإصدارات، في صندوق بريد الجميع." + }, + "retentionDays": { + "label": "احتفظ بالتنبيهات لمدة (أيام)", + "description": "تتم إزالة التنبيهات القديمة من جميع صناديق البريد الوارد." + }, + "smtpHost": { + "label": "خادم SMTP", + "description": "هذا الحقل ضروري لقنوات البريد الإلكتروني. اتركه فارغاً لإيقاف تشغيل البريد الإلكتروني.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "منفذ SMTP", + "description": "عادةً ما يكون 587 مع STARTTLS أو 465 مع TLS." + }, + "smtpSecure": { + "label": "استخدم بروتوكول TLS منذ البداية", + "description": "قم بتشغيل المنفذ 465. اتركه معطلاً للمنفذ 587، الذي يتم ترقيته إلى TLS تلقائيًا." + }, + "smtpUser": { + "label": "اسم مستخدم SMTP", + "description": "اترك هذا الحقل فارغًا إذا لم يكن الخادم بحاجة إلى تسجيل دخول." + }, + "smtpPassword": { + "label": "كلمة مرور SMTP", + "description": "مخزنة بشكل مشفر." + }, + "smtpFrom": { + "label": "عنوان المرسل", + "description": "تأتي تنبيهات المرسل من...", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "نوافذ تنبيه منبثقة", + "description": "ما هي التنبيهات الجديدة التي تظهر أثناء استخدامك لبرنامج Termix؟ تصل هذه التنبيهات دائمًا إلى صندوق الوارد.", + "all": "جميع التنبيهات", + "warning": "تحذيرات ومعلومات هامة", + "critical": "للنقد فقط", + "off": "بلا" + } + } + }, + "sections": { + "inbox": "صندوق الوارد", + "channels": "القنوات", + "rules": "قواعد التوصيل" + }, + "severity": { + "info": "معلومات", + "success": "نجاح", + "warning": "تحذير", + "critical": "شديد الأهمية" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "فتح", + "view": "عرض", + "unread": "غير مقروء", + "deliveryFailed_one": "فشل القناة {{count}}", + "deliveryFailed_other": "فشلت القنوات {{count}}", + "markRead": "ضع علامة كمقروء", + "markUnread": "ضع علامة كغير مقروء", + "markAllRead": "ضع علامة \"مقروء\" على الكل", + "delete": "حذف", + "clearRead": "حذف تنبيهات القراءة", + "cleared_one": "تنبيه الحذف {{count}}", + "cleared_other": "تم حذف التنبيهات {{count}}", + "filterAll": "الكل", + "filterUnread": "غير مقروء", + "anySeverity": "أي درجة من الشدة", + "anySource": "أي مصدر", + "openAll": "افتح في علامة تبويب", + "empty": "لم يتم تلقي أي تنبيهات حتى الآن.", + "emptyUnread": "لقد اطلعت على كل شيء.", + "loadMore": "تحميل المزيد" + }, + "channels": { + "intro": "القنوات هي المكان الذي يمكن أن تصل إليه التنبيهات خارج Termix. وتحدد قواعد التسليم التنبيهات التي تستخدمها.", + "add": "إضافة قناة", + "edit": "قناة التحرير", + "test": "أرسل اختبارًا", + "testSent": "تم إرسال تنبيه اختبار", + "testFailed": "فشل الاختبار: {{error}}", + "deleteConfirm": "حذف القناة \"{{name}}\"؟", + "deleted": "تم حذف القناة", + "empty": "لا توجد قنوات حتى الآن.", + "enabled": "مُمكّن", + "needsSave": "يجب فتح هذه القناة وحفظها مرة أخرى قبل أن تتمكن من الإرسال.", + "name": "الاسم", + "nameRequired": "الاسم مطلوب", + "type": "النوع", + "types": { + "webhook": "رابط الويب", + "ntfy": "ntfy", + "discord": "Discord", + "email": "البريد الإلكتروني" + }, + "emailUnavailable": "يحتاج البريد الإلكتروني إلى خادم SMTP، والذي يقوم المسؤول بإعداده في إعدادات التنبيهات.", + "webhookUrl": "URL", + "webhookHint": "يحصل على نص JSON لكل تنبيه.", + "method": "طريقة", + "headers": "العناوين", + "headersHint": "واحد في كل سطر، مثل الاسم: القيمة.", + "ntfyServer": "عنوان URL للخادم", + "ntfyTopic": "الموضوع", + "ntfyToken": "رمز الوصول (اختياري)", + "discordUrl": "رابط ويب هوك ديسكورد", + "discordHint": "من إعدادات القناة في ديسكورد، ضمن قسم التكاملات.", + "discordUsername": "اسم العرض (اختياري)", + "discordAvatar": "رابط الصورة الرمزية (اختياري)", + "emailTo": "أرسل إلى", + "emailHint": "افصل بين أكثر من عنوان واحد باستخدام الفواصل.", + "privateNetwork": "السماح بعنوان شبكة خاصة", + "privateNetworkHint": "لا يعمل إلا مع المضيفين الذين يسمح لهم المسؤول بإضافتهم إلى قائمة نقاط النهاية الخاصة." + }, + "rules": { + "intro": "تقوم قاعدة التسليم بإرسال التنبيهات المطابقة إلى قنواتك. وتبقى التنبيهات دائمًا في صندوق الوارد أيضًا.", + "add": "إضافة قاعدة", + "edit": "تعديل القاعدة", + "empty": "لا توجد قواعد حتى الآن، لذا تظهر التنبيهات في صندوق الوارد فقط.", + "needChannel": "أضف قناة أولاً.", + "enabled": "مُمكّن", + "name": "الاسم", + "nameRequired": "الاسم مطلوب", + "match": "تنبيهات لإرسالها", + "matchHint": "* لكل شيء، الأتمتة.* لكل شيء من الأتمتة، أو نوع واحد محدد.", + "minSeverity": "على الأقل", + "channels": "أرسل إلى", + "channelRequired": "اختر قناة واحدة على الأقل", + "deleteConfirm": "هل تريد حذف القاعدة \"{{name}}\"؟", + "everything": "كل شئ", + "summary": "{{match}}، {{severity}} أو أعلى، إلى {{channels}}" + }, + "actions": { + "cancel": "إلغاء", + "save": "حفظ", + "saving": "جارٍ الحفظ...", + "delete": "حذف" + }, + "widget": { + "name": "موجز التنبيهات", + "description": "آخر تنبيهاتك، مع طريقة سريعة لوضع علامة \"مقروء\" عليها", + "maxItems": "ماكس فيش", + "showRead": "عرض تنبيهات القراءة", + "allClear": "كل شيء طبيعي", + "loading": "جارٍ التحميل..." + } +} diff --git a/plugins/alerts/locales/translated/bg_BG.json b/plugins/alerts/locales/translated/bg_BG.json new file mode 100644 index 000000000..18f1553d6 --- /dev/null +++ b/plugins/alerts/locales/translated/bg_BG.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Сигнали" + }, + "permissions": { + "use": { + "title": "Използвайте известия", + "description": "Получавайте известия във входящата си поща и ги изпращайте към вашите собствени канали." + } + }, + "onboarding": { + "feature": "Сигнали", + "featureDesc": "Всяко известие в една пощенска кутия, изпратено до Discord, ntfy, имейл или webhook, ако желаете." + }, + "settings": { + "group": { + "general": "Общи", + "email": "Имейл" + }, + "admin": { + "announcements": { + "label": "Съобщения на Termix", + "description": "Показвайте новини от екипа на Termix, като например съобщения и издания за сигурност, във входящата поща на всички." + }, + "retentionDays": { + "label": "Запазване на сигналите за (дни)", + "description": "По-старите известия се премахват от всяка пощенска кутия." + }, + "smtpHost": { + "label": "SMTP сървър", + "description": "Необходимо за имейл канали. Оставете празно, за да изключите имейла.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "SMTP порт", + "description": "Обикновено 587 със STARTTLS или 465 с TLS." + }, + "smtpSecure": { + "label": "Използвайте TLS от самото начало", + "description": "Включете за порт 465. Не го правете за 587, който самостоятелно надгражда до TLS." + }, + "smtpUser": { + "label": "SMTP потребителско име", + "description": "Оставете празно, ако сървърът не изисква вход." + }, + "smtpPassword": { + "label": "SMTP парола", + "description": "Съхранява се криптирано." + }, + "smtpFrom": { + "label": "От адрес", + "description": "Сигналите за подател идват от.", + "placeholder": "Термикс " + } + }, + "user": { + "popups": { + "label": "Изскачащи прозорци с предупреждения", + "description": "Кои нови известия се появяват, докато използвате Termix. Те винаги попадат във входящата поща.", + "all": "Всички сигнали", + "warning": "Предупреждения и критични", + "critical": "Само критично", + "off": "Няма" + } + } + }, + "sections": { + "inbox": "Входяща поща", + "channels": "Канали", + "rules": "Правила за доставка" + }, + "severity": { + "info": "Информация", + "success": "Успех", + "warning": "Предупреждение", + "critical": "Критично" + }, + "inbox": { + "sourceTermix": "Термикс", + "openLink": "Отворено", + "view": "Преглед", + "unread": "Непрочетено", + "deliveryFailed_one": "{{count}} каналът е неуспешен", + "deliveryFailed_other": "{{count}} канали неуспешни", + "markRead": "Маркирай като прочетено", + "markUnread": "Маркирай като непрочетено", + "markAllRead": "Маркирай всички като прочетени", + "delete": "Изтриване", + "clearRead": "Изтриване на известия за четене", + "cleared_one": "Изтрито предупреждение {{count}}", + "cleared_other": "Изтрити {{count}} сигнали", + "filterAll": "Всички", + "filterUnread": "Непрочетено", + "anySeverity": "Всякаква тежест", + "anySource": "Всеки източник", + "openAll": "Отваряне в раздел", + "empty": "Все още няма сигнали.", + "emptyUnread": "Всичко е наясно с вас.", + "loadMore": "Зареди още" + }, + "channels": { + "intro": "Каналите са местата, където известията могат да излизат извън Termix. Правилата за доставка избират кои известия ги използват.", + "add": "Добавяне на канал", + "edit": "Редактиране на канал", + "test": "Изпрати тест", + "testSent": "Изпратено е тестово предупреждение", + "testFailed": "Тестът не беше успешен: {{error}}", + "deleteConfirm": "Да се изтрие ли каналът „{{name}}“?", + "deleted": "Каналът е изтрит", + "empty": "Все още няма канали.", + "enabled": "Активирано", + "needsSave": "Този канал трябва да бъде отворен и запазен отново, преди да може да се изпраща.", + "name": "Име", + "nameRequired": "Името е задължително", + "type": "Тип", + "types": { + "webhook": "Уеб кукичка", + "ntfy": "ntfy", + "discord": "Дискорд", + "email": "Имейл" + }, + "emailUnavailable": "Имейлът се нуждае от SMTP сървър, който администраторът настройва в настройките за предупреждения.", + "webhookUrl": "URL адрес", + "webhookHint": "Получава JSON тяло за всяко предупреждение.", + "method": "Метод", + "headers": "Заглавки", + "headersHint": "По един на ред, като Име: стойност.", + "ntfyServer": "URL адрес на сървъра", + "ntfyTopic": "Тема", + "ntfyToken": "Токен за достъп (по избор)", + "discordUrl": "URL адрес на уеб кукичката на Discord", + "discordHint": "От настройките на канала в Discord, под „Интеграции“.", + "discordUsername": "Показвано име (по избор)", + "discordAvatar": "URL адрес на аватара (по избор)", + "emailTo": "Изпрати до", + "emailHint": "Разделете повече от един адрес със запетаи.", + "privateNetwork": "Разрешаване на адрес на частна мрежа", + "privateNetworkHint": "Работи само за хостове, които администраторът е разрешил в списъка с частни крайни точки." + }, + "rules": { + "intro": "Правило за доставка изпраща съответстващи известия до вашите канали. Известията винаги остават и във входящата поща.", + "add": "Добавяне на правило", + "edit": "Редактиране на правилото", + "empty": "Все още няма правила, така че известията се показват само във входящата поща.", + "needChannel": "Първо добавете канал.", + "enabled": "Активирано", + "name": "Име", + "nameRequired": "Името е задължително", + "match": "Сигнали за изпращане", + "matchHint": "* за всичко, автоматизации.* за всичко от автоматизации или един точно определен вид.", + "minSeverity": "Поне", + "channels": "Изпрати до", + "channelRequired": "Изберете поне един канал", + "deleteConfirm": "Да се изтрие ли правилото „{{name}}“?", + "everything": "Всичко", + "summary": "{{match}}, {{severity}} или по-висока, до {{channels}}" + }, + "actions": { + "cancel": "Отказ", + "save": "Запазване", + "saving": "Запазване...", + "delete": "Изтриване" + }, + "widget": { + "name": "Канал за предупреждения", + "description": "Най-новите ви сигнали с бърз начин да ги маркирате като прочетени", + "maxItems": "Максимален брой елементи", + "showRead": "Показване на известия за четене", + "allClear": "Всичко е чисто", + "loading": "Зареждане..." + } +} diff --git a/plugins/alerts/locales/translated/bn_BD.json b/plugins/alerts/locales/translated/bn_BD.json new file mode 100644 index 000000000..9d7514f0d --- /dev/null +++ b/plugins/alerts/locales/translated/bn_BD.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Alerts" + }, + "permissions": { + "use": { + "title": "Use alerts", + "description": "Get alerts in the inbox and send them to your own channels." + } + }, + "onboarding": { + "feature": "Alerts", + "featureDesc": "Every alert in one inbox, sent on to Discord, ntfy, email or a webhook if you want." + }, + "settings": { + "group": { + "general": "General", + "email": "Email" + }, + "admin": { + "announcements": { + "label": "Termix announcements", + "description": "Show news from the Termix team, like security notices and releases, in everyone's inbox." + }, + "retentionDays": { + "label": "Keep alerts for (days)", + "description": "Older alerts are removed from every inbox." + }, + "smtpHost": { + "label": "SMTP server", + "description": "Needed for email channels. Leave empty to turn email off.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "SMTP port", + "description": "Usually 587 with STARTTLS or 465 with TLS." + }, + "smtpSecure": { + "label": "Use TLS from the start", + "description": "Turn on for port 465. Leave off for 587, which upgrades to TLS on its own." + }, + "smtpUser": { + "label": "SMTP username", + "description": "Leave empty if the server does not need a login." + }, + "smtpPassword": { + "label": "SMTP password", + "description": "Stored encrypted." + }, + "smtpFrom": { + "label": "From address", + "description": "The sender alerts come from.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "Alert popups", + "description": "Which new alerts pop up while you use Termix. They always land in the inbox.", + "all": "All alerts", + "warning": "Warnings and critical", + "critical": "Critical only", + "off": "None" + } + } + }, + "sections": { + "inbox": "Inbox", + "channels": "Channels", + "rules": "Delivery rules" + }, + "severity": { + "info": "Info", + "success": "Success", + "warning": "Warning", + "critical": "Critical" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "Open", + "view": "View", + "unread": "Unread", + "deliveryFailed_one": "{{count}} channel failed", + "deliveryFailed_other": "{{count}} channels failed", + "markRead": "Mark as read", + "markUnread": "Mark as unread", + "markAllRead": "Mark all as read", + "delete": "Delete", + "clearRead": "Delete read alerts", + "cleared_one": "Deleted {{count}} alert", + "cleared_other": "Deleted {{count}} alerts", + "filterAll": "All", + "filterUnread": "Unread", + "anySeverity": "Any severity", + "anySource": "Any source", + "openAll": "Open in a tab", + "empty": "No alerts yet.", + "emptyUnread": "You are all caught up.", + "loadMore": "Load more" + }, + "channels": { + "intro": "Channels are where alerts can go outside Termix. Delivery rules pick which alerts use them.", + "add": "Add channel", + "edit": "Edit channel", + "test": "Send a test", + "testSent": "Test alert sent", + "testFailed": "Test failed: {{error}}", + "deleteConfirm": "Delete the channel \"{{name}}\"?", + "deleted": "Channel deleted", + "empty": "No channels yet.", + "enabled": "Enabled", + "needsSave": "This channel needs to be opened and saved again before it can send.", + "name": "Name", + "nameRequired": "Name is required", + "type": "Type", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Discord", + "email": "Email" + }, + "emailUnavailable": "Email needs an SMTP server, which an admin sets up in the Alerts settings.", + "webhookUrl": "URL", + "webhookHint": "Gets a JSON body for every alert.", + "method": "Method", + "headers": "Headers", + "headersHint": "One per line, like Name: value.", + "ntfyServer": "Server URL", + "ntfyTopic": "Topic", + "ntfyToken": "Access token (optional)", + "discordUrl": "Discord webhook URL", + "discordHint": "From the channel's settings in Discord, under Integrations.", + "discordUsername": "Display name (optional)", + "discordAvatar": "Avatar URL (optional)", + "emailTo": "Send to", + "emailHint": "Separate more than one address with commas.", + "privateNetwork": "Allow a private network address", + "privateNetworkHint": "Only works for hosts an admin allows in the private endpoint list." + }, + "rules": { + "intro": "A delivery rule sends matching alerts to your channels. Alerts always stay in the inbox too.", + "add": "Add rule", + "edit": "Edit rule", + "empty": "No rules yet, so alerts only show up in the inbox.", + "needChannel": "Add a channel first.", + "enabled": "Enabled", + "name": "Name", + "nameRequired": "Name is required", + "match": "Alerts to send", + "matchHint": "* for everything, automations.* for everything from automations, or one exact kind.", + "minSeverity": "At least", + "channels": "Send to", + "channelRequired": "Pick at least one channel", + "deleteConfirm": "Delete the rule \"{{name}}\"?", + "everything": "Everything", + "summary": "{{match}}, {{severity}} or higher, to {{channels}}" + }, + "actions": { + "cancel": "Cancel", + "save": "Save", + "saving": "Saving...", + "delete": "Delete" + }, + "widget": { + "name": "Alert Feed", + "description": "Your latest alerts, with a quick way to mark them read", + "maxItems": "Max items", + "showRead": "Show read alerts", + "allClear": "All clear", + "loading": "Loading..." + } +} diff --git a/plugins/alerts/locales/translated/ca_ES.json b/plugins/alerts/locales/translated/ca_ES.json new file mode 100644 index 000000000..092d637eb --- /dev/null +++ b/plugins/alerts/locales/translated/ca_ES.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Alertes" + }, + "permissions": { + "use": { + "title": "Utilitza alertes", + "description": "Rep alertes a la safata d'entrada i envia-les als teus propis canals." + } + }, + "onboarding": { + "feature": "Alertes", + "featureDesc": "Totes les alertes en una safata d'entrada, enviades a Discord, ntfy, correu electrònic o un webhook si ho desitges." + }, + "settings": { + "group": { + "general": "General", + "email": "Correu electrònic" + }, + "admin": { + "announcements": { + "label": "Anuncis de Termix", + "description": "Mostra notícies de l'equip de Termix, com ara avisos de seguretat i llançaments, a la safata d'entrada de tothom." + }, + "retentionDays": { + "label": "Mantén les alertes durant (dies)", + "description": "Les alertes més antigues s'eliminen de totes les safates d'entrada." + }, + "smtpHost": { + "label": "Servidor SMTP", + "description": "Necessari per als canals de correu electrònic. Deixeu-ho en blanc per desactivar el correu electrònic.", + "placeholder": "smtp.exemple.com" + }, + "smtpPort": { + "label": "Port SMTP", + "description": "Normalment 587 amb STARTTLS o 465 amb TLS." + }, + "smtpSecure": { + "label": "Utilitza TLS des del principi", + "description": "Activeu el port 465. Deixeu-lo desactivat per al 587, que s'actualitza a TLS pel seu compte." + }, + "smtpUser": { + "label": "Nom d'usuari SMTP", + "description": "Deixeu-ho en blanc si el servidor no necessita cap inici de sessió." + }, + "smtpPassword": { + "label": "Contrasenya SMTP", + "description": "Emmagatzemat xifrat." + }, + "smtpFrom": { + "label": "Adreça de remitent", + "description": "Les alertes del remitent provenen de.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "Finestres emergents d'alerta", + "description": "Quines noves alertes apareixen mentre fas servir Termix. Sempre arriben a la safata d'entrada.", + "all": "Totes les alertes", + "warning": "Avisos i crítics", + "critical": "Només crític", + "off": "Cap" + } + } + }, + "sections": { + "inbox": "Safata d'entrada", + "channels": "Canals", + "rules": "Normes de lliurament" + }, + "severity": { + "info": "Informació", + "success": "Èxit", + "warning": "Avís", + "critical": "Crític" + }, + "inbox": { + "sourceTermix": "Tèrmix", + "openLink": "Obre", + "view": "Vista", + "unread": "No llegit", + "deliveryFailed_one": "El canal {{count}} ha fallat", + "deliveryFailed_other": "Els canals {{count}} han fallat", + "markRead": "Marca com a llegit", + "markUnread": "Marca com a no llegit", + "markAllRead": "Marca-ho tot com a llegit", + "delete": "Suprimeix", + "clearRead": "Suprimeix les alertes de lectura", + "cleared_one": "Alerta suprimida {{count}}", + "cleared_other": "Alertes suprimides {{count}}", + "filterAll": "Tot", + "filterUnread": "No llegit", + "anySeverity": "Qualsevol gravetat", + "anySource": "Qualsevol font", + "openAll": "Obre en una pestanya", + "empty": "Encara no hi ha alertes.", + "emptyUnread": "Esteu tots atrapats.", + "loadMore": "Carrega'n més" + }, + "channels": { + "intro": "Els canals són on les alertes poden sortir de Termix. Les regles de lliurament trien quines alertes els utilitzen.", + "add": "Afegeix un canal", + "edit": "Edita el canal", + "test": "Envia una prova", + "testSent": "Alerta de prova enviada", + "testFailed": "Prova fallida: {{error}}", + "deleteConfirm": "Voleu eliminar el canal \"{{name}}\"?", + "deleted": "Canal suprimit", + "empty": "Encara no hi ha canals.", + "enabled": "Activat", + "needsSave": "Cal obrir i desar de nou aquest canal abans de poder enviar.", + "name": "Nom", + "nameRequired": "El nom és obligatori", + "type": "Tipus", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Discòrdia", + "email": "Correu electrònic" + }, + "emailUnavailable": "El correu electrònic necessita un servidor SMTP, que un administrador configura a la configuració d'Alertes.", + "webhookUrl": "URL", + "webhookHint": "Obté un cos JSON per a cada alerta.", + "method": "Mètode", + "headers": "Capçaleres", + "headersHint": "Un per línia, com ara Nom: valor.", + "ntfyServer": "URL del servidor", + "ntfyTopic": "Tema", + "ntfyToken": "Token d'accés (opcional)", + "discordUrl": "URL del webhook de Discord", + "discordHint": "Des de la configuració del canal a Discord, a Integracions.", + "discordUsername": "Nom per mostrar (opcional)", + "discordAvatar": "URL de l'avatar (opcional)", + "emailTo": "Enviar a", + "emailHint": "Separeu més d'una adreça amb comes.", + "privateNetwork": "Permetre una adreça de xarxa privada", + "privateNetworkHint": "Només funciona per a hosts que un administrador permet a la llista de punts finals privats." + }, + "rules": { + "intro": "Una regla de lliurament envia alertes coincidents als vostres canals. Les alertes també sempre romanen a la safata d'entrada.", + "add": "Afegeix una regla", + "edit": "Edita la regla", + "empty": "Encara no hi ha regles, així que les alertes només apareixen a la safata d'entrada.", + "needChannel": "Afegeix primer un canal.", + "enabled": "Activat", + "name": "Nom", + "nameRequired": "El nom és obligatori", + "match": "Alertes per enviar", + "matchHint": "* per a tot, automatitzacions. * per a tot, des d'automatitzacions o un tipus exacte.", + "minSeverity": "Almenys", + "channels": "Enviar a", + "channelRequired": "Trieu com a mínim un canal", + "deleteConfirm": "Voleu suprimir la regla \"{{name}}\"?", + "everything": "Tot", + "summary": "{{match}}, {{severity}} o superior, a {{channels}}" + }, + "actions": { + "cancel": "Cancel·la", + "save": "Desa", + "saving": "Desant...", + "delete": "Suprimeix" + }, + "widget": { + "name": "Canal d'alertes", + "description": "Les teves darreres alertes, amb una manera ràpida de marcar-les com a llegides", + "maxItems": "Màxim d'elements", + "showRead": "Mostra les alertes de lectura", + "allClear": "Tot clar", + "loading": "S'està carregant..." + } +} diff --git a/plugins/alerts/locales/translated/cs_CZ.json b/plugins/alerts/locales/translated/cs_CZ.json new file mode 100644 index 000000000..d8ac6e804 --- /dev/null +++ b/plugins/alerts/locales/translated/cs_CZ.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Upozornění" + }, + "permissions": { + "use": { + "title": "Používejte upozornění", + "description": "Získejte upozornění do složky Doručená pošta a odesílejte je na své vlastní kanály." + } + }, + "onboarding": { + "feature": "Upozornění", + "featureDesc": "Všechna upozornění v jedné schránce, odeslaná na Discord, ntfy, e-mail nebo webhook, pokud chcete." + }, + "settings": { + "group": { + "general": "Obecné", + "email": "E-mail" + }, + "admin": { + "announcements": { + "label": "Oznámení Termixu", + "description": "Zobrazujte novinky od týmu Termix, jako jsou bezpečnostní oznámení a vydání, ve schránce všech uživatelů." + }, + "retentionDays": { + "label": "Uchovávat upozornění po dobu (dnů)", + "description": "Starší upozornění jsou odstraněna ze všech složek doručené pošty." + }, + "smtpHost": { + "label": "SMTP server", + "description": "Požadováno pro e-mailové kanály. Pro vypnutí e-mailu ponechte prázdné.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "SMTP port", + "description": "Obvykle 587 se STARTTLS nebo 465 s TLS." + }, + "smtpSecure": { + "label": "Používejte TLS od začátku", + "description": "Zapněte pro port 465. Nechte vypnuto pro port 587, který se sám upgraduje na TLS." + }, + "smtpUser": { + "label": "Uživatelské jméno SMTP", + "description": "Pokud server nevyžaduje přihlášení, nechte pole prázdné." + }, + "smtpPassword": { + "label": "Heslo k SMTP", + "description": "Uloženo zašifrovaně." + }, + "smtpFrom": { + "label": "Odesílatel", + "description": "Upozornění odesílatele pocházejí od.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "Vyskakovací okna s upozorněními", + "description": "Která nová upozornění se zobrazují při používání Termixu. Vždy se dostanou do doručené pošty.", + "all": "Všechna upozornění", + "warning": "Varování a kritické", + "critical": "Pouze kritické", + "off": "Žádný" + } + } + }, + "sections": { + "inbox": "Doručená pošta", + "channels": "Kanály", + "rules": "Pravidla doručení" + }, + "severity": { + "info": "Informace", + "success": "Úspěch", + "warning": "Varování", + "critical": "Kritický" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "OTEVŘENO", + "view": "Pohled", + "unread": "Nepřečtený", + "deliveryFailed_one": "Kanál {{count}} selhal", + "deliveryFailed_other": "{{count}} kanálů selhalo", + "markRead": "Označit jako přečtené", + "markUnread": "Označit jako nepřečtené", + "markAllRead": "Označit vše jako přečtené", + "delete": "Vymazat", + "clearRead": "Smazat upozornění na přečtení", + "cleared_one": "Smazáno upozornění {{count}}", + "cleared_other": "Smazaná {{count}} upozornění", + "filterAll": "Vše", + "filterUnread": "Nepřečtený", + "anySeverity": "Jakákoli závažnost", + "anySource": "Jakýkoli zdroj", + "openAll": "Otevřít v kartě", + "empty": "Zatím žádná upozornění.", + "emptyUnread": "Všechno máte v obraze.", + "loadMore": "Načíst další" + }, + "channels": { + "intro": "Kanály jsou místem, kudy mohou upozornění odesílat mimo Termix. Pravidla doručování vybírají, která upozornění je používají.", + "add": "Přidat kanál", + "edit": "Upravit kanál", + "test": "Odeslat test", + "testSent": "Testovací upozornění odesláno", + "testFailed": "Test selhal: {{error}}", + "deleteConfirm": "Smazat kanál „{{name}}“?", + "deleted": "Kanál smazán", + "empty": "Zatím žádné kanály.", + "enabled": "Povoleno", + "needsSave": "Tento kanál je nutné před odesláním znovu otevřít a uložit.", + "name": "Jméno", + "nameRequired": "Jméno je povinné", + "type": "Typ", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Svár", + "email": "E-mail" + }, + "emailUnavailable": "E-mail potřebuje SMTP server, který administrátor nastaví v nastavení Upozornění.", + "webhookUrl": "URL", + "webhookHint": "Získá tělo JSON pro každé upozornění.", + "method": "Metoda", + "headers": "Záhlaví", + "headersHint": "Jeden na řádek, například Název: hodnota.", + "ntfyServer": "URL serveru", + "ntfyTopic": "Téma", + "ntfyToken": "Přístupový token (volitelné)", + "discordUrl": "URL webhooku na Discordu", + "discordHint": "V nastavení kanálu na Discordu, v sekci Integrace.", + "discordUsername": "Zobrazovaný název (volitelné)", + "discordAvatar": "URL adresa avatara (volitelné)", + "emailTo": "Odeslat", + "emailHint": "Více adres oddělte čárkami.", + "privateNetwork": "Povolit adresu privátní sítě", + "privateNetworkHint": "Funguje pouze pro hostitele, které správce povolí v seznamu privátních koncových bodů." + }, + "rules": { + "intro": "Pravidlo doručování odesílá odpovídající upozornění do vašich kanálů. Upozornění vždy zůstávají také ve složce Doručená pošta.", + "add": "Přidat pravidlo", + "edit": "Upravit pravidlo", + "empty": "Zatím žádná pravidla, takže upozornění se zobrazují pouze ve schránce.", + "needChannel": "Nejprve přidejte kanál.", + "enabled": "Povoleno", + "name": "Jméno", + "nameRequired": "Jméno je povinné", + "match": "Upozornění k odeslání", + "matchHint": "* pro všechno, automatizace.* pro všechno od automatizací nebo jeden přesný druh.", + "minSeverity": "Alespoň", + "channels": "Odeslat", + "channelRequired": "Vyberte alespoň jeden kanál", + "deleteConfirm": "Smazat pravidlo „{{name}}“?", + "everything": "Všechno", + "summary": "{{match}}, {{severity}} nebo vyšší, na {{channels}}" + }, + "actions": { + "cancel": "Zrušit", + "save": "Uložit", + "saving": "Ukládání…", + "delete": "Vymazat" + }, + "widget": { + "name": "Zdroj upozornění", + "description": "Vaše nejnovější upozornění s rychlým způsobem, jak je označit jako přečtené", + "maxItems": "Maximální počet položek", + "showRead": "Zobrazit upozornění na přečtení", + "allClear": "Všechno čisté", + "loading": "Načítání..." + } +} diff --git a/plugins/alerts/locales/translated/da_DK.json b/plugins/alerts/locales/translated/da_DK.json new file mode 100644 index 000000000..02034918f --- /dev/null +++ b/plugins/alerts/locales/translated/da_DK.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Advarsler" + }, + "permissions": { + "use": { + "title": "Brug alarmer", + "description": "Få besked i indbakken, og send dem til dine egne kanaler." + } + }, + "onboarding": { + "feature": "Advarsler", + "featureDesc": "Alle alarmer i én indbakke, sendt videre til Discord, ntfy, e-mail eller en webhook, hvis du vil." + }, + "settings": { + "group": { + "general": "Generel", + "email": "E-mail" + }, + "admin": { + "announcements": { + "label": "Termix-meddelelser", + "description": "Vis nyheder fra Termix-teamet, f.eks. sikkerhedsmeddelelser og udgivelser, i alles indbakke." + }, + "retentionDays": { + "label": "Gem advarsler i (dage)", + "description": "Ældre advarsler fjernes fra alle indbakker." + }, + "smtpHost": { + "label": "SMTP-server", + "description": "Nødvendigt for e-mailkanaler. Lad feltet stå tomt for at slå e-mail fra.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "SMTP-port", + "description": "Normalt 587 med STARTTLS eller 465 med TLS." + }, + "smtpSecure": { + "label": "Brug TLS fra starten", + "description": "Slå port 465 til. Slå port 587 fra, som opgraderer til TLS af sig selv." + }, + "smtpUser": { + "label": "SMTP-brugernavn", + "description": "Lad feltet stå tomt, hvis serveren ikke kræver login." + }, + "smtpPassword": { + "label": "SMTP-adgangskode", + "description": "Gemt krypteret." + }, + "smtpFrom": { + "label": "Fra adresse", + "description": "Afsenderbeskederne kommer fra.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "Popup-vinduer for alarmer", + "description": "Hvilke nye advarsler dukker op, mens du bruger Termix? De lander altid i indbakken.", + "all": "Alle advarsler", + "warning": "Advarsler og kritiske", + "critical": "Kun kritisk", + "off": "Ingen" + } + } + }, + "sections": { + "inbox": "Indbakke", + "channels": "Kanaler", + "rules": "Leveringsregler" + }, + "severity": { + "info": "Info", + "success": "Succes", + "warning": "Advarsel", + "critical": "Kritisk" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "Åben", + "view": "Udsigt", + "unread": "Ulæst", + "deliveryFailed_one": "{{count}} kanal mislykkedes", + "deliveryFailed_other": "{{count}} kanaler mislykkedes", + "markRead": "Markér som læst", + "markUnread": "Markér som ulæst", + "markAllRead": "Markér alle som læst", + "delete": "Slet", + "clearRead": "Slet læseadvarsler", + "cleared_one": "Slettet {{count}} -alarm", + "cleared_other": "Slettede {{count}} advarsler", + "filterAll": "Alle", + "filterUnread": "Ulæst", + "anySeverity": "Enhver alvorlighedsgrad", + "anySource": "Enhver kilde", + "openAll": "Åbn i en fane", + "empty": "Ingen advarsler endnu.", + "emptyUnread": "I er alle med på banen.", + "loadMore": "Indlæs mere" + }, + "channels": { + "intro": "Kanaler er hvor advarsler kan sendes uden for Termix. Leveringsregler vælger hvilke advarsler der bruger dem.", + "add": "Tilføj kanal", + "edit": "Rediger kanal", + "test": "Send en test", + "testSent": "Testalarm sendt", + "testFailed": "Test mislykkedes: {{error}}", + "deleteConfirm": "Slet kanalen \"{{name}}\"?", + "deleted": "Kanal slettet", + "empty": "Ingen kanaler endnu.", + "enabled": "Aktiveret", + "needsSave": "Denne kanal skal åbnes og gemmes igen, før den kan sende.", + "name": "Navn", + "nameRequired": "Navn er påkrævet", + "type": "Type", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Disharmoni", + "email": "E-mail" + }, + "emailUnavailable": "E-mail kræver en SMTP-server, som en administrator konfigurerer i indstillingerne for alarmer.", + "webhookUrl": "URL", + "webhookHint": "Henter en JSON-brødtekst for hver alarm.", + "method": "Metode", + "headers": "Overskrifter", + "headersHint": "En pr. linje, ligesom Navn: værdi.", + "ntfyServer": "Server-URL", + "ntfyTopic": "Emne", + "ntfyToken": "Adgangstoken (valgfrit)", + "discordUrl": "Discord webhook-URL", + "discordHint": "Fra kanalens indstillinger i Discord, under Integrationer.", + "discordUsername": "Visningsnavn (valgfrit)", + "discordAvatar": "Avatar-URL (valgfrit)", + "emailTo": "Send til", + "emailHint": "Adskil mere end én adresse med kommaer.", + "privateNetwork": "Tillad en privat netværksadresse", + "privateNetworkHint": "Fungerer kun for værter, som en administrator tillader på listen over private slutpunkter." + }, + "rules": { + "intro": "En leveringsregel sender matchende advarsler til dine kanaler. Advarsler forbliver også altid i indbakken.", + "add": "Tilføj regel", + "edit": "Rediger regel", + "empty": "Ingen regler endnu, så advarsler vises kun i indbakken.", + "needChannel": "Tilføj først en kanal.", + "enabled": "Aktiveret", + "name": "Navn", + "nameRequired": "Navn er påkrævet", + "match": "Advarsler, der skal sendes", + "matchHint": "* for alt, automatiseringer.* for alt fra automatiseringer, eller én præcis slags.", + "minSeverity": "Mindst", + "channels": "Send til", + "channelRequired": "Vælg mindst én kanal", + "deleteConfirm": "Slet reglen \"{{name}}\"?", + "everything": "Alt", + "summary": "{{match}}, {{severity}} eller højere, til {{channels}}" + }, + "actions": { + "cancel": "Ophæve", + "save": "Spare", + "saving": "Gemmer...", + "delete": "Slet" + }, + "widget": { + "name": "Alarmfeed", + "description": "Dine seneste advarsler, med en hurtig måde at markere dem som læst", + "maxItems": "Maks. antal varer", + "showRead": "Vis læseadvarsler", + "allClear": "Alt klart", + "loading": "Indlæser..." + } +} diff --git a/plugins/alerts/locales/translated/de_DE.json b/plugins/alerts/locales/translated/de_DE.json new file mode 100644 index 000000000..842a45601 --- /dev/null +++ b/plugins/alerts/locales/translated/de_DE.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Benachrichtigungen" + }, + "permissions": { + "use": { + "title": "Warnmeldungen verwenden", + "description": "Erhalten Sie Benachrichtigungen in Ihrem Posteingang und leiten Sie diese an Ihre eigenen Kanäle weiter." + } + }, + "onboarding": { + "feature": "Alarme", + "featureDesc": "Alle Benachrichtigungen in einem Posteingang, auf Wunsch auch per Discord, ntfy, E-Mail oder Webhook." + }, + "settings": { + "group": { + "general": "Allgemein", + "email": "E-Mail" + }, + "admin": { + "announcements": { + "label": "Termix-Ankündigungen", + "description": "Neuigkeiten vom Termix-Team, wie Sicherheitshinweise und Releases, werden direkt in den Posteingang aller Nutzer angezeigt." + }, + "retentionDays": { + "label": "Benachrichtigungen beibehalten für (Tage)", + "description": "Ältere Benachrichtigungen werden aus jedem Posteingang entfernt." + }, + "smtpHost": { + "label": "SMTP-Server", + "description": "Für E-Mail-Kanäle erforderlich. Leer lassen, um E-Mails zu deaktivieren.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "SMTP-Port", + "description": "Üblicherweise Port 587 mit STARTTLS oder Port 465 mit TLS." + }, + "smtpSecure": { + "label": "Verwenden Sie TLS von Anfang an", + "description": "Aktivieren Sie die Option für Port 465. Lassen Sie sie für Port 587 deaktiviert, da dieser automatisch auf TLS umstellt." + }, + "smtpUser": { + "label": "SMTP-Benutzername", + "description": "Lassen Sie dieses Feld leer, wenn der Server keine Anmeldung benötigt." + }, + "smtpPassword": { + "label": "SMTP-Passwort", + "description": "Verschlüsselt gespeichert." + }, + "smtpFrom": { + "label": "Von Adresse", + "description": "Die Absenderbenachrichtigungen stammen von", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "Warnmeldungen", + "description": "Welche neuen Benachrichtigungen erscheinen während der Nutzung von Termix? Sie landen immer im Posteingang.", + "all": "Alle Benachrichtigungen", + "warning": "Warnungen und kritische", + "critical": "Nur für kritische Zwecke", + "off": "Keine" + } + } + }, + "sections": { + "inbox": "Posteingang", + "channels": "Kanäle", + "rules": "Lieferregeln" + }, + "severity": { + "info": "Info", + "success": "Erfolgreich", + "warning": "Warnung", + "critical": "Kritisch" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "Offen", + "view": "Anzeigen", + "unread": "Ungelesen", + "deliveryFailed_one": "{{count}} Kanal fehlgeschlagen", + "deliveryFailed_other": "{{count}} Kanäle fehlgeschlagen", + "markRead": "Als gelesen markieren", + "markUnread": "Als ungelesen markieren", + "markAllRead": "Alle als gelesen markieren", + "delete": "Löschen", + "clearRead": "Lesebenachrichtigungen löschen", + "cleared_one": "Gelöschte {{count}} Warnung", + "cleared_other": "Gelöschte {{count}} Benachrichtigungen", + "filterAll": "Alle", + "filterUnread": "Ungelesen", + "anySeverity": "Jegliche Schwere", + "anySource": "Jede Quelle", + "openAll": "In einem Tab öffnen", + "empty": "Bisher keine Benachrichtigungen.", + "emptyUnread": "Sie sind nun auf dem neuesten Stand.", + "loadMore": "Mehr laden" + }, + "channels": { + "intro": "Kanäle sind die Wege, über die Benachrichtigungen außerhalb von Termix weitergeleitet werden können. Zustellungsregeln legen fest, welche Benachrichtigungen diese Kanäle nutzen.", + "add": "Kanal hinzufügen", + "edit": "Kanal bearbeiten", + "test": "Senden Sie einen Test", + "testSent": "Testalarm gesendet", + "testFailed": "Test fehlgeschlagen: {{error}}", + "deleteConfirm": "Kanal \"{{name}} \" löschen?", + "deleted": "Kanal gelöscht", + "empty": "Noch keine Kanäle.", + "enabled": "Aktiviert", + "needsSave": "Dieser Kanal muss erneut geöffnet und gespeichert werden, bevor er senden kann.", + "name": "Name", + "nameRequired": "Name ist erforderlich", + "type": "Typ", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Discord", + "email": "E-Mail" + }, + "emailUnavailable": "Für E-Mails wird ein SMTP-Server benötigt, der vom Administrator in den Benachrichtigungseinstellungen eingerichtet wird.", + "webhookUrl": "URL", + "webhookHint": "Erhält für jede Benachrichtigung einen JSON-Body.", + "method": "Verfahren", + "headers": "Überschriften", + "headersHint": "Ein Eintrag pro Zeile, z. B. Name: Wert.", + "ntfyServer": "Server-URL", + "ntfyTopic": "Topic", + "ntfyToken": "Zugriffstoken (optional)", + "discordUrl": "Discord-Webhook-URL", + "discordHint": "In den Kanaleinstellungen von Discord, unter Integrationen.", + "discordUsername": "Anzeigename (optional)", + "discordAvatar": "Avatar-URL (optional)", + "emailTo": "Senden an", + "emailHint": "Mehrere Adressen werden durch Kommas getrennt.", + "privateNetwork": "Erlauben Sie eine private Netzwerkadresse", + "privateNetworkHint": "Funktioniert nur für Hosts, die ein Administrator in der Liste der privaten Endpunkte zulässt." + }, + "rules": { + "intro": "Eine Zustellungsregel sendet passende Benachrichtigungen an Ihre Kanäle. Benachrichtigungen bleiben außerdem immer im Posteingang erhalten.", + "add": "Regel hinzufügen", + "edit": "Bearbeitungsregel", + "empty": "Da es noch keine Regeln gibt, werden Benachrichtigungen nur im Posteingang angezeigt.", + "needChannel": "Füge zuerst einen Kanal hinzu.", + "enabled": "Aktiviert", + "name": "Name", + "nameRequired": "Name ist erforderlich", + "match": "Zu sendende Benachrichtigungen", + "matchHint": "* für alles, Automatisierungen.* für alles von Automatisierungen oder eine ganz bestimmte Art.", + "minSeverity": "Mindestens", + "channels": "Senden an", + "channelRequired": "Wählen Sie mindestens einen Kanal aus", + "deleteConfirm": "Regel \"{{name}} \" löschen?", + "everything": "Alles", + "summary": "{{match}}, {{severity}} oder höher, bis {{channels}}" + }, + "actions": { + "cancel": "Abbrechen", + "save": "Speichern", + "saving": "Wird gespeichert …", + "delete": "Löschen" + }, + "widget": { + "name": "Alarm-Feed", + "description": "Ihre neuesten Benachrichtigungen mit einer schnellen Möglichkeit, sie als gelesen zu markieren.", + "maxItems": "Maximale Anzahl an Artikeln", + "showRead": "Lesebenachrichtigungen anzeigen", + "allClear": "Alles in Ordnung", + "loading": "Laden..." + } +} diff --git a/plugins/alerts/locales/translated/el_GR.json b/plugins/alerts/locales/translated/el_GR.json new file mode 100644 index 000000000..b47ac7762 --- /dev/null +++ b/plugins/alerts/locales/translated/el_GR.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Ειδοποιήσεις" + }, + "permissions": { + "use": { + "title": "Χρήση ειδοποιήσεων", + "description": "Λάβετε ειδοποιήσεις στα εισερχόμενα και στείλτε τις στα δικά σας κανάλια." + } + }, + "onboarding": { + "feature": "Ειδοποιήσεις", + "featureDesc": "Κάθε ειδοποίηση σε ένα μόνο inbox, αποστέλλεται στο Discord, ntfy, email ή σε webhook, αν θέλετε." + }, + "settings": { + "group": { + "general": "Γενικός", + "email": "E-mail" + }, + "admin": { + "announcements": { + "label": "Ανακοινώσεις Termix", + "description": "Εμφάνιση ειδήσεων από την ομάδα Termix, όπως ειδοποιήσεις ασφαλείας και εκδόσεις, στα εισερχόμενα όλων." + }, + "retentionDays": { + "label": "Διατήρηση ειδοποιήσεων για (ημέρες)", + "description": "Οι παλαιότερες ειδοποιήσεις αφαιρούνται από κάθε φάκελο εισερχομένων." + }, + "smtpHost": { + "label": "Διακομιστής SMTP", + "description": "Απαιτείται για κανάλια email. Αφήστε το κενό για να απενεργοποιήσετε το email.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "Θύρα SMTP", + "description": "Συνήθως 587 με STARTTLS ή 465 με TLS." + }, + "smtpSecure": { + "label": "Χρησιμοποιήστε TLS από την αρχή", + "description": "Ενεργοποιήστε τη θύρα 465. Αφήστε την απενεργοποιημένη για τη θύρα 587, η οποία αναβαθμίζεται σε TLS από μόνη της." + }, + "smtpUser": { + "label": "Όνομα χρήστη SMTP", + "description": "Αφήστε το κενό εάν ο διακομιστής δεν χρειάζεται σύνδεση." + }, + "smtpPassword": { + "label": "Κωδικός πρόσβασης SMTP", + "description": "Αποθηκεύεται κρυπτογραφημένο." + }, + "smtpFrom": { + "label": "Διεύθυνση από", + "description": "Οι ειδοποιήσεις αποστολέα προέρχονται από.", + "placeholder": "Termmix " + } + }, + "user": { + "popups": { + "label": "Αναδυόμενα παράθυρα ειδοποιήσεων", + "description": "Ποιες νέες ειδοποιήσεις εμφανίζονται ενώ χρησιμοποιείτε το Termix. Πάντα καταλήγουν στα εισερχόμενα.", + "all": "Όλες οι ειδοποιήσεις", + "warning": "Προειδοποιήσεις και κρίσιμα", + "critical": "Μόνο κρίσιμα", + "off": "Κανένας" + } + } + }, + "sections": { + "inbox": "Εισερχόμενα", + "channels": "Κανάλια", + "rules": "Κανόνες παράδοσης" + }, + "severity": { + "info": "Πληροφορίες", + "success": "Επιτυχία", + "warning": "Προειδοποίηση", + "critical": "Κρίσιμος" + }, + "inbox": { + "sourceTermix": "Τέρμιξ", + "openLink": "Ανοιχτό", + "view": "Θέα", + "unread": "Αδιάβαστος", + "deliveryFailed_one": "Το κανάλι {{count}} απέτυχε", + "deliveryFailed_other": "{{count}} κανάλια απέτυχαν", + "markRead": "Σήμανση ως αναγνωσμένου", + "markUnread": "Επισήμανση ως μη αναγνωσμένου", + "markAllRead": "Σήμανση όλων ως αναγνωσμένων", + "delete": "Διαγράφω", + "clearRead": "Διαγραφή ειδοποιήσεων ανάγνωσης", + "cleared_one": "Διαγραμμένη ειδοποίηση {{count}}", + "cleared_other": "Διαγραμμένες {{count}} ειδοποιήσεις", + "filterAll": "Ολοι", + "filterUnread": "Αδιάβαστος", + "anySeverity": "Οποιαδήποτε σοβαρότητα", + "anySource": "Οποιαδήποτε πηγή", + "openAll": "Άνοιγμα σε καρτέλα", + "empty": "Δεν υπάρχουν ακόμη ειδοποιήσεις.", + "emptyUnread": "Είστε όλοι ενημερωμένοι.", + "loadMore": "Φόρτωση περισσότερων" + }, + "channels": { + "intro": "Τα κανάλια είναι τα σημεία όπου οι ειδοποιήσεις μπορούν να μεταβούν εκτός Termix. Οι κανόνες παράδοσης επιλέγουν ποιες ειδοποιήσεις τις χρησιμοποιούν.", + "add": "Προσθήκη καναλιού", + "edit": "Επεξεργασία καναλιού", + "test": "Αποστολή δοκιμής", + "testSent": "Εστάλη δοκιμαστική ειδοποίηση", + "testFailed": "Η δοκιμή απέτυχε: {{error}}", + "deleteConfirm": "Διαγραφή του καναλιού \"{{name}}\";", + "deleted": "Το κανάλι διαγράφηκε", + "empty": "Δεν υπάρχουν ακόμη κανάλια.", + "enabled": "Ενεργοποιημένο", + "needsSave": "Αυτό το κανάλι πρέπει να ανοιχτεί και να αποθηκευτεί ξανά πριν από την αποστολή.", + "name": "Ονομα", + "nameRequired": "Απαιτείται όνομα", + "type": "Τύπος", + "types": { + "webhook": "Ιστότοπος", + "ntfy": "ntfy", + "discord": "Διχόνοια", + "email": "E-mail" + }, + "emailUnavailable": "Το ηλεκτρονικό ταχυδρομείο χρειάζεται έναν διακομιστή SMTP, τον οποίο ρυθμίζει ένας διαχειριστής στις ρυθμίσεις Ειδοποιήσεων.", + "webhookUrl": "URL", + "webhookHint": "Λαμβάνει ένα σώμα JSON για κάθε ειδοποίηση.", + "method": "Μέθοδος", + "headers": "Κεφαλίδες", + "headersHint": "Ένα ανά γραμμή, όπως Όνομα: τιμή.", + "ntfyServer": "URL διακομιστή", + "ntfyTopic": "Θέμα", + "ntfyToken": "Διακριτικό πρόσβασης (προαιρετικό)", + "discordUrl": "URL webhook του Discord", + "discordHint": "Από τις ρυθμίσεις του καναλιού στο Discord, στην ενότητα Ενσωματώσεις.", + "discordUsername": "Εμφανιζόμενο όνομα (προαιρετικό)", + "discordAvatar": "URL avatar (προαιρετικό)", + "emailTo": "Αποστολή σε", + "emailHint": "Διαχωρίστε περισσότερες από μία διευθύνσεις με κόμματα.", + "privateNetwork": "Να επιτρέπεται μια ιδιωτική διεύθυνση δικτύου", + "privateNetworkHint": "Λειτουργεί μόνο για κεντρικούς υπολογιστές που επιτρέπει ένας διαχειριστής στη λίστα ιδιωτικών τελικών σημείων." + }, + "rules": { + "intro": "Ένας κανόνας παράδοσης στέλνει αντίστοιχες ειδοποιήσεις στα κανάλια σας. Οι ειδοποιήσεις παραμένουν πάντα και στα εισερχόμενα.", + "add": "Προσθήκη κανόνα", + "edit": "Επεξεργασία κανόνα", + "empty": "Δεν υπάρχουν ακόμη κανόνες, επομένως οι ειδοποιήσεις εμφανίζονται μόνο στα εισερχόμενα.", + "needChannel": "Προσθέστε πρώτα ένα κανάλι.", + "enabled": "Ενεργοποιημένο", + "name": "Ονομα", + "nameRequired": "Απαιτείται όνομα", + "match": "Ειδοποιήσεις προς αποστολή", + "matchHint": "* για τα πάντα, αυτοματισμούς.* για τα πάντα, από αυτοματισμούς ή ένα συγκεκριμένο είδος.", + "minSeverity": "Τουλάχιστον", + "channels": "Αποστολή σε", + "channelRequired": "Επιλέξτε τουλάχιστον ένα κανάλι", + "deleteConfirm": "Να διαγραφεί ο κανόνας \"{{name}}\";", + "everything": "Πάντα", + "summary": "{{match}}, {{severity}} ή υψηλότερο, έως {{channels}}" + }, + "actions": { + "cancel": "Ματαίωση", + "save": "Εκτός", + "saving": "Οικονομία...", + "delete": "Διαγράφω" + }, + "widget": { + "name": "Ροή ειδοποιήσεων", + "description": "Οι τελευταίες ειδοποιήσεις σας, με έναν γρήγορο τρόπο για να τις επισημάνετε ως αναγνωσμένες", + "maxItems": "Μέγιστος αριθμός στοιχείων", + "showRead": "Εμφάνιση ειδοποιήσεων ανάγνωσης", + "allClear": "Ορίζοντας είναι σαφής", + "loading": "Φόρτωση..." + } +} diff --git a/plugins/alerts/locales/translated/es_ES.json b/plugins/alerts/locales/translated/es_ES.json new file mode 100644 index 000000000..aba6af717 --- /dev/null +++ b/plugins/alerts/locales/translated/es_ES.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Alertas" + }, + "permissions": { + "use": { + "title": "Usar alertas", + "description": "Recibe alertas en tu bandeja de entrada y envíalas a tus propios canales." + } + }, + "onboarding": { + "feature": "Alertas", + "featureDesc": "Todas las alertas en una sola bandeja de entrada, enviadas a Discord, ntfy, correo electrónico o un webhook si lo deseas." + }, + "settings": { + "group": { + "general": "General", + "email": "Correo electrónico" + }, + "admin": { + "announcements": { + "label": "Anuncios de Termix", + "description": "Muestra las novedades del equipo de Termix, como avisos de seguridad y actualizaciones, directamente en la bandeja de entrada de todos." + }, + "retentionDays": { + "label": "Mantener alertas durante (días)", + "description": "Las alertas más antiguas se eliminan de todas las bandejas de entrada." + }, + "smtpHost": { + "label": "servidor SMTP", + "description": "Necesario para los canales de correo electrónico. Déjelo en blanco para desactivar el correo electrónico.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "puerto SMTP", + "description": "Normalmente 587 con STARTTLS o 465 con TLS." + }, + "smtpSecure": { + "label": "Utilice TLS desde el principio.", + "description": "Habilítelo para el puerto 465. Déjelo desactivado para el puerto 587, que se actualiza a TLS automáticamente." + }, + "smtpUser": { + "label": "Nombre de usuario SMTP", + "description": "Déjelo en blanco si el servidor no requiere inicio de sesión." + }, + "smtpPassword": { + "label": "Contraseña SMTP", + "description": "Almacenado cifrado." + }, + "smtpFrom": { + "label": "Desde la dirección", + "description": "Las alertas del remitente provienen de.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "ventanas emergentes de alerta", + "description": "¿Qué alertas nuevas aparecen mientras usas Termix? Siempre llegan a la bandeja de entrada.", + "all": "Todas las alertas", + "warning": "Advertencias y críticas", + "critical": "Solo crítico", + "off": "Ninguna" + } + } + }, + "sections": { + "inbox": "Bandeja de entrada", + "channels": "Canales", + "rules": "Normas de entrega" + }, + "severity": { + "info": "Información", + "success": "Éxito", + "warning": "Advertencia", + "critical": "Crítico" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "Abrir", + "view": "Ver", + "unread": "No leído", + "deliveryFailed_one": "El canal {{count}} falló", + "deliveryFailed_other": "{{count}} canales fallaron", + "markRead": "Marcar como leído", + "markUnread": "Marcar como no leído", + "markAllRead": "Marcar todo como leído", + "delete": "Eliminar", + "clearRead": "Eliminar alertas de lectura", + "cleared_one": "Alerta eliminada {{count}}", + "cleared_other": "Alertas {{count}} eliminadas", + "filterAll": "Revocar todo", + "filterUnread": "No leído", + "anySeverity": "Cualquier gravedad", + "anySource": "Cualquier fuente", + "openAll": "Abrir en una pestaña", + "empty": "Aún no hay alertas.", + "emptyUnread": "Ya estás al día.", + "loadMore": "Cargar más" + }, + "channels": { + "intro": "Los canales son donde las alertas pueden enviarse fuera de Termix. Las reglas de entrega determinan qué alertas los utilizan.", + "add": "Agregar canal", + "edit": "Editar canal", + "test": "Enviar una prueba", + "testSent": "Alerta de prueba enviada", + "testFailed": "Prueba fallida: {{error}}", + "deleteConfirm": "¿Eliminar el canal \"{{name}}\"?", + "deleted": "Canal eliminado", + "empty": "Aún no hay canales.", + "enabled": "Activado", + "needsSave": "Este canal debe abrirse y guardarse de nuevo antes de poder enviar mensajes.", + "name": "Nombre", + "nameRequired": "El nombre es obligatorio", + "type": "Tipo", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Discord", + "email": "Correo electrónico" + }, + "emailUnavailable": "El correo electrónico necesita un servidor SMTP, que un administrador configura en los ajustes de alertas.", + "webhookUrl": "URL", + "webhookHint": "Obtiene un cuerpo JSON para cada alerta.", + "method": "Método", + "headers": "Encabezados", + "headersHint": "Uno por línea, como Nombre: valor.", + "ntfyServer": "URL del servidor", + "ntfyTopic": "Tema", + "ntfyToken": "Token de acceso (opcional)", + "discordUrl": "URL del webhook de Discord", + "discordHint": "Desde la configuración del canal en Discord, en Integraciones.", + "discordUsername": "Nombre para mostrar (opcional)", + "discordAvatar": "URL del avatar (opcional)", + "emailTo": "Enviar a", + "emailHint": "Separe las direcciones con comas.", + "privateNetwork": "Permitir una dirección de red privada", + "privateNetworkHint": "Solo funciona para los hosts que un administrador haya autorizado en la lista de puntos finales privados." + }, + "rules": { + "intro": "Una regla de envío envía alertas coincidentes a tus canales. Las alertas también permanecen siempre en la bandeja de entrada.", + "add": "Agregar regla", + "edit": "Regla de edición", + "empty": "Aún no hay reglas, por lo que las alertas solo aparecen en la bandeja de entrada.", + "needChannel": "Primero añade un canal.", + "enabled": "Activado", + "name": "Nombre", + "nameRequired": "El nombre es obligatorio", + "match": "Alertas para enviar", + "matchHint": "* para todo, automatizaciones.* para todo a partir de automatizaciones, o un tipo exacto.", + "minSeverity": "Al menos", + "channels": "Enviar a", + "channelRequired": "Elige al menos un canal.", + "deleteConfirm": "¿Eliminar la regla \"{{name}}\"?", + "everything": "Todo", + "summary": "{{match}}, {{severity}} o superior, a {{channels}}" + }, + "actions": { + "cancel": "Cancelar", + "save": "Guardar", + "saving": "Guardando...", + "delete": "Eliminar" + }, + "widget": { + "name": "Feed de alertas", + "description": "Tus últimas alertas, con una forma rápida de marcarlas como leídas.", + "maxItems": "Artículos máximos", + "showRead": "Mostrar alertas de lectura", + "allClear": "Todo correcto", + "loading": "Cargando..." + } +} diff --git a/plugins/alerts/locales/translated/fi_FI.json b/plugins/alerts/locales/translated/fi_FI.json new file mode 100644 index 000000000..3e9748ae8 --- /dev/null +++ b/plugins/alerts/locales/translated/fi_FI.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Hälytykset" + }, + "permissions": { + "use": { + "title": "Käytä hälytyksiä", + "description": "Saat hälytyksiä sähköpostiisi ja voit lähettää niitä omiin kanaviisi." + } + }, + "onboarding": { + "feature": "Hälytykset", + "featureDesc": "Jokainen ilmoitus yhdessä postilaatikossa, lähetettynä Discordiin, ntfyyn, sähköpostiin tai webhookiin, jos haluat." + }, + "settings": { + "group": { + "general": "Yleistä", + "email": "Sähköposti" + }, + "admin": { + "announcements": { + "label": "Termix-ilmoitukset", + "description": "Näytä Termix-tiimin uutiset, kuten tietoturvailmoitukset ja julkaisut, kaikkien postilaatikossa." + }, + "retentionDays": { + "label": "Säilytä hälytykset (päivää)", + "description": "Vanhemmat ilmoitukset poistetaan kaikista postilaatikoista." + }, + "smtpHost": { + "label": "SMTP-palvelin", + "description": "Tarvitaan sähköpostikanaville. Jätä tyhjäksi poistaaksesi sähköpostin käytöstä.", + "placeholder": "smtp.esimerkki.com" + }, + "smtpPort": { + "label": "SMTP-portti", + "description": "Yleensä 587 STARTTLS:n kanssa tai 465 TLS:n kanssa." + }, + "smtpSecure": { + "label": "Käytä TLS:ää alusta alkaen", + "description": "Ota käyttöön portissa 465. Jätä pois käytöstä portissa 587, joka päivittää TLS:ään automaattisesti." + }, + "smtpUser": { + "label": "SMTP-käyttäjätunnus", + "description": "Jätä tyhjäksi, jos palvelin ei vaadi kirjautumista." + }, + "smtpPassword": { + "label": "SMTP-salasana", + "description": "Tallennettu salattuna." + }, + "smtpFrom": { + "label": "Lähettäjän osoite", + "description": "Lähettäjän hälytykset tulevat.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "Hälytysikkunat", + "description": "Mitkä uudet hälytykset ilmestyvät Termixin käytön aikana? Ne päätyvät aina postilaatikkoon.", + "all": "Kaikki hälytykset", + "warning": "Varoitukset ja kriittiset", + "critical": "Vain kriittiset", + "off": "Ei mitään" + } + } + }, + "sections": { + "inbox": "Saapuneet", + "channels": "Kanavat", + "rules": "Toimitussäännöt" + }, + "severity": { + "info": "Tiedot", + "success": "Menestys", + "warning": "Varoitus", + "critical": "Kriittinen" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "Avata", + "view": "Näytä", + "unread": "Lukematon", + "deliveryFailed_one": "{{count}} kanava epäonnistui", + "deliveryFailed_other": "{{count}} kanavat epäonnistuivat", + "markRead": "Merkitse luetuksi", + "markUnread": "Merkitse lukemattomaksi", + "markAllRead": "Merkitse kaikki luetuiksi", + "delete": "Poistaa", + "clearRead": "Poista lukuilmoitukset", + "cleared_one": "Poistettu {{count}} -hälytys", + "cleared_other": "Poistetut {{count}} hälytykset", + "filterAll": "Kaikki", + "filterUnread": "Lukematon", + "anySeverity": "Mikä tahansa vakavuusaste", + "anySource": "Mikä tahansa lähde", + "openAll": "Avaa välilehdessä", + "empty": "Ei vielä hälytyksiä.", + "emptyUnread": "Olette kaikki kärryillä.", + "loadMore": "Lataa lisää" + }, + "channels": { + "intro": "Kanavat ovat kanavia, joihin hälytykset voivat mennä Termixin ulkopuolelle. Toimitussäännöt valitsevat, mitkä hälytykset niitä käyttävät.", + "add": "Lisää kanava", + "edit": "Muokkaa kanavaa", + "test": "Lähetä testi", + "testSent": "Testihälytys lähetetty", + "testFailed": "Testi epäonnistui: {{error}}", + "deleteConfirm": "Poistetaanko kanava \"{{name}}\"?", + "deleted": "Kanava poistettu", + "empty": "Ei vielä kanavia.", + "enabled": "Käytössä", + "needsSave": "Tämä kanava on avattava ja tallennettava uudelleen ennen kuin se voi lähettää.", + "name": "Nimi", + "nameRequired": "Nimi on pakollinen", + "type": "Tyyppi", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Eripura", + "email": "Sähköposti" + }, + "emailUnavailable": "Sähköposti tarvitsee SMTP-palvelimen, jonka järjestelmänvalvoja määrittää hälytysasetuksissa.", + "webhookUrl": "URL-osoite", + "webhookHint": "Hakee JSON-rungon jokaiselle hälytykselle.", + "method": "Menetelmä", + "headers": "Ylätunnisteet", + "headersHint": "Yksi riviä kohden, kuten Nimi: arvo.", + "ntfyServer": "Palvelimen URL-osoite", + "ntfyTopic": "Aihe", + "ntfyToken": "Käyttöoikeustunnus (valinnainen)", + "discordUrl": "Discord-webhookin URL-osoite", + "discordHint": "Kanavan asetuksista Discordissa, Integraatiot-kohdasta.", + "discordUsername": "Näyttönimi (valinnainen)", + "discordAvatar": "Avatarin URL-osoite (valinnainen)", + "emailTo": "Lähetä osoitteeseen", + "emailHint": "Erota useampi kuin yksi osoite pilkulla.", + "privateNetwork": "Salli yksityinen verkko-osoite", + "privateNetworkHint": "Toimii vain isännille, jotka ylläpitäjä sallii yksityisten päätepisteiden luettelossa." + }, + "rules": { + "intro": "Toimitussääntö lähettää vastaavat hälytykset kanavillesi. Hälytykset pysyvät aina myös postilaatikossasi.", + "add": "Lisää sääntö", + "edit": "Muokkaa sääntöä", + "empty": "Ei vielä sääntöjä, joten hälytykset näkyvät vain postilaatikossa.", + "needChannel": "Lisää ensin kanava.", + "enabled": "Käytössä", + "name": "Nimi", + "nameRequired": "Nimi on pakollinen", + "match": "Lähetettävät hälytykset", + "matchHint": "* kaikkeen, automaatiot.* kaikkeen automaatioista alkaen tai tietynlaiseen.", + "minSeverity": "Vähintään", + "channels": "Lähetä osoitteeseen", + "channelRequired": "Valitse ainakin yksi kanava", + "deleteConfirm": "Poistetaanko sääntö \"{{name}}\"?", + "everything": "Kaikki", + "summary": "{{match}}, {{severity}} tai korkeampi, arvoon {{channels}}" + }, + "actions": { + "cancel": "Peruuttaa", + "save": "Tallentaa", + "saving": "Tallennetaan...", + "delete": "Poistaa" + }, + "widget": { + "name": "Hälytyssyöte", + "description": "Uusimmat ilmoituksesi ja nopea tapa merkitä ne luetuiksi", + "maxItems": "Enimmäismäärä esineitä", + "showRead": "Näytä lukuilmoitukset", + "allClear": "Kaikki selvää", + "loading": "Ladataan..." + } +} diff --git a/plugins/alerts/locales/translated/fr_FR.json b/plugins/alerts/locales/translated/fr_FR.json new file mode 100644 index 000000000..06d4a378a --- /dev/null +++ b/plugins/alerts/locales/translated/fr_FR.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Alertes" + }, + "permissions": { + "use": { + "title": "Utiliser les alertes", + "description": "Recevez des alertes dans votre boîte de réception et transférez-les sur vos propres canaux." + } + }, + "onboarding": { + "feature": "Alertes", + "featureDesc": "Toutes les alertes dans une seule boîte de réception, envoyées sur Discord, ntfy, par e-mail ou via un webhook si vous le souhaitez." + }, + "settings": { + "group": { + "general": "Général", + "email": "E-mail" + }, + "admin": { + "announcements": { + "label": "Annonces de Termix", + "description": "Afficher les actualités de l'équipe Termix, telles que les avis de sécurité et les nouvelles versions, dans la boîte de réception de tous." + }, + "retentionDays": { + "label": "Conserver les alertes pendant (jours)", + "description": "Les alertes les plus anciennes sont supprimées de chaque boîte de réception." + }, + "smtpHost": { + "label": "Serveur SMTP", + "description": "Nécessaire pour les canaux de messagerie. Laisser vide pour désactiver les e-mails.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "Port SMTP", + "description": "Généralement 587 avec STARTTLS ou 465 avec TLS." + }, + "smtpSecure": { + "label": "Utilisez TLS dès le début", + "description": "Activez le port 465. Désactivez le port 587, qui passe automatiquement au protocole TLS." + }, + "smtpUser": { + "label": "Nom d'utilisateur SMTP", + "description": "Laissez ce champ vide si le serveur ne nécessite pas d'authentification." + }, + "smtpPassword": { + "label": "Mot de passe SMTP", + "description": "Stocké de manière cryptée." + }, + "smtpFrom": { + "label": "Adresse de départ", + "description": "L'expéditeur des alertes provient de :", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "fenêtres contextuelles d'alerte", + "description": "Quelles nouvelles alertes s'affichent lorsque vous utilisez Termix ? Elles arrivent toujours dans votre boîte de réception.", + "all": "Toutes les alertes", + "warning": "Avertissements et critiques", + "critical": "Critique uniquement", + "off": "Aucune" + } + } + }, + "sections": { + "inbox": "Boîte de réception", + "channels": "Canaux", + "rules": "Règles de livraison" + }, + "severity": { + "info": "Info", + "success": "Succès", + "warning": "Avertissement", + "critical": "Critique" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "Ouvrir", + "view": "Consultation", + "unread": "Non lu", + "deliveryFailed_one": "Le canal {{count}} a échoué", + "deliveryFailed_other": "Les canaux {{count}} ont échoué", + "markRead": "Marquer comme lu", + "markUnread": "Marquer comme non lu", + "markAllRead": "Marquer tout comme lu", + "delete": "Supprimer", + "clearRead": "Supprimer les alertes de lecture", + "cleared_one": "Alerte {{count}} supprimée", + "cleared_other": "Alertes supprimées {{count}}", + "filterAll": "Tout", + "filterUnread": "Non lu", + "anySeverity": "Toute gravité", + "anySource": "Toute source", + "openAll": "Ouvrir dans un onglet", + "empty": "Aucune alerte pour le moment.", + "emptyUnread": "Vous êtes à jour.", + "loadMore": "Charger plus" + }, + "channels": { + "intro": "Les canaux permettent aux alertes de sortir de Termix. Les règles de diffusion déterminent quelles alertes les utilisent.", + "add": "Ajouter une chaîne", + "edit": "Modifier la chaîne", + "test": "Envoyer un test", + "testSent": "Alerte de test envoyée", + "testFailed": "Test échoué : {{error}}", + "deleteConfirm": "Supprimer le canal \"{{name}}\"?", + "deleted": "Chaîne supprimée", + "empty": "Aucune chaîne pour le moment.", + "enabled": "Activé", + "needsSave": "Ce canal doit être ouvert et enregistré à nouveau avant de pouvoir envoyer des données.", + "name": "Nom", + "nameRequired": "Le nom est obligatoire", + "type": "Type", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Discord", + "email": "E-mail" + }, + "emailUnavailable": "La messagerie électronique nécessite un serveur SMTP, que l'administrateur configure dans les paramètres d'alertes.", + "webhookUrl": "URL", + "webhookHint": "Récupère un corps JSON pour chaque alerte.", + "method": "Méthode", + "headers": "En-têtes", + "headersHint": "Une par ligne, comme Nom : valeur.", + "ntfyServer": "URL du serveur", + "ntfyTopic": "Sujet", + "ntfyToken": "Jeton d'accès (facultatif)", + "discordUrl": "URL du webhook Discord", + "discordHint": "Dans les paramètres de la chaîne sur Discord, sous Intégrations.", + "discordUsername": "Nom d'affichage (facultatif)", + "discordAvatar": "URL de l'avatar (facultatif)", + "emailTo": "Envoyer à", + "emailHint": "Séparez les adresses multiples par des virgules.", + "privateNetwork": "Autoriser une adresse réseau privée", + "privateNetworkHint": "Fonctionne uniquement pour les hôtes autorisés par un administrateur dans la liste des points de terminaison privés." + }, + "rules": { + "intro": "Une règle de diffusion envoie des alertes correspondantes à vos canaux. Les alertes restent également disponibles dans votre boîte de réception.", + "add": "Ajouter une règle", + "edit": "Règle de modification", + "empty": "Aucune règle n'a encore été définie, les alertes n'apparaissent donc que dans la boîte de réception.", + "needChannel": "Commencez par ajouter un canal.", + "enabled": "Activé", + "name": "Nom", + "nameRequired": "Le nom est obligatoire", + "match": "Alertes à envoyer", + "matchHint": "* Pour tout, les automatisations.* Pour tout ce qui concerne les automatisations, ou un type précis.", + "minSeverity": "Au moins", + "channels": "Envoyer à", + "channelRequired": "Choisissez au moins une chaîne", + "deleteConfirm": "Supprimer la règle \"{{name}}\"?", + "everything": "Tout", + "summary": "{{match}}, {{severity}} ou supérieur, à {{channels}}" + }, + "actions": { + "cancel": "Annuler", + "save": "Enregistrer", + "saving": "Enregistrement…", + "delete": "Supprimer" + }, + "widget": { + "name": "Flux d'alertes", + "description": "Vos dernières alertes, avec un moyen rapide de les marquer comme lues", + "maxItems": "Articles maximum", + "showRead": "Afficher les alertes de lecture", + "allClear": "Aucune alerte", + "loading": "Chargement..." + } +} diff --git a/plugins/alerts/locales/translated/he_IL.json b/plugins/alerts/locales/translated/he_IL.json new file mode 100644 index 000000000..0f3b1a5dc --- /dev/null +++ b/plugins/alerts/locales/translated/he_IL.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "התראות" + }, + "permissions": { + "use": { + "title": "השתמש בהתראות", + "description": "קבל התראות לתיבת הדואר הנכנס ושלח אותן לערוצים שלך." + } + }, + "onboarding": { + "feature": "התראות", + "featureDesc": "כל התראה בתיבת דואר נכנס אחת, נשלחת לדיסקורד, ntfy, אימייל או webhook אם תרצו." + }, + "settings": { + "group": { + "general": "כְּלָלִי", + "email": "אֶלֶקטרוֹנִי" + }, + "admin": { + "announcements": { + "label": "הכרזות של טרמיקס", + "description": "הצג חדשות מצוות Termix, כמו הודעות אבטחה ושחרורים, בתיבת הדואר הנכנס של כולם." + }, + "retentionDays": { + "label": "שמור התראות למשך (ימים)", + "description": "התראות ישנות יותר מוסרות מכל תיבת דואר נכנס." + }, + "smtpHost": { + "label": "שרת SMTP", + "description": "נדרש עבור ערוצי דוא\"ל. השאר ריק כדי לכבות את הדוא\"ל.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "יציאת SMTP", + "description": "בדרך כלל 587 עם STARTTLS או 465 עם TLS." + }, + "smtpSecure": { + "label": "השתמש ב-TLS מההתחלה", + "description": "הפעל עבור פורט 465. השאר את היציאה כבויה עבור פורט 587, אשר משדרג ל-TLS בעצמו." + }, + "smtpUser": { + "label": "שם משתמש של SMTP", + "description": "השאר ריק אם השרת אינו דורש התחברות." + }, + "smtpPassword": { + "label": "סיסמת SMTP", + "description": "מאוחסן מוצפן." + }, + "smtpFrom": { + "label": "מכתובת", + "description": "התראות השולח מגיעות מ-.", + "placeholder": "טרמיקס " + } + }, + "user": { + "popups": { + "label": "חלונות קופצים של התראות", + "description": "אילו התראות חדשות מופיעות בזמן השימוש ב-Termix? הן תמיד מגיעות לתיבת הדואר הנכנס.", + "all": "כל ההתראות", + "warning": "אזהרות ומידע קריטי", + "critical": "קריטי בלבד", + "off": "אַף לֹא אֶחָד" + } + } + }, + "sections": { + "inbox": "תיבת הדואר הנכנס", + "channels": "ערוצים", + "rules": "כללי משלוח" + }, + "severity": { + "info": "מידע", + "success": "הַצלָחָה", + "warning": "אַזהָרָה", + "critical": "קרִיטִי" + }, + "inbox": { + "sourceTermix": "טרמיקס", + "openLink": "לִפְתוֹחַ", + "view": "נוֹף", + "unread": "לא נקרא", + "deliveryFailed_one": "ערוץ {{count}} נכשל", + "deliveryFailed_other": "ערוצים {{count}} נכשלו", + "markRead": "סמן כנקרא", + "markUnread": "סמן כלא נקרא", + "markAllRead": "סמן הכל כנקרא", + "delete": "לִמְחוֹק", + "clearRead": "מחיקת התראות קריאה", + "cleared_one": "התראה {{count}} נמחקה", + "cleared_other": "התראות שנמחקו {{count}}", + "filterAll": "כֹּל", + "filterUnread": "לא נקרא", + "anySeverity": "כל חומרה", + "anySource": "כל מקור", + "openAll": "פתח בכרטיסייה", + "empty": "עדיין אין התראות.", + "emptyUnread": "כולכם שקועים.", + "loadMore": "טען עוד" + }, + "channels": { + "intro": "ערוצים הם מקומות שבהם התראות יכולות להגיע מחוץ ל-Termix. כללי מסירה בוחרים אילו התראות משתמשות בהן.", + "add": "הוסף ערוץ", + "edit": "עריכת ערוץ", + "test": "שלח בדיקה", + "testSent": "התראת בדיקה נשלחה", + "testFailed": "הבדיקה נכשלה: {{error}}", + "deleteConfirm": "למחוק את הערוץ \"{{name}}\"?", + "deleted": "הערוץ נמחק", + "empty": "עדיין אין ערוצים.", + "enabled": "מופעל", + "needsSave": "יש לפתוח ולשמור שוב את הערוץ הזה לפני שניתן יהיה לשלוח אותו.", + "name": "שֵׁם", + "nameRequired": "שם נדרש", + "type": "סוּג", + "types": { + "webhook": "וובהוק", + "ntfy": "ntfy", + "discord": "מַחֲלוֹקֶת", + "email": "אֶלֶקטרוֹנִי" + }, + "emailUnavailable": "דוא\"ל דורש שרת SMTP, אותו מנהל מערכת מגדיר בהגדרות ההתראות.", + "webhookUrl": "כתובת אתר", + "webhookHint": "מקבל גוף JSON עבור כל התראה.", + "method": "שִׁיטָה", + "headers": "כותרות", + "headersHint": "אחד בכל שורה, כמו שם: ערך.", + "ntfyServer": "כתובת URL של השרת", + "ntfyTopic": "נוֹשֵׂא", + "ntfyToken": "אסימון גישה (אופציונלי)", + "discordUrl": "כתובת אתר של דיסקורד ליצירת קשר עם רשת (webhook)", + "discordHint": "מהגדרות הערוץ בדיסקורד, תחת אינטגרציות.", + "discordUsername": "שם תצוגה (אופציונלי)", + "discordAvatar": "כתובת URL של אווטאר (אופציונלי)", + "emailTo": "שלח אל", + "emailHint": "הפרד יותר מכתובת אחת באמצעות פסיקים.", + "privateNetwork": "אפשר כתובת רשת פרטית", + "privateNetworkHint": "עובד רק עבור מארחים שמנהל מאפשר ברשימת נקודות הקצה הפרטיות." + }, + "rules": { + "intro": "כלל מסירה שולח התראות תואמות לערוצים שלך. ההתראות תמיד נשארות גם בתיבת הדואר הנכנס.", + "add": "הוסף כלל", + "edit": "עריכת כלל", + "empty": "עדיין אין כללים, כך שההתראות מופיעות רק בתיבת הדואר הנכנס.", + "needChannel": "הוסף ערוץ קודם.", + "enabled": "מופעל", + "name": "שֵׁם", + "nameRequired": "שם נדרש", + "match": "התראות לשליחה", + "matchHint": "* להכל, אוטומציות.* להכל, החל מאוטומציות, או מסוג אחד מדויק.", + "minSeverity": "לְפָחוֹת", + "channels": "שלח אל", + "channelRequired": "בחר לפחות ערוץ אחד", + "deleteConfirm": "למחוק את הכלל \"{{name}}\"?", + "everything": "הַכֹּל", + "summary": "{{match}}, {{severity}} או גבוה יותר, עד {{channels}}" + }, + "actions": { + "cancel": "לְבַטֵל", + "save": "לְהַצִיל", + "saving": "חִסָכוֹן...", + "delete": "לִמְחוֹק" + }, + "widget": { + "name": "הזנת התראות", + "description": "ההתראות האחרונות שלך, עם דרך מהירה לסמן אותן כנקראו", + "maxItems": "מקסימום פריטים", + "showRead": "הצג התראות קריאה", + "allClear": "הכל ברור", + "loading": "טְעִינָה..." + } +} diff --git a/plugins/alerts/locales/translated/hi_IN.json b/plugins/alerts/locales/translated/hi_IN.json new file mode 100644 index 000000000..92b403d80 --- /dev/null +++ b/plugins/alerts/locales/translated/hi_IN.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "अलर्ट्स" + }, + "permissions": { + "use": { + "title": "Use alerts", + "description": "Get alerts in the inbox and send them to your own channels." + } + }, + "onboarding": { + "feature": "अलर्ट", + "featureDesc": "Every alert in one inbox, sent on to Discord, ntfy, email or a webhook if you want." + }, + "settings": { + "group": { + "general": "सामान्य", + "email": "ईमेल" + }, + "admin": { + "announcements": { + "label": "Termix announcements", + "description": "Show news from the Termix team, like security notices and releases, in everyone's inbox." + }, + "retentionDays": { + "label": "Keep alerts for (days)", + "description": "Older alerts are removed from every inbox." + }, + "smtpHost": { + "label": "SMTP server", + "description": "Needed for email channels. Leave empty to turn email off.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "SMTP port", + "description": "Usually 587 with STARTTLS or 465 with TLS." + }, + "smtpSecure": { + "label": "Use TLS from the start", + "description": "Turn on for port 465. Leave off for 587, which upgrades to TLS on its own." + }, + "smtpUser": { + "label": "SMTP username", + "description": "Leave empty if the server does not need a login." + }, + "smtpPassword": { + "label": "SMTP password", + "description": "Stored encrypted." + }, + "smtpFrom": { + "label": "From address", + "description": "The sender alerts come from.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "Alert popups", + "description": "Which new alerts pop up while you use Termix. They always land in the inbox.", + "all": "All alerts", + "warning": "Warnings and critical", + "critical": "Critical only", + "off": "कोई नहीं" + } + } + }, + "sections": { + "inbox": "Inbox", + "channels": "चैनल", + "rules": "Delivery rules" + }, + "severity": { + "info": "जानकारी", + "success": "सफल", + "warning": "चेतावनी", + "critical": "Critical" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "खोलें", + "view": "देखें", + "unread": "Unread", + "deliveryFailed_one": "{{count}} channel failed", + "deliveryFailed_other": "{{count}} channels failed", + "markRead": "Mark as read", + "markUnread": "Mark as unread", + "markAllRead": "Mark all as read", + "delete": "हटाएँ", + "clearRead": "Delete read alerts", + "cleared_one": "Deleted {{count}} alert", + "cleared_other": "Deleted {{count}} alerts", + "filterAll": "सभी", + "filterUnread": "Unread", + "anySeverity": "Any severity", + "anySource": "Any source", + "openAll": "Open in a tab", + "empty": "No alerts yet.", + "emptyUnread": "You are all caught up.", + "loadMore": "Load more" + }, + "channels": { + "intro": "Channels are where alerts can go outside Termix. Delivery rules pick which alerts use them.", + "add": "Add channel", + "edit": "Edit channel", + "test": "Send a test", + "testSent": "Test alert sent", + "testFailed": "Test failed: {{error}}", + "deleteConfirm": "Delete the channel \"{{name}}\"?", + "deleted": "Channel deleted", + "empty": "No channels yet.", + "enabled": "सक्षम", + "needsSave": "This channel needs to be opened and saved again before it can send.", + "name": "नाम", + "nameRequired": "नाम आवश्यक है", + "type": "प्रकार", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Discord", + "email": "ईमेल" + }, + "emailUnavailable": "Email needs an SMTP server, which an admin sets up in the Alerts settings.", + "webhookUrl": "URL", + "webhookHint": "Gets a JSON body for every alert.", + "method": "Method", + "headers": "Headers", + "headersHint": "One per line, like Name: value.", + "ntfyServer": "सर्वर URL", + "ntfyTopic": "विषय", + "ntfyToken": "Access token (optional)", + "discordUrl": "Discord webhook URL", + "discordHint": "From the channel's settings in Discord, under Integrations.", + "discordUsername": "Display name (optional)", + "discordAvatar": "Avatar URL (optional)", + "emailTo": "Send to", + "emailHint": "Separate more than one address with commas.", + "privateNetwork": "Allow a private network address", + "privateNetworkHint": "Only works for hosts an admin allows in the private endpoint list." + }, + "rules": { + "intro": "A delivery rule sends matching alerts to your channels. Alerts always stay in the inbox too.", + "add": "Add rule", + "edit": "Edit rule", + "empty": "No rules yet, so alerts only show up in the inbox.", + "needChannel": "Add a channel first.", + "enabled": "सक्षम", + "name": "नाम", + "nameRequired": "नाम आवश्यक है", + "match": "Alerts to send", + "matchHint": "* for everything, automations.* for everything from automations, or one exact kind.", + "minSeverity": "At least", + "channels": "Send to", + "channelRequired": "Pick at least one channel", + "deleteConfirm": "Delete the rule \"{{name}}\"?", + "everything": "Everything", + "summary": "{{match}}, {{severity}} or higher, to {{channels}}" + }, + "actions": { + "cancel": "रद्द करें", + "save": "सहेजें", + "saving": "सहेजा जा रहा है...", + "delete": "हटाएँ" + }, + "widget": { + "name": "अलर्ट फीड", + "description": "Your latest alerts, with a quick way to mark them read", + "maxItems": "Max items", + "showRead": "Show read alerts", + "allClear": "सब ठीक है", + "loading": "लोड हो रहा है..." + } +} diff --git a/plugins/alerts/locales/translated/hu_HU.json b/plugins/alerts/locales/translated/hu_HU.json new file mode 100644 index 000000000..8f5fcd7b4 --- /dev/null +++ b/plugins/alerts/locales/translated/hu_HU.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Riasztások" + }, + "permissions": { + "use": { + "title": "Értesítések használata", + "description": "Értesítéseket kaphatsz a beérkező levelek mappájába, és elküldheted azokat a saját csatornáidra." + } + }, + "onboarding": { + "feature": "Riasztások", + "featureDesc": "Minden értesítés egy postaládában, továbbítva Discordra, ntfy-ra, e-mailben vagy webhookon, ha szeretnéd." + }, + "settings": { + "group": { + "general": "Általános", + "email": "Email" + }, + "admin": { + "announcements": { + "label": "Termix bejelentések", + "description": "Jelenítse meg a Termix csapatától származó híreket, például a biztonsági értesítéseket és kiadásokat, mindenki postaládájában." + }, + "retentionDays": { + "label": "Figyelmeztetések megőrzése (nap)", + "description": "A régebbi értesítések minden beérkező üzenetből törlődnek." + }, + "smtpHost": { + "label": "SMTP-kiszolgáló", + "description": "E-mail csatornákhoz szükséges. Hagyja üresen az e-mail kikapcsolásához.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "SMTP-port", + "description": "Általában 587 STARTTLS-sel vagy 465 TLS-sel." + }, + "smtpSecure": { + "label": "Használj TLS-t a kezdetektől fogva", + "description": "Kapcsold be a 465-ös porton. Hagyd kikapcsolva az 587-es porton, amely önmagában frissít TLS-re." + }, + "smtpUser": { + "label": "SMTP felhasználónév", + "description": "Hagyja üresen, ha a szerver nem igényel bejelentkezést." + }, + "smtpPassword": { + "label": "SMTP jelszó", + "description": "Titkosítva tárolva." + }, + "smtpFrom": { + "label": "Feladó címe", + "description": "A feladó értesítései innen érkeznek.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "Figyelmeztető felugró ablakok", + "description": "Milyen új értesítések ugranak fel a Termix használata közben? Mindig a beérkezett üzenetek mappába érkeznek.", + "all": "Minden riasztás", + "warning": "Figyelmeztetések és kritikus fontosságú információk", + "critical": "Csak kritikus fontosságú", + "off": "Egyik sem" + } + } + }, + "sections": { + "inbox": "Beérkezett üzenetek", + "channels": "Csatornák", + "rules": "Szállítási szabályok" + }, + "severity": { + "info": "Információ", + "success": "Siker", + "warning": "Figyelmeztetés", + "critical": "Kritikai" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "Nyitott", + "view": "Kilátás", + "unread": "Nem olvasott", + "deliveryFailed_one": "{{count}} csatorna hibás", + "deliveryFailed_other": "{{count}} csatornák hibásak", + "markRead": "Megjelölés olvasottként", + "markUnread": "Megjelölés olvasatlanként", + "markAllRead": "Összes megjelölése olvasottként", + "delete": "Töröl", + "clearRead": "Olvasási értesítések törlése", + "cleared_one": "Törölt {{count}} riasztás", + "cleared_other": "Törölt {{count}} riasztások", + "filterAll": "Minden", + "filterUnread": "Nem olvasott", + "anySeverity": "Bármilyen súlyosságú", + "anySource": "Bármely forrás", + "openAll": "Megnyitás egy lapon", + "empty": "Még nincsenek riasztások.", + "emptyUnread": "Mindennel tisztában vagytok.", + "loadMore": "Továbbiak betöltése" + }, + "channels": { + "intro": "A csatornák azok a csatornák, amelyeken keresztül a riasztások a Termixen kívülre kerülhetnek. A kézbesítési szabályok választják ki, hogy mely riasztások használják ezeket a csatornákat.", + "add": "Csatorna hozzáadása", + "edit": "Csatorna szerkesztése", + "test": "Küldj egy tesztet", + "testSent": "Tesztriasztás elküldve", + "testFailed": "Sikertelen teszt: {{error}}", + "deleteConfirm": "Törölni a(z) \"{{name}} \" csatornát?", + "deleted": "Csatorna törölve", + "empty": "Még nincsenek csatornák.", + "enabled": "Engedélyezve", + "needsSave": "Ezt a csatornát újra meg kell nyitni és menteni, mielőtt küldeni tudna.", + "name": "Név", + "nameRequired": "Név megadása kötelező", + "type": "Típus", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Viszály", + "email": "Email" + }, + "emailUnavailable": "Az e-mailhez SMTP-kiszolgálóra van szükség, amelyet egy rendszergazda állít be a riasztási beállításokban.", + "webhookUrl": "URL-cím", + "webhookHint": "Minden riasztáshoz JSON törzset kap.", + "method": "Módszer", + "headers": "Fejlécek", + "headersHint": "Soronként egy, például Név: érték.", + "ntfyServer": "Szerver URL-címe", + "ntfyTopic": "Téma", + "ntfyToken": "Hozzáférési token (opcionális)", + "discordUrl": "Discord webhook URL", + "discordHint": "A csatorna beállításaiban a Discordban, az Integrációk alatt.", + "discordUsername": "Megjelenített név (opcionális)", + "discordAvatar": "Avatar URL-címe (opcionális)", + "emailTo": "Küldés ide:", + "emailHint": "Több cím esetén vesszővel válassza el az egyes címeket.", + "privateNetwork": "Privát hálózati cím engedélyezése", + "privateNetworkHint": "Csak azoknál a hosztoknál működik, amelyeket az adminisztrátor engedélyez a privát végpontok listájában." + }, + "rules": { + "intro": "A kézbesítési szabály egyező értesítéseket küld a csatornáidra. Az értesítések mindig a beérkezett üzenetek mappájában is maradnak.", + "add": "Szabály hozzáadása", + "edit": "Szabály szerkesztése", + "empty": "Még nincsenek szabályok, így az értesítések csak a beérkező levelek mappában jelennek meg.", + "needChannel": "Először adj hozzá egy csatornát.", + "enabled": "Engedélyezve", + "name": "Név", + "nameRequired": "Név megadása kötelező", + "match": "Küldendő riasztások", + "matchHint": "* mindenre, automatizálásokra.* mindenre az automatizálásoktól kezdve, vagy egy pontos fajtára.", + "minSeverity": "Legalább", + "channels": "Küldés ide:", + "channelRequired": "Válassz legalább egy csatornát", + "deleteConfirm": "Törölni kell a(z) \"{{name}} \" szabályt?", + "everything": "Minden", + "summary": "{{match}}, {{severity}} vagy magasabb, {{channels}}-ra" + }, + "actions": { + "cancel": "Mégsem", + "save": "Megtakarítás", + "saving": "Megtakarítás...", + "delete": "Töröl" + }, + "widget": { + "name": "Értesítési hírcsatorna", + "description": "Legfrissebb értesítéseid, gyors móddal az olvasottként való megjelölésre", + "maxItems": "Max. tételek", + "showRead": "Olvasási értesítések megjelenítése", + "allClear": "Minden tiszta", + "loading": "Terhelés..." + } +} diff --git a/plugins/alerts/locales/translated/id_ID.json b/plugins/alerts/locales/translated/id_ID.json new file mode 100644 index 000000000..9d7514f0d --- /dev/null +++ b/plugins/alerts/locales/translated/id_ID.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Alerts" + }, + "permissions": { + "use": { + "title": "Use alerts", + "description": "Get alerts in the inbox and send them to your own channels." + } + }, + "onboarding": { + "feature": "Alerts", + "featureDesc": "Every alert in one inbox, sent on to Discord, ntfy, email or a webhook if you want." + }, + "settings": { + "group": { + "general": "General", + "email": "Email" + }, + "admin": { + "announcements": { + "label": "Termix announcements", + "description": "Show news from the Termix team, like security notices and releases, in everyone's inbox." + }, + "retentionDays": { + "label": "Keep alerts for (days)", + "description": "Older alerts are removed from every inbox." + }, + "smtpHost": { + "label": "SMTP server", + "description": "Needed for email channels. Leave empty to turn email off.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "SMTP port", + "description": "Usually 587 with STARTTLS or 465 with TLS." + }, + "smtpSecure": { + "label": "Use TLS from the start", + "description": "Turn on for port 465. Leave off for 587, which upgrades to TLS on its own." + }, + "smtpUser": { + "label": "SMTP username", + "description": "Leave empty if the server does not need a login." + }, + "smtpPassword": { + "label": "SMTP password", + "description": "Stored encrypted." + }, + "smtpFrom": { + "label": "From address", + "description": "The sender alerts come from.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "Alert popups", + "description": "Which new alerts pop up while you use Termix. They always land in the inbox.", + "all": "All alerts", + "warning": "Warnings and critical", + "critical": "Critical only", + "off": "None" + } + } + }, + "sections": { + "inbox": "Inbox", + "channels": "Channels", + "rules": "Delivery rules" + }, + "severity": { + "info": "Info", + "success": "Success", + "warning": "Warning", + "critical": "Critical" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "Open", + "view": "View", + "unread": "Unread", + "deliveryFailed_one": "{{count}} channel failed", + "deliveryFailed_other": "{{count}} channels failed", + "markRead": "Mark as read", + "markUnread": "Mark as unread", + "markAllRead": "Mark all as read", + "delete": "Delete", + "clearRead": "Delete read alerts", + "cleared_one": "Deleted {{count}} alert", + "cleared_other": "Deleted {{count}} alerts", + "filterAll": "All", + "filterUnread": "Unread", + "anySeverity": "Any severity", + "anySource": "Any source", + "openAll": "Open in a tab", + "empty": "No alerts yet.", + "emptyUnread": "You are all caught up.", + "loadMore": "Load more" + }, + "channels": { + "intro": "Channels are where alerts can go outside Termix. Delivery rules pick which alerts use them.", + "add": "Add channel", + "edit": "Edit channel", + "test": "Send a test", + "testSent": "Test alert sent", + "testFailed": "Test failed: {{error}}", + "deleteConfirm": "Delete the channel \"{{name}}\"?", + "deleted": "Channel deleted", + "empty": "No channels yet.", + "enabled": "Enabled", + "needsSave": "This channel needs to be opened and saved again before it can send.", + "name": "Name", + "nameRequired": "Name is required", + "type": "Type", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Discord", + "email": "Email" + }, + "emailUnavailable": "Email needs an SMTP server, which an admin sets up in the Alerts settings.", + "webhookUrl": "URL", + "webhookHint": "Gets a JSON body for every alert.", + "method": "Method", + "headers": "Headers", + "headersHint": "One per line, like Name: value.", + "ntfyServer": "Server URL", + "ntfyTopic": "Topic", + "ntfyToken": "Access token (optional)", + "discordUrl": "Discord webhook URL", + "discordHint": "From the channel's settings in Discord, under Integrations.", + "discordUsername": "Display name (optional)", + "discordAvatar": "Avatar URL (optional)", + "emailTo": "Send to", + "emailHint": "Separate more than one address with commas.", + "privateNetwork": "Allow a private network address", + "privateNetworkHint": "Only works for hosts an admin allows in the private endpoint list." + }, + "rules": { + "intro": "A delivery rule sends matching alerts to your channels. Alerts always stay in the inbox too.", + "add": "Add rule", + "edit": "Edit rule", + "empty": "No rules yet, so alerts only show up in the inbox.", + "needChannel": "Add a channel first.", + "enabled": "Enabled", + "name": "Name", + "nameRequired": "Name is required", + "match": "Alerts to send", + "matchHint": "* for everything, automations.* for everything from automations, or one exact kind.", + "minSeverity": "At least", + "channels": "Send to", + "channelRequired": "Pick at least one channel", + "deleteConfirm": "Delete the rule \"{{name}}\"?", + "everything": "Everything", + "summary": "{{match}}, {{severity}} or higher, to {{channels}}" + }, + "actions": { + "cancel": "Cancel", + "save": "Save", + "saving": "Saving...", + "delete": "Delete" + }, + "widget": { + "name": "Alert Feed", + "description": "Your latest alerts, with a quick way to mark them read", + "maxItems": "Max items", + "showRead": "Show read alerts", + "allClear": "All clear", + "loading": "Loading..." + } +} diff --git a/plugins/alerts/locales/translated/it_IT.json b/plugins/alerts/locales/translated/it_IT.json new file mode 100644 index 000000000..d601c4a82 --- /dev/null +++ b/plugins/alerts/locales/translated/it_IT.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Avvisi" + }, + "permissions": { + "use": { + "title": "Utilizzare gli avvisi", + "description": "Ricevi notifiche nella casella di posta e inoltrale ai tuoi canali." + } + }, + "onboarding": { + "feature": "Avvisi", + "featureDesc": "Tutte le notifiche in un'unica casella di posta, inviate anche a Discord, ntfy, via email o tramite webhook, a seconda delle tue preferenze." + }, + "settings": { + "group": { + "general": "Generale", + "email": "Email" + }, + "admin": { + "announcements": { + "label": "Comunicazioni di Termix", + "description": "Mostra le notizie del team Termix, come avvisi di sicurezza e rilasci, direttamente nella casella di posta di tutti." + }, + "retentionDays": { + "label": "Mantieni gli avvisi per (giorni)", + "description": "Gli avvisi più vecchi vengono rimossi da tutte le caselle di posta." + }, + "smtpHost": { + "label": "server SMTP", + "description": "Necessario per i canali email. Lasciare vuoto per disattivare le email.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "porta SMTP", + "description": "Solitamente 587 con STARTTLS o 465 con TLS." + }, + "smtpSecure": { + "label": "Utilizzare TLS fin dall'inizio", + "description": "Attivare la porta 465. Disattivare la porta 587, che si aggiorna automaticamente a TLS." + }, + "smtpUser": { + "label": "nome utente SMTP", + "description": "Lascia vuoto se il server non richiede l'accesso tramite login." + }, + "smtpPassword": { + "label": "password SMTP", + "description": "Archiviato in forma crittografata." + }, + "smtpFrom": { + "label": "Da indirizzo", + "description": "Gli avvisi del mittente provengono da.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "popup di avviso", + "description": "Quali nuovi avvisi compaiono mentre usi Termix? Arrivano sempre nella tua casella di posta.", + "all": "Tutti gli avvisi", + "warning": "avvertimenti e critici", + "critical": "Solo critico", + "off": "Nessuno" + } + } + }, + "sections": { + "inbox": "Posta in arrivo", + "channels": "Canali", + "rules": "Regole di consegna" + }, + "severity": { + "info": "Info", + "success": "Successo", + "warning": "Attenzione", + "critical": "Critico" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "Apri", + "view": "Visualizza", + "unread": "Non letto", + "deliveryFailed_one": "{{count}} canale non riuscito", + "deliveryFailed_other": "{{count}} canali non funzionanti", + "markRead": "Segna come letto", + "markUnread": "Segna come non letto", + "markAllRead": "Segna tutto come letto", + "delete": "Elimina", + "clearRead": "Elimina gli avvisi di lettura", + "cleared_one": "Avviso eliminato {{count}}", + "cleared_other": "Avvisi eliminati {{count}}", + "filterAll": "Tutte", + "filterUnread": "Non letto", + "anySeverity": "Qualsiasi gravità", + "anySource": "Qualsiasi fonte", + "openAll": "Apri in una scheda", + "empty": "Nessun avviso per ora.", + "emptyUnread": "Sei al corrente di tutto.", + "loadMore": "Carica altro" + }, + "channels": { + "intro": "I canali sono i punti in cui gli avvisi possono essere inviati al di fuori di Termix. Le regole di consegna selezionano quali avvisi li utilizzano.", + "add": "Aggiungi canale", + "edit": "Modifica canale", + "test": "Invia un test", + "testSent": "Avviso di prova inviato", + "testFailed": "Test fallito: {{error}}", + "deleteConfirm": "Eliminare il canale \"{{name}}\"?", + "deleted": "Canale eliminato", + "empty": "Ancora nessun canale disponibile.", + "enabled": "Abilitato", + "needsSave": "Questo canale deve essere aperto e salvato nuovamente prima di poter inviare messaggi.", + "name": "Nome", + "nameRequired": "Nome obbligatorio", + "type": "Tipo", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Discord", + "email": "Email" + }, + "emailUnavailable": "Per l'invio di email è necessario un server SMTP, che l'amministratore configura nelle impostazioni degli avvisi.", + "webhookUrl": "URL", + "webhookHint": "Recupera un corpo JSON per ogni avviso.", + "method": "Metodo", + "headers": "Intestazioni", + "headersHint": "Uno per riga, ad esempio Nome: valore.", + "ntfyServer": "URL server", + "ntfyTopic": "Argomento", + "ntfyToken": "Token di accesso (facoltativo)", + "discordUrl": "URL del webhook di Discord", + "discordHint": "Dalle impostazioni del canale su Discord, alla voce Integrazioni.", + "discordUsername": "Nome visualizzato (facoltativo)", + "discordAvatar": "URL dell'avatar (facoltativo)", + "emailTo": "Invia a", + "emailHint": "Separare gli indirizzi con delle virgole.", + "privateNetwork": "Consentire un indirizzo di rete privato", + "privateNetworkHint": "Funziona solo per gli host che un amministratore consente nell'elenco degli endpoint privati." + }, + "rules": { + "intro": "Una regola di consegna invia avvisi corrispondenti ai tuoi canali. Gli avvisi rimangono sempre anche nella posta in arrivo.", + "add": "Aggiungi regola", + "edit": "Modifica regola", + "empty": "Non ci sono ancora regole, quindi gli avvisi vengono visualizzati solo nella casella di posta.", + "needChannel": "Aggiungi prima un canale.", + "enabled": "Abilitato", + "name": "Nome", + "nameRequired": "Nome obbligatorio", + "match": "Avvisi da inviare", + "matchHint": "* per tutto, automazioni.* per tutto ciò che riguarda le automazioni, o un tipo specifico.", + "minSeverity": "Almeno", + "channels": "Invia a", + "channelRequired": "Scegli almeno un canale", + "deleteConfirm": "Eliminare la regola \"{{name}}\"?", + "everything": "Qualunque cosa", + "summary": "{{match}}, {{severity}} o superiore, a {{channels}}" + }, + "actions": { + "cancel": "Annulla", + "save": "Salva", + "saving": "Salvando...", + "delete": "Elimina" + }, + "widget": { + "name": "Feed degli avvisi", + "description": "I tuoi ultimi avvisi, con un modo rapido per contrassegnarli come letti.", + "maxItems": "Numero massimo di elementi", + "showRead": "Mostra gli avvisi di lettura", + "allClear": "Tutto a posto", + "loading": "Caricamento in corso..." + } +} diff --git a/plugins/alerts/locales/translated/ja_JP.json b/plugins/alerts/locales/translated/ja_JP.json new file mode 100644 index 000000000..16274c924 --- /dev/null +++ b/plugins/alerts/locales/translated/ja_JP.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "アラート" + }, + "permissions": { + "use": { + "title": "アラートを使用する", + "description": "受信トレイでアラートを受け取り、自分のチャンネルに送信できます。" + } + }, + "onboarding": { + "feature": "アラート", + "featureDesc": "すべてのアラートを1つの受信トレイに集約し、必要に応じてDiscord、ntfy、メール、またはWebhookに送信します。" + }, + "settings": { + "group": { + "general": "全般", + "email": "メールアドレス" + }, + "admin": { + "announcements": { + "label": "Termixのお知らせ", + "description": "セキュリティに関する通知やリリースなど、Termixチームからのニュースを全員の受信トレイに表示します。" + }, + "retentionDays": { + "label": "(日間)アラートを保持する", + "description": "古いアラートはすべての受信トレイから削除されます。" + }, + "smtpHost": { + "label": "SMTPサーバー", + "description": "メール配信には必須です。メール配信をオフにする場合は空欄のままにしてください。", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "SMTPポート", + "description": "通常、STARTTLSの場合は587番ポート、TLSの場合は465番ポートが使用されます。" + }, + "smtpSecure": { + "label": "最初からTLSを使用する", + "description": "ポート465は有効にしてください。ポート587は無効のままにしておいてください。587は自動的にTLSにアップグレードされます。" + }, + "smtpUser": { + "label": "SMTPユーザー名", + "description": "サーバーへのログインが不要な場合は、空欄のままにしてください。" + }, + "smtpPassword": { + "label": "SMTPパスワード", + "description": "暗号化して保存されます。" + }, + "smtpFrom": { + "label": "送信元住所", + "description": "送信者アラートは以下から送信されます。", + "placeholder": "ターミックス " + } + }, + "user": { + "popups": { + "label": "アラートポップアップ", + "description": "Termixの使用中に新しいアラートが表示されますか?それらはすべて受信トレイに届きます。", + "all": "すべてのアラート", + "warning": "警告と重大な", + "critical": "クリティカルのみ", + "off": "すべて解除" + } + } + }, + "sections": { + "inbox": "受信箱", + "channels": "チャンネル", + "rules": "配送ルール" + }, + "severity": { + "info": "情報", + "success": "成功", + "warning": "警告", + "critical": "致命的" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "開く", + "view": "表示", + "unread": "未読", + "deliveryFailed_one": "{{count}} チャネルが失敗しました", + "deliveryFailed_other": "{{count}} チャネルが失敗しました", + "markRead": "既読にする", + "markUnread": "未読としてマークする", + "markAllRead": "すべて既読にする", + "delete": "削除", + "clearRead": "既読アラートを削除する", + "cleared_one": "削除済み {{count}} アラート", + "cleared_other": "削除された {{count}} アラート", + "filterAll": "すべて選択", + "filterUnread": "未読", + "anySeverity": "重症度は問わない", + "anySource": "あらゆる情報源", + "openAll": "タブで開く", + "empty": "まだアラートはありません。", + "emptyUnread": "皆さんは最新情報に追いつきました。", + "loadMore": "もっと読み込む" + }, + "channels": { + "intro": "チャネルとは、アラートをTermix外部に送信する場所です。配信ルールによって、どのアラートがチャネルを使用するかが決定されます。", + "add": "チャンネルを追加", + "edit": "チャンネルを編集", + "test": "テストを送信", + "testSent": "テストアラートが送信されました", + "testFailed": "テスト失敗: {{error}}", + "deleteConfirm": "チャンネル「{{name}}」を削除しますか?", + "deleted": "チャンネルが削除されました", + "empty": "まだチャンネルはありません。", + "enabled": "有効", + "needsSave": "このチャンネルは、送信する前に再度開いて保存する必要があります。", + "name": "名前", + "nameRequired": "名前は必須です", + "type": "タイプ", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Discord", + "email": "メールアドレス" + }, + "emailUnavailable": "メール送信にはSMTPサーバーが必要で、管理者がアラート設定で設定します。", + "webhookUrl": "URL", + "webhookHint": "アラートごとにJSON形式の本文を取得します。", + "method": "方法", + "headers": "ヘッダー", + "headersHint": "1行に1つずつ、例:名前:値。", + "ntfyServer": "サーバーURL", + "ntfyTopic": "トピック", + "ntfyToken": "アクセストークン(任意)", + "discordUrl": "DiscordウェブフックURL", + "discordHint": "Discordのチャンネル設定の「統合」セクションから設定できます。", + "discordUsername": "表示名(任意)", + "discordAvatar": "アバターのURL(任意)", + "emailTo": "送信先", + "emailHint": "複数の住所を入力する場合は、カンマで区切ってください。", + "privateNetwork": "プライベートネットワークアドレスを許可する", + "privateNetworkHint": "管理者がプライベートエンドポイントリストで許可したホストでのみ機能します。" + }, + "rules": { + "intro": "配信ルールを設定すると、該当するアラートが指定したチャネルに送信されます。アラートは常に受信トレイにも残ります。", + "add": "ルールを追加する", + "edit": "ルールを編集する", + "empty": "まだルールが設定されていないため、アラートは受信トレイにのみ表示されます。", + "needChannel": "まずチャンネルを追加してください。", + "enabled": "有効", + "name": "名前", + "nameRequired": "名前は必須です", + "match": "送信するアラート", + "matchHint": "* すべてに対して、自動化。* 自動化からのすべて、または特定の種類のもの。", + "minSeverity": "少なくとも", + "channels": "送信先", + "channelRequired": "少なくとも1つのチャンネルを選択してください", + "deleteConfirm": "ルール「{{name}}」を削除しますか?", + "everything": "すべて", + "summary": "{{match}}、 {{severity}} 以上、 {{channels}}まで" + }, + "actions": { + "cancel": "キャンセル", + "save": "保存", + "saving": "保存中...", + "delete": "削除" + }, + "widget": { + "name": "アラートフィード", + "description": "最新のアラートを既読にする簡単な方法", + "maxItems": "最大アイテム数", + "showRead": "既読通知を表示する", + "allClear": "すべて正常", + "loading": "読み込み中..." + } +} diff --git a/plugins/alerts/locales/translated/ko_KR.json b/plugins/alerts/locales/translated/ko_KR.json new file mode 100644 index 000000000..b3dfe9046 --- /dev/null +++ b/plugins/alerts/locales/translated/ko_KR.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "알림" + }, + "permissions": { + "use": { + "title": "알림 기능을 사용하세요", + "description": "받은 편지함으로 알림을 받고, 원하는 채널로도 알림을 보낼 수 있습니다." + } + }, + "onboarding": { + "feature": "알림", + "featureDesc": "모든 알림은 하나의 받은 편지함에 모이며, 원하시면 Discord, ntfy, 이메일 또는 웹훅으로 전송됩니다." + }, + "settings": { + "group": { + "general": "일반", + "email": "이메일" + }, + "admin": { + "announcements": { + "label": "Termix 공지사항", + "description": "보안 공지 및 릴리스와 같은 Termix 팀의 소식을 모든 사람의 받은 편지함에 표시합니다." + }, + "retentionDays": { + "label": "(일) 동안 알림을 유지하세요", + "description": "오래된 알림은 모든 받은 편지함에서 삭제됩니다." + }, + "smtpHost": { + "label": "SMTP 서버", + "description": "이메일 채널에 필요합니다. 이메일 기능을 끄려면 비워 두세요.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "SMTP 포트", + "description": "일반적으로 STARTTLS를 사용하는 경우 587, TLS를 사용하는 경우 465입니다." + }, + "smtpSecure": { + "label": "처음부터 TLS를 사용하세요", + "description": "포트 465에 대해서는 활성화하십시오. 포트 587은 자동으로 TLS로 업그레이드되므로 비활성화 상태로 두십시오." + }, + "smtpUser": { + "label": "SMTP 사용자 이름", + "description": "서버에 로그인이 필요하지 않은 경우 비워 두십시오." + }, + "smtpPassword": { + "label": "SMTP 비밀번호", + "description": "암호화되어 저장됩니다." + }, + "smtpFrom": { + "label": "발신 주소", + "description": "발신자 알림은 다음에서 옵니다.", + "placeholder": "터믹스 " + } + }, + "user": { + "popups": { + "label": "알림 팝업", + "description": "Termix를 사용하는 동안 어떤 새로운 알림이 뜨는지 확인하세요. 모든 알림은 받은 편지함에 표시됩니다.", + "all": "모든 알림", + "warning": "경고 및 중요 사항", + "critical": "중요 정보만", + "off": "전체 해제" + } + } + }, + "sections": { + "inbox": "받은편지함", + "channels": "채널", + "rules": "배송 규칙" + }, + "severity": { + "info": "정보", + "success": "성공", + "warning": "경고", + "critical": "비판적인" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "열기", + "view": "보기", + "unread": "읽히지 않는", + "deliveryFailed_one": "{{count}} 채널 실패", + "deliveryFailed_other": "{{count}} 채널이 실패했습니다", + "markRead": "읽음으로 표시", + "markUnread": "읽지 않음으로 표시", + "markAllRead": "모두 읽음으로 표시", + "delete": "삭제", + "clearRead": "읽음 알림 삭제", + "cleared_one": "삭제됨 {{count}} 알림", + "cleared_other": "삭제된 {{count}} 알림", + "filterAll": "모두", + "filterUnread": "읽히지 않는", + "anySeverity": "심각도와 관계없이", + "anySource": "어떤 출처든", + "openAll": "탭에서 열기", + "empty": "아직 알림이 없습니다.", + "emptyUnread": "이제 모든 내용을 따라잡으셨군요.", + "loadMore": "더 보기" + }, + "channels": { + "intro": "채널은 알림이 Termix 외부로 전달될 수 있는 경로입니다. 전달 규칙은 어떤 알림이 이러한 채널을 사용할지 결정합니다.", + "add": "채널 추가", + "edit": "채널 편집", + "test": "테스트를 보내세요", + "testSent": "테스트 알림이 전송되었습니다.", + "testFailed": "테스트 실패: {{error}}", + "deleteConfirm": "채널 \"{{name}} \"을 삭제하시겠습니까?", + "deleted": "채널이 삭제되었습니다", + "empty": "아직 채널이 없습니다.", + "enabled": "사용", + "needsSave": "이 채널은 전송하기 전에 다시 열고 저장해야 합니다.", + "name": "이름", + "nameRequired": "이름은 필수입니다", + "type": "유형", + "types": { + "webhook": "웹훅", + "ntfy": "ntfy", + "discord": "Discord", + "email": "이메일" + }, + "emailUnavailable": "이메일을 보내려면 SMTP 서버가 필요하며, 관리자는 알림 설정에서 이를 설정합니다.", + "webhookUrl": "URL", + "webhookHint": "모든 알림에 대한 JSON 본문을 가져옵니다.", + "method": "방법", + "headers": "헤더", + "headersHint": "이름: 값 형식으로 한 줄에 하나씩 입력합니다.", + "ntfyServer": "서버 URL", + "ntfyTopic": "토픽", + "ntfyToken": "액세스 토큰(선택 사항)", + "discordUrl": "디스코드 웹훅 URL", + "discordHint": "디스코드 채널 설정의 '통합' 메뉴에서 확인할 수 있습니다.", + "discordUsername": "표시 이름 (선택 사항)", + "discordAvatar": "아바타 URL (선택 사항)", + "emailTo": "보내기", + "emailHint": "여러 주소를 입력할 경우 쉼표로 구분하세요.", + "privateNetwork": "사설 네트워크 주소를 허용합니다", + "privateNetworkHint": "관리자가 개인 엔드포인트 목록에 허용한 호스트에서만 작동합니다." + }, + "rules": { + "intro": "전송 규칙은 일치하는 알림을 채널로 보냅니다. 알림은 항상 받은 편지함에 보관됩니다.", + "add": "규칙 추가", + "edit": "규칙 편집", + "empty": "아직 규칙이 설정되지 않아 알림은 받은 편지함에만 표시됩니다.", + "needChannel": "먼저 채널을 추가하세요.", + "enabled": "사용", + "name": "이름", + "nameRequired": "이름은 필수입니다", + "match": "보낼 알림", + "matchHint": "*모든 것을 위한 자동화.* 자동화를 통한 모든 것, 또는 정확히 한 가지 유형.", + "minSeverity": "적어도", + "channels": "보내기", + "channelRequired": "채널 하나 이상을 선택하세요", + "deleteConfirm": "규칙 \"{{name}} \"을 삭제하시겠습니까?", + "everything": "모든 것", + "summary": "{{match}}, {{severity}} 이상, {{channels}}까지" + }, + "actions": { + "cancel": "취소", + "save": "저장", + "saving": "저장 중...", + "delete": "삭제" + }, + "widget": { + "name": "알림 피드", + "description": "최신 알림과 읽음 표시 기능을 간편하게 이용하세요.", + "maxItems": "최대 항목", + "showRead": "읽음 알림 표시", + "allClear": "모두 정상", + "loading": "로딩 중..." + } +} diff --git a/plugins/alerts/locales/translated/nl_NL.json b/plugins/alerts/locales/translated/nl_NL.json new file mode 100644 index 000000000..c8ae3775f --- /dev/null +++ b/plugins/alerts/locales/translated/nl_NL.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Waarschuwingen" + }, + "permissions": { + "use": { + "title": "Gebruik waarschuwingen", + "description": "Ontvang meldingen in je inbox en deel ze via je eigen kanalen." + } + }, + "onboarding": { + "feature": "Waarschuwingen", + "featureDesc": "Alle meldingen in één inbox, die je desgewenst kunt doorsturen naar Discord, ntfy, e-mail of een webhook." + }, + "settings": { + "group": { + "general": "Algemeen", + "email": "E-mail" + }, + "admin": { + "announcements": { + "label": "Termix-aankondigingen", + "description": "Toon nieuws van het Termix-team, zoals beveiligingsmeldingen en releases, in ieders inbox." + }, + "retentionDays": { + "label": "Houd meldingen aan voor (dagen)", + "description": "Oudere meldingen worden uit alle inboxen verwijderd." + }, + "smtpHost": { + "label": "SMTP-server", + "description": "Nodig voor e-mailkanalen. Laat dit veld leeg om e-mail uit te schakelen.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "SMTP-poort", + "description": "Meestal poort 587 met STARTTLS of 465 met TLS." + }, + "smtpSecure": { + "label": "Gebruik TLS vanaf het begin.", + "description": "Schakel poort 465 in. Laat deze uitgeschakeld voor poort 587, die automatisch overschakelt naar TLS." + }, + "smtpUser": { + "label": "SMTP-gebruikersnaam", + "description": "Laat dit veld leeg als er geen inloggegevens nodig zijn voor de server." + }, + "smtpPassword": { + "label": "SMTP-wachtwoord", + "description": "Versleuteld opgeslagen." + }, + "smtpFrom": { + "label": "Van adres", + "description": "De afzenderwaarschuwingen zijn afkomstig van.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "Waarschuwingspop-ups", + "description": "Welke nieuwe meldingen verschijnen er tijdens het gebruik van Termix? Ze komen altijd in je inbox terecht.", + "all": "Alle meldingen", + "warning": "Waarschuwingen en kritieke", + "critical": "Alleen kritisch", + "off": "Geen" + } + } + }, + "sections": { + "inbox": "Inbox", + "channels": "Kanalen", + "rules": "Leveringsregels" + }, + "severity": { + "info": "Informatie", + "success": "Succes", + "warning": "Waarschuwing", + "critical": "Kritisch" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "Open", + "view": "Weergave", + "unread": "Ongelezen", + "deliveryFailed_one": "{{count}} kanaal mislukt", + "deliveryFailed_other": "{{count}} kanalen mislukt", + "markRead": "Markeer als gelezen", + "markUnread": "Markeer als ongelezen", + "markAllRead": "Markeer alles als gelezen", + "delete": "Verwijderen", + "clearRead": "Leeswaarschuwingen verwijderen", + "cleared_one": "Verwijderde {{count}} melding", + "cleared_other": "Verwijderde {{count}} -waarschuwingen", + "filterAll": "Alle", + "filterUnread": "Ongelezen", + "anySeverity": "Elke ernst", + "anySource": "Elke bron", + "openAll": "Openen in een tabblad", + "empty": "Nog geen meldingen.", + "emptyUnread": "Je bent helemaal bij.", + "loadMore": "Meer laden" + }, + "channels": { + "intro": "Kanalen zijn de plekken waar meldingen buiten Termix naartoe kunnen worden gestuurd. Leveringsregels bepalen welke meldingen via deze kanalen worden verzonden.", + "add": "Voeg kanaal toe", + "edit": "Bewerk het kanaal", + "test": "Stuur een test", + "testSent": "Testwaarschuwing verzonden", + "testFailed": "Test mislukt: {{error}}", + "deleteConfirm": "Verwijder het kanaal \"{{name}}\"?", + "deleted": "Kanaal verwijderd", + "empty": "Nog geen kanalen.", + "enabled": "Ingeschakeld", + "needsSave": "Dit kanaal moet opnieuw worden geopend en opgeslagen voordat er berichten kunnen worden verzonden.", + "name": "Naam", + "nameRequired": "Naam is verplicht", + "type": "Type", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Meningsverschil", + "email": "E-mail" + }, + "emailUnavailable": "Voor e-mail is een SMTP-server nodig, die een beheerder instelt in de waarschuwingsinstellingen.", + "webhookUrl": "URL", + "webhookHint": "Ontvangt een JSON-body voor elke melding.", + "method": "Methode", + "headers": "Kopteksten", + "headersHint": "Eén per regel, bijvoorbeeld: Naam: waarde.", + "ntfyServer": "Server-URL", + "ntfyTopic": "Onderwerp", + "ntfyToken": "Toegangstoken (optioneel)", + "discordUrl": "Discord webhook-URL", + "discordHint": "Via de kanaalinstellingen in Discord, onder Integraties.", + "discordUsername": "Weergavenaam (optioneel)", + "discordAvatar": "Avatar-URL (optioneel)", + "emailTo": "Verzenden naar", + "emailHint": "Scheid meerdere adressen met komma's.", + "privateNetwork": "Sta een privé-netwerkadres toe", + "privateNetworkHint": "Werkt alleen voor hosts die een beheerder toestaat in de lijst met privé-eindpunten." + }, + "rules": { + "intro": "Een verzendregel stuurt overeenkomende meldingen naar uw kanalen. De meldingen blijven ook altijd in uw inbox staan.", + "add": "Regel toevoegen", + "edit": "Regel bewerken", + "empty": "Er zijn nog geen regels, dus meldingen verschijnen alleen in de inbox.", + "needChannel": "Voeg eerst een kanaal toe.", + "enabled": "Ingeschakeld", + "name": "Naam", + "nameRequired": "Naam is verplicht", + "match": "Waarschuwingen om te verzenden", + "matchHint": "* voor alles, automatiseringen.* voor alles wat met automatiseringen te maken heeft, of één specifiek type.", + "minSeverity": "Ten minste", + "channels": "Verzenden naar", + "channelRequired": "Kies minstens één kanaal", + "deleteConfirm": "Verwijder de regel \"{{name}}\"?", + "everything": "Alles", + "summary": "{{match}}, {{severity}} of hoger, tot {{channels}}" + }, + "actions": { + "cancel": "Annuleren", + "save": "Redden", + "saving": "Besparing...", + "delete": "Verwijderen" + }, + "widget": { + "name": "Waarschuwingsfeed", + "description": "Je meest recente meldingen, met een snelle manier om ze als gelezen te markeren.", + "maxItems": "Max items", + "showRead": "Leeswaarschuwingen weergeven", + "allClear": "Alles in orde", + "loading": "Laden..." + } +} diff --git a/plugins/alerts/locales/translated/no_NO.json b/plugins/alerts/locales/translated/no_NO.json new file mode 100644 index 000000000..5e9f5305f --- /dev/null +++ b/plugins/alerts/locales/translated/no_NO.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Alerts" + }, + "permissions": { + "use": { + "title": "Use alerts", + "description": "Get alerts in the inbox and send them to your own channels." + } + }, + "onboarding": { + "feature": "Alerts", + "featureDesc": "Every alert in one inbox, sent on to Discord, ntfy, email or a webhook if you want." + }, + "settings": { + "group": { + "general": "Generelt", + "email": "E-post" + }, + "admin": { + "announcements": { + "label": "Termix announcements", + "description": "Show news from the Termix team, like security notices and releases, in everyone's inbox." + }, + "retentionDays": { + "label": "Keep alerts for (days)", + "description": "Older alerts are removed from every inbox." + }, + "smtpHost": { + "label": "SMTP server", + "description": "Needed for email channels. Leave empty to turn email off.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "SMTP port", + "description": "Usually 587 with STARTTLS or 465 with TLS." + }, + "smtpSecure": { + "label": "Use TLS from the start", + "description": "Turn on for port 465. Leave off for 587, which upgrades to TLS on its own." + }, + "smtpUser": { + "label": "SMTP username", + "description": "Leave empty if the server does not need a login." + }, + "smtpPassword": { + "label": "SMTP password", + "description": "Stored encrypted." + }, + "smtpFrom": { + "label": "From address", + "description": "The sender alerts come from.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "Alert popups", + "description": "Which new alerts pop up while you use Termix. They always land in the inbox.", + "all": "All alerts", + "warning": "Warnings and critical", + "critical": "Critical only", + "off": "Ingen" + } + } + }, + "sections": { + "inbox": "Inbox", + "channels": "Channels", + "rules": "Delivery rules" + }, + "severity": { + "info": "Info", + "success": "Suksess", + "warning": "Advarsel", + "critical": "Critical" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "Open", + "view": "View", + "unread": "Unread", + "deliveryFailed_one": "{{count}} channel failed", + "deliveryFailed_other": "{{count}} channels failed", + "markRead": "Mark as read", + "markUnread": "Mark as unread", + "markAllRead": "Mark all as read", + "delete": "Slett", + "clearRead": "Delete read alerts", + "cleared_one": "Deleted {{count}} alert", + "cleared_other": "Deleted {{count}} alerts", + "filterAll": "All", + "filterUnread": "Unread", + "anySeverity": "Any severity", + "anySource": "Any source", + "openAll": "Open in a tab", + "empty": "No alerts yet.", + "emptyUnread": "You are all caught up.", + "loadMore": "Load more" + }, + "channels": { + "intro": "Channels are where alerts can go outside Termix. Delivery rules pick which alerts use them.", + "add": "Add channel", + "edit": "Edit channel", + "test": "Send a test", + "testSent": "Test alert sent", + "testFailed": "Test failed: {{error}}", + "deleteConfirm": "Delete the channel \"{{name}}\"?", + "deleted": "Channel deleted", + "empty": "No channels yet.", + "enabled": "Aktivert", + "needsSave": "This channel needs to be opened and saved again before it can send.", + "name": "Navn", + "nameRequired": "Navn er påkrevd", + "type": "Type", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Discord", + "email": "E-post" + }, + "emailUnavailable": "Email needs an SMTP server, which an admin sets up in the Alerts settings.", + "webhookUrl": "URL", + "webhookHint": "Gets a JSON body for every alert.", + "method": "Method", + "headers": "Headers", + "headersHint": "One per line, like Name: value.", + "ntfyServer": "Server-URL", + "ntfyTopic": "Topic", + "ntfyToken": "Access token (optional)", + "discordUrl": "Discord webhook URL", + "discordHint": "From the channel's settings in Discord, under Integrations.", + "discordUsername": "Display name (optional)", + "discordAvatar": "Avatar URL (optional)", + "emailTo": "Send to", + "emailHint": "Separate more than one address with commas.", + "privateNetwork": "Allow a private network address", + "privateNetworkHint": "Only works for hosts an admin allows in the private endpoint list." + }, + "rules": { + "intro": "A delivery rule sends matching alerts to your channels. Alerts always stay in the inbox too.", + "add": "Add rule", + "edit": "Edit rule", + "empty": "No rules yet, so alerts only show up in the inbox.", + "needChannel": "Add a channel first.", + "enabled": "Aktivert", + "name": "Navn", + "nameRequired": "Navn er påkrevd", + "match": "Alerts to send", + "matchHint": "* for everything, automations.* for everything from automations, or one exact kind.", + "minSeverity": "At least", + "channels": "Send to", + "channelRequired": "Pick at least one channel", + "deleteConfirm": "Delete the rule \"{{name}}\"?", + "everything": "Everything", + "summary": "{{match}}, {{severity}} or higher, to {{channels}}" + }, + "actions": { + "cancel": "Avbryt", + "save": "Lagre", + "saving": "Lagrer...", + "delete": "Slett" + }, + "widget": { + "name": "Alert Feed", + "description": "Your latest alerts, with a quick way to mark them read", + "maxItems": "Max items", + "showRead": "Show read alerts", + "allClear": "All clear", + "loading": "Laster..." + } +} diff --git a/plugins/alerts/locales/translated/pl_PL.json b/plugins/alerts/locales/translated/pl_PL.json new file mode 100644 index 000000000..c1bbf8b49 --- /dev/null +++ b/plugins/alerts/locales/translated/pl_PL.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Alerty" + }, + "permissions": { + "use": { + "title": "Use alerts", + "description": "Get alerts in the inbox and send them to your own channels." + } + }, + "onboarding": { + "feature": "Alerty", + "featureDesc": "Every alert in one inbox, sent on to Discord, ntfy, email or a webhook if you want." + }, + "settings": { + "group": { + "general": "Ogólne", + "email": "E-mail" + }, + "admin": { + "announcements": { + "label": "Termix announcements", + "description": "Show news from the Termix team, like security notices and releases, in everyone's inbox." + }, + "retentionDays": { + "label": "Keep alerts for (days)", + "description": "Older alerts are removed from every inbox." + }, + "smtpHost": { + "label": "SMTP server", + "description": "Needed for email channels. Leave empty to turn email off.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "SMTP port", + "description": "Usually 587 with STARTTLS or 465 with TLS." + }, + "smtpSecure": { + "label": "Use TLS from the start", + "description": "Turn on for port 465. Leave off for 587, which upgrades to TLS on its own." + }, + "smtpUser": { + "label": "SMTP username", + "description": "Leave empty if the server does not need a login." + }, + "smtpPassword": { + "label": "SMTP password", + "description": "Stored encrypted." + }, + "smtpFrom": { + "label": "From address", + "description": "The sender alerts come from.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "Alert popups", + "description": "Which new alerts pop up while you use Termix. They always land in the inbox.", + "all": "All alerts", + "warning": "Warnings and critical", + "critical": "Critical only", + "off": "Żaden" + } + } + }, + "sections": { + "inbox": "Inbox", + "channels": "Kanały", + "rules": "Delivery rules" + }, + "severity": { + "info": "Informacje", + "success": "Powodzenie", + "warning": "Ostrzeżenie", + "critical": "Critical" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "Otwórz", + "view": "Podgląd", + "unread": "Unread", + "deliveryFailed_one": "{{count}} channel failed", + "deliveryFailed_other": "{{count}} channels failed", + "markRead": "Mark as read", + "markUnread": "Mark as unread", + "markAllRead": "Mark all as read", + "delete": "Usuń", + "clearRead": "Delete read alerts", + "cleared_one": "Deleted {{count}} alert", + "cleared_other": "Deleted {{count}} alerts", + "filterAll": "Wszystkie", + "filterUnread": "Unread", + "anySeverity": "Any severity", + "anySource": "Any source", + "openAll": "Open in a tab", + "empty": "No alerts yet.", + "emptyUnread": "You are all caught up.", + "loadMore": "Load more" + }, + "channels": { + "intro": "Channels are where alerts can go outside Termix. Delivery rules pick which alerts use them.", + "add": "Add channel", + "edit": "Edit channel", + "test": "Send a test", + "testSent": "Test alert sent", + "testFailed": "Test failed: {{error}}", + "deleteConfirm": "Delete the channel \"{{name}}\"?", + "deleted": "Kanał usunięty", + "empty": "No channels yet.", + "enabled": "Włączona", + "needsSave": "This channel needs to be opened and saved again before it can send.", + "name": "Nazwa", + "nameRequired": "Nazwa jest wymagana", + "type": "Typ", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Discord", + "email": "E-mail" + }, + "emailUnavailable": "Email needs an SMTP server, which an admin sets up in the Alerts settings.", + "webhookUrl": "Adres URL", + "webhookHint": "Gets a JSON body for every alert.", + "method": "Metoda", + "headers": "Headers", + "headersHint": "One per line, like Name: value.", + "ntfyServer": "Adres URL serwera", + "ntfyTopic": "Temat", + "ntfyToken": "Access token (optional)", + "discordUrl": "Discord webhook URL", + "discordHint": "From the channel's settings in Discord, under Integrations.", + "discordUsername": "Display name (optional)", + "discordAvatar": "Avatar URL (optional)", + "emailTo": "Send to", + "emailHint": "Separate more than one address with commas.", + "privateNetwork": "Allow a private network address", + "privateNetworkHint": "Only works for hosts an admin allows in the private endpoint list." + }, + "rules": { + "intro": "A delivery rule sends matching alerts to your channels. Alerts always stay in the inbox too.", + "add": "Add rule", + "edit": "Edit rule", + "empty": "No rules yet, so alerts only show up in the inbox.", + "needChannel": "Add a channel first.", + "enabled": "Włączona", + "name": "Nazwa", + "nameRequired": "Nazwa jest wymagana", + "match": "Alerts to send", + "matchHint": "* for everything, automations.* for everything from automations, or one exact kind.", + "minSeverity": "At least", + "channels": "Send to", + "channelRequired": "Pick at least one channel", + "deleteConfirm": "Delete the rule \"{{name}}\"?", + "everything": "Everything", + "summary": "{{match}}, {{severity}} or higher, to {{channels}}" + }, + "actions": { + "cancel": "Anuluj", + "save": "Zapisz", + "saving": "Zapisywanie...", + "delete": "Usuń" + }, + "widget": { + "name": "Kanał alertów", + "description": "Your latest alerts, with a quick way to mark them read", + "maxItems": "Max items", + "showRead": "Show read alerts", + "allClear": "Bez alertów", + "loading": "Ładowanie..." + } +} diff --git a/plugins/alerts/locales/translated/pt_BR.json b/plugins/alerts/locales/translated/pt_BR.json new file mode 100644 index 000000000..0afaab20a --- /dev/null +++ b/plugins/alerts/locales/translated/pt_BR.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Alerts" + }, + "permissions": { + "use": { + "title": "Use alerts", + "description": "Get alerts in the inbox and send them to your own channels." + } + }, + "onboarding": { + "feature": "Alerts", + "featureDesc": "Every alert in one inbox, sent on to Discord, ntfy, email or a webhook if you want." + }, + "settings": { + "group": { + "general": "Geral", + "email": "Email" + }, + "admin": { + "announcements": { + "label": "Termix announcements", + "description": "Show news from the Termix team, like security notices and releases, in everyone's inbox." + }, + "retentionDays": { + "label": "Keep alerts for (days)", + "description": "Older alerts are removed from every inbox." + }, + "smtpHost": { + "label": "SMTP server", + "description": "Needed for email channels. Leave empty to turn email off.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "SMTP port", + "description": "Usually 587 with STARTTLS or 465 with TLS." + }, + "smtpSecure": { + "label": "Use TLS from the start", + "description": "Turn on for port 465. Leave off for 587, which upgrades to TLS on its own." + }, + "smtpUser": { + "label": "SMTP username", + "description": "Leave empty if the server does not need a login." + }, + "smtpPassword": { + "label": "SMTP password", + "description": "Stored encrypted." + }, + "smtpFrom": { + "label": "From address", + "description": "The sender alerts come from.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "Alert popups", + "description": "Which new alerts pop up while you use Termix. They always land in the inbox.", + "all": "All alerts", + "warning": "Warnings and critical", + "critical": "Critical only", + "off": "Nenhum" + } + } + }, + "sections": { + "inbox": "Inbox", + "channels": "Channels", + "rules": "Delivery rules" + }, + "severity": { + "info": "Info", + "success": "Success", + "warning": "Atenção", + "critical": "Critical" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "Open", + "view": "View", + "unread": "Unread", + "deliveryFailed_one": "{{count}} channel failed", + "deliveryFailed_other": "{{count}} channels failed", + "markRead": "Mark as read", + "markUnread": "Mark as unread", + "markAllRead": "Mark all as read", + "delete": "Apagar", + "clearRead": "Delete read alerts", + "cleared_one": "Deleted {{count}} alert", + "cleared_other": "Deleted {{count}} alerts", + "filterAll": "All", + "filterUnread": "Unread", + "anySeverity": "Any severity", + "anySource": "Any source", + "openAll": "Open in a tab", + "empty": "No alerts yet.", + "emptyUnread": "You are all caught up.", + "loadMore": "Load more" + }, + "channels": { + "intro": "Channels are where alerts can go outside Termix. Delivery rules pick which alerts use them.", + "add": "Add channel", + "edit": "Edit channel", + "test": "Send a test", + "testSent": "Test alert sent", + "testFailed": "Test failed: {{error}}", + "deleteConfirm": "Delete the channel \"{{name}}\"?", + "deleted": "Channel deleted", + "empty": "No channels yet.", + "enabled": "Enabled", + "needsSave": "This channel needs to be opened and saved again before it can send.", + "name": "Name", + "nameRequired": "Name is required", + "type": "Tipo", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Discord", + "email": "Email" + }, + "emailUnavailable": "Email needs an SMTP server, which an admin sets up in the Alerts settings.", + "webhookUrl": "URL", + "webhookHint": "Gets a JSON body for every alert.", + "method": "Method", + "headers": "Headers", + "headersHint": "One per line, like Name: value.", + "ntfyServer": "URL do Servidor", + "ntfyTopic": "Topic", + "ntfyToken": "Access token (optional)", + "discordUrl": "Discord webhook URL", + "discordHint": "From the channel's settings in Discord, under Integrations.", + "discordUsername": "Display name (optional)", + "discordAvatar": "Avatar URL (optional)", + "emailTo": "Send to", + "emailHint": "Separate more than one address with commas.", + "privateNetwork": "Allow a private network address", + "privateNetworkHint": "Only works for hosts an admin allows in the private endpoint list." + }, + "rules": { + "intro": "A delivery rule sends matching alerts to your channels. Alerts always stay in the inbox too.", + "add": "Add rule", + "edit": "Edit rule", + "empty": "No rules yet, so alerts only show up in the inbox.", + "needChannel": "Add a channel first.", + "enabled": "Enabled", + "name": "Name", + "nameRequired": "Name is required", + "match": "Alerts to send", + "matchHint": "* for everything, automations.* for everything from automations, or one exact kind.", + "minSeverity": "At least", + "channels": "Send to", + "channelRequired": "Pick at least one channel", + "deleteConfirm": "Delete the rule \"{{name}}\"?", + "everything": "Everything", + "summary": "{{match}}, {{severity}} or higher, to {{channels}}" + }, + "actions": { + "cancel": "Cancelar", + "save": "Salvar", + "saving": "Salvando...", + "delete": "Apagar" + }, + "widget": { + "name": "Alert Feed", + "description": "Your latest alerts, with a quick way to mark them read", + "maxItems": "Max items", + "showRead": "Show read alerts", + "allClear": "All clear", + "loading": "Carregando..." + } +} diff --git a/plugins/alerts/locales/translated/pt_PT.json b/plugins/alerts/locales/translated/pt_PT.json new file mode 100644 index 000000000..e90d1bf97 --- /dev/null +++ b/plugins/alerts/locales/translated/pt_PT.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Alertas" + }, + "permissions": { + "use": { + "title": "Use alerts", + "description": "Get alerts in the inbox and send them to your own channels." + } + }, + "onboarding": { + "feature": "Alertas", + "featureDesc": "Every alert in one inbox, sent on to Discord, ntfy, email or a webhook if you want." + }, + "settings": { + "group": { + "general": "Geral", + "email": "E-mail" + }, + "admin": { + "announcements": { + "label": "Termix announcements", + "description": "Show news from the Termix team, like security notices and releases, in everyone's inbox." + }, + "retentionDays": { + "label": "Keep alerts for (days)", + "description": "Older alerts are removed from every inbox." + }, + "smtpHost": { + "label": "SMTP server", + "description": "Needed for email channels. Leave empty to turn email off.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "SMTP port", + "description": "Usually 587 with STARTTLS or 465 with TLS." + }, + "smtpSecure": { + "label": "Use TLS from the start", + "description": "Turn on for port 465. Leave off for 587, which upgrades to TLS on its own." + }, + "smtpUser": { + "label": "SMTP username", + "description": "Leave empty if the server does not need a login." + }, + "smtpPassword": { + "label": "SMTP password", + "description": "Stored encrypted." + }, + "smtpFrom": { + "label": "From address", + "description": "The sender alerts come from.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "Alert popups", + "description": "Which new alerts pop up while you use Termix. They always land in the inbox.", + "all": "All alerts", + "warning": "Warnings and critical", + "critical": "Critical only", + "off": "Nenhuma" + } + } + }, + "sections": { + "inbox": "Inbox", + "channels": "Canais", + "rules": "Delivery rules" + }, + "severity": { + "info": "Info", + "success": "Sucesso", + "warning": "Aviso", + "critical": "Critical" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "Abrir", + "view": "Ver", + "unread": "Unread", + "deliveryFailed_one": "{{count}} channel failed", + "deliveryFailed_other": "{{count}} channels failed", + "markRead": "Mark as read", + "markUnread": "Mark as unread", + "markAllRead": "Mark all as read", + "delete": "Eliminar", + "clearRead": "Delete read alerts", + "cleared_one": "Deleted {{count}} alert", + "cleared_other": "Deleted {{count}} alerts", + "filterAll": "Todas", + "filterUnread": "Unread", + "anySeverity": "Any severity", + "anySource": "Any source", + "openAll": "Open in a tab", + "empty": "No alerts yet.", + "emptyUnread": "You are all caught up.", + "loadMore": "Load more" + }, + "channels": { + "intro": "Channels are where alerts can go outside Termix. Delivery rules pick which alerts use them.", + "add": "Add channel", + "edit": "Edit channel", + "test": "Send a test", + "testSent": "Test alert sent", + "testFailed": "Test failed: {{error}}", + "deleteConfirm": "Delete the channel \"{{name}}\"?", + "deleted": "Channel deleted", + "empty": "No channels yet.", + "enabled": "Ativado", + "needsSave": "This channel needs to be opened and saved again before it can send.", + "name": "Nome", + "nameRequired": "O nome é obrigatório", + "type": "Tipo", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Discord", + "email": "E-mail" + }, + "emailUnavailable": "Email needs an SMTP server, which an admin sets up in the Alerts settings.", + "webhookUrl": "URL", + "webhookHint": "Gets a JSON body for every alert.", + "method": "Method", + "headers": "Headers", + "headersHint": "One per line, like Name: value.", + "ntfyServer": "URL do servidor", + "ntfyTopic": "Tópico", + "ntfyToken": "Access token (optional)", + "discordUrl": "Discord webhook URL", + "discordHint": "From the channel's settings in Discord, under Integrations.", + "discordUsername": "Display name (optional)", + "discordAvatar": "Avatar URL (optional)", + "emailTo": "Send to", + "emailHint": "Separate more than one address with commas.", + "privateNetwork": "Allow a private network address", + "privateNetworkHint": "Only works for hosts an admin allows in the private endpoint list." + }, + "rules": { + "intro": "A delivery rule sends matching alerts to your channels. Alerts always stay in the inbox too.", + "add": "Add rule", + "edit": "Edit rule", + "empty": "No rules yet, so alerts only show up in the inbox.", + "needChannel": "Add a channel first.", + "enabled": "Ativado", + "name": "Nome", + "nameRequired": "O nome é obrigatório", + "match": "Alerts to send", + "matchHint": "* for everything, automations.* for everything from automations, or one exact kind.", + "minSeverity": "At least", + "channels": "Send to", + "channelRequired": "Pick at least one channel", + "deleteConfirm": "Delete the rule \"{{name}}\"?", + "everything": "Everything", + "summary": "{{match}}, {{severity}} or higher, to {{channels}}" + }, + "actions": { + "cancel": "Cancelar", + "save": "Guardar", + "saving": "A guardar...", + "delete": "Eliminar" + }, + "widget": { + "name": "Feed de alertas", + "description": "Your latest alerts, with a quick way to mark them read", + "maxItems": "Max items", + "showRead": "Show read alerts", + "allClear": "Tudo em ordem", + "loading": "A carregar..." + } +} diff --git a/plugins/alerts/locales/translated/ro_RO.json b/plugins/alerts/locales/translated/ro_RO.json new file mode 100644 index 000000000..1d86d245e --- /dev/null +++ b/plugins/alerts/locales/translated/ro_RO.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Alerte" + }, + "permissions": { + "use": { + "title": "Utilizați alertele", + "description": "Primește alerte în căsuța poștală și trimite-le către propriile canale." + } + }, + "onboarding": { + "feature": "Alerte", + "featureDesc": "Fiecare alertă într-o singură căsuță poștală, trimisă pe Discord, ntfy, e-mail sau un webhook, dacă dorești." + }, + "settings": { + "group": { + "general": "General", + "email": "E-mail" + }, + "admin": { + "announcements": { + "label": "Anunțuri Termix", + "description": "Afișează știri de la echipa Termix, cum ar fi notificări de securitate și lansări, în căsuța poștală a tuturor." + }, + "retentionDays": { + "label": "Păstrați alertele timp de (zile)", + "description": "Alertele mai vechi sunt eliminate din fiecare inbox." + }, + "smtpHost": { + "label": "Server SMTP", + "description": "Necesar pentru canalele de e-mail. Lăsați gol pentru a dezactiva e-mailul.", + "placeholder": "smtp.exemplu.com" + }, + "smtpPort": { + "label": "Port SMTP", + "description": "De obicei 587 cu STARTTLS sau 465 cu TLS." + }, + "smtpSecure": { + "label": "Folosește TLS de la început", + "description": "Activați portul 465. Lăsați dezactivat portul 587, care face upgrade la TLS de la sine." + }, + "smtpUser": { + "label": "Nume de utilizator SMTP", + "description": "Lăsați câmpul gol dacă serverul nu necesită date de autentificare." + }, + "smtpPassword": { + "label": "Parolă SMTP", + "description": "Stocat criptat." + }, + "smtpFrom": { + "label": "Adresă de la", + "description": "Alertele expeditorului provin de la.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "Ferestre pop-up de alertă", + "description": "Ce alerte noi apar în timp ce folosești Termix. Acestea ajung întotdeauna în inbox.", + "all": "Toate alertele", + "warning": "Avertismente și aspecte critice", + "critical": "Numai critice", + "off": "Nici unul" + } + } + }, + "sections": { + "inbox": "Inbox", + "channels": "Canale", + "rules": "Reguli de livrare" + }, + "severity": { + "info": "Informații", + "success": "Succes", + "warning": "Avertizare", + "critical": "Critic" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "Deschide", + "view": "Vedere", + "unread": "Necitit", + "deliveryFailed_one": "Canalul {{count}} a eșuat", + "deliveryFailed_other": "{{count}} canale au eșuat", + "markRead": "Marchează ca citit", + "markUnread": "Marchează ca necitit", + "markAllRead": "Marchează toate ca citite", + "delete": "Şterge", + "clearRead": "Ștergeți alertele de citire", + "cleared_one": "Alertă {{count}} ștearsă", + "cleared_other": "Alerte {{count}} șterse", + "filterAll": "Toate", + "filterUnread": "Necitit", + "anySeverity": "Orice severitate", + "anySource": "Orice sursă", + "openAll": "Deschide într-o filă", + "empty": "Încă nu există alerte.", + "emptyUnread": "Sunteți cu toții prinși la zi.", + "loadMore": "Încărcați mai multe" + }, + "channels": { + "intro": "Canalele sunt locurile prin care alertele pot fi trimise în afara Termix. Regulile de livrare aleg alertele care le utilizează.", + "add": "Adăugați canal", + "edit": "Editați canalul", + "test": "Trimiteți un test", + "testSent": "Alertă de test trimisă", + "testFailed": "Testul a eșuat: {{error}}", + "deleteConfirm": "Ștergeți canalul „{{name}}”?", + "deleted": "Canalul a fost șters", + "empty": "Încă nu există canale.", + "enabled": "Activat", + "needsSave": "Acest canal trebuie deschis și salvat din nou înainte de a putea trimite.", + "name": "Nume", + "nameRequired": "Numele este obligatoriu", + "type": "Tip", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Discordie", + "email": "E-mail" + }, + "emailUnavailable": "E-mailul necesită un server SMTP, pe care un administrator îl configurează în setările Alerte.", + "webhookUrl": "URL-ul", + "webhookHint": "Obține un corp JSON pentru fiecare alertă.", + "method": "Metodă", + "headers": "Anteturi", + "headersHint": "Unul pe linie, cum ar fi Nume: valoare.", + "ntfyServer": "URL-ul serverului", + "ntfyTopic": "Subiect", + "ntfyToken": "Token de acces (opțional)", + "discordUrl": "Adresa URL a webhook-ului Discord", + "discordHint": "Din setările canalului din Discord, la Integrări.", + "discordUsername": "Nume afișat (opțional)", + "discordAvatar": "URL-ul avatarului (opțional)", + "emailTo": "Trimiteți către", + "emailHint": "Separați mai multe adrese prin virgule.", + "privateNetwork": "Permiteți o adresă de rețea privată", + "privateNetworkHint": "Funcționează doar pentru gazdele permise de un administrator în lista de puncte finale private." + }, + "rules": { + "intro": "O regulă de livrare trimite alerte corespunzătoare către canalele dvs. Alertele rămân întotdeauna și în căsuța poștală.", + "add": "Adăugați o regulă", + "edit": "Editați regula", + "empty": "Încă nu există reguli, așa că alertele apar doar în inbox.", + "needChannel": "Adăugați mai întâi un canal.", + "enabled": "Activat", + "name": "Nume", + "nameRequired": "Numele este obligatoriu", + "match": "Alerte de trimis", + "matchHint": "* pentru orice, automatizări. * pentru orice, de la automatizări sau pentru un singur tip exact.", + "minSeverity": "Cel puţin", + "channels": "Trimiteți către", + "channelRequired": "Alege cel puțin un canal", + "deleteConfirm": "Ștergeți regula „{{name}}”?", + "everything": "Tot", + "summary": "{{match}}, {{severity}} sau mai mare, până la {{channels}}" + }, + "actions": { + "cancel": "Anula", + "save": "Salva", + "saving": "Economisire...", + "delete": "Şterge" + }, + "widget": { + "name": "Flux de alerte", + "description": "Cele mai recente alerte, cu o modalitate rapidă de a le marca ca fiind citite", + "maxItems": "Articole maxime", + "showRead": "Afișează alertele de citire", + "allClear": "Totul este clar", + "loading": "Încărcare..." + } +} diff --git a/plugins/alerts/locales/translated/ru_RU.json b/plugins/alerts/locales/translated/ru_RU.json new file mode 100644 index 000000000..900f0ebff --- /dev/null +++ b/plugins/alerts/locales/translated/ru_RU.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Оповещения" + }, + "permissions": { + "use": { + "title": "Use alerts", + "description": "Get alerts in the inbox and send them to your own channels." + } + }, + "onboarding": { + "feature": "Оповещения", + "featureDesc": "Every alert in one inbox, sent on to Discord, ntfy, email or a webhook if you want." + }, + "settings": { + "group": { + "general": "Общие", + "email": "Email" + }, + "admin": { + "announcements": { + "label": "Termix announcements", + "description": "Show news from the Termix team, like security notices and releases, in everyone's inbox." + }, + "retentionDays": { + "label": "Keep alerts for (days)", + "description": "Older alerts are removed from every inbox." + }, + "smtpHost": { + "label": "SMTP server", + "description": "Needed for email channels. Leave empty to turn email off.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "SMTP port", + "description": "Usually 587 with STARTTLS or 465 with TLS." + }, + "smtpSecure": { + "label": "Use TLS from the start", + "description": "Turn on for port 465. Leave off for 587, which upgrades to TLS on its own." + }, + "smtpUser": { + "label": "SMTP username", + "description": "Leave empty if the server does not need a login." + }, + "smtpPassword": { + "label": "SMTP password", + "description": "Stored encrypted." + }, + "smtpFrom": { + "label": "From address", + "description": "The sender alerts come from.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "Alert popups", + "description": "Which new alerts pop up while you use Termix. They always land in the inbox.", + "all": "All alerts", + "warning": "Warnings and critical", + "critical": "Critical only", + "off": "Ни одного" + } + } + }, + "sections": { + "inbox": "Inbox", + "channels": "Каналы", + "rules": "Delivery rules" + }, + "severity": { + "info": "Информация", + "success": "Успех", + "warning": "Предупреждение", + "critical": "Critical" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "Открыть", + "view": "Просмотр", + "unread": "Unread", + "deliveryFailed_one": "{{count}} channel failed", + "deliveryFailed_other": "{{count}} channels failed", + "markRead": "Mark as read", + "markUnread": "Mark as unread", + "markAllRead": "Mark all as read", + "delete": "Удалить", + "clearRead": "Delete read alerts", + "cleared_one": "Deleted {{count}} alert", + "cleared_other": "Deleted {{count}} alerts", + "filterAll": "Все", + "filterUnread": "Unread", + "anySeverity": "Any severity", + "anySource": "Any source", + "openAll": "Open in a tab", + "empty": "No alerts yet.", + "emptyUnread": "You are all caught up.", + "loadMore": "Load more" + }, + "channels": { + "intro": "Channels are where alerts can go outside Termix. Delivery rules pick which alerts use them.", + "add": "Add channel", + "edit": "Edit channel", + "test": "Send a test", + "testSent": "Test alert sent", + "testFailed": "Test failed: {{error}}", + "deleteConfirm": "Delete the channel \"{{name}}\"?", + "deleted": "Channel deleted", + "empty": "No channels yet.", + "enabled": "Включено", + "needsSave": "This channel needs to be opened and saved again before it can send.", + "name": "Название", + "nameRequired": "Имя обязательно", + "type": "Тип", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Discord", + "email": "Email" + }, + "emailUnavailable": "Email needs an SMTP server, which an admin sets up in the Alerts settings.", + "webhookUrl": "URL", + "webhookHint": "Gets a JSON body for every alert.", + "method": "Method", + "headers": "Headers", + "headersHint": "One per line, like Name: value.", + "ntfyServer": "URL сервера", + "ntfyTopic": "Тема", + "ntfyToken": "Access token (optional)", + "discordUrl": "Discord webhook URL", + "discordHint": "From the channel's settings in Discord, under Integrations.", + "discordUsername": "Display name (optional)", + "discordAvatar": "Avatar URL (optional)", + "emailTo": "Send to", + "emailHint": "Separate more than one address with commas.", + "privateNetwork": "Allow a private network address", + "privateNetworkHint": "Only works for hosts an admin allows in the private endpoint list." + }, + "rules": { + "intro": "A delivery rule sends matching alerts to your channels. Alerts always stay in the inbox too.", + "add": "Add rule", + "edit": "Edit rule", + "empty": "No rules yet, so alerts only show up in the inbox.", + "needChannel": "Add a channel first.", + "enabled": "Включено", + "name": "Название", + "nameRequired": "Имя обязательно", + "match": "Alerts to send", + "matchHint": "* for everything, automations.* for everything from automations, or one exact kind.", + "minSeverity": "At least", + "channels": "Send to", + "channelRequired": "Pick at least one channel", + "deleteConfirm": "Delete the rule \"{{name}}\"?", + "everything": "Everything", + "summary": "{{match}}, {{severity}} or higher, to {{channels}}" + }, + "actions": { + "cancel": "Отмена", + "save": "Сохранить", + "saving": "Сохранение…", + "delete": "Удалить" + }, + "widget": { + "name": "Лента оповещений", + "description": "Your latest alerts, with a quick way to mark them read", + "maxItems": "Max items", + "showRead": "Show read alerts", + "allClear": "Всё в порядке", + "loading": "Загрузка..." + } +} diff --git a/plugins/alerts/locales/translated/sr_SP.json b/plugins/alerts/locales/translated/sr_SP.json new file mode 100644 index 000000000..9d7514f0d --- /dev/null +++ b/plugins/alerts/locales/translated/sr_SP.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Alerts" + }, + "permissions": { + "use": { + "title": "Use alerts", + "description": "Get alerts in the inbox and send them to your own channels." + } + }, + "onboarding": { + "feature": "Alerts", + "featureDesc": "Every alert in one inbox, sent on to Discord, ntfy, email or a webhook if you want." + }, + "settings": { + "group": { + "general": "General", + "email": "Email" + }, + "admin": { + "announcements": { + "label": "Termix announcements", + "description": "Show news from the Termix team, like security notices and releases, in everyone's inbox." + }, + "retentionDays": { + "label": "Keep alerts for (days)", + "description": "Older alerts are removed from every inbox." + }, + "smtpHost": { + "label": "SMTP server", + "description": "Needed for email channels. Leave empty to turn email off.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "SMTP port", + "description": "Usually 587 with STARTTLS or 465 with TLS." + }, + "smtpSecure": { + "label": "Use TLS from the start", + "description": "Turn on for port 465. Leave off for 587, which upgrades to TLS on its own." + }, + "smtpUser": { + "label": "SMTP username", + "description": "Leave empty if the server does not need a login." + }, + "smtpPassword": { + "label": "SMTP password", + "description": "Stored encrypted." + }, + "smtpFrom": { + "label": "From address", + "description": "The sender alerts come from.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "Alert popups", + "description": "Which new alerts pop up while you use Termix. They always land in the inbox.", + "all": "All alerts", + "warning": "Warnings and critical", + "critical": "Critical only", + "off": "None" + } + } + }, + "sections": { + "inbox": "Inbox", + "channels": "Channels", + "rules": "Delivery rules" + }, + "severity": { + "info": "Info", + "success": "Success", + "warning": "Warning", + "critical": "Critical" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "Open", + "view": "View", + "unread": "Unread", + "deliveryFailed_one": "{{count}} channel failed", + "deliveryFailed_other": "{{count}} channels failed", + "markRead": "Mark as read", + "markUnread": "Mark as unread", + "markAllRead": "Mark all as read", + "delete": "Delete", + "clearRead": "Delete read alerts", + "cleared_one": "Deleted {{count}} alert", + "cleared_other": "Deleted {{count}} alerts", + "filterAll": "All", + "filterUnread": "Unread", + "anySeverity": "Any severity", + "anySource": "Any source", + "openAll": "Open in a tab", + "empty": "No alerts yet.", + "emptyUnread": "You are all caught up.", + "loadMore": "Load more" + }, + "channels": { + "intro": "Channels are where alerts can go outside Termix. Delivery rules pick which alerts use them.", + "add": "Add channel", + "edit": "Edit channel", + "test": "Send a test", + "testSent": "Test alert sent", + "testFailed": "Test failed: {{error}}", + "deleteConfirm": "Delete the channel \"{{name}}\"?", + "deleted": "Channel deleted", + "empty": "No channels yet.", + "enabled": "Enabled", + "needsSave": "This channel needs to be opened and saved again before it can send.", + "name": "Name", + "nameRequired": "Name is required", + "type": "Type", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Discord", + "email": "Email" + }, + "emailUnavailable": "Email needs an SMTP server, which an admin sets up in the Alerts settings.", + "webhookUrl": "URL", + "webhookHint": "Gets a JSON body for every alert.", + "method": "Method", + "headers": "Headers", + "headersHint": "One per line, like Name: value.", + "ntfyServer": "Server URL", + "ntfyTopic": "Topic", + "ntfyToken": "Access token (optional)", + "discordUrl": "Discord webhook URL", + "discordHint": "From the channel's settings in Discord, under Integrations.", + "discordUsername": "Display name (optional)", + "discordAvatar": "Avatar URL (optional)", + "emailTo": "Send to", + "emailHint": "Separate more than one address with commas.", + "privateNetwork": "Allow a private network address", + "privateNetworkHint": "Only works for hosts an admin allows in the private endpoint list." + }, + "rules": { + "intro": "A delivery rule sends matching alerts to your channels. Alerts always stay in the inbox too.", + "add": "Add rule", + "edit": "Edit rule", + "empty": "No rules yet, so alerts only show up in the inbox.", + "needChannel": "Add a channel first.", + "enabled": "Enabled", + "name": "Name", + "nameRequired": "Name is required", + "match": "Alerts to send", + "matchHint": "* for everything, automations.* for everything from automations, or one exact kind.", + "minSeverity": "At least", + "channels": "Send to", + "channelRequired": "Pick at least one channel", + "deleteConfirm": "Delete the rule \"{{name}}\"?", + "everything": "Everything", + "summary": "{{match}}, {{severity}} or higher, to {{channels}}" + }, + "actions": { + "cancel": "Cancel", + "save": "Save", + "saving": "Saving...", + "delete": "Delete" + }, + "widget": { + "name": "Alert Feed", + "description": "Your latest alerts, with a quick way to mark them read", + "maxItems": "Max items", + "showRead": "Show read alerts", + "allClear": "All clear", + "loading": "Loading..." + } +} diff --git a/plugins/alerts/locales/translated/sv_SE.json b/plugins/alerts/locales/translated/sv_SE.json new file mode 100644 index 000000000..9d7514f0d --- /dev/null +++ b/plugins/alerts/locales/translated/sv_SE.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Alerts" + }, + "permissions": { + "use": { + "title": "Use alerts", + "description": "Get alerts in the inbox and send them to your own channels." + } + }, + "onboarding": { + "feature": "Alerts", + "featureDesc": "Every alert in one inbox, sent on to Discord, ntfy, email or a webhook if you want." + }, + "settings": { + "group": { + "general": "General", + "email": "Email" + }, + "admin": { + "announcements": { + "label": "Termix announcements", + "description": "Show news from the Termix team, like security notices and releases, in everyone's inbox." + }, + "retentionDays": { + "label": "Keep alerts for (days)", + "description": "Older alerts are removed from every inbox." + }, + "smtpHost": { + "label": "SMTP server", + "description": "Needed for email channels. Leave empty to turn email off.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "SMTP port", + "description": "Usually 587 with STARTTLS or 465 with TLS." + }, + "smtpSecure": { + "label": "Use TLS from the start", + "description": "Turn on for port 465. Leave off for 587, which upgrades to TLS on its own." + }, + "smtpUser": { + "label": "SMTP username", + "description": "Leave empty if the server does not need a login." + }, + "smtpPassword": { + "label": "SMTP password", + "description": "Stored encrypted." + }, + "smtpFrom": { + "label": "From address", + "description": "The sender alerts come from.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "Alert popups", + "description": "Which new alerts pop up while you use Termix. They always land in the inbox.", + "all": "All alerts", + "warning": "Warnings and critical", + "critical": "Critical only", + "off": "None" + } + } + }, + "sections": { + "inbox": "Inbox", + "channels": "Channels", + "rules": "Delivery rules" + }, + "severity": { + "info": "Info", + "success": "Success", + "warning": "Warning", + "critical": "Critical" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "Open", + "view": "View", + "unread": "Unread", + "deliveryFailed_one": "{{count}} channel failed", + "deliveryFailed_other": "{{count}} channels failed", + "markRead": "Mark as read", + "markUnread": "Mark as unread", + "markAllRead": "Mark all as read", + "delete": "Delete", + "clearRead": "Delete read alerts", + "cleared_one": "Deleted {{count}} alert", + "cleared_other": "Deleted {{count}} alerts", + "filterAll": "All", + "filterUnread": "Unread", + "anySeverity": "Any severity", + "anySource": "Any source", + "openAll": "Open in a tab", + "empty": "No alerts yet.", + "emptyUnread": "You are all caught up.", + "loadMore": "Load more" + }, + "channels": { + "intro": "Channels are where alerts can go outside Termix. Delivery rules pick which alerts use them.", + "add": "Add channel", + "edit": "Edit channel", + "test": "Send a test", + "testSent": "Test alert sent", + "testFailed": "Test failed: {{error}}", + "deleteConfirm": "Delete the channel \"{{name}}\"?", + "deleted": "Channel deleted", + "empty": "No channels yet.", + "enabled": "Enabled", + "needsSave": "This channel needs to be opened and saved again before it can send.", + "name": "Name", + "nameRequired": "Name is required", + "type": "Type", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Discord", + "email": "Email" + }, + "emailUnavailable": "Email needs an SMTP server, which an admin sets up in the Alerts settings.", + "webhookUrl": "URL", + "webhookHint": "Gets a JSON body for every alert.", + "method": "Method", + "headers": "Headers", + "headersHint": "One per line, like Name: value.", + "ntfyServer": "Server URL", + "ntfyTopic": "Topic", + "ntfyToken": "Access token (optional)", + "discordUrl": "Discord webhook URL", + "discordHint": "From the channel's settings in Discord, under Integrations.", + "discordUsername": "Display name (optional)", + "discordAvatar": "Avatar URL (optional)", + "emailTo": "Send to", + "emailHint": "Separate more than one address with commas.", + "privateNetwork": "Allow a private network address", + "privateNetworkHint": "Only works for hosts an admin allows in the private endpoint list." + }, + "rules": { + "intro": "A delivery rule sends matching alerts to your channels. Alerts always stay in the inbox too.", + "add": "Add rule", + "edit": "Edit rule", + "empty": "No rules yet, so alerts only show up in the inbox.", + "needChannel": "Add a channel first.", + "enabled": "Enabled", + "name": "Name", + "nameRequired": "Name is required", + "match": "Alerts to send", + "matchHint": "* for everything, automations.* for everything from automations, or one exact kind.", + "minSeverity": "At least", + "channels": "Send to", + "channelRequired": "Pick at least one channel", + "deleteConfirm": "Delete the rule \"{{name}}\"?", + "everything": "Everything", + "summary": "{{match}}, {{severity}} or higher, to {{channels}}" + }, + "actions": { + "cancel": "Cancel", + "save": "Save", + "saving": "Saving...", + "delete": "Delete" + }, + "widget": { + "name": "Alert Feed", + "description": "Your latest alerts, with a quick way to mark them read", + "maxItems": "Max items", + "showRead": "Show read alerts", + "allClear": "All clear", + "loading": "Loading..." + } +} diff --git a/plugins/alerts/locales/translated/th_TH.json b/plugins/alerts/locales/translated/th_TH.json new file mode 100644 index 000000000..9d7514f0d --- /dev/null +++ b/plugins/alerts/locales/translated/th_TH.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Alerts" + }, + "permissions": { + "use": { + "title": "Use alerts", + "description": "Get alerts in the inbox and send them to your own channels." + } + }, + "onboarding": { + "feature": "Alerts", + "featureDesc": "Every alert in one inbox, sent on to Discord, ntfy, email or a webhook if you want." + }, + "settings": { + "group": { + "general": "General", + "email": "Email" + }, + "admin": { + "announcements": { + "label": "Termix announcements", + "description": "Show news from the Termix team, like security notices and releases, in everyone's inbox." + }, + "retentionDays": { + "label": "Keep alerts for (days)", + "description": "Older alerts are removed from every inbox." + }, + "smtpHost": { + "label": "SMTP server", + "description": "Needed for email channels. Leave empty to turn email off.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "SMTP port", + "description": "Usually 587 with STARTTLS or 465 with TLS." + }, + "smtpSecure": { + "label": "Use TLS from the start", + "description": "Turn on for port 465. Leave off for 587, which upgrades to TLS on its own." + }, + "smtpUser": { + "label": "SMTP username", + "description": "Leave empty if the server does not need a login." + }, + "smtpPassword": { + "label": "SMTP password", + "description": "Stored encrypted." + }, + "smtpFrom": { + "label": "From address", + "description": "The sender alerts come from.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "Alert popups", + "description": "Which new alerts pop up while you use Termix. They always land in the inbox.", + "all": "All alerts", + "warning": "Warnings and critical", + "critical": "Critical only", + "off": "None" + } + } + }, + "sections": { + "inbox": "Inbox", + "channels": "Channels", + "rules": "Delivery rules" + }, + "severity": { + "info": "Info", + "success": "Success", + "warning": "Warning", + "critical": "Critical" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "Open", + "view": "View", + "unread": "Unread", + "deliveryFailed_one": "{{count}} channel failed", + "deliveryFailed_other": "{{count}} channels failed", + "markRead": "Mark as read", + "markUnread": "Mark as unread", + "markAllRead": "Mark all as read", + "delete": "Delete", + "clearRead": "Delete read alerts", + "cleared_one": "Deleted {{count}} alert", + "cleared_other": "Deleted {{count}} alerts", + "filterAll": "All", + "filterUnread": "Unread", + "anySeverity": "Any severity", + "anySource": "Any source", + "openAll": "Open in a tab", + "empty": "No alerts yet.", + "emptyUnread": "You are all caught up.", + "loadMore": "Load more" + }, + "channels": { + "intro": "Channels are where alerts can go outside Termix. Delivery rules pick which alerts use them.", + "add": "Add channel", + "edit": "Edit channel", + "test": "Send a test", + "testSent": "Test alert sent", + "testFailed": "Test failed: {{error}}", + "deleteConfirm": "Delete the channel \"{{name}}\"?", + "deleted": "Channel deleted", + "empty": "No channels yet.", + "enabled": "Enabled", + "needsSave": "This channel needs to be opened and saved again before it can send.", + "name": "Name", + "nameRequired": "Name is required", + "type": "Type", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Discord", + "email": "Email" + }, + "emailUnavailable": "Email needs an SMTP server, which an admin sets up in the Alerts settings.", + "webhookUrl": "URL", + "webhookHint": "Gets a JSON body for every alert.", + "method": "Method", + "headers": "Headers", + "headersHint": "One per line, like Name: value.", + "ntfyServer": "Server URL", + "ntfyTopic": "Topic", + "ntfyToken": "Access token (optional)", + "discordUrl": "Discord webhook URL", + "discordHint": "From the channel's settings in Discord, under Integrations.", + "discordUsername": "Display name (optional)", + "discordAvatar": "Avatar URL (optional)", + "emailTo": "Send to", + "emailHint": "Separate more than one address with commas.", + "privateNetwork": "Allow a private network address", + "privateNetworkHint": "Only works for hosts an admin allows in the private endpoint list." + }, + "rules": { + "intro": "A delivery rule sends matching alerts to your channels. Alerts always stay in the inbox too.", + "add": "Add rule", + "edit": "Edit rule", + "empty": "No rules yet, so alerts only show up in the inbox.", + "needChannel": "Add a channel first.", + "enabled": "Enabled", + "name": "Name", + "nameRequired": "Name is required", + "match": "Alerts to send", + "matchHint": "* for everything, automations.* for everything from automations, or one exact kind.", + "minSeverity": "At least", + "channels": "Send to", + "channelRequired": "Pick at least one channel", + "deleteConfirm": "Delete the rule \"{{name}}\"?", + "everything": "Everything", + "summary": "{{match}}, {{severity}} or higher, to {{channels}}" + }, + "actions": { + "cancel": "Cancel", + "save": "Save", + "saving": "Saving...", + "delete": "Delete" + }, + "widget": { + "name": "Alert Feed", + "description": "Your latest alerts, with a quick way to mark them read", + "maxItems": "Max items", + "showRead": "Show read alerts", + "allClear": "All clear", + "loading": "Loading..." + } +} diff --git a/plugins/alerts/locales/translated/tr_TR.json b/plugins/alerts/locales/translated/tr_TR.json new file mode 100644 index 000000000..2e8dd2a69 --- /dev/null +++ b/plugins/alerts/locales/translated/tr_TR.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Uyarılar" + }, + "permissions": { + "use": { + "title": "Use alerts", + "description": "Get alerts in the inbox and send them to your own channels." + } + }, + "onboarding": { + "feature": "Uyarılar", + "featureDesc": "Every alert in one inbox, sent on to Discord, ntfy, email or a webhook if you want." + }, + "settings": { + "group": { + "general": "Genel", + "email": "E-posta" + }, + "admin": { + "announcements": { + "label": "Termix announcements", + "description": "Show news from the Termix team, like security notices and releases, in everyone's inbox." + }, + "retentionDays": { + "label": "Keep alerts for (days)", + "description": "Older alerts are removed from every inbox." + }, + "smtpHost": { + "label": "SMTP server", + "description": "Needed for email channels. Leave empty to turn email off.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "SMTP port", + "description": "Usually 587 with STARTTLS or 465 with TLS." + }, + "smtpSecure": { + "label": "Use TLS from the start", + "description": "Turn on for port 465. Leave off for 587, which upgrades to TLS on its own." + }, + "smtpUser": { + "label": "SMTP username", + "description": "Leave empty if the server does not need a login." + }, + "smtpPassword": { + "label": "SMTP password", + "description": "Stored encrypted." + }, + "smtpFrom": { + "label": "From address", + "description": "The sender alerts come from.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "Alert popups", + "description": "Which new alerts pop up while you use Termix. They always land in the inbox.", + "all": "All alerts", + "warning": "Warnings and critical", + "critical": "Critical only", + "off": "Yok" + } + } + }, + "sections": { + "inbox": "Inbox", + "channels": "Kanallar", + "rules": "Delivery rules" + }, + "severity": { + "info": "Bilgi", + "success": "Başarılı", + "warning": "Uyarı", + "critical": "Critical" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "Aç", + "view": "Görüntüle", + "unread": "Unread", + "deliveryFailed_one": "{{count}} channel failed", + "deliveryFailed_other": "{{count}} channels failed", + "markRead": "Mark as read", + "markUnread": "Mark as unread", + "markAllRead": "Mark all as read", + "delete": "Sil", + "clearRead": "Delete read alerts", + "cleared_one": "Deleted {{count}} alert", + "cleared_other": "Deleted {{count}} alerts", + "filterAll": "Tümü", + "filterUnread": "Unread", + "anySeverity": "Any severity", + "anySource": "Any source", + "openAll": "Open in a tab", + "empty": "No alerts yet.", + "emptyUnread": "You are all caught up.", + "loadMore": "Load more" + }, + "channels": { + "intro": "Channels are where alerts can go outside Termix. Delivery rules pick which alerts use them.", + "add": "Add channel", + "edit": "Edit channel", + "test": "Send a test", + "testSent": "Test alert sent", + "testFailed": "Test failed: {{error}}", + "deleteConfirm": "Delete the channel \"{{name}}\"?", + "deleted": "Channel deleted", + "empty": "No channels yet.", + "enabled": "Etkin", + "needsSave": "This channel needs to be opened and saved again before it can send.", + "name": "Ad", + "nameRequired": "Ad zorunludur", + "type": "Tür", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Discord", + "email": "E-posta" + }, + "emailUnavailable": "Email needs an SMTP server, which an admin sets up in the Alerts settings.", + "webhookUrl": "URL", + "webhookHint": "Gets a JSON body for every alert.", + "method": "Method", + "headers": "Headers", + "headersHint": "One per line, like Name: value.", + "ntfyServer": "Sunucu URL'si", + "ntfyTopic": "Konu", + "ntfyToken": "Access token (optional)", + "discordUrl": "Discord webhook URL", + "discordHint": "From the channel's settings in Discord, under Integrations.", + "discordUsername": "Display name (optional)", + "discordAvatar": "Avatar URL (optional)", + "emailTo": "Send to", + "emailHint": "Separate more than one address with commas.", + "privateNetwork": "Allow a private network address", + "privateNetworkHint": "Only works for hosts an admin allows in the private endpoint list." + }, + "rules": { + "intro": "A delivery rule sends matching alerts to your channels. Alerts always stay in the inbox too.", + "add": "Add rule", + "edit": "Edit rule", + "empty": "No rules yet, so alerts only show up in the inbox.", + "needChannel": "Add a channel first.", + "enabled": "Etkin", + "name": "Ad", + "nameRequired": "Ad zorunludur", + "match": "Alerts to send", + "matchHint": "* for everything, automations.* for everything from automations, or one exact kind.", + "minSeverity": "At least", + "channels": "Send to", + "channelRequired": "Pick at least one channel", + "deleteConfirm": "Delete the rule \"{{name}}\"?", + "everything": "Everything", + "summary": "{{match}}, {{severity}} or higher, to {{channels}}" + }, + "actions": { + "cancel": "İptal", + "save": "Kaydet", + "saving": "Kaydediliyor...", + "delete": "Sil" + }, + "widget": { + "name": "Uyarı Akışı", + "description": "Your latest alerts, with a quick way to mark them read", + "maxItems": "Max items", + "showRead": "Show read alerts", + "allClear": "Her şey normal", + "loading": "Yükleniyor..." + } +} diff --git a/plugins/alerts/locales/translated/uk_UA.json b/plugins/alerts/locales/translated/uk_UA.json new file mode 100644 index 000000000..9d7514f0d --- /dev/null +++ b/plugins/alerts/locales/translated/uk_UA.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Alerts" + }, + "permissions": { + "use": { + "title": "Use alerts", + "description": "Get alerts in the inbox and send them to your own channels." + } + }, + "onboarding": { + "feature": "Alerts", + "featureDesc": "Every alert in one inbox, sent on to Discord, ntfy, email or a webhook if you want." + }, + "settings": { + "group": { + "general": "General", + "email": "Email" + }, + "admin": { + "announcements": { + "label": "Termix announcements", + "description": "Show news from the Termix team, like security notices and releases, in everyone's inbox." + }, + "retentionDays": { + "label": "Keep alerts for (days)", + "description": "Older alerts are removed from every inbox." + }, + "smtpHost": { + "label": "SMTP server", + "description": "Needed for email channels. Leave empty to turn email off.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "SMTP port", + "description": "Usually 587 with STARTTLS or 465 with TLS." + }, + "smtpSecure": { + "label": "Use TLS from the start", + "description": "Turn on for port 465. Leave off for 587, which upgrades to TLS on its own." + }, + "smtpUser": { + "label": "SMTP username", + "description": "Leave empty if the server does not need a login." + }, + "smtpPassword": { + "label": "SMTP password", + "description": "Stored encrypted." + }, + "smtpFrom": { + "label": "From address", + "description": "The sender alerts come from.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "Alert popups", + "description": "Which new alerts pop up while you use Termix. They always land in the inbox.", + "all": "All alerts", + "warning": "Warnings and critical", + "critical": "Critical only", + "off": "None" + } + } + }, + "sections": { + "inbox": "Inbox", + "channels": "Channels", + "rules": "Delivery rules" + }, + "severity": { + "info": "Info", + "success": "Success", + "warning": "Warning", + "critical": "Critical" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "Open", + "view": "View", + "unread": "Unread", + "deliveryFailed_one": "{{count}} channel failed", + "deliveryFailed_other": "{{count}} channels failed", + "markRead": "Mark as read", + "markUnread": "Mark as unread", + "markAllRead": "Mark all as read", + "delete": "Delete", + "clearRead": "Delete read alerts", + "cleared_one": "Deleted {{count}} alert", + "cleared_other": "Deleted {{count}} alerts", + "filterAll": "All", + "filterUnread": "Unread", + "anySeverity": "Any severity", + "anySource": "Any source", + "openAll": "Open in a tab", + "empty": "No alerts yet.", + "emptyUnread": "You are all caught up.", + "loadMore": "Load more" + }, + "channels": { + "intro": "Channels are where alerts can go outside Termix. Delivery rules pick which alerts use them.", + "add": "Add channel", + "edit": "Edit channel", + "test": "Send a test", + "testSent": "Test alert sent", + "testFailed": "Test failed: {{error}}", + "deleteConfirm": "Delete the channel \"{{name}}\"?", + "deleted": "Channel deleted", + "empty": "No channels yet.", + "enabled": "Enabled", + "needsSave": "This channel needs to be opened and saved again before it can send.", + "name": "Name", + "nameRequired": "Name is required", + "type": "Type", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Discord", + "email": "Email" + }, + "emailUnavailable": "Email needs an SMTP server, which an admin sets up in the Alerts settings.", + "webhookUrl": "URL", + "webhookHint": "Gets a JSON body for every alert.", + "method": "Method", + "headers": "Headers", + "headersHint": "One per line, like Name: value.", + "ntfyServer": "Server URL", + "ntfyTopic": "Topic", + "ntfyToken": "Access token (optional)", + "discordUrl": "Discord webhook URL", + "discordHint": "From the channel's settings in Discord, under Integrations.", + "discordUsername": "Display name (optional)", + "discordAvatar": "Avatar URL (optional)", + "emailTo": "Send to", + "emailHint": "Separate more than one address with commas.", + "privateNetwork": "Allow a private network address", + "privateNetworkHint": "Only works for hosts an admin allows in the private endpoint list." + }, + "rules": { + "intro": "A delivery rule sends matching alerts to your channels. Alerts always stay in the inbox too.", + "add": "Add rule", + "edit": "Edit rule", + "empty": "No rules yet, so alerts only show up in the inbox.", + "needChannel": "Add a channel first.", + "enabled": "Enabled", + "name": "Name", + "nameRequired": "Name is required", + "match": "Alerts to send", + "matchHint": "* for everything, automations.* for everything from automations, or one exact kind.", + "minSeverity": "At least", + "channels": "Send to", + "channelRequired": "Pick at least one channel", + "deleteConfirm": "Delete the rule \"{{name}}\"?", + "everything": "Everything", + "summary": "{{match}}, {{severity}} or higher, to {{channels}}" + }, + "actions": { + "cancel": "Cancel", + "save": "Save", + "saving": "Saving...", + "delete": "Delete" + }, + "widget": { + "name": "Alert Feed", + "description": "Your latest alerts, with a quick way to mark them read", + "maxItems": "Max items", + "showRead": "Show read alerts", + "allClear": "All clear", + "loading": "Loading..." + } +} diff --git a/plugins/alerts/locales/translated/vi_VN.json b/plugins/alerts/locales/translated/vi_VN.json new file mode 100644 index 000000000..44d8a66ae --- /dev/null +++ b/plugins/alerts/locales/translated/vi_VN.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "Cảnh báo" + }, + "permissions": { + "use": { + "title": "Use alerts", + "description": "Get alerts in the inbox and send them to your own channels." + } + }, + "onboarding": { + "feature": "Cảnh báo", + "featureDesc": "Every alert in one inbox, sent on to Discord, ntfy, email or a webhook if you want." + }, + "settings": { + "group": { + "general": "Chung", + "email": "Email" + }, + "admin": { + "announcements": { + "label": "Termix announcements", + "description": "Show news from the Termix team, like security notices and releases, in everyone's inbox." + }, + "retentionDays": { + "label": "Keep alerts for (days)", + "description": "Older alerts are removed from every inbox." + }, + "smtpHost": { + "label": "SMTP server", + "description": "Needed for email channels. Leave empty to turn email off.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "SMTP port", + "description": "Usually 587 with STARTTLS or 465 with TLS." + }, + "smtpSecure": { + "label": "Use TLS from the start", + "description": "Turn on for port 465. Leave off for 587, which upgrades to TLS on its own." + }, + "smtpUser": { + "label": "SMTP username", + "description": "Leave empty if the server does not need a login." + }, + "smtpPassword": { + "label": "SMTP password", + "description": "Stored encrypted." + }, + "smtpFrom": { + "label": "From address", + "description": "The sender alerts come from.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "Alert popups", + "description": "Which new alerts pop up while you use Termix. They always land in the inbox.", + "all": "All alerts", + "warning": "Warnings and critical", + "critical": "Critical only", + "off": "Không" + } + } + }, + "sections": { + "inbox": "Inbox", + "channels": "Kênh", + "rules": "Delivery rules" + }, + "severity": { + "info": "Thông tin", + "success": "Thành công", + "warning": "Cảnh báo", + "critical": "Critical" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "Mở", + "view": "Xem", + "unread": "Unread", + "deliveryFailed_one": "{{count}} channel failed", + "deliveryFailed_other": "{{count}} channels failed", + "markRead": "Mark as read", + "markUnread": "Mark as unread", + "markAllRead": "Mark all as read", + "delete": "Xóa", + "clearRead": "Delete read alerts", + "cleared_one": "Deleted {{count}} alert", + "cleared_other": "Deleted {{count}} alerts", + "filterAll": "Tất cả", + "filterUnread": "Unread", + "anySeverity": "Any severity", + "anySource": "Any source", + "openAll": "Open in a tab", + "empty": "No alerts yet.", + "emptyUnread": "You are all caught up.", + "loadMore": "Load more" + }, + "channels": { + "intro": "Channels are where alerts can go outside Termix. Delivery rules pick which alerts use them.", + "add": "Add channel", + "edit": "Edit channel", + "test": "Send a test", + "testSent": "Test alert sent", + "testFailed": "Test failed: {{error}}", + "deleteConfirm": "Delete the channel \"{{name}}\"?", + "deleted": "Channel deleted", + "empty": "No channels yet.", + "enabled": "Đã bật", + "needsSave": "This channel needs to be opened and saved again before it can send.", + "name": "Tên", + "nameRequired": "Tên là bắt buộc", + "type": "Loại", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Discord", + "email": "Email" + }, + "emailUnavailable": "Email needs an SMTP server, which an admin sets up in the Alerts settings.", + "webhookUrl": "URL", + "webhookHint": "Gets a JSON body for every alert.", + "method": "Method", + "headers": "Headers", + "headersHint": "One per line, like Name: value.", + "ntfyServer": "URL máy chủ", + "ntfyTopic": "Chủ đề", + "ntfyToken": "Access token (optional)", + "discordUrl": "Discord webhook URL", + "discordHint": "From the channel's settings in Discord, under Integrations.", + "discordUsername": "Display name (optional)", + "discordAvatar": "Avatar URL (optional)", + "emailTo": "Send to", + "emailHint": "Separate more than one address with commas.", + "privateNetwork": "Allow a private network address", + "privateNetworkHint": "Only works for hosts an admin allows in the private endpoint list." + }, + "rules": { + "intro": "A delivery rule sends matching alerts to your channels. Alerts always stay in the inbox too.", + "add": "Add rule", + "edit": "Edit rule", + "empty": "No rules yet, so alerts only show up in the inbox.", + "needChannel": "Add a channel first.", + "enabled": "Đã bật", + "name": "Tên", + "nameRequired": "Tên là bắt buộc", + "match": "Alerts to send", + "matchHint": "* for everything, automations.* for everything from automations, or one exact kind.", + "minSeverity": "At least", + "channels": "Send to", + "channelRequired": "Pick at least one channel", + "deleteConfirm": "Delete the rule \"{{name}}\"?", + "everything": "Everything", + "summary": "{{match}}, {{severity}} or higher, to {{channels}}" + }, + "actions": { + "cancel": "Hủy", + "save": "Lưu", + "saving": "Đang lưu...", + "delete": "Xóa" + }, + "widget": { + "name": "Luồng cảnh báo", + "description": "Your latest alerts, with a quick way to mark them read", + "maxItems": "Max items", + "showRead": "Show read alerts", + "allClear": "Tất cả ổn", + "loading": "Đang tải..." + } +} diff --git a/plugins/alerts/locales/translated/zh_CN.json b/plugins/alerts/locales/translated/zh_CN.json new file mode 100644 index 000000000..bc0c435f5 --- /dev/null +++ b/plugins/alerts/locales/translated/zh_CN.json @@ -0,0 +1,175 @@ +{ + "nav": { + "alerts": "告警" + }, + "permissions": { + "use": { + "title": "使用告警", + "description": "在收件箱中接收告警,并发送到你自己的渠道。" + } + }, + "onboarding": { + "feature": "告警", + "featureDesc": "在统一收件箱中查看所有告警,也可将它们发送到 Discord、ntfy、电子邮箱或 Webhook。" + }, + "settings": { + "group": { + "general": "常规", + "email": "邮箱" + }, + "admin": { + "announcements": { + "label": "Termix 公告", + "description": "在所有用户的收件箱中显示 Termix 团队发布的安全通知、版本更新等消息。" + }, + "retentionDays": { + "label": "告警保留天数", + "description": "超过保留时间的告警将从所有收件箱中移除。" + }, + "smtpHost": { + "label": "SMTP 服务器", + "description": "邮件渠道需要此项,留空则关闭邮件发送。", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "SMTP 端口", + "description": "通常使用 587(STARTTLS)或 465(TLS)。" + }, + "smtpSecure": { + "label": "连接时直接使用 TLS", + "description": "使用端口 465 时开启。使用端口 587 时关闭,该端口会自动升级为 TLS。" + }, + "smtpUser": { + "label": "SMTP 用户名", + "description": "服务器无需登录时留空。" + }, + "smtpPassword": { + "label": "SMTP 密码", + "description": "加密保存。" + }, + "smtpFrom": { + "label": "发件人地址", + "description": "告警邮件的发件人。", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "告警弹窗", + "description": "选择使用 Termix 时哪些新告警会弹出提示。所有告警都会保留在收件箱中。", + "all": "所有告警", + "warning": "警告和严重告警", + "critical": "仅严重告警", + "off": "全不选" + } + } + }, + "sections": { + "inbox": "收件箱", + "channels": "通道", + "rules": "投递规则" + }, + "severity": { + "info": "信息", + "success": "成功", + "warning": "警告", + "critical": "严重" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "打开", + "view": "查看", + "unread": "未读", + "deliveryFailed_one": "{{count}} 个渠道发送失败", + "deliveryFailed_other": "{{count}} 个渠道发送失败", + "markRead": "标记为已读", + "markUnread": "标记为未读", + "markAllRead": "全部标记为已读", + "delete": "删除", + "clearRead": "删除已读告警", + "cleared_one": "已删除 {{count}} 条告警", + "cleared_other": "已删除 {{count}} 条告警", + "filterAll": "全部", + "filterUnread": "未读", + "anySeverity": "任意严重程度", + "anySource": "任意来源", + "openAll": "在标签页中打开", + "empty": "暂无告警。", + "emptyUnread": "没有未读消息。", + "loadMore": "加载更多" + }, + "channels": { + "intro": "渠道用于将告警发送到 Termix 之外,投递规则决定哪些告警使用这些渠道。", + "add": "添加渠道", + "edit": "编辑渠道", + "test": "发送测试消息", + "testSent": "测试告警已发送", + "testFailed": "测试失败:{{error}}", + "deleteConfirm": "删除渠道“{{name}}”?", + "deleted": "渠道已删除", + "empty": "暂无渠道。", + "enabled": "已启用", + "needsSave": "此渠道需要重新打开并保存后才能发送。", + "name": "名称", + "nameRequired": "名称为必填项", + "type": "类型", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Discord", + "email": "邮箱" + }, + "emailUnavailable": "邮件需要 SMTP 服务器,由管理员在告警设置中配置。", + "webhookUrl": "URL", + "webhookHint": "每条告警都会发送包含 JSON 数据的请求体。", + "method": "请求方法", + "headers": "请求头", + "headersHint": "每行一项,例如 Name: value。", + "ntfyServer": "服务器 URL", + "ntfyTopic": "主题", + "ntfyToken": "访问令牌(可选)", + "discordUrl": "Discord Webhook 地址", + "discordHint": "可在 Discord 频道设置的“集成”中获取。", + "discordUsername": "显示名称(可选)", + "discordAvatar": "头像 URL(可选)", + "emailTo": "发送至", + "emailHint": "多个地址之间用逗号分隔。", + "privateNetwork": "允许内网地址", + "privateNetworkHint": "仅适用于管理员在私有端点列表中允许的主机。" + }, + "rules": { + "intro": "投递规则将匹配的告警发送到你的渠道,告警也会始终保留在收件箱中。", + "add": "添加规则", + "edit": "编辑规则", + "empty": "暂无规则,告警仅显示在收件箱中。", + "needChannel": "请先添加渠道。", + "enabled": "已启用", + "name": "名称", + "nameRequired": "名称为必填项", + "match": "要发送的告警", + "matchHint": "使用 * 匹配全部,automations.* 匹配所有自动化告警,或填写一个精确的类型。", + "minSeverity": "最低严重程度", + "channels": "发送至", + "channelRequired": "请至少选择一个渠道", + "deleteConfirm": "删除规则“{{name}}”?", + "everything": "全部", + "summary": "{{match}},{{severity}} 及以上,发送至 {{channels}}" + }, + "actions": { + "cancel": "取消", + "save": "保存", + "saving": "保存中...", + "delete": "删除" + }, + "widget": { + "name": "告警信息流", + "description": "显示最新告警,并可快速标记为已读", + "maxItems": "最大条目数", + "showRead": "显示已读告警", + "allClear": "一切正常", + "loading": "加载中..." + }, + "plugin": { + "name": "告警" + } +} diff --git a/plugins/alerts/locales/translated/zh_TW.json b/plugins/alerts/locales/translated/zh_TW.json new file mode 100644 index 000000000..a5f743f1a --- /dev/null +++ b/plugins/alerts/locales/translated/zh_TW.json @@ -0,0 +1,172 @@ +{ + "nav": { + "alerts": "警示" + }, + "permissions": { + "use": { + "title": "Use alerts", + "description": "Get alerts in the inbox and send them to your own channels." + } + }, + "onboarding": { + "feature": "警示", + "featureDesc": "Every alert in one inbox, sent on to Discord, ntfy, email or a webhook if you want." + }, + "settings": { + "group": { + "general": "一般", + "email": "電子郵件" + }, + "admin": { + "announcements": { + "label": "Termix announcements", + "description": "Show news from the Termix team, like security notices and releases, in everyone's inbox." + }, + "retentionDays": { + "label": "Keep alerts for (days)", + "description": "Older alerts are removed from every inbox." + }, + "smtpHost": { + "label": "SMTP server", + "description": "Needed for email channels. Leave empty to turn email off.", + "placeholder": "smtp.example.com" + }, + "smtpPort": { + "label": "SMTP port", + "description": "Usually 587 with STARTTLS or 465 with TLS." + }, + "smtpSecure": { + "label": "Use TLS from the start", + "description": "Turn on for port 465. Leave off for 587, which upgrades to TLS on its own." + }, + "smtpUser": { + "label": "SMTP username", + "description": "Leave empty if the server does not need a login." + }, + "smtpPassword": { + "label": "SMTP password", + "description": "Stored encrypted." + }, + "smtpFrom": { + "label": "From address", + "description": "The sender alerts come from.", + "placeholder": "Termix " + } + }, + "user": { + "popups": { + "label": "Alert popups", + "description": "Which new alerts pop up while you use Termix. They always land in the inbox.", + "all": "All alerts", + "warning": "Warnings and critical", + "critical": "Critical only", + "off": "取消全選" + } + } + }, + "sections": { + "inbox": "Inbox", + "channels": "通道", + "rules": "Delivery rules" + }, + "severity": { + "info": "資訊", + "success": "成功", + "warning": "警告", + "critical": "Critical" + }, + "inbox": { + "sourceTermix": "Termix", + "openLink": "開啟", + "view": "檢視", + "unread": "Unread", + "deliveryFailed_one": "{{count}} channel failed", + "deliveryFailed_other": "{{count}} channels failed", + "markRead": "Mark as read", + "markUnread": "Mark as unread", + "markAllRead": "Mark all as read", + "delete": "刪除", + "clearRead": "Delete read alerts", + "cleared_one": "Deleted {{count}} alert", + "cleared_other": "Deleted {{count}} alerts", + "filterAll": "全選", + "filterUnread": "Unread", + "anySeverity": "Any severity", + "anySource": "Any source", + "openAll": "Open in a tab", + "empty": "No alerts yet.", + "emptyUnread": "You are all caught up.", + "loadMore": "Load more" + }, + "channels": { + "intro": "Channels are where alerts can go outside Termix. Delivery rules pick which alerts use them.", + "add": "Add channel", + "edit": "Edit channel", + "test": "Send a test", + "testSent": "Test alert sent", + "testFailed": "Test failed: {{error}}", + "deleteConfirm": "Delete the channel \"{{name}}\"?", + "deleted": "Channel deleted", + "empty": "No channels yet.", + "enabled": "已啟用", + "needsSave": "This channel needs to be opened and saved again before it can send.", + "name": "名稱", + "nameRequired": "名稱為必填", + "type": "類型", + "types": { + "webhook": "Webhook", + "ntfy": "ntfy", + "discord": "Discord", + "email": "電子郵件" + }, + "emailUnavailable": "Email needs an SMTP server, which an admin sets up in the Alerts settings.", + "webhookUrl": "URL", + "webhookHint": "Gets a JSON body for every alert.", + "method": "Method", + "headers": "Headers", + "headersHint": "One per line, like Name: value.", + "ntfyServer": "伺服器 URL", + "ntfyTopic": "主題", + "ntfyToken": "Access token (optional)", + "discordUrl": "Discord webhook URL", + "discordHint": "From the channel's settings in Discord, under Integrations.", + "discordUsername": "Display name (optional)", + "discordAvatar": "Avatar URL (optional)", + "emailTo": "Send to", + "emailHint": "Separate more than one address with commas.", + "privateNetwork": "Allow a private network address", + "privateNetworkHint": "Only works for hosts an admin allows in the private endpoint list." + }, + "rules": { + "intro": "A delivery rule sends matching alerts to your channels. Alerts always stay in the inbox too.", + "add": "Add rule", + "edit": "Edit rule", + "empty": "No rules yet, so alerts only show up in the inbox.", + "needChannel": "Add a channel first.", + "enabled": "已啟用", + "name": "名稱", + "nameRequired": "名稱為必填", + "match": "Alerts to send", + "matchHint": "* for everything, automations.* for everything from automations, or one exact kind.", + "minSeverity": "At least", + "channels": "Send to", + "channelRequired": "Pick at least one channel", + "deleteConfirm": "Delete the rule \"{{name}}\"?", + "everything": "Everything", + "summary": "{{match}}, {{severity}} or higher, to {{channels}}" + }, + "actions": { + "cancel": "取消", + "save": "儲存", + "saving": "儲存中…", + "delete": "刪除" + }, + "widget": { + "name": "警報動態", + "description": "Your latest alerts, with a quick way to mark them read", + "maxItems": "Max items", + "showRead": "Show read alerts", + "allClear": "一切正常", + "loading": "載入中..." + } +} diff --git a/plugins/alerts/src/backend/repository.ts b/plugins/alerts/src/backend/repository.ts index 76bc04671..41358df4f 100644 --- a/plugins/alerts/src/backend/repository.ts +++ b/plugins/alerts/src/backend/repository.ts @@ -304,7 +304,7 @@ export async function createAlertsRepository( dedupeKey: item.dedupeKey ?? null, createdAt, }); - await db.persist(); + await db.persist({ lazy: true }); return toItem({ id, ...item, @@ -322,7 +322,7 @@ export async function createAlertsRepository( .update(items) .set({ deliveries: JSON.stringify(results) }) .where(eq(items.id, id)); - await db.persist(); + await db.persist({ lazy: true }); }, async hasUnreadWithKey(userId: string, key: string): Promise { diff --git a/plugins/automations/locales/en.json b/plugins/automations/locales/en.json index b459b4ade..77a517290 100644 --- a/plugins/automations/locales/en.json +++ b/plugins/automations/locales/en.json @@ -207,5 +207,19 @@ "remove": "Remove schedule", "loadFailed": "Could not refresh maintenance status. Changes are disabled until it can be loaded.", "loading": "Loading maintenance status…" + }, + "ui": { + "sidebar": { + "automations": { + "options": { + "connect": "connect", + "disconnect": "disconnect", + "offline": "offline", + "online": "online", + "failing": "failing", + "recovered": "recovered" + } + } + } } } diff --git a/plugins/automations/locales/translated/af_ZA.json b/plugins/automations/locales/translated/af_ZA.json index 134386398..68f0a8db6 100644 --- a/plugins/automations/locales/translated/af_ZA.json +++ b/plugins/automations/locales/translated/af_ZA.json @@ -1,4 +1,26 @@ { + "permissions": { + "view": { + "title": "Bekyk outomatisasies", + "description": "Sien die outomatisasies en hul geskiedenis." + }, + "create": { + "title": "Skep outomatisasies", + "description": "Voeg nuwe outomatisasies by." + }, + "edit": { + "title": "Wysig outomatisasies", + "description": "Verander bestaande outomatisasies." + }, + "delete": { + "title": "Vee outomatisasies uit", + "description": "Verwyder outomatisasies." + }, + "run": { + "title": "Voer outomatisasies uit", + "description": "Aktiveer 'n outomatisering met die hand." + } + }, "newUi": { "sidebar": { "automations": { @@ -12,14 +34,8 @@ "editTitle": "Wysig Outomatisering", "empty": "Geen outomatisasies nog nie. Skep een om op 'n maatstaf, 'n skedule of 'n gebeurtenis te reageer.", "emptyRuns": "Geen lopies nog nie.", - "emptyChannels": "Geen kanale nog nie. Voeg een by om kennisgewings êrens heen te stuur.", - "noChannelsHint": "Geen kanale nog opgestel nie. Voeg een by in die Kanale-oortjie.", - "addChannel": "Voeg kanaal by", - "testChannel": "Toets", - "channelTestSent": "Toetskennisgewing gestuur", - "channelTestFailed": "Toetskennisgewing het misluk", - "channelDeleted": "Kanaal uitgevee", - "deleteChannelConfirm": "Vee hierdie kanaal uit? Outomatiserings wat dit gebruik, sal ophou om kennisgewings te stuur.", + "channelsHint": "Kanale word in Waarskuwings opgestel", + "noChannelsHint": "Die waarskuwing gaan altyd na jou inboks. Voeg kanale by Waarskuwings om dit ook elders te stuur.", "nameLabel": "Naam", "namePlaceholder": "bv. Maak /data skoon wanneer dit vol is", "nameRequired": "Naam word vereis", @@ -79,7 +95,7 @@ "webhook": "Inkomende webhook" }, "stepTypes": { - "notify": "Stuur 'n kennisgewing", + "notify": "Stuur 'n waarskuwing", "http": "Roep 'n URL op", "run_snippet": "Voer 'n brokkie uit", "run_command": "Voer 'n opdrag uit", @@ -118,7 +134,7 @@ "url": "URL", "method": "Metode", "body": "Liggaam", - "channels": "Kanale", + "channels": "Stuur ook na", "title": "Titel", "message": "Boodskap", "snippet": "Brokkie", @@ -135,6 +151,16 @@ "onError": { "stop": "Stop die hardloop", "continue": "Gaan voort" + }, + "needsPlugin": "Benodig {{plugin}}", + "needsPluginHint": "Hierdie outomatisering word oorgeslaan totdat die funksie wat dit benodig weer beskikbaar is.", + "offBadge": "Af", + "docsLink": "Bekyk dokumente", + "ago": { + "seconds": "{{count}}s gelede", + "minutes": "{{count}}m gelede", + "hours": "{{count}}uur gelede", + "days": "{{count}}dae gelede" } } } @@ -145,5 +171,41 @@ "onboarding": { "feature_automations": "Outomatisasies", "feature_automations_desc": "Voer stappe outomaties uit wanneer iets gebeur, en word in kennis gestel." + }, + "maintenance": { + "title": "Onderhoud", + "description": "Onderbreek gasheerstatus, gesondheid, metrieke, houer- en tonnel-ontkoppelingsoutomatisasies terwyl werk aan die gang is. Monitering, handmatige lopies en geskeduleerde outomatisasies gaan voort.", + "denied": "Jy het nie toestemming om onderhoud te sien nie.", + "sharedReadOnly": "Hierdie gasheer is met jou gedeel. Slegs die eienaar kan die onderhoud verander.", + "failed": "Onderhoud kon nie opgedateer word nie.", + "active": "Onderhoud aktief", + "estimated": "Geraamde voltooiing", + "noAutoEnd": "Die skatting beëindig nie onderhoud nie. Beëindig dit eksplisiet wanneer die werk voltooi is.", + "endConfirm": "Beëindig onderhoud en hervat gebeurtenis-geaktiveerde outomatisasies vir hierdie gasheer?", + "confirmEnd": "Bevestig einde", + "cancel": "Kanselleer", + "end": "Einde van onderhoud", + "action": "Aksie", + "startNow": "Begin nou", + "schedule": "Skeduleer vir later", + "reason": "Rede", + "startUtc": "Eerste begin (UTC)", + "repeat": "Herhaal", + "once": "Eens", + "weekly": "Weekliks", + "monthly": "Maandeliks", + "utcHelp": "Skedules gebruik UTC dwarsdeur die jaar. Maandelikse skedules slaan maande oor sonder die gekose dag. Beplande vensters kan nie oorvleuel nie; oorskrydende onderhoud gaan voort oor latere vensters.", + "duration": "Geraamde duur (minute)", + "grace": "Genadetydperk (minute)", + "notify": "Stel een keer in kennis indien steeds vanlyn na die skatting plus grasietydperk", + "addSchedule": "Voeg skedule by", + "schedules": "Skedules", + "noSchedules": "Geen onderhoudskedules nie.", + "completed": "Reeds begin", + "minutes_one": "{{count}} minuut", + "minutes_other": "{{count}} minute", + "remove": "Verwyder skedule", + "loadFailed": "Kon nie onderhoudstatus verfris nie. Veranderinge is gedeaktiveer totdat dit gelaai kan word.", + "loading": "Laai onderhoudstatus…" } } diff --git a/plugins/automations/locales/translated/ar_SA.json b/plugins/automations/locales/translated/ar_SA.json index 860c17fd5..57ad4dc0c 100644 --- a/plugins/automations/locales/translated/ar_SA.json +++ b/plugins/automations/locales/translated/ar_SA.json @@ -1,4 +1,26 @@ { + "permissions": { + "view": { + "title": "عرض عمليات التشغيل الآلي", + "description": "اطلع على أنظمة التشغيل الآلي وتاريخها." + }, + "create": { + "title": "إنشاء عمليات أتمتة", + "description": "أضف عمليات أتمتة جديدة." + }, + "edit": { + "title": "تحرير عمليات التشغيل الآلي", + "description": "قم بتغيير أنظمة التشغيل الآلي الحالية." + }, + "delete": { + "title": "حذف عمليات التشغيل الآلي", + "description": "إزالة العمليات الآلية." + }, + "run": { + "title": "تشغيل عمليات التشغيل الآلي", + "description": "قم بتشغيل عملية أتمتة يدوياً." + } + }, "newUi": { "sidebar": { "automations": { @@ -12,20 +34,14 @@ "editTitle": "أتمتة التحرير", "empty": "لا توجد عمليات أتمتة حتى الآن. أنشئ واحدة للتفاعل مع مقياس أو جدول زمني أو حدث.", "emptyRuns": "لم يتم تسجيل أي نقاط حتى الآن.", - "emptyChannels": "لا توجد قنوات حتى الآن. أضف قناة لإرسال الإشعارات إلى مكان ما.", - "noChannelsHint": "لم يتم إعداد أي قنوات بعد. أضف قناة في تبويب القنوات.", - "addChannel": "إضافة قناة", - "testChannel": "امتحان", - "channelTestSent": "تم إرسال إشعار الاختبار", - "channelTestFailed": "فشل إشعار الاختبار", - "channelDeleted": "تم حذف القناة", - "deleteChannelConfirm": "هل تريد حذف هذه القناة؟ ستتوقف عمليات التشغيل الآلي التي تستخدمها عن إرسال الإشعارات.", - "nameLabel": "اسم", + "channelsHint": "يتم إعداد القنوات في قسم التنبيهات", + "noChannelsHint": "تصل التنبيهات دائمًا إلى بريدك الوارد. أضف قنوات في قسم التنبيهات لإرسالها إلى مكان آخر أيضًا.", + "nameLabel": "الاسم", "namePlaceholder": "مثال: تنظيف /data عند امتلائها", "nameRequired": "الاسم مطلوب", - "descriptionLabel": "وصف", + "descriptionLabel": "الوصف", "descriptionPlaceholder": "وصف اختياري", - "enabledLabel": "مُفعّل", + "enabledLabel": "مُمكّن", "concurrencyLabel": "إذا كان قيد التشغيل بالفعل", "concurrencyHint": "ماذا نفعل عندما يتم تشغيل هذا مرة أخرى قبل انتهاء التشغيل الأخير؟", "concurrency": { @@ -33,7 +49,7 @@ "queue": "انتظر واركض خلفه", "allow": "قم بتشغيل كليهما في وقت واحد" }, - "save": "يحفظ", + "save": "حفظ", "created": "تم إنشاء الأتمتة", "updated": "تم حفظ الأتمتة", "deleted": "تم حذف الأتمتة", @@ -42,8 +58,8 @@ "testRun": "تشغيل تجريبي", "testRunHint": "يقوم بتنفيذ كل خطوة ولكنه لا يلمس أي شيء خارج Termix.", "runStarted": "بدأ الجري", - "runFinished": "انتهت العملية: {{status}}", - "trigger": "مشغل", + "runFinished": "انتهى التشغيل: {{status}}", + "trigger": "المشغّل", "steps": "خطوات", "addStep": "خطوات إضافية", "removeStep": "خطوة الإزالة", @@ -52,15 +68,15 @@ "noSteps": "لم تُتخذ أي خطوات بعد. أضف خطوة واحدة لتوضيح ما ينبغي أن يحدث.", "webhookTokenTitle": "رابط الويب هوك", "webhookTokenDescription": "هذا يظهر مرة واحدة فقط. احفظه الآن، فلن تتمكن من استعادته لاحقاً.", - "copy": "ينسخ", + "copy": "نسخ", "copied": "تم النسخ", "viewJson": "JSON", "viewBuilder": "باني", "viewGraph": "الرسم البياني", "lastRun": "الجولة الأخيرة", - "never": "أبداً", + "never": "أبدًا", "duration": "{{seconds}}s", - "stepOutput": "الناتج", + "stepOutput": "المخرجات", "stepError": "خطأ", "dryRunBadge": "تشغيل تجريبي", "hostSelector": { @@ -79,7 +95,7 @@ "webhook": "رابط الويب الوارد" }, "stepTypes": { - "notify": "إرسال إشعار", + "notify": "إرسال تنبيه", "http": "استدعاء عنوان URL", "run_snippet": "قم بتشغيل جزء من التعليمات البرمجية", "run_command": "نفّذ أمرًا", @@ -90,10 +106,10 @@ "set_var": "قم بتعيين متغير", "if": "إذا / خلاف ذلك", "run_automation": "قم بتشغيل عملية أتمتة أخرى", - "stop": "قف" + "stop": "التوقف" }, "statuses": { - "running": "جري", + "running": "قيد التشغيل", "success": "نجاح", "failed": "فشل", "timeout": "انتهت مهلة الاتصال", @@ -101,8 +117,8 @@ "cancelled": "تم الإلغاء" }, "fields": { - "host": "يستضيف", - "metric": "متري", + "host": "المضيف", + "metric": "المقياس", "mount": "نقطة التثبيت", "operator": "يكون", "value": "قيمة", @@ -114,12 +130,12 @@ "timezoneServer": "وقت الخادم", "timezoneHint": "تُقرأ أوقات Cron في هذه المنطقة. لا ينطبق ذلك على الجداول الزمنية الفاصلة.", "container": "حاوية", - "command": "يأمر", - "url": "عنوان URL", + "command": "الأمر", + "url": "URL", "method": "طريقة", "body": "جسم", - "channels": "القنوات", - "title": "عنوان", + "channels": "أرسل أيضًا إلى", + "title": "العنوان", "message": "رسالة", "snippet": "مقتطف", "seconds": "ثوانٍ", @@ -135,6 +151,16 @@ "onError": { "stop": "أوقف الجري", "continue": "حمل" + }, + "needsPlugin": "الاحتياجات {{plugin}}", + "needsPluginHint": "يتم تخطي هذه العملية الآلية حتى تصبح الميزة التي تحتاجها متاحة مرة أخرى.", + "offBadge": "غير مفعلة", + "docsLink": "عرض المستندات", + "ago": { + "seconds": "{{count}}منذ ثانية", + "minutes": "قبل {{count}}m", + "hours": "قبل {{count}}h", + "days": "قبل {{count}}d" } } } @@ -145,5 +171,41 @@ "onboarding": { "feature_automations": "الأتمتة", "feature_automations_desc": "قم بتشغيل الخطوات تلقائيًا عند حدوث شيء ما، واحصل على إشعار بذلك." + }, + "maintenance": { + "title": "صيانة", + "description": "أوقف عمليات أتمتة حالة المضيف، وصحته، ومقاييسه، والحاويات، وفصل الأنفاق مؤقتًا أثناء سير العمل. وتستمر عمليات المراقبة، والتشغيل اليدوي، والأتمتة المجدولة.", + "denied": "ليس لديك إذن للاطلاع على أعمال الصيانة.", + "sharedReadOnly": "تمت مشاركة هذا المضيف معك. مالكه فقط هو من يستطيع تغيير إعداداته.", + "failed": "تعذر تحديث الصيانة.", + "active": "الصيانة نشطة", + "estimated": "تاريخ الإنجاز المتوقع", + "noAutoEnd": "لا يُنهي التقدير أعمال الصيانة. يجب إنهاؤه صراحةً عند اكتمال العمل.", + "endConfirm": "هل تريد إنهاء الصيانة واستئناف عمليات التشغيل الآلي التي يتم تشغيلها بواسطة الأحداث لهذا المضيف؟", + "confirmEnd": "تأكيد الإنهاء", + "cancel": "إلغاء", + "end": "إنهاء الصيانة", + "action": "الإجراء", + "startNow": "ابدأ الآن", + "schedule": "جدولة لاحقاً", + "reason": "سبب", + "startUtc": "بداية التشغيل الأولى (UTC)", + "repeat": "يكرر", + "once": "مرة واحدة", + "weekly": "أسبوعي", + "monthly": "شهريا", + "utcHelp": "تستخدم الجداول الزمنية التوقيت العالمي المنسق (UTC) على مدار العام. وتتخطى الجداول الشهرية الأشهر التي لا تتضمن اليوم المحدد. ولا يمكن أن تتداخل فترات التخطيط؛ إذ تستمر أعمال الصيانة المتأخرة خلال الفترات اللاحقة.", + "duration": "المدة المقدرة (بالدقائق)", + "grace": "فترة السماح (بالدقائق)", + "notify": "قم بالإخطار مرة واحدة إذا كنت لا تزال غير متصل بالإنترنت بعد الفترة التقديرية بالإضافة إلى فترة السماح", + "addSchedule": "إضافة جدول", + "schedules": "الجداول الزمنية", + "noSchedules": "لا توجد جداول صيانة.", + "completed": "ابدأ بالفعل", + "minutes_one": "{{count}} minute", + "minutes_other": "{{count}} دقائق", + "remove": "إزالة الجدول الزمني", + "loadFailed": "تعذر تحديث حالة الصيانة. التغييرات معطلة حتى يتم تحميلها.", + "loading": "جارٍ تحميل حالة الصيانة…" } } diff --git a/plugins/automations/locales/translated/bg_BG.json b/plugins/automations/locales/translated/bg_BG.json index 1c1e71809..f4ee12569 100644 --- a/plugins/automations/locales/translated/bg_BG.json +++ b/plugins/automations/locales/translated/bg_BG.json @@ -1,4 +1,26 @@ { + "permissions": { + "view": { + "title": "Преглед на автоматизациите", + "description": "Вижте автоматизациите и тяхната история." + }, + "create": { + "title": "Създаване на автоматизации", + "description": "Добавете нови автоматизации." + }, + "edit": { + "title": "Редактиране на автоматизации", + "description": "Променете съществуващите автоматизации." + }, + "delete": { + "title": "Изтриване на автоматизации", + "description": "Премахнете автоматизациите." + }, + "run": { + "title": "Изпълнявайте автоматизации", + "description": "Задействайте автоматизация ръчно." + } + }, "newUi": { "sidebar": { "automations": { @@ -12,14 +34,8 @@ "editTitle": "Редактиране на автоматизация", "empty": "Все още няма автоматизации. Създайте такава, която да реагира на показател, график или събитие.", "emptyRuns": "Все още няма бягания.", - "emptyChannels": "Все още няма канали. Добавете такъв, за да изпращате известия някъде.", - "noChannelsHint": "Все още няма настроени канали. Добавете такъв в раздела „Канали“.", - "addChannel": "Добавяне на канал", - "testChannel": "Тест", - "channelTestSent": "Тестово известие е изпратено", - "channelTestFailed": "Тестовото известие не беше успешно", - "channelDeleted": "Каналът е изтрит", - "deleteChannelConfirm": "Да се изтрие ли този канал? Автоматизациите, които го използват, ще спрат да получават известия.", + "channelsHint": "Каналите се настройват в „Известия“", + "noChannelsHint": "Сигналът винаги отива във входящата ви поща. Добавете канали в „Сигнали“, за да го изпращате и някъде другаде.", "nameLabel": "Име", "namePlaceholder": "напр. Почистване на /данни, когато се запълни", "nameRequired": "Името е задължително", @@ -79,7 +95,7 @@ "webhook": "Входящ уеб кукичка" }, "stepTypes": { - "notify": "Изпращане на известие", + "notify": "Изпрати сигнал", "http": "Извикване на URL адрес", "run_snippet": "Изпълнете фрагмент", "run_command": "Изпълнете команда", @@ -118,7 +134,7 @@ "url": "URL адрес", "method": "Метод", "body": "Тяло", - "channels": "Канали", + "channels": "Изпрати също до", "title": "Заглавие", "message": "Съобщение", "snippet": "Фрагмент", @@ -135,6 +151,16 @@ "onError": { "stop": "Спрете бягането", "continue": "Продължавай" + }, + "needsPlugin": "Изисква {{plugin}}", + "needsPluginHint": "Тази автоматизация се пропуска, докато функцията, от която се нуждае, не стане отново налична.", + "offBadge": "Изключено", + "docsLink": "Преглед на документи", + "ago": { + "seconds": "преди {{count}}сек", + "minutes": "преди {{count}}мин.", + "hours": "преди {{count}}ч", + "days": "преди {{count}}дни" } } } @@ -145,5 +171,41 @@ "onboarding": { "feature_automations": "Автоматизации", "feature_automations_desc": "Изпълнявайте стъпките автоматично, когато нещо се случи, и получавайте известия." + }, + "maintenance": { + "title": "Поддръжка", + "description": "Паузирайте автоматизациите за състоянието на хоста, здравето, метриките, контейнерите и прекъсванията на тунелите, докато работата е в ход. Мониторингът, ръчните изпълнения и планираните автоматизации продължават.", + "denied": "Нямате разрешение да преглеждате поддръжката.", + "sharedReadOnly": "Този хост беше споделен с вас. Само собственикът му може да променя поддръжката.", + "failed": "Поддръжката не можа да бъде актуализирана.", + "active": "Поддръжката е активна", + "estimated": "Очаквано завършване", + "noAutoEnd": "Оценката не прекратява поддръжката. Прекратете я изрично, когато работата е завършена.", + "endConfirm": "Да се прекрати ли поддръжката и да се възобновят автоматизациите, задействани от събития, за този хост?", + "confirmEnd": "Потвърждаване на края", + "cancel": "Отказ", + "end": "Край на поддръжката", + "action": "Действие", + "startNow": "Започнете сега", + "schedule": "Планирайте за по-късно", + "reason": "Причина", + "startUtc": "Първо стартиране (UTC)", + "repeat": "Повторете", + "once": "Веднъж", + "weekly": "Седмично", + "monthly": "Месечно", + "utcHelp": "Графиците използват UTC през цялата година. Месечните графици пропускат месеците без избрания ден. Планираните прозорци не могат да се припокриват; превишаването на поддръжката продължава и през по-късни прозорци.", + "duration": "Очаквана продължителност (минути)", + "grace": "Гратисен период (минути)", + "notify": "Уведомявай веднъж, ако все още си офлайн след прогнозната цена плюс гратисен период", + "addSchedule": "Добавяне на график", + "schedules": "Разписания", + "noSchedules": "Няма графици за поддръжка.", + "completed": "Вече започна", + "minutes_one": "{{count}} минута", + "minutes_other": "{{count}} минути", + "remove": "Премахване на графика", + "loadFailed": "Не можа да се обнови състоянието на поддръжката. Промените са деактивирани, докато не може да бъде заредено.", + "loading": "Зареждане на състоянието на поддръжката…" } } diff --git a/plugins/automations/locales/translated/bn_BD.json b/plugins/automations/locales/translated/bn_BD.json index 7a29f0613..b459b4ade 100644 --- a/plugins/automations/locales/translated/bn_BD.json +++ b/plugins/automations/locales/translated/bn_BD.json @@ -1,149 +1,211 @@ { + "permissions": { + "view": { + "title": "View automations", + "description": "See the automations and their history." + }, + "create": { + "title": "Create automations", + "description": "Add new automations." + }, + "edit": { + "title": "Edit automations", + "description": "Change existing automations." + }, + "delete": { + "title": "Delete automations", + "description": "Remove automations." + }, + "run": { + "title": "Run automations", + "description": "Trigger an automation by hand." + } + }, "newUi": { "sidebar": { "automations": { - "title": "অটোমেশন", - "tabAutomations": "অটোমেশন", - "tabRuns": "রান", - "tabChannels": "চ্যানেল", - "createAutomation": "নতুন অটোমেশন", - "backToAutomations": "অটোমেশনে ফিরে যান", - "createTitle": "নতুন অটোমেশন", - "editTitle": "সম্পাদনা অটোমেশন", - "empty": "এখনো কোনো অটোমেশন নেই। কোনো মেট্রিক, শিডিউল বা ইভেন্টের প্রতিক্রিয়ায় একটি তৈরি করুন।", - "emptyRuns": "এখনো কোনো রান হয়নি।", - "emptyChannels": "এখনো কোনো চ্যানেল নেই। নোটিফিকেশন পাঠানোর জন্য একটি চ্যানেল যোগ করুন।", - "noChannelsHint": "এখনো কোনো চ্যানেল সেট আপ করা হয়নি। চ্যানেল ট্যাবে একটি চ্যানেল যোগ করুন।", - "addChannel": "চ্যানেল যোগ করুন", - "testChannel": "পরীক্ষা", - "channelTestSent": "পরীক্ষার বিজ্ঞপ্তি পাঠানো হয়েছে", - "channelTestFailed": "পরীক্ষার বিজ্ঞপ্তি ব্যর্থ হয়েছে", - "channelDeleted": "চ্যানেল মুছে ফেলা হয়েছে", - "deleteChannelConfirm": "এই চ্যানেলটি মুছে ফেললে? এটি ব্যবহার করা অটোমেশনগুলো নোটিফিকেশন পাঠানো বন্ধ করে দেবে।", - "nameLabel": "নাম", - "namePlaceholder": "যেমন, /data পূর্ণ হয়ে গেলে তা পরিষ্কার করুন।", - "nameRequired": "নাম আবশ্যক", - "descriptionLabel": "বর্ণনা", - "descriptionPlaceholder": "ঐচ্ছিক বিবরণ", - "enabledLabel": "সক্ষম করা হয়েছে", - "concurrencyLabel": "যদি এটি ইতিমধ্যে চালু থাকে", - "concurrencyHint": "শেষ রান শেষ হওয়ার আগেই এটি আবার চালু হলে কী করতে হবে।", + "title": "Automations", + "tabAutomations": "Automations", + "tabRuns": "Runs", + "tabChannels": "Channels", + "createAutomation": "New Automation", + "backToAutomations": "Back to Automations", + "createTitle": "New Automation", + "editTitle": "Edit Automation", + "empty": "No automations yet. Create one to react to a metric, a schedule, or an event.", + "emptyRuns": "No runs yet.", + "channelsHint": "Channels are set up in Alerts", + "noChannelsHint": "The alert always goes to your inbox. Add channels in Alerts to also send it somewhere else.", + "nameLabel": "Name", + "namePlaceholder": "e.g., Clean up /data when it fills", + "nameRequired": "Name is required", + "descriptionLabel": "Description", + "descriptionPlaceholder": "Optional description", + "enabledLabel": "Enabled", + "concurrencyLabel": "If it is already running", + "concurrencyHint": "What to do when this is triggered again before the last run has finished.", "concurrency": { - "skip": "নতুন রানটি এড়িয়ে যান।", - "queue": "অপেক্ষা করো এবং পিছনে দৌড়াও", - "allow": "একসাথে দুটোই চালান" + "skip": "Skip the new run", + "queue": "Wait and run after", + "allow": "Run both at once" }, - "save": "সংরক্ষণ করুন", - "created": "অটোমেশন তৈরি করা হয়েছে", - "updated": "অটোমেশন সংরক্ষিত", - "deleted": "অটোমেশন মুছে ফেলা হয়েছে", - "deleteConfirm": "এই অটোমেশনটি ডিলিট করলে, এর রান হিস্ট্রিও ডিলিট হয়ে যাবে।", - "runNow": "এখনই দৌড়ান", - "testRun": "পরীক্ষামূলক চালনা", - "testRunHint": "প্রতিটি ধাপ চলে কিন্তু টার্মিক্সের বাইরের কোনো কিছু স্পর্শ করে না।", - "runStarted": "দৌড় শুরু হলো", - "runFinished": "দৌড় শেষ: {{status}}", - "trigger": "ট্রিগার", - "steps": "পদক্ষেপ", - "addStep": "ধাপ যোগ করুন", - "removeStep": "ধাপটি সরান", - "moveUp": "উপরে উঠুন", - "moveDown": "নিচে নামুন", - "noSteps": "এখনো কোনো ধাপ যোগ করা হয়নি। কী হওয়া উচিত তা জানাতে একটি ধাপ যোগ করুন।", - "webhookTokenTitle": "ওয়েবহুক ইউআরএল", - "webhookTokenDescription": "এটি একবারই দেখানো হবে। এখনই সংরক্ষণ করুন, পরে আর পুনরুদ্ধার করা যাবে না।", - "copy": "অনুলিপি", - "copied": "অনুলিপি করা হয়েছে", + "save": "Save", + "created": "Automation created", + "updated": "Automation saved", + "deleted": "Automation deleted", + "deleteConfirm": "Delete this automation? Its run history is deleted too.", + "runNow": "Run now", + "testRun": "Test run", + "testRunHint": "Runs every step but does not touch anything outside Termix.", + "runStarted": "Run started", + "runFinished": "Run finished: {{status}}", + "trigger": "Trigger", + "steps": "Steps", + "addStep": "Add step", + "removeStep": "Remove step", + "moveUp": "Move up", + "moveDown": "Move down", + "noSteps": "No steps yet. Add one to say what should happen.", + "webhookTokenTitle": "Webhook URL", + "webhookTokenDescription": "This is shown once. Save it now, it cannot be retrieved later.", + "copy": "Copy", + "copied": "Copied", "viewJson": "JSON", - "viewBuilder": "নির্মাতা", - "viewGraph": "গ্রাফ", - "lastRun": "শেষ দৌড়", - "never": "কখনো না", + "viewBuilder": "Builder", + "viewGraph": "Graph", + "lastRun": "Last run", + "never": "Never", "duration": "{{seconds}}s", - "stepOutput": "আউটপুট", - "stepError": "ত্রুটি", - "dryRunBadge": "পরীক্ষামূলক চালনা", + "stepOutput": "Output", + "stepError": "Error", + "dryRunBadge": "Test run", "hostSelector": { - "trigger": "ট্রিগারিং হোস্ট", - "host": "নির্দিষ্ট হোস্ট", - "fleet": "ফ্লিট", - "all": "সকল হোস্ট" + "trigger": "Triggering host", + "host": "Specific host", + "fleet": "Fleet", + "all": "All hosts" }, "triggerKinds": { - "metric_threshold": "মেট্রিক থ্রেশহোল্ড", - "host_status": "হোস্ট উপরে বা নিচে যায়", - "health_check": "স্বাস্থ্য পরীক্ষার পরিবর্তন", - "schedule": "একটি সময়সূচী অনুযায়ী", - "docker_event": "কন্টেইনার ইভেন্ট", - "internal_event": "টারমিক্স ইভেন্ট", - "webhook": "ইনকামিং ওয়েবহুক" + "metric_threshold": "Metric threshold", + "host_status": "Host goes up or down", + "health_check": "Health check changes", + "schedule": "On a schedule", + "docker_event": "Container event", + "internal_event": "Termix event", + "webhook": "Incoming webhook" }, "stepTypes": { - "notify": "একটি বিজ্ঞপ্তি পাঠান", - "http": "একটি URL কল করুন", - "run_snippet": "একটি স্নিপেট চালান", - "run_command": "একটি কমান্ড চালান", - "docker": "একটি কন্টেইনার নিয়ন্ত্রণ করুন", - "tunnel": "একটি টানেল নিয়ন্ত্রণ করুন", - "wol": "একজন হোস্টকে জাগান", - "wait": "অপেক্ষা করুন", - "set_var": "একটি ভেরিয়েবল সেট করুন", - "if": "যদি / অন্যথায়", - "run_automation": "আরেকটি অটোমেশন চালান", - "stop": "থামুন" + "notify": "Send an alert", + "http": "Call a URL", + "run_snippet": "Run a snippet", + "run_command": "Run a command", + "docker": "Control a container", + "tunnel": "Control a tunnel", + "wol": "Wake a host", + "wait": "Wait", + "set_var": "Set a variable", + "if": "If / otherwise", + "run_automation": "Run another automation", + "stop": "Stop" }, "statuses": { - "running": "দৌড়ানো", - "success": "সাফল্য", - "failed": "ব্যর্থ", - "timeout": "সময়সীমা শেষ", - "skipped": "বাদ দেওয়া হয়েছে", - "cancelled": "বাতিল করা হয়েছে" + "running": "Running", + "success": "Success", + "failed": "Failed", + "timeout": "Timed out", + "skipped": "Skipped", + "cancelled": "Cancelled" }, "fields": { - "host": "হোস্ট", - "metric": "মেট্রিক", - "mount": "মাউন্ট পয়েন্ট", - "operator": "হয়", - "value": "মূল্য", - "forSeconds": "(সেকেন্ড) ধরে স্থায়ী", - "cooldown": "কুলডাউন (মিনিট)", - "cron": "ক্রোন এক্সপ্রেশন", - "intervalSeconds": "প্রতি (সেকেন্ডে)", - "timezone": "সময় অঞ্চল", - "timezoneServer": "সার্ভারের সময়", - "timezoneHint": "এই জোনে ক্রন টাইম পড়া হয়। এটি ইন্টারভাল শিডিউলের ক্ষেত্রে প্রযোজ্য নয়।", - "container": "কন্টেইনার", - "command": "আদেশ", - "url": "ইউআরএল", - "method": "পদ্ধতি", - "body": "শরীর", - "channels": "চ্যানেল", - "title": "শিরোনাম", - "message": "বার্তা", - "snippet": "স্নিপেট", - "seconds": "সেকেন্ড", - "conditionLeftPlaceholder": "যাচাই করার মান", - "conditionRightPlaceholder": "তুলনা করুন", - "variableName": "ভেরিয়েবলের নাম", - "variableValue": "মূল্য", - "elevated": "sudo দিয়ে চালান", - "onError": "যদি এটি ব্যর্থ হয়", - "allowPrivateNetwork": "স্থানীয় নেটওয়ার্ক ঠিকানাগুলির অনুমতি দিন", - "allowPrivateNetworkHint": "আপনার ল্যানে সেলফ-হোস্টেড সার্ভিসের জন্য প্রয়োজন। অভ্যন্তরীণ অ্যাড্রেসে অনুরোধ পাঠানো প্রতিরোধ করতে এটি ডিফল্টরূপে বন্ধ থাকে।" + "host": "Host", + "metric": "Metric", + "mount": "Mount point", + "operator": "Is", + "value": "Value", + "forSeconds": "Sustained for (seconds)", + "cooldown": "Cooldown (minutes)", + "cron": "Cron expression", + "intervalSeconds": "Every (seconds)", + "timezone": "Time zone", + "timezoneServer": "Server time", + "timezoneHint": "Cron times are read in this zone. Does not apply to interval schedules.", + "container": "Container", + "command": "Command", + "url": "URL", + "method": "Method", + "body": "Body", + "channels": "Also send to", + "title": "Title", + "message": "Message", + "snippet": "Snippet", + "seconds": "Seconds", + "conditionLeftPlaceholder": "Value to check", + "conditionRightPlaceholder": "Compare against", + "variableName": "Variable name", + "variableValue": "Value", + "elevated": "Run with sudo", + "onError": "If this fails", + "allowPrivateNetwork": "Allow local network addresses", + "allowPrivateNetworkHint": "Needed for a self-hosted service on your LAN. Off by default to prevent requests to internal addresses." }, "onError": { - "stop": "দৌড় থামাও", - "continue": "চালিয়ে যান" + "stop": "Stop the run", + "continue": "Carry on" + }, + "needsPlugin": "Needs {{plugin}}", + "needsPluginHint": "This automation is skipped until the feature it needs is available again.", + "offBadge": "Off", + "docsLink": "View docs", + "ago": { + "seconds": "{{count}}s ago", + "minutes": "{{count}}m ago", + "hours": "{{count}}h ago", + "days": "{{count}}d ago" } } } }, "nav": { - "automations": "অটোমেশন" + "automations": "Automations" }, "onboarding": { - "feature_automations": "অটোমেশন", - "feature_automations_desc": "কোনো ঘটনা ঘটলে স্বয়ংক্রিয়ভাবে ধাপগুলো সম্পন্ন করুন এবং বিজ্ঞপ্তি পান।" + "feature_automations": "Automations", + "feature_automations_desc": "Run steps automatically when something happens, and get notified." + }, + "maintenance": { + "title": "Maintenance", + "description": "Pause host status, health, metric, container and tunnel-disconnection automations while work is in progress. Monitoring, manual runs and scheduled automations continue.", + "denied": "You do not have permission to view maintenance.", + "sharedReadOnly": "This host was shared with you. Only its owner can change maintenance.", + "failed": "Maintenance could not be updated.", + "active": "Maintenance active", + "estimated": "Estimated completion", + "noAutoEnd": "The estimate does not end maintenance. End it explicitly when the work is complete.", + "endConfirm": "End maintenance and resume event-triggered automations for this host?", + "confirmEnd": "Confirm end", + "cancel": "Cancel", + "end": "End maintenance", + "action": "Action", + "startNow": "Start now", + "schedule": "Schedule for later", + "reason": "Reason", + "startUtc": "First start (UTC)", + "repeat": "Repeat", + "once": "Once", + "weekly": "Weekly", + "monthly": "Monthly", + "utcHelp": "Schedules use UTC throughout the year. Monthly schedules skip months without the selected day. Planned windows cannot overlap; overrunning maintenance continues across later windows.", + "duration": "Estimated duration (minutes)", + "grace": "Grace period (minutes)", + "notify": "Notify once if still offline after the estimate plus grace period", + "addSchedule": "Add schedule", + "schedules": "Schedules", + "noSchedules": "No maintenance schedules.", + "completed": "Already started", + "minutes_one": "{{count}} minute", + "minutes_other": "{{count}} minutes", + "remove": "Remove schedule", + "loadFailed": "Could not refresh maintenance status. Changes are disabled until it can be loaded.", + "loading": "Loading maintenance status…" } } diff --git a/plugins/automations/locales/translated/ca_ES.json b/plugins/automations/locales/translated/ca_ES.json index eb1394e65..e9836b346 100644 --- a/plugins/automations/locales/translated/ca_ES.json +++ b/plugins/automations/locales/translated/ca_ES.json @@ -1,4 +1,26 @@ { + "permissions": { + "view": { + "title": "Veure automatitzacions", + "description": "Vegeu les automatitzacions i el seu historial." + }, + "create": { + "title": "Crea automatitzacions", + "description": "Afegiu noves automatitzacions." + }, + "edit": { + "title": "Edita automatitzacions", + "description": "Canviar les automatitzacions existents." + }, + "delete": { + "title": "Suprimeix automatitzacions", + "description": "Eliminar automatitzacions." + }, + "run": { + "title": "Executar automatitzacions", + "description": "Activa una automatització manualment." + } + }, "newUi": { "sidebar": { "automations": { @@ -12,14 +34,8 @@ "editTitle": "Edita l'automatització", "empty": "Encara no hi ha automatitzacions. Crea'n una per reaccionar a una mètrica, una programació o un esdeveniment.", "emptyRuns": "Encara no hi ha curses.", - "emptyChannels": "Encara no hi ha cap canal. Afegeix-ne un per enviar notificacions a algun lloc.", - "noChannelsHint": "Encara no s'ha configurat cap canal. Afegeix-ne un a la pestanya Canals.", - "addChannel": "Afegeix un canal", - "testChannel": "Prova", - "channelTestSent": "Notificació de prova enviada", - "channelTestFailed": "La notificació de prova ha fallat", - "channelDeleted": "Canal suprimit", - "deleteChannelConfirm": "Voleu suprimir aquest canal? Les automatitzacions que l'utilitzen deixaran de notificar.", + "channelsHint": "Els canals es configuren a Alertes", + "noChannelsHint": "L'alerta sempre va a la teva safata d'entrada. Afegeix canals a Alertes per enviar-la també a un altre lloc.", "nameLabel": "Nom", "namePlaceholder": "p. ex., Neteja /dades quan s'ompli", "nameRequired": "El nom és obligatori", @@ -79,7 +95,7 @@ "webhook": "Webhook entrant" }, "stepTypes": { - "notify": "Enviar una notificació", + "notify": "Enviar una alerta", "http": "Crida a una URL", "run_snippet": "Executa un fragment", "run_command": "Executa una ordre", @@ -118,7 +134,7 @@ "url": "URL", "method": "Mètode", "body": "Cos", - "channels": "Canals", + "channels": "També envia a", "title": "Títol", "message": "Missatge", "snippet": "Fragment", @@ -135,6 +151,16 @@ "onError": { "stop": "Atura la cursa", "continue": "Continua" + }, + "needsPlugin": "Necessita {{plugin}}", + "needsPluginHint": "Aquesta automatització s'omet fins que la funció que necessita torni a estar disponible.", + "offBadge": "Desactivat", + "docsLink": "Veure documents", + "ago": { + "seconds": "Fa {{count}}segons", + "minutes": "fa {{count}}minuts", + "hours": "fa {{count}}h", + "days": "fa {{count}}dies" } } } @@ -145,5 +171,41 @@ "onboarding": { "feature_automations": "Automatitzacions", "feature_automations_desc": "Executa els passos automàticament quan passi alguna cosa i rep notificacions." + }, + "maintenance": { + "title": "Manteniment", + "description": "Pausa les automatitzacions d'estat, salut, mètriques, contenidors i desconnexió de túnels de l'amfitrió mentre la feina està en curs. La supervisió, les execucions manuals i les automatitzacions programades continuen.", + "denied": "No teniu permís per veure el manteniment.", + "sharedReadOnly": "Aquest amfitrió s'ha compartit amb tu. Només el seu propietari pot canviar el manteniment.", + "failed": "No s'ha pogut actualitzar el manteniment.", + "active": "Manteniment actiu", + "estimated": "Finalització prevista", + "noAutoEnd": "El pressupost no finalitza el manteniment. Finalitzeu-lo explícitament quan la feina s'hagi completat.", + "endConfirm": "Voleu finalitzar el manteniment i reprendre les automatitzacions activades per esdeveniments per a aquest amfitrió?", + "confirmEnd": "Confirma la fi", + "cancel": "Cancel·la", + "end": "Finalitzar el manteniment", + "action": "Acció", + "startNow": "Comença ara", + "schedule": "Programa per a més tard", + "reason": "Raó", + "startUtc": "Primer inici (UTC)", + "repeat": "Repetir", + "once": "Un cop", + "weekly": "Setmanal", + "monthly": "Mensual", + "utcHelp": "Les programacions utilitzen UTC durant tot l'any. Les programacions mensuals salten mesos sense el dia seleccionat. Les finestres planificades no es poden superposar; el manteniment que s'executa de manera excessiva continua a les finestres posteriors.", + "duration": "Durada estimada (minuts)", + "grace": "Període de gràcia (minuts)", + "notify": "Notifica una vegada si encara estàs fora de línia després de l'estimació més el període de gràcia", + "addSchedule": "Afegeix una programació", + "schedules": "Horaris", + "noSchedules": "Sense programes de manteniment.", + "completed": "Ja ha començat", + "minutes_one": "{{count}} minut", + "minutes_other": "{{count}} minuts", + "remove": "Elimina la programació", + "loadFailed": "No s'ha pogut actualitzar l'estat del manteniment. Els canvis estan desactivats fins que es pugui carregar.", + "loading": "S'està carregant l'estat del manteniment…" } } diff --git a/plugins/automations/locales/translated/cs_CZ.json b/plugins/automations/locales/translated/cs_CZ.json index 5c7776c8b..14533a055 100644 --- a/plugins/automations/locales/translated/cs_CZ.json +++ b/plugins/automations/locales/translated/cs_CZ.json @@ -1,4 +1,26 @@ { + "permissions": { + "view": { + "title": "Zobrazit automatizace", + "description": "Podívejte se na automatizace a jejich historii." + }, + "create": { + "title": "Vytvářejte automatizace", + "description": "Přidejte nové automatizace." + }, + "edit": { + "title": "Upravit automatizace", + "description": "Změňte stávající automatizace." + }, + "delete": { + "title": "Smazat automatizace", + "description": "Odstraňte automatizace." + }, + "run": { + "title": "Spouštění automatizací", + "description": "Ručně spusťte automatizaci." + } + }, "newUi": { "sidebar": { "automations": { @@ -12,14 +34,8 @@ "editTitle": "Upravit automatizaci", "empty": "Zatím žádné automatizace. Vytvořte si automatizaci, která bude reagovat na metriku, plán nebo událost.", "emptyRuns": "Zatím žádné běhy.", - "emptyChannels": "Zatím žádné kanály. Přidejte jeden, abyste někam mohli odesílat oznámení.", - "noChannelsHint": "Zatím nejsou nastaveny žádné kanály. Přidejte jeden na kartě Kanály.", - "addChannel": "Přidat kanál", - "testChannel": "Test", - "channelTestSent": "Testovací oznámení odesláno", - "channelTestFailed": "Testovací oznámení selhalo", - "channelDeleted": "Kanál smazán", - "deleteChannelConfirm": "Smazat tento kanál? Automatizace, které ho používají, přestanou zasílat upozornění.", + "channelsHint": "Kanály se nastavují v části Upozornění", + "noChannelsHint": "Upozornění se vždy dostane do vaší schránky. Přidejte si do Upozornění kanály, aby se odesílalo i někam jinam.", "nameLabel": "Jméno", "namePlaceholder": "např. Vyčistit /data, když se zaplní", "nameRequired": "Jméno je povinné", @@ -79,7 +95,7 @@ "webhook": "Příchozí webhook" }, "stepTypes": { - "notify": "Odeslat oznámení", + "notify": "Odeslat upozornění", "http": "Zavolat URL", "run_snippet": "Spustit úryvek", "run_command": "Spusťte příkaz", @@ -118,7 +134,7 @@ "url": "URL", "method": "Metoda", "body": "Tělo", - "channels": "Kanály", + "channels": "Také poslat na", "title": "Titul", "message": "Zpráva", "snippet": "Úryvek", @@ -127,7 +143,7 @@ "conditionRightPlaceholder": "Porovnat s", "variableName": "Název proměnné", "variableValue": "Hodnota", - "elevated": "Spusťte pomocí sudo", + "elevated": "Spustit se sudo", "onError": "Pokud se to nepodaří", "allowPrivateNetwork": "Povolit lokální síťové adresy", "allowPrivateNetworkHint": "Vyžadováno pro službu hostovanou na vašem lokálním serveru (LAN). Ve výchozím nastavení vypnuto, aby se zabránilo požadavkům na interní adresy." @@ -135,6 +151,16 @@ "onError": { "stop": "Zastav běh", "continue": "Pokračovat" + }, + "needsPlugin": "Potřeby {{plugin}}", + "needsPluginHint": "Tato automatizace se přeskočí, dokud nebude znovu k dispozici funkce, kterou potřebuje.", + "offBadge": "Vypnuto", + "docsLink": "Zobrazit dokumenty", + "ago": { + "seconds": "Před {{count}}s", + "minutes": "{{count}}před m", + "hours": "{{count}}před hodinami", + "days": "Před {{count}}dny" } } } @@ -145,5 +171,41 @@ "onboarding": { "feature_automations": "Automatizace", "feature_automations_desc": "Automaticky spouštět kroky, když se něco stane, a dostávat upozornění." + }, + "maintenance": { + "title": "Údržba", + "description": "Během probíhající práce pozastavte automatizaci stavu hostitele, jeho kondice, metrik, kontejnerů a odpojení tunelů. Monitorování, ruční spuštění a plánované automatizace pokračují.", + "denied": "Nemáte oprávnění k zobrazení údržby.", + "sharedReadOnly": "Tento hostitel byl s vámi sdílen. Pouze jeho majitel může změnit údržbu.", + "failed": "Údržbu se nepodařilo aktualizovat.", + "active": "Údržba aktivní", + "estimated": "Předpokládané dokončení", + "noAutoEnd": "Odhad údržby neukončuje. Ukončete ji explicitně po dokončení prací.", + "endConfirm": "Ukončit údržbu a obnovit automatizace spouštěné událostmi pro tohoto hostitele?", + "confirmEnd": "Potvrdit konec", + "cancel": "Zrušit", + "end": "Ukončení údržby", + "action": "Akce", + "startNow": "Začněte hned", + "schedule": "Naplánovat na později", + "reason": "Důvod", + "startUtc": "První spuštění (UTC)", + "repeat": "Opakovat", + "once": "Jednou", + "weekly": "Týdně", + "monthly": "Měsíční", + "utcHelp": "Harmonogramy používají po celý rok UTC. Měsíční harmonogramy přeskakují měsíce bez vybraného dne. Plánovaná okna se nemohou překrývat; údržba překročením se provádí i v pozdějších oknech.", + "duration": "Odhadovaná doba trvání (minuty)", + "grace": "Dodatečná lhůta (minuty)", + "notify": "Upozornit jednou, pokud je stále offline po uplynutí odhadované doby plus lhůty.", + "addSchedule": "Přidat rozvrh", + "schedules": "Rozvrhy", + "noSchedules": "Žádné plány údržby.", + "completed": "Již začalo", + "minutes_one": "{{count}} minuta", + "minutes_other": "{{count}} minut", + "remove": "Odebrat plán", + "loadFailed": "Nepodařilo se obnovit stav údržby. Změny jsou zakázány, dokud nebude možné jej načíst.", + "loading": "Načítání stavu údržby…" } } diff --git a/plugins/automations/locales/translated/da_DK.json b/plugins/automations/locales/translated/da_DK.json index ce479f3be..6b887b51f 100644 --- a/plugins/automations/locales/translated/da_DK.json +++ b/plugins/automations/locales/translated/da_DK.json @@ -1,4 +1,26 @@ { + "permissions": { + "view": { + "title": "Se automatiseringer", + "description": "Se automatiseringerne og deres historik." + }, + "create": { + "title": "Opret automatiseringer", + "description": "Tilføj nye automatiseringer." + }, + "edit": { + "title": "Rediger automatiseringer", + "description": "Ændr eksisterende automatiseringer." + }, + "delete": { + "title": "Slet automatiseringer", + "description": "Fjern automatiseringer." + }, + "run": { + "title": "Kør automatiseringer", + "description": "Udløs en automatisering manuelt." + } + }, "newUi": { "sidebar": { "automations": { @@ -12,14 +34,8 @@ "editTitle": "Rediger automatisering", "empty": "Ingen automatiseringer endnu. Opret en for at reagere på en metric, en tidsplan eller en begivenhed.", "emptyRuns": "Ingen løb endnu.", - "emptyChannels": "Ingen kanaler endnu. Tilføj en for at sende notifikationer et sted hen.", - "noChannelsHint": "Ingen kanaler er konfigureret endnu. Tilføj en i fanen Kanaler.", - "addChannel": "Tilføj kanal", - "testChannel": "Prøve", - "channelTestSent": "Testnotifikation sendt", - "channelTestFailed": "Testnotifikation mislykkedes", - "channelDeleted": "Kanal slettet", - "deleteChannelConfirm": "Vil du slette denne kanal? Automatiseringer, der bruger den, vil stoppe med at sende dig notifikationer.", + "channelsHint": "Kanaler er konfigureret i advarsler", + "noChannelsHint": "Beskeden sendes altid til din indbakke. Tilføj kanaler i Beskeder for også at sende den et andet sted hen.", "nameLabel": "Navn", "namePlaceholder": "f.eks. Ryd op i /data når den fyldes op", "nameRequired": "Navn er påkrævet", @@ -79,7 +95,7 @@ "webhook": "Indgående webhook" }, "stepTypes": { - "notify": "Send en notifikation", + "notify": "Send en alarm", "http": "Kald en URL", "run_snippet": "Kør et uddrag", "run_command": "Kør en kommando", @@ -118,7 +134,7 @@ "url": "URL", "method": "Metode", "body": "Legeme", - "channels": "Kanaler", + "channels": "Send også til", "title": "Titel", "message": "Besked", "snippet": "Uddrag", @@ -135,6 +151,16 @@ "onError": { "stop": "Stop løbet", "continue": "Fortsæt" + }, + "needsPlugin": "Behøver {{plugin}}", + "needsPluginHint": "Denne automatisering springes over, indtil den nødvendige funktion er tilgængelig igen.", + "offBadge": "Slukket", + "docsLink": "Se dokumenter", + "ago": { + "seconds": "For {{count}}sekunder siden", + "minutes": "For {{count}}minutter siden", + "hours": "For {{count}}timer siden", + "days": "for {{count}}dage siden" } } } @@ -145,5 +171,41 @@ "onboarding": { "feature_automations": "Automatiseringer", "feature_automations_desc": "Kør trin automatisk, når der sker noget, og få besked." + }, + "maintenance": { + "title": "Opretholdelse", + "description": "Sæt automatiseringer for værtsstatus, tilstand, metrikker, containere og tunnelfrakobling på pause, mens arbejdet er i gang. Overvågning, manuelle kørsel og planlagte automatiseringer fortsætter.", + "denied": "Du har ikke tilladelse til at se vedligeholdelsen.", + "sharedReadOnly": "Denne vært blev delt med dig. Kun dens ejer kan ændre vedligeholdelsen.", + "failed": "Vedligeholdelsen kunne ikke opdateres.", + "active": "Vedligeholdelse aktiv", + "estimated": "Forventet færdiggørelse", + "noAutoEnd": "Estimatet afslutter ikke vedligeholdelsen. Afslut den eksplicit, når arbejdet er færdigt.", + "endConfirm": "Vil du afslutte vedligeholdelsen og genoptage hændelsesudløste automatiseringer for denne vært?", + "confirmEnd": "Bekræft slut", + "cancel": "Ophæve", + "end": "Afslut vedligeholdelse", + "action": "Handling", + "startNow": "Start nu", + "schedule": "Planlæg til senere", + "reason": "Årsag", + "startUtc": "Første start (UTC)", + "repeat": "Gentage", + "once": "Engang", + "weekly": "Ugentlig", + "monthly": "Månedlig", + "utcHelp": "Tidsplaner bruger UTC hele året. Månedlige tidsplaner springer måneder over uden den valgte dag. Planlagte vinduer kan ikke overlappe hinanden; overstyring af vedligeholdelse fortsætter på tværs af senere vinduer.", + "duration": "Estimeret varighed (minutter)", + "grace": "Frist (minutter)", + "notify": "Giv én besked, hvis du stadig er offline efter estimatet plus den henstandsperiode", + "addSchedule": "Tilføj tidsplan", + "schedules": "Tidsplaner", + "noSchedules": "Ingen vedligeholdelsesplaner.", + "completed": "Allerede startet", + "minutes_one": "{{count}} minut", + "minutes_other": "{{count}} minutter", + "remove": "Fjern tidsplan", + "loadFailed": "Vedligeholdelsesstatus kunne ikke opdateres. Ændringer er deaktiveret, indtil den kan indlæses.", + "loading": "Indlæser vedligeholdelsesstatus…" } } diff --git a/plugins/automations/locales/translated/de_DE.json b/plugins/automations/locales/translated/de_DE.json index 035e3a490..9e9842af8 100644 --- a/plugins/automations/locales/translated/de_DE.json +++ b/plugins/automations/locales/translated/de_DE.json @@ -1,4 +1,26 @@ { + "permissions": { + "view": { + "title": "Automatisierungen anzeigen", + "description": "Sehen Sie sich die Automatisierungen und deren Verlauf an." + }, + "create": { + "title": "Automatisierungen erstellen", + "description": "Neue Automatisierungen hinzufügen." + }, + "edit": { + "title": "Automatisierungen bearbeiten", + "description": "Bestehende Automatisierungen ändern." + }, + "delete": { + "title": "Automatisierungen löschen", + "description": "Automatisierungen entfernen." + }, + "run": { + "title": "Automatisierungen ausführen", + "description": "Eine Automatisierung manuell auslösen." + } + }, "newUi": { "sidebar": { "automations": { @@ -12,20 +34,14 @@ "editTitle": "Automatisierung bearbeiten", "empty": "Noch keine Automatisierungen. Erstellen Sie eine, um auf eine Kennzahl, einen Zeitplan oder ein Ereignis zu reagieren.", "emptyRuns": "Bisher keine Läufe.", - "emptyChannels": "Noch keine Kanäle. Fügen Sie einen hinzu, um Benachrichtigungen an einen bestimmten Ort zu senden.", - "noChannelsHint": "Es sind noch keine Kanäle eingerichtet. Fügen Sie einen im Tab „Kanäle“ hinzu.", - "addChannel": "Kanal hinzufügen", - "testChannel": "Prüfen", - "channelTestSent": "Testbenachrichtigung gesendet", - "channelTestFailed": "Testbenachrichtigung fehlgeschlagen", - "channelDeleted": "Kanal gelöscht", - "deleteChannelConfirm": "Diesen Kanal löschen? Automatisierungen, die diesen Kanal verwenden, werden keine Benachrichtigungen mehr senden.", + "channelsHint": "Kanäle werden in den Benachrichtigungen eingerichtet.", + "noChannelsHint": "Die Benachrichtigung wird immer in Ihrem Posteingang angezeigt. Fügen Sie in den Benachrichtigungen Kanäle hinzu, um sie auch an andere Orte zu senden.", "nameLabel": "Name", "namePlaceholder": "z.B. das Verzeichnis /data leeren, wenn es voll ist", - "nameRequired": "Name erforderlich", + "nameRequired": "Name ist erforderlich", "descriptionLabel": "Beschreibung", "descriptionPlaceholder": "Optionale Beschreibung", - "enabledLabel": "Ermöglicht", + "enabledLabel": "Aktiviert", "concurrencyLabel": "Wenn es bereits läuft", "concurrencyHint": "Was ist zu tun, wenn dies erneut ausgelöst wird, bevor der letzte Durchlauf abgeschlossen ist?", "concurrency": { @@ -43,7 +59,7 @@ "testRunHint": "Führt jeden Schritt aus, greift aber auf nichts außerhalb von Termix ein.", "runStarted": "Lauf gestartet", "runFinished": "Lauf beendet: {{status}}", - "trigger": "Auslösen", + "trigger": "Auslöser", "steps": "Schritte", "addStep": "Schritt hinzufügen", "removeStep": "Schritt entfernen", @@ -52,13 +68,13 @@ "noSteps": "Noch keine Schritte. Füge einen hinzu, um zu beschreiben, was passieren soll.", "webhookTokenTitle": "Webhook-URL", "webhookTokenDescription": "Dies wird nur einmal angezeigt. Speichern Sie es jetzt, es kann später nicht mehr abgerufen werden.", - "copy": "Kopie", + "copy": "Kopieren", "copied": "Kopiert", "viewJson": "JSON", "viewBuilder": "Bauherr", "viewGraph": "Graph", "lastRun": "Letzter Lauf", - "never": "Niemals", + "never": "Nie", "duration": "{{seconds}}s", "stepOutput": "Ausgabe", "stepError": "Fehler", @@ -67,7 +83,7 @@ "trigger": "Auslösender Host", "host": "Spezifischer Wirt", "fleet": "Flotte", - "all": "Alle Gastgeber" + "all": "Alle Hosts" }, "triggerKinds": { "metric_threshold": "Metrischer Schwellenwert", @@ -79,7 +95,7 @@ "webhook": "Eingehender Webhook" }, "stepTypes": { - "notify": "Sende eine Benachrichtigung", + "notify": "Benachrichtigung senden", "http": "URL aufrufen", "run_snippet": "Führe einen Codeausschnitt aus", "run_command": "Führe einen Befehl aus", @@ -94,20 +110,20 @@ }, "statuses": { "running": "Läuft", - "success": "Erfolg", + "success": "Erfolgreich", "failed": "Fehlgeschlagen", "timeout": "Zeitüberschreitung", "skipped": "Übersprungen", "cancelled": "Abgesagt" }, "fields": { - "host": "Gastgeber", - "metric": "Metrisch", + "host": "Host", + "metric": "Metrik", "mount": "Montagepunkt", "operator": "Ist", "value": "Wert", "forSeconds": "Anhaltend für (Sekunden)", - "cooldown": "Abkühlzeit (Minuten)", + "cooldown": "Abklingzeit (Minuten)", "cron": "Cron-Ausdruck", "intervalSeconds": "Alle (Sekunden)", "timezone": "Zeitzone", @@ -118,7 +134,7 @@ "url": "URL", "method": "Verfahren", "body": "Körper", - "channels": "Kanäle", + "channels": "Bitte auch senden an", "title": "Titel", "message": "Nachricht", "snippet": "Ausschnitt", @@ -135,6 +151,16 @@ "onError": { "stop": "Stoppt die Flucht!", "continue": "Weiter geht's" + }, + "needsPlugin": "Benötigt {{plugin}}", + "needsPluginHint": "Diese Automatisierung wird übersprungen, bis die benötigte Funktion wieder verfügbar ist.", + "offBadge": "Aus", + "docsLink": "Dokumentation ansehen", + "ago": { + "seconds": "{{count}}s ago", + "minutes": "vor {{count}} Min.", + "hours": "vor {{count}} Std.", + "days": "vor {{count}} Tagen" } } } @@ -145,5 +171,41 @@ "onboarding": { "feature_automations": "Automatisierungen", "feature_automations_desc": "Schritte automatisch ausführen, wenn etwas passiert, und Benachrichtigungen erhalten." + }, + "maintenance": { + "title": "Wartung", + "description": "Die Automatisierungen für Hoststatus, Integrität, Metriken, Container- und Tunnel-Trennung werden während der laufenden Arbeiten pausiert. Überwachung, manuelle Ausführungen und geplante Automatisierungen werden fortgesetzt.", + "denied": "Sie haben keine Berechtigung, Wartungsarbeiten anzuzeigen.", + "sharedReadOnly": "Dieser Host wurde Ihnen zur Verfügung gestellt. Nur der Eigentümer kann Wartungsänderungen vornehmen.", + "failed": "Die Wartungsarbeiten konnten nicht aktualisiert werden.", + "active": "Wartung aktiv", + "estimated": "Voraussichtlicher Abschluss", + "noAutoEnd": "Die Kostenschätzung beendet die Wartungsarbeiten nicht. Beenden Sie sie explizit, sobald die Arbeiten abgeschlossen sind.", + "endConfirm": "Wartungsarbeiten beenden und ereignisgesteuerte Automatisierungen für diesen Host wiederaufnehmen?", + "confirmEnd": "Ende bestätigen", + "cancel": "Abbrechen", + "end": "Wartungsarbeiten beenden", + "action": "Aktion", + "startNow": "Jetzt starten", + "schedule": "Termin für später", + "reason": "Grund", + "startUtc": "Erster Start (UTC)", + "repeat": "Wiederholen", + "once": "Einmal", + "weekly": "Wöchentlich", + "monthly": "Monatlich", + "utcHelp": "Die Zeitpläne verwenden ganzjährig UTC. Monatliche Zeitpläne überspringen Monate ohne den ausgewählten Tag. Geplante Zeiträume dürfen sich nicht überschneiden; Wartungsarbeiten, die über die vereinbarten Zeiträume hinausgehen, werden fortgesetzt.", + "duration": "Geschätzte Dauer (Minuten)", + "grace": "Kulanzfrist (Minuten)", + "notify": "Benachrichtigen Sie uns einmalig, falls Sie nach Ablauf der Schätzung und der Kulanzfrist immer noch offline sind.", + "addSchedule": "Zeitplan hinzufügen", + "schedules": "Zeitpläne", + "noSchedules": "Keine Wartungspläne.", + "completed": "Bereits begonnen", + "minutes_one": "{{count}} Minute", + "minutes_other": "{{count}} Minuten", + "remove": "Zeitplan entfernen", + "loadFailed": "Der Wartungsstatus konnte nicht aktualisiert werden. Änderungen sind deaktiviert, bis die Daten geladen werden können.", + "loading": "Lade Wartungsstatus…" } } diff --git a/plugins/automations/locales/translated/el_GR.json b/plugins/automations/locales/translated/el_GR.json index 614728faa..116e2b767 100644 --- a/plugins/automations/locales/translated/el_GR.json +++ b/plugins/automations/locales/translated/el_GR.json @@ -1,4 +1,26 @@ { + "permissions": { + "view": { + "title": "Προβολή αυτοματισμών", + "description": "Δείτε τους αυτοματισμούς και το ιστορικό τους." + }, + "create": { + "title": "Δημιουργήστε αυτοματισμούς", + "description": "Προσθήκη νέων αυτοματισμών." + }, + "edit": { + "title": "Επεξεργασία αυτοματισμών", + "description": "Αλλαγή υπαρχόντων αυτοματισμών." + }, + "delete": { + "title": "Διαγραφή αυτοματισμών", + "description": "Αφαίρεση αυτοματισμών." + }, + "run": { + "title": "Εκτέλεση αυτοματισμών", + "description": "Ενεργοποιήστε έναν αυτοματισμό χειροκίνητα." + } + }, "newUi": { "sidebar": { "automations": { @@ -12,14 +34,8 @@ "editTitle": "Επεξεργασία αυτοματισμού", "empty": "Δεν υπάρχουν ακόμη αυτοματοποιήσεις. Δημιουργήστε μία για να αντιδράτε σε μια μέτρηση, ένα πρόγραμμα ή ένα συμβάν.", "emptyRuns": "Δεν υπάρχουν τρεξίματα ακόμα.", - "emptyChannels": "Δεν υπάρχουν ακόμη κανάλια. Προσθέστε ένα για να στέλνετε ειδοποιήσεις κάπου.", - "noChannelsHint": "Δεν έχουν ρυθμιστεί ακόμη κανάλια. Προσθέστε ένα στην καρτέλα Κανάλια.", - "addChannel": "Προσθήκη καναλιού", - "testChannel": "Δοκιμή", - "channelTestSent": "Αποστολή ειδοποίησης δοκιμής", - "channelTestFailed": "Η ειδοποίηση δοκιμής απέτυχε.", - "channelDeleted": "Το κανάλι διαγράφηκε", - "deleteChannelConfirm": "Διαγραφή αυτού του καναλιού; Οι αυτοματοποιήσεις που το χρησιμοποιούν θα σταματήσουν να ειδοποιούν.", + "channelsHint": "Τα κανάλια έχουν ρυθμιστεί στις Ειδοποιήσεις", + "noChannelsHint": "Η ειδοποίηση αποστέλλεται πάντα στα εισερχόμενά σας. Προσθέστε κανάλια στις Ειδοποιήσεις για να την στείλετε και κάπου αλλού.", "nameLabel": "Ονομα", "namePlaceholder": "π.χ., Καθαρισμός /data όταν γεμίσει", "nameRequired": "Απαιτείται όνομα", @@ -118,7 +134,7 @@ "url": "URL", "method": "Μέθοδος", "body": "Σώμα", - "channels": "Κανάλια", + "channels": "Αποστολή επίσης σε", "title": "Τίτλος", "message": "Μήνυμα", "snippet": "Απόσπασμα", @@ -135,6 +151,16 @@ "onError": { "stop": "Σταμάτα το τρέξιμο", "continue": "Συνεχίζω" + }, + "needsPlugin": "Ανάγκες {{plugin}}", + "needsPluginHint": "Αυτή η αυτοματοποίηση παραλείπεται μέχρι να γίνει ξανά διαθέσιμη η λειτουργία που χρειάζεται.", + "offBadge": "Μακριά από", + "docsLink": "Προβολή εγγράφων", + "ago": { + "seconds": "{{count}}πριν από s", + "minutes": "{{count}}πριν από λεπτά", + "hours": "{{count}}πριν από ώρες", + "days": "{{count}}πριν από ημέρες" } } } @@ -145,5 +171,41 @@ "onboarding": { "feature_automations": "Αυτοματισμοί", "feature_automations_desc": "Εκτελέστε αυτόματα βήματα όταν συμβεί κάτι και λάβετε ειδοποίηση." + }, + "maintenance": { + "title": "Συντήρηση", + "description": "Παύση των αυτοματισμών κατάστασης κεντρικού υπολογιστή, εύρυθμης λειτουργίας, μετρήσεων, κοντέινερ και αποσύνδεσης σήραγγας ενώ οι εργασίες βρίσκονται σε εξέλιξη. Η παρακολούθηση, οι χειροκίνητες εκτελέσεις και οι προγραμματισμένοι αυτοματισμοί συνεχίζονται.", + "denied": "Δεν έχετε άδεια προβολής συντήρησης.", + "sharedReadOnly": "Αυτός ο κεντρικός υπολογιστής κοινοποιήθηκε σε εσάς. Μόνο ο κάτοχός του μπορεί να αλλάξει τη συντήρηση.", + "failed": "Δεν ήταν δυνατή η ενημέρωση της συντήρησης.", + "active": "Ενεργή συντήρηση", + "estimated": "Εκτιμώμενη ολοκλήρωση", + "noAutoEnd": "Η εκτίμηση κόστους δεν τερματίζει τη συντήρηση. Τερματίζει ρητά όταν ολοκληρωθεί η εργασία.", + "endConfirm": "Να τερματιστεί η συντήρηση και να συνεχιστούν οι αυτοματοποιήσεις που ενεργοποιούνται από συμβάντα για αυτόν τον κεντρικό υπολογιστή;", + "confirmEnd": "Επιβεβαίωση τέλους", + "cancel": "Ματαίωση", + "end": "Τέλος συντήρησης", + "action": "Δράση", + "startNow": "Ξεκινήστε τώρα", + "schedule": "Προγραμματισμός για αργότερα", + "reason": "Λόγος", + "startUtc": "Πρώτη εκκίνηση (UTC)", + "repeat": "Επαναλαμβάνω", + "once": "Μια φορά", + "weekly": "Εβδομαδιαίος", + "monthly": "Μηνιαίος", + "utcHelp": "Τα χρονοδιαγράμματα χρησιμοποιούν UTC καθ' όλη τη διάρκεια του έτους. Τα μηνιαία χρονοδιαγράμματα παραλείπουν μήνες χωρίς την επιλεγμένη ημέρα. Τα προγραμματισμένα παράθυρα δεν μπορούν να επικαλύπτονται. Η συντήρηση που εκτελείται εκτός προγράμματος συνεχίζεται και σε μεταγενέστερα παράθυρα.", + "duration": "Εκτιμώμενη διάρκεια (λεπτά)", + "grace": "Περίοδος χάριτος (λεπτά)", + "notify": "Ειδοποιήστε μία φορά εάν εξακολουθείτε να είστε εκτός σύνδεσης μετά την εκτίμηση συν την περίοδο χάριτος", + "addSchedule": "Προσθήκη χρονοδιαγράμματος", + "schedules": "Δρομολόγια", + "noSchedules": "Δεν υπάρχουν χρονοδιαγράμματα συντήρησης.", + "completed": "Ήδη ξεκίνησε", + "minutes_one": "{{count}} λεπτό", + "minutes_other": "{{count}} λεπτά", + "remove": "Κατάργηση χρονοδιαγράμματος", + "loadFailed": "Δεν ήταν δυνατή η ανανέωση της κατάστασης συντήρησης. Οι αλλαγές είναι απενεργοποιημένες μέχρι να είναι δυνατή η φόρτωσή τους.", + "loading": "Φόρτωση κατάστασης συντήρησης…" } } diff --git a/plugins/automations/locales/translated/es_ES.json b/plugins/automations/locales/translated/es_ES.json index 47226cef4..6daf1c195 100644 --- a/plugins/automations/locales/translated/es_ES.json +++ b/plugins/automations/locales/translated/es_ES.json @@ -1,4 +1,26 @@ { + "permissions": { + "view": { + "title": "Ver automatizaciones", + "description": "Consulta las automatizaciones y su historial." + }, + "create": { + "title": "Crear automatizaciones", + "description": "Agregar nuevas automatizaciones." + }, + "edit": { + "title": "Editar automatizaciones", + "description": "Modificar las automatizaciones existentes." + }, + "delete": { + "title": "Eliminar automatizaciones", + "description": "Eliminar automatizaciones." + }, + "run": { + "title": "Ejecutar automatizaciones", + "description": "Activar una automatización manualmente." + } + }, "newUi": { "sidebar": { "automations": { @@ -12,17 +34,11 @@ "editTitle": "Automatización de edición", "empty": "Aún no hay automatizaciones. Crea una para que reaccione a una métrica, una programación o un evento.", "emptyRuns": "Aún no hay carreras.", - "emptyChannels": "Aún no hay canales. Añade uno para enviar notificaciones a algún lugar.", - "noChannelsHint": "Aún no hay canales configurados. Añade uno en la pestaña Canales.", - "addChannel": "Agregar canal", - "testChannel": "Prueba", - "channelTestSent": "Notificación de prueba enviada", - "channelTestFailed": "Falló la notificación de prueba", - "channelDeleted": "Canal eliminado", - "deleteChannelConfirm": "¿Eliminar este canal? Las automatizaciones que lo utilicen dejarán de enviar notificaciones.", + "channelsHint": "Los canales se configuran en Alertas.", + "noChannelsHint": "La alerta siempre llega a tu bandeja de entrada. Agrega canales en Alertas para enviarla también a otros lugares.", "nameLabel": "Nombre", "namePlaceholder": "Por ejemplo, limpiar /data cuando se llena", - "nameRequired": "Se requiere el nombre", + "nameRequired": "El nombre es obligatorio", "descriptionLabel": "Descripción", "descriptionPlaceholder": "Descripción opcional", "enabledLabel": "Activado", @@ -31,9 +47,9 @@ "concurrency": { "skip": "Saltarse la nueva carrera", "queue": "Espera y corre tras", - "allow": "Ejecuta ambos a la vez" + "allow": "Ejecutar ambos a la vez" }, - "save": "Ahorrar", + "save": "Guardar", "created": "Automatización creada", "updated": "Automatización guardada", "deleted": "Automatización eliminada", @@ -43,7 +59,7 @@ "testRunHint": "Ejecuta todos los pasos, pero no toca nada fuera de Termix.", "runStarted": "La carrera ha comenzado.", "runFinished": "Ejecución finalizada: {{status}}", - "trigger": "Desencadenar", + "trigger": "Disparador", "steps": "Pasos", "addStep": "Agregar paso", "removeStep": "Eliminar paso", @@ -60,14 +76,14 @@ "lastRun": "Última carrera", "never": "Nunca", "duration": "{{seconds}}s", - "stepOutput": "Producción", + "stepOutput": "Salida", "stepError": "Error", "dryRunBadge": "Ejecución de prueba", "hostSelector": { "trigger": "Host desencadenante", "host": "Anfitrión específico", "fleet": "Flota", - "all": "Todos los anfitriones" + "all": "Todos los hosts" }, "triggerKinds": { "metric_threshold": "Umbral métrico", @@ -79,7 +95,7 @@ "webhook": "Webhook entrante" }, "stepTypes": { - "notify": "Enviar una notificación", + "notify": "Enviar alerta", "http": "Llamar a una URL", "run_snippet": "Ejecutar un fragmento", "run_command": "Ejecutar un comando", @@ -90,10 +106,10 @@ "set_var": "Establecer una variable", "if": "Si / de lo contrario", "run_automation": "Ejecuta otra automatización", - "stop": "Detener" + "stop": "Parada" }, "statuses": { - "running": "Correr", + "running": "En ejecución", "success": "Éxito", "failed": "Fallido", "timeout": "Tiempo de espera agotado", @@ -101,24 +117,24 @@ "cancelled": "Cancelado" }, "fields": { - "host": "Anfitrión", - "metric": "Métrico", + "host": "Host", + "metric": "Métrica", "mount": "Punto de montaje", "operator": "Es", "value": "Valor", "forSeconds": "Mantenido durante (segundos)", - "cooldown": "Tiempo de enfriamiento (minutos)", + "cooldown": "Tiempo de espera (minutos)", "cron": "Expresión cron", "intervalSeconds": "Cada (segundos)", "timezone": "Huso horario", "timezoneServer": "Hora del servidor", "timezoneHint": "En esta zona se leen las horas cron. No se aplica a los horarios de intervalo.", "container": "Recipiente", - "command": "Dominio", + "command": "Comando", "url": "URL", "method": "Método", "body": "Cuerpo", - "channels": "Canales", + "channels": "También enviar a", "title": "Título", "message": "Mensaje", "snippet": "Retazo", @@ -135,6 +151,16 @@ "onError": { "stop": "Detengan la carrera", "continue": "Continuar" + }, + "needsPlugin": "Necesidades {{plugin}}", + "needsPluginHint": "Esta automatización se omite hasta que la función que necesita vuelva a estar disponible.", + "offBadge": "Desactivado", + "docsLink": "Ver documentación", + "ago": { + "seconds": "{{count}}hace s", + "minutes": "hace {{count}}m", + "hours": "hace {{count}}h", + "days": "hace {{count}}d" } } } @@ -145,5 +171,41 @@ "onboarding": { "feature_automations": "Automatizaciones", "feature_automations_desc": "Ejecuta pasos automáticamente cuando ocurra algo y recibe notificaciones." + }, + "maintenance": { + "title": "Mantenimiento", + "description": "Se pausan las automatizaciones de estado del host, salud, métricas, contenedores y desconexión de túneles mientras se realiza el trabajo. La monitorización, las ejecuciones manuales y las automatizaciones programadas continúan.", + "denied": "No tienes permiso para ver el mantenimiento.", + "sharedReadOnly": "Este servidor se ha compartido contigo. Solo su propietario puede modificar el mantenimiento.", + "failed": "No se pudo actualizar el mantenimiento.", + "active": "Mantenimiento activo", + "estimated": "Finalización estimada", + "noAutoEnd": "El presupuesto no pone fin al mantenimiento. Finalícelo explícitamente cuando el trabajo esté terminado.", + "endConfirm": "¿Finalizar el mantenimiento y reanudar las automatizaciones activadas por eventos para este host?", + "confirmEnd": "Confirmar fin", + "cancel": "Cancelar", + "end": "Fin del mantenimiento", + "action": "Acción", + "startNow": "Empieza ahora", + "schedule": "Programar para más tarde", + "reason": "Razón", + "startUtc": "Primer inicio (UTC)", + "repeat": "Repetir", + "once": "Una vez", + "weekly": "Semanalmente", + "monthly": "Mensual", + "utcHelp": "Los horarios utilizan UTC durante todo el año. Los horarios mensuales omiten los meses que no incluyen el día seleccionado. Los periodos de mantenimiento planificados no pueden superponerse; el mantenimiento prolongado continúa en los periodos posteriores.", + "duration": "Duración estimada (minutos)", + "grace": "Período de gracia (minutos)", + "notify": "Notificar una vez si sigue sin conexión después del período estimado más el período de gracia.", + "addSchedule": "Agregar horario", + "schedules": "Horarios", + "noSchedules": "Sin programas de mantenimiento.", + "completed": "Ya ha comenzado", + "minutes_one": "{{count}} minuto", + "minutes_other": "{{count}} minutos", + "remove": "Eliminar horario", + "loadFailed": "No se pudo actualizar el estado de mantenimiento. Los cambios están deshabilitados hasta que se puedan cargar.", + "loading": "Cargando estado de mantenimiento…" } } diff --git a/plugins/automations/locales/translated/fi_FI.json b/plugins/automations/locales/translated/fi_FI.json index 416104441..f18d8a66b 100644 --- a/plugins/automations/locales/translated/fi_FI.json +++ b/plugins/automations/locales/translated/fi_FI.json @@ -1,4 +1,26 @@ { + "permissions": { + "view": { + "title": "Näytä automaatiot", + "description": "Katso automaatiot ja niiden historia." + }, + "create": { + "title": "Luo automaatioita", + "description": "Lisää uusia automaatioita." + }, + "edit": { + "title": "Muokkaa automaatioita", + "description": "Muuta olemassa olevia automaatioita." + }, + "delete": { + "title": "Poista automaatiot", + "description": "Poista automaatiot." + }, + "run": { + "title": "Suorita automaatioita", + "description": "Käynnistä automaatio manuaalisesti." + } + }, "newUi": { "sidebar": { "automations": { @@ -12,14 +34,8 @@ "editTitle": "Muokkaa automatisointia", "empty": "Ei vielä automaatioita. Luo sellainen reagoimaan mittariin, aikatauluun tai tapahtumaan.", "emptyRuns": "Ei vielä juoksuja.", - "emptyChannels": "Ei kanavia vielä. Lisää yksi lähettääksesi ilmoituksia jonnekin.", - "noChannelsHint": "Kanavia ei ole vielä määritetty. Lisää yksi Kanavat-välilehdellä.", - "addChannel": "Lisää kanava", - "testChannel": "Testata", - "channelTestSent": "Testi-ilmoitus lähetetty", - "channelTestFailed": "Testi-ilmoitus epäonnistui", - "channelDeleted": "Kanava poistettu", - "deleteChannelConfirm": "Poistetaanko tämä kanava? Sitä käyttävät automaatiot lakkaavat lähettämästä ilmoituksia.", + "channelsHint": "Kanavat määritetään Hälytykset-kohdassa", + "noChannelsHint": "Ilmoitus menee aina postilaatikkoosi. Lisää kanavia Ilmoitukset-kohtaan lähettääksesi sen myös muualle.", "nameLabel": "Nimi", "namePlaceholder": "esim. Siivoa /data, kun se täyttyy", "nameRequired": "Nimi on pakollinen", @@ -79,7 +95,7 @@ "webhook": "Saapuva webhook" }, "stepTypes": { - "notify": "Lähetä ilmoitus", + "notify": "Lähetä hälytys", "http": "Soita URL-osoitteeseen", "run_snippet": "Suorita koodinpätkä", "run_command": "Suorita komento", @@ -118,7 +134,7 @@ "url": "URL-osoite", "method": "Menetelmä", "body": "Keho", - "channels": "Kanavat", + "channels": "Lähetä myös osoitteeseen", "title": "Otsikko", "message": "Viesti", "snippet": "Katkelma", @@ -135,6 +151,16 @@ "onError": { "stop": "Pysäytä juoksu", "continue": "Jatkaa" + }, + "needsPlugin": "Tarpeet {{plugin}}", + "needsPluginHint": "Tämä automaatio ohitetaan, kunnes sen tarvitsema ominaisuus on taas käytettävissä.", + "offBadge": "Pois", + "docsLink": "Näytä dokumentit", + "ago": { + "seconds": "{{count}}s sitten", + "minutes": "{{count}}minuuttia sitten", + "hours": "{{count}}tuntia sitten", + "days": "{{count}}d sitten" } } } @@ -145,5 +171,41 @@ "onboarding": { "feature_automations": "Automaatiot", "feature_automations_desc": "Suorita vaiheet automaattisesti, kun jotain tapahtuu, ja saat ilmoituksen." + }, + "maintenance": { + "title": "Huolto", + "description": "Keskeytä isännän tilan, kunnon, mittareiden, säilön ja tunnelin katkaisun automatisoinnit työn ollessa käynnissä. Valvonta, manuaaliset suoritukset ja ajoitetut automatisoinnit jatkuvat.", + "denied": "Sinulla ei ole oikeutta tarkastella ylläpitoa.", + "sharedReadOnly": "Tämä isäntä jaettiin kanssasi. Vain sen omistaja voi muuttaa ylläpitoa.", + "failed": "Ylläpitoa ei voitu päivittää.", + "active": "Huolto aktiivinen", + "estimated": "Arvioitu valmistuminen", + "noAutoEnd": "Arvio ei lopeta huoltoa. Lopeta se nimenomaisesti, kun työ on valmis.", + "endConfirm": "Lopetetaanko ylläpito ja jatketaanko tapahtumien laukaisemia automaatioita tälle isännälle?", + "confirmEnd": "Vahvista loppu", + "cancel": "Peruuttaa", + "end": "Huoltopäätös", + "action": "Toiminta", + "startNow": "Aloita nyt", + "schedule": "Aikatauluta myöhemmin", + "reason": "Syy", + "startUtc": "Ensimmäinen lähtö (UTC)", + "repeat": "Toistaa", + "once": "Kerran", + "weekly": "Viikoittain", + "monthly": "Kuukausittain", + "utcHelp": "Aikataulut käyttävät UTC-aikaa ympäri vuoden. Kuukausiaikataulut ohittavat kuukaudet, joilla ei ole valittua päivää. Suunnitellut ikkunat eivät voi olla päällekkäisiä; ylikuormittava huolto jatkuu myöhemmissä ikkuna-ajoissa.", + "duration": "Arvioitu kesto (minuutteina)", + "grace": "Lisäaika (minuutteina)", + "notify": "Ilmoita kerran, jos olet edelleen offline-tilassa arvion ja lisäajan jälkeen", + "addSchedule": "Lisää aikataulu", + "schedules": "Aikataulut", + "noSchedules": "Ei huoltoaikatauluja.", + "completed": "Jo aloitettu", + "minutes_one": "{{count}} minuutti", + "minutes_other": "{{count}} minuuttia", + "remove": "Poista aikataulu", + "loadFailed": "Ylläpidon tilaa ei voitu päivittää. Muutokset on poistettu käytöstä, kunnes ne voidaan ladata.", + "loading": "Ladataan ylläpitotilaa…" } } diff --git a/plugins/automations/locales/translated/fr_FR.json b/plugins/automations/locales/translated/fr_FR.json index 2186f410f..628674df9 100644 --- a/plugins/automations/locales/translated/fr_FR.json +++ b/plugins/automations/locales/translated/fr_FR.json @@ -1,28 +1,44 @@ { + "permissions": { + "view": { + "title": "Afficher les automatisations", + "description": "Consultez les automatisations et leur historique." + }, + "create": { + "title": "Créer des automatisations", + "description": "Ajouter de nouvelles automatisations." + }, + "edit": { + "title": "Modifier les automatisations", + "description": "Modifier les automatisations existantes." + }, + "delete": { + "title": "Supprimer les automatisations", + "description": "Supprimer les automatisations." + }, + "run": { + "title": "Exécuter des automatisations", + "description": "Déclencher une automatisation manuellement." + } + }, "newUi": { "sidebar": { "automations": { "title": "Automatisations", "tabAutomations": "Automatisations", "tabRuns": "Courses", - "tabChannels": "Chaînes", + "tabChannels": "Canaux", "createAutomation": "Nouvelle automatisation", "backToAutomations": "Retour aux automatisations", "createTitle": "Nouvelle automatisation", "editTitle": "Automatisation de la modification", "empty": "Aucune automatisation pour le moment. Créez-en une pour qu'elle réagisse à une mesure, une planification ou un événement.", "emptyRuns": "Pas encore de runs.", - "emptyChannels": "Aucun canal pour le moment. Ajoutez-en un pour envoyer des notifications.", - "noChannelsHint": "Aucune chaîne n'est encore configurée. Ajoutez-en une dans l'onglet Chaînes.", - "addChannel": "Ajouter une chaîne", - "testChannel": "Test", - "channelTestSent": "Notification de test envoyée", - "channelTestFailed": "La notification de test a échoué", - "channelDeleted": "Chaîne supprimée", - "deleteChannelConfirm": "Supprimer ce canal ? Les automatisations qui l'utilisent cesseront d'envoyer des notifications.", + "channelsHint": "Les canaux sont configurés dans les alertes", + "noChannelsHint": "L'alerte est toujours envoyée dans votre boîte de réception. Ajoutez des canaux dans les alertes pour la diffuser également ailleurs.", "nameLabel": "Nom", "namePlaceholder": "Par exemple, nettoyer le répertoire /data lorsqu'il est plein.", - "nameRequired": "Le nom est requis.", + "nameRequired": "Le nom est obligatoire", "descriptionLabel": "Description", "descriptionPlaceholder": "Description facultative", "enabledLabel": "Activé", @@ -33,7 +49,7 @@ "queue": "Attendez et courez après", "allow": "Exécutez les deux simultanément." }, - "save": "Sauvegarder", + "save": "Enregistrer", "created": "L'automatisation a créé", "updated": "L'automatisation a permis de sauver", "deleted": "Automatisation supprimée", @@ -43,7 +59,7 @@ "testRunHint": "Exécute chaque étape mais ne touche à rien en dehors de Termix.", "runStarted": "La course a commencé", "runFinished": "Course terminée : {{status}}", - "trigger": "Déclenchement", + "trigger": "Déclencheur", "steps": "Mesures", "addStep": "Ajouter une étape", "removeStep": "Supprimer l'étape", @@ -52,7 +68,7 @@ "noSteps": "Aucune étape pour l'instant. Ajoutez-en une pour décrire ce qui doit se passer.", "webhookTokenTitle": "URL du webhook", "webhookTokenDescription": "Ceci ne s'affiche qu'une seule fois. Enregistrez-le maintenant, il ne pourra pas être récupéré ultérieurement.", - "copy": "Copie", + "copy": "Copier", "copied": "Copié", "viewJson": "JSON", "viewBuilder": "Constructeur", @@ -60,7 +76,7 @@ "lastRun": "Dernière course", "never": "Jamais", "duration": "{{seconds}}s", - "stepOutput": "Sortir", + "stepOutput": "Sortie", "stepError": "Erreur", "dryRunBadge": "Essai", "hostSelector": { @@ -79,7 +95,7 @@ "webhook": "Webhook entrant" }, "stepTypes": { - "notify": "Envoyer une notification", + "notify": "Envoyer une alerte", "http": "Appeler une URL", "run_snippet": "Exécuter un extrait de code", "run_command": "Exécuter une commande", @@ -90,12 +106,12 @@ "set_var": "Définir une variable", "if": "Si / sinon", "run_automation": "Exécutez une autre automatisation", - "stop": "Arrêt" + "stop": "Stop" }, "statuses": { - "running": "En cours d'exécution", + "running": "En cours d’exécution", "success": "Succès", - "failed": "Échoué", + "failed": "Échec", "timeout": "Délai d'attente dépassé", "skipped": "Omission", "cancelled": "Annulé" @@ -107,7 +123,7 @@ "operator": "Est", "value": "Valeur", "forSeconds": "Maintenu pendant (secondes)", - "cooldown": "Temps de récupération (minutes)", + "cooldown": "Temporisation (minutes)", "cron": "Expression de Cron", "intervalSeconds": "Toutes les (secondes)", "timezone": "Fuseau horaire", @@ -118,7 +134,7 @@ "url": "URL", "method": "Méthode", "body": "Corps", - "channels": "Chaînes", + "channels": "Envoyer également à", "title": "Titre", "message": "Message", "snippet": "Fragment", @@ -135,6 +151,16 @@ "onError": { "stop": "Arrêtez la course", "continue": "Continuer" + }, + "needsPlugin": "Besoins {{plugin}}", + "needsPluginHint": "Cette automatisation est suspendue jusqu'à ce que la fonctionnalité nécessaire soit de nouveau disponible.", + "offBadge": "Désactivée", + "docsLink": "Voir la documentation", + "ago": { + "seconds": "{{count}}il y a s", + "minutes": "il y a {{count}} min", + "hours": "il y a {{count}} h", + "days": "il y a {{count}} j" } } } @@ -145,5 +171,41 @@ "onboarding": { "feature_automations": "Automatisations", "feature_automations_desc": "Exécutez des actions automatiquement lorsqu'un événement se produit et recevez une notification." + }, + "maintenance": { + "title": "Maintenance", + "description": "Suspendez les automatisations relatives à l'état des hôtes, à leur santé, aux métriques, aux conteneurs et à la déconnexion des tunnels pendant la durée de l'opération. La surveillance, les exécutions manuelles et les automatisations planifiées se poursuivent.", + "denied": "Vous n'êtes pas autorisé à consulter les informations de maintenance.", + "sharedReadOnly": "Cet hébergement vous a été proposé à la location. Seul son propriétaire peut en modifier la maintenance.", + "failed": "La maintenance n'a pas pu être mise à jour.", + "active": "Maintenance active", + "estimated": "Achèvement estimé", + "noAutoEnd": "Le devis ne met pas fin à la maintenance. Il faut y mettre fin explicitement une fois les travaux terminés.", + "endConfirm": "Mettre fin à la maintenance et reprendre les automatisations déclenchées par des événements pour cet hôte ?", + "confirmEnd": "Confirmer la fin", + "cancel": "Annuler", + "end": "Maintenance finale", + "action": "Action", + "startNow": "Commencez maintenant", + "schedule": "Planifiez plus tard", + "reason": "Raison", + "startUtc": "Premier démarrage (UTC)", + "repeat": "Répéter", + "once": "Une fois", + "weekly": "Hebdomadaire", + "monthly": "Mensuel", + "utcHelp": "Les planifications utilisent le temps universel coordonné (UTC) tout au long de l'année. Les planifications mensuelles ignorent les mois sans le jour sélectionné. Les fenêtres de planification ne peuvent pas se chevaucher ; la maintenance en cours se poursuit sur les fenêtres suivantes.", + "duration": "Durée estimée (minutes)", + "grace": "Délai de grâce (minutes)", + "notify": "Veuillez nous informer une seule fois si nous sommes toujours hors ligne après la période estimée et le délai de grâce. Veuillez nous avertir une fois si nous sommes toujours hors ligne après la période estimée et le délai de grâce.", + "addSchedule": "Ajouter un horaire", + "schedules": "Horaires", + "noSchedules": "Aucun programme de maintenance.", + "completed": "Déjà commencé", + "minutes_one": "{{count}} minute", + "minutes_other": "{{count}} minutes", + "remove": "Supprimer le planning", + "loadFailed": "Impossible d'actualiser l'état de maintenance. Les modifications sont désactivées jusqu'à ce que le chargement soit possible.", + "loading": "État de la maintenance en cours de chargement…" } } diff --git a/plugins/automations/locales/translated/he_IL.json b/plugins/automations/locales/translated/he_IL.json index 930eef807..7e0312d94 100644 --- a/plugins/automations/locales/translated/he_IL.json +++ b/plugins/automations/locales/translated/he_IL.json @@ -1,4 +1,26 @@ { + "permissions": { + "view": { + "title": "הצג אוטומציות", + "description": "ראה את האוטומציות ואת ההיסטוריה שלהן." + }, + "create": { + "title": "צור אוטומציות", + "description": "הוסף אוטומציות חדשות." + }, + "edit": { + "title": "עריכת אוטומציות", + "description": "שינוי אוטומציות קיימות." + }, + "delete": { + "title": "מחיקת אוטומציות", + "description": "הסר אוטומציות." + }, + "run": { + "title": "הפעלת אוטומציות", + "description": "הפעל אוטומציה באופן ידני." + } + }, "newUi": { "sidebar": { "automations": { @@ -12,14 +34,8 @@ "editTitle": "עריכה אוטומציה", "empty": "אין עדיין אוטומציות. צור אחת שתגיב למדד, לוח זמנים או אירוע.", "emptyRuns": "עדיין אין ריצות.", - "emptyChannels": "אין עדיין ערוצים. הוסף ערוצים כדי לשלוח התראות לאנשהו.", - "noChannelsHint": "עדיין לא הוגדרו ערוצים. הוסף אחד בכרטיסייה ערוצים.", - "addChannel": "הוסף ערוץ", - "testChannel": "מִבְחָן", - "channelTestSent": "הודעת בדיקה נשלחה", - "channelTestFailed": "הודעת הבדיקה נכשלה", - "channelDeleted": "הערוץ נמחק", - "deleteChannelConfirm": "למחוק את הערוץ הזה? אוטומציות המשתמשות בו יפסיקו לשלוח התראות.", + "channelsHint": "ערוצים מוגדרים בהתראות", + "noChannelsHint": "ההתראה תמיד מגיעה לתיבת הדואר הנכנס שלך. הוסף ערוצים בהתראות כדי לשלוח אותה גם למקום אחר.", "nameLabel": "שֵׁם", "namePlaceholder": "לדוגמה, ניקוי /נתונים כאשר הוא מתמלא", "nameRequired": "שם נדרש", @@ -30,7 +46,7 @@ "concurrencyHint": "מה לעשות כאשר זה מופעל שוב לפני שהריצה האחרונה הסתיימה.", "concurrency": { "skip": "דלג על הריצה החדשה", - "queue": "חכו ורצנו אחרי", + "queue": "חכו ורוץ אחרי", "allow": "הפעל את שניהם בו זמנית" }, "save": "לְהַצִיל", @@ -79,7 +95,7 @@ "webhook": "וובהוק נכנס" }, "stepTypes": { - "notify": "שלח הודעה", + "notify": "שלח התראה", "http": "קריאה לכתובת URL", "run_snippet": "הפעלת קטע קוד", "run_command": "הפעל פקודה", @@ -118,7 +134,7 @@ "url": "כתובת אתר", "method": "שִׁיטָה", "body": "גוּף", - "channels": "ערוצים", + "channels": "שלחו גם אל", "title": "כּוֹתֶרֶת", "message": "הוֹדָעָה", "snippet": "קטע", @@ -135,6 +151,16 @@ "onError": { "stop": "עצור את הריצה", "continue": "לְהַמשִׁיך" + }, + "needsPlugin": "צרכים {{plugin}}", + "needsPluginHint": "אוטומציה זו מדלגת עד שהתכונה הדרושה לה תהיה זמינה שוב.", + "offBadge": "כבוי", + "docsLink": "הצג מסמכים", + "ago": { + "seconds": "לפני {{count}}שניות", + "minutes": "לפני {{count}}דקות", + "hours": "{{count}}h ago", + "days": "{{count}}d ago" } } } @@ -145,5 +171,41 @@ "onboarding": { "feature_automations": "אוטומציות", "feature_automations_desc": "הפעל שלבים באופן אוטומטי כאשר משהו קורה, וקבל הודעה." + }, + "maintenance": { + "title": "תַחזוּקָה", + "description": "השהה אוטומציות של סטטוס המארח, תקינות, מדדים, ניתוק מנהרות ומכולות בזמן שהעבודה מתבצעת. ניטור, הרצות ידניות ואוטומציות מתוזמנות ממשיכות.", + "denied": "אין לך הרשאה לצפות בתחזוקה.", + "sharedReadOnly": "מארח זה שותף איתך. רק בעליו יכול לשנות את התחזוקה.", + "failed": "לא ניתן היה לעדכן את תוכנית התחזוקה.", + "active": "תחזוקה פעילה", + "estimated": "השלמה משוערת", + "noAutoEnd": "ההערכה אינה מסיימת את התחזוקה. יש לסיים אותה במפורש כאשר העבודה הושלמה.", + "endConfirm": "לסיים את התחזוקה ולחדש אוטומציות המופעלות על ידי אירועים עבור מארח זה?", + "confirmEnd": "אישור סיום", + "cancel": "לְבַטֵל", + "end": "סיום תחזוקה", + "action": "פְּעוּלָה", + "startNow": "התחל עכשיו", + "schedule": "קבע למועד מאוחר יותר", + "reason": "לְנַמֵק", + "startUtc": "התחלה ראשונה (UTC)", + "repeat": "לַחֲזוֹר עַל", + "once": "פַּעַם", + "weekly": "שְׁבוּעִי", + "monthly": "יַרחוֹן", + "utcHelp": "לוחות זמנים משתמשים ב-UTC לאורך כל השנה. לוחות זמנים חודשיים מדלגים על חודשים ללא היום שנבחר. חלונות מתוכננים אינם יכולים לחפוף; תחזוקה מדורגת ממשיכה בחלונות מאוחרים יותר.", + "duration": "משך זמן משוער (בדקות)", + "grace": "תקופת חסד (בדקות)", + "notify": "הודעה אחת אם עדיין לא מחובר לאחר תקופת ההערכה בתוספת חסד", + "addSchedule": "הוסף לוח זמנים", + "schedules": "לוחות זמנים", + "noSchedules": "אין לוחות זמנים לתחזוקה.", + "completed": "כבר התחיל", + "minutes_one": "דקה {{count}}", + "minutes_other": "{{count}} דקות", + "remove": "הסר את לוח הזמנים", + "loadFailed": "לא ניתן היה לרענן את סטטוס התחזוקה. השינויים מושבתים עד שניתן יהיה לטעון אותו.", + "loading": "טוען סטטוס תחזוקה…" } } diff --git a/plugins/automations/locales/translated/hi_IN.json b/plugins/automations/locales/translated/hi_IN.json index 509772b20..e4c13111a 100644 --- a/plugins/automations/locales/translated/hi_IN.json +++ b/plugins/automations/locales/translated/hi_IN.json @@ -1,149 +1,211 @@ { + "permissions": { + "view": { + "title": "View automations", + "description": "See the automations and their history." + }, + "create": { + "title": "Create automations", + "description": "Add new automations." + }, + "edit": { + "title": "Edit automations", + "description": "Change existing automations." + }, + "delete": { + "title": "Delete automations", + "description": "Remove automations." + }, + "run": { + "title": "Run automations", + "description": "Trigger an automation by hand." + } + }, "newUi": { "sidebar": { "automations": { - "title": "स्वचालन", - "tabAutomations": "स्वचालन", - "tabRuns": "दौड़ें", + "title": "Automations", + "tabAutomations": "Automations", + "tabRuns": "Runs", "tabChannels": "चैनल", - "createAutomation": "नया स्वचालन", - "backToAutomations": "स्वचालन पर वापस जाएँ", - "createTitle": "नया स्वचालन", - "editTitle": "संपादन स्वचालन", - "empty": "अभी तक कोई ऑटोमेशन नहीं है। किसी मेट्रिक, शेड्यूल या इवेंट के आधार पर प्रतिक्रिया देने के लिए एक ऑटोमेशन बनाएं।", - "emptyRuns": "अभी तक कोई रन नहीं बना है।", - "emptyChannels": "अभी तक कोई चैनल नहीं है। सूचनाएं भेजने के लिए एक चैनल जोड़ें।", - "noChannelsHint": "अभी तक कोई चैनल सेट अप नहीं किया गया है। चैनल टैब में एक चैनल जोड़ें।", - "addChannel": "चैनल जोड़ें", - "testChannel": "परीक्षा", - "channelTestSent": "परीक्षण अधिसूचना भेजी गई", - "channelTestFailed": "टेस्ट नोटिफिकेशन विफल रहा", - "channelDeleted": "चैनल हटा दिया गया", - "deleteChannelConfirm": "क्या इस चैनल को हटा दें? इसका उपयोग करने वाले ऑटोमेशन नोटिफिकेशन भेजना बंद कर देंगे।", + "createAutomation": "New Automation", + "backToAutomations": "Back to Automations", + "createTitle": "New Automation", + "editTitle": "Edit Automation", + "empty": "No automations yet. Create one to react to a metric, a schedule, or an event.", + "emptyRuns": "No runs yet.", + "channelsHint": "Channels are set up in Alerts", + "noChannelsHint": "The alert always goes to your inbox. Add channels in Alerts to also send it somewhere else.", "nameLabel": "नाम", - "namePlaceholder": "उदाहरण के लिए, जब /data भर जाए तो उसे साफ़ कर दें।", + "namePlaceholder": "e.g., Clean up /data when it fills", "nameRequired": "नाम आवश्यक है", "descriptionLabel": "विवरण", "descriptionPlaceholder": "वैकल्पिक विवरण", - "enabledLabel": "सक्रिय", - "concurrencyLabel": "यदि यह पहले से चल रहा है", - "concurrencyHint": "पिछली बार रन पूरा होने से पहले ही अगर यह समस्या दोबारा उत्पन्न हो जाए तो क्या करें।", + "enabledLabel": "सक्षम", + "concurrencyLabel": "If it is already running", + "concurrencyHint": "What to do when this is triggered again before the last run has finished.", "concurrency": { - "skip": "नए रन को छोड़ दें", - "queue": "प्रतीक्षा करो और उसके पीछे दौड़ो", - "allow": "दोनों को एक साथ चलाएं" + "skip": "Skip the new run", + "queue": "Wait and run after", + "allow": "Run both at once" }, - "save": "बचाना", - "created": "स्वचालन द्वारा निर्मित", - "updated": "स्वचालन ने बचत की", - "deleted": "स्वचालित रूप से हटा दिया गया", - "deleteConfirm": "इस ऑटोमेशन को डिलीट करने पर, इसका रन हिस्ट्री भी डिलीट हो जाएगा।", - "runNow": "अब दौड़े", - "testRun": "परीक्षण के लिए चलाना", - "testRunHint": "यह हर चरण में दौड़ता है लेकिन टर्मिक्स के बाहर किसी भी चीज को नहीं छूता है।", - "runStarted": "दौड़ शुरू हो गई", - "runFinished": "रन समाप्त: {{status}}", - "trigger": "चालू कर देना", - "steps": "चरण", - "addStep": "चरण जोड़ें", - "removeStep": "चरण हटाएँ", - "moveUp": "बढ़ाना", - "moveDown": "नीचे की ओर", - "noSteps": "अभी तक कोई चरण निर्धारित नहीं हैं। कृपया एक चरण जोड़कर बताएं कि आगे क्या होना चाहिए।", - "webhookTokenTitle": "वेबहुक यूआरएल", - "webhookTokenDescription": "यह केवल एक बार दिखाया जाएगा। इसे अभी सहेज लें, बाद में इसे पुनः प्राप्त नहीं किया जा सकेगा।", - "copy": "प्रतिलिपि", + "save": "सहेजें", + "created": "Automation created", + "updated": "Automation saved", + "deleted": "Automation deleted", + "deleteConfirm": "Delete this automation? Its run history is deleted too.", + "runNow": "Run now", + "testRun": "Test run", + "testRunHint": "Runs every step but does not touch anything outside Termix.", + "runStarted": "Run started", + "runFinished": "Run finished: {{status}}", + "trigger": "ट्रिगर", + "steps": "Steps", + "addStep": "Add step", + "removeStep": "Remove step", + "moveUp": "Move up", + "moveDown": "Move down", + "noSteps": "No steps yet. Add one to say what should happen.", + "webhookTokenTitle": "Webhook URL", + "webhookTokenDescription": "This is shown once. Save it now, it cannot be retrieved later.", + "copy": "कॉपी", "copied": "कॉपी किया गया", - "viewJson": "जेएन", - "viewBuilder": "निर्माता", - "viewGraph": "ग्राफ़", - "lastRun": "आखरी बार", + "viewJson": "JSON", + "viewBuilder": "Builder", + "viewGraph": "Graph", + "lastRun": "Last run", "never": "कभी नहीं", "duration": "{{seconds}}s", - "stepOutput": "उत्पादन", - "stepError": "गलती", - "dryRunBadge": "परीक्षण के लिए चलाना", + "stepOutput": "आउटपुट", + "stepError": "त्रुटि", + "dryRunBadge": "Test run", "hostSelector": { - "trigger": "ट्रिगरिंग होस्ट", - "host": "विशिष्ट मेज़बान", - "fleet": "बेड़ा", - "all": "सभी मेजबान" + "trigger": "Triggering host", + "host": "Specific host", + "fleet": "Fleet", + "all": "सभी होस्ट" }, "triggerKinds": { - "metric_threshold": "मीट्रिक सीमा", - "host_status": "होस्ट ऊपर या नीचे जाता है", - "health_check": "स्वास्थ्य जांच में बदलाव", - "schedule": "एक निर्धारित कार्यक्रम के अनुसार", - "docker_event": "कंटेनर घटना", - "internal_event": "टर्मिक्स घटना", - "webhook": "इनकमिंग वेबहुक" + "metric_threshold": "Metric threshold", + "host_status": "Host goes up or down", + "health_check": "Health check changes", + "schedule": "On a schedule", + "docker_event": "Container event", + "internal_event": "Termix event", + "webhook": "Incoming webhook" }, "stepTypes": { - "notify": "सूचना भेजें", - "http": "किसी URL को कॉल करें", - "run_snippet": "एक स्निपेट चलाएँ", - "run_command": "एक कमांड चलाएँ", - "docker": "एक कंटेनर को नियंत्रित करें", - "tunnel": "एक सुरंग को नियंत्रित करें", - "wol": "किसी मेजबान को जगाओ", - "wait": "इंतज़ार", - "set_var": "एक चर सेट करें", - "if": "यदि / अन्यथा", - "run_automation": "एक और ऑटोमेशन चलाएँ", - "stop": "रुकना" + "notify": "Send an alert", + "http": "Call a URL", + "run_snippet": "Run a snippet", + "run_command": "Run a command", + "docker": "Control a container", + "tunnel": "Control a tunnel", + "wol": "Wake a host", + "wait": "Wait", + "set_var": "Set a variable", + "if": "If / otherwise", + "run_automation": "Run another automation", + "stop": "स्टॉप" }, "statuses": { - "running": "दौड़ना", - "success": "सफलता", + "running": "चालू", + "success": "सफल", "failed": "असफल", - "timeout": "समय समााप्त", - "skipped": "छोड़ा गया", - "cancelled": "रद्द कर दिया गया" + "timeout": "Timed out", + "skipped": "Skipped", + "cancelled": "Cancelled" }, "fields": { - "host": "मेज़बान", + "host": "होस्ट", "metric": "मीट्रिक", - "mount": "माउंट पॉइंट", - "operator": "है", - "value": "कीमत", - "forSeconds": "(सेकंड) तक कायम रहा", - "cooldown": "कूलडाउन (मिनटों में)", - "cron": "क्रोन अभिव्यक्ति", - "intervalSeconds": "हर (सेकंड)", - "timezone": "समय क्षेत्र", - "timezoneServer": "सर्वर समय", - "timezoneHint": "इस ज़ोन में क्रॉन टाइम पढ़े जाते हैं। यह इंटरवल शेड्यूल पर लागू नहीं होता है।", - "container": "पात्र", - "command": "आज्ञा", - "url": "यूआरएल", - "method": "तरीका", - "body": "शरीर", - "channels": "चैनल", + "mount": "Mount point", + "operator": "Is", + "value": "Value", + "forSeconds": "Sustained for (seconds)", + "cooldown": "कूलडाउन (मिनट)", + "cron": "Cron expression", + "intervalSeconds": "Every (seconds)", + "timezone": "Time zone", + "timezoneServer": "Server time", + "timezoneHint": "Cron times are read in this zone. Does not apply to interval schedules.", + "container": "Container", + "command": "कमांड", + "url": "URL", + "method": "Method", + "body": "Body", + "channels": "Also send to", "title": "शीर्षक", - "message": "संदेश", - "snippet": "टुकड़ा", - "seconds": "सेकंड", - "conditionLeftPlaceholder": "जाँच करने के लिए मान", - "conditionRightPlaceholder": "तुलना करें", - "variableName": "चर का नाम", - "variableValue": "कीमत", - "elevated": "sudo के साथ चलाएँ", - "onError": "यदि यह विफल हो जाता है", - "allowPrivateNetwork": "स्थानीय नेटवर्क पतों की अनुमति दें", - "allowPrivateNetworkHint": "आपके लोकल एरिया नेटवर्क (LAN) पर सेल्फ-होस्टेड सेवा के लिए आवश्यक। आंतरिक पतों पर अनुरोधों को रोकने के लिए डिफ़ॉल्ट रूप से बंद।" + "message": "Message", + "snippet": "Snippet", + "seconds": "Seconds", + "conditionLeftPlaceholder": "Value to check", + "conditionRightPlaceholder": "Compare against", + "variableName": "Variable name", + "variableValue": "Value", + "elevated": "Run with sudo", + "onError": "If this fails", + "allowPrivateNetwork": "Allow local network addresses", + "allowPrivateNetworkHint": "Needed for a self-hosted service on your LAN. Off by default to prevent requests to internal addresses." }, "onError": { - "stop": "दौड़ रोको", - "continue": "जारी रखो" + "stop": "Stop the run", + "continue": "Carry on" + }, + "needsPlugin": "Needs {{plugin}}", + "needsPluginHint": "This automation is skipped until the feature it needs is available again.", + "offBadge": "बंद", + "docsLink": "दस्तावेज़ देखें", + "ago": { + "seconds": "{{count}}s ago", + "minutes": "{{count}}m पहले", + "hours": "{{count}}h पहले", + "days": "{{count}}d पहले" } } } }, "nav": { - "automations": "स्वचालन" + "automations": "Automations" }, "onboarding": { - "feature_automations": "स्वचालन", - "feature_automations_desc": "कुछ घटित होने पर चरणों को स्वचालित रूप से चलाएं और सूचना प्राप्त करें।" + "feature_automations": "Automations", + "feature_automations_desc": "Run steps automatically when something happens, and get notified." + }, + "maintenance": { + "title": "रखरखाव", + "description": "Pause host status, health, metric, container and tunnel-disconnection automations while work is in progress. Monitoring, manual runs and scheduled automations continue.", + "denied": "You do not have permission to view maintenance.", + "sharedReadOnly": "This host was shared with you. Only its owner can change maintenance.", + "failed": "Maintenance could not be updated.", + "active": "Maintenance active", + "estimated": "Estimated completion", + "noAutoEnd": "The estimate does not end maintenance. End it explicitly when the work is complete.", + "endConfirm": "End maintenance and resume event-triggered automations for this host?", + "confirmEnd": "Confirm end", + "cancel": "रद्द करें", + "end": "End maintenance", + "action": "क्रिया", + "startNow": "Start now", + "schedule": "Schedule for later", + "reason": "Reason", + "startUtc": "First start (UTC)", + "repeat": "Repeat", + "once": "Once", + "weekly": "Weekly", + "monthly": "Monthly", + "utcHelp": "Schedules use UTC throughout the year. Monthly schedules skip months without the selected day. Planned windows cannot overlap; overrunning maintenance continues across later windows.", + "duration": "Estimated duration (minutes)", + "grace": "Grace period (minutes)", + "notify": "Notify once if still offline after the estimate plus grace period", + "addSchedule": "Add schedule", + "schedules": "Schedules", + "noSchedules": "No maintenance schedules.", + "completed": "Already started", + "minutes_one": "{{count}} minute", + "minutes_other": "{{count}} minutes", + "remove": "Remove schedule", + "loadFailed": "Could not refresh maintenance status. Changes are disabled until it can be loaded.", + "loading": "Loading maintenance status…" } } diff --git a/plugins/automations/locales/translated/hu_HU.json b/plugins/automations/locales/translated/hu_HU.json index 23f06e1c3..acb58a15e 100644 --- a/plugins/automations/locales/translated/hu_HU.json +++ b/plugins/automations/locales/translated/hu_HU.json @@ -1,4 +1,26 @@ { + "permissions": { + "view": { + "title": "Automatizálások megtekintése", + "description": "Tekintse meg az automatizálásokat és azok előzményeit." + }, + "create": { + "title": "Automatizálások létrehozása", + "description": "Új automatizálások hozzáadása." + }, + "edit": { + "title": "Automatizálások szerkesztése", + "description": "Módosítsa a meglévő automatizálásokat." + }, + "delete": { + "title": "Automatizálások törlése", + "description": "Automatizálások eltávolítása." + }, + "run": { + "title": "Automatizálások futtatása", + "description": "Automatizálás manuális indítása." + } + }, "newUi": { "sidebar": { "automations": { @@ -12,14 +34,8 @@ "editTitle": "Szerkesztési automatizálás", "empty": "Még nincsenek automatizálások. Hozz létre egyet, amely egy mérőszámra, ütemezésre vagy eseményre reagál.", "emptyRuns": "Még nincsenek futások.", - "emptyChannels": "Még nincsenek csatornák. Adj hozzá egyet, hogy értesítéseket küldhess valahova.", - "noChannelsHint": "Még nincsenek beállítva csatornák. Adjon hozzá egyet a Csatornák fülön.", - "addChannel": "Csatorna hozzáadása", - "testChannel": "Teszt", - "channelTestSent": "Tesztértesítés elküldve", - "channelTestFailed": "Tesztértesítés sikertelen", - "channelDeleted": "Csatorna törölve", - "deleteChannelConfirm": "Törlöd ezt a csatornát? Az azt használó automatizálások nem fognak értesítéseket küldeni.", + "channelsHint": "A csatornák a Riasztások menüpontban vannak beállítva.", + "noChannelsHint": "Az értesítés mindig a beérkező levelek mappájába érkezik. Adj hozzá csatornákat az Értesítések részben, hogy máshová is elküldhesd.", "nameLabel": "Név", "namePlaceholder": "pl. /data törlése, amikor megtelik", "nameRequired": "Név megadása kötelező", @@ -118,7 +134,7 @@ "url": "URL-cím", "method": "Módszer", "body": "Test", - "channels": "Csatornák", + "channels": "Küldés ide is", "title": "Cím", "message": "Üzenet", "snippet": "Töredék", @@ -135,6 +151,16 @@ "onError": { "stop": "Állítsd meg a futást", "continue": "Folytat" + }, + "needsPlugin": "Szükségletek {{plugin}}", + "needsPluginHint": "Ez az automatizálás kimarad, amíg a szükséges funkció újra elérhetővé nem válik.", + "offBadge": "Le", + "docsLink": "Dokumentumok megtekintése", + "ago": { + "seconds": "{{count}}másodperccel ezelőtt", + "minutes": "{{count}}perccel ezelőtt", + "hours": "{{count}}órával ezelőtt", + "days": "{{count}}nappal ezelőtt" } } } @@ -145,5 +171,41 @@ "onboarding": { "feature_automations": "Automatizálások", "feature_automations_desc": "Automatikusan futtassa a lépéseket, amikor valami történik, és kapjon értesítést." + }, + "maintenance": { + "title": "Karbantartás", + "description": "A folyamatban lévő munka alatt szüneteltesse a hoszt állapot-, egészség-, metrika-, konténer- és alagút-leválasztási automatizálásokat. A monitorozás, a manuális futtatások és az ütemezett automatizálások továbbra is működnek.", + "denied": "Nincs jogosultsága a karbantartás megtekintésére.", + "sharedReadOnly": "Ezt a gazdagépet megosztották veled. Csak a tulajdonosa módosíthatja a karbantartási beállításokat.", + "failed": "A karbantartás frissítése nem sikerült.", + "active": "Karbantartás aktív", + "estimated": "Várható befejezés", + "noAutoEnd": "A becslés nem fejezi be a karbantartást. A munka befejezésekor explicit módon fejezze be.", + "endConfirm": "Befejezi a karbantartást, és folytatja az eseményvezérelt automatizálásokat ennél a gazdagépnél?", + "confirmEnd": "Vég megerősítése", + "cancel": "Mégsem", + "end": "Karbantartás vége", + "action": "Akció", + "startNow": "Kezdés most", + "schedule": "Későbbi időpontra ütemezhető", + "reason": "Ok", + "startUtc": "Első indítás (UTC)", + "repeat": "Ismétlés", + "once": "Egyszer", + "weekly": "Heti", + "monthly": "Havi", + "utcHelp": "Az ütemtervek az év során UTC-t használják. A havi ütemtervek kihagyják a kiválasztott nap nélküli hónapokat. A tervezett ablakok nem fedhetik át egymást; a túlterheléses karbantartás a későbbi ablakokban is folytatódik.", + "duration": "Becsült időtartam (perc)", + "grace": "Türelmi időszak (perc)", + "notify": "Értesítsen egyszer, ha a becslés és a türelmi időszak után is offline állapotban van", + "addSchedule": "Ütemezés hozzáadása", + "schedules": "Ütemtervek", + "noSchedules": "Nincsenek karbantartási ütemtervek.", + "completed": "Már elkezdődött", + "minutes_one": "{{count}} perc", + "minutes_other": "{{count}} perc", + "remove": "Ütemezés eltávolítása", + "loadFailed": "Nem sikerült frissíteni a karbantartási állapotot. A változtatások le vannak tiltva, amíg be nem töltődik.", + "loading": "Karbantartási állapot betöltése…" } } diff --git a/plugins/automations/locales/translated/id_ID.json b/plugins/automations/locales/translated/id_ID.json index 4f52e8a49..3e5f8c65e 100644 --- a/plugins/automations/locales/translated/id_ID.json +++ b/plugins/automations/locales/translated/id_ID.json @@ -1,149 +1,211 @@ { + "permissions": { + "view": { + "title": "View automations", + "description": "See the automations and their history." + }, + "create": { + "title": "Create automations", + "description": "Add new automations." + }, + "edit": { + "title": "Edit automations", + "description": "Change existing automations." + }, + "delete": { + "title": "Delete automations", + "description": "Remove automations." + }, + "run": { + "title": "Run automations", + "description": "Trigger an automation by hand." + } + }, "newUi": { "sidebar": { "automations": { - "title": "Otomatisasi", - "tabAutomations": "Otomatisasi", - "tabRuns": "Lari", - "tabChannels": "Saluran", - "createAutomation": "Otomatisasi Baru", - "backToAutomations": "Kembali ke Otomatisasi", - "createTitle": "Otomatisasi Baru", - "editTitle": "Edit Otomatisasi", - "empty": "Belum ada otomatisasi. Buat satu untuk bereaksi terhadap metrik, jadwal, atau peristiwa.", - "emptyRuns": "Belum ada percobaan lari.", - "emptyChannels": "Belum ada saluran. Tambahkan satu untuk mengirim notifikasi ke suatu tempat.", - "noChannelsHint": "Belum ada saluran yang dibuat. Tambahkan satu di tab Saluran.", - "addChannel": "Tambahkan Saluran", - "testChannel": "Tes", - "channelTestSent": "Notifikasi pengujian telah dikirim.", - "channelTestFailed": "Notifikasi pengujian gagal", - "channelDeleted": "Saluran dihapus", - "deleteChannelConfirm": "Hapus saluran ini? Otomatisasi yang menggunakannya akan berhenti memberi notifikasi.", - "nameLabel": "Nama", - "namePlaceholder": "misalnya, Bersihkan /data saat sudah penuh", - "nameRequired": "Nama wajib diisi.", - "descriptionLabel": "Keterangan", - "descriptionPlaceholder": "Deskripsi opsional", - "enabledLabel": "Diaktifkan", - "concurrencyLabel": "Jika sudah berjalan", - "concurrencyHint": "Apa yang harus dilakukan jika ini terpicu lagi sebelum proses terakhir selesai.", + "title": "Automations", + "tabAutomations": "Automations", + "tabRuns": "Runs", + "tabChannels": "Channels", + "createAutomation": "New Automation", + "backToAutomations": "Back to Automations", + "createTitle": "New Automation", + "editTitle": "Edit Automation", + "empty": "No automations yet. Create one to react to a metric, a schedule, or an event.", + "emptyRuns": "No runs yet.", + "channelsHint": "Channels are set up in Alerts", + "noChannelsHint": "The alert always goes to your inbox. Add channels in Alerts to also send it somewhere else.", + "nameLabel": "Name", + "namePlaceholder": "e.g., Clean up /data when it fills", + "nameRequired": "Name is required", + "descriptionLabel": "Description", + "descriptionPlaceholder": "Optional description", + "enabledLabel": "Enabled", + "concurrencyLabel": "If it is already running", + "concurrencyHint": "What to do when this is triggered again before the last run has finished.", "concurrency": { - "skip": "Lewati lari baru", - "queue": "Tunggu dan lari setelahnya", - "allow": "Jalankan keduanya sekaligus" + "skip": "Skip the new run", + "queue": "Wait and run after", + "allow": "Run both at once" }, - "save": "Menyimpan", - "created": "Otomatisasi dibuat", - "updated": "Otomatisasi tersimpan", - "deleted": "Otomatisasi dihapus", - "deleteConfirm": "Hapus otomatisasi ini? Riwayat eksekusinya juga akan terhapus.", - "runNow": "Lari sekarang", - "testRun": "Uji coba", - "testRunHint": "Berjalan di setiap langkah tetapi tidak menyentuh apa pun di luar Termix.", - "runStarted": "Lari dimulai", - "runFinished": "Eksekusi selesai: {{status}}", - "trigger": "Pemicu", - "steps": "Tangga", - "addStep": "Tambahkan langkah", - "removeStep": "Hapus langkah", - "moveUp": "Naikkan", - "moveDown": "Turun ke bawah", - "noSteps": "Belum ada langkah. Tambahkan satu langkah untuk menjelaskan apa yang seharusnya terjadi.", - "webhookTokenTitle": "URL Webhook", - "webhookTokenDescription": "Ini hanya ditampilkan sekali. Simpan sekarang, karena tidak dapat diambil kembali nanti.", - "copy": "Menyalin", - "copied": "Disalin", + "save": "Save", + "created": "Automation created", + "updated": "Automation saved", + "deleted": "Automation deleted", + "deleteConfirm": "Delete this automation? Its run history is deleted too.", + "runNow": "Run now", + "testRun": "Test run", + "testRunHint": "Runs every step but does not touch anything outside Termix.", + "runStarted": "Run started", + "runFinished": "Run finished: {{status}}", + "trigger": "Trigger", + "steps": "Steps", + "addStep": "Add step", + "removeStep": "Remove step", + "moveUp": "Move up", + "moveDown": "Move down", + "noSteps": "No steps yet. Add one to say what should happen.", + "webhookTokenTitle": "Webhook URL", + "webhookTokenDescription": "This is shown once. Save it now, it cannot be retrieved later.", + "copy": "Copy", + "copied": "Copied", "viewJson": "JSON", - "viewBuilder": "Pembangun", - "viewGraph": "Grafik", - "lastRun": "Lari terakhir", - "never": "Tidak pernah", + "viewBuilder": "Builder", + "viewGraph": "Graph", + "lastRun": "Last run", + "never": "Never", "duration": "{{seconds}}s", - "stepOutput": "Keluaran", - "stepError": "Kesalahan", - "dryRunBadge": "Uji coba", + "stepOutput": "Output", + "stepError": "Error", + "dryRunBadge": "Test run", "hostSelector": { - "trigger": "Host pemicu", - "host": "Host spesifik", - "fleet": "Armada", - "all": "Semua tuan rumah" + "trigger": "Triggering host", + "host": "Specific host", + "fleet": "Fleet", + "all": "All hosts" }, "triggerKinds": { - "metric_threshold": "Ambang batas metrik", - "host_status": "Pembawa acara naik atau turun", - "health_check": "Perubahan pemeriksaan kesehatan", - "schedule": "Sesuai jadwal", - "docker_event": "Acara kontainer", - "internal_event": "Acara Termix", - "webhook": "Webhook masuk" + "metric_threshold": "Metric threshold", + "host_status": "Host goes up or down", + "health_check": "Health check changes", + "schedule": "On a schedule", + "docker_event": "Container event", + "internal_event": "Termix event", + "webhook": "Incoming webhook" }, "stepTypes": { - "notify": "Kirim pemberitahuan", - "http": "Memanggil URL", - "run_snippet": "Jalankan cuplikan kode", - "run_command": "Jalankan perintah", - "docker": "Mengendalikan sebuah kontainer", - "tunnel": "Mengendalikan terowongan", - "wol": "Bangunkan tuan rumah", - "wait": "Tunggu", - "set_var": "Tetapkan sebuah variabel", - "if": "Jika/sebaliknya", - "run_automation": "Jalankan otomatisasi lainnya", - "stop": "Berhenti" + "notify": "Send an alert", + "http": "Call a URL", + "run_snippet": "Run a snippet", + "run_command": "Run a command", + "docker": "Control a container", + "tunnel": "Control a tunnel", + "wol": "Wake a host", + "wait": "Wait", + "set_var": "Set a variable", + "if": "If / otherwise", + "run_automation": "Run another automation", + "stop": "Stop" }, "statuses": { - "running": "Berlari", - "success": "Kesuksesan", - "failed": "Gagal", - "timeout": "Waktu habis", - "skipped": "Dilewati", - "cancelled": "Dibatalkan" + "running": "Running", + "success": "Success", + "failed": "Failed", + "timeout": "Timed out", + "skipped": "Skipped", + "cancelled": "Cancelled" }, "fields": { - "host": "Tuan rumah", - "metric": "Metrik", - "mount": "Titik pemasangan", - "operator": "Adalah", - "value": "Nilai", - "forSeconds": "Berlangsung selama (detik)", - "cooldown": "Waktu pendinginan (menit)", - "cron": "Ekspresi Cron", - "intervalSeconds": "Setiap (detik)", - "timezone": "Zona waktu", - "timezoneServer": "Waktu server", - "timezoneHint": "Waktu Cron dibaca di zona ini. Tidak berlaku untuk jadwal interval.", - "container": "Wadah", - "command": "Memerintah", + "host": "Host", + "metric": "Metric", + "mount": "Mount point", + "operator": "Is", + "value": "Value", + "forSeconds": "Sustained for (seconds)", + "cooldown": "Cooldown (minutes)", + "cron": "Cron expression", + "intervalSeconds": "Every (seconds)", + "timezone": "Time zone", + "timezoneServer": "Server time", + "timezoneHint": "Cron times are read in this zone. Does not apply to interval schedules.", + "container": "Container", + "command": "Command", "url": "URL", - "method": "Metode", - "body": "Tubuh", - "channels": "Saluran", - "title": "Judul", - "message": "Pesan", - "snippet": "Potongan", - "seconds": "Detik", - "conditionLeftPlaceholder": "Nilai yang perlu diperiksa", - "conditionRightPlaceholder": "Bandingkan dengan", - "variableName": "Nama variabel", - "variableValue": "Nilai", - "elevated": "Jalankan dengan sudo", - "onError": "Jika ini gagal", - "allowPrivateNetwork": "Izinkan alamat jaringan lokal", - "allowPrivateNetworkHint": "Diperlukan untuk layanan yang dihosting sendiri di LAN Anda. Secara default dinonaktifkan untuk mencegah permintaan ke alamat internal." + "method": "Method", + "body": "Body", + "channels": "Also send to", + "title": "Title", + "message": "Message", + "snippet": "Snippet", + "seconds": "Seconds", + "conditionLeftPlaceholder": "Value to check", + "conditionRightPlaceholder": "Compare against", + "variableName": "Variable name", + "variableValue": "Value", + "elevated": "Run with sudo", + "onError": "If this fails", + "allowPrivateNetwork": "Allow local network addresses", + "allowPrivateNetworkHint": "Needed for a self-hosted service on your LAN. Off by default to prevent requests to internal addresses." }, "onError": { - "stop": "Hentikan larinya", - "continue": "Melanjutkan" + "stop": "Stop the run", + "continue": "Carry on" + }, + "needsPlugin": "Needs {{plugin}}", + "needsPluginHint": "This automation is skipped until the feature it needs is available again.", + "offBadge": "Off", + "docsLink": "View docs", + "ago": { + "seconds": "{{count}}s ago", + "minutes": "{{count}} menit lalu", + "hours": "{{count}} jam lalu", + "days": "{{count}} detik lalu" } } } }, "nav": { - "automations": "Otomatisasi" + "automations": "Automations" }, "onboarding": { - "feature_automations": "Otomatisasi", - "feature_automations_desc": "Jalankan langkah-langkah secara otomatis saat sesuatu terjadi, dan dapatkan notifikasi." + "feature_automations": "Automations", + "feature_automations_desc": "Run steps automatically when something happens, and get notified." + }, + "maintenance": { + "title": "Maintenance", + "description": "Pause host status, health, metric, container and tunnel-disconnection automations while work is in progress. Monitoring, manual runs and scheduled automations continue.", + "denied": "You do not have permission to view maintenance.", + "sharedReadOnly": "This host was shared with you. Only its owner can change maintenance.", + "failed": "Maintenance could not be updated.", + "active": "Maintenance active", + "estimated": "Estimated completion", + "noAutoEnd": "The estimate does not end maintenance. End it explicitly when the work is complete.", + "endConfirm": "End maintenance and resume event-triggered automations for this host?", + "confirmEnd": "Confirm end", + "cancel": "Cancel", + "end": "End maintenance", + "action": "Action", + "startNow": "Start now", + "schedule": "Schedule for later", + "reason": "Reason", + "startUtc": "First start (UTC)", + "repeat": "Repeat", + "once": "Once", + "weekly": "Weekly", + "monthly": "Monthly", + "utcHelp": "Schedules use UTC throughout the year. Monthly schedules skip months without the selected day. Planned windows cannot overlap; overrunning maintenance continues across later windows.", + "duration": "Estimated duration (minutes)", + "grace": "Grace period (minutes)", + "notify": "Notify once if still offline after the estimate plus grace period", + "addSchedule": "Add schedule", + "schedules": "Schedules", + "noSchedules": "No maintenance schedules.", + "completed": "Already started", + "minutes_one": "{{count}} minute", + "minutes_other": "{{count}} minutes", + "remove": "Remove schedule", + "loadFailed": "Could not refresh maintenance status. Changes are disabled until it can be loaded.", + "loading": "Loading maintenance status…" } } diff --git a/plugins/automations/locales/translated/it_IT.json b/plugins/automations/locales/translated/it_IT.json index a46c29cf3..b5df9ff8a 100644 --- a/plugins/automations/locales/translated/it_IT.json +++ b/plugins/automations/locales/translated/it_IT.json @@ -1,4 +1,26 @@ { + "permissions": { + "view": { + "title": "Visualizza le automazioni", + "description": "Visualizza le automazioni e la loro cronologia." + }, + "create": { + "title": "Creare automazioni", + "description": "Aggiungi nuove automazioni." + }, + "edit": { + "title": "Automazioni di modifica", + "description": "Modifica le automazioni esistenti." + }, + "delete": { + "title": "Eliminazione delle automazioni", + "description": "Rimuovi le automazioni." + }, + "run": { + "title": "Eseguire automazioni", + "description": "Attivare un'automazione manualmente." + } + }, "newUi": { "sidebar": { "automations": { @@ -12,19 +34,13 @@ "editTitle": "Automazione di modifica", "empty": "Nessuna automazione ancora disponibile. Creane una per reagire a una metrica, a una pianificazione o a un evento.", "emptyRuns": "Nessuna corsa ancora.", - "emptyChannels": "Nessun canale ancora. Aggiungine uno per inviare notifiche da qualche parte.", - "noChannelsHint": "Nessun canale configurato al momento. Aggiungine uno nella scheda Canali.", - "addChannel": "Aggiungi canale", - "testChannel": "Test", - "channelTestSent": "Notifica di test inviata", - "channelTestFailed": "Notifica di prova non riuscita", - "channelDeleted": "Canale eliminato", - "deleteChannelConfirm": "Eliminare questo canale? Le automazioni che lo utilizzano smetteranno di inviare notifiche.", + "channelsHint": "I canali sono configurati negli avvisi", + "noChannelsHint": "L'avviso viene sempre inviato alla tua casella di posta. Aggiungi i canali agli avvisi per inviarlo anche ad altri destinatari.", "nameLabel": "Nome", "namePlaceholder": "Ad esempio, pulire /data quando è pieno", - "nameRequired": "Il nome è obbligatorio", + "nameRequired": "Nome obbligatorio", "descriptionLabel": "Descrizione", - "descriptionPlaceholder": "Descrizione facoltativa", + "descriptionPlaceholder": "Descrizione opzionale", "enabledLabel": "Abilitato", "concurrencyLabel": "Se è già in esecuzione", "concurrencyHint": "Cosa fare se questo problema si ripresenta prima che l'ultima esecuzione sia terminata.", @@ -43,7 +59,7 @@ "testRunHint": "Esegue ogni passaggio ma non tocca nulla al di fuori di Termix.", "runStarted": "Corsa iniziata", "runFinished": "Corsa terminata: {{status}}", - "trigger": "Grilletto", + "trigger": "Trigger", "steps": "Passaggi", "addStep": "Aggiungi passaggio", "removeStep": "Rimuovere il passaggio", @@ -60,7 +76,7 @@ "lastRun": "Prima corsa", "never": "Mai", "duration": "{{seconds}}s", - "stepOutput": "Produzione", + "stepOutput": "Output", "stepError": "Errore", "dryRunBadge": "Esecuzione del test", "hostSelector": { @@ -79,7 +95,7 @@ "webhook": "Webhook in entrata" }, "stepTypes": { - "notify": "Invia una notifica", + "notify": "Invia un avviso", "http": "Chiamare un medico", "run_snippet": "Esegui uno snippet", "run_command": "Eseguire un comando", @@ -90,10 +106,10 @@ "set_var": "Imposta una variabile", "if": "Se / altrimenti", "run_automation": "Esegui un'altra automazione", - "stop": "Fermare" + "stop": "Stop" }, "statuses": { - "running": "Corsa", + "running": "In esecuzione", "success": "Successo", "failed": "Fallito", "timeout": "Tempo scaduto", @@ -101,13 +117,13 @@ "cancelled": "Annullato" }, "fields": { - "host": "Ospite", - "metric": "metrico", + "host": "Host", + "metric": "Metrica", "mount": "Punto di appoggio", "operator": "È", "value": "Valore", "forSeconds": "Sostenuto per (secondi)", - "cooldown": "Tempo di raffreddamento (minuti)", + "cooldown": "Cooldown (minuti)", "cron": "espressione Cron", "intervalSeconds": "Ogni (secondi)", "timezone": "Fuso orario", @@ -118,7 +134,7 @@ "url": "URL", "method": "Metodo", "body": "Corpo", - "channels": "Canali", + "channels": "Invia anche a", "title": "Titolo", "message": "Messaggio", "snippet": "Frammento", @@ -135,6 +151,16 @@ "onError": { "stop": "Ferma la corsa", "continue": "Proseguire" + }, + "needsPlugin": "Bisogno {{plugin}}", + "needsPluginHint": "Questa automazione viene saltata finché la funzionalità necessaria non sarà nuovamente disponibile.", + "offBadge": "Disattivo", + "docsLink": "Vedi documenti", + "ago": { + "seconds": "{{count}}secondi fa", + "minutes": "{{count}}m fa", + "hours": "{{count}}h fa", + "days": "{{count}}d fa" } } } @@ -145,5 +171,41 @@ "onboarding": { "feature_automations": "Automazioni", "feature_automations_desc": "Esegui automaticamente i passaggi quando si verifica un evento e ricevi una notifica." + }, + "maintenance": { + "title": "Manutenzione", + "description": "Metti in pausa le automazioni relative allo stato dell'host, all'integrità, alle metriche, ai container e alla disconnessione del tunnel durante l'esecuzione dei lavori. Il monitoraggio, le esecuzioni manuali e le automazioni pianificate continuano.", + "denied": "Non hai l'autorizzazione per visualizzare gli interventi di manutenzione.", + "sharedReadOnly": "Questo host è stato condiviso con te. Solo il proprietario può modificarne la manutenzione.", + "failed": "Impossibile aggiornare la manutenzione.", + "active": "Manutenzione attiva", + "estimated": "Completamento previsto", + "noAutoEnd": "Il preventivo non conclude la manutenzione. La sua conclusione va esplicitamente al termine dei lavori.", + "endConfirm": "Terminare la manutenzione e riprendere le automazioni attivate da eventi per questo host?", + "confirmEnd": "Conferma fine", + "cancel": "Annulla", + "end": "Manutenzione finale", + "action": "Azione", + "startNow": "Inizia ora", + "schedule": "Programma per dopo", + "reason": "Motivo", + "startUtc": "Primo inizio (UTC)", + "repeat": "Ripetere", + "once": "Una volta", + "weekly": "Settimanale", + "monthly": "Mensile", + "utcHelp": "Le pianificazioni utilizzano il fuso orario UTC durante tutto l'anno. Le pianificazioni mensili saltano i mesi in cui non è selezionato il giorno. Le finestre temporali pianificate non possono sovrapporsi; la manutenzione straordinaria si estende anche alle finestre successive.", + "duration": "Durata stimata (minuti)", + "grace": "Periodo di grazia (minuti)", + "notify": "Avvisami una volta se rimani ancora offline dopo il periodo stimato più il periodo di tolleranza.", + "addSchedule": "Aggiungi programma", + "schedules": "Orari", + "noSchedules": "Nessun programma di manutenzione.", + "completed": "iniziato", + "minutes_one": "{{count}} minuto", + "minutes_other": "{{count}} minuti", + "remove": "Rimuovere la pianificazione", + "loadFailed": "Impossibile aggiornare lo stato della manutenzione. Le modifiche sono disabilitate fino al caricamento.", + "loading": "Caricamento dello stato di manutenzione…" } } diff --git a/plugins/automations/locales/translated/ja_JP.json b/plugins/automations/locales/translated/ja_JP.json index 986e159b9..539d90589 100644 --- a/plugins/automations/locales/translated/ja_JP.json +++ b/plugins/automations/locales/translated/ja_JP.json @@ -1,4 +1,26 @@ { + "permissions": { + "view": { + "title": "自動化を表示する", + "description": "自動化処理とその履歴をご覧ください。" + }, + "create": { + "title": "自動化を作成する", + "description": "新しい自動化機能を追加します。" + }, + "edit": { + "title": "自動化を編集する", + "description": "既存の自動化プロセスを変更します。" + }, + "delete": { + "title": "自動化を削除する", + "description": "自動化機能を削除してください。" + }, + "run": { + "title": "自動化を実行する", + "description": "自動化処理を手動で起動する。" + } + }, "newUi": { "sidebar": { "automations": { @@ -12,19 +34,13 @@ "editTitle": "編集自動化", "empty": "自動化はまだ設定されていません。指標、スケジュール、またはイベントに応じて自動化を設定してください。", "emptyRuns": "まだ得点はありません。", - "emptyChannels": "まだチャンネルがありません。通知を送信するチャンネルを追加してください。", - "noChannelsHint": "チャンネルがまだ設定されていません。チャンネルタブで追加してください。", - "addChannel": "チャンネルを追加", - "testChannel": "テスト", - "channelTestSent": "テスト通知が送信されました", - "channelTestFailed": "テスト通知が失敗しました", - "channelDeleted": "チャンネルが削除されました", - "deleteChannelConfirm": "このチャンネルを削除しますか?このチャンネルを使用している自動化機能は通知を停止します。", + "channelsHint": "アラートでチャンネルを設定します", + "noChannelsHint": "アラートは常に受信トレイに届きます。アラート設定でチャネルを追加すれば、他の場所にも送信できます。", "nameLabel": "名前", "namePlaceholder": "例:/data がいっぱいになったらクリーンアップする", "nameRequired": "名前は必須です", "descriptionLabel": "説明", - "descriptionPlaceholder": "オプションの説明", + "descriptionPlaceholder": "任意の説明", "enabledLabel": "有効", "concurrencyLabel": "既に実行中の場合", "concurrencyHint": "前回の実行が終了する前に、これが再び発生した場合の対処法。", @@ -34,7 +50,7 @@ "allow": "両方を同時に実行する" }, "save": "保存", - "created": "自動化が作成しました", + "created": "自動化によって作成されました", "updated": "自動化が保存されました", "deleted": "自動化が削除されました", "deleteConfirm": "この自動化を削除すると、実行履歴も削除されます。", @@ -58,7 +74,7 @@ "viewBuilder": "ビルダー", "viewGraph": "グラフ", "lastRun": "最後の走行", - "never": "一度もない", + "never": "なし", "duration": "{{seconds}}s", "stepOutput": "出力", "stepError": "エラー", @@ -79,7 +95,7 @@ "webhook": "受信ウェブフック" }, "stepTypes": { - "notify": "通知を送信する", + "notify": "アラートを送信する", "http": "URLを呼び出す", "run_snippet": "スニペットを実行する", "run_command": "コマンドを実行する", @@ -90,12 +106,12 @@ "set_var": "変数を設定する", "if": "もし/そうでなければ", "run_automation": "別の自動化を実行する", - "stop": "停止" + "stop": "ストップ" }, "statuses": { - "running": "ランニング", + "running": "実行中", "success": "成功", - "failed": "失敗した", + "failed": "失敗", "timeout": "タイムアウト", "skipped": "スキップしました", "cancelled": "キャンセル" @@ -107,18 +123,18 @@ "operator": "は", "value": "価値", "forSeconds": "(秒)の間持続", - "cooldown": "クールダウン時間(分)", + "cooldown": "クールダウン(分)", "cron": "Cron発現", "intervalSeconds": "(秒)ごとに", "timezone": "タイムゾーン", "timezoneServer": "サーバー時間", "timezoneHint": "このゾーンでは、cronの実行時間が読み取られます。インターバルスケジュールには適用されません。", "container": "容器", - "command": "指示", + "command": "コマンド", "url": "URL", "method": "方法", "body": "体", - "channels": "チャンネル", + "channels": "また、以下へも送信してください。", "title": "タイトル", "message": "メッセージ", "snippet": "抜粋", @@ -135,6 +151,16 @@ "onError": { "stop": "走るのをやめろ", "continue": "続ける" + }, + "needsPlugin": "必要数 {{plugin}}", + "needsPluginHint": "この自動化処理は、必要な機能が再び利用可能になるまでスキップされます。", + "offBadge": "オフ", + "docsLink": "ドキュメントを見る", + "ago": { + "seconds": "{{count}}秒前", + "minutes": "{{count}}分前", + "hours": "{{count}}時間前", + "days": "{{count}}日前" } } } @@ -145,5 +171,41 @@ "onboarding": { "feature_automations": "自動化", "feature_automations_desc": "何かが発生した際に自動的に手順を実行し、通知を受け取ります。" + }, + "maintenance": { + "title": "メンテナンス", + "description": "作業中は、ホストの状態、健全性、メトリック、コンテナ、トンネル切断に関する自動化処理を一時停止します。監視、手動実行、およびスケジュールされた自動化処理は継続されます。", + "denied": "メンテナンス情報を閲覧する権限がありません。", + "sharedReadOnly": "このホストはあなたと共有されています。メンテナンス設定を変更できるのは所有者のみです。", + "failed": "メンテナンスの更新ができませんでした。", + "active": "メンテナンスが有効です", + "estimated": "完成予定", + "noAutoEnd": "見積もりはメンテナンスの終了を意味するものではありません。作業が完了した時点で、明示的に終了してください。", + "endConfirm": "このホストのメンテナンスを終了し、イベントトリガーによる自動化を再開しますか?", + "confirmEnd": "終了を確認する", + "cancel": "キャンセル", + "end": "最終メンテナンス", + "action": "アクション", + "startNow": "今すぐ始めましょう", + "schedule": "後でスケジュールする", + "reason": "理由", + "startUtc": "最初の開始時刻(UTC)", + "repeat": "繰り返す", + "once": "一度", + "weekly": "毎週", + "monthly": "月刊", + "utcHelp": "年間を通してスケジュールはUTCを使用します。月間スケジュールでは、選択した日がない月はスキップされます。計画された作業期間は重複できません。作業期間が超過した場合、その超過作業は後の作業期間にも引き継がれます。", + "duration": "所要時間の目安(分)", + "grace": "猶予期間(分)", + "notify": "推定期間と猶予期間を過ぎてもオフライン状態が続く場合は、一度通知してください。", + "addSchedule": "スケジュールを追加", + "schedules": "スケジュール", + "noSchedules": "メンテナンススケジュールはありません。", + "completed": "既に開始済み", + "minutes_one": "{{count}} 分", + "minutes_other": "{{count}} 分", + "remove": "スケジュールを削除", + "loadFailed": "メンテナンス状況を更新できませんでした。読み込みが完了するまで、変更は無効になっています。", + "loading": "メンテナンスステータスをロード中…" } } diff --git a/plugins/automations/locales/translated/ko_KR.json b/plugins/automations/locales/translated/ko_KR.json index 69f2013b1..3947cebab 100644 --- a/plugins/automations/locales/translated/ko_KR.json +++ b/plugins/automations/locales/translated/ko_KR.json @@ -1,4 +1,26 @@ { + "permissions": { + "view": { + "title": "자동화 보기", + "description": "자동화 기능과 그 이력을 확인하세요." + }, + "create": { + "title": "자동화를 생성하세요", + "description": "새로운 자동화를 추가하세요." + }, + "edit": { + "title": "자동화 편집", + "description": "기존 자동화 설정을 변경하세요." + }, + "delete": { + "title": "자동화 삭제", + "description": "자동화 기능을 제거하세요." + }, + "run": { + "title": "자동화 실행", + "description": "자동화 기능을 수동으로 실행합니다." + } + }, "newUi": { "sidebar": { "automations": { @@ -12,20 +34,14 @@ "editTitle": "편집 자동화", "empty": "아직 자동화가 설정되어 있지 않습니다. 지표, 일정 또는 이벤트에 반응하는 자동화를 생성하세요.", "emptyRuns": "아직 실행된 적이 없습니다.", - "emptyChannels": "아직 채널이 없습니다. 알림을 보낼 채널을 추가하세요.", - "noChannelsHint": "아직 채널이 설정되지 않았습니다. 채널 탭에서 채널을 추가하세요.", - "addChannel": "채널 추가", - "testChannel": "시험", - "channelTestSent": "테스트 알림이 전송되었습니다.", - "channelTestFailed": "테스트 알림 실패", - "channelDeleted": "채널이 삭제되었습니다", - "deleteChannelConfirm": "이 채널을 삭제하시겠습니까? 그러면 해당 채널을 사용하는 자동화 기능이 더 이상 알림을 보내지 않게 됩니다.", + "channelsHint": "알림에 채널이 설정됩니다.", + "noChannelsHint": "알림은 항상 받은 편지함으로 전송됩니다. 알림 설정에서 채널을 추가하면 다른 곳으로도 알림을 보낼 수 있습니다.", "nameLabel": "이름", - "namePlaceholder": "예: /data 폴더가 가득 차면 정리합니다.", - "nameRequired": "이름은 필수 입력 사항입니다.", + "namePlaceholder": "예: /data 디렉토리가 가득 차면 정리합니다.", + "nameRequired": "이름은 필수입니다", "descriptionLabel": "설명", - "descriptionPlaceholder": "선택적 설명", - "enabledLabel": "활성화됨", + "descriptionPlaceholder": "선택 사항 설명", + "enabledLabel": "사용", "concurrencyLabel": "이미 실행 중인 경우", "concurrencyHint": "마지막 실행이 완료되기 전에 이 문제가 다시 발생할 경우 어떻게 해야 할까요?", "concurrency": { @@ -33,7 +49,7 @@ "queue": "기다렸다가 실행하세요", "allow": "두 가지를 동시에 실행하세요" }, - "save": "구하다", + "save": "저장", "created": "자동화 생성됨", "updated": "자동화 저장됨", "deleted": "자동화 삭제됨", @@ -43,7 +59,7 @@ "testRunHint": "모든 단계를 실행하지만 Termix 외부의 어떤 것도 건드리지 않습니다.", "runStarted": "실행 시작됨", "runFinished": "실행 완료: {{status}}", - "trigger": "방아쇠", + "trigger": "트리거", "steps": "단계", "addStep": "단계 추가", "removeStep": "제거 단계", @@ -51,16 +67,16 @@ "moveDown": "아래로 이동", "noSteps": "아직 단계가 없습니다. 어떤 일이 일어나야 하는지 설명하는 단계를 추가하세요.", "webhookTokenTitle": "웹훅 URL", - "webhookTokenDescription": "이 내용은 한 번만 표시됩니다. 지금 저장하세요. 나중에 불러올 수 없습니다.", + "webhookTokenDescription": "이 내용은 한 번만 표시됩니다. 지금 저장하세요. 나중에 다시 불러올 수 없습니다.", "copy": "복사", "copied": "복사됨", "viewJson": "JSON", "viewBuilder": "건축업자", "viewGraph": "그래프", "lastRun": "마지막 실행", - "never": "절대", + "never": "없음", "duration": "{{seconds}}s", - "stepOutput": "산출", + "stepOutput": "출력", "stepError": "오류", "dryRunBadge": "테스트 실행", "hostSelector": { @@ -79,7 +95,7 @@ "webhook": "수신 웹훅" }, "stepTypes": { - "notify": "알림 보내기", + "notify": "알림을 보내세요", "http": "URL을 호출합니다", "run_snippet": "코드 조각을 실행하세요", "run_command": "명령어를 실행하세요", @@ -90,24 +106,24 @@ "set_var": "변수를 설정하세요", "if": "만약 / 그렇지 않다면", "run_automation": "다른 자동화를 실행합니다", - "stop": "멈추다" + "stop": "스톱" }, "statuses": { - "running": "달리기", + "running": "실행 중", "success": "성공", - "failed": "실패한", + "failed": "실패", "timeout": "시간 초과됨", "skipped": "건너뛰었습니다", "cancelled": "취소" }, "fields": { - "host": "주인", - "metric": "미터법", + "host": "호스트", + "metric": "메트릭", "mount": "마운트 포인트", "operator": "~이다", "value": "값", "forSeconds": "(초) 동안 지속됨", - "cooldown": "재사용 대기 시간(분)", + "cooldown": "쿨다운 (분)", "cron": "크론 발현", "intervalSeconds": "매 (초)", "timezone": "시간대", @@ -118,7 +134,7 @@ "url": "URL", "method": "방법", "body": "몸", - "channels": "채널", + "channels": "또한 다음에도 보내주세요", "title": "제목", "message": "메시지", "snippet": "단편", @@ -135,6 +151,16 @@ "onError": { "stop": "달리기를 멈춰라", "continue": "계속하세요" + }, + "needsPlugin": "{{plugin}}가 필요합니다", + "needsPluginHint": "이 자동화 작업은 필요한 기능이 다시 사용 가능해질 때까지 건너뛰어집니다.", + "offBadge": "꺼짐", + "docsLink": "문서 보기", + "ago": { + "seconds": "{{count}}초 전", + "minutes": "{{count}}분 전", + "hours": "{{count}}시간 전", + "days": "{{count}}일 전" } } } @@ -145,5 +171,41 @@ "onboarding": { "feature_automations": "자동화", "feature_automations_desc": "어떤 상황이 발생하면 자동으로 단계를 실행하고 알림을 받으세요." + }, + "maintenance": { + "title": "유지 관리", + "description": "작업이 진행되는 동안 호스트 상태, 상태 모니터링, 메트릭 모니터링, 컨테이너 모니터링 및 터널 연결 해제 자동화가 일시 중지됩니다. 모니터링, 수동 실행 및 예약된 자동화는 계속 실행됩니다.", + "denied": "유지보수 화면을 볼 권한이 없습니다.", + "sharedReadOnly": "이 호스트는 귀하와 공유되었습니다. 유지 관리 변경은 호스트 소유자만 할 수 있습니다.", + "failed": "유지보수 업데이트를 할 수 없습니다.", + "active": "유지보수 중", + "estimated": "예상 완료일", + "noAutoEnd": "견적은 유지보수를 종료하는 것이 아닙니다. 작업이 완료되면 명시적으로 유지보수를 종료하십시오.", + "endConfirm": "이 호스트에 대한 유지 관리를 종료하고 이벤트 기반 자동화를 다시 시작하시겠습니까?", + "confirmEnd": "종료 확인", + "cancel": "취소", + "end": "유지보수 종료", + "action": "작업", + "startNow": "지금 시작하세요", + "schedule": "나중에 일정 잡기", + "reason": "이유", + "startUtc": "첫 시작 (UTC)", + "repeat": "반복하다", + "once": "한 번", + "weekly": "주간", + "monthly": "월간 간행물", + "utcHelp": "일정은 연중 UTC를 기준으로 합니다. 월별 일정은 선택한 날짜가 없는 달은 건너뜁니다. 계획된 기간은 겹칠 수 없으며, 연장된 유지 보수 작업은 이후 기간에도 계속됩니다.", + "duration": "예상 소요 시간(분)", + "grace": "유예 기간(분)", + "notify": "예상 시간 및 유예 기간이 지난 후에도 오프라인 상태인 경우 한 번만 알림을 보내주세요.", + "addSchedule": "일정을 추가하세요", + "schedules": "일정", + "noSchedules": "정기 유지보수 일정이 없습니다.", + "completed": "이미 시작했습니다", + "minutes_one": "{{count}} 분", + "minutes_other": "{{count}} 분", + "remove": "일정을 삭제합니다", + "loadFailed": "점검 상태를 새로 고칠 수 없습니다. 점검 상태가 로드될 때까지 변경 사항이 적용되지 않습니다.", + "loading": "유지보수 상태 로딩 중…" } } diff --git a/plugins/automations/locales/translated/nl_NL.json b/plugins/automations/locales/translated/nl_NL.json index 4ff9589cc..17accf2fd 100644 --- a/plugins/automations/locales/translated/nl_NL.json +++ b/plugins/automations/locales/translated/nl_NL.json @@ -1,4 +1,26 @@ { + "permissions": { + "view": { + "title": "Automatiseringen bekijken", + "description": "Bekijk de automatiseringen en hun geschiedenis." + }, + "create": { + "title": "Automatiseringen maken", + "description": "Voeg nieuwe automatiseringen toe." + }, + "edit": { + "title": "Automatiseringen bewerken", + "description": "Wijzig bestaande automatiseringsprocessen." + }, + "delete": { + "title": "Automatiseringen verwijderen", + "description": "Automatiseringen uitschakelen." + }, + "run": { + "title": "Automatiseringen uitvoeren", + "description": "Activeer een automatisering handmatig." + } + }, "newUi": { "sidebar": { "automations": { @@ -12,14 +34,8 @@ "editTitle": "Automatisering bewerken", "empty": "Nog geen automatiseringen. Maak er een aan die reageert op een meetwaarde, een planning of een gebeurtenis.", "emptyRuns": "Nog geen runs.", - "emptyChannels": "Nog geen kanalen. Voeg er een toe om meldingen ergens naartoe te sturen.", - "noChannelsHint": "Er zijn nog geen kanalen ingesteld. Voeg er een toe via het tabblad Kanalen.", - "addChannel": "Kanaal toevoegen", - "testChannel": "Test", - "channelTestSent": "Testmelding verzonden", - "channelTestFailed": "Testmelding mislukt", - "channelDeleted": "Kanaal verwijderd", - "deleteChannelConfirm": "Als u dit kanaal wilt verwijderen, zullen automatiseringsprocessen die ervan gebruikmaken geen meldingen meer versturen.", + "channelsHint": "Kanalen worden ingesteld in waarschuwingen.", + "noChannelsHint": "De melding komt altijd in je inbox terecht. Voeg kanalen toe in Meldingen om de melding ook naar een andere locatie te verzenden.", "nameLabel": "Naam", "namePlaceholder": "Bijvoorbeeld: maak /data leeg wanneer het vol is.", "nameRequired": "Naam is verplicht", @@ -31,7 +47,7 @@ "concurrency": { "skip": "Sla de nieuwe run over", "queue": "Wacht en ren erachteraan.", - "allow": "Voer ze allebei tegelijk uit." + "allow": "Voer ze allebei tegelijk uit" }, "save": "Redden", "created": "Automatisering gecreëerd", @@ -40,7 +56,7 @@ "deleteConfirm": "Als je deze automatisering verwijdert, wordt ook de uitvoeringsgeschiedenis ervan verwijderd.", "runNow": "Ren nu", "testRun": "Testrun", - "testRunHint": "Voert elke stap uit, maar raakt niets buiten Termix aan.", + "testRunHint": "Het voert elke stap uit, maar raakt niets buiten Termix aan.", "runStarted": "De run is gestart.", "runFinished": "Run voltooid: {{status}}", "trigger": "Trekker", @@ -79,10 +95,10 @@ "webhook": "Inkomende webhook" }, "stepTypes": { - "notify": "Een melding verzenden", + "notify": "Verzend een melding", "http": "Roep een URL aan", "run_snippet": "Voer een codefragment uit", - "run_command": "Voer een commando uit", + "run_command": "Voer een opdracht uit", "docker": "Een container besturen", "tunnel": "Beheer een tunnel", "wol": "Maak een gastheer wakker", @@ -118,7 +134,7 @@ "url": "URL", "method": "Methode", "body": "Lichaam", - "channels": "Kanalen", + "channels": "Ook verzenden naar", "title": "Titel", "message": "Bericht", "snippet": "Fragment", @@ -135,6 +151,16 @@ "onError": { "stop": "Stop de loop", "continue": "Ga zo door" + }, + "needsPlugin": "Vereist {{plugin}}", + "needsPluginHint": "Deze automatisering wordt overgeslagen totdat de benodigde functie weer beschikbaar is.", + "offBadge": "Uit", + "docsLink": "Documenten bekijken", + "ago": { + "seconds": "{{count}}s geleden", + "minutes": "{{count}}m geleden", + "hours": "{{count}}uur geleden", + "days": "{{count}}dagen geleden" } } } @@ -145,5 +171,41 @@ "onboarding": { "feature_automations": "Automatiseringen", "feature_automations_desc": "Voer stappen automatisch uit wanneer er iets gebeurt en ontvang meldingen." + }, + "maintenance": { + "title": "Onderhoud", + "description": "Pauzeer de automatiseringsprocessen voor hoststatus, gezondheid, metrics, containers en tunnelontkoppeling terwijl de werkzaamheden worden uitgevoerd. Monitoring, handmatige uitvoeringen en geplande automatiseringsprocessen worden wel voortgezet.", + "denied": "U hebt geen toestemming om onderhoudswerkzaamheden te bekijken.", + "sharedReadOnly": "Deze host is met u gedeeld. Alleen de eigenaar kan het onderhoud wijzigen.", + "failed": "Het onderhoud kon niet worden bijgewerkt.", + "active": "Onderhoud actief", + "estimated": "Geschatte voltooiing", + "noAutoEnd": "De begroting beëindigt het onderhoud niet. Beëindig het expliciet wanneer de werkzaamheden zijn voltooid.", + "endConfirm": "Onderhoud beëindigen en gebeurtenisgestuurde automatiseringen voor deze host hervatten?", + "confirmEnd": "Bevestig einde", + "cancel": "Annuleren", + "end": "Einde onderhoud", + "action": "Actie", + "startNow": "Begin nu", + "schedule": "Plan voor later", + "reason": "Reden", + "startUtc": "Eerste start (UTC)", + "repeat": "Herhalen", + "once": "Eenmaal", + "weekly": "Wekelijks", + "monthly": "Maandelijks", + "utcHelp": "De planning gebruikt het hele jaar door UTC. Maandelijkse planningen slaan maanden over waarin de geselecteerde dag niet voorkomt. Geplande onderhoudsvensters mogen elkaar niet overlappen; uitlopend onderhoud wordt voortgezet in latere vensters.", + "duration": "Geschatte duur (minuten)", + "grace": "Respijtperiode (minuten)", + "notify": "Eenmalige melding verzenden indien de verbinding na de geschatte tijd plus de respijtperiode nog steeds verbroken is.", + "addSchedule": "Voeg een schema toe", + "schedules": "Roosters", + "noSchedules": "Geen onderhoudsschema's.", + "completed": "Reeds begonnen", + "minutes_one": "{{count}} minuut", + "minutes_other": "{{count}} minuten", + "remove": "Schema verwijderen", + "loadFailed": "De onderhoudsstatus kon niet worden vernieuwd. Wijzigingen zijn uitgeschakeld totdat de status kan worden geladen.", + "loading": "Onderhoudsstatus laden…" } } diff --git a/plugins/automations/locales/translated/no_NO.json b/plugins/automations/locales/translated/no_NO.json index 226688470..c74f6f289 100644 --- a/plugins/automations/locales/translated/no_NO.json +++ b/plugins/automations/locales/translated/no_NO.json @@ -1,149 +1,211 @@ { + "permissions": { + "view": { + "title": "View automations", + "description": "See the automations and their history." + }, + "create": { + "title": "Create automations", + "description": "Add new automations." + }, + "edit": { + "title": "Edit automations", + "description": "Change existing automations." + }, + "delete": { + "title": "Delete automations", + "description": "Remove automations." + }, + "run": { + "title": "Run automations", + "description": "Trigger an automation by hand." + } + }, "newUi": { "sidebar": { "automations": { - "title": "Automatiseringer", - "tabAutomations": "Automatiseringer", - "tabRuns": "Løper", - "tabChannels": "Kanaler", - "createAutomation": "Ny automatisering", - "backToAutomations": "Tilbake til automatiseringer", - "createTitle": "Ny automatisering", - "editTitle": "Rediger automatisering", - "empty": "Ingen automatiseringer ennå. Opprett en for å reagere på en beregning, en tidsplan eller en hendelse.", - "emptyRuns": "Ingen løp ennå.", - "emptyChannels": "Ingen kanaler ennå. Legg til en for å sende varsler et sted.", - "noChannelsHint": "Ingen kanaler er konfigurert ennå. Legg til en i Kanaler-fanen.", - "addChannel": "Legg til kanal", - "testChannel": "Test", - "channelTestSent": "Testvarsel sendt", - "channelTestFailed": "Testvarsel mislyktes", - "channelDeleted": "Kanalen slettet", - "deleteChannelConfirm": "Vil du slette denne kanalen? Automatiseringer som bruker den, vil slutte å varsle.", + "title": "Automations", + "tabAutomations": "Automations", + "tabRuns": "Runs", + "tabChannels": "Channels", + "createAutomation": "New Automation", + "backToAutomations": "Back to Automations", + "createTitle": "New Automation", + "editTitle": "Edit Automation", + "empty": "No automations yet. Create one to react to a metric, a schedule, or an event.", + "emptyRuns": "No runs yet.", + "channelsHint": "Channels are set up in Alerts", + "noChannelsHint": "The alert always goes to your inbox. Add channels in Alerts to also send it somewhere else.", "nameLabel": "Navn", - "namePlaceholder": "f.eks. Rydd opp i /data når den fylles", - "nameRequired": "Navn er obligatorisk", + "namePlaceholder": "e.g., Clean up /data when it fills", + "nameRequired": "Navn er påkrevd", "descriptionLabel": "Beskrivelse", "descriptionPlaceholder": "Valgfri beskrivelse", "enabledLabel": "Aktivert", - "concurrencyLabel": "Hvis den allerede kjører", - "concurrencyHint": "Hva skal man gjøre når dette utløses igjen før siste kjøring er ferdig?", + "concurrencyLabel": "If it is already running", + "concurrencyHint": "What to do when this is triggered again before the last run has finished.", "concurrency": { - "skip": "Hopp over den nye kjøringen", - "queue": "Vent og løp etter", - "allow": "Kjør begge samtidig" + "skip": "Skip the new run", + "queue": "Wait and run after", + "allow": "Run both at once" }, - "save": "Spare", - "created": "Automatisering opprettet", - "updated": "Automatisering lagret", - "deleted": "Automatisering slettet", - "deleteConfirm": "Vil du slette denne automatiseringen? Kjørehistorikken slettes også.", - "runNow": "Løp nå", - "testRun": "Testkjøring", - "testRunHint": "Kjører hvert trinn, men berører ikke noe utenfor Termix.", - "runStarted": "Løpet startet", - "runFinished": "Kjøring fullført: {{status}}", - "trigger": "Avtrekker", - "steps": "Trinn", - "addStep": "Legg til trinn", - "removeStep": "Fjern trinn", - "moveUp": "Flytt opp", - "moveDown": "Flytt ned", - "noSteps": "Ingen trinn ennå. Legg til ett for å si hva som skal skje.", - "webhookTokenTitle": "Webhook-URL", - "webhookTokenDescription": "Dette vises én gang. Lagre det nå, det kan ikke hentes frem senere.", - "copy": "Kopiere", - "copied": "Kopiert", + "save": "Lagre", + "created": "Automation created", + "updated": "Automation saved", + "deleted": "Automation deleted", + "deleteConfirm": "Delete this automation? Its run history is deleted too.", + "runNow": "Run now", + "testRun": "Test run", + "testRunHint": "Runs every step but does not touch anything outside Termix.", + "runStarted": "Run started", + "runFinished": "Run finished: {{status}}", + "trigger": "Trigger", + "steps": "Steps", + "addStep": "Add step", + "removeStep": "Remove step", + "moveUp": "Move up", + "moveDown": "Move down", + "noSteps": "No steps yet. Add one to say what should happen.", + "webhookTokenTitle": "Webhook URL", + "webhookTokenDescription": "This is shown once. Save it now, it cannot be retrieved later.", + "copy": "Kopier", + "copied": "Copied", "viewJson": "JSON", - "viewBuilder": "Bygger", - "viewGraph": "Kurve", - "lastRun": "Siste løp", - "never": "Aldri", + "viewBuilder": "Builder", + "viewGraph": "Graph", + "lastRun": "Last run", + "never": "Never", "duration": "{{seconds}}s", - "stepOutput": "Produksjon", + "stepOutput": "Output", "stepError": "Feil", - "dryRunBadge": "Testkjøring", + "dryRunBadge": "Test run", "hostSelector": { - "trigger": "Utløsende vert", - "host": "Spesifikk vert", - "fleet": "Flåte", - "all": "Alle verter" + "trigger": "Triggering host", + "host": "Specific host", + "fleet": "Fleet", + "all": "All hosts" }, "triggerKinds": { - "metric_threshold": "Metrisk terskel", - "host_status": "Verten går opp eller ned", - "health_check": "Endringer i helsesjekken", - "schedule": "På en tidsplan", - "docker_event": "Containerhendelse", - "internal_event": "Termix-arrangementet", - "webhook": "Innkommende webhook" + "metric_threshold": "Metric threshold", + "host_status": "Host goes up or down", + "health_check": "Health check changes", + "schedule": "On a schedule", + "docker_event": "Container event", + "internal_event": "Termix event", + "webhook": "Incoming webhook" }, "stepTypes": { - "notify": "Send et varsel", - "http": "Kall en URL", - "run_snippet": "Kjør et utdrag", - "run_command": "Kjør en kommando", - "docker": "Kontroller en container", - "tunnel": "Kontroller en tunnel", - "wol": "Vekk en vert", - "wait": "Vente", - "set_var": "Angi en variabel", - "if": "Hvis / ellers", - "run_automation": "Kjør en annen automatisering", - "stop": "Stoppe" + "notify": "Send an alert", + "http": "Call a URL", + "run_snippet": "Run a snippet", + "run_command": "Run a command", + "docker": "Control a container", + "tunnel": "Control a tunnel", + "wol": "Wake a host", + "wait": "Wait", + "set_var": "Set a variable", + "if": "If / otherwise", + "run_automation": "Run another automation", + "stop": "Stopp" }, "statuses": { - "running": "Løping", + "running": "Kjører", "success": "Suksess", "failed": "Mislyktes", - "timeout": "Tidsavbrutt", - "skipped": "Hoppet over", - "cancelled": "Avlyst" + "timeout": "Timed out", + "skipped": "Skipped", + "cancelled": "Cancelled" }, "fields": { - "host": "Vert", - "metric": "Metrisk", - "mount": "Monteringspunkt", - "operator": "Er", - "value": "Verdi", - "forSeconds": "Vedvarende i (sekunder)", - "cooldown": "Nedkjølingstid (minutter)", - "cron": "Cron-uttrykk", - "intervalSeconds": "Hvert (sekund)", - "timezone": "Tidssone", - "timezoneServer": "Servertid", - "timezoneHint": "Cron-tider leses i denne sonen. Gjelder ikke for intervallplaner.", + "host": "Host", + "metric": "Metric", + "mount": "Mount point", + "operator": "Is", + "value": "Value", + "forSeconds": "Sustained for (seconds)", + "cooldown": "Cooldown (minutes)", + "cron": "Cron expression", + "intervalSeconds": "Every (seconds)", + "timezone": "Time zone", + "timezoneServer": "Server time", + "timezoneHint": "Cron times are read in this zone. Does not apply to interval schedules.", "container": "Container", "command": "Kommando", - "url": "URL-adresse", - "method": "Metode", - "body": "Kropp", - "channels": "Kanaler", - "title": "Tittel", - "message": "Beskjed", - "snippet": "Utdrag", - "seconds": "Sekunder", - "conditionLeftPlaceholder": "Verdi å sjekke", - "conditionRightPlaceholder": "Sammenlign mot", - "variableName": "Variabelnavn", - "variableValue": "Verdi", - "elevated": "Kjør med sudo", - "onError": "Hvis dette mislykkes", - "allowPrivateNetwork": "Tillat lokale nettverksadresser", - "allowPrivateNetworkHint": "Nødvendig for en selvhostet tjeneste på LAN-et ditt. Av som standard for å forhindre forespørsler til interne adresser." + "url": "URL", + "method": "Method", + "body": "Body", + "channels": "Also send to", + "title": "Title", + "message": "Message", + "snippet": "Snippet", + "seconds": "Seconds", + "conditionLeftPlaceholder": "Value to check", + "conditionRightPlaceholder": "Compare against", + "variableName": "Variable name", + "variableValue": "Value", + "elevated": "Run with sudo", + "onError": "If this fails", + "allowPrivateNetwork": "Allow local network addresses", + "allowPrivateNetworkHint": "Needed for a self-hosted service on your LAN. Off by default to prevent requests to internal addresses." }, "onError": { - "stop": "Stopp løpet", - "continue": "Fortsett" + "stop": "Stop the run", + "continue": "Carry on" + }, + "needsPlugin": "Needs {{plugin}}", + "needsPluginHint": "This automation is skipped until the feature it needs is available again.", + "offBadge": "Off", + "docsLink": "View docs", + "ago": { + "seconds": "{{count}}s ago", + "minutes": "{{count}}m ago", + "hours": "{{count}}h ago", + "days": "{{count}}d ago" } } } }, "nav": { - "automations": "Automatiseringer" + "automations": "Automations" }, "onboarding": { - "feature_automations": "Automatiseringer", - "feature_automations_desc": "Kjør trinnene automatisk når noe skjer, og bli varslet." + "feature_automations": "Automations", + "feature_automations_desc": "Run steps automatically when something happens, and get notified." + }, + "maintenance": { + "title": "Vedlikehold", + "description": "Pause host status, health, metric, container and tunnel-disconnection automations while work is in progress. Monitoring, manual runs and scheduled automations continue.", + "denied": "You do not have permission to view maintenance.", + "sharedReadOnly": "This host was shared with you. Only its owner can change maintenance.", + "failed": "Maintenance could not be updated.", + "active": "Maintenance active", + "estimated": "Estimated completion", + "noAutoEnd": "The estimate does not end maintenance. End it explicitly when the work is complete.", + "endConfirm": "End maintenance and resume event-triggered automations for this host?", + "confirmEnd": "Confirm end", + "cancel": "Avbryt", + "end": "End maintenance", + "action": "Action", + "startNow": "Start now", + "schedule": "Schedule for later", + "reason": "Reason", + "startUtc": "First start (UTC)", + "repeat": "Repeat", + "once": "Once", + "weekly": "Weekly", + "monthly": "Monthly", + "utcHelp": "Schedules use UTC throughout the year. Monthly schedules skip months without the selected day. Planned windows cannot overlap; overrunning maintenance continues across later windows.", + "duration": "Estimated duration (minutes)", + "grace": "Grace period (minutes)", + "notify": "Notify once if still offline after the estimate plus grace period", + "addSchedule": "Add schedule", + "schedules": "Schedules", + "noSchedules": "No maintenance schedules.", + "completed": "Already started", + "minutes_one": "{{count}} minute", + "minutes_other": "{{count}} minutes", + "remove": "Remove schedule", + "loadFailed": "Could not refresh maintenance status. Changes are disabled until it can be loaded.", + "loading": "Loading maintenance status…" } } diff --git a/plugins/automations/locales/translated/pl_PL.json b/plugins/automations/locales/translated/pl_PL.json index 06bcac36c..2a06a9864 100644 --- a/plugins/automations/locales/translated/pl_PL.json +++ b/plugins/automations/locales/translated/pl_PL.json @@ -1,4 +1,26 @@ { + "permissions": { + "view": { + "title": "View automations", + "description": "See the automations and their history." + }, + "create": { + "title": "Create automations", + "description": "Add new automations." + }, + "edit": { + "title": "Edit automations", + "description": "Change existing automations." + }, + "delete": { + "title": "Delete automations", + "description": "Remove automations." + }, + "run": { + "title": "Run automations", + "description": "Trigger an automation by hand." + } + }, "newUi": { "sidebar": { "automations": { @@ -12,14 +34,8 @@ "editTitle": "Edytuj automatyzację", "empty": "Brak jeszcze automatyzacji. Utwórz automatyzację, która będzie reagować na metrykę, harmonogram lub zdarzenie.", "emptyRuns": "Brak uruchomień.", - "emptyChannels": "Brak kanałów. Dodaj jeden, aby wysyłać powiadomienia.", - "noChannelsHint": "Nie skonfigurowano jeszcze żadnych kanałów. Dodaj jeden w zakładce Kanały.", - "addChannel": "Dodaj kanał", - "testChannel": "Test", - "channelTestSent": "Wysłano powiadomienie testowe", - "channelTestFailed": "Powiadomienie testowe nie powiodło się", - "channelDeleted": "Kanał usunięty", - "deleteChannelConfirm": "Usunąć ten kanał? Automatyzacje z niego korzystające przestaną wysyłać powiadomienia.", + "channelsHint": "Channels are set up in Alerts", + "noChannelsHint": "The alert always goes to your inbox. Add channels in Alerts to also send it somewhere else.", "nameLabel": "Nazwa", "namePlaceholder": "np. Wyczyść /data, gdy się zapełni", "nameRequired": "Nazwa jest wymagana", @@ -79,7 +95,7 @@ "webhook": "Przychodzący webhook" }, "stepTypes": { - "notify": "Wyślij powiadomienie", + "notify": "Send an alert", "http": "Wywołaj adres URL", "run_snippet": "Uruchom snippet", "run_command": "Uruchom polecenie", @@ -118,7 +134,7 @@ "url": "Adres URL", "method": "Metoda", "body": "Treść", - "channels": "Kanały", + "channels": "Also send to", "title": "Tytuł", "message": "Wiadomość", "snippet": "Snippet", @@ -135,6 +151,16 @@ "onError": { "stop": "Zatrzymaj uruchomienie", "continue": "Kontynuuj" + }, + "needsPlugin": "Needs {{plugin}}", + "needsPluginHint": "This automation is skipped until the feature it needs is available again.", + "offBadge": "Wył.", + "docsLink": "Zobacz dokumentację", + "ago": { + "seconds": "{{count}}s ago", + "minutes": "{{count}} min temu", + "hours": "{{count}} godz. temu", + "days": "{{count}} dni temu" } } } @@ -145,5 +171,41 @@ "onboarding": { "feature_automations": "Automatyzacje", "feature_automations_desc": "Uruchamiaj kroki automatycznie, gdy coś się wydarzy, i otrzymuj powiadomienia." + }, + "maintenance": { + "title": "Konserwacja", + "description": "Pause host status, health, metric, container and tunnel-disconnection automations while work is in progress. Monitoring, manual runs and scheduled automations continue.", + "denied": "You do not have permission to view maintenance.", + "sharedReadOnly": "This host was shared with you. Only its owner can change maintenance.", + "failed": "Maintenance could not be updated.", + "active": "Maintenance active", + "estimated": "Estimated completion", + "noAutoEnd": "The estimate does not end maintenance. End it explicitly when the work is complete.", + "endConfirm": "End maintenance and resume event-triggered automations for this host?", + "confirmEnd": "Confirm end", + "cancel": "Anuluj", + "end": "End maintenance", + "action": "Akcja", + "startNow": "Start now", + "schedule": "Schedule for later", + "reason": "Reason", + "startUtc": "First start (UTC)", + "repeat": "Powtórz", + "once": "Once", + "weekly": "Weekly", + "monthly": "Monthly", + "utcHelp": "Schedules use UTC throughout the year. Monthly schedules skip months without the selected day. Planned windows cannot overlap; overrunning maintenance continues across later windows.", + "duration": "Estimated duration (minutes)", + "grace": "Grace period (minutes)", + "notify": "Notify once if still offline after the estimate plus grace period", + "addSchedule": "Add schedule", + "schedules": "Schedules", + "noSchedules": "No maintenance schedules.", + "completed": "Already started", + "minutes_one": "{{count}} minute", + "minutes_other": "{{count}} minutes", + "remove": "Remove schedule", + "loadFailed": "Could not refresh maintenance status. Changes are disabled until it can be loaded.", + "loading": "Loading maintenance status…" } } diff --git a/plugins/automations/locales/translated/pt_BR.json b/plugins/automations/locales/translated/pt_BR.json index b198fcf0d..5489a735d 100644 --- a/plugins/automations/locales/translated/pt_BR.json +++ b/plugins/automations/locales/translated/pt_BR.json @@ -1,149 +1,211 @@ { + "permissions": { + "view": { + "title": "View automations", + "description": "See the automations and their history." + }, + "create": { + "title": "Create automations", + "description": "Add new automations." + }, + "edit": { + "title": "Edit automations", + "description": "Change existing automations." + }, + "delete": { + "title": "Delete automations", + "description": "Remove automations." + }, + "run": { + "title": "Run automations", + "description": "Trigger an automation by hand." + } + }, "newUi": { "sidebar": { "automations": { - "title": "Automações", - "tabAutomations": "Automações", - "tabRuns": "Corridas", - "tabChannels": "Canais", - "createAutomation": "Nova Automação", - "backToAutomations": "Voltar para Automações", - "createTitle": "Nova Automação", - "editTitle": "Editar Automação", - "empty": "Ainda não há automações. Crie uma para reagir a uma métrica, a um agendamento ou a um evento.", - "emptyRuns": "Ainda não houve nenhuma corrida.", - "emptyChannels": "Ainda não há canais. Adicione um para enviar notificações para algum lugar.", - "noChannelsHint": "Nenhum canal configurado ainda. Adicione um na aba Canais.", - "addChannel": "Adicionar canal", - "testChannel": "Teste", - "channelTestSent": "Notificação de teste enviada", - "channelTestFailed": "Falha na notificação de teste", - "channelDeleted": "Canal excluído", - "deleteChannelConfirm": "Excluir este canal? As automações que o utilizam deixarão de enviar notificações.", - "nameLabel": "Nome", - "namePlaceholder": "Por exemplo, limpe a pasta /data quando ela estiver cheia.", - "nameRequired": "O nome é obrigatório.", - "descriptionLabel": "Descrição", - "descriptionPlaceholder": "Descrição opcional", - "enabledLabel": "Habilitado", - "concurrencyLabel": "Se já estiver em execução", - "concurrencyHint": "O que fazer quando isso for acionado novamente antes da última execução terminar?", + "title": "Automations", + "tabAutomations": "Automations", + "tabRuns": "Runs", + "tabChannels": "Channels", + "createAutomation": "New Automation", + "backToAutomations": "Back to Automations", + "createTitle": "New Automation", + "editTitle": "Edit Automation", + "empty": "No automations yet. Create one to react to a metric, a schedule, or an event.", + "emptyRuns": "No runs yet.", + "channelsHint": "Channels are set up in Alerts", + "noChannelsHint": "The alert always goes to your inbox. Add channels in Alerts to also send it somewhere else.", + "nameLabel": "Name", + "namePlaceholder": "e.g., Clean up /data when it fills", + "nameRequired": "Name is required", + "descriptionLabel": "Description", + "descriptionPlaceholder": "Optional description", + "enabledLabel": "Enabled", + "concurrencyLabel": "If it is already running", + "concurrencyHint": "What to do when this is triggered again before the last run has finished.", "concurrency": { - "skip": "Pule a nova corrida", - "queue": "Espere e corra atrás.", - "allow": "Execute ambos simultaneamente" + "skip": "Skip the new run", + "queue": "Wait and run after", + "allow": "Run both at once" }, "save": "Salvar", - "created": "Automação criada", - "updated": "Automação economizou", - "deleted": "Automação excluída", - "deleteConfirm": "Excluir esta automação? O histórico de execução dela também será excluído.", - "runNow": "Corra agora", - "testRun": "Teste de execução", - "testRunHint": "Executa cada etapa, mas não toca em nada fora do Termix.", - "runStarted": "A corrida começou.", - "runFinished": "Execução concluída: {{status}}", - "trigger": "Acionar", - "steps": "Passos", - "addStep": "Adicionar etapa", - "removeStep": "Remover etapa", - "moveUp": "Suba", - "moveDown": "Desça", - "noSteps": "Ainda não há etapas. Adicione uma para descrever o que deve acontecer.", - "webhookTokenTitle": "URL do Webhook", - "webhookTokenDescription": "Esta mensagem será exibida apenas uma vez. Salve-a agora, pois não poderá ser recuperada posteriormente.", - "copy": "Cópia", + "created": "Automation created", + "updated": "Automation saved", + "deleted": "Automation deleted", + "deleteConfirm": "Delete this automation? Its run history is deleted too.", + "runNow": "Run now", + "testRun": "Test run", + "testRunHint": "Runs every step but does not touch anything outside Termix.", + "runStarted": "Run started", + "runFinished": "Run finished: {{status}}", + "trigger": "Trigger", + "steps": "Steps", + "addStep": "Add step", + "removeStep": "Remove step", + "moveUp": "Move up", + "moveDown": "Move down", + "noSteps": "No steps yet. Add one to say what should happen.", + "webhookTokenTitle": "Webhook URL", + "webhookTokenDescription": "This is shown once. Save it now, it cannot be retrieved later.", + "copy": "Copiar", "copied": "Copiado", "viewJson": "JSON", - "viewBuilder": "Construtor", - "viewGraph": "Gráfico", - "lastRun": "Última corrida", - "never": "Nunca", + "viewBuilder": "Builder", + "viewGraph": "Graph", + "lastRun": "Last run", + "never": "Never", "duration": "{{seconds}}s", - "stepOutput": "Saída", + "stepOutput": "Output", "stepError": "Erro", - "dryRunBadge": "Teste de execução", + "dryRunBadge": "Test run", "hostSelector": { - "trigger": "Host que desencadeia o ataque", - "host": "hospedeiro específico", - "fleet": "Frota", - "all": "Todos os anfitriões" + "trigger": "Triggering host", + "host": "Specific host", + "fleet": "Fleet", + "all": "All hosts" }, "triggerKinds": { - "metric_threshold": "Limiar métrico", - "host_status": "O host sobe ou desce.", - "health_check": "Alterações na verificação de saúde", - "schedule": "De acordo com um cronograma", - "docker_event": "Evento de contêiner", - "internal_event": "Evento Termix", - "webhook": "Webhook de entrada" + "metric_threshold": "Metric threshold", + "host_status": "Host goes up or down", + "health_check": "Health check changes", + "schedule": "On a schedule", + "docker_event": "Container event", + "internal_event": "Termix event", + "webhook": "Incoming webhook" }, "stepTypes": { - "notify": "Enviar notificação", - "http": "Chamar um URL", - "run_snippet": "Executar um trecho de código", - "run_command": "Executar um comando", - "docker": "Controle um contêiner", - "tunnel": "Controle um túnel", - "wol": "Acorde um anfitrião", - "wait": "Espere", - "set_var": "Defina uma variável", - "if": "Se/caso contrário", - "run_automation": "Execute outra automação", - "stop": "Parar" + "notify": "Send an alert", + "http": "Call a URL", + "run_snippet": "Run a snippet", + "run_command": "Run a command", + "docker": "Control a container", + "tunnel": "Control a tunnel", + "wol": "Wake a host", + "wait": "Wait", + "set_var": "Set a variable", + "if": "If / otherwise", + "run_automation": "Run another automation", + "stop": "Stop" }, "statuses": { - "running": "Correndo", - "success": "Sucesso", - "failed": "Fracassado", - "timeout": "Tempo limite excedido", - "skipped": "Ignorado", - "cancelled": "Cancelado" + "running": "Running", + "success": "Success", + "failed": "Failed", + "timeout": "Timed out", + "skipped": "Skipped", + "cancelled": "Cancelled" }, "fields": { - "host": "Hospedar", - "metric": "Métrica", - "mount": "Ponto de montagem", - "operator": "É", - "value": "Valor", - "forSeconds": "Sustentado por (segundos)", - "cooldown": "Tempo de resfriamento (minutos)", - "cron": "Expressão de Cron", - "intervalSeconds": "A cada (segundos)", - "timezone": "Fuso horário", - "timezoneServer": "Hora do servidor", - "timezoneHint": "Os horários cron são lidos nesta zona. Não se aplica a agendamentos por intervalo.", - "container": "Recipiente", - "command": "Comando", + "host": "Host", + "metric": "Metric", + "mount": "Mount point", + "operator": "Is", + "value": "Value", + "forSeconds": "Sustained for (seconds)", + "cooldown": "Cooldown (minutes)", + "cron": "Cron expression", + "intervalSeconds": "Every (seconds)", + "timezone": "Time zone", + "timezoneServer": "Server time", + "timezoneHint": "Cron times are read in this zone. Does not apply to interval schedules.", + "container": "Container", + "command": "Command", "url": "URL", - "method": "Método", - "body": "Corpo", - "channels": "Canais", - "title": "Título", - "message": "Mensagem", - "snippet": "Trecho", - "seconds": "Segundos", - "conditionLeftPlaceholder": "Valor a verificar", - "conditionRightPlaceholder": "Compare com", - "variableName": "Nome da variável", - "variableValue": "Valor", - "elevated": "Executar com sudo", - "onError": "Se isso falhar", - "allowPrivateNetwork": "Permitir endereços de rede local", - "allowPrivateNetworkHint": "Necessário para um serviço autohospedado em sua rede local (LAN). Desativado por padrão para evitar solicitações a endereços internos." + "method": "Method", + "body": "Body", + "channels": "Also send to", + "title": "Title", + "message": "Message", + "snippet": "Snippet", + "seconds": "Seconds", + "conditionLeftPlaceholder": "Value to check", + "conditionRightPlaceholder": "Compare against", + "variableName": "Variable name", + "variableValue": "Value", + "elevated": "Run with sudo", + "onError": "If this fails", + "allowPrivateNetwork": "Allow local network addresses", + "allowPrivateNetworkHint": "Needed for a self-hosted service on your LAN. Off by default to prevent requests to internal addresses." }, "onError": { - "stop": "Pare a corrida", - "continue": "Continuar" + "stop": "Stop the run", + "continue": "Carry on" + }, + "needsPlugin": "Needs {{plugin}}", + "needsPluginHint": "This automation is skipped until the feature it needs is available again.", + "offBadge": "Off", + "docsLink": "Documentação", + "ago": { + "seconds": "{{count}}s ago", + "minutes": "{{count}}m ago", + "hours": "{{count}}h ago", + "days": "{{count}}d ago" } } } }, "nav": { - "automations": "Automações" + "automations": "Automations" }, "onboarding": { - "feature_automations": "Automações", - "feature_automations_desc": "Execute etapas automaticamente quando algo acontecer e receba notificações." + "feature_automations": "Automations", + "feature_automations_desc": "Run steps automatically when something happens, and get notified." + }, + "maintenance": { + "title": "Manutenção", + "description": "Pause host status, health, metric, container and tunnel-disconnection automations while work is in progress. Monitoring, manual runs and scheduled automations continue.", + "denied": "You do not have permission to view maintenance.", + "sharedReadOnly": "This host was shared with you. Only its owner can change maintenance.", + "failed": "Maintenance could not be updated.", + "active": "Maintenance active", + "estimated": "Estimated completion", + "noAutoEnd": "The estimate does not end maintenance. End it explicitly when the work is complete.", + "endConfirm": "End maintenance and resume event-triggered automations for this host?", + "confirmEnd": "Confirm end", + "cancel": "Cancelar", + "end": "End maintenance", + "action": "Action", + "startNow": "Start now", + "schedule": "Schedule for later", + "reason": "Reason", + "startUtc": "First start (UTC)", + "repeat": "Repeat", + "once": "Once", + "weekly": "Weekly", + "monthly": "Monthly", + "utcHelp": "Schedules use UTC throughout the year. Monthly schedules skip months without the selected day. Planned windows cannot overlap; overrunning maintenance continues across later windows.", + "duration": "Estimated duration (minutes)", + "grace": "Grace period (minutes)", + "notify": "Notify once if still offline after the estimate plus grace period", + "addSchedule": "Add schedule", + "schedules": "Schedules", + "noSchedules": "No maintenance schedules.", + "completed": "Already started", + "minutes_one": "{{count}} minute", + "minutes_other": "{{count}} minutes", + "remove": "Remove schedule", + "loadFailed": "Could not refresh maintenance status. Changes are disabled until it can be loaded.", + "loading": "Loading maintenance status…" } } diff --git a/plugins/automations/locales/translated/pt_PT.json b/plugins/automations/locales/translated/pt_PT.json index 7c6244394..1ea6b9f12 100644 --- a/plugins/automations/locales/translated/pt_PT.json +++ b/plugins/automations/locales/translated/pt_PT.json @@ -1,149 +1,211 @@ { + "permissions": { + "view": { + "title": "View automations", + "description": "See the automations and their history." + }, + "create": { + "title": "Create automations", + "description": "Add new automations." + }, + "edit": { + "title": "Edit automations", + "description": "Change existing automations." + }, + "delete": { + "title": "Delete automations", + "description": "Remove automations." + }, + "run": { + "title": "Run automations", + "description": "Trigger an automation by hand." + } + }, "newUi": { "sidebar": { "automations": { - "title": "Automações", - "tabAutomations": "Automações", - "tabRuns": "Corridas", + "title": "Automations", + "tabAutomations": "Automations", + "tabRuns": "Runs", "tabChannels": "Canais", - "createAutomation": "Nova Automação", - "backToAutomations": "Voltar para Automações", - "createTitle": "Nova Automação", - "editTitle": "Editar Automação", - "empty": "Ainda não há automatizações. Crie uma para reagir a uma métrica, a um agendamento ou a um evento.", - "emptyRuns": "Ainda não houve qualquer corrida.", - "emptyChannels": "Ainda não há canais. Adicione um para enviar notificações para algum lugar.", - "noChannelsHint": "Nenhum canal configurado ainda. Adicione um no separador Canais.", - "addChannel": "Adicionar canal", - "testChannel": "Teste", - "channelTestSent": "Notificação de teste enviada", - "channelTestFailed": "Falha na notificação de teste", - "channelDeleted": "Canal excluído", - "deleteChannelConfirm": "Apagar este canal? As automatizações que o utilizam deixarão de enviar notificações.", + "createAutomation": "New Automation", + "backToAutomations": "Back to Automations", + "createTitle": "New Automation", + "editTitle": "Edit Automation", + "empty": "No automations yet. Create one to react to a metric, a schedule, or an event.", + "emptyRuns": "No runs yet.", + "channelsHint": "Channels are set up in Alerts", + "noChannelsHint": "The alert always goes to your inbox. Add channels in Alerts to also send it somewhere else.", "nameLabel": "Nome", - "namePlaceholder": "Por exemplo, limpe a pasta /data quando esta estiver cheia.", - "nameRequired": "O nome é obrigatório.", + "namePlaceholder": "e.g., Clean up /data when it fills", + "nameRequired": "O nome é obrigatório", "descriptionLabel": "Descrição", "descriptionPlaceholder": "Descrição opcional", - "enabledLabel": "Habilitado", - "concurrencyLabel": "Se já estiver em execução", - "concurrencyHint": "O que fazer quando este for novamente acionado antes da última execução terminar?", + "enabledLabel": "Ativado", + "concurrencyLabel": "If it is already running", + "concurrencyHint": "What to do when this is triggered again before the last run has finished.", "concurrency": { - "skip": "Salte a nova corrida", - "queue": "Espere e corra atrás.", - "allow": "Execute ambos em simultâneo" + "skip": "Skip the new run", + "queue": "Wait and run after", + "allow": "Run both at once" }, "save": "Guardar", - "created": "Automação criada", - "updated": "A automação economizou", - "deleted": "Automação excluída", - "deleteConfirm": "Apagar esta automação? O histórico de execução da mesma também será eliminado.", - "runNow": "Corra agora", - "testRun": "Teste de execução", - "testRunHint": "Executa cada passo, mas não toca em nada fora do Termix.", - "runStarted": "A corrida começou.", - "runFinished": "Execução concluída: {{status}}", + "created": "Automation created", + "updated": "Automation saved", + "deleted": "Automation deleted", + "deleteConfirm": "Delete this automation? Its run history is deleted too.", + "runNow": "Run now", + "testRun": "Test run", + "testRunHint": "Runs every step but does not touch anything outside Termix.", + "runStarted": "Run started", + "runFinished": "Run finished: {{status}}", "trigger": "Gatilho", - "steps": "Passos", - "addStep": "Adicionar etapa", - "removeStep": "Remover etapa", - "moveUp": "Suba", - "moveDown": "Desça", - "noSteps": "Ainda não há etapas. Adicione uma para descrever o que deve acontecer.", - "webhookTokenTitle": "URL do Webhook", - "webhookTokenDescription": "Esta mensagem será apresentada apenas uma vez. Guarde-a agora, pois não poderá ser recuperada posteriormente.", - "copy": "Cópia", + "steps": "Steps", + "addStep": "Add step", + "removeStep": "Remove step", + "moveUp": "Move up", + "moveDown": "Move down", + "noSteps": "No steps yet. Add one to say what should happen.", + "webhookTokenTitle": "Webhook URL", + "webhookTokenDescription": "This is shown once. Save it now, it cannot be retrieved later.", + "copy": "Copiar", "copied": "Copiado", "viewJson": "JSON", - "viewBuilder": "Construtor", - "viewGraph": "Gráfico", - "lastRun": "Última corrida", + "viewBuilder": "Builder", + "viewGraph": "Graph", + "lastRun": "Last run", "never": "Nunca", "duration": "{{seconds}}s", "stepOutput": "Saída", "stepError": "Erro", - "dryRunBadge": "Teste de execução", + "dryRunBadge": "Test run", "hostSelector": { - "trigger": "Host que desencadeia o ataque", - "host": "hospedeiro específico", - "fleet": "Frota", - "all": "Todos os anfitriões" + "trigger": "Triggering host", + "host": "Specific host", + "fleet": "Fleet", + "all": "Todos os hosts" }, "triggerKinds": { - "metric_threshold": "Limiar métrico", - "host_status": "O host sobe ou desce.", - "health_check": "Alterações na verificação de saúde", - "schedule": "De acordo com um cronograma", - "docker_event": "Evento de contentor", - "internal_event": "Evento Termix", - "webhook": "Webhook de entrada" + "metric_threshold": "Metric threshold", + "host_status": "Host goes up or down", + "health_check": "Health check changes", + "schedule": "On a schedule", + "docker_event": "Container event", + "internal_event": "Termix event", + "webhook": "Incoming webhook" }, "stepTypes": { - "notify": "Enviar notificação", - "http": "Chamar um URL", - "run_snippet": "Executar um excerto de código", - "run_command": "Executar um comando", - "docker": "Controle um contentor", - "tunnel": "Controle um túnel", - "wol": "Acorde um anfitrião", - "wait": "Espera", - "set_var": "Defina uma variável", - "if": "Se/caso contrário", - "run_automation": "Execute outra automatização", - "stop": "Parar" + "notify": "Send an alert", + "http": "Call a URL", + "run_snippet": "Run a snippet", + "run_command": "Run a command", + "docker": "Control a container", + "tunnel": "Control a tunnel", + "wol": "Wake a host", + "wait": "Wait", + "set_var": "Set a variable", + "if": "If / otherwise", + "run_automation": "Run another automation", + "stop": "Stop" }, "statuses": { - "running": "Corrida", + "running": "Em execução", "success": "Sucesso", "failed": "Falhou", - "timeout": "Tempo limite excedido", - "skipped": "Ignorado", - "cancelled": "Cancelado" + "timeout": "Timed out", + "skipped": "Skipped", + "cancelled": "Cancelled" }, "fields": { - "host": "Anfitrião", + "host": "Servidor", "metric": "Métrica", - "mount": "Ponto de montagem", - "operator": "É", - "value": "Valor", - "forSeconds": "Sustentado por (segundos)", - "cooldown": "Tempo de arrefecimento (minutos)", - "cron": "Expressão de Cron", - "intervalSeconds": "A cada (segundos)", - "timezone": "Fuso horário", - "timezoneServer": "Hora do servidor", - "timezoneHint": "Os tempos cron são lidos nesta zona. Não se aplica a agendamentos por intervalo.", - "container": "Recipiente", + "mount": "Mount point", + "operator": "Is", + "value": "Value", + "forSeconds": "Sustained for (seconds)", + "cooldown": "Período de arrefecimento (minutos)", + "cron": "Cron expression", + "intervalSeconds": "Every (seconds)", + "timezone": "Time zone", + "timezoneServer": "Server time", + "timezoneHint": "Cron times are read in this zone. Does not apply to interval schedules.", + "container": "Container", "command": "Comando", "url": "URL", - "method": "Método", - "body": "Corpo", - "channels": "Canais", + "method": "Method", + "body": "Body", + "channels": "Also send to", "title": "Título", - "message": "Mensagem", - "snippet": "Trecho", - "seconds": "Segundos", - "conditionLeftPlaceholder": "Valor a verificar", - "conditionRightPlaceholder": "Compare com", - "variableName": "Nome da variável", - "variableValue": "Valor", - "elevated": "Executar com sudo", - "onError": "Se isso falhar", - "allowPrivateNetwork": "Permitir endereços de rede local", - "allowPrivateNetworkHint": "Necessário para um serviço auto-hospedado na sua rede local (LAN). Desativado por defeito para evitar pedidos a endereços internos." + "message": "Message", + "snippet": "Snippet", + "seconds": "Seconds", + "conditionLeftPlaceholder": "Value to check", + "conditionRightPlaceholder": "Compare against", + "variableName": "Variable name", + "variableValue": "Value", + "elevated": "Run with sudo", + "onError": "If this fails", + "allowPrivateNetwork": "Allow local network addresses", + "allowPrivateNetworkHint": "Needed for a self-hosted service on your LAN. Off by default to prevent requests to internal addresses." }, "onError": { - "stop": "Pare a corrida", - "continue": "Continuar" + "stop": "Stop the run", + "continue": "Carry on" + }, + "needsPlugin": "Needs {{plugin}}", + "needsPluginHint": "This automation is skipped until the feature it needs is available again.", + "offBadge": "Desativado", + "docsLink": "Ver docs", + "ago": { + "seconds": "{{count}}s ago", + "minutes": "há {{count}} min", + "hours": "há {{count}} h", + "days": "há {{count}} d" } } } }, "nav": { - "automations": "Automações" + "automations": "Automations" }, "onboarding": { - "feature_automations": "Automações", - "feature_automations_desc": "Execute automaticamente os passos quando algo acontece e receba notificações." + "feature_automations": "Automations", + "feature_automations_desc": "Run steps automatically when something happens, and get notified." + }, + "maintenance": { + "title": "Manutenção", + "description": "Pause host status, health, metric, container and tunnel-disconnection automations while work is in progress. Monitoring, manual runs and scheduled automations continue.", + "denied": "You do not have permission to view maintenance.", + "sharedReadOnly": "This host was shared with you. Only its owner can change maintenance.", + "failed": "Maintenance could not be updated.", + "active": "Maintenance active", + "estimated": "Estimated completion", + "noAutoEnd": "The estimate does not end maintenance. End it explicitly when the work is complete.", + "endConfirm": "End maintenance and resume event-triggered automations for this host?", + "confirmEnd": "Confirm end", + "cancel": "Cancelar", + "end": "End maintenance", + "action": "Ação", + "startNow": "Start now", + "schedule": "Schedule for later", + "reason": "Reason", + "startUtc": "First start (UTC)", + "repeat": "Repeat", + "once": "Once", + "weekly": "Weekly", + "monthly": "Monthly", + "utcHelp": "Schedules use UTC throughout the year. Monthly schedules skip months without the selected day. Planned windows cannot overlap; overrunning maintenance continues across later windows.", + "duration": "Estimated duration (minutes)", + "grace": "Grace period (minutes)", + "notify": "Notify once if still offline after the estimate plus grace period", + "addSchedule": "Add schedule", + "schedules": "Schedules", + "noSchedules": "No maintenance schedules.", + "completed": "Already started", + "minutes_one": "{{count}} minute", + "minutes_other": "{{count}} minutes", + "remove": "Remove schedule", + "loadFailed": "Could not refresh maintenance status. Changes are disabled until it can be loaded.", + "loading": "Loading maintenance status…" } } diff --git a/plugins/automations/locales/translated/ro_RO.json b/plugins/automations/locales/translated/ro_RO.json index c829b9647..ea56208ae 100644 --- a/plugins/automations/locales/translated/ro_RO.json +++ b/plugins/automations/locales/translated/ro_RO.json @@ -1,4 +1,26 @@ { + "permissions": { + "view": { + "title": "Vizualizați automatizările", + "description": "Vedeți automatizările și istoricul lor." + }, + "create": { + "title": "Creați automatizări", + "description": "Adăugați noi automatizări." + }, + "edit": { + "title": "Editați automatizările", + "description": "Modificați automatizările existente." + }, + "delete": { + "title": "Șterge automatizările", + "description": "Eliminați automatizările." + }, + "run": { + "title": "Rulați automatizări", + "description": "Declanșează o automatizare manual." + } + }, "newUi": { "sidebar": { "automations": { @@ -12,14 +34,8 @@ "editTitle": "Editare automatizare", "empty": "Încă nu există automatizări. Creați una pentru a reacționa la o metrică, un program sau un eveniment.", "emptyRuns": "Nicio alergare încă.", - "emptyChannels": "Încă nu există canale. Adaugă unul pentru a trimite notificări undeva.", - "noChannelsHint": "Încă nu a fost configurat niciun canal. Adăugați unul în fila Canale.", - "addChannel": "Adăugați canal", - "testChannel": "Test", - "channelTestSent": "Notificare de testare trimisă", - "channelTestFailed": "Notificarea de testare a eșuat", - "channelDeleted": "Canalul a fost șters", - "deleteChannelConfirm": "Ștergeți acest canal? Automatizările care îl folosesc vor înceta să mai trimită notificări.", + "channelsHint": "Canalele sunt configurate în Alerte", + "noChannelsHint": "Alerta ajunge întotdeauna în căsuța ta poștală. Adaugă canale în Alerte pentru a o trimite și în altă parte.", "nameLabel": "Nume", "namePlaceholder": "De exemplu, curățați /data când se umple", "nameRequired": "Numele este obligatoriu", @@ -41,7 +57,7 @@ "runNow": "Aleargă acum", "testRun": "Test de funcționare", "testRunHint": "Aleargă la fiecare pas, dar nu atinge nimic din afara Termixului.", - "runStarted": "Cursa a început", + "runStarted": "Rularea a început", "runFinished": "Execuția s-a încheiat: {{status}}", "trigger": "Declanșator", "steps": "Pași", @@ -79,7 +95,7 @@ "webhook": "Webhook de intrare" }, "stepTypes": { - "notify": "Trimiteți o notificare", + "notify": "Trimiteți o alertă", "http": "Apelați o adresă URL", "run_snippet": "Executați un fragment", "run_command": "Executați o comandă", @@ -118,7 +134,7 @@ "url": "URL-ul", "method": "Metodă", "body": "Corp", - "channels": "Canale", + "channels": "Trimiteți și către", "title": "Titlu", "message": "Mesaj", "snippet": "Fragment", @@ -135,6 +151,16 @@ "onError": { "stop": "Oprește alergarea", "continue": "Continuă" + }, + "needsPlugin": "Necesită {{plugin}}", + "needsPluginHint": "Această automatizare este omisă până când funcția de care are nevoie este din nou disponibilă.", + "offBadge": "Dezactivat", + "docsLink": "Vizualizați documentele", + "ago": { + "seconds": "Acum {{count}}secunde", + "minutes": "{{count}}acum câteva minute", + "hours": "{{count}}acum o oră", + "days": "{{count}}zile în urmă" } } } @@ -145,5 +171,41 @@ "onboarding": { "feature_automations": "Automatizări", "feature_automations_desc": "Execută pașii automat când se întâmplă ceva și primește notificări." + }, + "maintenance": { + "title": "Întreţinere", + "description": "Întrerupeți automatizările privind starea gazdei, sănătatea, metrica, containerul și deconectarea tunelului în timp ce lucrul este în desfășurare. Monitorizarea, rulările manuale și automatizările programate continuă.", + "denied": "Nu aveți permisiunea de a vizualiza întreținerea.", + "sharedReadOnly": "Această gazdă a fost partajată cu dvs. Numai proprietarul acesteia poate modifica întreținerea.", + "failed": "Întreținerea nu a putut fi actualizată.", + "active": "Mentenanță activă", + "estimated": "Finalizare estimată", + "noAutoEnd": "Estimarea nu încheie întreținerea. Încheiați-o explicit când lucrarea este finalizată.", + "endConfirm": "Încheiați întreținerea și reluați automatizările declanșate de evenimente pentru această gazdă?", + "confirmEnd": "Confirmați sfârșitul", + "cancel": "Anula", + "end": "Sfârșitul întreținerii", + "action": "Acţiune", + "startNow": "Începeți acum", + "schedule": "Programați pentru mai târziu", + "reason": "Motiv", + "startUtc": "Prima pornire (UTC)", + "repeat": "Repeta", + "once": "Dată", + "weekly": "Săptămânal", + "monthly": "Lunar", + "utcHelp": "Programările utilizează UTC pe tot parcursul anului. Programările lunare sar peste luni fără ziua selectată. Ferestrele planificate nu se pot suprapune; întreținerea depășită continuă în ferestrele ulterioare.", + "duration": "Durată estimată (minute)", + "grace": "Perioadă de grație (minute)", + "notify": "Notificați o dată dacă sunteți încă offline după estimare plus perioada de grație", + "addSchedule": "Adăugați un program", + "schedules": "Programe", + "noSchedules": "Fără programe de întreținere.", + "completed": "Deja început", + "minutes_one": "{{count}} minut", + "minutes_other": "{{count}} minute", + "remove": "Eliminați programul", + "loadFailed": "Nu s-a putut actualiza starea de întreținere. Modificările sunt dezactivate până când pot fi încărcate.", + "loading": "Se încarcă starea de întreținere…" } } diff --git a/plugins/automations/locales/translated/ru_RU.json b/plugins/automations/locales/translated/ru_RU.json index 0e1f489cd..956e266b0 100644 --- a/plugins/automations/locales/translated/ru_RU.json +++ b/plugins/automations/locales/translated/ru_RU.json @@ -1,149 +1,211 @@ { + "permissions": { + "view": { + "title": "View automations", + "description": "See the automations and their history." + }, + "create": { + "title": "Create automations", + "description": "Add new automations." + }, + "edit": { + "title": "Edit automations", + "description": "Change existing automations." + }, + "delete": { + "title": "Delete automations", + "description": "Remove automations." + }, + "run": { + "title": "Run automations", + "description": "Trigger an automation by hand." + } + }, "newUi": { "sidebar": { "automations": { - "title": "Автоматизация", - "tabAutomations": "Автоматизация", - "tabRuns": "Беги", + "title": "Automations", + "tabAutomations": "Automations", + "tabRuns": "Runs", "tabChannels": "Каналы", - "createAutomation": "Новая автоматизация", - "backToAutomations": "Назад к автоматизации", - "createTitle": "Новая автоматизация", - "editTitle": "Редактировать автоматизацию", - "empty": "Автоматизации пока нет. Создайте автоматизацию, которая будет реагировать на показатель, расписание или событие.", - "emptyRuns": "Пока ни одного заезда.", - "emptyChannels": "Каналов пока нет. Добавьте канал, чтобы отправлять уведомления куда-нибудь.", - "noChannelsHint": "Каналы пока не созданы. Добавьте его на вкладке «Каналы».", - "addChannel": "Добавить канал", - "testChannel": "Тест", - "channelTestSent": "Уведомление о тестировании отправлено.", - "channelTestFailed": "Тестовое уведомление не удалось.", - "channelDeleted": "Канал удален", - "deleteChannelConfirm": "Удалить этот канал? Тогда автоматизация, использующая его, перестанет отправлять уведомления.", - "nameLabel": "Имя", - "namePlaceholder": "Например, очищать каталог /data, когда он заполняется.", - "nameRequired": "Имя обязательно для указания.", + "createAutomation": "New Automation", + "backToAutomations": "Back to Automations", + "createTitle": "New Automation", + "editTitle": "Edit Automation", + "empty": "No automations yet. Create one to react to a metric, a schedule, or an event.", + "emptyRuns": "No runs yet.", + "channelsHint": "Channels are set up in Alerts", + "noChannelsHint": "The alert always goes to your inbox. Add channels in Alerts to also send it somewhere else.", + "nameLabel": "Название", + "namePlaceholder": "e.g., Clean up /data when it fills", + "nameRequired": "Имя обязательно", "descriptionLabel": "Описание", - "descriptionPlaceholder": "Дополнительное описание", + "descriptionPlaceholder": "Необязательное описание", "enabledLabel": "Включено", - "concurrencyLabel": "Если он уже запущен", - "concurrencyHint": "Что делать, если это снова произойдет до завершения последнего запуска?", + "concurrencyLabel": "If it is already running", + "concurrencyHint": "What to do when this is triggered again before the last run has finished.", "concurrency": { - "skip": "Пропустите новый запуск", - "queue": "Подожди и беги после", - "allow": "Запустите оба одновременно." + "skip": "Skip the new run", + "queue": "Wait and run after", + "allow": "Run both at once" }, - "save": "Сохранять", - "created": "Создана автоматизация", - "updated": "Автоматизация спасла", - "deleted": "Автоматизация удалена", - "deleteConfirm": "Удалить эту автоматизацию? История её выполнения также будет удалена.", - "runNow": "Запустите сейчас", - "testRun": "Тестовый запуск", - "testRunHint": "Программа выполняет каждый этап, но не затрагивает ничего за пределами Termix.", - "runStarted": "Запуск начался", - "runFinished": "Выполнение завершено: {{status}}", - "trigger": "Курок", - "steps": "Шаги", - "addStep": "Добавить шаг", - "removeStep": "Удалить шаг", - "moveUp": "Поднимитесь выше", - "moveDown": "Спуститесь вниз", - "noSteps": "Шагов пока нет. Добавьте один, чтобы указать, что должно произойти.", - "webhookTokenTitle": "URL веб-перехватчика", - "webhookTokenDescription": "Эта информация отображается только один раз. Сохраните её сейчас, позже восстановить её будет невозможно.", - "copy": "Копия", + "save": "Сохранить", + "created": "Automation created", + "updated": "Automation saved", + "deleted": "Automation deleted", + "deleteConfirm": "Delete this automation? Its run history is deleted too.", + "runNow": "Run now", + "testRun": "Test run", + "testRunHint": "Runs every step but does not touch anything outside Termix.", + "runStarted": "Run started", + "runFinished": "Run finished: {{status}}", + "trigger": "Триггер", + "steps": "Steps", + "addStep": "Add step", + "removeStep": "Remove step", + "moveUp": "Move up", + "moveDown": "Move down", + "noSteps": "No steps yet. Add one to say what should happen.", + "webhookTokenTitle": "Webhook URL", + "webhookTokenDescription": "This is shown once. Save it now, it cannot be retrieved later.", + "copy": "Копировать", "copied": "Скопировано", "viewJson": "JSON", - "viewBuilder": "Строитель", - "viewGraph": "График", - "lastRun": "Последний забег", + "viewBuilder": "Builder", + "viewGraph": "Graph", + "lastRun": "Last run", "never": "Никогда", - "duration": "{{seconds}}с", - "stepOutput": "Выход", + "duration": "{{seconds}}s", + "stepOutput": "Вывод", "stepError": "Ошибка", - "dryRunBadge": "Тестовый запуск", + "dryRunBadge": "Test run", "hostSelector": { - "trigger": "Запуск хоста", - "host": "Конкретный хост", - "fleet": "Флот", + "trigger": "Triggering host", + "host": "Specific host", + "fleet": "Fleet", "all": "Все хосты" }, "triggerKinds": { - "metric_threshold": "Пороговое значение метрики", - "host_status": "Хост переходит в режим повышения или понижения.", - "health_check": "Изменения в результатах медицинского осмотра", - "schedule": "По расписанию", - "docker_event": "Событие контейнера", - "internal_event": "Мероприятие Termix", - "webhook": "Входящий веб-хук" + "metric_threshold": "Metric threshold", + "host_status": "Host goes up or down", + "health_check": "Health check changes", + "schedule": "On a schedule", + "docker_event": "Container event", + "internal_event": "Termix event", + "webhook": "Incoming webhook" }, "stepTypes": { - "notify": "Отправить уведомление", - "http": "Вызов URL-адреса", - "run_snippet": "Запустить фрагмент кода", - "run_command": "Выполните команду", - "docker": "Управлять контейнером", - "tunnel": "Контролировать туннель", - "wol": "Разбудить хозяина", - "wait": "Ждать", - "set_var": "Задайте переменную", - "if": "Если / в противном случае", - "run_automation": "Запустите еще одну автоматизацию", - "stop": "Останавливаться" + "notify": "Send an alert", + "http": "Call a URL", + "run_snippet": "Run a snippet", + "run_command": "Run a command", + "docker": "Control a container", + "tunnel": "Control a tunnel", + "wol": "Wake a host", + "wait": "Wait", + "set_var": "Set a variable", + "if": "If / otherwise", + "run_automation": "Run another automation", + "stop": "Остановить" }, "statuses": { - "running": "Бег", + "running": "Запущен", "success": "Успех", - "failed": "Неуспешный", - "timeout": "Время истекло", - "skipped": "Пропущено", - "cancelled": "Отменено" + "failed": "Ошибка", + "timeout": "Timed out", + "skipped": "Skipped", + "cancelled": "Cancelled" }, "fields": { - "host": "Хозяин", + "host": "Хост", "metric": "Метрика", - "mount": "Маунт-Пойнт", - "operator": "Является", - "value": "Ценить", - "forSeconds": "Длительность (секунды)", - "cooldown": "Время восстановления (минуты)", - "cron": "Выражение Cron", - "intervalSeconds": "Каждые (секунды)", - "timezone": "Часовой пояс", - "timezoneServer": "Время сервера", - "timezoneHint": "В этой зоне считываются временные параметры Cron. Это не относится к интервальным расписаниям.", - "container": "Контейнер", - "command": "Командование", + "mount": "Mount point", + "operator": "Is", + "value": "Value", + "forSeconds": "Sustained for (seconds)", + "cooldown": "Задержка повторения (минут)", + "cron": "Cron expression", + "intervalSeconds": "Every (seconds)", + "timezone": "Time zone", + "timezoneServer": "Server time", + "timezoneHint": "Cron times are read in this zone. Does not apply to interval schedules.", + "container": "Container", + "command": "Команда", "url": "URL", - "method": "Метод", - "body": "Тело", - "channels": "Каналы", - "title": "Заголовок", - "message": "Сообщение", - "snippet": "Фрагмент", - "seconds": "Секунды", - "conditionLeftPlaceholder": "Значение для проверки", - "conditionRightPlaceholder": "Сравните с", - "variableName": "Имя переменной", - "variableValue": "Ценить", - "elevated": "Запустить с правами суперпользователя (sudo)", - "onError": "Если это не поможет", - "allowPrivateNetwork": "Разрешить использование локальных сетевых адресов", - "allowPrivateNetworkHint": "Необходим для самостоятельного размещения сервиса в вашей локальной сети. По умолчанию отключен, чтобы предотвратить запросы к внутренним адресам." + "method": "Method", + "body": "Body", + "channels": "Also send to", + "title": "Название", + "message": "Message", + "snippet": "Snippet", + "seconds": "Seconds", + "conditionLeftPlaceholder": "Value to check", + "conditionRightPlaceholder": "Compare against", + "variableName": "Variable name", + "variableValue": "Value", + "elevated": "Run with sudo", + "onError": "If this fails", + "allowPrivateNetwork": "Allow local network addresses", + "allowPrivateNetworkHint": "Needed for a self-hosted service on your LAN. Off by default to prevent requests to internal addresses." }, "onError": { - "stop": "Остановить бег", - "continue": "Продолжать" + "stop": "Stop the run", + "continue": "Carry on" + }, + "needsPlugin": "Needs {{plugin}}", + "needsPluginHint": "This automation is skipped until the feature it needs is available again.", + "offBadge": "Отключено", + "docsLink": "Документация", + "ago": { + "seconds": "{{count}}s ago", + "minutes": "{{count}}м назад", + "hours": "{{count}}ч назад", + "days": "{{count}}д назад" } } } }, "nav": { - "automations": "Автоматизация" + "automations": "Automations" }, "onboarding": { - "feature_automations": "Автоматизация", - "feature_automations_desc": "Запускайте шаги автоматически при возникновении событий и получайте уведомления." + "feature_automations": "Automations", + "feature_automations_desc": "Run steps automatically when something happens, and get notified." + }, + "maintenance": { + "title": "Обслуживание", + "description": "Pause host status, health, metric, container and tunnel-disconnection automations while work is in progress. Monitoring, manual runs and scheduled automations continue.", + "denied": "You do not have permission to view maintenance.", + "sharedReadOnly": "This host was shared with you. Only its owner can change maintenance.", + "failed": "Maintenance could not be updated.", + "active": "Maintenance active", + "estimated": "Estimated completion", + "noAutoEnd": "The estimate does not end maintenance. End it explicitly when the work is complete.", + "endConfirm": "End maintenance and resume event-triggered automations for this host?", + "confirmEnd": "Confirm end", + "cancel": "Отмена", + "end": "End maintenance", + "action": "Действие", + "startNow": "Start now", + "schedule": "Schedule for later", + "reason": "Reason", + "startUtc": "First start (UTC)", + "repeat": "Repeat", + "once": "Once", + "weekly": "Weekly", + "monthly": "Monthly", + "utcHelp": "Schedules use UTC throughout the year. Monthly schedules skip months without the selected day. Planned windows cannot overlap; overrunning maintenance continues across later windows.", + "duration": "Estimated duration (minutes)", + "grace": "Grace period (minutes)", + "notify": "Notify once if still offline after the estimate plus grace period", + "addSchedule": "Add schedule", + "schedules": "Schedules", + "noSchedules": "No maintenance schedules.", + "completed": "Already started", + "minutes_one": "{{count}} minute", + "minutes_other": "{{count}} minutes", + "remove": "Remove schedule", + "loadFailed": "Could not refresh maintenance status. Changes are disabled until it can be loaded.", + "loading": "Loading maintenance status…" } } diff --git a/plugins/automations/locales/translated/sr_SP.json b/plugins/automations/locales/translated/sr_SP.json index a3eb6fc7c..b459b4ade 100644 --- a/plugins/automations/locales/translated/sr_SP.json +++ b/plugins/automations/locales/translated/sr_SP.json @@ -1,149 +1,211 @@ { + "permissions": { + "view": { + "title": "View automations", + "description": "See the automations and their history." + }, + "create": { + "title": "Create automations", + "description": "Add new automations." + }, + "edit": { + "title": "Edit automations", + "description": "Change existing automations." + }, + "delete": { + "title": "Delete automations", + "description": "Remove automations." + }, + "run": { + "title": "Run automations", + "description": "Trigger an automation by hand." + } + }, "newUi": { "sidebar": { "automations": { - "title": "Аутоматизације", - "tabAutomations": "Аутоматизације", - "tabRuns": "Трчања", - "tabChannels": "Канали", - "createAutomation": "Нова аутоматизација", - "backToAutomations": "Назад на аутоматизацију", - "createTitle": "Нова аутоматизација", - "editTitle": "Уреди аутоматизацију", - "empty": "Још увек нема аутоматизација. Направите једну да бисте реаговали на метрику, распоред или догађај.", - "emptyRuns": "Још нема трчања.", - "emptyChannels": "Још нема канала. Додајте један да бисте слали обавештења негде.", - "noChannelsHint": "Још увек нема подешених канала. Додајте један на картици Канали.", - "addChannel": "Додај канал", - "testChannel": "Тест", - "channelTestSent": "Обавештење о тестирању је послато", - "channelTestFailed": "Обавештење о тестирању није успело", - "channelDeleted": "Канал је обрисан", - "deleteChannelConfirm": "Да ли желите да обришете овај канал? Аутоматизације које га користе ће престати да шаљу обавештења.", - "nameLabel": "Име", - "namePlaceholder": "нпр. Очисти /подаци када се попуне", - "nameRequired": "Име је обавезно", - "descriptionLabel": "Опис", - "descriptionPlaceholder": "Опциони опис", - "enabledLabel": "Омогућено", - "concurrencyLabel": "Ако већ ради", - "concurrencyHint": "Шта урадити када се ово поново покрене пре него што се заврши последње покретање.", + "title": "Automations", + "tabAutomations": "Automations", + "tabRuns": "Runs", + "tabChannels": "Channels", + "createAutomation": "New Automation", + "backToAutomations": "Back to Automations", + "createTitle": "New Automation", + "editTitle": "Edit Automation", + "empty": "No automations yet. Create one to react to a metric, a schedule, or an event.", + "emptyRuns": "No runs yet.", + "channelsHint": "Channels are set up in Alerts", + "noChannelsHint": "The alert always goes to your inbox. Add channels in Alerts to also send it somewhere else.", + "nameLabel": "Name", + "namePlaceholder": "e.g., Clean up /data when it fills", + "nameRequired": "Name is required", + "descriptionLabel": "Description", + "descriptionPlaceholder": "Optional description", + "enabledLabel": "Enabled", + "concurrencyLabel": "If it is already running", + "concurrencyHint": "What to do when this is triggered again before the last run has finished.", "concurrency": { - "skip": "Прескочи нову вожњу", - "queue": "Чекај и трчи за њим", - "allow": "Покрени оба одједном" + "skip": "Skip the new run", + "queue": "Wait and run after", + "allow": "Run both at once" }, - "save": "Сачувај", - "created": "Аутоматизација је креирана", - "updated": "Аутоматизација је сачувана", - "deleted": "Аутоматизација је обрисана", - "deleteConfirm": "Да ли желите да обришете ову аутоматизацију? Њена историја покретања је такође обрисана.", - "runNow": "Трчи сада", - "testRun": "Тестирање", - "testRunHint": "Покреће сваки корак, али не додирује ништа изван Термикса.", - "runStarted": "Трчање је започето", - "runFinished": "Трка завршена: {{status}}", - "trigger": "Окидач", - "steps": "Кораци", - "addStep": "Додај корак", - "removeStep": "Уклони корак", - "moveUp": "Помери горе", - "moveDown": "Помери надоле", - "noSteps": "Још нема корака. Додајте један да бисте рекли шта треба да се деси.", - "webhookTokenTitle": "URL вебхука", - "webhookTokenDescription": "Ово се приказује једном. Сачувајте то сада, не можете то касније преузети.", - "copy": "Копија", - "copied": "Копирано", + "save": "Save", + "created": "Automation created", + "updated": "Automation saved", + "deleted": "Automation deleted", + "deleteConfirm": "Delete this automation? Its run history is deleted too.", + "runNow": "Run now", + "testRun": "Test run", + "testRunHint": "Runs every step but does not touch anything outside Termix.", + "runStarted": "Run started", + "runFinished": "Run finished: {{status}}", + "trigger": "Trigger", + "steps": "Steps", + "addStep": "Add step", + "removeStep": "Remove step", + "moveUp": "Move up", + "moveDown": "Move down", + "noSteps": "No steps yet. Add one to say what should happen.", + "webhookTokenTitle": "Webhook URL", + "webhookTokenDescription": "This is shown once. Save it now, it cannot be retrieved later.", + "copy": "Copy", + "copied": "Copied", "viewJson": "JSON", - "viewBuilder": "Градитељ", - "viewGraph": "График", - "lastRun": "Последње трчање", - "never": "Никад", - "duration": "{{seconds}}с", - "stepOutput": "Излаз", - "stepError": "Грешка", - "dryRunBadge": "Тестирање", + "viewBuilder": "Builder", + "viewGraph": "Graph", + "lastRun": "Last run", + "never": "Never", + "duration": "{{seconds}}s", + "stepOutput": "Output", + "stepError": "Error", + "dryRunBadge": "Test run", "hostSelector": { - "trigger": "Покретач хоста", - "host": "Одређени домаћин", - "fleet": "Флота", - "all": "Сви домаћини" + "trigger": "Triggering host", + "host": "Specific host", + "fleet": "Fleet", + "all": "All hosts" }, "triggerKinds": { - "metric_threshold": "Праг метрике", - "host_status": "Домаћин иде горе или доле", - "health_check": "Промене у провери исправности", - "schedule": "По распореду", - "docker_event": "Догађај контејнера", - "internal_event": "Термикс догађај", - "webhook": "Долазни вебхук" + "metric_threshold": "Metric threshold", + "host_status": "Host goes up or down", + "health_check": "Health check changes", + "schedule": "On a schedule", + "docker_event": "Container event", + "internal_event": "Termix event", + "webhook": "Incoming webhook" }, "stepTypes": { - "notify": "Пошаљи обавештење", - "http": "Позовите URL", - "run_snippet": "Покрени исечак", - "run_command": "Покрените команду", - "docker": "Контролишите контејнер", - "tunnel": "Контролишите тунел", - "wol": "Пробудите домаћина", - "wait": "Чекај", - "set_var": "Поставите променљиву", - "if": "Ако / иначе", - "run_automation": "Покрените још једну аутоматизацију", - "stop": "Заустави" + "notify": "Send an alert", + "http": "Call a URL", + "run_snippet": "Run a snippet", + "run_command": "Run a command", + "docker": "Control a container", + "tunnel": "Control a tunnel", + "wol": "Wake a host", + "wait": "Wait", + "set_var": "Set a variable", + "if": "If / otherwise", + "run_automation": "Run another automation", + "stop": "Stop" }, "statuses": { - "running": "Трчање", - "success": "Успех", - "failed": "Неуспешно", - "timeout": "Временско ограничење је истекло", - "skipped": "Прескочено", - "cancelled": "Отказано" + "running": "Running", + "success": "Success", + "failed": "Failed", + "timeout": "Timed out", + "skipped": "Skipped", + "cancelled": "Cancelled" }, "fields": { - "host": "Домаћин", - "metric": "Метрика", - "mount": "Тачка монтирања", - "operator": "Је", - "value": "Вредност", - "forSeconds": "Задржано (секунде)", - "cooldown": "Хлађење (минути)", - "cron": "Cron израз", - "intervalSeconds": "Сваких (секунде)", - "timezone": "Временска зона", - "timezoneServer": "Време сервера", - "timezoneHint": "Cron времена се очитавају у овој зони. Не односи се на интервалне распореде.", - "container": "Контејнер", - "command": "Команда", + "host": "Host", + "metric": "Metric", + "mount": "Mount point", + "operator": "Is", + "value": "Value", + "forSeconds": "Sustained for (seconds)", + "cooldown": "Cooldown (minutes)", + "cron": "Cron expression", + "intervalSeconds": "Every (seconds)", + "timezone": "Time zone", + "timezoneServer": "Server time", + "timezoneHint": "Cron times are read in this zone. Does not apply to interval schedules.", + "container": "Container", + "command": "Command", "url": "URL", - "method": "Метод", - "body": "Тело", - "channels": "Канали", - "title": "Наслов", - "message": "Порука", - "snippet": "Исечак", - "seconds": "Секунде", - "conditionLeftPlaceholder": "Вредност за проверу", - "conditionRightPlaceholder": "Упореди са", - "variableName": "Назив променљиве", - "variableValue": "Вредност", - "elevated": "Покрени са sudo-ом", - "onError": "Ако ово не успе", - "allowPrivateNetwork": "Дозволи локалне мрежне адресе", - "allowPrivateNetworkHint": "Потребно за самостално хостовану услугу на вашој локалној мрежи. Подразумевано искључено да би се спречили захтеви ка интерним адресама." + "method": "Method", + "body": "Body", + "channels": "Also send to", + "title": "Title", + "message": "Message", + "snippet": "Snippet", + "seconds": "Seconds", + "conditionLeftPlaceholder": "Value to check", + "conditionRightPlaceholder": "Compare against", + "variableName": "Variable name", + "variableValue": "Value", + "elevated": "Run with sudo", + "onError": "If this fails", + "allowPrivateNetwork": "Allow local network addresses", + "allowPrivateNetworkHint": "Needed for a self-hosted service on your LAN. Off by default to prevent requests to internal addresses." }, "onError": { - "stop": "Заустави трчање", - "continue": "Настави" + "stop": "Stop the run", + "continue": "Carry on" + }, + "needsPlugin": "Needs {{plugin}}", + "needsPluginHint": "This automation is skipped until the feature it needs is available again.", + "offBadge": "Off", + "docsLink": "View docs", + "ago": { + "seconds": "{{count}}s ago", + "minutes": "{{count}}m ago", + "hours": "{{count}}h ago", + "days": "{{count}}d ago" } } } }, "nav": { - "automations": "Аутоматизације" + "automations": "Automations" }, "onboarding": { - "feature_automations": "Аутоматизације", - "feature_automations_desc": "Аутоматски покрените кораке када се нешто деси и добијте обавештења." + "feature_automations": "Automations", + "feature_automations_desc": "Run steps automatically when something happens, and get notified." + }, + "maintenance": { + "title": "Maintenance", + "description": "Pause host status, health, metric, container and tunnel-disconnection automations while work is in progress. Monitoring, manual runs and scheduled automations continue.", + "denied": "You do not have permission to view maintenance.", + "sharedReadOnly": "This host was shared with you. Only its owner can change maintenance.", + "failed": "Maintenance could not be updated.", + "active": "Maintenance active", + "estimated": "Estimated completion", + "noAutoEnd": "The estimate does not end maintenance. End it explicitly when the work is complete.", + "endConfirm": "End maintenance and resume event-triggered automations for this host?", + "confirmEnd": "Confirm end", + "cancel": "Cancel", + "end": "End maintenance", + "action": "Action", + "startNow": "Start now", + "schedule": "Schedule for later", + "reason": "Reason", + "startUtc": "First start (UTC)", + "repeat": "Repeat", + "once": "Once", + "weekly": "Weekly", + "monthly": "Monthly", + "utcHelp": "Schedules use UTC throughout the year. Monthly schedules skip months without the selected day. Planned windows cannot overlap; overrunning maintenance continues across later windows.", + "duration": "Estimated duration (minutes)", + "grace": "Grace period (minutes)", + "notify": "Notify once if still offline after the estimate plus grace period", + "addSchedule": "Add schedule", + "schedules": "Schedules", + "noSchedules": "No maintenance schedules.", + "completed": "Already started", + "minutes_one": "{{count}} minute", + "minutes_other": "{{count}} minutes", + "remove": "Remove schedule", + "loadFailed": "Could not refresh maintenance status. Changes are disabled until it can be loaded.", + "loading": "Loading maintenance status…" } } diff --git a/plugins/automations/locales/translated/sv_SE.json b/plugins/automations/locales/translated/sv_SE.json index b17ab3315..b459b4ade 100644 --- a/plugins/automations/locales/translated/sv_SE.json +++ b/plugins/automations/locales/translated/sv_SE.json @@ -1,149 +1,211 @@ { + "permissions": { + "view": { + "title": "View automations", + "description": "See the automations and their history." + }, + "create": { + "title": "Create automations", + "description": "Add new automations." + }, + "edit": { + "title": "Edit automations", + "description": "Change existing automations." + }, + "delete": { + "title": "Delete automations", + "description": "Remove automations." + }, + "run": { + "title": "Run automations", + "description": "Trigger an automation by hand." + } + }, "newUi": { "sidebar": { "automations": { - "title": "Automatiseringar", - "tabAutomations": "Automatiseringar", - "tabRuns": "Löpningar", - "tabChannels": "Kanaler", - "createAutomation": "Ny automatisering", - "backToAutomations": "Tillbaka till Automatiseringar", - "createTitle": "Ny automatisering", - "editTitle": "Redigera automatisering", - "empty": "Inga automatiseringar ännu. Skapa en för att reagera på ett mätvärde, ett schema eller en händelse.", - "emptyRuns": "Inga löpningar än.", - "emptyChannels": "Inga kanaler ännu. Lägg till en för att skicka aviseringar någonstans.", - "noChannelsHint": "Inga kanaler är konfigurerade än. Lägg till en på fliken Kanaler.", - "addChannel": "Lägg till kanal", - "testChannel": "Testa", - "channelTestSent": "Testmeddelande skickat", - "channelTestFailed": "Testmeddelandet misslyckades", - "channelDeleted": "Kanalen raderad", - "deleteChannelConfirm": "Vill du ta bort den här kanalen? Automatiseringar som använder den kommer att sluta skicka aviseringar.", - "nameLabel": "Namn", - "namePlaceholder": "t.ex. Rensa upp /data när den fylls", - "nameRequired": "Namn krävs", - "descriptionLabel": "Beskrivning", - "descriptionPlaceholder": "Valfri beskrivning", - "enabledLabel": "Aktiverad", - "concurrencyLabel": "Om den redan är igång", - "concurrencyHint": "Vad man ska göra när detta utlöses igen innan den sista körningen är klar.", + "title": "Automations", + "tabAutomations": "Automations", + "tabRuns": "Runs", + "tabChannels": "Channels", + "createAutomation": "New Automation", + "backToAutomations": "Back to Automations", + "createTitle": "New Automation", + "editTitle": "Edit Automation", + "empty": "No automations yet. Create one to react to a metric, a schedule, or an event.", + "emptyRuns": "No runs yet.", + "channelsHint": "Channels are set up in Alerts", + "noChannelsHint": "The alert always goes to your inbox. Add channels in Alerts to also send it somewhere else.", + "nameLabel": "Name", + "namePlaceholder": "e.g., Clean up /data when it fills", + "nameRequired": "Name is required", + "descriptionLabel": "Description", + "descriptionPlaceholder": "Optional description", + "enabledLabel": "Enabled", + "concurrencyLabel": "If it is already running", + "concurrencyHint": "What to do when this is triggered again before the last run has finished.", "concurrency": { - "skip": "Hoppa över den nya körningen", - "queue": "Vänta och spring efter", - "allow": "Kör båda samtidigt" + "skip": "Skip the new run", + "queue": "Wait and run after", + "allow": "Run both at once" }, - "save": "Spara", - "created": "Automatisering skapad", - "updated": "Automatisering sparad", - "deleted": "Automatisering borttagen", - "deleteConfirm": "Vill du ta bort den här automatiseringen? Dess körhistorik raderas också.", - "runNow": "Kör nu", - "testRun": "Testkörning", - "testRunHint": "Kör varje steg men rör ingenting utanför Termix.", - "runStarted": "Löpningen har startat", - "runFinished": "Körning avslutad: {{status}}", - "trigger": "Utlösare", - "steps": "Steg", - "addStep": "Lägg till steg", - "removeStep": "Ta bort steg", - "moveUp": "Flytta upp", - "moveDown": "Flytta nedåt", - "noSteps": "Inga steg ännu. Lägg till ett för att ange vad som ska hända.", - "webhookTokenTitle": "Webhook-URL", - "webhookTokenDescription": "Detta visas en gång. Spara det nu, det kan inte hämtas senare.", - "copy": "Kopiera", - "copied": "Kopierad", + "save": "Save", + "created": "Automation created", + "updated": "Automation saved", + "deleted": "Automation deleted", + "deleteConfirm": "Delete this automation? Its run history is deleted too.", + "runNow": "Run now", + "testRun": "Test run", + "testRunHint": "Runs every step but does not touch anything outside Termix.", + "runStarted": "Run started", + "runFinished": "Run finished: {{status}}", + "trigger": "Trigger", + "steps": "Steps", + "addStep": "Add step", + "removeStep": "Remove step", + "moveUp": "Move up", + "moveDown": "Move down", + "noSteps": "No steps yet. Add one to say what should happen.", + "webhookTokenTitle": "Webhook URL", + "webhookTokenDescription": "This is shown once. Save it now, it cannot be retrieved later.", + "copy": "Copy", + "copied": "Copied", "viewJson": "JSON", - "viewBuilder": "Byggmästare", - "viewGraph": "Graf", - "lastRun": "Sista körningen", - "never": "Aldrig", + "viewBuilder": "Builder", + "viewGraph": "Graph", + "lastRun": "Last run", + "never": "Never", "duration": "{{seconds}}s", - "stepOutput": "Produktion", - "stepError": "Fel", - "dryRunBadge": "Testkörning", + "stepOutput": "Output", + "stepError": "Error", + "dryRunBadge": "Test run", "hostSelector": { - "trigger": "Utlösande värd", - "host": "Specifik värd", - "fleet": "Flotta", - "all": "Alla värdar" + "trigger": "Triggering host", + "host": "Specific host", + "fleet": "Fleet", + "all": "All hosts" }, "triggerKinds": { - "metric_threshold": "Metrisk tröskelvärde", - "host_status": "Värden går upp eller ner", - "health_check": "Ändringar i hälsokontrollen", - "schedule": "Enligt ett schema", - "docker_event": "Containerhändelse", - "internal_event": "Termix-evenemang", - "webhook": "Inkommande webhook" + "metric_threshold": "Metric threshold", + "host_status": "Host goes up or down", + "health_check": "Health check changes", + "schedule": "On a schedule", + "docker_event": "Container event", + "internal_event": "Termix event", + "webhook": "Incoming webhook" }, "stepTypes": { - "notify": "Skicka en avisering", - "http": "Anropa en URL", - "run_snippet": "Kör ett utdrag", - "run_command": "Kör ett kommando", - "docker": "Styr en container", - "tunnel": "Kontrollera en tunnel", - "wol": "Väck en värd", - "wait": "Vänta", - "set_var": "Ställ in en variabel", - "if": "Om / annars", - "run_automation": "Kör en annan automatisering", - "stop": "Stopp" + "notify": "Send an alert", + "http": "Call a URL", + "run_snippet": "Run a snippet", + "run_command": "Run a command", + "docker": "Control a container", + "tunnel": "Control a tunnel", + "wol": "Wake a host", + "wait": "Wait", + "set_var": "Set a variable", + "if": "If / otherwise", + "run_automation": "Run another automation", + "stop": "Stop" }, "statuses": { - "running": "Spring", - "success": "Framgång", - "failed": "Misslyckades", - "timeout": "Timeout", - "skipped": "Hoppade över", - "cancelled": "Avbruten" + "running": "Running", + "success": "Success", + "failed": "Failed", + "timeout": "Timed out", + "skipped": "Skipped", + "cancelled": "Cancelled" }, "fields": { - "host": "Värd", - "metric": "Metrisk", - "mount": "Monteringspunkt", - "operator": "Är", - "value": "Värde", - "forSeconds": "Uthållen i (sekunder)", - "cooldown": "Nedkylningstid (minuter)", - "cron": "Cron-uttryck", - "intervalSeconds": "Varje (sekund)", - "timezone": "Tidszon", - "timezoneServer": "Servertid", - "timezoneHint": "Cron-tider läses i denna zon. Gäller inte för intervallscheman.", - "container": "Behållare", - "command": "Kommando", + "host": "Host", + "metric": "Metric", + "mount": "Mount point", + "operator": "Is", + "value": "Value", + "forSeconds": "Sustained for (seconds)", + "cooldown": "Cooldown (minutes)", + "cron": "Cron expression", + "intervalSeconds": "Every (seconds)", + "timezone": "Time zone", + "timezoneServer": "Server time", + "timezoneHint": "Cron times are read in this zone. Does not apply to interval schedules.", + "container": "Container", + "command": "Command", "url": "URL", - "method": "Metod", - "body": "Kropp", - "channels": "Kanaler", - "title": "Titel", - "message": "Meddelande", - "snippet": "Utdrag", - "seconds": "Sekunder", - "conditionLeftPlaceholder": "Värde att kontrollera", - "conditionRightPlaceholder": "Jämför mot", - "variableName": "Variabelnamn", - "variableValue": "Värde", - "elevated": "Kör med sudo", - "onError": "Om detta misslyckas", - "allowPrivateNetwork": "Tillåt lokala nätverksadresser", - "allowPrivateNetworkHint": "Behövs för en självhostad tjänst på ditt lokala nätverk. Avstängt som standard för att förhindra förfrågningar till interna adresser." + "method": "Method", + "body": "Body", + "channels": "Also send to", + "title": "Title", + "message": "Message", + "snippet": "Snippet", + "seconds": "Seconds", + "conditionLeftPlaceholder": "Value to check", + "conditionRightPlaceholder": "Compare against", + "variableName": "Variable name", + "variableValue": "Value", + "elevated": "Run with sudo", + "onError": "If this fails", + "allowPrivateNetwork": "Allow local network addresses", + "allowPrivateNetworkHint": "Needed for a self-hosted service on your LAN. Off by default to prevent requests to internal addresses." }, "onError": { - "stop": "Stoppa löpningen", - "continue": "Fortsätta" + "stop": "Stop the run", + "continue": "Carry on" + }, + "needsPlugin": "Needs {{plugin}}", + "needsPluginHint": "This automation is skipped until the feature it needs is available again.", + "offBadge": "Off", + "docsLink": "View docs", + "ago": { + "seconds": "{{count}}s ago", + "minutes": "{{count}}m ago", + "hours": "{{count}}h ago", + "days": "{{count}}d ago" } } } }, "nav": { - "automations": "Automatiseringar" + "automations": "Automations" }, "onboarding": { - "feature_automations": "Automatiseringar", - "feature_automations_desc": "Kör steg automatiskt när något händer och få aviseringar." + "feature_automations": "Automations", + "feature_automations_desc": "Run steps automatically when something happens, and get notified." + }, + "maintenance": { + "title": "Maintenance", + "description": "Pause host status, health, metric, container and tunnel-disconnection automations while work is in progress. Monitoring, manual runs and scheduled automations continue.", + "denied": "You do not have permission to view maintenance.", + "sharedReadOnly": "This host was shared with you. Only its owner can change maintenance.", + "failed": "Maintenance could not be updated.", + "active": "Maintenance active", + "estimated": "Estimated completion", + "noAutoEnd": "The estimate does not end maintenance. End it explicitly when the work is complete.", + "endConfirm": "End maintenance and resume event-triggered automations for this host?", + "confirmEnd": "Confirm end", + "cancel": "Cancel", + "end": "End maintenance", + "action": "Action", + "startNow": "Start now", + "schedule": "Schedule for later", + "reason": "Reason", + "startUtc": "First start (UTC)", + "repeat": "Repeat", + "once": "Once", + "weekly": "Weekly", + "monthly": "Monthly", + "utcHelp": "Schedules use UTC throughout the year. Monthly schedules skip months without the selected day. Planned windows cannot overlap; overrunning maintenance continues across later windows.", + "duration": "Estimated duration (minutes)", + "grace": "Grace period (minutes)", + "notify": "Notify once if still offline after the estimate plus grace period", + "addSchedule": "Add schedule", + "schedules": "Schedules", + "noSchedules": "No maintenance schedules.", + "completed": "Already started", + "minutes_one": "{{count}} minute", + "minutes_other": "{{count}} minutes", + "remove": "Remove schedule", + "loadFailed": "Could not refresh maintenance status. Changes are disabled until it can be loaded.", + "loading": "Loading maintenance status…" } } diff --git a/plugins/automations/locales/translated/th_TH.json b/plugins/automations/locales/translated/th_TH.json index 72b00d2db..b459b4ade 100644 --- a/plugins/automations/locales/translated/th_TH.json +++ b/plugins/automations/locales/translated/th_TH.json @@ -1,149 +1,211 @@ { + "permissions": { + "view": { + "title": "View automations", + "description": "See the automations and their history." + }, + "create": { + "title": "Create automations", + "description": "Add new automations." + }, + "edit": { + "title": "Edit automations", + "description": "Change existing automations." + }, + "delete": { + "title": "Delete automations", + "description": "Remove automations." + }, + "run": { + "title": "Run automations", + "description": "Trigger an automation by hand." + } + }, "newUi": { "sidebar": { "automations": { - "title": "ระบบอัตโนมัติ", - "tabAutomations": "ระบบอัตโนมัติ", - "tabRuns": "วิ่ง", - "tabChannels": "ช่องต่างๆ", - "createAutomation": "ระบบอัตโนมัติใหม่", - "backToAutomations": "กลับสู่ระบบอัตโนมัติ", - "createTitle": "ระบบอัตโนมัติใหม่", - "editTitle": "แก้ไขอัตโนมัติ", - "empty": "ยังไม่มีระบบอัตโนมัติใดๆ สร้างระบบอัตโนมัติเพื่อตอบสนองต่อตัวชี้วัด กำหนดการ หรือเหตุการณ์ต่างๆ", - "emptyRuns": "ยังไม่มีการทดลองใดๆ เกิดขึ้น", - "emptyChannels": "ยังไม่มีช่องทางการแจ้งเตือน เพิ่มช่องทางเพื่อส่งการแจ้งเตือนไปยังที่ใดที่หนึ่ง", - "noChannelsHint": "ยังไม่ได้ตั้งค่าช่องใดๆ เพิ่มช่องในแท็บช่องได้เลย", - "addChannel": "เพิ่มช่องทาง", - "testChannel": "ทดสอบ", - "channelTestSent": "ส่งการแจ้งเตือนการทดสอบแล้ว", - "channelTestFailed": "การแจ้งเตือนการทดสอบล้มเหลว", - "channelDeleted": "ช่องถูกลบแล้ว", - "deleteChannelConfirm": "ลบช่องทางนี้? ระบบอัตโนมัติที่ใช้ช่องทางนี้จะหยุดแจ้งเตือน", - "nameLabel": "ชื่อ", - "namePlaceholder": "เช่น ล้างข้อมูลใน /data เมื่อเต็ม", - "nameRequired": "ต้องระบุชื่อ", - "descriptionLabel": "คำอธิบาย", - "descriptionPlaceholder": "คำอธิบายเพิ่มเติม (ไม่บังคับ)", - "enabledLabel": "เปิดใช้งาน", - "concurrencyLabel": "หากกำลังทำงานอยู่แล้ว", - "concurrencyHint": "ควรทำอย่างไรเมื่อเหตุการณ์นี้เกิดขึ้นอีกครั้งก่อนที่การทำงานครั้งสุดท้ายจะเสร็จสิ้น", + "title": "Automations", + "tabAutomations": "Automations", + "tabRuns": "Runs", + "tabChannels": "Channels", + "createAutomation": "New Automation", + "backToAutomations": "Back to Automations", + "createTitle": "New Automation", + "editTitle": "Edit Automation", + "empty": "No automations yet. Create one to react to a metric, a schedule, or an event.", + "emptyRuns": "No runs yet.", + "channelsHint": "Channels are set up in Alerts", + "noChannelsHint": "The alert always goes to your inbox. Add channels in Alerts to also send it somewhere else.", + "nameLabel": "Name", + "namePlaceholder": "e.g., Clean up /data when it fills", + "nameRequired": "Name is required", + "descriptionLabel": "Description", + "descriptionPlaceholder": "Optional description", + "enabledLabel": "Enabled", + "concurrencyLabel": "If it is already running", + "concurrencyHint": "What to do when this is triggered again before the last run has finished.", "concurrency": { - "skip": "ข้ามการวิ่งรอบใหม่ไป", - "queue": "รอและวิ่งตาม", - "allow": "เรียกใช้ทั้งสองอย่างพร้อมกัน" + "skip": "Skip the new run", + "queue": "Wait and run after", + "allow": "Run both at once" }, - "save": "บันทึก", - "created": "ระบบอัตโนมัติสร้างขึ้น", - "updated": "ระบบอัตโนมัติได้รับการบันทึกแล้ว", - "deleted": "ระบบอัตโนมัติลบแล้ว", - "deleteConfirm": "ลบระบบอัตโนมัตินี้แล้วใช่ไหม? ประวัติการทำงานของมันก็จะถูกลบไปด้วย", - "runNow": "วิ่งเลยตอนนี้", - "testRun": "การทดสอบการทำงาน", - "testRunHint": "ทำงานทุกขั้นตอน แต่ไม่แตะต้องสิ่งใดนอกเหนือจาก Termix", - "runStarted": "การวิ่งเริ่มต้นขึ้นแล้ว", - "runFinished": "การทำงานเสร็จสิ้น: {{status}}", - "trigger": "สิ่งกระตุ้น", - "steps": "ขั้นตอน", - "addStep": "เพิ่มขั้นตอน", - "removeStep": "ลบขั้นตอน", - "moveUp": "เลื่อนขึ้น", - "moveDown": "เลื่อนลง", - "noSteps": "ยังไม่มีขั้นตอนใดๆ เพิ่มขั้นตอนเพื่ออธิบายว่าควรเกิดอะไรขึ้น", - "webhookTokenTitle": "URL ของเว็บฮุค", - "webhookTokenDescription": "แสดงเพียงครั้งเดียว บันทึกตอนนี้ ไม่สามารถเรียกดูซ้ำได้ในภายหลัง", - "copy": "สำเนา", - "copied": "คัดลอกแล้ว", - "viewJson": "เจซอน", - "viewBuilder": "ผู้สร้าง", - "viewGraph": "กราฟ", - "lastRun": "การวิ่งครั้งสุดท้าย", - "never": "ไม่เคย", + "save": "Save", + "created": "Automation created", + "updated": "Automation saved", + "deleted": "Automation deleted", + "deleteConfirm": "Delete this automation? Its run history is deleted too.", + "runNow": "Run now", + "testRun": "Test run", + "testRunHint": "Runs every step but does not touch anything outside Termix.", + "runStarted": "Run started", + "runFinished": "Run finished: {{status}}", + "trigger": "Trigger", + "steps": "Steps", + "addStep": "Add step", + "removeStep": "Remove step", + "moveUp": "Move up", + "moveDown": "Move down", + "noSteps": "No steps yet. Add one to say what should happen.", + "webhookTokenTitle": "Webhook URL", + "webhookTokenDescription": "This is shown once. Save it now, it cannot be retrieved later.", + "copy": "Copy", + "copied": "Copied", + "viewJson": "JSON", + "viewBuilder": "Builder", + "viewGraph": "Graph", + "lastRun": "Last run", + "never": "Never", "duration": "{{seconds}}s", - "stepOutput": "เอาต์พุต", - "stepError": "ข้อผิดพลาด", - "dryRunBadge": "การทดสอบการทำงาน", + "stepOutput": "Output", + "stepError": "Error", + "dryRunBadge": "Test run", "hostSelector": { - "trigger": "โฮสต์ทริกเกอร์", - "host": "โฮสต์เฉพาะ", - "fleet": "กองเรือ", - "all": "โฮสต์ทั้งหมด" + "trigger": "Triggering host", + "host": "Specific host", + "fleet": "Fleet", + "all": "All hosts" }, "triggerKinds": { - "metric_threshold": "เกณฑ์เมตริก", - "host_status": "โฮสต์ขึ้นหรือลง", - "health_check": "การเปลี่ยนแปลงการตรวจสุขภาพ", - "schedule": "ตามกำหนดเวลา", - "docker_event": "เหตุการณ์คอนเทนเนอร์", - "internal_event": "กิจกรรมเทอร์มิกซ์", - "webhook": "เว็บฮุคขาเข้า" + "metric_threshold": "Metric threshold", + "host_status": "Host goes up or down", + "health_check": "Health check changes", + "schedule": "On a schedule", + "docker_event": "Container event", + "internal_event": "Termix event", + "webhook": "Incoming webhook" }, "stepTypes": { - "notify": "ส่งการแจ้งเตือน", - "http": "เรียกใช้ URL", - "run_snippet": "เรียกใช้โค้ดตัวอย่าง", - "run_command": "เรียกใช้คำสั่ง", - "docker": "ควบคุมตู้คอนเทนเนอร์", - "tunnel": "ควบคุมอุโมงค์", - "wol": "ปลุกโฮสต์", - "wait": "รอ", - "set_var": "ตั้งค่าตัวแปร", - "if": "ถ้า / มิฉะนั้น", - "run_automation": "เรียกใช้ระบบอัตโนมัติอีกครั้ง", - "stop": "หยุด" + "notify": "Send an alert", + "http": "Call a URL", + "run_snippet": "Run a snippet", + "run_command": "Run a command", + "docker": "Control a container", + "tunnel": "Control a tunnel", + "wol": "Wake a host", + "wait": "Wait", + "set_var": "Set a variable", + "if": "If / otherwise", + "run_automation": "Run another automation", + "stop": "Stop" }, "statuses": { - "running": "วิ่ง", - "success": "ความสำเร็จ", - "failed": "ล้มเหลว", - "timeout": "หมดเวลา", - "skipped": "ข้ามไป", - "cancelled": "ยกเลิก" + "running": "Running", + "success": "Success", + "failed": "Failed", + "timeout": "Timed out", + "skipped": "Skipped", + "cancelled": "Cancelled" }, "fields": { - "host": "เจ้าภาพ", - "metric": "เมตริก", - "mount": "จุดยึด", - "operator": "เป็น", - "value": "ค่า", - "forSeconds": "ต่อเนื่องเป็นเวลา (วินาที)", - "cooldown": "ระยะเวลาคูลดาวน์ (นาที)", - "cron": "การแสดงออกของ Cron", - "intervalSeconds": "ทุกๆ (วินาที)", - "timezone": "เขตเวลา", - "timezoneServer": "เวลาเซิร์ฟเวอร์", - "timezoneHint": "เวลาของ Cron จะอ่านได้ในโซนนี้ ไม่สามารถใช้ได้กับตารางเวลาแบบช่วงเวลา", - "container": "คอนเทนเนอร์", - "command": "สั่งการ", + "host": "Host", + "metric": "Metric", + "mount": "Mount point", + "operator": "Is", + "value": "Value", + "forSeconds": "Sustained for (seconds)", + "cooldown": "Cooldown (minutes)", + "cron": "Cron expression", + "intervalSeconds": "Every (seconds)", + "timezone": "Time zone", + "timezoneServer": "Server time", + "timezoneHint": "Cron times are read in this zone. Does not apply to interval schedules.", + "container": "Container", + "command": "Command", "url": "URL", - "method": "วิธี", - "body": "ร่างกาย", - "channels": "ช่องต่างๆ", - "title": "ชื่อ", - "message": "ข้อความ", - "snippet": "ส่วนหนึ่ง", - "seconds": "วินาที", - "conditionLeftPlaceholder": "ค่าที่ต้องตรวจสอบ", - "conditionRightPlaceholder": "เปรียบเทียบกับ", - "variableName": "ชื่อตัวแปร", - "variableValue": "ค่า", - "elevated": "เรียกใช้ด้วยคำสั่ง sudo", - "onError": "หากวิธีนี้ล้มเหลว", - "allowPrivateNetwork": "อนุญาตให้ใช้ที่อยู่เครือข่ายท้องถิ่น", - "allowPrivateNetworkHint": "จำเป็นสำหรับบริการที่โฮสต์เองบนเครือข่าย LAN ของคุณ โดยค่าเริ่มต้นจะปิดใช้งานเพื่อป้องกันการร้องขอไปยังที่อยู่ภายใน" + "method": "Method", + "body": "Body", + "channels": "Also send to", + "title": "Title", + "message": "Message", + "snippet": "Snippet", + "seconds": "Seconds", + "conditionLeftPlaceholder": "Value to check", + "conditionRightPlaceholder": "Compare against", + "variableName": "Variable name", + "variableValue": "Value", + "elevated": "Run with sudo", + "onError": "If this fails", + "allowPrivateNetwork": "Allow local network addresses", + "allowPrivateNetworkHint": "Needed for a self-hosted service on your LAN. Off by default to prevent requests to internal addresses." }, "onError": { - "stop": "หยุดการวิ่ง", - "continue": "ดำเนินการต่อไป" + "stop": "Stop the run", + "continue": "Carry on" + }, + "needsPlugin": "Needs {{plugin}}", + "needsPluginHint": "This automation is skipped until the feature it needs is available again.", + "offBadge": "Off", + "docsLink": "View docs", + "ago": { + "seconds": "{{count}}s ago", + "minutes": "{{count}}m ago", + "hours": "{{count}}h ago", + "days": "{{count}}d ago" } } } }, "nav": { - "automations": "ระบบอัตโนมัติ" + "automations": "Automations" }, "onboarding": { - "feature_automations": "ระบบอัตโนมัติ", - "feature_automations_desc": "ดำเนินการตามขั้นตอนโดยอัตโนมัติเมื่อเกิดเหตุการณ์ใดๆ และรับการแจ้งเตือน" + "feature_automations": "Automations", + "feature_automations_desc": "Run steps automatically when something happens, and get notified." + }, + "maintenance": { + "title": "Maintenance", + "description": "Pause host status, health, metric, container and tunnel-disconnection automations while work is in progress. Monitoring, manual runs and scheduled automations continue.", + "denied": "You do not have permission to view maintenance.", + "sharedReadOnly": "This host was shared with you. Only its owner can change maintenance.", + "failed": "Maintenance could not be updated.", + "active": "Maintenance active", + "estimated": "Estimated completion", + "noAutoEnd": "The estimate does not end maintenance. End it explicitly when the work is complete.", + "endConfirm": "End maintenance and resume event-triggered automations for this host?", + "confirmEnd": "Confirm end", + "cancel": "Cancel", + "end": "End maintenance", + "action": "Action", + "startNow": "Start now", + "schedule": "Schedule for later", + "reason": "Reason", + "startUtc": "First start (UTC)", + "repeat": "Repeat", + "once": "Once", + "weekly": "Weekly", + "monthly": "Monthly", + "utcHelp": "Schedules use UTC throughout the year. Monthly schedules skip months without the selected day. Planned windows cannot overlap; overrunning maintenance continues across later windows.", + "duration": "Estimated duration (minutes)", + "grace": "Grace period (minutes)", + "notify": "Notify once if still offline after the estimate plus grace period", + "addSchedule": "Add schedule", + "schedules": "Schedules", + "noSchedules": "No maintenance schedules.", + "completed": "Already started", + "minutes_one": "{{count}} minute", + "minutes_other": "{{count}} minutes", + "remove": "Remove schedule", + "loadFailed": "Could not refresh maintenance status. Changes are disabled until it can be loaded.", + "loading": "Loading maintenance status…" } } diff --git a/plugins/automations/locales/translated/tr_TR.json b/plugins/automations/locales/translated/tr_TR.json index d2099477e..219593365 100644 --- a/plugins/automations/locales/translated/tr_TR.json +++ b/plugins/automations/locales/translated/tr_TR.json @@ -1,149 +1,211 @@ { + "permissions": { + "view": { + "title": "View automations", + "description": "See the automations and their history." + }, + "create": { + "title": "Create automations", + "description": "Add new automations." + }, + "edit": { + "title": "Edit automations", + "description": "Change existing automations." + }, + "delete": { + "title": "Delete automations", + "description": "Remove automations." + }, + "run": { + "title": "Run automations", + "description": "Trigger an automation by hand." + } + }, "newUi": { "sidebar": { "automations": { - "title": "Otomasyonlar", - "tabAutomations": "Otomasyonlar", - "tabRuns": "Koşular", + "title": "Automations", + "tabAutomations": "Automations", + "tabRuns": "Runs", "tabChannels": "Kanallar", - "createAutomation": "Yeni Otomasyon", - "backToAutomations": "Otomasyonlara geri dön", - "createTitle": "Yeni Otomasyon", - "editTitle": "Düzenleme Otomasyonu", - "empty": "Henüz otomasyon yok. Bir ölçüme, bir programa veya bir olaya tepki verecek bir otomasyon oluşturun.", - "emptyRuns": "Henüz hiçbir deneme yapılmadı.", - "emptyChannels": "Henüz kanal yok. Bildirim göndermek için bir kanal ekleyin.", - "noChannelsHint": "Henüz hiçbir kanal ayarlanmadı. Kanallar sekmesinden bir kanal ekleyin.", - "addChannel": "Kanal Ekle", - "testChannel": "Test", - "channelTestSent": "Test bildirimi gönderildi", - "channelTestFailed": "Test bildirimi başarısız oldu.", - "channelDeleted": "Kanal silindi", - "deleteChannelConfirm": "Bu kanalı silmek ister misiniz? Bu kanalı kullanan otomasyonlar bildirim göndermeyi durduracaktır.", - "nameLabel": "İsim", - "namePlaceholder": "Örneğin, /data klasörü dolduğunda temizle.", - "nameRequired": "İsim zorunludur.", - "descriptionLabel": "Tanım", + "createAutomation": "New Automation", + "backToAutomations": "Back to Automations", + "createTitle": "New Automation", + "editTitle": "Edit Automation", + "empty": "No automations yet. Create one to react to a metric, a schedule, or an event.", + "emptyRuns": "No runs yet.", + "channelsHint": "Channels are set up in Alerts", + "noChannelsHint": "The alert always goes to your inbox. Add channels in Alerts to also send it somewhere else.", + "nameLabel": "Ad", + "namePlaceholder": "e.g., Clean up /data when it fills", + "nameRequired": "Ad zorunludur", + "descriptionLabel": "Açıklama", "descriptionPlaceholder": "İsteğe bağlı açıklama", - "enabledLabel": "Etkinleştirilmiş", - "concurrencyLabel": "Eğer zaten çalışıyorsa", - "concurrencyHint": "Son çalıştırma tamamlanmadan önce bu durum tekrar tetiklendiğinde ne yapılmalı?", + "enabledLabel": "Etkin", + "concurrencyLabel": "If it is already running", + "concurrencyHint": "What to do when this is triggered again before the last run has finished.", "concurrency": { - "skip": "Yeni sürümü atla", - "queue": "Bekle ve sonra koş", - "allow": "İkisini birden çalıştırın" + "skip": "Skip the new run", + "queue": "Wait and run after", + "allow": "Run both at once" }, - "save": "Kaydetmek", - "created": "Otomasyon oluşturuldu", - "updated": "Otomasyon kaydedildi", - "deleted": "Otomasyon silindi", - "deleteConfirm": "Bu otomasyonu silerseniz, çalıştırma geçmişi de silinir.", - "runNow": "Şimdi çalıştır", - "testRun": "Test çalıştırması", - "testRunHint": "Her adımı çalıştırır ancak Termix dışındaki hiçbir şeye dokunmaz.", - "runStarted": "Koşu başladı", - "runFinished": "Çalıştırma tamamlandı: {{status}}", - "trigger": "Tetiklemek", - "steps": "Adımlar", - "addStep": "Adım ekle", - "removeStep": "Adımı kaldır", - "moveUp": "Yukarı çık", - "moveDown": "Aşağıya doğru hareket edin", - "noSteps": "Henüz hiçbir adım yok. Ne olması gerektiğini belirtmek için bir adım ekleyin.", + "save": "Kaydet", + "created": "Automation created", + "updated": "Automation saved", + "deleted": "Automation deleted", + "deleteConfirm": "Delete this automation? Its run history is deleted too.", + "runNow": "Run now", + "testRun": "Test run", + "testRunHint": "Runs every step but does not touch anything outside Termix.", + "runStarted": "Run started", + "runFinished": "Run finished: {{status}}", + "trigger": "Tetikleyici", + "steps": "Steps", + "addStep": "Add step", + "removeStep": "Remove step", + "moveUp": "Move up", + "moveDown": "Move down", + "noSteps": "No steps yet. Add one to say what should happen.", "webhookTokenTitle": "Webhook URL", - "webhookTokenDescription": "Bu yalnızca bir kez gösterilecektir. Şimdi kaydedin, daha sonra geri alınamaz.", + "webhookTokenDescription": "This is shown once. Save it now, it cannot be retrieved later.", "copy": "Kopyala", "copied": "Kopyalandı", "viewJson": "JSON", - "viewBuilder": "İnşaatçı", - "viewGraph": "Grafik", - "lastRun": "Son koşu", - "never": "Asla", + "viewBuilder": "Builder", + "viewGraph": "Graph", + "lastRun": "Last run", + "never": "Hiçbir zaman", "duration": "{{seconds}}s", "stepOutput": "Çıktı", "stepError": "Hata", - "dryRunBadge": "Test çalıştırması", + "dryRunBadge": "Test run", "hostSelector": { - "trigger": "Tetikleyici sunucu", - "host": "Belirli ev sahibi", - "fleet": "Filo", - "all": "Tüm ev sahipleri" + "trigger": "Triggering host", + "host": "Specific host", + "fleet": "Fleet", + "all": "Tüm sunucular" }, "triggerKinds": { - "metric_threshold": "Metrik eşik", - "host_status": "Sunucu yukarı veya aşağı hareket eder.", - "health_check": "Sağlık kontrolü değişiklikleri", - "schedule": "Bir programa göre", - "docker_event": "Konteyner olayı", - "internal_event": "Termix etkinliği", - "webhook": "Gelen web kancası" + "metric_threshold": "Metric threshold", + "host_status": "Host goes up or down", + "health_check": "Health check changes", + "schedule": "On a schedule", + "docker_event": "Container event", + "internal_event": "Termix event", + "webhook": "Incoming webhook" }, "stepTypes": { - "notify": "Bildirim gönder", - "http": "Bir URL'yi çağırın", - "run_snippet": "Bir kod parçası çalıştırın.", - "run_command": "Bir komut çalıştır", - "docker": "Bir konteyneri kontrol edin.", - "tunnel": "Bir tüneli kontrol edin.", - "wol": "Bir ev sahibini uyandırın", - "wait": "Beklemek", - "set_var": "Bir değişken tanımlayın", - "if": "Eğer / aksi takdirde", - "run_automation": "Başka bir otomasyon çalıştırın", - "stop": "Durmak" + "notify": "Send an alert", + "http": "Call a URL", + "run_snippet": "Run a snippet", + "run_command": "Run a command", + "docker": "Control a container", + "tunnel": "Control a tunnel", + "wol": "Wake a host", + "wait": "Wait", + "set_var": "Set a variable", + "if": "If / otherwise", + "run_automation": "Run another automation", + "stop": "Durdurma" }, "statuses": { - "running": "Koşma", - "success": "Başarı", - "failed": "Arızalı", - "timeout": "Süre doldu", - "skipped": "Atlandı", - "cancelled": "İptal edildi" + "running": "Çalışıyor", + "success": "Başarılı", + "failed": "Başarısız", + "timeout": "Timed out", + "skipped": "Skipped", + "cancelled": "Cancelled" }, "fields": { - "host": "Ev sahibi", + "host": "Ana Bilgisayar", "metric": "Metrik", - "mount": "Montaj noktası", - "operator": "O", - "value": "Değer", - "forSeconds": "(Saniye) süreyle sürdürüldü", - "cooldown": "Soğuma süresi (dakika)", - "cron": "Cron ifadesi", - "intervalSeconds": "Her (saniye)", - "timezone": "Saat dilimi", - "timezoneServer": "Sunucu zamanı", - "timezoneHint": "Cron zamanlama ayarları bu bölgede okunur. Aralıklı zamanlamalar için geçerli değildir.", - "container": "Konteyner", - "command": "Emretmek", + "mount": "Mount point", + "operator": "Is", + "value": "Value", + "forSeconds": "Sustained for (seconds)", + "cooldown": "Bekleme süresi (dakika)", + "cron": "Cron expression", + "intervalSeconds": "Every (seconds)", + "timezone": "Time zone", + "timezoneServer": "Server time", + "timezoneHint": "Cron times are read in this zone. Does not apply to interval schedules.", + "container": "Container", + "command": "Komut", "url": "URL", - "method": "Yöntem", - "body": "Vücut", - "channels": "Kanallar", + "method": "Method", + "body": "Body", + "channels": "Also send to", "title": "Başlık", - "message": "Mesaj", - "snippet": "Alıntı", - "seconds": "Saniyeler", - "conditionLeftPlaceholder": "Kontrol edilecek değer", - "conditionRightPlaceholder": "Karşılaştırın", - "variableName": "Değişken adı", - "variableValue": "Değer", - "elevated": "sudo ile çalıştır", - "onError": "Eğer bu başarısız olursa", - "allowPrivateNetwork": "Yerel ağ adreslerine izin verin.", - "allowPrivateNetworkHint": "Yerel ağınızda kendi sunucunuzda barındırdığınız bir hizmet için gereklidir. Dahili adreslere yapılan istekleri engellemek için varsayılan olarak kapalıdır." + "message": "Message", + "snippet": "Snippet", + "seconds": "Seconds", + "conditionLeftPlaceholder": "Value to check", + "conditionRightPlaceholder": "Compare against", + "variableName": "Variable name", + "variableValue": "Value", + "elevated": "Run with sudo", + "onError": "If this fails", + "allowPrivateNetwork": "Allow local network addresses", + "allowPrivateNetworkHint": "Needed for a self-hosted service on your LAN. Off by default to prevent requests to internal addresses." }, "onError": { - "stop": "Koşuyu durdurun", - "continue": "Devam edin" + "stop": "Stop the run", + "continue": "Carry on" + }, + "needsPlugin": "Needs {{plugin}}", + "needsPluginHint": "This automation is skipped until the feature it needs is available again.", + "offBadge": "Kapalı", + "docsLink": "Belgelere bak", + "ago": { + "seconds": "{{count}}s ago", + "minutes": "{{count}} dakika önce", + "hours": "{{count}} saat önce", + "days": "{{count}} gün önce" } } } }, "nav": { - "automations": "Otomasyonlar" + "automations": "Automations" }, "onboarding": { - "feature_automations": "Otomasyonlar", - "feature_automations_desc": "Bir şey olduğunda adımları otomatik olarak çalıştırın ve bildirim alın." + "feature_automations": "Automations", + "feature_automations_desc": "Run steps automatically when something happens, and get notified." + }, + "maintenance": { + "title": "Bakım", + "description": "Pause host status, health, metric, container and tunnel-disconnection automations while work is in progress. Monitoring, manual runs and scheduled automations continue.", + "denied": "You do not have permission to view maintenance.", + "sharedReadOnly": "This host was shared with you. Only its owner can change maintenance.", + "failed": "Maintenance could not be updated.", + "active": "Maintenance active", + "estimated": "Estimated completion", + "noAutoEnd": "The estimate does not end maintenance. End it explicitly when the work is complete.", + "endConfirm": "End maintenance and resume event-triggered automations for this host?", + "confirmEnd": "Confirm end", + "cancel": "İptal", + "end": "End maintenance", + "action": "İşlem", + "startNow": "Start now", + "schedule": "Schedule for later", + "reason": "Reason", + "startUtc": "First start (UTC)", + "repeat": "Repeat", + "once": "Once", + "weekly": "Weekly", + "monthly": "Monthly", + "utcHelp": "Schedules use UTC throughout the year. Monthly schedules skip months without the selected day. Planned windows cannot overlap; overrunning maintenance continues across later windows.", + "duration": "Estimated duration (minutes)", + "grace": "Grace period (minutes)", + "notify": "Notify once if still offline after the estimate plus grace period", + "addSchedule": "Add schedule", + "schedules": "Schedules", + "noSchedules": "No maintenance schedules.", + "completed": "Already started", + "minutes_one": "{{count}} minute", + "minutes_other": "{{count}} minutes", + "remove": "Remove schedule", + "loadFailed": "Could not refresh maintenance status. Changes are disabled until it can be loaded.", + "loading": "Loading maintenance status…" } } diff --git a/plugins/automations/locales/translated/uk_UA.json b/plugins/automations/locales/translated/uk_UA.json index 2fbe13446..b459b4ade 100644 --- a/plugins/automations/locales/translated/uk_UA.json +++ b/plugins/automations/locales/translated/uk_UA.json @@ -1,149 +1,211 @@ { + "permissions": { + "view": { + "title": "View automations", + "description": "See the automations and their history." + }, + "create": { + "title": "Create automations", + "description": "Add new automations." + }, + "edit": { + "title": "Edit automations", + "description": "Change existing automations." + }, + "delete": { + "title": "Delete automations", + "description": "Remove automations." + }, + "run": { + "title": "Run automations", + "description": "Trigger an automation by hand." + } + }, "newUi": { "sidebar": { "automations": { - "title": "Автоматизація", - "tabAutomations": "Автоматизація", - "tabRuns": "Пробіжки", - "tabChannels": "Канали", - "createAutomation": "Нова автоматизація", - "backToAutomations": "Назад до автоматизації", - "createTitle": "Нова автоматизація", - "editTitle": "Редагувати автоматизацію", - "empty": "Автоматизації поки що немає. Створіть її, щоб реагувати на метрику, розклад або подію.", - "emptyRuns": "Поки що жодних пробіжок.", - "emptyChannels": "Поки що немає каналів. Додайте один, щоб надсилати сповіщення кудись.", - "noChannelsHint": "Канали ще не налаштовано. Додайте його на вкладці «Канали».", - "addChannel": "Додати канал", - "testChannel": "Тест", - "channelTestSent": "Тестове сповіщення надіслано", - "channelTestFailed": "Не вдалося виконати тестове сповіщення", - "channelDeleted": "Канал видалено", - "deleteChannelConfirm": "Видалити цей канал? Автоматизації, що його використовують, перестануть надсилати сповіщення.", - "nameLabel": "Ім'я", - "namePlaceholder": "наприклад, Очищати /дані, коли вони заповнюються", - "nameRequired": "Ім'я обов'язкове", - "descriptionLabel": "Опис", - "descriptionPlaceholder": "Додатковий опис", - "enabledLabel": "Увімкнено", - "concurrencyLabel": "Якщо воно вже працює", - "concurrencyHint": "Що робити, якщо це спрацьовує знову до завершення останнього запуску.", + "title": "Automations", + "tabAutomations": "Automations", + "tabRuns": "Runs", + "tabChannels": "Channels", + "createAutomation": "New Automation", + "backToAutomations": "Back to Automations", + "createTitle": "New Automation", + "editTitle": "Edit Automation", + "empty": "No automations yet. Create one to react to a metric, a schedule, or an event.", + "emptyRuns": "No runs yet.", + "channelsHint": "Channels are set up in Alerts", + "noChannelsHint": "The alert always goes to your inbox. Add channels in Alerts to also send it somewhere else.", + "nameLabel": "Name", + "namePlaceholder": "e.g., Clean up /data when it fills", + "nameRequired": "Name is required", + "descriptionLabel": "Description", + "descriptionPlaceholder": "Optional description", + "enabledLabel": "Enabled", + "concurrencyLabel": "If it is already running", + "concurrencyHint": "What to do when this is triggered again before the last run has finished.", "concurrency": { - "skip": "Пропустити новий пробіг", - "queue": "Чекай і біжіть за ним", - "allow": "Запустіть обидва одночасно" + "skip": "Skip the new run", + "queue": "Wait and run after", + "allow": "Run both at once" }, - "save": "Зберегти", - "created": "Автоматизація створена", - "updated": "Автоматизація збережена", - "deleted": "Автоматизацію видалено", - "deleteConfirm": "Видалити цю автоматизацію? Історія її запуску також видаляється.", - "runNow": "Біжи зараз", - "testRun": "Тестовий запуск", - "testRunHint": "Виконує кожен крок, але не торкається нічого поза Termix.", - "runStarted": "Біг розпочато", - "runFinished": "Виконання завершено: {{status}}", - "trigger": "Тригер", - "steps": "Кроки", - "addStep": "Додати крок", - "removeStep": "Видалити крок", - "moveUp": "Перемістити вгору", - "moveDown": "Перемістити вниз", - "noSteps": "Кроків поки що немає. Додайте один, щоб пояснити, що має статися.", - "webhookTokenTitle": "URL-адреса вебхука", - "webhookTokenDescription": "Це відображається один раз. Збережіть це зараз, пізніше це неможливо буде отримати.", - "copy": "Копіювати", - "copied": "Скопійовано", + "save": "Save", + "created": "Automation created", + "updated": "Automation saved", + "deleted": "Automation deleted", + "deleteConfirm": "Delete this automation? Its run history is deleted too.", + "runNow": "Run now", + "testRun": "Test run", + "testRunHint": "Runs every step but does not touch anything outside Termix.", + "runStarted": "Run started", + "runFinished": "Run finished: {{status}}", + "trigger": "Trigger", + "steps": "Steps", + "addStep": "Add step", + "removeStep": "Remove step", + "moveUp": "Move up", + "moveDown": "Move down", + "noSteps": "No steps yet. Add one to say what should happen.", + "webhookTokenTitle": "Webhook URL", + "webhookTokenDescription": "This is shown once. Save it now, it cannot be retrieved later.", + "copy": "Copy", + "copied": "Copied", "viewJson": "JSON", - "viewBuilder": "Будівельник", - "viewGraph": "Графік", - "lastRun": "Останній запуск", - "never": "Ніколи", - "duration": "{{seconds}}с", - "stepOutput": "Вихід", - "stepError": "Помилка", - "dryRunBadge": "Тестовий запуск", + "viewBuilder": "Builder", + "viewGraph": "Graph", + "lastRun": "Last run", + "never": "Never", + "duration": "{{seconds}}s", + "stepOutput": "Output", + "stepError": "Error", + "dryRunBadge": "Test run", "hostSelector": { - "trigger": "Хост-тригер", - "host": "Конкретний хост", - "fleet": "Флот", - "all": "Усі хости" + "trigger": "Triggering host", + "host": "Specific host", + "fleet": "Fleet", + "all": "All hosts" }, "triggerKinds": { - "metric_threshold": "Поріг показника", - "host_status": "Хост піднімається або опускається", - "health_check": "Зміни в перевірці стану здоров'я", - "schedule": "За розкладом", - "docker_event": "Подія контейнера", - "internal_event": "Подія Termix", - "webhook": "Вхідний вебхук" + "metric_threshold": "Metric threshold", + "host_status": "Host goes up or down", + "health_check": "Health check changes", + "schedule": "On a schedule", + "docker_event": "Container event", + "internal_event": "Termix event", + "webhook": "Incoming webhook" }, "stepTypes": { - "notify": "Надіслати сповіщення", - "http": "Виклик URL-адреси", - "run_snippet": "Виконати фрагмент коду", - "run_command": "Виконайте команду", - "docker": "Керування контейнером", - "tunnel": "Контролюйте тунель", - "wol": "Розбудити господаря", - "wait": "Зачекайте", - "set_var": "Встановити змінну", - "if": "Якщо / інакше", - "run_automation": "Запустіть ще одну автоматизацію", - "stop": "СТІЙ" + "notify": "Send an alert", + "http": "Call a URL", + "run_snippet": "Run a snippet", + "run_command": "Run a command", + "docker": "Control a container", + "tunnel": "Control a tunnel", + "wol": "Wake a host", + "wait": "Wait", + "set_var": "Set a variable", + "if": "If / otherwise", + "run_automation": "Run another automation", + "stop": "Stop" }, "statuses": { - "running": "Біг", - "success": "Успіх", - "failed": "Не вдалося", - "timeout": "Час очікування минув", - "skipped": "Пропущено", - "cancelled": "Скасовано" + "running": "Running", + "success": "Success", + "failed": "Failed", + "timeout": "Timed out", + "skipped": "Skipped", + "cancelled": "Cancelled" }, "fields": { - "host": "Хост", - "metric": "Метрика", - "mount": "Точка монтування", - "operator": "Є", - "value": "Значення", - "forSeconds": "Триває протягом (секунд)", - "cooldown": "Охолодження (хвилини)", - "cron": "Cron-вираз", - "intervalSeconds": "Кожні (секунди)", - "timezone": "Часовий пояс", - "timezoneServer": "Час сервера", - "timezoneHint": "Час Cron зчитується в цій зоні. Не стосується інтервальних розкладів.", - "container": "Контейнер", - "command": "Команда", - "url": "URL-адреса", - "method": "Метод", - "body": "Тіло", - "channels": "Канали", - "title": "Назва", - "message": "Повідомлення", - "snippet": "Фрагмент", - "seconds": "Секунди", - "conditionLeftPlaceholder": "Значення для перевірки", - "conditionRightPlaceholder": "Порівняйте з", - "variableName": "Ім'я змінної", - "variableValue": "Значення", - "elevated": "Запустити за допомогою sudo", - "onError": "Якщо це не вдасться", - "allowPrivateNetwork": "Дозволити адреси локальної мережі", - "allowPrivateNetworkHint": "Потрібно для самостійно розміщеної служби у вашій локальній мережі. Вимкнено за замовчуванням, щоб запобігти запитам до внутрішніх адрес." + "host": "Host", + "metric": "Metric", + "mount": "Mount point", + "operator": "Is", + "value": "Value", + "forSeconds": "Sustained for (seconds)", + "cooldown": "Cooldown (minutes)", + "cron": "Cron expression", + "intervalSeconds": "Every (seconds)", + "timezone": "Time zone", + "timezoneServer": "Server time", + "timezoneHint": "Cron times are read in this zone. Does not apply to interval schedules.", + "container": "Container", + "command": "Command", + "url": "URL", + "method": "Method", + "body": "Body", + "channels": "Also send to", + "title": "Title", + "message": "Message", + "snippet": "Snippet", + "seconds": "Seconds", + "conditionLeftPlaceholder": "Value to check", + "conditionRightPlaceholder": "Compare against", + "variableName": "Variable name", + "variableValue": "Value", + "elevated": "Run with sudo", + "onError": "If this fails", + "allowPrivateNetwork": "Allow local network addresses", + "allowPrivateNetworkHint": "Needed for a self-hosted service on your LAN. Off by default to prevent requests to internal addresses." }, "onError": { - "stop": "Зупинити біг", - "continue": "Продовжуйте" + "stop": "Stop the run", + "continue": "Carry on" + }, + "needsPlugin": "Needs {{plugin}}", + "needsPluginHint": "This automation is skipped until the feature it needs is available again.", + "offBadge": "Off", + "docsLink": "View docs", + "ago": { + "seconds": "{{count}}s ago", + "minutes": "{{count}}m ago", + "hours": "{{count}}h ago", + "days": "{{count}}d ago" } } } }, "nav": { - "automations": "Автоматизація" + "automations": "Automations" }, "onboarding": { - "feature_automations": "Автоматизація", - "feature_automations_desc": "Автоматично виконувати кроки, коли щось відбувається, та отримувати сповіщення." + "feature_automations": "Automations", + "feature_automations_desc": "Run steps automatically when something happens, and get notified." + }, + "maintenance": { + "title": "Maintenance", + "description": "Pause host status, health, metric, container and tunnel-disconnection automations while work is in progress. Monitoring, manual runs and scheduled automations continue.", + "denied": "You do not have permission to view maintenance.", + "sharedReadOnly": "This host was shared with you. Only its owner can change maintenance.", + "failed": "Maintenance could not be updated.", + "active": "Maintenance active", + "estimated": "Estimated completion", + "noAutoEnd": "The estimate does not end maintenance. End it explicitly when the work is complete.", + "endConfirm": "End maintenance and resume event-triggered automations for this host?", + "confirmEnd": "Confirm end", + "cancel": "Cancel", + "end": "End maintenance", + "action": "Action", + "startNow": "Start now", + "schedule": "Schedule for later", + "reason": "Reason", + "startUtc": "First start (UTC)", + "repeat": "Repeat", + "once": "Once", + "weekly": "Weekly", + "monthly": "Monthly", + "utcHelp": "Schedules use UTC throughout the year. Monthly schedules skip months without the selected day. Planned windows cannot overlap; overrunning maintenance continues across later windows.", + "duration": "Estimated duration (minutes)", + "grace": "Grace period (minutes)", + "notify": "Notify once if still offline after the estimate plus grace period", + "addSchedule": "Add schedule", + "schedules": "Schedules", + "noSchedules": "No maintenance schedules.", + "completed": "Already started", + "minutes_one": "{{count}} minute", + "minutes_other": "{{count}} minutes", + "remove": "Remove schedule", + "loadFailed": "Could not refresh maintenance status. Changes are disabled until it can be loaded.", + "loading": "Loading maintenance status…" } } diff --git a/plugins/automations/locales/translated/vi_VN.json b/plugins/automations/locales/translated/vi_VN.json index 3b36d81cd..1e53b35f0 100644 --- a/plugins/automations/locales/translated/vi_VN.json +++ b/plugins/automations/locales/translated/vi_VN.json @@ -1,149 +1,211 @@ { + "permissions": { + "view": { + "title": "View automations", + "description": "See the automations and their history." + }, + "create": { + "title": "Create automations", + "description": "Add new automations." + }, + "edit": { + "title": "Edit automations", + "description": "Change existing automations." + }, + "delete": { + "title": "Delete automations", + "description": "Remove automations." + }, + "run": { + "title": "Run automations", + "description": "Trigger an automation by hand." + } + }, "newUi": { "sidebar": { "automations": { - "title": "Tự động hóa", - "tabAutomations": "Tự động hóa", - "tabRuns": "Chạy", + "title": "Automations", + "tabAutomations": "Automations", + "tabRuns": "Runs", "tabChannels": "Kênh", - "createAutomation": "Tự động hóa mới", - "backToAutomations": "Quay lại phần Tự động hóa", - "createTitle": "Tự động hóa mới", - "editTitle": "Tự động chỉnh sửa", - "empty": "Hiện chưa có tính năng tự động hóa nào. Hãy tạo một tính năng để phản ứng với một chỉ số, lịch trình hoặc sự kiện nào đó.", - "emptyRuns": "Chưa có lượt chạy nào.", - "emptyChannels": "Chưa có kênh nào. Thêm một kênh để gửi thông báo đến đâu đó.", - "noChannelsHint": "Chưa có kênh nào được thiết lập. Thêm một kênh trong tab Kênh.", - "addChannel": "Thêm kênh", - "testChannel": "Bài kiểm tra", - "channelTestSent": "Thông báo kiểm tra đã được gửi", - "channelTestFailed": "Thông báo kiểm tra thất bại", - "channelDeleted": "Kênh đã bị xóa", - "deleteChannelConfirm": "Xóa kênh này? Các tự động hóa sử dụng kênh này sẽ ngừng gửi thông báo.", + "createAutomation": "New Automation", + "backToAutomations": "Back to Automations", + "createTitle": "New Automation", + "editTitle": "Edit Automation", + "empty": "No automations yet. Create one to react to a metric, a schedule, or an event.", + "emptyRuns": "No runs yet.", + "channelsHint": "Channels are set up in Alerts", + "noChannelsHint": "The alert always goes to your inbox. Add channels in Alerts to also send it somewhere else.", "nameLabel": "Tên", - "namePlaceholder": "Ví dụ: Dọn dẹp thư mục /data khi nó đầy.", + "namePlaceholder": "e.g., Clean up /data when it fills", "nameRequired": "Tên là bắt buộc", - "descriptionLabel": "Sự miêu tả", + "descriptionLabel": "Mô tả", "descriptionPlaceholder": "Mô tả tùy chọn", "enabledLabel": "Đã bật", - "concurrencyLabel": "Nếu nó đang chạy", - "concurrencyHint": "Phải làm gì khi sự cố này xảy ra lần nữa trước khi quá trình chạy cuối cùng hoàn tất?", + "concurrencyLabel": "If it is already running", + "concurrencyHint": "What to do when this is triggered again before the last run has finished.", "concurrency": { - "skip": "Bỏ qua lần chạy mới", - "queue": "Chờ đợi và chạy theo", - "allow": "Chạy cả hai cùng một lúc" + "skip": "Skip the new run", + "queue": "Wait and run after", + "allow": "Run both at once" }, - "save": "Cứu", - "created": "Tự động hóa được tạo", - "updated": "Tự động hóa đã được lưu", - "deleted": "Tự động hóa đã bị xóa", - "deleteConfirm": "Xóa tự động hóa này? Lịch sử chạy của nó cũng bị xóa.", - "runNow": "Chạy ngay", - "testRun": "Chạy thử nghiệm", - "testRunHint": "Nó chạy theo từng bước nhưng không chạm vào bất cứ thứ gì bên ngoài Termix.", - "runStarted": "Chạy bắt đầu", - "runFinished": "Quá trình chạy đã hoàn tất: {{status}}", - "trigger": "Cò súng", - "steps": "Các bước", - "addStep": "Thêm bước", - "removeStep": "Xóa bước", - "moveUp": "Tiến lên", - "moveDown": "Di chuyển xuống", - "noSteps": "Chưa có bước nào. Hãy thêm một bước để mô tả những gì cần xảy ra.", - "webhookTokenTitle": "URL Webhook", - "webhookTokenDescription": "Thông tin này chỉ hiển thị một lần. Hãy lưu lại ngay, bạn sẽ không thể khôi phục lại sau này.", + "save": "Lưu", + "created": "Automation created", + "updated": "Automation saved", + "deleted": "Automation deleted", + "deleteConfirm": "Delete this automation? Its run history is deleted too.", + "runNow": "Run now", + "testRun": "Test run", + "testRunHint": "Runs every step but does not touch anything outside Termix.", + "runStarted": "Run started", + "runFinished": "Run finished: {{status}}", + "trigger": "Kích hoạt", + "steps": "Steps", + "addStep": "Add step", + "removeStep": "Remove step", + "moveUp": "Move up", + "moveDown": "Move down", + "noSteps": "No steps yet. Add one to say what should happen.", + "webhookTokenTitle": "Webhook URL", + "webhookTokenDescription": "This is shown once. Save it now, it cannot be retrieved later.", "copy": "Sao chép", "copied": "Đã sao chép", "viewJson": "JSON", - "viewBuilder": "Nhà xây dựng", - "viewGraph": "Đồ thị", - "lastRun": "Lần chạy cuối", - "never": "Không bao giờ", + "viewBuilder": "Builder", + "viewGraph": "Graph", + "lastRun": "Last run", + "never": "Chưa bao giờ", "duration": "{{seconds}}s", "stepOutput": "Đầu ra", "stepError": "Lỗi", - "dryRunBadge": "Chạy thử nghiệm", + "dryRunBadge": "Test run", "hostSelector": { - "trigger": "Máy chủ kích hoạt", - "host": "Máy chủ cụ thể", - "fleet": "Hạm đội", - "all": "Tất cả người chủ trì" + "trigger": "Triggering host", + "host": "Specific host", + "fleet": "Fleet", + "all": "Tất cả máy chủ" }, "triggerKinds": { - "metric_threshold": "Ngưỡng số liệu", - "host_status": "Máy chủ tăng hoặc giảm", - "health_check": "Thay đổi trong kiểm tra sức khỏe", - "schedule": "Theo lịch trình", - "docker_event": "Sự kiện container", - "internal_event": "Sự kiện Termix", - "webhook": "Webhook đến" + "metric_threshold": "Metric threshold", + "host_status": "Host goes up or down", + "health_check": "Health check changes", + "schedule": "On a schedule", + "docker_event": "Container event", + "internal_event": "Termix event", + "webhook": "Incoming webhook" }, "stepTypes": { - "notify": "Gửi thông báo", - "http": "Gọi một URL", - "run_snippet": "Chạy một đoạn mã", - "run_command": "Chạy một lệnh", - "docker": "Kiểm soát một container", - "tunnel": "Kiểm soát đường hầm", - "wol": "Đánh thức một chủ nhà", - "wait": "Chờ đợi", - "set_var": "Đặt một biến", - "if": "Nếu/ngược lại", - "run_automation": "Chạy một quy trình tự động hóa khác", - "stop": "Dừng lại" + "notify": "Send an alert", + "http": "Call a URL", + "run_snippet": "Run a snippet", + "run_command": "Run a command", + "docker": "Control a container", + "tunnel": "Control a tunnel", + "wol": "Wake a host", + "wait": "Wait", + "set_var": "Set a variable", + "if": "If / otherwise", + "run_automation": "Run another automation", + "stop": "Bit dừng" }, "statuses": { "running": "Đang chạy", "success": "Thành công", "failed": "Thất bại", - "timeout": "Hết thời gian", - "skipped": "Bỏ qua", - "cancelled": "Đã hủy" + "timeout": "Timed out", + "skipped": "Skipped", + "cancelled": "Cancelled" }, "fields": { - "host": "Chủ nhà", - "metric": "Số liệu", - "mount": "Điểm gắn kết", - "operator": "Là", - "value": "Giá trị", - "forSeconds": "Duy trì trong (giây)", - "cooldown": "Thời gian hồi chiêu (phút)", - "cron": "Biểu thức Cron", - "intervalSeconds": "Mỗi (giây)", - "timezone": "Múi giờ", - "timezoneServer": "Thời gian máy chủ", - "timezoneHint": "Thời gian Cron được đọc trong vùng này. Không áp dụng cho lịch trình theo khoảng thời gian.", - "container": "Thùng chứa", - "command": "Yêu cầu", + "host": "Máy chủ", + "metric": "Chỉ số", + "mount": "Mount point", + "operator": "Is", + "value": "Value", + "forSeconds": "Sustained for (seconds)", + "cooldown": "Thời gian chờ (phút)", + "cron": "Cron expression", + "intervalSeconds": "Every (seconds)", + "timezone": "Time zone", + "timezoneServer": "Server time", + "timezoneHint": "Cron times are read in this zone. Does not apply to interval schedules.", + "container": "Container", + "command": "Lệnh", "url": "URL", - "method": "Phương pháp", - "body": "Thân hình", - "channels": "Kênh", + "method": "Method", + "body": "Body", + "channels": "Also send to", "title": "Tiêu đề", - "message": "Tin nhắn", - "snippet": "Đoạn trích", - "seconds": "Giây", - "conditionLeftPlaceholder": "Giá trị cần kiểm tra", - "conditionRightPlaceholder": "So sánh với", - "variableName": "Tên biến", - "variableValue": "Giá trị", - "elevated": "Chạy với quyền sudo", - "onError": "Nếu điều này thất bại", - "allowPrivateNetwork": "Cho phép địa chỉ mạng cục bộ", - "allowPrivateNetworkHint": "Cần thiết cho dịch vụ tự lưu trữ trên mạng LAN của bạn. Mặc định là tắt để ngăn chặn các yêu cầu đến các địa chỉ nội bộ." + "message": "Message", + "snippet": "Snippet", + "seconds": "Seconds", + "conditionLeftPlaceholder": "Value to check", + "conditionRightPlaceholder": "Compare against", + "variableName": "Variable name", + "variableValue": "Value", + "elevated": "Run with sudo", + "onError": "If this fails", + "allowPrivateNetwork": "Allow local network addresses", + "allowPrivateNetworkHint": "Needed for a self-hosted service on your LAN. Off by default to prevent requests to internal addresses." }, "onError": { - "stop": "Dừng cuộc chạy", - "continue": "Tiếp tục" + "stop": "Stop the run", + "continue": "Carry on" + }, + "needsPlugin": "Needs {{plugin}}", + "needsPluginHint": "This automation is skipped until the feature it needs is available again.", + "offBadge": "Tắt", + "docsLink": "Xem tài liệu", + "ago": { + "seconds": "{{count}}s ago", + "minutes": "{{count}} phút trước", + "hours": "{{count}} giờ trước", + "days": "{{count}} ngày trước" } } } }, "nav": { - "automations": "Tự động hóa" + "automations": "Automations" }, "onboarding": { - "feature_automations": "Tự động hóa", - "feature_automations_desc": "Thực hiện các bước tự động khi có sự kiện xảy ra và nhận thông báo." + "feature_automations": "Automations", + "feature_automations_desc": "Run steps automatically when something happens, and get notified." + }, + "maintenance": { + "title": "Bảo trì", + "description": "Pause host status, health, metric, container and tunnel-disconnection automations while work is in progress. Monitoring, manual runs and scheduled automations continue.", + "denied": "You do not have permission to view maintenance.", + "sharedReadOnly": "This host was shared with you. Only its owner can change maintenance.", + "failed": "Maintenance could not be updated.", + "active": "Maintenance active", + "estimated": "Estimated completion", + "noAutoEnd": "The estimate does not end maintenance. End it explicitly when the work is complete.", + "endConfirm": "End maintenance and resume event-triggered automations for this host?", + "confirmEnd": "Confirm end", + "cancel": "Hủy", + "end": "End maintenance", + "action": "Hành động", + "startNow": "Start now", + "schedule": "Schedule for later", + "reason": "Reason", + "startUtc": "First start (UTC)", + "repeat": "Repeat", + "once": "Once", + "weekly": "Weekly", + "monthly": "Monthly", + "utcHelp": "Schedules use UTC throughout the year. Monthly schedules skip months without the selected day. Planned windows cannot overlap; overrunning maintenance continues across later windows.", + "duration": "Estimated duration (minutes)", + "grace": "Grace period (minutes)", + "notify": "Notify once if still offline after the estimate plus grace period", + "addSchedule": "Add schedule", + "schedules": "Schedules", + "noSchedules": "No maintenance schedules.", + "completed": "Already started", + "minutes_one": "{{count}} minute", + "minutes_other": "{{count}} minutes", + "remove": "Remove schedule", + "loadFailed": "Could not refresh maintenance status. Changes are disabled until it can be loaded.", + "loading": "Loading maintenance status…" } } diff --git a/plugins/automations/locales/translated/zh_CN.json b/plugins/automations/locales/translated/zh_CN.json index f634ce3ce..05f31bc25 100644 --- a/plugins/automations/locales/translated/zh_CN.json +++ b/plugins/automations/locales/translated/zh_CN.json @@ -1,94 +1,110 @@ { + "permissions": { + "view": { + "title": "查看自动化", + "description": "查看自动化及其执行历史。" + }, + "create": { + "title": "创建自动化", + "description": "添加新的自动化。" + }, + "edit": { + "title": "编辑自动化", + "description": "修改现有自动化。" + }, + "delete": { + "title": "删除自动化", + "description": "移除自动化。" + }, + "run": { + "title": "运行自动化", + "description": "手动触发自动化。" + } + }, "newUi": { "sidebar": { "automations": { "title": "自动化", "tabAutomations": "自动化", "tabRuns": "运行记录", - "tabChannels": "频道", - "createAutomation": "新自动化", - "backToAutomations": "返回自动化页面", - "createTitle": "新自动化", + "tabChannels": "通道", + "createAutomation": "新建自动化", + "backToAutomations": "返回自动化", + "createTitle": "新建自动化", "editTitle": "编辑自动化", - "empty": "尚未设置任何自动化流程。请创建一个自动化流程,使其能够根据指标、日程安排或事件做出反应。", + "empty": "暂无自动化。创建自动化以响应指标、计划或事件。", "emptyRuns": "暂无运行记录。", - "emptyChannels": "暂无频道。添加一个频道以便向某个地方发送通知。", - "noChannelsHint": "尚未设置任何频道。请在“频道”标签页中添加频道。", - "addChannel": "添加频道", - "testChannel": "测试", - "channelTestSent": "已发送测试通知", - "channelTestFailed": "测试通知失败", - "channelDeleted": "频道已删除", - "deleteChannelConfirm": "删除此频道?使用该频道的自动化功能将停止通知。", + "channelsHint": "渠道在“告警”中设置", + "noChannelsHint": "告警始终会发送到收件箱。在“告警”中添加渠道后,也可发送到其他位置。", "nameLabel": "名称", - "namePlaceholder": "例如,当 /data 目录填满时进行清理。", + "namePlaceholder": "例如:/data 空间不足时自动清理", "nameRequired": "名称为必填项", "descriptionLabel": "描述", "descriptionPlaceholder": "可选描述", "enabledLabel": "已启用", - "concurrencyLabel": "如果它已经在运行", - "concurrencyHint": "如果在上次运行结束前再次触发此问题,该怎么办?", + "concurrencyLabel": "已有任务运行时", + "concurrencyHint": "上次运行尚未结束时再次触发的处理方式。", "concurrency": { - "skip": "跳过新一轮", + "skip": "跳过本次运行", "queue": "稍等会再运行", - "allow": "同时运行这两个程序" + "allow": "同时运行两个任务" }, "save": "保存", "created": "自动化已创建", "updated": "自动化已保存", "deleted": "自动化已删除", - "deleteConfirm": "删除此自动化流程?其运行历史记录也会被删除。", + "deleteConfirm": "删除此自动化?其运行历史也会一并删除。", "runNow": "立即运行", "testRun": "测试运行", - "testRunHint": "执行所有步骤,但不触及 Termix 之外的任何内容。", - "runStarted": "运行已启动", - "runFinished": "运行结束: {{status}}", + "testRunHint": "执行每个步骤,但不会修改 Termix 之外的任何内容。", + "runStarted": "已开始运行", + "runFinished": "运行结束:{{status}}", "trigger": "触发器", "steps": "步骤", "addStep": "添加步骤", "removeStep": "移除步骤", - "moveUp": "向上", - "moveDown": "向下", - "noSteps": "暂无步骤。请添加步骤说明应该发生什么。", - "webhookTokenTitle": "Webhook URL", - "webhookTokenDescription": "此信息仅显示一次。请立即保存,之后将无法调取。", + "moveUp": "上移", + "moveDown": "下移", + "noSteps": "暂无步骤。添加步骤以定义要执行的操作。", + "webhookTokenTitle": "Webhook 地址", + "webhookTokenDescription": "此内容仅显示一次,请立即保存,之后无法再次获取。", "copy": "复制", "copied": "已复制", "viewJson": "JSON", "viewBuilder": "构建器", - "viewGraph": "图形", + "viewGraph": "流程图", "lastRun": "上次运行", - "never": "绝不", - "duration": "{{seconds}}s", + "never": "从未", + "duration": "{{seconds}} 秒", "stepOutput": "输出", "stepError": "错误", "dryRunBadge": "测试运行", "hostSelector": { - "trigger": "触发主机", - "host": "特定主机", - "fleet": "舰队", + "trigger": "触发事件的主机", + "host": "指定主机", + "fleet": "主机组", "all": "所有主机" }, "triggerKinds": { "metric_threshold": "指标阈值", "host_status": "主机上线或离线", - "health_check": "健康检查变化", - "schedule": "按计划", + "health_check": "健康检查状态变化", + "schedule": "按计划运行", "docker_event": "容器事件", "internal_event": "Termix 事件", - "webhook": "传入的 webhook" + "webhook": "接收 Webhook" }, "stepTypes": { - "notify": "发送通知", - "http": "调用 URL", - "run_snippet": "运行一段代码片段", - "run_command": "运行命令", + "notify": "发送告警", + "http": "请求 URL", + "run_snippet": "执行代码片段", + "run_command": "执行命令", "docker": "控制容器", "tunnel": "控制隧道", "wol": "唤醒主机", "wait": "等待", "set_var": "设置变量", - "if": "如果/否则", + "if": "如果 / 否则", "run_automation": "运行另一个自动化程序", "stop": "停止" }, @@ -96,45 +112,55 @@ "running": "运行中", "success": "成功", "failed": "失败", - "timeout": "超时", - "skipped": "跳过", + "timeout": "已超时", + "skipped": "已跳过", "cancelled": "已取消" }, "fields": { "host": "主机", "metric": "指标", "mount": "挂载点", - "operator": "是", + "operator": "等于", "value": "值", - "forSeconds": "持续(秒)", + "forSeconds": "持续时间(秒)", "cooldown": "冷却时间(分钟)", "cron": "Cron 表达式", - "intervalSeconds": "每隔(秒)", + "intervalSeconds": "间隔(秒)", "timezone": "时区", "timezoneServer": "服务器时间", - "timezoneHint": "此区域读取 cron 任务的时间。不适用于间隔任务。", + "timezoneHint": "Cron 时间按此时区解释,不适用于按间隔运行的计划。", "container": "容器", "command": "命令", "url": "URL", - "method": "方法", + "method": "请求方法", "body": "请求体", - "channels": "频道", + "channels": "同时发送至", "title": "标题", "message": "消息", - "snippet": "片段", + "snippet": "代码片段", "seconds": "秒", "conditionLeftPlaceholder": "待检查的值", - "conditionRightPlaceholder": "与……比较", + "conditionRightPlaceholder": "比较目标值", "variableName": "变量名", "variableValue": "值", - "elevated": "使用 sudo 运行", - "onError": "如果失败", - "allowPrivateNetwork": "允许本地网络地址", - "allowPrivateNetworkHint": "在局域网内运行自托管服务时需要此功能。默认情况下处于关闭状态,以防止向内部地址发送请求。" + "elevated": "使用 sudo 执行", + "onError": "失败时", + "allowPrivateNetwork": "允许局域网地址", + "allowPrivateNetworkHint": "访问局域网内的自托管服务时需要开启。默认关闭,以防止请求内部地址。" }, "onError": { "stop": "停止运行", - "continue": "继续" + "continue": "继续执行" + }, + "needsPlugin": "需要 {{plugin}}", + "needsPluginHint": "在所需功能恢复可用之前,此自动化将被跳过。", + "offBadge": "关闭", + "docsLink": "查看文档", + "ago": { + "seconds": "{{count}} 秒前", + "minutes": "{{count}} 分钟前", + "hours": "{{count}} 小时前", + "days": "{{count}} 天前" } } } @@ -145,5 +171,55 @@ "onboarding": { "feature_automations": "自动化", "feature_automations_desc": "触发特定事件时自动执行任务,并接收通知。" + }, + "maintenance": { + "title": "维护中", + "description": "维护期间暂停由主机状态、健康检查、指标、容器和隧道断开事件触发的自动化。监控、手动执行和定时自动化继续运行。", + "denied": "你没有查看维护信息的权限。", + "sharedReadOnly": "此主机由他人共享给你,只有所有者才能修改维护设置。", + "failed": "无法更新维护设置。", + "active": "维护中", + "estimated": "预计完成时间", + "noAutoEnd": "预计时间不会自动结束维护,请在工作完成后手动结束。", + "endConfirm": "结束维护并恢复此主机的事件触发自动化?", + "confirmEnd": "确认结束", + "cancel": "取消", + "end": "结束维护", + "action": "操作", + "startNow": "立即开始", + "schedule": "安排稍后执行", + "reason": "原因", + "startUtc": "首次开始时间(UTC)", + "repeat": "重复", + "once": "仅一次", + "weekly": "每周", + "monthly": "每月", + "utcHelp": "计划全年使用 UTC。每月计划会跳过没有指定日期的月份。计划窗口不能重叠;超时未结束的维护会持续到后续窗口。", + "duration": "预计时长(分钟)", + "grace": "宽限期(分钟)", + "notify": "预计完成时间加宽限期后仍离线时,发送一次通知", + "addSchedule": "添加计划", + "schedules": "计划", + "noSchedules": "暂无维护计划。", + "completed": "已开始", + "minutes_one": "{{count}} 分钟", + "minutes_other": "{{count}} 分钟", + "remove": "移除计划", + "loadFailed": "无法刷新维护状态,在成功加载之前无法更改设置。", + "loading": "正在加载维护状态……" + }, + "ui": { + "sidebar": { + "automations": { + "options": { + "connect": "连接", + "disconnect": "断开连接", + "offline": "离线", + "online": "在线", + "failing": "故障", + "recovered": "已恢复" + } + } + } } } diff --git a/plugins/automations/locales/translated/zh_TW.json b/plugins/automations/locales/translated/zh_TW.json index 7bc08c3d7..3104650f6 100644 --- a/plugins/automations/locales/translated/zh_TW.json +++ b/plugins/automations/locales/translated/zh_TW.json @@ -1,149 +1,211 @@ { + "permissions": { + "view": { + "title": "View automations", + "description": "See the automations and their history." + }, + "create": { + "title": "Create automations", + "description": "Add new automations." + }, + "edit": { + "title": "Edit automations", + "description": "Change existing automations." + }, + "delete": { + "title": "Delete automations", + "description": "Remove automations." + }, + "run": { + "title": "Run automations", + "description": "Trigger an automation by hand." + } + }, "newUi": { "sidebar": { "automations": { - "title": "自動化", - "tabAutomations": "自動化", - "tabRuns": "跑", - "tabChannels": "頻道", - "createAutomation": "新自動化", - "backToAutomations": "返回自動化頁面", - "createTitle": "新自動化", - "editTitle": "編輯自動化", - "empty": "尚未設定任何自動化流程。請建立一個自動化流程,使其能夠根據指標、日程安排或事件做出反應。", - "emptyRuns": "目前還沒有人運行。", - "emptyChannels": "暫無頻道。新增一個頻道以便向某個地方發送通知。", - "noChannelsHint": "尚未設定任何頻道。請在「頻道」標籤中新增頻道。", - "addChannel": "新增頻道", - "testChannel": "測試", - "channelTestSent": "已發送測試通知", - "channelTestFailed": "測試通知失敗", - "channelDeleted": "頻道已刪除", - "deleteChannelConfirm": "刪除此頻道?使用該頻道的自動化功能將停止通知。", - "nameLabel": "姓名", - "namePlaceholder": "例如,當 /data 目錄填滿時進行清理。", - "nameRequired": "姓名(必填)", - "descriptionLabel": "描述", - "descriptionPlaceholder": "選用描述", + "title": "Automations", + "tabAutomations": "Automations", + "tabRuns": "Runs", + "tabChannels": "通道", + "createAutomation": "New Automation", + "backToAutomations": "Back to Automations", + "createTitle": "New Automation", + "editTitle": "Edit Automation", + "empty": "No automations yet. Create one to react to a metric, a schedule, or an event.", + "emptyRuns": "No runs yet.", + "channelsHint": "Channels are set up in Alerts", + "noChannelsHint": "The alert always goes to your inbox. Add channels in Alerts to also send it somewhere else.", + "nameLabel": "名稱", + "namePlaceholder": "e.g., Clean up /data when it fills", + "nameRequired": "名稱為必填", + "descriptionLabel": "說明", + "descriptionPlaceholder": "選用說明", "enabledLabel": "已啟用", - "concurrencyLabel": "如果它已經在運行", - "concurrencyHint": "如果在上次運行結束前再次觸發此問題,該怎麼辦?", + "concurrencyLabel": "If it is already running", + "concurrencyHint": "What to do when this is triggered again before the last run has finished.", "concurrency": { - "skip": "跳過新一輪", - "queue": "等待並追趕", - "allow": "同時運行這兩個程序" + "skip": "Skip the new run", + "queue": "Wait and run after", + "allow": "Run both at once" }, - "save": "節省", - "created": "自動化創建", - "updated": "自動化保存", - "deleted": "自動化刪除", - "deleteConfirm": "刪除此自動化流程?其運行歷史記錄也會被刪除。", - "runNow": "立即運行", - "testRun": "測試運行", - "testRunHint": "執行所有步驟,但不觸及 Termix 以外的任何內容。", - "runStarted": "運行已啟動", - "runFinished": "運轉結束: {{status}}", - "trigger": "扳機", - "steps": "步驟", - "addStep": "新增步驟", - "removeStep": "移除步驟", - "moveUp": "向上", - "moveDown": "向下", - "noSteps": "暫無步驟。請加入步驟說明應該發生什麼。", + "save": "儲存", + "created": "Automation created", + "updated": "Automation saved", + "deleted": "Automation deleted", + "deleteConfirm": "Delete this automation? Its run history is deleted too.", + "runNow": "Run now", + "testRun": "Test run", + "testRunHint": "Runs every step but does not touch anything outside Termix.", + "runStarted": "Run started", + "runFinished": "Run finished: {{status}}", + "trigger": "觸發條件", + "steps": "Steps", + "addStep": "Add step", + "removeStep": "Remove step", + "moveUp": "Move up", + "moveDown": "Move down", + "noSteps": "No steps yet. Add one to say what should happen.", "webhookTokenTitle": "Webhook URL", - "webhookTokenDescription": "此資訊僅顯示一次。請立即儲存,之後將無法調取。", + "webhookTokenDescription": "This is shown once. Save it now, it cannot be retrieved later.", "copy": "複製", "copied": "已複製", "viewJson": "JSON", - "viewBuilder": "建造者", - "viewGraph": "圖形", - "lastRun": "最後一次運行", - "never": "絕不", + "viewBuilder": "Builder", + "viewGraph": "Graph", + "lastRun": "Last run", + "never": "從未", "duration": "{{seconds}}s", "stepOutput": "輸出", "stepError": "錯誤", - "dryRunBadge": "測試運行", + "dryRunBadge": "Test run", "hostSelector": { - "trigger": "觸發主機", - "host": "特定主機", - "fleet": "艦隊", - "all": "所有主持人" + "trigger": "Triggering host", + "host": "Specific host", + "fleet": "Fleet", + "all": "所有主機" }, "triggerKinds": { - "metric_threshold": "指標閾值", - "host_status": "主機升溫或降溫", - "health_check": "健康檢查變化", - "schedule": "按計劃", - "docker_event": "容器事件", - "internal_event": "Termix 活動", - "webhook": "傳入的 webhook" + "metric_threshold": "Metric threshold", + "host_status": "Host goes up or down", + "health_check": "Health check changes", + "schedule": "On a schedule", + "docker_event": "Container event", + "internal_event": "Termix event", + "webhook": "Incoming webhook" }, "stepTypes": { - "notify": "發送通知", - "http": "呼叫 URL", - "run_snippet": "運行一段程式碼片段", - "run_command": "運行命令", - "docker": "控制容器", - "tunnel": "控制隧道", - "wol": "喚醒主機", - "wait": "等待", - "set_var": "設定變數", - "if": "如果/否則", - "run_automation": "執行另一個自動化流程", - "stop": "停止" + "notify": "Send an alert", + "http": "Call a URL", + "run_snippet": "Run a snippet", + "run_command": "Run a command", + "docker": "Control a container", + "tunnel": "Control a tunnel", + "wol": "Wake a host", + "wait": "Wait", + "set_var": "Set a variable", + "if": "If / otherwise", + "run_automation": "Run another automation", + "stop": "停止位元" }, "statuses": { - "running": "跑步", + "running": "執行中", "success": "成功", - "failed": "失敗的", - "timeout": "超時", - "skipped": "跳過", - "cancelled": "取消" + "failed": "失敗", + "timeout": "Timed out", + "skipped": "Skipped", + "cancelled": "Cancelled" }, "fields": { - "host": "主持人", + "host": "主機", "metric": "指標", - "mount": "登山點", - "operator": "是", - "value": "價值", - "forSeconds": "持續(秒)", + "mount": "Mount point", + "operator": "Is", + "value": "Value", + "forSeconds": "Sustained for (seconds)", "cooldown": "冷卻時間(分鐘)", - "cron": "複製表達式", - "intervalSeconds": "每隔(秒)", - "timezone": "時區", - "timezoneServer": "伺服器時間", - "timezoneHint": "此區域讀取 cron 任務的時間。不適用於間隔任務。", - "container": "容器", - "command": "命令", + "cron": "Cron expression", + "intervalSeconds": "Every (seconds)", + "timezone": "Time zone", + "timezoneServer": "Server time", + "timezoneHint": "Cron times are read in this zone. Does not apply to interval schedules.", + "container": "Container", + "command": "指令", "url": "URL", - "method": "方法", - "body": "身體", - "channels": "頻道", + "method": "Method", + "body": "Body", + "channels": "Also send to", "title": "標題", - "message": "訊息", - "snippet": "片段", - "seconds": "秒", - "conditionLeftPlaceholder": "待檢查的數值", - "conditionRightPlaceholder": "與…比較", - "variableName": "變數名", - "variableValue": "價值", - "elevated": "使用 sudo 運行", - "onError": "如果失敗", - "allowPrivateNetwork": "允許本地網路位址", - "allowPrivateNetworkHint": "在區域網路內執行自託管服務時需要此功能。預設為關閉狀態,以防止向內部位址發送請求。" + "message": "Message", + "snippet": "Snippet", + "seconds": "Seconds", + "conditionLeftPlaceholder": "Value to check", + "conditionRightPlaceholder": "Compare against", + "variableName": "Variable name", + "variableValue": "Value", + "elevated": "Run with sudo", + "onError": "If this fails", + "allowPrivateNetwork": "Allow local network addresses", + "allowPrivateNetworkHint": "Needed for a self-hosted service on your LAN. Off by default to prevent requests to internal addresses." }, "onError": { - "stop": "停止奔跑", - "continue": "繼續" + "stop": "Stop the run", + "continue": "Carry on" + }, + "needsPlugin": "Needs {{plugin}}", + "needsPluginHint": "This automation is skipped until the feature it needs is available again.", + "offBadge": "關閉", + "docsLink": "檢視文件", + "ago": { + "seconds": "{{count}}s ago", + "minutes": "{{count}} 分鐘前", + "hours": "{{count}} 小時前", + "days": "{{count}} 天前" } } } }, "nav": { - "automations": "自動化" + "automations": "Automations" }, "onboarding": { - "feature_automations": "自動化", - "feature_automations_desc": "當發生某些事情時,自動運行步驟並接收通知。" + "feature_automations": "Automations", + "feature_automations_desc": "Run steps automatically when something happens, and get notified." + }, + "maintenance": { + "title": "維護", + "description": "Pause host status, health, metric, container and tunnel-disconnection automations while work is in progress. Monitoring, manual runs and scheduled automations continue.", + "denied": "You do not have permission to view maintenance.", + "sharedReadOnly": "This host was shared with you. Only its owner can change maintenance.", + "failed": "Maintenance could not be updated.", + "active": "Maintenance active", + "estimated": "Estimated completion", + "noAutoEnd": "The estimate does not end maintenance. End it explicitly when the work is complete.", + "endConfirm": "End maintenance and resume event-triggered automations for this host?", + "confirmEnd": "Confirm end", + "cancel": "取消", + "end": "End maintenance", + "action": "動作", + "startNow": "Start now", + "schedule": "Schedule for later", + "reason": "Reason", + "startUtc": "First start (UTC)", + "repeat": "Repeat", + "once": "Once", + "weekly": "Weekly", + "monthly": "Monthly", + "utcHelp": "Schedules use UTC throughout the year. Monthly schedules skip months without the selected day. Planned windows cannot overlap; overrunning maintenance continues across later windows.", + "duration": "Estimated duration (minutes)", + "grace": "Grace period (minutes)", + "notify": "Notify once if still offline after the estimate plus grace period", + "addSchedule": "Add schedule", + "schedules": "Schedules", + "noSchedules": "No maintenance schedules.", + "completed": "Already started", + "minutes_one": "{{count}} minute", + "minutes_other": "{{count}} minutes", + "remove": "Remove schedule", + "loadFailed": "Could not refresh maintenance status. Changes are disabled until it can be loaded.", + "loading": "Loading maintenance status…" } } diff --git a/plugins/automations/manifest.json b/plugins/automations/manifest.json index ba149255f..0da548831 100644 --- a/plugins/automations/manifest.json +++ b/plugins/automations/manifest.json @@ -17,6 +17,7 @@ "capabilities": [ "hosts:read", "credentials:use", + "credentials:read", "ssh:connect", "db:own", "events:core", diff --git a/plugins/automations/src/backend/repository.ts b/plugins/automations/src/backend/repository.ts index 5592a8b94..d200e6dc5 100644 --- a/plugins/automations/src/backend/repository.ts +++ b/plugins/automations/src/backend/repository.ts @@ -528,7 +528,7 @@ export async function createAutomationRepository( .set({ lastRunAt: run[0].startedAt, lastRunStatus: input.status }) .where(eq(automations.id, run[0].automationId)); } - await db.persist(); + await db.persist({ lazy: true }); }, async listRuns( @@ -630,7 +630,7 @@ export async function createAutomationRepository( .where(lt(runs.startedAt, cutoff)); if (old.length === 0) return 0; await drizzle.delete(runs).where(lt(runs.startedAt, cutoff)); - await db.persist(); + await db.persist({ lazy: true }); return old.length; }, diff --git a/plugins/automations/src/frontend/automations/StepBlock.tsx b/plugins/automations/src/frontend/automations/StepBlock.tsx index 1927052c3..653b7a51a 100644 --- a/plugins/automations/src/frontend/automations/StepBlock.tsx +++ b/plugins/automations/src/frontend/automations/StepBlock.tsx @@ -368,8 +368,12 @@ export function StepBlock({ - connect - disconnect + + {t("ui.sidebar.automations.options.connect")} + + + {t("ui.sidebar.automations.options.disconnect")} + {trigger.kind === "host_status" ? ( <> - offline - online + + {t("ui.sidebar.automations.options.offline")} + + + {t("ui.sidebar.automations.options.online")} + ) : ( <> - failing - recovered + + {t("ui.sidebar.automations.options.failing")} + + + {t("ui.sidebar.automations.options.recovered")} + )} diff --git a/plugins/automations/tests/backend/sudo-capability.test.ts b/plugins/automations/tests/backend/sudo-capability.test.ts new file mode 100644 index 000000000..ab3f3d7a1 --- /dev/null +++ b/plugins/automations/tests/backend/sudo-capability.test.ts @@ -0,0 +1,17 @@ +import { describe, expect, it } from "vitest"; +import fs from "node:fs"; +import path from "node:path"; + +// Elevated commands read the host's sudo password, which core only hands to +// a plugin holding credentials:read. +describe("sudo password access", () => { + it("declares credentials:read", () => { + const manifest = JSON.parse( + fs.readFileSync( + path.resolve(import.meta.dirname, "../../manifest.json"), + "utf8", + ), + ); + expect(manifest.capabilities).toContain("credentials:read"); + }); +}); diff --git a/plugins/docker/locales/translated/af_ZA.json b/plugins/docker/locales/translated/af_ZA.json index a0b91cfff..5f4ba7276 100644 --- a/plugins/docker/locales/translated/af_ZA.json +++ b/plugins/docker/locales/translated/af_ZA.json @@ -21,6 +21,11 @@ "ports": "Hawens", "noPorts": "Geen poorte nie", "start": "Begin", + "stop": "Stop", + "status": "Status", + "actions": "Aksies", + "cardView": "Kaartaansig", + "listView": "Lysaansig", "confirmRemoveContainer": "Is jy seker jy wil die houer '{{name}}' verwyder? Hierdie aksie kan nie ongedaan gemaak word nie.", "runningContainerWarning": "Waarskuwing: Hierdie houer loop tans. As dit verwyder word, sal die houer eers gestop word.", "loadingContainers": "Laai houers...", @@ -73,6 +78,7 @@ "containerMustBeRunning": "Die houer moet loop om toegang tot die konsole te verkry", "verificationCodePrompt": "Voer verifikasiekode in", "totpVerificationFailed": "TOTP-verifikasie het misluk. Probeer asseblief weer.", + "browserSignInFailed": "Aanmelding het misluk. Probeer asseblief weer.", "connectedTo": "Gekoppel aan {{containerName}}", "disconnected": "Ontkoppel", "consoleError": "Konsolefout", @@ -93,7 +99,10 @@ "logs": "Logboeke", "stats": "Statistiek", "consoleTab": "Konsole", - "startContainerToAccess": "Begin die houer om toegang tot die konsole te verkry" + "startContainerToAccess": "Begin die houer om toegang tot die konsole te verkry", + "noHostSelected": "Geen gasheer gekies nie", + "failedToFetchLogs": "Kon nie logboeke haal nie: {{error}}", + "failedToDownloadLogs": "Kon nie logboeke aflaai nie: {{error}}" }, "nav": { "docker": "Docker" @@ -102,10 +111,22 @@ "feature_docker": "Docker", "feature_docker_desc": "Sien houers, lees logs en kyk na statistieke op enige gasheer wat Docker gebruik." }, + "terminal": { + "retry": "Probeer weer", + "clipboardReadFailed": "Kon nie vanaf knipbord lees nie. Maak seker dat knipbordtoestemmings toegestaan is.", + "clipboardWriteFailed": "Kon nie na knipbord kopieer nie. Maak seker dat die bladsy oor HTTPS of localhost bedien word." + }, + "permissions": { + "use": { + "title": "Gebruik Docker", + "description": "Maak die Docker-bestuurder en houerkonsoles op gashere oop met Docker geaktiveer." + } + }, "settings": { "host": { "enable": { - "label": "Aktiveer Docker" + "label": "Aktiveer Docker", + "description": "Bestuur houers op hierdie gasheer." }, "containerRuntime": { "label": "Houerlooptyd", @@ -122,9 +143,5 @@ "docsLink": "Bekyk dokumente", "hostNotFound": "Gasheer nie gevind nie", "loadingHost": "Laai gasheer..." - }, - "terminal": { - "clipboardReadFailed": "Kon nie vanaf knipbord lees nie. Maak seker dat knipbordtoestemmings toegestaan is.", - "clipboardWriteFailed": "Kon nie na knipbord kopieer nie. Maak seker dat die bladsy oor HTTPS of localhost bedien word." } } diff --git a/plugins/docker/locales/translated/ar_SA.json b/plugins/docker/locales/translated/ar_SA.json index aee542733..35909373c 100644 --- a/plugins/docker/locales/translated/ar_SA.json +++ b/plugins/docker/locales/translated/ar_SA.json @@ -21,6 +21,11 @@ "ports": "منافذ", "noPorts": "لا توجد منافذ", "start": "ابدأ", + "stop": "التوقف", + "status": "الحالة", + "actions": "الإجراءات", + "cardView": "عرض البطاقة", + "listView": "عرض القائمة", "confirmRemoveContainer": "هل أنت متأكد من رغبتك في إزالة الحاوية '{{name}}'؟ لا يمكن التراجع عن هذا الإجراء.", "runningContainerWarning": "تحذير: هذه الحاوية قيد التشغيل حالياً. ستؤدي إزالتها إلى إيقافها أولاً.", "loadingContainers": "جارٍ تحميل الحاويات...", @@ -73,6 +78,7 @@ "containerMustBeRunning": "يجب أن تكون الحاوية قيد التشغيل للوصول إلى وحدة التحكم", "verificationCodePrompt": "أدخل رمز التحقق", "totpVerificationFailed": "فشل التحقق من TOTP. يرجى المحاولة مرة أخرى.", + "browserSignInFailed": "فشل تسجيل الدخول. يرجى المحاولة مرة أخرى.", "connectedTo": "متصل بـ {{containerName}}", "disconnected": "تم قطع الاتصال", "consoleError": "خطأ في وحدة التحكم", @@ -93,19 +99,34 @@ "logs": "السجلات", "stats": "الإحصائيات", "consoleTab": "وحدة التحكم", - "startContainerToAccess": "ابدأ تشغيل الحاوية للوصول إلى وحدة التحكم" + "startContainerToAccess": "ابدأ تشغيل الحاوية للوصول إلى وحدة التحكم", + "noHostSelected": "لم يتم تحديد أي جهاز مضيف", + "failedToFetchLogs": "فشل في جلب السجلات: {{error}}", + "failedToDownloadLogs": "فشل تنزيل السجلات: {{error}}" }, "nav": { "docker": "Docker" }, "onboarding": { - "feature_docker": "عامل ميناء", + "feature_docker": "Docker", "feature_docker_desc": "اطلع على الحاويات، واقرأ السجلات، وراقب الإحصائيات على أي مضيف يعمل بنظام Docker." }, + "terminal": { + "retry": "إعادة المحاولة", + "clipboardReadFailed": "فشلت القراءة من الحافظة. تأكد من منح أذونات الحافظة.", + "clipboardWriteFailed": "فشل النسخ إلى الحافظة. تأكد من تقديم الصفحة عبر HTTPS أو localhost." + }, + "permissions": { + "use": { + "title": "استخدم Docker", + "description": "افتح مدير Docker ووحدات تحكم الحاويات على المضيفين الذين تم تمكين Docker عليهم." + } + }, "settings": { "host": { "enable": { - "label": "تمكين Docker" + "label": "تفعيل Docker", + "description": "إدارة الحاويات على هذا المضيف." }, "containerRuntime": { "label": "بيئة تشغيل الحاويات", @@ -122,9 +143,5 @@ "docsLink": "عرض المستندات", "hostNotFound": "المضيف غير موجود", "loadingHost": "جارٍ تحميل المضيف..." - }, - "terminal": { - "clipboardReadFailed": "فشلت القراءة من الحافظة. تأكد من منح أذونات الحافظة.", - "clipboardWriteFailed": "فشل النسخ إلى الحافظة. تأكد من تقديم الصفحة عبر HTTPS أو localhost." } } diff --git a/plugins/docker/locales/translated/bg_BG.json b/plugins/docker/locales/translated/bg_BG.json index 9343d324f..b750a504d 100644 --- a/plugins/docker/locales/translated/bg_BG.json +++ b/plugins/docker/locales/translated/bg_BG.json @@ -21,6 +21,11 @@ "ports": "Портове", "noPorts": "Няма портове", "start": "Старт", + "stop": "Спри", + "status": "Статус", + "actions": "Действия", + "cardView": "Изглед на картата", + "listView": "Списъчен изглед", "confirmRemoveContainer": "Сигурни ли сте, че искате да премахнете контейнера „{{name}}“? Това действие не може да бъде отменено.", "runningContainerWarning": "Предупреждение: Този контейнер в момента работи. Премахването му първо ще спре контейнера.", "loadingContainers": "Зареждане на контейнери...", @@ -73,6 +78,7 @@ "containerMustBeRunning": "Контейнерът трябва да е работещ, за да има достъп до конзолата", "verificationCodePrompt": "Въведете код за потвърждение", "totpVerificationFailed": "Проверката на TOTP не бе успешна. Моля, опитайте отново.", + "browserSignInFailed": "Влизането не бе успешно. Моля, опитайте отново.", "connectedTo": "Свързано с {{containerName}}", "disconnected": "Изключен", "consoleError": "Грешка в конзолата", @@ -93,7 +99,10 @@ "logs": "Дневници", "stats": "Статистика", "consoleTab": "Конзола", - "startContainerToAccess": "Стартирайте контейнера, за да получите достъп до конзолата" + "startContainerToAccess": "Стартирайте контейнера, за да получите достъп до конзолата", + "noHostSelected": "Няма избран хост", + "failedToFetchLogs": "Неуспешно извличане на лог файлове: {{error}}", + "failedToDownloadLogs": "Неуспешно изтегляне на лог файлове: {{error}}" }, "nav": { "docker": "Докер" @@ -102,10 +111,22 @@ "feature_docker": "Докер", "feature_docker_desc": "Вижте контейнери, прочетете лог файлове и наблюдавайте статистики на всеки хост, на който работи Docker." }, + "terminal": { + "retry": "Опитай отново", + "clipboardReadFailed": "Четенето от клипборда не бе успешно. Уверете се, че са предоставени разрешения за достъп до клипборда.", + "clipboardWriteFailed": "Копирането в клипборда не бе успешно. Уверете се, че страницата се предоставя през HTTPS или localhost." + }, + "permissions": { + "use": { + "title": "Използвайте Докер", + "description": "Отворете Docker manager-а и конзолите за контейнери на хостове с активиран Docker." + } + }, "settings": { "host": { "enable": { - "label": "Активиране на Докер" + "label": "Активиране на Докер", + "description": "Управлявайте контейнери на този хост." }, "containerRuntime": { "label": "Изпълнение на контейнера", @@ -122,9 +143,5 @@ "docsLink": "Преглед на документи", "hostNotFound": "Хостът не е намерен", "loadingHost": "Зареждане на хоста..." - }, - "terminal": { - "clipboardReadFailed": "Четенето от клипборда не бе успешно. Уверете се, че са предоставени разрешения за достъп до клипборда.", - "clipboardWriteFailed": "Копирането в буфера не бе успешно. Уверете се, че страницата се предоставя през HTTPS или localhost." } } diff --git a/plugins/docker/locales/translated/bn_BD.json b/plugins/docker/locales/translated/bn_BD.json index ccf797258..631c3a919 100644 --- a/plugins/docker/locales/translated/bn_BD.json +++ b/plugins/docker/locales/translated/bn_BD.json @@ -1,130 +1,147 @@ { "docker": { - "notEnabled": "এই হোস্টের জন্য ডকার সক্রিয় করা নেই।", - "validating": "ডকার যাচাই করা হচ্ছে...", - "connecting": "সংযোগ স্থাপন...", - "error": "ত্রুটি", + "notEnabled": "Docker is not enabled for this host", + "validating": "Validating Docker...", + "connecting": "Connecting...", + "error": "Error", "version": "{{runtime}} {{version}}", - "connectionFailed": "ডকারের সাথে সংযোগ করতে ব্যর্থ হয়েছে", - "containerStarted": "কন্টেইনার {{name}} চালু হয়েছে", - "failedToStartContainer": "{{name}} কন্টেইনারটি শুরু করতে ব্যর্থ হয়েছে", - "containerStopped": "কন্টেইনার {{name}} থেমে গেছে", - "failedToStopContainer": "কন্টেইনার বন্ধ করতে ব্যর্থ {{name}}", - "containerRestarted": "কন্টেইনার {{name}} পুনরায় চালু হয়েছে", - "failedToRestartContainer": "কন্টেইনার পুনরায় চালু করতে ব্যর্থ {{name}}", - "containerPaused": "কন্টেইনার {{name}} থামানো হয়েছে", - "containerUnpaused": "কন্টেইনার {{name}} বিরতিহীন", - "failedToTogglePauseContainer": "কন্টেইনার {{name}} এর জন্য বিরতি অবস্থা টগল করতে ব্যর্থ হয়েছে", - "containerRemoved": "কন্টেইনার {{name}} সরানো হয়েছে", - "failedToRemoveContainer": "কন্টেইনার অপসারণ করা সম্ভব হয়নি {{name}}", - "image": "ছবি", - "ports": "বন্দর", - "noPorts": "কোন পোর্ট নেই", - "start": "শুরু করুন", - "confirmRemoveContainer": "আপনি কি '{{name}}' কন্টেইনারটি সরাতে নিশ্চিত? এই কাজটি পূর্বাবস্থায় ফেরানো যাবে না।", - "runningContainerWarning": "সতর্কীকরণ: এই কন্টেইনারটি বর্তমানে চালু আছে। এটি অপসারণ করলে প্রথমে কন্টেইনারটি বন্ধ হবে।", - "loadingContainers": "কন্টেইনার লোড করা হচ্ছে...", - "manager": "ডকার ম্যানেজার", - "autoRefresh": "স্বয়ংক্রিয় রিফ্রেশ", - "timestamps": "টাইমস্ট্যাম্প", - "lines": "লাইন", - "filterLogs": "লগ ফিল্টার করুন...", - "refresh": "রিফ্রেশ", - "download": "ডাউনলোড করুন", - "clear": "পরিষ্কার", - "logsDownloaded": "লগগুলি সফলভাবে ডাউনলোড করা হয়েছে।", - "last50": "শেষ ৫০", - "last100": "শেষ ১০০", - "last500": "শেষ ৫০০", - "last1000": "শেষ ১০০০", - "allLogs": "সমস্ত লগ", - "noLogsMatching": "\"{{query}} \" এর সাথে মেলে এমন কোনও লগ নেই", - "noLogsAvailable": "কোন লগ উপলব্ধ নেই", - "noContainersFound": "কোন কন্টেইনার পাওয়া যায়নি", - "noContainersFoundHint": "এই হোস্টে কোনো ডকার কন্টেইনার উপলব্ধ নেই।", - "searchPlaceholder": "কন্টেইনারগুলি অনুসন্ধান করুন...", - "allStatuses": "সমস্ত স্ট্যাটাস", - "stateRunning": "দৌড়ানো", - "statePaused": "বিরতি দেওয়া হয়েছে", - "stateExited": "উত্তেজিত", - "stateRestarting": "পুনরায় চালু করা", - "noContainersMatchFilters": "আপনার ফিল্টারগুলির সাথে কোনও কন্টেইনার মেলে না", - "noContainersMatchFiltersHint": "আপনার অনুসন্ধান বা ফিল্টারের শর্তাবলী পরিবর্তন করে দেখুন।", - "failedToFetchStats": "কন্টেইনার পরিসংখ্যান আনতে ব্যর্থ হয়েছে", - "containerNotRunning": "কন্টেইনারটি চলছে না", - "startContainerToViewStats": "পরিসংখ্যান দেখতে কন্টেইনারটি চালু করুন।", - "loadingStats": "পরিসংখ্যান লোড হচ্ছে...", - "errorLoadingStats": "পরিসংখ্যান লোড করতে ত্রুটি", - "noStatsAvailable": "কোন পরিসংখ্যান উপলব্ধ নেই", - "cpuUsage": "সিপিইউ ব্যবহার", - "current": "বর্তমান", - "memoryUsage": "মেমরি ব্যবহার", - "networkIo": "নেটওয়ার্ক আই/ও", - "input": "ইনপুট", - "output": "আউটপুট", - "blockIo": "ব্লক আই/ও", - "read": "পড়ুন", - "write": "লিখুন", - "pids": "পিআইডি", - "containerInformation": "কন্টেইনারের তথ্য", - "name": "নাম", - "id": "আইডি", - "state": "রাজ্য", - "containerMustBeRunning": "কনসোল অ্যাক্সেস করতে হলে কন্টেইনারটি অবশ্যই চালু থাকতে হবে।", - "verificationCodePrompt": "যাচাইকরণ কোড প্রবেশ করান", - "totpVerificationFailed": "TOTP যাচাইকরণ ব্যর্থ হয়েছে। অনুগ্রহ করে আবার চেষ্টা করুন।", - "connectedTo": "{{containerName}} এর সাথে সংযুক্ত", - "disconnected": "বিচ্ছিন্ন", - "consoleError": "কনসোল ত্রুটি", - "errorMessage": "ত্রুটি: {{message}}", - "failedToConnect": "কন্টেইনারের সাথে সংযোগ করতে ব্যর্থ হয়েছে", - "console": "কনসোল", - "selectShell": "শেল নির্বাচন করুন", - "bash": "ব্যাশ", - "sh": "শ", - "ash": "ছাই", - "connect": "সংযোগ করুন", - "disconnect": "সংযোগ বিচ্ছিন্ন করুন", - "notConnected": "সংযুক্ত নয়", - "clickToConnect": "শেল সেশন শুরু করতে কানেক্ট-এ ক্লিক করুন।", - "connectingTo": "{{containerName}} এর সাথে সংযোগ স্থাপন করা হচ্ছে...", - "containerNotFound": "কন্টেইনারটি খুঁজে পাওয়া যায়নি", - "backToList": "তালিকায় ফিরে যান", - "logs": "লগ", - "stats": "পরিসংখ্যান", - "consoleTab": "কনসোল", - "startContainerToAccess": "কনসোল অ্যাক্সেস করতে কন্টেইনারটি চালু করুন।" + "connectionFailed": "Failed to connect to Docker", + "containerStarted": "Container {{name}} started", + "failedToStartContainer": "Failed to start container {{name}}", + "containerStopped": "Container {{name}} stopped", + "failedToStopContainer": "Failed to stop container {{name}}", + "containerRestarted": "Container {{name}} restarted", + "failedToRestartContainer": "Failed to restart container {{name}}", + "containerPaused": "Container {{name}} paused", + "containerUnpaused": "Container {{name}} unpaused", + "failedToTogglePauseContainer": "Failed to toggle pause state for container {{name}}", + "containerRemoved": "Container {{name}} removed", + "failedToRemoveContainer": "Failed to remove container {{name}}", + "image": "Image", + "ports": "Ports", + "noPorts": "No ports", + "start": "Start", + "stop": "Stop", + "status": "Status", + "actions": "Actions", + "cardView": "Card view", + "listView": "List view", + "confirmRemoveContainer": "Are you sure you want to remove the container '{{name}}'? This action cannot be undone.", + "runningContainerWarning": "Warning: This container is currently running. Removing it will stop the container first.", + "loadingContainers": "Loading containers...", + "manager": "Docker Manager", + "autoRefresh": "Auto Refresh", + "timestamps": "Timestamps", + "lines": "Lines", + "filterLogs": "Filter logs...", + "refresh": "Refresh", + "download": "Download", + "clear": "Clear", + "logsDownloaded": "Logs downloaded successfully", + "last50": "Last 50", + "last100": "Last 100", + "last500": "Last 500", + "last1000": "Last 1000", + "allLogs": "All Logs", + "noLogsMatching": "No logs matching \"{{query}}\"", + "noLogsAvailable": "No logs available", + "noContainersFound": "No containers found", + "noContainersFoundHint": "No Docker containers are available on this host", + "searchPlaceholder": "Search containers...", + "allStatuses": "All Statuses", + "stateRunning": "Running", + "statePaused": "Paused", + "stateExited": "Exited", + "stateRestarting": "Restarting", + "noContainersMatchFilters": "No containers match your filters", + "noContainersMatchFiltersHint": "Try adjusting your search or filter criteria", + "failedToFetchStats": "Failed to fetch container statistics", + "containerNotRunning": "Container not running", + "startContainerToViewStats": "Start the container to view statistics", + "loadingStats": "Loading statistics...", + "errorLoadingStats": "Error loading statistics", + "noStatsAvailable": "No statistics available", + "cpuUsage": "CPU Usage", + "current": "Current", + "memoryUsage": "Memory Usage", + "networkIo": "Network I/O", + "input": "Input", + "output": "Output", + "blockIo": "Block I/O", + "read": "Read", + "write": "Write", + "pids": "PIDs", + "containerInformation": "Container Information", + "name": "Name", + "id": "ID", + "state": "State", + "containerMustBeRunning": "Container must be running to access console", + "verificationCodePrompt": "Enter verification code", + "totpVerificationFailed": "TOTP verification failed. Please try again.", + "browserSignInFailed": "Sign-in failed. Please try again.", + "connectedTo": "Connected to {{containerName}}", + "disconnected": "Disconnected", + "consoleError": "Console error", + "errorMessage": "Error: {{message}}", + "failedToConnect": "Failed to connect to container", + "console": "Console", + "selectShell": "Select shell", + "bash": "Bash", + "sh": "sh", + "ash": "ash", + "connect": "Connect", + "disconnect": "Disconnect", + "notConnected": "Not connected", + "clickToConnect": "Click connect to start a shell session", + "connectingTo": "Connecting to {{containerName}}...", + "containerNotFound": "Container not found", + "backToList": "Back to List", + "logs": "Logs", + "stats": "Stats", + "consoleTab": "Console", + "startContainerToAccess": "Start the container to access the console", + "noHostSelected": "No host selected", + "failedToFetchLogs": "Failed to fetch logs: {{error}}", + "failedToDownloadLogs": "Failed to download logs: {{error}}" }, "nav": { - "docker": "ডকার" + "docker": "Docker" }, "onboarding": { - "feature_docker": "ডকার", - "feature_docker_desc": "ডকার চালিত যেকোনো হোস্টে কন্টেইনার দেখুন, লগ পড়ুন এবং পরিসংখ্যান পর্যবেক্ষণ করুন।" + "feature_docker": "Docker", + "feature_docker_desc": "See containers, read logs and watch stats on any host running Docker." + }, + "terminal": { + "retry": "Retry", + "clipboardReadFailed": "Failed to read from clipboard. Make sure clipboard permissions are granted.", + "clipboardWriteFailed": "Failed to copy to clipboard. Make sure the page is served over HTTPS or localhost." + }, + "permissions": { + "use": { + "title": "Use Docker", + "description": "Open the Docker manager and container consoles on hosts with Docker enabled." + } }, "settings": { "host": { "enable": { - "label": "ডকার সক্রিয় করুন" + "label": "Enable Docker", + "description": "Manage containers on this host." }, "containerRuntime": { - "label": "কন্টেইনার রানটাইম", - "description": "এই হোস্টে কন্টেইনার ব্যবস্থাপনার জন্য ব্যবহৃত CLI নির্বাচন করুন", - "docker": "ডকার", - "podman": "পডম্যান" + "label": "Container Runtime", + "description": "Choose the CLI used for container management on this host", + "docker": "Docker", + "podman": "Podman" } } }, "errors": { - "remoteServerRequired": "রিমোট সার্ভার প্রয়োজন। এই সংযোগের ধরণটি ব্যবহার করতে সেটিংস-এ একটি রিমোট সার্ভার সংযুক্ত করুন।" + "remoteServerRequired": "Remote server required. Connect a remote server in Settings to use this connection type." }, "hosts": { - "docsLink": "নথি দেখুন", - "hostNotFound": "হোস্ট খুঁজে পাওয়া যায়নি", - "loadingHost": "হোস্ট লোড হচ্ছে..." - }, - "terminal": { - "clipboardReadFailed": "ক্লিপবোর্ড থেকে পড়তে ব্যর্থ হয়েছে। নিশ্চিত করুন যে ক্লিপবোর্ডের অনুমতি দেওয়া আছে।", - "clipboardWriteFailed": "ক্লিপবোর্ডে কপি করা সম্ভব হয়নি। নিশ্চিত করুন যে পৃষ্ঠাটি HTTPS বা লোকালহোস্টের মাধ্যমে পরিবেশিত হচ্ছে।" + "docsLink": "View docs", + "hostNotFound": "Host not found", + "loadingHost": "Loading host..." } } diff --git a/plugins/docker/locales/translated/ca_ES.json b/plugins/docker/locales/translated/ca_ES.json index e22d5cbe3..752b52f75 100644 --- a/plugins/docker/locales/translated/ca_ES.json +++ b/plugins/docker/locales/translated/ca_ES.json @@ -21,6 +21,11 @@ "ports": "Ports", "noPorts": "Sense ports", "start": "Inici", + "stop": "Atura", + "status": "Estat", + "actions": "Accions", + "cardView": "Vista de targeta", + "listView": "Vista de llista", "confirmRemoveContainer": "Esteu segur que voleu eliminar el contenidor '{{name}}'? Aquesta acció no es pot desfer.", "runningContainerWarning": "Avís: Aquest contenidor està en execució. Si el suprimiu, primer s'aturarà el contenidor.", "loadingContainers": "Carregant contenidors...", @@ -36,7 +41,7 @@ "last50": "Últims 50", "last100": "Últims 100", "last500": "Últims 500", - "last1000": "Els últims 1000", + "last1000": "Últims 1000", "allLogs": "Tots els registres", "noLogsMatching": "No hi ha registres que coincideixin amb \"{{query}}\"", "noLogsAvailable": "No hi ha registres disponibles", @@ -65,7 +70,7 @@ "blockIo": "Bloc d'E/S", "read": "Llegir", "write": "Escriure", - "pids": "PIDs", + "pids": "PID", "containerInformation": "Informació del contenidor", "name": "Nom", "id": "ID", @@ -73,6 +78,7 @@ "containerMustBeRunning": "El contenidor ha d'estar en execució per accedir a la consola.", "verificationCodePrompt": "Introduïu el codi de verificació", "totpVerificationFailed": "La verificació TOTP ha fallat. Torna-ho a provar.", + "browserSignInFailed": "L'inici de sessió ha fallat. Torna-ho a provar.", "connectedTo": "Connectat a {{containerName}}", "disconnected": "Desconnectat", "consoleError": "Error de consola", @@ -93,7 +99,10 @@ "logs": "Registres", "stats": "Estadístiques", "consoleTab": "Consola", - "startContainerToAccess": "Inicieu el contenidor per accedir a la consola" + "startContainerToAccess": "Inicieu el contenidor per accedir a la consola", + "noHostSelected": "No s'ha seleccionat cap amfitrió", + "failedToFetchLogs": "No s'han pogut obtenir els registres: {{error}}", + "failedToDownloadLogs": "No s'han pogut descarregar els registres: {{error}}" }, "nav": { "docker": "Docker" @@ -102,10 +111,22 @@ "feature_docker": "Docker", "feature_docker_desc": "Veure contenidors, llegir registres i observar estadístiques de qualsevol host que executi Docker." }, + "terminal": { + "retry": "Torna-ho a intentar", + "clipboardReadFailed": "No s'ha pogut llegir del porta-retalls. Assegureu-vos que els permisos del porta-retalls estiguin concedits.", + "clipboardWriteFailed": "No s'ha pogut copiar al porta-retalls. Assegureu-vos que la pàgina es serveix per HTTPS o localhost." + }, + "permissions": { + "use": { + "title": "Utilitza Docker", + "description": "Obriu el gestor de Docker i les consoles de contenidors als hosts amb Docker habilitat." + } + }, "settings": { "host": { "enable": { - "label": "Activa Docker" + "label": "Activa Docker", + "description": "Gestiona els contenidors en aquest amfitrió." }, "containerRuntime": { "label": "Temps d'execució del contenidor", @@ -122,9 +143,5 @@ "docsLink": "Veure documents", "hostNotFound": "No s'ha trobat l'amfitrió", "loadingHost": "S'està carregant l'amfitrió..." - }, - "terminal": { - "clipboardReadFailed": "No s'ha pogut llegir del porta-retalls. Assegureu-vos que els permisos del porta-retalls estiguin concedits.", - "clipboardWriteFailed": "No s'ha pogut copiar al porta-retalls. Assegureu-vos que la pàgina es serveix per HTTPS o localhost." } } diff --git a/plugins/docker/locales/translated/cs_CZ.json b/plugins/docker/locales/translated/cs_CZ.json index cd07beb1e..04a289181 100644 --- a/plugins/docker/locales/translated/cs_CZ.json +++ b/plugins/docker/locales/translated/cs_CZ.json @@ -21,6 +21,11 @@ "ports": "Porty", "noPorts": "Žádné porty", "start": "Start", + "stop": "Zastávka", + "status": "Postavení", + "actions": "Akce", + "cardView": "Zobrazení karty", + "listView": "Seznam", "confirmRemoveContainer": "Opravdu chcete odstranit kontejner '{{name}}'? Tuto akci nelze vrátit zpět.", "runningContainerWarning": "Varování: Tento kontejner je aktuálně spuštěný. Jeho odstraněním se nejprve zastaví.", "loadingContainers": "Nakládání kontejnerů...", @@ -73,6 +78,7 @@ "containerMustBeRunning": "Pro přístup ke konzoli musí být kontejner spuštěný.", "verificationCodePrompt": "Zadejte ověřovací kód", "totpVerificationFailed": "Ověření TOTP se nezdařilo. Zkuste to prosím znovu.", + "browserSignInFailed": "Přihlášení se nezdařilo. Zkuste to prosím znovu.", "connectedTo": "Připojeno k {{containerName}}", "disconnected": "Odpojeno", "consoleError": "Chyba konzole", @@ -93,7 +99,10 @@ "logs": "Protokoly", "stats": "Statistiky", "consoleTab": "Utěšit", - "startContainerToAccess": "Spusťte kontejner pro přístup ke konzoli" + "startContainerToAccess": "Spusťte kontejner pro přístup ke konzoli", + "noHostSelected": "Nebyl vybrán žádný hostitel", + "failedToFetchLogs": "Nepodařilo se načíst protokoly: {{error}}", + "failedToDownloadLogs": "Stažení protokolů se nezdařilo: {{error}}" }, "nav": { "docker": "Přístavní dělník" @@ -102,10 +111,22 @@ "feature_docker": "Přístavní dělník", "feature_docker_desc": "Zobrazujte kontejnery, čtěte protokoly a sledujte statistiky na jakémkoli hostiteli s Dockerem." }, + "terminal": { + "retry": "Zkusit znovu", + "clipboardReadFailed": "Čtení ze schránky se nezdařilo. Ujistěte se, že máte povolena přístup ke schránce.", + "clipboardWriteFailed": "Kopírování do schránky se nezdařilo. Ujistěte se, že stránka je zobrazována přes HTTPS nebo localhost." + }, + "permissions": { + "use": { + "title": "Použijte Docker", + "description": "Otevřete správce Dockeru a konzole kontejnerů na hostitelích s povoleným Dockerem." + } + }, "settings": { "host": { "enable": { - "label": "Povolit Docker" + "label": "Povolit Docker", + "description": "Spravovat kontejnery na tomto hostiteli." }, "containerRuntime": { "label": "Běh kontejneru", @@ -122,9 +143,5 @@ "docsLink": "Zobrazit dokumenty", "hostNotFound": "Hostitel nenalezen", "loadingHost": "Načítání hostitele..." - }, - "terminal": { - "clipboardReadFailed": "Čtení ze schránky se nezdařilo. Ujistěte se, že máte povolena přístup ke schránce.", - "clipboardWriteFailed": "Kopírování do schránky se nezdařilo. Ujistěte se, že stránka je zobrazována přes HTTPS nebo localhost." } } diff --git a/plugins/docker/locales/translated/da_DK.json b/plugins/docker/locales/translated/da_DK.json index 2477a6b8c..b2179fddb 100644 --- a/plugins/docker/locales/translated/da_DK.json +++ b/plugins/docker/locales/translated/da_DK.json @@ -21,6 +21,11 @@ "ports": "Havne", "noPorts": "Ingen porte", "start": "Starte", + "stop": "Stop", + "status": "Status", + "actions": "Handlinger", + "cardView": "Kortvisning", + "listView": "Listevisning", "confirmRemoveContainer": "Er du sikker på, at du vil fjerne containeren '{{name}}'? Denne handling kan ikke fortrydes.", "runningContainerWarning": "Advarsel: Denne container kører i øjeblikket. Fjernelse af den vil stoppe containeren først.", "loadingContainers": "Indlæser containere...", @@ -73,6 +78,7 @@ "containerMustBeRunning": "Containeren skal køre for at få adgang til konsollen", "verificationCodePrompt": "Indtast bekræftelseskode", "totpVerificationFailed": "TOTP-bekræftelse mislykkedes. Prøv igen.", + "browserSignInFailed": "Log ind mislykkedes. Prøv igen.", "connectedTo": "Forbundet til {{containerName}}", "disconnected": "Afbrudt", "consoleError": "Konsolfejl", @@ -93,7 +99,10 @@ "logs": "Logfiler", "stats": "Statistik", "consoleTab": "Konsol", - "startContainerToAccess": "Start containeren for at få adgang til konsollen" + "startContainerToAccess": "Start containeren for at få adgang til konsollen", + "noHostSelected": "Ingen vært valgt", + "failedToFetchLogs": "Kunne ikke hente logfiler: {{error}}", + "failedToDownloadLogs": "Kunne ikke downloade logfiler: {{error}}" }, "nav": { "docker": "Docker" @@ -102,10 +111,22 @@ "feature_docker": "Docker", "feature_docker_desc": "Se containere, læs logfiler og se statistikker på enhver vært, der kører Docker." }, + "terminal": { + "retry": "Prøv igen", + "clipboardReadFailed": "Kunne ikke læse fra udklipsholderen. Sørg for, at der er givet tilladelse til udklipsholderen.", + "clipboardWriteFailed": "Kunne ikke kopiere til udklipsholder. Sørg for, at siden serveres via HTTPS eller localhost." + }, + "permissions": { + "use": { + "title": "Brug Docker", + "description": "Åbn Docker-manageren og containerkonsollerne på værter med Docker aktiveret." + } + }, "settings": { "host": { "enable": { - "label": "Aktivér Docker" + "label": "Aktivér Docker", + "description": "Administrer containere på denne vært." }, "containerRuntime": { "label": "Containerkørselstid", @@ -122,9 +143,5 @@ "docsLink": "Se dokumenter", "hostNotFound": "Værten blev ikke fundet", "loadingHost": "Indlæser vært..." - }, - "terminal": { - "clipboardReadFailed": "Kunne ikke læse fra udklipsholderen. Sørg for, at der er givet tilladelse til udklipsholderen.", - "clipboardWriteFailed": "Kunne ikke kopiere til udklipsholder. Sørg for, at siden serveres via HTTPS eller localhost." } } diff --git a/plugins/docker/locales/translated/de_DE.json b/plugins/docker/locales/translated/de_DE.json index 160fedc9f..e4aae504d 100644 --- a/plugins/docker/locales/translated/de_DE.json +++ b/plugins/docker/locales/translated/de_DE.json @@ -21,6 +21,11 @@ "ports": "Ports", "noPorts": "Keine Ports", "start": "Start", + "stop": "Stoppen", + "status": "Status", + "actions": "Aktionen", + "cardView": "Kartenansicht", + "listView": "Listenansicht", "confirmRemoveContainer": "Sind Sie sicher, dass Sie den Container '{{name}}' entfernen möchten? Diese Aktion kann nicht rückgängig gemacht werden.", "runningContainerWarning": "Warnung: Dieser Container wird gerade ausgeführt. Beim Entfernen wird der Container zuerst gestoppt.", "loadingContainers": "Container werden geladen...", @@ -73,6 +78,7 @@ "containerMustBeRunning": "Der Container muss ausgeführt werden, um auf die Konsole zuzugreifen", "verificationCodePrompt": "Bestätigungscode eingeben", "totpVerificationFailed": "TOTP-Überprüfung fehlgeschlagen. Bitte versuchen Sie es erneut.", + "browserSignInFailed": "Anmeldung fehlgeschlagen. Bitte versuchen Sie es erneut.", "connectedTo": "Verbunden mit {{containerName}}", "disconnected": "Getrennt", "consoleError": "Konsolenfehler", @@ -93,7 +99,10 @@ "logs": "Protokolle", "stats": "Statistiken", "consoleTab": "Konsole", - "startContainerToAccess": "Starten Sie den Container, um auf die Konsole zuzugreifen" + "startContainerToAccess": "Starten Sie den Container, um auf die Konsole zuzugreifen", + "noHostSelected": "Kein Host ausgewählt", + "failedToFetchLogs": "Protokolle konnten nicht abgerufen werden: {{error}}", + "failedToDownloadLogs": "Protokolle konnten nicht heruntergeladen werden: {{error}}" }, "nav": { "docker": "Docker" @@ -102,10 +111,22 @@ "feature_docker": "Docker", "feature_docker_desc": "Container anzeigen, Protokolle lesen und Statistiken auf jedem Host, auf dem Docker ausgeführt wird, einsehen." }, + "terminal": { + "retry": "Erneut versuchen", + "clipboardReadFailed": "Lesen aus der Zwischenablage fehlgeschlagen. Stellen Sie sicher, dass die Zwischenablageberechtigungen erteilt wurden.", + "clipboardWriteFailed": "Kopieren in die Zwischenablage fehlgeschlagen. Stellen Sie sicher, dass die Seite über HTTPS oder localhost bereitgestellt wird." + }, + "permissions": { + "use": { + "title": "Docker verwenden", + "description": "Öffnen Sie die Docker Manager- und Containerkonsolen auf Hosts, auf denen Docker aktiviert ist." + } + }, "settings": { "host": { "enable": { - "label": "Docker aktivieren" + "label": "Docker aktivieren", + "description": "Container auf diesem Host verwalten." }, "containerRuntime": { "label": "Container-Runtime", @@ -122,9 +143,5 @@ "docsLink": "Dokumentation anzeigen", "hostNotFound": "Host nicht gefunden", "loadingHost": "Host wird geladen..." - }, - "terminal": { - "clipboardReadFailed": "Lesen aus der Zwischenablage fehlgeschlagen. Stellen Sie sicher, dass die Zwischenablageberechtigungen erteilt wurden.", - "clipboardWriteFailed": "Kopieren in die Zwischenablage fehlgeschlagen. Stellen Sie sicher, dass die Seite über HTTPS oder localhost bereitgestellt wird." } } diff --git a/plugins/docker/locales/translated/el_GR.json b/plugins/docker/locales/translated/el_GR.json index 3287379ef..d32d64498 100644 --- a/plugins/docker/locales/translated/el_GR.json +++ b/plugins/docker/locales/translated/el_GR.json @@ -21,6 +21,11 @@ "ports": "Λιμάνια", "noPorts": "Δεν υπάρχουν θύρες", "start": "Αρχή", + "stop": "Στάση", + "status": "Κατάσταση", + "actions": "Ενέργειες", + "cardView": "Προβολή κάρτας", + "listView": "Προβολή λίστας", "confirmRemoveContainer": "Είστε βέβαιοι ότι θέλετε να καταργήσετε το κοντέινερ '{{name}}'; Αυτή η ενέργεια δεν μπορεί να αναιρεθεί.", "runningContainerWarning": "Προειδοποίηση: Αυτό το κοντέινερ εκτελείται αυτήν τη στιγμή. Η αφαίρεσή του θα διακόψει πρώτα τη λειτουργία του.", "loadingContainers": "Φόρτωση κοντέινερ...", @@ -73,6 +78,7 @@ "containerMustBeRunning": "Το κοντέινερ πρέπει να εκτελείται για πρόσβαση στην κονσόλα", "verificationCodePrompt": "Εισαγάγετε τον κωδικό επαλήθευσης", "totpVerificationFailed": "Η επαλήθευση TOTP απέτυχε. Δοκιμάστε ξανά.", + "browserSignInFailed": "Η σύνδεση απέτυχε. Δοκιμάστε ξανά.", "connectedTo": "Συνδεδεμένο με {{containerName}}", "disconnected": "Ασύνδετος", "consoleError": "Σφάλμα κονσόλας", @@ -93,7 +99,10 @@ "logs": "Αρχεία καταγραφής", "stats": "Στατιστικά", "consoleTab": "Κονσόλα", - "startContainerToAccess": "Ξεκινήστε το κοντέινερ για να αποκτήσετε πρόσβαση στην κονσόλα" + "startContainerToAccess": "Ξεκινήστε το κοντέινερ για να αποκτήσετε πρόσβαση στην κονσόλα", + "noHostSelected": "Δεν έχει επιλεγεί κεντρικός υπολογιστής", + "failedToFetchLogs": "Αποτυχία ανάκτησης αρχείων καταγραφής: {{error}}", + "failedToDownloadLogs": "Αποτυχία λήψης αρχείων καταγραφής: {{error}}" }, "nav": { "docker": "Λιμενεργάτης" @@ -102,10 +111,22 @@ "feature_docker": "Λιμενεργάτης", "feature_docker_desc": "Δείτε κοντέινερ, διαβάστε αρχεία καταγραφής και παρακολουθήστε στατιστικά στοιχεία σε οποιονδήποτε κεντρικό υπολογιστή που εκτελεί Docker." }, + "terminal": { + "retry": "Δοκιμάζω πάλι", + "clipboardReadFailed": "Αποτυχία ανάγνωσης από το πρόχειρο. Βεβαιωθείτε ότι έχουν εκχωρηθεί δικαιώματα στο πρόχειρο.", + "clipboardWriteFailed": "Αποτυχία αντιγραφής στο πρόχειρο. Βεβαιωθείτε ότι η σελίδα προβάλλεται μέσω HTTPS ή localhost." + }, + "permissions": { + "use": { + "title": "Χρήση Docker", + "description": "Ανοίξτε τον διαχειριστή Docker και τις κονσόλες κοντέινερ σε κεντρικούς υπολογιστές με ενεργοποιημένο το Docker." + } + }, "settings": { "host": { "enable": { - "label": "Ενεργοποίηση Docker" + "label": "Ενεργοποίηση Docker", + "description": "Διαχείριση κοντέινερ σε αυτόν τον κεντρικό υπολογιστή." }, "containerRuntime": { "label": "Χρόνος εκτέλεσης κοντέινερ", @@ -122,9 +143,5 @@ "docsLink": "Προβολή εγγράφων", "hostNotFound": "Δεν βρέθηκε κεντρικός υπολογιστής", "loadingHost": "Φόρτωση κεντρικού υπολογιστή..." - }, - "terminal": { - "clipboardReadFailed": "Αποτυχία ανάγνωσης από το πρόχειρο. Βεβαιωθείτε ότι έχουν εκχωρηθεί δικαιώματα στο πρόχειρο.", - "clipboardWriteFailed": "Αποτυχία αντιγραφής στο πρόχειρο. Βεβαιωθείτε ότι η σελίδα προβάλλεται μέσω HTTPS ή localhost." } } diff --git a/plugins/docker/locales/translated/es_ES.json b/plugins/docker/locales/translated/es_ES.json index e3fd2b972..4462aac8a 100644 --- a/plugins/docker/locales/translated/es_ES.json +++ b/plugins/docker/locales/translated/es_ES.json @@ -21,6 +21,11 @@ "ports": "Puertos", "noPorts": "Sin puertos", "start": "Iniciar", + "stop": "Parada", + "status": "Estado", + "actions": "Comportamiento", + "cardView": "Vista de la tarjeta", + "listView": "Vista de lista", "confirmRemoveContainer": "¿Está seguro de que desea eliminar el contenedor '{{name}}'? Esta acción no se puede deshacer.", "runningContainerWarning": "Advertencia: Este contenedor está actualmente en ejecución. Al eliminarlo, se detendrá primero.", "loadingContainers": "Cargando contenedores...", @@ -73,6 +78,7 @@ "containerMustBeRunning": "El contenedor debe estar en ejecución para acceder a la consola", "verificationCodePrompt": "Introduzca el código de verificación", "totpVerificationFailed": "La verificación TOTP falló. Inténtelo de nuevo.", + "browserSignInFailed": "Error al iniciar sesión. Inténtalo de nuevo.", "connectedTo": "Conectado a {{containerName}}", "disconnected": "Desconectado", "consoleError": "Error de consola", @@ -93,19 +99,34 @@ "logs": "Registros", "stats": "Estadísticas", "consoleTab": "Consola", - "startContainerToAccess": "Inicie el contenedor para acceder a la consola" + "startContainerToAccess": "Inicie el contenedor para acceder a la consola", + "noHostSelected": "Ningún host seleccionado", + "failedToFetchLogs": "Error al obtener los registros: {{error}}", + "failedToDownloadLogs": "Error al descargar los registros: {{error}}" }, "nav": { "docker": "Docker" }, "onboarding": { - "feature_docker": "Estibador", + "feature_docker": "Docker", "feature_docker_desc": "Vea los contenedores, lea los registros y observe las estadísticas en cualquier host que ejecute Docker." }, + "terminal": { + "retry": "Reintentar", + "clipboardReadFailed": "No se pudo leer del portapapeles. Asegúrese de que los permisos del portapapeles estén concedidos.", + "clipboardWriteFailed": "Error al copiar al portapapeles. Asegúrese de que la página se sirva a través de HTTPS o en localhost." + }, + "permissions": { + "use": { + "title": "Utiliza Docker", + "description": "Abra las consolas del administrador de Docker y de los contenedores en los hosts que tengan Docker habilitado." + } + }, "settings": { "host": { "enable": { - "label": "Activar Docker" + "label": "Activar Docker", + "description": "Administra los contenedores en este host." }, "containerRuntime": { "label": "Runtime de contenedores", @@ -122,9 +143,5 @@ "docsLink": "Ver documentación", "hostNotFound": "Host no encontrado", "loadingHost": "Cargando host..." - }, - "terminal": { - "clipboardReadFailed": "No se pudo leer del portapapeles. Asegúrese de que los permisos del portapapeles estén concedidos.", - "clipboardWriteFailed": "Error al copiar al portapapeles. Asegúrese de que la página se sirva a través de HTTPS o en localhost." } } diff --git a/plugins/docker/locales/translated/fi_FI.json b/plugins/docker/locales/translated/fi_FI.json index df4289e82..1b9e9145e 100644 --- a/plugins/docker/locales/translated/fi_FI.json +++ b/plugins/docker/locales/translated/fi_FI.json @@ -21,6 +21,11 @@ "ports": "Portit", "noPorts": "Ei portteja", "start": "Aloita", + "stop": "Stop", + "status": "Status", + "actions": "Toiminnot", + "cardView": "Korttinäkymä", + "listView": "Listanäkymä", "confirmRemoveContainer": "Haluatko varmasti poistaa säilön '{{name}}'? Tätä toimintoa ei voi perua.", "runningContainerWarning": "Varoitus: Tämä säilö on parhaillaan käynnissä. Sen poistaminen pysäyttää säilön ensin.", "loadingContainers": "Konttien lastaus...", @@ -73,6 +78,7 @@ "containerMustBeRunning": "Kontin on oltava käynnissä, jotta konsoliin pääsee käsiksi.", "verificationCodePrompt": "Syötä vahvistuskoodi", "totpVerificationFailed": "TOTP-vahvistus epäonnistui. Yritä uudelleen.", + "browserSignInFailed": "Kirjautuminen epäonnistui. Yritä uudelleen.", "connectedTo": "Yhdistetty kohteeseen {{containerName}}", "disconnected": "Yhteys katkennut", "consoleError": "Konsolivirhe", @@ -93,7 +99,10 @@ "logs": "Lokit", "stats": "Tilastot", "consoleTab": "Konsoli", - "startContainerToAccess": "Käynnistä säilö päästäksesi konsoliin" + "startContainerToAccess": "Käynnistä säilö päästäksesi konsoliin", + "noHostSelected": "Ei valittua isäntää", + "failedToFetchLogs": "Lokien nouto epäonnistui: {{error}}", + "failedToDownloadLogs": "Lokien lataus epäonnistui: {{error}}" }, "nav": { "docker": "Satamatyöläinen" @@ -102,10 +111,22 @@ "feature_docker": "Satamatyöläinen", "feature_docker_desc": "Katso säilöjä, lue lokeja ja seuraa tilastoja millä tahansa Dockeria käyttävällä isännällä." }, + "terminal": { + "retry": "Yritä uudelleen", + "clipboardReadFailed": "Leikepöydän lukeminen epäonnistui. Varmista, että leikepöydän käyttöoikeudet on myönnetty.", + "clipboardWriteFailed": "Kopiointi leikepöydälle epäonnistui. Varmista, että sivua käytetään HTTPS:n tai paikallisen isännän kautta." + }, + "permissions": { + "use": { + "title": "Käytä Dockeria", + "description": "Avaa Docker-hallinta ja säilökonsolit isännillä, joissa Docker on käytössä." + } + }, "settings": { "host": { "enable": { - "label": "Ota Docker käyttöön" + "label": "Ota Docker käyttöön", + "description": "Hallitse säilöjä tällä isännöinnillä." }, "containerRuntime": { "label": "Säilön suoritusaika", @@ -122,9 +143,5 @@ "docsLink": "Näytä dokumentit", "hostNotFound": "Isäntää ei löydy", "loadingHost": "Ladataan isäntää..." - }, - "terminal": { - "clipboardReadFailed": "Leikepöydän lukeminen epäonnistui. Varmista, että leikepöydän käyttöoikeudet on myönnetty.", - "clipboardWriteFailed": "Kopiointi leikepöydälle epäonnistui. Varmista, että sivua käytetään HTTPS:n tai paikallisen isännän kautta." } } diff --git a/plugins/docker/locales/translated/fr_FR.json b/plugins/docker/locales/translated/fr_FR.json index 18650af02..af7787daa 100644 --- a/plugins/docker/locales/translated/fr_FR.json +++ b/plugins/docker/locales/translated/fr_FR.json @@ -21,6 +21,11 @@ "ports": "Ports", "noPorts": "Aucun port", "start": "Démarrer", + "stop": "Stop", + "status": "État", + "actions": "Actes", + "cardView": "Vue de carte", + "listView": "Vue liste", "confirmRemoveContainer": "Êtes-vous sûr de vouloir supprimer le conteneur '{{name}}' ? Cette action est irréversible.", "runningContainerWarning": "Attention : Ce conteneur est en cours d'exécution. Sa suppression l'arrêtera d'abord.", "loadingContainers": "Chargement des conteneurs...", @@ -73,6 +78,7 @@ "containerMustBeRunning": "Le conteneur doit être en cours d'exécution pour accéder à la console", "verificationCodePrompt": "Saisissez le code de vérification", "totpVerificationFailed": "La vérification TOTP a échoué. Veuillez réessayer.", + "browserSignInFailed": "Échec de la connexion. Veuillez réessayer.", "connectedTo": "Connecté à {{containerName}}", "disconnected": "Déconnecté", "consoleError": "Erreur de la console", @@ -93,7 +99,10 @@ "logs": "Journaux", "stats": "Stats", "consoleTab": "Console", - "startContainerToAccess": "Démarrez le conteneur pour accéder à la console" + "startContainerToAccess": "Démarrez le conteneur pour accéder à la console", + "noHostSelected": "Aucun hôte sélectionné", + "failedToFetchLogs": "Échec de la récupération des journaux : {{error}}", + "failedToDownloadLogs": "Échec du téléchargement des journaux : {{error}}" }, "nav": { "docker": "Docker" @@ -102,10 +111,22 @@ "feature_docker": "Docker", "feature_docker_desc": "Consultez les conteneurs, lisez les journaux et surveillez les statistiques sur n'importe quel hôte exécutant Docker." }, + "terminal": { + "retry": "Réessayer", + "clipboardReadFailed": "Échec de la lecture du presse-papiers. Assurez-vous que les autorisations du presse-papiers sont accordées.", + "clipboardWriteFailed": "Échec de la copie dans le presse-papiers. Assurez-vous que la page est servie en HTTPS ou localhost." + }, + "permissions": { + "use": { + "title": "Utilisez Docker", + "description": "Ouvrez les consoles du gestionnaire Docker et des conteneurs sur les hôtes sur lesquels Docker est activé." + } + }, "settings": { "host": { "enable": { - "label": "Activer Docker" + "label": "Activer Docker", + "description": "Gérer les conteneurs sur cet hôte." }, "containerRuntime": { "label": "Moteur d'exécution de conteneurs", @@ -122,9 +143,5 @@ "docsLink": "Voir la documentation", "hostNotFound": "Hôte introuvable", "loadingHost": "Chargement de l'hôte..." - }, - "terminal": { - "clipboardReadFailed": "Échec de la lecture du presse-papiers. Assurez-vous que les autorisations du presse-papiers sont accordées.", - "clipboardWriteFailed": "Échec de la copie dans le presse-papiers. Assurez-vous que la page est servie en HTTPS ou localhost." } } diff --git a/plugins/docker/locales/translated/he_IL.json b/plugins/docker/locales/translated/he_IL.json index 1454d74a8..b0dfe8ff4 100644 --- a/plugins/docker/locales/translated/he_IL.json +++ b/plugins/docker/locales/translated/he_IL.json @@ -21,6 +21,11 @@ "ports": "נמלים", "noPorts": "אין יציאות", "start": "הַתחָלָה", + "stop": "לְהַפְסִיק", + "status": "סטָטוּס", + "actions": "פעולות", + "cardView": "תצוגת כרטיס", + "listView": "תצוגת רשימה", "confirmRemoveContainer": "האם אתה בטוח שברצונך להסיר את המכולה '{{name}}'? לא ניתן לבטל פעולה זו.", "runningContainerWarning": "אזהרה: מיכל זה פועל כעת. הסרתו תעצור את המיכל תחילה.", "loadingContainers": "טוען מכולות...", @@ -73,6 +78,7 @@ "containerMustBeRunning": "יש לפעול על מנת לגשת למסוף.", "verificationCodePrompt": "הזן קוד אימות", "totpVerificationFailed": "אימות TOTP נכשל. אנא נסה שוב.", + "browserSignInFailed": "הכניסה נכשלה. אנא נסה שוב.", "connectedTo": "מחובר אל {{containerName}}", "disconnected": "מְנוּתָק", "consoleError": "שגיאת קונסולה", @@ -93,7 +99,10 @@ "logs": "יומני רישום", "stats": "סטטיסטיקות", "consoleTab": "לְנַחֵם", - "startContainerToAccess": "הפעל את המכולה כדי לגשת לקונסולה" + "startContainerToAccess": "הפעל את המכולה כדי לגשת לקונסולה", + "noHostSelected": "לא נבחר מארח", + "failedToFetchLogs": "נכשלה אחזור הלוגים: {{error}}", + "failedToDownloadLogs": "הורדת יומני רישום נכשלה: {{error}}" }, "nav": { "docker": "דוקר" @@ -102,10 +111,22 @@ "feature_docker": "דוקר", "feature_docker_desc": "ראה קונטיינרים, קרא יומני רישום וצפה בסטטיסטיקות על כל מארח שמפעיל את Docker." }, + "terminal": { + "retry": "נסה שוב", + "clipboardReadFailed": "הקריאה מהלוח נכשלה. ודא שהרשאות הלוח ניתנות.", + "clipboardWriteFailed": "ההעתקה ללוח נכשלה. ודא שהדף מוגש דרך HTTPS או localhost." + }, + "permissions": { + "use": { + "title": "השתמש ב-Docker", + "description": "פתח את מנהל ה-Docker ואת קונסולות המכולות במחשבים מארחים שבהם Docker מופעל." + } + }, "settings": { "host": { "enable": { - "label": "הפעל את Docker" + "label": "הפעל את Docker", + "description": "ניהול מכולות במארח זה." }, "containerRuntime": { "label": "זמן ריצה של המכולה", @@ -122,9 +143,5 @@ "docsLink": "הצג מסמכים", "hostNotFound": "המארח לא נמצא", "loadingHost": "טוען מארח..." - }, - "terminal": { - "clipboardReadFailed": "הקריאה מהלוח נכשלה. ודא שהרשאות הלוח ניתנות.", - "clipboardWriteFailed": "ההעתקה ללוח נכשלה. ודא שהדף מוגש דרך HTTPS או localhost." } } diff --git a/plugins/docker/locales/translated/hi_IN.json b/plugins/docker/locales/translated/hi_IN.json index f8bacaae9..e4b3e602d 100644 --- a/plugins/docker/locales/translated/hi_IN.json +++ b/plugins/docker/locales/translated/hi_IN.json @@ -21,6 +21,11 @@ "ports": "पोर्ट", "noPorts": "कोई पोर्ट नहीं", "start": "प्रारंभ करें", + "stop": "स्टॉप", + "status": "स्थिति", + "actions": "Actions", + "cardView": "Card view", + "listView": "List view", "confirmRemoveContainer": "क्या आप वाकई कंटेनर '{{name}}' हटाना चाहते हैं? यह क्रिया पूर्ववत नहीं की जा सकती।", "runningContainerWarning": "चेतावनी: यह कंटेनर वर्तमान में चल रहा है। हटाने पर पहले इसे रोका जाएगा।", "loadingContainers": "कंटेनर लोड हो रहे हैं...", @@ -73,6 +78,7 @@ "containerMustBeRunning": "कंसोल तक पहुंचने के लिए कंटेनर चालू होना चाहिए", "verificationCodePrompt": "सत्यापन कोड दर्ज करें", "totpVerificationFailed": "TOTP सत्यापन विफल। कृपया पुनः प्रयास करें।", + "browserSignInFailed": "Sign-in failed. Please try again.", "connectedTo": "{{containerName}} से जुड़ा", "disconnected": "डिस्कनेक्टेड", "consoleError": "कंसोल त्रुटि", @@ -93,19 +99,34 @@ "logs": "लॉग", "stats": "आंकड़े", "consoleTab": "कंसोल", - "startContainerToAccess": "कंसोल तक पहुंचने के लिए कंटेनर चालू करें" + "startContainerToAccess": "कंसोल तक पहुंचने के लिए कंटेनर चालू करें", + "noHostSelected": "कोई होस्ट चयनित नहीं है", + "failedToFetchLogs": "Failed to fetch logs: {{error}}", + "failedToDownloadLogs": "Failed to download logs: {{error}}" }, "nav": { "docker": "Docker" }, "onboarding": { - "feature_docker": "डाक में काम करनेवाला मज़दूर", - "feature_docker_desc": "डॉकर चलाने वाले किसी भी होस्ट पर कंटेनर देखें, लॉग पढ़ें और आंकड़े देखें।" + "feature_docker": "Docker", + "feature_docker_desc": "See containers, read logs and watch stats on any host running Docker." + }, + "terminal": { + "retry": "पुनः प्रयास करें", + "clipboardReadFailed": "क्लिपबोर्ड से पढ़ने में विफल। सुनिश्चित करें कि क्लिपबोर्ड अनुमतियाँ दी गई हैं।", + "clipboardWriteFailed": "क्लिपबोर्ड पर कॉपी करने में विफल। सुनिश्चित करें कि पेज HTTPS या लोकलहोस्ट पर सर्व किया गया है।" + }, + "permissions": { + "use": { + "title": "Use Docker", + "description": "Open the Docker manager and container consoles on hosts with Docker enabled." + } }, "settings": { "host": { "enable": { - "label": "Docker सक्षम करें" + "label": "Docker सक्षम करें", + "description": "Manage containers on this host." }, "containerRuntime": { "label": "कंटेनर रनटाइम", @@ -116,15 +137,11 @@ } }, "errors": { - "remoteServerRequired": "रिमोट सर्वर आवश्यक है। इस कनेक्शन प्रकार का उपयोग करने के लिए सेटिंग्स में जाकर रिमोट सर्वर कनेक्ट करें।" + "remoteServerRequired": "Remote server required. Connect a remote server in Settings to use this connection type." }, "hosts": { "docsLink": "दस्तावेज़ देखें", "hostNotFound": "होस्ट नहीं मिला", "loadingHost": "होस्ट लोड हो रहा है..." - }, - "terminal": { - "clipboardReadFailed": "क्लिपबोर्ड से पढ़ने में विफल। सुनिश्चित करें कि क्लिपबोर्ड अनुमतियाँ दी गई हैं।", - "clipboardWriteFailed": "क्लिपबोर्ड पर कॉपी करने में विफल। सुनिश्चित करें कि पेज HTTPS या लोकलहोस्ट पर सर्व किया गया है।" } } diff --git a/plugins/docker/locales/translated/hu_HU.json b/plugins/docker/locales/translated/hu_HU.json index d871357ae..3c5ac7340 100644 --- a/plugins/docker/locales/translated/hu_HU.json +++ b/plugins/docker/locales/translated/hu_HU.json @@ -21,6 +21,11 @@ "ports": "kikötők", "noPorts": "Nincsenek portok", "start": "Indul", + "stop": "Stop", + "status": "Állapot", + "actions": "Műveletek", + "cardView": "Kártyanézet", + "listView": "Lista nézet", "confirmRemoveContainer": "Are you sure you want to remove the container '{{name}}'? This action cannot be undone.", "runningContainerWarning": "Figyelmeztetés: Ez a konténer jelenleg fut. Eltávolítása először a konténer leállítását jelenti.", "loadingContainers": "Konténerek betöltése...", @@ -73,6 +78,7 @@ "containerMustBeRunning": "A konténernek futnia kell a konzol eléréséhez", "verificationCodePrompt": "Írja be az ellenőrző kódot", "totpVerificationFailed": "A TOTP ellenőrzése sikertelen. Próbáld újra.", + "browserSignInFailed": "Sikertelen bejelentkezés. Kérjük, próbálja újra.", "connectedTo": "Csatlakoztatva ehhez: {{containerName}}", "disconnected": "Szétkapcsolt", "consoleError": "Konzolhiba", @@ -93,7 +99,10 @@ "logs": "Naplók", "stats": "Statisztikák", "consoleTab": "Konzol", - "startContainerToAccess": "Indítsa el a konténert a konzol eléréséhez" + "startContainerToAccess": "Indítsa el a konténert a konzol eléréséhez", + "noHostSelected": "Nincs kiválasztva gazdagép", + "failedToFetchLogs": "Nem sikerült lekérni a naplókat: {{error}}", + "failedToDownloadLogs": "Nem sikerült letölteni a naplókat: {{error}}" }, "nav": { "docker": "Dokkmunkás" @@ -102,10 +111,22 @@ "feature_docker": "Dokkmunkás", "feature_docker_desc": "Tekintsd meg a konténereket, olvasd el a naplókat és figyeld a statisztikákat bármelyik Dockert futtató gazdagépen." }, + "terminal": { + "retry": "Újrapróbálkozás", + "clipboardReadFailed": "Nem sikerült beolvasni a vágólapról. Győződjön meg arról, hogy a vágólapra vonatkozó engedélyek meg vannak adva.", + "clipboardWriteFailed": "Nem sikerült a vágólapra másolni. Győződjön meg arról, hogy az oldal HTTPS vagy localhost protokollon keresztül jelenik meg." + }, + "permissions": { + "use": { + "title": "Docker használata", + "description": "Nyissa meg a Docker Managert és a konténerkonzolokat olyan gazdagépeken, amelyeken engedélyezve van a Docker." + } + }, "settings": { "host": { "enable": { - "label": "Docker engedélyezése" + "label": "Docker engedélyezése", + "description": "Konténerek kezelése ezen a gazdagépen." }, "containerRuntime": { "label": "Konténer futásideje", @@ -122,9 +143,5 @@ "docsLink": "Dokumentumok megtekintése", "hostNotFound": "Nem található gazdagép", "loadingHost": "Gazdagép betöltése..." - }, - "terminal": { - "clipboardReadFailed": "Nem sikerült beolvasni a vágólapról. Győződjön meg arról, hogy a vágólapra vonatkozó engedélyek meg vannak adva.", - "clipboardWriteFailed": "Nem sikerült a vágólapra másolni. Győződjön meg arról, hogy az oldal HTTPS vagy localhost protokollon keresztül jelenik meg." } } diff --git a/plugins/docker/locales/translated/id_ID.json b/plugins/docker/locales/translated/id_ID.json index 07eb0cb88..631c3a919 100644 --- a/plugins/docker/locales/translated/id_ID.json +++ b/plugins/docker/locales/translated/id_ID.json @@ -1,130 +1,147 @@ { "docker": { - "notEnabled": "Docker tidak diaktifkan untuk host ini.", - "validating": "Memvalidasi Docker...", - "connecting": "Menghubungkan...", - "error": "Kesalahan", + "notEnabled": "Docker is not enabled for this host", + "validating": "Validating Docker...", + "connecting": "Connecting...", + "error": "Error", "version": "{{runtime}} {{version}}", - "connectionFailed": "Gagal terhubung ke Docker", - "containerStarted": "Kontainer {{name}} dimulai", - "failedToStartContainer": "Gagal memulai kontainer {{name}}", - "containerStopped": "Kontainer {{name}} berhenti", - "failedToStopContainer": "Gagal menghentikan kontainer {{name}}", - "containerRestarted": "Kontainer {{name}} dimulai ulang", - "failedToRestartContainer": "Gagal memulai ulang kontainer {{name}}", - "containerPaused": "Kontainer {{name}} berhenti", - "containerUnpaused": "Kontainer {{name}} tidak dijeda", - "failedToTogglePauseContainer": "Gagal mengubah status jeda untuk kontainer {{name}}", - "containerRemoved": "Kontainer {{name}} dihapus", - "failedToRemoveContainer": "Gagal menghapus kontainer {{name}}", - "image": "Gambar", - "ports": "Pelabuhan", - "noPorts": "Tidak ada port", - "start": "Awal", - "confirmRemoveContainer": "Apakah Anda yakin ingin menghapus kontainer '{{name}}'? Tindakan ini tidak dapat dibatalkan.", - "runningContainerWarning": "Peringatan: Kontainer ini sedang berjalan. Menghapusnya akan menghentikan kontainer terlebih dahulu.", - "loadingContainers": "Memuat kontainer...", - "manager": "Manajer Docker", - "autoRefresh": "Penyegaran Otomatis", - "timestamps": "Cap waktu", - "lines": "Garis", - "filterLogs": "Filter log...", - "refresh": "Menyegarkan", - "download": "Unduh", - "clear": "Jernih", - "logsDownloaded": "Log berhasil diunduh.", - "last50": "50 Terakhir", - "last100": "100 terakhir", - "last500": "500 Terakhir", - "last1000": "1000 terakhir", - "allLogs": "Semua Log", - "noLogsMatching": "Tidak ada log yang cocok dengan \"{{query}}\"", - "noLogsAvailable": "Tidak ada log yang tersedia.", - "noContainersFound": "Tidak ditemukan wadah apa pun", - "noContainersFoundHint": "Tidak ada kontainer Docker yang tersedia di host ini.", - "searchPlaceholder": "Cari kontainer...", - "allStatuses": "Semua Status", - "stateRunning": "Berlari", - "statePaused": "Dijeda", - "stateExited": "Keluar", - "stateRestarting": "Memulai ulang", - "noContainersMatchFilters": "Tidak ada wadah yang sesuai dengan filter Anda.", - "noContainersMatchFiltersHint": "Cobalah menyesuaikan kriteria pencarian atau filter Anda.", - "failedToFetchStats": "Gagal mengambil statistik kontainer", - "containerNotRunning": "Kontainer tidak berjalan", - "startContainerToViewStats": "Jalankan kontainer untuk melihat statistik.", - "loadingStats": "Memuat statistik...", - "errorLoadingStats": "Terjadi kesalahan saat memuat statistik.", - "noStatsAvailable": "Tidak ada statistik yang tersedia.", - "cpuUsage": "Penggunaan CPU", - "current": "Saat ini", - "memoryUsage": "Penggunaan Memori", - "networkIo": "Input/Output Jaringan", - "input": "Masukan", - "output": "Keluaran", - "blockIo": "Blok I/O", - "read": "Membaca", - "write": "Menulis", - "pids": "PID", - "containerInformation": "Informasi Kontainer", - "name": "Nama", - "id": "PENGENAL", - "state": "Negara", - "containerMustBeRunning": "Kontainer harus berjalan agar dapat mengakses konsol.", - "verificationCodePrompt": "Masukkan kode verifikasi", - "totpVerificationFailed": "Verifikasi TOTP gagal. Silakan coba lagi.", - "connectedTo": "Terhubung ke {{containerName}}", - "disconnected": "Terputus", - "consoleError": "Kesalahan konsol", - "errorMessage": "Kesalahan: {{message}}", - "failedToConnect": "Gagal terhubung ke kontainer", - "console": "Menghibur", - "selectShell": "Pilih cangkang", - "bash": "Pesta", + "connectionFailed": "Failed to connect to Docker", + "containerStarted": "Container {{name}} started", + "failedToStartContainer": "Failed to start container {{name}}", + "containerStopped": "Container {{name}} stopped", + "failedToStopContainer": "Failed to stop container {{name}}", + "containerRestarted": "Container {{name}} restarted", + "failedToRestartContainer": "Failed to restart container {{name}}", + "containerPaused": "Container {{name}} paused", + "containerUnpaused": "Container {{name}} unpaused", + "failedToTogglePauseContainer": "Failed to toggle pause state for container {{name}}", + "containerRemoved": "Container {{name}} removed", + "failedToRemoveContainer": "Failed to remove container {{name}}", + "image": "Image", + "ports": "Ports", + "noPorts": "No ports", + "start": "Start", + "stop": "Stop", + "status": "Status", + "actions": "Actions", + "cardView": "Card view", + "listView": "List view", + "confirmRemoveContainer": "Are you sure you want to remove the container '{{name}}'? This action cannot be undone.", + "runningContainerWarning": "Warning: This container is currently running. Removing it will stop the container first.", + "loadingContainers": "Loading containers...", + "manager": "Docker Manager", + "autoRefresh": "Auto Refresh", + "timestamps": "Timestamps", + "lines": "Lines", + "filterLogs": "Filter logs...", + "refresh": "Refresh", + "download": "Download", + "clear": "Clear", + "logsDownloaded": "Logs downloaded successfully", + "last50": "Last 50", + "last100": "Last 100", + "last500": "Last 500", + "last1000": "Last 1000", + "allLogs": "All Logs", + "noLogsMatching": "No logs matching \"{{query}}\"", + "noLogsAvailable": "No logs available", + "noContainersFound": "No containers found", + "noContainersFoundHint": "No Docker containers are available on this host", + "searchPlaceholder": "Search containers...", + "allStatuses": "All Statuses", + "stateRunning": "Running", + "statePaused": "Paused", + "stateExited": "Exited", + "stateRestarting": "Restarting", + "noContainersMatchFilters": "No containers match your filters", + "noContainersMatchFiltersHint": "Try adjusting your search or filter criteria", + "failedToFetchStats": "Failed to fetch container statistics", + "containerNotRunning": "Container not running", + "startContainerToViewStats": "Start the container to view statistics", + "loadingStats": "Loading statistics...", + "errorLoadingStats": "Error loading statistics", + "noStatsAvailable": "No statistics available", + "cpuUsage": "CPU Usage", + "current": "Current", + "memoryUsage": "Memory Usage", + "networkIo": "Network I/O", + "input": "Input", + "output": "Output", + "blockIo": "Block I/O", + "read": "Read", + "write": "Write", + "pids": "PIDs", + "containerInformation": "Container Information", + "name": "Name", + "id": "ID", + "state": "State", + "containerMustBeRunning": "Container must be running to access console", + "verificationCodePrompt": "Enter verification code", + "totpVerificationFailed": "TOTP verification failed. Please try again.", + "browserSignInFailed": "Sign-in failed. Please try again.", + "connectedTo": "Connected to {{containerName}}", + "disconnected": "Disconnected", + "consoleError": "Console error", + "errorMessage": "Error: {{message}}", + "failedToConnect": "Failed to connect to container", + "console": "Console", + "selectShell": "Select shell", + "bash": "Bash", "sh": "sh", - "ash": "abu", - "connect": "Menghubungkan", - "disconnect": "Memutuskan", - "notConnected": "Tidak terhubung", - "clickToConnect": "Klik sambungkan untuk memulai sesi shell.", - "connectingTo": "Menghubungkan ke {{containerName}}...", - "containerNotFound": "Kontainer tidak ditemukan", - "backToList": "Kembali ke Daftar", - "logs": "Log", - "stats": "Statistik", - "consoleTab": "Menghibur", - "startContainerToAccess": "Jalankan kontainer untuk mengakses konsol." + "ash": "ash", + "connect": "Connect", + "disconnect": "Disconnect", + "notConnected": "Not connected", + "clickToConnect": "Click connect to start a shell session", + "connectingTo": "Connecting to {{containerName}}...", + "containerNotFound": "Container not found", + "backToList": "Back to List", + "logs": "Logs", + "stats": "Stats", + "consoleTab": "Console", + "startContainerToAccess": "Start the container to access the console", + "noHostSelected": "No host selected", + "failedToFetchLogs": "Failed to fetch logs: {{error}}", + "failedToDownloadLogs": "Failed to download logs: {{error}}" }, "nav": { - "docker": "Buruh pelabuhan" + "docker": "Docker" }, "onboarding": { - "feature_docker": "Buruh pelabuhan", - "feature_docker_desc": "Lihat kontainer, baca log, dan pantau statistik pada host mana pun yang menjalankan Docker." + "feature_docker": "Docker", + "feature_docker_desc": "See containers, read logs and watch stats on any host running Docker." + }, + "terminal": { + "retry": "Retry", + "clipboardReadFailed": "Failed to read from clipboard. Make sure clipboard permissions are granted.", + "clipboardWriteFailed": "Failed to copy to clipboard. Make sure the page is served over HTTPS or localhost." + }, + "permissions": { + "use": { + "title": "Use Docker", + "description": "Open the Docker manager and container consoles on hosts with Docker enabled." + } }, "settings": { "host": { "enable": { - "label": "Aktifkan Docker" + "label": "Enable Docker", + "description": "Manage containers on this host." }, "containerRuntime": { - "label": "Lingkungan Eksekusi Kontainer", - "description": "Pilih CLI yang digunakan untuk manajemen kontainer pada host ini.", - "docker": "Buruh pelabuhan", + "label": "Container Runtime", + "description": "Choose the CLI used for container management on this host", + "docker": "Docker", "podman": "Podman" } } }, "errors": { - "remoteServerRequired": "Diperlukan server jarak jauh. Hubungkan server jarak jauh di Pengaturan untuk menggunakan jenis koneksi ini." + "remoteServerRequired": "Remote server required. Connect a remote server in Settings to use this connection type." }, "hosts": { - "docsLink": "Lihat dokumen", - "hostNotFound": "Host tidak ditemukan", - "loadingHost": "Memuat host..." - }, - "terminal": { - "clipboardReadFailed": "Gagal membaca dari clipboard. Pastikan izin clipboard telah diberikan.", - "clipboardWriteFailed": "Gagal menyalin ke papan klip. Pastikan halaman disajikan melalui HTTPS atau localhost." + "docsLink": "View docs", + "hostNotFound": "Host not found", + "loadingHost": "Loading host..." } } diff --git a/plugins/docker/locales/translated/it_IT.json b/plugins/docker/locales/translated/it_IT.json index 6ec4a296d..a55d3295d 100644 --- a/plugins/docker/locales/translated/it_IT.json +++ b/plugins/docker/locales/translated/it_IT.json @@ -21,6 +21,11 @@ "ports": "Porte", "noPorts": "Nessuna porta", "start": "Avvia", + "stop": "Stop", + "status": "Stato", + "actions": "Azioni", + "cardView": "Visualizzazione a schede", + "listView": "Visualizzazione elenco", "confirmRemoveContainer": "Sei sicuro di voler rimuovere il container '{{name}}'? Questa azione non può essere annullata.", "runningContainerWarning": "Attenzione: questo container è attualmente in esecuzione. La rimozione lo arresterà prima.", "loadingContainers": "Caricamento container in corso...", @@ -73,6 +78,7 @@ "containerMustBeRunning": "Il container deve essere in esecuzione per accedere alla console", "verificationCodePrompt": "Inserisci il codice di verifica", "totpVerificationFailed": "Verifica TOTP fallita. Riprova.", + "browserSignInFailed": "Accesso non riuscito. Riprova.", "connectedTo": "Connesso a {{containerName}}", "disconnected": "Disconnesso", "consoleError": "Errore console", @@ -93,7 +99,10 @@ "logs": "Log", "stats": "Statistiche", "consoleTab": "Console", - "startContainerToAccess": "Avvia il container per accedere alla console" + "startContainerToAccess": "Avvia il container per accedere alla console", + "noHostSelected": "Nessun host selezionato", + "failedToFetchLogs": "Impossibile recuperare i log: {{error}}", + "failedToDownloadLogs": "Impossibile scaricare i log: {{error}}" }, "nav": { "docker": "Docker" @@ -102,10 +111,22 @@ "feature_docker": "Docker", "feature_docker_desc": "Visualizza i container, leggi i log e controlla le statistiche su qualsiasi host che esegue Docker." }, + "terminal": { + "retry": "Riprova", + "clipboardReadFailed": "Lettura dagli appunti non riuscita. Assicurati che i permessi degli appunti siano stati concessi.", + "clipboardWriteFailed": "Copia negli appunti non riuscita. Assicurati che la pagina sia servita via HTTPS o localhost." + }, + "permissions": { + "use": { + "title": "Utilizzare Docker", + "description": "Apri il gestore Docker e le console dei container sugli host in cui Docker è abilitato." + } + }, "settings": { "host": { "enable": { - "label": "Abilita Docker" + "label": "Abilita Docker", + "description": "Gestisci i container su questo host." }, "containerRuntime": { "label": "Runtime container", @@ -122,9 +143,5 @@ "docsLink": "Visualizza documentazione", "hostNotFound": "Host non trovato", "loadingHost": "Caricamento host..." - }, - "terminal": { - "clipboardReadFailed": "Lettura dagli appunti non riuscita. Assicurati che i permessi degli appunti siano stati concessi.", - "clipboardWriteFailed": "Copia negli appunti non riuscita. Assicurati che la pagina sia servita via HTTPS o localhost." } } diff --git a/plugins/docker/locales/translated/ja_JP.json b/plugins/docker/locales/translated/ja_JP.json index 7a35d30b9..596730469 100644 --- a/plugins/docker/locales/translated/ja_JP.json +++ b/plugins/docker/locales/translated/ja_JP.json @@ -21,6 +21,11 @@ "ports": "ポート", "noPorts": "ポートなし", "start": "起動", + "stop": "ストップ", + "status": "状態", + "actions": "行動", + "cardView": "カードビュー", + "listView": "リストビュー", "confirmRemoveContainer": "コンテナ '{{name}}' を削除してもよろしいですか? この操作は元に戻せません。", "runningContainerWarning": "警告: このコンテナは現在実行中です。削除すると、まずコンテナが停止されます。", "loadingContainers": "コンテナを読み込み中...", @@ -73,6 +78,7 @@ "containerMustBeRunning": "コンソールにアクセスするにはコンテナが実行中である必要があります", "verificationCodePrompt": "認証コードを入力してください", "totpVerificationFailed": "TOTP認証に失敗しました。もう一度お試しください。", + "browserSignInFailed": "ログインに失敗しました。もう一度お試しください。", "connectedTo": "{{containerName}}に接続しました", "disconnected": "切断されました", "consoleError": "コンソールエラー", @@ -93,19 +99,34 @@ "logs": "ログ", "stats": "統計", "consoleTab": "コンソール", - "startContainerToAccess": "コンテナを起動してコンソールにアクセスしてください" + "startContainerToAccess": "コンテナを起動してコンソールにアクセスしてください", + "noHostSelected": "ホストが選択されていません", + "failedToFetchLogs": "ログの取得に失敗しました: {{error}}", + "failedToDownloadLogs": "ログのダウンロードに失敗しました: {{error}}" }, "nav": { "docker": "Docker" }, "onboarding": { - "feature_docker": "ドッカー", + "feature_docker": "Docker", "feature_docker_desc": "Dockerを実行している任意のホスト上で、コンテナの表示、ログの読み取り、統計情報の監視が可能です。" }, + "terminal": { + "retry": "再試行", + "clipboardReadFailed": "クリップボードからの読み取りに失敗しました。クリップボードのアクセス許可が付与されていることを確認してください。", + "clipboardWriteFailed": "クリップボードへのコピーに失敗しました。ページがHTTPSまたはlocalhostで提供されていることを確認してください。" + }, + "permissions": { + "use": { + "title": "Dockerを使用する", + "description": "Dockerが有効になっているホスト上で、Dockerマネージャーとコンテナコンソールを開きます。" + } + }, "settings": { "host": { "enable": { - "label": "Docker有効化" + "label": "Dockerを有効化", + "description": "このホスト上のコンテナを管理します。" }, "containerRuntime": { "label": "コンテナランタイム", @@ -122,9 +143,5 @@ "docsLink": "ドキュメントを表示", "hostNotFound": "ホストが見つかりません", "loadingHost": "ホストを読み込み中..." - }, - "terminal": { - "clipboardReadFailed": "クリップボードからの読み取りに失敗しました。クリップボードのアクセス許可が付与されていることを確認してください。", - "clipboardWriteFailed": "クリップボードへのコピーに失敗しました。ページがHTTPSまたはlocalhostで提供されていることを確認してください。" } } diff --git a/plugins/docker/locales/translated/ko_KR.json b/plugins/docker/locales/translated/ko_KR.json index 00cff812a..626d23871 100644 --- a/plugins/docker/locales/translated/ko_KR.json +++ b/plugins/docker/locales/translated/ko_KR.json @@ -21,6 +21,11 @@ "ports": "포트", "noPorts": "포트 없음", "start": "시작", + "stop": "중지", + "status": "상태", + "actions": "작업", + "cardView": "카드 보기", + "listView": "목록 보기", "confirmRemoveContainer": "컨테이너 '{{name}}'을(를) 제거하시겠습니까? 이 작업은 되돌릴 수 없습니다.", "runningContainerWarning": "경고: 이 컨테이너는 현재 실행 중입니다. 제거하면 먼저 컨테이너가 중지됩니다.", "loadingContainers": "컨테이너 로딩 중...", @@ -73,6 +78,7 @@ "containerMustBeRunning": "컨테이너가 실행 중이어야 콘솔에 접근할 수 있습니다", "verificationCodePrompt": "인증 코드를 입력하세요", "totpVerificationFailed": "TOTP 인증에 실패했습니다. 다시 시도하세요.", + "browserSignInFailed": "로그인에 실패했습니다. 다시 시도해 주세요.", "connectedTo": "{{containerName}}에 연결됨", "disconnected": "연결 끊김", "consoleError": "콘솔 오류", @@ -93,19 +99,34 @@ "logs": "로그", "stats": "통계", "consoleTab": "콘솔", - "startContainerToAccess": "컨테이너를 시작하여 콘솔에 접근하세요" + "startContainerToAccess": "컨테이너를 시작하여 콘솔에 접근하세요", + "noHostSelected": "선택된 호스트가 없습니다", + "failedToFetchLogs": "로그를 가져오는 데 실패했습니다: {{error}}", + "failedToDownloadLogs": "로그 다운로드 실패: {{error}}" }, "nav": { "docker": "Docker" }, "onboarding": { - "feature_docker": "도커", + "feature_docker": "Docker", "feature_docker_desc": "Docker가 실행 중인 모든 호스트에서 컨테이너를 확인하고, 로그를 읽고, 통계를 볼 수 있습니다." }, + "terminal": { + "retry": "재시도", + "clipboardReadFailed": "클립보드에서 읽지 못했습니다. 클립보드 권한이 허용되었는지 확인하세요.", + "clipboardWriteFailed": "클립보드에 복사하지 못했습니다. 페이지가 HTTPS 또는 localhost에서 제공되는지 확인하세요." + }, + "permissions": { + "use": { + "title": "Docker를 사용하세요", + "description": "Docker가 활성화된 호스트에서 Docker 관리자 및 컨테이너 콘솔을 엽니다." + } + }, "settings": { "host": { "enable": { - "label": "Docker 활성화" + "label": "Docker 활성화", + "description": "이 호스트에서 컨테이너를 관리하세요." }, "containerRuntime": { "label": "컨테이너 런타임", @@ -122,9 +143,5 @@ "docsLink": "문서 보기", "hostNotFound": "호스트를 찾을 수 없습니다", "loadingHost": "호스트 로드 중..." - }, - "terminal": { - "clipboardReadFailed": "클립보드에서 읽지 못했습니다. 클립보드 권한이 허용되었는지 확인하세요.", - "clipboardWriteFailed": "클립보드에 복사하지 못했습니다. 페이지가 HTTPS 또는 localhost에서 제공되는지 확인하세요." } } diff --git a/plugins/docker/locales/translated/nl_NL.json b/plugins/docker/locales/translated/nl_NL.json index 2bf0b4341..813a79869 100644 --- a/plugins/docker/locales/translated/nl_NL.json +++ b/plugins/docker/locales/translated/nl_NL.json @@ -21,6 +21,11 @@ "ports": "Havens", "noPorts": "Geen poorten", "start": "Begin", + "stop": "Stop", + "status": "Status", + "actions": "Acties", + "cardView": "Kaartweergave", + "listView": "Lijstweergave", "confirmRemoveContainer": "Weet je zeker dat je de container '{{name}}' wilt verwijderen? Deze actie kan niet ongedaan worden gemaakt.", "runningContainerWarning": "Waarschuwing: Deze container is momenteel actief. Als u deze verwijdert, wordt de container eerst gestopt.", "loadingContainers": "Containers laden...", @@ -73,6 +78,7 @@ "containerMustBeRunning": "De container moet actief zijn om toegang te krijgen tot de console.", "verificationCodePrompt": "Voer de verificatiecode in.", "totpVerificationFailed": "TOTP-verificatie mislukt. Probeer het opnieuw.", + "browserSignInFailed": "Aanmelden is mislukt. Probeer het opnieuw.", "connectedTo": "Verbonden met {{containerName}}", "disconnected": "Verbinding verbroken", "consoleError": "Consolefout", @@ -93,7 +99,10 @@ "logs": "Logboeken", "stats": "Statistieken", "consoleTab": "Troosten", - "startContainerToAccess": "Start de container om toegang te krijgen tot de console." + "startContainerToAccess": "Start de container om toegang te krijgen tot de console.", + "noHostSelected": "Geen host geselecteerd", + "failedToFetchLogs": "Het ophalen van logbestanden is mislukt: {{error}}", + "failedToDownloadLogs": "Het downloaden van logbestanden is mislukt: {{error}}" }, "nav": { "docker": "Docker" @@ -102,10 +111,22 @@ "feature_docker": "Docker", "feature_docker_desc": "Bekijk containers, lees logboeken en bekijk statistieken op elke host waarop Docker draait." }, + "terminal": { + "retry": "Opnieuw proberen", + "clipboardReadFailed": "Het lezen van het klembord is mislukt. Zorg ervoor dat de juiste klembordrechten zijn verleend.", + "clipboardWriteFailed": "Kopiëren naar klembord mislukt. Zorg ervoor dat de pagina via HTTPS of localhost wordt aangeboden." + }, + "permissions": { + "use": { + "title": "Gebruik Docker", + "description": "Open de Docker Manager en de containerconsoles op hosts waarop Docker is ingeschakeld." + } + }, "settings": { "host": { "enable": { - "label": "Docker inschakelen" + "label": "Docker inschakelen", + "description": "Beheer containers op deze host." }, "containerRuntime": { "label": "Container Runtime", @@ -122,9 +143,5 @@ "docsLink": "Documenten bekijken", "hostNotFound": "Host niet gevonden", "loadingHost": "Host wordt geladen..." - }, - "terminal": { - "clipboardReadFailed": "Het lezen van het klembord is mislukt. Zorg ervoor dat de juiste klembordrechten zijn verleend.", - "clipboardWriteFailed": "Kopiëren naar klembord mislukt. Zorg ervoor dat de pagina via HTTPS of localhost wordt aangeboden." } } diff --git a/plugins/docker/locales/translated/no_NO.json b/plugins/docker/locales/translated/no_NO.json index f749a2d98..f3f5c6eb4 100644 --- a/plugins/docker/locales/translated/no_NO.json +++ b/plugins/docker/locales/translated/no_NO.json @@ -1,130 +1,147 @@ { "docker": { - "notEnabled": "Docker er ikke aktivert for denne verten", - "validating": "Validerer Docker...", + "notEnabled": "Docker is not enabled for this host", + "validating": "Validating Docker...", "connecting": "Kobler til...", "error": "Feil", "version": "{{runtime}} {{version}}", - "connectionFailed": "Kunne ikke koble til Docker", - "containerStarted": "Container {{name}} startet", - "failedToStartContainer": "Kunne ikke starte containeren {{name}}", - "containerStopped": "Container {{name}} stoppet", - "failedToStopContainer": "Klarte ikke å stoppe containeren {{name}}", - "containerRestarted": "Beholder {{name}} startet på nytt", - "failedToRestartContainer": "Kunne ikke starte beholderen {{name}} på nytt", - "containerPaused": "Beholder {{name}} satt på pause", - "containerUnpaused": "Beholder {{name}} er ikke satt på pause lenger", - "failedToTogglePauseContainer": "Kunne ikke slå av/på pausetilstand for container {{name}}", - "containerRemoved": "Beholder {{name}} fjernet", - "failedToRemoveContainer": "Kunne ikke fjerne beholderen {{name}}", - "image": "Bilde", - "ports": "Porter", - "noPorts": "Ingen porter", + "connectionFailed": "Failed to connect to Docker", + "containerStarted": "Container {{name}} started", + "failedToStartContainer": "Failed to start container {{name}}", + "containerStopped": "Container {{name}} stopped", + "failedToStopContainer": "Failed to stop container {{name}}", + "containerRestarted": "Container {{name}} restarted", + "failedToRestartContainer": "Failed to restart container {{name}}", + "containerPaused": "Container {{name}} paused", + "containerUnpaused": "Container {{name}} unpaused", + "failedToTogglePauseContainer": "Failed to toggle pause state for container {{name}}", + "containerRemoved": "Container {{name}} removed", + "failedToRemoveContainer": "Failed to remove container {{name}}", + "image": "Image", + "ports": "Ports", + "noPorts": "No ports", "start": "Start", - "confirmRemoveContainer": "Er du sikker på at du vil fjerne beholderen '{{name}}'? Denne handlingen kan ikke angres.", - "runningContainerWarning": "Advarsel: Denne beholderen kjører for øyeblikket. Hvis du fjerner den, stoppes beholderen først.", - "loadingContainers": "Laster containere ...", + "stop": "Stopp", + "status": "Status", + "actions": "Handlinger", + "cardView": "Card view", + "listView": "List view", + "confirmRemoveContainer": "Are you sure you want to remove the container '{{name}}'? This action cannot be undone.", + "runningContainerWarning": "Warning: This container is currently running. Removing it will stop the container first.", + "loadingContainers": "Loading containers...", "manager": "Docker Manager", - "autoRefresh": "Automatisk oppdatering", - "timestamps": "Tidsstempler", - "lines": "Linjer", - "filterLogs": "Filtrer logger...", - "refresh": "Forfriske", + "autoRefresh": "Auto Refresh", + "timestamps": "Timestamps", + "lines": "Lines", + "filterLogs": "Filter logs...", + "refresh": "Oppdater", "download": "Last ned", - "clear": "Klar", - "logsDownloaded": "Loggene er lastet ned", - "last50": "Siste 50", - "last100": "Siste 100", - "last500": "Siste 500", - "last1000": "Siste 1000", - "allLogs": "Alle logger", - "noLogsMatching": "Ingen logger som samsvarer med «{{query}}»", - "noLogsAvailable": "Ingen logger tilgjengelig", - "noContainersFound": "Ingen containere funnet", - "noContainersFoundHint": "Ingen Docker-containere er tilgjengelige på denne verten", - "searchPlaceholder": "Søk i containere...", - "allStatuses": "Alle statuser", - "stateRunning": "Løping", - "statePaused": "Pauset", - "stateExited": "Avsluttet", - "stateRestarting": "Starter på nytt", - "noContainersMatchFilters": "Ingen beholdere samsvarer med filtrene dine", - "noContainersMatchFiltersHint": "Prøv å justere søke- eller filterkriteriene dine", - "failedToFetchStats": "Kunne ikke hente containerstatistikk", - "containerNotRunning": "Beholderen kjører ikke", - "startContainerToViewStats": "Start beholderen for å se statistikk", - "loadingStats": "Laster inn statistikk ...", - "errorLoadingStats": "Feil ved lasting av statistikk", - "noStatsAvailable": "Ingen statistikk tilgjengelig", + "clear": "Tøm", + "logsDownloaded": "Logs downloaded successfully", + "last50": "Last 50", + "last100": "Last 100", + "last500": "Last 500", + "last1000": "Last 1000", + "allLogs": "All Logs", + "noLogsMatching": "No logs matching \"{{query}}\"", + "noLogsAvailable": "No logs available", + "noContainersFound": "No containers found", + "noContainersFoundHint": "No Docker containers are available on this host", + "searchPlaceholder": "Search containers...", + "allStatuses": "All Statuses", + "stateRunning": "Kjører", + "statePaused": "Paused", + "stateExited": "Exited", + "stateRestarting": "Restarting", + "noContainersMatchFilters": "No containers match your filters", + "noContainersMatchFiltersHint": "Try adjusting your search or filter criteria", + "failedToFetchStats": "Failed to fetch container statistics", + "containerNotRunning": "Container not running", + "startContainerToViewStats": "Start the container to view statistics", + "loadingStats": "Loading statistics...", + "errorLoadingStats": "Error loading statistics", + "noStatsAvailable": "No statistics available", "cpuUsage": "CPU-bruk", - "current": "Nåværende", + "current": "Current", "memoryUsage": "Minnebruk", - "networkIo": "Nettverk I/O", - "input": "Inndata", - "output": "Produksjon", - "blockIo": "Blokk I/O", - "read": "Lese", - "write": "Skrive", - "pids": "PID-er", - "containerInformation": "Containerinformasjon", + "networkIo": "Network I/O", + "input": "Input", + "output": "Output", + "blockIo": "Block I/O", + "read": "Les", + "write": "Skriv", + "pids": "PIDs", + "containerInformation": "Container Information", "name": "Navn", "id": "ID", - "state": "Tilstand", - "containerMustBeRunning": "Containeren må kjøre for å få tilgang til konsollen", - "verificationCodePrompt": "Skriv inn bekreftelseskoden", - "totpVerificationFailed": "TOTP-verifisering mislyktes. Prøv på nytt.", - "connectedTo": "Koblet til {{containerName}}", + "state": "State", + "containerMustBeRunning": "Container must be running to access console", + "verificationCodePrompt": "Angi verifikasjonskode", + "totpVerificationFailed": "TOTP verification failed. Please try again.", + "browserSignInFailed": "Sign-in failed. Please try again.", + "connectedTo": "Connected to {{containerName}}", "disconnected": "Frakoblet", - "consoleError": "Konsollfeil", + "consoleError": "Console error", "errorMessage": "Feil: {{message}}", - "failedToConnect": "Kunne ikke koble til beholderen", - "console": "Konsoll", - "selectShell": "Velg skall", + "failedToConnect": "Failed to connect to container", + "console": "Console", + "selectShell": "Select shell", "bash": "Bash", "sh": "sh", - "ash": "aske", + "ash": "ash", "connect": "Koble til", - "disconnect": "Frakople", - "notConnected": "Ikke tilkoblet", - "clickToConnect": "Klikk på koble til for å starte en skalløkt", - "connectingTo": "Kobler til {{containerName}}...", - "containerNotFound": "Beholderen ble ikke funnet", - "backToList": "Tilbake til listen", - "logs": "Logger", - "stats": "Statistikk", - "consoleTab": "Konsoll", - "startContainerToAccess": "Start containeren for å få tilgang til konsollen" + "disconnect": "Koble fra", + "notConnected": "Not connected", + "clickToConnect": "Click connect to start a shell session", + "connectingTo": "Connecting to {{containerName}}...", + "containerNotFound": "Container not found", + "backToList": "Back to List", + "logs": "Logs", + "stats": "Stats", + "consoleTab": "Console", + "startContainerToAccess": "Start the container to access the console", + "noHostSelected": "Ingen vert valgt", + "failedToFetchLogs": "Failed to fetch logs: {{error}}", + "failedToDownloadLogs": "Failed to download logs: {{error}}" }, "nav": { - "docker": "Dokker" + "docker": "Docker" }, "onboarding": { - "feature_docker": "Dokker", - "feature_docker_desc": "Se containere, les logger og se statistikk på alle verter som kjører Docker." + "feature_docker": "Docker", + "feature_docker_desc": "See containers, read logs and watch stats on any host running Docker." + }, + "terminal": { + "retry": "Prøv igjen", + "clipboardReadFailed": "Failed to read from clipboard. Make sure clipboard permissions are granted.", + "clipboardWriteFailed": "Failed to copy to clipboard. Make sure the page is served over HTTPS or localhost." + }, + "permissions": { + "use": { + "title": "Use Docker", + "description": "Open the Docker manager and container consoles on hosts with Docker enabled." + } }, "settings": { "host": { "enable": { - "label": "Aktiver Docker" + "label": "Enable Docker", + "description": "Manage containers on this host." }, "containerRuntime": { - "label": "Containerkjøringstid", - "description": "Velg CRI-et som brukes for containeradministrasjon på denne verten", - "docker": "Dokker", + "label": "Container Runtime", + "description": "Choose the CLI used for container management on this host", + "docker": "Docker", "podman": "Podman" } } }, "errors": { - "remoteServerRequired": "Ekstern server kreves. Koble til en ekstern server i Innstillinger for å bruke denne tilkoblingstypen." + "remoteServerRequired": "Remote server required. Connect a remote server in Settings to use this connection type." }, "hosts": { - "docsLink": "Vis dokumenter", - "hostNotFound": "Verten ble ikke funnet", - "loadingHost": "Laster inn vert ..." - }, - "terminal": { - "clipboardReadFailed": "Kunne ikke lese fra utklippstavlen. Sørg for at utklippstavlen har tillatelser.", - "clipboardWriteFailed": "Kunne ikke kopiere til utklippstavlen. Sørg for at siden serveres via HTTPS eller localhost." + "docsLink": "View docs", + "hostNotFound": "Host not found", + "loadingHost": "Loading host..." } } diff --git a/plugins/docker/locales/translated/pl_PL.json b/plugins/docker/locales/translated/pl_PL.json index 1570c6e6c..2c2474b57 100644 --- a/plugins/docker/locales/translated/pl_PL.json +++ b/plugins/docker/locales/translated/pl_PL.json @@ -21,6 +21,11 @@ "ports": "Porty", "noPorts": "Brak portów", "start": "Start", + "stop": "Stop", + "status": "Status", + "actions": "Actions", + "cardView": "Card view", + "listView": "List view", "confirmRemoveContainer": "Czy na pewno chcesz usunąć kontener „{{name}}”? Tej czynności nie można cofnąć.", "runningContainerWarning": "Ostrzeżenie: Ten kontener jest obecnie uruchomiony. Jego usunięcie spowoduje najpierw jego zatrzymanie.", "loadingContainers": "Ładowanie kontenerów...", @@ -73,6 +78,7 @@ "containerMustBeRunning": "Aby uzyskać dostęp do konsoli, kontener musi być uruchomiony", "verificationCodePrompt": "Wprowadź kod weryfikacyjny", "totpVerificationFailed": "Weryfikacja TOTP nie powiodła się. Spróbuj ponownie.", + "browserSignInFailed": "Sign-in failed. Please try again.", "connectedTo": "Połączono z {{containerName}}", "disconnected": "Rozłączono", "consoleError": "Błąd konsoli", @@ -93,7 +99,10 @@ "logs": "Logi", "stats": "Statystyki", "consoleTab": "Konsola", - "startContainerToAccess": "Uruchom kontener, aby uzyskać dostęp do konsoli" + "startContainerToAccess": "Uruchom kontener, aby uzyskać dostęp do konsoli", + "noHostSelected": "Nie wybrano hosta", + "failedToFetchLogs": "Failed to fetch logs: {{error}}", + "failedToDownloadLogs": "Failed to download logs: {{error}}" }, "nav": { "docker": "Docker" @@ -102,10 +111,22 @@ "feature_docker": "Docker", "feature_docker_desc": "Przeglądaj kontenery, czytaj logi i śledź statystyki na dowolnym hoście, na którym działa Docker." }, + "terminal": { + "retry": "Ponów", + "clipboardReadFailed": "Nie udało się odczytać danych ze schowka. Upewnij się, że uprawnienia do schowka zostały przyznane.", + "clipboardWriteFailed": "Nie udało się skopiować do schowka. Upewnij się, że strona jest serwowana przez HTTPS lub localhost." + }, + "permissions": { + "use": { + "title": "Use Docker", + "description": "Open the Docker manager and container consoles on hosts with Docker enabled." + } + }, "settings": { "host": { "enable": { - "label": "Włącz Docker" + "label": "Włącz Docker", + "description": "Manage containers on this host." }, "containerRuntime": { "label": "Środowisko wykonawcze kontenera", @@ -122,9 +143,5 @@ "docsLink": "Zobacz dokumentację", "hostNotFound": "Nie znaleziono hosta", "loadingHost": "Ładowanie hosta..." - }, - "terminal": { - "clipboardReadFailed": "Nie udało się odczytać danych ze schowka. Upewnij się, że uprawnienia do schowka zostały przyznane.", - "clipboardWriteFailed": "Nie udało się skopiować do schowka. Upewnij się, że strona jest serwowana przez HTTPS lub localhost." } } diff --git a/plugins/docker/locales/translated/pt_BR.json b/plugins/docker/locales/translated/pt_BR.json index b5db6a8d2..a9bee900a 100644 --- a/plugins/docker/locales/translated/pt_BR.json +++ b/plugins/docker/locales/translated/pt_BR.json @@ -1,130 +1,147 @@ { "docker": { - "notEnabled": "O Docker não está habilitado para este host.", - "validating": "Validando o Docker...", + "notEnabled": "Docker is not enabled for this host", + "validating": "Validating Docker...", "connecting": "Conectando...", "error": "Erro", "version": "{{runtime}} {{version}}", - "connectionFailed": "Falha ao conectar ao Docker", - "containerStarted": "Contêiner {{name}} iniciado", - "failedToStartContainer": "Falha ao iniciar o contêiner {{name}}", - "containerStopped": "Contêiner {{name}} parado", - "failedToStopContainer": "Falha ao parar o contêiner {{name}}", - "containerRestarted": "Contêiner {{name}} reiniciado", - "failedToRestartContainer": "Falha ao reiniciar o contêiner {{name}}", - "containerPaused": "Contêiner {{name}} pausado", - "containerUnpaused": "Contêiner {{name}} despausado", - "failedToTogglePauseContainer": "Falha ao alternar o estado de pausa para o contêiner {{name}}", - "containerRemoved": "Contêiner {{name}} removido", - "failedToRemoveContainer": "Falha ao remover o contêiner {{name}}", - "image": "Imagem", - "ports": "Portos", - "noPorts": "Sem portas", - "start": "Começar", - "confirmRemoveContainer": "Tem certeza de que deseja remover o contêiner '{{name}}'? Esta ação não pode ser desfeita.", - "runningContainerWarning": "Aviso: Este contêiner está em execução. Removê-lo interromperá o contêiner primeiro.", - "loadingContainers": "Carregando contêineres...", - "manager": "Gerenciador de Docker", - "autoRefresh": "Atualização automática", - "timestamps": "Carimbos de data/hora", - "lines": "Linhas", - "filterLogs": "Filtrar registros...", + "connectionFailed": "Failed to connect to Docker", + "containerStarted": "Container {{name}} started", + "failedToStartContainer": "Failed to start container {{name}}", + "containerStopped": "Container {{name}} stopped", + "failedToStopContainer": "Failed to stop container {{name}}", + "containerRestarted": "Container {{name}} restarted", + "failedToRestartContainer": "Failed to restart container {{name}}", + "containerPaused": "Container {{name}} paused", + "containerUnpaused": "Container {{name}} unpaused", + "failedToTogglePauseContainer": "Failed to toggle pause state for container {{name}}", + "containerRemoved": "Container {{name}} removed", + "failedToRemoveContainer": "Failed to remove container {{name}}", + "image": "Image", + "ports": "Ports", + "noPorts": "No ports", + "start": "Iniciar", + "stop": "Stop", + "status": "Status", + "actions": "Actions", + "cardView": "Card view", + "listView": "List view", + "confirmRemoveContainer": "Are you sure you want to remove the container '{{name}}'? This action cannot be undone.", + "runningContainerWarning": "Warning: This container is currently running. Removing it will stop the container first.", + "loadingContainers": "Loading containers...", + "manager": "Docker Manager", + "autoRefresh": "Auto Refresh", + "timestamps": "Timestamps", + "lines": "Lines", + "filterLogs": "Filter logs...", "refresh": "Atualizar", "download": "Download", - "clear": "Claro", - "logsDownloaded": "Registros baixados com sucesso", - "last50": "Últimos 50", - "last100": "Últimos 100", - "last500": "Últimos 500", - "last1000": "Últimos 1000", - "allLogs": "Todos os registros", - "noLogsMatching": "Nenhum registro correspondente a \"{{query}}\"", - "noLogsAvailable": "Nenhum registro disponível", - "noContainersFound": "Nenhum contêiner encontrado", - "noContainersFoundHint": "Não há contêineres Docker disponíveis neste host.", - "searchPlaceholder": "Contêineres de pesquisa...", - "allStatuses": "Todos os status", - "stateRunning": "Correndo", - "statePaused": "Em pausa", - "stateExited": "Saiu", - "stateRestarting": "Reiniciando", - "noContainersMatchFilters": "Nenhum recipiente corresponde aos seus filtros.", - "noContainersMatchFiltersHint": "Tente ajustar seus critérios de pesquisa ou filtro.", - "failedToFetchStats": "Falha ao obter as estatísticas do contêiner.", - "containerNotRunning": "Contêiner não está em execução", - "startContainerToViewStats": "Inicie o contêiner para visualizar as estatísticas.", - "loadingStats": "Carregando estatísticas...", - "errorLoadingStats": "Estatísticas de carregamento de erros", - "noStatsAvailable": "Não há estatísticas disponíveis.", - "cpuUsage": "Utilização da CPU", - "current": "Atual", - "memoryUsage": "Uso de memória", - "networkIo": "E/S de rede", + "clear": "Limpar", + "logsDownloaded": "Logs downloaded successfully", + "last50": "Last 50", + "last100": "Last 100", + "last500": "Last 500", + "last1000": "Last 1000", + "allLogs": "All Logs", + "noLogsMatching": "No logs matching \"{{query}}\"", + "noLogsAvailable": "No logs available", + "noContainersFound": "No containers found", + "noContainersFoundHint": "No Docker containers are available on this host", + "searchPlaceholder": "Search containers...", + "allStatuses": "All Statuses", + "stateRunning": "Running", + "statePaused": "Paused", + "stateExited": "Exited", + "stateRestarting": "Restarting", + "noContainersMatchFilters": "No containers match your filters", + "noContainersMatchFiltersHint": "Try adjusting your search or filter criteria", + "failedToFetchStats": "Failed to fetch container statistics", + "containerNotRunning": "Container not running", + "startContainerToViewStats": "Start the container to view statistics", + "loadingStats": "Loading statistics...", + "errorLoadingStats": "Error loading statistics", + "noStatsAvailable": "No statistics available", + "cpuUsage": "CPU Usage", + "current": "Current", + "memoryUsage": "Memory Usage", + "networkIo": "Entrada e Saída de rede", "input": "Entrada", - "output": "Saída", + "output": "Output", "blockIo": "Bloco de E/S", - "read": "Ler", - "write": "Escrever", - "pids": "PIDs", - "containerInformation": "Informações do contêiner", - "name": "Nome", - "id": "EU IA", - "state": "Estado", - "containerMustBeRunning": "O contêiner precisa estar em execução para acessar o console.", - "verificationCodePrompt": "Insira o código de verificação", - "totpVerificationFailed": "A verificação TOTP falhou. Tente novamente.", - "connectedTo": "Conectado a {{containerName}}", - "disconnected": "Desconectado", - "consoleError": "Erro no console", - "errorMessage": "Erro: {{message}}", - "failedToConnect": "Falha ao conectar ao contêiner", + "read": "Read", + "write": "Write", + "pids": "Identificadores de Processos", + "containerInformation": "Container Information", + "name": "Name", + "id": "ID", + "state": "State", + "containerMustBeRunning": "O contêiner precisa estar em execução para acessar o console", + "verificationCodePrompt": "Enter verification code", + "totpVerificationFailed": "TOTP verification failed. Please try again.", + "browserSignInFailed": "Sign-in failed. Please try again.", + "connectedTo": "Connected to {{containerName}}", + "disconnected": "Disconnected", + "consoleError": "Console error", + "errorMessage": "Error: {{message}}", + "failedToConnect": "Failed to connect to container", "console": "Console", - "selectShell": "Selecione shell", + "selectShell": "Select shell", "bash": "Bash", "sh": "sh", - "ash": "cinzas", + "ash": "ash", "connect": "Conectar", "disconnect": "Desconectar", - "notConnected": "Não conectado", - "clickToConnect": "Clique em conectar para iniciar uma sessão de shell.", - "connectingTo": "Conectando a {{containerName}}...", - "containerNotFound": "Contêiner não encontrado", - "backToList": "Voltar à lista", - "logs": "Registros", - "stats": "Estatísticas", + "notConnected": "Not connected", + "clickToConnect": "Click connect to start a shell session", + "connectingTo": "Connecting to {{containerName}}...", + "containerNotFound": "Container not found", + "backToList": "Back to List", + "logs": "Logs", + "stats": "Stats", "consoleTab": "Console", - "startContainerToAccess": "Inicie o contêiner para acessar o console." + "startContainerToAccess": "Start the container to access the console", + "noHostSelected": "No host selected", + "failedToFetchLogs": "Failed to fetch logs: {{error}}", + "failedToDownloadLogs": "Failed to download logs: {{error}}" }, "nav": { "docker": "Docker" }, "onboarding": { "feature_docker": "Docker", - "feature_docker_desc": "Visualize contêineres, leia registros e acompanhe as estatísticas em qualquer host que execute o Docker." + "feature_docker_desc": "See containers, read logs and watch stats on any host running Docker." + }, + "terminal": { + "retry": "Retry", + "clipboardReadFailed": "Failed to read from clipboard. Make sure clipboard permissions are granted.", + "clipboardWriteFailed": "Failed to copy to clipboard. Make sure the page is served over HTTPS or localhost." + }, + "permissions": { + "use": { + "title": "Use Docker", + "description": "Open the Docker manager and container consoles on hosts with Docker enabled." + } }, "settings": { "host": { "enable": { - "label": "Habilitar Docker" + "label": "Ativar Docker", + "description": "Manage containers on this host." }, "containerRuntime": { - "label": "Tempo de execução do contêiner", - "description": "Escolha a CLI usada para gerenciamento de contêineres neste host.", + "label": "Container Runtime", + "description": "Choose the CLI used for container management on this host", "docker": "Docker", "podman": "Podman" } } }, "errors": { - "remoteServerRequired": "É necessário um servidor remoto. Conecte um servidor remoto nas Configurações para usar este tipo de conexão." + "remoteServerRequired": "Remote server required. Connect a remote server in Settings to use this connection type." }, "hosts": { - "docsLink": "Ver documentos", - "hostNotFound": "Host não encontrado", - "loadingHost": "Carregando host..." - }, - "terminal": { - "clipboardReadFailed": "Não foi possível ler o conteúdo da área de transferência. Certifique-se de que as permissões de acesso à área de transferência estejam concedidas.", - "clipboardWriteFailed": "Falha ao copiar para a área de transferência. Certifique-se de que a página esteja sendo servida via HTTPS ou localhost." + "docsLink": "Documentação", + "hostNotFound": "Host not found", + "loadingHost": "Loading host..." } } diff --git a/plugins/docker/locales/translated/pt_PT.json b/plugins/docker/locales/translated/pt_PT.json index 9dffc37a7..5da41c447 100644 --- a/plugins/docker/locales/translated/pt_PT.json +++ b/plugins/docker/locales/translated/pt_PT.json @@ -21,6 +21,11 @@ "ports": "Portas", "noPorts": "Sem portas", "start": "Iniciar", + "stop": "Stop", + "status": "Estado", + "actions": "Actions", + "cardView": "Card view", + "listView": "List view", "confirmRemoveContainer": "Tem a certeza de que pretende remover o contentor '{{name}}'? Esta ação não pode ser desfeita.", "runningContainerWarning": "Aviso: Este contentor está em execução. Removê-lo irá pará-lo primeiro.", "loadingContainers": "A carregar contentores...", @@ -73,6 +78,7 @@ "containerMustBeRunning": "O contentor tem de estar em execução para aceder à consola", "verificationCodePrompt": "Introduza o código de verificação", "totpVerificationFailed": "A verificação TOTP falhou. Por favor, tente novamente.", + "browserSignInFailed": "Sign-in failed. Please try again.", "connectedTo": "Ligado a {{containerName}}", "disconnected": "Desligado", "consoleError": "Erro da consola", @@ -93,19 +99,34 @@ "logs": "Registos", "stats": "Estatísticas", "consoleTab": "Consola", - "startContainerToAccess": "Inicie o contentor para aceder à consola" + "startContainerToAccess": "Inicie o contentor para aceder à consola", + "noHostSelected": "Nenhum anfitrião selecionado", + "failedToFetchLogs": "Failed to fetch logs: {{error}}", + "failedToDownloadLogs": "Failed to download logs: {{error}}" }, "nav": { "docker": "Docker" }, "onboarding": { "feature_docker": "Docker", - "feature_docker_desc": "Visualize contentores, leia registos e acompanhe as estatísticas em qualquer host que execute o Docker." + "feature_docker_desc": "See containers, read logs and watch stats on any host running Docker." + }, + "terminal": { + "retry": "Repetir", + "clipboardReadFailed": "Erro ao ler da área de transferência. Certifique-se de que as permissões da área de transferência foram concedidas.", + "clipboardWriteFailed": "Erro ao copiar para a área de transferência. Certifique-se de que a página é servida via HTTPS ou localhost." + }, + "permissions": { + "use": { + "title": "Use Docker", + "description": "Open the Docker manager and container consoles on hosts with Docker enabled." + } }, "settings": { "host": { "enable": { - "label": "Ativar Docker" + "label": "Ativar Docker", + "description": "Manage containers on this host." }, "containerRuntime": { "label": "Runtime de Contentores", @@ -116,15 +137,11 @@ } }, "errors": { - "remoteServerRequired": "É necessário um servidor remoto. Ligue um servidor remoto nas Definições para utilizar este tipo de ligação." + "remoteServerRequired": "Remote server required. Connect a remote server in Settings to use this connection type." }, "hosts": { "docsLink": "Ver documentação", "hostNotFound": "Host não encontrado", "loadingHost": "A carregar o host..." - }, - "terminal": { - "clipboardReadFailed": "Erro ao ler da área de transferência. Certifique-se de que as permissões da área de transferência foram concedidas.", - "clipboardWriteFailed": "Erro ao copiar para a área de transferência. Certifique-se de que a página é servida via HTTPS ou localhost." } } diff --git a/plugins/docker/locales/translated/ro_RO.json b/plugins/docker/locales/translated/ro_RO.json index 6ed5116c1..f62b384d0 100644 --- a/plugins/docker/locales/translated/ro_RO.json +++ b/plugins/docker/locales/translated/ro_RO.json @@ -21,6 +21,11 @@ "ports": "Porturi", "noPorts": "Fără porturi", "start": "Început", + "stop": "Stop", + "status": "Stare", + "actions": "Acțiuni", + "cardView": "Vizualizare card", + "listView": "Vizualizare listă", "confirmRemoveContainer": "Sigur doriți să eliminați containerul „{{name}}”? Această acțiune nu poate fi anulată.", "runningContainerWarning": "Avertisment: Acest container rulează în prezent. Eliminarea sa va opri mai întâi containerul.", "loadingContainers": "Se încarcă containerele...", @@ -41,7 +46,7 @@ "noLogsMatching": "Niciun jurnal care să corespundă cu „{{query}}”", "noLogsAvailable": "Nu sunt disponibile jurnale", "noContainersFound": "Nu s-au găsit containere", - "noContainersFoundHint": "Nu există containere Docker disponibile pe această gazdă.", + "noContainersFoundHint": "Nu există containere Docker disponibile pe această gazdă", "searchPlaceholder": "Căutați containere...", "allStatuses": "Toate stările", "stateRunning": "Funcţionare", @@ -73,6 +78,7 @@ "containerMustBeRunning": "Containerul trebuie să ruleze pentru a accesa consola.", "verificationCodePrompt": "Introduceți codul de verificare", "totpVerificationFailed": "Verificarea TOTP a eșuat. Vă rugăm să încercați din nou.", + "browserSignInFailed": "Conectarea a eșuat. Vă rugăm să încercați din nou.", "connectedTo": "Conectat la {{containerName}}", "disconnected": "Deconectat", "consoleError": "Eroare consolă", @@ -93,7 +99,10 @@ "logs": "Jurnalele", "stats": "Statistici", "consoleTab": "Consolă", - "startContainerToAccess": "Porniți containerul pentru a accesa consola" + "startContainerToAccess": "Porniți containerul pentru a accesa consola", + "noHostSelected": "Nicio gazdă selectată", + "failedToFetchLogs": "Nu s-au putut prelua jurnalele: {{error}}", + "failedToDownloadLogs": "Descărcarea jurnalelor a eșuat: {{error}}" }, "nav": { "docker": "Docher" @@ -102,10 +111,22 @@ "feature_docker": "Docher", "feature_docker_desc": "Vizualizați containere, citiți jurnale și urmăriți statistici pe orice gazdă care rulează Docker." }, + "terminal": { + "retry": "Reîncercați", + "clipboardReadFailed": "Citirea din clipboard nu a reușit. Asigurați-vă că permisiunile de acces la clipboard sunt acordate.", + "clipboardWriteFailed": "Copierea în clipboard nu a reușit. Asigurați-vă că pagina este servită prin HTTPS sau localhost." + }, + "permissions": { + "use": { + "title": "Folosește Docker", + "description": "Deschideți managerul Docker și consolele containerelor pe gazdele cu Docker activat." + } + }, "settings": { "host": { "enable": { - "label": "Activează Docker" + "label": "Activează Docker", + "description": "Gestionați containerele de pe această gazdă." }, "containerRuntime": { "label": "Runtime de container", @@ -122,9 +143,5 @@ "docsLink": "Vizualizați documentele", "hostNotFound": "Gazdă negăsită", "loadingHost": "Se încarcă gazda..." - }, - "terminal": { - "clipboardReadFailed": "Citirea din clipboard nu a reușit. Asigurați-vă că permisiunile de acces la clipboard sunt acordate.", - "clipboardWriteFailed": "Copierea în clipboard nu a reușit. Asigurați-vă că pagina este servită prin HTTPS sau localhost." } } diff --git a/plugins/docker/locales/translated/ru_RU.json b/plugins/docker/locales/translated/ru_RU.json index f3759f1c3..281841e97 100644 --- a/plugins/docker/locales/translated/ru_RU.json +++ b/plugins/docker/locales/translated/ru_RU.json @@ -21,6 +21,11 @@ "ports": "Порты", "noPorts": "Нет портов", "start": "Запустить", + "stop": "Остановить", + "status": "Статус", + "actions": "Actions", + "cardView": "Card view", + "listView": "List view", "confirmRemoveContainer": "Вы уверены, что хотите удалить контейнер «{{name}}»? Это действие нельзя отменить.", "runningContainerWarning": "Предупреждение: этот контейнер в настоящее время работает. При удалении он будет сначала остановлен.", "loadingContainers": "Загрузка контейнеров...", @@ -73,6 +78,7 @@ "containerMustBeRunning": "Для доступа к консоли контейнер должен быть запущен", "verificationCodePrompt": "Введите код подтверждения", "totpVerificationFailed": "Ошибка проверки TOTP. Попробуйте еще раз.", + "browserSignInFailed": "Sign-in failed. Please try again.", "connectedTo": "Подключено к {{containerName}}", "disconnected": "Отключено", "consoleError": "Ошибка консоли", @@ -93,19 +99,34 @@ "logs": "Логи", "stats": "Статистика", "consoleTab": "Консоль", - "startContainerToAccess": "Запустите контейнер, чтобы получить доступ к консоли" + "startContainerToAccess": "Запустите контейнер, чтобы получить доступ к консоли", + "noHostSelected": "Хост не выбран", + "failedToFetchLogs": "Failed to fetch logs: {{error}}", + "failedToDownloadLogs": "Failed to download logs: {{error}}" }, "nav": { "docker": "Docker" }, "onboarding": { "feature_docker": "Docker", - "feature_docker_desc": "Просматривайте контейнеры, читайте журналы и отслеживайте статистику на любом хосте, где запущен Docker." + "feature_docker_desc": "See containers, read logs and watch stats on any host running Docker." + }, + "terminal": { + "retry": "Повторить", + "clipboardReadFailed": "Не удалось прочитать из буфера обмена. Убедитесь, что предоставлены разрешения на доступ к буферу обмена.", + "clipboardWriteFailed": "Не удалось скопировать в буфер обмена. Убедитесь, что страница загружена по HTTPS или с localhost." + }, + "permissions": { + "use": { + "title": "Use Docker", + "description": "Open the Docker manager and container consoles on hosts with Docker enabled." + } }, "settings": { "host": { "enable": { - "label": "Включить Docker" + "label": "Включить Docker", + "description": "Manage containers on this host." }, "containerRuntime": { "label": "Среда выполнения контейнеров", @@ -116,15 +137,11 @@ } }, "errors": { - "remoteServerRequired": "Требуется удаленный сервер. Для использования этого типа подключения подключите удаленный сервер в настройках." + "remoteServerRequired": "Remote server required. Connect a remote server in Settings to use this connection type." }, "hosts": { "docsLink": "Документация", "hostNotFound": "Хост не найден", "loadingHost": "Загрузка хоста..." - }, - "terminal": { - "clipboardReadFailed": "Не удалось прочитать из буфера обмена. Убедитесь, что предоставлены разрешения на доступ к буферу обмена.", - "clipboardWriteFailed": "Не удалось скопировать в буфер обмена. Убедитесь, что страница загружена по HTTPS или с localhost." } } diff --git a/plugins/docker/locales/translated/sr_SP.json b/plugins/docker/locales/translated/sr_SP.json index d2695248b..631c3a919 100644 --- a/plugins/docker/locales/translated/sr_SP.json +++ b/plugins/docker/locales/translated/sr_SP.json @@ -1,130 +1,147 @@ { "docker": { - "notEnabled": "Докер није омогућен за овај хост", - "validating": "Валидација Докера...", - "connecting": "Повезивање...", - "error": "Грешка", + "notEnabled": "Docker is not enabled for this host", + "validating": "Validating Docker...", + "connecting": "Connecting...", + "error": "Error", "version": "{{runtime}} {{version}}", - "connectionFailed": "Повезивање са Докером није успело", - "containerStarted": "Контејнер {{name}} је покренут", - "failedToStartContainer": "Покретање контејнера {{name}} није успело", - "containerStopped": "Контејнер {{name}} је заустављен", - "failedToStopContainer": "Заустављање контејнера {{name}} није успело", - "containerRestarted": "Контејнер {{name}} поново покренут", - "failedToRestartContainer": "Поновно покретање контејнера није успело {{name}}", - "containerPaused": "Контејнер {{name}} је паузиран", - "containerUnpaused": "Паузирање контејнера {{name}} је прекинуто", - "failedToTogglePauseContainer": "Није успело пребацивање стања паузе за контејнер {{name}}", - "containerRemoved": "Контејнер {{name}} је уклоњен", - "failedToRemoveContainer": "Није успело уклањање контејнера {{name}}", - "image": "Слика", - "ports": "Портови", - "noPorts": "Нема портова", - "start": "Почетак", - "confirmRemoveContainer": "Да ли сте сигурни да желите да уклоните контејнер „{{name}}“? Ова радња се не може поништити.", - "runningContainerWarning": "Упозорење: Овај контејнер је тренутно покренут. Његово уклањање ће прво зауставити рад контејнера.", - "loadingContainers": "Учитавање контејнера...", - "manager": "Докер менаџер", - "autoRefresh": "Аутоматско освежавање", - "timestamps": "Временске ознаке", - "lines": "Линије", - "filterLogs": "Филтрирај логове...", - "refresh": "Освежи", - "download": "Преузми", - "clear": "Јасно", - "logsDownloaded": "Дневници су успешно преузети", - "last50": "Последњих 50", - "last100": "Последњих 100", - "last500": "Последњих 500", - "last1000": "Последњих 1000", - "allLogs": "Сви дневници", - "noLogsMatching": "Нема логова који одговарају „{{query}}“", - "noLogsAvailable": "Нема доступних логова", - "noContainersFound": "Нису пронађени контејнери", - "noContainersFoundHint": "На овом хосту нису доступни Docker контејнери", - "searchPlaceholder": "Претражи контејнере...", - "allStatuses": "Сви статуси", - "stateRunning": "Трчање", - "statePaused": "Паузирано", - "stateExited": "Изашао/ла", - "stateRestarting": "Поновно покретање", - "noContainersMatchFilters": "Ниједан контејнер не одговара вашим филтерима", - "noContainersMatchFiltersHint": "Покушајте да прилагодите критеријуме претраге или филтрирања", - "failedToFetchStats": "Није успело преузимање статистике контејнера", - "containerNotRunning": "Контејнер се не покреће", - "startContainerToViewStats": "Покрените контејнер да бисте видели статистику", - "loadingStats": "Учитавање статистике...", - "errorLoadingStats": "Грешка при учитавању статистике", - "noStatsAvailable": "Нема доступних статистика", - "cpuUsage": "Искоришћеност процесора", - "current": "Тренутни", - "memoryUsage": "Коришћење меморије", - "networkIo": "Мрежни улаз/излаз", - "input": "Унос", - "output": "Излаз", - "blockIo": "Блок У/И", - "read": "Читај", - "write": "Пиши", - "pids": "ПИД-ови", - "containerInformation": "Информације о контејнеру", - "name": "Име", - "id": "ИД", - "state": "Држава", - "containerMustBeRunning": "Контејнер мора бити покренут да би се приступило конзоли", - "verificationCodePrompt": "Унесите верификациони код", - "totpVerificationFailed": "Верификација TOTP-а није успела. Молимо покушајте поново.", - "connectedTo": "Повезано са {{containerName}}", - "disconnected": "Искључено", - "consoleError": "Грешка конзоле", - "errorMessage": "Грешка: {{message}}", - "failedToConnect": "Повезивање са контејнером није успело", - "console": "Конзола", - "selectShell": "Изаберите љуску", - "bash": "Баш", - "sh": "ш", - "ash": "пепео", - "connect": "Повежи се", - "disconnect": "Прекини везу", - "notConnected": "Није повезано", - "clickToConnect": "Кликните на повезивање да бисте покренули сесију шкољке", - "connectingTo": "Повезивање са {{containerName}}...", - "containerNotFound": "Контејнер није пронађен", - "backToList": "Назад на листу", - "logs": "Дневници", - "stats": "Статистика", - "consoleTab": "Конзола", - "startContainerToAccess": "Покрените контејнер да бисте приступили конзоли" + "connectionFailed": "Failed to connect to Docker", + "containerStarted": "Container {{name}} started", + "failedToStartContainer": "Failed to start container {{name}}", + "containerStopped": "Container {{name}} stopped", + "failedToStopContainer": "Failed to stop container {{name}}", + "containerRestarted": "Container {{name}} restarted", + "failedToRestartContainer": "Failed to restart container {{name}}", + "containerPaused": "Container {{name}} paused", + "containerUnpaused": "Container {{name}} unpaused", + "failedToTogglePauseContainer": "Failed to toggle pause state for container {{name}}", + "containerRemoved": "Container {{name}} removed", + "failedToRemoveContainer": "Failed to remove container {{name}}", + "image": "Image", + "ports": "Ports", + "noPorts": "No ports", + "start": "Start", + "stop": "Stop", + "status": "Status", + "actions": "Actions", + "cardView": "Card view", + "listView": "List view", + "confirmRemoveContainer": "Are you sure you want to remove the container '{{name}}'? This action cannot be undone.", + "runningContainerWarning": "Warning: This container is currently running. Removing it will stop the container first.", + "loadingContainers": "Loading containers...", + "manager": "Docker Manager", + "autoRefresh": "Auto Refresh", + "timestamps": "Timestamps", + "lines": "Lines", + "filterLogs": "Filter logs...", + "refresh": "Refresh", + "download": "Download", + "clear": "Clear", + "logsDownloaded": "Logs downloaded successfully", + "last50": "Last 50", + "last100": "Last 100", + "last500": "Last 500", + "last1000": "Last 1000", + "allLogs": "All Logs", + "noLogsMatching": "No logs matching \"{{query}}\"", + "noLogsAvailable": "No logs available", + "noContainersFound": "No containers found", + "noContainersFoundHint": "No Docker containers are available on this host", + "searchPlaceholder": "Search containers...", + "allStatuses": "All Statuses", + "stateRunning": "Running", + "statePaused": "Paused", + "stateExited": "Exited", + "stateRestarting": "Restarting", + "noContainersMatchFilters": "No containers match your filters", + "noContainersMatchFiltersHint": "Try adjusting your search or filter criteria", + "failedToFetchStats": "Failed to fetch container statistics", + "containerNotRunning": "Container not running", + "startContainerToViewStats": "Start the container to view statistics", + "loadingStats": "Loading statistics...", + "errorLoadingStats": "Error loading statistics", + "noStatsAvailable": "No statistics available", + "cpuUsage": "CPU Usage", + "current": "Current", + "memoryUsage": "Memory Usage", + "networkIo": "Network I/O", + "input": "Input", + "output": "Output", + "blockIo": "Block I/O", + "read": "Read", + "write": "Write", + "pids": "PIDs", + "containerInformation": "Container Information", + "name": "Name", + "id": "ID", + "state": "State", + "containerMustBeRunning": "Container must be running to access console", + "verificationCodePrompt": "Enter verification code", + "totpVerificationFailed": "TOTP verification failed. Please try again.", + "browserSignInFailed": "Sign-in failed. Please try again.", + "connectedTo": "Connected to {{containerName}}", + "disconnected": "Disconnected", + "consoleError": "Console error", + "errorMessage": "Error: {{message}}", + "failedToConnect": "Failed to connect to container", + "console": "Console", + "selectShell": "Select shell", + "bash": "Bash", + "sh": "sh", + "ash": "ash", + "connect": "Connect", + "disconnect": "Disconnect", + "notConnected": "Not connected", + "clickToConnect": "Click connect to start a shell session", + "connectingTo": "Connecting to {{containerName}}...", + "containerNotFound": "Container not found", + "backToList": "Back to List", + "logs": "Logs", + "stats": "Stats", + "consoleTab": "Console", + "startContainerToAccess": "Start the container to access the console", + "noHostSelected": "No host selected", + "failedToFetchLogs": "Failed to fetch logs: {{error}}", + "failedToDownloadLogs": "Failed to download logs: {{error}}" }, "nav": { - "docker": "Докер" + "docker": "Docker" }, "onboarding": { - "feature_docker": "Докер", - "feature_docker_desc": "Погледајте контејнере, читајте логове и пратите статистику на било ком хосту који користи Docker." + "feature_docker": "Docker", + "feature_docker_desc": "See containers, read logs and watch stats on any host running Docker." + }, + "terminal": { + "retry": "Retry", + "clipboardReadFailed": "Failed to read from clipboard. Make sure clipboard permissions are granted.", + "clipboardWriteFailed": "Failed to copy to clipboard. Make sure the page is served over HTTPS or localhost." + }, + "permissions": { + "use": { + "title": "Use Docker", + "description": "Open the Docker manager and container consoles on hosts with Docker enabled." + } }, "settings": { "host": { "enable": { - "label": "Омогући Докер" + "label": "Enable Docker", + "description": "Manage containers on this host." }, "containerRuntime": { - "label": "Време извршавања контејнера", - "description": "Изаберите CLI који се користи за управљање контејнерима на овом хосту", - "docker": "Докер", - "podman": "Подман" + "label": "Container Runtime", + "description": "Choose the CLI used for container management on this host", + "docker": "Docker", + "podman": "Podman" } } }, "errors": { - "remoteServerRequired": "Потребан је удаљени сервер. Повежите се са удаљеним сервером у Подешавањима да бисте користили овај тип везе." + "remoteServerRequired": "Remote server required. Connect a remote server in Settings to use this connection type." }, "hosts": { - "docsLink": "Прикажи документе", - "hostNotFound": "Хост није пронађен", - "loadingHost": "Учитавање хоста..." - }, - "terminal": { - "clipboardReadFailed": "Читање из међуспремника није успело. Уверите се да су дозволе за међуспремник одобрене.", - "clipboardWriteFailed": "Копирање у међуспремник није успело. Уверите се да се страница приказује преко HTTPS-а или localhost-а." + "docsLink": "View docs", + "hostNotFound": "Host not found", + "loadingHost": "Loading host..." } } diff --git a/plugins/docker/locales/translated/sv_SE.json b/plugins/docker/locales/translated/sv_SE.json index 302c82793..631c3a919 100644 --- a/plugins/docker/locales/translated/sv_SE.json +++ b/plugins/docker/locales/translated/sv_SE.json @@ -1,130 +1,147 @@ { "docker": { - "notEnabled": "Docker är inte aktiverat för den här värden", - "validating": "Validerar Docker...", - "connecting": "Ansluter...", - "error": "Fel", + "notEnabled": "Docker is not enabled for this host", + "validating": "Validating Docker...", + "connecting": "Connecting...", + "error": "Error", "version": "{{runtime}} {{version}}", - "connectionFailed": "Misslyckades med att ansluta till Docker", - "containerStarted": "Behållaren {{name}} startad", - "failedToStartContainer": "Misslyckades med att starta containern {{name}}", - "containerStopped": "Behållaren {{name}} har stoppats", - "failedToStopContainer": "Misslyckades med att stoppa containern {{name}}", - "containerRestarted": "Behållaren {{name}} har startats om", - "failedToRestartContainer": "Misslyckades med att starta om behållaren {{name}}", - "containerPaused": "Behållaren {{name}} pausad", - "containerUnpaused": "Behållaren {{name}} har återupptagits", - "failedToTogglePauseContainer": "Misslyckades med att växla pausläge för container {{name}}", - "containerRemoved": "Behållaren {{name}} har tagits bort", - "failedToRemoveContainer": "Misslyckades med att ta bort behållaren {{name}}", - "image": "Bild", - "ports": "Hamnar", - "noPorts": "Inga portar", + "connectionFailed": "Failed to connect to Docker", + "containerStarted": "Container {{name}} started", + "failedToStartContainer": "Failed to start container {{name}}", + "containerStopped": "Container {{name}} stopped", + "failedToStopContainer": "Failed to stop container {{name}}", + "containerRestarted": "Container {{name}} restarted", + "failedToRestartContainer": "Failed to restart container {{name}}", + "containerPaused": "Container {{name}} paused", + "containerUnpaused": "Container {{name}} unpaused", + "failedToTogglePauseContainer": "Failed to toggle pause state for container {{name}}", + "containerRemoved": "Container {{name}} removed", + "failedToRemoveContainer": "Failed to remove container {{name}}", + "image": "Image", + "ports": "Ports", + "noPorts": "No ports", "start": "Start", - "confirmRemoveContainer": "Är du säker på att du vill ta bort behållaren '{{name}}'? Den här åtgärden kan inte ångras.", - "runningContainerWarning": "Varning: Den här behållaren körs för närvarande. Om du tar bort den stoppas behållaren först.", - "loadingContainers": "Lastar containrar...", + "stop": "Stop", + "status": "Status", + "actions": "Actions", + "cardView": "Card view", + "listView": "List view", + "confirmRemoveContainer": "Are you sure you want to remove the container '{{name}}'? This action cannot be undone.", + "runningContainerWarning": "Warning: This container is currently running. Removing it will stop the container first.", + "loadingContainers": "Loading containers...", "manager": "Docker Manager", - "autoRefresh": "Automatisk uppdatering", - "timestamps": "Tidsstämplar", - "lines": "Rader", - "filterLogs": "Filtrera loggar...", - "refresh": "Uppdatera", - "download": "Ladda ner", - "clear": "Rensa", - "logsDownloaded": "Loggarna har laddats ner", - "last50": "Senaste 50", - "last100": "Senaste 100", - "last500": "Senaste 500", - "last1000": "Senaste 1000", - "allLogs": "Alla loggar", - "noLogsMatching": "Inga loggar som matchar \"{{query}}\"", - "noLogsAvailable": "Inga loggar tillgängliga", - "noContainersFound": "Inga containrar hittades", - "noContainersFoundHint": "Inga Docker-containrar är tillgängliga på den här värden", - "searchPlaceholder": "Sök behållare...", - "allStatuses": "Alla statusar", - "stateRunning": "Spring", - "statePaused": "Pausad", - "stateExited": "Avslutad", - "stateRestarting": "Omstart", - "noContainersMatchFilters": "Inga behållare matchar dina filter", - "noContainersMatchFiltersHint": "Försök att justera dina sök- eller filterkriterier", - "failedToFetchStats": "Misslyckades med att hämta containerstatistik", - "containerNotRunning": "Behållaren körs inte", - "startContainerToViewStats": "Starta containern för att visa statistik", - "loadingStats": "Laddar statistik...", - "errorLoadingStats": "Fel vid inläsning av statistik", - "noStatsAvailable": "Ingen statistik tillgänglig", - "cpuUsage": "CPU-användning", - "current": "Nuvarande", - "memoryUsage": "Minnesanvändning", - "networkIo": "Nätverks-I/O", + "autoRefresh": "Auto Refresh", + "timestamps": "Timestamps", + "lines": "Lines", + "filterLogs": "Filter logs...", + "refresh": "Refresh", + "download": "Download", + "clear": "Clear", + "logsDownloaded": "Logs downloaded successfully", + "last50": "Last 50", + "last100": "Last 100", + "last500": "Last 500", + "last1000": "Last 1000", + "allLogs": "All Logs", + "noLogsMatching": "No logs matching \"{{query}}\"", + "noLogsAvailable": "No logs available", + "noContainersFound": "No containers found", + "noContainersFoundHint": "No Docker containers are available on this host", + "searchPlaceholder": "Search containers...", + "allStatuses": "All Statuses", + "stateRunning": "Running", + "statePaused": "Paused", + "stateExited": "Exited", + "stateRestarting": "Restarting", + "noContainersMatchFilters": "No containers match your filters", + "noContainersMatchFiltersHint": "Try adjusting your search or filter criteria", + "failedToFetchStats": "Failed to fetch container statistics", + "containerNotRunning": "Container not running", + "startContainerToViewStats": "Start the container to view statistics", + "loadingStats": "Loading statistics...", + "errorLoadingStats": "Error loading statistics", + "noStatsAvailable": "No statistics available", + "cpuUsage": "CPU Usage", + "current": "Current", + "memoryUsage": "Memory Usage", + "networkIo": "Network I/O", "input": "Input", - "output": "Produktion", - "blockIo": "Blockera I/O", - "read": "Läsa", - "write": "Skriva", - "pids": "PID:er", - "containerInformation": "Containerinformation", - "name": "Namn", + "output": "Output", + "blockIo": "Block I/O", + "read": "Read", + "write": "Write", + "pids": "PIDs", + "containerInformation": "Container Information", + "name": "Name", "id": "ID", - "state": "Ange", - "containerMustBeRunning": "Behållaren måste köras för att komma åt konsolen", - "verificationCodePrompt": "Ange verifieringskod", - "totpVerificationFailed": "TOTP-verifieringen misslyckades. Försök igen.", - "connectedTo": "Ansluten till {{containerName}}", - "disconnected": "Osammanhängande", - "consoleError": "Konsolfel", - "errorMessage": "Fel: {{message}}", - "failedToConnect": "Misslyckades med att ansluta till containern", - "console": "Trösta", - "selectShell": "Välj skal", - "bash": "Våldsamt slag", + "state": "State", + "containerMustBeRunning": "Container must be running to access console", + "verificationCodePrompt": "Enter verification code", + "totpVerificationFailed": "TOTP verification failed. Please try again.", + "browserSignInFailed": "Sign-in failed. Please try again.", + "connectedTo": "Connected to {{containerName}}", + "disconnected": "Disconnected", + "consoleError": "Console error", + "errorMessage": "Error: {{message}}", + "failedToConnect": "Failed to connect to container", + "console": "Console", + "selectShell": "Select shell", + "bash": "Bash", "sh": "sh", - "ash": "aska", - "connect": "Ansluta", - "disconnect": "Koppla från", - "notConnected": "Inte ansluten", - "clickToConnect": "Klicka på Anslut för att starta en shell-session", - "connectingTo": "Ansluter till {{containerName}}...", - "containerNotFound": "Behållaren hittades inte", - "backToList": "Tillbaka till listan", - "logs": "Loggar", - "stats": "Statistik", - "consoleTab": "Trösta", - "startContainerToAccess": "Starta containern för att komma åt konsolen" + "ash": "ash", + "connect": "Connect", + "disconnect": "Disconnect", + "notConnected": "Not connected", + "clickToConnect": "Click connect to start a shell session", + "connectingTo": "Connecting to {{containerName}}...", + "containerNotFound": "Container not found", + "backToList": "Back to List", + "logs": "Logs", + "stats": "Stats", + "consoleTab": "Console", + "startContainerToAccess": "Start the container to access the console", + "noHostSelected": "No host selected", + "failedToFetchLogs": "Failed to fetch logs: {{error}}", + "failedToDownloadLogs": "Failed to download logs: {{error}}" }, "nav": { - "docker": "Hamnarbetare" + "docker": "Docker" }, "onboarding": { - "feature_docker": "Hamnarbetare", - "feature_docker_desc": "Se containrar, läs loggar och titta på statistik för alla värdar som kör Docker." + "feature_docker": "Docker", + "feature_docker_desc": "See containers, read logs and watch stats on any host running Docker." + }, + "terminal": { + "retry": "Retry", + "clipboardReadFailed": "Failed to read from clipboard. Make sure clipboard permissions are granted.", + "clipboardWriteFailed": "Failed to copy to clipboard. Make sure the page is served over HTTPS or localhost." + }, + "permissions": { + "use": { + "title": "Use Docker", + "description": "Open the Docker manager and container consoles on hosts with Docker enabled." + } }, "settings": { "host": { "enable": { - "label": "Aktivera Docker" + "label": "Enable Docker", + "description": "Manage containers on this host." }, "containerRuntime": { - "label": "Containerkörningstid", - "description": "Välj det CRI som används för containerhantering på den här värden", - "docker": "Hamnarbetare", + "label": "Container Runtime", + "description": "Choose the CLI used for container management on this host", + "docker": "Docker", "podman": "Podman" } } }, "errors": { - "remoteServerRequired": "Fjärrserver krävs. Anslut en fjärrserver i Inställningar för att använda den här anslutningstypen." + "remoteServerRequired": "Remote server required. Connect a remote server in Settings to use this connection type." }, "hosts": { - "docsLink": "Visa dokument", - "hostNotFound": "Värden hittades inte", - "loadingHost": "Laddar värd..." - }, - "terminal": { - "clipboardReadFailed": "Kunde inte läsa från urklipp. Kontrollera att behörigheter för urklipp är beviljade.", - "clipboardWriteFailed": "Kunde inte kopiera till urklipp. Kontrollera att sidan serveras via HTTPS eller localhost." + "docsLink": "View docs", + "hostNotFound": "Host not found", + "loadingHost": "Loading host..." } } diff --git a/plugins/docker/locales/translated/th_TH.json b/plugins/docker/locales/translated/th_TH.json index 84e8edc11..631c3a919 100644 --- a/plugins/docker/locales/translated/th_TH.json +++ b/plugins/docker/locales/translated/th_TH.json @@ -1,130 +1,147 @@ { "docker": { - "notEnabled": "Docker ไม่ได้เปิดใช้งานสำหรับโฮสต์นี้", - "validating": "กำลังตรวจสอบความถูกต้องของ Docker...", - "connecting": "กำลังเชื่อมต่อ...", - "error": "ข้อผิดพลาด", + "notEnabled": "Docker is not enabled for this host", + "validating": "Validating Docker...", + "connecting": "Connecting...", + "error": "Error", "version": "{{runtime}} {{version}}", - "connectionFailed": "ไม่สามารถเชื่อมต่อกับ Docker ได้", - "containerStarted": "คอนเทนเนอร์ {{name}} เริ่มทำงานแล้ว", - "failedToStartContainer": "ไม่สามารถเริ่มต้นคอนเทนเนอร์ได้ {{name}}", - "containerStopped": "คอนเทนเนอร์ {{name}} หยุดทำงานแล้ว", - "failedToStopContainer": "ไม่สามารถหยุดคอนเทนเนอร์ได้ {{name}}", - "containerRestarted": "คอนเทนเนอร์ {{name}} รีสตาร์ทแล้ว", - "failedToRestartContainer": "ไม่สามารถรีสตาร์ทคอนเทนเนอร์ได้ {{name}}", - "containerPaused": "คอนเทนเนอร์ {{name}} หยุดชั่วคราว", - "containerUnpaused": "คอนเทนเนอร์ {{name}} ยกเลิกการหยุดชั่วคราว", - "failedToTogglePauseContainer": "ไม่สามารถสลับสถานะหยุดชั่วคราวสำหรับคอนเทนเนอร์ {{name}} ได้", - "containerRemoved": "คอนเทนเนอร์ {{name}} ถูกลบออกแล้ว", - "failedToRemoveContainer": "ไม่สามารถลบคอนเทนเนอร์ {{name}} ได้", - "image": "ภาพ", - "ports": "ท่าเรือ", - "noPorts": "ไม่มีพอร์ต", - "start": "เริ่ม", - "confirmRemoveContainer": "คุณแน่ใจหรือไม่ว่าต้องการลบคอนเทนเนอร์ '{{name}}'? การกระทำนี้ไม่สามารถย้อนกลับได้", - "runningContainerWarning": "คำเตือน: ขณะนี้คอนเทนเนอร์นี้กำลังทำงานอยู่ การลบคอนเทนเนอร์นี้จะหยุดการทำงานของคอนเทนเนอร์ก่อน", - "loadingContainers": "กำลังขนถ่ายตู้คอนเทนเนอร์...", - "manager": "ตัวจัดการ Docker", - "autoRefresh": "รีเฟรชอัตโนมัติ", - "timestamps": "ไทม์สแตมป์", - "lines": "เส้น", - "filterLogs": "กรองบันทึก...", - "refresh": "รีเฟรช", - "download": "ดาวน์โหลด", - "clear": "ชัดเจน", - "logsDownloaded": "ดาวน์โหลดบันทึกข้อมูลสำเร็จแล้ว", - "last50": "50 ครั้งสุดท้าย", - "last100": "100 ปีที่แล้ว", - "last500": "500 ครั้งสุดท้าย", - "last1000": "1000 ครั้งสุดท้าย", - "allLogs": "บันทึกทั้งหมด", - "noLogsMatching": "ไม่พบบันทึกใดที่ตรงกับ \"{{query}}\"", - "noLogsAvailable": "ไม่มีบันทึกข้อมูล", - "noContainersFound": "ไม่พบภาชนะบรรจุใดๆ", - "noContainersFoundHint": "ไม่มีคอนเทนเนอร์ Docker ให้บริการบนโฮสต์นี้", - "searchPlaceholder": "ค้นหาตู้คอนเทนเนอร์...", - "allStatuses": "สถานะทั้งหมด", - "stateRunning": "วิ่ง", - "statePaused": "หยุดชั่วคราว", - "stateExited": "ออกแล้ว", - "stateRestarting": "เริ่มใหม่อีกครั้ง", - "noContainersMatchFilters": "ไม่มีภาชนะใดตรงกับตัวกรองของคุณ", - "noContainersMatchFiltersHint": "ลองปรับเกณฑ์การค้นหาหรือตัวกรองของคุณดู", - "failedToFetchStats": "ไม่สามารถดึงข้อมูลสถิติของคอนเทนเนอร์ได้", - "containerNotRunning": "คอนเทนเนอร์ไม่ทำงาน", - "startContainerToViewStats": "เริ่มคอนเทนเนอร์เพื่อดูสถิติ", - "loadingStats": "กำลังโหลดสถิติ...", - "errorLoadingStats": "ข้อผิดพลาดในการโหลดสถิติ", - "noStatsAvailable": "ไม่มีสถิติให้ดู", - "cpuUsage": "การใช้งาน CPU", - "current": "ปัจจุบัน", - "memoryUsage": "การใช้งานหน่วยความจำ", - "networkIo": "อินพุต/เอาต์พุตเครือข่าย", - "input": "ป้อนข้อมูล", - "output": "เอาต์พุต", - "blockIo": "บล็อก I/O", - "read": "อ่าน", - "write": "เขียน", + "connectionFailed": "Failed to connect to Docker", + "containerStarted": "Container {{name}} started", + "failedToStartContainer": "Failed to start container {{name}}", + "containerStopped": "Container {{name}} stopped", + "failedToStopContainer": "Failed to stop container {{name}}", + "containerRestarted": "Container {{name}} restarted", + "failedToRestartContainer": "Failed to restart container {{name}}", + "containerPaused": "Container {{name}} paused", + "containerUnpaused": "Container {{name}} unpaused", + "failedToTogglePauseContainer": "Failed to toggle pause state for container {{name}}", + "containerRemoved": "Container {{name}} removed", + "failedToRemoveContainer": "Failed to remove container {{name}}", + "image": "Image", + "ports": "Ports", + "noPorts": "No ports", + "start": "Start", + "stop": "Stop", + "status": "Status", + "actions": "Actions", + "cardView": "Card view", + "listView": "List view", + "confirmRemoveContainer": "Are you sure you want to remove the container '{{name}}'? This action cannot be undone.", + "runningContainerWarning": "Warning: This container is currently running. Removing it will stop the container first.", + "loadingContainers": "Loading containers...", + "manager": "Docker Manager", + "autoRefresh": "Auto Refresh", + "timestamps": "Timestamps", + "lines": "Lines", + "filterLogs": "Filter logs...", + "refresh": "Refresh", + "download": "Download", + "clear": "Clear", + "logsDownloaded": "Logs downloaded successfully", + "last50": "Last 50", + "last100": "Last 100", + "last500": "Last 500", + "last1000": "Last 1000", + "allLogs": "All Logs", + "noLogsMatching": "No logs matching \"{{query}}\"", + "noLogsAvailable": "No logs available", + "noContainersFound": "No containers found", + "noContainersFoundHint": "No Docker containers are available on this host", + "searchPlaceholder": "Search containers...", + "allStatuses": "All Statuses", + "stateRunning": "Running", + "statePaused": "Paused", + "stateExited": "Exited", + "stateRestarting": "Restarting", + "noContainersMatchFilters": "No containers match your filters", + "noContainersMatchFiltersHint": "Try adjusting your search or filter criteria", + "failedToFetchStats": "Failed to fetch container statistics", + "containerNotRunning": "Container not running", + "startContainerToViewStats": "Start the container to view statistics", + "loadingStats": "Loading statistics...", + "errorLoadingStats": "Error loading statistics", + "noStatsAvailable": "No statistics available", + "cpuUsage": "CPU Usage", + "current": "Current", + "memoryUsage": "Memory Usage", + "networkIo": "Network I/O", + "input": "Input", + "output": "Output", + "blockIo": "Block I/O", + "read": "Read", + "write": "Write", "pids": "PIDs", - "containerInformation": "ข้อมูลเกี่ยวกับตู้คอนเทนเนอร์", - "name": "ชื่อ", - "id": "รหัสประจำตัว", - "state": "สถานะ", - "containerMustBeRunning": "ต้องเปิดใช้งานคอนเทนเนอร์ก่อนจึงจะสามารถเข้าถึงคอนโซลได้", - "verificationCodePrompt": "ป้อนรหัสยืนยัน", - "totpVerificationFailed": "การตรวจสอบ TOTP ล้มเหลว โปรดลองอีกครั้ง", - "connectedTo": "เชื่อมต่อกับ {{containerName}}", - "disconnected": "ตัดการเชื่อมต่อ", - "consoleError": "ข้อผิดพลาดของคอนโซล", - "errorMessage": "ข้อผิดพลาด: {{message}}", - "failedToConnect": "ไม่สามารถเชื่อมต่อกับคอนเทนเนอร์ได้", - "console": "คอนโซล", - "selectShell": "เลือกเปลือกหอย", - "bash": "ทุบตี", - "sh": "ช", - "ash": "เถ้า", - "connect": "เชื่อมต่อ", - "disconnect": "ตัดการเชื่อมต่อ", - "notConnected": "ไม่ได้เชื่อมต่อ", - "clickToConnect": "คลิกเชื่อมต่อเพื่อเริ่มเซสชันเชลล์", - "connectingTo": "กำลังเชื่อมต่อกับ {{containerName}}...", - "containerNotFound": "ไม่พบคอนเทนเนอร์", - "backToList": "กลับสู่รายการ", - "logs": "บันทึก", - "stats": "สถิติ", - "consoleTab": "คอนโซล", - "startContainerToAccess": "เริ่มคอนเทนเนอร์เพื่อเข้าถึงคอนโซล" + "containerInformation": "Container Information", + "name": "Name", + "id": "ID", + "state": "State", + "containerMustBeRunning": "Container must be running to access console", + "verificationCodePrompt": "Enter verification code", + "totpVerificationFailed": "TOTP verification failed. Please try again.", + "browserSignInFailed": "Sign-in failed. Please try again.", + "connectedTo": "Connected to {{containerName}}", + "disconnected": "Disconnected", + "consoleError": "Console error", + "errorMessage": "Error: {{message}}", + "failedToConnect": "Failed to connect to container", + "console": "Console", + "selectShell": "Select shell", + "bash": "Bash", + "sh": "sh", + "ash": "ash", + "connect": "Connect", + "disconnect": "Disconnect", + "notConnected": "Not connected", + "clickToConnect": "Click connect to start a shell session", + "connectingTo": "Connecting to {{containerName}}...", + "containerNotFound": "Container not found", + "backToList": "Back to List", + "logs": "Logs", + "stats": "Stats", + "consoleTab": "Console", + "startContainerToAccess": "Start the container to access the console", + "noHostSelected": "No host selected", + "failedToFetchLogs": "Failed to fetch logs: {{error}}", + "failedToDownloadLogs": "Failed to download logs: {{error}}" }, "nav": { - "docker": "ด็อกเกอร์" + "docker": "Docker" }, "onboarding": { - "feature_docker": "ด็อกเกอร์", - "feature_docker_desc": "ดูคอนเทนเนอร์ อ่านบันทึก และตรวจสอบสถิติบนโฮสต์ใดก็ได้ที่ใช้งาน Docker" + "feature_docker": "Docker", + "feature_docker_desc": "See containers, read logs and watch stats on any host running Docker." + }, + "terminal": { + "retry": "Retry", + "clipboardReadFailed": "Failed to read from clipboard. Make sure clipboard permissions are granted.", + "clipboardWriteFailed": "Failed to copy to clipboard. Make sure the page is served over HTTPS or localhost." + }, + "permissions": { + "use": { + "title": "Use Docker", + "description": "Open the Docker manager and container consoles on hosts with Docker enabled." + } }, "settings": { "host": { "enable": { - "label": "เปิดใช้งาน Docker" + "label": "Enable Docker", + "description": "Manage containers on this host." }, "containerRuntime": { - "label": "รันไทม์คอนเทนเนอร์", - "description": "เลือก CLI ที่ใช้สำหรับการจัดการคอนเทนเนอร์บนโฮสต์นี้", - "docker": "ด็อกเกอร์", - "podman": "พอดแมน" + "label": "Container Runtime", + "description": "Choose the CLI used for container management on this host", + "docker": "Docker", + "podman": "Podman" } } }, "errors": { - "remoteServerRequired": "จำเป็นต้องใช้เซิร์ฟเวอร์ระยะไกล เชื่อมต่อเซิร์ฟเวอร์ระยะไกลในการตั้งค่าเพื่อใช้ประเภทการเชื่อมต่อนี้" + "remoteServerRequired": "Remote server required. Connect a remote server in Settings to use this connection type." }, "hosts": { - "docsLink": "ดูเอกสาร", - "hostNotFound": "ไม่พบโฮสต์", - "loadingHost": "กำลังโหลดโฮสต์..." - }, - "terminal": { - "clipboardReadFailed": "ไม่สามารถอ่านข้อมูลจากคลิปบอร์ดได้ โปรดตรวจสอบให้แน่ใจว่าได้ให้สิทธิ์การเข้าถึงคลิปบอร์ดแล้ว", - "clipboardWriteFailed": "ไม่สามารถคัดลอกไปยังคลิปบอร์ดได้ โปรดตรวจสอบให้แน่ใจว่าหน้าเว็บนั้นให้บริการผ่าน HTTPS หรือ localhost" + "docsLink": "View docs", + "hostNotFound": "Host not found", + "loadingHost": "Loading host..." } } diff --git a/plugins/docker/locales/translated/tr_TR.json b/plugins/docker/locales/translated/tr_TR.json index 7a9eff0eb..2624361ab 100644 --- a/plugins/docker/locales/translated/tr_TR.json +++ b/plugins/docker/locales/translated/tr_TR.json @@ -21,6 +21,11 @@ "ports": "Portlar", "noPorts": "Port yok", "start": "Başlat", + "stop": "Durdurma", + "status": "Durum", + "actions": "Actions", + "cardView": "Card view", + "listView": "List view", "confirmRemoveContainer": "'{{name}}' konteynerini kaldırmak istediğinizden emin misiniz? Bu işlem geri alınamaz.", "runningContainerWarning": "Uyarı: Bu konteyner şu anda çalışıyor. Kaldırma işlemi önce konteyneri durduracak.", "loadingContainers": "Konteynerler yükleniyor...", @@ -73,6 +78,7 @@ "containerMustBeRunning": "Konsola erişmek için konteyner çalışıyor olmalıdır", "verificationCodePrompt": "Doğrulama kodunu girin", "totpVerificationFailed": "TOTP doğrulaması başarısız oldu. Lütfen tekrar deneyin.", + "browserSignInFailed": "Sign-in failed. Please try again.", "connectedTo": "{{containerName}} ile bağlantı kuruldu", "disconnected": "Bağlantı kesildi", "consoleError": "Konsol hatası", @@ -93,19 +99,34 @@ "logs": "Günlükler", "stats": "İstatistikler", "consoleTab": "Konsol", - "startContainerToAccess": "Konsola erişmek için konteyneri başlatın" + "startContainerToAccess": "Konsola erişmek için konteyneri başlatın", + "noHostSelected": "Sunucu seçilmedi", + "failedToFetchLogs": "Failed to fetch logs: {{error}}", + "failedToDownloadLogs": "Failed to download logs: {{error}}" }, "nav": { "docker": "Docker" }, "onboarding": { - "feature_docker": "Liman işçisi", - "feature_docker_desc": "Docker çalıştıran herhangi bir sunucudaki konteynerleri görüntüleyin, günlükleri okuyun ve istatistikleri izleyin." + "feature_docker": "Docker", + "feature_docker_desc": "See containers, read logs and watch stats on any host running Docker." + }, + "terminal": { + "retry": "Yeniden dene", + "clipboardReadFailed": "Panodan okuma başarısız oldu. Pano izinlerinin verildiğinden emin olun.", + "clipboardWriteFailed": "Panoya kopyalama başarısız oldu. Sayfanın HTTPS veya localhost üzerinden sunulduğundan emin olun." + }, + "permissions": { + "use": { + "title": "Use Docker", + "description": "Open the Docker manager and container consoles on hosts with Docker enabled." + } }, "settings": { "host": { "enable": { - "label": "Docker'ı Etkinleştir" + "label": "Docker'ı Etkinleştir", + "description": "Manage containers on this host." }, "containerRuntime": { "label": "Kapsayıcı Çalışma Zamanı", @@ -116,15 +137,11 @@ } }, "errors": { - "remoteServerRequired": "Uzak sunucu gereklidir. Bu bağlantı türünü kullanmak için Ayarlar'dan bir uzak sunucu bağlayın." + "remoteServerRequired": "Remote server required. Connect a remote server in Settings to use this connection type." }, "hosts": { "docsLink": "Dokümanları görüntüle", "hostNotFound": "Host bulunamadı", "loadingHost": "Host yükleniyor..." - }, - "terminal": { - "clipboardReadFailed": "Panodan okuma başarısız oldu. Pano izinlerinin verildiğinden emin olun.", - "clipboardWriteFailed": "Panoya kopyalama başarısız oldu. Sayfanın HTTPS veya localhost üzerinden sunulduğundan emin olun." } } diff --git a/plugins/docker/locales/translated/uk_UA.json b/plugins/docker/locales/translated/uk_UA.json index d7c3488b9..631c3a919 100644 --- a/plugins/docker/locales/translated/uk_UA.json +++ b/plugins/docker/locales/translated/uk_UA.json @@ -1,130 +1,147 @@ { "docker": { - "notEnabled": "Docker не ввімкнено для цього хоста", - "validating": "Перевірка Docker...", - "connecting": "Підключення...", - "error": "Помилка", + "notEnabled": "Docker is not enabled for this host", + "validating": "Validating Docker...", + "connecting": "Connecting...", + "error": "Error", "version": "{{runtime}} {{version}}", - "connectionFailed": "Не вдалося підключитися до Docker", - "containerStarted": "Контейнер {{name}} запущено", - "failedToStartContainer": "Не вдалося запустити контейнер {{name}}", - "containerStopped": "Контейнер {{name}} зупинено", - "failedToStopContainer": "Не вдалося зупинити контейнер {{name}}", - "containerRestarted": "Контейнер {{name}} перезапущено", - "failedToRestartContainer": "Не вдалося перезапустити контейнер {{name}}", - "containerPaused": "Контейнер {{name}} призупинено", - "containerUnpaused": "Контейнер {{name}} відновлено", - "failedToTogglePauseContainer": "Не вдалося перемкнути стан паузи для контейнера {{name}}", - "containerRemoved": "Контейнер {{name}} видалено", - "failedToRemoveContainer": "Не вдалося видалити контейнер {{name}}", - "image": "Зображення", - "ports": "Порти", - "noPorts": "Без портів", - "start": "Початок", - "confirmRemoveContainer": "Ви впевнені, що хочете видалити контейнер '{{name}}'? Цю дію неможливо скасувати.", - "runningContainerWarning": "Попередження: Цей контейнер зараз працює. Його видалення спочатку зупинить його роботу.", - "loadingContainers": "Завантаження контейнерів...", - "manager": "Менеджер Докера", - "autoRefresh": "Автоматичне оновлення", - "timestamps": "Позначки часу", - "lines": "Лінії", - "filterLogs": "Фільтрувати журнали...", - "refresh": "Оновити", - "download": "Завантажити", - "clear": "Очистити", - "logsDownloaded": "Журнали успішно завантажено", - "last50": "Останні 50", - "last100": "Останні 100", - "last500": "Останні 500", - "last1000": "Останні 1000", - "allLogs": "Усі журнали", - "noLogsMatching": "Немає журналів, що відповідають \"{{query}}\"", - "noLogsAvailable": "Журнали недоступні", - "noContainersFound": "Контейнерів не знайдено", - "noContainersFoundHint": "На цьому хості немає доступних контейнерів Docker", - "searchPlaceholder": "Пошук контейнерів...", - "allStatuses": "Усі статуси", - "stateRunning": "Біг", - "statePaused": "Призупинено", - "stateExited": "Вихід", - "stateRestarting": "Перезапуск", - "noContainersMatchFilters": "Немає контейнерів, що відповідають вашим фільтрам", - "noContainersMatchFiltersHint": "Спробуйте змінити критерії пошуку або фільтра", - "failedToFetchStats": "Не вдалося отримати статистику контейнера", - "containerNotRunning": "Контейнер не працює", - "startContainerToViewStats": "Запустіть контейнер для перегляду статистики", - "loadingStats": "Завантаження статистики...", - "errorLoadingStats": "Помилка завантаження статистики", - "noStatsAvailable": "Статистика недоступна", - "cpuUsage": "Використання процесора", - "current": "Поточний", - "memoryUsage": "Використання пам'яті", - "networkIo": "Мережевий ввід/вивід", - "input": "Вхід", - "output": "Вихід", - "blockIo": "Блок вводу/виводу", - "read": "Читати", - "write": "Написати", - "pids": "PID-ідентифікатори", - "containerInformation": "Інформація про контейнер", - "name": "Ім'я", - "id": "Ідентифікатор", - "state": "Штат", - "containerMustBeRunning": "Для доступу до консолі контейнер має бути запущений", - "verificationCodePrompt": "Введіть код підтвердження", - "totpVerificationFailed": "Не вдалося перевірити TOTP. Спробуйте ще раз.", - "connectedTo": "Підключено до {{containerName}}", - "disconnected": "Відключено", - "consoleError": "Помилка консолі", - "errorMessage": "Помилка: {{message}}", - "failedToConnect": "Не вдалося підключитися до контейнера", - "console": "Консоль", - "selectShell": "Виберіть оболонку", - "bash": "Баш", - "sh": "ш", - "ash": "попіл", - "connect": "Підключитися", - "disconnect": "Відключитися", - "notConnected": "Не підключено", - "clickToConnect": "Натисніть кнопку «Підключитися», щоб розпочати сеанс оболонки", - "connectingTo": "Підключення до {{containerName}}...", - "containerNotFound": "Контейнер не знайдено", - "backToList": "Назад до списку", - "logs": "Журнали", - "stats": "Статистика", - "consoleTab": "Консоль", - "startContainerToAccess": "Запустіть контейнер для доступу до консолі" + "connectionFailed": "Failed to connect to Docker", + "containerStarted": "Container {{name}} started", + "failedToStartContainer": "Failed to start container {{name}}", + "containerStopped": "Container {{name}} stopped", + "failedToStopContainer": "Failed to stop container {{name}}", + "containerRestarted": "Container {{name}} restarted", + "failedToRestartContainer": "Failed to restart container {{name}}", + "containerPaused": "Container {{name}} paused", + "containerUnpaused": "Container {{name}} unpaused", + "failedToTogglePauseContainer": "Failed to toggle pause state for container {{name}}", + "containerRemoved": "Container {{name}} removed", + "failedToRemoveContainer": "Failed to remove container {{name}}", + "image": "Image", + "ports": "Ports", + "noPorts": "No ports", + "start": "Start", + "stop": "Stop", + "status": "Status", + "actions": "Actions", + "cardView": "Card view", + "listView": "List view", + "confirmRemoveContainer": "Are you sure you want to remove the container '{{name}}'? This action cannot be undone.", + "runningContainerWarning": "Warning: This container is currently running. Removing it will stop the container first.", + "loadingContainers": "Loading containers...", + "manager": "Docker Manager", + "autoRefresh": "Auto Refresh", + "timestamps": "Timestamps", + "lines": "Lines", + "filterLogs": "Filter logs...", + "refresh": "Refresh", + "download": "Download", + "clear": "Clear", + "logsDownloaded": "Logs downloaded successfully", + "last50": "Last 50", + "last100": "Last 100", + "last500": "Last 500", + "last1000": "Last 1000", + "allLogs": "All Logs", + "noLogsMatching": "No logs matching \"{{query}}\"", + "noLogsAvailable": "No logs available", + "noContainersFound": "No containers found", + "noContainersFoundHint": "No Docker containers are available on this host", + "searchPlaceholder": "Search containers...", + "allStatuses": "All Statuses", + "stateRunning": "Running", + "statePaused": "Paused", + "stateExited": "Exited", + "stateRestarting": "Restarting", + "noContainersMatchFilters": "No containers match your filters", + "noContainersMatchFiltersHint": "Try adjusting your search or filter criteria", + "failedToFetchStats": "Failed to fetch container statistics", + "containerNotRunning": "Container not running", + "startContainerToViewStats": "Start the container to view statistics", + "loadingStats": "Loading statistics...", + "errorLoadingStats": "Error loading statistics", + "noStatsAvailable": "No statistics available", + "cpuUsage": "CPU Usage", + "current": "Current", + "memoryUsage": "Memory Usage", + "networkIo": "Network I/O", + "input": "Input", + "output": "Output", + "blockIo": "Block I/O", + "read": "Read", + "write": "Write", + "pids": "PIDs", + "containerInformation": "Container Information", + "name": "Name", + "id": "ID", + "state": "State", + "containerMustBeRunning": "Container must be running to access console", + "verificationCodePrompt": "Enter verification code", + "totpVerificationFailed": "TOTP verification failed. Please try again.", + "browserSignInFailed": "Sign-in failed. Please try again.", + "connectedTo": "Connected to {{containerName}}", + "disconnected": "Disconnected", + "consoleError": "Console error", + "errorMessage": "Error: {{message}}", + "failedToConnect": "Failed to connect to container", + "console": "Console", + "selectShell": "Select shell", + "bash": "Bash", + "sh": "sh", + "ash": "ash", + "connect": "Connect", + "disconnect": "Disconnect", + "notConnected": "Not connected", + "clickToConnect": "Click connect to start a shell session", + "connectingTo": "Connecting to {{containerName}}...", + "containerNotFound": "Container not found", + "backToList": "Back to List", + "logs": "Logs", + "stats": "Stats", + "consoleTab": "Console", + "startContainerToAccess": "Start the container to access the console", + "noHostSelected": "No host selected", + "failedToFetchLogs": "Failed to fetch logs: {{error}}", + "failedToDownloadLogs": "Failed to download logs: {{error}}" }, "nav": { - "docker": "Докер" + "docker": "Docker" }, "onboarding": { - "feature_docker": "Докер", - "feature_docker_desc": "Переглядайте контейнери, читайте журнали та переглядайте статистику на будь-якому хості, на якому працює Docker." + "feature_docker": "Docker", + "feature_docker_desc": "See containers, read logs and watch stats on any host running Docker." + }, + "terminal": { + "retry": "Retry", + "clipboardReadFailed": "Failed to read from clipboard. Make sure clipboard permissions are granted.", + "clipboardWriteFailed": "Failed to copy to clipboard. Make sure the page is served over HTTPS or localhost." + }, + "permissions": { + "use": { + "title": "Use Docker", + "description": "Open the Docker manager and container consoles on hosts with Docker enabled." + } }, "settings": { "host": { "enable": { - "label": "Увімкнути Докер" + "label": "Enable Docker", + "description": "Manage containers on this host." }, "containerRuntime": { - "label": "Середовище виконання контейнера", - "description": "Виберіть інтерфейс командного рядка, який використовується для керування контейнерами на цьому хості", - "docker": "Докер", - "podman": "Подман" + "label": "Container Runtime", + "description": "Choose the CLI used for container management on this host", + "docker": "Docker", + "podman": "Podman" } } }, "errors": { - "remoteServerRequired": "Потрібен віддалений сервер. Підключіться до віддаленого сервера в налаштуваннях, щоб використовувати цей тип підключення." + "remoteServerRequired": "Remote server required. Connect a remote server in Settings to use this connection type." }, "hosts": { - "docsLink": "Переглянути документи", - "hostNotFound": "Хост не знайдено", - "loadingHost": "Завантаження хоста..." - }, - "terminal": { - "clipboardReadFailed": "Не вдалося прочитати з буфера обміну. Переконайтеся, що надано дозволи на доступ до буфера обміну.", - "clipboardWriteFailed": "Не вдалося скопіювати в буфер обміну. Переконайтеся, що сторінка обслуговується через HTTPS або localhost." + "docsLink": "View docs", + "hostNotFound": "Host not found", + "loadingHost": "Loading host..." } } diff --git a/plugins/docker/locales/translated/vi_VN.json b/plugins/docker/locales/translated/vi_VN.json index 9f8815520..793883141 100644 --- a/plugins/docker/locales/translated/vi_VN.json +++ b/plugins/docker/locales/translated/vi_VN.json @@ -21,6 +21,11 @@ "ports": "Cổng", "noPorts": "Không có cổng nào", "start": "Khởi động", + "stop": "Bit dừng", + "status": "Trạng thái", + "actions": "Actions", + "cardView": "Card view", + "listView": "List view", "confirmRemoveContainer": "Bạn có chắc chắn muốn xóa container '{{name}}' không? Hành động này không thể hoàn tác.", "runningContainerWarning": "Cảnh báo: Container này đang chạy. Xóa nó sẽ dừng container trước.", "loadingContainers": "Đang tải danh sách container...", @@ -73,6 +78,7 @@ "containerMustBeRunning": "Container phải đang chạy để truy cập bảng điều khiển", "verificationCodePrompt": "Nhập mã xác minh", "totpVerificationFailed": "Xác minh TOTP thất bại. Vui lòng thử lại.", + "browserSignInFailed": "Sign-in failed. Please try again.", "connectedTo": "Đã kết nối đến {{containerName}}", "disconnected": "Đã ngắt kết nối", "consoleError": "Lỗi bảng điều khiển", @@ -93,19 +99,34 @@ "logs": "Nhật ký", "stats": "Thống kê", "consoleTab": "Bảng điều khiển", - "startContainerToAccess": "Khởi động container để truy cập bảng điều khiển" + "startContainerToAccess": "Khởi động container để truy cập bảng điều khiển", + "noHostSelected": "Chưa chọn máy chủ", + "failedToFetchLogs": "Failed to fetch logs: {{error}}", + "failedToDownloadLogs": "Failed to download logs: {{error}}" }, "nav": { "docker": "Docker" }, "onboarding": { "feature_docker": "Docker", - "feature_docker_desc": "Xem các container, đọc nhật ký và theo dõi số liệu thống kê trên bất kỳ máy chủ nào đang chạy Docker." + "feature_docker_desc": "See containers, read logs and watch stats on any host running Docker." + }, + "terminal": { + "retry": "Thử lại", + "clipboardReadFailed": "Đọc từ clipboard thất bại. Đảm bảo quyền truy cập clipboard đã được cấp.", + "clipboardWriteFailed": "Sao chép vào clipboard thất bại. Đảm bảo trang được phục vụ qua HTTPS hoặc localhost." + }, + "permissions": { + "use": { + "title": "Use Docker", + "description": "Open the Docker manager and container consoles on hosts with Docker enabled." + } }, "settings": { "host": { "enable": { - "label": "Bật Docker" + "label": "Bật Docker", + "description": "Manage containers on this host." }, "containerRuntime": { "label": "Môi trường chạy container", @@ -116,15 +137,11 @@ } }, "errors": { - "remoteServerRequired": "Cần có máy chủ từ xa. Kết nối máy chủ từ xa trong Cài đặt để sử dụng loại kết nối này." + "remoteServerRequired": "Remote server required. Connect a remote server in Settings to use this connection type." }, "hosts": { "docsLink": "Xem tài liệu", "hostNotFound": "Không tìm thấy máy chủ", "loadingHost": "Đang tải máy chủ..." - }, - "terminal": { - "clipboardReadFailed": "Đọc từ clipboard thất bại. Đảm bảo quyền truy cập clipboard đã được cấp.", - "clipboardWriteFailed": "Sao chép vào clipboard thất bại. Đảm bảo trang được phục vụ qua HTTPS hoặc localhost." } } diff --git a/plugins/docker/locales/translated/zh_CN.json b/plugins/docker/locales/translated/zh_CN.json index 172869aac..e6a47976d 100644 --- a/plugins/docker/locales/translated/zh_CN.json +++ b/plugins/docker/locales/translated/zh_CN.json @@ -21,6 +21,11 @@ "ports": "端口", "noPorts": "无端口", "start": "启动", + "stop": "停止", + "status": "状态", + "actions": "操作", + "cardView": "卡片视图", + "listView": "列表视图", "confirmRemoveContainer": "确定要移除容器 '{{name}}' 吗?此操作无法撤销。", "runningContainerWarning": "警告:此容器正在运行。移除操作将先停止容器。", "loadingContainers": "正在加载容器...", @@ -65,7 +70,7 @@ "blockIo": "块 I/O", "read": "读取", "write": "写入", - "pids": "PIDs", + "pids": "进程 ID", "containerInformation": "容器信息", "name": "名称", "id": "ID", @@ -73,6 +78,7 @@ "containerMustBeRunning": "访问控制台需要容器处于运行状态", "verificationCodePrompt": "输入验证码", "totpVerificationFailed": "TOTP 验证失败,请重试。", + "browserSignInFailed": "登录失败,请重试。", "connectedTo": "已连接到 {{containerName}}", "disconnected": "已断开连接", "consoleError": "控制台错误", @@ -93,7 +99,10 @@ "logs": "日志", "stats": "统计", "consoleTab": "控制台", - "startContainerToAccess": "启动容器以访问控制台" + "startContainerToAccess": "启动容器以访问控制台", + "noHostSelected": "未选择主机", + "failedToFetchLogs": "获取日志失败:{{error}}", + "failedToDownloadLogs": "日志下载失败:{{error}}" }, "nav": { "docker": "Docker" @@ -102,10 +111,22 @@ "feature_docker": "Docker", "feature_docker_desc": "在任何运行 Docker 的主机上查看容器、读取日志及监控运行状态。" }, + "terminal": { + "retry": "重试", + "clipboardReadFailed": "从剪贴板读取失败。请确保已授予剪贴板权限。", + "clipboardWriteFailed": "复制到剪贴板失败。请确保页面通过 HTTPS 或 localhost 提供服务。" + }, + "permissions": { + "use": { + "title": "使用 Docker", + "description": "在启用了 Docker 的主机上打开 Docker 管理器和容器控制台。" + } + }, "settings": { "host": { "enable": { - "label": "启用 Docker" + "label": "启用 Docker", + "description": "管理此主机上的容器。" }, "containerRuntime": { "label": "容器运行时", @@ -116,15 +137,11 @@ } }, "errors": { - "remoteServerRequired": "需要远程服务器。请在“设置”中连接远程服务器以使用此连接类型。" + "remoteServerRequired": "需要远程服务器。请在设置中连接远程服务器以使用此连接类型。" }, "hosts": { "docsLink": "查看文档", "hostNotFound": "未找到主机", "loadingHost": "正在加载主机..." - }, - "terminal": { - "clipboardReadFailed": "从剪贴板读取失败。请确保已授予剪贴板权限。", - "clipboardWriteFailed": "复制到剪贴板失败。请确保页面通过 HTTPS 或 localhost 提供服务。" } } diff --git a/plugins/docker/locales/translated/zh_TW.json b/plugins/docker/locales/translated/zh_TW.json index e2f68d5c7..df863cecb 100644 --- a/plugins/docker/locales/translated/zh_TW.json +++ b/plugins/docker/locales/translated/zh_TW.json @@ -21,6 +21,11 @@ "ports": "連接埠", "noPorts": "無連接埠", "start": "啟動", + "stop": "停止位元", + "status": "狀態", + "actions": "Actions", + "cardView": "Card view", + "listView": "List view", "confirmRemoveContainer": "確定要移除容器 '{{name}}' 嗎?此動作無法復原。", "runningContainerWarning": "警告:此容器正在執行中。移除時會先將其停止。", "loadingContainers": "正在載入容器...", @@ -73,6 +78,7 @@ "containerMustBeRunning": "容器必須在執行中才能存取主控台", "verificationCodePrompt": "請輸入驗證碼", "totpVerificationFailed": "TOTP 驗證失敗,請再試一次。", + "browserSignInFailed": "Sign-in failed. Please try again.", "connectedTo": "已連線至 {{containerName}}", "disconnected": "已中斷連線", "consoleError": "主控台錯誤", @@ -93,19 +99,34 @@ "logs": "記錄", "stats": "統計資料", "consoleTab": "主控台", - "startContainerToAccess": "啟動容器以存取主控台" + "startContainerToAccess": "啟動容器以存取主控台", + "noHostSelected": "未選擇主機", + "failedToFetchLogs": "Failed to fetch logs: {{error}}", + "failedToDownloadLogs": "Failed to download logs: {{error}}" }, "nav": { "docker": "Docker" }, "onboarding": { "feature_docker": "Docker", - "feature_docker_desc": "查看執行 Docker 的任何主機上的容器、讀取日誌和查看統計資料。" + "feature_docker_desc": "See containers, read logs and watch stats on any host running Docker." + }, + "terminal": { + "retry": "重試", + "clipboardReadFailed": "從剪貼簿讀取失敗。請確認已授予剪貼簿權限。", + "clipboardWriteFailed": "複製到剪貼簿失敗。請確認頁面是透過 HTTPS 或 localhost 提供。" + }, + "permissions": { + "use": { + "title": "Use Docker", + "description": "Open the Docker manager and container consoles on hosts with Docker enabled." + } }, "settings": { "host": { "enable": { - "label": "啟用 Docker" + "label": "啟用 Docker", + "description": "Manage containers on this host." }, "containerRuntime": { "label": "容器執行環境", @@ -116,15 +137,11 @@ } }, "errors": { - "remoteServerRequired": "需要遠端伺服器。請在「設定」中連接遠端伺服器以使用此連線類型。" + "remoteServerRequired": "Remote server required. Connect a remote server in Settings to use this connection type." }, "hosts": { "docsLink": "檢視文件", "hostNotFound": "找不到主機", "loadingHost": "正在載入主機..." - }, - "terminal": { - "clipboardReadFailed": "從剪貼簿讀取失敗。請確認已授予剪貼簿權限。", - "clipboardWriteFailed": "複製到剪貼簿失敗。請確認頁面是透過 HTTPS 或 localhost 提供。" } } diff --git a/plugins/docker/src/backend/routes.ts b/plugins/docker/src/backend/routes.ts index b031d6f99..672d241d8 100644 --- a/plugins/docker/src/backend/routes.ts +++ b/plugins/docker/src/backend/routes.ts @@ -210,11 +210,13 @@ export function registerRoutes(router: Router, { ctx, sessions, log }: Deps) { ), ); - const target: PluginSshHost = { - ...host, - id: numericHostId, - port: host.port || 22, - }; + const hasAuthOverride = [ + userProvidedPassword, + userProvidedSshKey, + userProvidedKeyPassword, + ].some((value) => typeof value === "string" && value.length > 0); + // Core associates the redacted host object with its stored credentials. + const target: PluginSshHost = hasAuthOverride ? { ...host } : host; if (typeof userProvidedPassword === "string" && userProvidedPassword) { target.password = userProvidedPassword; target.authType = "password"; diff --git a/plugins/docker/tests/backend/routes.test.ts b/plugins/docker/tests/backend/routes.test.ts index 5a76e4754..f317be6f3 100644 --- a/plugins/docker/tests/backend/routes.test.ts +++ b/plugins/docker/tests/backend/routes.test.ts @@ -3,7 +3,7 @@ import type { PluginSshConnectOptions, PluginSshHost, } from "@termix/plugin-sdk/backend"; -import { startServer, type TestServer } from "./server"; +import { startServer, sshHost, type TestServer } from "./server"; import { FakeClient } from "./fake-ssh"; let server: TestServer | null = null; @@ -76,6 +76,41 @@ describe("docker routes", () => { expect((await connect(server, "s1", 99)).status).toBe(404); }); + it("keeps the core-resolved host identity when using stored credentials", async () => { + server = await startServer(); + const host = sshHost(7, { authType: "key", password: undefined }); + const originalConnect = server.mock.ctx.ssh.connect; + server.mock.ctx.ssh.resolveHost = async () => host; + server.mock.ctx.ssh.connect = (async (target, options) => { + if (target !== host) + throw new Error("Stored credential association lost"); + return originalConnect(target, options); + }) as typeof originalConnect; + const response = await connect(server); + expect(response.status).toBe(200); + expect(response.body.success).toBe(true); + }); + + it("applies explicit authentication overrides without changing the resolved host", async () => { + server = await startServer(); + const host = sshHost(7, { authType: "key", password: undefined }); + server.mock.ctx.ssh.resolveHost = async () => host; + const response = await server.request("POST", "/ssh/connect", { + body: { + sessionId: "override", + hostId: 7, + userProvidedPassword: "replacement", + }, + }); + expect(response.status).toBe(200); + expect(server.mock.sshConnections.at(-1)?.host).toMatchObject({ + authType: "password", + password: "replacement", + }); + expect(host.authType).toBe("key"); + expect(host.password).toBeUndefined(); + }); + it("connects, validates and manages containers on the session", async () => { server = await startServer(); const connected = await connect(server); diff --git a/plugins/file-manager/locales/en.json b/plugins/file-manager/locales/en.json index dc86761ce..e162e7c37 100644 --- a/plugins/file-manager/locales/en.json +++ b/plugins/file-manager/locales/en.json @@ -323,7 +323,7 @@ "sideBySide": "Side by Side", "inline": "Inline", "fileComparison": "File Comparison: {{file1}} vs {{file2}}", - "fileTooLarge": "File too large: {{error}}", + "fileTooLarge": "File is too large (> 10MB) and cannot be opened as text for security reasons.", "sshConnectionFailed": "SSH connection failed. Please check your connection to {{name}} ({{ip}}:{{port}})", "loadFileFailed": "Failed to load file: {{error}}", "connecting": "Connecting...", @@ -365,7 +365,7 @@ "comfortableLayout": "Use comfortable layout", "cannotLoadPdf": "Cannot load PDF", "pdfLoadError": "There was an error loading this PDF file.", - "loadingPdf": "Loading PDF...", + "loadingPdf": "Loading PDF viewer...", "loadingPage": "Loading page...", "cancel": "Cancel", "copiedItems_one": "Copied {{count}} item", @@ -383,7 +383,16 @@ "videoUnsupported": "Your browser cannot play this video format.", "downloadToPlay": "Download to play it elsewhere", "cannotPreviewType": "Cannot preview this file type", - "cannotPreviewTypeHint": "This file type has no preview. Download it to open it in another app." + "cannotPreviewTypeHint": "This file type has no preview. Download it to open it in another app.", + "loadingFile": "Loading file...", + "loadingImage": "Loading image...", + "loadingEditor": "Loading editor...", + "loadingPreview": "Loading preview...", + "loadingAudio": "Loading audio player...", + "emptyPreview": "Nothing to preview yet...", + "revert": "Revert", + "openAsText": "Open as Text", + "confirmOpenAsText": "Do you want to continue opening this file as text? This may slow down your browser." }, "sftpTransfer": { "title": "SFTP", @@ -539,5 +548,8 @@ "metricsHopSourceRead": "Source → server: {{throughput}}", "metricsHopDestSftpWrite": "Server → dest (SFTP): {{throughput}}", "metricsHopDestLocalWrite": "Server → dest (local): {{throughput}}" + }, + "plugin": { + "name": "File Manager" } } diff --git a/plugins/file-manager/locales/translated/af_ZA.json b/plugins/file-manager/locales/translated/af_ZA.json index fd4079049..3b38d9405 100644 --- a/plugins/file-manager/locales/translated/af_ZA.json +++ b/plugins/file-manager/locales/translated/af_ZA.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "Lêers", + "sftp": "SFTP", + "openFileManager": "Maak Lêerbestuurder oop" + }, + "permissions": { + "use": { + "title": "Gebruik lêerbestuurder", + "description": "Blaai, wysig en dra lêers oor SFTP oor." + } + }, + "settings": { + "host": { + "enable": { + "label": "Aktiveer Lêerbestuurder", + "description": "Blaai en wysig lêers op hierdie gasheer via SFTP." + }, + "defaultPath": { + "label": "Standaardpad" + }, + "scpLegacy": { + "label": "SCP Legacy-modus" + } + }, + "user": { + "transferConcurrency": { + "label": "Gelyktydige lêeroordragte", + "description": "Hoeveel lêers die sy-aan-sy plaaslike/afgeleë bestuurder gelyktydig oplaai of aflaai. Verlaag dit as jou bediener SFTP-kanale beperk." + }, + "confirmBeforeTrash": { + "label": "Bevestig voordat lêers na die asblik geskuif word", + "description": "Vra voordat afgeleë lêers na die asblik geskuif word. Permanente verwydering vereis steeds bevestiging." + } + } + }, + "hostCapability": { + "label": "Lêerbestuurder" + }, "fileManager": { "noHostSelected": "Geen gasheer gekies nie", "initializingEditor": "Inisialiseer redigeerder...", @@ -11,7 +49,7 @@ "archiveExtractedSuccessfully": "{{name}} suksesvol onttrek", "extractFailed": "Uittreksel het misluk", "compressFile": "Komprimeer lêer", - "compressFiles": "Kompresseer lêers", + "compressFiles": "Komprimeer lêers", "compressFilesDesc": "Kompresseer {{count}} items in 'n argief", "archiveName": "Argiefnaam", "enterArchiveName": "Voer argiefnaam in...", @@ -34,6 +72,7 @@ "rename": "Hernoem", "uploading": "Laai tans op...", "uploadingFile": "Laai tans {{name}} op ...", + "uploadingChunk": "Laai tans {{name}}op: {{percent}}% (deel {{chunk}} van {{total}})", "fileName": "Lêernaam", "folderName": "Vouernaam", "fileUploadedSuccessfully": "Lêer \"{{name}}\" is suksesvol opgelaai", @@ -41,7 +80,7 @@ "uploadingFolderFiles": "Laai tans {{count}} lêer(s) op...", "uploadedFolderFiles": "{{count}} lêer(s) suksesvol opgelaai", "uploadedFolderPartial": "Opgelaaide {{uploaded}} lêer(s), {{failed}} het misluk", - "fileDownloadedSuccessfully": "Lêer \"{{name}}\" is suksesvol afgelaai", + "fileDownloadedSuccessfully": "Lêer \"{{name}}\" suksesvol afgelaai", "failedToDownloadFile": "Kon nie lêer aflaai nie", "fileCreatedSuccessfully": "Lêer \"{{name}}\" suksesvol geskep", "folderCreatedSuccessfully": "Lêer \"{{name}}\" suksesvol geskep", @@ -290,6 +329,7 @@ "connecting": "Verbind...", "connectedSuccessfully": "Suksesvol gekoppel", "totpVerificationFailed": "TOTP-verifikasie het misluk", + "browserSignInFailed": "Aanmelding het misluk. Probeer asseblief weer.", "authenticationFailed": "Verifikasie het misluk", "incorrectPassphrase": "Verkeerde wagwoordfrase. Probeer asseblief weer.", "verificationCodePrompt": "Verifikasiekode:", @@ -326,7 +366,24 @@ "cannotLoadPdf": "Kan nie PDF laai nie", "pdfLoadError": "Daar was 'n fout tydens die laai van hierdie PDF-lêer.", "loadingPdf": "Laai PDF...", - "loadingPage": "Laai bladsy..." + "loadingPage": "Laai bladsy...", + "cancel": "Kanselleer", + "copiedItems_one": "Gekopieerde {{count}} item", + "copiedItems_other": "Gekopieerde {{count}} items", + "deleteCopiedFileFailed": "Kon nie die kopie van {{name}}verwyder nie: {{error}}", + "dragMovedItems_one": "Het {{count}} item na {{target}} geskuif", + "dragMovedItems_other": "Het {{count}} items na {{target}} geskuif", + "moveBackFileFailed": "Kon nie {{name}} terugskuif nie: {{error}}", + "terminal": "Terminaal: {{host}} ({{path}})", + "dragToDesktop": "Sleep {{name}} na die lessenaar", + "dragFilesToDesktop": "Sleep {{count}} lêers na die lessenaar", + "folderDragUnsupported": "Die sleep van lêers na die lessenaar word nog nie ondersteun nie", + "saveToDesktopFailed": "Stoor het misluk: {{error}}", + "dragFailedDetail": "Sleep het misluk: {{error}}", + "videoUnsupported": "Jou blaaier kan nie hierdie videoformaat speel nie.", + "downloadToPlay": "Laai dit af om dit elders te speel", + "cannotPreviewType": "Kan nie hierdie lêertipe voorbeskou nie", + "cannotPreviewTypeHint": "Hierdie lêertipe het geen voorskou nie. Laai dit af om dit in 'n ander toepassing oop te maak." }, "sftpTransfer": { "title": "SFTP", @@ -374,42 +431,12 @@ }, "hosts": { "fileManager": "Lêerbestuurder", - "tabFiles": "Lêers", - "enableFileManagerMonitor": "Aktiveer Lêerbestuurder", - "enableFileManagerMonitorDesc": "Blaai deur en bestuur lêers op hierdie gasheer via SFTP", - "scpLegacyLabel": "SCP Legacy-modus", - "scpLegacyDesc": "Gebruik ouer lêeroordrag vir bedieners wat nie die SFTP-substelsel ondersteun nie (bv. ingebedde of minimale SSH-bedieners).", - "defaultPathLabel": "Standaardpad", - "fileManagerPathHint": "Die gids om oop te maak wanneer die lêerbestuurder vir hierdie gasheer begin.", "fileManagerUrlCopied": "Lêerbestuurder-URL gekopieer", "copyFileManagerUrlAction": "Kopieer Lêerbestuurder URL", "docsLink": "Bekyk dokumente", "hostNotFound": "Gasheer nie gevind nie", "loadingHost": "Laai gasheer..." }, - "settings": { - "host": { - "enable": { - "label": "Aktiveer Lêerbestuurder" - }, - "defaultPath": { - "label": "Standaardpad" - }, - "scpLegacy": { - "label": "SCP Legacy-modus" - } - }, - "user": { - "transferConcurrency": { - "label": "Gelyktydige lêeroordragte", - "description": "Hoeveel lêers die sy-aan-sy plaaslike/afgeleë bestuurder gelyktydig oplaai of aflaai. Verlaag dit as jou bediener SFTP-kanale beperk." - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "Lêers" - }, "onboarding": { "feature_files": "Lêerbestuurder", "feature_files_desc": "Blaai, laai op, laai af en wysig lêers via SFTP sonder om die toepassing te verlaat." @@ -426,7 +453,7 @@ "cancel": "Kanselleer", "cleanupDestFiles": "Maak bestemming skoon", "cleanupDestFilesError": "Opruiming het misluk", - "cleanupDestFilesNothing": "Niks om op die bestemming op te ruim nie", + "cleanupDestFilesNothing": "Niks om op die bestemming skoon te maak nie", "cleanupDestFilesPartial": "Sommige gedeeltelike lêers kon nie verwyder word nie", "cleanupDestFilesSuccess": "Gedeeltelike lêers van die bestemming verwyder", "confirmCopy": "Kopieer", @@ -437,7 +464,7 @@ "destinationPath": "Bestemmingspad", "destMustBeDirectory": "Bestemming moet 'n gids wees vir oordragte van verskeie items", "goUp": "Gaan op", - "hostAuthRequired": "Verifikasie vereis — maak eers Lêerbestuurder op hierdie gasheer oop", + "hostAuthRequired": "Verifikasie vereis. Maak eers Lêerbestuurder op hierdie gasheer oop", "hostConnecting": "Verbind…", "hostConnectionFailed": "Verbinding het misluk", "hostDisconnected": "Nie gekoppel nie", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "Jy het SFTP per lêer gekies.", "user_tar": "Jy het teer-argief gekies.", - "tar_unavailable": "Teer is nie beskikbaar op een of albei gashere nie — SFTP per lêer sal eerder gebruik word.", - "windows_host": "'n Windows-gasheer is betrokke — teer word nie gebruik nie.", - "auto_multi_large": "Outomaties: veelvuldige lêers, insluitend 'n groot lêer ({{largestSize}}) met saampersbare data — teer bundels in een oordrag.", - "auto_single_large_in_archive": "Outomaties: een groot lêer ({{largestSize}}) in hierdie stel — SFTP per lêer.", - "auto_many_incompressible": "Outomaties: meestal onsaampersbare data — SFTP per lêer.", - "auto_many_files": "Outomaties: baie lêers ({{fileCount}}) — teer verminder oorhoofse koste per lêer.", + "tar_unavailable": "Teer is nie beskikbaar op een of albei gashere nie, dus sal SFTP per lêer eerder gebruik word.", + "windows_host": "'n Windows-gasheer is betrokke, dus word teer nie gebruik nie.", + "auto_multi_large": "Outomaties: veelvuldige lêers, insluitend 'n groot lêer ({{largestSize}}) met saampersbare data. Tar bundel hulle in een oordrag.", + "auto_single_large_in_archive": "Outomaties: een groot lêer ({{largestSize}}) in hierdie stel, dus SFTP per lêer.", + "auto_many_incompressible": "Outomaties: meestal onsaampersbare data, dus SFTP per lêer.", + "auto_many_files": "Outomaties: baie lêers ({{fileCount}}), tar sny die oorhoofse koste per lêer.", "auto_default": "Outomaties: SFTP per lêer vir hierdie stel." }, "methodTar": "Teer-argief", @@ -471,7 +498,7 @@ "metricsCompress": "Kompresseer op bron: {{duration}}", "metricsExtract": "Uittreksel op bestemming: {{duration}}", "metricsPrepare": "Berei bestemming voor: {{duration}}", - "metricsRouteBenchmark": "Roete-sonde — direk: {{direct}}, aflos: {{relay}}", + "metricsRouteBenchmark": "Roete-sonde: direk {{direct}}, aflos {{relay}}", "metricsSourceDelete": "Verwyder van bron: {{duration}}", "metricsTotal": "Totaal: {{duration}}", "metricsTransfer": "Van begin tot einde: {{throughput}} ({{duration}})", @@ -508,6 +535,9 @@ "transferError": "Oordrag het misluk", "transferFailedRetryHint": "Gedeeltelike data is op die bestemming gehou. Herprobeer sal hervat word wanneer die verbinding terug is.", "transferPartialHint": "Kon nie oordra nie: {{paths}}", - "transferSuccess": "Oordrag voltooi" + "transferSuccess": "Oordrag voltooi", + "metricsHopSourceRead": "Bron → bediener: {{throughput}}", + "metricsHopDestSftpWrite": "Bediener → bestemming (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Bediener → bestemming (plaaslik): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/ar_SA.json b/plugins/file-manager/locales/translated/ar_SA.json index 2cd51f5fc..bb659990d 100644 --- a/plugins/file-manager/locales/translated/ar_SA.json +++ b/plugins/file-manager/locales/translated/ar_SA.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "الملفات", + "sftp": "SFTP", + "openFileManager": "فتح مدير الملفات" + }, + "permissions": { + "use": { + "title": "استخدم مدير الملفات", + "description": "تصفح الملفات وحررها وانقلها عبر بروتوكول SFTP." + } + }, + "settings": { + "host": { + "enable": { + "label": "تمكين مدير الملفات", + "description": "تصفح الملفات وقم بتحريرها على هذا المضيف عبر بروتوكول SFTP." + }, + "defaultPath": { + "label": "المسار الافتراضي" + }, + "scpLegacy": { + "label": "وضع SCP القديم" + } + }, + "user": { + "transferConcurrency": { + "label": "نقل الملفات المتزامن", + "description": "كم عدد الملفات التي يقوم مدير الملفات المحلي/البعيد بتحميلها أو تنزيلها في نفس الوقت؟ قلل هذا العدد إذا كان خادمك يحد من قنوات SFTP." + }, + "confirmBeforeTrash": { + "label": "تأكد قبل نقل الملفات إلى سلة المهملات", + "description": "استأذن قبل نقل الملفات البعيدة إلى سلة المهملات. الحذف النهائي يتطلب تأكيداً." + } + } + }, + "hostCapability": { + "label": "مدير الملفات" + }, "fileManager": { "noHostSelected": "لم يتم اختيار مضيف", "initializingEditor": "جارٍ تهيئة المحرر...", @@ -34,6 +72,7 @@ "rename": "إعادة تسمية", "uploading": "جارٍ الرفع...", "uploadingFile": "جارٍ رفع {{name}}...", + "uploadingChunk": "جارٍ تحميل {{name}}: {{percent}}% (الجزء {{chunk}} من {{total}})", "fileName": "اسم الملف", "folderName": "اسم المجلد", "fileUploadedSuccessfully": "تم رفع الملف \"{{name}}\" بنجاح", @@ -67,9 +106,9 @@ "localHideHidden": "إخفاء الملفات المخفية", "localRevealInFileManager": "إظهار في مدير ملفات النظام", "localCannotOpenFolder": "لا يمكن فتح المجلد", - "localItemCount": "{{count}} عناصر", - "localSelectedCount": "{{count}} تم الاختيار", - "back": "خلف", + "localItemCount": "{{count}} عنصر", + "localSelectedCount": "تم تحديد {{count}}", + "back": "رجوع", "forward": "إلى الأمام", "up": "أعلى", "kind": "عطوف", @@ -77,7 +116,7 @@ "localDownloadingProgress": "جارٍ تنزيل {{current}} من {{total}}", "localTransferInFlight": "{{count}} دفعة واحدة", "localPreparingDownload": "جارٍ تحضير التنزيل...", - "localTransferCancelled": "تم إلغاء التحويل", + "localTransferCancelled": "تم إلغاء النقل", "localNothingToTransfer": "لا يوجد شيء لنقله", "localUploadComplete": "تم تحميل {{count}} ملف(ملفات)", "localUploadFailed": "فشل التحميل", @@ -86,11 +125,11 @@ "localDownloadFailed": "فشل التنزيل", "localDownloadPartial": "تم تنزيل {{done}} ملفًا، {{failed}} فشل", "localReplaceExistingPrompt": "{{count}} العنصر (العناصر) موجودة بالفعل في هذا المجلد. هل تريد استبدالها؟", - "localReplace": "يستبدل", + "localReplace": "استبدال", "localSkipExisting": "يتخطى", "localSkippedExisting": "تم تخطي {{count}} عنصر (عناصر) موجودة", "localUnsafeNamesSkipped": "تم تخطي {{count}} عنصرًا لا يمكن استخدام أسمائها على هذا الكمبيوتر", - "localOpen": "يفتح", + "localOpen": "فتح", "localOpenFolder": "افتح المجلد", "localUploadToRemote": "التحميل إلى الخادم", "localUploadToRemoteMany": "قم بتحميل {{count}} عنصرًا إلى الخادم", @@ -163,13 +202,13 @@ "confirmDeleteMultipleItemsWithFolders": "هل أنت متأكد أنك تريد حذف {{count}} عناصر نهائيًا؟ يتضمن ذلك المجلدات ومحتوياتها.", "confirmDeleteFolder": "هل أنت متأكد أنك تريد حذف المجلد \"{{name}}\" وجميع محتوياته نهائيًا؟", "permanentDeleteWarning": "لا يمكن التراجع عن هذا الإجراء. سيتم حذف العنصر (العناصر) نهائيًا من الخادم.", - "moveToTrashWarning": "سيتم نقل العنصر (العناصر) إلى سلة مهملات Termix ويمكن استعادته قبل انتهاء فترة الاحتفاظ.", + "moveToTrashWarning": "سيتم نقل العنصر (العناصر) إلى سلة مهملات Termix ويمكن استعادتها قبل انتهاء فترة الاحتفاظ.", "itemsMovedToTrash": "تم نقل العنصر (العناصر) إلى سلة المهملات {{count}}", "trash": "نفاية", "trashDescription": "يتم الاحتفاظ بالعناصر المحذوفة لمدة {{days}} يوم (أيام) على هذا المضيف.", "trashLoadFailed": "فشل تحميل سلة المهملات", "trashEmpty": "سلة المهملات فارغة", - "trashRestore": "يعيد", + "trashRestore": "استعادة", "trashRestored": "تمت الاستعادة {{name}}", "trashRestoreFailed": "فشلت عملية استعادة العنصر. قد يكون المسار الأصلي موجودًا بالفعل.", "trashDeletePermanently": "حذف نهائياً", @@ -290,6 +329,7 @@ "connecting": "جارٍ الاتصال...", "connectedSuccessfully": "تم الاتصال بنجاح", "totpVerificationFailed": "فشل التحقق من TOTP", + "browserSignInFailed": "فشل تسجيل الدخول. يرجى المحاولة مرة أخرى.", "authenticationFailed": "فشلت المصادقة", "incorrectPassphrase": "عبارة المرور غير صحيحة. يرجى المحاولة مرة أخرى.", "verificationCodePrompt": "رمز التحقق:", @@ -326,7 +366,24 @@ "cannotLoadPdf": "لا يمكن تحميل PDF", "pdfLoadError": "حدث خطأ أثناء تحميل ملف PDF هذا.", "loadingPdf": "جارٍ تحميل PDF...", - "loadingPage": "جارٍ تحميل الصفحة..." + "loadingPage": "جارٍ تحميل الصفحة...", + "cancel": "إلغاء", + "copiedItems_one": "تم نسخ العنصر {{count}}", + "copiedItems_other": "تم نسخ {{count}} عنصرًا", + "deleteCopiedFileFailed": "تعذر حذف نسخة من {{name}}: {{error}}", + "dragMovedItems_one": "تم نقل العنصر {{count}} إلى {{target}}", + "dragMovedItems_other": "تم نقل {{count}} عنصرًا إلى {{target}}", + "moveBackFileFailed": "تعذر تحريك {{name}} للخلف: {{error}}", + "terminal": "الطرفية: {{host}} ({{path}})", + "dragToDesktop": "سحب {{name}} إلى سطح المكتب", + "dragFilesToDesktop": "سحب الملفات {{count}} إلى سطح المكتب", + "folderDragUnsupported": "لا يدعم التطبيق سحب المجلدات إلى سطح المكتب حتى الآن", + "saveToDesktopFailed": "فشل الحفظ: {{error}}", + "dragFailedDetail": "فشل السحب: {{error}}", + "videoUnsupported": "لا يمكن لمتصفحك تشغيل هذا الفيديو.", + "downloadToPlay": "قم بتنزيله لتشغيله في مكان آخر", + "cannotPreviewType": "لا يمكن معاينة هذا النوع من الملفات", + "cannotPreviewTypeHint": "لا يتوفر معاينة لهذا النوع من الملفات. قم بتنزيله لفتحه في تطبيق آخر." }, "sftpTransfer": { "title": "SFTP", @@ -334,34 +391,34 @@ "sourceServer": "خادم المصدر", "destinationServer": "خادم الوجهة", "selectHost": "حدد المضيف", - "noHostSelected": "لم يتم تحديد أي مضيف", - "move": "يتحرك", - "copy": "ينسخ", + "noHostSelected": "لم يتم تحديد أي جهاز مضيف", + "move": "نقل", + "copy": "نسخ", "upload": "رفع", "itemsSelected": "تم تحديد العنصر {{count}}", "itemsSelected_other": "تم تحديد {{count}} عنصر", - "ready": "مستعد", + "ready": "جاهز", "loadingHosts": "جارٍ تحميل المضيفين...", - "name": "اسم", - "modified": "معدل", - "size": "مقاس", + "name": "الاسم", + "modified": "تاريخ التعديل", + "size": "الحجم", "noFiles": "لا توجد ملفات", - "open": "يفتح", + "open": "فتح", "up": "أعلى", - "refresh": "ينعش", + "refresh": "تحديث", "copyToTarget": "انسخ إلى الدليل الهدف", "rename": "إعادة تسمية", - "delete": "يمسح", + "delete": "حذف", "editPermissions": "تعديل الأذونات", "createNewFolder": "إنشاء مجلد جديد", "deleteSelectedItems": "حذف العناصر المحددة", "deleteConfirm": "حذف العنصر المحدد {{count}}؟", "deleteConfirm_other": "حذف {{count}} من العناصر المحددة؟", - "cancel": "يلغي", - "save": "يحفظ", + "cancel": "إلغاء", + "save": "حفظ", "folderCreated": "تم إنشاء المجلد", "itemRenamed": "تمت إعادة تسمية العنصر", - "actionFailed": "فشلت العملية", + "actionFailed": "فشل الإجراء", "itemsDeleted": "تم حذف العنصر {{count}}", "itemsDeleted_other": "تم حذف {{count}} عنصر", "deleteFailed": "فشلت عملية الحذف", @@ -374,42 +431,12 @@ }, "hosts": { "fileManager": "مدير الملفات", - "tabFiles": "الملفات", - "enableFileManagerMonitor": "تمكين مدير الملفات", - "enableFileManagerMonitorDesc": "استعراض وإدارة الملفات على هذا المضيف عبر SFTP", - "scpLegacyLabel": "وضع SCP القديم", - "scpLegacyDesc": "استخدم وضع النقل القديم للملفات للخوادم التي لا تدعم النظام الفرعي SFTP (مثل خوادم SSH المدمجة أو ذات الإمكانيات المحدودة).", - "defaultPathLabel": "المسار الافتراضي", - "fileManagerPathHint": "الدليل الذي سيتم فتحه عند تشغيل مدير الملفات لهذا المضيف.", "fileManagerUrlCopied": "تم نسخ رابط مدير الملفات", "copyFileManagerUrlAction": "نسخ رابط مدير الملفات", "docsLink": "عرض المستندات", "hostNotFound": "المضيف غير موجود", "loadingHost": "جارٍ تحميل المضيف..." }, - "settings": { - "host": { - "enable": { - "label": "تمكين مدير الملفات" - }, - "defaultPath": { - "label": "المسار الافتراضي" - }, - "scpLegacy": { - "label": "وضع SCP القديم" - } - }, - "user": { - "transferConcurrency": { - "label": "نقل الملفات المتزامن", - "description": "كم عدد الملفات التي يقوم مدير الملفات المحلي/البعيد بتحميلها أو تنزيلها في نفس الوقت؟ قلل هذا العدد إذا كان خادمك يحد من قنوات SFTP." - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "الملفات" - }, "onboarding": { "feature_files": "مدير الملفات", "feature_files_desc": "تصفح الملفات وقم بتحميلها وتنزيلها وتعديلها عبر بروتوكول SFTP دون مغادرة التطبيق." @@ -437,7 +464,7 @@ "destinationPath": "مسار الوجهة", "destMustBeDirectory": "يجب أن تكون الوجهة مجلدًا لنقل عناصر متعددة", "goUp": "للأعلى", - "hostAuthRequired": "المصادقة مطلوبة — افتح مدير الملفات على هذا المضيف أولاً", + "hostAuthRequired": "يلزم المصادقة. افتح مدير الملفات على هذا المضيف أولاً", "hostConnecting": "جارٍ الاتصال…", "hostConnectionFailed": "فشل الاتصال", "hostDisconnected": "غير متصل", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "اخترت SFTP لكل ملف.", "user_tar": "اخترت أرشيف tar.", - "tar_unavailable": "tar غير متوفر على أحد المضيفين أو كليهما — سيُستخدم SFTP لكل ملف بدلاً من ذلك.", - "windows_host": "يوجد مضيف Windows — لا يُستخدم tar.", - "auto_multi_large": "تلقائي: عدة ملفات بما فيها ملف كبير ({{largestSize}}) ببيانات قابلة للضغط — يجمعها tar في حزمة واحدة.", - "auto_single_large_in_archive": "تلقائي: ملف كبير واحد ({{largestSize}}) في هذه المجموعة — SFTP لكل ملف.", - "auto_many_incompressible": "تلقائي: البيانات غالبًا غير قابلة للضغط — SFTP لكل ملف.", - "auto_many_files": "تلقائي: عدة ملفات ({{fileCount}}) — يقلل tar الحمل لكل ملف.", + "tar_unavailable": "برنامج Tar غير متوفر على أحد المضيفين أو كليهما، لذلك سيتم استخدام SFTP لكل ملف بدلاً من ذلك.", + "windows_host": "يتم استخدام مضيف يعمل بنظام ويندوز، لذلك لا يتم استخدام برنامج tar.", + "auto_multi_large": "تلقائي: ملفات متعددة، بما في ذلك ملف كبير ({{largestSize}}) يحتوي على بيانات قابلة للضغط. يقوم برنامج Tar بتجميعها في عملية نقل واحدة.", + "auto_single_large_in_archive": "تلقائي: ملف واحد كبير ({{largestSize}}) في هذه المجموعة، لذا SFTP لكل ملف.", + "auto_many_incompressible": "تلقائي: بيانات غير قابلة للضغط في الغالب، لذا يتم استخدام بروتوكول SFTP لكل ملف.", + "auto_many_files": "الوضع التلقائي: العديد من الملفات ({{fileCount}})، يقوم برنامج tar بتقليل الحمل الزائد لكل ملف.", "auto_default": "تلقائي: SFTP لكل ملف لهذه المجموعة." }, "methodTar": "أرشيف Tar", @@ -471,7 +498,7 @@ "metricsCompress": "ضغط على المصدر: {{duration}}", "metricsExtract": "فك على الوجهة: {{duration}}", "metricsPrepare": "تحضير الوجهة: {{duration}}", - "metricsRouteBenchmark": "مسبار المسار — مباشر: {{direct}}، مرحل: {{relay}}", + "metricsRouteBenchmark": "مسار التحقيق: مباشر {{direct}}، مرحل {{relay}}", "metricsSourceDelete": "إزالة من المصدر: {{duration}}", "metricsTotal": "الإجمالي: {{duration}}", "metricsTransfer": "نقل شامل: {{throughput}} ({{duration}})", @@ -508,6 +535,9 @@ "transferError": "فشل النقل", "transferFailedRetryHint": "تم الاحتفاظ بالبيانات الجزئية على الوجهة. ستُستأنف إعادة المحاولة عند عودة الاتصال.", "transferPartialHint": "تعذر النقل: {{paths}}", - "transferSuccess": "اكتمل النقل" + "transferSuccess": "اكتمل النقل", + "metricsHopSourceRead": "المصدر → الخادم: {{throughput}}", + "metricsHopDestSftpWrite": "الخادم → الوجهة (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "الخادم → الوجهة (محلي): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/bg_BG.json b/plugins/file-manager/locales/translated/bg_BG.json index de720cbf0..501d9d548 100644 --- a/plugins/file-manager/locales/translated/bg_BG.json +++ b/plugins/file-manager/locales/translated/bg_BG.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "Файлове", + "sftp": "SFTP", + "openFileManager": "Отворете файловия мениджър" + }, + "permissions": { + "use": { + "title": "Използвайте файлов мениджър", + "description": "Преглеждайте, редактирайте и прехвърляйте файлове през SFTP." + } + }, + "settings": { + "host": { + "enable": { + "label": "Активиране на файловия мениджър", + "description": "Разглеждайте и редактирайте файлове на този хост през SFTP." + }, + "defaultPath": { + "label": "Път по подразбиране" + }, + "scpLegacy": { + "label": "SCP Legacy режим" + } + }, + "user": { + "transferConcurrency": { + "label": "Едновременно прехвърляне на файлове", + "description": "Колко файла едновременно качва или изтегля локалният/отдалечен мениджър. Намалете това, ако вашият сървър ограничава SFTP каналите." + }, + "confirmBeforeTrash": { + "label": "Потвърдете преди преместване на файлове в кошчето", + "description": "Попитай преди преместване на отдалечени файлове в кошчето. За постоянното изтриване все още е необходимо потвърждение." + } + } + }, + "hostCapability": { + "label": "Файлов мениджър" + }, "fileManager": { "noHostSelected": "Няма избран хост", "initializingEditor": "Инициализиране на редактора...", @@ -34,6 +72,7 @@ "rename": "Преименуване", "uploading": "Качване...", "uploadingFile": "Качване {{name}}...", + "uploadingChunk": "Качване {{name}}: {{percent}}% (част {{chunk}} от {{total}})", "fileName": "Име на файл", "folderName": "Име на папката", "fileUploadedSuccessfully": "Файлът „{{name}}“ е качен успешно", @@ -164,7 +203,7 @@ "confirmDeleteFolder": "Сигурни ли сте, че искате да изтриете окончателно папката „{{name}}“ и цялото ѝ съдържание?", "permanentDeleteWarning": "Това действие не може да бъде отменено. Елементът(ите) ще бъдат изтрити за постоянно от сървъра.", "moveToTrashWarning": "Елементът(ите) ще бъдат преместени в кошчето на Termix и могат да бъдат възстановени преди изтичане на срока на съхранение.", - "itemsMovedToTrash": "{{count}} елемент(а) са преместени в кошчето", + "itemsMovedToTrash": "{{count}} елемент(а) преместени в кошчето", "trash": "Кошче", "trashDescription": "Изтритите елементи се запазват за {{days}} дни на този хост.", "trashLoadFailed": "Зареждането на кошчето не бе успешно", @@ -223,7 +262,7 @@ "confirm": "Потвърди", "find": "Намерете...", "replace": "Замяна", - "downloadInstead": "Изтеглете вместо това", + "downloadInstead": "Изтегляне вместо това", "keyboardShortcuts": "Клавишни комбинации", "searchAndReplace": "Търсене и замяна", "editing": "Редактиране", @@ -255,7 +294,7 @@ "comparingFiles": "Сравняване на файлове: {{file1}} и {{file2}}", "dragFailed": "Плъзгането не беше успешно", "filePinnedSuccessfully": "Файлът „{{name}}“ е успешно закачен", - "pinFileFailed": "Закрепването на файла не бе успешно", + "pinFileFailed": "Закачването на файла не бе успешно", "fileUnpinnedSuccessfully": "Файлът „{{name}}“ е откачен успешно", "unpinFileFailed": "Откачването на файла не бе успешно", "shortcutAddedSuccessfully": "Прякият път към папка „{{name}}“ е добавен успешно", @@ -290,6 +329,7 @@ "connecting": "Свързване...", "connectedSuccessfully": "Свързаването е осъществено успешно", "totpVerificationFailed": "Проверката на TOTP не бе успешна", + "browserSignInFailed": "Влизането не бе успешно. Моля, опитайте отново.", "authenticationFailed": "Удостоверяването не бе успешно", "incorrectPassphrase": "Неправилна парола. Моля, опитайте отново.", "verificationCodePrompt": "Код за потвърждение:", @@ -326,7 +366,24 @@ "cannotLoadPdf": "Не може да се зареди PDF файл", "pdfLoadError": "Възникна грешка при зареждането на този PDF файл.", "loadingPdf": "Зареждане на PDF файл...", - "loadingPage": "Зареждане на страницата..." + "loadingPage": "Зареждане на страницата...", + "cancel": "Отказ", + "copiedItems_one": "Копиран елемент {{count}}", + "copiedItems_other": "Копирани {{count}} елементи", + "deleteCopiedFileFailed": "Не можа да се изтрие копието на {{name}}: {{error}}", + "dragMovedItems_one": "Елементът {{count}} е преместен в {{target}}", + "dragMovedItems_other": "Преместихме {{count}} елементи в {{target}}", + "moveBackFileFailed": "Не можа да се премести {{name}} назад: {{error}}", + "terminal": "Терминал: {{host}} ({{path}})", + "dragToDesktop": "Плъзгане на {{name}} към работния плот", + "dragFilesToDesktop": "Плъзгане на {{count}} файлове на работния плот", + "folderDragUnsupported": "Плъзгането на папки към работния плот все още не се поддържа", + "saveToDesktopFailed": "Запазването не бе успешно: {{error}}", + "dragFailedDetail": "Плъзгането не бе успешно: {{error}}", + "videoUnsupported": "Вашият браузър не може да възпроизведе този видео формат.", + "downloadToPlay": "Изтеглете, за да го играете другаде", + "cannotPreviewType": "Не може да се прегледа този тип файл", + "cannotPreviewTypeHint": "Този тип файл няма предварителен преглед. Изтеглете го, за да го отворите в друго приложение." }, "sftpTransfer": { "title": "SFTP", @@ -348,7 +405,7 @@ "noFiles": "Няма файлове", "open": "Отворено", "up": "Нагоре", - "refresh": "Опресняване", + "refresh": "Обновяване", "copyToTarget": "Копиране в целевата директория", "rename": "Преименуване", "delete": "Изтриване", @@ -374,42 +431,12 @@ }, "hosts": { "fileManager": "Файлов мениджър", - "tabFiles": "Файлове", - "enableFileManagerMonitor": "Активиране на файловия мениджър", - "enableFileManagerMonitorDesc": "Разглеждайте и управлявайте файлове на този хост през SFTP", - "scpLegacyLabel": "SCP Legacy режим", - "scpLegacyDesc": "Използвайте наследствен трансфер на файлове за сървъри, които не поддържат SFTP подсистемата (напр. вградени или минимални SSH сървъри).", - "defaultPathLabel": "Път по подразбиране", - "fileManagerPathHint": "Директорията, която да се отвори при стартиране на файловия мениджър за този хост.", "fileManagerUrlCopied": "URL адресът на файловия мениджър е копиран", "copyFileManagerUrlAction": "Копиране на URL адреса на файловия мениджър", "docsLink": "Преглед на документи", "hostNotFound": "Хостът не е намерен", "loadingHost": "Зареждане на хоста..." }, - "settings": { - "host": { - "enable": { - "label": "Активиране на файловия мениджър" - }, - "defaultPath": { - "label": "Път по подразбиране" - }, - "scpLegacy": { - "label": "SCP Legacy режим" - } - }, - "user": { - "transferConcurrency": { - "label": "Едновременно прехвърляне на файлове", - "description": "Колко файла едновременно качва или изтегля локалният/отдалечен мениджър. Намалете това, ако вашият сървър ограничава SFTP каналите." - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "Файлове" - }, "onboarding": { "feature_files": "Файлов мениджър", "feature_files_desc": "Преглеждайте, качвайте, изтегляйте и редактирайте файлове през SFTP, без да напускате приложението." @@ -436,8 +463,8 @@ "copyToHost": "Копиране към хост…", "destinationPath": "Път на местоназначението", "destMustBeDirectory": "Дестинацията трябва да е директория за прехвърляне на множество елементи", - "goUp": "Качи се нагоре", - "hostAuthRequired": "Изисква се удостоверяване — първо отворете Файловия мениджър на този хост", + "goUp": "Качи се", + "hostAuthRequired": "Изисква се удостоверяване. Първо отворете Файловия мениджър на този хост.", "hostConnecting": "Свързване…", "hostConnectionFailed": "Връзката не бе успешна", "hostDisconnected": "Няма връзка", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "Избрали сте SFTP за всеки файл.", "user_tar": "Избрахте tar архив.", - "tar_unavailable": "Tar не е наличен на единия или и на двата хоста — вместо това ще се използва SFTP за всеки файл.", - "windows_host": "Включен е хост на Windows — tar не се използва.", - "auto_multi_large": "Автоматично: множество файлове, включително голям файл ({{largestSize}}) със свиваеми данни — tar пакети в един трансфер.", - "auto_single_large_in_archive": "Автоматично: един голям файл ({{largestSize}}) в този набор — SFTP за всеки файл.", - "auto_many_incompressible": "Автоматично: предимно некомпресируеми данни — SFTP за всеки файл.", - "auto_many_files": "Автоматично: много файлове ({{fileCount}}) — tar намалява натоварването на всеки файл.", + "tar_unavailable": "Tar не е наличен на единия или и на двата хоста, така че вместо това ще се използва SFTP за всеки файл.", + "windows_host": "Включен е хост на Windows, така че tar не се използва.", + "auto_multi_large": "Автоматично: множество файлове, включително голям файл ({{largestSize}}) със свиваеми данни. Tar ги обединява в един трансфер.", + "auto_single_large_in_archive": "Автоматично: един голям файл ({{largestSize}}) в този набор, така че SFTP за всеки файл.", + "auto_many_incompressible": "Автоматично: предимно некомпресируеми данни, така че SFTP за всеки файл.", + "auto_many_files": "Автоматично: много файлове ({{fileCount}}), tar намалява натоварването на всеки файл.", "auto_default": "Автоматично: SFTP за всеки файл за този набор." }, "methodTar": "Тар архив", @@ -471,7 +498,7 @@ "metricsCompress": "Компресиране при източника: {{duration}}", "metricsExtract": "Извличане в местоназначението: {{duration}}", "metricsPrepare": "Подготовка на дестинацията: {{duration}}", - "metricsRouteBenchmark": "Сонда за маршрут — директна: {{direct}}, релейна: {{relay}}", + "metricsRouteBenchmark": "Сонда за маршрут: директна {{direct}}, релейна {{relay}}", "metricsSourceDelete": "Премахване от източника: {{duration}}", "metricsTotal": "Общо: {{duration}}", "metricsTransfer": "От край до край: {{throughput}} ({{duration}})", @@ -508,6 +535,9 @@ "transferError": "Прехвърлянето не бе успешно", "transferFailedRetryHint": "В местоназначението са запазени частични данни. Повторният опит ще се възобнови, когато връзката се възстанови.", "transferPartialHint": "Не можа да се прехвърли: {{paths}}", - "transferSuccess": "Прехвърлянето е завършено" + "transferSuccess": "Прехвърлянето е завършено", + "metricsHopSourceRead": "Източник → сървър: {{throughput}}", + "metricsHopDestSftpWrite": "Сървър → дестинация (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Сървър → дестинация (локална): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/bn_BD.json b/plugins/file-manager/locales/translated/bn_BD.json index 754a65353..dc86761ce 100644 --- a/plugins/file-manager/locales/translated/bn_BD.json +++ b/plugins/file-manager/locales/translated/bn_BD.json @@ -1,513 +1,543 @@ { - "fileManager": { - "noHostSelected": "কোন হোস্ট নির্বাচন করা হয়নি", - "initializingEditor": "এডিটর চালু করা হচ্ছে...", - "file": "ফাইল", - "folder": "ফোল্ডার", - "uploadFile": "ফাইল আপলোড করুন", - "downloadFile": "ডাউনলোড করুন", - "extractArchive": "আর্কাইভ নিষ্কাশন করুন", - "extractingArchive": "{{name}} নিষ্কাশন করা হচ্ছে ...", - "archiveExtractedSuccessfully": "{{name}} সফলভাবে নিষ্কাশন করা হয়েছে", - "extractFailed": "নিষ্কাশন ব্যর্থ হয়েছে", - "compressFile": "ফাইল সংকুচিত করুন", - "compressFiles": "ফাইলগুলি সংকুচিত করুন", - "compressFilesDesc": "{{count}} টি আইটেমকে আর্কাইভে সংকুচিত করুন", - "archiveName": "আর্কাইভের নাম", - "enterArchiveName": "আর্কাইভের নাম লিখুন...", - "compressionFormat": "কম্প্রেশন ফরম্যাট", - "selectedFiles": "নির্বাচিত ফাইল", - "andMoreFiles": "এবং {{count}} আরও...", - "compress": "সংকুচিত করুন", - "compressingFiles": "{{count}} টি আইটেমকে {{name}} টি আইটেমে সংকুচিত করা হচ্ছে...", - "filesCompressedSuccessfully": "{{name}} সফলভাবে তৈরি হয়েছে", - "compressFailed": "সংকোচন ব্যর্থ হয়েছে", - "edit": "সম্পাদনা", - "preview": "প্রিভিউ", - "previous": "পূর্ববর্তী", - "next": "পরবর্তী", - "pageXOfY": "{{current}} এর {{total}} পৃষ্ঠা", - "zoomOut": "জুম আউট", - "zoomIn": "জুম ইন", - "newFile": "নতুন ফাইল", - "newFolder": "নতুন ফোল্ডার", - "rename": "পুনঃনামকরণ", - "uploading": "আপলোড হচ্ছে...", - "uploadingFile": "{{name}} আপলোড হচ্ছে ...", - "fileName": "ফাইলের নাম", - "folderName": "ফোল্ডারের নাম", - "fileUploadedSuccessfully": "ফাইল \"{{name}}\" সফলভাবে আপলোড হয়েছে", - "failedToUploadFile": "ফাইল আপলোড করতে ব্যর্থ হয়েছে", - "uploadingFolderFiles": "{{count}} টি ফাইল আপলোড করা হচ্ছে...", - "uploadedFolderFiles": "{{count}} টি ফাইল সফলভাবে আপলোড করা হয়েছে", - "uploadedFolderPartial": "{{uploaded}} টি ফাইল আপলোড করা হয়েছে, {{failed}} টি ফাইল আপলোড ব্যর্থ হয়েছে", - "fileDownloadedSuccessfully": "ফাইল \"{{name}}\" সফলভাবে ডাউনলোড হয়েছে", - "failedToDownloadFile": "ফাইল ডাউনলোড করতে ব্যর্থ হয়েছে", - "fileCreatedSuccessfully": "ফাইল \"{{name}}\" সফলভাবে তৈরি হয়েছে", - "folderCreatedSuccessfully": "\"{{name}}\" ফোল্ডারটি সফলভাবে তৈরি করা হয়েছে", - "failedToCreateItem": "আইটেম তৈরি করতে ব্যর্থ হয়েছে", - "operationFailed": "{{operation}} অপারেশনটি {{name}}এর জন্য ব্যর্থ হয়েছে: {{error}}", - "failedToResolveSymlink": "সিমলিঙ্ক সমাধান করতে ব্যর্থ হয়েছে", - "itemsDeletedSuccessfully": "{{count}} আইটেম সফলভাবে মুছে ফেলা হয়েছে", - "failedToDeleteItems": "আইটেমগুলি মুছে ফেলতে ব্যর্থ হয়েছে", - "sudoPasswordRequired": "প্রশাসক পাসওয়ার্ড আবশ্যক", - "enterSudoPassword": "এই অপারেশনটি চালিয়ে যেতে sudo পাসওয়ার্ড দিন।", - "sudoPassword": "সুডো পাসওয়ার্ড", - "sudoOperationFailed": "Sudo অপারেশন ব্যর্থ হয়েছে", - "sudoAuthFailed": "Sudo প্রমাণীকরণ ব্যর্থ হয়েছে", - "dragFilesToUpload": "আপলোড করার জন্য ফাইলগুলো এখানে রাখুন।", - "dropToUploadHere": "এখানে আপলোড করতে ড্রপ করুন", - "dropToDownloadHere": "ডাউনলোড করতে এখানে ক্লিক করুন", - "localFiles": "স্থানীয়", - "showLocalFiles": "স্থানীয় ফাইলগুলি দেখান (বিভক্ত দৃশ্য)", - "hideLocalFiles": "স্থানীয় ফাইলগুলি লুকান", - "localHome": "হোম ফোল্ডার", - "localPathPlaceholder": "স্থানীয় ফোল্ডার পাথ", - "localShowHidden": "লুকানো ফাইলগুলি দেখান", - "localHideHidden": "লুকানো ফাইলগুলি লুকান", - "localRevealInFileManager": "সিস্টেম ফাইল ম্যানেজারে প্রকাশ করুন", - "localCannotOpenFolder": "ফোল্ডার খোলা যাচ্ছে না", - "localItemCount": "{{count}} আইটেম", - "localSelectedCount": "{{count}} নির্বাচিত", - "back": "ফিরে যান", - "forward": "ফরোয়ার্ড", - "up": "উপরে", - "kind": "ধরনের", - "localUploadingProgress": "{{total}} এর {{current}} আপলোড করা হচ্ছে", - "localDownloadingProgress": "{{total}} এর {{current}} ডাউনলোড হচ্ছে", - "localTransferInFlight": "{{count}} একবারে", - "localPreparingDownload": "ডাউনলোড প্রস্তুত হচ্ছে...", - "localTransferCancelled": "স্থানান্তর বাতিল করা হয়েছে", - "localNothingToTransfer": "স্থানান্তর করার কিছু নেই", - "localUploadComplete": "{{count}} টি ফাইল আপলোড করা হয়েছে", - "localUploadFailed": "আপলোড ব্যর্থ হয়েছে", - "localUploadPartial": "{{done}} টি ফাইল আপলোড করা হয়েছে, {{failed}} টি ফাইল আপলোড ব্যর্থ হয়েছে", - "localDownloadComplete": "{{count}} টি ফাইল ডাউনলোড করা হয়েছে", - "localDownloadFailed": "ডাউনলোড ব্যর্থ হয়েছে", - "localDownloadPartial": "{{done}} টি ফাইল ডাউনলোড করা হয়েছে, {{failed}} টি ফাইল ডাউনলোড ব্যর্থ হয়েছে", - "localReplaceExistingPrompt": "এই ফোল্ডারে {{count}} টি আইটেম ইতিমধ্যেই বিদ্যমান। এগুলো প্রতিস্থাপন করবেন?", - "localReplace": "প্রতিস্থাপন করুন", - "localSkipExisting": "এড়িয়ে যান", - "localSkippedExisting": "{{count}} টি বিদ্যমান আইটেম বাদ দেওয়া হয়েছে", - "localUnsafeNamesSkipped": "{{count}} টি আইটেম বাদ দেওয়া হয়েছে, যেগুলোর নাম এই কম্পিউটারে ব্যবহার করা যাবে না।", - "localOpen": "খোলা", - "localOpenFolder": "ফোল্ডার খুলুন", - "localUploadToRemote": "সার্ভারে আপলোড করুন", - "localUploadToRemoteMany": "সার্ভারে {{count}} টি আইটেম আপলোড করুন", - "localMoveToTrash": "ট্র্যাশে সরান", - "localMoveToTrashMany": "{{count}} টি আইটেম ট্র্যাশে সরান", - "localTrashConfirmSingle": "\"{{name}}\" ট্র্যাশে সরাবেন?", - "localTrashConfirmFolder": "\"{{name}}\" ফোল্ডারটি এবং এর সমস্ত বিষয়বস্তু ট্র্যাশে সরান?", - "localTrashConfirmMany": "{{count}} টি আইটেম ট্র্যাশে সরাবেন?", - "localTrashed": "ট্র্যাশে {{count}} টি আইটেম সরানো হয়েছে", - "localTrashFailed": "ট্র্যাশে সরানো যায়নি", - "localRenameFailed": "নাম পরিবর্তন ব্যর্থ হয়েছে", - "localCreateFailed": "আইটেমটি তৈরি করা যায়নি", - "goToParentFolder": "প্যারেন্ট ফোল্ডারে যান", - "resizeSidebar": "সাইডবারের আকার পরিবর্তন করতে ড্র্যাগ করুন (রিসেট করতে ডাবল-ক্লিক করুন)", - "resizeLocalPane": "স্থানীয় প্যানেলের আকার পরিবর্তন করতে ড্র্যাগ করুন (রিসেট করতে ডাবল-ক্লিক করুন)", - "columns": "কলাম", - "columnsHint": "কলাম বাছাই করতে ডান-ক্লিক করুন", - "emptyFolder": "এই ফোল্ডারটি খালি", - "searchFiles": "ফাইলগুলি অনুসন্ধান করুন...", - "upload": "আপলোড", - "selectHostToStart": "ফাইল ব্যবস্থাপনা শুরু করতে একটি হোস্ট নির্বাচন করুন", - "sshRequiredForFileManager": "ফাইল ম্যানেজারের জন্য SSH প্রয়োজন। এই হোস্টে SSH সক্রিয় করা নেই।", - "failedToConnect": "SSH-এর সাথে সংযোগ করতে ব্যর্থ হয়েছে", - "failedToLoadDirectory": "ডিরেক্টরি লোড করতে ব্যর্থ হয়েছে", - "noSSHConnection": "কোন SSH সংযোগ উপলব্ধ নেই", - "copy": "অনুলিপি", - "cut": "কাটা", - "paste": "পেস্ট", - "copyPath": "কপি পাথ", - "copyPaths": "কপি পাথ", - "delete": "মুছে ফেলুন", - "properties": "বৈশিষ্ট্য", - "refresh": "রিফ্রেশ", - "downloadFiles": "ব্রাউজারে {{count}} ফাইলগুলো ডাউনলোড করুন", - "copyFiles": "{{count}} আইটেম কপি করুন", - "cutFiles": "{{count}} টি আইটেম কাটুন", - "deleteFiles": "{{count}} টি আইটেম মুছুন", - "filesCopiedToClipboard": "{{count}} আইটেম ক্লিপবোর্ডে কপি করা হয়েছে", - "filesCutToClipboard": "{{count}} আইটেমগুলো ক্লিপবোর্ডে কাটা হয়েছে", - "pathCopiedToClipboard": "পাথটি ক্লিপবোর্ডে কপি করা হয়েছে", - "pathsCopiedToClipboard": "{{count}} পাথগুলো ক্লিপবোর্ডে কপি করা হয়েছে", - "failedToCopyPath": "ক্লিপবোর্ডে পাথ কপি করতে ব্যর্থ হয়েছে", - "copyFolderLink": "ফোল্ডারে লিঙ্ক কপি করুন", - "copyCurrentFolderLink": "বর্তমান ফোল্ডারে লিঙ্ক কপি করুন", - "folderLinkCopied": "ফোল্ডারের লিঙ্ক ক্লিপবোর্ডে কপি করা হয়েছে", - "failedToCopyFolderLink": "ফোল্ডার লিঙ্ক কপি করতে ব্যর্থ হয়েছে", - "movedItems": "{{count}} টি আইটেম সরানো হয়েছে", - "failedToDeleteItem": "আইটেমটি মুছে ফেলতে ব্যর্থ হয়েছে", - "itemRenamedSuccessfully": "{{type}} সফলভাবে নাম পরিবর্তন করা হয়েছে", - "failedToRenameItem": "আইটেমের নাম পরিবর্তন করতে ব্যর্থ হয়েছে", - "download": "ডাউনলোড করুন", - "openExternalEditor": "বাইরে খুলুন", - "chooseExternalEditor": "বাহ্যিক সম্পাদক নির্বাচন করুন", - "externalEditorSelected": "বাহ্যিক সম্পাদক নির্বাচিত", - "externalEditorDesktopOnly": "এক্সটার্নাল এডিটর শুধুমাত্র ডেস্কটপ অ্যাপে উপলব্ধ।", - "externalEditorOpened": "বাহ্যিক এডিটরে খোলা হয়েছে। সেখানে সেভ করলে পরিবর্তনগুলো সার্ভারে আপলোড হয়ে যাবে।", - "failedToOpenExternalEditor": "বাহ্যিক সম্পাদক খুলতে ব্যর্থ হয়েছে", - "failedToSelectExternalEditor": "বাহ্যিক সম্পাদক নির্বাচন করতে ব্যর্থ হয়েছে", - "permissions": "অনুমতি", - "size": "আকার", - "modified": "পরিবর্তিত", - "path": "পথ", - "confirmDelete": "আপনি কি {{name}} মুছে ফেলতে নিশ্চিত?", - "permissionDenied": "অনুমতি প্রত্যাখ্যান করা হয়েছে", - "serverError": "সার্ভার ত্রুটি", - "fileSavedSuccessfully": "ফাইল সফলভাবে সংরক্ষিত হয়েছে।", - "failedToSaveFile": "ফাইল সংরক্ষণ করতে ব্যর্থ হয়েছে", - "confirmDeleteSingleItem": "আপনি কি \"{{name}} \" স্থায়ীভাবে মুছে ফেলতে চান?", - "confirmDeleteMultipleItems": "আপনি কি {{count}} টি আইটেম স্থায়ীভাবে মুছে ফেলতে চান?", - "confirmDeleteMultipleItemsWithFolders": "আপনি কি {{count}} টি আইটেম স্থায়ীভাবে মুছে ফেলতে নিশ্চিত? এর মধ্যে ফোল্ডার এবং তার ভেতরের সবকিছু অন্তর্ভুক্ত।", - "confirmDeleteFolder": "আপনি কি \"{{name}}\" ফোল্ডারটি এবং এর ভেতরের সবকিছু স্থায়ীভাবে মুছে ফেলতে চান?", - "permanentDeleteWarning": "এই কাজটি পূর্বাবস্থায় ফেরানো যাবে না। আইটেম(গুলি) সার্ভার থেকে স্থায়ীভাবে মুছে ফেলা হবে।", - "moveToTrashWarning": "আইটেমটি টারমিক্স ট্র্যাশে স্থানান্তরিত হবে এবং সংরক্ষণের সময়সীমা শেষ হওয়ার আগে তা পুনরুদ্ধার করা যাবে।", - "itemsMovedToTrash": "{{count}} আইটেম(গুলি) ট্র্যাশে সরানো হয়েছে", - "trash": "আবর্জনা", - "trashDescription": "এই হোস্টে মুছে ফেলা আইটেমগুলি {{days}} দিন পর্যন্ত সংরক্ষিত থাকে।", - "trashLoadFailed": "ট্র্যাশ লোড করতে ব্যর্থ হয়েছে", - "trashEmpty": "ময়লার ঝুড়ি খালি", - "trashRestore": "পুনরুদ্ধার করুন", - "trashRestored": "পুনরুদ্ধার করা হয়েছে {{name}}", - "trashRestoreFailed": "আইটেমটি পুনরুদ্ধার করা সম্ভব হয়নি। মূল পাথটি হয়তো ইতিমধ্যেই বিদ্যমান আছে।", - "trashDeletePermanently": "স্থায়ীভাবে মুছে ফেলুন", - "trashDeleteConfirm": "{{name}}স্থায়ীভাবে মুছে ফেলবেন? এটি আর পূর্বাবস্থায় ফেরানো যাবে না।", - "trashPermanentlyDeleted": "স্থায়ীভাবে মুছে ফেলা হয়েছে {{name}}", - "trashDeleteFailed": "আইটেমটি স্থায়ীভাবে মুছে ফেলতে ব্যর্থ হয়েছে", - "trashEmptyAction": "ময়লা খালি করুন", - "trashEmptyConfirm": "ট্র্যাশের প্রতিটি আইটেম স্থায়ীভাবে মুছে ফেলবেন? এটি আর পূর্বাবস্থায় ফেরানো যাবে না।", - "trashEmptied": "ময়লা খালি করা হয়েছে", - "trashRetention": "(দিন) পর স্বয়ংক্রিয়ভাবে পরিষ্কার করা হবে", - "trashRetentionSaved": "আবর্জনা সংরক্ষণের সময় আপডেট করা হয়েছে", - "trashRetentionFailed": "ট্র্যাশ রিটেনশন আপডেট করতে ব্যর্থ হয়েছে", - "trashUnavailableConfirm": "এই আইটেমটি ট্র্যাশে সরানো যাচ্ছে না, কারণ এটি সাধারণত অন্য ফাইলসিস্টেমে রয়েছে অথবা এর জন্য বিশেষ অনুমতির প্রয়োজন। এর পরিবর্তে এটি স্থায়ীভাবে মুছে ফেলবেন?", - "recent": "সাম্প্রতিক", - "pinned": "পিন করা", - "folderShortcuts": "ফোল্ডার শর্টকাট", - "failedToReconnectSSH": "SSH সেশন পুনরায় সংযোগ করতে ব্যর্থ হয়েছে", - "openTerminalHere": "এখানে টার্মিনাল খুলুন", - "run": "দৌড়", - "openTerminalInFolder": "এই ফোল্ডারে টার্মিনাল খুলুন", - "openTerminalInFileLocation": "ফাইল লোকেশনে টার্মিনাল খুলুন", - "runningFile": "দৌড়ানো - {{file}}", - "onlyRunExecutableFiles": "শুধুমাত্র এক্সিকিউটেবল ফাইল চালানো যাবে", - "directories": "ডিরেক্টরি", - "removedFromRecentFiles": "সাম্প্রতিক ফাইলগুলি থেকে \"{{name}}\" সরানো হয়েছে", - "removeFailed": "ব্যর্থ অপসারণ", - "unpinnedSuccessfully": "\"{{name}}\" সফলভাবে আনপিন করা হয়েছে", - "unpinFailed": "আনপিন ব্যর্থ হয়েছে", - "removedShortcut": "\"{{name}} \" শর্টকাটটি সরানো হয়েছে", - "removeShortcutFailed": "শর্টকাট অপসারণ ব্যর্থ হয়েছে", - "clearedAllRecentFiles": "সাম্প্রতিক সমস্ত ফাইল মুছে ফেলা হয়েছে", - "clearFailed": "পরিষ্কার করতে ব্যর্থ হয়েছে", - "removeFromRecentFiles": "সাম্প্রতিক ফাইলগুলি থেকে সরান", - "clearAllRecentFiles": "সাম্প্রতিক সমস্ত ফাইল মুছে ফেলুন", - "unpinFile": "ফাইলটি আনপিন করুন", - "removeShortcut": "শর্টকাট সরান", - "pinFile": "পিন ফাইল", - "addToShortcuts": "শর্টকাটে যোগ করুন", - "pasteFailed": "পেস্ট ব্যর্থ হয়েছে", - "noUndoableActions": "কোনো পূর্বাবস্থায় ফেরানো যায় না এমন কাজ নেই।", - "undoCopySuccess": "কপি অপারেশন বাতিল করা হয়েছে: {{count}} টি কপি করা ফাইল মুছে ফেলা হয়েছে", - "undoCopyFailedDelete": "পূর্বাবস্থায় ফেরানো ব্যর্থ হয়েছে: কপি করা কোনো ফাইল মুছে ফেলা সম্ভব হয়নি", - "undoCopyFailedNoInfo": "পূর্বাবস্থায় ফেরানো ব্যর্থ হয়েছে: কপি করা ফাইলের তথ্য খুঁজে পাওয়া যায়নি", - "undoMoveSuccess": "স্থানান্তর প্রক্রিয়া বাতিল করা হয়েছে: {{count}} টি ফাইল মূল অবস্থানে ফিরিয়ে আনা হয়েছে", - "undoMoveFailedMove": "পূর্বাবস্থায় ফেরানো ব্যর্থ হয়েছে: কোনো ফাইল আগের জায়গায় সরানো সম্ভব হয়নি", - "undoMoveFailedNoInfo": "পূর্বাবস্থায় ফেরানো ব্যর্থ হয়েছে: স্থানান্তরিত ফাইলের তথ্য খুঁজে পাওয়া যায়নি", - "undoDeleteNotSupported": "মুছে ফেলার প্রক্রিয়াটি পূর্বাবস্থায় ফেরানো যাবে না: ফাইলগুলো সার্ভার থেকে স্থায়ীভাবে মুছে ফেলা হয়েছে।", - "undoTypeNotSupported": "অসমর্থিত পূর্বাবস্থায় ফেরানোর অপারেশনের ধরণ", - "undoOperationFailed": "পূর্বাবস্থায় ফেরানো ব্যর্থ হয়েছে", - "unknownError": "অজানা ত্রুটি", - "confirm": "নিশ্চিত করুন", - "find": "খুঁজুন...", - "replace": "প্রতিস্থাপন করুন", - "downloadInstead": "পরিবর্তে ডাউনলোড করুন", - "keyboardShortcuts": "কীবোর্ড শর্টকাট", - "searchAndReplace": "অনুসন্ধান ও প্রতিস্থাপন", - "editing": "সম্পাদনা", - "search": "অনুসন্ধান", - "findNext": "পরবর্তী খুঁজুন", - "findPrevious": "পূর্ববর্তী খুঁজুন", - "save": "সংরক্ষণ করুন", - "selectAll": "সব নির্বাচন করুন", - "undo": "পূর্বাবস্থায় ফেরান", - "redo": "পুনরায় করুন", - "moveLineUp": "লাইন আপ সরান", - "moveLineDown": "লাইন নিচে সরান", - "toggleComment": "মন্তব্য টগল করুন", - "autoComplete": "স্বয়ংক্রিয়ভাবে সম্পূর্ণ", - "imageLoadError": "ছবি লোড করতে ব্যর্থ হয়েছে", - "startTyping": "টাইপ করা শুরু করুন...", - "unknownSize": "অজানা আকার", - "fileIsEmpty": "ফাইলটি খালি", - "largeFileWarning": "বড় ফাইলের সতর্কতা", - "largeFileWarningDesc": "এই ফাইলটির আকার {{size}} , যা টেক্সট হিসেবে খুললে পারফরম্যান্সের সমস্যা সৃষ্টি করতে পারে।", - "fileNotFoundAndRemoved": "\"{{name}}\" ফাইলটি খুঁজে পাওয়া যায়নি এবং সাম্প্রতিক/পিন করা ফাইলগুলো থেকে সরিয়ে ফেলা হয়েছে।", - "failedToLoadFile": "ফাইল লোড করতে ব্যর্থ: {{error}}", - "serverErrorOccurred": "সার্ভার ত্রুটি ঘটেছে। অনুগ্রহ করে পরে আবার চেষ্টা করুন।", - "autoSaveFailed": "স্বয়ংক্রিয় সংরক্ষণ ব্যর্থ হয়েছে", - "fileAutoSaved": "ফাইল স্বয়ংক্রিয়ভাবে সংরক্ষিত হয়েছে", - "moveFileFailed": "{{name}} সরাতে ব্যর্থ", - "moveOperationFailed": "স্থানান্তর প্রক্রিয়া ব্যর্থ হয়েছে", - "canOnlyCompareFiles": "শুধুমাত্র দুটি ফাইল তুলনা করা যাবে।", - "comparingFiles": "ফাইলগুলোর তুলনা: {{file1}} এবং {{file2}}", - "dragFailed": "ড্র্যাগ অপারেশন ব্যর্থ হয়েছে", - "filePinnedSuccessfully": "ফাইল \"{{name}}\" সফলভাবে পিন করা হয়েছে", - "pinFileFailed": "ফাইল পিন করতে ব্যর্থ হয়েছে", - "fileUnpinnedSuccessfully": "ফাইল \"{{name}}\" সফলভাবে আনপিন করা হয়েছে", - "unpinFileFailed": "ফাইল আনপিন করতে ব্যর্থ হয়েছে", - "shortcutAddedSuccessfully": "ফোল্ডার শর্টকাট \"{{name}}\" সফলভাবে যোগ করা হয়েছে", - "addShortcutFailed": "শর্টকাট যোগ করতে ব্যর্থ হয়েছে", - "operationCompletedSuccessfully": "{{operation}} {{count}} আইটেম সফলভাবে", - "operationCompleted": "{{operation}} {{count}} আইটেম", - "downloadFileSuccess": "ফাইল {{name}} সফলভাবে ডাউনলোড হয়েছে", - "downloadFileFailed": "ডাউনলোড ব্যর্থ হয়েছে", - "downloadingFile": "ডাউনলোড হচ্ছে {{name}}…", - "downloadProgressBytes": "{{transferred}} / {{total}}", - "moveTo": "{{name}} এ যান", - "diffCompareWith": "{{name}} এর সাথে পার্থক্য তুলনা করুন", - "dragOutsideToDownload": "ডাউনলোড করতে উইন্ডোর বাইরে টেনে আনুন ({{count}} ফাইলগুলো)", - "newFolderDefault": "নতুন ফোল্ডার", - "newFileDefault": "NewFile.txt", - "successfullyMovedItems": "{{count}} টি আইটেম সফলভাবে {{target}} টি আইটেমে সরানো হয়েছে", - "move": "স্থানান্তর", - "searchInFile": "ফাইলে অনুসন্ধান করুন (Ctrl+F)", - "showKeyboardShortcuts": "কিবোর্ড শর্টকাট দেখান", - "decreaseFontSize": "ফন্টের আকার কমান", - "increaseFontSize": "ফন্টের আকার বাড়ান", - "startWritingMarkdown": "আপনার মার্কডাউন কন্টেন্ট লেখা শুরু করুন...", - "loadingFileComparison": "ফাইল তুলনা লোড হচ্ছে...", - "reload": "পুনরায় লোড করুন", - "compare": "তুলনা করুন", - "sideBySide": "পাশাপাশি", - "inline": "ইনলাইন", - "fileComparison": "ফাইল তুলনা: {{file1}} বনাম {{file2}}", - "fileTooLarge": "ফাইলের আকার অনেক বড়: {{error}}", - "sshConnectionFailed": "SSH সংযোগ ব্যর্থ হয়েছে। অনুগ্রহ করে {{name}} ({{ip}}:{{port}} ) -এ আপনার সংযোগ পরীক্ষা করুন।", - "loadFileFailed": "ফাইল লোড করতে ব্যর্থ: {{error}}", - "connecting": "সংযোগ স্থাপন...", - "connectedSuccessfully": "সফলভাবে সংযুক্ত হয়েছে", - "totpVerificationFailed": "TOTP যাচাইকরণ ব্যর্থ হয়েছে", - "authenticationFailed": "প্রমাণীকরণ ব্যর্থ হয়েছে", - "incorrectPassphrase": "ভুল পাসফ্রেজ। অনুগ্রহ করে আবার চেষ্টা করুন।", - "verificationCodePrompt": "যাচাইকরণ কোড:", - "changePermissions": "অনুমতি পরিবর্তন করুন", - "currentPermissions": "বর্তমান অনুমতি", - "owner": "মালিক", - "group": "গ্রুপ", - "others": "অন্যান্য", - "read": "পড়ুন", - "write": "লিখুন", - "execute": "কার্যকর করুন", - "permissionsChangedSuccessfully": "অনুমতি সফলভাবে পরিবর্তন করা হয়েছে", - "failedToChangePermissions": "অনুমতি পরিবর্তন করতে ব্যর্থ হয়েছে", - "name": "নাম", - "sortByName": "নাম", - "sortByDate": "পরিবর্তিত তারিখ", - "sortBySize": "আকার", - "ascending": "আরোহী", - "descending": "অবতরণ", - "root": "মূল", - "new": "নতুন", - "sortBy": "অনুসারে সাজান", - "items": "আইটেম", - "selected": "নির্বাচিত", - "editor": "সম্পাদক", - "octal": "অক্টাল", - "storage": "স্টোরেজ", - "disk": "ডিস্ক", - "used": "ব্যবহৃত", - "of": "এর", - "toggleSidebar": "সাইডবার টগল করুন", - "compactLayout": "সংক্ষিপ্ত বিন্যাস ব্যবহার করুন", - "comfortableLayout": "আরামদায়ক বিন্যাস ব্যবহার করুন", - "cannotLoadPdf": "পিডিএফ লোড করা যাচ্ছে না", - "pdfLoadError": "এই পিডিএফ ফাইলটি লোড করতে ত্রুটি হয়েছে।", - "loadingPdf": "পিডিএফ লোড হচ্ছে...", - "loadingPage": "পৃষ্ঠা লোড হচ্ছে..." + "nav": { + "files": "Files", + "sftp": "SFTP", + "openFileManager": "Open File Manager" }, - "sftpTransfer": { - "title": "এসএফটিপি", - "description": "দুটি SSH হোস্টের মধ্যে ফাইল স্থানান্তর করুন।", - "sourceServer": "উৎস সার্ভার", - "destinationServer": "গন্তব্য সার্ভার", - "selectHost": "হোস্ট নির্বাচন করুন", - "noHostSelected": "কোন হোস্ট নির্বাচন করা হয়নি", - "move": "স্থানান্তর", - "copy": "অনুলিপি", - "upload": "আপলোড", - "itemsSelected": "{{count}} আইটেম নির্বাচিত", - "itemsSelected_other": "{{count}} নির্বাচিত আইটেম", - "ready": "প্রস্তুত", - "loadingHosts": "হোস্ট লোড হচ্ছে...", - "name": "নাম", - "modified": "পরিবর্তিত", - "size": "আকার", - "noFiles": "কোন ফাইল নেই", - "open": "খোলা", - "up": "উপরে", - "refresh": "রিফ্রেশ", - "copyToTarget": "লক্ষ্য ডিরেক্টরিতে অনুলিপি করুন", - "rename": "নাম পরিবর্তন", - "delete": "মুছে ফেলুন", - "editPermissions": "সম্পাদনার অনুমতি", - "createNewFolder": "নতুন ফোল্ডার তৈরি করুন", - "deleteSelectedItems": "নির্বাচিত আইটেমগুলি মুছুন", - "deleteConfirm": "{{count}} নির্বাচিত আইটেমটি মুছবেন?", - "deleteConfirm_other": "{{count}} নির্বাচিত আইটেমগুলি মুছবেন?", - "cancel": "বাতিল করুন", - "save": "সংরক্ষণ করুন", - "folderCreated": "ফোল্ডার তৈরি করা হয়েছে", - "itemRenamed": "আইটেমের নাম পরিবর্তন করা হয়েছে", - "actionFailed": "পদক্ষেপ ব্যর্থ হয়েছে", - "itemsDeleted": "{{count}} আইটেমটি মুছে ফেলা হয়েছে", - "itemsDeleted_other": "{{count}} আইটেম মুছে ফেলা হয়েছে", - "deleteFailed": "মুছে ফেলা ব্যর্থ হয়েছে", - "permissionsUpdated": "অনুমতি আপডেট করা হয়েছে", - "noRemoteSessionConnected": "কোন রিমোট সেশন সংযুক্ত নেই", - "failedToListFiles": "ফাইলগুলি তালিকাভুক্ত করতে ব্যর্থ হয়েছে", - "failedToRefresh": "রিফ্রেশ করতে ব্যর্থ হয়েছে", - "destinationInsideSource": "গন্তব্য নির্বাচিত উৎস পথের মধ্যে থাকতে পারবে না।", - "sameHostNoOp": "উৎস এবং গন্তব্য একই ফোল্ডার।" - }, - "hosts": { - "fileManager": "ফাইল ম্যানেজার", - "tabFiles": "ফাইল", - "enableFileManagerMonitor": "ফাইল ম্যানেজার সক্রিয় করুন", - "enableFileManagerMonitorDesc": "SFTP-এর মাধ্যমে এই হোস্টের ফাইলগুলি ব্রাউজ ও পরিচালনা করুন।", - "scpLegacyLabel": "SCP লিগ্যাসি মোড", - "scpLegacyDesc": "যেসব সার্ভার SFTP সাবসিস্টেম সমর্থন করে না (যেমন এমবেডেড বা মিনিমাল SSH সার্ভার), সেগুলোর জন্য লিগ্যাসি ফাইল ট্রান্সফার ব্যবহার করুন।", - "defaultPathLabel": "ডিফল্ট পথ", - "fileManagerPathHint": "এই হোস্টের জন্য ফাইল ম্যানেজার চালু হলে যে ডিরেক্টরিটি খুলবে।", - "fileManagerUrlCopied": "ফাইল ম্যানেজার ইউআরএল কপি করা হয়েছে", - "copyFileManagerUrlAction": "ফাইল ম্যানেজার ইউআরএল কপি করুন", - "docsLink": "নথি দেখুন", - "hostNotFound": "হোস্ট খুঁজে পাওয়া যায়নি", - "loadingHost": "হোস্ট লোড হচ্ছে..." + "permissions": { + "use": { + "title": "Use file manager", + "description": "Browse, edit and transfer files over SFTP." + } }, "settings": { "host": { "enable": { - "label": "ফাইল ম্যানেজার সক্রিয় করুন" + "label": "Enable File Manager", + "description": "Browse and edit files on this host over SFTP." }, "defaultPath": { - "label": "ডিফল্ট পথ" + "label": "Default Path" }, "scpLegacy": { - "label": "SCP লিগ্যাসি মোড" + "label": "SCP Legacy Mode" } }, "user": { "transferConcurrency": { - "label": "একযোগে ফাইল স্থানান্তর", - "description": "সাইড বাই সাইড লোকাল/রিমোট ম্যানেজার একই সময়ে কতগুলো ফাইল আপলোড বা ডাউনলোড করে। আপনার সার্ভার যদি SFTP চ্যানেল সীমিত করে, তবে এই সংখ্যাটি কমিয়ে দিন।" + "label": "Simultaneous File Transfers", + "description": "How many files the side by side local/remote manager uploads or downloads at the same time. Lower this if your server limits SFTP channels." + }, + "confirmBeforeTrash": { + "label": "Confirm before moving files to trash", + "description": "Ask before moving remote files to trash. Permanent deletion still requires confirmation." } } }, - "nav": { - "sftp": "এসএফটিপি", - "files": "ফাইল" + "hostCapability": { + "label": "File Manager" + }, + "fileManager": { + "noHostSelected": "No host selected", + "initializingEditor": "Initializing editor...", + "file": "File", + "folder": "Folder", + "uploadFile": "Upload File", + "downloadFile": "Download", + "extractArchive": "Extract Archive", + "extractingArchive": "Extracting {{name}}...", + "archiveExtractedSuccessfully": "{{name}} extracted successfully", + "extractFailed": "Extract failed", + "compressFile": "Compress File", + "compressFiles": "Compress Files", + "compressFilesDesc": "Compress {{count}} items into an archive", + "archiveName": "Archive Name", + "enterArchiveName": "Enter archive name...", + "compressionFormat": "Compression Format", + "selectedFiles": "Selected files", + "andMoreFiles": "and {{count}} more...", + "compress": "Compress", + "compressingFiles": "Compressing {{count}} items into {{name}}...", + "filesCompressedSuccessfully": "{{name}} created successfully", + "compressFailed": "Compression failed", + "edit": "Edit", + "preview": "Preview", + "previous": "Previous", + "next": "Next", + "pageXOfY": "Page {{current}} of {{total}}", + "zoomOut": "Zoom Out", + "zoomIn": "Zoom In", + "newFile": "New File", + "newFolder": "New Folder", + "rename": "Rename", + "uploading": "Uploading...", + "uploadingFile": "Uploading {{name}}...", + "uploadingChunk": "Uploading {{name}}: {{percent}}% (part {{chunk}} of {{total}})", + "fileName": "File Name", + "folderName": "Folder Name", + "fileUploadedSuccessfully": "File \"{{name}}\" uploaded successfully", + "failedToUploadFile": "Failed to upload file", + "uploadingFolderFiles": "Uploading {{count}} file(s)...", + "uploadedFolderFiles": "Uploaded {{count}} file(s) successfully", + "uploadedFolderPartial": "Uploaded {{uploaded}} file(s), {{failed}} failed", + "fileDownloadedSuccessfully": "File \"{{name}}\" downloaded successfully", + "failedToDownloadFile": "Failed to download file", + "fileCreatedSuccessfully": "File \"{{name}}\" created successfully", + "folderCreatedSuccessfully": "Folder \"{{name}}\" created successfully", + "failedToCreateItem": "Failed to create item", + "operationFailed": "{{operation}} operation failed for {{name}}: {{error}}", + "failedToResolveSymlink": "Failed to resolve symlink", + "itemsDeletedSuccessfully": "{{count}} items deleted successfully", + "failedToDeleteItems": "Failed to delete items", + "sudoPasswordRequired": "Administrator Password Required", + "enterSudoPassword": "Enter sudo password to continue this operation", + "sudoPassword": "Sudo password", + "sudoOperationFailed": "Sudo operation failed", + "sudoAuthFailed": "Sudo authentication failed", + "dragFilesToUpload": "Drop files here to upload", + "dropToUploadHere": "Drop to upload here", + "dropToDownloadHere": "Drop to download here", + "localFiles": "Local", + "showLocalFiles": "Show local files (split view)", + "hideLocalFiles": "Hide local files", + "localHome": "Home folder", + "localPathPlaceholder": "Local folder path", + "localShowHidden": "Show hidden files", + "localHideHidden": "Hide hidden files", + "localRevealInFileManager": "Reveal in system file manager", + "localCannotOpenFolder": "Cannot open folder", + "localItemCount": "{{count}} items", + "localSelectedCount": "{{count}} selected", + "back": "Back", + "forward": "Forward", + "up": "Up", + "kind": "Kind", + "localUploadingProgress": "Uploading {{current}} of {{total}}", + "localDownloadingProgress": "Downloading {{current}} of {{total}}", + "localTransferInFlight": "{{count}} at once", + "localPreparingDownload": "Preparing download...", + "localTransferCancelled": "Transfer cancelled", + "localNothingToTransfer": "Nothing to transfer", + "localUploadComplete": "Uploaded {{count}} file(s)", + "localUploadFailed": "Upload failed", + "localUploadPartial": "Uploaded {{done}} file(s), {{failed}} failed", + "localDownloadComplete": "Downloaded {{count}} file(s)", + "localDownloadFailed": "Download failed", + "localDownloadPartial": "Downloaded {{done}} file(s), {{failed}} failed", + "localReplaceExistingPrompt": "{{count}} item(s) already exist in this folder. Replace them?", + "localReplace": "Replace", + "localSkipExisting": "Skip", + "localSkippedExisting": "Skipped {{count}} existing item(s)", + "localUnsafeNamesSkipped": "Skipped {{count}} item(s) whose names cannot be used on this computer", + "localOpen": "Open", + "localOpenFolder": "Open folder", + "localUploadToRemote": "Upload to server", + "localUploadToRemoteMany": "Upload {{count}} items to server", + "localMoveToTrash": "Move to Trash", + "localMoveToTrashMany": "Move {{count}} items to Trash", + "localTrashConfirmSingle": "Move \"{{name}}\" to the Trash?", + "localTrashConfirmFolder": "Move the folder \"{{name}}\" and all its contents to the Trash?", + "localTrashConfirmMany": "Move {{count}} items to the Trash?", + "localTrashed": "Moved {{count}} item(s) to the Trash", + "localTrashFailed": "Could not move to the Trash", + "localRenameFailed": "Rename failed", + "localCreateFailed": "Could not create item", + "goToParentFolder": "Go to parent folder", + "resizeSidebar": "Drag to resize the sidebar (double-click to reset)", + "resizeLocalPane": "Drag to resize the local pane (double-click to reset)", + "columns": "Columns", + "columnsHint": "Right-click to choose columns", + "emptyFolder": "This folder is empty", + "searchFiles": "Search files...", + "upload": "Upload", + "selectHostToStart": "Select a host to start file management", + "sshRequiredForFileManager": "File manager requires SSH. This host does not have SSH enabled.", + "failedToConnect": "Failed to connect to SSH", + "failedToLoadDirectory": "Failed to load directory", + "noSSHConnection": "No SSH connection available", + "copy": "Copy", + "cut": "Cut", + "paste": "Paste", + "copyPath": "Copy Path", + "copyPaths": "Copy Paths", + "delete": "Delete", + "properties": "Properties", + "refresh": "Refresh", + "downloadFiles": "Download {{count}} files to Browser", + "copyFiles": "Copy {{count}} items", + "cutFiles": "Cut {{count}} items", + "deleteFiles": "Delete {{count}} items", + "filesCopiedToClipboard": "{{count}} items copied to clipboard", + "filesCutToClipboard": "{{count}} items cut to clipboard", + "pathCopiedToClipboard": "Path copied to clipboard", + "pathsCopiedToClipboard": "{{count}} paths copied to clipboard", + "failedToCopyPath": "Failed to copy path to clipboard", + "copyFolderLink": "Copy Link to Folder", + "copyCurrentFolderLink": "Copy Link to Current Folder", + "folderLinkCopied": "Folder link copied to clipboard", + "failedToCopyFolderLink": "Failed to copy folder link", + "movedItems": "Moved {{count}} items", + "failedToDeleteItem": "Failed to delete item", + "itemRenamedSuccessfully": "{{type}} renamed successfully", + "failedToRenameItem": "Failed to rename item", + "download": "Download", + "openExternalEditor": "Open externally", + "chooseExternalEditor": "Choose external editor", + "externalEditorSelected": "External editor selected", + "externalEditorDesktopOnly": "External editor is only available in the desktop app", + "externalEditorOpened": "Opened in external editor. Saving there will upload changes back to the server.", + "failedToOpenExternalEditor": "Failed to open external editor", + "failedToSelectExternalEditor": "Failed to select external editor", + "permissions": "Permissions", + "size": "Size", + "modified": "Modified", + "path": "Path", + "confirmDelete": "Are you sure you want to delete {{name}}?", + "permissionDenied": "Permission denied", + "serverError": "Server Error", + "fileSavedSuccessfully": "File saved successfully", + "failedToSaveFile": "Failed to save file", + "confirmDeleteSingleItem": "Are you sure you want to permanently delete \"{{name}}\"?", + "confirmDeleteMultipleItems": "Are you sure you want to permanently delete {{count}} items?", + "confirmDeleteMultipleItemsWithFolders": "Are you sure you want to permanently delete {{count}} items? This includes folders and their contents.", + "confirmDeleteFolder": "Are you sure you want to permanently delete the folder \"{{name}}\" and all its contents?", + "permanentDeleteWarning": "This action cannot be undone. The item(s) will be permanently deleted from the server.", + "moveToTrashWarning": "The item(s) will be moved to the Termix Trash and can be restored before the retention period expires.", + "itemsMovedToTrash": "{{count}} item(s) moved to Trash", + "trash": "Trash", + "trashDescription": "Deleted items are retained for {{days}} day(s) on this host.", + "trashLoadFailed": "Failed to load Trash", + "trashEmpty": "Trash is empty", + "trashRestore": "Restore", + "trashRestored": "Restored {{name}}", + "trashRestoreFailed": "Failed to restore item. The original path may already exist.", + "trashDeletePermanently": "Delete permanently", + "trashDeleteConfirm": "Permanently delete {{name}}? This cannot be undone.", + "trashPermanentlyDeleted": "Permanently deleted {{name}}", + "trashDeleteFailed": "Failed to permanently delete item", + "trashEmptyAction": "Empty Trash", + "trashEmptyConfirm": "Permanently delete every item in Trash? This cannot be undone.", + "trashEmptied": "Trash emptied", + "trashRetention": "Automatic cleanup after (days)", + "trashRetentionSaved": "Trash retention updated", + "trashRetentionFailed": "Failed to update Trash retention", + "trashUnavailableConfirm": "This item cannot be moved to Trash, usually because it is on another filesystem or requires elevated permissions. Delete it permanently instead?", + "recent": "Recent", + "pinned": "Pinned", + "folderShortcuts": "Folder Shortcuts", + "failedToReconnectSSH": "Failed to reconnect SSH session", + "openTerminalHere": "Open Terminal Here", + "run": "Run", + "openTerminalInFolder": "Open Terminal in This Folder", + "openTerminalInFileLocation": "Open Terminal at File Location", + "runningFile": "Running - {{file}}", + "onlyRunExecutableFiles": "Can only run executable files", + "directories": "Directories", + "removedFromRecentFiles": "Removed \"{{name}}\" from recent files", + "removeFailed": "Remove failed", + "unpinnedSuccessfully": "Unpinned \"{{name}}\" successfully", + "unpinFailed": "Unpin failed", + "removedShortcut": "Removed shortcut \"{{name}}\"", + "removeShortcutFailed": "Remove shortcut failed", + "clearedAllRecentFiles": "Cleared all recent files", + "clearFailed": "Clear failed", + "removeFromRecentFiles": "Remove from recent files", + "clearAllRecentFiles": "Clear all recent files", + "unpinFile": "Unpin file", + "removeShortcut": "Remove shortcut", + "pinFile": "Pin file", + "addToShortcuts": "Add to shortcuts", + "pasteFailed": "Paste failed", + "noUndoableActions": "No undoable actions", + "undoCopySuccess": "Undid copy operation: Deleted {{count}} copied files", + "undoCopyFailedDelete": "Undo failed: Could not delete any copied files", + "undoCopyFailedNoInfo": "Undo failed: Could not find copied file information", + "undoMoveSuccess": "Undid move operation: Moved {{count}} files back to original location", + "undoMoveFailedMove": "Undo failed: Could not move any files back", + "undoMoveFailedNoInfo": "Undo failed: Could not find moved file information", + "undoDeleteNotSupported": "Delete operation cannot be undone: Files have been permanently deleted from server", + "undoTypeNotSupported": "Unsupported undo operation type", + "undoOperationFailed": "Undo operation failed", + "unknownError": "Unknown error", + "confirm": "Confirm", + "find": "Find...", + "replace": "Replace", + "downloadInstead": "Download Instead", + "keyboardShortcuts": "Keyboard Shortcuts", + "searchAndReplace": "Search & Replace", + "editing": "Editing", + "search": "Search", + "findNext": "Find Next", + "findPrevious": "Find Previous", + "save": "Save", + "selectAll": "Select All", + "undo": "Undo", + "redo": "Redo", + "moveLineUp": "Move Line Up", + "moveLineDown": "Move Line Down", + "toggleComment": "Toggle Comment", + "autoComplete": "Auto Complete", + "imageLoadError": "Failed to load image", + "startTyping": "Start typing...", + "unknownSize": "Unknown size", + "fileIsEmpty": "File is empty", + "largeFileWarning": "Large File Warning", + "largeFileWarningDesc": "This file is {{size}} in size, which may cause performance issues when opened as text.", + "fileNotFoundAndRemoved": "File \"{{name}}\" not found and has been removed from recent/pinned files", + "failedToLoadFile": "Failed to load file: {{error}}", + "serverErrorOccurred": "Server error occurred. Please try again later.", + "autoSaveFailed": "Auto-save failed", + "fileAutoSaved": "File auto-saved", + "moveFileFailed": "Failed to move {{name}}", + "moveOperationFailed": "Move operation failed", + "canOnlyCompareFiles": "Can only compare two files", + "comparingFiles": "Comparing files: {{file1}} and {{file2}}", + "dragFailed": "Drag operation failed", + "filePinnedSuccessfully": "File \"{{name}}\" pinned successfully", + "pinFileFailed": "Failed to pin file", + "fileUnpinnedSuccessfully": "File \"{{name}}\" unpinned successfully", + "unpinFileFailed": "Failed to unpin file", + "shortcutAddedSuccessfully": "Folder shortcut \"{{name}}\" added successfully", + "addShortcutFailed": "Failed to add shortcut", + "operationCompletedSuccessfully": "{{operation}} {{count}} items successfully", + "operationCompleted": "{{operation}} {{count}} items", + "downloadFileSuccess": "File {{name}} downloaded successfully", + "downloadFileFailed": "Download failed", + "downloadingFile": "Downloading {{name}}…", + "downloadProgressBytes": "{{transferred}} / {{total}}", + "moveTo": "Move to {{name}}", + "diffCompareWith": "Diff compare with {{name}}", + "dragOutsideToDownload": "Drag outside window to download ({{count}} files)", + "newFolderDefault": "NewFolder", + "newFileDefault": "NewFile.txt", + "successfullyMovedItems": "Successfully moved {{count}} items to {{target}}", + "move": "Move", + "searchInFile": "Search in file (Ctrl+F)", + "showKeyboardShortcuts": "Show keyboard shortcuts", + "decreaseFontSize": "Decrease font size", + "increaseFontSize": "Increase font size", + "startWritingMarkdown": "Start writing your markdown content...", + "loadingFileComparison": "Loading file comparison...", + "reload": "Reload", + "compare": "Compare", + "sideBySide": "Side by Side", + "inline": "Inline", + "fileComparison": "File Comparison: {{file1}} vs {{file2}}", + "fileTooLarge": "File too large: {{error}}", + "sshConnectionFailed": "SSH connection failed. Please check your connection to {{name}} ({{ip}}:{{port}})", + "loadFileFailed": "Failed to load file: {{error}}", + "connecting": "Connecting...", + "connectedSuccessfully": "Connected successfully", + "totpVerificationFailed": "TOTP verification failed", + "browserSignInFailed": "Sign-in failed. Please try again.", + "authenticationFailed": "Authentication failed", + "incorrectPassphrase": "Incorrect passphrase. Please try again.", + "verificationCodePrompt": "Verification code:", + "changePermissions": "Change Permissions", + "currentPermissions": "Current Permissions", + "owner": "Owner", + "group": "Group", + "others": "Others", + "read": "Read", + "write": "Write", + "execute": "Execute", + "permissionsChangedSuccessfully": "Permissions changed successfully", + "failedToChangePermissions": "Failed to change permissions", + "name": "Name", + "sortByName": "Name", + "sortByDate": "Date Modified", + "sortBySize": "Size", + "ascending": "Ascending", + "descending": "Descending", + "root": "Root", + "new": "New", + "sortBy": "Sort By", + "items": "Items", + "selected": "Selected", + "editor": "Editor", + "octal": "Octal", + "storage": "Storage", + "disk": "Disk", + "used": "Used", + "of": "of", + "toggleSidebar": "Toggle Sidebar", + "compactLayout": "Use compact layout", + "comfortableLayout": "Use comfortable layout", + "cannotLoadPdf": "Cannot load PDF", + "pdfLoadError": "There was an error loading this PDF file.", + "loadingPdf": "Loading PDF...", + "loadingPage": "Loading page...", + "cancel": "Cancel", + "copiedItems_one": "Copied {{count}} item", + "copiedItems_other": "Copied {{count}} items", + "deleteCopiedFileFailed": "Could not delete the copy of {{name}}: {{error}}", + "dragMovedItems_one": "Moved {{count}} item to {{target}}", + "dragMovedItems_other": "Moved {{count}} items to {{target}}", + "moveBackFileFailed": "Could not move {{name}} back: {{error}}", + "terminal": "Terminal: {{host}} ({{path}})", + "dragToDesktop": "Dragging {{name}} to the desktop", + "dragFilesToDesktop": "Dragging {{count}} files to the desktop", + "folderDragUnsupported": "Dragging folders to the desktop is not supported yet", + "saveToDesktopFailed": "Save failed: {{error}}", + "dragFailedDetail": "Drag failed: {{error}}", + "videoUnsupported": "Your browser cannot play this video format.", + "downloadToPlay": "Download to play it elsewhere", + "cannotPreviewType": "Cannot preview this file type", + "cannotPreviewTypeHint": "This file type has no preview. Download it to open it in another app." + }, + "sftpTransfer": { + "title": "SFTP", + "description": "Transfer files between two SSH hosts.", + "sourceServer": "Source Server", + "destinationServer": "Destination Server", + "selectHost": "Select host", + "noHostSelected": "No host selected", + "move": "Move", + "copy": "Copy", + "upload": "Upload", + "itemsSelected": "{{count}} item selected", + "itemsSelected_other": "{{count}} items selected", + "ready": "Ready", + "loadingHosts": "Loading hosts...", + "name": "Name", + "modified": "Modified", + "size": "Size", + "noFiles": "No files", + "open": "Open", + "up": "Up", + "refresh": "Refresh", + "copyToTarget": "Copy to Target Directory", + "rename": "Rename", + "delete": "Delete", + "editPermissions": "Edit Permissions", + "createNewFolder": "Create New Folder", + "deleteSelectedItems": "Delete Selected Items", + "deleteConfirm": "Delete {{count}} selected item?", + "deleteConfirm_other": "Delete {{count}} selected items?", + "cancel": "Cancel", + "save": "Save", + "folderCreated": "Folder created", + "itemRenamed": "Item renamed", + "actionFailed": "Action failed", + "itemsDeleted": "{{count}} item deleted", + "itemsDeleted_other": "{{count}} items deleted", + "deleteFailed": "Delete failed", + "permissionsUpdated": "Permissions updated", + "noRemoteSessionConnected": "No remote session connected", + "failedToListFiles": "Failed to list files", + "failedToRefresh": "Failed to refresh", + "destinationInsideSource": "Destination cannot be inside the selected source path.", + "sameHostNoOp": "Source and destination are the same folder." + }, + "hosts": { + "fileManager": "File Manager", + "fileManagerUrlCopied": "File Manager URL copied", + "copyFileManagerUrlAction": "Copy File Manager URL", + "docsLink": "View docs", + "hostNotFound": "Host not found", + "loadingHost": "Loading host..." }, "onboarding": { - "feature_files": "ফাইল ম্যানেজার", - "feature_files_desc": "অ্যাপ থেকে বের না হয়েই SFTP-এর মাধ্যমে ফাইল ব্রাউজ, আপলোড, ডাউনলোড এবং সম্পাদনা করুন।" + "feature_files": "File manager", + "feature_files_desc": "Browse, upload, download and edit files over SFTP without leaving the app." }, "terminal": { - "runTitle": "দৌড়ানো {{command}} - {{host}}", - "terminalTitle": "টার্মিনাল - {{host}}", - "terminalWithPath": "টার্মিনাল - {{host}}:{{path}}" + "runTitle": "Running {{command}} - {{host}}", + "terminalTitle": "Terminal - {{host}}", + "terminalWithPath": "Terminal - {{host}}:{{path}}" }, "transfer": { - "browseFolders": "গন্তব্য ফোল্ডারগুলি ব্রাউজ করুন", - "browsePathError": "গন্তব্য হোস্টে এই পাথটি খোলা সম্ভব হয়নি।", - "browsePathWillBeCreated": "এই ফোল্ডারটি এখনও তৈরি হয়নি। স্থানান্তর শুরু হলে এটি তৈরি হয়ে যাবে।", - "cancel": "বাতিল করুন", - "cleanupDestFiles": "পরিষ্কার করার গন্তব্য", - "cleanupDestFilesError": "পরিষ্কার করা ব্যর্থ হয়েছে", - "cleanupDestFilesNothing": "গন্তব্যে পরিষ্কার করার কিছু নেই।", - "cleanupDestFilesPartial": "কিছু আংশিক ফাইল সরানো যায়নি", - "cleanupDestFilesSuccess": "গন্তব্য থেকে আংশিক ফাইল সরানো হয়েছে", - "confirmCopy": "অনুলিপি", - "confirmMove": "স্থানান্তর", - "copyFolderToHost": "ফোল্ডারটি হোস্টে কপি করুন…", - "copyItemsToHost": "{{count}} টি আইটেম হোস্টে কপি করুন…", - "copyToHost": "হোস্টে কপি করুন…", - "destinationPath": "গন্তব্য পথ", - "destMustBeDirectory": "একাধিক আইটেম স্থানান্তরের জন্য গন্তব্য অবশ্যই একটি ডিরেক্টরি হতে হবে।", - "goUp": "উপরে যান", - "hostAuthRequired": "প্রমাণীকরণ আবশ্যক — প্রথমে এই হোস্টে ফাইল ম্যানেজার খুলুন।", - "hostConnecting": "… সংযোগ করা হচ্ছে", - "hostConnectionFailed": "সংযোগ ব্যর্থ হয়েছে", - "hostDisconnected": "সংযুক্ত নয়", - "hostReady": "প্রস্তুত", - "itemsSummary": "{{count}} আইটেম", - "jumpHostLimitation": "উভয় হোস্টকেই টারমিক্স সার্ভার থেকে পৌঁছানো সম্ভব হতে হবে। সরাসরি হোস্ট-টু-হোস্ট রাউটিং সমর্থিত নয়।", - "methodAuto": "অটো", - "methodAutoHint": "ফাইলের সংখ্যা, আকার এবং সংকোচনযোগ্যতার উপর ভিত্তি করে tar অথবা ফাইল-ভিত্তিক SFTP নির্বাচন করে। একক ফাইলের ক্ষেত্রে সর্বদা স্ট্রিমিং SFTP ব্যবহৃত হয়।", - "methodItemSftp": "প্রতি-ফাইল এসএফটিপি", - "methodItemSftpHint": "SFTP-এর মাধ্যমে প্রতিটি ফাইল আলাদাভাবে স্থানান্তর করুন। উইন্ডোজ সহ সকল হোস্টে কাজ করে।", - "methodItemSftpLimitation": "প্রতিটি ফাইল একই SFTP স্ট্রিম ব্যবহার করে একটির পর একটি একক-ফাইল কপি হিসেবে তৈরি হয়। সমস্ত ফাইলের অগ্রগতি একত্রিত করা হয়, তাই বড় ফাইলের ক্ষেত্রে বারটি ধীরে চলে।", - "methodLabel": "স্থানান্তর পদ্ধতি", - "methodPreviewError": "স্থানান্তর পদ্ধতির প্রিভিউ দেখা সম্ভব হয়নি। আপনি চালু করার সময় সার্ভার নিজেই একটি পদ্ধতি বেছে নেবে।", - "methodPreviewLoading": "স্থানান্তর পদ্ধতি গণনা করা হচ্ছে…", - "methodPreviewScanSummary": "{{fileCount}} টি ফাইল, {{totalSize}} টি মোট (উৎস হোস্টে স্ক্যান করা হয়েছে)।", - "methodPreviewWillUseItemSftp": "ব্যবহার করা হবে: প্রতি-ফাইল এসএফটিপি", - "methodPreviewWillUseTar": "ব্যবহৃত হবে: টার আর্কাইভ", + "browseFolders": "Browse destination folders", + "browsePathError": "Could not open this path on the destination host.", + "browsePathWillBeCreated": "This folder does not exist yet. It will be created when the transfer starts.", + "cancel": "Cancel", + "cleanupDestFiles": "Clean up destination", + "cleanupDestFilesError": "Cleanup failed", + "cleanupDestFilesNothing": "Nothing to clean up on the destination", + "cleanupDestFilesPartial": "Some partial files could not be removed", + "cleanupDestFilesSuccess": "Removed partial files from the destination", + "confirmCopy": "Copy", + "confirmMove": "Move", + "copyFolderToHost": "Copy folder to host…", + "copyItemsToHost": "Copy {{count}} items to host…", + "copyToHost": "Copy to host…", + "destinationPath": "Destination path", + "destMustBeDirectory": "Destination must be a directory for multi-item transfers", + "goUp": "Go up", + "hostAuthRequired": "Authentication required. Open File Manager on this host first", + "hostConnecting": "Connecting…", + "hostConnectionFailed": "Connection failed", + "hostDisconnected": "Not connected", + "hostReady": "Ready", + "itemsSummary": "{{count}} items", + "jumpHostLimitation": "Both hosts must be reachable from the Termix server. Direct host-to-host routing is not supported.", + "methodAuto": "Auto", + "methodAutoHint": "Picks tar or per-file SFTP based on file count, size, and compressibility. Single files always use streaming SFTP.", + "methodItemSftp": "Per-file SFTP", + "methodItemSftpHint": "Transfer each file individually over SFTP. Works on all hosts including Windows.", + "methodItemSftpLimitation": "Each file uses the same SFTP stream as a single-file copy, one after another. Progress is combined across all files, so the bar moves slowly during large files.", + "methodLabel": "Transfer method", + "methodPreviewError": "Could not preview transfer method. The server will still pick a method when you start.", + "methodPreviewLoading": "Calculating transfer method…", + "methodPreviewScanSummary": "{{fileCount}} files, {{totalSize}} total (scanned on source host).", + "methodPreviewWillUseItemSftp": "Will use: Per-file SFTP", + "methodPreviewWillUseTar": "Will use: Tar archive", "methodReason": { - "user_item_sftp": "আপনি ফাইল-ভিত্তিক এসএফটিপি বেছে নিয়েছেন।", - "user_tar": "আপনি tar আর্কাইভটি বেছে নিয়েছেন।", - "tar_unavailable": "এক বা উভয় হোস্টে Tar উপলব্ধ না থাকায়, এর পরিবর্তে ফাইল-ভিত্তিক SFTP ব্যবহার করা হবে।", - "windows_host": "এখানে একটি উইন্ডোজ হোস্ট জড়িত — tar ব্যবহৃত হয় না।", - "auto_multi_large": "স্বয়ংক্রিয়: সংকোচনযোগ্য ডেটা সহ একটি বড় ফাইল ({{largestSize}}) সহ একাধিক ফাইল — tar বান্ডেল করে একটি একক স্থানান্তরে পাঠানো হয়।", - "auto_single_large_in_archive": "স্বয়ংক্রিয়: এই সেটে একটি বড় ফাইল ({{largestSize}}) — ফাইল-ভিত্তিক SFTP।", - "auto_many_incompressible": "স্বয়ংক্রিয়: প্রধানত অসংকোচনযোগ্য ডেটা — ফাইল-ভিত্তিক এসএফটিপি।", - "auto_many_files": "স্বয়ংক্রিয়: একাধিক ফাইল ({{fileCount}}) — tar প্রতি-ফাইল ওভারহেড কমায়।", - "auto_default": "স্বয়ংক্রিয়: এই সেটের জন্য প্রতি-ফাইল এসএফটিপি।" + "user_item_sftp": "You chose per-file SFTP.", + "user_tar": "You chose tar archive.", + "tar_unavailable": "Tar is not available on one or both hosts, so per-file SFTP will be used instead.", + "windows_host": "A Windows host is involved, so tar is not used.", + "auto_multi_large": "Auto: multiple files including a large file ({{largestSize}}) with compressible data. Tar bundles them into one transfer.", + "auto_single_large_in_archive": "Auto: one large file ({{largestSize}}) in this set, so per-file SFTP.", + "auto_many_incompressible": "Auto: mostly incompressible data, so per-file SFTP.", + "auto_many_files": "Auto: many files ({{fileCount}}), tar cuts the per-file overhead.", + "auto_default": "Auto: per-file SFTP for this set." }, - "methodTar": "টার আর্কাইভ", - "methodTarHint": "উৎসস্থলে কম্প্রেস করুন, একটি আর্কাইভ স্থানান্তর করুন, এবং গন্তব্যে এক্সট্র্যাক্ট করুন। উভয় ইউনিক্স হোস্টে tar প্রয়োজন।", - "metricsCompress": "উৎস থেকে সংকুচিত করুন: {{duration}}", - "metricsExtract": "গন্তব্যে নিষ্কাশন: {{duration}}", - "metricsPrepare": "গন্তব্য প্রস্তুত করুন: {{duration}}", - "metricsRouteBenchmark": "রুট প্রোব — সরাসরি: {{direct}}, রিলে: {{relay}}", - "metricsSourceDelete": "উৎস থেকে সরান: {{duration}}", - "metricsTotal": "মোট: {{duration}}", - "metricsTransfer": "প্রান্ত থেকে প্রান্ত: {{throughput}} ({{duration}})", - "metricsVerify": "SHA-256 দ্বারা যাচাইকৃত: {{duration}}", - "moveFolderToHost": "ফোল্ডারটি হোস্টে সরান…", - "moveItemsToHost": "{{count}} টি আইটেম… টি হোস্টে সরান", - "moveToHost": "হোস্টে যান…", - "noHostsConnected": "অন্য কোনো ফাইল-ম্যানেজার হোস্ট উপলব্ধ নেই।", - "noHostsConnectedHint": "হোস্ট ম্যানেজারে ফাইল ম্যানেজার সক্রিয় করা আছে এমন আরেকটি SSH হোস্ট যোগ করুন।", - "parallelSegmentsHint": "বড় ফাইলগুলোকে ২৫৬ মেগাবাইটের খণ্ডে ভাগ করা হয়। মোট থ্রুপুট বাড়ানোর জন্য একাধিক লেন আলাদা সংযোগ ব্যবহার করে (যেমন কয়েকটি ট্রান্সফার শুরু করা)।", - "parallelSegmentsLabel": "সমান্তরাল স্থানান্তর লেন", - "parallelSegmentsOption": "{{count}} লেন", - "progressBenchmarking": "দ্রুততম স্থানান্তর পথ নির্বাচন করা হচ্ছে…", + "methodTar": "Tar archive", + "methodTarHint": "Compress on source, transfer one archive, extract on destination. Requires tar on both Unix hosts.", + "metricsCompress": "Compress on source: {{duration}}", + "metricsExtract": "Extract on destination: {{duration}}", + "metricsPrepare": "Prepare destination: {{duration}}", + "metricsRouteBenchmark": "Route probe: direct {{direct}}, relay {{relay}}", + "metricsSourceDelete": "Remove from source: {{duration}}", + "metricsTotal": "Total: {{duration}}", + "metricsTransfer": "End-to-end: {{throughput}} ({{duration}})", + "metricsVerify": "SHA-256 verified: {{duration}}", + "moveFolderToHost": "Move folder to host…", + "moveItemsToHost": "Move {{count}} items to host…", + "moveToHost": "Move to host…", + "noHostsConnected": "No other file-manager hosts available.", + "noHostsConnectedHint": "Add another SSH host with File Manager enabled in Host Manager.", + "parallelSegmentsHint": "Large files are split into 256 MB chunks. Multiple lanes use separate connections (like starting several transfers) for higher total throughput.", + "parallelSegmentsLabel": "Parallel transfer lanes", + "parallelSegmentsOption": "{{count}} lanes", + "progressBenchmarking": "Selecting the fastest transfer route…", "progressBytes": "{{transferred}} / {{total}}", - "progressCancel": "বাতিল করুন", - "progressCancelling": "বাতিল করা হচ্ছে…", - "progressCompressing": "উৎস হোস্টে সংকুচিত করা হচ্ছে…", - "progressExtracting": "গন্তব্য… থেকে নিষ্কাশন করা হচ্ছে", - "progressItems": "{{current}} / {{total}} ফাইল", - "progressReconnecting": "পুনরায় সংযোগ স্থাপন…", - "progressStalled": "স্থবির", - "progressTotalSpeed": "{{speed}} মোট ({{lanes}} লেন)", - "progressTransferring": "ডেটা স্থানান্তর করা হচ্ছে…", - "progressTransferringItems": "ফাইল স্থানান্তর করা হচ্ছে ({{current}} {{total}})…", - "progressVerifying": "ফাইলের অখণ্ডতা যাচাই করা হচ্ছে…", - "recentDestinations": "সাম্প্রতিক গন্তব্যস্থল", - "resumedHint": "অন্য একটি উইন্ডোতে শুরু হওয়া একটি সক্রিয় ট্রান্সফারের সাথে পুনরায় সংযুক্ত হওয়া গেছে।", - "retryTransfer": "পুনরায় চেষ্টা করুন", - "retryTransferError": "পুনরায় চেষ্টা ব্যর্থ হয়েছে", - "selectDestinationHost": "গন্তব্য হোস্ট নির্বাচন করুন", - "transferCancelled": "স্থানান্তর বাতিল করা হয়েছে", - "transferCancelledCopyHint": "গন্তব্যে আংশিক ফাইল থেকে যেতে পারে।", - "transferCancelledMoveHint": "গন্তব্যে আংশিক ফাইল থেকে যেতে পারে। মূল ফাইলগুলো সরানো হয়নি।", - "transferError": "স্থানান্তর ব্যর্থ হয়েছে", - "transferFailedRetryHint": "গন্তব্যে আংশিক ডেটা সংরক্ষিত হয়েছে। সংযোগ ফিরে এলে পুনরায় চেষ্টা শুরু হবে।", - "transferPartialHint": "স্থানান্তর করা যায়নি: {{paths}}", - "transferSuccess": "স্থানান্তর সম্পন্ন হয়েছে" + "progressCancel": "Cancel", + "progressCancelling": "Cancelling…", + "progressCompressing": "Compressing on source host…", + "progressExtracting": "Extracting on destination…", + "progressItems": "{{current}} / {{total}} files", + "progressReconnecting": "Reconnecting…", + "progressStalled": "Stalled", + "progressTotalSpeed": "{{speed}} total ({{lanes}} lanes)", + "progressTransferring": "Transferring data…", + "progressTransferringItems": "Transferring files ({{current}} of {{total}})…", + "progressVerifying": "Verifying file integrity…", + "recentDestinations": "Recent destinations", + "resumedHint": "Reconnected to an active transfer started in another window.", + "retryTransfer": "Retry", + "retryTransferError": "Retry failed", + "selectDestinationHost": "Select destination host", + "transferCancelled": "Transfer cancelled", + "transferCancelledCopyHint": "Partial files may remain on the destination.", + "transferCancelledMoveHint": "Partial files may remain on the destination. Source files were not removed.", + "transferError": "Transfer failed", + "transferFailedRetryHint": "Partial data was kept on the destination. Retry will resume when the connection is back.", + "transferPartialHint": "Could not transfer: {{paths}}", + "transferSuccess": "Transfer complete", + "metricsHopSourceRead": "Source → server: {{throughput}}", + "metricsHopDestSftpWrite": "Server → dest (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Server → dest (local): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/ca_ES.json b/plugins/file-manager/locales/translated/ca_ES.json index 78207a117..0f6c88420 100644 --- a/plugins/file-manager/locales/translated/ca_ES.json +++ b/plugins/file-manager/locales/translated/ca_ES.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "Fitxers", + "sftp": "SFTP", + "openFileManager": "Obre el gestor de fitxers" + }, + "permissions": { + "use": { + "title": "Utilitza el gestor de fitxers", + "description": "Navega, edita i transfereix fitxers a través de SFTP." + } + }, + "settings": { + "host": { + "enable": { + "label": "Habilita el gestor de fitxers", + "description": "Navega i edita fitxers en aquest amfitrió mitjançant SFTP." + }, + "defaultPath": { + "label": "Camí predeterminat" + }, + "scpLegacy": { + "label": "Mode Llegat de SCP" + } + }, + "user": { + "transferConcurrency": { + "label": "Transferències simultànies de fitxers", + "description": "Quants fitxers puja o descarrega el gestor local/remot en paral·lel alhora. Redueix aquest valor si el teu servidor limita els canals SFTP." + }, + "confirmBeforeTrash": { + "label": "Confirma abans de moure els fitxers a la paperera", + "description": "Pregunta abans de moure fitxers remots a la paperera. L'eliminació permanent encara requereix confirmació." + } + } + }, + "hostCapability": { + "label": "Gestor de fitxers" + }, "fileManager": { "noHostSelected": "No s'ha seleccionat cap amfitrió", "initializingEditor": "Inicialitzant l'editor...", @@ -34,13 +72,14 @@ "rename": "Canvia el nom", "uploading": "S'està carregant...", "uploadingFile": "S'està carregant {{name}}...", + "uploadingChunk": "Pujant {{name}}: {{percent}}% (part {{chunk}} de {{total}})", "fileName": "Nom del fitxer", "folderName": "Nom de la carpeta", "fileUploadedSuccessfully": "El fitxer \"{{name}}\" s'ha carregat correctament", "failedToUploadFile": "No s'ha pogut carregar el fitxer", "uploadingFolderFiles": "S'estan pujant {{count}} fitxer(s)...", - "uploadedFolderFiles": "S'han carregat correctament els fitxers {{count}}", - "uploadedFolderPartial": "No s'ha pogut pujar el(s) fitxer(s) {{uploaded}} , {{failed}}", + "uploadedFolderFiles": "S'han carregat correctament {{count}} fitxers.", + "uploadedFolderPartial": "No s'han pogut pujar els fitxers {{uploaded}} i {{failed}}.", "fileDownloadedSuccessfully": "Fitxer \"{{name}}\" descarregat correctament", "failedToDownloadFile": "No s'ha pogut descarregar el fitxer", "fileCreatedSuccessfully": "Fitxer \"{{name}}\" creat correctament", @@ -54,7 +93,7 @@ "enterSudoPassword": "Introduïu la contrasenya sudo per continuar amb aquesta operació", "sudoPassword": "Contrasenya de Sudo", "sudoOperationFailed": "L'operació Sudo ha fallat.", - "sudoAuthFailed": "L'autenticació de Sudo ha fallat.", + "sudoAuthFailed": "L'autenticació del Sudo ha fallat.", "dragFilesToUpload": "Deixa anar els fitxers aquí per pujar-los", "dropToUploadHere": "Deixa anar per pujar aquí", "dropToDownloadHere": "Deixa anar per descarregar aquí", @@ -73,7 +112,7 @@ "forward": "Endavant", "up": "Amunt", "kind": "Amable", - "localUploadingProgress": "S'està carregant {{current}} de {{total}}", + "localUploadingProgress": "S'està pujant {{current}} de {{total}}", "localDownloadingProgress": "Descarregant {{current}} de {{total}}", "localTransferInFlight": "{{count}} alhora", "localPreparingDownload": "Preparant la descàrrega...", @@ -81,7 +120,7 @@ "localNothingToTransfer": "Res a transferir", "localUploadComplete": "Fitxer(s) {{count}} penjat(s)", "localUploadFailed": "La pujada ha fallat", - "localUploadPartial": "No s'ha pogut pujar el(s) fitxer(s) {{done}} , {{failed}}", + "localUploadPartial": "No s'han pogut pujar els fitxers {{done}} i {{failed}}.", "localDownloadComplete": "Fitxer(s) descarregat(s) {{count}}", "localDownloadFailed": "La descàrrega ha fallat", "localDownloadPartial": "No s'ha pogut descarregar el(s) fitxer(s) {{done}} , {{failed}}.", @@ -212,7 +251,7 @@ "noUndoableActions": "Sense accions desfaibles", "undoCopySuccess": "Operació de còpia desfeta: S'han suprimit {{count}} fitxers copiats", "undoCopyFailedDelete": "Error en desfer: no s'han pogut suprimir els fitxers copiats.", - "undoCopyFailedNoInfo": "Error en desfer: no s'ha pogut trobar la informació del fitxer copiat", + "undoCopyFailedNoInfo": "Error en desfer: no s'ha trobat la informació del fitxer copiat", "undoMoveSuccess": "Operació de moviment desfeta: S'han tornat a moure els fitxers {{count}} a la ubicació original.", "undoMoveFailedMove": "Desfer ha fallat: no s'han pogut moure cap fitxer enrere", "undoMoveFailedNoInfo": "Desfer ha fallat: no s'ha pogut trobar la informació del fitxer mogut", @@ -247,7 +286,7 @@ "fileNotFoundAndRemoved": "No s'ha trobat el fitxer \"{{name}}\" i s'ha eliminat dels fitxers recents/fixats.", "failedToLoadFile": "No s'ha pogut carregar el fitxer: {{error}}", "serverErrorOccurred": "S'ha produït un error del servidor. Torna-ho a provar més tard.", - "autoSaveFailed": "El desament automàtic ha fallat", + "autoSaveFailed": "Ha fallat el desament automàtic", "fileAutoSaved": "Fitxer desat automàticament", "moveFileFailed": "No s'ha pogut moure {{name}}", "moveOperationFailed": "L'operació de moviment ha fallat", @@ -290,6 +329,7 @@ "connecting": "Connectant...", "connectedSuccessfully": "Connexió correcta", "totpVerificationFailed": "La verificació TOTP ha fallat", + "browserSignInFailed": "L'inici de sessió ha fallat. Torna-ho a provar.", "authenticationFailed": "L'autenticació ha fallat", "incorrectPassphrase": "Contrasenya incorrecta. Si us plau, torneu-ho a intentar.", "verificationCodePrompt": "Codi de verificació:", @@ -326,7 +366,24 @@ "cannotLoadPdf": "No es pot carregar el PDF", "pdfLoadError": "S'ha produït un error en carregar aquest fitxer PDF.", "loadingPdf": "S'està carregant el PDF...", - "loadingPage": "S'està carregant la pàgina..." + "loadingPage": "S'està carregant la pàgina...", + "cancel": "Cancel·la", + "copiedItems_one": "S'ha copiat l'element {{count}}", + "copiedItems_other": "S'han copiat {{count}} elements", + "deleteCopiedFileFailed": "No s'ha pogut suprimir la còpia de {{name}}: {{error}}", + "dragMovedItems_one": "S'ha mogut l'element {{count}} a {{target}}", + "dragMovedItems_other": "S'han mogut {{count}} elements a {{target}}", + "moveBackFileFailed": "No s'ha pogut moure {{name}} enrere: {{error}}", + "terminal": "Terminal: {{host}} ({{path}})", + "dragToDesktop": "Arrossegant {{name}} a l'escriptori", + "dragFilesToDesktop": "Arrossegar fitxers {{count}} a l'escriptori", + "folderDragUnsupported": "Encara no es pot arrossegar carpetes a l'escriptori.", + "saveToDesktopFailed": "No s'ha pogut desar: {{error}}", + "dragFailedDetail": "No s'ha pogut arrossegar: {{error}}", + "videoUnsupported": "El vostre navegador no pot reproduir aquest format de vídeo.", + "downloadToPlay": "Descarrega-ho per reproduir-ho en un altre lloc", + "cannotPreviewType": "No es pot previsualitzar aquest tipus de fitxer", + "cannotPreviewTypeHint": "Aquest tipus de fitxer no té vista prèvia. Baixeu-lo per obrir-lo en una altra aplicació." }, "sftpTransfer": { "title": "SFTP", @@ -374,42 +431,12 @@ }, "hosts": { "fileManager": "Gestor de fitxers", - "tabFiles": "Fitxers", - "enableFileManagerMonitor": "Habilita el gestor de fitxers", - "enableFileManagerMonitorDesc": "Navega i gestiona fitxers en aquest amfitrió mitjançant SFTP", - "scpLegacyLabel": "Mode Llegat de SCP", - "scpLegacyDesc": "Feu servir la transferència de fitxers antiga per a servidors que no admeten el subsistema SFTP (per exemple, servidors SSH integrats o mínims).", - "defaultPathLabel": "Camí predeterminat", - "fileManagerPathHint": "El directori que s'obrirà quan s'iniciï el gestor de fitxers per a aquest amfitrió.", "fileManagerUrlCopied": "S'ha copiat l'URL del gestor de fitxers", "copyFileManagerUrlAction": "Copia l'URL del gestor de fitxers", "docsLink": "Veure documents", "hostNotFound": "No s'ha trobat l'amfitrió", "loadingHost": "S'està carregant l'amfitrió..." }, - "settings": { - "host": { - "enable": { - "label": "Habilita el gestor de fitxers" - }, - "defaultPath": { - "label": "Camí predeterminat" - }, - "scpLegacy": { - "label": "Mode Llegat de SCP" - } - }, - "user": { - "transferConcurrency": { - "label": "Transferències simultànies de fitxers", - "description": "Quants fitxers puja o descarrega el gestor local/remot en paral·lel alhora. Redueix aquest valor si el teu servidor limita els canals SFTP." - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "Fitxers" - }, "onboarding": { "feature_files": "Gestor de fitxers", "feature_files_desc": "Navegueu, pengeu, descarregueu i editeu fitxers a través de SFTP sense sortir de l'aplicació." @@ -437,7 +464,7 @@ "destinationPath": "Camí de destinació", "destMustBeDirectory": "La destinació ha de ser un directori per a transferències de diversos elements", "goUp": "Puja", - "hostAuthRequired": "Cal autenticació: obriu primer el Gestor de fitxers en aquest amfitrió.", + "hostAuthRequired": "Cal autenticació. Obriu primer el Gestor de fitxers en aquest amfitrió.", "hostConnecting": "Connectant…", "hostConnectionFailed": "La connexió ha fallat", "hostDisconnected": "No connectat", @@ -445,7 +472,7 @@ "itemsSummary": "{{count}} elements", "jumpHostLimitation": "Tots dos hosts han de ser accessibles des del servidor Termix. No s'admet l'encaminament directe d'host a host.", "methodAuto": "Automàtic", - "methodAutoHint": "Tria SFTP tar o per fitxer en funció del nombre de fitxers, la mida i la compressibilitat. Els fitxers individuals sempre utilitzen SFTP en temps real.", + "methodAutoHint": "Tria tar o SFTP per fitxer en funció del nombre de fitxers, la mida i la compressibilitat. Els fitxers individuals sempre utilitzen SFTP en temps real.", "methodItemSftp": "SFTP per fitxer", "methodItemSftpHint": "Transfereix cada fitxer individualment per SFTP. Funciona en tots els hosts, inclòs Windows.", "methodItemSftpLimitation": "Cada fitxer utilitza el mateix flux SFTP com una còpia d'un sol fitxer, un darrere l'altre. El progrés es combina en tots els fitxers, de manera que la barra es mou lentament durant els fitxers grans.", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "Heu triat SFTP per fitxer.", "user_tar": "Has triat l'arxiu tar.", - "tar_unavailable": "Tar no està disponible en un o tots dos hosts; s'utilitzarà SFTP per fitxer.", - "windows_host": "Hi ha un host de Windows implicat; no s'utilitza tar.", - "auto_multi_large": "Automàtic: diversos fitxers, inclòs un fitxer gran ({{largestSize}}) amb dades compressibles: paquets de fitxers tar en una sola transferència.", - "auto_single_large_in_archive": "Automàtic: un fitxer gran ({{largestSize}}) en aquest conjunt — SFTP per fitxer.", - "auto_many_incompressible": "Automàtic: dades majoritàriament incompressibles — SFTP per fitxer.", - "auto_many_files": "Automàtic: molts fitxers ({{fileCount}}) — tar redueix la sobrecàrrega per fitxer.", + "tar_unavailable": "Tar no està disponible en un o tots dos amfitrions, per tant, s'utilitzarà SFTP per fitxer.", + "windows_host": "Hi ha un host de Windows implicat, per tant no s'utilitza tar.", + "auto_multi_large": "Automàtic: diversos fitxers, inclòs un fitxer gran ({{largestSize}}) amb dades compressibles. Tar els agrupa en una sola transferència.", + "auto_single_large_in_archive": "Automàtic: un fitxer gran ({{largestSize}}) en aquest conjunt, per tant, SFTP per fitxer.", + "auto_many_incompressible": "Automàtic: dades majoritàriament incompressibles, per tant, SFTP per fitxer.", + "auto_many_files": "Automàtic: molts fitxers ({{fileCount}}), tar redueix la sobrecàrrega per fitxer.", "auto_default": "Automàtic: SFTP per fitxer per a aquest conjunt." }, "methodTar": "Arxiu Tar", @@ -471,7 +498,7 @@ "metricsCompress": "Comprimir a la font: {{duration}}", "metricsExtract": "Extracte a la destinació: {{duration}}", "metricsPrepare": "Prepara la destinació: {{duration}}", - "metricsRouteBenchmark": "Sonda de ruta — directa: {{direct}}, relé: {{relay}}", + "metricsRouteBenchmark": "Sonda de ruta: directa {{direct}}, relé {{relay}}", "metricsSourceDelete": "Elimina de la font: {{duration}}", "metricsTotal": "Total: {{duration}}", "metricsTransfer": "Extrem a extrem: {{throughput}} ({{duration}})", @@ -508,6 +535,9 @@ "transferError": "La transferència ha fallat", "transferFailedRetryHint": "S'han conservat dades parcials a la destinació. El reintent es reprendrà quan es restableixi la connexió.", "transferPartialHint": "No s'ha pogut transferir: {{paths}}", - "transferSuccess": "Transferència completada" + "transferSuccess": "Transferència completada", + "metricsHopSourceRead": "Font → servidor: {{throughput}}", + "metricsHopDestSftpWrite": "Servidor → destí (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Servidor → destí (local): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/cs_CZ.json b/plugins/file-manager/locales/translated/cs_CZ.json index 7facfa704..4f85a43b4 100644 --- a/plugins/file-manager/locales/translated/cs_CZ.json +++ b/plugins/file-manager/locales/translated/cs_CZ.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "Soubory", + "sftp": "SFTP", + "openFileManager": "Otevřít Správce souborů" + }, + "permissions": { + "use": { + "title": "Používejte správce souborů", + "description": "Procházejte, upravujte a přenášejte soubory přes SFTP." + } + }, + "settings": { + "host": { + "enable": { + "label": "Povolit Správce souborů", + "description": "Procházejte a upravujte soubory na tomto hostiteli přes SFTP." + }, + "defaultPath": { + "label": "Výchozí cesta" + }, + "scpLegacy": { + "label": "Starší režim SCP" + } + }, + "user": { + "transferConcurrency": { + "label": "Současné přenosy souborů", + "description": "Kolik souborů souběžně nahrává nebo stahuje lokální/vzdálený správce. Snižte tuto hodnotu, pokud váš server omezuje SFTP kanály." + }, + "confirmBeforeTrash": { + "label": "Potvrďte před přesunutím souborů do koše", + "description": "Před přesunutím vzdálených souborů do koše se zeptat. Trvalé smazání stále vyžaduje potvrzení." + } + } + }, + "hostCapability": { + "label": "Správce souborů" + }, "fileManager": { "noHostSelected": "Nebyl vybrán žádný hostitel", "initializingEditor": "Inicializace editoru...", @@ -34,13 +72,14 @@ "rename": "Přejmenovat", "uploading": "Nahrávání...", "uploadingFile": "Nahrávání {{name}}...", + "uploadingChunk": "Nahrávání {{name}}: {{percent}}% (část {{chunk}} z {{total}})", "fileName": "Název souboru", "folderName": "Název složky", "fileUploadedSuccessfully": "Soubor „{{name}}“ byl úspěšně nahrán", "failedToUploadFile": "Nahrávání souboru se nezdařilo", "uploadingFolderFiles": "Nahrávání {{count}} souborů...", "uploadedFolderFiles": "Úspěšně nahráno {{count}} souborů", - "uploadedFolderPartial": "Nahrání souboru (souborů) {{uploaded}} se nezdařilo. {{failed}}", + "uploadedFolderPartial": "Nahrání souboru {{uploaded}} , {{failed}} se nezdařilo", "fileDownloadedSuccessfully": "Soubor „{{name}}“ byl úspěšně stažen", "failedToDownloadFile": "Stažení souboru se nezdařilo", "fileCreatedSuccessfully": "Soubor „{{name}}“ byl úspěšně vytvořen", @@ -81,7 +120,7 @@ "localNothingToTransfer": "Nic k převodu", "localUploadComplete": "Nahráno {{count}} souborů", "localUploadFailed": "Nahrávání se nezdařilo", - "localUploadPartial": "Nahrání souboru (souborů) {{done}} se nezdařilo. {{failed}}", + "localUploadPartial": "Nahrání souboru {{done}} , {{failed}} se nezdařilo", "localDownloadComplete": "Staženo {{count}} souborů", "localDownloadFailed": "Stahování se nezdařilo", "localDownloadPartial": "Stažení souboru (souborů) {{done}} se nezdařilo. {{failed}}", @@ -139,7 +178,7 @@ "failedToCopyFolderLink": "Nepodařilo se zkopírovat odkaz na složku", "movedItems": "Přesunuto {{count}} položek", "failedToDeleteItem": "Položku se nepodařilo smazat", - "itemRenamedSuccessfully": "{{type}} byl úspěšně přejmenován", + "itemRenamedSuccessfully": "{{type}} přejmenováno úspěšně", "failedToRenameItem": "Přejmenování položky se nezdařilo", "download": "Stáhnout", "openExternalEditor": "Otevřít externě", @@ -290,6 +329,7 @@ "connecting": "Spojovací...", "connectedSuccessfully": "Úspěšné připojení", "totpVerificationFailed": "Ověření TOTP se nezdařilo", + "browserSignInFailed": "Přihlášení se nezdařilo. Zkuste to prosím znovu.", "authenticationFailed": "Ověření se nezdařilo", "incorrectPassphrase": "Nesprávné heslo. Zkuste to prosím znovu.", "verificationCodePrompt": "Ověřovací kód:", @@ -326,7 +366,24 @@ "cannotLoadPdf": "Nelze načíst PDF", "pdfLoadError": "Při načítání tohoto PDF souboru došlo k chybě.", "loadingPdf": "Načítání PDF...", - "loadingPage": "Načítání stránky..." + "loadingPage": "Načítání stránky...", + "cancel": "Zrušit", + "copiedItems_one": "Zkopírována položka {{count}}", + "copiedItems_other": "Zkopírováno {{count}} položek", + "deleteCopiedFileFailed": "Nelze smazat kopii {{name}}: {{error}}", + "dragMovedItems_one": "Položka {{count}} přesunuta do {{target}}", + "dragMovedItems_other": "Přesunuto {{count}} položek do {{target}}", + "moveBackFileFailed": "Nelze přesunout {{name}} zpět: {{error}}", + "terminal": "Terminál: {{host}} ({{path}})", + "dragToDesktop": "Přetažení {{name}} na plochu", + "dragFilesToDesktop": "Přetažení souborů {{count}} na plochu", + "folderDragUnsupported": "Přetahování složek na plochu zatím není podporováno", + "saveToDesktopFailed": "Uložení se nezdařilo: {{error}}", + "dragFailedDetail": "Přetažení se nezdařilo: {{error}}", + "videoUnsupported": "Váš prohlížeč tento formát videa nepřehrává.", + "downloadToPlay": "Stáhněte si pro přehrávání jinde", + "cannotPreviewType": "Nelze zobrazit náhled tohoto typu souboru", + "cannotPreviewTypeHint": "Tento typ souboru nemá náhled. Stáhněte si jej a otevřete jej v jiné aplikaci." }, "sftpTransfer": { "title": "SFTP", @@ -374,42 +431,12 @@ }, "hosts": { "fileManager": "Správce souborů", - "tabFiles": "Soubory", - "enableFileManagerMonitor": "Povolit Správce souborů", - "enableFileManagerMonitorDesc": "Procházení a správa souborů na tomto hostiteli přes SFTP", - "scpLegacyLabel": "Starší režim SCP", - "scpLegacyDesc": "Pro servery, které nepodporují subsystém SFTP (např. vestavěné nebo minimální SSH servery), použijte starší přenos souborů.", - "defaultPathLabel": "Výchozí cesta", - "fileManagerPathHint": "Adresář, který se má otevřít při spuštění správce souborů pro tento hostitel.", "fileManagerUrlCopied": "URL adresa Správce souborů zkopírována", "copyFileManagerUrlAction": "Kopírovat URL Správce souborů", "docsLink": "Zobrazit dokumenty", "hostNotFound": "Hostitel nenalezen", "loadingHost": "Načítání hostitele..." }, - "settings": { - "host": { - "enable": { - "label": "Povolit Správce souborů" - }, - "defaultPath": { - "label": "Výchozí cesta" - }, - "scpLegacy": { - "label": "Starší režim SCP" - } - }, - "user": { - "transferConcurrency": { - "label": "Současné přenosy souborů", - "description": "Kolik souborů souběžně nahrává nebo stahuje lokální/vzdálený správce. Snižte tuto hodnotu, pokud váš server omezuje SFTP kanály." - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "Soubory" - }, "onboarding": { "feature_files": "Správce souborů", "feature_files_desc": "Procházejte, nahrávejte, stahujte a upravujte soubory přes SFTP, aniž byste museli opustit aplikaci." @@ -437,7 +464,7 @@ "destinationPath": "Cílová cesta", "destMustBeDirectory": "Cíl musí být adresář pro přenosy více položek.", "goUp": "Jdi nahoru", - "hostAuthRequired": "Vyžadováno ověření – nejprve otevřete Správce souborů na tomto hostiteli.", + "hostAuthRequired": "Vyžaduje se ověření. Nejprve otevřete Správce souborů na tomto hostiteli.", "hostConnecting": "Připojování…", "hostConnectionFailed": "Připojení se nezdařilo", "hostDisconnected": "Nepřipojeno", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "Zvolili jste SFTP pro jednotlivé soubory.", "user_tar": "Zvolili jste archiv tar.", - "tar_unavailable": "Tar není k dispozici na jednom nebo obou hostitelích — místo toho bude použit protokol SFTP pro jednotlivé soubory.", - "windows_host": "Je zapojen hostitelský systém Windows – tar se nepoužívá.", - "auto_multi_large": "Automaticky: více souborů včetně velkého souboru ({{largestSize}}) s komprimovatelnými daty — tar se sbalí do jednoho přenosu.", - "auto_single_large_in_archive": "Automaticky: jeden velký soubor ({{largestSize}}) v této sadě – SFTP pro každý soubor.", - "auto_many_incompressible": "Auto: většinou nekomprimovatelná data – SFTP pro jednotlivé soubory.", - "auto_many_files": "Automaticky: mnoho souborů ({{fileCount}}) – tar snižuje režii pro každý soubor.", + "tar_unavailable": "Tar není k dispozici na jednom nebo obou hostitelích, takže se místo toho použije SFTP pro jednotlivé soubory.", + "windows_host": "Je zapojen hostitelský systém Windows, takže se nepoužívá tar.", + "auto_multi_large": "Auto: více souborů včetně velkého souboru ({{largestSize}}) s komprimovatelnými daty. Tar je sloučí do jednoho přenosu.", + "auto_single_large_in_archive": "Auto: jeden velký soubor ({{largestSize}}) v této sadě, takže SFTP pro jednotlivé soubory.", + "auto_many_incompressible": "Auto: většinou nekomprimovatelná data, takže SFTP pro jednotlivé soubory.", + "auto_many_files": "Automaticky: mnoho souborů ({{fileCount}}), tar snižuje režii pro každý soubor.", "auto_default": "Automaticky: SFTP pro jednotlivé soubory pro tuto sadu." }, "methodTar": "Archiv Tar", @@ -471,7 +498,7 @@ "metricsCompress": "Komprimovat u zdroje: {{duration}}", "metricsExtract": "Extrahovat v cíli: {{duration}}", "metricsPrepare": "Připravit cíl: {{duration}}", - "metricsRouteBenchmark": "Sonda trasy — přímá: {{direct}}, relé: {{relay}}", + "metricsRouteBenchmark": "Sonda trasy: přímá {{direct}}, reléová {{relay}}", "metricsSourceDelete": "Odebrat ze zdroje: {{duration}}", "metricsTotal": "Celkem: {{duration}}", "metricsTransfer": "Konec od konce: {{throughput}} ({{duration}})", @@ -508,6 +535,9 @@ "transferError": "Přenos se nezdařil", "transferFailedRetryHint": "V cíli byla uložena částečná data. Po obnovení připojení bude pokus pokračovat.", "transferPartialHint": "Nepodařilo se přenést: {{paths}}", - "transferSuccess": "Převod dokončen" + "transferSuccess": "Převod dokončen", + "metricsHopSourceRead": "Zdroj → server: {{throughput}}", + "metricsHopDestSftpWrite": "Server → cíl (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Server → cíl (lokální): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/da_DK.json b/plugins/file-manager/locales/translated/da_DK.json index a10cdbb00..2f6568c7f 100644 --- a/plugins/file-manager/locales/translated/da_DK.json +++ b/plugins/file-manager/locales/translated/da_DK.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "Filer", + "sftp": "SFTP", + "openFileManager": "Åbn Filhåndtering" + }, + "permissions": { + "use": { + "title": "Brug filhåndtering", + "description": "Gennemse, rediger og overfør filer via SFTP." + } + }, + "settings": { + "host": { + "enable": { + "label": "Aktivér Filhåndtering", + "description": "Gennemse og rediger filer på denne vært via SFTP." + }, + "defaultPath": { + "label": "Standardsti" + }, + "scpLegacy": { + "label": "SCP Legacy-tilstand" + } + }, + "user": { + "transferConcurrency": { + "label": "Samtidige filoverførsler", + "description": "Hvor mange filer den side om side lokale/fjernstyrede administrator uploader eller downloader på samme tid. Sænk dette, hvis din server begrænser SFTP-kanaler." + }, + "confirmBeforeTrash": { + "label": "Bekræft før du flytter filer til papirkurven", + "description": "Spørg før du flytter eksterne filer til papirkurven. Permanent sletning kræver stadig bekræftelse." + } + } + }, + "hostCapability": { + "label": "Filhåndtering" + }, "fileManager": { "noHostSelected": "Ingen vært valgt", "initializingEditor": "Initialiserer editor...", @@ -34,6 +72,7 @@ "rename": "Omdøb", "uploading": "Uploader...", "uploadingFile": "Uploader {{name}}...", + "uploadingChunk": "Uploader {{name}}: {{percent}}% (del {{chunk}} af {{total}})", "fileName": "Filnavn", "folderName": "Mappenavn", "fileUploadedSuccessfully": "Filen \"{{name}}\" er blevet uploadet", @@ -290,6 +329,7 @@ "connecting": "Forbinder...", "connectedSuccessfully": "Forbindelsen er oprettet", "totpVerificationFailed": "TOTP-bekræftelse mislykkedes", + "browserSignInFailed": "Log ind mislykkedes. Prøv igen.", "authenticationFailed": "Godkendelse mislykkedes", "incorrectPassphrase": "Forkert adgangskode. Prøv igen.", "verificationCodePrompt": "Bekræftelseskode:", @@ -326,7 +366,24 @@ "cannotLoadPdf": "Kan ikke indlæse PDF'en", "pdfLoadError": "Der opstod en fejl under indlæsning af denne PDF-fil.", "loadingPdf": "Indlæser PDF...", - "loadingPage": "Indlæser side..." + "loadingPage": "Indlæser side...", + "cancel": "Ophæve", + "copiedItems_one": "Kopieret {{count}} element", + "copiedItems_other": "Kopierede {{count}} elementer", + "deleteCopiedFileFailed": "Kunne ikke slette kopien af {{name}}: {{error}}", + "dragMovedItems_one": "Flyttede {{count}} element til {{target}}", + "dragMovedItems_other": "Flyttede {{count}} elementer til {{target}}", + "moveBackFileFailed": "Kunne ikke flytte {{name}} tilbage: {{error}}", + "terminal": "Terminal: {{host}} ({{path}})", + "dragToDesktop": "Træk {{name}} til skrivebordet", + "dragFilesToDesktop": "Træk {{count}} filer til skrivebordet", + "folderDragUnsupported": "Det understøttes endnu ikke at trække mapper til skrivebordet", + "saveToDesktopFailed": "Gemning mislykkedes: {{error}}", + "dragFailedDetail": "Træk mislykkedes: {{error}}", + "videoUnsupported": "Din browser kan ikke afspille dette videoformat.", + "downloadToPlay": "Download for at afspille det et andet sted", + "cannotPreviewType": "Kan ikke forhåndsvise denne filtype", + "cannotPreviewTypeHint": "Denne filtype har ingen forhåndsvisning. Download den for at åbne den i en anden app." }, "sftpTransfer": { "title": "SFTP", @@ -374,42 +431,12 @@ }, "hosts": { "fileManager": "Filhåndtering", - "tabFiles": "Filer", - "enableFileManagerMonitor": "Aktivér Filhåndtering", - "enableFileManagerMonitorDesc": "Gennemse og administrer filer på denne vært via SFTP", - "scpLegacyLabel": "SCP Legacy-tilstand", - "scpLegacyDesc": "Brug ældre filoverførsel til servere, der ikke understøtter SFTP-undersystemet (f.eks. integrerede eller minimale SSH-servere).", - "defaultPathLabel": "Standardsti", - "fileManagerPathHint": "Den mappe, der skal åbnes, når filhåndteringen starter for denne vært.", "fileManagerUrlCopied": "URL'en til filhåndtering er kopieret", "copyFileManagerUrlAction": "Kopiér URL til filhåndtering", "docsLink": "Se dokumenter", "hostNotFound": "Værten blev ikke fundet", "loadingHost": "Indlæser vært..." }, - "settings": { - "host": { - "enable": { - "label": "Aktivér Filhåndtering" - }, - "defaultPath": { - "label": "Standardsti" - }, - "scpLegacy": { - "label": "SCP Legacy-tilstand" - } - }, - "user": { - "transferConcurrency": { - "label": "Samtidige filoverførsler", - "description": "Hvor mange filer den side om side lokale/fjernstyrede administrator uploader eller downloader på samme tid. Sænk dette, hvis din server begrænser SFTP-kanaler." - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "Filer" - }, "onboarding": { "feature_files": "Filhåndtering", "feature_files_desc": "Gennemse, upload, download og rediger filer via SFTP uden at forlade appen." @@ -437,7 +464,7 @@ "destinationPath": "Destinationssti", "destMustBeDirectory": "Destinationen skal være en mappe for overførsler af flere elementer", "goUp": "Gå op", - "hostAuthRequired": "Godkendelse kræves — åbn først Filhåndtering på denne vært", + "hostAuthRequired": "Godkendelse kræves. Åbn først Filhåndtering på denne vært", "hostConnecting": "Forbinder…", "hostConnectionFailed": "Forbindelsen mislykkedes", "hostDisconnected": "Ikke forbundet", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "Du valgte SFTP pr. fil.", "user_tar": "Du valgte tar-arkivet.", - "tar_unavailable": "Tar er ikke tilgængelig på en eller begge værter — SFTP pr. fil vil blive brugt i stedet.", - "windows_host": "En Windows-vært er involveret — tar bruges ikke.", - "auto_multi_large": "Auto: flere filer inklusive en stor fil ({{largestSize}}) med komprimerbare data — tar samler filer i én overførsel.", - "auto_single_large_in_archive": "Auto: én stor fil ({{largestSize}}) i dette sæt — SFTP pr. fil.", - "auto_many_incompressible": "Auto: for det meste inkomprimerbare data — SFTP pr. fil.", - "auto_many_files": "Auto: mange filer ({{fileCount}}) — tar reducerer overhead pr. fil.", + "tar_unavailable": "Tar er ikke tilgængelig på den ene eller begge værter, så SFTP pr. fil vil blive brugt i stedet.", + "windows_host": "En Windows-vært er involveret, så tar bruges ikke.", + "auto_multi_large": "Auto: flere filer inklusive en stor fil ({{largestSize}}) med komprimerbare data. Tar samler dem i én overførsel.", + "auto_single_large_in_archive": "Auto: én stor fil ({{largestSize}}) i dette sæt, så SFTP pr. fil.", + "auto_many_incompressible": "Auto: for det meste inkomprimerbare data, så SFTP pr. fil.", + "auto_many_files": "Auto: mange filer ({{fileCount}}), tar reducerer overhead pr. fil.", "auto_default": "Auto: SFTP pr. fil for dette sæt." }, "methodTar": "Tar-arkiv", @@ -471,7 +498,7 @@ "metricsCompress": "Komprimer på kilde: {{duration}}", "metricsExtract": "Udtræk på destination: {{duration}}", "metricsPrepare": "Forbered destination: {{duration}}", - "metricsRouteBenchmark": "Rutesonde — direkte: {{direct}}, relæ: {{relay}}", + "metricsRouteBenchmark": "Ruteprobe: direkte {{direct}}, relæ {{relay}}", "metricsSourceDelete": "Fjern fra kilde: {{duration}}", "metricsTotal": "I alt: {{duration}}", "metricsTransfer": "End-to-end: {{throughput}} ({{duration}})", @@ -508,6 +535,9 @@ "transferError": "Overførslen mislykkedes", "transferFailedRetryHint": "Delvise data blev gemt på destinationen. Forsøget genoptages, når forbindelsen er tilbage.", "transferPartialHint": "Kunne ikke overføre: {{paths}}", - "transferSuccess": "Overførsel fuldført" + "transferSuccess": "Overførsel fuldført", + "metricsHopSourceRead": "Kilde → server: {{throughput}}", + "metricsHopDestSftpWrite": "Server → destination (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Server → destination (lokal): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/de_DE.json b/plugins/file-manager/locales/translated/de_DE.json index b5ed64840..6f60ad6fe 100644 --- a/plugins/file-manager/locales/translated/de_DE.json +++ b/plugins/file-manager/locales/translated/de_DE.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "Dateien", + "sftp": "SFTP", + "openFileManager": "Dateimanager öffnen" + }, + "permissions": { + "use": { + "title": "Verwenden Sie den Dateimanager.", + "description": "Dateien per SFTP durchsuchen, bearbeiten und übertragen." + } + }, + "settings": { + "host": { + "enable": { + "label": "Dateimanager aktivieren", + "description": "Dateien auf diesem Host können über SFTP durchsucht und bearbeitet werden." + }, + "defaultPath": { + "label": "Standardpfad" + }, + "scpLegacy": { + "label": "SCP-Legacy-Modus" + } + }, + "user": { + "transferConcurrency": { + "label": "Gleichzeitige Dateiübertragungen", + "description": "Wie viele Dateien der lokale/Remote-Manager gleichzeitig hoch- oder herunterlädt. Verringern Sie diesen Wert, wenn Ihr Server die Anzahl der SFTP-Kanäle begrenzt." + }, + "confirmBeforeTrash": { + "label": "Bitte prüfen Sie dies, bevor Sie Dateien in den Papierkorb verschieben.", + "description": "Vor dem Verschieben von Dateien in den Papierkorb fragen. Auch für das endgültige Löschen ist eine Bestätigung erforderlich." + } + } + }, + "hostCapability": { + "label": "Dateimanager" + }, "fileManager": { "noHostSelected": "Kein Host ausgewählt", "initializingEditor": "Editor wird initialisiert...", @@ -34,6 +72,7 @@ "rename": "Umbenennen", "uploading": "Lade hoch...", "uploadingFile": "Lade {{name}} hoch...", + "uploadingChunk": "Hochladen von {{name}}: {{percent}}% (Teil {{chunk}} von {{total}})", "fileName": "Dateiname", "folderName": "Ordnername", "fileUploadedSuccessfully": "Datei \"{{name}}\" erfolgreich hochgeladen", @@ -67,7 +106,7 @@ "localHideHidden": "Versteckte Dateien ausblenden", "localRevealInFileManager": "Im Systemdateimanager anzeigen", "localCannotOpenFolder": "Ordner kann nicht geöffnet werden", - "localItemCount": "{{count}} Artikel", + "localItemCount": "{{count}} Elemente", "localSelectedCount": "{{count}} ausgewählt", "back": "Zurück", "forward": "Nach vorne", @@ -77,7 +116,7 @@ "localDownloadingProgress": "Herunterladen von {{current}} von {{total}}", "localTransferInFlight": "{{count}} gleichzeitig", "localPreparingDownload": "Download wird vorbereitet...", - "localTransferCancelled": "Transfer storniert", + "localTransferCancelled": "Übertragung abgebrochen", "localNothingToTransfer": "Nichts zu übertragen", "localUploadComplete": "Es wurden {{count}} Dateien hochgeladen", "localUploadFailed": "Hochladen fehlgeschlagen", @@ -95,7 +134,7 @@ "localUploadToRemote": "Auf Server hochladen", "localUploadToRemoteMany": "{{count}} Elemente auf den Server hochladen", "localMoveToTrash": "In den Papierkorb verschieben", - "localMoveToTrashMany": "Verschiebe {{count}} Objekte in den Papierkorb.", + "localMoveToTrashMany": "Verschiebe {{count}} Elemente in den Papierkorb.", "localTrashConfirmSingle": "\"{{name}}\" in den Papierkorb verschieben?", "localTrashConfirmFolder": "Den Ordner \"{{name}}\" und seinen gesamten Inhalt in den Papierkorb verschieben?", "localTrashConfirmMany": "{{count}} Elemente in den Papierkorb verschieben?", @@ -290,6 +329,7 @@ "connecting": "Verbindung wird hergestellt...", "connectedSuccessfully": "Erfolgreich verbunden", "totpVerificationFailed": "TOTP-Überprüfung fehlgeschlagen", + "browserSignInFailed": "Anmeldung fehlgeschlagen. Bitte versuchen Sie es erneut.", "authenticationFailed": "Authentifizierung fehlgeschlagen", "incorrectPassphrase": "Falsche Passphrase. Bitte versuchen Sie es erneut.", "verificationCodePrompt": "Verifizierungscode:", @@ -326,7 +366,24 @@ "cannotLoadPdf": "PDF kann nicht geladen werden", "pdfLoadError": "Beim Laden dieser PDF-Datei ist ein Fehler aufgetreten.", "loadingPdf": "PDF wird geladen...", - "loadingPage": "Seite wird geladen..." + "loadingPage": "Seite wird geladen...", + "cancel": "Abbrechen", + "copiedItems_one": "Kopierter Eintrag {{count}}", + "copiedItems_other": "Kopierte {{count}} Elemente", + "deleteCopiedFileFailed": "Die Kopie von {{name}}konnte nicht gelöscht werden: {{error}}", + "dragMovedItems_one": "Element {{count}} nach {{target}} verschoben", + "dragMovedItems_other": "{{count}} Elemente nach {{target}} verschoben", + "moveBackFileFailed": "{{name}} konnte nicht zurückbewegt werden: {{error}}", + "terminal": "Terminal: {{host}} ({{path}})", + "dragToDesktop": "Ziehen Sie {{name}} auf den Desktop", + "dragFilesToDesktop": "Ziehen von {{count}} -Dateien auf den Desktop", + "folderDragUnsupported": "Das Ziehen von Ordnern auf den Desktop wird noch nicht unterstützt.", + "saveToDesktopFailed": "Speichern fehlgeschlagen: {{error}}", + "dragFailedDetail": "Drag fehlgeschlagen: {{error}}", + "videoUnsupported": "Ihr Browser kann dieses Videoformat nicht abspielen.", + "downloadToPlay": "Laden Sie es herunter, um es woanders abzuspielen.", + "cannotPreviewType": "Vorschau dieses Dateityps nicht möglich", + "cannotPreviewTypeHint": "Dieser Dateityp hat keine Vorschau. Laden Sie ihn herunter, um ihn in einer anderen App zu öffnen." }, "sftpTransfer": { "title": "SFTP", @@ -335,15 +392,15 @@ "destinationServer": "Zielserver", "selectHost": "Host auswählen", "noHostSelected": "Kein Host ausgewählt", - "move": "Bewegen", - "copy": "Kopie", + "move": "Verschieben", + "copy": "Kopieren", "upload": "Hochladen", "itemsSelected": "{{count}} Element ausgewählt", "itemsSelected_other": "{{count}} ausgewählte Elemente", "ready": "Bereit", "loadingHosts": "Hosts werden geladen...", "name": "Name", - "modified": "Modifiziert", + "modified": "Geändert", "size": "Größe", "noFiles": "Keine Dateien", "open": "Offen", @@ -357,7 +414,7 @@ "deleteSelectedItems": "Ausgewählte Elemente löschen", "deleteConfirm": "Delete {{count}} selected item?", "deleteConfirm_other": "{{count}} ausgewählte Elemente löschen?", - "cancel": "Stornieren", + "cancel": "Abbrechen", "save": "Speichern", "folderCreated": "Ordner erstellt", "itemRenamed": "Artikel umbenannt", @@ -374,42 +431,12 @@ }, "hosts": { "fileManager": "Dateimanager", - "tabFiles": "Dateien", - "enableFileManagerMonitor": "Dateimanager aktivieren", - "enableFileManagerMonitorDesc": "Dateien auf diesem Host über SFTP durchsuchen und verwalten", - "scpLegacyLabel": "SCP-Legacy-Modus", - "scpLegacyDesc": "Verwenden Sie die Legacy-Dateiübertragung für Server, die das SFTP-Subsystem nicht unterstützen (z. B. eingebettete oder minimale SSH-Server).", - "defaultPathLabel": "Standardpfad", - "fileManagerPathHint": "Das Verzeichnis, das geöffnet wird, wenn der Dateimanager für diesen Host gestartet wird.", "fileManagerUrlCopied": "Dateimanager-URL kopiert", "copyFileManagerUrlAction": "Dateimanager-URL kopieren", "docsLink": "Dokumentation anzeigen", "hostNotFound": "Host nicht gefunden", "loadingHost": "Host wird geladen..." }, - "settings": { - "host": { - "enable": { - "label": "Dateimanager aktivieren" - }, - "defaultPath": { - "label": "Standardpfad" - }, - "scpLegacy": { - "label": "SCP-Legacy-Modus" - } - }, - "user": { - "transferConcurrency": { - "label": "Gleichzeitige Dateiübertragungen", - "description": "Wie viele Dateien der lokale/Remote-Manager gleichzeitig hoch- oder herunterlädt. Verringern Sie diesen Wert, wenn Ihr Server die Anzahl der SFTP-Kanäle begrenzt." - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "Dateien" - }, "onboarding": { "feature_files": "Dateimanager", "feature_files_desc": "Durchsuchen, hochladen, herunterladen und bearbeiten Sie Dateien über SFTP, ohne die App zu verlassen." @@ -437,7 +464,7 @@ "destinationPath": "Zielpfad", "destMustBeDirectory": "Bei Übertragung mehrerer Elemente muss das Ziel ein Verzeichnis sein.", "goUp": "Nach oben", - "hostAuthRequired": "Authentifizierung erforderlich — öffnen Sie zuerst den Dateimanager auf diesem Host", + "hostAuthRequired": "Authentifizierung erforderlich. Öffnen Sie zuerst den Dateimanager auf diesem Host.", "hostConnecting": "Verbinden …", "hostConnectionFailed": "Verbindung fehlgeschlagen", "hostDisconnected": "Nicht verbunden", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "Sie haben dateiweises SFTP ausgewählt.", "user_tar": "Sie haben tar-Archiv ausgewählt.", - "tar_unavailable": "Tar ist auf einem oder beiden Hosts nicht verfügbar – stattdessen wird dateiweises SFTP verwendet.", - "windows_host": "Ein Windows-Host ist beteiligt – tar wird nicht verwendet.", - "auto_multi_large": "Automatisch: mehrere Dateien, darunter eine große Datei ({{largestSize}}) mit komprimierbaren Daten – tar bündelt sie in eine Übertragung.", - "auto_single_large_in_archive": "Automatisch: eine große Datei ({{largestSize}}) in diesem Satz – dateiweises SFTP.", - "auto_many_incompressible": "Automatisch: überwiegend nicht komprimierbare Daten – dateiweises SFTP.", - "auto_many_files": "Automatisch: viele Dateien ({{fileCount}}) – tar reduziert den Overhead pro Datei.", + "tar_unavailable": "Tar ist auf einem oder beiden Hosts nicht verfügbar, daher wird stattdessen SFTP pro Datei verwendet.", + "windows_host": "Da es sich um einen Windows-Host handelt, wird tar nicht verwendet.", + "auto_multi_large": "Auto: Mehrere Dateien, darunter eine große Datei ({{largestSize}}) mit komprimierbaren Daten. Tar bündelt sie zu einer einzigen Übertragung.", + "auto_single_large_in_archive": "Auto: eine große Datei ({{largestSize}}) in diesem Satz, also SFTP pro Datei.", + "auto_many_incompressible": "Auto: Meist unkomprimierbare Daten, daher SFTP pro Datei.", + "auto_many_files": "Auto: Viele Dateien ({{fileCount}}), tar reduziert den Overhead pro Datei.", "auto_default": "Automatisch: dateiweises SFTP für diesen Satz." }, "methodTar": "Tar-Archiv", @@ -471,7 +498,7 @@ "metricsCompress": "Komprimieren auf der Quelle: {{duration}}", "metricsExtract": "Entpacken auf dem Ziel: {{duration}}", "metricsPrepare": "Ziel vorbereiten: {{duration}}", - "metricsRouteBenchmark": "Routenprüfung — direkt: {{direct}}, Relay: {{relay}}", + "metricsRouteBenchmark": "Routenprüfung: direkt {{direct}}, Relais {{relay}}", "metricsSourceDelete": "Löschen von der Quelle: {{duration}}", "metricsTotal": "Gesamt: {{duration}}", "metricsTransfer": "Ende-zu-Ende: {{throughput}} ({{duration}})", @@ -508,6 +535,9 @@ "transferError": "Übertragung fehlgeschlagen", "transferFailedRetryHint": "Unvollständige Daten wurden am Ziel beibehalten. Die Wiederholung wird fortgesetzt, sobald die Verbindung wiederhergestellt ist.", "transferPartialHint": "Konnte nicht übertragen werden: {{paths}}", - "transferSuccess": "Übertragung abgeschlossen" + "transferSuccess": "Übertragung abgeschlossen", + "metricsHopSourceRead": "Quelle → Server: {{throughput}}", + "metricsHopDestSftpWrite": "Server → Ziel (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Server → Ziel (lokal): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/el_GR.json b/plugins/file-manager/locales/translated/el_GR.json index 4a142bf83..4ab2d42d1 100644 --- a/plugins/file-manager/locales/translated/el_GR.json +++ b/plugins/file-manager/locales/translated/el_GR.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "Αρχεία", + "sftp": "SFTP", + "openFileManager": "Άνοιγμα Διαχείρισης Αρχείων" + }, + "permissions": { + "use": { + "title": "Χρήση διαχειριστή αρχείων", + "description": "Περιηγηθείτε, επεξεργαστείτε και μεταφέρετε αρχεία μέσω SFTP." + } + }, + "settings": { + "host": { + "enable": { + "label": "Ενεργοποίηση Διαχείρισης Αρχείων", + "description": "Περιηγηθείτε και επεξεργαστείτε αρχεία σε αυτόν τον κεντρικό υπολογιστή μέσω SFTP." + }, + "defaultPath": { + "label": "Προεπιλεγμένη διαδρομή" + }, + "scpLegacy": { + "label": "Λειτουργία παλαιού τύπου SCP" + } + }, + "user": { + "transferConcurrency": { + "label": "Ταυτόχρονες μεταφορές αρχείων", + "description": "Πόσα αρχεία ανεβάζει ή κατεβάζει ο τοπικός/απομακρυσμένος διαχειριστής παράλληλων λήψεων ταυτόχρονα. Μειώστε αυτό το ποσό εάν ο διακομιστής σας περιορίζει τα κανάλια SFTP." + }, + "confirmBeforeTrash": { + "label": "Επιβεβαίωση πριν από τη μετακίνηση αρχείων στον κάδο απορριμμάτων", + "description": "Ρωτήστε πριν μετακινήσετε απομακρυσμένα αρχεία στον κάδο απορριμμάτων. Η μόνιμη διαγραφή εξακολουθεί να απαιτεί επιβεβαίωση." + } + } + }, + "hostCapability": { + "label": "Διαχειριστής αρχείων" + }, "fileManager": { "noHostSelected": "Δεν έχει επιλεγεί κεντρικός υπολογιστής", "initializingEditor": "Αρχικοποίηση προγράμματος επεξεργασίας...", @@ -34,6 +72,7 @@ "rename": "Μετονομάζω", "uploading": "Μεταφόρτωση...", "uploadingFile": "Μεταφόρτωση {{name}}...", + "uploadingChunk": "Μεταφόρτωση {{name}}: {{percent}}% (μέρος {{chunk}} από {{total}})", "fileName": "Όνομα αρχείου", "folderName": "Όνομα φακέλου", "fileUploadedSuccessfully": "Το αρχείο \"{{name}}\" μεταφορτώθηκε με επιτυχία", @@ -290,6 +329,7 @@ "connecting": "Συνδετικός...", "connectedSuccessfully": "Η σύνδεση ολοκληρώθηκε με επιτυχία", "totpVerificationFailed": "Η επαλήθευση TOTP απέτυχε.", + "browserSignInFailed": "Η σύνδεση απέτυχε. Δοκιμάστε ξανά.", "authenticationFailed": "Η επαλήθευση ταυτότητας απέτυχε", "incorrectPassphrase": "Λανθασμένη φράση πρόσβασης. Δοκιμάστε ξανά.", "verificationCodePrompt": "Κωδικός επαλήθευσης:", @@ -326,7 +366,24 @@ "cannotLoadPdf": "Δεν είναι δυνατή η φόρτωση του PDF", "pdfLoadError": "Παρουσιάστηκε σφάλμα κατά τη φόρτωση αυτού του αρχείου PDF.", "loadingPdf": "Φόρτωση PDF...", - "loadingPage": "Φόρτωση σελίδας..." + "loadingPage": "Φόρτωση σελίδας...", + "cancel": "Ματαίωση", + "copiedItems_one": "Αντιγράφηκε {{count}} στοιχείο", + "copiedItems_other": "Αντιγράφηκαν {{count}} στοιχεία", + "deleteCopiedFileFailed": "Δεν ήταν δυνατή η διαγραφή του αντιγράφου του {{name}}: {{error}}", + "dragMovedItems_one": "Μετακινήθηκε το στοιχείο {{count}} στο {{target}}", + "dragMovedItems_other": "Μετακινήθηκαν {{count}} στοιχεία σε {{target}}", + "moveBackFileFailed": "Δεν ήταν δυνατή η μετακίνηση του {{name}} προς τα πίσω: {{error}}", + "terminal": "Τερματικό: {{host}} ({{path}})", + "dragToDesktop": "Σύρσιμο του {{name}} στην επιφάνεια εργασίας", + "dragFilesToDesktop": "Σύρσιμο αρχείων {{count}} στην επιφάνεια εργασίας", + "folderDragUnsupported": "Η μεταφορά φακέλων στην επιφάνεια εργασίας δεν υποστηρίζεται ακόμη", + "saveToDesktopFailed": "Η αποθήκευση απέτυχε: {{error}}", + "dragFailedDetail": "Η μεταφορά απέτυχε: {{error}}", + "videoUnsupported": "Το πρόγραμμα περιήγησής σας δεν μπορεί να αναπαράγει αυτήν τη μορφή βίντεο.", + "downloadToPlay": "Κατεβάστε το για να το παίξετε αλλού", + "cannotPreviewType": "Δεν είναι δυνατή η προεπισκόπηση αυτού του τύπου αρχείου", + "cannotPreviewTypeHint": "Αυτός ο τύπος αρχείου δεν έχει προεπισκόπηση. Κατεβάστε το για να το ανοίξετε σε άλλη εφαρμογή." }, "sftpTransfer": { "title": "SFTP", @@ -374,42 +431,12 @@ }, "hosts": { "fileManager": "Διαχειριστής αρχείων", - "tabFiles": "Αρχεία", - "enableFileManagerMonitor": "Ενεργοποίηση Διαχείρισης Αρχείων", - "enableFileManagerMonitorDesc": "Περιηγηθείτε και διαχειριστείτε αρχεία σε αυτόν τον κεντρικό υπολογιστή μέσω SFTP", - "scpLegacyLabel": "Λειτουργία παλαιού τύπου SCP", - "scpLegacyDesc": "Χρησιμοποιήστε μεταφορά αρχείων παλαιού τύπου για διακομιστές που δεν υποστηρίζουν το υποσύστημα SFTP (π.χ. ενσωματωμένοι ή ελάχιστοι διακομιστές SSH).", - "defaultPathLabel": "Προεπιλεγμένη διαδρομή", - "fileManagerPathHint": "Ο κατάλογος που θα ανοίξει κατά την εκκίνηση του διαχειριστή αρχείων για αυτόν τον κεντρικό υπολογιστή.", "fileManagerUrlCopied": "Η διεύθυνση URL του διαχειριστή αρχείων αντιγράφηκε", "copyFileManagerUrlAction": "Αντιγραφή URL Διαχείρισης Αρχείων", "docsLink": "Προβολή εγγράφων", "hostNotFound": "Δεν βρέθηκε κεντρικός υπολογιστής", "loadingHost": "Φόρτωση κεντρικού υπολογιστή..." }, - "settings": { - "host": { - "enable": { - "label": "Ενεργοποίηση Διαχείρισης Αρχείων" - }, - "defaultPath": { - "label": "Προεπιλεγμένη διαδρομή" - }, - "scpLegacy": { - "label": "Λειτουργία παλαιού τύπου SCP" - } - }, - "user": { - "transferConcurrency": { - "label": "Ταυτόχρονες μεταφορές αρχείων", - "description": "Πόσα αρχεία ανεβάζει ή κατεβάζει ο τοπικός/απομακρυσμένος διαχειριστής παράλληλων λήψεων ταυτόχρονα. Μειώστε αυτό το ποσό εάν ο διακομιστής σας περιορίζει τα κανάλια SFTP." - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "Αρχεία" - }, "onboarding": { "feature_files": "Διαχειριστής αρχείων", "feature_files_desc": "Περιηγηθείτε, ανεβάστε, κατεβάστε και επεξεργαστείτε αρχεία μέσω SFTP χωρίς να φύγετε από την εφαρμογή." @@ -437,7 +464,7 @@ "destinationPath": "Διαδρομή προορισμού", "destMustBeDirectory": "Ο προορισμός πρέπει να είναι ένας κατάλογος για μεταφορές πολλαπλών στοιχείων", "goUp": "Ανεβαίνω", - "hostAuthRequired": "Απαιτείται έλεγχος ταυτότητας — ανοίξτε πρώτα τη Διαχείριση αρχείων σε αυτόν τον κεντρικό υπολογιστή", + "hostAuthRequired": "Απαιτείται έλεγχος ταυτότητας. Ανοίξτε πρώτα τη Διαχείριση αρχείων σε αυτόν τον κεντρικό υπολογιστή.", "hostConnecting": "Σύνδεση…", "hostConnectionFailed": "Η σύνδεση απέτυχε", "hostDisconnected": "Δεν είναι συνδεδεμένο", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "Επιλέξατε SFTP ανά αρχείο.", "user_tar": "Επιλέξατε το αρχείο tar.", - "tar_unavailable": "Το Tar δεν είναι διαθέσιμο σε έναν ή και στους δύο κεντρικούς υπολογιστές — θα χρησιμοποιηθεί αντ' αυτού το SFTP ανά αρχείο.", - "windows_host": "Εμπλέκεται ένας κεντρικός υπολογιστής των Windows — δεν χρησιμοποιείται το tar.", - "auto_multi_large": "Αυτόματα: πολλά αρχεία, συμπεριλαμβανομένου ενός μεγάλου αρχείου ({{largestSize}}) με συμπιέσιμα δεδομένα — tar ομαδοποιεί σε μία μεταφορά.", - "auto_single_large_in_archive": "Αυτόματα: ένα μεγάλο αρχείο ({{largestSize}}) σε αυτό το σύνολο — ανά αρχείο SFTP.", - "auto_many_incompressible": "Αυτόματα: ως επί το πλείστον ασυμπίεστα δεδομένα — SFTP ανά αρχείο.", - "auto_many_files": "Αυτόματα: πολλά αρχεία ({{fileCount}}) — το tar μειώνει την επιβάρυνση ανά αρχείο.", + "tar_unavailable": "Το Tar δεν είναι διαθέσιμο σε έναν ή και στους δύο κεντρικούς υπολογιστές, επομένως θα χρησιμοποιηθεί το SFTP ανά αρχείο.", + "windows_host": "Εμπλέκεται ένας κεντρικός υπολογιστής των Windows, επομένως δεν χρησιμοποιείται το tar.", + "auto_multi_large": "Αυτόματα: πολλά αρχεία, συμπεριλαμβανομένου ενός μεγάλου αρχείου ({{largestSize}}) με συμπιέσιμα δεδομένα. Το Tar τα ομαδοποιεί σε μία μεταφορά.", + "auto_single_large_in_archive": "Αυτόματα: ένα μεγάλο αρχείο ({{largestSize}}) σε αυτό το σύνολο, άρα SFTP ανά αρχείο.", + "auto_many_incompressible": "Αυτόματα: ως επί το πλείστον ασυμπίεστα δεδομένα, άρα SFTP ανά αρχείο.", + "auto_many_files": "Αυτόματα: πολλά αρχεία ({{fileCount}}), η εντολή tar μειώνει την επιβάρυνση ανά αρχείο.", "auto_default": "Αυτόματα: SFTP ανά αρχείο για αυτό το σύνολο." }, "methodTar": "Αρχείο Tar", @@ -471,13 +498,13 @@ "metricsCompress": "Συμπίεση στην πηγή: {{duration}}", "metricsExtract": "Εξαγωγή στον προορισμό: {{duration}}", "metricsPrepare": "Προετοιμασία προορισμού: {{duration}}", - "metricsRouteBenchmark": "Δρομολόγηση ανιχνευτή — άμεση: {{direct}}, αναμετάδοση: {{relay}}", + "metricsRouteBenchmark": "Δρομολόγηση αισθητήρα: άμεση {{direct}}, αναμετάδοση {{relay}}", "metricsSourceDelete": "Αφαίρεση από την πηγή: {{duration}}", "metricsTotal": "Σύνολο: {{duration}}", "metricsTransfer": "Από άκρο σε άκρο: {{throughput}} ({{duration}})", "metricsVerify": "Επαληθεύτηκε το SHA-256: {{duration}}", "moveFolderToHost": "Μετακίνηση φακέλου στον κεντρικό υπολογιστή…", - "moveItemsToHost": "Μετακίνηση στοιχείων {{count}} για να φιλοξενήσει το…", + "moveItemsToHost": "Μετακίνηση στοιχείων {{count}} για φιλοξενία…", "moveToHost": "Μετακίνηση στον κεντρικό υπολογιστή…", "noHostsConnected": "Δεν υπάρχουν άλλοι διαθέσιμοι κεντρικοί υπολογιστές διαχείρισης αρχείων.", "noHostsConnectedHint": "Προσθέστε έναν άλλο κεντρικό υπολογιστή SSH με ενεργοποιημένο το File Manager στο Host Manager.", @@ -508,6 +535,9 @@ "transferError": "Η μεταφορά απέτυχε", "transferFailedRetryHint": "Μερικά δεδομένα διατηρήθηκαν στον προορισμό. Η επανάληψη θα συνεχιστεί όταν αποκατασταθεί η σύνδεση.", "transferPartialHint": "Δεν ήταν δυνατή η μεταφορά: {{paths}}", - "transferSuccess": "Η μεταφορά ολοκληρώθηκε" + "transferSuccess": "Η μεταφορά ολοκληρώθηκε", + "metricsHopSourceRead": "Πηγή → διακομιστής: {{throughput}}", + "metricsHopDestSftpWrite": "Διακομιστής → προορισμός (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Διακομιστής → προορισμός (τοπικός): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/es_ES.json b/plugins/file-manager/locales/translated/es_ES.json index 32502951c..d9643f946 100644 --- a/plugins/file-manager/locales/translated/es_ES.json +++ b/plugins/file-manager/locales/translated/es_ES.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "Archivos", + "sftp": "SFTP", + "openFileManager": "Abrir gestor de archivos" + }, + "permissions": { + "use": { + "title": "Utilice el administrador de archivos", + "description": "Explora, edita y transfiere archivos a través de SFTP." + } + }, + "settings": { + "host": { + "enable": { + "label": "Habilitar Gestor de archivos", + "description": "Explore y edite archivos en este servidor a través de SFTP." + }, + "defaultPath": { + "label": "Ruta predeterminada" + }, + "scpLegacy": { + "label": "Modo SCP heredado" + } + }, + "user": { + "transferConcurrency": { + "label": "Transferencias simultáneas de archivos", + "description": "¿Cuántos archivos sube o descarga simultáneamente el gestor local/remoto? Reduzca este valor si su servidor limita los canales SFTP." + }, + "confirmBeforeTrash": { + "label": "Confirme antes de mover los archivos a la papelera.", + "description": "Pregunte antes de mover archivos remotos a la papelera. La eliminación permanente aún requiere confirmación." + } + } + }, + "hostCapability": { + "label": "Gestor de archivos" + }, "fileManager": { "noHostSelected": "Ningún host seleccionado", "initializingEditor": "Inicializando editor...", @@ -34,6 +72,7 @@ "rename": "Renombrar", "uploading": "Subiendo...", "uploadingFile": "Subiendo {{name}}...", + "uploadingChunk": "Cargando {{name}}: {{percent}}% (parte {{chunk}} de {{total}})", "fileName": "Nombre del archivo", "folderName": "Nombre de la carpeta", "fileUploadedSuccessfully": "Archivo \"{{name}}\" subido correctamente", @@ -68,8 +107,8 @@ "localRevealInFileManager": "Mostrar en el administrador de archivos del sistema", "localCannotOpenFolder": "No se puede abrir la carpeta", "localItemCount": "{{count}} elementos", - "localSelectedCount": "{{count}} seleccionado", - "back": "Atrás", + "localSelectedCount": "{{count}} seleccionados", + "back": "Volver", "forward": "Adelante", "up": "Arriba", "kind": "Amable", @@ -83,14 +122,14 @@ "localUploadFailed": "Error al cargar la página", "localUploadPartial": "Se subieron {{done}} archivos, {{failed}} falló.", "localDownloadComplete": "Archivo(s) descargado(s) {{count}}", - "localDownloadFailed": "Falló la descarga.", + "localDownloadFailed": "Error en la descarga", "localDownloadPartial": "Se descargaron {{done}} archivos, {{failed}} falló.", "localReplaceExistingPrompt": "Ya existen {{count}} elementos en esta carpeta. ¿Desea reemplazarlos?", "localReplace": "Reemplazar", "localSkipExisting": "Saltar", "localSkippedExisting": "Se omitieron {{count}} elementos existentes", "localUnsafeNamesSkipped": "Se omitieron {{count}} elementos cuyos nombres no se pueden usar en este ordenador.", - "localOpen": "Abierto", + "localOpen": "Abrir", "localOpenFolder": "Abrir carpeta", "localUploadToRemote": "Subir al servidor", "localUploadToRemoteMany": "Sube {{count}} elementos al servidor", @@ -178,7 +217,7 @@ "trashDeleteFailed": "No se pudo eliminar el elemento de forma permanente.", "trashEmptyAction": "Vaciar la basura", "trashEmptyConfirm": "¿Eliminar permanentemente todos los elementos de la Papelera? Esta acción es irreversible.", - "trashEmptied": "Basura vaciada", + "trashEmptied": "Vaciado de basura", "trashRetention": "Limpieza automática después de (días)", "trashRetentionSaved": "Se ha actualizado la retención de basura.", "trashRetentionFailed": "Error al actualizar la retención de la papelera", @@ -290,6 +329,7 @@ "connecting": "Conectando...", "connectedSuccessfully": "Conectado correctamente", "totpVerificationFailed": "Error en la verificación TOTP", + "browserSignInFailed": "Error al iniciar sesión. Inténtalo de nuevo.", "authenticationFailed": "Error de autenticación", "incorrectPassphrase": "Frase de contraseña incorrecta. Inténtelo de nuevo.", "verificationCodePrompt": "Código de verificación:", @@ -326,7 +366,24 @@ "cannotLoadPdf": "No se puede cargar el PDF", "pdfLoadError": "Se produjo un error al cargar este archivo PDF.", "loadingPdf": "Cargando PDF...", - "loadingPage": "Cargando página..." + "loadingPage": "Cargando página...", + "cancel": "Cancelar", + "copiedItems_one": "Copiado {{count}} elemento", + "copiedItems_other": "Elementos copiados {{count}}", + "deleteCopiedFileFailed": "No se pudo eliminar la copia de {{name}}: {{error}}", + "dragMovedItems_one": "Se movió el elemento {{count}} a {{target}}", + "dragMovedItems_other": "Se movieron {{count}} elementos a {{target}}", + "moveBackFileFailed": "No se pudo mover {{name}} hacia atrás: {{error}}", + "terminal": "Terminal: {{host}} ({{path}})", + "dragToDesktop": "Arrastrando {{name}} al escritorio", + "dragFilesToDesktop": "Arrastrar archivos {{count}} al escritorio", + "folderDragUnsupported": "Todavía no se admite arrastrar carpetas al escritorio.", + "saveToDesktopFailed": "Error al guardar: {{error}}", + "dragFailedDetail": "Error al arrastrar: {{error}}", + "videoUnsupported": "Tu navegador no puede reproducir este formato de vídeo.", + "downloadToPlay": "Descárgalo para jugarlo en otro lugar.", + "cannotPreviewType": "No se puede previsualizar este tipo de archivo.", + "cannotPreviewTypeHint": "Este tipo de archivo no tiene vista previa. Descárguelo para abrirlo en otra aplicación." }, "sftpTransfer": { "title": "SFTP", @@ -334,7 +391,7 @@ "sourceServer": "Servidor de origen", "destinationServer": "Servidor de destino", "selectHost": "Seleccione el host", - "noHostSelected": "No se ha seleccionado ningún host.", + "noHostSelected": "Ningún host seleccionado", "move": "Mover", "copy": "Copiar", "upload": "Subir", @@ -346,22 +403,22 @@ "modified": "Modificado", "size": "Tamaño", "noFiles": "No hay archivos", - "open": "Abierto", + "open": "Abrir", "up": "Arriba", - "refresh": "Refrescar", + "refresh": "Actualizar", "copyToTarget": "Copiar al directorio de destino", - "rename": "Rebautizar", - "delete": "Borrar", + "rename": "Renombrar", + "delete": "Eliminar", "editPermissions": "Editar permisos", "createNewFolder": "Crear nueva carpeta", "deleteSelectedItems": "Eliminar elementos seleccionados", "deleteConfirm": "¿Eliminar {{count}} elemento seleccionado?", "deleteConfirm_other": "¿Eliminar {{count}} elementos seleccionados?", "cancel": "Cancelar", - "save": "Ahorrar", + "save": "Guardar", "folderCreated": "Carpeta creada", "itemRenamed": "Artículo renombrado", - "actionFailed": "La acción fracasó", + "actionFailed": "Acción fallida", "itemsDeleted": "{{count}} elemento eliminado", "itemsDeleted_other": "{{count}} elementos eliminados", "deleteFailed": "Error al eliminar", @@ -374,42 +431,12 @@ }, "hosts": { "fileManager": "Gestor de archivos", - "tabFiles": "Archivos", - "enableFileManagerMonitor": "Habilitar Gestor de archivos", - "enableFileManagerMonitorDesc": "Explorar y gestionar archivos en este host mediante SFTP", - "scpLegacyLabel": "Modo SCP heredado", - "scpLegacyDesc": "Usar transferencia de archivos heredada para servidores que no admiten el subsistema SFTP (p. ej., servidores SSH integrados o mínimos).", - "defaultPathLabel": "Ruta predeterminada", - "fileManagerPathHint": "Directorio que se abre al iniciar el gestor de archivos para este host.", "fileManagerUrlCopied": "URL del gestor de archivos copiada", "copyFileManagerUrlAction": "Copiar URL del gestor de archivos", "docsLink": "Ver documentación", "hostNotFound": "Host no encontrado", "loadingHost": "Cargando host..." }, - "settings": { - "host": { - "enable": { - "label": "Habilitar Gestor de archivos" - }, - "defaultPath": { - "label": "Ruta predeterminada" - }, - "scpLegacy": { - "label": "Modo SCP heredado" - } - }, - "user": { - "transferConcurrency": { - "label": "Transferencias simultáneas de archivos", - "description": "¿Cuántos archivos sube o descarga simultáneamente el gestor local/remoto? Reduzca este valor si su servidor limita los canales SFTP." - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "Archivos" - }, "onboarding": { "feature_files": "Gestor de archivos", "feature_files_desc": "Navega, sube, descarga y edita archivos a través de SFTP sin salir de la aplicación." @@ -437,7 +464,7 @@ "destinationPath": "Ruta de destino", "destMustBeDirectory": "El destino debe ser un directorio para transferencias de múltiples elementos", "goUp": "Subir", - "hostAuthRequired": "Se requiere autenticación — abre primero el Gestor de Archivos en este host", + "hostAuthRequired": "Se requiere autenticación. Abra primero el administrador de archivos en este host.", "hostConnecting": "Conectando…", "hostConnectionFailed": "Conexión fallida", "hostDisconnected": "No conectado", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "Has elegido SFTP por archivo.", "user_tar": "Has elegido archivo tar.", - "tar_unavailable": "Tar no está disponible en uno o ambos hosts; se usará SFTP por archivo.", - "windows_host": "Hay un host Windows implicado; no se usa tar.", - "auto_multi_large": "Auto: múltiples archivos incluido uno grande ({{largestSize}}) con datos comprimibles; tar los agrupa en una sola transferencia.", - "auto_single_large_in_archive": "Auto: un archivo grande ({{largestSize}}) en este conjunto; SFTP por archivo.", - "auto_many_incompressible": "Auto: datos mayoritariamente incompresibles; SFTP por archivo.", - "auto_many_files": "Auto: muchos archivos ({{fileCount}}); tar reduce la sobrecarga por archivo.", + "tar_unavailable": "Tar no está disponible en uno o ambos hosts, por lo que se utilizará SFTP por archivo.", + "windows_host": "Se trata de un sistema operativo Windows, por lo que no se utiliza tar.", + "auto_multi_large": "Automático: varios archivos, incluido un archivo grande ({{largestSize}}) con datos comprimibles. Tar los agrupa en una sola transferencia.", + "auto_single_large_in_archive": "Automático: un archivo grande ({{largestSize}}) en este conjunto, por lo que SFTP por archivo.", + "auto_many_incompressible": "Automático: datos mayormente incompresibles, por lo que se utiliza SFTP por archivo.", + "auto_many_files": "Automático: muchos archivos ({{fileCount}}), tar reduce la sobrecarga por archivo.", "auto_default": "Auto: SFTP por archivo para este conjunto." }, "methodTar": "Archivo Tar", @@ -471,7 +498,7 @@ "metricsCompress": "Compresión en origen: {{duration}}", "metricsExtract": "Extracción en destino: {{duration}}", "metricsPrepare": "Preparar destino: {{duration}}", - "metricsRouteBenchmark": "Sondeo de ruta: directo: {{direct}}, retransmisión: {{relay}}", + "metricsRouteBenchmark": "Sondeo de ruta: directo {{direct}}, relé {{relay}}", "metricsSourceDelete": "Eliminación del origen: {{duration}}", "metricsTotal": "Total: {{duration}}", "metricsTransfer": "Extremo a extremo: {{throughput}} ({{duration}})", @@ -508,6 +535,9 @@ "transferError": "Transferencia fallida", "transferFailedRetryHint": "Se conservaron datos parciales en el destino. El reintento se reanudará cuando se restablezca la conexión.", "transferPartialHint": "No se pudo transferir: {{paths}}", - "transferSuccess": "Transferencia completada" + "transferSuccess": "Transferencia completada", + "metricsHopSourceRead": "Origen → servidor: {{throughput}}", + "metricsHopDestSftpWrite": "Servidor → destino (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Servidor → destino (local): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/fi_FI.json b/plugins/file-manager/locales/translated/fi_FI.json index 92c3146dd..816a9e65a 100644 --- a/plugins/file-manager/locales/translated/fi_FI.json +++ b/plugins/file-manager/locales/translated/fi_FI.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "Tiedostot", + "sftp": "SFTP", + "openFileManager": "Avaa tiedostonhallinta" + }, + "permissions": { + "use": { + "title": "Käytä tiedostonhallintaa", + "description": "Selaa, muokkaa ja siirrä tiedostoja SFTP:n kautta." + } + }, + "settings": { + "host": { + "enable": { + "label": "Ota tiedostonhallinta käyttöön", + "description": "Selaa ja muokkaa tiedostoja tällä isännöinnillä SFTP:n kautta." + }, + "defaultPath": { + "label": "Oletuspolku" + }, + "scpLegacy": { + "label": "SCP:n vanha tila" + } + }, + "user": { + "transferConcurrency": { + "label": "Samanaikaiset tiedostonsiirrot", + "description": "Kuinka monta tiedostoa rinnakkainen paikallinen/etähallinta lataa tai lataa samanaikaisesti. Laske tätä arvoa, jos palvelimesi rajoittaa SFTP-kanavia." + }, + "confirmBeforeTrash": { + "label": "Vahvista ennen tiedostojen siirtämistä roskakoriin", + "description": "Kysy ennen etätiedostojen siirtämistä roskakoriin. Pysyvä poistaminen vaatii edelleen vahvistuksen." + } + } + }, + "hostCapability": { + "label": "Tiedostonhallinta" + }, "fileManager": { "noHostSelected": "Ei valittua isäntää", "initializingEditor": "Editorin alustaminen...", @@ -34,6 +72,7 @@ "rename": "Nimeä uudelleen", "uploading": "Ladataan...", "uploadingFile": "Ladataan {{name}}...", + "uploadingChunk": "Ladataan {{name}}: {{percent}}% (osa {{chunk}} / {{total}})", "fileName": "Tiedoston nimi", "folderName": "Kansion nimi", "fileUploadedSuccessfully": "Tiedosto \"{{name}}\" ladattu onnistuneesti", @@ -290,6 +329,7 @@ "connecting": "Yhdistetään...", "connectedSuccessfully": "Yhteys onnistui", "totpVerificationFailed": "TOTP-vahvistus epäonnistui", + "browserSignInFailed": "Kirjautuminen epäonnistui. Yritä uudelleen.", "authenticationFailed": "Todennus epäonnistui", "incorrectPassphrase": "Virheellinen salasana. Yritä uudelleen.", "verificationCodePrompt": "Vahvistuskoodi:", @@ -326,7 +366,24 @@ "cannotLoadPdf": "PDF-tiedoston lataaminen ei onnistu", "pdfLoadError": "PDF-tiedoston lataamisessa tapahtui virhe.", "loadingPdf": "Ladataan PDF-tiedostoa...", - "loadingPage": "Sivua ladataan..." + "loadingPage": "Sivua ladataan...", + "cancel": "Peruuttaa", + "copiedItems_one": "Kopioitu {{count}} kohde", + "copiedItems_other": "Kopioitu {{count}} kohdetta", + "deleteCopiedFileFailed": "Tiedoston {{name}}kopiota ei voitu poistaa : {{error}}", + "dragMovedItems_one": "Siirretty kohde {{count}} kohteeseen {{target}}", + "dragMovedItems_other": "Siirretty {{count}} kohdetta kohteeseen {{target}}", + "moveBackFileFailed": "Ei voitu siirtää {{name}} takaisin: {{error}}", + "terminal": "Pääte: {{host}} ({{path}})", + "dragToDesktop": "Vetämällä {{name}} työpöydälle", + "dragFilesToDesktop": "Tiedostojen {{count}} vetäminen työpöydälle", + "folderDragUnsupported": "Kansioiden vetäminen työpöydälle ei ole vielä tuettua", + "saveToDesktopFailed": "Tallennus epäonnistui: {{error}}", + "dragFailedDetail": "Vetäminen epäonnistui: {{error}}", + "videoUnsupported": "Selaimesi ei voi toistaa tätä videomuotoa.", + "downloadToPlay": "Lataa toistaaksesi sen muualla", + "cannotPreviewType": "Tätä tiedostotyyppiä ei voi esikatsella", + "cannotPreviewTypeHint": "Tällä tiedostotyypillä ei ole esikatselua. Lataa se avataksesi sen toisessa sovelluksessa." }, "sftpTransfer": { "title": "SFTP", @@ -374,42 +431,12 @@ }, "hosts": { "fileManager": "Tiedostonhallinta", - "tabFiles": "Tiedostot", - "enableFileManagerMonitor": "Ota tiedostonhallinta käyttöön", - "enableFileManagerMonitorDesc": "Selaa ja hallinnoi tiedostoja tällä isännöinnillä SFTP:n kautta", - "scpLegacyLabel": "SCP:n vanha tila", - "scpLegacyDesc": "Käytä vanhaa tiedostonsiirtoa palvelimilla, jotka eivät tue SFTP-alijärjestelmää (esim. sulautetut tai minimaaliset SSH-palvelimet).", - "defaultPathLabel": "Oletuspolku", - "fileManagerPathHint": "Hakemisto, joka avataan, kun tiedostonhallinta käynnistyy tälle isännälle.", "fileManagerUrlCopied": "Tiedostonhallinnan URL-osoite kopioitu", "copyFileManagerUrlAction": "Kopioi tiedostonhallinnan URL-osoite", "docsLink": "Näytä dokumentit", "hostNotFound": "Isäntää ei löydy", "loadingHost": "Ladataan isäntää..." }, - "settings": { - "host": { - "enable": { - "label": "Ota tiedostonhallinta käyttöön" - }, - "defaultPath": { - "label": "Oletuspolku" - }, - "scpLegacy": { - "label": "SCP:n vanha tila" - } - }, - "user": { - "transferConcurrency": { - "label": "Samanaikaiset tiedostonsiirrot", - "description": "Kuinka monta tiedostoa rinnakkainen paikallinen/etähallinta lataa tai lataa samanaikaisesti. Laske tätä arvoa, jos palvelimesi rajoittaa SFTP-kanavia." - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "Tiedostot" - }, "onboarding": { "feature_files": "Tiedostonhallinta", "feature_files_desc": "Selaa, lähetä, lataa ja muokkaa tiedostoja SFTP:n kautta poistumatta sovelluksesta." @@ -437,7 +464,7 @@ "destinationPath": "Kohdepolku", "destMustBeDirectory": "Määränpään on oltava hakemisto useiden kohteiden siirtoja varten", "goUp": "Mene ylös", - "hostAuthRequired": "Todennus vaaditaan — avaa ensin tiedostonhallinta tällä isännöintikoneella", + "hostAuthRequired": "Todennus vaaditaan. Avaa ensin tiedostonhallinta tällä isännöintikoneella.", "hostConnecting": "Yhdistetään…", "hostConnectionFailed": "Yhteys epäonnistui", "hostDisconnected": "Ei yhdistetty", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "Valitsit tiedostokohtaisen SFTP:n.", "user_tar": "Valitsit tar-arkiston.", - "tar_unavailable": "Tar ei ole käytettävissä yhdellä tai molemmilla isännillä — sen sijaan käytetään tiedostokohtaista SFTP:tä.", - "windows_host": "Windows-isäntä on mukana – tar-tiedostoa ei käytetä.", - "auto_multi_large": "Automaattinen: useita tiedostoja, mukaan lukien suuri tiedosto ({{largestSize}}), jossa on pakattavaa dataa — tar niputtaa yhdeksi siirroksi.", - "auto_single_large_in_archive": "Automaattinen: yksi suuri tiedosto ({{largestSize}}) tässä joukossa — tiedostokohtainen SFTP.", - "auto_many_incompressible": "Automaattinen: enimmäkseen pakkaamatonta dataa — tiedostokohtainen SFTP.", - "auto_many_files": "Automaattinen: monta tiedostoa ({{fileCount}}) — tar vähentää tiedostokohtaista laskentatehoa.", + "tar_unavailable": "Tar ei ole käytettävissä yhdellä tai molemmilla isännillä, joten käytetään tiedostokohtaista SFTP:tä.", + "windows_host": "Windows-isäntä on mukana, joten tar-tiedostoa ei käytetä.", + "auto_multi_large": "Automaattinen: useita tiedostoja, mukaan lukien suuri tiedosto ({{largestSize}}), jossa on pakattavaa dataa. Tar niputtaa ne yhdeksi siirtokohteeksi.", + "auto_single_large_in_archive": "Automaattinen: yksi suuri tiedosto ({{largestSize}}) tässä joukossa, joten tiedostokohtainen SFTP.", + "auto_many_incompressible": "Automaattinen: enimmäkseen pakkaamatonta dataa, joten tiedostokohtainen SFTP.", + "auto_many_files": "Automaattinen: monta tiedostoa ({{fileCount}}), tar vähentää tiedostokohtaista kuormaa.", "auto_default": "Automaattinen: tiedostokohtainen SFTP tälle joukolle." }, "methodTar": "Tar-arkisto", @@ -471,7 +498,7 @@ "metricsCompress": "Pakkaa lähdekoodissa: {{duration}}", "metricsExtract": "Ote määränpäässä: {{duration}}", "metricsPrepare": "Valmistele kohde: {{duration}}", - "metricsRouteBenchmark": "Reitityskoetin — suora: {{direct}}, välitys: {{relay}}", + "metricsRouteBenchmark": "Reititysanturi: suora {{direct}}, rele {{relay}}", "metricsSourceDelete": "Poista lähteestä: {{duration}}", "metricsTotal": "Yhteensä: {{duration}}", "metricsTransfer": "Päästä päähän: {{throughput}} ({{duration}})", @@ -508,6 +535,9 @@ "transferError": "Siirto epäonnistui", "transferFailedRetryHint": "Kohteessa säilytettiin vain osa tiedoista. Uudelleenyritys jatkuu, kun yhteys on palannut.", "transferPartialHint": "Siirto epäonnistui: {{paths}}", - "transferSuccess": "Siirto valmis" + "transferSuccess": "Siirto valmis", + "metricsHopSourceRead": "Lähde → palvelin: {{throughput}}", + "metricsHopDestSftpWrite": "Palvelin → kohde (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Palvelin → kohde (paikallinen): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/fr_FR.json b/plugins/file-manager/locales/translated/fr_FR.json index d5ab87fb9..0b626a3ab 100644 --- a/plugins/file-manager/locales/translated/fr_FR.json +++ b/plugins/file-manager/locales/translated/fr_FR.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "Fichiers", + "sftp": "SFTP", + "openFileManager": "Ouvrir le gestionnaire de fichiers" + }, + "permissions": { + "use": { + "title": "Utilisez le gestionnaire de fichiers", + "description": "Parcourez, modifiez et transférez des fichiers via SFTP." + } + }, + "settings": { + "host": { + "enable": { + "label": "Activer le gestionnaire de fichiers", + "description": "Parcourez et modifiez les fichiers hébergés sur ce serveur via SFTP." + }, + "defaultPath": { + "label": "Chemin par défaut" + }, + "scpLegacy": { + "label": "Mode SCP hérité" + } + }, + "user": { + "transferConcurrency": { + "label": "Transferts de fichiers simultanés", + "description": "Nombre de fichiers que le gestionnaire local/distant côte à côte télécharge ou charge simultanément. Réduisez cette valeur si votre serveur limite le nombre de canaux SFTP." + }, + "confirmBeforeTrash": { + "label": "Veuillez confirmer avant de déplacer des fichiers vers la corbeille.", + "description": "Demandez l'autorisation avant de déplacer des fichiers distants vers la corbeille. La suppression définitive nécessite toujours une confirmation." + } + } + }, + "hostCapability": { + "label": "Gestionnaire de fichiers" + }, "fileManager": { "noHostSelected": "Aucun hôte sélectionné", "initializingEditor": "Initialisation de l'éditeur...", @@ -34,6 +72,7 @@ "rename": "Renommer", "uploading": "Téléversement...", "uploadingFile": "Téléversement de {{name}}...", + "uploadingChunk": "Téléchargement de {{name}}: {{percent}}% (partie de {{chunk}} de {{total}})", "fileName": "Nom du fichier", "folderName": "Nom du dossier", "fileUploadedSuccessfully": "Fichier \"{{name}}\" téléversé avec succès", @@ -67,9 +106,9 @@ "localHideHidden": "Masquer les fichiers cachés", "localRevealInFileManager": "Afficher dans le gestionnaire de fichiers système", "localCannotOpenFolder": "Impossible d'ouvrir le dossier", - "localItemCount": "{{count}} articles", - "localSelectedCount": "{{count}} sélectionné", - "back": "Dos", + "localItemCount": "{{count}} éléments", + "localSelectedCount": "{{count}} sélectionné(s)", + "back": "Retour", "forward": "Avant", "up": "En haut", "kind": "Gentil", @@ -290,6 +329,7 @@ "connecting": "Connexion en cours...", "connectedSuccessfully": "Connecté avec succès", "totpVerificationFailed": "Échec de la vérification TOTP", + "browserSignInFailed": "Échec de la connexion. Veuillez réessayer.", "authenticationFailed": "Échec de l'authentification", "incorrectPassphrase": "Phrase secrète incorrecte. Veuillez réessayer.", "verificationCodePrompt": "Code de vérification :", @@ -326,7 +366,24 @@ "cannotLoadPdf": "Impossible de charger le PDF", "pdfLoadError": "Une erreur s'est produite lors du chargement de ce fichier PDF.", "loadingPdf": "Chargement du PDF...", - "loadingPage": "Chargement de la page..." + "loadingPage": "Chargement de la page...", + "cancel": "Annuler", + "copiedItems_one": "Élément copié {{count}}", + "copiedItems_other": "Éléments copiés {{count}}", + "deleteCopiedFileFailed": "Impossible de supprimer la copie de {{name}}: {{error}}", + "dragMovedItems_one": "Élément déplacé {{count}} vers {{target}}", + "dragMovedItems_other": "Éléments déplacés {{count}} vers {{target}}", + "moveBackFileFailed": "Impossible de déplacer {{name}} vers l'arrière : {{error}}", + "terminal": "Terminal : {{host}} ({{path}})", + "dragToDesktop": "Faire glisser {{name}} sur le bureau", + "dragFilesToDesktop": "Glisser-déposer des fichiers {{count}} sur le bureau", + "folderDragUnsupported": "Le glisser-déposer de dossiers sur le bureau n'est pas encore pris en charge.", + "saveToDesktopFailed": "Échec de l'enregistrement : {{error}}", + "dragFailedDetail": "Échec du glissement : {{error}}", + "videoUnsupported": "Votre navigateur ne peut pas lire ce format vidéo.", + "downloadToPlay": "Téléchargez-le pour y jouer ailleurs", + "cannotPreviewType": "Impossible de prévisualiser ce type de fichier", + "cannotPreviewTypeHint": "Ce type de fichier ne possède pas d'aperçu. Téléchargez-le pour l'ouvrir dans une autre application." }, "sftpTransfer": { "title": "SFTP", @@ -335,9 +392,9 @@ "destinationServer": "Serveur de destination", "selectHost": "Sélectionner l'hôte", "noHostSelected": "Aucun hôte sélectionné", - "move": "Se déplacer", - "copy": "Copie", - "upload": "Télécharger", + "move": "Déplacer", + "copy": "Copier", + "upload": "Téléverser", "itemsSelected": "{{count}} élément sélectionné", "itemsSelected_other": "{{count}} éléments sélectionnés", "ready": "Prêt", @@ -348,9 +405,9 @@ "noFiles": "Aucun fichier", "open": "Ouvrir", "up": "En haut", - "refresh": "Rafraîchir", + "refresh": "Actualiser", "copyToTarget": "Copier dans le répertoire cible", - "rename": "Rebaptiser", + "rename": "Renommer", "delete": "Supprimer", "editPermissions": "Autorisations de modification", "createNewFolder": "Créer un nouveau dossier", @@ -358,10 +415,10 @@ "deleteConfirm": "Supprimer l'élément sélectionné {{count}} ?", "deleteConfirm_other": "Supprimer les éléments sélectionnés {{count}} ?", "cancel": "Annuler", - "save": "Sauvegarder", + "save": "Enregistrer", "folderCreated": "Dossier créé", "itemRenamed": "Article renommé", - "actionFailed": "L'action a échoué", + "actionFailed": "Action échouée", "itemsDeleted": "{{count}} élément supprimé", "itemsDeleted_other": "{{count}} éléments supprimés", "deleteFailed": "Échec de la suppression", @@ -374,42 +431,12 @@ }, "hosts": { "fileManager": "Gestionnaire de fichiers", - "tabFiles": "Fichiers", - "enableFileManagerMonitor": "Activer le gestionnaire de fichiers", - "enableFileManagerMonitorDesc": "Parcourir et gérer les fichiers de cet hôte via SFTP", - "scpLegacyLabel": "Mode SCP hérité", - "scpLegacyDesc": "Utiliser le transfert de fichiers hérité pour les serveurs qui ne prennent pas en charge le sous-système SFTP (par exemple, serveurs SSH embarqués ou minimalistes).", - "defaultPathLabel": "Chemin par défaut", - "fileManagerPathHint": "Le répertoire à ouvrir lors du lancement du gestionnaire de fichiers pour cet hôte.", "fileManagerUrlCopied": "URL du gestionnaire de fichiers copiée", "copyFileManagerUrlAction": "Copier l'URL du gestionnaire de fichiers", "docsLink": "Voir la documentation", "hostNotFound": "Hôte introuvable", "loadingHost": "Chargement de l'hôte..." }, - "settings": { - "host": { - "enable": { - "label": "Activer le gestionnaire de fichiers" - }, - "defaultPath": { - "label": "Chemin par défaut" - }, - "scpLegacy": { - "label": "Mode SCP hérité" - } - }, - "user": { - "transferConcurrency": { - "label": "Transferts de fichiers simultanés", - "description": "Nombre de fichiers que le gestionnaire local/distant côte à côte télécharge ou charge simultanément. Réduisez cette valeur si votre serveur limite le nombre de canaux SFTP." - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "Fichiers" - }, "onboarding": { "feature_files": "Gestionnaire de fichiers", "feature_files_desc": "Parcourez, téléchargez, chargez et modifiez des fichiers via SFTP sans quitter l'application." @@ -437,7 +464,7 @@ "destinationPath": "Chemin de destination", "destMustBeDirectory": "La destination doit être un dossier pour les transferts de plusieurs éléments", "goUp": "Remonter", - "hostAuthRequired": "Authentification requise — ouvrez d’abord le gestionnaire de fichiers sur cet hôte", + "hostAuthRequired": "Authentification requise. Ouvrez d'abord le Gestionnaire de fichiers sur cet hôte.", "hostConnecting": "Connexion en cours…", "hostConnectionFailed": "Échec de la connexion", "hostDisconnected": "Non connecté", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "Vous avez choisi SFTP par fichier.", "user_tar": "Vous avez choisi l'archive tar.", - "tar_unavailable": "Tar n'est pas disponible sur l'un ou les deux hôtes — SFTP par fichier sera utilisé à la place.", - "windows_host": "Un hôte Windows est impliqué — tar n'est pas utilisé.", - "auto_multi_large": "Auto : plusieurs fichiers dont un fichier volumineux ({{largestSize}}) avec des données compressibles — tar regroupe en un seul transfert.", - "auto_single_large_in_archive": "Auto : un fichier volumineux ({{largestSize}}) dans cet ensemble — SFTP par fichier.", - "auto_many_incompressible": "Auto : données principalement incompressibles — SFTP par fichier.", - "auto_many_files": "Auto : nombreux fichiers ({{fileCount}}) — tar réduit la surcharge par fichier.", + "tar_unavailable": "Tar n'étant pas disponible sur l'un ou les deux hôtes, le transfert SFTP par fichier sera utilisé à la place.", + "windows_host": "Un système hôte Windows est impliqué, donc tar n'est pas utilisé.", + "auto_multi_large": "Auto : plusieurs fichiers, dont un fichier volumineux ({{largestSize}}) contenant des données compressibles. Tar les regroupe en un seul transfert.", + "auto_single_large_in_archive": "Auto : un fichier volumineux ({{largestSize}}) dans cet ensemble, donc SFTP par fichier.", + "auto_many_incompressible": "Auto : données majoritairement incompressibles, donc SFTP par fichier.", + "auto_many_files": "Auto : nombreux fichiers ({{fileCount}}), tar réduit la surcharge par fichier.", "auto_default": "Auto : SFTP par fichier pour cet ensemble." }, "methodTar": "Archive tar", @@ -471,7 +498,7 @@ "metricsCompress": "Compression sur la source : {{duration}}", "metricsExtract": "Extraction sur la destination : {{duration}}", "metricsPrepare": "Préparation de la destination : {{duration}}", - "metricsRouteBenchmark": "Sonde d'itinéraire — direct : {{direct}}, relais : {{relay}}", + "metricsRouteBenchmark": "Sonde d'itinéraire : direct {{direct}}, relais {{relay}}", "metricsSourceDelete": "Suppression depuis la source : {{duration}}", "metricsTotal": "Total : {{duration}}", "metricsTransfer": "De bout en bout : {{throughput}} ({{duration}})", @@ -508,6 +535,9 @@ "transferError": "Échec du transfert", "transferFailedRetryHint": "Des données partielles ont été conservées sur la destination. La nouvelle tentative reprendra lorsque la connexion sera rétablie.", "transferPartialHint": "Impossible de transférer : {{paths}}", - "transferSuccess": "Transfert terminé" + "transferSuccess": "Transfert terminé", + "metricsHopSourceRead": "Source → serveur : {{throughput}}", + "metricsHopDestSftpWrite": "Serveur → dest (SFTP) : {{throughput}}", + "metricsHopDestLocalWrite": "Serveur → dest (local) : {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/he_IL.json b/plugins/file-manager/locales/translated/he_IL.json index e3bfe8a11..6a4bfe4db 100644 --- a/plugins/file-manager/locales/translated/he_IL.json +++ b/plugins/file-manager/locales/translated/he_IL.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "קבצים", + "sftp": "SFTP", + "openFileManager": "פתח את מנהל הקבצים" + }, + "permissions": { + "use": { + "title": "השתמש במנהל הקבצים", + "description": "עיון, עריכה והעברה של קבצים דרך SFTP." + } + }, + "settings": { + "host": { + "enable": { + "label": "הפעל את מנהל הקבצים", + "description": "עיין וערוך קבצים במארח זה דרך SFTP." + }, + "defaultPath": { + "label": "נתיב ברירת מחדל" + }, + "scpLegacy": { + "label": "מצב SCP Legacy" + } + }, + "user": { + "transferConcurrency": { + "label": "העברות קבצים בו זמנית", + "description": "כמה קבצים מעלה או מוריד המנהל המקומי/מרחוק בו זמנית. יש להוריד ערך זה אם השרת שלך מגביל ערוצי SFTP." + }, + "confirmBeforeTrash": { + "label": "אשר לפני העברת קבצים לאשפה", + "description": "שאל לפני העברת קבצים מרוחקים לאשפה. מחיקה לצמיתות עדיין דורשת אישור." + } + } + }, + "hostCapability": { + "label": "מנהל הקבצים" + }, "fileManager": { "noHostSelected": "לא נבחר מארח", "initializingEditor": "מאתחל עורך...", @@ -34,6 +72,7 @@ "rename": "שינוי שם", "uploading": "מעלה...", "uploadingFile": "מעלה {{name}}...", + "uploadingChunk": "מעלה {{name}}: {{percent}}% (חלק {{chunk}} מתוך {{total}})", "fileName": "שם הקובץ", "folderName": "שם התיקייה", "fileUploadedSuccessfully": "הקובץ \"{{name}}\" הועלה בהצלחה", @@ -143,7 +182,7 @@ "failedToRenameItem": "שינוי שם הפריט נכשל", "download": "הורדה", "openExternalEditor": "פתוח חיצונית", - "chooseExternalEditor": "בחירת עורך חיצוני", + "chooseExternalEditor": "בחר עורך חיצוני", "externalEditorSelected": "עורך חיצוני נבחר", "externalEditorDesktopOnly": "עורך חיצוני זמין רק באפליקציית שולחן העבודה", "externalEditorOpened": "נפתח בעורך חיצוני. שמירה שם תעלה את השינויים בחזרה לשרת.", @@ -290,6 +329,7 @@ "connecting": "מְקַשֵׁר...", "connectedSuccessfully": "התחבר בהצלחה", "totpVerificationFailed": "אימות TOTP נכשל", + "browserSignInFailed": "הכניסה נכשלה. אנא נסה שוב.", "authenticationFailed": "האימות נכשל", "incorrectPassphrase": "סיסמה שגויה. אנא נסה שוב.", "verificationCodePrompt": "קוד אימות:", @@ -326,7 +366,24 @@ "cannotLoadPdf": "לא ניתן לטעון את ה-PDF", "pdfLoadError": "אירעה שגיאה בטעינת קובץ PDF זה.", "loadingPdf": "טוען PDF...", - "loadingPage": "טוען דף..." + "loadingPage": "טוען דף...", + "cancel": "לְבַטֵל", + "copiedItems_one": "פריט {{count}} הועתק", + "copiedItems_other": "הועתקו {{count}} פריטים", + "deleteCopiedFileFailed": "לא ניתן היה למחוק את העותק של {{name}}: {{error}}", + "dragMovedItems_one": "הועבר פריט {{count}} אל {{target}}", + "dragMovedItems_other": "הועבר {{count}} פריטים ל- {{target}}", + "moveBackFileFailed": "לא ניתן היה להזיז {{name}} אחורה: {{error}}", + "terminal": "טרמינל: {{host}} ({{path}})", + "dragToDesktop": "גרירת {{name}} לשולחן העבודה", + "dragFilesToDesktop": "גרירת קבצים {{count}} לשולחן העבודה", + "folderDragUnsupported": "גרירת תיקיות לשולחן העבודה אינה נתמכת עדיין", + "saveToDesktopFailed": "השמירה נכשלה: {{error}}", + "dragFailedDetail": "גרירה נכשלה: {{error}}", + "videoUnsupported": "הדפדפן שלך לא יכול להפעיל פורמט וידאו זה.", + "downloadToPlay": "הורד כדי להפעיל אותו במקום אחר", + "cannotPreviewType": "לא ניתן להציג תצוגה מקדימה של סוג קובץ זה", + "cannotPreviewTypeHint": "לסוג קובץ זה אין תצוגה מקדימה. הורד אותו כדי לפתוח אותו באפליקציה אחרת." }, "sftpTransfer": { "title": "SFTP", @@ -374,42 +431,12 @@ }, "hosts": { "fileManager": "מנהל הקבצים", - "tabFiles": "קבצים", - "enableFileManagerMonitor": "הפעל את מנהל הקבצים", - "enableFileManagerMonitorDesc": "עיון וניהול קבצים במארח זה דרך SFTP", - "scpLegacyLabel": "מצב SCP Legacy", - "scpLegacyDesc": "השתמש בהעברת קבצים מדור קודם עבור שרתים שאינם תומכים בתת-מערכת SFTP (למשל שרתי SSH מוטמעים או מינימליים).", - "defaultPathLabel": "נתיב ברירת מחדל", - "fileManagerPathHint": "הספרייה שתיפתח כאשר מנהל הקבצים יופעל עבור מארח זה.", "fileManagerUrlCopied": "כתובת ה-URL של מנהל הקבצים הועתקה", "copyFileManagerUrlAction": "העתקת כתובת URL של מנהל הקבצים", "docsLink": "הצג מסמכים", "hostNotFound": "המארח לא נמצא", "loadingHost": "טוען מארח..." }, - "settings": { - "host": { - "enable": { - "label": "הפעל את מנהל הקבצים" - }, - "defaultPath": { - "label": "נתיב ברירת מחדל" - }, - "scpLegacy": { - "label": "מצב SCP Legacy" - } - }, - "user": { - "transferConcurrency": { - "label": "העברות קבצים בו זמנית", - "description": "כמה קבצים מעלה או מוריד המנהל המקומי/מרחוק בו זמנית. יש להוריד ערך זה אם השרת שלך מגביל ערוצי SFTP." - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "קבצים" - }, "onboarding": { "feature_files": "מנהל הקבצים", "feature_files_desc": "דפדף, העלה, הורד וערוך קבצים דרך SFTP מבלי לצאת מהאפליקציה." @@ -437,7 +464,7 @@ "destinationPath": "נתיב היעד", "destMustBeDirectory": "היעד חייב להיות ספרייה עבור העברות מרובות פריטים", "goUp": "לַעֲלוֹת", - "hostAuthRequired": "נדרש אימות - פתח תחילה את מנהל הקבצים במארח זה", + "hostAuthRequired": "נדרש אימות. פתח תחילה את מנהל הקבצים במארח זה", "hostConnecting": "חיבור…", "hostConnectionFailed": "החיבור נכשל", "hostDisconnected": "לא מחובר", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "בחרת SFTP לפי קובץ.", "user_tar": "בחרת בארכיון tar.", - "tar_unavailable": "Tar אינו זמין באחד המארחים או בשניהם - במקום זאת ייעשה שימוש ב-SFTP לפי קובץ.", - "windows_host": "מחשב מארח של Windows מעורב - tar אינו בשימוש.", - "auto_multi_large": "אוטומטי: קבצים מרובים כולל קובץ גדול ({{largestSize}}) עם נתונים דחוסים - tar מאחד את הנתונים להעברה אחת.", - "auto_single_large_in_archive": "אוטומטי: קובץ גדול אחד ({{largestSize}}) בקבוצה זו - SFTP לכל קובץ.", - "auto_many_incompressible": "אוטומטי: נתונים לרוב בלתי ניתנים לדחיסה - SFTP לכל קובץ.", - "auto_many_files": "אוטומטי: קבצים רבים ({{fileCount}}) — tar מפחית את התקורה של כל קובץ.", + "tar_unavailable": "Tar אינו זמין באחד המארחים או בשניהם, לכן ייעשה שימוש במקום זאת ב-SFTP לפי קובץ.", + "windows_host": "מחשב מארח של Windows מעורב, לכן לא נעשה שימוש ב-tar.", + "auto_multi_large": "אוטומטי: קבצים מרובים כולל קובץ גדול ({{largestSize}}) עם נתונים הניתנים לדחיסה. Tar מאגד אותם להעברה אחת.", + "auto_single_large_in_archive": "אוטומטי: קובץ אחד גדול ({{largestSize}}) בקבוצה זו, לכן SFTP לכל קובץ.", + "auto_many_incompressible": "אוטומטי: נתונים לרוב בלתי ניתנים לדחיסה, לכן SFTP לכל קובץ.", + "auto_many_files": "אוטומטי: קבצים רבים ({{fileCount}}), tar מוריד את התקורה לכל קובץ.", "auto_default": "אוטומטי: SFTP לכל קובץ עבור קבוצה זו." }, "methodTar": "ארכיון טאר", @@ -471,7 +498,7 @@ "metricsCompress": "דחיסה במקור: {{duration}}", "metricsExtract": "חילוץ ביעד: {{duration}}", "metricsPrepare": "הכנת יעד: {{duration}}", - "metricsRouteBenchmark": "גשש מסלול — ישיר: {{direct}}, ממסר: {{relay}}", + "metricsRouteBenchmark": "גשש מסלול: ישיר {{direct}}, ממסר {{relay}}", "metricsSourceDelete": "הסר מהמקור: {{duration}}", "metricsTotal": "סה\"כ: {{duration}}", "metricsTransfer": "מקצה לקצה: {{throughput}} ({{duration}})", @@ -506,8 +533,11 @@ "transferCancelledCopyHint": "ייתכן שיישארו קבצים חלקיים ביעד.", "transferCancelledMoveHint": "ייתכן שיישארו קבצים חלקיים ביעד. קבצי המקור לא הוסרו.", "transferError": "ההעברה נכשלה", - "transferFailedRetryHint": "נתונים חלקיים נשמרו ביעד. ניסיון חוזר יחודש כאשר החיבור יחזור.", + "transferFailedRetryHint": "נתונים חלקיים נשמרו ביעד. ניסיון חוזר יתחדש כאשר החיבור יחזור.", "transferPartialHint": "לא ניתן היה להעביר: {{paths}}", - "transferSuccess": "ההעברה הושלמה" + "transferSuccess": "ההעברה הושלמה", + "metricsHopSourceRead": "מקור → שרת: {{throughput}}", + "metricsHopDestSftpWrite": "שרת → יעד (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "שרת → יעד (מקומי): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/hi_IN.json b/plugins/file-manager/locales/translated/hi_IN.json index 8fad2b363..db82088f3 100644 --- a/plugins/file-manager/locales/translated/hi_IN.json +++ b/plugins/file-manager/locales/translated/hi_IN.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "फ़ाइलें", + "sftp": "SFTP", + "openFileManager": "फ़ाइल प्रबंधक खोलें" + }, + "permissions": { + "use": { + "title": "Use file manager", + "description": "Browse, edit and transfer files over SFTP." + } + }, + "settings": { + "host": { + "enable": { + "label": "फ़ाइल प्रबंधक सक्षम करें", + "description": "Browse and edit files on this host over SFTP." + }, + "defaultPath": { + "label": "डिफ़ॉल्ट पथ" + }, + "scpLegacy": { + "label": "SCP लीगेसी मोड" + } + }, + "user": { + "transferConcurrency": { + "label": "Simultaneous File Transfers", + "description": "How many files the side by side local/remote manager uploads or downloads at the same time. Lower this if your server limits SFTP channels." + }, + "confirmBeforeTrash": { + "label": "Confirm before moving files to trash", + "description": "Ask before moving remote files to trash. Permanent deletion still requires confirmation." + } + } + }, + "hostCapability": { + "label": "फ़ाइल प्रबंधक" + }, "fileManager": { "noHostSelected": "कोई होस्ट चयनित नहीं", "initializingEditor": "संपादक आरंभ हो रहा है...", @@ -34,13 +72,14 @@ "rename": "नाम बदलें", "uploading": "अपलोड हो रहा है...", "uploadingFile": "{{name}} अपलोड हो रहा है...", + "uploadingChunk": "Uploading {{name}}: {{percent}}% (part {{chunk}} of {{total}})", "fileName": "फ़ाइल का नाम", "folderName": "फ़ोल्डर का नाम", "fileUploadedSuccessfully": "फ़ाइल \"{{name}}\" सफलतापूर्वक अपलोड हो गई", "failedToUploadFile": "फ़ाइल अपलोड करने में विफल", - "uploadingFolderFiles": "{{count}} फ़ाइलें अपलोड की जा रही हैं...", - "uploadedFolderFiles": "{{count}} फ़ाइलें सफलतापूर्वक अपलोड हो गईं", - "uploadedFolderPartial": "{{uploaded}} फ़ाइलें अपलोड की गईं, {{failed}} विफल रहीं", + "uploadingFolderFiles": "Uploading {{count}} file(s)...", + "uploadedFolderFiles": "Uploaded {{count}} file(s) successfully", + "uploadedFolderPartial": "Uploaded {{uploaded}} file(s), {{failed}} failed", "fileDownloadedSuccessfully": "फ़ाइल \"{{name}}\" सफलतापूर्वक डाउनलोड हो गई", "failedToDownloadFile": "फ़ाइल डाउनलोड करने में विफल", "fileCreatedSuccessfully": "फ़ाइल \"{{name}}\" सफलतापूर्वक बनाई गई", @@ -56,58 +95,58 @@ "sudoOperationFailed": "sudo संचालन विफल", "sudoAuthFailed": "sudo प्रमाणीकरण विफल", "dragFilesToUpload": "अपलोड करने के लिए फ़ाइलें यहाँ छोड़ें", - "dropToUploadHere": "अपलोड करने के लिए यहां ड्रॉप करें", - "dropToDownloadHere": "डाउनलोड करने के लिए यहां क्लिक करें", + "dropToUploadHere": "Drop to upload here", + "dropToDownloadHere": "Drop to download here", "localFiles": "स्थानीय", - "showLocalFiles": "स्थानीय फ़ाइलें दिखाएँ (स्प्लिट व्यू)", - "hideLocalFiles": "स्थानीय फ़ाइलों को छुपाएँ", - "localHome": "होम फ़ोल्डर", - "localPathPlaceholder": "स्थानीय फ़ोल्डर पथ", - "localShowHidden": "छिपी हुई फ़ाइलें दिखाएँ", - "localHideHidden": "छिपी हुई फ़ाइलों को छुपाएँ", - "localRevealInFileManager": "सिस्टम फ़ाइल प्रबंधक में दिखाएँ", - "localCannotOpenFolder": "फ़ोल्डर नहीं खोला जा सकता", + "showLocalFiles": "Show local files (split view)", + "hideLocalFiles": "Hide local files", + "localHome": "Home folder", + "localPathPlaceholder": "Local folder path", + "localShowHidden": "Show hidden files", + "localHideHidden": "Hide hidden files", + "localRevealInFileManager": "Reveal in system file manager", + "localCannotOpenFolder": "Cannot open folder", "localItemCount": "{{count}} आइटम", "localSelectedCount": "{{count}} चयनित", - "back": "पीछे", - "forward": "आगे", - "up": "ऊपर", - "kind": "दयालु", - "localUploadingProgress": "{{total}} में से {{current}} अपलोड किया जा रहा है", - "localDownloadingProgress": "{{total}} में से {{current}} डाउनलोड हो रहा है", - "localTransferInFlight": "{{count}} एक साथ", - "localPreparingDownload": "डाउनलोड की तैयारी हो रही है...", - "localTransferCancelled": "स्थानांतरण रद्द", - "localNothingToTransfer": "स्थानांतरित करने के लिए कुछ भी नहीं है", - "localUploadComplete": "{{count}} फाइल अपलोड की गई", - "localUploadFailed": "अपलोड विफल", - "localUploadPartial": "{{done}} फ़ाइलें अपलोड की गईं, {{failed}} विफल रहीं", - "localDownloadComplete": "डाउनलोड की गई {{count}} फ़ाइलें", + "back": "वापस", + "forward": "Forward", + "up": "Up", + "kind": "Kind", + "localUploadingProgress": "Uploading {{current}} of {{total}}", + "localDownloadingProgress": "Downloading {{current}} of {{total}}", + "localTransferInFlight": "{{count}} at once", + "localPreparingDownload": "Preparing download...", + "localTransferCancelled": "स्थानांतरण रद्द किया गया।", + "localNothingToTransfer": "Nothing to transfer", + "localUploadComplete": "Uploaded {{count}} file(s)", + "localUploadFailed": "Upload failed", + "localUploadPartial": "Uploaded {{done}} file(s), {{failed}} failed", + "localDownloadComplete": "Downloaded {{count}} file(s)", "localDownloadFailed": "डाउनलोड विफल", - "localDownloadPartial": "{{done}} फ़ाइलें डाउनलोड की गईं, {{failed}} डाउनलोड विफल रहा।", - "localReplaceExistingPrompt": "इस फ़ोल्डर में पहले से ही {{count}} आइटम मौजूद हैं। क्या आप उन्हें बदलना चाहेंगे?", - "localReplace": "प्रतिस्थापित करें", - "localSkipExisting": "छोडना", - "localSkippedExisting": "मौजूदा आइटमों में से {{count}} को छोड़ दिया गया", - "localUnsafeNamesSkipped": "इस कंप्यूटर पर जिन आइटमों के नाम इस्तेमाल नहीं किए जा सकते, उन्हें छोड़ दिया गया है {{count}}", - "localOpen": "खुला", - "localOpenFolder": "फोल्डर खोलें", - "localUploadToRemote": "सर्वर पर अपलोड करें", - "localUploadToRemoteMany": "सर्वर पर {{count}} आइटम अपलोड करें", - "localMoveToTrash": "ट्रैश में ले जाएं", - "localMoveToTrashMany": "{{count}} आइटम ट्रैश में ले जाएं", - "localTrashConfirmSingle": "क्या आप \"{{name}}\" को ट्रैश में ले जाना चाहते हैं?", - "localTrashConfirmFolder": "क्या आप फोल्डर \"{{name}}\" और उसकी सभी सामग्री को ट्रैश में ले जाना चाहते हैं?", - "localTrashConfirmMany": "क्या {{count}} आइटम ट्रैश में ले जाएं?", - "localTrashed": "{{count}} आइटम ट्रैश में भेज दिए गए हैं", - "localTrashFailed": "ट्रैश में नहीं ले जाया जा सका", - "localRenameFailed": "नाम बदलने में विफल रहा", - "localCreateFailed": "आइटम नहीं बनाया जा सका", - "goToParentFolder": "मूल फ़ोल्डर पर जाएँ", - "resizeSidebar": "साइडबार का आकार बदलने के लिए उसे खींचें (रीसेट करने के लिए उस पर डबल-क्लिक करें)", - "resizeLocalPane": "स्थानीय फलक का आकार बदलने के लिए उसे खींचें (आकार बदलने के लिए उस पर दो बार क्लिक करें)", + "localDownloadPartial": "Downloaded {{done}} file(s), {{failed}} failed", + "localReplaceExistingPrompt": "{{count}} item(s) already exist in this folder. Replace them?", + "localReplace": "बदलें", + "localSkipExisting": "Skip", + "localSkippedExisting": "Skipped {{count}} existing item(s)", + "localUnsafeNamesSkipped": "Skipped {{count}} item(s) whose names cannot be used on this computer", + "localOpen": "खोलें", + "localOpenFolder": "Open folder", + "localUploadToRemote": "Upload to server", + "localUploadToRemoteMany": "Upload {{count}} items to server", + "localMoveToTrash": "Move to Trash", + "localMoveToTrashMany": "Move {{count}} items to Trash", + "localTrashConfirmSingle": "Move \"{{name}}\" to the Trash?", + "localTrashConfirmFolder": "Move the folder \"{{name}}\" and all its contents to the Trash?", + "localTrashConfirmMany": "Move {{count}} items to the Trash?", + "localTrashed": "Moved {{count}} item(s) to the Trash", + "localTrashFailed": "Could not move to the Trash", + "localRenameFailed": "Rename failed", + "localCreateFailed": "Could not create item", + "goToParentFolder": "Go to parent folder", + "resizeSidebar": "Drag to resize the sidebar (double-click to reset)", + "resizeLocalPane": "Drag to resize the local pane (double-click to reset)", "columns": "कॉलम", - "columnsHint": "कॉलम चुनने के लिए राइट-क्लिक करें", + "columnsHint": "Right-click to choose columns", "emptyFolder": "यह फ़ोल्डर खाली है", "searchFiles": "फ़ाइलें खोजें...", "upload": "अपलोड करें", @@ -163,26 +202,26 @@ "confirmDeleteMultipleItemsWithFolders": "क्या आप वाकई {{count}} आइटम स्थायी रूप से हटाना चाहते हैं? इसमें फ़ोल्डर और उनकी सामग्री शामिल है।", "confirmDeleteFolder": "क्या आप वाकई फ़ोल्डर \"{{name}}\" और उसकी सभी सामग्री को स्थायी रूप से हटाना चाहते हैं?", "permanentDeleteWarning": "यह क्रिया पूर्ववत नहीं की जा सकती। आइटम सर्वर से स्थायी रूप से हटा दिए जाएँगे।", - "moveToTrashWarning": "आइटम को टर्मिक्स ट्रैश में भेज दिया जाएगा और प्रतिधारण अवधि समाप्त होने से पहले इसे पुनर्स्थापित किया जा सकता है।", - "itemsMovedToTrash": "{{count}} आइटम ट्रैश में चले गए", - "trash": "कचरा", - "trashDescription": "हटाए गए आइटम इस होस्ट पर {{days}} दिनों तक रखे जाते हैं।", - "trashLoadFailed": "ट्रैश लोड करने में विफल", - "trashEmpty": "कचरा पात्र खाली है", - "trashRestore": "पुनर्स्थापित करना", - "trashRestored": "पुनर्स्थापित {{name}}", - "trashRestoreFailed": "आइटम को पुनर्स्थापित करने में विफल। मूल पथ पहले से मौजूद हो सकता है।", - "trashDeletePermanently": "स्थायी रूप से हटाएं", - "trashDeleteConfirm": "{{name}}को स्थायी रूप से हटा दें? इसे पूर्ववत नहीं किया जा सकता।", - "trashPermanentlyDeleted": "स्थायी रूप से हटा दिया गया {{name}}", - "trashDeleteFailed": "आइटम को स्थायी रूप से हटाने में विफल रहा", - "trashEmptyAction": "कचरा खाली करें", - "trashEmptyConfirm": "ट्रैश में मौजूद सभी आइटम को स्थायी रूप से हटाना चाहते हैं? इसे वापस नहीं लिया जा सकता।", - "trashEmptied": "कचरा खाली कर दिया गया", - "trashRetention": "(दिनों) के बाद स्वचालित सफाई", - "trashRetentionSaved": "कचरा संग्रहण प्रणाली को अद्यतन किया गया", - "trashRetentionFailed": "ट्रैश रिटेंशन को अपडेट करने में विफलता", - "trashUnavailableConfirm": "इस आइटम को ट्रैश में नहीं ले जाया जा सकता, आमतौर पर इसलिए क्योंकि यह किसी अन्य फ़ाइल सिस्टम पर है या इसके लिए उच्च अनुमतियों की आवश्यकता होती है। क्या इसे स्थायी रूप से हटा देना बेहतर होगा?", + "moveToTrashWarning": "The item(s) will be moved to the Termix Trash and can be restored before the retention period expires.", + "itemsMovedToTrash": "{{count}} item(s) moved to Trash", + "trash": "Trash", + "trashDescription": "Deleted items are retained for {{days}} day(s) on this host.", + "trashLoadFailed": "Failed to load Trash", + "trashEmpty": "Trash is empty", + "trashRestore": "पुनर्स्थापित करें", + "trashRestored": "Restored {{name}}", + "trashRestoreFailed": "Failed to restore item. The original path may already exist.", + "trashDeletePermanently": "Delete permanently", + "trashDeleteConfirm": "Permanently delete {{name}}? This cannot be undone.", + "trashPermanentlyDeleted": "Permanently deleted {{name}}", + "trashDeleteFailed": "Failed to permanently delete item", + "trashEmptyAction": "Empty Trash", + "trashEmptyConfirm": "Permanently delete every item in Trash? This cannot be undone.", + "trashEmptied": "Trash emptied", + "trashRetention": "Automatic cleanup after (days)", + "trashRetentionSaved": "Trash retention updated", + "trashRetentionFailed": "Failed to update Trash retention", + "trashUnavailableConfirm": "This item cannot be moved to Trash, usually because it is on another filesystem or requires elevated permissions. Delete it permanently instead?", "recent": "हाल ही", "pinned": "पिन किए गए", "folderShortcuts": "फ़ोल्डर शॉर्टकट", @@ -264,7 +303,7 @@ "operationCompleted": "{{operation}} {{count}} आइटम", "downloadFileSuccess": "फ़ाइल {{name}} सफलतापूर्वक डाउनलोड हुई", "downloadFileFailed": "डाउनलोड विफल", - "downloadingFile": "डाउनलोड हो रहा है {{name}}…", + "downloadingFile": "Downloading {{name}}…", "downloadProgressBytes": "{{transferred}} / {{total}}", "moveTo": "{{name}} में ले जाएँ", "diffCompareWith": "{{name}} के साथ डिफ तुलना करें", @@ -290,6 +329,7 @@ "connecting": "कनेक्ट हो रहा है...", "connectedSuccessfully": "सफलतापूर्वक कनेक्ट हुआ", "totpVerificationFailed": "TOTP सत्यापन विफल", + "browserSignInFailed": "Sign-in failed. Please try again.", "authenticationFailed": "प्रमाणीकरण विफल", "incorrectPassphrase": "गलत पासफ़्रेज़। कृपया पुनः प्रयास करें।", "verificationCodePrompt": "सत्यापन कोड:", @@ -321,98 +361,85 @@ "used": "प्रयुक्त", "of": "में से", "toggleSidebar": "साइडबार टॉगल करें", - "compactLayout": "कॉम्पैक्ट लेआउट का उपयोग करें", - "comfortableLayout": "सुविधाजनक लेआउट का उपयोग करें", + "compactLayout": "Use compact layout", + "comfortableLayout": "Use comfortable layout", "cannotLoadPdf": "PDF लोड नहीं कर सकता", "pdfLoadError": "इस PDF फ़ाइल को लोड करने में त्रुटि हुई।", "loadingPdf": "PDF लोड हो रहा है...", - "loadingPage": "पृष्ठ लोड हो रहा है..." + "loadingPage": "पृष्ठ लोड हो रहा है...", + "cancel": "रद्द करें", + "copiedItems_one": "Copied {{count}} item", + "copiedItems_other": "Copied {{count}} items", + "deleteCopiedFileFailed": "Could not delete the copy of {{name}}: {{error}}", + "dragMovedItems_one": "Moved {{count}} item to {{target}}", + "dragMovedItems_other": "Moved {{count}} items to {{target}}", + "moveBackFileFailed": "Could not move {{name}} back: {{error}}", + "terminal": "Terminal: {{host}} ({{path}})", + "dragToDesktop": "Dragging {{name}} to the desktop", + "dragFilesToDesktop": "Dragging {{count}} files to the desktop", + "folderDragUnsupported": "Dragging folders to the desktop is not supported yet", + "saveToDesktopFailed": "Save failed: {{error}}", + "dragFailedDetail": "Drag failed: {{error}}", + "videoUnsupported": "Your browser cannot play this video format.", + "downloadToPlay": "Download to play it elsewhere", + "cannotPreviewType": "Cannot preview this file type", + "cannotPreviewTypeHint": "This file type has no preview. Download it to open it in another app." }, "sftpTransfer": { - "title": "एसएफटीपी", - "description": "दो SSH होस्ट के बीच फ़ाइलें स्थानांतरित करें।", - "sourceServer": "स्रोत सर्वर", - "destinationServer": "गंतव्य सर्वर", - "selectHost": "होस्ट का चयन करें", + "title": "SFTP", + "description": "Transfer files between two SSH hosts.", + "sourceServer": "Source Server", + "destinationServer": "Destination Server", + "selectHost": "Select host", "noHostSelected": "कोई होस्ट चयनित नहीं है", - "move": "कदम", - "copy": "प्रतिलिपि", + "move": "ले जाएँ", + "copy": "कॉपी", "upload": "अपलोड करें", - "itemsSelected": "{{count}} आइटम चयनित", - "itemsSelected_other": "{{count}} आइटम चयनित", + "itemsSelected": "{{count}} item selected", + "itemsSelected_other": "{{count}} items selected", "ready": "तैयार", "loadingHosts": "होस्ट लोड हो रहे हैं...", "name": "नाम", "modified": "संशोधित", "size": "आकार", - "noFiles": "कोई फ़ाइल नहीं", - "open": "खुला", - "up": "ऊपर", - "refresh": "ताज़ा करना", - "copyToTarget": "लक्ष्य निर्देशिका में प्रतिलिपि करें", + "noFiles": "No files", + "open": "खोलें", + "up": "Up", + "refresh": "ताज़ा करें", + "copyToTarget": "Copy to Target Directory", "rename": "नाम बदलें", - "delete": "मिटाना", - "editPermissions": "संपादन अनुमतियाँ", - "createNewFolder": "नया फ़ोल्डर बनाएं", - "deleteSelectedItems": "चयनित आइटम हटाएं", - "deleteConfirm": "चयनित आइटम हटाएं {{count}}?", - "deleteConfirm_other": "चयनित आइटम हटाएं {{count}}?", - "cancel": "रद्द करना", - "save": "बचाना", - "folderCreated": "फ़ोल्डर बनाया गया", - "itemRenamed": "आइटम का नाम बदल दिया गया", - "actionFailed": "क्रिया: विफल रही है", - "itemsDeleted": "{{count}} आइटम हटा दिया गया", - "itemsDeleted_other": "{{count}} आइटम हटा दिए गए", - "deleteFailed": "डिलीट विफल", - "permissionsUpdated": "अनुमतियाँ अपडेट की गईं", - "noRemoteSessionConnected": "कोई रिमोट सेशन कनेक्ट नहीं हुआ", - "failedToListFiles": "फ़ाइलों को सूचीबद्ध करने में विफल", - "failedToRefresh": "रीफ़्रेश करने में विफल", - "destinationInsideSource": "गंतव्य चयनित स्रोत पथ के अंदर नहीं हो सकता।", - "sameHostNoOp": "स्रोत और गंतव्य एक ही फ़ोल्डर हैं।" + "delete": "हटाएँ", + "editPermissions": "Edit Permissions", + "createNewFolder": "Create New Folder", + "deleteSelectedItems": "Delete Selected Items", + "deleteConfirm": "Delete {{count}} selected item?", + "deleteConfirm_other": "Delete {{count}} selected items?", + "cancel": "रद्द करें", + "save": "सहेजें", + "folderCreated": "Folder created", + "itemRenamed": "Item renamed", + "actionFailed": "कार्रवाई विफल", + "itemsDeleted": "{{count}} item deleted", + "itemsDeleted_other": "{{count}} items deleted", + "deleteFailed": "Delete failed", + "permissionsUpdated": "Permissions updated", + "noRemoteSessionConnected": "No remote session connected", + "failedToListFiles": "Failed to list files", + "failedToRefresh": "Failed to refresh", + "destinationInsideSource": "Destination cannot be inside the selected source path.", + "sameHostNoOp": "Source and destination are the same folder." }, "hosts": { "fileManager": "फ़ाइल प्रबंधक", - "tabFiles": "फ़ाइलें", - "enableFileManagerMonitor": "फ़ाइल प्रबंधक सक्षम करें", - "enableFileManagerMonitorDesc": "इस होस्ट पर SFTP के ज़रिए फ़ाइलें ब्राउज़ और प्रबंधित करें", - "scpLegacyLabel": "SCP लीगेसी मोड", - "scpLegacyDesc": "उन सर्वरों के लिए लीगेसी फ़ाइल स्थानांतरण का उपयोग करें जो SFTP सबसिस्टम का समर्थन नहीं करते (जैसे एम्बेडेड या न्यूनतम SSH सर्वर)।", - "defaultPathLabel": "डिफ़ॉल्ट पथ", - "fileManagerPathHint": "जब इस होस्ट के लिए फ़ाइल प्रबंधक लॉन्च होता है तो खोलने के लिए निर्देशिका।", "fileManagerUrlCopied": "फ़ाइल प्रबंधक URL कॉपी किया गया", "copyFileManagerUrlAction": "फ़ाइल प्रबंधक URL कॉपी करें", "docsLink": "दस्तावेज़ देखें", "hostNotFound": "होस्ट नहीं मिला", "loadingHost": "होस्ट लोड हो रहा है..." }, - "settings": { - "host": { - "enable": { - "label": "फ़ाइल प्रबंधक सक्षम करें" - }, - "defaultPath": { - "label": "डिफ़ॉल्ट पथ" - }, - "scpLegacy": { - "label": "SCP लीगेसी मोड" - } - }, - "user": { - "transferConcurrency": { - "label": "एक साथ फ़ाइल स्थानांतरण", - "description": "साइड-बाय-साइड लोकल/रिमोट मैनेजर एक ही समय में कितनी फाइलें अपलोड या डाउनलोड कर सकता है। यदि आपका सर्वर SFTP चैनलों को सीमित करता है तो इसे कम करें।" - } - } - }, - "nav": { - "sftp": "एसएफटीपी", - "files": "फ़ाइलें" - }, "onboarding": { - "feature_files": "फ़ाइल मैनेजर", - "feature_files_desc": "ऐप छोड़े बिना SFTP के माध्यम से फाइलों को ब्राउज़ करें, अपलोड करें, डाउनलोड करें और संपादित करें।" + "feature_files": "File manager", + "feature_files_desc": "Browse, upload, download and edit files over SFTP without leaving the app." }, "terminal": { "runTitle": "{{command}} चल रहा है - {{host}}", @@ -437,7 +464,7 @@ "destinationPath": "गंतव्य पथ", "destMustBeDirectory": "कई आइटम स्थानांतरण के लिए गंतव्य एक निर्देशिका होना चाहिए", "goUp": "ऊपर जाएं", - "hostAuthRequired": "प्रमाणीकरण आवश्यक है — पहले इस होस्ट पर फ़ाइल प्रबंधक खोलें", + "hostAuthRequired": "Authentication required. Open File Manager on this host first", "hostConnecting": "कनेक्ट हो रहा है…", "hostConnectionFailed": "कनेक्शन विफल", "hostDisconnected": "कनेक्ट नहीं है", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "आपने प्रति-फ़ाइल SFTP चुना।", "user_tar": "आपने tar संग्रह चुना।", - "tar_unavailable": "Tar एक या दोनों होस्ट पर उपलब्ध नहीं है — इसके बजाय प्रति-फ़ाइल SFTP का उपयोग किया जाएगा।", - "windows_host": "कोई Windows होस्ट शामिल है — tar का उपयोग नहीं होता।", - "auto_multi_large": "ऑटो: संपीड़न योग्य डेटा वाली एक बड़ी फ़ाइल ({{largestSize}}) सहित अनेक फ़ाइलें — tar एकल स्थानांतरण में बंडल करता है।", - "auto_single_large_in_archive": "ऑटो: इस सेट में एक बड़ी फ़ाइल ({{largestSize}}) — प्रति-फ़ाइल SFTP।", - "auto_many_incompressible": "ऑटो: अधिकतर असंपीड़नीय डेटा — प्रति-फ़ाइल SFTP।", - "auto_many_files": "ऑटो: बहुत सारी फ़ाइलें ({{fileCount}}) — tar प्रति-फ़ाइल ओवरहेड कम करता है।", + "tar_unavailable": "Tar is not available on one or both hosts, so per-file SFTP will be used instead.", + "windows_host": "A Windows host is involved, so tar is not used.", + "auto_multi_large": "Auto: multiple files including a large file ({{largestSize}}) with compressible data. Tar bundles them into one transfer.", + "auto_single_large_in_archive": "Auto: one large file ({{largestSize}}) in this set, so per-file SFTP.", + "auto_many_incompressible": "Auto: mostly incompressible data, so per-file SFTP.", + "auto_many_files": "Auto: many files ({{fileCount}}), tar cuts the per-file overhead.", "auto_default": "ऑटो: इस सेट के लिए प्रति-फ़ाइल SFTP।" }, "methodTar": "Tar संग्रह", @@ -471,11 +498,11 @@ "metricsCompress": "स्रोत पर संपीड़न: {{duration}}", "metricsExtract": "गंतव्य पर निष्कर्षण: {{duration}}", "metricsPrepare": "गंतव्य तैयारी: {{duration}}", - "metricsRouteBenchmark": "रूट प्रोब — डायरेक्ट: {{direct}}, रिले: {{relay}}", + "metricsRouteBenchmark": "Route probe: direct {{direct}}, relay {{relay}}", "metricsSourceDelete": "स्रोत से हटाना: {{duration}}", "metricsTotal": "कुल: {{duration}}", "metricsTransfer": "एंड-टू-एंड: {{throughput}} ({{duration}})", - "metricsVerify": "SHA-256 सत्यापित: {{duration}}", + "metricsVerify": "SHA-256 verified: {{duration}}", "moveFolderToHost": "फ़ोल्डर होस्ट पर स्थानांतरित करें…", "moveItemsToHost": "{{count}} आइटम होस्ट पर स्थानांतरित करें…", "moveToHost": "होस्ट पर ले जाएँ…", @@ -484,7 +511,7 @@ "parallelSegmentsHint": "बड़ी फ़ाइलें 256 MB टुकड़ों में विभाजित होती हैं। एकाधिक लेन उच्च कुल थ्रूपुट के लिए अलग-अलग कनेक्शन का उपयोग करती हैं (जैसे कई स्थानांतरण प्रारंभ करना)।", "parallelSegmentsLabel": "समानांतर स्थानांतरण लेन", "parallelSegmentsOption": "{{count}} लेन", - "progressBenchmarking": "सबसे तेज़ स्थानांतरण मार्ग का चयन करना…", + "progressBenchmarking": "Selecting the fastest transfer route…", "progressBytes": "{{transferred}} / {{total}}", "progressCancel": "रद्द करें", "progressCancelling": "रद्द कर रहा है…", @@ -496,7 +523,7 @@ "progressTotalSpeed": "{{speed}} कुल ({{lanes}} लेन)", "progressTransferring": "डेटा स्थानांतरित कर रहा है…", "progressTransferringItems": "फ़ाइलें स्थानांतरित कर रहा है ({{current}} / {{total}})…", - "progressVerifying": "फ़ाइल की अखंडता का सत्यापन…", + "progressVerifying": "Verifying file integrity…", "recentDestinations": "हाल के गंतव्य", "resumedHint": "किसी अन्य विंडो में शुरू हुए सक्रिय स्थानांतरण से पुनः जुड़ा।", "retryTransfer": "पुनः प्रयास करें", @@ -508,6 +535,9 @@ "transferError": "स्थानांतरण विफल", "transferFailedRetryHint": "आंशिक डेटा गंतव्य पर रखा गया था। कनेक्शन वापस आने पर पुनः प्रयास फिर से शुरू होगा।", "transferPartialHint": "स्थानांतरित नहीं किया जा सका: {{paths}}", - "transferSuccess": "स्थानांतरण पूर्ण" + "transferSuccess": "स्थानांतरण पूर्ण", + "metricsHopSourceRead": "स्रोत → सर्वर: {{throughput}}", + "metricsHopDestSftpWrite": "सर्वर → गंतव्य (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "सर्वर → गंतव्य (स्थानीय): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/hu_HU.json b/plugins/file-manager/locales/translated/hu_HU.json index 7ca100da3..505a543f0 100644 --- a/plugins/file-manager/locales/translated/hu_HU.json +++ b/plugins/file-manager/locales/translated/hu_HU.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "Fájlok", + "sftp": "SFTP", + "openFileManager": "Fájlkezelő megnyitása" + }, + "permissions": { + "use": { + "title": "Fájlkezelő használata", + "description": "Fájlok böngészése, szerkesztése és átvitele SFTP-n keresztül." + } + }, + "settings": { + "host": { + "enable": { + "label": "Fájlkezelő engedélyezése", + "description": "Böngésszen és szerkessze a fájlokat ezen a gazdagépen SFTP-n keresztül." + }, + "defaultPath": { + "label": "Alapértelmezett elérési út" + }, + "scpLegacy": { + "label": "SCP örökölt mód" + } + }, + "user": { + "transferConcurrency": { + "label": "Egyidejű fájlátvitel", + "description": "Hány fájlt tölt fel vagy tölt le egyszerre az egymás melletti helyi/távoli kezelő. Csökkentse ezt az értéket, ha a szerver korlátozza az SFTP csatornákat." + }, + "confirmBeforeTrash": { + "label": "Fájlok kukába helyezése előtt erősítse meg", + "description": "Kérdezzen rá, mielőtt a távoli fájlokat a kukába helyezi. A végleges törlés továbbra is megerősítést igényel." + } + } + }, + "hostCapability": { + "label": "Fájlkezelő" + }, "fileManager": { "noHostSelected": "Nincs kiválasztva gazdagép", "initializingEditor": "Szerkesztő inicializálása...", @@ -34,6 +72,7 @@ "rename": "Átnevezés", "uploading": "Feltöltés...", "uploadingFile": "Feltöltés {{name}}...", + "uploadingChunk": "Feltöltés folyamatban {{name}}: {{percent}}% (a {{chunk}} része a {{total}}-ból)", "fileName": "Fájlnév", "folderName": "Mappa neve", "fileUploadedSuccessfully": "A(z) \"{{name}}\" fájl feltöltése sikeresen megtörtént.", @@ -214,7 +253,7 @@ "undoCopyFailedDelete": "Visszavonás sikertelen: Nem sikerült törölni a másolt fájlokat", "undoCopyFailedNoInfo": "Visszavonás sikertelen: Nem találhatók másolt fájlinformációk", "undoMoveSuccess": "Visszavont áthelyezési művelet: {{count}} fájl visszahelyezése az eredeti helyére", - "undoMoveFailedMove": "Visszavonás sikertelen: Nem sikerült fájlokat visszahelyezni", + "undoMoveFailedMove": "Visszavonás sikertelen: Nem sikerült visszahelyezni a fájlokat", "undoMoveFailedNoInfo": "Visszavonás sikertelen: Nem találhatók áthelyezett fájlinformációk", "undoDeleteNotSupported": "A törlési művelet nem vonható vissza: A fájlok véglegesen törölve lettek a szerverről.", "undoTypeNotSupported": "Nem támogatott visszavonási művelettípus", @@ -290,6 +329,7 @@ "connecting": "Kapcsolódás...", "connectedSuccessfully": "Sikeres csatlakozás", "totpVerificationFailed": "TOTP-ellenőrzés sikertelen", + "browserSignInFailed": "Sikertelen bejelentkezés. Kérjük, próbálja újra.", "authenticationFailed": "Hitelesítés sikertelen", "incorrectPassphrase": "Hibás jelszó. Kérjük, próbálja újra.", "verificationCodePrompt": "Ellenőrző kód:", @@ -326,7 +366,24 @@ "cannotLoadPdf": "Nem tudom betölteni a PDF-et", "pdfLoadError": "Hiba történt a PDF fájl betöltésekor.", "loadingPdf": "PDF betöltése...", - "loadingPage": "Oldal betöltése..." + "loadingPage": "Oldal betöltése...", + "cancel": "Mégsem", + "copiedItems_one": "Másolt {{count}} elem", + "copiedItems_other": "{{count}} elem másolva", + "deleteCopiedFileFailed": "Nem sikerült törölni a(z) {{name}}másolatát : {{error}}", + "dragMovedItems_one": "Áthelyezve a {{count}} elemet ide: {{target}}", + "dragMovedItems_other": "{{count}} elem áthelyezve ide: {{target}}", + "moveBackFileFailed": "Nem sikerült a {{name}} visszamozgatása: {{error}}", + "terminal": "Terminál: {{host}} ({{path}})", + "dragToDesktop": "A {{name}} húzása az asztalra", + "dragFilesToDesktop": "{{count}} fájlok húzása az asztalra", + "folderDragUnsupported": "A mappák asztalra húzása még nem támogatott.", + "saveToDesktopFailed": "Mentés sikertelen: {{error}}", + "dragFailedDetail": "Húzása sikertelen: {{error}}", + "videoUnsupported": "A böngésződ nem tudja lejátszani ezt a videóformátumot.", + "downloadToPlay": "Töltsd le, hogy máshol is lejátszhasd", + "cannotPreviewType": "Ez a fájltípus nem tekinthető meg előnézetben", + "cannotPreviewTypeHint": "Ennek a fájltípusnak nincs előnézete. Töltse le, hogy egy másik alkalmazásban megnyissa." }, "sftpTransfer": { "title": "SFTP", @@ -374,42 +431,12 @@ }, "hosts": { "fileManager": "Fájlkezelő", - "tabFiles": "Fájlok", - "enableFileManagerMonitor": "Fájlkezelő engedélyezése", - "enableFileManagerMonitorDesc": "Fájlok böngészése és kezelése ezen a gazdagépen SFTP-n keresztül", - "scpLegacyLabel": "SCP örökölt mód", - "scpLegacyDesc": "Használjon hagyományos fájlátvitelt olyan szerverekhez, amelyek nem támogatják az SFTP alrendszert (pl. beágyazott vagy minimális SSH szerverek).", - "defaultPathLabel": "Alapértelmezett elérési út", - "fileManagerPathHint": "A könyvtár, amely megnyílik, amikor a fájlkezelő elindul ehhez a gazdagéphez.", "fileManagerUrlCopied": "Fájlkezelő URL-címe másolva", "copyFileManagerUrlAction": "Fájlkezelő URL-címének másolása", "docsLink": "Dokumentumok megtekintése", "hostNotFound": "Nem található gazdagép", "loadingHost": "Gazdagép betöltése..." }, - "settings": { - "host": { - "enable": { - "label": "Fájlkezelő engedélyezése" - }, - "defaultPath": { - "label": "Alapértelmezett elérési út" - }, - "scpLegacy": { - "label": "SCP örökölt mód" - } - }, - "user": { - "transferConcurrency": { - "label": "Egyidejű fájlátvitel", - "description": "Hány fájlt tölt fel vagy tölt le egyszerre az egymás melletti helyi/távoli kezelő. Csökkentse ezt az értéket, ha a szerver korlátozza az SFTP csatornákat." - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "Fájlok" - }, "onboarding": { "feature_files": "Fájlkezelő", "feature_files_desc": "Böngésszen, töltsön fel, töltsön le és szerkeszthessen fájlokat SFTP-n keresztül az alkalmazás elhagyása nélkül." @@ -437,7 +464,7 @@ "destinationPath": "Célútvonal", "destMustBeDirectory": "Több elem átviteléhez a célnak egy könyvtárnak kell lennie", "goUp": "Felmegy", - "hostAuthRequired": "Hitelesítés szükséges — először nyissa meg a Fájlkezelőt ezen a gépen", + "hostAuthRequired": "Hitelesítés szükséges. Először nyissa meg a Fájlkezelőt ezen a gazdagépen.", "hostConnecting": "… csatlakoztatása", "hostConnectionFailed": "Kapcsolódás sikertelen", "hostDisconnected": "Nincs csatlakoztatva", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "Fájlonkénti SFTP-t választottál.", "user_tar": "A tar archívumot választottad.", - "tar_unavailable": "A Tar nem érhető el az egyik vagy mindkét hoszton – helyette fájlonkénti SFTP-t fog használni.", - "windows_host": "Egy Windows gazdagép érintett – tar-t nem használunk.", - "auto_multi_large": "Automatikus: több fájl, beleértve egy nagy fájlt ({{largestSize}}) tömöríthető adatokkal — a tar egyetlen átvitelbe csomagolja.", - "auto_single_large_in_archive": "Automatikus: egy nagy fájl ({{largestSize}}) ebben a készletben — fájlonként SFTP.", - "auto_many_incompressible": "Automatikus: többnyire tömöríthetetlen adatok — fájlonkénti SFTP.", - "auto_many_files": "Auto: sok fájl ({{fileCount}}) — a tar csökkenti a fájlonkénti terhelést.", + "tar_unavailable": "A Tar nem érhető el az egyik vagy mindkét hoszton, ezért fájlonkénti SFTP-t fogunk használni.", + "windows_host": "Egy Windows gazdagép érintett, így a tar-t nem használjuk.", + "auto_multi_large": "Automatikus: több fájl, beleértve egy nagy fájlt ({{largestSize}}) tömöríthető adatokkal. A Tar egyetlen átvitellé köti őket.", + "auto_single_large_in_archive": "Automatikus: egy nagy fájl ({{largestSize}}) ebben a készletben, tehát fájlonkénti SFTP.", + "auto_many_incompressible": "Automatikus: többnyire tömöríthetetlen adatok, tehát fájlonkénti SFTP.", + "auto_many_files": "Auto: sok fájl ({{fileCount}}), a tar csökkenti a fájlonkénti terhelést.", "auto_default": "Automatikus: fájlonkénti SFTP ehhez a készlethez." }, "methodTar": "Tar archívum", @@ -471,13 +498,13 @@ "metricsCompress": "Tömörítés forráskód szerint: {{duration}}", "metricsExtract": "Kivonat a rendeltetési helyen: {{duration}}", "metricsPrepare": "Célhely előkészítése: {{duration}}", - "metricsRouteBenchmark": "Útvonalszonda — közvetlen: {{direct}}, relé: {{relay}}", + "metricsRouteBenchmark": "Útvonalszonda: direkt {{direct}}, relé {{relay}}", "metricsSourceDelete": "Eltávolítás a forrásból: {{duration}}", "metricsTotal": "Összesen: {{duration}}", "metricsTransfer": "Végtől végig: {{throughput}} ({{duration}})", "metricsVerify": "SHA-256 ellenőrizve: {{duration}}", "moveFolderToHost": "Mappa áthelyezése a… gazdagépre", - "moveItemsToHost": "Áthelyez {{count}} elemet a… tárhelyre", + "moveItemsToHost": "Mozgass {{count}} elemet a… tárhelyre", "moveToHost": "Áthelyezés a… gazdagépre", "noHostsConnected": "Nincsenek más elérhető fájlkezelő gazdagépek.", "noHostsConnectedHint": "Adjon hozzá egy másik SSH-hosztot, amelynél a Fájlkezelő engedélyezve van a Host Managerben.", @@ -508,6 +535,9 @@ "transferError": "Átvitel sikertelen", "transferFailedRetryHint": "Részleges adatok maradtak a célállomáson. Az újrapróbálkozás a kapcsolat helyreállásakor folytatódik.", "transferPartialHint": "Nem sikerült átvinni: {{paths}}", - "transferSuccess": "Átvitel befejezve" + "transferSuccess": "Átvitel befejezve", + "metricsHopSourceRead": "Forrás → szerver: {{throughput}}", + "metricsHopDestSftpWrite": "Szerver → cél (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Szerver → cél (helyi): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/id_ID.json b/plugins/file-manager/locales/translated/id_ID.json index fdb148fc2..9c4c6d35e 100644 --- a/plugins/file-manager/locales/translated/id_ID.json +++ b/plugins/file-manager/locales/translated/id_ID.json @@ -1,513 +1,543 @@ { - "fileManager": { - "noHostSelected": "Tidak ada pembawa acara yang dipilih.", - "initializingEditor": "Menginisialisasi editor...", - "file": "Mengajukan", - "folder": "Map", - "uploadFile": "Unggah File", - "downloadFile": "Unduh", - "extractArchive": "Ekstrak Arsip", - "extractingArchive": "Mengekstrak {{name}}...", - "archiveExtractedSuccessfully": "{{name}} berhasil diekstrak", - "extractFailed": "Ekstraksi gagal", - "compressFile": "Kompres File", - "compressFiles": "Kompres File", - "compressFilesDesc": "Kompres {{count}} item ke dalam arsip", - "archiveName": "Nama Arsip", - "enterArchiveName": "Masukkan nama arsip...", - "compressionFormat": "Format Kompresi", - "selectedFiles": "File terpilih", - "andMoreFiles": "dan {{count}} lainnya...", - "compress": "Kompres", - "compressingFiles": "Mengompres {{count}} item menjadi {{name}}...", - "filesCompressedSuccessfully": "{{name}} berhasil dibuat", - "compressFailed": "Kompresi gagal", - "edit": "Edit", - "preview": "Pratinjau", - "previous": "Sebelumnya", - "next": "Berikutnya", - "pageXOfY": "Halaman {{current}} dari {{total}}", - "zoomOut": "Perkecil tampilan", - "zoomIn": "Perbesar", - "newFile": "Berkas Baru", - "newFolder": "Folder Baru", - "rename": "Ganti nama", - "uploading": "Sedang mengunggah...", - "uploadingFile": "Mengunggah {{name}}...", - "fileName": "Nama File", - "folderName": "Nama Folder", - "fileUploadedSuccessfully": "Berkas \"{{name}}\" berhasil diunggah", - "failedToUploadFile": "Gagal mengunggah file", - "uploadingFolderFiles": "Mengunggah {{count}} berkas...", - "uploadedFolderFiles": "Berhasil mengunggah {{count}} berkas", - "uploadedFolderPartial": "Pengunggahan {{uploaded}} berkas, {{failed}} gagal", - "fileDownloadedSuccessfully": "File \"{{name}}\" berhasil diunduh", - "failedToDownloadFile": "Gagal mengunduh file", - "fileCreatedSuccessfully": "File \"{{name}}\" berhasil dibuat", - "folderCreatedSuccessfully": "Folder \"{{name}}\" berhasil dibuat", - "failedToCreateItem": "Gagal membuat item", - "operationFailed": "Operasi {{operation}} gagal untuk {{name}}: {{error}}", - "failedToResolveSymlink": "Gagal menyelesaikan symlink", - "itemsDeletedSuccessfully": "{{count}} item berhasil dihapus", - "failedToDeleteItems": "Gagal menghapus item", - "sudoPasswordRequired": "Kata Sandi Administrator Diperlukan", - "enterSudoPassword": "Masukkan kata sandi sudo untuk melanjutkan operasi ini.", - "sudoPassword": "Kata sandi Sudo", - "sudoOperationFailed": "Operasi Sudo gagal", - "sudoAuthFailed": "Autentikasi Sudo gagal", - "dragFilesToUpload": "Seret file ke sini untuk mengunggah", - "dropToUploadHere": "Unggah di sini", - "dropToDownloadHere": "Klik di sini untuk mengunduh.", - "localFiles": "Lokal", - "showLocalFiles": "Tampilkan file lokal (tampilan terpisah)", - "hideLocalFiles": "Sembunyikan file lokal", - "localHome": "Folder beranda", - "localPathPlaceholder": "Jalur folder lokal", - "localShowHidden": "Tampilkan file tersembunyi", - "localHideHidden": "Sembunyikan file tersembunyi", - "localRevealInFileManager": "Ungkapkan di pengelola file sistem", - "localCannotOpenFolder": "Tidak dapat membuka folder", - "localItemCount": "{{count}} item", - "localSelectedCount": "{{count}} terpilih", - "back": "Kembali", - "forward": "Maju", - "up": "Ke atas", - "kind": "Baik", - "localUploadingProgress": "Mengunggah {{current}} dari {{total}}", - "localDownloadingProgress": "Mengunduh {{current}} dari {{total}}", - "localTransferInFlight": "{{count}} sekaligus", - "localPreparingDownload": "Mempersiapkan pengunduhan...", - "localTransferCancelled": "Transfer dibatalkan", - "localNothingToTransfer": "Tidak ada yang perlu ditransfer", - "localUploadComplete": "Berkas {{count}} telah diunggah", - "localUploadFailed": "Unggahan gagal", - "localUploadPartial": "Pengunggahan {{done}} berkas, {{failed}} gagal", - "localDownloadComplete": "Berkas {{count}} telah diunduh", - "localDownloadFailed": "Pengunduhan gagal", - "localDownloadPartial": "Pengunduhan {{done}} berkas, {{failed}} gagal", - "localReplaceExistingPrompt": "{{count}} item sudah ada di folder ini. Ganti item tersebut?", - "localReplace": "Mengganti", - "localSkipExisting": "Melewati", - "localSkippedExisting": "Melewati {{count}} item yang sudah ada", - "localUnsafeNamesSkipped": "Melewati {{count}} item karena namanya tidak dapat digunakan di komputer ini", - "localOpen": "Membuka", - "localOpenFolder": "Buka folder", - "localUploadToRemote": "Unggah ke server", - "localUploadToRemoteMany": "Unggah {{count}} item ke server", - "localMoveToTrash": "Pindahkan ke Tempat Sampah", - "localMoveToTrashMany": "Pindahkan {{count}} item ke Sampah", - "localTrashConfirmSingle": "Pindahkan \"{{name}}\" ke Sampah?", - "localTrashConfirmFolder": "Pindahkan folder \"{{name}}\" beserta seluruh isinya ke Sampah?", - "localTrashConfirmMany": "Pindahkan {{count}} item ke Sampah?", - "localTrashed": "Memindahkan {{count}} item ke Sampah", - "localTrashFailed": "Tidak bisa dipindahkan ke tempat sampah", - "localRenameFailed": "Penggantian nama gagal", - "localCreateFailed": "Tidak dapat membuat item", - "goToParentFolder": "Buka folder induk", - "resizeSidebar": "Seret untuk mengubah ukuran bilah sisi (klik dua kali untuk mengatur ulang)", - "resizeLocalPane": "Seret untuk mengubah ukuran panel lokal (klik dua kali untuk mengatur ulang)", - "columns": "Kolom", - "columnsHint": "Klik kanan untuk memilih kolom", - "emptyFolder": "Folder ini kosong", - "searchFiles": "Cari file...", - "upload": "Mengunggah", - "selectHostToStart": "Pilih host untuk memulai manajemen file.", - "sshRequiredForFileManager": "Pengelola file memerlukan SSH. Host ini tidak mengaktifkan SSH.", - "failedToConnect": "Gagal terhubung ke SSH", - "failedToLoadDirectory": "Gagal memuat direktori", - "noSSHConnection": "Tidak ada koneksi SSH yang tersedia.", - "copy": "Menyalin", - "cut": "Memotong", - "paste": "Pasta", - "copyPath": "Salin Jalur", - "copyPaths": "Salin Jalur", - "delete": "Menghapus", - "properties": "Properti", - "refresh": "Menyegarkan", - "downloadFiles": "Unduh {{count}} file ke Browser", - "copyFiles": "Salin {{count}} item", - "cutFiles": "Potong {{count}} item", - "deleteFiles": "Hapus {{count}} item", - "filesCopiedToClipboard": "{{count}} item disalin ke papan klip", - "filesCutToClipboard": "{{count}} item dipotong ke papan klip", - "pathCopiedToClipboard": "Jalur disalin ke papan klip", - "pathsCopiedToClipboard": "{{count}} jalur disalin ke papan klip", - "failedToCopyPath": "Gagal menyalin jalur ke papan klip.", - "copyFolderLink": "Salin Tautan ke Folder", - "copyCurrentFolderLink": "Salin Tautan ke Folder Saat Ini", - "folderLinkCopied": "Tautan folder disalin ke papan klip", - "failedToCopyFolderLink": "Gagal menyalin tautan folder", - "movedItems": "Memindahkan {{count}} item", - "failedToDeleteItem": "Gagal menghapus item", - "itemRenamedSuccessfully": "{{type}} berhasil diganti namanya", - "failedToRenameItem": "Gagal mengganti nama item", - "download": "Unduh", - "openExternalEditor": "Buka secara eksternal", - "chooseExternalEditor": "Pilih editor eksternal", - "externalEditorSelected": "Editor eksternal terpilih", - "externalEditorDesktopOnly": "Editor eksternal hanya tersedia di aplikasi desktop.", - "externalEditorOpened": "Dibuka di editor eksternal. Menyimpan di sana akan mengunggah perubahan kembali ke server.", - "failedToOpenExternalEditor": "Gagal membuka editor eksternal", - "failedToSelectExternalEditor": "Gagal memilih editor eksternal", - "permissions": "Izin", - "size": "Ukuran", - "modified": "Dimodifikasi", - "path": "Jalur", - "confirmDelete": "Apakah Anda yakin ingin menghapus {{name}}?", - "permissionDenied": "Izin ditolak", - "serverError": "Kesalahan Server", - "fileSavedSuccessfully": "Berkas berhasil disimpan.", - "failedToSaveFile": "Gagal menyimpan file", - "confirmDeleteSingleItem": "Apakah Anda yakin ingin menghapus \"{{name}} \" secara permanen?", - "confirmDeleteMultipleItems": "Apakah Anda yakin ingin menghapus {{count}} item secara permanen?", - "confirmDeleteMultipleItemsWithFolders": "Apakah Anda yakin ingin menghapus {{count}} item secara permanen? Ini termasuk folder dan isinya.", - "confirmDeleteFolder": "Apakah Anda yakin ingin menghapus folder \"{{name}}\" beserta seluruh isinya secara permanen?", - "permanentDeleteWarning": "Tindakan ini tidak dapat dibatalkan. Item tersebut akan dihapus secara permanen dari server.", - "moveToTrashWarning": "Item tersebut akan dipindahkan ke Tempat Sampah Termix dan dapat dipulihkan sebelum masa penyimpanan berakhir.", - "itemsMovedToTrash": "{{count}} item dipindahkan ke Sampah", - "trash": "Sampah", - "trashDescription": "Item yang dihapus akan tetap tersimpan selama {{days}} hari di host ini.", - "trashLoadFailed": "Sampah gagal dimuat", - "trashEmpty": "Tempat sampah sudah kosong", - "trashRestore": "Memulihkan", - "trashRestored": "Dipulihkan {{name}}", - "trashRestoreFailed": "Gagal memulihkan item. Jalur asli mungkin sudah ada.", - "trashDeletePermanently": "Hapus secara permanen", - "trashDeleteConfirm": "Hapus secara permanen {{name}}? Tindakan ini tidak dapat dibatalkan.", - "trashPermanentlyDeleted": "Dihapus secara permanen {{name}}", - "trashDeleteFailed": "Gagal menghapus item secara permanen.", - "trashEmptyAction": "Kosongkan Tempat Sampah", - "trashEmptyConfirm": "Menghapus semua item di Sampah secara permanen? Tindakan ini tidak dapat dibatalkan.", - "trashEmptied": "Sampah dikosongkan", - "trashRetention": "Pembersihan otomatis setelah (hari)", - "trashRetentionSaved": "Pembaruan tentang retensi sampah", - "trashRetentionFailed": "Gagal memperbarui pengaturan penyimpanan sampah.", - "trashUnavailableConfirm": "Item ini tidak dapat dipindahkan ke Sampah, biasanya karena berada di sistem file lain atau memerlukan hak akses administrator. Hapus saja secara permanen?", - "recent": "Terkini", - "pinned": "Disematkan", - "folderShortcuts": "Pintasan Folder", - "failedToReconnectSSH": "Gagal menyambungkan kembali sesi SSH", - "openTerminalHere": "Buka Terminal di Sini", - "run": "Berlari", - "openTerminalInFolder": "Buka Terminal di Folder Ini", - "openTerminalInFileLocation": "Buka Terminal di Lokasi File", - "runningFile": "Berlari - {{file}}", - "onlyRunExecutableFiles": "Hanya dapat menjalankan file yang dapat dieksekusi.", - "directories": "Direktori", - "removedFromRecentFiles": "Menghapus \"{{name}}\" dari file terbaru", - "removeFailed": "Hapus yang gagal", - "unpinnedSuccessfully": "Pin \"{{name}}\" berhasil dilepas", - "unpinFailed": "Gagal membuka pin", - "removedShortcut": "Pintasan \"{{name}} \" telah dihapus", - "removeShortcutFailed": "Penghapusan pintasan gagal.", - "clearedAllRecentFiles": "Semua file terbaru telah dihapus.", - "clearFailed": "Hapus gagal", - "removeFromRecentFiles": "Hapus dari berkas terbaru", - "clearAllRecentFiles": "Hapus semua file terbaru", - "unpinFile": "Lepaskan pin file", - "removeShortcut": "Hapus pintasan", - "pinFile": "Pin file", - "addToShortcuts": "Tambahkan ke pintasan", - "pasteFailed": "Pasta gagal", - "noUndoableActions": "Tidak ada tindakan yang tidak dapat dibatalkan.", - "undoCopySuccess": "Batalkan operasi penyalinan: Menghapus {{count}} file yang disalin", - "undoCopyFailedDelete": "Pembatalan gagal: Tidak dapat menghapus file yang disalin.", - "undoCopyFailedNoInfo": "Pembatalan gagal: Informasi file yang disalin tidak ditemukan.", - "undoMoveSuccess": "Operasi pemindahan dibatalkan: {{count}} berkas dipindahkan kembali ke lokasi semula", - "undoMoveFailedMove": "Pembatalan gagal: Tidak dapat memindahkan file apa pun kembali.", - "undoMoveFailedNoInfo": "Pembatalan gagal: Informasi file yang dipindahkan tidak ditemukan.", - "undoDeleteNotSupported": "Operasi penghapusan tidak dapat dibatalkan: File telah dihapus secara permanen dari server.", - "undoTypeNotSupported": "Jenis operasi undo yang tidak didukung", - "undoOperationFailed": "Operasi pembatalan gagal", - "unknownError": "Kesalahan tidak dikenal", - "confirm": "Mengonfirmasi", - "find": "Menemukan...", - "replace": "Mengganti", - "downloadInstead": "Unduh sebagai gantinya", - "keyboardShortcuts": "Pintasan Keyboard", - "searchAndReplace": "Cari & Ganti", - "editing": "Pengeditan", - "search": "Mencari", - "findNext": "Temukan Selanjutnya", - "findPrevious": "Temukan Sebelumnya", - "save": "Menyimpan", - "selectAll": "Pilih Semua", - "undo": "Membuka", - "redo": "Mengulangi", - "moveLineUp": "Susunan Langkah", - "moveLineDown": "Geser Garis ke Bawah", - "toggleComment": "Alihkan Komentar", - "autoComplete": "Pelengkapan Otomatis", - "imageLoadError": "Gambar gagal dimuat", - "startTyping": "Mulai mengetik...", - "unknownSize": "Ukuran tidak diketahui", - "fileIsEmpty": "Berkas kosong", - "largeFileWarning": "Peringatan Ukuran File Besar", - "largeFileWarningDesc": "File ini berukuran {{size}} , yang dapat menyebabkan masalah kinerja saat dibuka sebagai teks.", - "fileNotFoundAndRemoved": "Berkas \"{{name}}\" tidak ditemukan dan telah dihapus dari berkas terbaru/yang disematkan", - "failedToLoadFile": "Gagal memuat file: {{error}}", - "serverErrorOccurred": "Terjadi kesalahan server. Silakan coba lagi nanti.", - "autoSaveFailed": "Penyimpanan otomatis gagal", - "fileAutoSaved": "Berkas tersimpan otomatis", - "moveFileFailed": "Gagal memindahkan {{name}}", - "moveOperationFailed": "Operasi pemindahan gagal", - "canOnlyCompareFiles": "Hanya dapat membandingkan dua file.", - "comparingFiles": "Membandingkan berkas: {{file1}} dan {{file2}}", - "dragFailed": "Operasi seret gagal", - "filePinnedSuccessfully": "Berkas \"{{name}}\" berhasil disematkan", - "pinFileFailed": "Gagal menyematkan file", - "fileUnpinnedSuccessfully": "Berkas \"{{name}}\" berhasil dilepas dari pin", - "unpinFileFailed": "Gagal melepaskan pin file", - "shortcutAddedSuccessfully": "Pintasan folder \"{{name}}\" berhasil ditambahkan", - "addShortcutFailed": "Gagal menambahkan pintasan", - "operationCompletedSuccessfully": "{{operation}} {{count}} item berhasil", - "operationCompleted": "{{operation}} {{count}} item", - "downloadFileSuccess": "File {{name}} berhasil diunduh", - "downloadFileFailed": "Pengunduhan gagal", - "downloadingFile": "Mengunduh {{name}}…", - "downloadProgressBytes": "{{transferred}} / {{total}}", - "moveTo": "Pindah ke {{name}}", - "diffCompareWith": "Bandingkan perbedaan dengan {{name}}", - "dragOutsideToDownload": "Seret ke luar jendela untuk mengunduh ({{count}} file)", - "newFolderDefault": "Folder Baru", - "newFileDefault": "File Baru.txt", - "successfullyMovedItems": "Berhasil memindahkan {{count}} item ke {{target}}", - "move": "Bergerak", - "searchInFile": "Cari di dalam file (Ctrl+F)", - "showKeyboardShortcuts": "Tampilkan pintasan keyboard", - "decreaseFontSize": "Kurangi ukuran font", - "increaseFontSize": "Perbesar ukuran font", - "startWritingMarkdown": "Mulailah menulis konten markdown Anda...", - "loadingFileComparison": "Sedang memuat perbandingan file...", - "reload": "Muat ulang", - "compare": "Membandingkan", - "sideBySide": "Berdampingan", - "inline": "Sejajar", - "fileComparison": "Perbandingan File: {{file1}} vs {{file2}}", - "fileTooLarge": "Ukuran file terlalu besar: {{error}}", - "sshConnectionFailed": "Koneksi SSH gagal. Harap periksa koneksi Anda ke {{name}} ({{ip}}:{{port}})", - "loadFileFailed": "Gagal memuat file: {{error}}", - "connecting": "Menghubungkan...", - "connectedSuccessfully": "Terhubung berhasil", - "totpVerificationFailed": "Verifikasi TOTP gagal", - "authenticationFailed": "Autentikasi gagal", - "incorrectPassphrase": "Kata sandi salah. Silakan coba lagi.", - "verificationCodePrompt": "Kode verifikasi:", - "changePermissions": "Ubah Izin", - "currentPermissions": "Izin Saat Ini", - "owner": "Pemilik", - "group": "Kelompok", - "others": "Yang lain", - "read": "Membaca", - "write": "Menulis", - "execute": "Menjalankan", - "permissionsChangedSuccessfully": "Izin berhasil diubah.", - "failedToChangePermissions": "Gagal mengubah izin.", - "name": "Nama", - "sortByName": "Nama", - "sortByDate": "Tanggal Diubah", - "sortBySize": "Ukuran", - "ascending": "Naik", - "descending": "Menurun", - "root": "Akar", - "new": "Baru", - "sortBy": "Urutkan Berdasarkan", - "items": "Barang-barang", - "selected": "Terpilih", - "editor": "Editor", - "octal": "Oktal", - "storage": "Penyimpanan", - "disk": "Disk", - "used": "Digunakan", - "of": "dari", - "toggleSidebar": "Alihkan Sidebar", - "compactLayout": "Gunakan tata letak yang ringkas.", - "comfortableLayout": "Gunakan tata letak yang nyaman.", - "cannotLoadPdf": "Tidak dapat memuat PDF", - "pdfLoadError": "Terjadi kesalahan saat memuat file PDF ini.", - "loadingPdf": "Sedang memuat PDF...", - "loadingPage": "Sedang memuat halaman..." + "nav": { + "files": "Files", + "sftp": "SFTP", + "openFileManager": "Open File Manager" }, - "sftpTransfer": { - "title": "SFTP", - "description": "Mentransfer file antara dua host SSH.", - "sourceServer": "Server Sumber", - "destinationServer": "Server Tujuan", - "selectHost": "Pilih tuan rumah", - "noHostSelected": "Tidak ada pembawa acara yang dipilih.", - "move": "Bergerak", - "copy": "Menyalin", - "upload": "Mengunggah", - "itemsSelected": "{{count}} item dipilih", - "itemsSelected_other": "{{count}} item terpilih", - "ready": "Siap", - "loadingHosts": "Memuat host...", - "name": "Nama", - "modified": "Dimodifikasi", - "size": "Ukuran", - "noFiles": "Tidak ada berkas", - "open": "Membuka", - "up": "Ke atas", - "refresh": "Menyegarkan", - "copyToTarget": "Salin ke Direktori Target", - "rename": "Ganti nama", - "delete": "Menghapus", - "editPermissions": "Edit Izin", - "createNewFolder": "Buat Folder Baru", - "deleteSelectedItems": "Hapus Item yang Dipilih", - "deleteConfirm": "Hapus {{count}} item yang dipilih?", - "deleteConfirm_other": "Hapus {{count}} item yang dipilih?", - "cancel": "Membatalkan", - "save": "Menyimpan", - "folderCreated": "Folder telah dibuat.", - "itemRenamed": "Item diganti namanya", - "actionFailed": "Tindakan gagal", - "itemsDeleted": "{{count}} item dihapus", - "itemsDeleted_other": "{{count}} item dihapus", - "deleteFailed": "Penghapusan gagal", - "permissionsUpdated": "Izin telah diperbarui.", - "noRemoteSessionConnected": "Tidak ada sesi jarak jauh yang terhubung.", - "failedToListFiles": "Gagal menampilkan daftar file.", - "failedToRefresh": "Gagal memperbarui", - "destinationInsideSource": "Tujuan tidak boleh berada di dalam jalur sumber yang dipilih.", - "sameHostNoOp": "Sumber dan tujuan berada di folder yang sama." - }, - "hosts": { - "fileManager": "Pengelola File", - "tabFiles": "Berkas", - "enableFileManagerMonitor": "Aktifkan Pengelola File", - "enableFileManagerMonitorDesc": "Jelajahi dan kelola file di host ini melalui SFTP.", - "scpLegacyLabel": "Mode Warisan SCP", - "scpLegacyDesc": "Gunakan transfer file lama untuk server yang tidak mendukung subsistem SFTP (misalnya server SSH terintegrasi atau minimal).", - "defaultPathLabel": "Jalur Default", - "fileManagerPathHint": "Direktori yang akan dibuka saat pengelola file diluncurkan untuk host ini.", - "fileManagerUrlCopied": "URL Pengelola File disalin", - "copyFileManagerUrlAction": "Salin URL Pengelola File", - "docsLink": "Lihat dokumen", - "hostNotFound": "Host tidak ditemukan", - "loadingHost": "Memuat host..." + "permissions": { + "use": { + "title": "Use file manager", + "description": "Browse, edit and transfer files over SFTP." + } }, "settings": { "host": { "enable": { - "label": "Aktifkan Pengelola File" + "label": "Enable File Manager", + "description": "Browse and edit files on this host over SFTP." }, "defaultPath": { - "label": "Jalur Default" + "label": "Default Path" }, "scpLegacy": { - "label": "Mode Warisan SCP" + "label": "SCP Legacy Mode" } }, "user": { "transferConcurrency": { - "label": "Transfer File Serentak", - "description": "Jumlah file yang diunggah atau diunduh oleh pengelola file lokal/jarak jauh secara bersamaan. Kurangi nilai ini jika server Anda membatasi saluran SFTP." + "label": "Simultaneous File Transfers", + "description": "How many files the side by side local/remote manager uploads or downloads at the same time. Lower this if your server limits SFTP channels." + }, + "confirmBeforeTrash": { + "label": "Confirm before moving files to trash", + "description": "Ask before moving remote files to trash. Permanent deletion still requires confirmation." } } }, - "nav": { - "sftp": "SFTP", - "files": "Berkas" + "hostCapability": { + "label": "File Manager" + }, + "fileManager": { + "noHostSelected": "No host selected", + "initializingEditor": "Initializing editor...", + "file": "File", + "folder": "Folder", + "uploadFile": "Upload File", + "downloadFile": "Download", + "extractArchive": "Extract Archive", + "extractingArchive": "Extracting {{name}}...", + "archiveExtractedSuccessfully": "{{name}} extracted successfully", + "extractFailed": "Extract failed", + "compressFile": "Compress File", + "compressFiles": "Compress Files", + "compressFilesDesc": "Compress {{count}} items into an archive", + "archiveName": "Archive Name", + "enterArchiveName": "Enter archive name...", + "compressionFormat": "Compression Format", + "selectedFiles": "Selected files", + "andMoreFiles": "and {{count}} more...", + "compress": "Compress", + "compressingFiles": "Compressing {{count}} items into {{name}}...", + "filesCompressedSuccessfully": "{{name}} created successfully", + "compressFailed": "Compression failed", + "edit": "Edit", + "preview": "Preview", + "previous": "Previous", + "next": "Next", + "pageXOfY": "Page {{current}} of {{total}}", + "zoomOut": "Zoom Out", + "zoomIn": "Zoom In", + "newFile": "New File", + "newFolder": "New Folder", + "rename": "Rename", + "uploading": "Uploading...", + "uploadingFile": "Uploading {{name}}...", + "uploadingChunk": "Uploading {{name}}: {{percent}}% (part {{chunk}} of {{total}})", + "fileName": "File Name", + "folderName": "Folder Name", + "fileUploadedSuccessfully": "File \"{{name}}\" uploaded successfully", + "failedToUploadFile": "Failed to upload file", + "uploadingFolderFiles": "Uploading {{count}} file(s)...", + "uploadedFolderFiles": "Uploaded {{count}} file(s) successfully", + "uploadedFolderPartial": "Uploaded {{uploaded}} file(s), {{failed}} failed", + "fileDownloadedSuccessfully": "File \"{{name}}\" downloaded successfully", + "failedToDownloadFile": "Failed to download file", + "fileCreatedSuccessfully": "File \"{{name}}\" created successfully", + "folderCreatedSuccessfully": "Folder \"{{name}}\" created successfully", + "failedToCreateItem": "Failed to create item", + "operationFailed": "{{operation}} operation failed for {{name}}: {{error}}", + "failedToResolveSymlink": "Failed to resolve symlink", + "itemsDeletedSuccessfully": "{{count}} items deleted successfully", + "failedToDeleteItems": "Failed to delete items", + "sudoPasswordRequired": "Administrator Password Required", + "enterSudoPassword": "Enter sudo password to continue this operation", + "sudoPassword": "Sudo password", + "sudoOperationFailed": "Sudo operation failed", + "sudoAuthFailed": "Sudo authentication failed", + "dragFilesToUpload": "Drop files here to upload", + "dropToUploadHere": "Drop to upload here", + "dropToDownloadHere": "Drop to download here", + "localFiles": "Local", + "showLocalFiles": "Show local files (split view)", + "hideLocalFiles": "Hide local files", + "localHome": "Home folder", + "localPathPlaceholder": "Local folder path", + "localShowHidden": "Show hidden files", + "localHideHidden": "Hide hidden files", + "localRevealInFileManager": "Reveal in system file manager", + "localCannotOpenFolder": "Cannot open folder", + "localItemCount": "{{count}} items", + "localSelectedCount": "{{count}} selected", + "back": "Back", + "forward": "Forward", + "up": "Up", + "kind": "Kind", + "localUploadingProgress": "Uploading {{current}} of {{total}}", + "localDownloadingProgress": "Downloading {{current}} of {{total}}", + "localTransferInFlight": "{{count}} at once", + "localPreparingDownload": "Preparing download...", + "localTransferCancelled": "Transfer cancelled", + "localNothingToTransfer": "Nothing to transfer", + "localUploadComplete": "Uploaded {{count}} file(s)", + "localUploadFailed": "Upload failed", + "localUploadPartial": "Uploaded {{done}} file(s), {{failed}} failed", + "localDownloadComplete": "Downloaded {{count}} file(s)", + "localDownloadFailed": "Download failed", + "localDownloadPartial": "Downloaded {{done}} file(s), {{failed}} failed", + "localReplaceExistingPrompt": "{{count}} item(s) already exist in this folder. Replace them?", + "localReplace": "Replace", + "localSkipExisting": "Skip", + "localSkippedExisting": "Skipped {{count}} existing item(s)", + "localUnsafeNamesSkipped": "Skipped {{count}} item(s) whose names cannot be used on this computer", + "localOpen": "Open", + "localOpenFolder": "Open folder", + "localUploadToRemote": "Upload to server", + "localUploadToRemoteMany": "Upload {{count}} items to server", + "localMoveToTrash": "Move to Trash", + "localMoveToTrashMany": "Move {{count}} items to Trash", + "localTrashConfirmSingle": "Move \"{{name}}\" to the Trash?", + "localTrashConfirmFolder": "Move the folder \"{{name}}\" and all its contents to the Trash?", + "localTrashConfirmMany": "Move {{count}} items to the Trash?", + "localTrashed": "Moved {{count}} item(s) to the Trash", + "localTrashFailed": "Could not move to the Trash", + "localRenameFailed": "Rename failed", + "localCreateFailed": "Could not create item", + "goToParentFolder": "Go to parent folder", + "resizeSidebar": "Drag to resize the sidebar (double-click to reset)", + "resizeLocalPane": "Drag to resize the local pane (double-click to reset)", + "columns": "Columns", + "columnsHint": "Right-click to choose columns", + "emptyFolder": "This folder is empty", + "searchFiles": "Search files...", + "upload": "Upload", + "selectHostToStart": "Select a host to start file management", + "sshRequiredForFileManager": "File manager requires SSH. This host does not have SSH enabled.", + "failedToConnect": "Failed to connect to SSH", + "failedToLoadDirectory": "Failed to load directory", + "noSSHConnection": "No SSH connection available", + "copy": "Copy", + "cut": "Cut", + "paste": "Paste", + "copyPath": "Copy Path", + "copyPaths": "Copy Paths", + "delete": "Delete", + "properties": "Properties", + "refresh": "Refresh", + "downloadFiles": "Download {{count}} files to Browser", + "copyFiles": "Copy {{count}} items", + "cutFiles": "Cut {{count}} items", + "deleteFiles": "Delete {{count}} items", + "filesCopiedToClipboard": "{{count}} items copied to clipboard", + "filesCutToClipboard": "{{count}} items cut to clipboard", + "pathCopiedToClipboard": "Path copied to clipboard", + "pathsCopiedToClipboard": "{{count}} paths copied to clipboard", + "failedToCopyPath": "Failed to copy path to clipboard", + "copyFolderLink": "Copy Link to Folder", + "copyCurrentFolderLink": "Copy Link to Current Folder", + "folderLinkCopied": "Folder link copied to clipboard", + "failedToCopyFolderLink": "Failed to copy folder link", + "movedItems": "Moved {{count}} items", + "failedToDeleteItem": "Failed to delete item", + "itemRenamedSuccessfully": "{{type}} renamed successfully", + "failedToRenameItem": "Failed to rename item", + "download": "Download", + "openExternalEditor": "Open externally", + "chooseExternalEditor": "Choose external editor", + "externalEditorSelected": "External editor selected", + "externalEditorDesktopOnly": "External editor is only available in the desktop app", + "externalEditorOpened": "Opened in external editor. Saving there will upload changes back to the server.", + "failedToOpenExternalEditor": "Failed to open external editor", + "failedToSelectExternalEditor": "Failed to select external editor", + "permissions": "Permissions", + "size": "Size", + "modified": "Modified", + "path": "Path", + "confirmDelete": "Are you sure you want to delete {{name}}?", + "permissionDenied": "Permission denied", + "serverError": "Server Error", + "fileSavedSuccessfully": "File saved successfully", + "failedToSaveFile": "Failed to save file", + "confirmDeleteSingleItem": "Are you sure you want to permanently delete \"{{name}}\"?", + "confirmDeleteMultipleItems": "Are you sure you want to permanently delete {{count}} items?", + "confirmDeleteMultipleItemsWithFolders": "Are you sure you want to permanently delete {{count}} items? This includes folders and their contents.", + "confirmDeleteFolder": "Are you sure you want to permanently delete the folder \"{{name}}\" and all its contents?", + "permanentDeleteWarning": "This action cannot be undone. The item(s) will be permanently deleted from the server.", + "moveToTrashWarning": "The item(s) will be moved to the Termix Trash and can be restored before the retention period expires.", + "itemsMovedToTrash": "{{count}} item(s) moved to Trash", + "trash": "Trash", + "trashDescription": "Deleted items are retained for {{days}} day(s) on this host.", + "trashLoadFailed": "Failed to load Trash", + "trashEmpty": "Trash is empty", + "trashRestore": "Restore", + "trashRestored": "Restored {{name}}", + "trashRestoreFailed": "Failed to restore item. The original path may already exist.", + "trashDeletePermanently": "Delete permanently", + "trashDeleteConfirm": "Permanently delete {{name}}? This cannot be undone.", + "trashPermanentlyDeleted": "Permanently deleted {{name}}", + "trashDeleteFailed": "Failed to permanently delete item", + "trashEmptyAction": "Empty Trash", + "trashEmptyConfirm": "Permanently delete every item in Trash? This cannot be undone.", + "trashEmptied": "Trash emptied", + "trashRetention": "Automatic cleanup after (days)", + "trashRetentionSaved": "Trash retention updated", + "trashRetentionFailed": "Failed to update Trash retention", + "trashUnavailableConfirm": "This item cannot be moved to Trash, usually because it is on another filesystem or requires elevated permissions. Delete it permanently instead?", + "recent": "Recent", + "pinned": "Pinned", + "folderShortcuts": "Folder Shortcuts", + "failedToReconnectSSH": "Failed to reconnect SSH session", + "openTerminalHere": "Open Terminal Here", + "run": "Run", + "openTerminalInFolder": "Open Terminal in This Folder", + "openTerminalInFileLocation": "Open Terminal at File Location", + "runningFile": "Running - {{file}}", + "onlyRunExecutableFiles": "Can only run executable files", + "directories": "Directories", + "removedFromRecentFiles": "Removed \"{{name}}\" from recent files", + "removeFailed": "Remove failed", + "unpinnedSuccessfully": "Unpinned \"{{name}}\" successfully", + "unpinFailed": "Unpin failed", + "removedShortcut": "Removed shortcut \"{{name}}\"", + "removeShortcutFailed": "Remove shortcut failed", + "clearedAllRecentFiles": "Cleared all recent files", + "clearFailed": "Clear failed", + "removeFromRecentFiles": "Remove from recent files", + "clearAllRecentFiles": "Clear all recent files", + "unpinFile": "Unpin file", + "removeShortcut": "Remove shortcut", + "pinFile": "Pin file", + "addToShortcuts": "Add to shortcuts", + "pasteFailed": "Paste failed", + "noUndoableActions": "No undoable actions", + "undoCopySuccess": "Undid copy operation: Deleted {{count}} copied files", + "undoCopyFailedDelete": "Undo failed: Could not delete any copied files", + "undoCopyFailedNoInfo": "Undo failed: Could not find copied file information", + "undoMoveSuccess": "Undid move operation: Moved {{count}} files back to original location", + "undoMoveFailedMove": "Undo failed: Could not move any files back", + "undoMoveFailedNoInfo": "Undo failed: Could not find moved file information", + "undoDeleteNotSupported": "Delete operation cannot be undone: Files have been permanently deleted from server", + "undoTypeNotSupported": "Unsupported undo operation type", + "undoOperationFailed": "Undo operation failed", + "unknownError": "Unknown error", + "confirm": "Confirm", + "find": "Find...", + "replace": "Replace", + "downloadInstead": "Download Instead", + "keyboardShortcuts": "Keyboard Shortcuts", + "searchAndReplace": "Search & Replace", + "editing": "Editing", + "search": "Search", + "findNext": "Find Next", + "findPrevious": "Find Previous", + "save": "Save", + "selectAll": "Select All", + "undo": "Undo", + "redo": "Redo", + "moveLineUp": "Move Line Up", + "moveLineDown": "Move Line Down", + "toggleComment": "Toggle Comment", + "autoComplete": "Auto Complete", + "imageLoadError": "Failed to load image", + "startTyping": "Start typing...", + "unknownSize": "Unknown size", + "fileIsEmpty": "File is empty", + "largeFileWarning": "Large File Warning", + "largeFileWarningDesc": "This file is {{size}} in size, which may cause performance issues when opened as text.", + "fileNotFoundAndRemoved": "File \"{{name}}\" not found and has been removed from recent/pinned files", + "failedToLoadFile": "Failed to load file: {{error}}", + "serverErrorOccurred": "Server error occurred. Please try again later.", + "autoSaveFailed": "Auto-save failed", + "fileAutoSaved": "File auto-saved", + "moveFileFailed": "Failed to move {{name}}", + "moveOperationFailed": "Move operation failed", + "canOnlyCompareFiles": "Can only compare two files", + "comparingFiles": "Comparing files: {{file1}} and {{file2}}", + "dragFailed": "Drag operation failed", + "filePinnedSuccessfully": "File \"{{name}}\" pinned successfully", + "pinFileFailed": "Failed to pin file", + "fileUnpinnedSuccessfully": "File \"{{name}}\" unpinned successfully", + "unpinFileFailed": "Failed to unpin file", + "shortcutAddedSuccessfully": "Folder shortcut \"{{name}}\" added successfully", + "addShortcutFailed": "Failed to add shortcut", + "operationCompletedSuccessfully": "{{operation}} {{count}} items successfully", + "operationCompleted": "{{operation}} {{count}} items", + "downloadFileSuccess": "File {{name}} downloaded successfully", + "downloadFileFailed": "Download failed", + "downloadingFile": "Downloading {{name}}…", + "downloadProgressBytes": "{{transferred}} / {{total}}", + "moveTo": "Move to {{name}}", + "diffCompareWith": "Diff compare with {{name}}", + "dragOutsideToDownload": "Drag outside window to download ({{count}} files)", + "newFolderDefault": "NewFolder", + "newFileDefault": "NewFile.txt", + "successfullyMovedItems": "Successfully moved {{count}} items to {{target}}", + "move": "Move", + "searchInFile": "Search in file (Ctrl+F)", + "showKeyboardShortcuts": "Show keyboard shortcuts", + "decreaseFontSize": "Decrease font size", + "increaseFontSize": "Increase font size", + "startWritingMarkdown": "Start writing your markdown content...", + "loadingFileComparison": "Loading file comparison...", + "reload": "Muat Ulang", + "compare": "Compare", + "sideBySide": "Side by Side", + "inline": "Inline", + "fileComparison": "File Comparison: {{file1}} vs {{file2}}", + "fileTooLarge": "File too large: {{error}}", + "sshConnectionFailed": "SSH connection failed. Please check your connection to {{name}} ({{ip}}:{{port}})", + "loadFileFailed": "Failed to load file: {{error}}", + "connecting": "Connecting...", + "connectedSuccessfully": "Connected successfully", + "totpVerificationFailed": "TOTP verification failed", + "browserSignInFailed": "Sign-in failed. Please try again.", + "authenticationFailed": "Authentication failed", + "incorrectPassphrase": "Incorrect passphrase. Please try again.", + "verificationCodePrompt": "Verification code:", + "changePermissions": "Change Permissions", + "currentPermissions": "Current Permissions", + "owner": "Owner", + "group": "Group", + "others": "Others", + "read": "Read", + "write": "Write", + "execute": "Execute", + "permissionsChangedSuccessfully": "Permissions changed successfully", + "failedToChangePermissions": "Failed to change permissions", + "name": "Name", + "sortByName": "Name", + "sortByDate": "Date Modified", + "sortBySize": "Size", + "ascending": "Ascending", + "descending": "Descending", + "root": "Root", + "new": "New", + "sortBy": "Sort By", + "items": "Items", + "selected": "Selected", + "editor": "Editor", + "octal": "Octal", + "storage": "Storage", + "disk": "Disk", + "used": "Used", + "of": "of", + "toggleSidebar": "Toggle Sidebar", + "compactLayout": "Use compact layout", + "comfortableLayout": "Use comfortable layout", + "cannotLoadPdf": "Cannot load PDF", + "pdfLoadError": "There was an error loading this PDF file.", + "loadingPdf": "Loading PDF...", + "loadingPage": "Loading page...", + "cancel": "Cancel", + "copiedItems_one": "Copied {{count}} item", + "copiedItems_other": "Copied {{count}} items", + "deleteCopiedFileFailed": "Could not delete the copy of {{name}}: {{error}}", + "dragMovedItems_one": "Moved {{count}} item to {{target}}", + "dragMovedItems_other": "Moved {{count}} items to {{target}}", + "moveBackFileFailed": "Could not move {{name}} back: {{error}}", + "terminal": "Terminal: {{host}} ({{path}})", + "dragToDesktop": "Dragging {{name}} to the desktop", + "dragFilesToDesktop": "Dragging {{count}} files to the desktop", + "folderDragUnsupported": "Dragging folders to the desktop is not supported yet", + "saveToDesktopFailed": "Save failed: {{error}}", + "dragFailedDetail": "Drag failed: {{error}}", + "videoUnsupported": "Your browser cannot play this video format.", + "downloadToPlay": "Download to play it elsewhere", + "cannotPreviewType": "Cannot preview this file type", + "cannotPreviewTypeHint": "This file type has no preview. Download it to open it in another app." + }, + "sftpTransfer": { + "title": "SFTP", + "description": "Transfer files between two SSH hosts.", + "sourceServer": "Source Server", + "destinationServer": "Destination Server", + "selectHost": "Select host", + "noHostSelected": "No host selected", + "move": "Move", + "copy": "Copy", + "upload": "Upload", + "itemsSelected": "{{count}} item selected", + "itemsSelected_other": "{{count}} items selected", + "ready": "Ready", + "loadingHosts": "Loading hosts...", + "name": "Name", + "modified": "Modified", + "size": "Size", + "noFiles": "No files", + "open": "Open", + "up": "Up", + "refresh": "Refresh", + "copyToTarget": "Copy to Target Directory", + "rename": "Rename", + "delete": "Delete", + "editPermissions": "Edit Permissions", + "createNewFolder": "Create New Folder", + "deleteSelectedItems": "Delete Selected Items", + "deleteConfirm": "Delete {{count}} selected item?", + "deleteConfirm_other": "Delete {{count}} selected items?", + "cancel": "Cancel", + "save": "Save", + "folderCreated": "Folder created", + "itemRenamed": "Item renamed", + "actionFailed": "Action failed", + "itemsDeleted": "{{count}} item deleted", + "itemsDeleted_other": "{{count}} items deleted", + "deleteFailed": "Delete failed", + "permissionsUpdated": "Permissions updated", + "noRemoteSessionConnected": "No remote session connected", + "failedToListFiles": "Failed to list files", + "failedToRefresh": "Failed to refresh", + "destinationInsideSource": "Destination cannot be inside the selected source path.", + "sameHostNoOp": "Source and destination are the same folder." + }, + "hosts": { + "fileManager": "File Manager", + "fileManagerUrlCopied": "File Manager URL copied", + "copyFileManagerUrlAction": "Copy File Manager URL", + "docsLink": "View docs", + "hostNotFound": "Host not found", + "loadingHost": "Loading host..." }, "onboarding": { - "feature_files": "Pengelola berkas", - "feature_files_desc": "Jelajahi, unggah, unduh, dan edit file melalui SFTP tanpa meninggalkan aplikasi." + "feature_files": "File manager", + "feature_files_desc": "Browse, upload, download and edit files over SFTP without leaving the app." }, "terminal": { - "runTitle": "Menjalankan {{command}} - {{host}}", + "runTitle": "Running {{command}} - {{host}}", "terminalTitle": "Terminal - {{host}}", "terminalWithPath": "Terminal - {{host}}:{{path}}" }, "transfer": { - "browseFolders": "Telusuri folder tujuan", - "browsePathError": "Tidak dapat membuka jalur ini pada host tujuan.", - "browsePathWillBeCreated": "Folder ini belum ada. Folder ini akan dibuat saat transfer dimulai.", - "cancel": "Membatalkan", - "cleanupDestFiles": "Tujuan pembersihan", - "cleanupDestFilesError": "Pembersihan gagal", - "cleanupDestFilesNothing": "Tidak ada yang perlu dibersihkan di tempat tujuan.", - "cleanupDestFilesPartial": "Beberapa file parsial tidak dapat dihapus.", - "cleanupDestFilesSuccess": "File parsial telah dihapus dari tujuan.", - "confirmCopy": "Menyalin", - "confirmMove": "Bergerak", - "copyFolderToHost": "Salin folder ke host…", - "copyItemsToHost": "Salin {{count}} item ke host…", - "copyToHost": "Salin ke host…", - "destinationPath": "Jalur tujuan", - "destMustBeDirectory": "Tujuan harus berupa direktori untuk transfer multi-item.", - "goUp": "Naik", - "hostAuthRequired": "Diperlukan autentikasi — buka File Manager di host ini terlebih dahulu.", - "hostConnecting": "Menghubungkan…", - "hostConnectionFailed": "Koneksi gagal", - "hostDisconnected": "Tidak terhubung", - "hostReady": "Siap", - "itemsSummary": "{{count}} item", - "jumpHostLimitation": "Kedua host harus dapat dijangkau dari server Termix. Perutean langsung antar host tidak didukung.", - "methodAuto": "Mobil", - "methodAutoHint": "Memilih antara tar atau SFTP per-file berdasarkan jumlah file, ukuran, dan kemampuan kompresi. File tunggal selalu menggunakan SFTP streaming.", - "methodItemSftp": "SFTP per file", - "methodItemSftpHint": "Transfer setiap file secara individual melalui SFTP. Berfungsi di semua host termasuk Windows.", - "methodItemSftpLimitation": "Setiap berkas menggunakan aliran SFTP yang sama sebagai salinan berkas tunggal, satu demi satu. Kemajuan digabungkan di semua berkas, sehingga bilah kemajuan bergerak lambat selama pemrosesan berkas berukuran besar.", - "methodLabel": "Metode transfer", - "methodPreviewError": "Metode transfer tidak dapat dipratinjau. Server akan tetap memilih metode saat Anda memulai.", - "methodPreviewLoading": "Metode perhitungan transfer…", - "methodPreviewScanSummary": "{{fileCount}} berkas, {{totalSize}} total (dipindai pada host sumber).", - "methodPreviewWillUseItemSftp": "Akan menggunakan: SFTP per file", - "methodPreviewWillUseTar": "Akan menggunakan: Arsip Tar", + "browseFolders": "Browse destination folders", + "browsePathError": "Could not open this path on the destination host.", + "browsePathWillBeCreated": "This folder does not exist yet. It will be created when the transfer starts.", + "cancel": "Cancel", + "cleanupDestFiles": "Clean up destination", + "cleanupDestFilesError": "Cleanup failed", + "cleanupDestFilesNothing": "Nothing to clean up on the destination", + "cleanupDestFilesPartial": "Some partial files could not be removed", + "cleanupDestFilesSuccess": "Removed partial files from the destination", + "confirmCopy": "Copy", + "confirmMove": "Move", + "copyFolderToHost": "Copy folder to host…", + "copyItemsToHost": "Copy {{count}} items to host…", + "copyToHost": "Copy to host…", + "destinationPath": "Destination path", + "destMustBeDirectory": "Destination must be a directory for multi-item transfers", + "goUp": "Go up", + "hostAuthRequired": "Authentication required. Open File Manager on this host first", + "hostConnecting": "Connecting…", + "hostConnectionFailed": "Connection failed", + "hostDisconnected": "Not connected", + "hostReady": "Ready", + "itemsSummary": "{{count}} items", + "jumpHostLimitation": "Both hosts must be reachable from the Termix server. Direct host-to-host routing is not supported.", + "methodAuto": "Auto", + "methodAutoHint": "Picks tar or per-file SFTP based on file count, size, and compressibility. Single files always use streaming SFTP.", + "methodItemSftp": "Per-file SFTP", + "methodItemSftpHint": "Transfer each file individually over SFTP. Works on all hosts including Windows.", + "methodItemSftpLimitation": "Each file uses the same SFTP stream as a single-file copy, one after another. Progress is combined across all files, so the bar moves slowly during large files.", + "methodLabel": "Transfer method", + "methodPreviewError": "Could not preview transfer method. The server will still pick a method when you start.", + "methodPreviewLoading": "Calculating transfer method…", + "methodPreviewScanSummary": "{{fileCount}} files, {{totalSize}} total (scanned on source host).", + "methodPreviewWillUseItemSftp": "Will use: Per-file SFTP", + "methodPreviewWillUseTar": "Will use: Tar archive", "methodReason": { - "user_item_sftp": "Anda memilih SFTP per-file.", - "user_tar": "Anda memilih arsip tar.", - "tar_unavailable": "Tar tidak tersedia di salah satu atau kedua host — SFTP per-file akan digunakan sebagai gantinya.", - "windows_host": "Sistem operasi yang digunakan adalah Windows — tar tidak digunakan.", - "auto_multi_large": "Otomatis: beberapa file termasuk file besar ({{largestSize}}) dengan data yang dapat dikompresi — tar menggabungkan menjadi satu transfer.", - "auto_single_large_in_archive": "Otomatis: satu file besar ({{largestSize}}) dalam set ini — SFTP per file.", - "auto_many_incompressible": "Otomatis: sebagian besar data tidak dapat dikompresi — SFTP per file.", - "auto_many_files": "Otomatis: banyak file ({{fileCount}}) — tar mengurangi overhead per file.", - "auto_default": "Otomatis: SFTP per-file untuk set ini." + "user_item_sftp": "You chose per-file SFTP.", + "user_tar": "You chose tar archive.", + "tar_unavailable": "Tar is not available on one or both hosts, so per-file SFTP will be used instead.", + "windows_host": "A Windows host is involved, so tar is not used.", + "auto_multi_large": "Auto: multiple files including a large file ({{largestSize}}) with compressible data. Tar bundles them into one transfer.", + "auto_single_large_in_archive": "Auto: one large file ({{largestSize}}) in this set, so per-file SFTP.", + "auto_many_incompressible": "Auto: mostly incompressible data, so per-file SFTP.", + "auto_many_files": "Auto: many files ({{fileCount}}), tar cuts the per-file overhead.", + "auto_default": "Auto: per-file SFTP for this set." }, - "methodTar": "Arsip Tar", - "methodTarHint": "Kompres di sumber, transfer satu arsip, ekstrak di tujuan. Membutuhkan tar di kedua host Unix.", - "metricsCompress": "Kompres pada sumber: {{duration}}", - "metricsExtract": "Ekstrak pada tujuan: {{duration}}", - "metricsPrepare": "Siapkan tujuan: {{duration}}", - "metricsRouteBenchmark": "Pemeriksaan rute — langsung: {{direct}}, relai: {{relay}}", - "metricsSourceDelete": "Hapus dari sumber: {{duration}}", + "methodTar": "Tar archive", + "methodTarHint": "Compress on source, transfer one archive, extract on destination. Requires tar on both Unix hosts.", + "metricsCompress": "Compress on source: {{duration}}", + "metricsExtract": "Extract on destination: {{duration}}", + "metricsPrepare": "Prepare destination: {{duration}}", + "metricsRouteBenchmark": "Route probe: direct {{direct}}, relay {{relay}}", + "metricsSourceDelete": "Remove from source: {{duration}}", "metricsTotal": "Total: {{duration}}", - "metricsTransfer": "Ujung ke ujung: {{throughput}} ({{duration}})", - "metricsVerify": "SHA-256 terverifikasi: {{duration}}", - "moveFolderToHost": "Pindahkan folder ke host…", - "moveItemsToHost": "Pindahkan {{count}} item ke host…", - "moveToHost": "Pindah ke host…", - "noHostsConnected": "Tidak ada penyedia pengelola file lain yang tersedia.", - "noHostsConnectedHint": "Tambahkan host SSH lain dengan File Manager diaktifkan di Host Manager.", - "parallelSegmentsHint": "File berukuran besar dibagi menjadi bagian-bagian berukuran 256 MB. Beberapa jalur menggunakan koneksi terpisah (seperti memulai beberapa transfer) untuk throughput total yang lebih tinggi.", - "parallelSegmentsLabel": "Jalur transfer paralel", - "parallelSegmentsOption": "{{count}} jalur", - "progressBenchmarking": "Memilih rute transfer tercepat…", + "metricsTransfer": "End-to-end: {{throughput}} ({{duration}})", + "metricsVerify": "SHA-256 verified: {{duration}}", + "moveFolderToHost": "Move folder to host…", + "moveItemsToHost": "Move {{count}} items to host…", + "moveToHost": "Move to host…", + "noHostsConnected": "No other file-manager hosts available.", + "noHostsConnectedHint": "Add another SSH host with File Manager enabled in Host Manager.", + "parallelSegmentsHint": "Large files are split into 256 MB chunks. Multiple lanes use separate connections (like starting several transfers) for higher total throughput.", + "parallelSegmentsLabel": "Parallel transfer lanes", + "parallelSegmentsOption": "{{count}} lanes", + "progressBenchmarking": "Selecting the fastest transfer route…", "progressBytes": "{{transferred}} / {{total}}", - "progressCancel": "Membatalkan", - "progressCancelling": "Membatalkan…", - "progressCompressing": "Kompresi pada host sumber…", - "progressExtracting": "Mengekstraksi pada tujuan…", - "progressItems": "berkas {{current}} / {{total}}", - "progressReconnecting": "Menghubungkan kembali…", - "progressStalled": "Terhenti", - "progressTotalSpeed": "{{speed}} total ({{lanes}} lajur)", - "progressTransferring": "Mentransfer data…", - "progressTransferringItems": "Mentransfer berkas ({{current}} dari {{total}})…", - "progressVerifying": "Memverifikasi integritas file…", - "recentDestinations": "Destinasi terkini", - "resumedHint": "Terhubung kembali ke transfer aktif yang dimulai di jendela lain.", - "retryTransfer": "Mencoba kembali", - "retryTransferError": "Percobaan ulang gagal.", - "selectDestinationHost": "Pilih host tujuan", - "transferCancelled": "Transfer dibatalkan", - "transferCancelledCopyHint": "File yang tidak lengkap mungkin masih tersisa di tujuan.", - "transferCancelledMoveHint": "Sebagian berkas mungkin masih tersisa di tujuan. Berkas sumber tidak dihapus.", - "transferError": "Transfer gagal", - "transferFailedRetryHint": "Sebagian data tersimpan di tujuan. Upaya pengulangan akan dilanjutkan saat koneksi kembali pulih.", - "transferPartialHint": "Tidak dapat mentransfer: {{paths}}", - "transferSuccess": "Transfer selesai" + "progressCancel": "Cancel", + "progressCancelling": "Cancelling…", + "progressCompressing": "Compressing on source host…", + "progressExtracting": "Extracting on destination…", + "progressItems": "{{current}} / {{total}} files", + "progressReconnecting": "Reconnecting…", + "progressStalled": "Stalled", + "progressTotalSpeed": "{{speed}} total ({{lanes}} lanes)", + "progressTransferring": "Transferring data…", + "progressTransferringItems": "Transferring files ({{current}} of {{total}})…", + "progressVerifying": "Verifying file integrity…", + "recentDestinations": "Recent destinations", + "resumedHint": "Reconnected to an active transfer started in another window.", + "retryTransfer": "Retry", + "retryTransferError": "Retry failed", + "selectDestinationHost": "Select destination host", + "transferCancelled": "Transfer cancelled", + "transferCancelledCopyHint": "Partial files may remain on the destination.", + "transferCancelledMoveHint": "Partial files may remain on the destination. Source files were not removed.", + "transferError": "Transfer failed", + "transferFailedRetryHint": "Partial data was kept on the destination. Retry will resume when the connection is back.", + "transferPartialHint": "Could not transfer: {{paths}}", + "transferSuccess": "Transfer complete", + "metricsHopSourceRead": "Source → server: {{throughput}}", + "metricsHopDestSftpWrite": "Server → dest (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Server → dest (local): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/it_IT.json b/plugins/file-manager/locales/translated/it_IT.json index 1dd34c9fa..a30ceedae 100644 --- a/plugins/file-manager/locales/translated/it_IT.json +++ b/plugins/file-manager/locales/translated/it_IT.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "File", + "sftp": "SFTP", + "openFileManager": "Apri Gestione file" + }, + "permissions": { + "use": { + "title": "Utilizzare il gestore file", + "description": "Sfoglia, modifica e trasferisci file tramite SFTP." + } + }, + "settings": { + "host": { + "enable": { + "label": "Abilita File Manager", + "description": "È possibile visualizzare e modificare i file su questo host tramite SFTP." + }, + "defaultPath": { + "label": "Percorso predefinito" + }, + "scpLegacy": { + "label": "Modalità SCP legacy" + } + }, + "user": { + "transferConcurrency": { + "label": "Trasferimenti simultanei di file", + "description": "Quanti file il gestore locale/remoto affiancato carica o scarica contemporaneamente. Riduci questo valore se il tuo server limita i canali SFTP." + }, + "confirmBeforeTrash": { + "label": "Conferma prima di spostare i file nel cestino", + "description": "Chiedi conferma prima di spostare i file remoti nel cestino. Anche la cancellazione definitiva richiede conferma." + } + } + }, + "hostCapability": { + "label": "Gestore file" + }, "fileManager": { "noHostSelected": "Nessun host selezionato", "initializingEditor": "Inizializzazione editor...", @@ -34,13 +72,14 @@ "rename": "Rinomina", "uploading": "Caricamento in corso...", "uploadingFile": "Caricamento di {{name}}...", + "uploadingChunk": "Caricamento di {{name}}: {{percent}}% (parte {{chunk}} di {{total}})", "fileName": "Nome file", "folderName": "Nome cartella", "fileUploadedSuccessfully": "File \"{{name}}\" caricato con successo", "failedToUploadFile": "Caricamento file non riuscito", "uploadingFolderFiles": "Caricamento del/dei file {{count}} in corso...", "uploadedFolderFiles": "File caricati con successo {{count}}", - "uploadedFolderPartial": "Caricamento del/i file {{uploaded}} non riuscito/i {{failed}}", + "uploadedFolderPartial": "Uploaded {{uploaded}} file(s), {{failed}} failed", "fileDownloadedSuccessfully": "File \"{{name}}\" scaricato con successo", "failedToDownloadFile": "Scaricamento file non riuscito", "fileCreatedSuccessfully": "File \"{{name}}\" creato con successo", @@ -68,7 +107,7 @@ "localRevealInFileManager": "Mostra nel gestore file di sistema", "localCannotOpenFolder": "Impossibile aprire la cartella", "localItemCount": "{{count}} elementi", - "localSelectedCount": "{{count}} selezionato", + "localSelectedCount": "{{count}} selezionati", "back": "Indietro", "forward": "Inoltrare", "up": "Su", @@ -81,16 +120,16 @@ "localNothingToTransfer": "Nulla da trasferire", "localUploadComplete": "Caricato/i file {{count}}", "localUploadFailed": "Caricamento non riuscito", - "localUploadPartial": "Caricamento del/i file {{done}} non riuscito/i {{failed}}", + "localUploadPartial": "Uploaded {{done}} file(s), {{failed}} failed", "localDownloadComplete": "Scaricato il/i file {{count}}", "localDownloadFailed": "Download non riuscito", "localDownloadPartial": "Scaricamento del/dei file {{done}} , {{failed}} non riuscito", "localReplaceExistingPrompt": "{{count}} L'elemento/gli elementi esistono già in questa cartella. Sostituirli?", - "localReplace": "Sostituire", + "localReplace": "Sostituisci", "localSkipExisting": "Saltare", "localSkippedExisting": "Saltato {{count}} elemento/i esistente/i", "localUnsafeNamesSkipped": "Saltati {{count}} elementi i cui nomi non possono essere utilizzati su questo computer", - "localOpen": "Aprire", + "localOpen": "Apri", "localOpenFolder": "Apri la cartella", "localUploadToRemote": "Carica sul server", "localUploadToRemoteMany": "Carica {{count}} elementi sul server", @@ -163,13 +202,13 @@ "confirmDeleteMultipleItemsWithFolders": "Sei sicuro di voler eliminare definitivamente {{count}} elementi? Sono incluse cartelle e il loro contenuto.", "confirmDeleteFolder": "Sei sicuro di voler eliminare definitivamente la cartella \"{{name}}\" e tutto il suo contenuto?", "permanentDeleteWarning": "Questa azione non può essere annullata. Gli elementi verranno eliminati definitivamente dal server.", - "moveToTrashWarning": "L'articolo o gli articoli verranno spostati nel Cestino Termix e potranno essere ripristinati prima della scadenza del periodo di conservazione.", + "moveToTrashWarning": "L'articolo o gli articoli verranno spostati nel Cestino di Termix e potranno essere ripristinati prima della scadenza del periodo di conservazione.", "itemsMovedToTrash": "{{count}} elemento/i spostato/i nel Cestino", "trash": "Spazzatura", "trashDescription": "Gli elementi eliminati vengono conservati per {{days}} giorni su questo host.", "trashLoadFailed": "Impossibile caricare il Cestino", "trashEmpty": "Il cestino è vuoto", - "trashRestore": "Ripristinare", + "trashRestore": "Ripristina", "trashRestored": "Ripristinato {{name}}", "trashRestoreFailed": "Impossibile ripristinare l'elemento. Il percorso originale potrebbe già esistere.", "trashDeletePermanently": "Eliminare definitivamente", @@ -290,6 +329,7 @@ "connecting": "Connessione in corso...", "connectedSuccessfully": "Connesso con successo", "totpVerificationFailed": "Verifica TOTP non riuscita", + "browserSignInFailed": "Accesso non riuscito. Riprova.", "authenticationFailed": "Autenticazione non riuscita", "incorrectPassphrase": "Frase di accesso non corretta. Riprova.", "verificationCodePrompt": "Codice di verifica:", @@ -326,7 +366,24 @@ "cannotLoadPdf": "Impossibile caricare il PDF", "pdfLoadError": "Si è verificato un errore durante il caricamento del file PDF.", "loadingPdf": "Caricamento PDF in corso...", - "loadingPage": "Caricamento pagina in corso..." + "loadingPage": "Caricamento pagina in corso...", + "cancel": "Annulla", + "copiedItems_one": "Elemento copiato {{count}}", + "copiedItems_other": "Elementi copiati {{count}}", + "deleteCopiedFileFailed": "Impossibile eliminare la copia di {{name}}: {{error}}", + "dragMovedItems_one": "Elemento {{count}} spostato in {{target}}", + "dragMovedItems_other": "Spostati {{count}} elementi in {{target}}", + "moveBackFileFailed": "Impossibile spostare {{name}} indietro: {{error}}", + "terminal": "Terminale: {{host}} ({{path}})", + "dragToDesktop": "Trascinando {{name}} sul desktop", + "dragFilesToDesktop": "Trascinamento dei file {{count}} sul desktop", + "folderDragUnsupported": "Il trascinamento delle cartelle sul desktop non è ancora supportato.", + "saveToDesktopFailed": "Salvataggio non riuscito: {{error}}", + "dragFailedDetail": "Trascinamento non riuscito: {{error}}", + "videoUnsupported": "Il tuo browser non è in grado di riprodurre questo formato video.", + "downloadToPlay": "Scaricalo per riprodurlo altrove", + "cannotPreviewType": "Impossibile visualizzare l'anteprima di questo tipo di file", + "cannotPreviewTypeHint": "Questo tipo di file non ha un'anteprima. Scaricalo per aprirlo in un'altra applicazione." }, "sftpTransfer": { "title": "SFTP", @@ -335,33 +392,33 @@ "destinationServer": "Server di destinazione", "selectHost": "Seleziona l'host", "noHostSelected": "Nessun host selezionato", - "move": "Mossa", + "move": "Sposta", "copy": "Copia", - "upload": "Caricamento", + "upload": "Carica", "itemsSelected": "{{count}} elemento selezionato", "itemsSelected_other": "{{count}} elementi selezionati", "ready": "Pronto", - "loadingHosts": "Caricamento host in corso...", + "loadingHosts": "Caricamento host...", "name": "Nome", "modified": "Modificato", - "size": "Misurare", + "size": "Dimensione", "noFiles": "Nessun file", - "open": "Aprire", + "open": "Apri", "up": "Su", - "refresh": "Rinfrescato", + "refresh": "Aggiorna", "copyToTarget": "Copia nella directory di destinazione", - "rename": "Rinominare", - "delete": "Eliminare", + "rename": "Rinomina", + "delete": "Elimina", "editPermissions": "Modifica autorizzazioni", "createNewFolder": "Crea una nuova cartella", "deleteSelectedItems": "Elimina gli elementi selezionati", "deleteConfirm": "Eliminare l'elemento selezionato {{count}}?", "deleteConfirm_other": "Eliminare gli elementi selezionati {{count}}?", - "cancel": "Cancellare", + "cancel": "Annulla", "save": "Salva", "folderCreated": "Cartella creata", "itemRenamed": "Elemento rinominato", - "actionFailed": "L'azione è fallita", + "actionFailed": "Azione non riuscita", "itemsDeleted": "{{count}} elemento eliminato", "itemsDeleted_other": "{{count}} elementi eliminati", "deleteFailed": "Eliminazione non riuscita", @@ -374,42 +431,12 @@ }, "hosts": { "fileManager": "File Manager", - "tabFiles": "File", - "enableFileManagerMonitor": "Abilita File Manager", - "enableFileManagerMonitorDesc": "Sfoglia e gestisci i file su questo host tramite SFTP", - "scpLegacyLabel": "Modalità SCP legacy", - "scpLegacyDesc": "Usa il trasferimento file legacy per server che non supportano il sottosistema SFTP (ad es. server SSH embedded o minimali).", - "defaultPathLabel": "Percorso predefinito", - "fileManagerPathHint": "La directory da aprire all'avvio del file manager per questo host.", "fileManagerUrlCopied": "URL file manager copiato", "copyFileManagerUrlAction": "Copia URL File Manager", "docsLink": "Visualizza documentazione", "hostNotFound": "Host non trovato", "loadingHost": "Caricamento host..." }, - "settings": { - "host": { - "enable": { - "label": "Abilita File Manager" - }, - "defaultPath": { - "label": "Percorso predefinito" - }, - "scpLegacy": { - "label": "Modalità SCP legacy" - } - }, - "user": { - "transferConcurrency": { - "label": "Trasferimenti simultanei di file", - "description": "Quanti file il gestore locale/remoto affiancato carica o scarica contemporaneamente. Riduci questo valore se il tuo server limita i canali SFTP." - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "File" - }, "onboarding": { "feature_files": "Gestore file", "feature_files_desc": "Esplora, carica, scarica e modifica file tramite SFTP senza uscire dall'applicazione." @@ -437,7 +464,7 @@ "destinationPath": "Percorso di destinazione", "destMustBeDirectory": "La destinazione deve essere una directory per il trasferimento di più elementi", "goUp": "Salire", - "hostAuthRequired": "Autenticazione richiesta — aprire prima File Manager su questo host", + "hostAuthRequired": "Autenticazione richiesta. Apri prima il File Manager su questo host", "hostConnecting": "Connessione in corso…", "hostConnectionFailed": "Connessione non riuscita", "hostDisconnected": "Non connesso", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "Hai scelto SFTP per-file.", "user_tar": "Hai scelto archivio tar.", - "tar_unavailable": "Tar non è disponibile su uno o entrambi gli host — verrà utilizzato SFTP per-file.", - "windows_host": "È coinvolto un host Windows — tar non viene utilizzato.", - "auto_multi_large": "Auto: più file, incluso un file grande ({{largestSize}}) con dati comprimibili — tar li raggruppa in un unico trasferimento.", - "auto_single_large_in_archive": "Auto: un file grande ({{largestSize}}) in questo set — SFTP per-file.", - "auto_many_incompressible": "Auto: dati per lo più incomprimibili — SFTP per-file.", - "auto_many_files": "Auto: molti file ({{fileCount}}) — tar riduce il sovraccarico per-file.", + "tar_unavailable": "Tar non è disponibile su uno o entrambi gli host, quindi verrà utilizzato SFTP per singolo file.", + "windows_host": "Poiché si tratta di un sistema host Windows, non viene utilizzato il comando tar.", + "auto_multi_large": "Automatico: più file, incluso un file di grandi dimensioni ({{largestSize}}) con dati comprimibili. Tar li raggruppa in un unico trasferimento.", + "auto_single_large_in_archive": "Automatico: un file di grandi dimensioni ({{largestSize}}) in questo set, quindi SFTP per file.", + "auto_many_incompressible": "Automatico: dati perlopiù incomprimibili, quindi SFTP file per file.", + "auto_many_files": "Auto: molti file ({{fileCount}}), tar riduce l'overhead per file.", "auto_default": "Auto: SFTP per-file per questo set." }, "methodTar": "Archivio Tar", @@ -471,7 +498,7 @@ "metricsCompress": "Compressione sul sorgente: {{duration}}", "metricsExtract": "Estrazione sulla destinazione: {{duration}}", "metricsPrepare": "Prepara destinazione: {{duration}}", - "metricsRouteBenchmark": "Sondaggio di percorso — diretto: {{direct}}, relè: {{relay}}", + "metricsRouteBenchmark": "Sondaggio di percorso: diretto {{direct}}, relè {{relay}}", "metricsSourceDelete": "Rimozione dal sorgente: {{duration}}", "metricsTotal": "Totale: {{duration}}", "metricsTransfer": "End-to-end: {{throughput}} ({{duration}})", @@ -508,6 +535,9 @@ "transferError": "Trasferimento non riuscito", "transferFailedRetryHint": "I dati parziali sono stati conservati sulla destinazione. Il nuovo tentativo riprenderà quando la connessione sarà ripristinata.", "transferPartialHint": "Impossibile trasferire: {{paths}}", - "transferSuccess": "Trasferimento completato" + "transferSuccess": "Trasferimento completato", + "metricsHopSourceRead": "Sorgente → server: {{throughput}}", + "metricsHopDestSftpWrite": "Server → dest (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Server → dest (locale): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/ja_JP.json b/plugins/file-manager/locales/translated/ja_JP.json index 5ce62d15f..866e59a80 100644 --- a/plugins/file-manager/locales/translated/ja_JP.json +++ b/plugins/file-manager/locales/translated/ja_JP.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "ファイル", + "sftp": "SFTP", + "openFileManager": "ファイルマネージャーを開く" + }, + "permissions": { + "use": { + "title": "ファイルマネージャーを使用する", + "description": "SFTP経由でファイルを閲覧、編集、転送できます。" + } + }, + "settings": { + "host": { + "enable": { + "label": "ファイルマネージャーを有効にする", + "description": "SFTP経由でこのホスト上のファイルを閲覧および編集できます。" + }, + "defaultPath": { + "label": "デフォルトパス" + }, + "scpLegacy": { + "label": "SCP レガシーモード" + } + }, + "user": { + "transferConcurrency": { + "label": "同時ファイル転送", + "description": "ローカル/リモートマネージャーが同時にアップロードまたはダウンロードできるファイルの数を指定します。サーバーがSFTPチャネルを制限している場合は、この値を小さくしてください。" + }, + "confirmBeforeTrash": { + "label": "ファイルをゴミ箱に移動する前に確認してください", + "description": "リモートファイルをゴミ箱に移動する前に、必ず確認してください。完全削除の場合も確認が必要です。" + } + } + }, + "hostCapability": { + "label": "ファイルマネージャー" + }, "fileManager": { "noHostSelected": "ホストが選択されていません", "initializingEditor": "エディターを初期化中...", @@ -34,6 +72,7 @@ "rename": "名前を変更", "uploading": "アップロード中...", "uploadingFile": "{{name}} をアップロード中...", + "uploadingChunk": "{{name}}をアップロード中 : {{percent}}% ( {{chunk}} の一部、 {{total}})", "fileName": "ファイル名", "folderName": "フォルダ名", "fileUploadedSuccessfully": "ファイル \"{{name}}\" のアップロードが完了しました", @@ -58,7 +97,7 @@ "dragFilesToUpload": "ここにファイルをドロップしてアップロード", "dropToUploadHere": "ここにアップロードしてください", "dropToDownloadHere": "ここからダウンロードしてください", - "localFiles": "地元", + "localFiles": "ローカル", "showLocalFiles": "ローカルファイルを表示する(分割表示)", "hideLocalFiles": "ローカルファイルを非表示にする", "localHome": "ホームフォルダ", @@ -68,7 +107,7 @@ "localRevealInFileManager": "システムファイルマネージャで表示", "localCannotOpenFolder": "フォルダーを開けません", "localItemCount": "{{count}} アイテム", - "localSelectedCount": "{{count}} 選択済み", + "localSelectedCount": "{{count}} 件選択中", "back": "戻る", "forward": "フォワード", "up": "上", @@ -86,11 +125,11 @@ "localDownloadFailed": "ダウンロードに失敗しました", "localDownloadPartial": "{{done}} 個のファイルをダウンロードしましたが、 {{failed}} 失敗しました。", "localReplaceExistingPrompt": "このフォルダには既に{{count}} 個のアイテムが存在します。置き換えますか?", - "localReplace": "交換する", + "localReplace": "置換", "localSkipExisting": "スキップ", "localSkippedExisting": "既存のアイテムをスキップしました {{count}}", "localUnsafeNamesSkipped": "このコンピューターでは名前を使用できない {{count}} 個のアイテムをスキップしました", - "localOpen": "開ける", + "localOpen": "開く", "localOpenFolder": "フォルダーを開く", "localUploadToRemote": "サーバーにアップロード", "localUploadToRemoteMany": "{{count}} 個のアイテムをサーバーにアップロードします", @@ -106,7 +145,7 @@ "goToParentFolder": "親フォルダへ移動", "resizeSidebar": "サイドバーのサイズを変更するにはドラッグしてください(ダブルクリックでリセットできます)。", "resizeLocalPane": "ローカルペインのサイズを変更するにはドラッグしてください(ダブルクリックでリセットできます)。", - "columns": "コラム", + "columns": "列", "columnsHint": "右クリックして列を選択", "emptyFolder": "このフォルダーは空です", "searchFiles": "ファイルを検索...", @@ -169,7 +208,7 @@ "trashDescription": "削除されたアイテムは、このホスト上で {{days}} 日間保持されます。", "trashLoadFailed": "ゴミ箱の読み込みに失敗しました", "trashEmpty": "ゴミ箱は空です", - "trashRestore": "復元する", + "trashRestore": "復元", "trashRestored": "復元済み {{name}}", "trashRestoreFailed": "アイテムの復元に失敗しました。元のパスが既に存在している可能性があります。", "trashDeletePermanently": "完全に削除する", @@ -290,6 +329,7 @@ "connecting": "接続中...", "connectedSuccessfully": "接続しました", "totpVerificationFailed": "TOTP検証に失敗しました", + "browserSignInFailed": "ログインに失敗しました。もう一度お試しください。", "authenticationFailed": "認証に失敗しました", "incorrectPassphrase": "パスフレーズが間違っています。もう一度お試しください。", "verificationCodePrompt": "認証コード:", @@ -326,7 +366,24 @@ "cannotLoadPdf": "PDFを読み込めません", "pdfLoadError": "このPDFファイルの読み込み中にエラーが発生しました。", "loadingPdf": "PDFを読み込み中...", - "loadingPage": "ページを読み込み中..." + "loadingPage": "ページを読み込み中...", + "cancel": "キャンセル", + "copiedItems_one": "{{count}} アイテムをコピーしました", + "copiedItems_other": "{{count}} 個のアイテムをコピーしました", + "deleteCopiedFileFailed": "{{name}}のコピーを削除できませんでした: {{error}}", + "dragMovedItems_one": "{{count}} アイテムを {{target}} に移動しました。", + "dragMovedItems_other": "{{count}} 個のアイテムを {{target}}に移動しました。", + "moveBackFileFailed": "{{name}} を {{error}} に戻すことができませんでした。", + "terminal": "端末: {{host}} ({{path}})", + "dragToDesktop": "{{name}} をデスクトップにドラッグ", + "dragFilesToDesktop": "{{count}} ファイルをデスクトップにドラッグしています", + "folderDragUnsupported": "フォルダをデスクトップにドラッグする機能はまだサポートされていません。", + "saveToDesktopFailed": "保存に失敗しました: {{error}}", + "dragFailedDetail": "ドラッグに失敗しました: {{error}}", + "videoUnsupported": "お使いのブラウザはこの動画フォーマットを再生できません。", + "downloadToPlay": "他の場所でプレイするにはダウンロードしてください", + "cannotPreviewType": "このファイルタイプはプレビューできません", + "cannotPreviewTypeHint": "このファイル形式にはプレビュー機能がありません。ダウンロードして別のアプリで開いてください。" }, "sftpTransfer": { "title": "SFTP", @@ -335,23 +392,23 @@ "destinationServer": "宛先サーバー", "selectHost": "ホストを選択", "noHostSelected": "ホストが選択されていません", - "move": "動く", + "move": "移動", "copy": "コピー", "upload": "アップロード", "itemsSelected": "{{count}} アイテムが選択されました", "itemsSelected_other": "{{count}} 個のアイテムが選択されました", - "ready": "準備ができて", - "loadingHosts": "ホストを読み込んでいます...", + "ready": "準備完了", + "loadingHosts": "ホストを読み込み中...", "name": "名前", - "modified": "修正済み", + "modified": "更新日時", "size": "サイズ", "noFiles": "ファイルなし", - "open": "開ける", + "open": "開く", "up": "上", - "refresh": "更新", + "refresh": "再読み込み", "copyToTarget": "ターゲットディレクトリにコピー", - "rename": "名前を変更する", - "delete": "消去", + "rename": "名前変更", + "delete": "削除", "editPermissions": "権限の編集", "createNewFolder": "新しいフォルダーを作成する", "deleteSelectedItems": "選択したアイテムを削除", @@ -361,7 +418,7 @@ "save": "保存", "folderCreated": "フォルダが作成されました", "itemRenamed": "アイテム名が変更されました", - "actionFailed": "アクションが失敗しました", + "actionFailed": "アクションに失敗しました", "itemsDeleted": "{{count}} アイテムが削除されました", "itemsDeleted_other": "{{count}} 個のアイテムが削除されました", "deleteFailed": "削除に失敗しました", @@ -374,42 +431,12 @@ }, "hosts": { "fileManager": "ファイルマネージャー", - "tabFiles": "ファイル", - "enableFileManagerMonitor": "ファイルマネージャーを有効にする", - "enableFileManagerMonitorDesc": "このホストのファイルを SFTP で閲覧・管理します", - "scpLegacyLabel": "SCP レガシーモード", - "scpLegacyDesc": "SFTP サブシステムをサポートしないサーバー(組み込みや最小構成の SSH サーバーなど)に対してレガシーファイル転送を使用します", - "defaultPathLabel": "デフォルトパス", - "fileManagerPathHint": "このホストのファイルマネージャー起動時に開くディレクトリ", "fileManagerUrlCopied": "ファイルマネージャーURLをコピーしました", "copyFileManagerUrlAction": "ファイルマネージャー URL をコピー", "docsLink": "ドキュメントを表示", "hostNotFound": "ホストが見つかりません", "loadingHost": "ホストを読み込み中..." }, - "settings": { - "host": { - "enable": { - "label": "ファイルマネージャーを有効にする" - }, - "defaultPath": { - "label": "デフォルトパス" - }, - "scpLegacy": { - "label": "SCP レガシーモード" - } - }, - "user": { - "transferConcurrency": { - "label": "同時ファイル転送", - "description": "ローカル/リモートマネージャーが同時にアップロードまたはダウンロードできるファイルの数を指定します。サーバーがSFTPチャネルを制限している場合は、この値を小さくしてください。" - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "ファイル" - }, "onboarding": { "feature_files": "ファイルマネージャー", "feature_files_desc": "アプリを離れることなく、SFTP経由でファイルの閲覧、アップロード、ダウンロード、編集が可能です。" @@ -437,7 +464,7 @@ "destinationPath": "転送先パス", "destMustBeDirectory": "複数アイテムの転送では転送先はディレクトリである必要があります", "goUp": "上へ", - "hostAuthRequired": "認証が必要です — まずこのホストでファイルマネージャを開いてください", + "hostAuthRequired": "認証が必要です。まずこのホストでファイルマネージャを開いてください。", "hostConnecting": "接続中…", "hostConnectionFailed": "接続に失敗しました", "hostDisconnected": "未接続", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "ファイルごとのSFTPを選択しました。", "user_tar": "tarアーカイブを選択しました。", - "tar_unavailable": "一方または両方のホストでtarが利用できないため、代わりにファイルごとのSFTPが使用されます。", - "windows_host": "Windows ホストが含まれているため、tar は使用されません。", - "auto_multi_large": "自動: 複数ファイルに大きな圧縮可能なファイル ({{largestSize}}) が含まれるため、tarで1回の転送にまとめます。", - "auto_single_large_in_archive": "自動: このセットに1つの大きなファイル ({{largestSize}}) があるため、ファイルごとのSFTPです。", - "auto_many_incompressible": "自動: ほとんど圧縮不可能なデータのため、ファイルごとのSFTPです。", - "auto_many_files": "自動: 多数のファイル ({{fileCount}}) があるため、tarでファイルごとのオーバーヘッドを削減します。", + "tar_unavailable": "片方または両方のホストでtarが利用できないため、代わりにファイル単位のSFTPが使用されます。", + "windows_host": "Windowsホストが関係しているため、tarコマンドは使用しません。", + "auto_multi_large": "自動: 圧縮可能なデータを含む、大きなファイル ({{largestSize}}) を含む複数のファイル。tar はそれらを 1 つの転送にまとめます。", + "auto_single_large_in_archive": "自動: このセットには大きなファイルが 1 つ ({{largestSize}}) 含まれているため、ファイルごとの SFTP です。", + "auto_many_incompressible": "自動: ほとんどが非圧縮データなので、ファイル単位のSFTPを使用します。", + "auto_many_files": "Auto: 多数のファイル ({{fileCount}}) 、tar はファイルごとのオーバーヘッドを削減します。", "auto_default": "自動: このセットではファイルごとのSFTPです。" }, "methodTar": "Tar アーカイブ", @@ -471,7 +498,7 @@ "metricsCompress": "送信元での圧縮: {{duration}}", "metricsExtract": "送信先で展開: {{duration}}", "metricsPrepare": "転送先の準備: {{duration}}", - "metricsRouteBenchmark": "ルートプローブ — 直接: {{direct}}、リレー: {{relay}}", + "metricsRouteBenchmark": "経路プローブ: 直接 {{direct}}、リレー {{relay}}", "metricsSourceDelete": "送信元から削除: {{duration}}", "metricsTotal": "合計: {{duration}}", "metricsTransfer": "エンドツーエンド: {{throughput}} ({{duration}})", @@ -508,6 +535,9 @@ "transferError": "転送に失敗しました", "transferFailedRetryHint": "部分的なデータが宛先に保持されました。接続が復旧したら再試行が再開されます。", "transferPartialHint": "転送できませんでした: {{paths}}", - "transferSuccess": "転送が完了しました" + "transferSuccess": "転送が完了しました", + "metricsHopSourceRead": "送信元 → サーバー: {{throughput}}", + "metricsHopDestSftpWrite": "サーバー → 送信先 (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "サーバー → 送信先 (ローカル): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/ko_KR.json b/plugins/file-manager/locales/translated/ko_KR.json index 4004c3fb5..c116858b5 100644 --- a/plugins/file-manager/locales/translated/ko_KR.json +++ b/plugins/file-manager/locales/translated/ko_KR.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "파일", + "sftp": "SFTP", + "openFileManager": "파일 관리자 열기" + }, + "permissions": { + "use": { + "title": "파일 관리자를 사용하세요", + "description": "SFTP를 통해 파일을 검색, 편집 및 전송하세요." + } + }, + "settings": { + "host": { + "enable": { + "label": "파일 관리자 활성화", + "description": "SFTP를 통해 이 호스트의 파일을 탐색하고 편집하세요." + }, + "defaultPath": { + "label": "기본 경로" + }, + "scpLegacy": { + "label": "SCP 레거시 모드" + } + }, + "user": { + "transferConcurrency": { + "label": "동시 파일 전송", + "description": "로컬/원격 파일 관리자가 동시에 업로드 또는 다운로드할 수 있는 파일 수를 지정합니다. 서버에서 SFTP 채널 수를 제한하는 경우 이 값을 낮추십시오." + }, + "confirmBeforeTrash": { + "label": "파일을 휴지통으로 이동하기 전에 확인하십시오.", + "description": "원격 파일을 휴지통으로 이동하기 전에 확인 메시지를 표시합니다. 영구 삭제 시에는 여전히 확인이 필요합니다." + } + } + }, + "hostCapability": { + "label": "파일 관리자" + }, "fileManager": { "noHostSelected": "선택된 호스트 없음", "initializingEditor": "편집기 초기화 중...", @@ -34,6 +72,7 @@ "rename": "이름 변경", "uploading": "업로드 중...", "uploadingFile": "{{name}} 업로드 중...", + "uploadingChunk": "{{name}}업로드 중 : {{percent}}% ( {{total}}의 {{chunk}} 부분)", "fileName": "파일 이름", "folderName": "폴더 이름", "fileUploadedSuccessfully": "파일 \"{{name}}\" 업로드 완료", @@ -58,7 +97,7 @@ "dragFilesToUpload": "업로드할 파일을 여기에 놓으세요", "dropToUploadHere": "여기에 드롭하여 업로드하세요", "dropToDownloadHere": "여기를 클릭하여 다운로드하세요", - "localFiles": "현지의", + "localFiles": "로컬", "showLocalFiles": "로컬 파일 표시(분할 화면)", "hideLocalFiles": "로컬 파일 숨기기", "localHome": "홈 폴더", @@ -67,9 +106,9 @@ "localHideHidden": "숨겨진 파일 숨기기", "localRevealInFileManager": "시스템 파일 관리자에서 보기", "localCannotOpenFolder": "폴더를 열 수 없습니다", - "localItemCount": "{{count}} 항목", - "localSelectedCount": "{{count}} 선택됨", - "back": "뒤쪽에", + "localItemCount": "{{count}}개 항목", + "localSelectedCount": "{{count}}개 선택됨", + "back": "뒤로", "forward": "앞으로", "up": "위로", "kind": "친절한", @@ -77,20 +116,20 @@ "localDownloadingProgress": "{{current}} 의 {{total}} 다운로드 중", "localTransferInFlight": "{{count}} 즉시", "localPreparingDownload": "다운로드 준비 중...", - "localTransferCancelled": "이적 취소됨", + "localTransferCancelled": "전송 취소됨", "localNothingToTransfer": "이체할 내용이 없습니다", "localUploadComplete": "{{count}} 개의 파일을 업로드했습니다.", "localUploadFailed": "업로드 실패", - "localUploadPartial": "업로드된 파일 {{done}} 개, {{failed}} 개에 실패했습니다.", + "localUploadPartial": "업로드된 파일 {{done}} 개 중 {{failed}} 개에 실패했습니다.", "localDownloadComplete": "{{count}} 파일을 다운로드했습니다.", "localDownloadFailed": "다운로드 실패", "localDownloadPartial": "{{done}} 파일 다운로드 실패, {{failed}}", "localReplaceExistingPrompt": "이 폴더에 {{count}} 항목이 이미 있습니다. 바꾸시겠습니까?", - "localReplace": "바꾸다", + "localReplace": "바꾸기", "localSkipExisting": "건너뛰다", "localSkippedExisting": "기존 항목 {{count}} 개를 건너뛰었습니다.", "localUnsafeNamesSkipped": "이 컴퓨터에서 사용할 수 없는 이름을 가진 {{count}} 항목을 건너뛰었습니다.", - "localOpen": "열려 있는", + "localOpen": "열기", "localOpenFolder": "폴더 열기", "localUploadToRemote": "서버에 업로드", "localUploadToRemoteMany": "{{count}} 아이템을 서버에 업로드하세요", @@ -106,7 +145,7 @@ "goToParentFolder": "상위 폴더로 이동", "resizeSidebar": "드래그하여 사이드바 크기를 조절하세요 (더블 클릭하면 원래 크기로 돌아갑니다).", "resizeLocalPane": "드래그하여 로컬 창의 크기를 조정하세요(두 번 클릭하면 원래 크기로 돌아갑니다).", - "columns": "컬럼", + "columns": "열", "columnsHint": "마우스 오른쪽 버튼을 클릭하여 열을 선택하세요.", "emptyFolder": "이 폴더는 비어 있습니다", "searchFiles": "파일 검색...", @@ -169,7 +208,7 @@ "trashDescription": "삭제된 항목은 이 호스트에 {{days}} 일 동안 보관됩니다.", "trashLoadFailed": "휴지통을 불러오는 데 실패했습니다.", "trashEmpty": "쓰레기통이 비어있습니다", - "trashRestore": "복원하다", + "trashRestore": "복원", "trashRestored": "복원됨 {{name}}", "trashRestoreFailed": "항목 복원에 실패했습니다. 원래 경로가 이미 존재할 수 있습니다.", "trashDeletePermanently": "영구 삭제", @@ -290,6 +329,7 @@ "connecting": "연결 중...", "connectedSuccessfully": "연결 성공", "totpVerificationFailed": "TOTP 인증 실패", + "browserSignInFailed": "로그인에 실패했습니다. 다시 시도해 주세요.", "authenticationFailed": "인증 실패", "incorrectPassphrase": "잘못된 암호입니다. 다시 시도하세요.", "verificationCodePrompt": "인증 코드:", @@ -326,7 +366,24 @@ "cannotLoadPdf": "PDF를 로드할 수 없습니다", "pdfLoadError": "이 PDF 파일을 로드하는 중 오류가 발생했습니다.", "loadingPdf": "PDF 로드 중...", - "loadingPage": "페이지 로드 중..." + "loadingPage": "페이지 로드 중...", + "cancel": "취소", + "copiedItems_one": "복사됨 {{count}} 항목", + "copiedItems_other": "복사된 {{count}} 항목", + "deleteCopiedFileFailed": "{{name}}: {{error}}의 복사본을 삭제할 수 없습니다.", + "dragMovedItems_one": "{{count}} 항목을 {{target}}로 이동했습니다.", + "dragMovedItems_other": "{{count}} 항목을 {{target}}로 이동했습니다.", + "moveBackFileFailed": "{{name}} 뒤로 이동할 수 없습니다: {{error}}", + "terminal": "터미널: {{host}} ({{path}})", + "dragToDesktop": "{{name}} 를 바탕 화면으로 드래그", + "dragFilesToDesktop": "{{count}} 파일을 바탕화면으로 드래그하기", + "folderDragUnsupported": "폴더를 데스크톱으로 드래그하는 기능은 아직 지원되지 않습니다.", + "saveToDesktopFailed": "저장 실패: {{error}}", + "dragFailedDetail": "드래그 실패: {{error}}", + "videoUnsupported": "현재 사용 중인 브라우저는 이 비디오 형식을 재생할 수 없습니다.", + "downloadToPlay": "다운로드하여 다른 곳에서 재생하세요.", + "cannotPreviewType": "이 파일 형식을 미리 볼 수 없습니다.", + "cannotPreviewTypeHint": "이 파일 형식은 미리보기를 지원하지 않습니다. 다운로드하여 다른 앱에서 열어보세요." }, "sftpTransfer": { "title": "SFTP", @@ -334,23 +391,23 @@ "sourceServer": "소스 서버", "destinationServer": "대상 서버", "selectHost": "호스트를 선택하세요", - "noHostSelected": "호스트가 선택되지 않았습니다.", - "move": "이동하다", + "noHostSelected": "선택된 호스트가 없습니다", + "move": "이동", "copy": "복사", "upload": "업로드", "itemsSelected": "{{count}} 항목이 선택되었습니다", "itemsSelected_other": "{{count}} 항목이 선택되었습니다", - "ready": "준비가 된", - "loadingHosts": "호스트를 불러오는 중...", + "ready": "준비됨", + "loadingHosts": "호스트 로드 중...", "name": "이름", "modified": "수정됨", "size": "크기", "noFiles": "파일 없음", - "open": "열려 있는", + "open": "열기", "up": "위로", - "refresh": "새로 고치다", + "refresh": "새로 고침", "copyToTarget": "대상 디렉터리로 복사", - "rename": "이름 변경", + "rename": "이름 바꾸기", "delete": "삭제", "editPermissions": "편집 권한", "createNewFolder": "새 폴더 만들기", @@ -358,10 +415,10 @@ "deleteConfirm": "선택한 항목 {{count}} 을 삭제하시겠습니까?", "deleteConfirm_other": "선택한 항목 {{count}} 을 삭제하시겠습니까?", "cancel": "취소", - "save": "구하다", + "save": "저장", "folderCreated": "폴더가 생성되었습니다", "itemRenamed": "항목 이름이 변경됨", - "actionFailed": "작업이 실패했습니다", + "actionFailed": "작업 실패", "itemsDeleted": "{{count}} 항목이 삭제되었습니다", "itemsDeleted_other": "{{count}} 항목이 삭제되었습니다", "deleteFailed": "삭제 실패", @@ -374,42 +431,12 @@ }, "hosts": { "fileManager": "파일 관리자", - "tabFiles": "파일", - "enableFileManagerMonitor": "파일 관리자 활성화", - "enableFileManagerMonitorDesc": "SFTP를 통해 이 호스트의 파일 탐색 및 관리", - "scpLegacyLabel": "SCP 레거시 모드", - "scpLegacyDesc": "SFTP 하위 시스템을 지원하지 않는 서버(예: 임베디드 또는 최소 SSH 서버)에 레거시 파일 전송을 사용합니다.", - "defaultPathLabel": "기본 경로", - "fileManagerPathHint": "이 호스트의 파일 관리자 실행 시 열리는 디렉터리입니다.", "fileManagerUrlCopied": "파일 관리자 URL 복사됨", "copyFileManagerUrlAction": "파일 관리자 URL 복사", "docsLink": "문서 보기", "hostNotFound": "호스트를 찾을 수 없습니다", "loadingHost": "호스트 로드 중..." }, - "settings": { - "host": { - "enable": { - "label": "파일 관리자 활성화" - }, - "defaultPath": { - "label": "기본 경로" - }, - "scpLegacy": { - "label": "SCP 레거시 모드" - } - }, - "user": { - "transferConcurrency": { - "label": "동시 파일 전송", - "description": "로컬/원격 파일 관리자가 동시에 업로드 또는 다운로드할 수 있는 파일 수를 지정합니다. 서버에서 SFTP 채널 수를 제한하는 경우 이 값을 낮추십시오." - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "파일" - }, "onboarding": { "feature_files": "파일 관리자", "feature_files_desc": "앱을 종료하지 않고 SFTP를 통해 파일을 검색, 업로드, 다운로드 및 편집할 수 있습니다." @@ -437,7 +464,7 @@ "destinationPath": "대상 경로", "destMustBeDirectory": "여러 항목 전송 시 대상은 디렉터리여야 합니다.", "goUp": "위로", - "hostAuthRequired": "인증 필요 — 먼저 이 호스트에서 파일 관리자를 여십시오.", + "hostAuthRequired": "인증이 필요합니다. 먼저 이 호스트에서 파일 관리자를 여십시오.", "hostConnecting": "연결 중…", "hostConnectionFailed": "연결 실패", "hostDisconnected": "연결되지 않음", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "파일별 SFTP를 선택하셨습니다.", "user_tar": "tar 아카이브를 선택하셨습니다.", - "tar_unavailable": "한쪽 또는 양쪽 호스트에서 tar를 사용할 수 없어 대신 파일별 SFTP를 사용합니다.", - "windows_host": "Windows 호스트가 포함되어 tar를 사용하지 않습니다.", - "auto_multi_large": "자동: 압축 가능한 대용량 파일({{largestSize}})을 포함한 여러 파일 — tar로 하나의 전송으로 묶습니다.", - "auto_single_large_in_archive": "자동: 이 세트에 대용량 파일({{largestSize}}) 하나 — 파일별 SFTP.", - "auto_many_incompressible": "자동: 대부분 압축 불가능한 데이터 — 파일별 SFTP.", - "auto_many_files": "자동: 다수의 파일({{fileCount}}) — tar로 파일별 오버헤드를 줄입니다.", + "tar_unavailable": "두 호스트 중 하나 또는 둘 모두에서 Tar를 사용할 수 없으므로 파일별 SFTP 전송이 대신 사용됩니다.", + "windows_host": "Windows 호스트가 사용되므로 tar는 사용되지 않습니다.", + "auto_multi_large": "자동: 압축 가능한 데이터가 포함된 대용량 파일({{largestSize}})을 비롯한 여러 파일. Tar는 이 파일들을 하나의 전송으로 묶습니다.", + "auto_single_large_in_archive": "자동: 이 세트에는 하나의 큰 파일({{largestSize}})이 있으므로 파일별 SFTP입니다.", + "auto_many_incompressible": "자동: 대부분 압축 불가능한 데이터이므로 파일별 SFTP를 사용합니다.", + "auto_many_files": "자동: 파일이 많음({{fileCount}}), tar는 파일당 오버헤드를 줄입니다.", "auto_default": "자동: 이 세트에 대해 파일별 SFTP." }, "methodTar": "Tar 아카이브", @@ -471,7 +498,7 @@ "metricsCompress": "소스에서 압축: {{duration}}", "metricsExtract": "목적지에서 추출: {{duration}}", "metricsPrepare": "대상 준비: {{duration}}", - "metricsRouteBenchmark": "경로 탐색 — 직접: {{direct}}, 중계: {{relay}}", + "metricsRouteBenchmark": "경로 탐색: 직접 {{direct}}, 릴레이 {{relay}}", "metricsSourceDelete": "소스에서 제거: {{duration}}", "metricsTotal": "총 시간: {{duration}}", "metricsTransfer": "엔드 투 엔드: {{throughput}} ({{duration}})", @@ -508,6 +535,9 @@ "transferError": "전송 실패", "transferFailedRetryHint": "대상에 부분 데이터가 유지되었습니다. 연결이 복구되면 다시 시도하면 이어서 전송됩니다.", "transferPartialHint": "전송할 수 없습니다: {{paths}}", - "transferSuccess": "전송 완료" + "transferSuccess": "전송 완료", + "metricsHopSourceRead": "소스 → 서버: {{throughput}}", + "metricsHopDestSftpWrite": "서버 → 목적지 (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "서버 → 목적지 (로컬): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/nl_NL.json b/plugins/file-manager/locales/translated/nl_NL.json index 9f3d6a60c..ce88a0ed9 100644 --- a/plugins/file-manager/locales/translated/nl_NL.json +++ b/plugins/file-manager/locales/translated/nl_NL.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "Bestanden", + "sftp": "SFTP", + "openFileManager": "Open bestandsbeheerder" + }, + "permissions": { + "use": { + "title": "Gebruik de bestandsbeheerder", + "description": "Bestanden bekijken, bewerken en overdragen via SFTP." + } + }, + "settings": { + "host": { + "enable": { + "label": "Bestandsbeheer inschakelen", + "description": "Via SFTP kunt u bestanden op deze host bekijken en bewerken." + }, + "defaultPath": { + "label": "Standaardpad" + }, + "scpLegacy": { + "label": "SCP Legacy-modus" + } + }, + "user": { + "transferConcurrency": { + "label": "Gelijktijdige bestandsoverdracht", + "description": "Hoeveel bestanden de lokale/externe manager naast elkaar tegelijkertijd uploadt of downloadt. Verlaag deze waarde als uw server het aantal SFTP-kanalen beperkt." + }, + "confirmBeforeTrash": { + "label": "Controleer voordat u bestanden naar de prullenbak verplaatst.", + "description": "Vraag eerst toestemming voordat je bestanden van een externe locatie naar de prullenbak verplaatst. Voor definitieve verwijdering is nog steeds bevestiging vereist." + } + } + }, + "hostCapability": { + "label": "Bestandsbeheerder" + }, "fileManager": { "noHostSelected": "Geen host geselecteerd", "initializingEditor": "Editor wordt geïnitialiseerd...", @@ -19,7 +57,7 @@ "selectedFiles": "Geselecteerde bestanden", "andMoreFiles": "en {{count}} meer...", "compress": "Comprimeren", - "compressingFiles": "Het comprimeren van {{count}} items naar {{name}}...", + "compressingFiles": "{{count}} items comprimeren tot {{name}}...", "filesCompressedSuccessfully": "{{name}} succesvol aangemaakt", "compressFailed": "Compressie mislukt", "edit": "Bewerking", @@ -34,6 +72,7 @@ "rename": "Naam wijzigen", "uploading": "Bezig met uploaden...", "uploadingFile": "Bezig met uploaden {{name}}...", + "uploadingChunk": "Uploaden {{name}}: {{percent}}% (deel {{chunk}} van {{total}})", "fileName": "Bestandsnaam", "folderName": "Mapnaam", "fileUploadedSuccessfully": "Bestand \"{{name}}\" succesvol geüpload", @@ -290,6 +329,7 @@ "connecting": "Verbinden...", "connectedSuccessfully": "Verbinding succesvol tot stand gebracht.", "totpVerificationFailed": "TOTP-verificatie mislukt", + "browserSignInFailed": "Aanmelden is mislukt. Probeer het opnieuw.", "authenticationFailed": "Authenticatie mislukt", "incorrectPassphrase": "Onjuiste wachtzin. Probeer het opnieuw.", "verificationCodePrompt": "Verificatiecode:", @@ -326,7 +366,24 @@ "cannotLoadPdf": "Kan PDF niet laden", "pdfLoadError": "Er is een fout opgetreden bij het laden van dit PDF-bestand.", "loadingPdf": "PDF laden...", - "loadingPage": "Pagina laden..." + "loadingPage": "Pagina laden...", + "cancel": "Annuleren", + "copiedItems_one": "Gekopieerd {{count}} item", + "copiedItems_other": "Gekopieerde {{count}} items", + "deleteCopiedFileFailed": "Kon de kopie van {{name}}niet verwijderen: {{error}}", + "dragMovedItems_one": "Item {{count}} verplaatst naar {{target}}", + "dragMovedItems_other": "Verplaatste {{count}} items naar {{target}}", + "moveBackFileFailed": "Kon {{name}} niet terugzetten: {{error}}", + "terminal": "Terminal: {{host}} ({{path}})", + "dragToDesktop": "{{name}} naar het bureaublad slepen", + "dragFilesToDesktop": "{{count}} bestanden naar het bureaublad slepen", + "folderDragUnsupported": "Het slepen van mappen naar het bureaublad wordt momenteel nog niet ondersteund.", + "saveToDesktopFailed": "Opslaan mislukt: {{error}}", + "dragFailedDetail": "Slepen mislukt: {{error}}", + "videoUnsupported": "Uw browser kan dit videoformaat niet afspelen.", + "downloadToPlay": "Download het om het elders te spelen.", + "cannotPreviewType": "Kan dit bestandstype niet bekijken.", + "cannotPreviewTypeHint": "Dit bestandstype heeft geen voorbeeldweergave. Download het om het in een andere app te openen." }, "sftpTransfer": { "title": "SFTP", @@ -374,42 +431,12 @@ }, "hosts": { "fileManager": "Bestandsbeheerder", - "tabFiles": "Bestanden", - "enableFileManagerMonitor": "Bestandsbeheer inschakelen", - "enableFileManagerMonitorDesc": "Blader door en beheer bestanden op deze host via SFTP.", - "scpLegacyLabel": "SCP Legacy-modus", - "scpLegacyDesc": "Gebruik de traditionele bestandsoverdrachtsmethode voor servers die het SFTP-subsysteem niet ondersteunen (bijvoorbeeld ingebouwde of minimale SSH-servers).", - "defaultPathLabel": "Standaardpad", - "fileManagerPathHint": "De map die geopend moet worden wanneer de bestandsbeheerder voor deze host wordt gestart.", "fileManagerUrlCopied": "URL van bestandsbeheerder gekopieerd", "copyFileManagerUrlAction": "Kopieer de URL van de bestandsbeheerder", "docsLink": "Documenten bekijken", "hostNotFound": "Host niet gevonden", "loadingHost": "Host wordt geladen..." }, - "settings": { - "host": { - "enable": { - "label": "Bestandsbeheer inschakelen" - }, - "defaultPath": { - "label": "Standaardpad" - }, - "scpLegacy": { - "label": "SCP Legacy-modus" - } - }, - "user": { - "transferConcurrency": { - "label": "Gelijktijdige bestandsoverdracht", - "description": "Hoeveel bestanden de lokale/externe manager naast elkaar tegelijkertijd uploadt of downloadt. Verlaag deze waarde als uw server het aantal SFTP-kanalen beperkt." - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "Bestanden" - }, "onboarding": { "feature_files": "Bestandsbeheerder", "feature_files_desc": "Blader door bestanden, upload ze, download ze en bewerk ze via SFTP zonder de app te verlaten." @@ -437,7 +464,7 @@ "destinationPath": "Bestemmingspad", "destMustBeDirectory": "De bestemming moet een adresboek zijn voor overdrachten van meerdere items.", "goUp": "Ga omhoog", - "hostAuthRequired": "Authenticatie vereist — open eerst Bestandsbeheer op deze host.", + "hostAuthRequired": "Authenticatie vereist. Open eerst Bestandsbeheer op deze host.", "hostConnecting": "Verbinding maken…", "hostConnectionFailed": "Verbinding mislukt", "hostDisconnected": "Niet verbonden", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "Je hebt gekozen voor SFTP per bestand.", "user_tar": "Je hebt gekozen voor een tar-archief.", - "tar_unavailable": "Tar is niet beschikbaar op een of beide hosts; in plaats daarvan wordt SFTP per bestand gebruikt.", - "windows_host": "Er wordt gebruikgemaakt van een Windows-host; tar wordt niet gebruikt.", - "auto_multi_large": "Automatisch: meerdere bestanden, waaronder een groot bestand ({{largestSize}}) met comprimeerbare gegevens — tar bundelt deze tot één overdracht.", - "auto_single_large_in_archive": "Auto: één groot bestand ({{largestSize}}) in deze set — SFTP per bestand.", - "auto_many_incompressible": "Automatisch: voornamelijk niet-comprimeerbare gegevens — SFTP per bestand.", - "auto_many_files": "Auto: veel bestanden ({{fileCount}}) — tar vermindert de overhead per bestand.", + "tar_unavailable": "Tar is niet beschikbaar op een of beide hosts, daarom wordt in plaats daarvan SFTP per bestand gebruikt.", + "windows_host": "Het betreft een Windows-host, dus tar wordt niet gebruikt.", + "auto_multi_large": "Auto: meerdere bestanden, waaronder een groot bestand ({{largestSize}}) met comprimeerbare gegevens. Tar bundelt ze tot één overdracht.", + "auto_single_large_in_archive": "Auto: één groot bestand ({{largestSize}}) in deze set, dus SFTP per bestand.", + "auto_many_incompressible": "Automatisch: meestal niet-comprimeerbare gegevens, dus SFTP per bestand.", + "auto_many_files": "Auto: veel bestanden ({{fileCount}}), tar vermindert de overhead per bestand.", "auto_default": "Automatisch: SFTP per bestand voor deze set." }, "methodTar": "Tar-archief", @@ -471,7 +498,7 @@ "metricsCompress": "Comprimeren op bron: {{duration}}", "metricsExtract": "Uitpakken op bestemming: {{duration}}", "metricsPrepare": "Bestemming voorbereiden: {{duration}}", - "metricsRouteBenchmark": "Route probe — direct: {{direct}}, relay: {{relay}}", + "metricsRouteBenchmark": "Route probe: direct {{direct}}, relay {{relay}}", "metricsSourceDelete": "Verwijderen uit de bron: {{duration}}", "metricsTotal": "Totaal: {{duration}}", "metricsTransfer": "Einde tot einde: {{throughput}} ({{duration}})", @@ -508,6 +535,9 @@ "transferError": "Overdracht mislukt", "transferFailedRetryHint": "Er zijn gedeeltelijke gegevens op de bestemming bewaard gebleven. De herhaalpoging wordt hervat zodra de verbinding hersteld is.", "transferPartialHint": "Overdracht mislukt: {{paths}}", - "transferSuccess": "Overdracht voltooid" + "transferSuccess": "Overdracht voltooid", + "metricsHopSourceRead": "Bron → server: {{throughput}}", + "metricsHopDestSftpWrite": "Server → bestemming (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Server → bestemming (lokaal): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/no_NO.json b/plugins/file-manager/locales/translated/no_NO.json index f243db57d..f6d1ca1c3 100644 --- a/plugins/file-manager/locales/translated/no_NO.json +++ b/plugins/file-manager/locales/translated/no_NO.json @@ -1,30 +1,68 @@ { + "nav": { + "files": "Files", + "sftp": "SFTP", + "openFileManager": "Åpne filutforsker" + }, + "permissions": { + "use": { + "title": "Use file manager", + "description": "Browse, edit and transfer files over SFTP." + } + }, + "settings": { + "host": { + "enable": { + "label": "Aktiver filutforsker", + "description": "Browse and edit files on this host over SFTP." + }, + "defaultPath": { + "label": "Standardsti" + }, + "scpLegacy": { + "label": "SCP Legacy Mode" + } + }, + "user": { + "transferConcurrency": { + "label": "Simultaneous File Transfers", + "description": "How many files the side by side local/remote manager uploads or downloads at the same time. Lower this if your server limits SFTP channels." + }, + "confirmBeforeTrash": { + "label": "Confirm before moving files to trash", + "description": "Ask before moving remote files to trash. Permanent deletion still requires confirmation." + } + } + }, + "hostCapability": { + "label": "Filbehandler" + }, "fileManager": { "noHostSelected": "Ingen vert valgt", - "initializingEditor": "Initialiserer redigeringsprogrammet...", + "initializingEditor": "Initializing editor...", "file": "Fil", "folder": "Mappe", "uploadFile": "Last opp fil", "downloadFile": "Last ned", - "extractArchive": "Utdragsarkiv", - "extractingArchive": "Uttrekker {{name}}...", + "extractArchive": "Pakk ut arkiv", + "extractingArchive": "Pakker ut {{name}}...", "archiveExtractedSuccessfully": "{{name}} ble pakket ut", "extractFailed": "Utpakking mislyktes", "compressFile": "Komprimer fil", "compressFiles": "Komprimer filer", - "compressFilesDesc": "Komprimer {{count}} elementer til et arkiv", + "compressFilesDesc": "Komprimer {{count}} elementer til ett arkiv", "archiveName": "Arkivnavn", "enterArchiveName": "Skriv inn arkivnavn...", - "compressionFormat": "Kompresjonsformat", + "compressionFormat": "Komprimeringsformat", "selectedFiles": "Valgte filer", - "andMoreFiles": "og {{count}} mer...", - "compress": "Komprimere", + "andMoreFiles": "og {{count}} til...", + "compress": "Komprimer", "compressingFiles": "Komprimerer {{count}} elementer til {{name}}...", "filesCompressedSuccessfully": "{{name}} ble opprettet", - "compressFailed": "Komprimeringen mislyktes", - "edit": "Redigere", - "preview": "Forhåndsvisning", - "previous": "Tidligere", + "compressFailed": "Komprimering mislyktes", + "edit": "Rediger", + "preview": "Forhåndsvis", + "previous": "Forrige", "next": "Neste", "pageXOfY": "Side {{current}} av {{total}}", "zoomOut": "Zoom ut", @@ -34,96 +72,97 @@ "rename": "Gi nytt navn", "uploading": "Laster opp...", "uploadingFile": "Laster opp {{name}}...", + "uploadingChunk": "Uploading {{name}}: {{percent}}% (part {{chunk}} of {{total}})", "fileName": "Filnavn", "folderName": "Mappenavn", - "fileUploadedSuccessfully": "Filen «{{name}}» ble lastet opp", - "failedToUploadFile": "Kunne ikke laste opp filen", - "uploadingFolderFiles": "Laster opp {{count}} fil(er)...", - "uploadedFolderFiles": "Lastet opp {{count}} fil(er)", - "uploadedFolderPartial": "Opplasting av {{uploaded}} fil(er), {{failed}} mislyktes", - "fileDownloadedSuccessfully": "Filen «{{name}}» er lastet ned", - "failedToDownloadFile": "Kunne ikke laste ned filen", - "fileCreatedSuccessfully": "Filen «{{name}}» er opprettet", - "folderCreatedSuccessfully": "Mappen «{{name}}» er opprettet", - "failedToCreateItem": "Kunne ikke opprette elementet", - "operationFailed": "{{operation}} operasjonen mislyktes for {{name}}: {{error}}", - "failedToResolveSymlink": "Klarte ikke å løse symbolsk lenke", - "itemsDeletedSuccessfully": "{{count}} elementer er slettet", + "fileUploadedSuccessfully": "Fil \"{{name}}\" ble lastet opp", + "failedToUploadFile": "Kunne ikke laste opp fil", + "uploadingFolderFiles": "Uploading {{count}} file(s)...", + "uploadedFolderFiles": "Uploaded {{count}} file(s) successfully", + "uploadedFolderPartial": "Uploaded {{uploaded}} file(s), {{failed}} failed", + "fileDownloadedSuccessfully": "Filen ble lastet ned", + "failedToDownloadFile": "Kunne ikke laste ned fil", + "fileCreatedSuccessfully": "Fil \"{{name}}\" ble opprettet", + "folderCreatedSuccessfully": "Mappe \"{{name}}\" ble opprettet", + "failedToCreateItem": "Kunne ikke opprette element", + "operationFailed": "{{operation}} mislyktes for {{name}}: {{error}}", + "failedToResolveSymlink": "Kunne ikke løse symbolske lenker", + "itemsDeletedSuccessfully": "{{count}} elementer ble slettet", "failedToDeleteItems": "Kunne ikke slette elementer", - "sudoPasswordRequired": "Administratorpassord kreves", - "enterSudoPassword": "Skriv inn sudo-passordet for å fortsette denne operasjonen", - "sudoPassword": "Sudo-passord", - "sudoOperationFailed": "Sudo-operasjonen mislyktes", - "sudoAuthFailed": "Sudo-autentisering mislyktes", - "dragFilesToUpload": "Slipp filer her for å laste dem opp", - "dropToUploadHere": "Slipp for å laste opp her", - "dropToDownloadHere": "Slipp for å laste ned her", - "localFiles": "Lokalt", - "showLocalFiles": "Vis lokale filer (delt visning)", - "hideLocalFiles": "Skjul lokale filer", - "localHome": "Hjemmappe", - "localPathPlaceholder": "Lokal mappebane", - "localShowHidden": "Vis skjulte filer", - "localHideHidden": "Skjul skjulte filer", - "localRevealInFileManager": "Avslør i systemfilbehandleren", - "localCannotOpenFolder": "Kan ikke åpne mappen", + "sudoPasswordRequired": "Administrator Password Required", + "enterSudoPassword": "Enter sudo password to continue this operation", + "sudoPassword": "Sudo password", + "sudoOperationFailed": "Sudo operation failed", + "sudoAuthFailed": "Sudo authentication failed", + "dragFilesToUpload": "Slipp filer her for å laste opp", + "dropToUploadHere": "Drop to upload here", + "dropToDownloadHere": "Drop to download here", + "localFiles": "Lokal", + "showLocalFiles": "Show local files (split view)", + "hideLocalFiles": "Hide local files", + "localHome": "Home folder", + "localPathPlaceholder": "Local folder path", + "localShowHidden": "Show hidden files", + "localHideHidden": "Hide hidden files", + "localRevealInFileManager": "Reveal in system file manager", + "localCannotOpenFolder": "Cannot open folder", "localItemCount": "{{count}} elementer", "localSelectedCount": "{{count}} valgt", "back": "Tilbake", - "forward": "Framover", - "up": "Opp", - "kind": "Type", - "localUploadingProgress": "Laster opp {{current}} av {{total}}", - "localDownloadingProgress": "Laster ned {{current}} av {{total}}", - "localTransferInFlight": "{{count}} med en gang", - "localPreparingDownload": "Forbereder nedlasting ...", - "localTransferCancelled": "Overføringen er avbrutt", - "localNothingToTransfer": "Ingenting å overføre", - "localUploadComplete": "Opplastede {{count}} fil(er)", - "localUploadFailed": "Opplastingen mislyktes", - "localUploadPartial": "Opplasting av {{done}} fil(er), {{failed}} mislyktes", - "localDownloadComplete": "Lastet ned {{count}} fil(er)", - "localDownloadFailed": "Nedlastingen mislyktes", - "localDownloadPartial": "Nedlasting av {{done}} fil(er), {{failed}} mislyktes", - "localReplaceExistingPrompt": "{{count}} element(er) finnes allerede i denne mappen. Vil du erstatte dem?", + "forward": "Forward", + "up": "Up", + "kind": "Kind", + "localUploadingProgress": "Uploading {{current}} of {{total}}", + "localDownloadingProgress": "Downloading {{current}} of {{total}}", + "localTransferInFlight": "{{count}} at once", + "localPreparingDownload": "Preparing download...", + "localTransferCancelled": "Transfer cancelled", + "localNothingToTransfer": "Nothing to transfer", + "localUploadComplete": "Uploaded {{count}} file(s)", + "localUploadFailed": "Upload failed", + "localUploadPartial": "Uploaded {{done}} file(s), {{failed}} failed", + "localDownloadComplete": "Downloaded {{count}} file(s)", + "localDownloadFailed": "Nedlasting mislyktes", + "localDownloadPartial": "Downloaded {{done}} file(s), {{failed}} failed", + "localReplaceExistingPrompt": "{{count}} item(s) already exist in this folder. Replace them?", "localReplace": "Erstatt", - "localSkipExisting": "Hopp over", - "localSkippedExisting": "Hoppet over {{count}} eksisterende element(er)", - "localUnsafeNamesSkipped": "Hoppet over {{count}} elementer hvis navn ikke kan brukes på denne datamaskinen", - "localOpen": "Åpne", - "localOpenFolder": "Åpne mappen", - "localUploadToRemote": "Last opp til server", - "localUploadToRemoteMany": "Last opp {{count}} elementer til serveren", - "localMoveToTrash": "Flytt til papirkurven", - "localMoveToTrashMany": "Flytt {{count}} elementer til papirkurven", - "localTrashConfirmSingle": "Flytte «{{name}}» til papirkurven?", - "localTrashConfirmFolder": "Flytte mappen «{{name}}» og alt innholdet til papirkurven?", - "localTrashConfirmMany": "Flytte {{count}} elementer til papirkurven?", - "localTrashed": "Flyttet {{count}} element(er) til papirkurven", - "localTrashFailed": "Kunne ikke flytte til papirkurven", - "localRenameFailed": "Mislyktes i å gi nytt navn", - "localCreateFailed": "Kunne ikke opprette elementet", - "goToParentFolder": "Gå til overordnet mappe", - "resizeSidebar": "Dra for å endre størrelsen på sidefeltet (dobbeltklikk for å tilbakestille)", - "resizeLocalPane": "Dra for å endre størrelsen på den lokale ruten (dobbeltklikk for å tilbakestille)", - "columns": "Kolonner", - "columnsHint": "Høyreklikk for å velge kolonner", + "localSkipExisting": "Skip", + "localSkippedExisting": "Skipped {{count}} existing item(s)", + "localUnsafeNamesSkipped": "Skipped {{count}} item(s) whose names cannot be used on this computer", + "localOpen": "Open", + "localOpenFolder": "Open folder", + "localUploadToRemote": "Upload to server", + "localUploadToRemoteMany": "Upload {{count}} items to server", + "localMoveToTrash": "Move to Trash", + "localMoveToTrashMany": "Move {{count}} items to Trash", + "localTrashConfirmSingle": "Move \"{{name}}\" to the Trash?", + "localTrashConfirmFolder": "Move the folder \"{{name}}\" and all its contents to the Trash?", + "localTrashConfirmMany": "Move {{count}} items to the Trash?", + "localTrashed": "Moved {{count}} item(s) to the Trash", + "localTrashFailed": "Could not move to the Trash", + "localRenameFailed": "Rename failed", + "localCreateFailed": "Could not create item", + "goToParentFolder": "Go to parent folder", + "resizeSidebar": "Drag to resize the sidebar (double-click to reset)", + "resizeLocalPane": "Drag to resize the local pane (double-click to reset)", + "columns": "Columns", + "columnsHint": "Right-click to choose columns", "emptyFolder": "Denne mappen er tom", "searchFiles": "Søk i filer...", "upload": "Last opp", - "selectHostToStart": "Velg en vert for å starte filbehandling", - "sshRequiredForFileManager": "Filbehandleren krever SSH. Denne verten har ikke SSH aktivert.", + "selectHostToStart": "Velg en vert for å starte filhåndtering", + "sshRequiredForFileManager": "File manager requires SSH. This host does not have SSH enabled.", "failedToConnect": "Kunne ikke koble til SSH", - "failedToLoadDirectory": "Kunne ikke laste inn katalogen", + "failedToLoadDirectory": "Kunne ikke laste katalog", "noSSHConnection": "Ingen SSH-tilkobling tilgjengelig", - "copy": "Kopiere", - "cut": "Kutt", + "copy": "Kopier", + "cut": "Klipp ut", "paste": "Lim inn", - "copyPath": "Kopier bane", + "copyPath": "Kopier sti", "copyPaths": "Kopier stier", "delete": "Slett", - "properties": "Eiendommer", - "refresh": "Forfriske", + "properties": "Egenskaper", + "refresh": "Oppdater", "downloadFiles": "Last ned {{count}} filer til nettleseren", "copyFiles": "Kopier {{count}} elementer", "cutFiles": "Klipp ut {{count}} elementer", @@ -132,96 +171,96 @@ "filesCutToClipboard": "{{count}} elementer klippet til utklippstavlen", "pathCopiedToClipboard": "Sti kopiert til utklippstavlen", "pathsCopiedToClipboard": "{{count}} stier kopiert til utklippstavlen", - "failedToCopyPath": "Kunne ikke kopiere banen til utklippstavlen", - "copyFolderLink": "Kopier lenke til mappe", - "copyCurrentFolderLink": "Kopier lenke til gjeldende mappe", - "folderLinkCopied": "Mappelenke kopiert til utklippstavlen", - "failedToCopyFolderLink": "Kunne ikke kopiere mappelenken", + "failedToCopyPath": "Kunne ikke kopiere sti", + "copyFolderLink": "Copy Link to Folder", + "copyCurrentFolderLink": "Copy Link to Current Folder", + "folderLinkCopied": "Folder link copied to clipboard", + "failedToCopyFolderLink": "Failed to copy folder link", "movedItems": "Flyttet {{count}} elementer", - "failedToDeleteItem": "Kunne ikke slette elementet", - "itemRenamedSuccessfully": "{{type}} har fått nytt navn", - "failedToRenameItem": "Kunne ikke gi nytt navn til elementet", + "failedToDeleteItem": "Kunne ikke slette element", + "itemRenamedSuccessfully": "{{type}} fikk nytt navn", + "failedToRenameItem": "Kunne ikke gi element nytt navn", "download": "Last ned", - "openExternalEditor": "Åpne eksternt", - "chooseExternalEditor": "Velg ekstern editor", - "externalEditorSelected": "Ekstern redigerer valgt", - "externalEditorDesktopOnly": "Ekstern editor er bare tilgjengelig i skrivebordsappen", - "externalEditorOpened": "Åpnet i ekstern editor. Hvis du lagrer der, lastes endringene opp tilbake til serveren.", - "failedToOpenExternalEditor": "Kunne ikke åpne ekstern editor", - "failedToSelectExternalEditor": "Kunne ikke velge ekstern redigeringsprogram", + "openExternalEditor": "Open externally", + "chooseExternalEditor": "Choose external editor", + "externalEditorSelected": "External editor selected", + "externalEditorDesktopOnly": "External editor is only available in the desktop app", + "externalEditorOpened": "Opened in external editor. Saving there will upload changes back to the server.", + "failedToOpenExternalEditor": "Failed to open external editor", + "failedToSelectExternalEditor": "Failed to select external editor", "permissions": "Tillatelser", "size": "Størrelse", - "modified": "Modifisert", + "modified": "Endret", "path": "Sti", "confirmDelete": "Er du sikker på at du vil slette {{name}}?", "permissionDenied": "Tillatelse nektet", "serverError": "Serverfeil", - "fileSavedSuccessfully": "Filen er lagret", - "failedToSaveFile": "Kunne ikke lagre filen", - "confirmDeleteSingleItem": "Er du sikker på at du vil slette «{{name}}» permanent?", + "fileSavedSuccessfully": "Filen ble lagret", + "failedToSaveFile": "Kunne ikke lagre fil", + "confirmDeleteSingleItem": "Er du sikker på at du vil slette \"{{name}}\" permanent?", "confirmDeleteMultipleItems": "Er du sikker på at du vil slette {{count}} elementer permanent?", - "confirmDeleteMultipleItemsWithFolders": "Er du sikker på at du vil slette {{count}} elementer permanent? Dette inkluderer mapper og innholdet i dem.", - "confirmDeleteFolder": "Er du sikker på at du vil slette mappen «{{name}}» og alt innholdet i den permanent?", - "permanentDeleteWarning": "Denne handlingen kan ikke angres. Elementet/elementene vil bli permanent slettet fra serveren.", - "moveToTrashWarning": "Elementet/elementene vil bli flyttet til Termix-papirkurven og kan gjenopprettes før oppbevaringsperioden utløper.", - "itemsMovedToTrash": "{{count}} element(er) flyttet til papirkurven", - "trash": "Søppel", - "trashDescription": "Slettede elementer lagres i {{days}} dag(er) på denne verten.", - "trashLoadFailed": "Kunne ikke laste inn papirkurven", - "trashEmpty": "Papirkurven er tom", - "trashRestore": "Restaurere", - "trashRestored": "Gjenopprettet {{name}}", - "trashRestoreFailed": "Kunne ikke gjenopprette elementet. Den opprinnelige banen finnes kanskje allerede.", - "trashDeletePermanently": "Slett permanent", - "trashDeleteConfirm": "Vil du slette {{name}}permanent? Dette kan ikke angres.", - "trashPermanentlyDeleted": "Slettet permanent {{name}}", - "trashDeleteFailed": "Kunne ikke slette elementet permanent", - "trashEmptyAction": "Tøm søppelbøtten", - "trashEmptyConfirm": "Vil du slette alle elementene i papirkurven permanent? Dette kan ikke angres.", - "trashEmptied": "Søppelet tømt", - "trashRetention": "Automatisk opprydding etter (dager)", - "trashRetentionSaved": "Oppbevaring av søppel er oppdatert", - "trashRetentionFailed": "Kunne ikke oppdatere papirkurven", - "trashUnavailableConfirm": "Dette elementet kan ikke flyttes til papirkurven, vanligvis fordi det er på et annet filsystem eller krever utvidede tillatelser. Slette det permanent i stedet?", - "recent": "Nylig", + "confirmDeleteMultipleItemsWithFolders": "Er du sikker på at du vil slette {{count}} elementer permanent? Dette inkluderer mapper og innholdet deres.", + "confirmDeleteFolder": "Er du sikker på at du vil slette mappen \"{{name}}\" og alt innholdet permanent?", + "permanentDeleteWarning": "Denne handlingen kan ikke angres. Elementene blir slettet permanent fra serveren.", + "moveToTrashWarning": "The item(s) will be moved to the Termix Trash and can be restored before the retention period expires.", + "itemsMovedToTrash": "{{count}} item(s) moved to Trash", + "trash": "Trash", + "trashDescription": "Deleted items are retained for {{days}} day(s) on this host.", + "trashLoadFailed": "Failed to load Trash", + "trashEmpty": "Trash is empty", + "trashRestore": "Restore", + "trashRestored": "Restored {{name}}", + "trashRestoreFailed": "Failed to restore item. The original path may already exist.", + "trashDeletePermanently": "Delete permanently", + "trashDeleteConfirm": "Permanently delete {{name}}? This cannot be undone.", + "trashPermanentlyDeleted": "Permanently deleted {{name}}", + "trashDeleteFailed": "Failed to permanently delete item", + "trashEmptyAction": "Empty Trash", + "trashEmptyConfirm": "Permanently delete every item in Trash? This cannot be undone.", + "trashEmptied": "Trash emptied", + "trashRetention": "Automatic cleanup after (days)", + "trashRetentionSaved": "Trash retention updated", + "trashRetentionFailed": "Failed to update Trash retention", + "trashUnavailableConfirm": "This item cannot be moved to Trash, usually because it is on another filesystem or requires elevated permissions. Delete it permanently instead?", + "recent": "Nylige", "pinned": "Festet", "folderShortcuts": "Mappesnarveier", - "failedToReconnectSSH": "Kunne ikke koble til SSH-økten på nytt", - "openTerminalHere": "Åpne terminalen her", - "run": "Løp", - "openTerminalInFolder": "Åpne terminalen i denne mappen", - "openTerminalInFileLocation": "Åpne terminalen på filplassering", - "runningFile": "Løping - {{file}}", + "failedToReconnectSSH": "Kunne ikke koble til SSH-økt på nytt", + "openTerminalHere": "Åpne terminal her", + "run": "Kjør", + "openTerminalInFolder": "Åpne terminal i denne mappen", + "openTerminalInFileLocation": "Åpne terminal ved filplassering", + "runningFile": "Kjører - {{file}}", "onlyRunExecutableFiles": "Kan bare kjøre kjørbare filer", "directories": "Kataloger", - "removedFromRecentFiles": "Fjernet «{{name}}» fra nylige filer", + "removedFromRecentFiles": "Fjernet \"{{name}}\" fra nylige filer", "removeFailed": "Fjerning mislyktes", - "unpinnedSuccessfully": "«{{name}}» er løsnet", - "unpinFailed": "Løsne mislyktes", - "removedShortcut": "Fjernet snarveien «{{name}}»", - "removeShortcutFailed": "Fjerning av snarvei mislyktes", - "clearedAllRecentFiles": "Slettet alle nylige filer", - "clearFailed": "Fjerning mislyktes", + "unpinnedSuccessfully": "Fjernet festing av \"{{name}}\"", + "unpinFailed": "Fjerning av festing mislyktes", + "removedShortcut": "Fjernet snarvei \"{{name}}\"", + "removeShortcutFailed": "Kunne ikke fjerne snarvei", + "clearedAllRecentFiles": "Tømte alle nylige filer", + "clearFailed": "Tømming mislyktes", "removeFromRecentFiles": "Fjern fra nylige filer", - "clearAllRecentFiles": "Fjern alle nylige filer", - "unpinFile": "Løsne filen", + "clearAllRecentFiles": "Tøm alle nylige filer", + "unpinFile": "Løsne fil", "removeShortcut": "Fjern snarvei", - "pinFile": "Fest filen", - "addToShortcuts": "Legg til i snarveier", - "pasteFailed": "Lime inn mislyktes", - "noUndoableActions": "Ingen angrebare handlinger", + "pinFile": "Fest fil", + "addToShortcuts": "Legg til snarveier", + "pasteFailed": "Innliming mislyktes", + "noUndoableActions": "Ingen handlinger kan angres", "undoCopySuccess": "Angret kopiering: Slettet {{count}} kopierte filer", - "undoCopyFailedDelete": "Angre mislyktes: Kunne ikke slette noen kopierte filer", - "undoCopyFailedNoInfo": "Angre mislyktes: Finner ikke informasjon om den kopierte filen", - "undoMoveSuccess": "Angret flytteoperasjon: Flyttet {{count}} filer tilbake til opprinnelig plassering", - "undoMoveFailedMove": "Angre mislyktes: Kunne ikke flytte noen filer tilbake", - "undoMoveFailedNoInfo": "Angre mislyktes: Finner ikke informasjon om den flyttede filen", - "undoDeleteNotSupported": "Sletteoperasjonen kan ikke angres: Filene er slettet permanent fra serveren", - "undoTypeNotSupported": "Ustøttet angreoperasjonstype", - "undoOperationFailed": "Angreoperasjonen mislyktes", + "undoCopyFailedDelete": "Angre mislyktes: Kunne ikke slette kopierte filer", + "undoCopyFailedNoInfo": "Angre mislyktes: Fant ingen info om kopierte filer", + "undoMoveSuccess": "Angret flytting: Flyttet {{count}} filer tilbake", + "undoMoveFailedMove": "Angre mislyktes: Kunne ikke flytte filer tilbake", + "undoMoveFailedNoInfo": "Angre mislyktes: Fant ingen info om flyttede filer", + "undoDeleteNotSupported": "Sletteoperasjon kan ikke angres: Filer er slettet permanent fra server", + "undoTypeNotSupported": "Ikke støttet angretype", + "undoOperationFailed": "Angreoperasjon mislyktes", "unknownError": "Ukjent feil", - "confirm": "Bekrefte", - "find": "Finne...", + "confirm": "Bekreft", + "find": "Finn...", "replace": "Erstatt", "downloadInstead": "Last ned i stedet", "keyboardShortcuts": "Tastatursnarveier", @@ -230,189 +269,177 @@ "search": "Søk", "findNext": "Finn neste", "findPrevious": "Finn forrige", - "save": "Spare", - "selectAll": "Velg alle", + "save": "Lagre", + "selectAll": "Marker alt", "undo": "Angre", "redo": "Gjør om", "moveLineUp": "Flytt linje opp", "moveLineDown": "Flytt linje ned", "toggleComment": "Veksle kommentar", "autoComplete": "Autofullfør", - "imageLoadError": "Kunne ikke laste inn bildet", + "imageLoadError": "Kunne ikke laste bilde", "startTyping": "Begynn å skrive...", "unknownSize": "Ukjent størrelse", "fileIsEmpty": "Filen er tom", "largeFileWarning": "Advarsel om stor fil", - "largeFileWarningDesc": "Denne filen er {{size}} stor, noe som kan forårsake ytelsesproblemer når den åpnes som tekst.", + "largeFileWarningDesc": "Denne filen er {{size}} stor, noe som kan gi ytelsesproblemer når den åpnes som tekst.", "fileNotFoundAndRemoved": "Filen «{{name}}» ble ikke funnet og er fjernet fra nylige/festede filer", - "failedToLoadFile": "Kunne ikke laste inn filen: {{error}}", - "serverErrorOccurred": "Det oppsto en serverfeil. Prøv igjen senere.", - "autoSaveFailed": "Automatisk lagring mislyktes", - "fileAutoSaved": "Fil lagret automatisk", + "failedToLoadFile": "Kunne ikke laste fil: {{error}}", + "serverErrorOccurred": "Serverfeil oppstod. Prøv igjen senere.", + "autoSaveFailed": "Autolagring mislyktes", + "fileAutoSaved": "Filen ble autolagret", "moveFileFailed": "Kunne ikke flytte {{name}}", - "moveOperationFailed": "Flytteoperasjonen mislyktes", - "canOnlyCompareFiles": "Kan bare sammenligne to filer", - "comparingFiles": "Sammenligning av filer: {{file1}} og {{file2}}", - "dragFailed": "Draoperasjonen mislyktes", - "filePinnedSuccessfully": "Filen «{{name}}» er låst", - "pinFileFailed": "Kunne ikke feste filen", + "moveOperationFailed": "Flytteoperasjon mislyktes", + "canOnlyCompareFiles": "Kan kun sammenligne to filer", + "comparingFiles": "Sammenligner filer: {{file1}} og {{file2}}", + "dragFailed": "Draoperasjon mislyktes", + "filePinnedSuccessfully": "Filen «{{name}}» ble festet", + "pinFileFailed": "Kunne ikke feste fil", "fileUnpinnedSuccessfully": "Filen «{{name}}» ble løsnet", - "unpinFileFailed": "Kunne ikke løsne filen", - "shortcutAddedSuccessfully": "Mappsnarveien «{{name}}» er lagt til", + "unpinFileFailed": "Kunne ikke løsne fil", + "shortcutAddedSuccessfully": "Mappesnarvei «{{name}}» ble lagt til", "addShortcutFailed": "Kunne ikke legge til snarvei", - "operationCompletedSuccessfully": "{{operation}} {{count}} elementer ble vellykket", + "operationCompletedSuccessfully": "{{operation}} {{count}} elementer", "operationCompleted": "{{operation}} {{count}} elementer", - "downloadFileSuccess": "Fil {{name}} er lastet ned", - "downloadFileFailed": "Nedlastingen mislyktes", - "downloadingFile": "Laster ned {{name}}…", + "downloadFileSuccess": "Fil {{name}} ble lastet ned", + "downloadFileFailed": "Nedlasting mislyktes", + "downloadingFile": "Downloading {{name}}…", "downloadProgressBytes": "{{transferred}} / {{total}}", "moveTo": "Flytt til {{name}}", - "diffCompareWith": "Differansesammenligning med {{name}}", + "diffCompareWith": "Sammenlign forskjeller med {{name}}", "dragOutsideToDownload": "Dra utenfor vinduet for å laste ned ({{count}} filer)", - "newFolderDefault": "Ny mappe", - "newFileDefault": "Nyfil.txt", + "newFolderDefault": "NyMappe", + "newFileDefault": "NyFil.txt", "successfullyMovedItems": "Flyttet {{count}} elementer til {{target}}", - "move": "Flytte", - "searchInFile": "Søk i filen (Ctrl+F)", - "showKeyboardShortcuts": "Vis hurtigtaster", - "decreaseFontSize": "Reduser skriftstørrelsen", - "increaseFontSize": "Øk skriftstørrelsen", - "startWritingMarkdown": "Begynn å skrive innholdet ditt med nedsatt pris...", - "loadingFileComparison": "Laster inn filsammenligning ...", + "move": "Flytt", + "searchInFile": "Søk i fil (Ctrl+F)", + "showKeyboardShortcuts": "Vis tastatursnarveier", + "decreaseFontSize": "Decrease font size", + "increaseFontSize": "Increase font size", + "startWritingMarkdown": "Begynn å skrive markdown-innhold...", + "loadingFileComparison": "Laster filsammenligning...", "reload": "Last inn på nytt", - "compare": "Sammenligne", + "compare": "Sammenlign", "sideBySide": "Side om side", - "inline": "Innebygd", - "fileComparison": "Filsammenligning: {{file1}} vs. {{file2}}", - "fileTooLarge": "Filen er for stor: {{error}}", - "sshConnectionFailed": "SSH-tilkoblingen mislyktes. Sjekk tilkoblingen din til {{name}} ({{ip}}:{{port}})", - "loadFileFailed": "Kunne ikke laste inn filen: {{error}}", + "inline": "Inline", + "fileComparison": "Filsammenligning: {{file1}} vs {{file2}}", + "fileTooLarge": "Fil for stor: {{error}}", + "sshConnectionFailed": "SSH-tilkobling mislyktes. Kontroller tilkoblingen til {{name}} ({{ip}}:{{port}})", + "loadFileFailed": "Kunne ikke laste fil: {{error}}", "connecting": "Kobler til...", "connectedSuccessfully": "Tilkoblet", "totpVerificationFailed": "TOTP-verifisering mislyktes", - "authenticationFailed": "Autentisering mislyktes", - "incorrectPassphrase": "Feil passordfrase. Prøv på nytt.", - "verificationCodePrompt": "Verifiseringskode:", + "browserSignInFailed": "Sign-in failed. Please try again.", + "authenticationFailed": "Authentication failed", + "incorrectPassphrase": "Incorrect passphrase. Please try again.", + "verificationCodePrompt": "Verification code:", "changePermissions": "Endre tillatelser", "currentPermissions": "Gjeldende tillatelser", "owner": "Eier", "group": "Gruppe", "others": "Andre", - "read": "Lese", - "write": "Skrive", - "execute": "Henrette", - "permissionsChangedSuccessfully": "Tillatelsene er endret", + "read": "Les", + "write": "Skriv", + "execute": "Kjør", + "permissionsChangedSuccessfully": "Tillatelser endret", "failedToChangePermissions": "Kunne ikke endre tillatelser", "name": "Navn", "sortByName": "Navn", - "sortByDate": "Dato endret", + "sortByDate": "Date Modified", "sortBySize": "Størrelse", - "ascending": "Stigende", - "descending": "Synkende", - "root": "Rot", - "new": "Ny", - "sortBy": "Sorter etter", - "items": "Elementer", - "selected": "Valgt", - "editor": "Redaktør", - "octal": "Oktal", - "storage": "Lagring", + "ascending": "Ascending", + "descending": "Descending", + "root": "Root", + "new": "New", + "sortBy": "Sort By", + "items": "Items", + "selected": "Selected", + "editor": "Editor", + "octal": "Octal", + "storage": "Storage", "disk": "Disk", "used": "Brukt", "of": "av", - "toggleSidebar": "Slå sidefeltet av/på", - "compactLayout": "Bruk kompakt oppsett", - "comfortableLayout": "Bruk komfortabel layout", - "cannotLoadPdf": "Kan ikke laste inn PDF-filen", - "pdfLoadError": "Det oppsto en feil under lasting av denne PDF-filen.", - "loadingPdf": "Laster inn PDF-filen...", - "loadingPage": "Laster inn side..." + "toggleSidebar": "Slå av/på sidepanel", + "compactLayout": "Use compact layout", + "comfortableLayout": "Use comfortable layout", + "cannotLoadPdf": "Cannot load PDF", + "pdfLoadError": "There was an error loading this PDF file.", + "loadingPdf": "Loading PDF...", + "loadingPage": "Loading page...", + "cancel": "Avbryt", + "copiedItems_one": "Copied {{count}} item", + "copiedItems_other": "Copied {{count}} items", + "deleteCopiedFileFailed": "Could not delete the copy of {{name}}: {{error}}", + "dragMovedItems_one": "Moved {{count}} item to {{target}}", + "dragMovedItems_other": "Moved {{count}} items to {{target}}", + "moveBackFileFailed": "Could not move {{name}} back: {{error}}", + "terminal": "Terminal: {{host}} ({{path}})", + "dragToDesktop": "Dragging {{name}} to the desktop", + "dragFilesToDesktop": "Dragging {{count}} files to the desktop", + "folderDragUnsupported": "Dragging folders to the desktop is not supported yet", + "saveToDesktopFailed": "Save failed: {{error}}", + "dragFailedDetail": "Drag failed: {{error}}", + "videoUnsupported": "Your browser cannot play this video format.", + "downloadToPlay": "Download to play it elsewhere", + "cannotPreviewType": "Cannot preview this file type", + "cannotPreviewTypeHint": "This file type has no preview. Download it to open it in another app." }, "sftpTransfer": { "title": "SFTP", - "description": "Overfør filer mellom to SSH-verter.", - "sourceServer": "Kildeserver", - "destinationServer": "Destinasjonsserver", - "selectHost": "Velg vert", + "description": "Transfer files between two SSH hosts.", + "sourceServer": "Source Server", + "destinationServer": "Destination Server", + "selectHost": "Select host", "noHostSelected": "Ingen vert valgt", - "move": "Flytte", - "copy": "Kopiere", + "move": "Flytt", + "copy": "Kopier", "upload": "Last opp", - "itemsSelected": "{{count}} element valgt", - "itemsSelected_other": "{{count}} elementer valgt", - "ready": "Ferdig", - "loadingHosts": "Laster inn verter ...", + "itemsSelected": "{{count}} item selected", + "itemsSelected_other": "{{count}} items selected", + "ready": "Klar", + "loadingHosts": "Laster verter...", "name": "Navn", - "modified": "Modifisert", + "modified": "Endret", "size": "Størrelse", - "noFiles": "Ingen filer", - "open": "Åpne", - "up": "Opp", - "refresh": "Forfriske", - "copyToTarget": "Kopier til målkatalogen", + "noFiles": "No files", + "open": "Open", + "up": "Up", + "refresh": "Oppdater", + "copyToTarget": "Copy to Target Directory", "rename": "Gi nytt navn", "delete": "Slett", - "editPermissions": "Rediger tillatelser", + "editPermissions": "Edit Permissions", "createNewFolder": "Opprett ny mappe", - "deleteSelectedItems": "Slett valgte elementer", - "deleteConfirm": "Slette {{count}} valgt element?", - "deleteConfirm_other": "Slette {{count}} valgte elementer?", - "cancel": "Kansellere", - "save": "Spare", - "folderCreated": "Mappe opprettet", - "itemRenamed": "Elementet har fått nytt navn", - "actionFailed": "Handlingen mislyktes", - "itemsDeleted": "{{count}} element slettet", - "itemsDeleted_other": "{{count}} elementer slettet", - "deleteFailed": "Slettingen mislyktes", - "permissionsUpdated": "Tillatelser oppdatert", - "noRemoteSessionConnected": "Ingen ekstern økt tilkoblet", - "failedToListFiles": "Kunne ikke liste opp filer", - "failedToRefresh": "Kunne ikke laste inn på nytt", - "destinationInsideSource": "Destinasjonen kan ikke være innenfor den valgte kildebanen.", - "sameHostNoOp": "Kilde og destinasjon er i samme mappe." + "deleteSelectedItems": "Delete Selected Items", + "deleteConfirm": "Delete {{count}} selected item?", + "deleteConfirm_other": "Delete {{count}} selected items?", + "cancel": "Avbryt", + "save": "Lagre", + "folderCreated": "Folder created", + "itemRenamed": "Item renamed", + "actionFailed": "Action failed", + "itemsDeleted": "{{count}} item deleted", + "itemsDeleted_other": "{{count}} items deleted", + "deleteFailed": "Delete failed", + "permissionsUpdated": "Permissions updated", + "noRemoteSessionConnected": "No remote session connected", + "failedToListFiles": "Kunne ikke liste filer", + "failedToRefresh": "Failed to refresh", + "destinationInsideSource": "Destination cannot be inside the selected source path.", + "sameHostNoOp": "Source and destination are the same folder." }, "hosts": { "fileManager": "Filbehandler", - "tabFiles": "Filer", - "enableFileManagerMonitor": "Aktiver filbehandler", - "enableFileManagerMonitorDesc": "Bla gjennom og administrer filer på denne verten via SFTP", - "scpLegacyLabel": "SCP Legacy-modus", - "scpLegacyDesc": "Bruk eldre filoverføring for servere som ikke støtter SFTP-undersystemet (f.eks. innebygde eller minimale SSH-servere).", - "defaultPathLabel": "Standardsti", - "fileManagerPathHint": "Katalogen som skal åpnes når filbehandleren starter for denne verten.", - "fileManagerUrlCopied": "URL-adressen til filbehandleren er kopiert", - "copyFileManagerUrlAction": "Kopier URL-adressen til filbehandleren", - "docsLink": "Vis dokumenter", - "hostNotFound": "Verten ble ikke funnet", - "loadingHost": "Laster inn vert ..." - }, - "settings": { - "host": { - "enable": { - "label": "Aktiver filbehandler" - }, - "defaultPath": { - "label": "Standardsti" - }, - "scpLegacy": { - "label": "SCP Legacy-modus" - } - }, - "user": { - "transferConcurrency": { - "label": "Samtidige filoverføringer", - "description": "Hvor mange filer den side om side lokale/fjernstyrte administratoren laster opp eller ned samtidig. Reduser dette hvis serveren din begrenser SFTP-kanaler." - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "Filer" + "fileManagerUrlCopied": "File Manager URL copied", + "copyFileManagerUrlAction": "Copy File Manager URL", + "docsLink": "View docs", + "hostNotFound": "Host not found", + "loadingHost": "Loading host..." }, "onboarding": { - "feature_files": "Filbehandler", - "feature_files_desc": "Bla gjennom, last opp, last ned og rediger filer via SFTP uten å forlate appen." + "feature_files": "File manager", + "feature_files_desc": "Browse, upload, download and edit files over SFTP without leaving the app." }, "terminal": { "runTitle": "Kjører {{command}} - {{host}}", @@ -420,94 +447,97 @@ "terminalWithPath": "Terminal - {{host}}:{{path}}" }, "transfer": { - "browseFolders": "Bla gjennom målmapper", - "browsePathError": "Kunne ikke åpne denne banen på målverten.", - "browsePathWillBeCreated": "Denne mappen finnes ikke ennå. Den vil bli opprettet når overføringen starter.", - "cancel": "Kansellere", - "cleanupDestFiles": "Rydd opp destinasjonen", - "cleanupDestFilesError": "Opprydding mislyktes", - "cleanupDestFilesNothing": "Ingenting å rydde opp i på destinasjonen", - "cleanupDestFilesPartial": "Kunne ikke fjerne noen delvise filer", - "cleanupDestFilesSuccess": "Fjernet delvise filer fra destinasjonen", - "confirmCopy": "Kopiere", - "confirmMove": "Flytte", - "copyFolderToHost": "Kopier mappe til vert…", - "copyItemsToHost": "Kopier {{count}} elementer til å være vert for…", - "copyToHost": "Kopier til vert…", - "destinationPath": "Destinasjonssti", - "destMustBeDirectory": "Destinasjonen må være en katalog for overføringer av flere elementer", - "goUp": "Gå opp", - "hostAuthRequired": "Autentisering kreves – åpne Filbehandler på denne verten først", - "hostConnecting": "Kobler til…", - "hostConnectionFailed": "Tilkoblingen mislyktes", - "hostDisconnected": "Ikke tilkoblet", - "hostReady": "Ferdig", + "browseFolders": "Browse destination folders", + "browsePathError": "Could not open this path on the destination host.", + "browsePathWillBeCreated": "This folder does not exist yet. It will be created when the transfer starts.", + "cancel": "Avbryt", + "cleanupDestFiles": "Clean up destination", + "cleanupDestFilesError": "Cleanup failed", + "cleanupDestFilesNothing": "Nothing to clean up on the destination", + "cleanupDestFilesPartial": "Some partial files could not be removed", + "cleanupDestFilesSuccess": "Removed partial files from the destination", + "confirmCopy": "Kopier", + "confirmMove": "Flytt", + "copyFolderToHost": "Copy folder to host…", + "copyItemsToHost": "Copy {{count}} items to host…", + "copyToHost": "Copy to host…", + "destinationPath": "Destination path", + "destMustBeDirectory": "Destination must be a directory for multi-item transfers", + "goUp": "Go up", + "hostAuthRequired": "Authentication required. Open File Manager on this host first", + "hostConnecting": "Connecting…", + "hostConnectionFailed": "Tilkobling mislyktes", + "hostDisconnected": "Not connected", + "hostReady": "Klar", "itemsSummary": "{{count}} elementer", - "jumpHostLimitation": "Begge vertene må være tilgjengelige fra Termix-serveren. Direkte vert-til-vert-ruting støttes ikke.", - "methodAuto": "Bil", - "methodAutoHint": "Velger tar eller SFTP per fil basert på antall filer, størrelse og komprimerbarhet. Enkeltfiler bruker alltid strømme-SFTP.", - "methodItemSftp": "SFTP per fil", - "methodItemSftpHint": "Overfør hver fil individuelt via SFTP. Fungerer på alle verter, inkludert Windows.", - "methodItemSftpLimitation": "Hver fil bruker den samme SFTP-strømmen som en enkeltfilskopi, én etter én. Fremdriften kombineres på tvers av alle filene, så linjen beveger seg sakte under store filer.", - "methodLabel": "Overføringsmetode", - "methodPreviewError": "Kunne ikke forhåndsvise overføringsmetoden. Serveren vil fortsatt velge en metode når du starter.", - "methodPreviewLoading": "Beregning av overføringsmetode…", - "methodPreviewScanSummary": "{{fileCount}} filer, {{totalSize}} totalt (skannet på kildeverten).", - "methodPreviewWillUseItemSftp": "Vil bruke: SFTP per fil", - "methodPreviewWillUseTar": "Vil bruke: Tar-arkiv", + "jumpHostLimitation": "Both hosts must be reachable from the Termix server. Direct host-to-host routing is not supported.", + "methodAuto": "Auto", + "methodAutoHint": "Picks tar or per-file SFTP based on file count, size, and compressibility. Single files always use streaming SFTP.", + "methodItemSftp": "Per-file SFTP", + "methodItemSftpHint": "Transfer each file individually over SFTP. Works on all hosts including Windows.", + "methodItemSftpLimitation": "Each file uses the same SFTP stream as a single-file copy, one after another. Progress is combined across all files, so the bar moves slowly during large files.", + "methodLabel": "Transfer method", + "methodPreviewError": "Could not preview transfer method. The server will still pick a method when you start.", + "methodPreviewLoading": "Calculating transfer method…", + "methodPreviewScanSummary": "{{fileCount}} files, {{totalSize}} total (scanned on source host).", + "methodPreviewWillUseItemSftp": "Will use: Per-file SFTP", + "methodPreviewWillUseTar": "Will use: Tar archive", "methodReason": { - "user_item_sftp": "Du valgte SFTP per fil.", - "user_tar": "Du valgte tar-arkiv.", - "tar_unavailable": "Tar er ikke tilgjengelig på én eller begge vertene – SFTP per fil vil bli brukt i stedet.", - "windows_host": "En Windows-vert er involvert – tar brukes ikke.", - "auto_multi_large": "Auto: flere filer, inkludert en stor fil ({{largestSize}}) med komprimerbare data — tar-pakker i én overføring.", - "auto_single_large_in_archive": "Auto: én stor fil ({{largestSize}}) i dette settet — SFTP per fil.", - "auto_many_incompressible": "Auto: stort sett inkomprimerbare data — SFTP per fil.", - "auto_many_files": "Auto: mange filer ({{fileCount}}) — tar reduserer overhead per fil.", - "auto_default": "Auto: SFTP per fil for dette settet." + "user_item_sftp": "You chose per-file SFTP.", + "user_tar": "You chose tar archive.", + "tar_unavailable": "Tar is not available on one or both hosts, so per-file SFTP will be used instead.", + "windows_host": "A Windows host is involved, so tar is not used.", + "auto_multi_large": "Auto: multiple files including a large file ({{largestSize}}) with compressible data. Tar bundles them into one transfer.", + "auto_single_large_in_archive": "Auto: one large file ({{largestSize}}) in this set, so per-file SFTP.", + "auto_many_incompressible": "Auto: mostly incompressible data, so per-file SFTP.", + "auto_many_files": "Auto: many files ({{fileCount}}), tar cuts the per-file overhead.", + "auto_default": "Auto: per-file SFTP for this set." }, - "methodTar": "Tar-arkiv", - "methodTarHint": "Komprimer på kildekode, overfør ett arkiv, pakk ut på destinasjon. Krever tar på begge Unix-vertene.", - "metricsCompress": "Komprimer på kilde: {{duration}}", - "metricsExtract": "Uttrekk på destinasjon: {{duration}}", - "metricsPrepare": "Forbered destinasjon: {{duration}}", - "metricsRouteBenchmark": "Rutesonde — direkte: {{direct}}, relé: {{relay}}", - "metricsSourceDelete": "Fjern fra kilden: {{duration}}", - "metricsTotal": "Totalt: {{duration}}", - "metricsTransfer": "Ende-til-ende: {{throughput}} ({{duration}})", - "metricsVerify": "SHA-256 bekreftet: {{duration}}", - "moveFolderToHost": "Flytt mappen til verten…", - "moveItemsToHost": "Flytt {{count}} elementer til vert for…", - "moveToHost": "Flytt til vert…", - "noHostsConnected": "Ingen andre filbehandlerverter tilgjengelig.", - "noHostsConnectedHint": "Legg til en annen SSH-vert med Filbehandling aktivert i Vertsbehandling.", - "parallelSegmentsHint": "Store filer deles inn i deler på 256 MB. Flere baner bruker separate tilkoblinger (som å starte flere overføringer) for høyere total gjennomstrømning.", - "parallelSegmentsLabel": "Parallelle overføringsfelt", - "parallelSegmentsOption": "{{count}} baner", - "progressBenchmarking": "Velge den raskeste overgangsruten…", + "methodTar": "Tar archive", + "methodTarHint": "Compress on source, transfer one archive, extract on destination. Requires tar on both Unix hosts.", + "metricsCompress": "Compress on source: {{duration}}", + "metricsExtract": "Extract on destination: {{duration}}", + "metricsPrepare": "Prepare destination: {{duration}}", + "metricsRouteBenchmark": "Route probe: direct {{direct}}, relay {{relay}}", + "metricsSourceDelete": "Remove from source: {{duration}}", + "metricsTotal": "Total: {{duration}}", + "metricsTransfer": "End-to-end: {{throughput}} ({{duration}})", + "metricsVerify": "SHA-256 verified: {{duration}}", + "moveFolderToHost": "Move folder to host…", + "moveItemsToHost": "Move {{count}} items to host…", + "moveToHost": "Move to host…", + "noHostsConnected": "No other file-manager hosts available.", + "noHostsConnectedHint": "Add another SSH host with File Manager enabled in Host Manager.", + "parallelSegmentsHint": "Large files are split into 256 MB chunks. Multiple lanes use separate connections (like starting several transfers) for higher total throughput.", + "parallelSegmentsLabel": "Parallel transfer lanes", + "parallelSegmentsOption": "{{count}} lanes", + "progressBenchmarking": "Selecting the fastest transfer route…", "progressBytes": "{{transferred}} / {{total}}", - "progressCancel": "Kansellere", - "progressCancelling": "Avbryter…", - "progressCompressing": "Komprimering på kildevert…", - "progressExtracting": "Uttrekker på destinasjon…", - "progressItems": "{{current}} / {{total}} filer", - "progressReconnecting": "Kobler til igjen…", - "progressStalled": "Fastlåst", - "progressTotalSpeed": "{{speed}} totalt ({{lanes}} baner)", - "progressTransferring": "Overføring av data…", - "progressTransferringItems": "Overføring av filer ({{current}} av {{total}})…", - "progressVerifying": "Verifiserer filintegritet…", - "recentDestinations": "Nylige destinasjoner", - "resumedHint": "Koblet til igjen en aktiv overføring som startet i et annet vindu.", - "retryTransfer": "Prøv på nytt", - "retryTransferError": "Forsøk på nytt mislyktes", - "selectDestinationHost": "Velg destinasjonsvert", - "transferCancelled": "Overføringen er avbrutt", - "transferCancelledCopyHint": "Delvise filer kan bli liggende igjen på destinasjonen.", - "transferCancelledMoveHint": "Delvise filer kan bli liggende igjen på destinasjonen. Kildefilene ble ikke fjernet.", - "transferError": "Overføringen mislyktes", - "transferFailedRetryHint": "Delvise data ble lagret på destinasjonen. Forsøket gjenopptas når forbindelsen er tilbake.", - "transferPartialHint": "Kunne ikke overføre: {{paths}}", - "transferSuccess": "Overføringen er fullført" + "progressCancel": "Avbryt", + "progressCancelling": "Cancelling…", + "progressCompressing": "Compressing on source host…", + "progressExtracting": "Extracting on destination…", + "progressItems": "{{current}} / {{total}} files", + "progressReconnecting": "Reconnecting…", + "progressStalled": "Stalled", + "progressTotalSpeed": "{{speed}} total ({{lanes}} lanes)", + "progressTransferring": "Transferring data…", + "progressTransferringItems": "Transferring files ({{current}} of {{total}})…", + "progressVerifying": "Verifying file integrity…", + "recentDestinations": "Recent destinations", + "resumedHint": "Reconnected to an active transfer started in another window.", + "retryTransfer": "Prøv igjen", + "retryTransferError": "Retry failed", + "selectDestinationHost": "Select destination host", + "transferCancelled": "Transfer cancelled", + "transferCancelledCopyHint": "Partial files may remain on the destination.", + "transferCancelledMoveHint": "Partial files may remain on the destination. Source files were not removed.", + "transferError": "Transfer failed", + "transferFailedRetryHint": "Partial data was kept on the destination. Retry will resume when the connection is back.", + "transferPartialHint": "Could not transfer: {{paths}}", + "transferSuccess": "Transfer complete", + "metricsHopSourceRead": "Source → server: {{throughput}}", + "metricsHopDestSftpWrite": "Server → dest (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Server → dest (local): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/pl_PL.json b/plugins/file-manager/locales/translated/pl_PL.json index 961a902c1..82c0c0c83 100644 --- a/plugins/file-manager/locales/translated/pl_PL.json +++ b/plugins/file-manager/locales/translated/pl_PL.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "Pliki", + "sftp": "SFTP", + "openFileManager": "Otwórz menedżer plików" + }, + "permissions": { + "use": { + "title": "Use file manager", + "description": "Browse, edit and transfer files over SFTP." + } + }, + "settings": { + "host": { + "enable": { + "label": "Włącz menedżer plików", + "description": "Browse and edit files on this host over SFTP." + }, + "defaultPath": { + "label": "Domyślna ścieżka" + }, + "scpLegacy": { + "label": "Tryb SCP Legacy" + } + }, + "user": { + "transferConcurrency": { + "label": "Simultaneous File Transfers", + "description": "How many files the side by side local/remote manager uploads or downloads at the same time. Lower this if your server limits SFTP channels." + }, + "confirmBeforeTrash": { + "label": "Confirm before moving files to trash", + "description": "Ask before moving remote files to trash. Permanent deletion still requires confirmation." + } + } + }, + "hostCapability": { + "label": "Menedżer plików" + }, "fileManager": { "noHostSelected": "Nie wybrano hosta", "initializingEditor": "Inicjalizacja edytora...", @@ -34,6 +72,7 @@ "rename": "Zmień nazwę", "uploading": "Przesyłanie...", "uploadingFile": "Przesyłanie {{name}}...", + "uploadingChunk": "Uploading {{name}}: {{percent}}% (part {{chunk}} of {{total}})", "fileName": "Nazwa pliku", "folderName": "Nazwa folderu", "fileUploadedSuccessfully": "Plik „{{name}}” został pomyślnie przesłany", @@ -56,58 +95,58 @@ "sudoOperationFailed": "Operacja sudo nie powiodła się", "sudoAuthFailed": "Uwierzytelnianie sudo nie powiodło się", "dragFilesToUpload": "Upuść pliki tutaj, aby je przesłać", - "dropToUploadHere": "Upuść, aby przesłać tutaj", - "dropToDownloadHere": "Upuść, aby pobrać tutaj", - "localFiles": "Lokalny", - "showLocalFiles": "Pokaż pliki lokalne (widok podzielony)", - "hideLocalFiles": "Ukryj pliki lokalne", - "localHome": "Folder domowy", - "localPathPlaceholder": "Ścieżka do folderu lokalnego", - "localShowHidden": "Pokaż ukryte pliki", - "localHideHidden": "Ukryj ukryte pliki", - "localRevealInFileManager": "Pokaż w menedżerze plików systemowych", - "localCannotOpenFolder": "Nie można otworzyć folderu", + "dropToUploadHere": "Drop to upload here", + "dropToDownloadHere": "Drop to download here", + "localFiles": "Lokalne", + "showLocalFiles": "Show local files (split view)", + "hideLocalFiles": "Hide local files", + "localHome": "Home folder", + "localPathPlaceholder": "Local folder path", + "localShowHidden": "Show hidden files", + "localHideHidden": "Hide hidden files", + "localRevealInFileManager": "Reveal in system file manager", + "localCannotOpenFolder": "Cannot open folder", "localItemCount": "{{count}} elementów", - "localSelectedCount": "{{count}} wybrano", - "back": "Z powrotem", - "forward": "Do przodu", - "up": "W górę", - "kind": "Uprzejmy", - "localUploadingProgress": "Przesyłanie {{current}} z {{total}}", - "localDownloadingProgress": "Pobieranie {{current}} z {{total}}", - "localTransferInFlight": "{{count}} natychmiast", - "localPreparingDownload": "Przygotowywanie do pobrania...", + "localSelectedCount": "Zaznaczono: {{count}}", + "back": "Wstecz", + "forward": "Forward", + "up": "Up", + "kind": "Kind", + "localUploadingProgress": "Uploading {{current}} of {{total}}", + "localDownloadingProgress": "Downloading {{current}} of {{total}}", + "localTransferInFlight": "{{count}} at once", + "localPreparingDownload": "Preparing download...", "localTransferCancelled": "Transfer anulowany", - "localNothingToTransfer": "Nic do przeniesienia", - "localUploadComplete": "Przesłano {{count}} plików", - "localUploadFailed": "Przesyłanie nie powiodło się", + "localNothingToTransfer": "Nothing to transfer", + "localUploadComplete": "Uploaded {{count}} file(s)", + "localUploadFailed": "Upload failed", "localUploadPartial": "Przesłano {{done}} plików, {{failed}} nie powiodło się", - "localDownloadComplete": "Pobrano {{count}} plików", + "localDownloadComplete": "Downloaded {{count}} file(s)", "localDownloadFailed": "Pobieranie nie powiodło się", - "localDownloadPartial": "Pobrano {{done}} plików, {{failed}} nie powiodło się", - "localReplaceExistingPrompt": "W tym folderze istnieje już {{count}} elementów. Czy je zastąpić?", - "localReplace": "Zastępować", - "localSkipExisting": "Pominąć", - "localSkippedExisting": "Pominięto {{count}} istniejących elementów", - "localUnsafeNamesSkipped": "Pominięto {{count}} elementów, których nazw nie można używać na tym komputerze", - "localOpen": "Otwarte", - "localOpenFolder": "Otwórz folder", - "localUploadToRemote": "Prześlij na serwer", - "localUploadToRemoteMany": "Prześlij {{count}} elementów na serwer", - "localMoveToTrash": "Przenieś do kosza", - "localMoveToTrashMany": "Przenieś {{count}} elementów do Kosza", - "localTrashConfirmSingle": "Przenieść „{{name}}” do Kosza?", - "localTrashConfirmFolder": "Czy przenieść folder „{{name}}” i całą jego zawartość do Kosza?", - "localTrashConfirmMany": "Przenieść {{count}} elementów do Kosza?", - "localTrashed": "Przeniesiono {{count}} elementów do Kosza", - "localTrashFailed": "Nie można przenieść do Kosza", - "localRenameFailed": "Zmiana nazwy nie powiodła się", - "localCreateFailed": "Nie można utworzyć elementu", - "goToParentFolder": "Przejdź do folderu nadrzędnego", - "resizeSidebar": "Przeciągnij, aby zmienić rozmiar paska bocznego (kliknij dwukrotnie, aby zresetować)", - "resizeLocalPane": "Przeciągnij, aby zmienić rozmiar panelu lokalnego (kliknij dwukrotnie, aby zresetować)", + "localDownloadPartial": "Downloaded {{done}} file(s), {{failed}} failed", + "localReplaceExistingPrompt": "{{count}} item(s) already exist in this folder. Replace them?", + "localReplace": "Zamień", + "localSkipExisting": "Skip", + "localSkippedExisting": "Skipped {{count}} existing item(s)", + "localUnsafeNamesSkipped": "Skipped {{count}} item(s) whose names cannot be used on this computer", + "localOpen": "Otwórz", + "localOpenFolder": "Open folder", + "localUploadToRemote": "Upload to server", + "localUploadToRemoteMany": "Upload {{count}} items to server", + "localMoveToTrash": "Move to Trash", + "localMoveToTrashMany": "Move {{count}} items to Trash", + "localTrashConfirmSingle": "Move \"{{name}}\" to the Trash?", + "localTrashConfirmFolder": "Move the folder \"{{name}}\" and all its contents to the Trash?", + "localTrashConfirmMany": "Move {{count}} items to the Trash?", + "localTrashed": "Moved {{count}} item(s) to the Trash", + "localTrashFailed": "Could not move to the Trash", + "localRenameFailed": "Rename failed", + "localCreateFailed": "Could not create item", + "goToParentFolder": "Go to parent folder", + "resizeSidebar": "Drag to resize the sidebar (double-click to reset)", + "resizeLocalPane": "Drag to resize the local pane (double-click to reset)", "columns": "Kolumny", - "columnsHint": "Kliknij prawym przyciskiem myszy, aby wybrać kolumny", + "columnsHint": "Right-click to choose columns", "emptyFolder": "Ten folder jest pusty", "searchFiles": "Wyszukaj pliki...", "upload": "Prześlij", @@ -290,6 +329,7 @@ "connecting": "Łączenie...", "connectedSuccessfully": "Połączono pomyślnie", "totpVerificationFailed": "Weryfikacja TOTP nie powiodła się", + "browserSignInFailed": "Sign-in failed. Please try again.", "authenticationFailed": "Uwierzytelnianie nie powiodło się", "incorrectPassphrase": "Nieprawidłowe hasło klucza. Spróbuj ponownie.", "verificationCodePrompt": "Kod weryfikacyjny:", @@ -321,95 +361,82 @@ "used": "Użyte", "of": "z", "toggleSidebar": "Przełącz pasek boczny", - "compactLayout": "Użyj kompaktowego układu", - "comfortableLayout": "Użyj wygodnego układu", + "compactLayout": "Use compact layout", + "comfortableLayout": "Use comfortable layout", "cannotLoadPdf": "Nie można załadować pliku PDF", "pdfLoadError": "Wystąpił błąd podczas ładowania pliku PDF.", "loadingPdf": "Ładowanie pliku PDF...", - "loadingPage": "Ładowanie strony..." + "loadingPage": "Ładowanie strony...", + "cancel": "Anuluj", + "copiedItems_one": "Copied {{count}} item", + "copiedItems_other": "Copied {{count}} items", + "deleteCopiedFileFailed": "Could not delete the copy of {{name}}: {{error}}", + "dragMovedItems_one": "Moved {{count}} item to {{target}}", + "dragMovedItems_other": "Moved {{count}} items to {{target}}", + "moveBackFileFailed": "Could not move {{name}} back: {{error}}", + "terminal": "Terminal: {{host}} ({{path}})", + "dragToDesktop": "Dragging {{name}} to the desktop", + "dragFilesToDesktop": "Dragging {{count}} files to the desktop", + "folderDragUnsupported": "Dragging folders to the desktop is not supported yet", + "saveToDesktopFailed": "Save failed: {{error}}", + "dragFailedDetail": "Drag failed: {{error}}", + "videoUnsupported": "Your browser cannot play this video format.", + "downloadToPlay": "Download to play it elsewhere", + "cannotPreviewType": "Cannot preview this file type", + "cannotPreviewTypeHint": "This file type has no preview. Download it to open it in another app." }, "sftpTransfer": { "title": "SFTP", - "description": "Przesyłanie plików pomiędzy dwoma hostami SSH.", - "sourceServer": "Serwer źródłowy", - "destinationServer": "Serwer docelowy", - "selectHost": "Wybierz hosta", + "description": "Transfer files between two SSH hosts.", + "sourceServer": "Source Server", + "destinationServer": "Destination Server", + "selectHost": "Select host", "noHostSelected": "Nie wybrano hosta", - "move": "Przenosić", - "copy": "Kopia", - "upload": "Wgrywać", - "itemsSelected": "{{count}} wybrano element", - "itemsSelected_other": "Wybrano {{count}} elementów", + "move": "Przenieś", + "copy": "Kopiuj", + "upload": "Prześlij", + "itemsSelected": "{{count}} item selected", + "itemsSelected_other": "{{count}} items selected", "ready": "Gotowy", "loadingHosts": "Ładowanie hostów...", "name": "Nazwa", - "modified": "Zmodyfikowany", + "modified": "Zmodyfikowano", "size": "Rozmiar", - "noFiles": "Brak plików", - "open": "Otwarte", - "up": "W górę", - "refresh": "Odświeżać", - "copyToTarget": "Kopiuj do katalogu docelowego", - "rename": "Przemianować", - "delete": "Usuwać", - "editPermissions": "Edytuj uprawnienia", - "createNewFolder": "Utwórz nowy folder", - "deleteSelectedItems": "Usuń wybrane elementy", - "deleteConfirm": "Usunąć {{count}} wybrany element?", - "deleteConfirm_other": "Usunąć {{count}} wybranych elementów?", - "cancel": "Anulować", - "save": "Ratować", - "folderCreated": "Utworzono folder", - "itemRenamed": "Zmieniono nazwę elementu", + "noFiles": "No files", + "open": "Otwórz", + "up": "Up", + "refresh": "Odśwież", + "copyToTarget": "Copy to Target Directory", + "rename": "Zmień nazwę", + "delete": "Usuń", + "editPermissions": "Edit Permissions", + "createNewFolder": "Create New Folder", + "deleteSelectedItems": "Delete Selected Items", + "deleteConfirm": "Delete {{count}} selected item?", + "deleteConfirm_other": "Delete {{count}} selected items?", + "cancel": "Anuluj", + "save": "Zapisz", + "folderCreated": "Folder created", + "itemRenamed": "Item renamed", "actionFailed": "Akcja nie powiodła się", - "itemsDeleted": "{{count}} element usunięty", - "itemsDeleted_other": "Usunięto {{count}} elementów", - "deleteFailed": "Usunięcie nie powiodło się", - "permissionsUpdated": "Zaktualizowano uprawnienia", - "noRemoteSessionConnected": "Brak połączonych sesji zdalnych", - "failedToListFiles": "Nie udało się wyświetlić listy plików", - "failedToRefresh": "Nie udało się odświeżyć", - "destinationInsideSource": "Miejsce docelowe nie może znajdować się wewnątrz wybranej ścieżki źródłowej.", - "sameHostNoOp": "Źródło i cel znajdują się w tym samym folderze." + "itemsDeleted": "{{count}} item deleted", + "itemsDeleted_other": "{{count}} items deleted", + "deleteFailed": "Delete failed", + "permissionsUpdated": "Permissions updated", + "noRemoteSessionConnected": "No remote session connected", + "failedToListFiles": "Failed to list files", + "failedToRefresh": "Failed to refresh", + "destinationInsideSource": "Destination cannot be inside the selected source path.", + "sameHostNoOp": "Source and destination are the same folder." }, "hosts": { "fileManager": "Menedżer plików", - "tabFiles": "Pliki", - "enableFileManagerMonitor": "Włącz menedżer plików", - "enableFileManagerMonitorDesc": "Przeglądaj i zarządzaj plikami na tym hoście przez SFTP", - "scpLegacyLabel": "Tryb SCP Legacy", - "scpLegacyDesc": "Użyj starszej metody transferu plików dla serwerów, które nie obsługują podsystemu SFTP (np. wbudowanych lub minimalnych serwerów SSH).", - "defaultPathLabel": "Domyślna ścieżka", - "fileManagerPathHint": "Katalog, który zostanie otwarty po uruchomieniu menedżera plików dla tego hosta.", "fileManagerUrlCopied": "Skopiowano adres URL menedżera plików", "copyFileManagerUrlAction": "Kopiuj adres URL menedżera plików", "docsLink": "Zobacz dokumentację", "hostNotFound": "Nie znaleziono hosta", "loadingHost": "Ładowanie hosta..." }, - "settings": { - "host": { - "enable": { - "label": "Włącz menedżer plików" - }, - "defaultPath": { - "label": "Domyślna ścieżka" - }, - "scpLegacy": { - "label": "Tryb SCP Legacy" - } - }, - "user": { - "transferConcurrency": { - "label": "Jednoczesne przesyłanie plików", - "description": "Ile plików lokalny/zdalny menedżer obok siebie przesyła lub pobiera jednocześnie? Zmniejsz tę wartość, jeśli Twój serwer ogranicza kanały SFTP." - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "Pliki" - }, "onboarding": { "feature_files": "Menedżer plików", "feature_files_desc": "Przeglądaj, przesyłaj, pobieraj i edytuj pliki przez SFTP bez opuszczania aplikacji." @@ -437,7 +464,7 @@ "destinationPath": "Ścieżka docelowa", "destMustBeDirectory": "Miejsce docelowe musi być katalogiem przy transferze wielu elementów", "goUp": "W górę", - "hostAuthRequired": "Wymagane uwierzytelnienie: najpierw otwórz menedżer plików na tym hoście", + "hostAuthRequired": "Authentication required. Open File Manager on this host first", "hostConnecting": "Łączenie…", "hostConnectionFailed": "Połączenie nieudane", "hostDisconnected": "Nie połączono", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "Wybrano SFTP dla poszczególnych plików.", "user_tar": "Wybrano archiwum tar.", - "tar_unavailable": "Tar nie jest dostępny na jednym lub obu hostach, zamiast niego zostanie użyty SFTP dla każdego pliku.", - "windows_host": "W transferze bierze udział host Windows, więc tar nie jest używany.", - "auto_multi_large": "Auto: wiele plików, w tym duży plik ({{largestSize}}) z kompresowalnymi danymi, tar pakuje je w jeden transfer.", - "auto_single_large_in_archive": "Auto: jeden duży plik ({{largestSize}}) w tym zestawie, SFTP dla każdego pliku.", - "auto_many_incompressible": "Auto: dane w większości niekompresowalne, SFTP dla każdego pliku.", - "auto_many_files": "Auto: wiele plików ({{fileCount}}), tar redukuje narzut na plik.", + "tar_unavailable": "Tar is not available on one or both hosts, so per-file SFTP will be used instead.", + "windows_host": "A Windows host is involved, so tar is not used.", + "auto_multi_large": "Auto: multiple files including a large file ({{largestSize}}) with compressible data. Tar bundles them into one transfer.", + "auto_single_large_in_archive": "Auto: one large file ({{largestSize}}) in this set, so per-file SFTP.", + "auto_many_incompressible": "Auto: mostly incompressible data, so per-file SFTP.", + "auto_many_files": "Auto: many files ({{fileCount}}), tar cuts the per-file overhead.", "auto_default": "Auto: SFTP dla każdego pliku w tym zestawie." }, "methodTar": "Archiwum tar", @@ -471,7 +498,7 @@ "metricsCompress": "Kompresja w źródle: {{duration}}", "metricsExtract": "Rozpakowanie w miejscu docelowym: {{duration}}", "metricsPrepare": "Przygotowanie miejsca docelowego: {{duration}}", - "metricsRouteBenchmark": "Sonda trasy. Bezpośrednia: {{direct}}, przez przekaźnik: {{relay}}", + "metricsRouteBenchmark": "Route probe: direct {{direct}}, relay {{relay}}", "metricsSourceDelete": "Usunięcie ze źródła: {{duration}}", "metricsTotal": "Razem: {{duration}}", "metricsTransfer": "Całościowo: {{throughput}} ({{duration}})", @@ -508,6 +535,9 @@ "transferError": "Transfer nie powiódł się", "transferFailedRetryHint": "W miejscu docelowym zachowano częściowe dane. Ponowna próba zostanie wznowiona po przywróceniu połączenia.", "transferPartialHint": "Nie można przesłać: {{paths}}", - "transferSuccess": "Transfer zakończony" + "transferSuccess": "Transfer zakończony", + "metricsHopSourceRead": "Źródło → serwer: {{throughput}}", + "metricsHopDestSftpWrite": "Serwer → cel (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Serwer → cel (lokalny): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/pt_BR.json b/plugins/file-manager/locales/translated/pt_BR.json index 862a11c58..01845e8af 100644 --- a/plugins/file-manager/locales/translated/pt_BR.json +++ b/plugins/file-manager/locales/translated/pt_BR.json @@ -1,513 +1,543 @@ { - "fileManager": { - "noHostSelected": "Nenhum host selecionado", - "initializingEditor": "Inicializando o editor...", - "file": "Arquivo", - "folder": "Pasta", - "uploadFile": "Carregar arquivo", - "downloadFile": "Download", - "extractArchive": "Extrair arquivo", - "extractingArchive": "Extraindo {{name}}...", - "archiveExtractedSuccessfully": "{{name}} extraído com sucesso", - "extractFailed": "A extração falhou", - "compressFile": "Compactar arquivo", - "compressFiles": "Comprimir arquivos", - "compressFilesDesc": "Comprima {{count}} itens em um arquivo", - "archiveName": "Nome do arquivo", - "enterArchiveName": "Digite o nome do arquivo...", - "compressionFormat": "Formato de compressão", - "selectedFiles": "Arquivos selecionados", - "andMoreFiles": "e {{count}} mais...", - "compress": "Compressa", - "compressingFiles": "Comprimir {{count}} itens em {{name}}...", - "filesCompressedSuccessfully": "{{name}} criado com sucesso", - "compressFailed": "A compressão falhou", - "edit": "Editar", - "preview": "Pré-visualização", - "previous": "Anterior", - "next": "Próximo", - "pageXOfY": "Página {{current}} de {{total}}", - "zoomOut": "Diminuir o zoom", - "zoomIn": "Ampliar", - "newFile": "Novo arquivo", - "newFolder": "Nova pasta", - "rename": "Renomear", - "uploading": "Carregando...", - "uploadingFile": "Carregando {{name}}...", - "fileName": "Nome do arquivo", - "folderName": "Nome da pasta", - "fileUploadedSuccessfully": "Arquivo \"{{name}}\" enviado com sucesso", - "failedToUploadFile": "Falha ao carregar o arquivo", - "uploadingFolderFiles": "Enviando {{count}} arquivo(s)...", - "uploadedFolderFiles": "Arquivo(s) carregado(s) com sucesso {{count}}", - "uploadedFolderPartial": "Uploaded {{uploaded}} file(s), {{failed}} failed", - "fileDownloadedSuccessfully": "Arquivo \"{{name}}\" baixado com sucesso", - "failedToDownloadFile": "Falha ao baixar o arquivo", - "fileCreatedSuccessfully": "Arquivo \"{{name}}\" criado com sucesso", - "folderCreatedSuccessfully": "Pasta \"{{name}}\" criada com sucesso", - "failedToCreateItem": "Falha ao criar o item", - "operationFailed": "A operação {{operation}} falhou para {{name}}: {{error}}", - "failedToResolveSymlink": "Falha ao resolver o link simbólico", - "itemsDeletedSuccessfully": "{{count}} itens excluídos com sucesso", - "failedToDeleteItems": "Falha ao excluir itens", - "sudoPasswordRequired": "Senha de administrador necessária", - "enterSudoPassword": "Digite a senha de sudo para continuar esta operação.", - "sudoPassword": "Senha de sudo", - "sudoOperationFailed": "A operação sudo falhou", - "sudoAuthFailed": "Falha na autenticação sudo", - "dragFilesToUpload": "Arraste e solte os arquivos aqui para fazer o upload.", - "dropToUploadHere": "Arraste e faça o upload aqui.", - "dropToDownloadHere": "Faça o download aqui.", - "localFiles": "Local", - "showLocalFiles": "Exibir arquivos locais (visualização dividida)", - "hideLocalFiles": "Ocultar arquivos locais", - "localHome": "Pasta inicial", - "localPathPlaceholder": "Caminho da pasta local", - "localShowHidden": "Mostrar arquivos ocultos", - "localHideHidden": "Ocultar arquivos ocultos", - "localRevealInFileManager": "Exibir no gerenciador de arquivos do sistema", - "localCannotOpenFolder": "Não é possível abrir a pasta", - "localItemCount": "{{count}} itens", - "localSelectedCount": "{{count}} selecionado", - "back": "Voltar", - "forward": "Avançar", - "up": "Acima", - "kind": "Tipo", - "localUploadingProgress": "Enviando {{current}} de {{total}}", - "localDownloadingProgress": "Baixando {{current}} de {{total}}", - "localTransferInFlight": "{{count}} imediatamente", - "localPreparingDownload": "Preparando o download...", - "localTransferCancelled": "Transferência cancelada", - "localNothingToTransfer": "Nada a transferir", - "localUploadComplete": "Uploaded {{count}} file(s)", - "localUploadFailed": "Falha no upload", - "localUploadPartial": "Uploaded {{done}} file(s), {{failed}} failed", - "localDownloadComplete": "Arquivo(s) baixado(s) {{count}}", - "localDownloadFailed": "Falha no download", - "localDownloadPartial": "Downloaded {{done}} file(s), {{failed}} failed", - "localReplaceExistingPrompt": "{{count}} Já existem itens nesta pasta. Deseja substituí-los?", - "localReplace": "Substituir", - "localSkipExisting": "Pular", - "localSkippedExisting": "Ignorou {{count}} item(ns) existente(s)", - "localUnsafeNamesSkipped": "Ignorado {{count}} item(ns) cujos nomes não podem ser usados neste computador", - "localOpen": "Abrir", - "localOpenFolder": "Abra a pasta", - "localUploadToRemote": "Enviar para o servidor", - "localUploadToRemoteMany": "Enviar {{count}} itens para o servidor", - "localMoveToTrash": "Mover para a Lixeira", - "localMoveToTrashMany": "Mova {{count}} itens para a Lixeira", - "localTrashConfirmSingle": "Mover \"{{name}}\" para a Lixeira?", - "localTrashConfirmFolder": "Mover a pasta \"{{name}}\" e todo o seu conteúdo para a Lixeira?", - "localTrashConfirmMany": "Mover {{count}} itens para a Lixeira?", - "localTrashed": "Movidos {{count}} itens para a Lixeira", - "localTrashFailed": "Não foi possível mover para a Lixeira", - "localRenameFailed": "A renomeação falhou", - "localCreateFailed": "Não foi possível criar o item.", - "goToParentFolder": "Acesse a pasta principal", - "resizeSidebar": "Arraste para redimensionar a barra lateral (clique duas vezes para redefinir).", - "resizeLocalPane": "Arraste para redimensionar o painel local (clique duas vezes para redefinir).", - "columns": "Colunas", - "columnsHint": "Clique com o botão direito do mouse para escolher as colunas.", - "emptyFolder": "Esta pasta está vazia", - "searchFiles": "Pesquisar arquivos...", - "upload": "Carregar", - "selectHostToStart": "Selecione um host para iniciar o gerenciamento de arquivos.", - "sshRequiredForFileManager": "O gerenciador de arquivos requer SSH. Este host não tem o SSH habilitado.", - "failedToConnect": "Falha ao conectar-se ao SSH", - "failedToLoadDirectory": "Falha ao carregar o diretório", - "noSSHConnection": "Nenhuma conexão SSH disponível", - "copy": "Cópia", - "cut": "Corte", - "paste": "Colar", - "copyPath": "Copiar caminho", - "copyPaths": "Copiar caminhos", - "delete": "Excluir", - "properties": "Propriedades", - "refresh": "Atualizar", - "downloadFiles": "Baixar {{count}} arquivos para o navegador", - "copyFiles": "Copiar {{count}} itens", - "cutFiles": "Recortar {{count}} itens", - "deleteFiles": "Excluir {{count}} itens", - "filesCopiedToClipboard": "{{count}} itens copiados para a área de transferência", - "filesCutToClipboard": "{{count}} itens copiados para a área de transferência", - "pathCopiedToClipboard": "Caminho copiado para a área de transferência", - "pathsCopiedToClipboard": "{{count}} caminhos copiados para a área de transferência", - "failedToCopyPath": "Falha ao copiar o caminho para a área de transferência", - "copyFolderLink": "Copiar link para a pasta", - "copyCurrentFolderLink": "Copiar link para a pasta atual", - "folderLinkCopied": "Link da pasta copiado para a área de transferência", - "failedToCopyFolderLink": "Falha ao copiar o link da pasta", - "movedItems": "Itens movidos {{count}}", - "failedToDeleteItem": "Falha ao excluir o item", - "itemRenamedSuccessfully": "{{type}} renomeado com sucesso", - "failedToRenameItem": "Falha ao renomear o item", - "download": "Download", - "openExternalEditor": "Abrir externamente", - "chooseExternalEditor": "Escolha um editor externo.", - "externalEditorSelected": "Editor externo selecionado", - "externalEditorDesktopOnly": "O editor externo está disponível apenas no aplicativo para desktop.", - "externalEditorOpened": "Aberto em um editor externo. Salvar aqui enviará as alterações de volta para o servidor.", - "failedToOpenExternalEditor": "Não foi possível abrir o editor externo.", - "failedToSelectExternalEditor": "Não foi possível selecionar o editor externo.", - "permissions": "Permissões", - "size": "Tamanho", - "modified": "Modificado", - "path": "Caminho", - "confirmDelete": "Tem certeza de que deseja excluir {{name}}?", - "permissionDenied": "Permissão negada", - "serverError": "Erro do servidor", - "fileSavedSuccessfully": "Arquivo salvo com sucesso", - "failedToSaveFile": "Falha ao salvar o arquivo", - "confirmDeleteSingleItem": "Tem certeza de que deseja excluir permanentemente \"{{name}}\"?", - "confirmDeleteMultipleItems": "Tem certeza de que deseja excluir permanentemente {{count}} itens?", - "confirmDeleteMultipleItemsWithFolders": "Tem certeza de que deseja excluir permanentemente {{count}} itens? Isso inclui pastas e seus conteúdos.", - "confirmDeleteFolder": "Tem certeza de que deseja excluir permanentemente a pasta \"{{name}}\" e todo o seu conteúdo?", - "permanentDeleteWarning": "Esta ação não pode ser desfeita. O(s) item(ns) será(ão) excluído(s) permanentemente do servidor.", - "moveToTrashWarning": "O(s) item(ns) será(ão) movido(s) para a Lixeira Termix e poderá(ão) ser restaurado(s) antes do término do período de retenção.", - "itemsMovedToTrash": "{{count}} item(ns) movido(s) para a Lixeira", - "trash": "Lixo", - "trashDescription": "Os itens excluídos são retidos por {{days}} dia(s) neste host.", - "trashLoadFailed": "Falha ao carregar a Lixeira", - "trashEmpty": "A lixeira está vazia.", - "trashRestore": "Restaurar", - "trashRestored": "Restaurado {{name}}", - "trashRestoreFailed": "Falha ao restaurar o item. O caminho original pode já existir.", - "trashDeletePermanently": "Excluir permanentemente", - "trashDeleteConfirm": "Excluir permanentemente {{name}}? Esta ação não pode ser desfeita.", - "trashPermanentlyDeleted": "Excluído permanentemente {{name}}", - "trashDeleteFailed": "Falha ao excluir o item permanentemente", - "trashEmptyAction": "Esvaziar o lixo", - "trashEmptyConfirm": "Excluir permanentemente todos os itens da Lixeira? Esta ação é irreversível.", - "trashEmptied": "Lixo esvaziado", - "trashRetention": "Limpeza automática após (dias)", - "trashRetentionSaved": "Retenção de lixo atualizada", - "trashRetentionFailed": "Falha na atualização da retenção de lixo", - "trashUnavailableConfirm": "Este item não pode ser movido para a Lixeira, geralmente porque está em outro sistema de arquivos ou requer permissões elevadas. Deseja excluí-lo permanentemente?", - "recent": "Recente", - "pinned": "Fixado", - "folderShortcuts": "Atalhos de pastas", - "failedToReconnectSSH": "Falha ao reconectar a sessão SSH", - "openTerminalHere": "Abra o terminal aqui", - "run": "Correr", - "openTerminalInFolder": "Abra o terminal nesta pasta.", - "openTerminalInFileLocation": "Abra o terminal no local do arquivo.", - "runningFile": "Correndo - {{file}}", - "onlyRunExecutableFiles": "Só é possível executar arquivos executáveis.", - "directories": "Diretórios", - "removedFromRecentFiles": "Removemos \"{{name}}\" dos arquivos recentes", - "removeFailed": "Remover falha", - "unpinnedSuccessfully": "Desfixado \"{{name}}\" com sucesso", - "unpinFailed": "Desafixar falhou", - "removedShortcut": "Atalho removido \"{{name}}\"", - "removeShortcutFailed": "A remoção do atalho falhou", - "clearedAllRecentFiles": "Apaguei todos os arquivos recentes.", - "clearFailed": "Limpar falhou", - "removeFromRecentFiles": "Remover dos arquivos recentes", - "clearAllRecentFiles": "Limpar todos os arquivos recentes", - "unpinFile": "Desafixar arquivo", - "removeShortcut": "Remover atalho", - "pinFile": "Arquivo PIN", - "addToShortcuts": "Adicionar aos atalhos", - "pasteFailed": "A colagem falhou", - "noUndoableActions": "Ações não podem ser desfeitas", - "undoCopySuccess": "Operação de cópia desfeita: Arquivos copiados excluídos {{count}}", - "undoCopyFailedDelete": "Falha ao desfazer: Não foi possível excluir nenhum arquivo copiado.", - "undoCopyFailedNoInfo": "A ação de desfazer falhou: Não foi possível encontrar as informações do arquivo copiado.", - "undoMoveSuccess": "Operação de movimentação desfeita: {{count}} arquivos foram movidos de volta para o local original.", - "undoMoveFailedMove": "Falha ao desfazer: Não foi possível mover nenhum arquivo de volta.", - "undoMoveFailedNoInfo": "A ação de desfazer falhou: Não foi possível encontrar as informações do arquivo movido.", - "undoDeleteNotSupported": "A operação de exclusão não pode ser desfeita: os arquivos foram excluídos permanentemente do servidor.", - "undoTypeNotSupported": "Tipo de operação de desfazer não suportado", - "undoOperationFailed": "A operação de desfazer falhou", - "unknownError": "Erro desconhecido", - "confirm": "Confirmar", - "find": "Encontrar...", - "replace": "Substituir", - "downloadInstead": "Baixe em vez de baixar.", - "keyboardShortcuts": "Atalhos de teclado", - "searchAndReplace": "Localizar e substituir", - "editing": "Edição", - "search": "Procurar", - "findNext": "Encontre a seguir", - "findPrevious": "Encontrar Anterior", - "save": "Salvar", - "selectAll": "Selecionar tudo", - "undo": "Desfazer", - "redo": "Refazer", - "moveLineUp": "Mova a fila para cima", - "moveLineDown": "Deslizar a linha para baixo", - "toggleComment": "Alternar comentário", - "autoComplete": "Preenchimento automático", - "imageLoadError": "Falha ao carregar a imagem", - "startTyping": "Comece a digitar...", - "unknownSize": "Tamanho desconhecido", - "fileIsEmpty": "O arquivo está vazio", - "largeFileWarning": "Aviso de Arquivo Grande", - "largeFileWarningDesc": "Este arquivo tem {{size}} de tamanho, o que pode causar problemas de desempenho ao ser aberto como texto.", - "fileNotFoundAndRemoved": "O arquivo \"{{name}}\" não foi encontrado e foi removido dos arquivos recentes/fixados", - "failedToLoadFile": "Falha ao carregar o arquivo: {{error}}", - "serverErrorOccurred": "Ocorreu um erro no servidor. Tente novamente mais tarde.", - "autoSaveFailed": "O salvamento automático falhou", - "fileAutoSaved": "Arquivo salvo automaticamente", - "moveFileFailed": "Falha ao mover {{name}}", - "moveOperationFailed": "A operação de movimentação falhou", - "canOnlyCompareFiles": "Só é possível comparar dois arquivos.", - "comparingFiles": "Comparando arquivos: {{file1}} e {{file2}}", - "dragFailed": "A operação de arrastar falhou", - "filePinnedSuccessfully": "Arquivo \"{{name}}\" fixado com sucesso", - "pinFileFailed": "Falha ao fixar o arquivo", - "fileUnpinnedSuccessfully": "Arquivo \"{{name}}\" desafixado com sucesso", - "unpinFileFailed": "Falha ao desafixar o arquivo", - "shortcutAddedSuccessfully": "Atalho de pasta \"{{name}}\" adicionado com sucesso", - "addShortcutFailed": "Falha ao adicionar atalho", - "operationCompletedSuccessfully": "{{operation}} {{count}} itens com sucesso", - "operationCompleted": "{{operation}} {{count}} itens", - "downloadFileSuccess": "Arquivo {{name}} baixado com sucesso", - "downloadFileFailed": "Falha no download", - "downloadingFile": "Baixando {{name}}…", - "downloadProgressBytes": "{{transferred}} / {{total}}", - "moveTo": "Mover para {{name}}", - "diffCompareWith": "Diff compare com {{name}}", - "dragOutsideToDownload": "Arraste para fora da janela para baixar ({{count}} arquivos)", - "newFolderDefault": "Nova pasta", - "newFileDefault": "NovoArquivo.txt", - "successfullyMovedItems": "Movidos com sucesso {{count}} itens para {{target}}", - "move": "Mover", - "searchInFile": "Pesquisar no arquivo (Ctrl+F)", - "showKeyboardShortcuts": "Mostrar atalhos de teclado", - "decreaseFontSize": "Diminuir o tamanho da fonte", - "increaseFontSize": "Aumentar o tamanho da fonte", - "startWritingMarkdown": "Comece a escrever seu conteúdo em Markdown...", - "loadingFileComparison": "Carregando comparação de arquivos...", - "reload": "Recarregar", - "compare": "Comparar", - "sideBySide": "Lado a lado", - "inline": "Em linha", - "fileComparison": "Comparação de arquivos: {{file1}} vs {{file2}}", - "fileTooLarge": "Arquivo muito grande: {{error}}", - "sshConnectionFailed": "A conexão SSH falhou. Verifique sua conexão com {{name}} ({{ip}}:{{port}})", - "loadFileFailed": "Falha ao carregar o arquivo: {{error}}", - "connecting": "Conectando...", - "connectedSuccessfully": "Conexão estabelecida com sucesso.", - "totpVerificationFailed": "A verificação TOTP falhou.", - "authenticationFailed": "A autenticação falhou.", - "incorrectPassphrase": "Senha incorreta. Tente novamente.", - "verificationCodePrompt": "Código de verificação:", - "changePermissions": "Alterar permissões", - "currentPermissions": "Permissões atuais", - "owner": "Proprietário", - "group": "Grupo", - "others": "Outros", - "read": "Ler", - "write": "Escrever", - "execute": "Executar", - "permissionsChangedSuccessfully": "Permissões alteradas com sucesso", - "failedToChangePermissions": "Falha ao alterar as permissões", - "name": "Nome", - "sortByName": "Nome", - "sortByDate": "Data de modificação", - "sortBySize": "Tamanho", - "ascending": "Ascendente", - "descending": "Descendente", - "root": "Raiz", - "new": "Novo", - "sortBy": "Ordenar por", - "items": "Unid", - "selected": "Selecionado", - "editor": "Editor", - "octal": "Octal", - "storage": "Armazenar", - "disk": "Disco", - "used": "Usado", - "of": "de", - "toggleSidebar": "Alternar barra lateral", - "compactLayout": "Utilize um layout compacto.", - "comfortableLayout": "Use um layout confortável", - "cannotLoadPdf": "Não foi possível carregar o PDF.", - "pdfLoadError": "Ocorreu um erro ao carregar este arquivo PDF.", - "loadingPdf": "Carregando PDF...", - "loadingPage": "Carregando página..." + "nav": { + "files": "Arquivos", + "sftp": "SFTP", + "openFileManager": "Abrir o Gerenciador de Arquivos" }, - "sftpTransfer": { - "title": "SFTP", - "description": "Transferir arquivos entre dois hosts SSH.", - "sourceServer": "Servidor de origem", - "destinationServer": "Servidor de destino", - "selectHost": "Selecione o host", - "noHostSelected": "Nenhum host selecionado", - "move": "Mover", - "copy": "Cópia", - "upload": "Carregar", - "itemsSelected": "{{count}} item selecionado", - "itemsSelected_other": "{{count}} itens selecionados", - "ready": "Preparar", - "loadingHosts": "Carregando hosts...", - "name": "Nome", - "modified": "Modificado", - "size": "Tamanho", - "noFiles": "Nenhum arquivo", - "open": "Abrir", - "up": "Acima", - "refresh": "Atualizar", - "copyToTarget": "Copiar para o diretório de destino", - "rename": "Renomear", - "delete": "Excluir", - "editPermissions": "Editar permissões", - "createNewFolder": "Criar nova pasta", - "deleteSelectedItems": "Excluir itens selecionados", - "deleteConfirm": "Delete {{count}} selected item?", - "deleteConfirm_other": "Excluir {{count}} itens selecionados?", - "cancel": "Cancelar", - "save": "Salvar", - "folderCreated": "Pasta criada", - "itemRenamed": "Item renomeado", - "actionFailed": "A ação falhou", - "itemsDeleted": "{{count}} item excluído", - "itemsDeleted_other": "{{count}} itens excluídos", - "deleteFailed": "Falha ao excluir", - "permissionsUpdated": "Permissões atualizadas", - "noRemoteSessionConnected": "Nenhuma sessão remota conectada.", - "failedToListFiles": "Falha ao listar os arquivos", - "failedToRefresh": "Falha ao atualizar", - "destinationInsideSource": "O destino não pode estar dentro do caminho de origem selecionado.", - "sameHostNoOp": "A origem e o destino são a mesma pasta." - }, - "hosts": { - "fileManager": "Gerenciador de arquivos", - "tabFiles": "Arquivos", - "enableFileManagerMonitor": "Ativar o Gerenciador de Arquivos", - "enableFileManagerMonitorDesc": "Navegue e gerencie arquivos neste host via SFTP.", - "scpLegacyLabel": "Modo Legado SCP", - "scpLegacyDesc": "Utilize a transferência de arquivos legada para servidores que não suportam o subsistema SFTP (por exemplo, servidores SSH embutidos ou mínimos).", - "defaultPathLabel": "Caminho padrão", - "fileManagerPathHint": "O diretório a ser aberto quando o gerenciador de arquivos for iniciado para este host.", - "fileManagerUrlCopied": "URL do Gerenciador de Arquivos copiada", - "copyFileManagerUrlAction": "Copiar URL do Gerenciador de Arquivos", - "docsLink": "Ver documentos", - "hostNotFound": "Host não encontrado", - "loadingHost": "Carregando host..." + "permissions": { + "use": { + "title": "Use file manager", + "description": "Browse, edit and transfer files over SFTP." + } }, "settings": { "host": { "enable": { - "label": "Ativar o Gerenciador de Arquivos" + "label": "Ativar Gerenciador de Arquivos", + "description": "Browse and edit files on this host over SFTP." }, "defaultPath": { "label": "Caminho padrão" }, "scpLegacy": { - "label": "Modo Legado SCP" + "label": "SCP Legacy Mode" } }, "user": { "transferConcurrency": { - "label": "Transferências simultâneas de arquivos", - "description": "Quantos arquivos o gerenciador local/remoto lado a lado carrega ou baixa simultaneamente? Diminua esse valor se o seu servidor limitar os canais SFTP." + "label": "Simultaneous File Transfers", + "description": "How many files the side by side local/remote manager uploads or downloads at the same time. Lower this if your server limits SFTP channels." + }, + "confirmBeforeTrash": { + "label": "Confirm before moving files to trash", + "description": "Ask before moving remote files to trash. Permanent deletion still requires confirmation." } } }, - "nav": { - "sftp": "SFTP", - "files": "Arquivos" + "hostCapability": { + "label": "Gerenciador de Arquivos" + }, + "fileManager": { + "noHostSelected": "No host selected", + "initializingEditor": "Initializing editor...", + "file": "File", + "folder": "Pasta", + "uploadFile": "Enviar arquivo", + "downloadFile": "Download", + "extractArchive": "Extract Archive", + "extractingArchive": "Extracting {{name}}...", + "archiveExtractedSuccessfully": "{{name}} extracted successfully", + "extractFailed": "Extract failed", + "compressFile": "Compress File", + "compressFiles": "Compress Files", + "compressFilesDesc": "Compress {{count}} items into an archive", + "archiveName": "Archive Name", + "enterArchiveName": "Enter archive name...", + "compressionFormat": "Compression Format", + "selectedFiles": "Selected files", + "andMoreFiles": "and {{count}} more...", + "compress": "Compress", + "compressingFiles": "Compressing {{count}} items into {{name}}...", + "filesCompressedSuccessfully": "{{name}} created successfully", + "compressFailed": "Compression failed", + "edit": "Editar", + "preview": "Preview", + "previous": "Voltar", + "next": "Próximo", + "pageXOfY": "Page {{current}} of {{total}}", + "zoomOut": "Zoom Out", + "zoomIn": "Zoom In", + "newFile": "New File", + "newFolder": "New Folder", + "rename": "Renomear", + "uploading": "Uploading...", + "uploadingFile": "Uploading {{name}}...", + "uploadingChunk": "Uploading {{name}}: {{percent}}% (part {{chunk}} of {{total}})", + "fileName": "File Name", + "folderName": "Folder Name", + "fileUploadedSuccessfully": "File \"{{name}}\" uploaded successfully", + "failedToUploadFile": "Failed to upload file", + "uploadingFolderFiles": "Uploading {{count}} file(s)...", + "uploadedFolderFiles": "Uploaded {{count}} file(s) successfully", + "uploadedFolderPartial": "Uploaded {{uploaded}} file(s), {{failed}} failed", + "fileDownloadedSuccessfully": "File \"{{name}}\" downloaded successfully", + "failedToDownloadFile": "Failed to download file", + "fileCreatedSuccessfully": "File \"{{name}}\" created successfully", + "folderCreatedSuccessfully": "Folder \"{{name}}\" created successfully", + "failedToCreateItem": "Failed to create item", + "operationFailed": "{{operation}} operation failed for {{name}}: {{error}}", + "failedToResolveSymlink": "Failed to resolve symlink", + "itemsDeletedSuccessfully": "{{count}} items deleted successfully", + "failedToDeleteItems": "Failed to delete items", + "sudoPasswordRequired": "Administrator Password Required", + "enterSudoPassword": "Enter sudo password to continue this operation", + "sudoPassword": "Sudo password", + "sudoOperationFailed": "Sudo operation failed", + "sudoAuthFailed": "Sudo authentication failed", + "dragFilesToUpload": "Drop files here to upload", + "dropToUploadHere": "Drop to upload here", + "dropToDownloadHere": "Drop to download here", + "localFiles": "Local", + "showLocalFiles": "Show local files (split view)", + "hideLocalFiles": "Hide local files", + "localHome": "Home folder", + "localPathPlaceholder": "Local folder path", + "localShowHidden": "Show hidden files", + "localHideHidden": "Hide hidden files", + "localRevealInFileManager": "Reveal in system file manager", + "localCannotOpenFolder": "Cannot open folder", + "localItemCount": "{{count}} items", + "localSelectedCount": "{{count}} selected", + "back": "Voltar", + "forward": "Forward", + "up": "Up", + "kind": "Kind", + "localUploadingProgress": "Uploading {{current}} of {{total}}", + "localDownloadingProgress": "Downloading {{current}} of {{total}}", + "localTransferInFlight": "{{count}} at once", + "localPreparingDownload": "Preparing download...", + "localTransferCancelled": "Transfer cancelled", + "localNothingToTransfer": "Nothing to transfer", + "localUploadComplete": "Uploaded {{count}} file(s)", + "localUploadFailed": "Upload failed", + "localUploadPartial": "Uploaded {{done}} file(s), {{failed}} failed", + "localDownloadComplete": "Downloaded {{count}} file(s)", + "localDownloadFailed": "Download failed", + "localDownloadPartial": "Downloaded {{done}} file(s), {{failed}} failed", + "localReplaceExistingPrompt": "{{count}} item(s) already exist in this folder. Replace them?", + "localReplace": "Replace", + "localSkipExisting": "Skip", + "localSkippedExisting": "Skipped {{count}} existing item(s)", + "localUnsafeNamesSkipped": "Skipped {{count}} item(s) whose names cannot be used on this computer", + "localOpen": "Open", + "localOpenFolder": "Open folder", + "localUploadToRemote": "Upload to server", + "localUploadToRemoteMany": "Upload {{count}} items to server", + "localMoveToTrash": "Move to Trash", + "localMoveToTrashMany": "Move {{count}} items to Trash", + "localTrashConfirmSingle": "Move \"{{name}}\" to the Trash?", + "localTrashConfirmFolder": "Move the folder \"{{name}}\" and all its contents to the Trash?", + "localTrashConfirmMany": "Move {{count}} items to the Trash?", + "localTrashed": "Moved {{count}} item(s) to the Trash", + "localTrashFailed": "Could not move to the Trash", + "localRenameFailed": "Rename failed", + "localCreateFailed": "Could not create item", + "goToParentFolder": "Go to parent folder", + "resizeSidebar": "Drag to resize the sidebar (double-click to reset)", + "resizeLocalPane": "Drag to resize the local pane (double-click to reset)", + "columns": "Columns", + "columnsHint": "Right-click to choose columns", + "emptyFolder": "This folder is empty", + "searchFiles": "Search files...", + "upload": "Fazer upload", + "selectHostToStart": "Select a host to start file management", + "sshRequiredForFileManager": "File manager requires SSH. This host does not have SSH enabled.", + "failedToConnect": "Failed to connect to SSH", + "failedToLoadDirectory": "Failed to load directory", + "noSSHConnection": "No SSH connection available", + "copy": "Copiar", + "cut": "Cut", + "paste": "Colar", + "copyPath": "Copy Path", + "copyPaths": "Copy Paths", + "delete": "Apagar", + "properties": "Properties", + "refresh": "Atualizar", + "downloadFiles": "Download {{count}} files to Browser", + "copyFiles": "Copy {{count}} items", + "cutFiles": "Cut {{count}} items", + "deleteFiles": "Delete {{count}} items", + "filesCopiedToClipboard": "{{count}} items copied to clipboard", + "filesCutToClipboard": "{{count}} items cut to clipboard", + "pathCopiedToClipboard": "Path copied to clipboard", + "pathsCopiedToClipboard": "{{count}} paths copied to clipboard", + "failedToCopyPath": "Failed to copy path to clipboard", + "copyFolderLink": "Copy Link to Folder", + "copyCurrentFolderLink": "Copy Link to Current Folder", + "folderLinkCopied": "Folder link copied to clipboard", + "failedToCopyFolderLink": "Failed to copy folder link", + "movedItems": "Moved {{count}} items", + "failedToDeleteItem": "Failed to delete item", + "itemRenamedSuccessfully": "{{type}} renamed successfully", + "failedToRenameItem": "Failed to rename item", + "download": "Download", + "openExternalEditor": "Open externally", + "chooseExternalEditor": "Choose external editor", + "externalEditorSelected": "External editor selected", + "externalEditorDesktopOnly": "External editor is only available in the desktop app", + "externalEditorOpened": "Opened in external editor. Saving there will upload changes back to the server.", + "failedToOpenExternalEditor": "Failed to open external editor", + "failedToSelectExternalEditor": "Failed to select external editor", + "permissions": "Permissions", + "size": "Size", + "modified": "Modified", + "path": "Path", + "confirmDelete": "Are you sure you want to delete {{name}}?", + "permissionDenied": "Permission denied", + "serverError": "Server Error", + "fileSavedSuccessfully": "File saved successfully", + "failedToSaveFile": "Failed to save file", + "confirmDeleteSingleItem": "Are you sure you want to permanently delete \"{{name}}\"?", + "confirmDeleteMultipleItems": "Are you sure you want to permanently delete {{count}} items?", + "confirmDeleteMultipleItemsWithFolders": "Are you sure you want to permanently delete {{count}} items? This includes folders and their contents.", + "confirmDeleteFolder": "Are you sure you want to permanently delete the folder \"{{name}}\" and all its contents?", + "permanentDeleteWarning": "This action cannot be undone. The item(s) will be permanently deleted from the server.", + "moveToTrashWarning": "The item(s) will be moved to the Termix Trash and can be restored before the retention period expires.", + "itemsMovedToTrash": "{{count}} item(s) moved to Trash", + "trash": "Trash", + "trashDescription": "Deleted items are retained for {{days}} day(s) on this host.", + "trashLoadFailed": "Failed to load Trash", + "trashEmpty": "Trash is empty", + "trashRestore": "Restaurar", + "trashRestored": "Restored {{name}}", + "trashRestoreFailed": "Failed to restore item. The original path may already exist.", + "trashDeletePermanently": "Delete permanently", + "trashDeleteConfirm": "Permanently delete {{name}}? This cannot be undone.", + "trashPermanentlyDeleted": "Permanently deleted {{name}}", + "trashDeleteFailed": "Failed to permanently delete item", + "trashEmptyAction": "Empty Trash", + "trashEmptyConfirm": "Permanently delete every item in Trash? This cannot be undone.", + "trashEmptied": "Trash emptied", + "trashRetention": "Automatic cleanup after (days)", + "trashRetentionSaved": "Trash retention updated", + "trashRetentionFailed": "Failed to update Trash retention", + "trashUnavailableConfirm": "This item cannot be moved to Trash, usually because it is on another filesystem or requires elevated permissions. Delete it permanently instead?", + "recent": "Recent", + "pinned": "Pinned", + "folderShortcuts": "Folder Shortcuts", + "failedToReconnectSSH": "Failed to reconnect SSH session", + "openTerminalHere": "Open Terminal Here", + "run": "Run", + "openTerminalInFolder": "Open Terminal in This Folder", + "openTerminalInFileLocation": "Open Terminal at File Location", + "runningFile": "Running - {{file}}", + "onlyRunExecutableFiles": "Can only run executable files", + "directories": "Directories", + "removedFromRecentFiles": "Removed \"{{name}}\" from recent files", + "removeFailed": "Remove failed", + "unpinnedSuccessfully": "Unpinned \"{{name}}\" successfully", + "unpinFailed": "Unpin failed", + "removedShortcut": "Removed shortcut \"{{name}}\"", + "removeShortcutFailed": "Remove shortcut failed", + "clearedAllRecentFiles": "Cleared all recent files", + "clearFailed": "Clear failed", + "removeFromRecentFiles": "Remove from recent files", + "clearAllRecentFiles": "Clear all recent files", + "unpinFile": "Unpin file", + "removeShortcut": "Remove shortcut", + "pinFile": "Pin file", + "addToShortcuts": "Add to shortcuts", + "pasteFailed": "Paste failed", + "noUndoableActions": "No undoable actions", + "undoCopySuccess": "Undid copy operation: Deleted {{count}} copied files", + "undoCopyFailedDelete": "Undo failed: Could not delete any copied files", + "undoCopyFailedNoInfo": "Undo failed: Could not find copied file information", + "undoMoveSuccess": "Undid move operation: Moved {{count}} files back to original location", + "undoMoveFailedMove": "Undo failed: Could not move any files back", + "undoMoveFailedNoInfo": "Undo failed: Could not find moved file information", + "undoDeleteNotSupported": "Delete operation cannot be undone: Files have been permanently deleted from server", + "undoTypeNotSupported": "Unsupported undo operation type", + "undoOperationFailed": "Undo operation failed", + "unknownError": "Unknown error", + "confirm": "Confirmar", + "find": "Find...", + "replace": "Replace", + "downloadInstead": "Download Instead", + "keyboardShortcuts": "Keyboard Shortcuts", + "searchAndReplace": "Search & Replace", + "editing": "Editing", + "search": "Search", + "findNext": "Find Next", + "findPrevious": "Find Previous", + "save": "Salvar", + "selectAll": "Selecionar Tudo", + "undo": "Undo", + "redo": "Redo", + "moveLineUp": "Move Line Up", + "moveLineDown": "Move Line Down", + "toggleComment": "Toggle Comment", + "autoComplete": "Auto Complete", + "imageLoadError": "Failed to load image", + "startTyping": "Start typing...", + "unknownSize": "Unknown size", + "fileIsEmpty": "File is empty", + "largeFileWarning": "Large File Warning", + "largeFileWarningDesc": "This file is {{size}} in size, which may cause performance issues when opened as text.", + "fileNotFoundAndRemoved": "File \"{{name}}\" not found and has been removed from recent/pinned files", + "failedToLoadFile": "Failed to load file: {{error}}", + "serverErrorOccurred": "Server error occurred. Please try again later.", + "autoSaveFailed": "Auto-save failed", + "fileAutoSaved": "File auto-saved", + "moveFileFailed": "Failed to move {{name}}", + "moveOperationFailed": "Move operation failed", + "canOnlyCompareFiles": "Can only compare two files", + "comparingFiles": "Comparing files: {{file1}} and {{file2}}", + "dragFailed": "Drag operation failed", + "filePinnedSuccessfully": "File \"{{name}}\" pinned successfully", + "pinFileFailed": "Failed to pin file", + "fileUnpinnedSuccessfully": "File \"{{name}}\" unpinned successfully", + "unpinFileFailed": "Failed to unpin file", + "shortcutAddedSuccessfully": "Folder shortcut \"{{name}}\" added successfully", + "addShortcutFailed": "Failed to add shortcut", + "operationCompletedSuccessfully": "{{operation}} {{count}} items successfully", + "operationCompleted": "{{operation}} {{count}} items", + "downloadFileSuccess": "File {{name}} downloaded successfully", + "downloadFileFailed": "Download failed", + "downloadingFile": "Downloading {{name}}…", + "downloadProgressBytes": "{{transferred}} / {{total}}", + "moveTo": "Move to {{name}}", + "diffCompareWith": "Diff compare with {{name}}", + "dragOutsideToDownload": "Drag outside window to download ({{count}} files)", + "newFolderDefault": "NewFolder", + "newFileDefault": "NewFile.txt", + "successfullyMovedItems": "Successfully moved {{count}} items to {{target}}", + "move": "Move", + "searchInFile": "Search in file (Ctrl+F)", + "showKeyboardShortcuts": "Show keyboard shortcuts", + "decreaseFontSize": "Decrease font size", + "increaseFontSize": "Increase font size", + "startWritingMarkdown": "Start writing your markdown content...", + "loadingFileComparison": "Loading file comparison...", + "reload": "Recarregar", + "compare": "Compare", + "sideBySide": "Side by Side", + "inline": "Inline", + "fileComparison": "File Comparison: {{file1}} vs {{file2}}", + "fileTooLarge": "File too large: {{error}}", + "sshConnectionFailed": "SSH connection failed. Please check your connection to {{name}} ({{ip}}:{{port}})", + "loadFileFailed": "Failed to load file: {{error}}", + "connecting": "Conectando...", + "connectedSuccessfully": "Connected successfully", + "totpVerificationFailed": "TOTP verification failed", + "browserSignInFailed": "Sign-in failed. Please try again.", + "authenticationFailed": "Authentication failed", + "incorrectPassphrase": "Incorrect passphrase. Please try again.", + "verificationCodePrompt": "Verification code:", + "changePermissions": "Change Permissions", + "currentPermissions": "Current Permissions", + "owner": "Owner", + "group": "Group", + "others": "Others", + "read": "Read", + "write": "Write", + "execute": "Execute", + "permissionsChangedSuccessfully": "Permissions changed successfully", + "failedToChangePermissions": "Failed to change permissions", + "name": "Name", + "sortByName": "Name", + "sortByDate": "Date Modified", + "sortBySize": "Size", + "ascending": "Ascending", + "descending": "Descending", + "root": "Root", + "new": "New", + "sortBy": "Sort By", + "items": "Items", + "selected": "Selected", + "editor": "Editor", + "octal": "Octal", + "storage": "Storage", + "disk": "Disk", + "used": "Used", + "of": "de", + "toggleSidebar": "Toggle Sidebar", + "compactLayout": "Use compact layout", + "comfortableLayout": "Use comfortable layout", + "cannotLoadPdf": "Cannot load PDF", + "pdfLoadError": "There was an error loading this PDF file.", + "loadingPdf": "Loading PDF...", + "loadingPage": "Loading page...", + "cancel": "Cancelar", + "copiedItems_one": "Copied {{count}} item", + "copiedItems_other": "Copied {{count}} items", + "deleteCopiedFileFailed": "Could not delete the copy of {{name}}: {{error}}", + "dragMovedItems_one": "Moved {{count}} item to {{target}}", + "dragMovedItems_other": "Moved {{count}} items to {{target}}", + "moveBackFileFailed": "Could not move {{name}} back: {{error}}", + "terminal": "Terminal: {{host}} ({{path}})", + "dragToDesktop": "Dragging {{name}} to the desktop", + "dragFilesToDesktop": "Dragging {{count}} files to the desktop", + "folderDragUnsupported": "Dragging folders to the desktop is not supported yet", + "saveToDesktopFailed": "Save failed: {{error}}", + "dragFailedDetail": "Drag failed: {{error}}", + "videoUnsupported": "Your browser cannot play this video format.", + "downloadToPlay": "Download to play it elsewhere", + "cannotPreviewType": "Cannot preview this file type", + "cannotPreviewTypeHint": "This file type has no preview. Download it to open it in another app." + }, + "sftpTransfer": { + "title": "SFTP", + "description": "Transfer files between two SSH hosts.", + "sourceServer": "Source Server", + "destinationServer": "Destination Server", + "selectHost": "Select host", + "noHostSelected": "No host selected", + "move": "Move", + "copy": "Copiar", + "upload": "Enviar", + "itemsSelected": "{{count}} item selected", + "itemsSelected_other": "{{count}} items selected", + "ready": "Ready", + "loadingHosts": "Loading hosts...", + "name": "Name", + "modified": "Modified", + "size": "Size", + "noFiles": "No files", + "open": "Open", + "up": "Up", + "refresh": "Atualizar", + "copyToTarget": "Copy to Target Directory", + "rename": "Renomear", + "delete": "Apagar", + "editPermissions": "Edit Permissions", + "createNewFolder": "Create New Folder", + "deleteSelectedItems": "Delete Selected Items", + "deleteConfirm": "Delete {{count}} selected item?", + "deleteConfirm_other": "Delete {{count}} selected items?", + "cancel": "Cancelar", + "save": "Salvar", + "folderCreated": "Folder created", + "itemRenamed": "Item renamed", + "actionFailed": "Action failed", + "itemsDeleted": "{{count}} item deleted", + "itemsDeleted_other": "{{count}} items deleted", + "deleteFailed": "Delete failed", + "permissionsUpdated": "Permissions updated", + "noRemoteSessionConnected": "No remote session connected", + "failedToListFiles": "Failed to list files", + "failedToRefresh": "Failed to refresh", + "destinationInsideSource": "Destination cannot be inside the selected source path.", + "sameHostNoOp": "Source and destination are the same folder." + }, + "hosts": { + "fileManager": "Gerenciador de Arquivos", + "fileManagerUrlCopied": "File Manager URL copied", + "copyFileManagerUrlAction": "Copiar URL do Gerenciador de Arquivos", + "docsLink": "Documentação", + "hostNotFound": "Host not found", + "loadingHost": "Loading host..." }, "onboarding": { - "feature_files": "Gerenciador de arquivos", - "feature_files_desc": "Navegue, carregue, baixe e edite arquivos via SFTP sem sair do aplicativo." + "feature_files": "File manager", + "feature_files_desc": "Browse, upload, download and edit files over SFTP without leaving the app." }, "terminal": { - "runTitle": "Executando {{command}} - {{host}}", + "runTitle": "Running {{command}} - {{host}}", "terminalTitle": "Terminal - {{host}}", "terminalWithPath": "Terminal - {{host}}:{{path}}" }, "transfer": { - "browseFolders": "Procurar pastas de destino", - "browsePathError": "Não foi possível abrir este caminho no host de destino.", - "browsePathWillBeCreated": "Esta pasta ainda não existe. Ela será criada quando a transferência começar.", + "browseFolders": "Browse destination folders", + "browsePathError": "Could not open this path on the destination host.", + "browsePathWillBeCreated": "This folder does not exist yet. It will be created when the transfer starts.", "cancel": "Cancelar", - "cleanupDestFiles": "destino de limpeza", - "cleanupDestFilesError": "A limpeza falhou", - "cleanupDestFilesNothing": "Nada para limpar no destino.", - "cleanupDestFilesPartial": "Alguns arquivos parciais não puderam ser removidos.", - "cleanupDestFilesSuccess": "Arquivos parciais removidos do destino.", - "confirmCopy": "Cópia", - "confirmMove": "Mover", - "copyFolderToHost": "Copiar pasta para o host…", - "copyItemsToHost": "Copiar {{count}} itens para o host…", - "copyToHost": "Copiar para o host…", - "destinationPath": "Caminho de destino", - "destMustBeDirectory": "O destino deve ser um diretório para transferências de múltiplos itens.", - "goUp": "Subir", - "hostAuthRequired": "Autenticação necessária — abra o Gerenciador de Arquivos neste host primeiro.", - "hostConnecting": "Conectando…", - "hostConnectionFailed": "Falha na conexão", - "hostDisconnected": "Não conectado", - "hostReady": "Preparar", - "itemsSummary": "{{count}} itens", - "jumpHostLimitation": "Ambos os hosts devem ser acessíveis a partir do servidor Termix. O roteamento direto de host para host não é suportado.", + "cleanupDestFiles": "Clean up destination", + "cleanupDestFilesError": "Cleanup failed", + "cleanupDestFilesNothing": "Nothing to clean up on the destination", + "cleanupDestFilesPartial": "Some partial files could not be removed", + "cleanupDestFilesSuccess": "Removed partial files from the destination", + "confirmCopy": "Copiar", + "confirmMove": "Move", + "copyFolderToHost": "Copy folder to host…", + "copyItemsToHost": "Copy {{count}} items to host…", + "copyToHost": "Copy to host…", + "destinationPath": "Destination path", + "destMustBeDirectory": "Destination must be a directory for multi-item transfers", + "goUp": "Go up", + "hostAuthRequired": "Authentication required. Open File Manager on this host first", + "hostConnecting": "Connecting…", + "hostConnectionFailed": "Connection failed", + "hostDisconnected": "Not connected", + "hostReady": "Ready", + "itemsSummary": "{{count}} items", + "jumpHostLimitation": "Both hosts must be reachable from the Termix server. Direct host-to-host routing is not supported.", "methodAuto": "Auto", - "methodAutoHint": "Seleciona o método de compactação (tar) ou SFTP por arquivo com base na quantidade de arquivos, tamanho e compressibilidade. Arquivos individuais sempre utilizam SFTP de streaming.", - "methodItemSftp": "SFTP por arquivo", - "methodItemSftpHint": "Transfira cada arquivo individualmente via SFTP. Funciona em todos os hosts, incluindo Windows.", - "methodItemSftpLimitation": "Cada arquivo utiliza o mesmo fluxo SFTP como uma cópia de arquivo único, um após o outro. O progresso é combinado em todos os arquivos, portanto a barra se move lentamente durante a transferência de arquivos grandes.", - "methodLabel": "Método de transferência", - "methodPreviewError": "Não foi possível visualizar o método de transferência. O servidor ainda escolherá um método quando você iniciar o servidor.", - "methodPreviewLoading": "Calculando o método de transferência…", - "methodPreviewScanSummary": "{{fileCount}} arquivos, {{totalSize}} total (verificado no host de origem).", - "methodPreviewWillUseItemSftp": "Será utilizado: SFTP por arquivo", - "methodPreviewWillUseTar": "Será utilizado: Arquivo tar", + "methodAutoHint": "Picks tar or per-file SFTP based on file count, size, and compressibility. Single files always use streaming SFTP.", + "methodItemSftp": "Per-file SFTP", + "methodItemSftpHint": "Transfer each file individually over SFTP. Works on all hosts including Windows.", + "methodItemSftpLimitation": "Each file uses the same SFTP stream as a single-file copy, one after another. Progress is combined across all files, so the bar moves slowly during large files.", + "methodLabel": "Transfer method", + "methodPreviewError": "Could not preview transfer method. The server will still pick a method when you start.", + "methodPreviewLoading": "Calculating transfer method…", + "methodPreviewScanSummary": "{{fileCount}} files, {{totalSize}} total (scanned on source host).", + "methodPreviewWillUseItemSftp": "Will use: Per-file SFTP", + "methodPreviewWillUseTar": "Will use: Tar archive", "methodReason": { - "user_item_sftp": "Você escolheu SFTP por arquivo.", - "user_tar": "Você escolheu o arquivo tar.", - "tar_unavailable": "O arquivo tar não está disponível em um ou ambos os hosts — em vez disso, será usado o SFTP por arquivo.", - "windows_host": "O sistema operacional host é Windows — o arquivo tar não é utilizado.", - "auto_multi_large": "Automático: vários arquivos, incluindo um arquivo grande ({{largestSize}}) com dados compressíveis — pacotes tar em uma única transferência.", - "auto_single_large_in_archive": "Automático: um arquivo grande ({{largestSize}}) neste conjunto — SFTP por arquivo.", - "auto_many_incompressible": "Automático: dados em sua maioria não compressíveis — SFTP por arquivo.", - "auto_many_files": "Automático: muitos arquivos ({{fileCount}}) — tar reduz a sobrecarga por arquivo.", - "auto_default": "Automático: SFTP por arquivo para este conjunto." + "user_item_sftp": "You chose per-file SFTP.", + "user_tar": "You chose tar archive.", + "tar_unavailable": "Tar is not available on one or both hosts, so per-file SFTP will be used instead.", + "windows_host": "A Windows host is involved, so tar is not used.", + "auto_multi_large": "Auto: multiple files including a large file ({{largestSize}}) with compressible data. Tar bundles them into one transfer.", + "auto_single_large_in_archive": "Auto: one large file ({{largestSize}}) in this set, so per-file SFTP.", + "auto_many_incompressible": "Auto: mostly incompressible data, so per-file SFTP.", + "auto_many_files": "Auto: many files ({{fileCount}}), tar cuts the per-file overhead.", + "auto_default": "Auto: per-file SFTP for this set." }, - "methodTar": "Arquivo Tar", - "methodTarHint": "Comprima na origem, transfira um único arquivo compactado e extraia no destino. Requer o uso do tar em ambos os hosts Unix.", - "metricsCompress": "Comprimir na origem: {{duration}}", - "metricsExtract": "Extrair no destino: {{duration}}", - "metricsPrepare": "Preparar destino: {{duration}}", - "metricsRouteBenchmark": "Sondagem de rota — direta: {{direct}}, retransmissão: {{relay}}", - "metricsSourceDelete": "Remover da fonte: {{duration}}", + "methodTar": "Tar archive", + "methodTarHint": "Compress on source, transfer one archive, extract on destination. Requires tar on both Unix hosts.", + "metricsCompress": "Compress on source: {{duration}}", + "metricsExtract": "Extract on destination: {{duration}}", + "metricsPrepare": "Prepare destination: {{duration}}", + "metricsRouteBenchmark": "Route probe: direct {{direct}}, relay {{relay}}", + "metricsSourceDelete": "Remove from source: {{duration}}", "metricsTotal": "Total: {{duration}}", - "metricsTransfer": "De ponta a ponta: {{throughput}} ({{duration}})", - "metricsVerify": "Verificado por SHA-256: {{duration}}", - "moveFolderToHost": "Mover pasta para o host…", - "moveItemsToHost": "Mova {{count}} itens para o host…", - "moveToHost": "Mover para o host…", - "noHostsConnected": "Não há outros servidores de gerenciamento de arquivos disponíveis.", - "noHostsConnectedHint": "Adicione outro host SSH com o Gerenciador de Arquivos habilitado no Gerenciador de Hosts.", - "parallelSegmentsHint": "Arquivos grandes são divididos em partes de 256 MB. Várias vias utilizam conexões separadas (como iniciar várias transferências) para obter uma taxa de transferência total maior.", - "parallelSegmentsLabel": "Faixas de transferência paralelas", - "parallelSegmentsOption": "{{count}} faixas", - "progressBenchmarking": "Selecionando a rota de transferência mais rápida…", + "metricsTransfer": "End-to-end: {{throughput}} ({{duration}})", + "metricsVerify": "SHA-256 verified: {{duration}}", + "moveFolderToHost": "Move folder to host…", + "moveItemsToHost": "Move {{count}} items to host…", + "moveToHost": "Move to host…", + "noHostsConnected": "No other file-manager hosts available.", + "noHostsConnectedHint": "Add another SSH host with File Manager enabled in Host Manager.", + "parallelSegmentsHint": "Large files are split into 256 MB chunks. Multiple lanes use separate connections (like starting several transfers) for higher total throughput.", + "parallelSegmentsLabel": "Parallel transfer lanes", + "parallelSegmentsOption": "{{count}} lanes", + "progressBenchmarking": "Selecting the fastest transfer route…", "progressBytes": "{{transferred}} / {{total}}", "progressCancel": "Cancelar", - "progressCancelling": "Cancelando…", - "progressCompressing": "Comprimindo no host de origem…", - "progressExtracting": "Extraindo no destino…", - "progressItems": "{{current}} / {{total}} arquivos", - "progressReconnecting": "Reconectando…", - "progressStalled": "Paralisado", - "progressTotalSpeed": "{{speed}} total ({{lanes}} faixas)", - "progressTransferring": "Transferindo dados…", - "progressTransferringItems": "Transferindo arquivos ({{current}} de {{total}})…", - "progressVerifying": "Verificando a integridade do arquivo…", - "recentDestinations": "Destinos recentes", - "resumedHint": "Reconectado a uma transferência ativa iniciada em outra janela.", - "retryTransfer": "Tentar novamente", - "retryTransferError": "A nova tentativa falhou.", - "selectDestinationHost": "Selecione o host de destino", - "transferCancelled": "Transferência cancelada", - "transferCancelledCopyHint": "Alguns arquivos podem permanecer no destino.", - "transferCancelledMoveHint": "É possível que alguns arquivos permaneçam no destino. Os arquivos de origem não foram removidos.", - "transferError": "A transferência falhou", - "transferFailedRetryHint": "Dados parciais foram mantidos no destino. A tentativa será retomada quando a conexão for restabelecida.", - "transferPartialHint": "Não foi possível transferir: {{paths}}", - "transferSuccess": "Transferência concluída" + "progressCancelling": "Cancelling…", + "progressCompressing": "Compressing on source host…", + "progressExtracting": "Extracting on destination…", + "progressItems": "{{current}} / {{total}} files", + "progressReconnecting": "Reconnecting…", + "progressStalled": "Stalled", + "progressTotalSpeed": "{{speed}} total ({{lanes}} lanes)", + "progressTransferring": "Transferring data…", + "progressTransferringItems": "Transferring files ({{current}} of {{total}})…", + "progressVerifying": "Verifying file integrity…", + "recentDestinations": "Recent destinations", + "resumedHint": "Reconnected to an active transfer started in another window.", + "retryTransfer": "Retry", + "retryTransferError": "Retry failed", + "selectDestinationHost": "Select destination host", + "transferCancelled": "Transfer cancelled", + "transferCancelledCopyHint": "Partial files may remain on the destination.", + "transferCancelledMoveHint": "Partial files may remain on the destination. Source files were not removed.", + "transferError": "Transfer failed", + "transferFailedRetryHint": "Partial data was kept on the destination. Retry will resume when the connection is back.", + "transferPartialHint": "Could not transfer: {{paths}}", + "transferSuccess": "Transfer complete", + "metricsHopSourceRead": "Source → server: {{throughput}}", + "metricsHopDestSftpWrite": "Server → dest (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Server → dest (local): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/pt_PT.json b/plugins/file-manager/locales/translated/pt_PT.json index c6c4b88fb..e0f1b14b4 100644 --- a/plugins/file-manager/locales/translated/pt_PT.json +++ b/plugins/file-manager/locales/translated/pt_PT.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "Ficheiros", + "sftp": "SFTP", + "openFileManager": "Abrir Gestor de Ficheiros" + }, + "permissions": { + "use": { + "title": "Use file manager", + "description": "Browse, edit and transfer files over SFTP." + } + }, + "settings": { + "host": { + "enable": { + "label": "Ativar Gestor de Ficheiros", + "description": "Browse and edit files on this host over SFTP." + }, + "defaultPath": { + "label": "Caminho Predefinido" + }, + "scpLegacy": { + "label": "Modo SCP Legado" + } + }, + "user": { + "transferConcurrency": { + "label": "Simultaneous File Transfers", + "description": "How many files the side by side local/remote manager uploads or downloads at the same time. Lower this if your server limits SFTP channels." + }, + "confirmBeforeTrash": { + "label": "Confirm before moving files to trash", + "description": "Ask before moving remote files to trash. Permanent deletion still requires confirmation." + } + } + }, + "hostCapability": { + "label": "Gestor de Ficheiros" + }, "fileManager": { "noHostSelected": "Nenhum host selecionado", "initializingEditor": "A inicializar editor...", @@ -34,12 +72,13 @@ "rename": "Renomear", "uploading": "A enviar...", "uploadingFile": "A enviar {{name}}...", + "uploadingChunk": "Uploading {{name}}: {{percent}}% (part {{chunk}} of {{total}})", "fileName": "Nome do ficheiro", "folderName": "Nome da pasta", "fileUploadedSuccessfully": "Ficheiro \"{{name}}\" enviado com sucesso", "failedToUploadFile": "Falha ao enviar ficheiro", - "uploadingFolderFiles": "A enviar {{count}} ficheiro(s)...", - "uploadedFolderFiles": "Ficheiro(s) carregado(s) com sucesso {{count}}", + "uploadingFolderFiles": "Uploading {{count}} file(s)...", + "uploadedFolderFiles": "Uploaded {{count}} file(s) successfully", "uploadedFolderPartial": "Uploaded {{uploaded}} file(s), {{failed}} failed", "fileDownloadedSuccessfully": "Ficheiro \"{{name}}\" descarregado com sucesso", "failedToDownloadFile": "Falha ao descarregar ficheiro", @@ -56,58 +95,58 @@ "sudoOperationFailed": "Operação sudo falhou", "sudoAuthFailed": "Autenticação sudo falhou", "dragFilesToUpload": "Arraste ficheiros aqui para carregar", - "dropToUploadHere": "Arraste e faça o upload aqui.", - "dropToDownloadHere": "Faça o download aqui.", + "dropToUploadHere": "Drop to upload here", + "dropToDownloadHere": "Drop to download here", "localFiles": "Local", - "showLocalFiles": "Visualizar ficheiros locais (visualização dividida)", - "hideLocalFiles": "Ocultar ficheiros locais", - "localHome": "Pasta inicial", - "localPathPlaceholder": "Caminho da pasta local", - "localShowHidden": "Mostrar ficheiros ocultos", - "localHideHidden": "Ocultar ficheiros ocultos", - "localRevealInFileManager": "Exibir no gestor de ficheiros do sistema", - "localCannotOpenFolder": "Não é possível abrir a pasta", - "localItemCount": "{{count}} artigos", - "localSelectedCount": "{{count}} selecionado", - "back": "Costas", - "forward": "Encaminhar", - "up": "Para cima", - "kind": "Amabilidade", - "localUploadingProgress": "A enviar {{current}} de {{total}}", - "localDownloadingProgress": "A descarregar {{current}} de {{total}}", - "localTransferInFlight": "{{count}} imediatamente", - "localPreparingDownload": "A preparar o download...", + "showLocalFiles": "Show local files (split view)", + "hideLocalFiles": "Hide local files", + "localHome": "Home folder", + "localPathPlaceholder": "Local folder path", + "localShowHidden": "Show hidden files", + "localHideHidden": "Hide hidden files", + "localRevealInFileManager": "Reveal in system file manager", + "localCannotOpenFolder": "Cannot open folder", + "localItemCount": "{{count}} itens", + "localSelectedCount": "{{count}} selecionado(s)", + "back": "Voltar", + "forward": "Forward", + "up": "Up", + "kind": "Kind", + "localUploadingProgress": "Uploading {{current}} of {{total}}", + "localDownloadingProgress": "Downloading {{current}} of {{total}}", + "localTransferInFlight": "{{count}} at once", + "localPreparingDownload": "Preparing download...", "localTransferCancelled": "Transferência cancelada", - "localNothingToTransfer": "Nada a transferir", + "localNothingToTransfer": "Nothing to transfer", "localUploadComplete": "Uploaded {{count}} file(s)", - "localUploadFailed": "Falha no upload", + "localUploadFailed": "Upload failed", "localUploadPartial": "Uploaded {{done}} file(s), {{failed}} failed", - "localDownloadComplete": "Ficheiro(s) descarregado(s) {{count}}", - "localDownloadFailed": "Falha no download", + "localDownloadComplete": "Downloaded {{count}} file(s)", + "localDownloadFailed": "Falha ao descarregar", "localDownloadPartial": "Downloaded {{done}} file(s), {{failed}} failed", - "localReplaceExistingPrompt": "{{count}} Já existem itens nesta pasta. Deseja substituí-los?", + "localReplaceExistingPrompt": "{{count}} item(s) already exist in this folder. Replace them?", "localReplace": "Substituir", - "localSkipExisting": "Ignorar", - "localSkippedExisting": "Ignorou {{count}} item(s) existente(s)", - "localUnsafeNamesSkipped": "Ignorado {{count}} item(s) cujos nomes não podem ser utilizados neste computador", - "localOpen": "Aberto", - "localOpenFolder": "Abra a pasta", - "localUploadToRemote": "Enviar para o servidor", - "localUploadToRemoteMany": "Enviar {{count}} itens para o servidor", - "localMoveToTrash": "Mover para a Reciclagem", - "localMoveToTrashMany": "Mover {{count}} itens para a Reciclagem", - "localTrashConfirmSingle": "Deslocar \"{{name}}\" para a Reciclagem?", - "localTrashConfirmFolder": "Mover a pasta \"{{name}}\" e todo o seu conteúdo para a Reciclagem?", - "localTrashConfirmMany": "Mover {{count}} itens para a Reciclagem?", - "localTrashed": "Movidos {{count}} itens para a Reciclagem", - "localTrashFailed": "Não foi possível mover para a Reciclagem", - "localRenameFailed": "A renomeação falhou", - "localCreateFailed": "Não foi possível criar o item.", - "goToParentFolder": "Aceda à pasta principal", - "resizeSidebar": "Arraste para redimensionar a barra lateral (clique duas vezes para repor).", - "resizeLocalPane": "Arraste para redimensionar o painel local (clique duas vezes para repor).", + "localSkipExisting": "Skip", + "localSkippedExisting": "Skipped {{count}} existing item(s)", + "localUnsafeNamesSkipped": "Skipped {{count}} item(s) whose names cannot be used on this computer", + "localOpen": "Abrir", + "localOpenFolder": "Open folder", + "localUploadToRemote": "Upload to server", + "localUploadToRemoteMany": "Upload {{count}} items to server", + "localMoveToTrash": "Move to Trash", + "localMoveToTrashMany": "Move {{count}} items to Trash", + "localTrashConfirmSingle": "Move \"{{name}}\" to the Trash?", + "localTrashConfirmFolder": "Move the folder \"{{name}}\" and all its contents to the Trash?", + "localTrashConfirmMany": "Move {{count}} items to the Trash?", + "localTrashed": "Moved {{count}} item(s) to the Trash", + "localTrashFailed": "Could not move to the Trash", + "localRenameFailed": "Rename failed", + "localCreateFailed": "Could not create item", + "goToParentFolder": "Go to parent folder", + "resizeSidebar": "Drag to resize the sidebar (double-click to reset)", + "resizeLocalPane": "Drag to resize the local pane (double-click to reset)", "columns": "Colunas", - "columnsHint": "Clique com o botão direito do rato para escolher as colunas.", + "columnsHint": "Right-click to choose columns", "emptyFolder": "Esta pasta está vazia", "searchFiles": "Procurar ficheiros...", "upload": "Carregar", @@ -163,26 +202,26 @@ "confirmDeleteMultipleItemsWithFolders": "Tem a certeza de que pretende eliminar permanentemente {{count}} itens? Isto inclui pastas e o seu conteúdo.", "confirmDeleteFolder": "Tem a certeza de que pretende eliminar permanentemente a pasta \"{{name}}\" e todo o seu conteúdo?", "permanentDeleteWarning": "Esta ação não pode ser anulada. Os itens serão permanentemente eliminados do servidor.", - "moveToTrashWarning": "O(s) artigo(s) será(ão) movido(s) para a Reciclagem Termix e poderá(ão) ser restaurado(s) antes do fim do período de retenção.", - "itemsMovedToTrash": "{{count}} artigo(s) movido(s) para a Reciclagem", - "trash": "Lixo", - "trashDescription": "Os itens eliminados são retidos durante {{days}} dia(s) neste host.", - "trashLoadFailed": "Falha ao carregar a Reciclagem", - "trashEmpty": "A papeleira está vazia.", + "moveToTrashWarning": "The item(s) will be moved to the Termix Trash and can be restored before the retention period expires.", + "itemsMovedToTrash": "{{count}} item(s) moved to Trash", + "trash": "Trash", + "trashDescription": "Deleted items are retained for {{days}} day(s) on this host.", + "trashLoadFailed": "Failed to load Trash", + "trashEmpty": "Trash is empty", "trashRestore": "Restaurar", - "trashRestored": "Restaurado {{name}}", - "trashRestoreFailed": "Falha ao restaurar o item. O caminho original pode já existir.", - "trashDeletePermanently": "Apagar permanentemente", - "trashDeleteConfirm": "Apagar permanentemente {{name}}? Esta ação não pode ser anulada.", - "trashPermanentlyDeleted": "Eliminado permanentemente {{name}}", - "trashDeleteFailed": "Falha ao eliminar o item permanentemente", - "trashEmptyAction": "Esvaziar o lixo", - "trashEmptyConfirm": "Apagar permanentemente todos os itens da Reciclagem? Esta ação é irreversível.", - "trashEmptied": "Lixo esvaziado", - "trashRetention": "Limpeza automática após (dias)", - "trashRetentionSaved": "Retenção de lixo atualizada", - "trashRetentionFailed": "Falha na atualização da retenção de lixo", - "trashUnavailableConfirm": "Este item não pode ser movido para a Reciclagem, geralmente porque está noutro sistema de ficheiros ou requer permissões elevadas. Deseja eliminá-lo permanentemente?", + "trashRestored": "Restored {{name}}", + "trashRestoreFailed": "Failed to restore item. The original path may already exist.", + "trashDeletePermanently": "Delete permanently", + "trashDeleteConfirm": "Permanently delete {{name}}? This cannot be undone.", + "trashPermanentlyDeleted": "Permanently deleted {{name}}", + "trashDeleteFailed": "Failed to permanently delete item", + "trashEmptyAction": "Empty Trash", + "trashEmptyConfirm": "Permanently delete every item in Trash? This cannot be undone.", + "trashEmptied": "Trash emptied", + "trashRetention": "Automatic cleanup after (days)", + "trashRetentionSaved": "Trash retention updated", + "trashRetentionFailed": "Failed to update Trash retention", + "trashUnavailableConfirm": "This item cannot be moved to Trash, usually because it is on another filesystem or requires elevated permissions. Delete it permanently instead?", "recent": "Recentes", "pinned": "Fixados", "folderShortcuts": "Atalhos de pastas", @@ -264,7 +303,7 @@ "operationCompleted": "{{operation}} {{count}} itens", "downloadFileSuccess": "Ficheiro {{name}} descarregado com sucesso", "downloadFileFailed": "Falha ao descarregar", - "downloadingFile": "A descarregar {{name}}…", + "downloadingFile": "Downloading {{name}}…", "downloadProgressBytes": "{{transferred}} / {{total}}", "moveTo": "Mover para {{name}}", "diffCompareWith": "Comparar diferenças com {{name}}", @@ -290,6 +329,7 @@ "connecting": "A ligar...", "connectedSuccessfully": "Ligado com sucesso", "totpVerificationFailed": "Falha na verificação TOTP", + "browserSignInFailed": "Sign-in failed. Please try again.", "authenticationFailed": "Falha na autenticação", "incorrectPassphrase": "Frase-passe incorreta. Tente novamente.", "verificationCodePrompt": "Código de verificação:", @@ -321,98 +361,85 @@ "used": "Utilizado", "of": "de", "toggleSidebar": "Alternar Barra Lateral", - "compactLayout": "Utilize um layout compacto.", - "comfortableLayout": "Utilize um layout confortável", + "compactLayout": "Use compact layout", + "comfortableLayout": "Use comfortable layout", "cannotLoadPdf": "Não é possível carregar o PDF", "pdfLoadError": "Ocorreu um erro ao carregar este ficheiro PDF.", "loadingPdf": "A carregar PDF...", - "loadingPage": "A carregar página..." + "loadingPage": "A carregar página...", + "cancel": "Cancelar", + "copiedItems_one": "Copied {{count}} item", + "copiedItems_other": "Copied {{count}} items", + "deleteCopiedFileFailed": "Could not delete the copy of {{name}}: {{error}}", + "dragMovedItems_one": "Moved {{count}} item to {{target}}", + "dragMovedItems_other": "Moved {{count}} items to {{target}}", + "moveBackFileFailed": "Could not move {{name}} back: {{error}}", + "terminal": "Terminal: {{host}} ({{path}})", + "dragToDesktop": "Dragging {{name}} to the desktop", + "dragFilesToDesktop": "Dragging {{count}} files to the desktop", + "folderDragUnsupported": "Dragging folders to the desktop is not supported yet", + "saveToDesktopFailed": "Save failed: {{error}}", + "dragFailedDetail": "Drag failed: {{error}}", + "videoUnsupported": "Your browser cannot play this video format.", + "downloadToPlay": "Download to play it elsewhere", + "cannotPreviewType": "Cannot preview this file type", + "cannotPreviewTypeHint": "This file type has no preview. Download it to open it in another app." }, "sftpTransfer": { "title": "SFTP", - "description": "Transferir ficheiros entre dois hosts SSH.", - "sourceServer": "Servidor de origem", - "destinationServer": "Servidor de destino", - "selectHost": "Selecione o host", - "noHostSelected": "Nenhum host selecionado", + "description": "Transfer files between two SSH hosts.", + "sourceServer": "Source Server", + "destinationServer": "Destination Server", + "selectHost": "Select host", + "noHostSelected": "Nenhum anfitrião selecionado", "move": "Mover", - "copy": "Cópia", + "copy": "Copiar", "upload": "Carregar", - "itemsSelected": "{{count}} item selecionado", - "itemsSelected_other": "{{count}} itens selecionados", + "itemsSelected": "{{count}} item selected", + "itemsSelected_other": "{{count}} items selected", "ready": "Pronto", - "loadingHosts": "Carregando hosts...", + "loadingHosts": "A carregar hosts...", "name": "Nome", "modified": "Modificado", "size": "Tamanho", - "noFiles": "Nenhum ficheiro", - "open": "Aberto", - "up": "Para cima", + "noFiles": "No files", + "open": "Abrir", + "up": "Up", "refresh": "Atualizar", - "copyToTarget": "Copiar para o diretório de destino", + "copyToTarget": "Copy to Target Directory", "rename": "Renomear", "delete": "Eliminar", - "editPermissions": "Editar permissões", - "createNewFolder": "Criar nova pasta", - "deleteSelectedItems": "Apagar itens selecionados", + "editPermissions": "Edit Permissions", + "createNewFolder": "Create New Folder", + "deleteSelectedItems": "Delete Selected Items", "deleteConfirm": "Delete {{count}} selected item?", - "deleteConfirm_other": "Apagar {{count}} itens selecionados?", + "deleteConfirm_other": "Delete {{count}} selected items?", "cancel": "Cancelar", "save": "Guardar", - "folderCreated": "Pasta criada", - "itemRenamed": "Artigo renomeado", + "folderCreated": "Folder created", + "itemRenamed": "Item renamed", "actionFailed": "A ação falhou", - "itemsDeleted": "{{count}} item eliminado", - "itemsDeleted_other": "{{count}} itens eliminados", - "deleteFailed": "Falha ao eliminar", - "permissionsUpdated": "Permissões atualizadas", - "noRemoteSessionConnected": "Nenhuma sessão remota ligada.", - "failedToListFiles": "Falha ao listar os ficheiros", - "failedToRefresh": "Falha ao atualizar", - "destinationInsideSource": "O destino não pode estar dentro do caminho de origem selecionado.", - "sameHostNoOp": "A origem e o destino são a mesma pasta." + "itemsDeleted": "{{count}} item deleted", + "itemsDeleted_other": "{{count}} items deleted", + "deleteFailed": "Delete failed", + "permissionsUpdated": "Permissions updated", + "noRemoteSessionConnected": "No remote session connected", + "failedToListFiles": "Failed to list files", + "failedToRefresh": "Failed to refresh", + "destinationInsideSource": "Destination cannot be inside the selected source path.", + "sameHostNoOp": "Source and destination are the same folder." }, "hosts": { "fileManager": "Gestor de Ficheiros", - "tabFiles": "Ficheiros", - "enableFileManagerMonitor": "Ativar Gestor de Ficheiros", - "enableFileManagerMonitorDesc": "Explorar e gerir ficheiros neste host via SFTP", - "scpLegacyLabel": "Modo SCP Legado", - "scpLegacyDesc": "Utilizar transferência de ficheiros legada para servidores que não suportam o subsistema SFTP (ex.: servidores SSH embebidos ou mínimos)", - "defaultPathLabel": "Caminho Predefinido", - "fileManagerPathHint": "O diretório a abrir quando o gestor de ficheiros for iniciado para este host", "fileManagerUrlCopied": "URL do gestor de ficheiros copiada", "copyFileManagerUrlAction": "Copiar URL do Gestor de Ficheiros", "docsLink": "Ver documentação", "hostNotFound": "Host não encontrado", "loadingHost": "A carregar o host..." }, - "settings": { - "host": { - "enable": { - "label": "Ativar Gestor de Ficheiros" - }, - "defaultPath": { - "label": "Caminho Predefinido" - }, - "scpLegacy": { - "label": "Modo SCP Legado" - } - }, - "user": { - "transferConcurrency": { - "label": "Transferências simultâneas de ficheiros", - "description": "Quantos ficheiros o gestor local/remoto lado a lado carrega ou descarrega simultaneamente? Diminua este valor se o seu servidor limitar os canais SFTP." - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "Ficheiros" - }, "onboarding": { - "feature_files": "Gestor de arquivos", - "feature_files_desc": "Navegue, carregue, descarregue e edite ficheiros via SFTP sem sair da aplicação." + "feature_files": "File manager", + "feature_files_desc": "Browse, upload, download and edit files over SFTP without leaving the app." }, "terminal": { "runTitle": "A executar {{command}} - {{host}}", @@ -437,7 +464,7 @@ "destinationPath": "Caminho de destino", "destMustBeDirectory": "O destino deve ser uma pasta para transferências de vários itens.", "goUp": "Subir", - "hostAuthRequired": "Autenticação necessária — abra o Gestor de Ficheiros neste host primeiro", + "hostAuthRequired": "Authentication required. Open File Manager on this host first", "hostConnecting": "A ligar…", "hostConnectionFailed": "Falha na ligação", "hostDisconnected": "Desligado", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "Optou por SFTP ficheiro a ficheiro.", "user_tar": "Optou por ficheiro tar.", - "tar_unavailable": "O tar não está disponível num ou em ambos os anfitriões — será usado SFTP ficheiro a ficheiro.", - "windows_host": "Está envolvido um anfitrião Windows — o tar não é utilizado.", - "auto_multi_large": "Automático: vários ficheiros, incluindo um grande ({{largestSize}}) com dados compressíveis — o tar agrupa numa transferência única.", - "auto_single_large_in_archive": "Automático: um ficheiro grande ({{largestSize}}) neste conjunto — SFTP ficheiro a ficheiro.", - "auto_many_incompressible": "Automático: dados maioritariamente incompressíveis — SFTP ficheiro a ficheiro.", - "auto_many_files": "Automático: muitos ficheiros ({{fileCount}}) — o tar reduz a sobrecarga por ficheiro.", + "tar_unavailable": "Tar is not available on one or both hosts, so per-file SFTP will be used instead.", + "windows_host": "A Windows host is involved, so tar is not used.", + "auto_multi_large": "Auto: multiple files including a large file ({{largestSize}}) with compressible data. Tar bundles them into one transfer.", + "auto_single_large_in_archive": "Auto: one large file ({{largestSize}}) in this set, so per-file SFTP.", + "auto_many_incompressible": "Auto: mostly incompressible data, so per-file SFTP.", + "auto_many_files": "Auto: many files ({{fileCount}}), tar cuts the per-file overhead.", "auto_default": "Automático: SFTP ficheiro a ficheiro para este conjunto." }, "methodTar": "Arquivo Tar", @@ -471,11 +498,11 @@ "metricsCompress": "Compressão na origem: {{duration}}", "metricsExtract": "Extração no destino: {{duration}}", "metricsPrepare": "Preparar destino: {{duration}}", - "metricsRouteBenchmark": "Sondagem de percurso — direta: {{direct}}, retransmissão: {{relay}}", + "metricsRouteBenchmark": "Route probe: direct {{direct}}, relay {{relay}}", "metricsSourceDelete": "Remoção da origem: {{duration}}", "metricsTotal": "Total: {{duration}}", "metricsTransfer": "Ponta a ponta: {{throughput}} ({{duration}})", - "metricsVerify": "Verificado por SHA-256: {{duration}}", + "metricsVerify": "SHA-256 verified: {{duration}}", "moveFolderToHost": "Mover pasta para o host…", "moveItemsToHost": "Mover {{count}} itens para o host…", "moveToHost": "Mover para o host…", @@ -484,7 +511,7 @@ "parallelSegmentsHint": "Os ficheiros grandes são divididos em partes de 256 MB. Múltiplas vias utilizam ligações separadas (como iniciar várias transferências) para um maior débito total.", "parallelSegmentsLabel": "Vias de transferência paralelas", "parallelSegmentsOption": "{{count}} vias", - "progressBenchmarking": "Selecionando a rota de transferência mais rápida…", + "progressBenchmarking": "Selecting the fastest transfer route…", "progressBytes": "{{transferred}} / {{total}}", "progressCancel": "Cancelar", "progressCancelling": "A cancelar…", @@ -496,7 +523,7 @@ "progressTotalSpeed": "{{speed}} total ({{lanes}} vias)", "progressTransferring": "A transferir dados…", "progressTransferringItems": "A transferir ficheiros ({{current}} de {{total}})…", - "progressVerifying": "Verificação da integridade do ficheiro…", + "progressVerifying": "Verifying file integrity…", "recentDestinations": "Destinos recentes", "resumedHint": "Reconectado a uma transferência ativa iniciada noutra janela.", "retryTransfer": "Repetir", @@ -508,6 +535,9 @@ "transferError": "Transferência falhou", "transferFailedRetryHint": "Foram mantidos dados parciais no destino. A repetição será retomada quando a ligação for restabelecida.", "transferPartialHint": "Não foi possível transferir: {{paths}}", - "transferSuccess": "Transferência concluída" + "transferSuccess": "Transferência concluída", + "metricsHopSourceRead": "Origem → servidor: {{throughput}}", + "metricsHopDestSftpWrite": "Servidor → destino (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Servidor → destino (local): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/ro_RO.json b/plugins/file-manager/locales/translated/ro_RO.json index 7e86cfa07..b6233bd42 100644 --- a/plugins/file-manager/locales/translated/ro_RO.json +++ b/plugins/file-manager/locales/translated/ro_RO.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "Fișiere", + "sftp": "SFTP", + "openFileManager": "Deschideți Managerul de fișiere" + }, + "permissions": { + "use": { + "title": "Folosește managerul de fișiere", + "description": "Răsfoiți, editați și transferați fișiere prin SFTP." + } + }, + "settings": { + "host": { + "enable": { + "label": "Activează Managerul de fișiere", + "description": "Răsfoiți și editați fișiere pe această gazdă prin SFTP." + }, + "defaultPath": { + "label": "Calea implicită" + }, + "scpLegacy": { + "label": "Modul SCP Legacy" + } + }, + "user": { + "transferConcurrency": { + "label": "Transferuri simultane de fișiere", + "description": "Câte fișiere încarcă sau descarcă simultan managerul local/la distanță. Reduceți această valoare dacă serverul dvs. limitează canalele SFTP." + }, + "confirmBeforeTrash": { + "label": "Confirmați înainte de a muta fișierele în coșul de gunoi", + "description": "Întreabă înainte de a muta fișierele la distanță în coșul de gunoi. Ștergerea definitivă necesită în continuare confirmare." + } + } + }, + "hostCapability": { + "label": "Manager de fișiere" + }, "fileManager": { "noHostSelected": "Nicio gazdă selectată", "initializingEditor": "Se inițializează editorul...", @@ -34,6 +72,7 @@ "rename": "Redenumire", "uploading": "Se încarcă...", "uploadingFile": "Se încarcă {{name}}...", + "uploadingChunk": "Se încarcă {{name}}: {{percent}}% (partea {{chunk}} din {{total}})", "fileName": "Nume de fișier", "folderName": "Nume folder", "fileUploadedSuccessfully": "Fișierul „{{name}}” a fost încărcat cu succes", @@ -95,7 +134,7 @@ "localUploadToRemote": "Încărcare pe server", "localUploadToRemoteMany": "Încărcați {{count}} elemente pe server", "localMoveToTrash": "Mută în coșul de gunoi", - "localMoveToTrashMany": "Mută articolele {{count}} în Coșul de gunoi", + "localMoveToTrashMany": "Mută articolele {{count}} în coșul de gunoi", "localTrashConfirmSingle": "Mutați „{{name}}” în coșul de gunoi?", "localTrashConfirmFolder": "Mutați folderul „{{name}}” și tot conținutul său în Coșul de gunoi?", "localTrashConfirmMany": "Mutați {{count}} elemente în coșul de gunoi?", @@ -117,7 +156,7 @@ "failedToLoadDirectory": "Directorul nu a putut fi încărcat", "noSSHConnection": "Nu este disponibilă nicio conexiune SSH", "copy": "Copie", - "cut": "Tăiere", + "cut": "Tăiați", "paste": "Pastă", "copyPath": "Copiere cale", "copyPaths": "Copiați căile", @@ -199,7 +238,7 @@ "unpinnedSuccessfully": "„{{name}}” a fost anulată cu succes", "unpinFailed": "Anularea fixării a eșuat", "removedShortcut": "S-a eliminat comanda rapidă „{{name}}”", - "removeShortcutFailed": "Eliminarea comenzii rapide a eșuat", + "removeShortcutFailed": "Eliminarea comenzii rapide a eșuat.", "clearedAllRecentFiles": "Am șters toate fișierele recente", "clearFailed": "Ștergerea a eșuat", "removeFromRecentFiles": "Eliminați din fișierele recente", @@ -290,6 +329,7 @@ "connecting": "Se conectează...", "connectedSuccessfully": "Conectare reușită", "totpVerificationFailed": "Verificarea TOTP a eșuat", + "browserSignInFailed": "Conectarea a eșuat. Vă rugăm să încercați din nou.", "authenticationFailed": "Autentificarea a eșuat", "incorrectPassphrase": "Parolă incorectă. Vă rugăm să încercați din nou.", "verificationCodePrompt": "Cod de verificare:", @@ -326,7 +366,24 @@ "cannotLoadPdf": "Nu se poate încărca PDF-ul", "pdfLoadError": "A apărut o eroare la încărcarea acestui fișier PDF.", "loadingPdf": "Se încarcă PDF-ul...", - "loadingPage": "Se încarcă pagina..." + "loadingPage": "Se încarcă pagina...", + "cancel": "Anula", + "copiedItems_one": "Elementul {{count}} a fost copiat", + "copiedItems_other": "Articole {{count}} copiate", + "deleteCopiedFileFailed": "Nu s-a putut șterge copia lui {{name}}: {{error}}", + "dragMovedItems_one": "Elementul {{count}} a fost mutat la {{target}}", + "dragMovedItems_other": "Am mutat {{count}} elemente la {{target}}", + "moveBackFileFailed": "Nu s-a putut muta {{name}} înapoi: {{error}}", + "terminal": "Terminal: {{host}} ({{path}})", + "dragToDesktop": "Tragerea {{name}} pe desktop", + "dragFilesToDesktop": "Tragerea fișierelor {{count}} pe desktop", + "folderDragUnsupported": "Tragerea folderelor pe desktop nu este încă acceptată", + "saveToDesktopFailed": "Salvarea a eșuat: {{error}}", + "dragFailedDetail": "Tragerea a eșuat: {{error}}", + "videoUnsupported": "Browserul dvs. nu poate reda acest format video.", + "downloadToPlay": "Descarcă pentru a-l reda în altă parte", + "cannotPreviewType": "Nu se poate previzualiza acest tip de fișier", + "cannotPreviewTypeHint": "Acest tip de fișier nu are previzualizare. Descărcați-l pentru a-l deschide în altă aplicație." }, "sftpTransfer": { "title": "SFTP", @@ -374,42 +431,12 @@ }, "hosts": { "fileManager": "Manager de fișiere", - "tabFiles": "Fișiere", - "enableFileManagerMonitor": "Activează Managerul de fișiere", - "enableFileManagerMonitorDesc": "Răsfoiți și gestionați fișierele de pe această gazdă prin SFTP", - "scpLegacyLabel": "Modul SCP Legacy", - "scpLegacyDesc": "Folosește transferul de fișiere vechi pentru serverele care nu acceptă subsistemul SFTP (de exemplu, servere SSH încorporate sau minimale).", - "defaultPathLabel": "Calea implicită", - "fileManagerPathHint": "Directorul care va fi deschis la lansarea managerului de fișiere pentru această gazdă.", "fileManagerUrlCopied": "Adresa URL a Managerului de fișiere a fost copiată", "copyFileManagerUrlAction": "Copiați adresa URL a managerului de fișiere", "docsLink": "Vizualizați documentele", "hostNotFound": "Gazdă negăsită", "loadingHost": "Se încarcă gazda..." }, - "settings": { - "host": { - "enable": { - "label": "Activează Managerul de fișiere" - }, - "defaultPath": { - "label": "Calea implicită" - }, - "scpLegacy": { - "label": "Modul SCP Legacy" - } - }, - "user": { - "transferConcurrency": { - "label": "Transferuri simultane de fișiere", - "description": "Câte fișiere încarcă sau descarcă simultan managerul local/la distanță. Reduceți această valoare dacă serverul dvs. limitează canalele SFTP." - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "Fișiere" - }, "onboarding": { "feature_files": "Manager de fișiere", "feature_files_desc": "Răsfoiți, încărcați, descărcați și editați fișiere prin SFTP fără a părăsi aplicația." @@ -437,7 +464,7 @@ "destinationPath": "Calea de destinație", "destMustBeDirectory": "Destinația trebuie să fie un director pentru transferurile cu mai multe elemente", "goUp": "Mergi sus", - "hostAuthRequired": "Autentificare necesară — deschideți mai întâi File Manager pe această gazdă", + "hostAuthRequired": "Autentificare necesară. Deschideți mai întâi File Manager pe această gazdă.", "hostConnecting": "Conectare…", "hostConnectionFailed": "Conexiunea a eșuat", "hostDisconnected": "Neconectat", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "Ai ales SFTP per fișier.", "user_tar": "Ai ales arhiva tar.", - "tar_unavailable": "Tar nu este disponibil pe una sau ambele gazde — se va folosi în schimb SFTP per fișier.", - "windows_host": "Este implicată o gazdă Windows — nu se folosește fișierul tar.", - "auto_multi_large": "Automat: fișiere multiple, inclusiv un fișier mare ({{largestSize}}) cu date compresibile — pachete tar într-un singur transfer.", - "auto_single_large_in_archive": "Automat: un fișier mare ({{largestSize}}) în acest set — SFTP per fișier.", - "auto_many_incompressible": "Automat: date în mare parte incompresibile — SFTP per fișier.", - "auto_many_files": "Auto: multe fișiere ({{fileCount}}) — tar reduce costul per fișier.", + "tar_unavailable": "Tar nu este disponibil pe una sau ambele gazde, așa că se va utiliza în schimb SFTP per fișier.", + "windows_host": "Este implicată o gazdă Windows, deci nu se folosește tar.", + "auto_multi_large": "Automat: fișiere multiple, inclusiv un fișier mare ({{largestSize}}) cu date compresibile. Tar le grupează într-un singur transfer.", + "auto_single_large_in_archive": "Automat: un fișier mare ({{largestSize}}) în acest set, deci SFTP per fișier.", + "auto_many_incompressible": "Automat: date în mare parte incompresibile, deci SFTP per fișier.", + "auto_many_files": "Auto: multe fișiere ({{fileCount}}), tar reduce costul per fișier.", "auto_default": "Automat: SFTP per fișier pentru acest set." }, "methodTar": "Arhivă Tar", @@ -471,7 +498,7 @@ "metricsCompress": "Comprimare pe sursă: {{duration}}", "metricsExtract": "Extras la destinație: {{duration}}", "metricsPrepare": "Pregătiți destinația: {{duration}}", - "metricsRouteBenchmark": "Sondă de rută — directă: {{direct}}, releu: {{relay}}", + "metricsRouteBenchmark": "Sondă de rută: directă {{direct}}, releu {{relay}}", "metricsSourceDelete": "Eliminare din sursă: {{duration}}", "metricsTotal": "Total: {{duration}}", "metricsTransfer": "De la un capăt la altul: {{throughput}} ({{duration}})", @@ -508,6 +535,9 @@ "transferError": "Transferul a eșuat", "transferFailedRetryHint": "Date parțiale au fost păstrate la destinație. Reîncercarea va fi reluată după restabilirea conexiunii.", "transferPartialHint": "Nu s-a putut transfera: {{paths}}", - "transferSuccess": "Transfer finalizat" + "transferSuccess": "Transfer finalizat", + "metricsHopSourceRead": "Sursă → server: {{throughput}}", + "metricsHopDestSftpWrite": "Server → destinație (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Server → destinație (locală): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/ru_RU.json b/plugins/file-manager/locales/translated/ru_RU.json index 1d1485dbb..4be46429a 100644 --- a/plugins/file-manager/locales/translated/ru_RU.json +++ b/plugins/file-manager/locales/translated/ru_RU.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "Файлы", + "sftp": "SFTP", + "openFileManager": "Открыть файловый менеджер" + }, + "permissions": { + "use": { + "title": "Use file manager", + "description": "Browse, edit and transfer files over SFTP." + } + }, + "settings": { + "host": { + "enable": { + "label": "Включить файловый менеджер", + "description": "Browse and edit files on this host over SFTP." + }, + "defaultPath": { + "label": "Путь по умолчанию" + }, + "scpLegacy": { + "label": "Устаревший режим SCP" + } + }, + "user": { + "transferConcurrency": { + "label": "Simultaneous File Transfers", + "description": "How many files the side by side local/remote manager uploads or downloads at the same time. Lower this if your server limits SFTP channels." + }, + "confirmBeforeTrash": { + "label": "Confirm before moving files to trash", + "description": "Ask before moving remote files to trash. Permanent deletion still requires confirmation." + } + } + }, + "hostCapability": { + "label": "Файловый менеджер" + }, "fileManager": { "noHostSelected": "Хост не выбран", "initializingEditor": "Инициализация редактора...", @@ -34,13 +72,14 @@ "rename": "Переименовать", "uploading": "Загрузка...", "uploadingFile": "Загрузка {{name}}...", + "uploadingChunk": "Uploading {{name}}: {{percent}}% (part {{chunk}} of {{total}})", "fileName": "Имя файла", "folderName": "Имя папки", "fileUploadedSuccessfully": "Файл «{{name}}» успешно загружен", "failedToUploadFile": "Не удалось загрузить файл", - "uploadingFolderFiles": "Загрузка {{count}} файла(ов)...", - "uploadedFolderFiles": "Файл(ы) {{count}} успешно загружен(ы).", - "uploadedFolderPartial": "Загрузка {{uploaded}} файла(ов), {{failed}} не удалась.", + "uploadingFolderFiles": "Uploading {{count}} file(s)...", + "uploadedFolderFiles": "Uploaded {{count}} file(s) successfully", + "uploadedFolderPartial": "Uploaded {{uploaded}} file(s), {{failed}} failed", "fileDownloadedSuccessfully": "Файл «{{name}}» успешно скачан", "failedToDownloadFile": "Не удалось скачать файл", "fileCreatedSuccessfully": "Файл «{{name}}» успешно создан", @@ -56,58 +95,58 @@ "sudoOperationFailed": "Операция sudo не удалась", "sudoAuthFailed": "Аутентификация sudo не удалась", "dragFilesToUpload": "Перетащите файлы сюда для загрузки", - "dropToUploadHere": "Перетащите файл для загрузки сюда.", - "dropToDownloadHere": "Скачать можно здесь (перетащите ссылку)", - "localFiles": "Местный", - "showLocalFiles": "Отображение локальных файлов (в режиме разделенного экрана)", - "hideLocalFiles": "Скрыть локальные файлы", - "localHome": "Домашняя папка", - "localPathPlaceholder": "Путь к локальной папке", - "localShowHidden": "Показать скрытые файлы", - "localHideHidden": "Скрыть скрытые файлы", - "localRevealInFileManager": "Показать в системном файловом менеджере", - "localCannotOpenFolder": "Не удаётся открыть папку", - "localItemCount": "{{count}} предметов", + "dropToUploadHere": "Drop to upload here", + "dropToDownloadHere": "Drop to download here", + "localFiles": "Локальная", + "showLocalFiles": "Show local files (split view)", + "hideLocalFiles": "Hide local files", + "localHome": "Home folder", + "localPathPlaceholder": "Local folder path", + "localShowHidden": "Show hidden files", + "localHideHidden": "Hide hidden files", + "localRevealInFileManager": "Reveal in system file manager", + "localCannotOpenFolder": "Cannot open folder", + "localItemCount": "{{count}} элементов", "localSelectedCount": "{{count}} выбрано", "back": "Назад", - "forward": "Вперед", - "up": "Вверх", - "kind": "Добрый", - "localUploadingProgress": "Загрузка {{current}} из {{total}}", - "localDownloadingProgress": "Загрузка {{current}} из {{total}}", - "localTransferInFlight": "{{count}} сразу", - "localPreparingDownload": "Подготовка к загрузке...", - "localTransferCancelled": "Трансфер отменен", - "localNothingToTransfer": "Нет ничего для перевода", - "localUploadComplete": "Загружено {{count}} файлов", - "localUploadFailed": "Загрузка не удалась.", - "localUploadPartial": "Загрузка {{done}} файла(ов), {{failed}} не удалась.", - "localDownloadComplete": "Загружено {{count}} файлов", - "localDownloadFailed": "Загрузка не удалась.", - "localDownloadPartial": "Загрузка {{done}} файла(ов), {{failed}} не удалась.", - "localReplaceExistingPrompt": "{{count}} Элемент(ы) уже существуют в этой папке. Заменить их?", - "localReplace": "Заменять", - "localSkipExisting": "Пропускать", - "localSkippedExisting": "Пропущено {{count}} существующих элементов", - "localUnsafeNamesSkipped": "Пропущено {{count}} элементов, названия которых нельзя использовать на этом компьютере", + "forward": "Forward", + "up": "Up", + "kind": "Kind", + "localUploadingProgress": "Uploading {{current}} of {{total}}", + "localDownloadingProgress": "Downloading {{current}} of {{total}}", + "localTransferInFlight": "{{count}} at once", + "localPreparingDownload": "Preparing download...", + "localTransferCancelled": "Передача отменена", + "localNothingToTransfer": "Nothing to transfer", + "localUploadComplete": "Uploaded {{count}} file(s)", + "localUploadFailed": "Upload failed", + "localUploadPartial": "Uploaded {{done}} file(s), {{failed}} failed", + "localDownloadComplete": "Downloaded {{count}} file(s)", + "localDownloadFailed": "Не удалось загрузить", + "localDownloadPartial": "Downloaded {{done}} file(s), {{failed}} failed", + "localReplaceExistingPrompt": "{{count}} item(s) already exist in this folder. Replace them?", + "localReplace": "Заменить", + "localSkipExisting": "Skip", + "localSkippedExisting": "Skipped {{count}} existing item(s)", + "localUnsafeNamesSkipped": "Skipped {{count}} item(s) whose names cannot be used on this computer", "localOpen": "Открыть", - "localOpenFolder": "Открыть папку", - "localUploadToRemote": "Загрузка на сервер", - "localUploadToRemoteMany": "Загрузите {{count}} предметов на сервер", - "localMoveToTrash": "Переместить в мусорное ведро", - "localMoveToTrashMany": "Переместите {{count}} элементов в корзину", - "localTrashConfirmSingle": "Переместить \"{{name}}\" в корзину?", - "localTrashConfirmFolder": "Переместить папку \"{{name}}\" и всё её содержимое в корзину?", - "localTrashConfirmMany": "Переместить {{count}} элементов в корзину?", - "localTrashed": "Перемещено {{count}} предметов в корзину", - "localTrashFailed": "Не удалось переместить в мусорный бак.", - "localRenameFailed": "Переименование не удалось.", - "localCreateFailed": "Не удалось создать элемент.", - "goToParentFolder": "Перейдите в родительскую папку", - "resizeSidebar": "Перетащите ползунок, чтобы изменить размер боковой панели (двойной щелчок для сброса).", - "resizeLocalPane": "Перетащите курсор, чтобы изменить размер локальной панели (двойной щелчок для сброса).", - "columns": "Колонки", - "columnsHint": "Щелкните правой кнопкой мыши, чтобы выбрать столбцы.", + "localOpenFolder": "Open folder", + "localUploadToRemote": "Upload to server", + "localUploadToRemoteMany": "Upload {{count}} items to server", + "localMoveToTrash": "Move to Trash", + "localMoveToTrashMany": "Move {{count}} items to Trash", + "localTrashConfirmSingle": "Move \"{{name}}\" to the Trash?", + "localTrashConfirmFolder": "Move the folder \"{{name}}\" and all its contents to the Trash?", + "localTrashConfirmMany": "Move {{count}} items to the Trash?", + "localTrashed": "Moved {{count}} item(s) to the Trash", + "localTrashFailed": "Could not move to the Trash", + "localRenameFailed": "Rename failed", + "localCreateFailed": "Could not create item", + "goToParentFolder": "Go to parent folder", + "resizeSidebar": "Drag to resize the sidebar (double-click to reset)", + "resizeLocalPane": "Drag to resize the local pane (double-click to reset)", + "columns": "Столбцы", + "columnsHint": "Right-click to choose columns", "emptyFolder": "Эта папка пуста", "searchFiles": "Поиск файлов...", "upload": "Загрузить", @@ -163,26 +202,26 @@ "confirmDeleteMultipleItemsWithFolders": "Вы уверены, что хотите безвозвратно удалить {{count}} элементов? Включая папки и их содержимое.", "confirmDeleteFolder": "Вы уверены, что хотите безвозвратно удалить папку \"{{name}}\" и всё её содержимое?", "permanentDeleteWarning": "Это действие необратимо. Элемент(ы) будут безвозвратно удалены с сервера.", - "moveToTrashWarning": "Изделие(а) будет перемещено в мусорный контейнер Termix и может быть возвращено в рабочее состояние до истечения срока хранения.", - "itemsMovedToTrash": "{{count}} элемент(ы) перемещены в корзину", - "trash": "Мусор", - "trashDescription": "Удаленные элементы сохраняются на этом хосте в течение {{days}} дней.", - "trashLoadFailed": "Не удалось загрузить мусор.", - "trashEmpty": "Мусорное ведро пусто.", + "moveToTrashWarning": "The item(s) will be moved to the Termix Trash and can be restored before the retention period expires.", + "itemsMovedToTrash": "{{count}} item(s) moved to Trash", + "trash": "Trash", + "trashDescription": "Deleted items are retained for {{days}} day(s) on this host.", + "trashLoadFailed": "Failed to load Trash", + "trashEmpty": "Trash is empty", "trashRestore": "Восстановить", - "trashRestored": "Восстановлено {{name}}", - "trashRestoreFailed": "Не удалось восстановить элемент. Возможно, исходный путь уже существует.", - "trashDeletePermanently": "Удалить навсегда", - "trashDeleteConfirm": "Удалить {{name}}навсегда? Это действие необратимо.", - "trashPermanentlyDeleted": "Удалено навсегда {{name}}", - "trashDeleteFailed": "Не удалось удалить элемент навсегда.", - "trashEmptyAction": "Опустошите мусорный бак", - "trashEmptyConfirm": "Удалить все элементы из корзины навсегда? Это действие необратимо.", - "trashEmptied": "Мусор вывезен", - "trashRetention": "Автоматическая очистка через (дней)", - "trashRetentionSaved": "Обновлена информация о хранении мусора.", - "trashRetentionFailed": "Не удалось обновить срок хранения корзины.", - "trashUnavailableConfirm": "Этот элемент нельзя переместить в корзину, как правило, потому что он находится в другой файловой системе или требует повышенных прав доступа. Может, лучше удалить его навсегда?", + "trashRestored": "Restored {{name}}", + "trashRestoreFailed": "Failed to restore item. The original path may already exist.", + "trashDeletePermanently": "Delete permanently", + "trashDeleteConfirm": "Permanently delete {{name}}? This cannot be undone.", + "trashPermanentlyDeleted": "Permanently deleted {{name}}", + "trashDeleteFailed": "Failed to permanently delete item", + "trashEmptyAction": "Empty Trash", + "trashEmptyConfirm": "Permanently delete every item in Trash? This cannot be undone.", + "trashEmptied": "Trash emptied", + "trashRetention": "Automatic cleanup after (days)", + "trashRetentionSaved": "Trash retention updated", + "trashRetentionFailed": "Failed to update Trash retention", + "trashUnavailableConfirm": "This item cannot be moved to Trash, usually because it is on another filesystem or requires elevated permissions. Delete it permanently instead?", "recent": "Недавние", "pinned": "Закреплённые", "folderShortcuts": "Ярлыки папок", @@ -264,7 +303,7 @@ "operationCompleted": "{{operation}} {{count}} элементов", "downloadFileSuccess": "Файл {{name}} успешно загружен", "downloadFileFailed": "Не удалось загрузить", - "downloadingFile": "Загрузка {{name}}…", + "downloadingFile": "Downloading {{name}}…", "downloadProgressBytes": "{{transferred}} / {{total}}", "moveTo": "Переместить в {{name}}", "diffCompareWith": "Сравнить с {{name}}", @@ -290,6 +329,7 @@ "connecting": "Подключение...", "connectedSuccessfully": "Подключено успешно", "totpVerificationFailed": "Ошибка проверки TOTP", + "browserSignInFailed": "Sign-in failed. Please try again.", "authenticationFailed": "Ошибка аутентификации", "incorrectPassphrase": "Неверная парольная фраза. Попробуйте еще раз.", "verificationCodePrompt": "Код подтверждения:", @@ -321,98 +361,85 @@ "used": "Занято", "of": "из", "toggleSidebar": "Переключить боковую панель", - "compactLayout": "Используйте компактную компоновку.", - "comfortableLayout": "Используйте удобную планировку", + "compactLayout": "Use compact layout", + "comfortableLayout": "Use comfortable layout", "cannotLoadPdf": "Не удаётся загрузить PDF", "pdfLoadError": "Ошибка при загрузке этого PDF-файла.", "loadingPdf": "Загрузка PDF...", - "loadingPage": "Загрузка страницы..." + "loadingPage": "Загрузка страницы...", + "cancel": "Отмена", + "copiedItems_one": "Copied {{count}} item", + "copiedItems_other": "Copied {{count}} items", + "deleteCopiedFileFailed": "Could not delete the copy of {{name}}: {{error}}", + "dragMovedItems_one": "Moved {{count}} item to {{target}}", + "dragMovedItems_other": "Moved {{count}} items to {{target}}", + "moveBackFileFailed": "Could not move {{name}} back: {{error}}", + "terminal": "Terminal: {{host}} ({{path}})", + "dragToDesktop": "Dragging {{name}} to the desktop", + "dragFilesToDesktop": "Dragging {{count}} files to the desktop", + "folderDragUnsupported": "Dragging folders to the desktop is not supported yet", + "saveToDesktopFailed": "Save failed: {{error}}", + "dragFailedDetail": "Drag failed: {{error}}", + "videoUnsupported": "Your browser cannot play this video format.", + "downloadToPlay": "Download to play it elsewhere", + "cannotPreviewType": "Cannot preview this file type", + "cannotPreviewTypeHint": "This file type has no preview. Download it to open it in another app." }, "sftpTransfer": { "title": "SFTP", - "description": "Передача файлов между двумя SSH-хостами.", - "sourceServer": "Исходный сервер", - "destinationServer": "Сервер назначения", - "selectHost": "Выберите хост", + "description": "Transfer files between two SSH hosts.", + "sourceServer": "Source Server", + "destinationServer": "Destination Server", + "selectHost": "Select host", "noHostSelected": "Хост не выбран", - "move": "Двигаться", - "copy": "Копия", + "move": "Переместить", + "copy": "Копировать", "upload": "Загрузить", - "itemsSelected": "{{count}} выбранный элемент", - "itemsSelected_other": "{{count}} выбранные элементы", - "ready": "Готовый", + "itemsSelected": "{{count}} item selected", + "itemsSelected_other": "{{count}} items selected", + "ready": "Готов", "loadingHosts": "Загрузка хостов...", - "name": "Имя", - "modified": "Модифицированный", - "size": "Размер", - "noFiles": "Нет файлов", + "name": "Название", + "modified": "Изменён", + "size": "По размеру", + "noFiles": "No files", "open": "Открыть", - "up": "Вверх", + "up": "Up", "refresh": "Обновить", - "copyToTarget": "Скопировать в целевую директорию", + "copyToTarget": "Copy to Target Directory", "rename": "Переименовать", "delete": "Удалить", - "editPermissions": "Изменить права доступа", - "createNewFolder": "Создать новую папку", - "deleteSelectedItems": "Удалить выбранные элементы", - "deleteConfirm": "Удалить {{count}} выбранный элемент?", - "deleteConfirm_other": "Удалить {{count}} выбранные элементы?", + "editPermissions": "Edit Permissions", + "createNewFolder": "Create New Folder", + "deleteSelectedItems": "Delete Selected Items", + "deleteConfirm": "Delete {{count}} selected item?", + "deleteConfirm_other": "Delete {{count}} selected items?", "cancel": "Отмена", - "save": "Сохранять", - "folderCreated": "Создана папка", - "itemRenamed": "Элемент переименован", - "actionFailed": "Действие не удалось.", - "itemsDeleted": "{{count}} элемент удален", - "itemsDeleted_other": "{{count}} удаленные элементы", - "deleteFailed": "Удаление не удалось.", - "permissionsUpdated": "Права доступа обновлены.", - "noRemoteSessionConnected": "Удалённая сессия не подключена", - "failedToListFiles": "Не удалось отобразить список файлов.", - "failedToRefresh": "Не удалось обновить", - "destinationInsideSource": "Место назначения не может находиться внутри выбранного пути источника.", - "sameHostNoOp": "Исходная и целевая папки — одна и та же." + "save": "Сохранить", + "folderCreated": "Folder created", + "itemRenamed": "Item renamed", + "actionFailed": "Действие не удалось", + "itemsDeleted": "{{count}} item deleted", + "itemsDeleted_other": "{{count}} items deleted", + "deleteFailed": "Delete failed", + "permissionsUpdated": "Permissions updated", + "noRemoteSessionConnected": "No remote session connected", + "failedToListFiles": "Failed to list files", + "failedToRefresh": "Failed to refresh", + "destinationInsideSource": "Destination cannot be inside the selected source path.", + "sameHostNoOp": "Source and destination are the same folder." }, "hosts": { "fileManager": "Файловый менеджер", - "tabFiles": "Файлы", - "enableFileManagerMonitor": "Включить файловый менеджер", - "enableFileManagerMonitorDesc": "Просмотр и управление файлами на этом хосте через SFTP", - "scpLegacyLabel": "Устаревший режим SCP", - "scpLegacyDesc": "Использовать устаревший протокол передачи файлов для серверов, не поддерживающих подсистему SFTP (например, встроенные или минимальные SSH-серверы).", - "defaultPathLabel": "Путь по умолчанию", - "fileManagerPathHint": "Каталог, который открывается при запуске файлового менеджера для этого хоста.", "fileManagerUrlCopied": "URL файлового менеджера скопирован", "copyFileManagerUrlAction": "Копировать URL файлового менеджера", "docsLink": "Документация", "hostNotFound": "Хост не найден", "loadingHost": "Загрузка хоста..." }, - "settings": { - "host": { - "enable": { - "label": "Включить файловый менеджер" - }, - "defaultPath": { - "label": "Путь по умолчанию" - }, - "scpLegacy": { - "label": "Устаревший режим SCP" - } - }, - "user": { - "transferConcurrency": { - "label": "Одновременная передача файлов", - "description": "Сколько файлов менеджер, работающий в режиме локального/удалённого доступа, может загружать или скачивать одновременно. Уменьшите это значение, если ваш сервер ограничивает количество SFTP-каналов." - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "Файлы" - }, "onboarding": { - "feature_files": "Файловый менеджер", - "feature_files_desc": "Просматривайте, загружайте, скачивайте и редактируйте файлы по протоколу SFTP, не выходя из приложения." + "feature_files": "File manager", + "feature_files_desc": "Browse, upload, download and edit files over SFTP without leaving the app." }, "terminal": { "runTitle": "Выполнение {{command}} - {{host}}", @@ -437,7 +464,7 @@ "destinationPath": "Путь назначения", "destMustBeDirectory": "Для передачи нескольких элементов путь назначения должен быть папкой", "goUp": "Вверх", - "hostAuthRequired": "Требуется аутентификация — сначала откройте Файловый Менеджер на этом хосте", + "hostAuthRequired": "Authentication required. Open File Manager on this host first", "hostConnecting": "Подключение…", "hostConnectionFailed": "Ошибка подключения", "hostDisconnected": "Не подключен", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "Вы выбрали пофайловый SFTP.", "user_tar": "Вы выбрали tar-архив.", - "tar_unavailable": "Tar недоступен на одном или обоих хостах — вместо этого будет использоваться пофайловый SFTP.", - "windows_host": "Участвует хост под Windows — tar не используется.", - "auto_multi_large": "Авто: несколько файлов, включая большой файл ({{largestSize}}) со сжимаемыми данными — tar объединяет в одну передачу.", - "auto_single_large_in_archive": "Авто: один большой файл ({{largestSize}}) в этом наборе — пофайловый SFTP.", - "auto_many_incompressible": "Авто: в основном несжимаемые данные — пофайловый SFTP.", - "auto_many_files": "Авто: много файлов ({{fileCount}}) — tar сокращает накладные расходы на каждый файл.", + "tar_unavailable": "Tar is not available on one or both hosts, so per-file SFTP will be used instead.", + "windows_host": "A Windows host is involved, so tar is not used.", + "auto_multi_large": "Auto: multiple files including a large file ({{largestSize}}) with compressible data. Tar bundles them into one transfer.", + "auto_single_large_in_archive": "Auto: one large file ({{largestSize}}) in this set, so per-file SFTP.", + "auto_many_incompressible": "Auto: mostly incompressible data, so per-file SFTP.", + "auto_many_files": "Auto: many files ({{fileCount}}), tar cuts the per-file overhead.", "auto_default": "Авто: пофайловый SFTP для этого набора." }, "methodTar": "Архив Tar", @@ -471,11 +498,11 @@ "metricsCompress": "Сжатие на источнике: {{duration}}", "metricsExtract": "Распаковка на назначении: {{duration}}", "metricsPrepare": "Подготовка назначения: {{duration}}", - "metricsRouteBenchmark": "Маршрутный зонд — прямой: {{direct}}, ретранслятор: {{relay}}", + "metricsRouteBenchmark": "Route probe: direct {{direct}}, relay {{relay}}", "metricsSourceDelete": "Удаление с источника: {{duration}}", "metricsTotal": "Всего: {{duration}}", "metricsTransfer": "Сквозной: {{throughput}} ({{duration}})", - "metricsVerify": "SHA-256 проверен: {{duration}}", + "metricsVerify": "SHA-256 verified: {{duration}}", "moveFolderToHost": "Переместить папку на хост…", "moveItemsToHost": "Переместить {{count}} элементов на хост…", "moveToHost": "Переместить на хост…", @@ -484,7 +511,7 @@ "parallelSegmentsHint": "Большие файлы разбиваются на фрагменты по 256 МБ. Несколько каналов используют отдельные соединения (как при запуске нескольких передач) для повышения общей пропускной способности.", "parallelSegmentsLabel": "Параллельные каналы передачи", "parallelSegmentsOption": "{{count}} каналов", - "progressBenchmarking": "Выбор самого быстрого маршрута пересадки…", + "progressBenchmarking": "Selecting the fastest transfer route…", "progressBytes": "{{transferred}} / {{total}}", "progressCancel": "Отмена", "progressCancelling": "Отмена…", @@ -496,7 +523,7 @@ "progressTotalSpeed": "{{speed}} всего ({{lanes}} каналов)", "progressTransferring": "Передача данных…", "progressTransferringItems": "Передача файлов ({{current}} из {{total}})…", - "progressVerifying": "Проверка целостности файла…", + "progressVerifying": "Verifying file integrity…", "recentDestinations": "Недавние назначения", "resumedHint": "Переподключено к активной передаче, запущенной в другом окне.", "retryTransfer": "Повторить", @@ -508,6 +535,9 @@ "transferError": "Ошибка передачи", "transferFailedRetryHint": "Частичные данные сохранены в месте назначения. Повтор возобновится, когда соединение восстановится.", "transferPartialHint": "Не удалось передать: {{paths}}", - "transferSuccess": "Передача завершена" + "transferSuccess": "Передача завершена", + "metricsHopSourceRead": "Источник → сервер: {{throughput}}", + "metricsHopDestSftpWrite": "Сервер → назначение (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Сервер → назначение (локально): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/sr_SP.json b/plugins/file-manager/locales/translated/sr_SP.json index 37e4ca8a6..dc86761ce 100644 --- a/plugins/file-manager/locales/translated/sr_SP.json +++ b/plugins/file-manager/locales/translated/sr_SP.json @@ -1,399 +1,23 @@ { - "fileManager": { - "noHostSelected": "Није изабран домаћин", - "initializingEditor": "Иницијализација уређивача...", - "file": "Датотека", - "folder": "Фасцикла", - "uploadFile": "Отпреми датотеку", - "downloadFile": "Преузми", - "extractArchive": "Издвоји архиву", - "extractingArchive": "Издвајање {{name}}...", - "archiveExtractedSuccessfully": "{{name}} је успешно извучено", - "extractFailed": "Издвајање није успело", - "compressFile": "Компресуј датотеку", - "compressFiles": "Компресуј датотеке", - "compressFilesDesc": "Компресуј {{count}} ставки у архиву", - "archiveName": "Назив архиве", - "enterArchiveName": "Унесите име архиве...", - "compressionFormat": "Формат компресије", - "selectedFiles": "Изабране датотеке", - "andMoreFiles": "и још {{count}}...", - "compress": "Компресуј", - "compressingFiles": "Компресија {{count}} ставки у {{name}}...", - "filesCompressedSuccessfully": "{{name}} је успешно креирано", - "compressFailed": "Компресија није успела", - "edit": "Измени", - "preview": "Преглед", - "previous": "Претходно", - "next": "Следеће", - "pageXOfY": "Страница {{current}} од {{total}}", - "zoomOut": "Умањи", - "zoomIn": "Увећај", - "newFile": "Нова датотека", - "newFolder": "Нова фасцикла", - "rename": "Преименуј", - "uploading": "Отпремање...", - "uploadingFile": "Отпремање {{name}}...", - "fileName": "Име датотеке", - "folderName": "Назив фасцикле", - "fileUploadedSuccessfully": "Датотека „{{name}}“ је успешно отпремљена", - "failedToUploadFile": "Отпремање датотеке није успело", - "uploadingFolderFiles": "Отпремање {{count}} датотека...", - "uploadedFolderFiles": "Успешно отпремљено {{count}} датотека", - "uploadedFolderPartial": "Отпремљено {{uploaded}} датотека, {{failed}} није успело", - "fileDownloadedSuccessfully": "Датотека „{{name}}“ је успешно преузета", - "failedToDownloadFile": "Преузимање датотеке није успело", - "fileCreatedSuccessfully": "Датотека „{{name}}“ је успешно креирана", - "folderCreatedSuccessfully": "Фасцикла „{{name}}“ је успешно креирана", - "failedToCreateItem": "Није успело креирање ставке", - "operationFailed": "Операција {{operation}} није успела за {{name}}: {{error}}", - "failedToResolveSymlink": "Није успело решавање симболичке везе", - "itemsDeletedSuccessfully": "{{count}} ставке су успешно обрисане", - "failedToDeleteItems": "Брисање ставки није успело", - "sudoPasswordRequired": "Потребна је администраторска лозинка", - "enterSudoPassword": "Унесите лозинку за судо да бисте наставили ову операцију", - "sudoPassword": "Sudo лозинка", - "sudoOperationFailed": "Sudo операција није успела", - "sudoAuthFailed": "Судо аутентификација није успела", - "dragFilesToUpload": "Отпустите датотеке овде да бисте их отпремили", - "dropToUploadHere": "Отпустите да бисте отпремили овде", - "dropToDownloadHere": "Отпустите да бисте преузели овде", - "localFiles": "Локално", - "showLocalFiles": "Прикажи локалне датотеке (подељени приказ)", - "hideLocalFiles": "Сакриј локалне датотеке", - "localHome": "Почетна фасцикла", - "localPathPlaceholder": "Путања локалне фасцикле", - "localShowHidden": "Прикажи скривене датотеке", - "localHideHidden": "Сакриј скривене датотеке", - "localRevealInFileManager": "Откриј у системском менаџеру датотека", - "localCannotOpenFolder": "Не могу да отворим фасциклу", - "localItemCount": "{{count}} ставке", - "localSelectedCount": "{{count}} изабрано", - "back": "Назад", - "forward": "Напред", - "up": "Горе", - "kind": "Врста", - "localUploadingProgress": "Отпремање {{current}} од {{total}}", - "localDownloadingProgress": "Преузимање {{current}} од {{total}}", - "localTransferInFlight": "{{count}} одједном", - "localPreparingDownload": "Припрема преузимања...", - "localTransferCancelled": "Трансфер отказан", - "localNothingToTransfer": "Ништа за пренос", - "localUploadComplete": "Отпремљено {{count}} датотека", - "localUploadFailed": "Отпремање није успело", - "localUploadPartial": "Отпремљено {{done}} датотека, {{failed}} није успело", - "localDownloadComplete": "Преузето {{count}} датотека", - "localDownloadFailed": "Преузимање није успело", - "localDownloadPartial": "Преузимање {{done}} датотека, {{failed}} није успело", - "localReplaceExistingPrompt": "{{count}} став(е) већ постоје у овој фасцикли. Заменити их?", - "localReplace": "Замени", - "localSkipExisting": "Прескочи", - "localSkippedExisting": "Прескочено {{count}} постојећих ставки", - "localUnsafeNamesSkipped": "Прескочено је {{count}} ставки чија имена се не могу користити на овом рачунару", - "localOpen": "Отворено", - "localOpenFolder": "Отвори фасциклу", - "localUploadToRemote": "Отпреми на сервер", - "localUploadToRemoteMany": "Отпреми {{count}} ставки на сервер", - "localMoveToTrash": "Премести у отпад", - "localMoveToTrashMany": "Премести {{count}} ставки у Отпад", - "localTrashConfirmSingle": "Преместити „{{name}}“ у Отпад?", - "localTrashConfirmFolder": "Преместити фасциклу „{{name}}“ и сав њен садржај у корпу за отпад?", - "localTrashConfirmMany": "Преместити {{count}} ставки у Отпад?", - "localTrashed": "Премештено {{count}} ставки у Отпад", - "localTrashFailed": "Није могуће преместити у Отпад", - "localRenameFailed": "Преименовање није успело", - "localCreateFailed": "Није могуће креирати ставку", - "goToParentFolder": "Иди у надређени фолдер", - "resizeSidebar": "Превуците да бисте променили величину бочне траке (двапут кликните да бисте ресетовали)", - "resizeLocalPane": "Превуците да бисте променили величину локалног окна (двапут кликните да бисте ресетовали)", - "columns": "Колоне", - "columnsHint": "Кликните десним тастером миша да бисте изабрали колоне", - "emptyFolder": "Ова фасцикла је празна", - "searchFiles": "Претражи датотеке...", - "upload": "Отпреми", - "selectHostToStart": "Изаберите хост да бисте започели управљање датотекама", - "sshRequiredForFileManager": "Менаџер датотека захтева SSH. Овај хост нема омогућен SSH.", - "failedToConnect": "Повезивање са SSH-ом није успело", - "failedToLoadDirectory": "Учитавање директоријума није успело", - "noSSHConnection": "SSH веза није доступна", - "copy": "Копија", - "cut": "Исеци", - "paste": "Залепи", - "copyPath": "Копирај путању", - "copyPaths": "Копирај путање", - "delete": "Обриши", - "properties": "Некретнине", - "refresh": "Освежи", - "downloadFiles": "Преузмите {{count}} датотека у прегледач", - "copyFiles": "Копирај {{count}} ставке", - "cutFiles": "Исеци {{count}} ставки", - "deleteFiles": "Обриши {{count}} ставки", - "filesCopiedToClipboard": "{{count}} ставке копиране у међуспремник", - "filesCutToClipboard": "{{count}} ставке исечене у међуспремник", - "pathCopiedToClipboard": "Путања је копирана у међуспремник", - "pathsCopiedToClipboard": "{{count}} путање копиране у међуспремник", - "failedToCopyPath": "Копирање путање у међуспремник није успело", - "copyFolderLink": "Копирај везу у фасциклу", - "copyCurrentFolderLink": "Копирај везу у тренутну фасциклу", - "folderLinkCopied": "Линк фасцикле копиран у међуспремник", - "failedToCopyFolderLink": "Копирање линка фасцикле није успело", - "movedItems": "Премештено {{count}} ставки", - "failedToDeleteItem": "Брисање ставке није успело", - "itemRenamedSuccessfully": "{{type}} је успешно преименован", - "failedToRenameItem": "Преименовање ставке није успело", - "download": "Преузми", - "openExternalEditor": "Отвори споља", - "chooseExternalEditor": "Изаберите спољни уређивач", - "externalEditorSelected": "Изабран је спољни уредник", - "externalEditorDesktopOnly": "Спољни уређивач је доступан само у десктоп апликацији", - "externalEditorOpened": "Отворено у екстерном уређивачу. Чувањем тамо ће се измене отпремити назад на сервер.", - "failedToOpenExternalEditor": "Отварање екстерног уређивача није успело", - "failedToSelectExternalEditor": "Није успело бирање спољног уређивача", - "permissions": "Дозволе", - "size": "Величина", - "modified": "Измењено", - "path": "Путања", - "confirmDelete": "Да ли сте сигурни да желите да обришете {{name}}?", - "permissionDenied": "Дозвола одбијена", - "serverError": "Грешка сервера", - "fileSavedSuccessfully": "Датотека је успешно сачувана", - "failedToSaveFile": "Чување датотеке није успело", - "confirmDeleteSingleItem": "Да ли сте сигурни да желите трајно да избришете „{{name}}“?", - "confirmDeleteMultipleItems": "Да ли сте сигурни да желите трајно да избришете {{count}} ставке?", - "confirmDeleteMultipleItemsWithFolders": "Да ли сте сигурни да желите трајно да избришете {{count}} ставке? Ово укључује фасцикле и њихов садржај.", - "confirmDeleteFolder": "Да ли сте сигурни да желите трајно да избришете фасциклу „{{name}}“ и сав њен садржај?", - "permanentDeleteWarning": "Ова радња се не може поништити. Ставка(е) ће бити трајно избрисане са сервера.", - "moveToTrashWarning": "Ставка(е) ће бити премештена(е) у смеће Термикса и може(ју) се вратити пре истека периода чувања.", - "itemsMovedToTrash": "{{count}} ставке премештено у Отпад", - "trash": "Смеће", - "trashDescription": "Обрисане ставке се чувају {{days}} дана на овом хосту.", - "trashLoadFailed": "Учитавање Отпада није успело", - "trashEmpty": "Отпад је празан", - "trashRestore": "Врати", - "trashRestored": "Враћено {{name}}", - "trashRestoreFailed": "Враћање ставке није успело. Оригинална путања можда већ постоји.", - "trashDeletePermanently": "Трајно избриши", - "trashDeleteConfirm": "Трајно избрисати {{name}}? Ово се не може поништити.", - "trashPermanentlyDeleted": "Трајно обрисано {{name}}", - "trashDeleteFailed": "Трајно брисање ставке није успело", - "trashEmptyAction": "Испразни отпад", - "trashEmptyConfirm": "Трајно избрисати сваку ставку у Отпаду? Ово се не може поништити.", - "trashEmptied": "Отпад је испражњен", - "trashRetention": "Аутоматско чишћење после (дана)", - "trashRetentionSaved": "Задржавање отпада је ажурирано", - "trashRetentionFailed": "Ажурирање задржавања у отпаду није успело", - "trashUnavailableConfirm": "Ова ставка не може бити премештена у Отпад, обично зато што се налази на другом систему датотека или захтева повишена права. Желите ли да је трајно избришете?", - "recent": "Недавно", - "pinned": "Закачено", - "folderShortcuts": "Пречице за фасцикле", - "failedToReconnectSSH": "Поновно повезивање SSH сесије није успело", - "openTerminalHere": "Отвори терминал овде", - "run": "Трчи", - "openTerminalInFolder": "Отвори терминал у овој фасцикли", - "openTerminalInFileLocation": "Отвори терминал на локацији датотеке", - "runningFile": "Трчање - {{file}}", - "onlyRunExecutableFiles": "Може покренути само извршне датотеке", - "directories": "Директоријуми", - "removedFromRecentFiles": "Уклоњено је „{{name}}“ из недавних датотека", - "removeFailed": "Уклањање није успело", - "unpinnedSuccessfully": "Откачено „{{name}}“ успешно", - "unpinFailed": "Откачивање није успело", - "removedShortcut": "Уклоњена пречица „{{name}}“", - "removeShortcutFailed": "Уклањање пречице није успело", - "clearedAllRecentFiles": "Обрисани су сви недавно објављени фајлови", - "clearFailed": "Брисање није успело", - "removeFromRecentFiles": "Уклони из недавних датотека", - "clearAllRecentFiles": "Обриши све недавно објављене датотеке", - "unpinFile": "Откачи датотеку", - "removeShortcut": "Уклони пречицу", - "pinFile": "Закачи датотеку", - "addToShortcuts": "Додај у пречице", - "pasteFailed": "Лепљење није успело", - "noUndoableActions": "Нема радњи које се могу поништити", - "undoCopySuccess": "Поништена операција копирања: Обрисано {{count}} копираних датотека", - "undoCopyFailedDelete": "Поништавање није успело: Није могуће обрисати ниједну копирану датотеку", - "undoCopyFailedNoInfo": "Поништавање није успело: Нису пронађене информације о копираној датотеци", - "undoMoveSuccess": "Поништена операција премештања: Премештено {{count}} датотека назад на оригиналну локацију", - "undoMoveFailedMove": "Поништавање није успело: Није могуће вратити датотеке", - "undoMoveFailedNoInfo": "Поништавање није успело: Нису пронађене информације о премештеној датотеци", - "undoDeleteNotSupported": "Брисање се не може поништити: Датотеке су трајно обрисане са сервера", - "undoTypeNotSupported": "Неподржани тип операције поништавања", - "undoOperationFailed": "Поништавање није успело", - "unknownError": "Непозната грешка", - "confirm": "Потврди", - "find": "Пронађи...", - "replace": "Замени", - "downloadInstead": "Преузми уместо тога", - "keyboardShortcuts": "Пречице на тастатури", - "searchAndReplace": "Претражи и замени", - "editing": "Уређивање", - "search": "Претрага", - "findNext": "Пронађи следеће", - "findPrevious": "Пронађи претходно", - "save": "Сачувај", - "selectAll": "Изабери све", - "undo": "Поништи", - "redo": "Понови", - "moveLineUp": "Помери ред нагоре", - "moveLineDown": "Помери ред надоле", - "toggleComment": "Укључи/искључи коментар", - "autoComplete": "Аутоматско довршавање", - "imageLoadError": "Учитавање слике није успело", - "startTyping": "Почни да куцаш...", - "unknownSize": "Непозната величина", - "fileIsEmpty": "Датотека је празна", - "largeFileWarning": "Упозорење о великој датотеци", - "largeFileWarningDesc": "Ова датотека је величине {{size}} , што може изазвати проблеме са перформансама када се отвори као текст.", - "fileNotFoundAndRemoved": "Датотека „{{name}}“ није пронађена и уклоњена је из недавно коришћених/закачених датотека", - "failedToLoadFile": "Учитавање датотеке није успело: {{error}}", - "serverErrorOccurred": "Дошло је до грешке сервера. Молимо покушајте поново касније.", - "autoSaveFailed": "Аутоматско чување није успело", - "fileAutoSaved": "Датотека је аутоматски сачувана", - "moveFileFailed": "Премештање није успело {{name}}", - "moveOperationFailed": "Операција премештања није успела", - "canOnlyCompareFiles": "Могуће је упоредити само две датотеке", - "comparingFiles": "Поређење датотека: {{file1}} и {{file2}}", - "dragFailed": "Превлачење није успело", - "filePinnedSuccessfully": "Датотека „{{name}}“ је успешно закачена", - "pinFileFailed": "Качење датотеке није успело", - "fileUnpinnedSuccessfully": "Датотека „{{name}}“ је успешно откачена", - "unpinFileFailed": "Откачивање датотеке није успело", - "shortcutAddedSuccessfully": "Пречица за фасциклу „{{name}}“ је успешно додата", - "addShortcutFailed": "Додавање пречице није успело", - "operationCompletedSuccessfully": "{{operation}} {{count}} ставке успешно", - "operationCompleted": "{{operation}} {{count}} ставке", - "downloadFileSuccess": "Датотека {{name}} је успешно преузета", - "downloadFileFailed": "Преузимање није успело", - "downloadingFile": "Преузимање {{name}}…", - "downloadProgressBytes": "{{transferred}} / {{total}}", - "moveTo": "Премести на {{name}}", - "diffCompareWith": "Разлика у поређењу са {{name}}", - "dragOutsideToDownload": "Превуците спољашњост прозора да бисте преузели ({{count}} датотека)", - "newFolderDefault": "Нови фолдер", - "newFileDefault": "НоваДатотека.txt", - "successfullyMovedItems": "Успешно премештено {{count}} ставки у {{target}}", - "move": "Помери", - "searchInFile": "Претражи у датотеци (Ctrl+F)", - "showKeyboardShortcuts": "Прикажи пречице на тастатури", - "decreaseFontSize": "Смањи величину фонта", - "increaseFontSize": "Повећај величину фонта", - "startWritingMarkdown": "Почните да пишете свој садржај у markdown формату...", - "loadingFileComparison": "Учитавање поређења датотека...", - "reload": "Поново учитај", - "compare": "Упореди", - "sideBySide": "Један поред другог", - "inline": "Уграђено", - "fileComparison": "Поређење датотека: {{file1}} наспрам {{file2}}", - "fileTooLarge": "Датотека је превелика: {{error}}", - "sshConnectionFailed": "SSH веза није успела. Молимо вас да проверите везу са {{name}} ({{ip}}:{{port}})", - "loadFileFailed": "Учитавање датотеке није успело: {{error}}", - "connecting": "Повезивање...", - "connectedSuccessfully": "Успешно повезано", - "totpVerificationFailed": "Верификација TOTP-а није успела", - "authenticationFailed": "Аутентификација није успела", - "incorrectPassphrase": "Нетачна лозинка. Молимо покушајте поново.", - "verificationCodePrompt": "Верификациони код:", - "changePermissions": "Промени дозволе", - "currentPermissions": "Тренутне дозволе", - "owner": "Власник", - "group": "Група", - "others": "Други", - "read": "Читај", - "write": "Пиши", - "execute": "Изврши", - "permissionsChangedSuccessfully": "Дозволе су успешно промењене", - "failedToChangePermissions": "Промена дозвола није успела", - "name": "Име", - "sortByName": "Име", - "sortByDate": "Датум измене", - "sortBySize": "Величина", - "ascending": "Растуће", - "descending": "Опадајући", - "root": "Корен", - "new": "Ново", - "sortBy": "Сортирај по", - "items": "Ставке", - "selected": "Изабрано", - "editor": "Уредник", - "octal": "Октално", - "storage": "Складиштење", - "disk": "Диск", - "used": "Коришћено", - "of": "од", - "toggleSidebar": "Укључи/искључи бочну траку", - "compactLayout": "Користите компактни распоред", - "comfortableLayout": "Користите удобан распоред", - "cannotLoadPdf": "Није могуће учитати PDF", - "pdfLoadError": "Дошло је до грешке при учитавању ове PDF датотеке.", - "loadingPdf": "Учитавање PDF-а...", - "loadingPage": "Учитавање странице..." + "nav": { + "files": "Files", + "sftp": "SFTP", + "openFileManager": "Open File Manager" }, - "sftpTransfer": { - "title": "СФТП", - "description": "Пренос датотека између два SSH хоста.", - "sourceServer": "Изворни сервер", - "destinationServer": "Одредишни сервер", - "selectHost": "Изаберите хоста", - "noHostSelected": "Није изабран домаћин", - "move": "Помери", - "copy": "Копија", - "upload": "Отпреми", - "itemsSelected": "{{count}} ставка је изабрана", - "itemsSelected_other": "Изабрано је {{count}} ставки", - "ready": "Спреман", - "loadingHosts": "Учитавање хостова...", - "name": "Име", - "modified": "Измењено", - "size": "Величина", - "noFiles": "Нема датотека", - "open": "Отворено", - "up": "Горе", - "refresh": "Освежи", - "copyToTarget": "Копирај у циљни директоријум", - "rename": "Преименуј", - "delete": "Обриши", - "editPermissions": "Измени дозволе", - "createNewFolder": "Направи нову фасциклу", - "deleteSelectedItems": "Обриши изабране ставке", - "deleteConfirm": "Обришите {{count}} изабрану ставку?", - "deleteConfirm_other": "Обришите {{count}} изабраних ставки?", - "cancel": "Откажи", - "save": "Сачувај", - "folderCreated": "Фасцикла је направљена", - "itemRenamed": "Ставка је преименована", - "actionFailed": "Акција није успела", - "itemsDeleted": "{{count}} ставка је обрисана", - "itemsDeleted_other": "{{count}} ставки су обрисане", - "deleteFailed": "Брисање није успело", - "permissionsUpdated": "Дозволе су ажуриране", - "noRemoteSessionConnected": "Није повезана удаљена сесија", - "failedToListFiles": "Навођење датотека није успело", - "failedToRefresh": "Освежавање није успело", - "destinationInsideSource": "Одредиште не може бити унутар изабране изворне путање.", - "sameHostNoOp": "Извор и одредиште су иста фасцикла." - }, - "hosts": { - "fileManager": "Менаџер датотека", - "tabFiles": "Датотеке", - "enableFileManagerMonitor": "Омогући менаџер датотека", - "enableFileManagerMonitorDesc": "Прегледајте и управљајте датотекама на овом хосту преко SFTP-а", - "scpLegacyLabel": "SCP Legacy Mode", - "scpLegacyDesc": "Користите старији пренос датотека за сервере који не подржавају SFTP подсистем (нпр. уграђени или минимални SSH сервери).", - "defaultPathLabel": "Подразумевана путања", - "fileManagerPathHint": "Директоријум који треба отворити када се покрене менаџер датотека за овај хост.", - "fileManagerUrlCopied": "URL менаџера датотека је копиран", - "copyFileManagerUrlAction": "Копирај URL менаџера датотека", - "docsLink": "Прикажи документе", - "hostNotFound": "Хост није пронађен", - "loadingHost": "Учитавање хоста..." + "permissions": { + "use": { + "title": "Use file manager", + "description": "Browse, edit and transfer files over SFTP." + } }, "settings": { "host": { "enable": { - "label": "Омогући менаџер датотека" + "label": "Enable File Manager", + "description": "Browse and edit files on this host over SFTP." }, "defaultPath": { - "label": "Подразумевана путања" + "label": "Default Path" }, "scpLegacy": { "label": "SCP Legacy Mode" @@ -401,113 +25,519 @@ }, "user": { "transferConcurrency": { - "label": "Истовремени пренос датотека", - "description": "Колико датотека локални/удаљени менаџер истовремено отпрема или преузима. Смањите ово ако ваш сервер ограничава SFTP канале." + "label": "Simultaneous File Transfers", + "description": "How many files the side by side local/remote manager uploads or downloads at the same time. Lower this if your server limits SFTP channels." + }, + "confirmBeforeTrash": { + "label": "Confirm before moving files to trash", + "description": "Ask before moving remote files to trash. Permanent deletion still requires confirmation." } } }, - "nav": { - "sftp": "СФТП", - "files": "Датотеке" + "hostCapability": { + "label": "File Manager" + }, + "fileManager": { + "noHostSelected": "No host selected", + "initializingEditor": "Initializing editor...", + "file": "File", + "folder": "Folder", + "uploadFile": "Upload File", + "downloadFile": "Download", + "extractArchive": "Extract Archive", + "extractingArchive": "Extracting {{name}}...", + "archiveExtractedSuccessfully": "{{name}} extracted successfully", + "extractFailed": "Extract failed", + "compressFile": "Compress File", + "compressFiles": "Compress Files", + "compressFilesDesc": "Compress {{count}} items into an archive", + "archiveName": "Archive Name", + "enterArchiveName": "Enter archive name...", + "compressionFormat": "Compression Format", + "selectedFiles": "Selected files", + "andMoreFiles": "and {{count}} more...", + "compress": "Compress", + "compressingFiles": "Compressing {{count}} items into {{name}}...", + "filesCompressedSuccessfully": "{{name}} created successfully", + "compressFailed": "Compression failed", + "edit": "Edit", + "preview": "Preview", + "previous": "Previous", + "next": "Next", + "pageXOfY": "Page {{current}} of {{total}}", + "zoomOut": "Zoom Out", + "zoomIn": "Zoom In", + "newFile": "New File", + "newFolder": "New Folder", + "rename": "Rename", + "uploading": "Uploading...", + "uploadingFile": "Uploading {{name}}...", + "uploadingChunk": "Uploading {{name}}: {{percent}}% (part {{chunk}} of {{total}})", + "fileName": "File Name", + "folderName": "Folder Name", + "fileUploadedSuccessfully": "File \"{{name}}\" uploaded successfully", + "failedToUploadFile": "Failed to upload file", + "uploadingFolderFiles": "Uploading {{count}} file(s)...", + "uploadedFolderFiles": "Uploaded {{count}} file(s) successfully", + "uploadedFolderPartial": "Uploaded {{uploaded}} file(s), {{failed}} failed", + "fileDownloadedSuccessfully": "File \"{{name}}\" downloaded successfully", + "failedToDownloadFile": "Failed to download file", + "fileCreatedSuccessfully": "File \"{{name}}\" created successfully", + "folderCreatedSuccessfully": "Folder \"{{name}}\" created successfully", + "failedToCreateItem": "Failed to create item", + "operationFailed": "{{operation}} operation failed for {{name}}: {{error}}", + "failedToResolveSymlink": "Failed to resolve symlink", + "itemsDeletedSuccessfully": "{{count}} items deleted successfully", + "failedToDeleteItems": "Failed to delete items", + "sudoPasswordRequired": "Administrator Password Required", + "enterSudoPassword": "Enter sudo password to continue this operation", + "sudoPassword": "Sudo password", + "sudoOperationFailed": "Sudo operation failed", + "sudoAuthFailed": "Sudo authentication failed", + "dragFilesToUpload": "Drop files here to upload", + "dropToUploadHere": "Drop to upload here", + "dropToDownloadHere": "Drop to download here", + "localFiles": "Local", + "showLocalFiles": "Show local files (split view)", + "hideLocalFiles": "Hide local files", + "localHome": "Home folder", + "localPathPlaceholder": "Local folder path", + "localShowHidden": "Show hidden files", + "localHideHidden": "Hide hidden files", + "localRevealInFileManager": "Reveal in system file manager", + "localCannotOpenFolder": "Cannot open folder", + "localItemCount": "{{count}} items", + "localSelectedCount": "{{count}} selected", + "back": "Back", + "forward": "Forward", + "up": "Up", + "kind": "Kind", + "localUploadingProgress": "Uploading {{current}} of {{total}}", + "localDownloadingProgress": "Downloading {{current}} of {{total}}", + "localTransferInFlight": "{{count}} at once", + "localPreparingDownload": "Preparing download...", + "localTransferCancelled": "Transfer cancelled", + "localNothingToTransfer": "Nothing to transfer", + "localUploadComplete": "Uploaded {{count}} file(s)", + "localUploadFailed": "Upload failed", + "localUploadPartial": "Uploaded {{done}} file(s), {{failed}} failed", + "localDownloadComplete": "Downloaded {{count}} file(s)", + "localDownloadFailed": "Download failed", + "localDownloadPartial": "Downloaded {{done}} file(s), {{failed}} failed", + "localReplaceExistingPrompt": "{{count}} item(s) already exist in this folder. Replace them?", + "localReplace": "Replace", + "localSkipExisting": "Skip", + "localSkippedExisting": "Skipped {{count}} existing item(s)", + "localUnsafeNamesSkipped": "Skipped {{count}} item(s) whose names cannot be used on this computer", + "localOpen": "Open", + "localOpenFolder": "Open folder", + "localUploadToRemote": "Upload to server", + "localUploadToRemoteMany": "Upload {{count}} items to server", + "localMoveToTrash": "Move to Trash", + "localMoveToTrashMany": "Move {{count}} items to Trash", + "localTrashConfirmSingle": "Move \"{{name}}\" to the Trash?", + "localTrashConfirmFolder": "Move the folder \"{{name}}\" and all its contents to the Trash?", + "localTrashConfirmMany": "Move {{count}} items to the Trash?", + "localTrashed": "Moved {{count}} item(s) to the Trash", + "localTrashFailed": "Could not move to the Trash", + "localRenameFailed": "Rename failed", + "localCreateFailed": "Could not create item", + "goToParentFolder": "Go to parent folder", + "resizeSidebar": "Drag to resize the sidebar (double-click to reset)", + "resizeLocalPane": "Drag to resize the local pane (double-click to reset)", + "columns": "Columns", + "columnsHint": "Right-click to choose columns", + "emptyFolder": "This folder is empty", + "searchFiles": "Search files...", + "upload": "Upload", + "selectHostToStart": "Select a host to start file management", + "sshRequiredForFileManager": "File manager requires SSH. This host does not have SSH enabled.", + "failedToConnect": "Failed to connect to SSH", + "failedToLoadDirectory": "Failed to load directory", + "noSSHConnection": "No SSH connection available", + "copy": "Copy", + "cut": "Cut", + "paste": "Paste", + "copyPath": "Copy Path", + "copyPaths": "Copy Paths", + "delete": "Delete", + "properties": "Properties", + "refresh": "Refresh", + "downloadFiles": "Download {{count}} files to Browser", + "copyFiles": "Copy {{count}} items", + "cutFiles": "Cut {{count}} items", + "deleteFiles": "Delete {{count}} items", + "filesCopiedToClipboard": "{{count}} items copied to clipboard", + "filesCutToClipboard": "{{count}} items cut to clipboard", + "pathCopiedToClipboard": "Path copied to clipboard", + "pathsCopiedToClipboard": "{{count}} paths copied to clipboard", + "failedToCopyPath": "Failed to copy path to clipboard", + "copyFolderLink": "Copy Link to Folder", + "copyCurrentFolderLink": "Copy Link to Current Folder", + "folderLinkCopied": "Folder link copied to clipboard", + "failedToCopyFolderLink": "Failed to copy folder link", + "movedItems": "Moved {{count}} items", + "failedToDeleteItem": "Failed to delete item", + "itemRenamedSuccessfully": "{{type}} renamed successfully", + "failedToRenameItem": "Failed to rename item", + "download": "Download", + "openExternalEditor": "Open externally", + "chooseExternalEditor": "Choose external editor", + "externalEditorSelected": "External editor selected", + "externalEditorDesktopOnly": "External editor is only available in the desktop app", + "externalEditorOpened": "Opened in external editor. Saving there will upload changes back to the server.", + "failedToOpenExternalEditor": "Failed to open external editor", + "failedToSelectExternalEditor": "Failed to select external editor", + "permissions": "Permissions", + "size": "Size", + "modified": "Modified", + "path": "Path", + "confirmDelete": "Are you sure you want to delete {{name}}?", + "permissionDenied": "Permission denied", + "serverError": "Server Error", + "fileSavedSuccessfully": "File saved successfully", + "failedToSaveFile": "Failed to save file", + "confirmDeleteSingleItem": "Are you sure you want to permanently delete \"{{name}}\"?", + "confirmDeleteMultipleItems": "Are you sure you want to permanently delete {{count}} items?", + "confirmDeleteMultipleItemsWithFolders": "Are you sure you want to permanently delete {{count}} items? This includes folders and their contents.", + "confirmDeleteFolder": "Are you sure you want to permanently delete the folder \"{{name}}\" and all its contents?", + "permanentDeleteWarning": "This action cannot be undone. The item(s) will be permanently deleted from the server.", + "moveToTrashWarning": "The item(s) will be moved to the Termix Trash and can be restored before the retention period expires.", + "itemsMovedToTrash": "{{count}} item(s) moved to Trash", + "trash": "Trash", + "trashDescription": "Deleted items are retained for {{days}} day(s) on this host.", + "trashLoadFailed": "Failed to load Trash", + "trashEmpty": "Trash is empty", + "trashRestore": "Restore", + "trashRestored": "Restored {{name}}", + "trashRestoreFailed": "Failed to restore item. The original path may already exist.", + "trashDeletePermanently": "Delete permanently", + "trashDeleteConfirm": "Permanently delete {{name}}? This cannot be undone.", + "trashPermanentlyDeleted": "Permanently deleted {{name}}", + "trashDeleteFailed": "Failed to permanently delete item", + "trashEmptyAction": "Empty Trash", + "trashEmptyConfirm": "Permanently delete every item in Trash? This cannot be undone.", + "trashEmptied": "Trash emptied", + "trashRetention": "Automatic cleanup after (days)", + "trashRetentionSaved": "Trash retention updated", + "trashRetentionFailed": "Failed to update Trash retention", + "trashUnavailableConfirm": "This item cannot be moved to Trash, usually because it is on another filesystem or requires elevated permissions. Delete it permanently instead?", + "recent": "Recent", + "pinned": "Pinned", + "folderShortcuts": "Folder Shortcuts", + "failedToReconnectSSH": "Failed to reconnect SSH session", + "openTerminalHere": "Open Terminal Here", + "run": "Run", + "openTerminalInFolder": "Open Terminal in This Folder", + "openTerminalInFileLocation": "Open Terminal at File Location", + "runningFile": "Running - {{file}}", + "onlyRunExecutableFiles": "Can only run executable files", + "directories": "Directories", + "removedFromRecentFiles": "Removed \"{{name}}\" from recent files", + "removeFailed": "Remove failed", + "unpinnedSuccessfully": "Unpinned \"{{name}}\" successfully", + "unpinFailed": "Unpin failed", + "removedShortcut": "Removed shortcut \"{{name}}\"", + "removeShortcutFailed": "Remove shortcut failed", + "clearedAllRecentFiles": "Cleared all recent files", + "clearFailed": "Clear failed", + "removeFromRecentFiles": "Remove from recent files", + "clearAllRecentFiles": "Clear all recent files", + "unpinFile": "Unpin file", + "removeShortcut": "Remove shortcut", + "pinFile": "Pin file", + "addToShortcuts": "Add to shortcuts", + "pasteFailed": "Paste failed", + "noUndoableActions": "No undoable actions", + "undoCopySuccess": "Undid copy operation: Deleted {{count}} copied files", + "undoCopyFailedDelete": "Undo failed: Could not delete any copied files", + "undoCopyFailedNoInfo": "Undo failed: Could not find copied file information", + "undoMoveSuccess": "Undid move operation: Moved {{count}} files back to original location", + "undoMoveFailedMove": "Undo failed: Could not move any files back", + "undoMoveFailedNoInfo": "Undo failed: Could not find moved file information", + "undoDeleteNotSupported": "Delete operation cannot be undone: Files have been permanently deleted from server", + "undoTypeNotSupported": "Unsupported undo operation type", + "undoOperationFailed": "Undo operation failed", + "unknownError": "Unknown error", + "confirm": "Confirm", + "find": "Find...", + "replace": "Replace", + "downloadInstead": "Download Instead", + "keyboardShortcuts": "Keyboard Shortcuts", + "searchAndReplace": "Search & Replace", + "editing": "Editing", + "search": "Search", + "findNext": "Find Next", + "findPrevious": "Find Previous", + "save": "Save", + "selectAll": "Select All", + "undo": "Undo", + "redo": "Redo", + "moveLineUp": "Move Line Up", + "moveLineDown": "Move Line Down", + "toggleComment": "Toggle Comment", + "autoComplete": "Auto Complete", + "imageLoadError": "Failed to load image", + "startTyping": "Start typing...", + "unknownSize": "Unknown size", + "fileIsEmpty": "File is empty", + "largeFileWarning": "Large File Warning", + "largeFileWarningDesc": "This file is {{size}} in size, which may cause performance issues when opened as text.", + "fileNotFoundAndRemoved": "File \"{{name}}\" not found and has been removed from recent/pinned files", + "failedToLoadFile": "Failed to load file: {{error}}", + "serverErrorOccurred": "Server error occurred. Please try again later.", + "autoSaveFailed": "Auto-save failed", + "fileAutoSaved": "File auto-saved", + "moveFileFailed": "Failed to move {{name}}", + "moveOperationFailed": "Move operation failed", + "canOnlyCompareFiles": "Can only compare two files", + "comparingFiles": "Comparing files: {{file1}} and {{file2}}", + "dragFailed": "Drag operation failed", + "filePinnedSuccessfully": "File \"{{name}}\" pinned successfully", + "pinFileFailed": "Failed to pin file", + "fileUnpinnedSuccessfully": "File \"{{name}}\" unpinned successfully", + "unpinFileFailed": "Failed to unpin file", + "shortcutAddedSuccessfully": "Folder shortcut \"{{name}}\" added successfully", + "addShortcutFailed": "Failed to add shortcut", + "operationCompletedSuccessfully": "{{operation}} {{count}} items successfully", + "operationCompleted": "{{operation}} {{count}} items", + "downloadFileSuccess": "File {{name}} downloaded successfully", + "downloadFileFailed": "Download failed", + "downloadingFile": "Downloading {{name}}…", + "downloadProgressBytes": "{{transferred}} / {{total}}", + "moveTo": "Move to {{name}}", + "diffCompareWith": "Diff compare with {{name}}", + "dragOutsideToDownload": "Drag outside window to download ({{count}} files)", + "newFolderDefault": "NewFolder", + "newFileDefault": "NewFile.txt", + "successfullyMovedItems": "Successfully moved {{count}} items to {{target}}", + "move": "Move", + "searchInFile": "Search in file (Ctrl+F)", + "showKeyboardShortcuts": "Show keyboard shortcuts", + "decreaseFontSize": "Decrease font size", + "increaseFontSize": "Increase font size", + "startWritingMarkdown": "Start writing your markdown content...", + "loadingFileComparison": "Loading file comparison...", + "reload": "Reload", + "compare": "Compare", + "sideBySide": "Side by Side", + "inline": "Inline", + "fileComparison": "File Comparison: {{file1}} vs {{file2}}", + "fileTooLarge": "File too large: {{error}}", + "sshConnectionFailed": "SSH connection failed. Please check your connection to {{name}} ({{ip}}:{{port}})", + "loadFileFailed": "Failed to load file: {{error}}", + "connecting": "Connecting...", + "connectedSuccessfully": "Connected successfully", + "totpVerificationFailed": "TOTP verification failed", + "browserSignInFailed": "Sign-in failed. Please try again.", + "authenticationFailed": "Authentication failed", + "incorrectPassphrase": "Incorrect passphrase. Please try again.", + "verificationCodePrompt": "Verification code:", + "changePermissions": "Change Permissions", + "currentPermissions": "Current Permissions", + "owner": "Owner", + "group": "Group", + "others": "Others", + "read": "Read", + "write": "Write", + "execute": "Execute", + "permissionsChangedSuccessfully": "Permissions changed successfully", + "failedToChangePermissions": "Failed to change permissions", + "name": "Name", + "sortByName": "Name", + "sortByDate": "Date Modified", + "sortBySize": "Size", + "ascending": "Ascending", + "descending": "Descending", + "root": "Root", + "new": "New", + "sortBy": "Sort By", + "items": "Items", + "selected": "Selected", + "editor": "Editor", + "octal": "Octal", + "storage": "Storage", + "disk": "Disk", + "used": "Used", + "of": "of", + "toggleSidebar": "Toggle Sidebar", + "compactLayout": "Use compact layout", + "comfortableLayout": "Use comfortable layout", + "cannotLoadPdf": "Cannot load PDF", + "pdfLoadError": "There was an error loading this PDF file.", + "loadingPdf": "Loading PDF...", + "loadingPage": "Loading page...", + "cancel": "Cancel", + "copiedItems_one": "Copied {{count}} item", + "copiedItems_other": "Copied {{count}} items", + "deleteCopiedFileFailed": "Could not delete the copy of {{name}}: {{error}}", + "dragMovedItems_one": "Moved {{count}} item to {{target}}", + "dragMovedItems_other": "Moved {{count}} items to {{target}}", + "moveBackFileFailed": "Could not move {{name}} back: {{error}}", + "terminal": "Terminal: {{host}} ({{path}})", + "dragToDesktop": "Dragging {{name}} to the desktop", + "dragFilesToDesktop": "Dragging {{count}} files to the desktop", + "folderDragUnsupported": "Dragging folders to the desktop is not supported yet", + "saveToDesktopFailed": "Save failed: {{error}}", + "dragFailedDetail": "Drag failed: {{error}}", + "videoUnsupported": "Your browser cannot play this video format.", + "downloadToPlay": "Download to play it elsewhere", + "cannotPreviewType": "Cannot preview this file type", + "cannotPreviewTypeHint": "This file type has no preview. Download it to open it in another app." + }, + "sftpTransfer": { + "title": "SFTP", + "description": "Transfer files between two SSH hosts.", + "sourceServer": "Source Server", + "destinationServer": "Destination Server", + "selectHost": "Select host", + "noHostSelected": "No host selected", + "move": "Move", + "copy": "Copy", + "upload": "Upload", + "itemsSelected": "{{count}} item selected", + "itemsSelected_other": "{{count}} items selected", + "ready": "Ready", + "loadingHosts": "Loading hosts...", + "name": "Name", + "modified": "Modified", + "size": "Size", + "noFiles": "No files", + "open": "Open", + "up": "Up", + "refresh": "Refresh", + "copyToTarget": "Copy to Target Directory", + "rename": "Rename", + "delete": "Delete", + "editPermissions": "Edit Permissions", + "createNewFolder": "Create New Folder", + "deleteSelectedItems": "Delete Selected Items", + "deleteConfirm": "Delete {{count}} selected item?", + "deleteConfirm_other": "Delete {{count}} selected items?", + "cancel": "Cancel", + "save": "Save", + "folderCreated": "Folder created", + "itemRenamed": "Item renamed", + "actionFailed": "Action failed", + "itemsDeleted": "{{count}} item deleted", + "itemsDeleted_other": "{{count}} items deleted", + "deleteFailed": "Delete failed", + "permissionsUpdated": "Permissions updated", + "noRemoteSessionConnected": "No remote session connected", + "failedToListFiles": "Failed to list files", + "failedToRefresh": "Failed to refresh", + "destinationInsideSource": "Destination cannot be inside the selected source path.", + "sameHostNoOp": "Source and destination are the same folder." + }, + "hosts": { + "fileManager": "File Manager", + "fileManagerUrlCopied": "File Manager URL copied", + "copyFileManagerUrlAction": "Copy File Manager URL", + "docsLink": "View docs", + "hostNotFound": "Host not found", + "loadingHost": "Loading host..." }, "onboarding": { - "feature_files": "Менаџер датотека", - "feature_files_desc": "Прегледајте, отпремајте, преузимајте и уређујте датотеке преко SFTP-а без напуштања апликације." + "feature_files": "File manager", + "feature_files_desc": "Browse, upload, download and edit files over SFTP without leaving the app." }, "terminal": { - "runTitle": "Покреће се {{command}} - {{host}}", - "terminalTitle": "Терминал - {{host}}", - "terminalWithPath": "Терминал - {{host}}:{{path}}" + "runTitle": "Running {{command}} - {{host}}", + "terminalTitle": "Terminal - {{host}}", + "terminalWithPath": "Terminal - {{host}}:{{path}}" }, "transfer": { - "browseFolders": "Прегледајте одредишне фасцикле", - "browsePathError": "Није могуће отворити ову путању на одредишном хосту.", - "browsePathWillBeCreated": "Ова фасцикла још увек не постоји. Биће креирана када пренос почне.", - "cancel": "Откажи", - "cleanupDestFiles": "Очистите одредиште", - "cleanupDestFilesError": "Чишћење није успело", - "cleanupDestFilesNothing": "Нема ништа за чишћење на одредишту", - "cleanupDestFilesPartial": "Неке делимичне датотеке нису могле бити уклоњене", - "cleanupDestFilesSuccess": "Уклоњене су делимичне датотеке са одредишта", - "confirmCopy": "Копија", - "confirmMove": "Помери", - "copyFolderToHost": "Копирај фасциклу на хост…", - "copyItemsToHost": "Копирај {{count}} ставке за хостовање…", - "copyToHost": "Копирај на хост…", - "destinationPath": "Путања одредишта", - "destMustBeDirectory": "Одредиште мора бити директоријум за преносе више ставки", - "goUp": "Иди горе", - "hostAuthRequired": "Потребна је аутентификација — прво отворите File Manager на овом хосту", - "hostConnecting": "Повезивање…", - "hostConnectionFailed": "Повезивање није успело", - "hostDisconnected": "Није повезано", - "hostReady": "Спреман", - "itemsSummary": "{{count}} ставке", - "jumpHostLimitation": "Оба хоста морају бити доступна са Termix сервера. Директно рутирање од хоста до хоста није подржано.", - "methodAuto": "Аутоматски", - "methodAutoHint": "Бира tar или SFTP за сваку датотеку на основу броја датотека, величине и компресибилности. Појединачне датотеке увек користе SFTP за стримовање.", - "methodItemSftp": "SFTP по датотеци", - "methodItemSftpHint": "Пренесите сваку датотеку појединачно преко SFTP-а. Ради на свим хостовима, укључујући Windows.", - "methodItemSftpLimitation": "Свака датотека користи исти SFTP ток као и копија појединачних датотека, једна за другом. Напредак се комбинује за све датотеке, тако да се трака помера споро током великих датотека.", - "methodLabel": "Метод преноса", - "methodPreviewError": "Није могуће прегледати метод преноса. Сервер ће ипак изабрати метод када покренете.", - "methodPreviewLoading": "Израчунавање методе преноса…", - "methodPreviewScanSummary": "{{fileCount}} датотека, {{totalSize}} укупно (скенирано на изворном хосту).", - "methodPreviewWillUseItemSftp": "Користиће се: SFTP за сваку датотеку", - "methodPreviewWillUseTar": "Користиће се: Тар архива", + "browseFolders": "Browse destination folders", + "browsePathError": "Could not open this path on the destination host.", + "browsePathWillBeCreated": "This folder does not exist yet. It will be created when the transfer starts.", + "cancel": "Cancel", + "cleanupDestFiles": "Clean up destination", + "cleanupDestFilesError": "Cleanup failed", + "cleanupDestFilesNothing": "Nothing to clean up on the destination", + "cleanupDestFilesPartial": "Some partial files could not be removed", + "cleanupDestFilesSuccess": "Removed partial files from the destination", + "confirmCopy": "Copy", + "confirmMove": "Move", + "copyFolderToHost": "Copy folder to host…", + "copyItemsToHost": "Copy {{count}} items to host…", + "copyToHost": "Copy to host…", + "destinationPath": "Destination path", + "destMustBeDirectory": "Destination must be a directory for multi-item transfers", + "goUp": "Go up", + "hostAuthRequired": "Authentication required. Open File Manager on this host first", + "hostConnecting": "Connecting…", + "hostConnectionFailed": "Connection failed", + "hostDisconnected": "Not connected", + "hostReady": "Ready", + "itemsSummary": "{{count}} items", + "jumpHostLimitation": "Both hosts must be reachable from the Termix server. Direct host-to-host routing is not supported.", + "methodAuto": "Auto", + "methodAutoHint": "Picks tar or per-file SFTP based on file count, size, and compressibility. Single files always use streaming SFTP.", + "methodItemSftp": "Per-file SFTP", + "methodItemSftpHint": "Transfer each file individually over SFTP. Works on all hosts including Windows.", + "methodItemSftpLimitation": "Each file uses the same SFTP stream as a single-file copy, one after another. Progress is combined across all files, so the bar moves slowly during large files.", + "methodLabel": "Transfer method", + "methodPreviewError": "Could not preview transfer method. The server will still pick a method when you start.", + "methodPreviewLoading": "Calculating transfer method…", + "methodPreviewScanSummary": "{{fileCount}} files, {{totalSize}} total (scanned on source host).", + "methodPreviewWillUseItemSftp": "Will use: Per-file SFTP", + "methodPreviewWillUseTar": "Will use: Tar archive", "methodReason": { - "user_item_sftp": "Изабрали сте SFTP за сваку датотеку.", - "user_tar": "Изабрали сте tar архиву.", - "tar_unavailable": "Тар није доступан на једном или оба хоста — уместо тога ће се користити SFTP протокол за сваку датотеку.", - "windows_host": "Укључен је Windows хост — tar се не користи.", - "auto_multi_large": "Аутоматски: више датотека укључујући велику датотеку ({{largestSize}}) са компресибилним подацима — tar пакети у један пренос.", - "auto_single_large_in_archive": "Аутоматски: једна велика датотека ({{largestSize}}) у овом скупу — SFTP за сваку датотеку.", - "auto_many_incompressible": "Аутоматски: углавном несемпљиви подаци — SFTP по датотеци.", - "auto_many_files": "Аутоматски: много датотека ({{fileCount}}) — tar смањује оптерећење по датотеци.", - "auto_default": "Аутоматски: SFTP за сваку датотеку за овај скуп." + "user_item_sftp": "You chose per-file SFTP.", + "user_tar": "You chose tar archive.", + "tar_unavailable": "Tar is not available on one or both hosts, so per-file SFTP will be used instead.", + "windows_host": "A Windows host is involved, so tar is not used.", + "auto_multi_large": "Auto: multiple files including a large file ({{largestSize}}) with compressible data. Tar bundles them into one transfer.", + "auto_single_large_in_archive": "Auto: one large file ({{largestSize}}) in this set, so per-file SFTP.", + "auto_many_incompressible": "Auto: mostly incompressible data, so per-file SFTP.", + "auto_many_files": "Auto: many files ({{fileCount}}), tar cuts the per-file overhead.", + "auto_default": "Auto: per-file SFTP for this set." }, - "methodTar": "Тар архива", - "methodTarHint": "Компресуј на изворном нивоу, пренеси једну архиву, распакуј на одредишту. Потребан је tar на оба Unix хоста.", - "metricsCompress": "Компресуј на изворном коду: {{duration}}", - "metricsExtract": "Издвајање на одредишту: {{duration}}", - "metricsPrepare": "Припреми одредиште: {{duration}}", - "metricsRouteBenchmark": "Сонда руте — директна: {{direct}}, релеј: {{relay}}", - "metricsSourceDelete": "Уклони из извора: {{duration}}", - "metricsTotal": "Укупно: {{duration}}", - "metricsTransfer": "Од краја до краја: {{throughput}} ({{duration}})", - "metricsVerify": "SHA-256 верификован: {{duration}}", - "moveFolderToHost": "Премести фасциклу на хост…", - "moveItemsToHost": "Премести {{count}} ставке на хост…", - "moveToHost": "Премести на хост…", - "noHostsConnected": "Нема других доступних хостова за управљање датотекама.", - "noHostsConnectedHint": "Додајте још један SSH хост са омогућеним File Manager-ом у Host Manager-у.", - "parallelSegmentsHint": "Велике датотеке су подељене на делове од 256 MB. Вишеструке траке користе одвојене везе (као што је покретање неколико преноса) за већи укупни проток.", - "parallelSegmentsLabel": "Паралелне траке за прелазак", - "parallelSegmentsOption": "{{count}} траке", - "progressBenchmarking": "Избор најбрже руте за трансфер…", + "methodTar": "Tar archive", + "methodTarHint": "Compress on source, transfer one archive, extract on destination. Requires tar on both Unix hosts.", + "metricsCompress": "Compress on source: {{duration}}", + "metricsExtract": "Extract on destination: {{duration}}", + "metricsPrepare": "Prepare destination: {{duration}}", + "metricsRouteBenchmark": "Route probe: direct {{direct}}, relay {{relay}}", + "metricsSourceDelete": "Remove from source: {{duration}}", + "metricsTotal": "Total: {{duration}}", + "metricsTransfer": "End-to-end: {{throughput}} ({{duration}})", + "metricsVerify": "SHA-256 verified: {{duration}}", + "moveFolderToHost": "Move folder to host…", + "moveItemsToHost": "Move {{count}} items to host…", + "moveToHost": "Move to host…", + "noHostsConnected": "No other file-manager hosts available.", + "noHostsConnectedHint": "Add another SSH host with File Manager enabled in Host Manager.", + "parallelSegmentsHint": "Large files are split into 256 MB chunks. Multiple lanes use separate connections (like starting several transfers) for higher total throughput.", + "parallelSegmentsLabel": "Parallel transfer lanes", + "parallelSegmentsOption": "{{count}} lanes", + "progressBenchmarking": "Selecting the fastest transfer route…", "progressBytes": "{{transferred}} / {{total}}", - "progressCancel": "Откажи", - "progressCancelling": "Отказивање…", - "progressCompressing": "Компресија на изворном хосту…", - "progressExtracting": "Распакује се на одредишту…", - "progressItems": "{{current}} / {{total}} датотеке", - "progressReconnecting": "Поновно повезивање…", - "progressStalled": "Заустављено", - "progressTotalSpeed": "{{speed}} укупно ({{lanes}} трака)", - "progressTransferring": "Пренос података…", - "progressTransferringItems": "Пренос датотека ({{current}} од {{total}})…", - "progressVerifying": "Провера интегритета датотеке…", - "recentDestinations": "Недавне дестинације", - "resumedHint": "Поново повезано са активним преносом започетим у другом прозору.", - "retryTransfer": "Покушај поново", - "retryTransferError": "Поновни покушај није успео", - "selectDestinationHost": "Изаберите одредишни хост", - "transferCancelled": "Трансфер отказан", - "transferCancelledCopyHint": "Делимични фајлови могу остати на одредишту.", - "transferCancelledMoveHint": "Делимични фајлови могу остати на одредишту. Изворни фајлови нису уклоњени.", - "transferError": "Пренос није успео", - "transferFailedRetryHint": "Делимични подаци су сачувани на одредишту. Покушај ће бити настављен када се веза поново успостави.", - "transferPartialHint": "Није могуће пренети: {{paths}}", - "transferSuccess": "Пренос завршен" + "progressCancel": "Cancel", + "progressCancelling": "Cancelling…", + "progressCompressing": "Compressing on source host…", + "progressExtracting": "Extracting on destination…", + "progressItems": "{{current}} / {{total}} files", + "progressReconnecting": "Reconnecting…", + "progressStalled": "Stalled", + "progressTotalSpeed": "{{speed}} total ({{lanes}} lanes)", + "progressTransferring": "Transferring data…", + "progressTransferringItems": "Transferring files ({{current}} of {{total}})…", + "progressVerifying": "Verifying file integrity…", + "recentDestinations": "Recent destinations", + "resumedHint": "Reconnected to an active transfer started in another window.", + "retryTransfer": "Retry", + "retryTransferError": "Retry failed", + "selectDestinationHost": "Select destination host", + "transferCancelled": "Transfer cancelled", + "transferCancelledCopyHint": "Partial files may remain on the destination.", + "transferCancelledMoveHint": "Partial files may remain on the destination. Source files were not removed.", + "transferError": "Transfer failed", + "transferFailedRetryHint": "Partial data was kept on the destination. Retry will resume when the connection is back.", + "transferPartialHint": "Could not transfer: {{paths}}", + "transferSuccess": "Transfer complete", + "metricsHopSourceRead": "Source → server: {{throughput}}", + "metricsHopDestSftpWrite": "Server → dest (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Server → dest (local): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/sv_SE.json b/plugins/file-manager/locales/translated/sv_SE.json index 8e18fc1be..dc86761ce 100644 --- a/plugins/file-manager/locales/translated/sv_SE.json +++ b/plugins/file-manager/locales/translated/sv_SE.json @@ -1,513 +1,543 @@ { - "fileManager": { - "noHostSelected": "Ingen värd vald", - "initializingEditor": "Initierar redigeraren...", - "file": "Fil", - "folder": "Mapp", - "uploadFile": "Ladda upp fil", - "downloadFile": "Ladda ner", - "extractArchive": "Utdragsarkiv", - "extractingArchive": "Extraherar {{name}}...", - "archiveExtractedSuccessfully": "{{name}} extraherades", - "extractFailed": "Extraheringen misslyckades", - "compressFile": "Komprimera fil", - "compressFiles": "Komprimera filer", - "compressFilesDesc": "Komprimera {{count}} objekt till ett arkiv", - "archiveName": "Arkivnamn", - "enterArchiveName": "Ange arkivnamn...", - "compressionFormat": "Komprimeringsformat", - "selectedFiles": "Valda filer", - "andMoreFiles": "och {{count}} mer...", - "compress": "Komprimera", - "compressingFiles": "Komprimerar {{count}} objekt till {{name}}...", - "filesCompressedSuccessfully": "{{name}} skapades", - "compressFailed": "Komprimeringen misslyckades", - "edit": "Redigera", - "preview": "Förhandsvisning", - "previous": "Tidigare", - "next": "Nästa", - "pageXOfY": "Sida {{current}} av {{total}}", - "zoomOut": "Zooma ut", - "zoomIn": "Zooma in", - "newFile": "Ny fil", - "newFolder": "Ny mapp", - "rename": "Döpa om", - "uploading": "Laddar upp...", - "uploadingFile": "Laddar upp {{name}}...", - "fileName": "Filnamn", - "folderName": "Mappnamn", - "fileUploadedSuccessfully": "Filen \"{{name}}\" har laddats upp", - "failedToUploadFile": "Misslyckades med att ladda upp filen", - "uploadingFolderFiles": "Laddar upp {{count}} fil(er)...", - "uploadedFolderFiles": "Uppladdade {{count}} fil(er) framgångsrikt", - "uploadedFolderPartial": "Uppladdade {{uploaded}} fil(er), {{failed}} misslyckades", - "fileDownloadedSuccessfully": "Filen \"{{name}}\" har laddats ner", - "failedToDownloadFile": "Misslyckades med att ladda ner filen", - "fileCreatedSuccessfully": "Filen \"{{name}}\" skapades", - "folderCreatedSuccessfully": "Mappen \"{{name}}\" skapades", - "failedToCreateItem": "Misslyckades med att skapa objektet", - "operationFailed": "{{operation}} -åtgärden misslyckades för {{name}}: {{error}}", - "failedToResolveSymlink": "Misslyckades med att lösa symbolisk länk", - "itemsDeletedSuccessfully": "{{count}} objekt har raderats", - "failedToDeleteItems": "Misslyckades med att ta bort objekt", - "sudoPasswordRequired": "Administratörslösenord krävs", - "enterSudoPassword": "Ange sudo-lösenordet för att fortsätta den här operationen", - "sudoPassword": "Sudo-lösenord", - "sudoOperationFailed": "Sudo-operationen misslyckades", - "sudoAuthFailed": "Sudo-autentisering misslyckades", - "dragFilesToUpload": "Släpp filer här för att ladda upp", - "dropToUploadHere": "Släpp för att ladda upp här", - "dropToDownloadHere": "Släpp för att ladda ner här", - "localFiles": "Lokal", - "showLocalFiles": "Visa lokala filer (delad vy)", - "hideLocalFiles": "Dölj lokala filer", - "localHome": "Hemmappen", - "localPathPlaceholder": "Sökväg till lokal mapp", - "localShowHidden": "Visa dolda filer", - "localHideHidden": "Dölj dolda filer", - "localRevealInFileManager": "Visa i systemets filhanterare", - "localCannotOpenFolder": "Kan inte öppna mappen", - "localItemCount": "{{count}} objekt", - "localSelectedCount": "{{count}} vald", - "back": "Tillbaka", - "forward": "Fram", - "up": "Upp", - "kind": "Slag", - "localUploadingProgress": "Laddar upp {{current}} av {{total}}", - "localDownloadingProgress": "Laddar ner {{current}} av {{total}}", - "localTransferInFlight": "{{count}} på en gång", - "localPreparingDownload": "Förbereder nedladdning...", - "localTransferCancelled": "Överföringen avbruten", - "localNothingToTransfer": "Inget att överföra", - "localUploadComplete": "Uppladdade {{count}} fil(er)", - "localUploadFailed": "Uppladdningen misslyckades", - "localUploadPartial": "Uppladdade {{done}} fil(er), {{failed}} misslyckades", - "localDownloadComplete": "Nedladdade {{count}} fil(er)", - "localDownloadFailed": "Nedladdningen misslyckades", - "localDownloadPartial": "Nedladdning av {{done}} fil(er), {{failed}} misslyckades", - "localReplaceExistingPrompt": "{{count}} objekt finns redan i den här mappen. Vill du ersätta dem?", - "localReplace": "Ersätta", - "localSkipExisting": "Hoppa", - "localSkippedExisting": "Hoppade över {{count}} befintliga objekt", - "localUnsafeNamesSkipped": "Hoppade över {{count}} objekt vars namn inte kan användas på den här datorn", - "localOpen": "Öppna", - "localOpenFolder": "Öppna mappen", - "localUploadToRemote": "Ladda upp till servern", - "localUploadToRemoteMany": "Ladda upp {{count}} objekt till servern", - "localMoveToTrash": "Flytta till papperskorgen", - "localMoveToTrashMany": "Flytta {{count}} objekt till papperskorgen", - "localTrashConfirmSingle": "Flytta \"{{name}}\" till papperskorgen?", - "localTrashConfirmFolder": "Flytta mappen \"{{name}}\" och allt dess innehåll till papperskorgen?", - "localTrashConfirmMany": "Flytta {{count}} objekt till papperskorgen?", - "localTrashed": "Flyttade {{count}} objekt till papperskorgen", - "localTrashFailed": "Kunde inte flytta till papperskorgen", - "localRenameFailed": "Byte av namn misslyckades", - "localCreateFailed": "Kunde inte skapa objektet", - "goToParentFolder": "Gå till överordnad mapp", - "resizeSidebar": "Dra för att ändra storlek på sidofältet (dubbelklicka för att återställa)", - "resizeLocalPane": "Dra för att ändra storlek på den lokala rutan (dubbelklicka för att återställa)", - "columns": "Kolumner", - "columnsHint": "Högerklicka för att välja kolumner", - "emptyFolder": "Den här mappen är tom", - "searchFiles": "Sök filer...", - "upload": "Ladda upp", - "selectHostToStart": "Välj en värd för att starta filhanteringen", - "sshRequiredForFileManager": "Filhanteraren kräver SSH. Den här värden har inte SSH aktiverat.", - "failedToConnect": "Misslyckades med att ansluta till SSH", - "failedToLoadDirectory": "Misslyckades med att ladda katalogen", - "noSSHConnection": "Ingen SSH-anslutning tillgänglig", - "copy": "Kopiera", - "cut": "Skära", - "paste": "Klistra", - "copyPath": "Kopiera sökväg", - "copyPaths": "Kopiera sökvägar", - "delete": "Radera", - "properties": "Fastigheter", - "refresh": "Uppdatera", - "downloadFiles": "Ladda ner {{count}} filer till webbläsaren", - "copyFiles": "Kopiera {{count}} objekt", - "cutFiles": "Klipp ut {{count}} objekt", - "deleteFiles": "Ta bort {{count}} objekt", - "filesCopiedToClipboard": "{{count}} objekt kopierade till urklipp", - "filesCutToClipboard": "{{count}} objekt klippta till urklipp", - "pathCopiedToClipboard": "Sökväg kopierad till urklipp", - "pathsCopiedToClipboard": "{{count}} sökvägar kopierade till urklipp", - "failedToCopyPath": "Misslyckades med att kopiera sökvägen till urklipp", - "copyFolderLink": "Kopiera länk till mapp", - "copyCurrentFolderLink": "Kopiera länk till aktuell mapp", - "folderLinkCopied": "Mapplänk kopierad till urklipp", - "failedToCopyFolderLink": "Misslyckades med att kopiera mapplänken", - "movedItems": "Flyttade {{count}} objekt", - "failedToDeleteItem": "Misslyckades med att ta bort objektet", - "itemRenamedSuccessfully": "{{type}} har bytt namn", - "failedToRenameItem": "Misslyckades med att byta namn på objektet", - "download": "Ladda ner", - "openExternalEditor": "Öppna externt", - "chooseExternalEditor": "Välj extern redigerare", - "externalEditorSelected": "Extern redigerare vald", - "externalEditorDesktopOnly": "Extern redigerare är endast tillgänglig i skrivbordsappen", - "externalEditorOpened": "Öppnad i extern redigerare. Om du sparar där laddas ändringarna upp tillbaka till servern.", - "failedToOpenExternalEditor": "Misslyckades med att öppna den externa redigeraren", - "failedToSelectExternalEditor": "Misslyckades med att välja extern redigerare", - "permissions": "Behörigheter", - "size": "Storlek", - "modified": "Ändrad", - "path": "Väg", - "confirmDelete": "Är du säker på att du vill ta bort {{name}}?", - "permissionDenied": "Tillstånd nekad", - "serverError": "Serverfel", - "fileSavedSuccessfully": "Filen har sparats", - "failedToSaveFile": "Misslyckades med att spara filen", - "confirmDeleteSingleItem": "Är du säker på att du vill ta bort \"{{name}} \" permanent?", - "confirmDeleteMultipleItems": "Är du säker på att du vill ta bort {{count}} objekt permanent?", - "confirmDeleteMultipleItemsWithFolders": "Är du säker på att du vill ta bort {{count}} objekt permanent? Detta inkluderar mappar och deras innehåll.", - "confirmDeleteFolder": "Är du säker på att du vill permanent ta bort mappen \"{{name}}\" och allt dess innehåll?", - "permanentDeleteWarning": "Den här åtgärden kan inte ångras. Objektet/objekten kommer att raderas permanent från servern.", - "moveToTrashWarning": "Objektet/objekten kommer att flyttas till Termix-papperskorgen och kan återställas innan lagringsperioden löper ut.", - "itemsMovedToTrash": "{{count}} objekt flyttade till papperskorgen", - "trash": "Skräp", - "trashDescription": "Borttagna objekt sparas i {{days}} dag(ar) på den här värden.", - "trashLoadFailed": "Misslyckades med att ladda papperskorgen", - "trashEmpty": "Papperskorgen är tom", - "trashRestore": "Återställa", - "trashRestored": "Återställd {{name}}", - "trashRestoreFailed": "Det gick inte att återställa objektet. Den ursprungliga sökvägen kan redan finnas.", - "trashDeletePermanently": "Ta bort permanent", - "trashDeleteConfirm": "Vill du permanent radera {{name}}? Detta kan inte ångras.", - "trashPermanentlyDeleted": "Permanent borttagen {{name}}", - "trashDeleteFailed": "Misslyckades med att ta bort objektet permanent", - "trashEmptyAction": "Töm papperskorgen", - "trashEmptyConfirm": "Vill du permanent radera alla objekt i papperskorgen? Det här kan inte ångras.", - "trashEmptied": "Papperskorgen tömd", - "trashRetention": "Automatisk rensning efter (dagar)", - "trashRetentionSaved": "Papperskorgen har lagrats uppdaterad", - "trashRetentionFailed": "Misslyckades med att uppdatera papperskorgen", - "trashUnavailableConfirm": "Det här objektet kan inte flyttas till papperskorgen, vanligtvis för att det finns på ett annat filsystem eller kräver utökade behörigheter. Vill du ta bort det permanent istället?", - "recent": "Ny", - "pinned": "Fäst", - "folderShortcuts": "Mappgenvägar", - "failedToReconnectSSH": "Misslyckades med att återansluta SSH-sessionen", - "openTerminalHere": "Öppna terminalen här", - "run": "Sikt", - "openTerminalInFolder": "Öppna terminalen i den här mappen", - "openTerminalInFileLocation": "Öppna terminalen på filplatsen", - "runningFile": "Löpning - {{file}}", - "onlyRunExecutableFiles": "Kan bara köra körbara filer", - "directories": "Kataloger", - "removedFromRecentFiles": "Tog bort \"{{name}}\" från senaste filer", - "removeFailed": "Borttagning misslyckades", - "unpinnedSuccessfully": "\"{{name}}\" har lossats", - "unpinFailed": "Misslyckades med att lossa", - "removedShortcut": "Tog bort genvägen \"{{name}}\"", - "removeShortcutFailed": "Misslyckades med att ta bort genvägen", - "clearedAllRecentFiles": "Rensade alla senaste filer", - "clearFailed": "Rensa misslyckades", - "removeFromRecentFiles": "Ta bort från senaste filer", - "clearAllRecentFiles": "Rensa alla senaste filer", - "unpinFile": "Lossa filen", - "removeShortcut": "Ta bort genväg", - "pinFile": "Fäst fil", - "addToShortcuts": "Lägg till i genvägar", - "pasteFailed": "Klistra in misslyckades", - "noUndoableActions": "Inga ångerbara åtgärder", - "undoCopySuccess": "Ångrad kopiering: Raderade {{count}} kopierade filer", - "undoCopyFailedDelete": "Ångra misslyckades: Kunde inte ta bort några kopierade filer", - "undoCopyFailedNoInfo": "Ångra misslyckades: Kunde inte hitta informationen om den kopierade filen", - "undoMoveSuccess": "Ångrade flyttåtgärd: Flyttade {{count}} filer tillbaka till ursprunglig plats", - "undoMoveFailedMove": "Ångra misslyckades: Kunde inte flytta tillbaka några filer", - "undoMoveFailedNoInfo": "Ångra misslyckades: Kunde inte hitta informationen om den flyttade filen", - "undoDeleteNotSupported": "Raderingen kan inte ångras: Filerna har raderats permanent från servern", - "undoTypeNotSupported": "Ångra-åtgärdstypen stöds inte", - "undoOperationFailed": "Ångraåtgärden misslyckades", - "unknownError": "Okänt fel", - "confirm": "Bekräfta", - "find": "Hitta...", - "replace": "Ersätta", - "downloadInstead": "Ladda ner istället", - "keyboardShortcuts": "Kortkommandon", - "searchAndReplace": "Sök och ersätt", - "editing": "Redigering", - "search": "Söka", - "findNext": "Hitta nästa", - "findPrevious": "Hitta föregående", - "save": "Spara", - "selectAll": "Markera alla", - "undo": "Ångra", - "redo": "Göra om", - "moveLineUp": "Flytta upp raden", - "moveLineDown": "Flytta raden nedåt", - "toggleComment": "Växla kommentar", - "autoComplete": "Autoslutför", - "imageLoadError": "Misslyckades med att ladda bilden", - "startTyping": "Börja skriva...", - "unknownSize": "Okänd storlek", - "fileIsEmpty": "Filen är tom", - "largeFileWarning": "Varning för stora filer", - "largeFileWarningDesc": "Den här filen är {{size}} stor, vilket kan orsaka prestandaproblem när den öppnas som text.", - "fileNotFoundAndRemoved": "Filen \"{{name}}\" hittades inte och har tagits bort från senaste/fästa filer", - "failedToLoadFile": "Misslyckades med att ladda filen: {{error}}", - "serverErrorOccurred": "Serverfel uppstod. Försök igen senare.", - "autoSaveFailed": "Automatisk sparning misslyckades", - "fileAutoSaved": "Filen sparades automatiskt", - "moveFileFailed": "Misslyckades med att flytta {{name}}", - "moveOperationFailed": "Flyttoperationen misslyckades", - "canOnlyCompareFiles": "Kan bara jämföra två filer", - "comparingFiles": "Jämför filer: {{file1}} och {{file2}}", - "dragFailed": "Dragningsåtgärden misslyckades", - "filePinnedSuccessfully": "Filen \"{{name}}\" har fästs", - "pinFileFailed": "Misslyckades med att fästa filen", - "fileUnpinnedSuccessfully": "Filen \"{{name}}\" har lossats", - "unpinFileFailed": "Misslyckades med att lossa filen", - "shortcutAddedSuccessfully": "Mappgenvägen \"{{name}}\" har lagts till", - "addShortcutFailed": "Misslyckades med att lägga till genväg", - "operationCompletedSuccessfully": "{{operation}} {{count}} objekt lyckades", - "operationCompleted": "{{operation}} {{count}} objekt", - "downloadFileSuccess": "Filen {{name}} har laddats ner", - "downloadFileFailed": "Nedladdningen misslyckades", - "downloadingFile": "Laddar ner {{name}}…", - "downloadProgressBytes": "{{transferred}} / {{total}}", - "moveTo": "Flytta till {{name}}", - "diffCompareWith": "Differensjämförelse med {{name}}", - "dragOutsideToDownload": "Dra utanför fönstret för att ladda ner ({{count}} filer)", - "newFolderDefault": "Nymapp", - "newFileDefault": "Nyfil.txt", - "successfullyMovedItems": "Flyttade {{count}} objekt till {{target}}", - "move": "Flytta", - "searchInFile": "Sök i filen (Ctrl+F)", - "showKeyboardShortcuts": "Visa kortkommandon", - "decreaseFontSize": "Minska teckenstorleken", - "increaseFontSize": "Öka teckenstorleken", - "startWritingMarkdown": "Börja skriva ditt nedskrivningsinnehåll...", - "loadingFileComparison": "Laddar filjämförelse...", - "reload": "Ladda om", - "compare": "Jämföra", - "sideBySide": "Sida vid sida", - "inline": "Inline", - "fileComparison": "Filjämförelse: {{file1}} vs {{file2}}", - "fileTooLarge": "Filen är för stor: {{error}}", - "sshConnectionFailed": "SSH-anslutningen misslyckades. Kontrollera din anslutning till {{name}} ({{ip}}:{{port}})", - "loadFileFailed": "Misslyckades med att ladda filen: {{error}}", - "connecting": "Ansluter...", - "connectedSuccessfully": "Ansluten", - "totpVerificationFailed": "TOTP-verifiering misslyckades", - "authenticationFailed": "Autentiseringen misslyckades", - "incorrectPassphrase": "Felaktigt lösenord. Försök igen.", - "verificationCodePrompt": "Verifieringskod:", - "changePermissions": "Ändra behörigheter", - "currentPermissions": "Nuvarande behörigheter", - "owner": "Ägare", - "group": "Grupp", - "others": "Andra", - "read": "Läsa", - "write": "Skriva", - "execute": "Utföra", - "permissionsChangedSuccessfully": "Behörigheter har ändrats", - "failedToChangePermissions": "Misslyckades med att ändra behörigheter", - "name": "Namn", - "sortByName": "Namn", - "sortByDate": "Datum ändrat", - "sortBySize": "Storlek", - "ascending": "Stigande", - "descending": "Fallande", - "root": "Rot", - "new": "Ny", - "sortBy": "Sortera efter", - "items": "Föremål", - "selected": "Vald", - "editor": "Redaktör", - "octal": "Oktal", - "storage": "Lagring", - "disk": "Disk", - "used": "Begagnad", - "of": "av", - "toggleSidebar": "Växla sidofält", - "compactLayout": "Använd kompakt layout", - "comfortableLayout": "Använd bekväm layout", - "cannotLoadPdf": "Kan inte ladda PDF-filen", - "pdfLoadError": "Det uppstod ett fel när PDF-filen laddades.", - "loadingPdf": "Laddar PDF...", - "loadingPage": "Laddar sida..." + "nav": { + "files": "Files", + "sftp": "SFTP", + "openFileManager": "Open File Manager" }, - "sftpTransfer": { - "title": "SFTP", - "description": "Överför filer mellan två SSH-värdar.", - "sourceServer": "Källserver", - "destinationServer": "Destinationsserver", - "selectHost": "Välj värd", - "noHostSelected": "Ingen värd vald", - "move": "Flytta", - "copy": "Kopiera", - "upload": "Ladda upp", - "itemsSelected": "{{count}} objekt valt", - "itemsSelected_other": "{{count}} objekt valda", - "ready": "Redo", - "loadingHosts": "Laddar värdar...", - "name": "Namn", - "modified": "Ändrad", - "size": "Storlek", - "noFiles": "Inga filer", - "open": "Öppna", - "up": "Upp", - "refresh": "Uppdatera", - "copyToTarget": "Kopiera till målkatalog", - "rename": "Döpa om", - "delete": "Radera", - "editPermissions": "Redigera behörigheter", - "createNewFolder": "Skapa ny mapp", - "deleteSelectedItems": "Ta bort valda objekt", - "deleteConfirm": "Ta bort {{count}} markerat objekt?", - "deleteConfirm_other": "Ta bort {{count}} markerade objekt?", - "cancel": "Avboka", - "save": "Spara", - "folderCreated": "Mapp skapad", - "itemRenamed": "Artikeln har bytt namn", - "actionFailed": "Åtgärden misslyckades", - "itemsDeleted": "{{count}} objekt borttaget", - "itemsDeleted_other": "{{count}} objekt raderade", - "deleteFailed": "Raderingen misslyckades", - "permissionsUpdated": "Behörigheter uppdaterade", - "noRemoteSessionConnected": "Ingen fjärrsession ansluten", - "failedToListFiles": "Misslyckades med att lista filer", - "failedToRefresh": "Misslyckades med att uppdatera", - "destinationInsideSource": "Destinationen får inte vara inom den valda källsökvägen.", - "sameHostNoOp": "Källa och destination är samma mapp." - }, - "hosts": { - "fileManager": "Filhanteraren", - "tabFiles": "Filer", - "enableFileManagerMonitor": "Aktivera filhanteraren", - "enableFileManagerMonitorDesc": "Bläddra bland och hantera filer på den här värden via SFTP", - "scpLegacyLabel": "SCP Legacy-läge", - "scpLegacyDesc": "Använd äldre filöverföring för servrar som inte stöder SFTP-undersystemet (t.ex. inbäddade eller minimala SSH-servrar).", - "defaultPathLabel": "Standardsökväg", - "fileManagerPathHint": "Katalogen som ska öppnas när filhanteraren startas för den här värden.", - "fileManagerUrlCopied": "Filhanterarens URL kopierad", - "copyFileManagerUrlAction": "Kopiera filhanterarens URL", - "docsLink": "Visa dokument", - "hostNotFound": "Värden hittades inte", - "loadingHost": "Laddar värd..." + "permissions": { + "use": { + "title": "Use file manager", + "description": "Browse, edit and transfer files over SFTP." + } }, "settings": { "host": { "enable": { - "label": "Aktivera filhanteraren" + "label": "Enable File Manager", + "description": "Browse and edit files on this host over SFTP." }, "defaultPath": { - "label": "Standardsökväg" + "label": "Default Path" }, "scpLegacy": { - "label": "SCP Legacy-läge" + "label": "SCP Legacy Mode" } }, "user": { "transferConcurrency": { - "label": "Samtidiga filöverföringar", - "description": "Hur många filer den sida vid sida lokala/fjärrstyrda hanteraren laddar upp eller laddar ner samtidigt. Sänk detta om din server begränsar SFTP-kanaler." + "label": "Simultaneous File Transfers", + "description": "How many files the side by side local/remote manager uploads or downloads at the same time. Lower this if your server limits SFTP channels." + }, + "confirmBeforeTrash": { + "label": "Confirm before moving files to trash", + "description": "Ask before moving remote files to trash. Permanent deletion still requires confirmation." } } }, - "nav": { - "sftp": "SFTP", - "files": "Filer" + "hostCapability": { + "label": "File Manager" + }, + "fileManager": { + "noHostSelected": "No host selected", + "initializingEditor": "Initializing editor...", + "file": "File", + "folder": "Folder", + "uploadFile": "Upload File", + "downloadFile": "Download", + "extractArchive": "Extract Archive", + "extractingArchive": "Extracting {{name}}...", + "archiveExtractedSuccessfully": "{{name}} extracted successfully", + "extractFailed": "Extract failed", + "compressFile": "Compress File", + "compressFiles": "Compress Files", + "compressFilesDesc": "Compress {{count}} items into an archive", + "archiveName": "Archive Name", + "enterArchiveName": "Enter archive name...", + "compressionFormat": "Compression Format", + "selectedFiles": "Selected files", + "andMoreFiles": "and {{count}} more...", + "compress": "Compress", + "compressingFiles": "Compressing {{count}} items into {{name}}...", + "filesCompressedSuccessfully": "{{name}} created successfully", + "compressFailed": "Compression failed", + "edit": "Edit", + "preview": "Preview", + "previous": "Previous", + "next": "Next", + "pageXOfY": "Page {{current}} of {{total}}", + "zoomOut": "Zoom Out", + "zoomIn": "Zoom In", + "newFile": "New File", + "newFolder": "New Folder", + "rename": "Rename", + "uploading": "Uploading...", + "uploadingFile": "Uploading {{name}}...", + "uploadingChunk": "Uploading {{name}}: {{percent}}% (part {{chunk}} of {{total}})", + "fileName": "File Name", + "folderName": "Folder Name", + "fileUploadedSuccessfully": "File \"{{name}}\" uploaded successfully", + "failedToUploadFile": "Failed to upload file", + "uploadingFolderFiles": "Uploading {{count}} file(s)...", + "uploadedFolderFiles": "Uploaded {{count}} file(s) successfully", + "uploadedFolderPartial": "Uploaded {{uploaded}} file(s), {{failed}} failed", + "fileDownloadedSuccessfully": "File \"{{name}}\" downloaded successfully", + "failedToDownloadFile": "Failed to download file", + "fileCreatedSuccessfully": "File \"{{name}}\" created successfully", + "folderCreatedSuccessfully": "Folder \"{{name}}\" created successfully", + "failedToCreateItem": "Failed to create item", + "operationFailed": "{{operation}} operation failed for {{name}}: {{error}}", + "failedToResolveSymlink": "Failed to resolve symlink", + "itemsDeletedSuccessfully": "{{count}} items deleted successfully", + "failedToDeleteItems": "Failed to delete items", + "sudoPasswordRequired": "Administrator Password Required", + "enterSudoPassword": "Enter sudo password to continue this operation", + "sudoPassword": "Sudo password", + "sudoOperationFailed": "Sudo operation failed", + "sudoAuthFailed": "Sudo authentication failed", + "dragFilesToUpload": "Drop files here to upload", + "dropToUploadHere": "Drop to upload here", + "dropToDownloadHere": "Drop to download here", + "localFiles": "Local", + "showLocalFiles": "Show local files (split view)", + "hideLocalFiles": "Hide local files", + "localHome": "Home folder", + "localPathPlaceholder": "Local folder path", + "localShowHidden": "Show hidden files", + "localHideHidden": "Hide hidden files", + "localRevealInFileManager": "Reveal in system file manager", + "localCannotOpenFolder": "Cannot open folder", + "localItemCount": "{{count}} items", + "localSelectedCount": "{{count}} selected", + "back": "Back", + "forward": "Forward", + "up": "Up", + "kind": "Kind", + "localUploadingProgress": "Uploading {{current}} of {{total}}", + "localDownloadingProgress": "Downloading {{current}} of {{total}}", + "localTransferInFlight": "{{count}} at once", + "localPreparingDownload": "Preparing download...", + "localTransferCancelled": "Transfer cancelled", + "localNothingToTransfer": "Nothing to transfer", + "localUploadComplete": "Uploaded {{count}} file(s)", + "localUploadFailed": "Upload failed", + "localUploadPartial": "Uploaded {{done}} file(s), {{failed}} failed", + "localDownloadComplete": "Downloaded {{count}} file(s)", + "localDownloadFailed": "Download failed", + "localDownloadPartial": "Downloaded {{done}} file(s), {{failed}} failed", + "localReplaceExistingPrompt": "{{count}} item(s) already exist in this folder. Replace them?", + "localReplace": "Replace", + "localSkipExisting": "Skip", + "localSkippedExisting": "Skipped {{count}} existing item(s)", + "localUnsafeNamesSkipped": "Skipped {{count}} item(s) whose names cannot be used on this computer", + "localOpen": "Open", + "localOpenFolder": "Open folder", + "localUploadToRemote": "Upload to server", + "localUploadToRemoteMany": "Upload {{count}} items to server", + "localMoveToTrash": "Move to Trash", + "localMoveToTrashMany": "Move {{count}} items to Trash", + "localTrashConfirmSingle": "Move \"{{name}}\" to the Trash?", + "localTrashConfirmFolder": "Move the folder \"{{name}}\" and all its contents to the Trash?", + "localTrashConfirmMany": "Move {{count}} items to the Trash?", + "localTrashed": "Moved {{count}} item(s) to the Trash", + "localTrashFailed": "Could not move to the Trash", + "localRenameFailed": "Rename failed", + "localCreateFailed": "Could not create item", + "goToParentFolder": "Go to parent folder", + "resizeSidebar": "Drag to resize the sidebar (double-click to reset)", + "resizeLocalPane": "Drag to resize the local pane (double-click to reset)", + "columns": "Columns", + "columnsHint": "Right-click to choose columns", + "emptyFolder": "This folder is empty", + "searchFiles": "Search files...", + "upload": "Upload", + "selectHostToStart": "Select a host to start file management", + "sshRequiredForFileManager": "File manager requires SSH. This host does not have SSH enabled.", + "failedToConnect": "Failed to connect to SSH", + "failedToLoadDirectory": "Failed to load directory", + "noSSHConnection": "No SSH connection available", + "copy": "Copy", + "cut": "Cut", + "paste": "Paste", + "copyPath": "Copy Path", + "copyPaths": "Copy Paths", + "delete": "Delete", + "properties": "Properties", + "refresh": "Refresh", + "downloadFiles": "Download {{count}} files to Browser", + "copyFiles": "Copy {{count}} items", + "cutFiles": "Cut {{count}} items", + "deleteFiles": "Delete {{count}} items", + "filesCopiedToClipboard": "{{count}} items copied to clipboard", + "filesCutToClipboard": "{{count}} items cut to clipboard", + "pathCopiedToClipboard": "Path copied to clipboard", + "pathsCopiedToClipboard": "{{count}} paths copied to clipboard", + "failedToCopyPath": "Failed to copy path to clipboard", + "copyFolderLink": "Copy Link to Folder", + "copyCurrentFolderLink": "Copy Link to Current Folder", + "folderLinkCopied": "Folder link copied to clipboard", + "failedToCopyFolderLink": "Failed to copy folder link", + "movedItems": "Moved {{count}} items", + "failedToDeleteItem": "Failed to delete item", + "itemRenamedSuccessfully": "{{type}} renamed successfully", + "failedToRenameItem": "Failed to rename item", + "download": "Download", + "openExternalEditor": "Open externally", + "chooseExternalEditor": "Choose external editor", + "externalEditorSelected": "External editor selected", + "externalEditorDesktopOnly": "External editor is only available in the desktop app", + "externalEditorOpened": "Opened in external editor. Saving there will upload changes back to the server.", + "failedToOpenExternalEditor": "Failed to open external editor", + "failedToSelectExternalEditor": "Failed to select external editor", + "permissions": "Permissions", + "size": "Size", + "modified": "Modified", + "path": "Path", + "confirmDelete": "Are you sure you want to delete {{name}}?", + "permissionDenied": "Permission denied", + "serverError": "Server Error", + "fileSavedSuccessfully": "File saved successfully", + "failedToSaveFile": "Failed to save file", + "confirmDeleteSingleItem": "Are you sure you want to permanently delete \"{{name}}\"?", + "confirmDeleteMultipleItems": "Are you sure you want to permanently delete {{count}} items?", + "confirmDeleteMultipleItemsWithFolders": "Are you sure you want to permanently delete {{count}} items? This includes folders and their contents.", + "confirmDeleteFolder": "Are you sure you want to permanently delete the folder \"{{name}}\" and all its contents?", + "permanentDeleteWarning": "This action cannot be undone. The item(s) will be permanently deleted from the server.", + "moveToTrashWarning": "The item(s) will be moved to the Termix Trash and can be restored before the retention period expires.", + "itemsMovedToTrash": "{{count}} item(s) moved to Trash", + "trash": "Trash", + "trashDescription": "Deleted items are retained for {{days}} day(s) on this host.", + "trashLoadFailed": "Failed to load Trash", + "trashEmpty": "Trash is empty", + "trashRestore": "Restore", + "trashRestored": "Restored {{name}}", + "trashRestoreFailed": "Failed to restore item. The original path may already exist.", + "trashDeletePermanently": "Delete permanently", + "trashDeleteConfirm": "Permanently delete {{name}}? This cannot be undone.", + "trashPermanentlyDeleted": "Permanently deleted {{name}}", + "trashDeleteFailed": "Failed to permanently delete item", + "trashEmptyAction": "Empty Trash", + "trashEmptyConfirm": "Permanently delete every item in Trash? This cannot be undone.", + "trashEmptied": "Trash emptied", + "trashRetention": "Automatic cleanup after (days)", + "trashRetentionSaved": "Trash retention updated", + "trashRetentionFailed": "Failed to update Trash retention", + "trashUnavailableConfirm": "This item cannot be moved to Trash, usually because it is on another filesystem or requires elevated permissions. Delete it permanently instead?", + "recent": "Recent", + "pinned": "Pinned", + "folderShortcuts": "Folder Shortcuts", + "failedToReconnectSSH": "Failed to reconnect SSH session", + "openTerminalHere": "Open Terminal Here", + "run": "Run", + "openTerminalInFolder": "Open Terminal in This Folder", + "openTerminalInFileLocation": "Open Terminal at File Location", + "runningFile": "Running - {{file}}", + "onlyRunExecutableFiles": "Can only run executable files", + "directories": "Directories", + "removedFromRecentFiles": "Removed \"{{name}}\" from recent files", + "removeFailed": "Remove failed", + "unpinnedSuccessfully": "Unpinned \"{{name}}\" successfully", + "unpinFailed": "Unpin failed", + "removedShortcut": "Removed shortcut \"{{name}}\"", + "removeShortcutFailed": "Remove shortcut failed", + "clearedAllRecentFiles": "Cleared all recent files", + "clearFailed": "Clear failed", + "removeFromRecentFiles": "Remove from recent files", + "clearAllRecentFiles": "Clear all recent files", + "unpinFile": "Unpin file", + "removeShortcut": "Remove shortcut", + "pinFile": "Pin file", + "addToShortcuts": "Add to shortcuts", + "pasteFailed": "Paste failed", + "noUndoableActions": "No undoable actions", + "undoCopySuccess": "Undid copy operation: Deleted {{count}} copied files", + "undoCopyFailedDelete": "Undo failed: Could not delete any copied files", + "undoCopyFailedNoInfo": "Undo failed: Could not find copied file information", + "undoMoveSuccess": "Undid move operation: Moved {{count}} files back to original location", + "undoMoveFailedMove": "Undo failed: Could not move any files back", + "undoMoveFailedNoInfo": "Undo failed: Could not find moved file information", + "undoDeleteNotSupported": "Delete operation cannot be undone: Files have been permanently deleted from server", + "undoTypeNotSupported": "Unsupported undo operation type", + "undoOperationFailed": "Undo operation failed", + "unknownError": "Unknown error", + "confirm": "Confirm", + "find": "Find...", + "replace": "Replace", + "downloadInstead": "Download Instead", + "keyboardShortcuts": "Keyboard Shortcuts", + "searchAndReplace": "Search & Replace", + "editing": "Editing", + "search": "Search", + "findNext": "Find Next", + "findPrevious": "Find Previous", + "save": "Save", + "selectAll": "Select All", + "undo": "Undo", + "redo": "Redo", + "moveLineUp": "Move Line Up", + "moveLineDown": "Move Line Down", + "toggleComment": "Toggle Comment", + "autoComplete": "Auto Complete", + "imageLoadError": "Failed to load image", + "startTyping": "Start typing...", + "unknownSize": "Unknown size", + "fileIsEmpty": "File is empty", + "largeFileWarning": "Large File Warning", + "largeFileWarningDesc": "This file is {{size}} in size, which may cause performance issues when opened as text.", + "fileNotFoundAndRemoved": "File \"{{name}}\" not found and has been removed from recent/pinned files", + "failedToLoadFile": "Failed to load file: {{error}}", + "serverErrorOccurred": "Server error occurred. Please try again later.", + "autoSaveFailed": "Auto-save failed", + "fileAutoSaved": "File auto-saved", + "moveFileFailed": "Failed to move {{name}}", + "moveOperationFailed": "Move operation failed", + "canOnlyCompareFiles": "Can only compare two files", + "comparingFiles": "Comparing files: {{file1}} and {{file2}}", + "dragFailed": "Drag operation failed", + "filePinnedSuccessfully": "File \"{{name}}\" pinned successfully", + "pinFileFailed": "Failed to pin file", + "fileUnpinnedSuccessfully": "File \"{{name}}\" unpinned successfully", + "unpinFileFailed": "Failed to unpin file", + "shortcutAddedSuccessfully": "Folder shortcut \"{{name}}\" added successfully", + "addShortcutFailed": "Failed to add shortcut", + "operationCompletedSuccessfully": "{{operation}} {{count}} items successfully", + "operationCompleted": "{{operation}} {{count}} items", + "downloadFileSuccess": "File {{name}} downloaded successfully", + "downloadFileFailed": "Download failed", + "downloadingFile": "Downloading {{name}}…", + "downloadProgressBytes": "{{transferred}} / {{total}}", + "moveTo": "Move to {{name}}", + "diffCompareWith": "Diff compare with {{name}}", + "dragOutsideToDownload": "Drag outside window to download ({{count}} files)", + "newFolderDefault": "NewFolder", + "newFileDefault": "NewFile.txt", + "successfullyMovedItems": "Successfully moved {{count}} items to {{target}}", + "move": "Move", + "searchInFile": "Search in file (Ctrl+F)", + "showKeyboardShortcuts": "Show keyboard shortcuts", + "decreaseFontSize": "Decrease font size", + "increaseFontSize": "Increase font size", + "startWritingMarkdown": "Start writing your markdown content...", + "loadingFileComparison": "Loading file comparison...", + "reload": "Reload", + "compare": "Compare", + "sideBySide": "Side by Side", + "inline": "Inline", + "fileComparison": "File Comparison: {{file1}} vs {{file2}}", + "fileTooLarge": "File too large: {{error}}", + "sshConnectionFailed": "SSH connection failed. Please check your connection to {{name}} ({{ip}}:{{port}})", + "loadFileFailed": "Failed to load file: {{error}}", + "connecting": "Connecting...", + "connectedSuccessfully": "Connected successfully", + "totpVerificationFailed": "TOTP verification failed", + "browserSignInFailed": "Sign-in failed. Please try again.", + "authenticationFailed": "Authentication failed", + "incorrectPassphrase": "Incorrect passphrase. Please try again.", + "verificationCodePrompt": "Verification code:", + "changePermissions": "Change Permissions", + "currentPermissions": "Current Permissions", + "owner": "Owner", + "group": "Group", + "others": "Others", + "read": "Read", + "write": "Write", + "execute": "Execute", + "permissionsChangedSuccessfully": "Permissions changed successfully", + "failedToChangePermissions": "Failed to change permissions", + "name": "Name", + "sortByName": "Name", + "sortByDate": "Date Modified", + "sortBySize": "Size", + "ascending": "Ascending", + "descending": "Descending", + "root": "Root", + "new": "New", + "sortBy": "Sort By", + "items": "Items", + "selected": "Selected", + "editor": "Editor", + "octal": "Octal", + "storage": "Storage", + "disk": "Disk", + "used": "Used", + "of": "of", + "toggleSidebar": "Toggle Sidebar", + "compactLayout": "Use compact layout", + "comfortableLayout": "Use comfortable layout", + "cannotLoadPdf": "Cannot load PDF", + "pdfLoadError": "There was an error loading this PDF file.", + "loadingPdf": "Loading PDF...", + "loadingPage": "Loading page...", + "cancel": "Cancel", + "copiedItems_one": "Copied {{count}} item", + "copiedItems_other": "Copied {{count}} items", + "deleteCopiedFileFailed": "Could not delete the copy of {{name}}: {{error}}", + "dragMovedItems_one": "Moved {{count}} item to {{target}}", + "dragMovedItems_other": "Moved {{count}} items to {{target}}", + "moveBackFileFailed": "Could not move {{name}} back: {{error}}", + "terminal": "Terminal: {{host}} ({{path}})", + "dragToDesktop": "Dragging {{name}} to the desktop", + "dragFilesToDesktop": "Dragging {{count}} files to the desktop", + "folderDragUnsupported": "Dragging folders to the desktop is not supported yet", + "saveToDesktopFailed": "Save failed: {{error}}", + "dragFailedDetail": "Drag failed: {{error}}", + "videoUnsupported": "Your browser cannot play this video format.", + "downloadToPlay": "Download to play it elsewhere", + "cannotPreviewType": "Cannot preview this file type", + "cannotPreviewTypeHint": "This file type has no preview. Download it to open it in another app." + }, + "sftpTransfer": { + "title": "SFTP", + "description": "Transfer files between two SSH hosts.", + "sourceServer": "Source Server", + "destinationServer": "Destination Server", + "selectHost": "Select host", + "noHostSelected": "No host selected", + "move": "Move", + "copy": "Copy", + "upload": "Upload", + "itemsSelected": "{{count}} item selected", + "itemsSelected_other": "{{count}} items selected", + "ready": "Ready", + "loadingHosts": "Loading hosts...", + "name": "Name", + "modified": "Modified", + "size": "Size", + "noFiles": "No files", + "open": "Open", + "up": "Up", + "refresh": "Refresh", + "copyToTarget": "Copy to Target Directory", + "rename": "Rename", + "delete": "Delete", + "editPermissions": "Edit Permissions", + "createNewFolder": "Create New Folder", + "deleteSelectedItems": "Delete Selected Items", + "deleteConfirm": "Delete {{count}} selected item?", + "deleteConfirm_other": "Delete {{count}} selected items?", + "cancel": "Cancel", + "save": "Save", + "folderCreated": "Folder created", + "itemRenamed": "Item renamed", + "actionFailed": "Action failed", + "itemsDeleted": "{{count}} item deleted", + "itemsDeleted_other": "{{count}} items deleted", + "deleteFailed": "Delete failed", + "permissionsUpdated": "Permissions updated", + "noRemoteSessionConnected": "No remote session connected", + "failedToListFiles": "Failed to list files", + "failedToRefresh": "Failed to refresh", + "destinationInsideSource": "Destination cannot be inside the selected source path.", + "sameHostNoOp": "Source and destination are the same folder." + }, + "hosts": { + "fileManager": "File Manager", + "fileManagerUrlCopied": "File Manager URL copied", + "copyFileManagerUrlAction": "Copy File Manager URL", + "docsLink": "View docs", + "hostNotFound": "Host not found", + "loadingHost": "Loading host..." }, "onboarding": { - "feature_files": "Filhanteraren", - "feature_files_desc": "Bläddra, ladda upp, ladda ner och redigera filer via SFTP utan att lämna appen." + "feature_files": "File manager", + "feature_files_desc": "Browse, upload, download and edit files over SFTP without leaving the app." }, "terminal": { - "runTitle": "Kör {{command}} - {{host}}", + "runTitle": "Running {{command}} - {{host}}", "terminalTitle": "Terminal - {{host}}", "terminalWithPath": "Terminal - {{host}}:{{path}}" }, "transfer": { - "browseFolders": "Bläddra bland målmappar", - "browsePathError": "Kunde inte öppna den här sökvägen på målvärden.", - "browsePathWillBeCreated": "Den här mappen finns inte ännu. Den kommer att skapas när överföringen startar.", - "cancel": "Avboka", - "cleanupDestFiles": "Städa upp destinationen", - "cleanupDestFilesError": "Rensningen misslyckades", - "cleanupDestFilesNothing": "Inget att städa upp på destinationen", - "cleanupDestFilesPartial": "Vissa delfiler kunde inte tas bort", - "cleanupDestFilesSuccess": "Tog bort delvisa filer från destinationen", - "confirmCopy": "Kopiera", - "confirmMove": "Flytta", - "copyFolderToHost": "Kopiera mapp till värden…", - "copyItemsToHost": "Kopiera {{count}} objekt till…", - "copyToHost": "Kopiera till värd…", - "destinationPath": "Destinationsväg", - "destMustBeDirectory": "Destinationen måste vara en katalog för överföringar av flera objekt", - "goUp": "Gå upp", - "hostAuthRequired": "Autentisering krävs — öppna filhanteraren på den här värden först", - "hostConnecting": "Ansluter…", - "hostConnectionFailed": "Anslutningen misslyckades", - "hostDisconnected": "Inte ansluten", - "hostReady": "Redo", - "itemsSummary": "{{count}} objekt", - "jumpHostLimitation": "Båda värdarna måste vara nåbara från Termix-servern. Direkt routing mellan värdar stöds inte.", - "methodAuto": "Bil", - "methodAutoHint": "Väljer tar eller SFTP per fil baserat på filantal, storlek och komprimerbarhet. Enstaka filer använder alltid strömmande SFTP.", - "methodItemSftp": "SFTP per fil", - "methodItemSftpHint": "Överför varje fil individuellt via SFTP. Fungerar på alla värdar inklusive Windows.", - "methodItemSftpLimitation": "Varje fil använder samma SFTP-ström som en kopia av en enda fil, en efter en. Förloppet kombineras över alla filer, så stapeln rör sig långsamt vid stora filer.", - "methodLabel": "Överföringsmetod", - "methodPreviewError": "Kunde inte förhandsgranska överföringsmetoden. Servern kommer fortfarande att välja en metod när du startar.", - "methodPreviewLoading": "Beräkning av överföringsmetod…", - "methodPreviewScanSummary": "{{fileCount}} filer, {{totalSize}} totalt (skannat på källvärd).", - "methodPreviewWillUseItemSftp": "Kommer att använda: SFTP per fil", - "methodPreviewWillUseTar": "Kommer att använda: Tar-arkiv", + "browseFolders": "Browse destination folders", + "browsePathError": "Could not open this path on the destination host.", + "browsePathWillBeCreated": "This folder does not exist yet. It will be created when the transfer starts.", + "cancel": "Cancel", + "cleanupDestFiles": "Clean up destination", + "cleanupDestFilesError": "Cleanup failed", + "cleanupDestFilesNothing": "Nothing to clean up on the destination", + "cleanupDestFilesPartial": "Some partial files could not be removed", + "cleanupDestFilesSuccess": "Removed partial files from the destination", + "confirmCopy": "Copy", + "confirmMove": "Move", + "copyFolderToHost": "Copy folder to host…", + "copyItemsToHost": "Copy {{count}} items to host…", + "copyToHost": "Copy to host…", + "destinationPath": "Destination path", + "destMustBeDirectory": "Destination must be a directory for multi-item transfers", + "goUp": "Go up", + "hostAuthRequired": "Authentication required. Open File Manager on this host first", + "hostConnecting": "Connecting…", + "hostConnectionFailed": "Connection failed", + "hostDisconnected": "Not connected", + "hostReady": "Ready", + "itemsSummary": "{{count}} items", + "jumpHostLimitation": "Both hosts must be reachable from the Termix server. Direct host-to-host routing is not supported.", + "methodAuto": "Auto", + "methodAutoHint": "Picks tar or per-file SFTP based on file count, size, and compressibility. Single files always use streaming SFTP.", + "methodItemSftp": "Per-file SFTP", + "methodItemSftpHint": "Transfer each file individually over SFTP. Works on all hosts including Windows.", + "methodItemSftpLimitation": "Each file uses the same SFTP stream as a single-file copy, one after another. Progress is combined across all files, so the bar moves slowly during large files.", + "methodLabel": "Transfer method", + "methodPreviewError": "Could not preview transfer method. The server will still pick a method when you start.", + "methodPreviewLoading": "Calculating transfer method…", + "methodPreviewScanSummary": "{{fileCount}} files, {{totalSize}} total (scanned on source host).", + "methodPreviewWillUseItemSftp": "Will use: Per-file SFTP", + "methodPreviewWillUseTar": "Will use: Tar archive", "methodReason": { - "user_item_sftp": "Du valde SFTP per fil.", - "user_tar": "Du valde tar-arkivet.", - "tar_unavailable": "Tar är inte tillgängligt på en eller båda värdarna — SFTP per fil kommer att användas istället.", - "windows_host": "En Windows-värd är inblandad — tar används inte.", - "auto_multi_large": "Auto: flera filer inklusive en stor fil ({{largestSize}}) med komprimerbar data — tar-paket samlas i en överföring.", - "auto_single_large_in_archive": "Auto: en stor fil ({{largestSize}}) i denna uppsättning — SFTP per fil.", - "auto_many_incompressible": "Auto: mestadels inkomprimerbar data — SFTP per fil.", - "auto_many_files": "Auto: många filer ({{fileCount}}) — tar minskar overhead per fil.", - "auto_default": "Auto: SFTP per fil för den här uppsättningen." + "user_item_sftp": "You chose per-file SFTP.", + "user_tar": "You chose tar archive.", + "tar_unavailable": "Tar is not available on one or both hosts, so per-file SFTP will be used instead.", + "windows_host": "A Windows host is involved, so tar is not used.", + "auto_multi_large": "Auto: multiple files including a large file ({{largestSize}}) with compressible data. Tar bundles them into one transfer.", + "auto_single_large_in_archive": "Auto: one large file ({{largestSize}}) in this set, so per-file SFTP.", + "auto_many_incompressible": "Auto: mostly incompressible data, so per-file SFTP.", + "auto_many_files": "Auto: many files ({{fileCount}}), tar cuts the per-file overhead.", + "auto_default": "Auto: per-file SFTP for this set." }, - "methodTar": "Tar-arkiv", - "methodTarHint": "Komprimera vid källan, överför ett arkiv, extrahera vid destinationen. Kräver tar på båda Unix-värdarna.", - "metricsCompress": "Komprimera på källan: {{duration}}", - "metricsExtract": "Extrahera på destination: {{duration}}", - "metricsPrepare": "Förbered destination: {{duration}}", - "metricsRouteBenchmark": "Ruttsond — direkt: {{direct}}, relä: {{relay}}", - "metricsSourceDelete": "Ta bort från källan: {{duration}}", - "metricsTotal": "Totalt: {{duration}}", - "metricsTransfer": "Från slut till slut: {{throughput}} ({{duration}})", - "metricsVerify": "SHA-256 verifierad: {{duration}}", - "moveFolderToHost": "Flytta mappen till värden…", - "moveItemsToHost": "Flytta {{count}} objekt till…", - "moveToHost": "Flytta till värd…", - "noHostsConnected": "Inga andra filhanterarvärdar tillgängliga.", - "noHostsConnectedHint": "Lägg till en annan SSH-värd med Filhanteraren aktiverad i Värdhanteraren.", - "parallelSegmentsHint": "Stora filer delas upp i bitar på 256 MB. Flera filer använder separata anslutningar (som att starta flera överföringar) för högre total dataflöde.", - "parallelSegmentsLabel": "Parallella överföringsfält", - "parallelSegmentsOption": "{{count}} körfält", - "progressBenchmarking": "Välja den snabbaste bytesvägen…", + "methodTar": "Tar archive", + "methodTarHint": "Compress on source, transfer one archive, extract on destination. Requires tar on both Unix hosts.", + "metricsCompress": "Compress on source: {{duration}}", + "metricsExtract": "Extract on destination: {{duration}}", + "metricsPrepare": "Prepare destination: {{duration}}", + "metricsRouteBenchmark": "Route probe: direct {{direct}}, relay {{relay}}", + "metricsSourceDelete": "Remove from source: {{duration}}", + "metricsTotal": "Total: {{duration}}", + "metricsTransfer": "End-to-end: {{throughput}} ({{duration}})", + "metricsVerify": "SHA-256 verified: {{duration}}", + "moveFolderToHost": "Move folder to host…", + "moveItemsToHost": "Move {{count}} items to host…", + "moveToHost": "Move to host…", + "noHostsConnected": "No other file-manager hosts available.", + "noHostsConnectedHint": "Add another SSH host with File Manager enabled in Host Manager.", + "parallelSegmentsHint": "Large files are split into 256 MB chunks. Multiple lanes use separate connections (like starting several transfers) for higher total throughput.", + "parallelSegmentsLabel": "Parallel transfer lanes", + "parallelSegmentsOption": "{{count}} lanes", + "progressBenchmarking": "Selecting the fastest transfer route…", "progressBytes": "{{transferred}} / {{total}}", - "progressCancel": "Avboka", - "progressCancelling": "Avbryter…", - "progressCompressing": "Komprimering på källvärd…", - "progressExtracting": "Extraherar på destination…", - "progressItems": "{{current}} / {{total}} filer", - "progressReconnecting": "Återansluter…", - "progressStalled": "Stannade", - "progressTotalSpeed": "{{speed}} totalt ({{lanes}} körfält)", - "progressTransferring": "Överför data…", - "progressTransferringItems": "Överföra filer ({{current}} av {{total}})…", - "progressVerifying": "Verifierar filintegritet…", - "recentDestinations": "Senaste destinationerna", - "resumedHint": "Återansluten till en aktiv överföring som startade i ett annat fönster.", - "retryTransfer": "Försöka igen", - "retryTransferError": "Återförsök misslyckades", - "selectDestinationHost": "Välj destinationsvärd", - "transferCancelled": "Överföringen avbruten", - "transferCancelledCopyHint": "Delvisa filer kan finnas kvar på destinationen.", - "transferCancelledMoveHint": "Delvisa filer kan finnas kvar på destinationen. Källfilerna togs inte bort.", - "transferError": "Överföringen misslyckades", - "transferFailedRetryHint": "Delvis data sparades på destinationen. Försöket återupptas när anslutningen är tillbaka.", - "transferPartialHint": "Kunde inte överföra: {{paths}}", - "transferSuccess": "Överföringen är klar" + "progressCancel": "Cancel", + "progressCancelling": "Cancelling…", + "progressCompressing": "Compressing on source host…", + "progressExtracting": "Extracting on destination…", + "progressItems": "{{current}} / {{total}} files", + "progressReconnecting": "Reconnecting…", + "progressStalled": "Stalled", + "progressTotalSpeed": "{{speed}} total ({{lanes}} lanes)", + "progressTransferring": "Transferring data…", + "progressTransferringItems": "Transferring files ({{current}} of {{total}})…", + "progressVerifying": "Verifying file integrity…", + "recentDestinations": "Recent destinations", + "resumedHint": "Reconnected to an active transfer started in another window.", + "retryTransfer": "Retry", + "retryTransferError": "Retry failed", + "selectDestinationHost": "Select destination host", + "transferCancelled": "Transfer cancelled", + "transferCancelledCopyHint": "Partial files may remain on the destination.", + "transferCancelledMoveHint": "Partial files may remain on the destination. Source files were not removed.", + "transferError": "Transfer failed", + "transferFailedRetryHint": "Partial data was kept on the destination. Retry will resume when the connection is back.", + "transferPartialHint": "Could not transfer: {{paths}}", + "transferSuccess": "Transfer complete", + "metricsHopSourceRead": "Source → server: {{throughput}}", + "metricsHopDestSftpWrite": "Server → dest (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Server → dest (local): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/th_TH.json b/plugins/file-manager/locales/translated/th_TH.json index 0324499b0..dc86761ce 100644 --- a/plugins/file-manager/locales/translated/th_TH.json +++ b/plugins/file-manager/locales/translated/th_TH.json @@ -1,513 +1,543 @@ { - "fileManager": { - "noHostSelected": "ไม่ได้เลือกโฮสต์", - "initializingEditor": "กำลังเริ่มต้นโปรแกรมแก้ไข...", - "file": "ไฟล์", - "folder": "โฟลเดอร์", - "uploadFile": "อัปโหลดไฟล์", - "downloadFile": "ดาวน์โหลด", - "extractArchive": "แตกไฟล์เก็บถาวร", - "extractingArchive": "กำลังดึงข้อมูล {{name}}...", - "archiveExtractedSuccessfully": "{{name}} ดึงข้อมูลสำเร็จแล้ว", - "extractFailed": "การดึงข้อมูลล้มเหลว", - "compressFile": "บีบอัดไฟล์", - "compressFiles": "บีบอัดไฟล์", - "compressFilesDesc": "บีบอัดรายการ {{count}} รายการลงในไฟล์เก็บถาวร", - "archiveName": "ชื่อไฟล์เก็บถาวร", - "enterArchiveName": "ป้อนชื่อไฟล์เก็บถาวร...", - "compressionFormat": "รูปแบบการบีบอัด", - "selectedFiles": "ไฟล์ที่เลือก", - "andMoreFiles": "และ {{count}} เพิ่มเติม...", - "compress": "บีบอัด", - "compressingFiles": "บีบอัดรายการ {{count}} รายการลงใน {{name}} รายการ ...", - "filesCompressedSuccessfully": "{{name}} สร้างสำเร็จแล้ว", - "compressFailed": "การบีบอัดล้มเหลว", - "edit": "แก้ไข", - "preview": "ตัวอย่าง", - "previous": "ก่อนหน้า", - "next": "ต่อไป", - "pageXOfY": "หน้า {{current}} จาก {{total}}", - "zoomOut": "ซูมออก", - "zoomIn": "ซูมเข้า", - "newFile": "ไฟล์ใหม่", - "newFolder": "โฟลเดอร์ใหม่", - "rename": "เปลี่ยนชื่อ", - "uploading": "กำลังอัปโหลด...", - "uploadingFile": "กำลังอัปโหลด {{name}}...", - "fileName": "ชื่อไฟล์", - "folderName": "ชื่อโฟลเดอร์", - "fileUploadedSuccessfully": "ไฟล์ \"{{name}}\" อัปโหลดสำเร็จแล้ว", - "failedToUploadFile": "ไม่สามารถอัปโหลดไฟล์ได้", - "uploadingFolderFiles": "กำลังอัปโหลดไฟล์ {{count}} ไฟล์...", - "uploadedFolderFiles": "อัปโหลดไฟล์ {{count}} ไฟล์สำเร็จแล้ว", - "uploadedFolderPartial": "อัปโหลดไฟล์ {{uploaded}} ไฟล์, {{failed}} ล้มเหลว", - "fileDownloadedSuccessfully": "ดาวน์โหลดไฟล์ \"{{name}}\" สำเร็จแล้ว", - "failedToDownloadFile": "ไม่สามารถดาวน์โหลดไฟล์ได้", - "fileCreatedSuccessfully": "สร้างไฟล์ \"{{name}}\" สำเร็จแล้ว", - "folderCreatedSuccessfully": "สร้างโฟลเดอร์ \"{{name}}\" สำเร็จแล้ว", - "failedToCreateItem": "ไม่สามารถสร้างรายการได้", - "operationFailed": "การดำเนินการ {{operation}} ล้มเหลวสำหรับ {{name}}: {{error}}", - "failedToResolveSymlink": "ไม่สามารถแก้ไขลิงก์สัญลักษณ์ได้", - "itemsDeletedSuccessfully": "รายการ {{count}} ถูกลบสำเร็จแล้ว", - "failedToDeleteItems": "ไม่สามารถลบรายการได้", - "sudoPasswordRequired": "ต้องใช้รหัสผ่านผู้ดูแลระบบ", - "enterSudoPassword": "ป้อนรหัสผ่าน sudo เพื่อดำเนินการต่อ", - "sudoPassword": "รหัสผ่าน Sudo", - "sudoOperationFailed": "การดำเนินการ Sudo ล้มเหลว", - "sudoAuthFailed": "การตรวจสอบสิทธิ์ Sudo ล้มเหลว", - "dragFilesToUpload": "ลากไฟล์มาวางที่นี่เพื่ออัปโหลด", - "dropToUploadHere": "ลากเส้นเพื่ออัปโหลดที่นี่", - "dropToDownloadHere": "คลิกที่นี่เพื่อดาวน์โหลด", - "localFiles": "ท้องถิ่น", - "showLocalFiles": "แสดงไฟล์ในเครื่อง (มุมมองแบบแบ่งหน้าจอ)", - "hideLocalFiles": "ซ่อนไฟล์ในเครื่อง", - "localHome": "โฟลเดอร์บ้าน", - "localPathPlaceholder": "เส้นทางโฟลเดอร์ในเครื่อง", - "localShowHidden": "แสดงไฟล์ที่ซ่อนอยู่", - "localHideHidden": "ซ่อนไฟล์ที่ซ่อนไว้", - "localRevealInFileManager": "เปิดเผยในตัวจัดการไฟล์ระบบ", - "localCannotOpenFolder": "ไม่สามารถเปิดโฟลเดอร์ได้", - "localItemCount": "{{count}} รายการ", - "localSelectedCount": "{{count}} เลือกแล้ว", - "back": "กลับ", - "forward": "ซึ่งไปข้างหน้า", - "up": "ขึ้น", - "kind": "ใจดี", - "localUploadingProgress": "กำลังอัปโหลด {{current}} จาก {{total}}", - "localDownloadingProgress": "กำลังดาวน์โหลด {{current}} จาก {{total}}", - "localTransferInFlight": "{{count}} ทันที", - "localPreparingDownload": "กำลังเตรียมดาวน์โหลด...", - "localTransferCancelled": "การโอนเงินถูกยกเลิก", - "localNothingToTransfer": "ไม่มีอะไรต้องโอน", - "localUploadComplete": "อัปโหลดไฟล์ {{count}} ไฟล์แล้ว", - "localUploadFailed": "การอัปโหลดล้มเหลว", - "localUploadPartial": "อัปโหลดไฟล์ {{done}} ไฟล์, {{failed}} ล้มเหลว", - "localDownloadComplete": "ดาวน์โหลดไฟล์ {{count}} ไฟล์แล้ว", - "localDownloadFailed": "การดาวน์โหลดล้มเหลว", - "localDownloadPartial": "ดาวน์โหลดไฟล์ {{done}} ไฟล์, {{failed}} ไฟล์ล้มเหลว", - "localReplaceExistingPrompt": "{{count}} รายการมีอยู่แล้วในโฟลเดอร์นี้ ต้องการแทนที่หรือไม่?", - "localReplace": "แทนที่", - "localSkipExisting": "ข้าม", - "localSkippedExisting": "ข้ามรายการที่มีอยู่ {{count}} รายการ", - "localUnsafeNamesSkipped": "ข้ามรายการ {{count}} รายการ เนื่องจากไม่สามารถใช้ชื่อรายการดังกล่าวในคอมพิวเตอร์เครื่องนี้ได้", - "localOpen": "เปิด", - "localOpenFolder": "เปิดโฟลเดอร์", - "localUploadToRemote": "อัปโหลดไปยังเซิร์ฟเวอร์", - "localUploadToRemoteMany": "อัปโหลด {{count}} รายการไปยังเซิร์ฟเวอร์", - "localMoveToTrash": "ย้ายไปที่ถังขยะ", - "localMoveToTrashMany": "ย้ายรายการ {{count}} รายการไปยังถังขยะ", - "localTrashConfirmSingle": "ย้าย \"{{name}}\" ไปที่ถังขยะ?", - "localTrashConfirmFolder": "ย้ายโฟลเดอร์ \"{{name}}\" และเนื้อหาทั้งหมดไปที่ถังขยะ?", - "localTrashConfirmMany": "ย้ายรายการ {{count}} รายการไปยังถังขยะหรือไม่?", - "localTrashed": "ย้ายรายการ {{count}} รายการไปยังถังขยะ", - "localTrashFailed": "ไม่สามารถย้ายไปถังขยะได้", - "localRenameFailed": "การเปลี่ยนชื่อล้มเหลว", - "localCreateFailed": "ไม่สามารถสร้างรายการได้", - "goToParentFolder": "ไปที่โฟลเดอร์หลัก", - "resizeSidebar": "ลากเพื่อปรับขนาดแถบด้านข้าง (ดับเบิ้ลคลิกเพื่อรีเซ็ต)", - "resizeLocalPane": "ลากเพื่อปรับขนาดบานหน้าต่างเฉพาะที่ (ดับเบิ้ลคลิกเพื่อรีเซ็ต)", - "columns": "คอลัมน์", - "columnsHint": "คลิกขวาเพื่อเลือกคอลัมน์", - "emptyFolder": "โฟลเดอร์นี้ว่างเปล่า", - "searchFiles": "ค้นหาไฟล์...", - "upload": "อัปโหลด", - "selectHostToStart": "เลือกโฮสต์เพื่อเริ่มการจัดการไฟล์", - "sshRequiredForFileManager": "โปรแกรมจัดการไฟล์ต้องการการเชื่อมต่อ SSH แต่เครื่องนี้ไม่ได้เปิดใช้งาน SSH", - "failedToConnect": "ไม่สามารถเชื่อมต่อ SSH ได้", - "failedToLoadDirectory": "ไม่สามารถโหลดไดเร็กทอรีได้", - "noSSHConnection": "ไม่มีการเชื่อมต่อ SSH ให้ใช้งาน", - "copy": "สำเนา", - "cut": "ตัด", - "paste": "แปะ", - "copyPath": "คัดลอกเส้นทาง", - "copyPaths": "คัดลอกเส้นทาง", - "delete": "ลบ", - "properties": "คุณสมบัติ", - "refresh": "รีเฟรช", - "downloadFiles": "ดาวน์โหลดไฟล์ {{count}} ไปยังเบราว์เซอร์", - "copyFiles": "คัดลอกรายการ {{count}} รายการ", - "cutFiles": "ตัด {{count}} รายการ", - "deleteFiles": "ลบรายการ {{count}} รายการ", - "filesCopiedToClipboard": "{{count}} รายการที่คัดลอกไปยังคลิปบอร์ด", - "filesCutToClipboard": "{{count}} รายการที่ถูกตัดไปยังคลิปบอร์ด", - "pathCopiedToClipboard": "คัดลอกเส้นทางไปยังคลิปบอร์ดแล้ว", - "pathsCopiedToClipboard": "{{count}} คัดลอกเส้นทางไปยังคลิปบอร์ดแล้ว", - "failedToCopyPath": "ไม่สามารถคัดลอกเส้นทางไปยังคลิปบอร์ดได้", - "copyFolderLink": "คัดลink ไปยังโฟลเดอร์", - "copyCurrentFolderLink": "คัดลink ไปยังโฟลเดอร์ปัจจุบัน", - "folderLinkCopied": "คัดลอกลิงก์โฟลเดอร์ไปยังคลิปบอร์ดแล้ว", - "failedToCopyFolderLink": "ไม่สามารถคัดลอกลิงก์โฟลเดอร์ได้", - "movedItems": "ย้ายรายการ {{count}} รายการ", - "failedToDeleteItem": "ไม่สามารถลบรายการได้", - "itemRenamedSuccessfully": "{{type}} เปลี่ยนชื่อสำเร็จแล้ว", - "failedToRenameItem": "ไม่สามารถเปลี่ยนชื่อรายการได้", - "download": "ดาวน์โหลด", - "openExternalEditor": "เปิดจากภายนอก", - "chooseExternalEditor": "เลือกตัวแก้ไขภายนอก", - "externalEditorSelected": "เลือกบรรณาธิการภายนอก", - "externalEditorDesktopOnly": "โปรแกรมแก้ไขภายนอกใช้งานได้เฉพาะในแอปพลิเคชันบนเดสก์ท็อปเท่านั้น", - "externalEditorOpened": "เปิดในโปรแกรมแก้ไขภายนอก การบันทึกในโปรแกรมแก้ไขนั้นจะอัปโหลดการเปลี่ยนแปลงกลับไปยังเซิร์ฟเวอร์", - "failedToOpenExternalEditor": "ไม่สามารถเปิดโปรแกรมแก้ไขภายนอกได้", - "failedToSelectExternalEditor": "ไม่สามารถเลือกตัวแก้ไขภายนอกได้", - "permissions": "สิทธิ์การเข้าถึง", - "size": "ขนาด", - "modified": "แก้ไขแล้ว", - "path": "เส้นทาง", - "confirmDelete": "คุณแน่ใจหรือไม่ว่าต้องการลบ {{name}}?", - "permissionDenied": "ไม่ได้รับอนุญาต", - "serverError": "ข้อผิดพลาดของเซิร์ฟเวอร์", - "fileSavedSuccessfully": "บันทึกไฟล์สำเร็จแล้ว", - "failedToSaveFile": "ไม่สามารถบันทึกไฟล์ได้", - "confirmDeleteSingleItem": "คุณแน่ใจหรือไม่ว่าต้องการลบ \"{{name}} \" อย่างถาวร?", - "confirmDeleteMultipleItems": "คุณแน่ใจหรือไม่ว่าต้องการลบรายการ {{count}} อย่างถาวร?", - "confirmDeleteMultipleItemsWithFolders": "คุณแน่ใจหรือไม่ว่าต้องการลบรายการ {{count}} รายการอย่างถาวร ซึ่งรวมถึงโฟลเดอร์และเนื้อหาภายในด้วย", - "confirmDeleteFolder": "คุณแน่ใจหรือไม่ว่าต้องการลบโฟลเดอร์ \"{{name}}\" และเนื้อหาทั้งหมดในนั้นอย่างถาวร?", - "permanentDeleteWarning": "การดำเนินการนี้ไม่สามารถยกเลิกได้ รายการดังกล่าวจะถูกลบออกจากเซิร์ฟเวอร์อย่างถาวร", - "moveToTrashWarning": "ไฟล์ดังกล่าวจะถูกย้ายไปยังถังขยะของ Termix และสามารถกู้คืนได้ก่อนที่ระยะเวลาการเก็บรักษาจะหมดลง", - "itemsMovedToTrash": "{{count}} รายการถูกย้ายไปยังถังขยะ", - "trash": "ขยะ", - "trashDescription": "รายการที่ถูกลบจะยังคงอยู่เป็นเวลา {{days}} วันบนโฮสต์นี้", - "trashLoadFailed": "ไม่สามารถโหลดถังขยะได้", - "trashEmpty": "ถังขยะว่างเปล่า", - "trashRestore": "คืนค่า", - "trashRestored": "กู้คืนแล้ว {{name}}", - "trashRestoreFailed": "ไม่สามารถกู้คืนรายการได้ เส้นทางเดิมอาจมีอยู่แล้ว", - "trashDeletePermanently": "ลบอย่างถาวร", - "trashDeleteConfirm": "ลบ {{name}}อย่างถาวรหรือไม่? การดำเนินการนี้ไม่สามารถย้อนกลับได้", - "trashPermanentlyDeleted": "ลบถาวร {{name}}", - "trashDeleteFailed": "ไม่สามารถลบรายการอย่างถาวรได้", - "trashEmptyAction": "ขยะทิ้ง", - "trashEmptyConfirm": "ต้องการลบทุกอย่างในถังขยะอย่างถาวรหรือไม่? การกระทำนี้ไม่สามารถย้อนกลับได้", - "trashEmptied": "ขยะถูกเก็บแล้ว", - "trashRetention": "ล้างข้อมูลอัตโนมัติหลังจาก (วัน)", - "trashRetentionSaved": "การปรับปรุงการเก็บรักษาขยะ", - "trashRetentionFailed": "ไม่สามารถอัปเดตการเก็บรักษาข้อมูลถังขยะได้", - "trashUnavailableConfirm": "ไม่สามารถย้ายรายการนี้ไปยังถังขยะได้ เนื่องจากไฟล์นี้อยู่ในระบบไฟล์อื่น หรือต้องใช้สิทธิ์ระดับสูง ต้องการลบอย่างถาวรแทนหรือไม่?", - "recent": "ล่าสุด", - "pinned": "ปักหมุด", - "folderShortcuts": "ทางลัดโฟลเดอร์", - "failedToReconnectSSH": "ไม่สามารถเชื่อมต่อเซสชัน SSH ใหม่ได้", - "openTerminalHere": "เปิดเทอร์มินัลที่นี่", - "run": "วิ่ง", - "openTerminalInFolder": "เปิดเทอร์มินัลในโฟลเดอร์นี้", - "openTerminalInFileLocation": "เปิดเทอร์มินัลที่ตำแหน่งไฟล์", - "runningFile": "การวิ่ง - {{file}}", - "onlyRunExecutableFiles": "สามารถเรียกใช้งานได้เฉพาะไฟล์ปฏิบัติการเท่านั้น", - "directories": "รายชื่อ", - "removedFromRecentFiles": "ลบ \"{{name}}\" ออกจากไฟล์ล่าสุดแล้ว", - "removeFailed": "ลบสิ่งที่ล้มเหลว", - "unpinnedSuccessfully": "ยกเลิกการตรึง \"{{name}}\" สำเร็จแล้ว", - "unpinFailed": "ยกเลิกการตรึงไม่สำเร็จ", - "removedShortcut": "ลบทางลัด \"{{name}} \" ออกแล้ว", - "removeShortcutFailed": "การลบทางลัดล้มเหลว", - "clearedAllRecentFiles": "ลบไฟล์ล่าสุดทั้งหมดแล้ว", - "clearFailed": "เคลียร์ล้มเหลว", - "removeFromRecentFiles": "ลบออกจากไฟล์ล่าสุด", - "clearAllRecentFiles": "ลบไฟล์ล่าสุดทั้งหมด", - "unpinFile": "ยกเลิกการตรึงไฟล์", - "removeShortcut": "ลบทางลัด", - "pinFile": "ไฟล์พิน", - "addToShortcuts": "เพิ่มไปยังทางลัด", - "pasteFailed": "การวางล้มเหลว", - "noUndoableActions": "ไม่มีการกระทำใดที่ย้อนกลับไม่ได้", - "undoCopySuccess": "ยกเลิกการคัดลอก: ลบไฟล์ที่คัดลอก {{count}} ไฟล์", - "undoCopyFailedDelete": "การยกเลิกการกระทำล้มเหลว: ไม่สามารถลบไฟล์ที่คัดลอกไว้ได้", - "undoCopyFailedNoInfo": "การยกเลิกการกระทำล้มเหลว: ไม่พบข้อมูลไฟล์ที่คัดลอกไว้", - "undoMoveSuccess": "ยกเลิกการย้าย: ย้ายไฟล์ {{count}} ไฟล์กลับไปยังตำแหน่งเดิม", - "undoMoveFailedMove": "การยกเลิกไม่สำเร็จ: ไม่สามารถย้ายไฟล์ใดๆ กลับได้", - "undoMoveFailedNoInfo": "การยกเลิกไม่สำเร็จ: ไม่พบข้อมูลไฟล์ที่ถูกย้าย", - "undoDeleteNotSupported": "ไม่สามารถยกเลิกการลบได้: ไฟล์ถูกลบออกจากเซิร์ฟเวอร์อย่างถาวรแล้ว", - "undoTypeNotSupported": "ประเภทการดำเนินการยกเลิกที่ไม่รองรับ", - "undoOperationFailed": "การยกเลิกการดำเนินการล้มเหลว", - "unknownError": "ข้อผิดพลาดที่ไม่ทราบสาเหตุ", - "confirm": "ยืนยัน", - "find": "หา...", - "replace": "แทนที่", - "downloadInstead": "ดาวน์โหลดแทน", - "keyboardShortcuts": "แป้นพิมพ์ลัด", - "searchAndReplace": "ค้นหาและแทนที่", - "editing": "การแก้ไข", - "search": "ค้นหา", - "findNext": "ค้นหาถัดไป", - "findPrevious": "ค้นหาก่อนหน้า", - "save": "บันทึก", - "selectAll": "เลือกทั้งหมด", - "undo": "เลิกทำ", - "redo": "ทำซ้ำ", - "moveLineUp": "เคลื่อนแถว", - "moveLineDown": "เลื่อนเส้นลง", - "toggleComment": "สลับการแสดงความคิดเห็น", - "autoComplete": "การเติมข้อความอัตโนมัติ", - "imageLoadError": "ไม่สามารถโหลดรูปภาพได้", - "startTyping": "เริ่มพิมพ์...", - "unknownSize": "ขนาดไม่ทราบแน่ชัด", - "fileIsEmpty": "ไฟล์ว่างเปล่า", - "largeFileWarning": "คำเตือนเกี่ยวกับไฟล์ขนาดใหญ่", - "largeFileWarningDesc": "ไฟล์นี้มีขนาด {{size}} ซึ่งอาจทำให้เกิดปัญหาด้านประสิทธิภาพเมื่อเปิดเป็นข้อความ", - "fileNotFoundAndRemoved": "ไม่พบไฟล์ \"{{name}}\" และไฟล์ดังกล่าวถูกลบออกจากไฟล์ล่าสุด/ไฟล์ปักหมุดแล้ว", - "failedToLoadFile": "ไม่สามารถโหลดไฟล์ได้: {{error}}", - "serverErrorOccurred": "เกิดข้อผิดพลาดของเซิร์ฟเวอร์ โปรดลองใหม่อีกครั้งในภายหลัง", - "autoSaveFailed": "การบันทึกอัตโนมัติล้มเหลว", - "fileAutoSaved": "ไฟล์ถูกบันทึกอัตโนมัติ", - "moveFileFailed": "การย้ายล้มเหลว {{name}}", - "moveOperationFailed": "การดำเนินการย้ายล้มเหลว", - "canOnlyCompareFiles": "สามารถเปรียบเทียบไฟล์ได้เพียงสองไฟล์เท่านั้น", - "comparingFiles": "เปรียบเทียบไฟล์: {{file1}} และ {{file2}}", - "dragFailed": "การดำเนินการลากล้มเหลว", - "filePinnedSuccessfully": "ไฟล์ \"{{name}}\" ถูกปักหมุดสำเร็จแล้ว", - "pinFileFailed": "ไม่สามารถตรึงไฟล์ได้", - "fileUnpinnedSuccessfully": "ไฟล์ \"{{name}}\" ถูกยกเลิกการตรึงสำเร็จแล้ว", - "unpinFileFailed": "ไม่สามารถยกเลิกการตรึงไฟล์ได้", - "shortcutAddedSuccessfully": "เพิ่มทางลัดโฟลเดอร์ \"{{name}}\" สำเร็จแล้ว", - "addShortcutFailed": "ไม่สามารถเพิ่มทางลัดได้", - "operationCompletedSuccessfully": "{{operation}} {{count}} รายการสำเร็จ", - "operationCompleted": "{{operation}} {{count}} รายการ", - "downloadFileSuccess": "ดาวน์โหลดไฟล์ {{name}} สำเร็จแล้ว", - "downloadFileFailed": "การดาวน์โหลดล้มเหลว", - "downloadingFile": "กำลังดาวน์โหลด {{name}}…", - "downloadProgressBytes": "{{transferred}} / {{total}}", - "moveTo": "ย้ายไปที่ {{name}}", - "diffCompareWith": "เปรียบเทียบความแตกต่างกับ {{name}}", - "dragOutsideToDownload": "ลากออกนอกหน้าต่างเพื่อดาวน์โหลดไฟล์ ({{count}} ไฟล์)", - "newFolderDefault": "โฟลเดอร์ใหม่", - "newFileDefault": "ไฟล์ใหม่.txt", - "successfullyMovedItems": "ย้ายรายการ {{count}} รายการไปยัง {{target}} สำเร็จแล้ว", - "move": "เคลื่อนไหว", - "searchInFile": "ค้นหาในไฟล์ (Ctrl+F)", - "showKeyboardShortcuts": "แสดงทางลัดแป้นพิมพ์", - "decreaseFontSize": "ลดขนาดตัวอักษร", - "increaseFontSize": "เพิ่มขนาดตัวอักษร", - "startWritingMarkdown": "เริ่มเขียนเนื้อหา Markdown ของคุณได้เลย...", - "loadingFileComparison": "กำลังโหลดการเปรียบเทียบไฟล์...", - "reload": "โหลดซ้ำ", - "compare": "เปรียบเทียบ", - "sideBySide": "เคียงข้างกัน", - "inline": "อินไลน์", - "fileComparison": "การเปรียบเทียบไฟล์: {{file1}} กับ {{file2}}", - "fileTooLarge": "ไฟล์มีขนาดใหญ่เกินไป: {{error}}", - "sshConnectionFailed": "การเชื่อมต่อ SSH ล้มเหลว โปรดตรวจสอบการเชื่อมต่อของคุณกับ {{name}} ({{ip}}:{{port}})", - "loadFileFailed": "ไม่สามารถโหลดไฟล์ได้: {{error}}", - "connecting": "กำลังเชื่อมต่อ...", - "connectedSuccessfully": "เชื่อมต่อสำเร็จแล้ว", - "totpVerificationFailed": "การตรวจสอบ TOTP ล้มเหลว", - "authenticationFailed": "การตรวจสอบสิทธิ์ล้มเหลว", - "incorrectPassphrase": "รหัสผ่านไม่ถูกต้อง โปรดลองอีกครั้ง", - "verificationCodePrompt": "รหัสยืนยัน:", - "changePermissions": "เปลี่ยนสิทธิ์การเข้าถึง", - "currentPermissions": "สิทธิ์การเข้าถึงปัจจุบัน", - "owner": "เจ้าของ", - "group": "กลุ่ม", - "others": "คนอื่น", - "read": "อ่าน", - "write": "เขียน", - "execute": "ดำเนินการ", - "permissionsChangedSuccessfully": "สิทธิ์การเข้าถึงเปลี่ยนแปลงสำเร็จแล้ว", - "failedToChangePermissions": "ไม่สามารถเปลี่ยนสิทธิ์ได้", - "name": "ชื่อ", - "sortByName": "ชื่อ", - "sortByDate": "วันที่แก้ไข", - "sortBySize": "ขนาด", - "ascending": "ขึ้นไป", - "descending": "ลง", - "root": "ราก", - "new": "ใหม่", - "sortBy": "เรียงลำดับตาม", - "items": "รายการ", - "selected": "เลือกแล้ว", - "editor": "บรรณาธิการ", - "octal": "แปด", - "storage": "พื้นที่จัดเก็บ", - "disk": "ดิสก์", - "used": "ใช้แล้ว", - "of": "ของ", - "toggleSidebar": "สลับแถบด้านข้าง", - "compactLayout": "ใช้รูปแบบการจัดวางที่กะทัดรัด", - "comfortableLayout": "ใช้รูปแบบการจัดวางที่สะดวกสบาย", - "cannotLoadPdf": "ไม่สามารถโหลดไฟล์ PDF ได้", - "pdfLoadError": "เกิดข้อผิดพลาดในการโหลดไฟล์ PDF นี้", - "loadingPdf": "กำลังโหลดไฟล์ PDF...", - "loadingPage": "กำลังโหลดหน้าเว็บ..." + "nav": { + "files": "Files", + "sftp": "SFTP", + "openFileManager": "Open File Manager" }, - "sftpTransfer": { - "title": "เอสเอฟทีพี", - "description": "โอนไฟล์ระหว่างโฮสต์ SSH สองเครื่อง", - "sourceServer": "เซิร์ฟเวอร์ต้นทาง", - "destinationServer": "เซิร์ฟเวอร์ปลายทาง", - "selectHost": "เลือกโฮสต์", - "noHostSelected": "ไม่ได้เลือกโฮสต์", - "move": "เคลื่อนไหว", - "copy": "สำเนา", - "upload": "อัปโหลด", - "itemsSelected": "{{count}} รายการที่เลือก", - "itemsSelected_other": "รายการที่เลือก {{count}} รายการ", - "ready": "พร้อม", - "loadingHosts": "กำลังโหลดโฮสต์...", - "name": "ชื่อ", - "modified": "แก้ไขแล้ว", - "size": "ขนาด", - "noFiles": "ไม่มีไฟล์", - "open": "เปิด", - "up": "ขึ้น", - "refresh": "รีเฟรช", - "copyToTarget": "คัดลอกไปยังไดเร็กทอรีเป้าหมาย", - "rename": "เปลี่ยนชื่อ", - "delete": "ลบ", - "editPermissions": "แก้ไขสิทธิ์การเข้าถึง", - "createNewFolder": "สร้างโฟลเดอร์ใหม่", - "deleteSelectedItems": "ลบรายการที่เลือก", - "deleteConfirm": "ลบรายการที่เลือก {{count}} รายการหรือไม่?", - "deleteConfirm_other": "ลบรายการที่เลือก {{count}} รายการหรือไม่?", - "cancel": "ยกเลิก", - "save": "บันทึก", - "folderCreated": "สร้างโฟลเดอร์แล้ว", - "itemRenamed": "เปลี่ยนชื่อรายการ", - "actionFailed": "การดำเนินการล้มเหลว", - "itemsDeleted": "{{count}} รายการถูกลบ", - "itemsDeleted_other": "รายการที่ถูกลบ {{count}} รายการ", - "deleteFailed": "การลบล้มเหลว", - "permissionsUpdated": "สิทธิ์การเข้าถึงได้รับการอัปเดตแล้ว", - "noRemoteSessionConnected": "ไม่มีการเชื่อมต่อเซสชันระยะไกล", - "failedToListFiles": "ไม่สามารถแสดงรายการไฟล์ได้", - "failedToRefresh": "ไม่สามารถรีเฟรชได้", - "destinationInsideSource": "ปลายทางต้องไม่อยู่ภายในเส้นทางต้นทางที่เลือกไว้", - "sameHostNoOp": "ต้นทางและปลายทางเป็นโฟลเดอร์เดียวกัน" - }, - "hosts": { - "fileManager": "ตัวจัดการไฟล์", - "tabFiles": "ไฟล์", - "enableFileManagerMonitor": "เปิดใช้งานตัวจัดการไฟล์", - "enableFileManagerMonitorDesc": "เรียกดูและจัดการไฟล์บนโฮสต์นี้ผ่านทาง SFTP", - "scpLegacyLabel": "โหมด SCP ดั้งเดิม", - "scpLegacyDesc": "สำหรับเซิร์ฟเวอร์ที่ไม่รองรับระบบย่อย SFTP (เช่น เซิร์ฟเวอร์ SSH แบบฝังตัวหรือแบบขั้นต่ำ) ให้ใช้การถ่ายโอนไฟล์แบบเดิม", - "defaultPathLabel": "เส้นทางเริ่มต้น", - "fileManagerPathHint": "โฟลเดอร์ที่จะเปิดเมื่อโปรแกรมจัดการไฟล์เริ่มทำงานสำหรับโฮสต์นี้", - "fileManagerUrlCopied": "คัดลอก URL ของตัวจัดการไฟล์แล้ว", - "copyFileManagerUrlAction": "คัดลอก URL ของตัวจัดการไฟล์", - "docsLink": "ดูเอกสาร", - "hostNotFound": "ไม่พบโฮสต์", - "loadingHost": "กำลังโหลดโฮสต์..." + "permissions": { + "use": { + "title": "Use file manager", + "description": "Browse, edit and transfer files over SFTP." + } }, "settings": { "host": { "enable": { - "label": "เปิดใช้งานตัวจัดการไฟล์" + "label": "Enable File Manager", + "description": "Browse and edit files on this host over SFTP." }, "defaultPath": { - "label": "เส้นทางเริ่มต้น" + "label": "Default Path" }, "scpLegacy": { - "label": "โหมด SCP ดั้งเดิม" + "label": "SCP Legacy Mode" } }, "user": { "transferConcurrency": { - "label": "การโอนไฟล์พร้อมกัน", - "description": "ตัวจัดการไฟล์แบบโลคอล/รีโมตที่ทำงานควบคู่กันไป สามารถอัปโหลดหรือดาวน์โหลดไฟล์ได้พร้อมกันกี่ไฟล์ ลดจำนวนไฟล์นี้ลงหากเซิร์ฟเวอร์ของคุณจำกัดจำนวนช่อง SFTP" + "label": "Simultaneous File Transfers", + "description": "How many files the side by side local/remote manager uploads or downloads at the same time. Lower this if your server limits SFTP channels." + }, + "confirmBeforeTrash": { + "label": "Confirm before moving files to trash", + "description": "Ask before moving remote files to trash. Permanent deletion still requires confirmation." } } }, - "nav": { - "sftp": "เอสเอฟทีพี", - "files": "ไฟล์" + "hostCapability": { + "label": "File Manager" + }, + "fileManager": { + "noHostSelected": "No host selected", + "initializingEditor": "Initializing editor...", + "file": "File", + "folder": "Folder", + "uploadFile": "Upload File", + "downloadFile": "Download", + "extractArchive": "Extract Archive", + "extractingArchive": "Extracting {{name}}...", + "archiveExtractedSuccessfully": "{{name}} extracted successfully", + "extractFailed": "Extract failed", + "compressFile": "Compress File", + "compressFiles": "Compress Files", + "compressFilesDesc": "Compress {{count}} items into an archive", + "archiveName": "Archive Name", + "enterArchiveName": "Enter archive name...", + "compressionFormat": "Compression Format", + "selectedFiles": "Selected files", + "andMoreFiles": "and {{count}} more...", + "compress": "Compress", + "compressingFiles": "Compressing {{count}} items into {{name}}...", + "filesCompressedSuccessfully": "{{name}} created successfully", + "compressFailed": "Compression failed", + "edit": "Edit", + "preview": "Preview", + "previous": "Previous", + "next": "Next", + "pageXOfY": "Page {{current}} of {{total}}", + "zoomOut": "Zoom Out", + "zoomIn": "Zoom In", + "newFile": "New File", + "newFolder": "New Folder", + "rename": "Rename", + "uploading": "Uploading...", + "uploadingFile": "Uploading {{name}}...", + "uploadingChunk": "Uploading {{name}}: {{percent}}% (part {{chunk}} of {{total}})", + "fileName": "File Name", + "folderName": "Folder Name", + "fileUploadedSuccessfully": "File \"{{name}}\" uploaded successfully", + "failedToUploadFile": "Failed to upload file", + "uploadingFolderFiles": "Uploading {{count}} file(s)...", + "uploadedFolderFiles": "Uploaded {{count}} file(s) successfully", + "uploadedFolderPartial": "Uploaded {{uploaded}} file(s), {{failed}} failed", + "fileDownloadedSuccessfully": "File \"{{name}}\" downloaded successfully", + "failedToDownloadFile": "Failed to download file", + "fileCreatedSuccessfully": "File \"{{name}}\" created successfully", + "folderCreatedSuccessfully": "Folder \"{{name}}\" created successfully", + "failedToCreateItem": "Failed to create item", + "operationFailed": "{{operation}} operation failed for {{name}}: {{error}}", + "failedToResolveSymlink": "Failed to resolve symlink", + "itemsDeletedSuccessfully": "{{count}} items deleted successfully", + "failedToDeleteItems": "Failed to delete items", + "sudoPasswordRequired": "Administrator Password Required", + "enterSudoPassword": "Enter sudo password to continue this operation", + "sudoPassword": "Sudo password", + "sudoOperationFailed": "Sudo operation failed", + "sudoAuthFailed": "Sudo authentication failed", + "dragFilesToUpload": "Drop files here to upload", + "dropToUploadHere": "Drop to upload here", + "dropToDownloadHere": "Drop to download here", + "localFiles": "Local", + "showLocalFiles": "Show local files (split view)", + "hideLocalFiles": "Hide local files", + "localHome": "Home folder", + "localPathPlaceholder": "Local folder path", + "localShowHidden": "Show hidden files", + "localHideHidden": "Hide hidden files", + "localRevealInFileManager": "Reveal in system file manager", + "localCannotOpenFolder": "Cannot open folder", + "localItemCount": "{{count}} items", + "localSelectedCount": "{{count}} selected", + "back": "Back", + "forward": "Forward", + "up": "Up", + "kind": "Kind", + "localUploadingProgress": "Uploading {{current}} of {{total}}", + "localDownloadingProgress": "Downloading {{current}} of {{total}}", + "localTransferInFlight": "{{count}} at once", + "localPreparingDownload": "Preparing download...", + "localTransferCancelled": "Transfer cancelled", + "localNothingToTransfer": "Nothing to transfer", + "localUploadComplete": "Uploaded {{count}} file(s)", + "localUploadFailed": "Upload failed", + "localUploadPartial": "Uploaded {{done}} file(s), {{failed}} failed", + "localDownloadComplete": "Downloaded {{count}} file(s)", + "localDownloadFailed": "Download failed", + "localDownloadPartial": "Downloaded {{done}} file(s), {{failed}} failed", + "localReplaceExistingPrompt": "{{count}} item(s) already exist in this folder. Replace them?", + "localReplace": "Replace", + "localSkipExisting": "Skip", + "localSkippedExisting": "Skipped {{count}} existing item(s)", + "localUnsafeNamesSkipped": "Skipped {{count}} item(s) whose names cannot be used on this computer", + "localOpen": "Open", + "localOpenFolder": "Open folder", + "localUploadToRemote": "Upload to server", + "localUploadToRemoteMany": "Upload {{count}} items to server", + "localMoveToTrash": "Move to Trash", + "localMoveToTrashMany": "Move {{count}} items to Trash", + "localTrashConfirmSingle": "Move \"{{name}}\" to the Trash?", + "localTrashConfirmFolder": "Move the folder \"{{name}}\" and all its contents to the Trash?", + "localTrashConfirmMany": "Move {{count}} items to the Trash?", + "localTrashed": "Moved {{count}} item(s) to the Trash", + "localTrashFailed": "Could not move to the Trash", + "localRenameFailed": "Rename failed", + "localCreateFailed": "Could not create item", + "goToParentFolder": "Go to parent folder", + "resizeSidebar": "Drag to resize the sidebar (double-click to reset)", + "resizeLocalPane": "Drag to resize the local pane (double-click to reset)", + "columns": "Columns", + "columnsHint": "Right-click to choose columns", + "emptyFolder": "This folder is empty", + "searchFiles": "Search files...", + "upload": "Upload", + "selectHostToStart": "Select a host to start file management", + "sshRequiredForFileManager": "File manager requires SSH. This host does not have SSH enabled.", + "failedToConnect": "Failed to connect to SSH", + "failedToLoadDirectory": "Failed to load directory", + "noSSHConnection": "No SSH connection available", + "copy": "Copy", + "cut": "Cut", + "paste": "Paste", + "copyPath": "Copy Path", + "copyPaths": "Copy Paths", + "delete": "Delete", + "properties": "Properties", + "refresh": "Refresh", + "downloadFiles": "Download {{count}} files to Browser", + "copyFiles": "Copy {{count}} items", + "cutFiles": "Cut {{count}} items", + "deleteFiles": "Delete {{count}} items", + "filesCopiedToClipboard": "{{count}} items copied to clipboard", + "filesCutToClipboard": "{{count}} items cut to clipboard", + "pathCopiedToClipboard": "Path copied to clipboard", + "pathsCopiedToClipboard": "{{count}} paths copied to clipboard", + "failedToCopyPath": "Failed to copy path to clipboard", + "copyFolderLink": "Copy Link to Folder", + "copyCurrentFolderLink": "Copy Link to Current Folder", + "folderLinkCopied": "Folder link copied to clipboard", + "failedToCopyFolderLink": "Failed to copy folder link", + "movedItems": "Moved {{count}} items", + "failedToDeleteItem": "Failed to delete item", + "itemRenamedSuccessfully": "{{type}} renamed successfully", + "failedToRenameItem": "Failed to rename item", + "download": "Download", + "openExternalEditor": "Open externally", + "chooseExternalEditor": "Choose external editor", + "externalEditorSelected": "External editor selected", + "externalEditorDesktopOnly": "External editor is only available in the desktop app", + "externalEditorOpened": "Opened in external editor. Saving there will upload changes back to the server.", + "failedToOpenExternalEditor": "Failed to open external editor", + "failedToSelectExternalEditor": "Failed to select external editor", + "permissions": "Permissions", + "size": "Size", + "modified": "Modified", + "path": "Path", + "confirmDelete": "Are you sure you want to delete {{name}}?", + "permissionDenied": "Permission denied", + "serverError": "Server Error", + "fileSavedSuccessfully": "File saved successfully", + "failedToSaveFile": "Failed to save file", + "confirmDeleteSingleItem": "Are you sure you want to permanently delete \"{{name}}\"?", + "confirmDeleteMultipleItems": "Are you sure you want to permanently delete {{count}} items?", + "confirmDeleteMultipleItemsWithFolders": "Are you sure you want to permanently delete {{count}} items? This includes folders and their contents.", + "confirmDeleteFolder": "Are you sure you want to permanently delete the folder \"{{name}}\" and all its contents?", + "permanentDeleteWarning": "This action cannot be undone. The item(s) will be permanently deleted from the server.", + "moveToTrashWarning": "The item(s) will be moved to the Termix Trash and can be restored before the retention period expires.", + "itemsMovedToTrash": "{{count}} item(s) moved to Trash", + "trash": "Trash", + "trashDescription": "Deleted items are retained for {{days}} day(s) on this host.", + "trashLoadFailed": "Failed to load Trash", + "trashEmpty": "Trash is empty", + "trashRestore": "Restore", + "trashRestored": "Restored {{name}}", + "trashRestoreFailed": "Failed to restore item. The original path may already exist.", + "trashDeletePermanently": "Delete permanently", + "trashDeleteConfirm": "Permanently delete {{name}}? This cannot be undone.", + "trashPermanentlyDeleted": "Permanently deleted {{name}}", + "trashDeleteFailed": "Failed to permanently delete item", + "trashEmptyAction": "Empty Trash", + "trashEmptyConfirm": "Permanently delete every item in Trash? This cannot be undone.", + "trashEmptied": "Trash emptied", + "trashRetention": "Automatic cleanup after (days)", + "trashRetentionSaved": "Trash retention updated", + "trashRetentionFailed": "Failed to update Trash retention", + "trashUnavailableConfirm": "This item cannot be moved to Trash, usually because it is on another filesystem or requires elevated permissions. Delete it permanently instead?", + "recent": "Recent", + "pinned": "Pinned", + "folderShortcuts": "Folder Shortcuts", + "failedToReconnectSSH": "Failed to reconnect SSH session", + "openTerminalHere": "Open Terminal Here", + "run": "Run", + "openTerminalInFolder": "Open Terminal in This Folder", + "openTerminalInFileLocation": "Open Terminal at File Location", + "runningFile": "Running - {{file}}", + "onlyRunExecutableFiles": "Can only run executable files", + "directories": "Directories", + "removedFromRecentFiles": "Removed \"{{name}}\" from recent files", + "removeFailed": "Remove failed", + "unpinnedSuccessfully": "Unpinned \"{{name}}\" successfully", + "unpinFailed": "Unpin failed", + "removedShortcut": "Removed shortcut \"{{name}}\"", + "removeShortcutFailed": "Remove shortcut failed", + "clearedAllRecentFiles": "Cleared all recent files", + "clearFailed": "Clear failed", + "removeFromRecentFiles": "Remove from recent files", + "clearAllRecentFiles": "Clear all recent files", + "unpinFile": "Unpin file", + "removeShortcut": "Remove shortcut", + "pinFile": "Pin file", + "addToShortcuts": "Add to shortcuts", + "pasteFailed": "Paste failed", + "noUndoableActions": "No undoable actions", + "undoCopySuccess": "Undid copy operation: Deleted {{count}} copied files", + "undoCopyFailedDelete": "Undo failed: Could not delete any copied files", + "undoCopyFailedNoInfo": "Undo failed: Could not find copied file information", + "undoMoveSuccess": "Undid move operation: Moved {{count}} files back to original location", + "undoMoveFailedMove": "Undo failed: Could not move any files back", + "undoMoveFailedNoInfo": "Undo failed: Could not find moved file information", + "undoDeleteNotSupported": "Delete operation cannot be undone: Files have been permanently deleted from server", + "undoTypeNotSupported": "Unsupported undo operation type", + "undoOperationFailed": "Undo operation failed", + "unknownError": "Unknown error", + "confirm": "Confirm", + "find": "Find...", + "replace": "Replace", + "downloadInstead": "Download Instead", + "keyboardShortcuts": "Keyboard Shortcuts", + "searchAndReplace": "Search & Replace", + "editing": "Editing", + "search": "Search", + "findNext": "Find Next", + "findPrevious": "Find Previous", + "save": "Save", + "selectAll": "Select All", + "undo": "Undo", + "redo": "Redo", + "moveLineUp": "Move Line Up", + "moveLineDown": "Move Line Down", + "toggleComment": "Toggle Comment", + "autoComplete": "Auto Complete", + "imageLoadError": "Failed to load image", + "startTyping": "Start typing...", + "unknownSize": "Unknown size", + "fileIsEmpty": "File is empty", + "largeFileWarning": "Large File Warning", + "largeFileWarningDesc": "This file is {{size}} in size, which may cause performance issues when opened as text.", + "fileNotFoundAndRemoved": "File \"{{name}}\" not found and has been removed from recent/pinned files", + "failedToLoadFile": "Failed to load file: {{error}}", + "serverErrorOccurred": "Server error occurred. Please try again later.", + "autoSaveFailed": "Auto-save failed", + "fileAutoSaved": "File auto-saved", + "moveFileFailed": "Failed to move {{name}}", + "moveOperationFailed": "Move operation failed", + "canOnlyCompareFiles": "Can only compare two files", + "comparingFiles": "Comparing files: {{file1}} and {{file2}}", + "dragFailed": "Drag operation failed", + "filePinnedSuccessfully": "File \"{{name}}\" pinned successfully", + "pinFileFailed": "Failed to pin file", + "fileUnpinnedSuccessfully": "File \"{{name}}\" unpinned successfully", + "unpinFileFailed": "Failed to unpin file", + "shortcutAddedSuccessfully": "Folder shortcut \"{{name}}\" added successfully", + "addShortcutFailed": "Failed to add shortcut", + "operationCompletedSuccessfully": "{{operation}} {{count}} items successfully", + "operationCompleted": "{{operation}} {{count}} items", + "downloadFileSuccess": "File {{name}} downloaded successfully", + "downloadFileFailed": "Download failed", + "downloadingFile": "Downloading {{name}}…", + "downloadProgressBytes": "{{transferred}} / {{total}}", + "moveTo": "Move to {{name}}", + "diffCompareWith": "Diff compare with {{name}}", + "dragOutsideToDownload": "Drag outside window to download ({{count}} files)", + "newFolderDefault": "NewFolder", + "newFileDefault": "NewFile.txt", + "successfullyMovedItems": "Successfully moved {{count}} items to {{target}}", + "move": "Move", + "searchInFile": "Search in file (Ctrl+F)", + "showKeyboardShortcuts": "Show keyboard shortcuts", + "decreaseFontSize": "Decrease font size", + "increaseFontSize": "Increase font size", + "startWritingMarkdown": "Start writing your markdown content...", + "loadingFileComparison": "Loading file comparison...", + "reload": "Reload", + "compare": "Compare", + "sideBySide": "Side by Side", + "inline": "Inline", + "fileComparison": "File Comparison: {{file1}} vs {{file2}}", + "fileTooLarge": "File too large: {{error}}", + "sshConnectionFailed": "SSH connection failed. Please check your connection to {{name}} ({{ip}}:{{port}})", + "loadFileFailed": "Failed to load file: {{error}}", + "connecting": "Connecting...", + "connectedSuccessfully": "Connected successfully", + "totpVerificationFailed": "TOTP verification failed", + "browserSignInFailed": "Sign-in failed. Please try again.", + "authenticationFailed": "Authentication failed", + "incorrectPassphrase": "Incorrect passphrase. Please try again.", + "verificationCodePrompt": "Verification code:", + "changePermissions": "Change Permissions", + "currentPermissions": "Current Permissions", + "owner": "Owner", + "group": "Group", + "others": "Others", + "read": "Read", + "write": "Write", + "execute": "Execute", + "permissionsChangedSuccessfully": "Permissions changed successfully", + "failedToChangePermissions": "Failed to change permissions", + "name": "Name", + "sortByName": "Name", + "sortByDate": "Date Modified", + "sortBySize": "Size", + "ascending": "Ascending", + "descending": "Descending", + "root": "Root", + "new": "New", + "sortBy": "Sort By", + "items": "Items", + "selected": "Selected", + "editor": "Editor", + "octal": "Octal", + "storage": "Storage", + "disk": "Disk", + "used": "Used", + "of": "of", + "toggleSidebar": "Toggle Sidebar", + "compactLayout": "Use compact layout", + "comfortableLayout": "Use comfortable layout", + "cannotLoadPdf": "Cannot load PDF", + "pdfLoadError": "There was an error loading this PDF file.", + "loadingPdf": "Loading PDF...", + "loadingPage": "Loading page...", + "cancel": "Cancel", + "copiedItems_one": "Copied {{count}} item", + "copiedItems_other": "Copied {{count}} items", + "deleteCopiedFileFailed": "Could not delete the copy of {{name}}: {{error}}", + "dragMovedItems_one": "Moved {{count}} item to {{target}}", + "dragMovedItems_other": "Moved {{count}} items to {{target}}", + "moveBackFileFailed": "Could not move {{name}} back: {{error}}", + "terminal": "Terminal: {{host}} ({{path}})", + "dragToDesktop": "Dragging {{name}} to the desktop", + "dragFilesToDesktop": "Dragging {{count}} files to the desktop", + "folderDragUnsupported": "Dragging folders to the desktop is not supported yet", + "saveToDesktopFailed": "Save failed: {{error}}", + "dragFailedDetail": "Drag failed: {{error}}", + "videoUnsupported": "Your browser cannot play this video format.", + "downloadToPlay": "Download to play it elsewhere", + "cannotPreviewType": "Cannot preview this file type", + "cannotPreviewTypeHint": "This file type has no preview. Download it to open it in another app." + }, + "sftpTransfer": { + "title": "SFTP", + "description": "Transfer files between two SSH hosts.", + "sourceServer": "Source Server", + "destinationServer": "Destination Server", + "selectHost": "Select host", + "noHostSelected": "No host selected", + "move": "Move", + "copy": "Copy", + "upload": "Upload", + "itemsSelected": "{{count}} item selected", + "itemsSelected_other": "{{count}} items selected", + "ready": "Ready", + "loadingHosts": "Loading hosts...", + "name": "Name", + "modified": "Modified", + "size": "Size", + "noFiles": "No files", + "open": "Open", + "up": "Up", + "refresh": "Refresh", + "copyToTarget": "Copy to Target Directory", + "rename": "Rename", + "delete": "Delete", + "editPermissions": "Edit Permissions", + "createNewFolder": "Create New Folder", + "deleteSelectedItems": "Delete Selected Items", + "deleteConfirm": "Delete {{count}} selected item?", + "deleteConfirm_other": "Delete {{count}} selected items?", + "cancel": "Cancel", + "save": "Save", + "folderCreated": "Folder created", + "itemRenamed": "Item renamed", + "actionFailed": "Action failed", + "itemsDeleted": "{{count}} item deleted", + "itemsDeleted_other": "{{count}} items deleted", + "deleteFailed": "Delete failed", + "permissionsUpdated": "Permissions updated", + "noRemoteSessionConnected": "No remote session connected", + "failedToListFiles": "Failed to list files", + "failedToRefresh": "Failed to refresh", + "destinationInsideSource": "Destination cannot be inside the selected source path.", + "sameHostNoOp": "Source and destination are the same folder." + }, + "hosts": { + "fileManager": "File Manager", + "fileManagerUrlCopied": "File Manager URL copied", + "copyFileManagerUrlAction": "Copy File Manager URL", + "docsLink": "View docs", + "hostNotFound": "Host not found", + "loadingHost": "Loading host..." }, "onboarding": { - "feature_files": "ตัวจัดการไฟล์", - "feature_files_desc": "เรียกดู อัปโหลด ดาวน์โหลด และแก้ไขไฟล์ผ่าน SFTP โดยไม่ต้องออกจากแอปพลิเคชัน" + "feature_files": "File manager", + "feature_files_desc": "Browse, upload, download and edit files over SFTP without leaving the app." }, "terminal": { - "runTitle": "กำลังวิ่ง {{command}} - {{host}}", - "terminalTitle": "เทอร์มินัล - {{host}}", - "terminalWithPath": "เทอร์มินัล - {{host}}:{{path}}" + "runTitle": "Running {{command}} - {{host}}", + "terminalTitle": "Terminal - {{host}}", + "terminalWithPath": "Terminal - {{host}}:{{path}}" }, "transfer": { - "browseFolders": "เรียกดูโฟลเดอร์ปลายทาง", - "browsePathError": "ไม่สามารถเปิดเส้นทางนี้บนโฮสต์ปลายทางได้", - "browsePathWillBeCreated": "โฟลเดอร์นี้ยังไม่มีอยู่ จะถูกสร้างขึ้นเมื่อการถ่ายโอนเริ่มต้นขึ้น", - "cancel": "ยกเลิก", - "cleanupDestFiles": "สถานที่ทำความสะอาด", - "cleanupDestFilesError": "การทำความสะอาดล้มเหลว", - "cleanupDestFilesNothing": "ไม่มีอะไรต้องทำความสะอาดที่ปลายทาง", - "cleanupDestFilesPartial": "ไม่สามารถลบไฟล์บางส่วนได้", - "cleanupDestFilesSuccess": "ลบไฟล์บางส่วนออกจากปลายทางแล้ว", - "confirmCopy": "สำเนา", - "confirmMove": "เคลื่อนไหว", - "copyFolderToHost": "คัดลอกโฟลเดอร์ไปยังโฮสต์…", - "copyItemsToHost": "คัดลอกรายการ {{count}} รายการไปยังโฮสต์…", - "copyToHost": "คัดลอกไปยังโฮสต์…", - "destinationPath": "เส้นทางปลายทาง", - "destMustBeDirectory": "สำหรับการโอนย้ายหลายรายการ ปลายทางต้องเป็นไดเร็กทอรี", - "goUp": "ขึ้นไป", - "hostAuthRequired": "ต้องมีการยืนยันตัวตน — โปรดเปิดตัวจัดการไฟล์บนโฮสต์นี้ก่อน", - "hostConnecting": "กำลังเชื่อมต่อ…", - "hostConnectionFailed": "การเชื่อมต่อล้มเหลว", - "hostDisconnected": "ไม่ได้เชื่อมต่อ", - "hostReady": "พร้อม", - "itemsSummary": "{{count}} รายการ", - "jumpHostLimitation": "โฮสต์ทั้งสองต้องสามารถเข้าถึงได้จากเซิร์ฟเวอร์ Termix การกำหนดเส้นทางโดยตรงระหว่างโฮสต์ไม่ได้รับการสนับสนุน", - "methodAuto": "อัตโนมัติ", - "methodAutoHint": "เลือกใช้ไฟล์บีบอัดแบบ tar หรือ SFTP แบบต่อไฟล์ โดยพิจารณาจากจำนวนไฟล์ ขนาดไฟล์ และความสามารถในการบีบอัด ไฟล์เดี่ยวจะใช้ SFTP แบบสตรีมมิ่งเสมอ", - "methodItemSftp": "SFTP ต่อไฟล์", - "methodItemSftpHint": "โอนไฟล์แต่ละไฟล์ทีละไฟล์ผ่าน SFTP ใช้งานได้กับทุกระบบปฏิบัติการ รวมถึง Windows", - "methodItemSftpLimitation": "แต่ละไฟล์จะใช้สตรีม SFTP เดียวกันในการคัดลอกไฟล์ทีละไฟล์ ความคืบหน้าจะถูกรวมเข้าด้วยกัน ทำให้แถบแสดงความคืบหน้าเคลื่อนที่ช้าลงเมื่อคัดลอกไฟล์ขนาดใหญ่", - "methodLabel": "วิธีการถ่ายโอน", - "methodPreviewError": "ไม่สามารถดูตัวอย่างวิธีการถ่ายโอนได้ เซิร์ฟเวอร์จะเลือกวิธีการเมื่อคุณเริ่มต้นใช้งาน", - "methodPreviewLoading": "กำลังคำนวณวิธีการโอน…", - "methodPreviewScanSummary": "ไฟล์ {{fileCount}} ไฟล์, รวม {{totalSize}} ไฟล์ (สแกนจากโฮสต์ต้นทาง)", - "methodPreviewWillUseItemSftp": "จะใช้: SFTP แบบแยกไฟล์", - "methodPreviewWillUseTar": "จะใช้: ไฟล์เก็บถาวร Tar", + "browseFolders": "Browse destination folders", + "browsePathError": "Could not open this path on the destination host.", + "browsePathWillBeCreated": "This folder does not exist yet. It will be created when the transfer starts.", + "cancel": "Cancel", + "cleanupDestFiles": "Clean up destination", + "cleanupDestFilesError": "Cleanup failed", + "cleanupDestFilesNothing": "Nothing to clean up on the destination", + "cleanupDestFilesPartial": "Some partial files could not be removed", + "cleanupDestFilesSuccess": "Removed partial files from the destination", + "confirmCopy": "Copy", + "confirmMove": "Move", + "copyFolderToHost": "Copy folder to host…", + "copyItemsToHost": "Copy {{count}} items to host…", + "copyToHost": "Copy to host…", + "destinationPath": "Destination path", + "destMustBeDirectory": "Destination must be a directory for multi-item transfers", + "goUp": "Go up", + "hostAuthRequired": "Authentication required. Open File Manager on this host first", + "hostConnecting": "Connecting…", + "hostConnectionFailed": "Connection failed", + "hostDisconnected": "Not connected", + "hostReady": "Ready", + "itemsSummary": "{{count}} items", + "jumpHostLimitation": "Both hosts must be reachable from the Termix server. Direct host-to-host routing is not supported.", + "methodAuto": "Auto", + "methodAutoHint": "Picks tar or per-file SFTP based on file count, size, and compressibility. Single files always use streaming SFTP.", + "methodItemSftp": "Per-file SFTP", + "methodItemSftpHint": "Transfer each file individually over SFTP. Works on all hosts including Windows.", + "methodItemSftpLimitation": "Each file uses the same SFTP stream as a single-file copy, one after another. Progress is combined across all files, so the bar moves slowly during large files.", + "methodLabel": "Transfer method", + "methodPreviewError": "Could not preview transfer method. The server will still pick a method when you start.", + "methodPreviewLoading": "Calculating transfer method…", + "methodPreviewScanSummary": "{{fileCount}} files, {{totalSize}} total (scanned on source host).", + "methodPreviewWillUseItemSftp": "Will use: Per-file SFTP", + "methodPreviewWillUseTar": "Will use: Tar archive", "methodReason": { - "user_item_sftp": "คุณเลือกใช้ SFTP แบบต่อไฟล์", - "user_tar": "คุณเลือกไฟล์เก็บถาวรแบบ tar", - "tar_unavailable": "Tar ไม่สามารถใช้งานได้บนโฮสต์หนึ่งหรือทั้งสองโฮสต์ จึงจะใช้ SFTP แบบแยกไฟล์แทน", - "windows_host": "ระบบปฏิบัติการที่ใช้คือ Windows — ไม่ได้ใช้โปรแกรม tar", - "auto_multi_large": "อัตโนมัติ: ไฟล์หลายไฟล์ รวมถึงไฟล์ขนาดใหญ่ ({{largestSize}}) ที่มีข้อมูลที่สามารถบีบอัดได้ — tar จะรวมไฟล์เหล่านั้นไว้ในการถ่ายโอนครั้งเดียว", - "auto_single_large_in_archive": "อัตโนมัติ: ไฟล์ขนาดใหญ่หนึ่งไฟล์ ({{largestSize}}) ในชุดนี้ — SFTP ต่อไฟล์", - "auto_many_incompressible": "อัตโนมัติ: ข้อมูลส่วนใหญ่ไม่สามารถบีบอัดได้ — SFTP แบบแยกไฟล์", - "auto_many_files": "อัตโนมัติ: หลายไฟล์ ({{fileCount}}) — tar ช่วยลดภาระต่อไฟล์", - "auto_default": "อัตโนมัติ: ตั้งค่า SFTP สำหรับแต่ละไฟล์ในชุดนี้" + "user_item_sftp": "You chose per-file SFTP.", + "user_tar": "You chose tar archive.", + "tar_unavailable": "Tar is not available on one or both hosts, so per-file SFTP will be used instead.", + "windows_host": "A Windows host is involved, so tar is not used.", + "auto_multi_large": "Auto: multiple files including a large file ({{largestSize}}) with compressible data. Tar bundles them into one transfer.", + "auto_single_large_in_archive": "Auto: one large file ({{largestSize}}) in this set, so per-file SFTP.", + "auto_many_incompressible": "Auto: mostly incompressible data, so per-file SFTP.", + "auto_many_files": "Auto: many files ({{fileCount}}), tar cuts the per-file overhead.", + "auto_default": "Auto: per-file SFTP for this set." }, - "methodTar": "คลังข้อมูลทาร์", - "methodTarHint": "บีบอัดไฟล์ที่ต้นทาง ถ่ายโอนไฟล์เก็บถาวรหนึ่งไฟล์ และแตกไฟล์ที่ปลายทาง ต้องใช้ tar บนเครื่อง Unix ทั้งสองเครื่อง", - "metricsCompress": "บีบอัดจากแหล่งที่มา: {{duration}}", - "metricsExtract": "แตกไฟล์ที่ปลายทาง: {{duration}}", - "metricsPrepare": "เตรียมปลายทาง: {{duration}}", - "metricsRouteBenchmark": "การตรวจสอบเส้นทาง — โดยตรง: {{direct}}, ส่งต่อ: {{relay}}", - "metricsSourceDelete": "ลบออกจากแหล่งที่มา: {{duration}}", - "metricsTotal": "รวม: {{duration}}", - "metricsTransfer": "จากต้นทางถึงปลายทาง: {{throughput}} ({{duration}})", - "metricsVerify": "ตรวจสอบด้วย SHA-256 แล้ว: {{duration}}", - "moveFolderToHost": "ย้ายโฟลเดอร์ไปยังโฮสต์…", - "moveItemsToHost": "ย้ายรายการ {{count}} รายการไปยังโฮสต์…", - "moveToHost": "ย้ายไปยังโฮสต์…", - "noHostsConnected": "ไม่มีโฮสต์ตัวจัดการไฟล์อื่นให้บริการ", - "noHostsConnectedHint": "เพิ่มโฮสต์ SSH อีกตัวโดยเปิดใช้งานตัวจัดการไฟล์ในตัวจัดการโฮสต์", - "parallelSegmentsHint": "ไฟล์ขนาดใหญ่จะถูกแบ่งออกเป็นส่วนย่อยขนาด 256 MB การใช้หลายเลนจะใช้การเชื่อมต่อแยกกัน (เช่น การเริ่มการถ่ายโอนหลายรายการพร้อมกัน) เพื่อให้ได้ปริมาณงานโดยรวมที่สูงขึ้น", - "parallelSegmentsLabel": "ช่องทางเปลี่ยนถ่ายแบบขนาน", - "parallelSegmentsOption": "{{count}} เลน", - "progressBenchmarking": "เลือกเส้นทางการโอนย้ายที่เร็วที่สุด…", + "methodTar": "Tar archive", + "methodTarHint": "Compress on source, transfer one archive, extract on destination. Requires tar on both Unix hosts.", + "metricsCompress": "Compress on source: {{duration}}", + "metricsExtract": "Extract on destination: {{duration}}", + "metricsPrepare": "Prepare destination: {{duration}}", + "metricsRouteBenchmark": "Route probe: direct {{direct}}, relay {{relay}}", + "metricsSourceDelete": "Remove from source: {{duration}}", + "metricsTotal": "Total: {{duration}}", + "metricsTransfer": "End-to-end: {{throughput}} ({{duration}})", + "metricsVerify": "SHA-256 verified: {{duration}}", + "moveFolderToHost": "Move folder to host…", + "moveItemsToHost": "Move {{count}} items to host…", + "moveToHost": "Move to host…", + "noHostsConnected": "No other file-manager hosts available.", + "noHostsConnectedHint": "Add another SSH host with File Manager enabled in Host Manager.", + "parallelSegmentsHint": "Large files are split into 256 MB chunks. Multiple lanes use separate connections (like starting several transfers) for higher total throughput.", + "parallelSegmentsLabel": "Parallel transfer lanes", + "parallelSegmentsOption": "{{count}} lanes", + "progressBenchmarking": "Selecting the fastest transfer route…", "progressBytes": "{{transferred}} / {{total}}", - "progressCancel": "ยกเลิก", - "progressCancelling": "การยกเลิก…", - "progressCompressing": "กำลังบีบอัดบนโฮสต์ต้นทาง…", - "progressExtracting": "กำลังแตกไฟล์ที่ปลายทาง…", - "progressItems": "ไฟล์ {{current}} / {{total}}", - "progressReconnecting": "กำลังเชื่อมต่อใหม่…", - "progressStalled": "หยุดชะงัก", - "progressTotalSpeed": "{{speed}} รวม ({{lanes}} เลน)", - "progressTransferring": "กำลังถ่ายโอนข้อมูล…", - "progressTransferringItems": "กำลังถ่ายโอนไฟล์ ({{current}} จาก {{total}})…", - "progressVerifying": "กำลังตรวจสอบความสมบูรณ์ของไฟล์…", - "recentDestinations": "จุดหมายปลายทางล่าสุด", - "resumedHint": "เชื่อมต่อใหม่กับการถ่ายโอนที่เริ่มทำงานในหน้าต่างอื่นแล้ว", - "retryTransfer": "ลองใหม่อีกครั้ง", - "retryTransferError": "การลองใหม่ล้มเหลว", - "selectDestinationHost": "เลือกโฮสต์ปลายทาง", - "transferCancelled": "การโอนเงินถูกยกเลิก", - "transferCancelledCopyHint": "ไฟล์บางส่วนอาจยังคงอยู่ในปลายทาง", - "transferCancelledMoveHint": "ไฟล์บางส่วนอาจยังคงอยู่ในปลายทาง ไฟล์ต้นฉบับไม่ได้ถูกลบออก", - "transferError": "การโอนล้มเหลว", - "transferFailedRetryHint": "ข้อมูลบางส่วนถูกเก็บไว้ในปลายทาง การลองใหม่จะดำเนินการต่อเมื่อการเชื่อมต่อกลับมาใช้งานได้", - "transferPartialHint": "ไม่สามารถโอนเงินได้: {{paths}}", - "transferSuccess": "การโอนเสร็จสมบูรณ์" + "progressCancel": "Cancel", + "progressCancelling": "Cancelling…", + "progressCompressing": "Compressing on source host…", + "progressExtracting": "Extracting on destination…", + "progressItems": "{{current}} / {{total}} files", + "progressReconnecting": "Reconnecting…", + "progressStalled": "Stalled", + "progressTotalSpeed": "{{speed}} total ({{lanes}} lanes)", + "progressTransferring": "Transferring data…", + "progressTransferringItems": "Transferring files ({{current}} of {{total}})…", + "progressVerifying": "Verifying file integrity…", + "recentDestinations": "Recent destinations", + "resumedHint": "Reconnected to an active transfer started in another window.", + "retryTransfer": "Retry", + "retryTransferError": "Retry failed", + "selectDestinationHost": "Select destination host", + "transferCancelled": "Transfer cancelled", + "transferCancelledCopyHint": "Partial files may remain on the destination.", + "transferCancelledMoveHint": "Partial files may remain on the destination. Source files were not removed.", + "transferError": "Transfer failed", + "transferFailedRetryHint": "Partial data was kept on the destination. Retry will resume when the connection is back.", + "transferPartialHint": "Could not transfer: {{paths}}", + "transferSuccess": "Transfer complete", + "metricsHopSourceRead": "Source → server: {{throughput}}", + "metricsHopDestSftpWrite": "Server → dest (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Server → dest (local): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/tr_TR.json b/plugins/file-manager/locales/translated/tr_TR.json index 679fbb03a..cf6e4829c 100644 --- a/plugins/file-manager/locales/translated/tr_TR.json +++ b/plugins/file-manager/locales/translated/tr_TR.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "Dosyalar", + "sftp": "SFTP", + "openFileManager": "Dosya Yöneticisini Aç" + }, + "permissions": { + "use": { + "title": "Use file manager", + "description": "Browse, edit and transfer files over SFTP." + } + }, + "settings": { + "host": { + "enable": { + "label": "Dosya Yöneticisini Etkinleştir", + "description": "Browse and edit files on this host over SFTP." + }, + "defaultPath": { + "label": "Varsayılan Yol" + }, + "scpLegacy": { + "label": "SCP Eski Modu" + } + }, + "user": { + "transferConcurrency": { + "label": "Simultaneous File Transfers", + "description": "How many files the side by side local/remote manager uploads or downloads at the same time. Lower this if your server limits SFTP channels." + }, + "confirmBeforeTrash": { + "label": "Confirm before moving files to trash", + "description": "Ask before moving remote files to trash. Permanent deletion still requires confirmation." + } + } + }, + "hostCapability": { + "label": "Dosya Yöneticisi" + }, "fileManager": { "noHostSelected": "Hiçbir sunucu seçilmedi", "initializingEditor": "Düzenleyici başlatılıyor...", @@ -34,13 +72,14 @@ "rename": "Yeniden Adlandır", "uploading": "Yükleniyor...", "uploadingFile": "{{name}} yükleniyor...", + "uploadingChunk": "Uploading {{name}}: {{percent}}% (part {{chunk}} of {{total}})", "fileName": "Dosya Adı", "folderName": "Klasör Adı", "fileUploadedSuccessfully": "\"{{name}}\" dosyası başarıyla yüklendi.", "failedToUploadFile": "Dosya yüklenemedi.", - "uploadingFolderFiles": "{{count}} dosya yükleniyor...", - "uploadedFolderFiles": "{{count}} dosya başarıyla yüklendi", - "uploadedFolderPartial": "{{uploaded}} dosya yüklendi, {{failed}} başarısız oldu", + "uploadingFolderFiles": "Uploading {{count}} file(s)...", + "uploadedFolderFiles": "Uploaded {{count}} file(s) successfully", + "uploadedFolderPartial": "Uploaded {{uploaded}} file(s), {{failed}} failed", "fileDownloadedSuccessfully": "\"{{name}}\" dosyası başarıyla indirildi.", "failedToDownloadFile": "Dosya indirilemedi.", "fileCreatedSuccessfully": "\"{{name}}\" dosyası başarıyla oluşturuldu.", @@ -56,58 +95,58 @@ "sudoOperationFailed": "Sudo işlemi başarısız", "sudoAuthFailed": "Sudo kimlik doğrulaması başarısız", "dragFilesToUpload": "Yüklemek için dosyaları buraya bırakın", - "dropToUploadHere": "Yüklemek için sürükle bırak özelliğini kullanın.", - "dropToDownloadHere": "İndirmek için buraya tıklayın", + "dropToUploadHere": "Drop to upload here", + "dropToDownloadHere": "Drop to download here", "localFiles": "Yerel", - "showLocalFiles": "Yerel dosyaları göster (bölünmüş görünüm)", - "hideLocalFiles": "Yerel dosyaları gizle", - "localHome": "Ana klasör", - "localPathPlaceholder": "Yerel klasör yolu", - "localShowHidden": "Gizli dosyaları göster", - "localHideHidden": "Gizli dosyaları gizle", - "localRevealInFileManager": "Sistem dosya yöneticisinde göster", - "localCannotOpenFolder": "Klasör açılamıyor.", + "showLocalFiles": "Show local files (split view)", + "hideLocalFiles": "Hide local files", + "localHome": "Home folder", + "localPathPlaceholder": "Local folder path", + "localShowHidden": "Show hidden files", + "localHideHidden": "Hide hidden files", + "localRevealInFileManager": "Reveal in system file manager", + "localCannotOpenFolder": "Cannot open folder", "localItemCount": "{{count}} öğe", - "localSelectedCount": "{{count}} seçildi", + "localSelectedCount": "{{count}} seçili", "back": "Geri", - "forward": "İleri", - "up": "Yukarı", - "kind": "Tür", - "localUploadingProgress": "{{total}}'ten {{current}} yükleniyor", - "localDownloadingProgress": "{{total}}'ten {{current}} indiriliyor", - "localTransferInFlight": "{{count}} hemen", - "localPreparingDownload": "İndirme işlemi hazırlanıyor...", - "localTransferCancelled": "Transfer iptal edildi.", - "localNothingToTransfer": "Aktarılacak bir şey yok.", - "localUploadComplete": "{{count}} dosya yüklendi", - "localUploadFailed": "Yükleme başarısız oldu", - "localUploadPartial": "{{done}} dosya yüklendi, {{failed}} başarısız oldu", - "localDownloadComplete": "{{count}} dosya indirildi", + "forward": "Forward", + "up": "Up", + "kind": "Kind", + "localUploadingProgress": "Uploading {{current}} of {{total}}", + "localDownloadingProgress": "Downloading {{current}} of {{total}}", + "localTransferInFlight": "{{count}} at once", + "localPreparingDownload": "Preparing download...", + "localTransferCancelled": "Aktarım iptal edildi", + "localNothingToTransfer": "Nothing to transfer", + "localUploadComplete": "Uploaded {{count}} file(s)", + "localUploadFailed": "Upload failed", + "localUploadPartial": "Uploaded {{done}} file(s), {{failed}} failed", + "localDownloadComplete": "Downloaded {{count}} file(s)", "localDownloadFailed": "İndirme başarısız oldu", - "localDownloadPartial": "{{done}} dosya indirildi, {{failed}} başarısız oldu", - "localReplaceExistingPrompt": "Bu klasörde zaten {{count}} öğe mevcut. Bunların yerine yenilerini mi koymak istiyorsunuz?", - "localReplace": "Yer değiştirmek", - "localSkipExisting": "Atlamak", - "localSkippedExisting": "{{count}} mevcut öğe atlandı", - "localUnsafeNamesSkipped": "Bu bilgisayarda adları kullanılamayan {{count}} öğe atlandı.", - "localOpen": "Açık", - "localOpenFolder": "Klasörü aç", - "localUploadToRemote": "Sunucuya yükle", - "localUploadToRemoteMany": "Sunucuya {{count}} öğe yükle", - "localMoveToTrash": "Çöp Kutusuna Taşı", - "localMoveToTrashMany": "{{count}} öğeyi Çöp Kutusuna Taşı", - "localTrashConfirmSingle": "\"{{name}}\" öğesini Çöp Kutusuna taşı?", - "localTrashConfirmFolder": "\"{{name}}\" klasörünü ve tüm içeriğini Çöp Kutusu'na taşı?", - "localTrashConfirmMany": "{{count}} öğeyi Çöp Kutusuna taşı?", - "localTrashed": "{{count}} öğe Çöp Kutusu'na taşındı", - "localTrashFailed": "Çöp kutusuna taşınamadı", - "localRenameFailed": "Yeniden adlandırma başarısız oldu.", - "localCreateFailed": "Öğe oluşturulamadı.", - "goToParentFolder": "Üst klasöre git", - "resizeSidebar": "Kenar çubuğunu yeniden boyutlandırmak için sürükleyin (sıfırlamak için çift tıklayın)", - "resizeLocalPane": "Yerel bölmeyi yeniden boyutlandırmak için sürükleyin (sıfırlamak için çift tıklayın).", + "localDownloadPartial": "Downloaded {{done}} file(s), {{failed}} failed", + "localReplaceExistingPrompt": "{{count}} item(s) already exist in this folder. Replace them?", + "localReplace": "Değiştir", + "localSkipExisting": "Skip", + "localSkippedExisting": "Skipped {{count}} existing item(s)", + "localUnsafeNamesSkipped": "Skipped {{count}} item(s) whose names cannot be used on this computer", + "localOpen": "Aç", + "localOpenFolder": "Open folder", + "localUploadToRemote": "Upload to server", + "localUploadToRemoteMany": "Upload {{count}} items to server", + "localMoveToTrash": "Move to Trash", + "localMoveToTrashMany": "Move {{count}} items to Trash", + "localTrashConfirmSingle": "Move \"{{name}}\" to the Trash?", + "localTrashConfirmFolder": "Move the folder \"{{name}}\" and all its contents to the Trash?", + "localTrashConfirmMany": "Move {{count}} items to the Trash?", + "localTrashed": "Moved {{count}} item(s) to the Trash", + "localTrashFailed": "Could not move to the Trash", + "localRenameFailed": "Rename failed", + "localCreateFailed": "Could not create item", + "goToParentFolder": "Go to parent folder", + "resizeSidebar": "Drag to resize the sidebar (double-click to reset)", + "resizeLocalPane": "Drag to resize the local pane (double-click to reset)", "columns": "Sütunlar", - "columnsHint": "Sütunları seçmek için sağ tıklayın.", + "columnsHint": "Right-click to choose columns", "emptyFolder": "Bu klasör boş", "searchFiles": "Dosya ara...", "upload": "Yükle", @@ -163,26 +202,26 @@ "confirmDeleteMultipleItemsWithFolders": "{{count}} öğeyi kalıcı olarak silmek istediğinize emin misiniz? Bu, klasörleri ve içeriklerini de kapsar.", "confirmDeleteFolder": "\"{{name}}\" klasörünü ve tüm içeriğini kalıcı olarak silmek istediğinize emin misiniz?", "permanentDeleteWarning": "Bu işlem geri alınamaz. Öğe(ler) sunucudan kalıcı olarak silinecek.", - "moveToTrashWarning": "Öğeler Termix Çöp Kutusu'na taşınacak ve saklama süresi dolmadan önce geri yüklenebilecektir.", - "itemsMovedToTrash": "{{count}} öğe Çöp Kutusuna taşındı", - "trash": "Çöp", - "trashDescription": "Silinen öğeler bu sunucuda {{days}} gün boyunca saklanır.", - "trashLoadFailed": "Çöp kutusu yüklenemedi.", - "trashEmpty": "Çöp kutusu boş.", - "trashRestore": "Eski haline getirmek", - "trashRestored": "Geri Yüklendi {{name}}", - "trashRestoreFailed": "Öğeyi geri yükleme başarısız oldu. Orijinal yol zaten mevcut olabilir.", - "trashDeletePermanently": "Kalıcı olarak sil", - "trashDeleteConfirm": "{{name}}öğesini kalıcı olarak silmek istiyor musunuz? Bu işlem geri alınamaz.", - "trashPermanentlyDeleted": "Kalıcı olarak silindi {{name}}", - "trashDeleteFailed": "Öğeyi kalıcı olarak silme işlemi başarısız oldu.", - "trashEmptyAction": "Çöpü Boşaltın", - "trashEmptyConfirm": "Çöp kutusundaki tüm öğeleri kalıcı olarak silmek mi istiyorsunuz? Bu işlem geri alınamaz.", - "trashEmptied": "Çöp boşaltıldı.", - "trashRetention": "Otomatik temizleme süresi (gün)", - "trashRetentionSaved": "Çöp saklama süresi güncellendi", - "trashRetentionFailed": "Çöp kutusu saklama süresi güncellenemedi.", - "trashUnavailableConfirm": "Bu öğe Çöp Kutusu'na taşınamaz, genellikle başka bir dosya sisteminde olduğu veya yükseltilmiş izinler gerektirdiği içindir. Bunun yerine kalıcı olarak silin.", + "moveToTrashWarning": "The item(s) will be moved to the Termix Trash and can be restored before the retention period expires.", + "itemsMovedToTrash": "{{count}} item(s) moved to Trash", + "trash": "Trash", + "trashDescription": "Deleted items are retained for {{days}} day(s) on this host.", + "trashLoadFailed": "Failed to load Trash", + "trashEmpty": "Trash is empty", + "trashRestore": "Geri Yükle", + "trashRestored": "Restored {{name}}", + "trashRestoreFailed": "Failed to restore item. The original path may already exist.", + "trashDeletePermanently": "Delete permanently", + "trashDeleteConfirm": "Permanently delete {{name}}? This cannot be undone.", + "trashPermanentlyDeleted": "Permanently deleted {{name}}", + "trashDeleteFailed": "Failed to permanently delete item", + "trashEmptyAction": "Empty Trash", + "trashEmptyConfirm": "Permanently delete every item in Trash? This cannot be undone.", + "trashEmptied": "Trash emptied", + "trashRetention": "Automatic cleanup after (days)", + "trashRetentionSaved": "Trash retention updated", + "trashRetentionFailed": "Failed to update Trash retention", + "trashUnavailableConfirm": "This item cannot be moved to Trash, usually because it is on another filesystem or requires elevated permissions. Delete it permanently instead?", "recent": "Son Kullanılanlar", "pinned": "Sabitlenmiş", "folderShortcuts": "Klasör Kısayolları", @@ -264,7 +303,7 @@ "operationCompleted": "{{count}} öğe {{operation}}", "downloadFileSuccess": "{{name}} dosyası başarıyla indirildi", "downloadFileFailed": "İndirme başarısız oldu", - "downloadingFile": "{{name}}… indiriliyor", + "downloadingFile": "Downloading {{name}}…", "downloadProgressBytes": "{{transferred}} / {{total}}", "moveTo": "{{name}} konumuna taşı", "diffCompareWith": "{{name}} ile diff karşılaştır", @@ -290,6 +329,7 @@ "connecting": "Bağlanıyor...", "connectedSuccessfully": "Bağlantı başarıyla kuruldu", "totpVerificationFailed": "TOTP doğrulaması başarısız oldu", + "browserSignInFailed": "Sign-in failed. Please try again.", "authenticationFailed": "Kimlik doğrulama başarısız oldu", "incorrectPassphrase": "Yanlış parola. Lütfen tekrar deneyin.", "verificationCodePrompt": "Doğrulama kodu:", @@ -321,98 +361,85 @@ "used": "Kullanılan", "of": " / ", "toggleSidebar": "Kenar Çubuğunu Göster/Gizle", - "compactLayout": "Kompakt düzeni kullanın.", - "comfortableLayout": "Rahat bir düzen kullanın.", + "compactLayout": "Use compact layout", + "comfortableLayout": "Use comfortable layout", "cannotLoadPdf": "PDF yüklenemiyor", "pdfLoadError": "Bu PDF dosyası yüklenirken bir hata oluştu.", "loadingPdf": "PDF yükleniyor...", - "loadingPage": "Sayfa yükleniyor..." + "loadingPage": "Sayfa yükleniyor...", + "cancel": "İptal", + "copiedItems_one": "Copied {{count}} item", + "copiedItems_other": "Copied {{count}} items", + "deleteCopiedFileFailed": "Could not delete the copy of {{name}}: {{error}}", + "dragMovedItems_one": "Moved {{count}} item to {{target}}", + "dragMovedItems_other": "Moved {{count}} items to {{target}}", + "moveBackFileFailed": "Could not move {{name}} back: {{error}}", + "terminal": "Terminal: {{host}} ({{path}})", + "dragToDesktop": "Dragging {{name}} to the desktop", + "dragFilesToDesktop": "Dragging {{count}} files to the desktop", + "folderDragUnsupported": "Dragging folders to the desktop is not supported yet", + "saveToDesktopFailed": "Save failed: {{error}}", + "dragFailedDetail": "Drag failed: {{error}}", + "videoUnsupported": "Your browser cannot play this video format.", + "downloadToPlay": "Download to play it elsewhere", + "cannotPreviewType": "Cannot preview this file type", + "cannotPreviewTypeHint": "This file type has no preview. Download it to open it in another app." }, "sftpTransfer": { "title": "SFTP", - "description": "İki SSH sunucusu arasında dosya aktarımı.", - "sourceServer": "Kaynak Sunucusu", - "destinationServer": "Hedef Sunucu", - "selectHost": "Sunucu seçin", - "noHostSelected": "Sunucu seçilmedi.", - "move": "Taşınmak", + "description": "Transfer files between two SSH hosts.", + "sourceServer": "Source Server", + "destinationServer": "Destination Server", + "selectHost": "Select host", + "noHostSelected": "Sunucu seçilmedi", + "move": "Taşı", "copy": "Kopyala", - "upload": "Yüklemek", - "itemsSelected": "{{count}} seçilen öğe", - "itemsSelected_other": "{{count}} öğe seçildi", + "upload": "Yükle", + "itemsSelected": "{{count}} item selected", + "itemsSelected_other": "{{count}} items selected", "ready": "Hazır", - "loadingHosts": "Sunucular yükleniyor...", - "name": "İsim", - "modified": "Değiştirildi", + "loadingHosts": "Hostlar yükleniyor...", + "name": "Ad", + "modified": "Değiştirilme", "size": "Boyut", - "noFiles": "Dosya yok", - "open": "Açık", - "up": "Yukarı", + "noFiles": "No files", + "open": "Aç", + "up": "Up", "refresh": "Yenile", - "copyToTarget": "Hedef Dizine Kopyala", - "rename": "Yeniden isimlendirmek", - "delete": "Silmek", - "editPermissions": "Düzenleme İzinleri", - "createNewFolder": "Yeni Klasör Oluştur", - "deleteSelectedItems": "Seçili Öğeleri Sil", + "copyToTarget": "Copy to Target Directory", + "rename": "Yeniden adlandır", + "delete": "Sil", + "editPermissions": "Edit Permissions", + "createNewFolder": "Create New Folder", + "deleteSelectedItems": "Delete Selected Items", "deleteConfirm": "Delete {{count}} selected item?", "deleteConfirm_other": "Delete {{count}} selected items?", - "cancel": "İptal etmek", - "save": "Kaydetmek", - "folderCreated": "Klasör oluşturuldu", - "itemRenamed": "Öğe yeniden adlandırıldı.", - "actionFailed": "İşlem başarısız oldu", - "itemsDeleted": "{{count}} öğe silindi", - "itemsDeleted_other": "{{count}} öğe silindi", - "deleteFailed": "Silme işlemi başarısız oldu.", - "permissionsUpdated": "İzinler güncellendi", - "noRemoteSessionConnected": "Bağlantı kurulmuş uzaktan oturum yok.", - "failedToListFiles": "Dosyaları listeleme başarısız oldu.", - "failedToRefresh": "Yenileme başarısız oldu", - "destinationInsideSource": "Hedef, seçilen kaynak yolunun içinde olamaz.", - "sameHostNoOp": "Kaynak ve hedef aynı klasördedir." + "cancel": "İptal", + "save": "Kaydet", + "folderCreated": "Folder created", + "itemRenamed": "Item renamed", + "actionFailed": "Eylem başarısız oldu", + "itemsDeleted": "{{count}} item deleted", + "itemsDeleted_other": "{{count}} items deleted", + "deleteFailed": "Delete failed", + "permissionsUpdated": "Permissions updated", + "noRemoteSessionConnected": "No remote session connected", + "failedToListFiles": "Failed to list files", + "failedToRefresh": "Failed to refresh", + "destinationInsideSource": "Destination cannot be inside the selected source path.", + "sameHostNoOp": "Source and destination are the same folder." }, "hosts": { "fileManager": "Dosya Yöneticisi", - "tabFiles": "Dosyalar", - "enableFileManagerMonitor": "Dosya Yöneticisini Etkinleştir", - "enableFileManagerMonitorDesc": "Bu sunucudaki dosyalara SFTP üzerinden göz atın ve yönetin", - "scpLegacyLabel": "SCP Eski Modu", - "scpLegacyDesc": "SFTP alt sistemini desteklemeyen sunucular için eski dosya aktarımını kullan (ör. gömülü veya minimal SSH sunucuları).", - "defaultPathLabel": "Varsayılan Yol", - "fileManagerPathHint": "Dosya yöneticisi bu sunucu için başlatıldığında açılacak dizin.", "fileManagerUrlCopied": "Dosya Yöneticisi URL'si kopyalandı", "copyFileManagerUrlAction": "Dosya Yöneticisi URL'sini Kopyala", "docsLink": "Dokümanları görüntüle", "hostNotFound": "Host bulunamadı", "loadingHost": "Host yükleniyor..." }, - "settings": { - "host": { - "enable": { - "label": "Dosya Yöneticisini Etkinleştir" - }, - "defaultPath": { - "label": "Varsayılan Yol" - }, - "scpLegacy": { - "label": "SCP Eski Modu" - } - }, - "user": { - "transferConcurrency": { - "label": "Eşzamanlı Dosya Aktarımları", - "description": "Yan yana yerel/uzaktan yönetici tarafından aynı anda yüklenen veya indirilen dosya sayısı. Sunucunuz SFTP kanallarını sınırlandırıyorsa bu değeri düşürün." - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "Dosyalar" - }, "onboarding": { - "feature_files": "Dosya yöneticisi", - "feature_files_desc": "Uygulamadan çıkmadan SFTP üzerinden dosyalara göz atın, yükleyin, indirin ve düzenleyin." + "feature_files": "File manager", + "feature_files_desc": "Browse, upload, download and edit files over SFTP without leaving the app." }, "terminal": { "runTitle": "Çalıştırılıyor: {{command}} - {{host}}", @@ -437,7 +464,7 @@ "destinationPath": "Hedef yol", "destMustBeDirectory": "Çoklu öğe aktarımları için hedef bir dizin olmalıdır", "goUp": "Yukarı", - "hostAuthRequired": "Kimlik doğrulama gerekli — önce bu ana bilgisayarda Dosya Yöneticisi'ni açın", + "hostAuthRequired": "Authentication required. Open File Manager on this host first", "hostConnecting": "Bağlanıyor…", "hostConnectionFailed": "Bağlantı başarısız", "hostDisconnected": "Bağlı değil", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "Dosya bazında SFTP seçtiniz.", "user_tar": "Tar arşivi seçtiniz.", - "tar_unavailable": "Bir veya her iki ana bilgisayarda Tar kullanılamıyor — bunun yerine dosya bazında SFTP kullanılacak.", - "windows_host": "Windows ana bilgisayarı söz konusu — tar kullanılmaz.", - "auto_multi_large": "Otomatik: sıkıştırılabilir veriye sahip büyük bir dosya ({{largestSize}}) dahil birden çok dosya — tar tek bir aktarımda birleştirir.", - "auto_single_large_in_archive": "Otomatik: bu kümede bir büyük dosya ({{largestSize}}) — dosya bazında SFTP.", - "auto_many_incompressible": "Otomatik: çoğunlukla sıkıştırılamayan veri — dosya bazında SFTP.", - "auto_many_files": "Otomatik: çok sayıda dosya ({{fileCount}}) — tar dosya başına ek yükü azaltır.", + "tar_unavailable": "Tar is not available on one or both hosts, so per-file SFTP will be used instead.", + "windows_host": "A Windows host is involved, so tar is not used.", + "auto_multi_large": "Auto: multiple files including a large file ({{largestSize}}) with compressible data. Tar bundles them into one transfer.", + "auto_single_large_in_archive": "Auto: one large file ({{largestSize}}) in this set, so per-file SFTP.", + "auto_many_incompressible": "Auto: mostly incompressible data, so per-file SFTP.", + "auto_many_files": "Auto: many files ({{fileCount}}), tar cuts the per-file overhead.", "auto_default": "Otomatik: bu küme için dosya bazında SFTP." }, "methodTar": "Tar arşivi", @@ -471,11 +498,11 @@ "metricsCompress": "Kaynakta sıkıştırma: {{duration}}", "metricsExtract": "Hedefte çıkarma: {{duration}}", "metricsPrepare": "Hedefi hazırla: {{duration}}", - "metricsRouteBenchmark": "Rota sondası — doğrudan: {{direct}}, röle: {{relay}}", + "metricsRouteBenchmark": "Route probe: direct {{direct}}, relay {{relay}}", "metricsSourceDelete": "Kaynaktan silme: {{duration}}", "metricsTotal": "Toplam: {{duration}}", "metricsTransfer": "Uçtan uca: {{throughput}} ({{duration}})", - "metricsVerify": "SHA-256 ile doğrulandı: {{duration}}", + "metricsVerify": "SHA-256 verified: {{duration}}", "moveFolderToHost": "Klasörü ana bilgisayara taşı…", "moveItemsToHost": "{{count}} öğeyi ana bilgisayara taşı…", "moveToHost": "Sunucuya taşı…", @@ -484,7 +511,7 @@ "parallelSegmentsHint": "Büyük dosyalar 256 MB'lık parçalara bölünür. Çoklu yollar, daha yüksek toplam aktarım hızı için ayrı bağlantılar kullanır (birden fazla aktarım başlatmak gibi).", "parallelSegmentsLabel": "Paralel aktarım yolları", "parallelSegmentsOption": "{{count}} yol", - "progressBenchmarking": "En hızlı aktarma rotasını seçme…", + "progressBenchmarking": "Selecting the fastest transfer route…", "progressBytes": "{{transferred}} / {{total}}", "progressCancel": "İptal", "progressCancelling": "İptal ediliyor…", @@ -496,7 +523,7 @@ "progressTotalSpeed": "{{speed}} toplam ({{lanes}} yol)", "progressTransferring": "Veri aktarılıyor…", "progressTransferringItems": "Dosyalar aktarılıyor ({{current}} / {{total}})…", - "progressVerifying": "Dosya bütünlüğünün doğrulanması…", + "progressVerifying": "Verifying file integrity…", "recentDestinations": "Son hedefler", "resumedHint": "Başka bir pencerede başlatılan aktif bir aktarıma yeniden bağlanıldı.", "retryTransfer": "Yeniden dene", @@ -508,6 +535,9 @@ "transferError": "Aktarım başarısız", "transferFailedRetryHint": "Hedefte kısmi veri tutuldu. Bağlantı geri geldiğinde yeniden deneme devam edecek.", "transferPartialHint": "Aktarılamadı: {{paths}}", - "transferSuccess": "Aktarım tamamlandı" + "transferSuccess": "Aktarım tamamlandı", + "metricsHopSourceRead": "Kaynak → sunucu: {{throughput}}", + "metricsHopDestSftpWrite": "Sunucu → hedef (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Sunucu → hedef (yerel): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/uk_UA.json b/plugins/file-manager/locales/translated/uk_UA.json index da589e37f..dc86761ce 100644 --- a/plugins/file-manager/locales/translated/uk_UA.json +++ b/plugins/file-manager/locales/translated/uk_UA.json @@ -1,513 +1,543 @@ { - "fileManager": { - "noHostSelected": "Хост не вибрано", - "initializingEditor": "Ініціалізація редактора...", - "file": "Файл", - "folder": "Папка", - "uploadFile": "Завантажити файл", - "downloadFile": "Завантажити", - "extractArchive": "Витягти архів", - "extractingArchive": "Видобування {{name}}...", - "archiveExtractedSuccessfully": "{{name}} успішно видобуто", - "extractFailed": "Не вдалося витягти", - "compressFile": "Стиснути файл", - "compressFiles": "Стиснути файли", - "compressFilesDesc": "Стиснути {{count}} елементів в архів", - "archiveName": "Назва архіву", - "enterArchiveName": "Введіть назву архіву...", - "compressionFormat": "Формат стиснення", - "selectedFiles": "Вибрані файли", - "andMoreFiles": "та {{count}} більше...", - "compress": "Стиснути", - "compressingFiles": "Стискання {{count}} елементів у {{name}}...", - "filesCompressedSuccessfully": "{{name}} успішно створено", - "compressFailed": "Стиснення не вдалося", - "edit": "Редагувати", - "preview": "Попередній перегляд", - "previous": "Попередній", - "next": "Далі", - "pageXOfY": "Сторінка {{current}} з {{total}}", - "zoomOut": "Зменшити масштаб", - "zoomIn": "Збільшити масштаб", - "newFile": "Новий файл", - "newFolder": "Нова папка", - "rename": "Перейменувати", - "uploading": "Завантаження...", - "uploadingFile": "Завантаження {{name}}...", - "fileName": "Ім'я файлу", - "folderName": "Назва папки", - "fileUploadedSuccessfully": "Файл «{{name}}» успішно завантажено", - "failedToUploadFile": "Не вдалося завантажити файл", - "uploadingFolderFiles": "Завантаження {{count}} файлів...", - "uploadedFolderFiles": "Успішно завантажено {{count}} файл(ів)", - "uploadedFolderPartial": "Завантажено {{uploaded}} файл(ів), {{failed}} не вдалося", - "fileDownloadedSuccessfully": "Файл «{{name}}» успішно завантажено", - "failedToDownloadFile": "Не вдалося завантажити файл", - "fileCreatedSuccessfully": "Файл «{{name}}» успішно створено", - "folderCreatedSuccessfully": "Папка «{{name}}» успішно створена", - "failedToCreateItem": "Не вдалося створити елемент", - "operationFailed": "Операція {{operation}} не вдалася для {{name}}: {{error}}", - "failedToResolveSymlink": "Не вдалося вирішити проблему з символічним посиланням", - "itemsDeletedSuccessfully": "{{count}} елементів успішно видалено", - "failedToDeleteItems": "Не вдалося видалити елементи", - "sudoPasswordRequired": "Потрібен пароль адміністратора", - "enterSudoPassword": "Введіть пароль sudo, щоб продовжити цю операцію", - "sudoPassword": "Пароль Sudo", - "sudoOperationFailed": "Операція Sudo не вдалася", - "sudoAuthFailed": "Не вдалося виконати автентифікацію Sudo", - "dragFilesToUpload": "Перетягніть сюди файли для завантаження", - "dropToUploadHere": "Перетягніть сюди, щоб завантажити", - "dropToDownloadHere": "Перетягніть сюди, щоб завантажити", - "localFiles": "Місцевий", - "showLocalFiles": "Показати локальні файли (розділений вигляд)", - "hideLocalFiles": "Приховати локальні файли", - "localHome": "Домашня папка", - "localPathPlaceholder": "Шлях до локальної папки", - "localShowHidden": "Показати приховані файли", - "localHideHidden": "Приховати приховані файли", - "localRevealInFileManager": "Показати в системному файловому менеджері", - "localCannotOpenFolder": "Не вдається відкрити папку", - "localItemCount": "{{count}} елементів", - "localSelectedCount": "{{count}} вибрано", - "back": "Назад", - "forward": "Вперед", - "up": "Вгору", - "kind": "Вид", - "localUploadingProgress": "Завантаження {{current}} з {{total}}", - "localDownloadingProgress": "Завантаження {{current}} з {{total}}", - "localTransferInFlight": "{{count}} одразу", - "localPreparingDownload": "Підготовка завантаження...", - "localTransferCancelled": "Переказ скасовано", - "localNothingToTransfer": "Нічого для перенесення", - "localUploadComplete": "Завантажено {{count}} файл(ів)", - "localUploadFailed": "Не вдалося завантажити", - "localUploadPartial": "Завантажено {{done}} файл(ів), {{failed}} не вдалося", - "localDownloadComplete": "Завантажено {{count}} файл(ів)", - "localDownloadFailed": "Завантаження не вдалося", - "localDownloadPartial": "Завантажено {{done}} файл(ів), {{failed}} не вдалося", - "localReplaceExistingPrompt": "{{count}} елементів вже є в цій папці. Замінити їх?", - "localReplace": "Замінити", - "localSkipExisting": "Пропустити", - "localSkippedExisting": "Пропущено {{count}} існуючих елементів", - "localUnsafeNamesSkipped": "Пропущено {{count}} елементів, назви яких не можна використовувати на цьому комп’ютері", - "localOpen": "ВІДЧИНЕНО", - "localOpenFolder": "Відкрити папку", - "localUploadToRemote": "Завантажити на сервер", - "localUploadToRemoteMany": "Завантажити {{count}} елементів на сервер", - "localMoveToTrash": "Перемістити в кошик", - "localMoveToTrashMany": "Перемістити {{count}} елементів до кошика", - "localTrashConfirmSingle": "Перемістити \"{{name}}\" до кошика?", - "localTrashConfirmFolder": "Перемістити папку «{{name}}» та весь її вміст до кошика?", - "localTrashConfirmMany": "Перемістити {{count}} елементів до кошика?", - "localTrashed": "Переміщено {{count}} елементів до кошика", - "localTrashFailed": "Не вдалося перемістити в кошик", - "localRenameFailed": "Не вдалося перейменувати", - "localCreateFailed": "Не вдалося створити елемент", - "goToParentFolder": "Перейти до батьківської папки", - "resizeSidebar": "Перетягніть, щоб змінити розмір бічної панелі (двічі клацніть, щоб скинути налаштування)", - "resizeLocalPane": "Перетягніть, щоб змінити розмір локальної панелі (двічі клацніть, щоб скинути налаштування)", - "columns": "Колонки", - "columnsHint": "Клацніть правою кнопкою миші, щоб вибрати стовпці", - "emptyFolder": "Ця папка порожня", - "searchFiles": "Пошук файлів...", - "upload": "Завантажити", - "selectHostToStart": "Виберіть хост, щоб розпочати керування файлами", - "sshRequiredForFileManager": "Файловий менеджер вимагає SSH. На цьому хості SSH не ввімкнено.", - "failedToConnect": "Не вдалося підключитися до SSH", - "failedToLoadDirectory": "Не вдалося завантажити каталог", - "noSSHConnection": "SSH-з'єднання недоступне", - "copy": "Копіювати", - "cut": "Вирізати", - "paste": "Вставити", - "copyPath": "Копіювати шлях", - "copyPaths": "Копіювати шляхи", - "delete": "Видалити", - "properties": "Властивості", - "refresh": "Оновити", - "downloadFiles": "Завантажити {{count}} файлів у браузер", - "copyFiles": "Копіювати {{count}} елементів", - "cutFiles": "Вирізати {{count}} елементів", - "deleteFiles": "Видалити {{count}} елементів", - "filesCopiedToClipboard": "{{count}} елементів, скопійованих у буфер обміну", - "filesCutToClipboard": "{{count}} елементів, вирізаних у буфер обміну", - "pathCopiedToClipboard": "Шлях скопійовано в буфер обміну", - "pathsCopiedToClipboard": "{{count}} шляхів скопійовано в буфер обміну", - "failedToCopyPath": "Не вдалося скопіювати шлях до буфера обміну", - "copyFolderLink": "Копіювати посилання до папки", - "copyCurrentFolderLink": "Копіювати посилання до поточної папки", - "folderLinkCopied": "Посилання на папку скопійовано в буфер обміну", - "failedToCopyFolderLink": "Не вдалося скопіювати посилання на папку", - "movedItems": "Переміщено {{count}} елементів", - "failedToDeleteItem": "Не вдалося видалити елемент", - "itemRenamedSuccessfully": "{{type}} успішно перейменовано", - "failedToRenameItem": "Не вдалося перейменувати елемент", - "download": "Завантажити", - "openExternalEditor": "Відкрити зовні", - "chooseExternalEditor": "Виберіть зовнішнього редактора", - "externalEditorSelected": "Вибрано зовнішнього редактора", - "externalEditorDesktopOnly": "Зовнішній редактор доступний лише в настільній програмі", - "externalEditorOpened": "Відкрито в зовнішньому редакторі. Збереження там завантажить зміни назад на сервер.", - "failedToOpenExternalEditor": "Не вдалося відкрити зовнішній редактор", - "failedToSelectExternalEditor": "Не вдалося вибрати зовнішній редактор", - "permissions": "Дозволи", - "size": "Розмір", - "modified": "Змінено", - "path": "Шлях", - "confirmDelete": "Ви впевнені, що хочете видалити {{name}}?", - "permissionDenied": "Дозвіл відхилено", - "serverError": "Помилка сервера", - "fileSavedSuccessfully": "Файл успішно збережено", - "failedToSaveFile": "Не вдалося зберегти файл", - "confirmDeleteSingleItem": "Ви впевнені, що хочете остаточно видалити \"{{name}}\"?", - "confirmDeleteMultipleItems": "Ви впевнені, що хочете остаточно видалити {{count}} елементів?", - "confirmDeleteMultipleItemsWithFolders": "Ви впевнені, що хочете остаточно видалити {{count}} елементів? Це стосується папок та їхнього вмісту.", - "confirmDeleteFolder": "Ви впевнені, що хочете остаточно видалити папку «{{name}}» та весь її вміст?", - "permanentDeleteWarning": "Цю дію неможливо скасувати. Елемент(и) буде назавжди видалено із сервера.", - "moveToTrashWarning": "Елемент(и) буде переміщено до кошика Termix і може бути відновлено до закінчення терміну зберігання.", - "itemsMovedToTrash": "{{count}} елементів переміщено до кошика", - "trash": "Сміття", - "trashDescription": "Видалені елементи зберігаються на цьому хості протягом {{days}} днів.", - "trashLoadFailed": "Не вдалося завантажити кошик", - "trashEmpty": "Кошик порожній", - "trashRestore": "Відновити", - "trashRestored": "Відновлено {{name}}", - "trashRestoreFailed": "Не вдалося відновити елемент. Можливо, початковий шлях уже існує.", - "trashDeletePermanently": "Видалити назавжди", - "trashDeleteConfirm": "Видалити {{name}}назавжди? Цю дію не можна скасувати.", - "trashPermanentlyDeleted": "Видалено назавжди {{name}}", - "trashDeleteFailed": "Не вдалося остаточно видалити елемент", - "trashEmptyAction": "Очистити кошик", - "trashEmptyConfirm": "Видалити всі елементи з кошика назавжди? Цю дію не можна скасувати.", - "trashEmptied": "Кошик очищено", - "trashRetention": "Автоматичне очищення через (дні)", - "trashRetentionSaved": "Зберігання в кошику оновлено", - "trashRetentionFailed": "Не вдалося оновити налаштування зберігання в кошику", - "trashUnavailableConfirm": "Цей елемент не можна перемістити до кошика, зазвичай тому, що він знаходиться в іншій файловій системі або потребує підвищених прав. Видалити його назавжди?", - "recent": "Нещодавні", - "pinned": "Закріплено", - "folderShortcuts": "Ярлики папок", - "failedToReconnectSSH": "Не вдалося відновити сеанс SSH", - "openTerminalHere": "Відкрити термінал тут", - "run": "Бігти", - "openTerminalInFolder": "Відкрити термінал у цій папці", - "openTerminalInFileLocation": "Відкрити термінал у місці розташування файлу", - "runningFile": "Біг – {{file}}", - "onlyRunExecutableFiles": "Можна запускати лише виконувані файли", - "directories": "Довідники", - "removedFromRecentFiles": "Видалено \"{{name}}\" з останніх файлів", - "removeFailed": "Видалити не вдалося", - "unpinnedSuccessfully": "Відкріплено \"{{name}}\" успішно", - "unpinFailed": "Не вдалося відкріпити", - "removedShortcut": "Видалено ярлик «{{name}}»", - "removeShortcutFailed": "Не вдалося видалити ярлик", - "clearedAllRecentFiles": "Очищено всі нещодавні файли", - "clearFailed": "Очистити не вдалося", - "removeFromRecentFiles": "Видалити з останніх файлів", - "clearAllRecentFiles": "Очистити всі нещодавні файли", - "unpinFile": "Відкріпити файл", - "removeShortcut": "Видалити ярлик", - "pinFile": "Закріпити файл", - "addToShortcuts": "Додати до ярликів", - "pasteFailed": "Вставити не вдалося", - "noUndoableActions": "Немає дій, які можна скасувати", - "undoCopySuccess": "Скасовано копіювання: Видалено {{count}} скопійованих файлів", - "undoCopyFailedDelete": "Не вдалося скасувати: не вдалося видалити жодного скопійованого файлу", - "undoCopyFailedNoInfo": "Не вдалося скасувати: не вдалося знайти інформацію про скопійований файл", - "undoMoveSuccess": "Скасовано операцію переміщення: {{count}} файлів переміщено назад у початкове розташування", - "undoMoveFailedMove": "Не вдалося скасувати: не вдалося перемістити жодного файлу назад", - "undoMoveFailedNoInfo": "Не вдалося скасувати: не вдалося знайти інформацію про переміщений файл", - "undoDeleteNotSupported": "Операцію видалення неможливо скасувати: файли остаточно видалено із сервера", - "undoTypeNotSupported": "Непідтримуваний тип операції скасування", - "undoOperationFailed": "Не вдалося скасувати операцію", - "unknownError": "Невідома помилка", - "confirm": "Підтвердити", - "find": "Знайти...", - "replace": "Замінити", - "downloadInstead": "Завантажити замість цього", - "keyboardShortcuts": "Комбінації клавіш", - "searchAndReplace": "Пошук і заміна", - "editing": "Редагування", - "search": "Пошук", - "findNext": "Знайти далі", - "findPrevious": "Знайти попередній", - "save": "Зберегти", - "selectAll": "Вибрати все", - "undo": "Скасувати", - "redo": "Повторити", - "moveLineUp": "Перемістити лінію вгору", - "moveLineDown": "Перемістити рядок вниз", - "toggleComment": "Перемикач коментарів", - "autoComplete": "Автоматичне завершення", - "imageLoadError": "Не вдалося завантажити зображення", - "startTyping": "Почніть друкувати...", - "unknownSize": "Невідомий розмір", - "fileIsEmpty": "Файл порожній", - "largeFileWarning": "Попередження про великий файл", - "largeFileWarningDesc": "Розмір цього файлу становить {{size}} , що може спричинити проблеми з продуктивністю під час відкриття його як тексту.", - "fileNotFoundAndRemoved": "Файл «{{name}}» не знайдено та видалено з нещодавніх/закріплених файлів", - "failedToLoadFile": "Не вдалося завантажити файл: {{error}}", - "serverErrorOccurred": "Сталася помилка сервера. Будь ласка, спробуйте пізніше.", - "autoSaveFailed": "Не вдалося автоматично зберегти", - "fileAutoSaved": "Файл автоматично збережено", - "moveFileFailed": "Не вдалося перемістити {{name}}", - "moveOperationFailed": "Не вдалося перемістити", - "canOnlyCompareFiles": "Можна порівняти лише два файли", - "comparingFiles": "Порівняння файлів: {{file1}} та {{file2}}", - "dragFailed": "Не вдалося перетягнути", - "filePinnedSuccessfully": "Файл «{{name}}» успішно закріплено", - "pinFileFailed": "Не вдалося закріпити файл", - "fileUnpinnedSuccessfully": "Файл «{{name}}» успішно відкріплено", - "unpinFileFailed": "Не вдалося відкріпити файл", - "shortcutAddedSuccessfully": "Ярлик папки «{{name}}» успішно додано", - "addShortcutFailed": "Не вдалося додати ярлик", - "operationCompletedSuccessfully": "{{operation}} {{count}} елементів успішно", - "operationCompleted": "{{operation}} {{count}} елементів", - "downloadFileSuccess": "Файл {{name}} успішно завантажено", - "downloadFileFailed": "Завантаження не вдалося", - "downloadingFile": "Завантаження {{name}}…", - "downloadProgressBytes": "{{transferred}} / {{total}}", - "moveTo": "Перейти до {{name}}", - "diffCompareWith": "Різниця у порівнянні з {{name}}", - "dragOutsideToDownload": "Перетягніть за межі вікна, щоб завантажити ({{count}} файлів)", - "newFolderDefault": "НоваПапка", - "newFileDefault": "НовийФайл.txt", - "successfullyMovedItems": "Елементів {{count}} успішно переміщено до {{target}}", - "move": "Перемістити", - "searchInFile": "Пошук у файлі (Ctrl+F)", - "showKeyboardShortcuts": "Показати комбінації клавіш", - "decreaseFontSize": "Зменшити розмір шрифту", - "increaseFontSize": "Збільшити розмір шрифту", - "startWritingMarkdown": "Почніть писати свій контент у форматі Markdown...", - "loadingFileComparison": "Завантаження порівняння файлів...", - "reload": "Перезавантажити", - "compare": "Порівняти", - "sideBySide": "Пліч-о-пліч", - "inline": "Вбудований", - "fileComparison": "Порівняння файлів: {{file1}} проти {{file2}}", - "fileTooLarge": "Файл занадто великий: {{error}}", - "sshConnectionFailed": "Помилка SSH-з’єднання. Будь ласка, перевірте ваше з’єднання з {{name}} ({{ip}}:{{port}})", - "loadFileFailed": "Не вдалося завантажити файл: {{error}}", - "connecting": "Підключення...", - "connectedSuccessfully": "Підключено успішно", - "totpVerificationFailed": "Не вдалося перевірити TOTP", - "authenticationFailed": "Помилка автентифікації", - "incorrectPassphrase": "Неправильна парольна фраза. Спробуйте ще раз.", - "verificationCodePrompt": "Код підтвердження:", - "changePermissions": "Змінити дозволи", - "currentPermissions": "Поточні дозволи", - "owner": "Власник", - "group": "Група", - "others": "Інші", - "read": "Читати", - "write": "Написати", - "execute": "Виконати", - "permissionsChangedSuccessfully": "Дозволи успішно змінено", - "failedToChangePermissions": "Не вдалося змінити дозволи", - "name": "Ім'я", - "sortByName": "Ім'я", - "sortByDate": "Дата зміни", - "sortBySize": "Розмір", - "ascending": "Зростаючий", - "descending": "Спадання", - "root": "Корінь", - "new": "Новий", - "sortBy": "Сортувати за", - "items": "Елементи", - "selected": "Вибрано", - "editor": "Редактор", - "octal": "Вісімкове", - "storage": "Зберігання", - "disk": "Диск", - "used": "Використано", - "of": "з", - "toggleSidebar": "Перемикання бічної панелі", - "compactLayout": "Використовуйте компактний макет", - "comfortableLayout": "Використовуйте зручний макет", - "cannotLoadPdf": "Не вдається завантажити PDF", - "pdfLoadError": "Під час завантаження цього PDF-файлу сталася помилка.", - "loadingPdf": "Завантаження PDF-файлу...", - "loadingPage": "Завантаження сторінки..." + "nav": { + "files": "Files", + "sftp": "SFTP", + "openFileManager": "Open File Manager" }, - "sftpTransfer": { - "title": "SFTP", - "description": "Передача файлів між двома SSH-хостами.", - "sourceServer": "Вихідний сервер", - "destinationServer": "Цільовий сервер", - "selectHost": "Виберіть хоста", - "noHostSelected": "Хост не вибрано", - "move": "Перемістити", - "copy": "Копіювати", - "upload": "Завантажити", - "itemsSelected": "Вибрано елемент {{count}}", - "itemsSelected_other": "Вибрано {{count}} елементів", - "ready": "Готовий", - "loadingHosts": "Завантаження хостів...", - "name": "Ім'я", - "modified": "Змінено", - "size": "Розмір", - "noFiles": "Немає файлів", - "open": "ВІДЧИНЕНО", - "up": "Вгору", - "refresh": "Оновити", - "copyToTarget": "Копіювати до цільового каталогу", - "rename": "Перейменувати", - "delete": "Видалити", - "editPermissions": "Редагувати дозволи", - "createNewFolder": "Створити нову папку", - "deleteSelectedItems": "Видалити вибрані елементи", - "deleteConfirm": "Видалити {{count}} вибраний елемент?", - "deleteConfirm_other": "Видалити {{count}} вибраних елементів?", - "cancel": "Скасувати", - "save": "Зберегти", - "folderCreated": "Папку створено", - "itemRenamed": "Елемент перейменовано", - "actionFailed": "Дія не вдалася", - "itemsDeleted": "{{count}} елемент видалено", - "itemsDeleted_other": "{{count}} елементів видалено", - "deleteFailed": "Видалити не вдалося", - "permissionsUpdated": "Дозволи оновлено", - "noRemoteSessionConnected": "Немає підключеного віддаленого сеансу", - "failedToListFiles": "Не вдалося переглянути файли", - "failedToRefresh": "Не вдалося оновити", - "destinationInsideSource": "Пункт призначення не може бути всередині вибраного вихідного шляху.", - "sameHostNoOp": "Джерело та призначення – це одна й та сама папка." - }, - "hosts": { - "fileManager": "Файловий менеджер", - "tabFiles": "Файли", - "enableFileManagerMonitor": "Увімкнути файловий менеджер", - "enableFileManagerMonitorDesc": "Переглядайте та керуйте файлами на цьому хості через SFTP", - "scpLegacyLabel": "Застарілий режим SCP", - "scpLegacyDesc": "Використовуйте застарілу передачу файлів для серверів, які не підтримують підсистему SFTP (наприклад, вбудовані або мінімальні SSH-сервери).", - "defaultPathLabel": "Шлях за замовчуванням", - "fileManagerPathHint": "Каталог, який потрібно відкрити під час запуску файлового менеджера для цього хоста.", - "fileManagerUrlCopied": "URL-адресу файлового менеджера скопійовано", - "copyFileManagerUrlAction": "Копіювати URL-адресу файлового менеджера", - "docsLink": "Переглянути документи", - "hostNotFound": "Хост не знайдено", - "loadingHost": "Завантаження хоста..." + "permissions": { + "use": { + "title": "Use file manager", + "description": "Browse, edit and transfer files over SFTP." + } }, "settings": { "host": { "enable": { - "label": "Увімкнути файловий менеджер" + "label": "Enable File Manager", + "description": "Browse and edit files on this host over SFTP." }, "defaultPath": { - "label": "Шлях за замовчуванням" + "label": "Default Path" }, "scpLegacy": { - "label": "Застарілий режим SCP" + "label": "SCP Legacy Mode" } }, "user": { "transferConcurrency": { - "label": "Одночасна передача файлів", - "description": "Скільки файлів одночасно завантажує або вивантажує локальний/віддалений менеджер. Зменште це значення, якщо ваш сервер обмежує кількість каналів SFTP." + "label": "Simultaneous File Transfers", + "description": "How many files the side by side local/remote manager uploads or downloads at the same time. Lower this if your server limits SFTP channels." + }, + "confirmBeforeTrash": { + "label": "Confirm before moving files to trash", + "description": "Ask before moving remote files to trash. Permanent deletion still requires confirmation." } } }, - "nav": { - "sftp": "SFTP", - "files": "Файли" + "hostCapability": { + "label": "File Manager" + }, + "fileManager": { + "noHostSelected": "No host selected", + "initializingEditor": "Initializing editor...", + "file": "File", + "folder": "Folder", + "uploadFile": "Upload File", + "downloadFile": "Download", + "extractArchive": "Extract Archive", + "extractingArchive": "Extracting {{name}}...", + "archiveExtractedSuccessfully": "{{name}} extracted successfully", + "extractFailed": "Extract failed", + "compressFile": "Compress File", + "compressFiles": "Compress Files", + "compressFilesDesc": "Compress {{count}} items into an archive", + "archiveName": "Archive Name", + "enterArchiveName": "Enter archive name...", + "compressionFormat": "Compression Format", + "selectedFiles": "Selected files", + "andMoreFiles": "and {{count}} more...", + "compress": "Compress", + "compressingFiles": "Compressing {{count}} items into {{name}}...", + "filesCompressedSuccessfully": "{{name}} created successfully", + "compressFailed": "Compression failed", + "edit": "Edit", + "preview": "Preview", + "previous": "Previous", + "next": "Next", + "pageXOfY": "Page {{current}} of {{total}}", + "zoomOut": "Zoom Out", + "zoomIn": "Zoom In", + "newFile": "New File", + "newFolder": "New Folder", + "rename": "Rename", + "uploading": "Uploading...", + "uploadingFile": "Uploading {{name}}...", + "uploadingChunk": "Uploading {{name}}: {{percent}}% (part {{chunk}} of {{total}})", + "fileName": "File Name", + "folderName": "Folder Name", + "fileUploadedSuccessfully": "File \"{{name}}\" uploaded successfully", + "failedToUploadFile": "Failed to upload file", + "uploadingFolderFiles": "Uploading {{count}} file(s)...", + "uploadedFolderFiles": "Uploaded {{count}} file(s) successfully", + "uploadedFolderPartial": "Uploaded {{uploaded}} file(s), {{failed}} failed", + "fileDownloadedSuccessfully": "File \"{{name}}\" downloaded successfully", + "failedToDownloadFile": "Failed to download file", + "fileCreatedSuccessfully": "File \"{{name}}\" created successfully", + "folderCreatedSuccessfully": "Folder \"{{name}}\" created successfully", + "failedToCreateItem": "Failed to create item", + "operationFailed": "{{operation}} operation failed for {{name}}: {{error}}", + "failedToResolveSymlink": "Failed to resolve symlink", + "itemsDeletedSuccessfully": "{{count}} items deleted successfully", + "failedToDeleteItems": "Failed to delete items", + "sudoPasswordRequired": "Administrator Password Required", + "enterSudoPassword": "Enter sudo password to continue this operation", + "sudoPassword": "Sudo password", + "sudoOperationFailed": "Sudo operation failed", + "sudoAuthFailed": "Sudo authentication failed", + "dragFilesToUpload": "Drop files here to upload", + "dropToUploadHere": "Drop to upload here", + "dropToDownloadHere": "Drop to download here", + "localFiles": "Local", + "showLocalFiles": "Show local files (split view)", + "hideLocalFiles": "Hide local files", + "localHome": "Home folder", + "localPathPlaceholder": "Local folder path", + "localShowHidden": "Show hidden files", + "localHideHidden": "Hide hidden files", + "localRevealInFileManager": "Reveal in system file manager", + "localCannotOpenFolder": "Cannot open folder", + "localItemCount": "{{count}} items", + "localSelectedCount": "{{count}} selected", + "back": "Back", + "forward": "Forward", + "up": "Up", + "kind": "Kind", + "localUploadingProgress": "Uploading {{current}} of {{total}}", + "localDownloadingProgress": "Downloading {{current}} of {{total}}", + "localTransferInFlight": "{{count}} at once", + "localPreparingDownload": "Preparing download...", + "localTransferCancelled": "Transfer cancelled", + "localNothingToTransfer": "Nothing to transfer", + "localUploadComplete": "Uploaded {{count}} file(s)", + "localUploadFailed": "Upload failed", + "localUploadPartial": "Uploaded {{done}} file(s), {{failed}} failed", + "localDownloadComplete": "Downloaded {{count}} file(s)", + "localDownloadFailed": "Download failed", + "localDownloadPartial": "Downloaded {{done}} file(s), {{failed}} failed", + "localReplaceExistingPrompt": "{{count}} item(s) already exist in this folder. Replace them?", + "localReplace": "Replace", + "localSkipExisting": "Skip", + "localSkippedExisting": "Skipped {{count}} existing item(s)", + "localUnsafeNamesSkipped": "Skipped {{count}} item(s) whose names cannot be used on this computer", + "localOpen": "Open", + "localOpenFolder": "Open folder", + "localUploadToRemote": "Upload to server", + "localUploadToRemoteMany": "Upload {{count}} items to server", + "localMoveToTrash": "Move to Trash", + "localMoveToTrashMany": "Move {{count}} items to Trash", + "localTrashConfirmSingle": "Move \"{{name}}\" to the Trash?", + "localTrashConfirmFolder": "Move the folder \"{{name}}\" and all its contents to the Trash?", + "localTrashConfirmMany": "Move {{count}} items to the Trash?", + "localTrashed": "Moved {{count}} item(s) to the Trash", + "localTrashFailed": "Could not move to the Trash", + "localRenameFailed": "Rename failed", + "localCreateFailed": "Could not create item", + "goToParentFolder": "Go to parent folder", + "resizeSidebar": "Drag to resize the sidebar (double-click to reset)", + "resizeLocalPane": "Drag to resize the local pane (double-click to reset)", + "columns": "Columns", + "columnsHint": "Right-click to choose columns", + "emptyFolder": "This folder is empty", + "searchFiles": "Search files...", + "upload": "Upload", + "selectHostToStart": "Select a host to start file management", + "sshRequiredForFileManager": "File manager requires SSH. This host does not have SSH enabled.", + "failedToConnect": "Failed to connect to SSH", + "failedToLoadDirectory": "Failed to load directory", + "noSSHConnection": "No SSH connection available", + "copy": "Copy", + "cut": "Cut", + "paste": "Paste", + "copyPath": "Copy Path", + "copyPaths": "Copy Paths", + "delete": "Delete", + "properties": "Properties", + "refresh": "Refresh", + "downloadFiles": "Download {{count}} files to Browser", + "copyFiles": "Copy {{count}} items", + "cutFiles": "Cut {{count}} items", + "deleteFiles": "Delete {{count}} items", + "filesCopiedToClipboard": "{{count}} items copied to clipboard", + "filesCutToClipboard": "{{count}} items cut to clipboard", + "pathCopiedToClipboard": "Path copied to clipboard", + "pathsCopiedToClipboard": "{{count}} paths copied to clipboard", + "failedToCopyPath": "Failed to copy path to clipboard", + "copyFolderLink": "Copy Link to Folder", + "copyCurrentFolderLink": "Copy Link to Current Folder", + "folderLinkCopied": "Folder link copied to clipboard", + "failedToCopyFolderLink": "Failed to copy folder link", + "movedItems": "Moved {{count}} items", + "failedToDeleteItem": "Failed to delete item", + "itemRenamedSuccessfully": "{{type}} renamed successfully", + "failedToRenameItem": "Failed to rename item", + "download": "Download", + "openExternalEditor": "Open externally", + "chooseExternalEditor": "Choose external editor", + "externalEditorSelected": "External editor selected", + "externalEditorDesktopOnly": "External editor is only available in the desktop app", + "externalEditorOpened": "Opened in external editor. Saving there will upload changes back to the server.", + "failedToOpenExternalEditor": "Failed to open external editor", + "failedToSelectExternalEditor": "Failed to select external editor", + "permissions": "Permissions", + "size": "Size", + "modified": "Modified", + "path": "Path", + "confirmDelete": "Are you sure you want to delete {{name}}?", + "permissionDenied": "Permission denied", + "serverError": "Server Error", + "fileSavedSuccessfully": "File saved successfully", + "failedToSaveFile": "Failed to save file", + "confirmDeleteSingleItem": "Are you sure you want to permanently delete \"{{name}}\"?", + "confirmDeleteMultipleItems": "Are you sure you want to permanently delete {{count}} items?", + "confirmDeleteMultipleItemsWithFolders": "Are you sure you want to permanently delete {{count}} items? This includes folders and their contents.", + "confirmDeleteFolder": "Are you sure you want to permanently delete the folder \"{{name}}\" and all its contents?", + "permanentDeleteWarning": "This action cannot be undone. The item(s) will be permanently deleted from the server.", + "moveToTrashWarning": "The item(s) will be moved to the Termix Trash and can be restored before the retention period expires.", + "itemsMovedToTrash": "{{count}} item(s) moved to Trash", + "trash": "Trash", + "trashDescription": "Deleted items are retained for {{days}} day(s) on this host.", + "trashLoadFailed": "Failed to load Trash", + "trashEmpty": "Trash is empty", + "trashRestore": "Restore", + "trashRestored": "Restored {{name}}", + "trashRestoreFailed": "Failed to restore item. The original path may already exist.", + "trashDeletePermanently": "Delete permanently", + "trashDeleteConfirm": "Permanently delete {{name}}? This cannot be undone.", + "trashPermanentlyDeleted": "Permanently deleted {{name}}", + "trashDeleteFailed": "Failed to permanently delete item", + "trashEmptyAction": "Empty Trash", + "trashEmptyConfirm": "Permanently delete every item in Trash? This cannot be undone.", + "trashEmptied": "Trash emptied", + "trashRetention": "Automatic cleanup after (days)", + "trashRetentionSaved": "Trash retention updated", + "trashRetentionFailed": "Failed to update Trash retention", + "trashUnavailableConfirm": "This item cannot be moved to Trash, usually because it is on another filesystem or requires elevated permissions. Delete it permanently instead?", + "recent": "Recent", + "pinned": "Pinned", + "folderShortcuts": "Folder Shortcuts", + "failedToReconnectSSH": "Failed to reconnect SSH session", + "openTerminalHere": "Open Terminal Here", + "run": "Run", + "openTerminalInFolder": "Open Terminal in This Folder", + "openTerminalInFileLocation": "Open Terminal at File Location", + "runningFile": "Running - {{file}}", + "onlyRunExecutableFiles": "Can only run executable files", + "directories": "Directories", + "removedFromRecentFiles": "Removed \"{{name}}\" from recent files", + "removeFailed": "Remove failed", + "unpinnedSuccessfully": "Unpinned \"{{name}}\" successfully", + "unpinFailed": "Unpin failed", + "removedShortcut": "Removed shortcut \"{{name}}\"", + "removeShortcutFailed": "Remove shortcut failed", + "clearedAllRecentFiles": "Cleared all recent files", + "clearFailed": "Clear failed", + "removeFromRecentFiles": "Remove from recent files", + "clearAllRecentFiles": "Clear all recent files", + "unpinFile": "Unpin file", + "removeShortcut": "Remove shortcut", + "pinFile": "Pin file", + "addToShortcuts": "Add to shortcuts", + "pasteFailed": "Paste failed", + "noUndoableActions": "No undoable actions", + "undoCopySuccess": "Undid copy operation: Deleted {{count}} copied files", + "undoCopyFailedDelete": "Undo failed: Could not delete any copied files", + "undoCopyFailedNoInfo": "Undo failed: Could not find copied file information", + "undoMoveSuccess": "Undid move operation: Moved {{count}} files back to original location", + "undoMoveFailedMove": "Undo failed: Could not move any files back", + "undoMoveFailedNoInfo": "Undo failed: Could not find moved file information", + "undoDeleteNotSupported": "Delete operation cannot be undone: Files have been permanently deleted from server", + "undoTypeNotSupported": "Unsupported undo operation type", + "undoOperationFailed": "Undo operation failed", + "unknownError": "Unknown error", + "confirm": "Confirm", + "find": "Find...", + "replace": "Replace", + "downloadInstead": "Download Instead", + "keyboardShortcuts": "Keyboard Shortcuts", + "searchAndReplace": "Search & Replace", + "editing": "Editing", + "search": "Search", + "findNext": "Find Next", + "findPrevious": "Find Previous", + "save": "Save", + "selectAll": "Select All", + "undo": "Undo", + "redo": "Redo", + "moveLineUp": "Move Line Up", + "moveLineDown": "Move Line Down", + "toggleComment": "Toggle Comment", + "autoComplete": "Auto Complete", + "imageLoadError": "Failed to load image", + "startTyping": "Start typing...", + "unknownSize": "Unknown size", + "fileIsEmpty": "File is empty", + "largeFileWarning": "Large File Warning", + "largeFileWarningDesc": "This file is {{size}} in size, which may cause performance issues when opened as text.", + "fileNotFoundAndRemoved": "File \"{{name}}\" not found and has been removed from recent/pinned files", + "failedToLoadFile": "Failed to load file: {{error}}", + "serverErrorOccurred": "Server error occurred. Please try again later.", + "autoSaveFailed": "Auto-save failed", + "fileAutoSaved": "File auto-saved", + "moveFileFailed": "Failed to move {{name}}", + "moveOperationFailed": "Move operation failed", + "canOnlyCompareFiles": "Can only compare two files", + "comparingFiles": "Comparing files: {{file1}} and {{file2}}", + "dragFailed": "Drag operation failed", + "filePinnedSuccessfully": "File \"{{name}}\" pinned successfully", + "pinFileFailed": "Failed to pin file", + "fileUnpinnedSuccessfully": "File \"{{name}}\" unpinned successfully", + "unpinFileFailed": "Failed to unpin file", + "shortcutAddedSuccessfully": "Folder shortcut \"{{name}}\" added successfully", + "addShortcutFailed": "Failed to add shortcut", + "operationCompletedSuccessfully": "{{operation}} {{count}} items successfully", + "operationCompleted": "{{operation}} {{count}} items", + "downloadFileSuccess": "File {{name}} downloaded successfully", + "downloadFileFailed": "Download failed", + "downloadingFile": "Downloading {{name}}…", + "downloadProgressBytes": "{{transferred}} / {{total}}", + "moveTo": "Move to {{name}}", + "diffCompareWith": "Diff compare with {{name}}", + "dragOutsideToDownload": "Drag outside window to download ({{count}} files)", + "newFolderDefault": "NewFolder", + "newFileDefault": "NewFile.txt", + "successfullyMovedItems": "Successfully moved {{count}} items to {{target}}", + "move": "Move", + "searchInFile": "Search in file (Ctrl+F)", + "showKeyboardShortcuts": "Show keyboard shortcuts", + "decreaseFontSize": "Decrease font size", + "increaseFontSize": "Increase font size", + "startWritingMarkdown": "Start writing your markdown content...", + "loadingFileComparison": "Loading file comparison...", + "reload": "Reload", + "compare": "Compare", + "sideBySide": "Side by Side", + "inline": "Inline", + "fileComparison": "File Comparison: {{file1}} vs {{file2}}", + "fileTooLarge": "File too large: {{error}}", + "sshConnectionFailed": "SSH connection failed. Please check your connection to {{name}} ({{ip}}:{{port}})", + "loadFileFailed": "Failed to load file: {{error}}", + "connecting": "Connecting...", + "connectedSuccessfully": "Connected successfully", + "totpVerificationFailed": "TOTP verification failed", + "browserSignInFailed": "Sign-in failed. Please try again.", + "authenticationFailed": "Authentication failed", + "incorrectPassphrase": "Incorrect passphrase. Please try again.", + "verificationCodePrompt": "Verification code:", + "changePermissions": "Change Permissions", + "currentPermissions": "Current Permissions", + "owner": "Owner", + "group": "Group", + "others": "Others", + "read": "Read", + "write": "Write", + "execute": "Execute", + "permissionsChangedSuccessfully": "Permissions changed successfully", + "failedToChangePermissions": "Failed to change permissions", + "name": "Name", + "sortByName": "Name", + "sortByDate": "Date Modified", + "sortBySize": "Size", + "ascending": "Ascending", + "descending": "Descending", + "root": "Root", + "new": "New", + "sortBy": "Sort By", + "items": "Items", + "selected": "Selected", + "editor": "Editor", + "octal": "Octal", + "storage": "Storage", + "disk": "Disk", + "used": "Used", + "of": "of", + "toggleSidebar": "Toggle Sidebar", + "compactLayout": "Use compact layout", + "comfortableLayout": "Use comfortable layout", + "cannotLoadPdf": "Cannot load PDF", + "pdfLoadError": "There was an error loading this PDF file.", + "loadingPdf": "Loading PDF...", + "loadingPage": "Loading page...", + "cancel": "Cancel", + "copiedItems_one": "Copied {{count}} item", + "copiedItems_other": "Copied {{count}} items", + "deleteCopiedFileFailed": "Could not delete the copy of {{name}}: {{error}}", + "dragMovedItems_one": "Moved {{count}} item to {{target}}", + "dragMovedItems_other": "Moved {{count}} items to {{target}}", + "moveBackFileFailed": "Could not move {{name}} back: {{error}}", + "terminal": "Terminal: {{host}} ({{path}})", + "dragToDesktop": "Dragging {{name}} to the desktop", + "dragFilesToDesktop": "Dragging {{count}} files to the desktop", + "folderDragUnsupported": "Dragging folders to the desktop is not supported yet", + "saveToDesktopFailed": "Save failed: {{error}}", + "dragFailedDetail": "Drag failed: {{error}}", + "videoUnsupported": "Your browser cannot play this video format.", + "downloadToPlay": "Download to play it elsewhere", + "cannotPreviewType": "Cannot preview this file type", + "cannotPreviewTypeHint": "This file type has no preview. Download it to open it in another app." + }, + "sftpTransfer": { + "title": "SFTP", + "description": "Transfer files between two SSH hosts.", + "sourceServer": "Source Server", + "destinationServer": "Destination Server", + "selectHost": "Select host", + "noHostSelected": "No host selected", + "move": "Move", + "copy": "Copy", + "upload": "Upload", + "itemsSelected": "{{count}} item selected", + "itemsSelected_other": "{{count}} items selected", + "ready": "Ready", + "loadingHosts": "Loading hosts...", + "name": "Name", + "modified": "Modified", + "size": "Size", + "noFiles": "No files", + "open": "Open", + "up": "Up", + "refresh": "Refresh", + "copyToTarget": "Copy to Target Directory", + "rename": "Rename", + "delete": "Delete", + "editPermissions": "Edit Permissions", + "createNewFolder": "Create New Folder", + "deleteSelectedItems": "Delete Selected Items", + "deleteConfirm": "Delete {{count}} selected item?", + "deleteConfirm_other": "Delete {{count}} selected items?", + "cancel": "Cancel", + "save": "Save", + "folderCreated": "Folder created", + "itemRenamed": "Item renamed", + "actionFailed": "Action failed", + "itemsDeleted": "{{count}} item deleted", + "itemsDeleted_other": "{{count}} items deleted", + "deleteFailed": "Delete failed", + "permissionsUpdated": "Permissions updated", + "noRemoteSessionConnected": "No remote session connected", + "failedToListFiles": "Failed to list files", + "failedToRefresh": "Failed to refresh", + "destinationInsideSource": "Destination cannot be inside the selected source path.", + "sameHostNoOp": "Source and destination are the same folder." + }, + "hosts": { + "fileManager": "File Manager", + "fileManagerUrlCopied": "File Manager URL copied", + "copyFileManagerUrlAction": "Copy File Manager URL", + "docsLink": "View docs", + "hostNotFound": "Host not found", + "loadingHost": "Loading host..." }, "onboarding": { - "feature_files": "Файловий менеджер", - "feature_files_desc": "Переглядайте, завантажуйте, вивантажуйте та редагуйте файли через SFTP, не виходячи з програми." + "feature_files": "File manager", + "feature_files_desc": "Browse, upload, download and edit files over SFTP without leaving the app." }, "terminal": { - "runTitle": "Запуск {{command}} - {{host}}", - "terminalTitle": "Термінал - {{host}}", - "terminalWithPath": "Термінал - {{host}}:{{path}}" + "runTitle": "Running {{command}} - {{host}}", + "terminalTitle": "Terminal - {{host}}", + "terminalWithPath": "Terminal - {{host}}:{{path}}" }, "transfer": { - "browseFolders": "Перегляд папок призначення", - "browsePathError": "Не вдалося відкрити цей шлях на хості призначення.", - "browsePathWillBeCreated": "Цієї папки ще не існує. Вона буде створена, коли розпочнеться передача.", - "cancel": "Скасувати", - "cleanupDestFiles": "Прибирання місця призначення", - "cleanupDestFilesError": "Очищення не вдалося", - "cleanupDestFilesNothing": "Нічого прибирати на місці призначення", - "cleanupDestFilesPartial": "Не вдалося видалити деякі часткові файли", - "cleanupDestFilesSuccess": "Видалено часткові файли з місця призначення", - "confirmCopy": "Копіювати", - "confirmMove": "Перемістити", - "copyFolderToHost": "Копіювати папку на хост…", - "copyItemsToHost": "Копіювати елементи {{count}} для розміщення…", - "copyToHost": "Копіювати на хост…", - "destinationPath": "Шлях призначення", - "destMustBeDirectory": "Для перенесення кількох елементів місцем призначення має бути каталог", - "goUp": "Піднімися", - "hostAuthRequired": "Потрібна автентифікація — спочатку відкрийте Файловий менеджер на цьому хості", - "hostConnecting": "Підключення…", - "hostConnectionFailed": "Помилка підключення", - "hostDisconnected": "Не підключено", - "hostReady": "Готовий", - "itemsSummary": "{{count}} елементів", - "jumpHostLimitation": "Обидва хости мають бути доступні з сервера Termix. Пряма маршрутизація між хостами не підтримується.", - "methodAuto": "Авто", - "methodAutoHint": "Вибирає tar-файл або SFTP для кожного файлу на основі кількості файлів, розміру та стискальності. Окремі файли завжди використовують потоковий SFTP.", - "methodItemSftp": "SFTP для кожного файлу", - "methodItemSftpHint": "Передавайте кожен файл окремо через SFTP. Працює на всіх хостах, включаючи Windows.", - "methodItemSftpLimitation": "Кожен файл використовує той самий потік SFTP, що й копія окремого файлу, послідовно. Прогрес об'єднується для всіх файлів, тому шкала рухається повільно під час роботи з великими файлами.", - "methodLabel": "Спосіб переказу", - "methodPreviewError": "Не вдалося переглянути метод передачі. Сервер все одно вибере метод під час запуску.", - "methodPreviewLoading": "Розрахунок методу переказу…", - "methodPreviewScanSummary": "{{fileCount}} файлів, {{totalSize}} всього (проскановано на вихідному хості).", - "methodPreviewWillUseItemSftp": "Буде використовуватися: SFTP для кожного файлу", - "methodPreviewWillUseTar": "Буде використано: архів Tar", + "browseFolders": "Browse destination folders", + "browsePathError": "Could not open this path on the destination host.", + "browsePathWillBeCreated": "This folder does not exist yet. It will be created when the transfer starts.", + "cancel": "Cancel", + "cleanupDestFiles": "Clean up destination", + "cleanupDestFilesError": "Cleanup failed", + "cleanupDestFilesNothing": "Nothing to clean up on the destination", + "cleanupDestFilesPartial": "Some partial files could not be removed", + "cleanupDestFilesSuccess": "Removed partial files from the destination", + "confirmCopy": "Copy", + "confirmMove": "Move", + "copyFolderToHost": "Copy folder to host…", + "copyItemsToHost": "Copy {{count}} items to host…", + "copyToHost": "Copy to host…", + "destinationPath": "Destination path", + "destMustBeDirectory": "Destination must be a directory for multi-item transfers", + "goUp": "Go up", + "hostAuthRequired": "Authentication required. Open File Manager on this host first", + "hostConnecting": "Connecting…", + "hostConnectionFailed": "Connection failed", + "hostDisconnected": "Not connected", + "hostReady": "Ready", + "itemsSummary": "{{count}} items", + "jumpHostLimitation": "Both hosts must be reachable from the Termix server. Direct host-to-host routing is not supported.", + "methodAuto": "Auto", + "methodAutoHint": "Picks tar or per-file SFTP based on file count, size, and compressibility. Single files always use streaming SFTP.", + "methodItemSftp": "Per-file SFTP", + "methodItemSftpHint": "Transfer each file individually over SFTP. Works on all hosts including Windows.", + "methodItemSftpLimitation": "Each file uses the same SFTP stream as a single-file copy, one after another. Progress is combined across all files, so the bar moves slowly during large files.", + "methodLabel": "Transfer method", + "methodPreviewError": "Could not preview transfer method. The server will still pick a method when you start.", + "methodPreviewLoading": "Calculating transfer method…", + "methodPreviewScanSummary": "{{fileCount}} files, {{totalSize}} total (scanned on source host).", + "methodPreviewWillUseItemSftp": "Will use: Per-file SFTP", + "methodPreviewWillUseTar": "Will use: Tar archive", "methodReason": { - "user_item_sftp": "Ви обрали SFTP для кожного файлу.", - "user_tar": "Ви обрали tar-архів.", - "tar_unavailable": "Архів TAR недоступний на одному або обох хостах — замість нього використовуватиметься SFTP для кожного файлу.", - "windows_host": "Задіяний хост Windows — tar не використовується.", - "auto_multi_large": "Авто: кілька файлів, включаючи великий файл ({{largestSize}}) зі стисливими даними — tar-пакети об'єднуються в одну передачу.", - "auto_single_large_in_archive": "Авто: один великий файл ({{largestSize}}) у цьому наборі — SFTP для кожного файлу.", - "auto_many_incompressible": "Авто: переважно нестисливі дані — SFTP для кожного файлу.", - "auto_many_files": "Авто: багато файлів ({{fileCount}}) — tar зменшує навантаження на кожен файл.", - "auto_default": "Авто: SFTP для кожного файлу для цього набору." + "user_item_sftp": "You chose per-file SFTP.", + "user_tar": "You chose tar archive.", + "tar_unavailable": "Tar is not available on one or both hosts, so per-file SFTP will be used instead.", + "windows_host": "A Windows host is involved, so tar is not used.", + "auto_multi_large": "Auto: multiple files including a large file ({{largestSize}}) with compressible data. Tar bundles them into one transfer.", + "auto_single_large_in_archive": "Auto: one large file ({{largestSize}}) in this set, so per-file SFTP.", + "auto_many_incompressible": "Auto: mostly incompressible data, so per-file SFTP.", + "auto_many_files": "Auto: many files ({{fileCount}}), tar cuts the per-file overhead.", + "auto_default": "Auto: per-file SFTP for this set." }, - "methodTar": "Архів Tar", - "methodTarHint": "Стиснення у вихідному коді, перенесення одного архіву, розпакування у кінцевому. Потрібен tar-архів на обох хостах Unix.", - "metricsCompress": "Стиснути у вихідному коді: {{duration}}", - "metricsExtract": "Вилучити в місці призначення: {{duration}}", - "metricsPrepare": "Підготувати пункт призначення: {{duration}}", - "metricsRouteBenchmark": "Зонд маршруту — прямий: {{direct}}, ретрансляція: {{relay}}", - "metricsSourceDelete": "Видалити з джерела: {{duration}}", - "metricsTotal": "Всього: {{duration}}", - "metricsTransfer": "Від кінця до кінця: {{throughput}} ({{duration}})", - "metricsVerify": "SHA-256 перевірено: {{duration}}", - "moveFolderToHost": "Перемістити папку на хост…", - "moveItemsToHost": "Перемістити {{count}} елементів на хост…", - "moveToHost": "Перемістити на хост…", - "noHostsConnected": "Інших хостів файлових менеджерів немає.", - "noHostsConnectedHint": "Додайте ще один SSH-хост з увімкненим файловим менеджером у Host Manager.", - "parallelSegmentsHint": "Великі файли розділяються на фрагменти по 256 МБ. Кілька ліній використовують окремі з’єднання (наприклад, запуск кількох передач) для підвищення загальної пропускної здатності.", - "parallelSegmentsLabel": "Паралельні пересадочні смуги", - "parallelSegmentsOption": "{{count}} смуги", - "progressBenchmarking": "Вибір найшвидшого маршруту пересадки…", + "methodTar": "Tar archive", + "methodTarHint": "Compress on source, transfer one archive, extract on destination. Requires tar on both Unix hosts.", + "metricsCompress": "Compress on source: {{duration}}", + "metricsExtract": "Extract on destination: {{duration}}", + "metricsPrepare": "Prepare destination: {{duration}}", + "metricsRouteBenchmark": "Route probe: direct {{direct}}, relay {{relay}}", + "metricsSourceDelete": "Remove from source: {{duration}}", + "metricsTotal": "Total: {{duration}}", + "metricsTransfer": "End-to-end: {{throughput}} ({{duration}})", + "metricsVerify": "SHA-256 verified: {{duration}}", + "moveFolderToHost": "Move folder to host…", + "moveItemsToHost": "Move {{count}} items to host…", + "moveToHost": "Move to host…", + "noHostsConnected": "No other file-manager hosts available.", + "noHostsConnectedHint": "Add another SSH host with File Manager enabled in Host Manager.", + "parallelSegmentsHint": "Large files are split into 256 MB chunks. Multiple lanes use separate connections (like starting several transfers) for higher total throughput.", + "parallelSegmentsLabel": "Parallel transfer lanes", + "parallelSegmentsOption": "{{count}} lanes", + "progressBenchmarking": "Selecting the fastest transfer route…", "progressBytes": "{{transferred}} / {{total}}", - "progressCancel": "Скасувати", - "progressCancelling": "Скасування…", - "progressCompressing": "Стиснення на вихідному хості…", - "progressExtracting": "Видобування в місці призначення…", - "progressItems": "{{current}} / {{total}} файли", - "progressReconnecting": "Повторне підключення…", - "progressStalled": "Зупинився", - "progressTotalSpeed": "{{speed}} всього ({{lanes}} смуг)", - "progressTransferring": "Передача даних…", - "progressTransferringItems": "Передача файлів ({{current}} з {{total}})…", - "progressVerifying": "Перевірка цілісності файлу…", - "recentDestinations": "Нещодавні напрямки", - "resumedHint": "Повторне підключення до активної передачі, розпочатої в іншому вікні.", - "retryTransfer": "Повторити спробу", - "retryTransferError": "Повторна спроба не вдалася", - "selectDestinationHost": "Виберіть хост призначення", - "transferCancelled": "Переказ скасовано", - "transferCancelledCopyHint": "Часткові файли можуть залишатися на пристрої призначення.", - "transferCancelledMoveHint": "Часткові файли можуть залишатися в місці призначення. Вихідні файли не видалено.", - "transferError": "Передача не вдалася", - "transferFailedRetryHint": "На місці призначення збережено частку даних. Повторна спроба відновиться після відновлення з’єднання.", - "transferPartialHint": "Не вдалося перенести: {{paths}}", - "transferSuccess": "Перенесення завершено" + "progressCancel": "Cancel", + "progressCancelling": "Cancelling…", + "progressCompressing": "Compressing on source host…", + "progressExtracting": "Extracting on destination…", + "progressItems": "{{current}} / {{total}} files", + "progressReconnecting": "Reconnecting…", + "progressStalled": "Stalled", + "progressTotalSpeed": "{{speed}} total ({{lanes}} lanes)", + "progressTransferring": "Transferring data…", + "progressTransferringItems": "Transferring files ({{current}} of {{total}})…", + "progressVerifying": "Verifying file integrity…", + "recentDestinations": "Recent destinations", + "resumedHint": "Reconnected to an active transfer started in another window.", + "retryTransfer": "Retry", + "retryTransferError": "Retry failed", + "selectDestinationHost": "Select destination host", + "transferCancelled": "Transfer cancelled", + "transferCancelledCopyHint": "Partial files may remain on the destination.", + "transferCancelledMoveHint": "Partial files may remain on the destination. Source files were not removed.", + "transferError": "Transfer failed", + "transferFailedRetryHint": "Partial data was kept on the destination. Retry will resume when the connection is back.", + "transferPartialHint": "Could not transfer: {{paths}}", + "transferSuccess": "Transfer complete", + "metricsHopSourceRead": "Source → server: {{throughput}}", + "metricsHopDestSftpWrite": "Server → dest (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Server → dest (local): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/vi_VN.json b/plugins/file-manager/locales/translated/vi_VN.json index 9b0331b7d..5af3813c6 100644 --- a/plugins/file-manager/locales/translated/vi_VN.json +++ b/plugins/file-manager/locales/translated/vi_VN.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "Tệp", + "sftp": "SFTP", + "openFileManager": "Mở quản lý tệp" + }, + "permissions": { + "use": { + "title": "Use file manager", + "description": "Browse, edit and transfer files over SFTP." + } + }, + "settings": { + "host": { + "enable": { + "label": "Bật Trình quản lý tập tin", + "description": "Browse and edit files on this host over SFTP." + }, + "defaultPath": { + "label": "Đường dẫn mặc định" + }, + "scpLegacy": { + "label": "Chế độ SCP cũ" + } + }, + "user": { + "transferConcurrency": { + "label": "Simultaneous File Transfers", + "description": "How many files the side by side local/remote manager uploads or downloads at the same time. Lower this if your server limits SFTP channels." + }, + "confirmBeforeTrash": { + "label": "Confirm before moving files to trash", + "description": "Ask before moving remote files to trash. Permanent deletion still requires confirmation." + } + } + }, + "hostCapability": { + "label": "Trình quản lý file" + }, "fileManager": { "noHostSelected": "Chưa chọn máy chủ", "initializingEditor": "Đang khởi tạo trình soạn thảo...", @@ -34,13 +72,14 @@ "rename": "Đổi tên", "uploading": "Đang tải lên...", "uploadingFile": "Đang tải lên {{name}}...", + "uploadingChunk": "Uploading {{name}}: {{percent}}% (part {{chunk}} of {{total}})", "fileName": "Tên tập tin", "folderName": "Tên thư mục", "fileUploadedSuccessfully": "Tập tin \"{{name}}\" đã được tải lên thành công", "failedToUploadFile": "Tải tập tin lên thất bại", - "uploadingFolderFiles": "Đang tải lên {{count}} tập tin...", - "uploadedFolderFiles": "Đã tải lên {{count}} tập tin thành công", - "uploadedFolderPartial": "Đã tải lên {{uploaded}} tập tin, {{failed}} thất bại", + "uploadingFolderFiles": "Uploading {{count}} file(s)...", + "uploadedFolderFiles": "Uploaded {{count}} file(s) successfully", + "uploadedFolderPartial": "Uploaded {{uploaded}} file(s), {{failed}} failed", "fileDownloadedSuccessfully": "Tập tin \"{{name}}\" đã được tải xuống thành công", "failedToDownloadFile": "Tải tập tin xuống thất bại", "fileCreatedSuccessfully": "Tập tin \"{{name}}\" đã được tạo thành công", @@ -56,58 +95,58 @@ "sudoOperationFailed": "Thao tác sudo thất bại", "sudoAuthFailed": "Xác thực sudo thất bại", "dragFilesToUpload": "Kéo tệp vào đây để tải lên", - "dropToUploadHere": "Kéo thả để tải lên tại đây", - "dropToDownloadHere": "Kéo thả để tải xuống tại đây", - "localFiles": "Địa phương", - "showLocalFiles": "Hiển thị các tệp cục bộ (chế độ chia đôi màn hình)", - "hideLocalFiles": "Ẩn các tệp cục bộ", - "localHome": "Thư mục trang chủ", - "localPathPlaceholder": "Đường dẫn thư mục cục bộ", - "localShowHidden": "Hiển thị các tệp ẩn", - "localHideHidden": "Ẩn các tệp tin ẩn", - "localRevealInFileManager": "Hiển thị trong trình quản lý tệp hệ thống", - "localCannotOpenFolder": "Không thể mở thư mục", + "dropToUploadHere": "Drop to upload here", + "dropToDownloadHere": "Drop to download here", + "localFiles": "Cục bộ", + "showLocalFiles": "Show local files (split view)", + "hideLocalFiles": "Hide local files", + "localHome": "Home folder", + "localPathPlaceholder": "Local folder path", + "localShowHidden": "Show hidden files", + "localHideHidden": "Hide hidden files", + "localRevealInFileManager": "Reveal in system file manager", + "localCannotOpenFolder": "Cannot open folder", "localItemCount": "{{count}} mục", "localSelectedCount": "{{count}} đã chọn", - "back": "Mặt sau", - "forward": "Phía trước", - "up": "Hướng lên", - "kind": "Loại", - "localUploadingProgress": "Đang tải lên {{current}} trong số {{total}}", - "localDownloadingProgress": "Đang tải xuống {{current}} của {{total}}", - "localTransferInFlight": "{{count}} ngay lập tức", - "localPreparingDownload": "Đang chuẩn bị tải xuống...", - "localTransferCancelled": "Giao dịch bị hủy", - "localNothingToTransfer": "Không có gì để chuyển", - "localUploadComplete": "Đã tải lên {{count}} tập tin", - "localUploadFailed": "Tải lên thất bại", - "localUploadPartial": "Đã tải lên {{done}} tập tin, {{failed}} thất bại", - "localDownloadComplete": "Đã tải xuống {{count}} tập tin", + "back": "Quay lại", + "forward": "Forward", + "up": "Up", + "kind": "Kind", + "localUploadingProgress": "Uploading {{current}} of {{total}}", + "localDownloadingProgress": "Downloading {{current}} of {{total}}", + "localTransferInFlight": "{{count}} at once", + "localPreparingDownload": "Preparing download...", + "localTransferCancelled": "Đã hủy chuyển", + "localNothingToTransfer": "Nothing to transfer", + "localUploadComplete": "Uploaded {{count}} file(s)", + "localUploadFailed": "Upload failed", + "localUploadPartial": "Uploaded {{done}} file(s), {{failed}} failed", + "localDownloadComplete": "Downloaded {{count}} file(s)", "localDownloadFailed": "Tải xuống thất bại", - "localDownloadPartial": "Đã tải xuống {{done}} tập tin, {{failed}} thất bại", - "localReplaceExistingPrompt": "{{count}} mục đã tồn tại trong thư mục này. Bạn có muốn thay thế chúng không?", + "localDownloadPartial": "Downloaded {{done}} file(s), {{failed}} failed", + "localReplaceExistingPrompt": "{{count}} item(s) already exist in this folder. Replace them?", "localReplace": "Thay thế", - "localSkipExisting": "Nhảy", - "localSkippedExisting": "Đã bỏ qua {{count}} mục hiện có", - "localUnsafeNamesSkipped": "Đã bỏ qua {{count}} mục mà tên của chúng không thể sử dụng trên máy tính này.", + "localSkipExisting": "Skip", + "localSkippedExisting": "Skipped {{count}} existing item(s)", + "localUnsafeNamesSkipped": "Skipped {{count}} item(s) whose names cannot be used on this computer", "localOpen": "Mở", - "localOpenFolder": "Mở thư mục", - "localUploadToRemote": "Tải lên máy chủ", - "localUploadToRemoteMany": "Tải lên {{count}} mục lên máy chủ", - "localMoveToTrash": "Chuyển vào thùng rác", - "localMoveToTrashMany": "Di chuyển {{count}} mục vào Thùng rác", - "localTrashConfirmSingle": "Di chuyển \"{{name}}\" vào Thùng rác?", - "localTrashConfirmFolder": "Di chuyển thư mục \"{{name}}\" và tất cả nội dung bên trong vào Thùng rác?", - "localTrashConfirmMany": "Di chuyển {{count}} mục vào Thùng rác?", - "localTrashed": "Đã chuyển {{count}} mục vào Thùng rác", - "localTrashFailed": "Không thể chuyển vào Thùng rác", - "localRenameFailed": "Đổi tên không thành công", - "localCreateFailed": "Không thể tạo mục", - "goToParentFolder": "Đi đến thư mục cha", - "resizeSidebar": "Kéo để thay đổi kích thước thanh bên (nhấp đúp để đặt lại về kích thước ban đầu)", - "resizeLocalPane": "Kéo chuột để thay đổi kích thước khung cục bộ (nhấp đúp chuột để đặt lại về kích thước ban đầu)", + "localOpenFolder": "Open folder", + "localUploadToRemote": "Upload to server", + "localUploadToRemoteMany": "Upload {{count}} items to server", + "localMoveToTrash": "Move to Trash", + "localMoveToTrashMany": "Move {{count}} items to Trash", + "localTrashConfirmSingle": "Move \"{{name}}\" to the Trash?", + "localTrashConfirmFolder": "Move the folder \"{{name}}\" and all its contents to the Trash?", + "localTrashConfirmMany": "Move {{count}} items to the Trash?", + "localTrashed": "Moved {{count}} item(s) to the Trash", + "localTrashFailed": "Could not move to the Trash", + "localRenameFailed": "Rename failed", + "localCreateFailed": "Could not create item", + "goToParentFolder": "Go to parent folder", + "resizeSidebar": "Drag to resize the sidebar (double-click to reset)", + "resizeLocalPane": "Drag to resize the local pane (double-click to reset)", "columns": "Cột", - "columnsHint": "Nhấp chuột phải để chọn cột", + "columnsHint": "Right-click to choose columns", "emptyFolder": "Thư mục này trống", "searchFiles": "Tìm kiếm tệp...", "upload": "Tải lên", @@ -163,26 +202,26 @@ "confirmDeleteMultipleItemsWithFolders": "Bạn có chắc chắn muốn xóa vĩnh viễn {{count}} mục? Điều này bao gồm các thư mục và nội dung của chúng.", "confirmDeleteFolder": "Bạn có chắc chắn muốn xóa vĩnh viễn thư mục \"{{name}}\" và tất cả nội dung của nó?", "permanentDeleteWarning": "Hành động này không thể hoàn tác. (Các) mục sẽ bị xóa vĩnh viễn khỏi máy chủ.", - "moveToTrashWarning": "Các mục này sẽ được chuyển vào Thùng rác Termix và có thể được khôi phục trước khi thời hạn lưu giữ hết hạn.", - "itemsMovedToTrash": "{{count}} mục đã được chuyển vào Thùng rác", - "trash": "Rác", - "trashDescription": "Các mục đã xóa sẽ được lưu giữ trong {{days}} ngày trên máy chủ này.", - "trashLoadFailed": "Không thể tải Thùng rác", - "trashEmpty": "Thùng rác trống", + "moveToTrashWarning": "The item(s) will be moved to the Termix Trash and can be restored before the retention period expires.", + "itemsMovedToTrash": "{{count}} item(s) moved to Trash", + "trash": "Trash", + "trashDescription": "Deleted items are retained for {{days}} day(s) on this host.", + "trashLoadFailed": "Failed to load Trash", + "trashEmpty": "Trash is empty", "trashRestore": "Khôi phục", - "trashRestored": "Đã khôi phục {{name}}", - "trashRestoreFailed": "Không thể khôi phục mục. Đường dẫn gốc có thể đã tồn tại.", - "trashDeletePermanently": "Xóa vĩnh viễn", - "trashDeleteConfirm": "Xóa vĩnh viễn {{name}}? Thao tác này không thể hoàn tác.", - "trashPermanentlyDeleted": "Đã xóa vĩnh viễn {{name}}", - "trashDeleteFailed": "Không thể xóa mục vĩnh viễn", - "trashEmptyAction": "Đổ rác", - "trashEmptyConfirm": "Xóa vĩnh viễn mọi mục trong Thùng rác? Thao tác này không thể hoàn tác.", - "trashEmptied": "Thùng rác đã được đổ", - "trashRetention": "Tự động dọn dẹp sau (ngày)", - "trashRetentionSaved": "Cập nhật thời gian lưu trữ rác", - "trashRetentionFailed": "Không thể cập nhật thời gian lưu trữ thùng rác.", - "trashUnavailableConfirm": "Không thể chuyển mục này vào Thùng rác, thường là do nó nằm trên hệ thống tệp khác hoặc yêu cầu quyền quản trị. Thay vào đó, hãy xóa vĩnh viễn mục này?", + "trashRestored": "Restored {{name}}", + "trashRestoreFailed": "Failed to restore item. The original path may already exist.", + "trashDeletePermanently": "Delete permanently", + "trashDeleteConfirm": "Permanently delete {{name}}? This cannot be undone.", + "trashPermanentlyDeleted": "Permanently deleted {{name}}", + "trashDeleteFailed": "Failed to permanently delete item", + "trashEmptyAction": "Empty Trash", + "trashEmptyConfirm": "Permanently delete every item in Trash? This cannot be undone.", + "trashEmptied": "Trash emptied", + "trashRetention": "Automatic cleanup after (days)", + "trashRetentionSaved": "Trash retention updated", + "trashRetentionFailed": "Failed to update Trash retention", + "trashUnavailableConfirm": "This item cannot be moved to Trash, usually because it is on another filesystem or requires elevated permissions. Delete it permanently instead?", "recent": "Gần đây", "pinned": "Đã ghim", "folderShortcuts": "Lối tắt thư mục", @@ -264,7 +303,7 @@ "operationCompleted": "Đã {{operation}} {{count}} mục", "downloadFileSuccess": "Đã tải xuống tệp {{name}} thành công", "downloadFileFailed": "Tải xuống thất bại", - "downloadingFile": "Đang tải xuống {{name}}…", + "downloadingFile": "Downloading {{name}}…", "downloadProgressBytes": "{{transferred}} / {{total}}", "moveTo": "Di chuyển tới {{name}}", "diffCompareWith": "So sánh khác biệt với {{name}}", @@ -290,6 +329,7 @@ "connecting": "Đang kết nối...", "connectedSuccessfully": "Đã kết nối thành công", "totpVerificationFailed": "Xác minh TOTP thất bại", + "browserSignInFailed": "Sign-in failed. Please try again.", "authenticationFailed": "Xác thực thất bại", "incorrectPassphrase": "Cụm mật khẩu không đúng. Vui lòng thử lại.", "verificationCodePrompt": "Mã xác minh:", @@ -321,98 +361,85 @@ "used": "Đã dùng", "of": "của", "toggleSidebar": "Ẩn/Hiện thanh bên", - "compactLayout": "Sử dụng bố cục nhỏ gọn", - "comfortableLayout": "Sử dụng bố cục thoải mái", + "compactLayout": "Use compact layout", + "comfortableLayout": "Use comfortable layout", "cannotLoadPdf": "Không thể tải PDF", "pdfLoadError": "Đã xảy ra lỗi khi tải tệp PDF này.", "loadingPdf": "Đang tải PDF...", - "loadingPage": "Đang tải trang..." + "loadingPage": "Đang tải trang...", + "cancel": "Hủy", + "copiedItems_one": "Copied {{count}} item", + "copiedItems_other": "Copied {{count}} items", + "deleteCopiedFileFailed": "Could not delete the copy of {{name}}: {{error}}", + "dragMovedItems_one": "Moved {{count}} item to {{target}}", + "dragMovedItems_other": "Moved {{count}} items to {{target}}", + "moveBackFileFailed": "Could not move {{name}} back: {{error}}", + "terminal": "Terminal: {{host}} ({{path}})", + "dragToDesktop": "Dragging {{name}} to the desktop", + "dragFilesToDesktop": "Dragging {{count}} files to the desktop", + "folderDragUnsupported": "Dragging folders to the desktop is not supported yet", + "saveToDesktopFailed": "Save failed: {{error}}", + "dragFailedDetail": "Drag failed: {{error}}", + "videoUnsupported": "Your browser cannot play this video format.", + "downloadToPlay": "Download to play it elsewhere", + "cannotPreviewType": "Cannot preview this file type", + "cannotPreviewTypeHint": "This file type has no preview. Download it to open it in another app." }, "sftpTransfer": { "title": "SFTP", - "description": "Truyền tệp giữa hai máy chủ SSH.", - "sourceServer": "Máy chủ nguồn", - "destinationServer": "Máy chủ đích", - "selectHost": "Chọn máy chủ", - "noHostSelected": "Chưa chọn máy chủ nào", + "description": "Transfer files between two SSH hosts.", + "sourceServer": "Source Server", + "destinationServer": "Destination Server", + "selectHost": "Select host", + "noHostSelected": "Chưa chọn máy chủ", "move": "Di chuyển", "copy": "Sao chép", "upload": "Tải lên", - "itemsSelected": "{{count}} mục đã chọn", - "itemsSelected_other": "{{count}} mục đã chọn", + "itemsSelected": "{{count}} item selected", + "itemsSelected_other": "{{count}} items selected", "ready": "Sẵn sàng", - "loadingHosts": "Đang tải máy chủ...", + "loadingHosts": "Đang tải các máy chủ...", "name": "Tên", - "modified": "Đã sửa đổi", - "size": "Kích cỡ", - "noFiles": "Không có tệp nào", + "modified": "Đã sửa", + "size": "Kích thước", + "noFiles": "No files", "open": "Mở", - "up": "Hướng lên", - "refresh": "Làm cho khỏe lại", - "copyToTarget": "Sao chép vào thư mục đích", + "up": "Up", + "refresh": "Làm mới", + "copyToTarget": "Copy to Target Directory", "rename": "Đổi tên", - "delete": "Xóa bỏ", - "editPermissions": "Chỉnh sửa quyền", - "createNewFolder": "Tạo thư mục mới", - "deleteSelectedItems": "Xóa các mục đã chọn", - "deleteConfirm": "Xóa mục đã chọn {{count}}?", - "deleteConfirm_other": "Xóa {{count}} mục đã chọn?", - "cancel": "Hủy bỏ", - "save": "Cứu", - "folderCreated": "Thư mục đã được tạo", - "itemRenamed": "Mục đã được đổi tên", + "delete": "Xóa", + "editPermissions": "Edit Permissions", + "createNewFolder": "Create New Folder", + "deleteSelectedItems": "Delete Selected Items", + "deleteConfirm": "Delete {{count}} selected item?", + "deleteConfirm_other": "Delete {{count}} selected items?", + "cancel": "Hủy", + "save": "Lưu", + "folderCreated": "Folder created", + "itemRenamed": "Item renamed", "actionFailed": "Hành động thất bại", - "itemsDeleted": "{{count}} mục đã bị xóa", - "itemsDeleted_other": "{{count}} mục đã bị xóa", - "deleteFailed": "Xóa không thành công", - "permissionsUpdated": "Quyền hạn đã được cập nhật", - "noRemoteSessionConnected": "Không có phiên kết nối từ xa nào được thiết lập.", - "failedToListFiles": "Không thể liệt kê các tệp.", - "failedToRefresh": "Không thể làm mới", - "destinationInsideSource": "Đường dẫn đích không được nằm bên trong đường dẫn nguồn đã chọn.", - "sameHostNoOp": "Thư mục nguồn và thư mục đích đều nằm trong cùng một thư mục." + "itemsDeleted": "{{count}} item deleted", + "itemsDeleted_other": "{{count}} items deleted", + "deleteFailed": "Delete failed", + "permissionsUpdated": "Permissions updated", + "noRemoteSessionConnected": "No remote session connected", + "failedToListFiles": "Failed to list files", + "failedToRefresh": "Failed to refresh", + "destinationInsideSource": "Destination cannot be inside the selected source path.", + "sameHostNoOp": "Source and destination are the same folder." }, "hosts": { "fileManager": "Trình quản lý tệp", - "tabFiles": "Tệp", - "enableFileManagerMonitor": "Bật Trình quản lý tập tin", - "enableFileManagerMonitorDesc": "Duyệt và quản lý tập tin trên máy này qua SFTP", - "scpLegacyLabel": "Chế độ SCP cũ", - "scpLegacyDesc": "Sử dụng truyền tập tin kiểu cũ cho các máy chủ không hỗ trợ hệ thống con SFTP (ví dụ: máy chủ SSH nhúng hoặc tối thiểu).", - "defaultPathLabel": "Đường dẫn mặc định", - "fileManagerPathHint": "Thư mục sẽ mở khi khởi chạy Trình quản lý tập tin cho máy này.", "fileManagerUrlCopied": "Đã sao chép URL Trình quản lý tệp", "copyFileManagerUrlAction": "Sao chép URL File Manager", "docsLink": "Xem tài liệu", "hostNotFound": "Không tìm thấy máy chủ", "loadingHost": "Đang tải máy chủ..." }, - "settings": { - "host": { - "enable": { - "label": "Bật Trình quản lý tập tin" - }, - "defaultPath": { - "label": "Đường dẫn mặc định" - }, - "scpLegacy": { - "label": "Chế độ SCP cũ" - } - }, - "user": { - "transferConcurrency": { - "label": "Truyền tệp đồng thời", - "description": "Số lượng tệp mà trình quản lý cục bộ/từ xa song song tải lên hoặc tải xuống cùng lúc. Giảm giá trị này nếu máy chủ của bạn giới hạn số kênh SFTP." - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "Tệp" - }, "onboarding": { - "feature_files": "Trình quản lý tập tin", - "feature_files_desc": "Duyệt, tải lên, tải xuống và chỉnh sửa tệp qua SFTP mà không cần rời khỏi ứng dụng." + "feature_files": "File manager", + "feature_files_desc": "Browse, upload, download and edit files over SFTP without leaving the app." }, "terminal": { "runTitle": "Đang chạy {{command}} - {{host}}", @@ -437,7 +464,7 @@ "destinationPath": "Đường dẫn đích", "destMustBeDirectory": "Đích phải là thư mục khi truyền tải nhiều mục", "goUp": "Lên trên", - "hostAuthRequired": "Yêu cầu xác thực — mở Trình quản lý tệp trên máy chủ này trước", + "hostAuthRequired": "Authentication required. Open File Manager on this host first", "hostConnecting": "Đang kết nối…", "hostConnectionFailed": "Kết nối thất bại", "hostDisconnected": "Chưa kết nối", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "Bạn đã chọn SFTP từng tệp.", "user_tar": "Bạn đã chọn dùng tar.", - "tar_unavailable": "Tar không có trên một hoặc cả hai máy — sẽ dùng SFTP từng tệp thay thế.", - "windows_host": "Có máy Windows — không dùng tar.", - "auto_multi_large": "Tự động: nhiều tệp bao gồm một tệp lớn ({{largestSize}}) có dữ liệu nén được — tar gộp thành một lần chuyển.", - "auto_single_large_in_archive": "Tự động: một tệp lớn ({{largestSize}}) trong tập này — SFTP từng tệp.", - "auto_many_incompressible": "Tự động: dữ liệu hầu như không nén được — SFTP từng tệp.", - "auto_many_files": "Tự động: nhiều tệp ({{fileCount}}) — tar giảm chi phí trên mỗi tệp.", + "tar_unavailable": "Tar is not available on one or both hosts, so per-file SFTP will be used instead.", + "windows_host": "A Windows host is involved, so tar is not used.", + "auto_multi_large": "Auto: multiple files including a large file ({{largestSize}}) with compressible data. Tar bundles them into one transfer.", + "auto_single_large_in_archive": "Auto: one large file ({{largestSize}}) in this set, so per-file SFTP.", + "auto_many_incompressible": "Auto: mostly incompressible data, so per-file SFTP.", + "auto_many_files": "Auto: many files ({{fileCount}}), tar cuts the per-file overhead.", "auto_default": "Tự động: SFTP từng tệp cho tập này." }, "methodTar": "Lưu trữ tar", @@ -471,11 +498,11 @@ "metricsCompress": "Nén tại nguồn: {{duration}}", "metricsExtract": "Giải nén tại đích: {{duration}}", "metricsPrepare": "Chuẩn bị đích: {{duration}}", - "metricsRouteBenchmark": "Tìm đường dẫn — trực tiếp: {{direct}}, chuyển tiếp: {{relay}}", + "metricsRouteBenchmark": "Route probe: direct {{direct}}, relay {{relay}}", "metricsSourceDelete": "Xóa khỏi nguồn: {{duration}}", "metricsTotal": "Tổng: {{duration}}", "metricsTransfer": "Toàn trình: {{throughput}} ({{duration}})", - "metricsVerify": "Đã xác thực SHA-256: {{duration}}", + "metricsVerify": "SHA-256 verified: {{duration}}", "moveFolderToHost": "Di chuyển thư mục tới máy chủ…", "moveItemsToHost": "Di chuyển {{count}} mục tới máy chủ…", "moveToHost": "Di chuyển đến máy chủ…", @@ -484,7 +511,7 @@ "parallelSegmentsHint": "Các tệp lớn được chia thành các khối 256 MB. Nhiều làn sử dụng các kết nối riêng biệt (như khởi chạy nhiều lần truyền) để tăng tổng thông lượng.", "parallelSegmentsLabel": "Làn truyền song song", "parallelSegmentsOption": "{{count}} làn", - "progressBenchmarking": "Chọn tuyến đường chuyển tiếp nhanh nhất…", + "progressBenchmarking": "Selecting the fastest transfer route…", "progressBytes": "{{transferred}} / {{total}}", "progressCancel": "Hủy", "progressCancelling": "Đang hủy…", @@ -496,7 +523,7 @@ "progressTotalSpeed": "{{speed}} tổng ({{lanes}} làn)", "progressTransferring": "Đang truyền dữ liệu…", "progressTransferringItems": "Đang truyền tệp ({{current}}/{{total}})…", - "progressVerifying": "Đang xác minh tính toàn vẹn của tệp…", + "progressVerifying": "Verifying file integrity…", "recentDestinations": "Đích gần đây", "resumedHint": "Đã kết nối lại với một tác vụ chuyển đang hoạt động được bắt đầu từ cửa sổ khác.", "retryTransfer": "Thử lại", @@ -508,6 +535,9 @@ "transferError": "Truyền tải thất bại", "transferFailedRetryHint": "Dữ liệu chưa hoàn chỉnh được giữ ở đích. Thử lại sẽ tiếp tục khi kết nối được khôi phục.", "transferPartialHint": "Không thể truyền tải: {{paths}}", - "transferSuccess": "Truyền tải hoàn tất" + "transferSuccess": "Truyền tải hoàn tất", + "metricsHopSourceRead": "Nguồn → máy chủ: {{throughput}}", + "metricsHopDestSftpWrite": "Máy chủ → đích (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "Máy chủ → đích (cục bộ): {{throughput}}" } } diff --git a/plugins/file-manager/locales/translated/zh_CN.json b/plugins/file-manager/locales/translated/zh_CN.json index f701bda7d..aa5d71a0c 100644 --- a/plugins/file-manager/locales/translated/zh_CN.json +++ b/plugins/file-manager/locales/translated/zh_CN.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "文件", + "sftp": "SFTP", + "openFileManager": "打开文件管理器" + }, + "permissions": { + "use": { + "title": "使用文件管理器", + "description": "通过 SFTP 浏览、编辑和传输文件。" + } + }, + "settings": { + "host": { + "enable": { + "label": "启用文件管理器", + "description": "通过 SFTP 浏览和编辑此主机上的文件。" + }, + "defaultPath": { + "label": "默认路径" + }, + "scpLegacy": { + "label": "SCP 传统模式" + } + }, + "user": { + "transferConcurrency": { + "label": "同时传输文件数", + "description": "本地与远程分栏文件管理器同时上传或下载的文件数。如果服务器限制 SFTP 通道数,请调低此值。" + }, + "confirmBeforeTrash": { + "label": "移入回收站前确认", + "description": "将远程文件移入回收站前询问。永久删除仍需确认。" + } + } + }, + "hostCapability": { + "label": "文件管理器" + }, "fileManager": { "noHostSelected": "未选择主机", "initializingEditor": "正在初始化编辑器...", @@ -34,13 +72,14 @@ "rename": "重命名", "uploading": "上传中...", "uploadingFile": "正在上传 {{name}}...", + "uploadingChunk": "正在上传 {{name}}:{{percent}}%(第 {{chunk}} 部分,共 {{total}} 部分)", "fileName": "文件名", "folderName": "文件夹名称", "fileUploadedSuccessfully": "文件 \"{{name}}\" 上传成功", "failedToUploadFile": "上传文件失败", - "uploadingFolderFiles": "正在上传 {{count}} 文件...", - "uploadedFolderFiles": "已成功上传 {{count}} 个文件", - "uploadedFolderPartial": "上传了 {{uploaded}} 个文件, {{failed}} 个文件失败", + "uploadingFolderFiles": "正在上传 {{count}} 个文件……", + "uploadedFolderFiles": "成功上传 {{count}} 个文件", + "uploadedFolderPartial": "已上传 {{uploaded}} 个文件,{{failed}} 个失败", "fileDownloadedSuccessfully": "文件 \"{{name}}\" 下载成功", "failedToDownloadFile": "下载文件失败", "fileCreatedSuccessfully": "文件 \"{{name}}\" 创建成功", @@ -56,58 +95,58 @@ "sudoOperationFailed": "Sudo 操作失败", "sudoAuthFailed": "Sudo 认证失败", "dragFilesToUpload": "将文件拖放到此处以上传", - "dropToUploadHere": "在此处上传", - "dropToDownloadHere": "点击此处下载", - "localFiles": "当地的", - "showLocalFiles": "显示本地文件(分屏显示)", + "dropToUploadHere": "拖放到此处上传", + "dropToDownloadHere": "拖放到此处下载", + "localFiles": "本地", + "showLocalFiles": "显示本地文件(分栏视图)", "hideLocalFiles": "隐藏本地文件", - "localHome": "主页", + "localHome": "主目录", "localPathPlaceholder": "本地文件夹路径", "localShowHidden": "显示隐藏文件", "localHideHidden": "隐藏隐藏文件", "localRevealInFileManager": "在系统文件管理器中显示", "localCannotOpenFolder": "无法打开文件夹", - "localItemCount": "{{count}} 项目", - "localSelectedCount": "{{count}} 已选择", - "back": "后退", - "forward": "向前", - "up": "向上", - "kind": "种类", - "localUploadingProgress": "正在上传 {{current}} 中的 {{total}}", - "localDownloadingProgress": "正在下载 {{current}} 中的 {{total}}", - "localTransferInFlight": "{{count}} 立刻", + "localItemCount": "{{count}} 个项目", + "localSelectedCount": "已选择 {{count}} 项", + "back": "返回", + "forward": "前进", + "up": "上一级", + "kind": "类型", + "localUploadingProgress": "正在上传第 {{current}} 个,共 {{total}} 个", + "localDownloadingProgress": "正在下载第 {{current}} 个,共 {{total}} 个", + "localTransferInFlight": "同时 {{count}} 个", "localPreparingDownload": "正在准备下载……", - "localTransferCancelled": "转账已取消", - "localNothingToTransfer": "无需转移", + "localTransferCancelled": "传输已取消", + "localNothingToTransfer": "没有需要传输的内容", "localUploadComplete": "已上传 {{count}} 个文件", "localUploadFailed": "上传失败", - "localUploadPartial": "上传了 {{done}} 个文件, {{failed}} 个文件失败", + "localUploadPartial": "已上传 {{done}} 个文件,{{failed}} 个失败", "localDownloadComplete": "已下载 {{count}} 个文件", "localDownloadFailed": "下载失败", - "localDownloadPartial": "下载了 {{done}} 个文件, {{failed}} 个文件失败", - "localReplaceExistingPrompt": "此文件夹中已存在 {{count}} 个项目。是否替换它们?", - "localReplace": "代替", + "localDownloadPartial": "已下载 {{done}} 个文件,{{failed}} 个失败", + "localReplaceExistingPrompt": "此文件夹中已有 {{count}} 个同名项目,是否替换?", + "localReplace": "替换", "localSkipExisting": "跳过", "localSkippedExisting": "已跳过 {{count}} 个现有项目", - "localUnsafeNamesSkipped": "已跳过 {{count}} 个名称无法在此计算机上使用的项目。", + "localUnsafeNamesSkipped": "已跳过 {{count}} 个名称无法在此计算机上使用的项目", "localOpen": "打开", "localOpenFolder": "打开文件夹", "localUploadToRemote": "上传到服务器", - "localUploadToRemoteMany": "上传 {{count}} 项到服务器", - "localMoveToTrash": "移至垃圾桶", - "localMoveToTrashMany": "将 {{count}} 个物品移至垃圾桶", - "localTrashConfirmSingle": "将“{{name}}”移至回收站?", - "localTrashConfirmFolder": "将文件夹“{{name}}”及其所有内容移至回收站?", - "localTrashConfirmMany": "将 {{count}} 个项目移至回收站?", - "localTrashed": "已将 {{count}} 个项目移至回收站", - "localTrashFailed": "无法移至垃圾桶", + "localUploadToRemoteMany": "将 {{count}} 个项目上传到服务器", + "localMoveToTrash": "移入回收站", + "localMoveToTrashMany": "将 {{count}} 个项目移入回收站", + "localTrashConfirmSingle": "将“{{name}}”移入回收站?", + "localTrashConfirmFolder": "将文件夹“{{name}}”及其中所有内容移入回收站?", + "localTrashConfirmMany": "将 {{count}} 个项目移入回收站?", + "localTrashed": "已将 {{count}} 个项目移入回收站", + "localTrashFailed": "无法移入回收站", "localRenameFailed": "重命名失败", "localCreateFailed": "无法创建项目", - "goToParentFolder": "转到上文件夹", - "resizeSidebar": "拖动即可调整侧边栏大小(双击即可重置)", - "resizeLocalPane": "拖动即可调整本地窗格大小(双击可重置)", + "goToParentFolder": "转到父文件夹", + "resizeSidebar": "拖动调整侧边栏宽度(双击重置)", + "resizeLocalPane": "拖动调整本地窗格大小(双击重置)", "columns": "列", - "columnsHint": "右键单击选择列", + "columnsHint": "右键点击选择显示的列", "emptyFolder": "此文件夹为空", "searchFiles": "搜索文件...", "upload": "上传", @@ -164,25 +203,25 @@ "confirmDeleteFolder": "确定要永久删除文件夹“{{name}}”及其所有内容吗?", "permanentDeleteWarning": "此操作无法撤销。项目将从服务器永久删除。", "moveToTrashWarning": "该项目将被移至 Termix 回收站,可在保留期到期前恢复。", - "itemsMovedToTrash": "{{count}} 项已移至回收站", + "itemsMovedToTrash": "已将 {{count}} 个项目移入回收站", "trash": "回收站", - "trashDescription": "已删除的项目将在本主机上保留 {{days}} 天。", + "trashDescription": "删除的项目将在此主机上保留 {{days}} 天。", "trashLoadFailed": "加载回收站失败", "trashEmpty": "回收站是空的", "trashRestore": "恢复", "trashRestored": "已恢复 {{name}}", - "trashRestoreFailed": "恢复项目失败。原始路径可能已存在。", + "trashRestoreFailed": "恢复项目失败,原路径可能已存在。", "trashDeletePermanently": "永久删除", "trashDeleteConfirm": "永久删除 {{name}}?此操作无法撤销。", - "trashPermanentlyDeleted": "永久删除 {{name}}", - "trashDeleteFailed": "无法永久删除项目", + "trashPermanentlyDeleted": "已永久删除 {{name}}", + "trashDeleteFailed": "永久删除项目失败", "trashEmptyAction": "清空回收站", "trashEmptyConfirm": "永久删除回收站中的所有项目?此操作无法撤销。", "trashEmptied": "回收站已清空", "trashRetention": "自动清理(N 天后)", "trashRetentionSaved": "回收站保留设置已更新", "trashRetentionFailed": "更新回收站保留设置失败", - "trashUnavailableConfirm": "此项目无法移至回收站,通常是因为它位于其他文件系统或需要更高的权限。是否将其永久删除?", + "trashUnavailableConfirm": "此项目无法移入回收站,通常是因为它位于其他文件系统中或需要更高权限。是否改为永久删除?", "recent": "最近", "pinned": "已固定", "folderShortcuts": "文件夹快捷方式", @@ -264,7 +303,7 @@ "operationCompleted": "{{operation}}了{{count}}个项目", "downloadFileSuccess": "文件 {{name}} 下载成功", "downloadFileFailed": "下载失败", - "downloadingFile": "正在下载 {{name}}…", + "downloadingFile": "正在下载 {{name}}……", "downloadProgressBytes": "{{transferred}} / {{total}}", "moveTo": "移动到 {{name}}", "diffCompareWith": "与 {{name}} 对比差异", @@ -284,12 +323,13 @@ "sideBySide": "并排", "inline": "内联", "fileComparison": "文件比较: {{file1}} 对比 {{file2}}", - "fileTooLarge": "文件过大: {{error}}", + "fileTooLarge": "文件过大(超过 10 MB),出于安全考虑无法作为文本打开。", "sshConnectionFailed": "SSH 连接失败。请检查您到 {{name}} ({{ip}}:{{port}}) 的连接", "loadFileFailed": "加载文件失败: {{error}}", "connecting": "连接中...", "connectedSuccessfully": "连接成功", "totpVerificationFailed": "TOTP 验证失败", + "browserSignInFailed": "登录失败,请重试。", "authenticationFailed": "认证失败", "incorrectPassphrase": "密码错误。请重试。", "verificationCodePrompt": "验证码:", @@ -321,16 +361,42 @@ "used": "已用", "of": "/", "toggleSidebar": "切换侧边栏", - "compactLayout": "采用紧凑型布局", - "comfortableLayout": "采用舒适的布局", + "compactLayout": "使用紧凑布局", + "comfortableLayout": "使用宽松布局", "cannotLoadPdf": "无法加载 PDF", "pdfLoadError": "加载此 PDF 文件时出错。", - "loadingPdf": "正在加载 PDF...", - "loadingPage": "正在加载页面..." + "loadingPdf": "正在加载 PDF 查看器……", + "loadingPage": "正在加载页面...", + "cancel": "取消", + "copiedItems_one": "已复制 {{count}} 个项目", + "copiedItems_other": "已复制 {{count}} 个项目", + "deleteCopiedFileFailed": "无法删除 {{name}} 的副本:{{error}}", + "dragMovedItems_one": "已将 {{count}} 个项目移至 {{target}}", + "dragMovedItems_other": "已将 {{count}} 个项目移至 {{target}}", + "moveBackFileFailed": "无法将 {{name}} 移回原处:{{error}}", + "terminal": "终端:{{host}}({{path}})", + "dragToDesktop": "正在将 {{name}} 拖到桌面", + "dragFilesToDesktop": "正在将 {{count}} 个文件拖到桌面", + "folderDragUnsupported": "暂不支持将文件夹拖到桌面", + "saveToDesktopFailed": "保存失败:{{error}}", + "dragFailedDetail": "拖放失败:{{error}}", + "videoUnsupported": "你的浏览器无法播放此视频格式。", + "downloadToPlay": "下载后使用其他程序播放", + "cannotPreviewType": "无法预览此文件类型", + "cannotPreviewTypeHint": "此文件类型不支持预览,请下载后使用其他应用打开。", + "loadingFile": "正在加载文件……", + "loadingImage": "正在加载图片……", + "loadingEditor": "正在加载编辑器……", + "loadingPreview": "正在加载预览……", + "loadingAudio": "正在加载音频播放器……", + "emptyPreview": "暂无可预览内容……", + "revert": "还原", + "openAsText": "作为文本打开", + "confirmOpenAsText": "是否继续将此文件作为文本打开?这可能导致浏览器运行变慢。" }, "sftpTransfer": { "title": "SFTP", - "description": "在两台SSH主机之间传输文件。", + "description": "在两台 SSH 主机之间传输文件。", "sourceServer": "源服务器", "destinationServer": "目标服务器", "selectHost": "选择主机", @@ -338,78 +404,48 @@ "move": "移动", "copy": "复制", "upload": "上传", - "itemsSelected": "{{count}} 已选择项目", - "itemsSelected_other": "{{count}} 已选择项目", - "ready": "准备好", + "itemsSelected": "已选择 {{count}} 个项目", + "itemsSelected_other": "已选择 {{count}} 个项目", + "ready": "就绪", "loadingHosts": "正在加载主机...", - "name": "姓名", - "modified": "修改的", - "size": "尺寸", + "name": "名称", + "modified": "修改时间", + "size": "大小", "noFiles": "没有文件", "open": "打开", - "up": "向上", + "up": "上一级", "refresh": "刷新", "copyToTarget": "复制到目标目录", "rename": "重命名", "delete": "删除", "editPermissions": "编辑权限", - "createNewFolder": "创建新文件夹", - "deleteSelectedItems": "删除选定项目", - "deleteConfirm": "删除 {{count}} 选定项目?", - "deleteConfirm_other": "删除 {{count}} 选定项目?", + "createNewFolder": "新建文件夹", + "deleteSelectedItems": "删除所选项目", + "deleteConfirm": "删除选中的 {{count}} 个项目?", + "deleteConfirm_other": "删除选中的 {{count}} 个项目?", "cancel": "取消", - "save": "节省", - "folderCreated": "已创建文件夹", + "save": "保存", + "folderCreated": "文件夹已创建", "itemRenamed": "项目已重命名", "actionFailed": "操作失败", - "itemsDeleted": "{{count}} 项目已删除", - "itemsDeleted_other": "{{count}} 项已删除", + "itemsDeleted": "已删除 {{count}} 个项目", + "itemsDeleted_other": "已删除 {{count}} 个项目", "deleteFailed": "删除失败", "permissionsUpdated": "权限已更新", - "noRemoteSessionConnected": "未连接远程会话", + "noRemoteSessionConnected": "尚未连接远程会话", "failedToListFiles": "文件列表失败", "failedToRefresh": "刷新失败", "destinationInsideSource": "目标路径不能位于所选源路径内。", - "sameHostNoOp": "源文件夹和目标文件夹是同一个文件夹。" + "sameHostNoOp": "源路径与目标路径为同一文件夹。" }, "hosts": { "fileManager": "文件管理器", - "tabFiles": "文件", - "enableFileManagerMonitor": "启用文件管理器", - "enableFileManagerMonitorDesc": "通过 SFTP 浏览和管理此主机上的文件", - "scpLegacyLabel": "SCP 传统模式", - "scpLegacyDesc": "对不支持 SFTP 子系统的服务器使用传统文件传输(例如嵌入式或最小化 SSH 服务器)。", - "defaultPathLabel": "默认路径", - "fileManagerPathHint": "为此主机启动文件管理器时要打开的目录。", "fileManagerUrlCopied": "文件管理器 URL 已复制", "copyFileManagerUrlAction": "复制文件管理器 URL", "docsLink": "查看文档", "hostNotFound": "未找到主机", "loadingHost": "正在加载主机..." }, - "settings": { - "host": { - "enable": { - "label": "启用文件管理器" - }, - "defaultPath": { - "label": "默认路径" - }, - "scpLegacy": { - "label": "SCP 传统模式" - } - }, - "user": { - "transferConcurrency": { - "label": "同时文件传输", - "description": "本地/远程并排管理器同时上传或下载的文件数量。如果您的服务器限制 SFTP 通道,请降低此值。" - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "文件" - }, "onboarding": { "feature_files": "文件管理器", "feature_files_desc": "无需离开应用,即可通过 SFTP 浏览、上传、下载及编辑文件。" @@ -437,7 +473,7 @@ "destinationPath": "目标路径", "destMustBeDirectory": "对于多项目传输,目标必须是一个目录", "goUp": "向上", - "hostAuthRequired": "需要身份验证 — 请先在此主机上打开文件管理器", + "hostAuthRequired": "需要身份验证,请先在此主机上打开文件管理器", "hostConnecting": "连接中…", "hostConnectionFailed": "连接失败", "hostDisconnected": "未连接", @@ -458,12 +494,12 @@ "methodReason": { "user_item_sftp": "您选择了逐文件 SFTP。", "user_tar": "您选择了 Tar 归档。", - "tar_unavailable": "一个或多个主机上不可用 tar — 将转而使用逐文件 SFTP。", - "windows_host": "涉及 Windows 主机 — 不使用 tar。", - "auto_multi_large": "自动:多个文件,其中包括一个包含可压缩数据的大文件({{largestSize}})— tar 将其打包成一次传输。", - "auto_single_large_in_archive": "自动:此集合中有一个大文件({{largestSize}})— 使用逐文件 SFTP。", - "auto_many_incompressible": "自动:大部分为不可压缩数据 — 使用逐文件 SFTP。", - "auto_many_files": "自动:文件众多({{fileCount}})— tar 可减少逐文件开销。", + "tar_unavailable": "一台或两台主机未安装 tar,将改为逐文件使用 SFTP 传输。", + "windows_host": "传输涉及 Windows 主机,因此不使用 tar。", + "auto_multi_large": "自动选择:多个文件中包含可压缩的大文件({{largestSize}}),使用 tar 打包后统一传输。", + "auto_single_large_in_archive": "自动选择:文件集中包含一个大文件({{largestSize}}),采用逐文件 SFTP 传输。", + "auto_many_incompressible": "自动选择:数据大多不可压缩,采用逐文件 SFTP 传输。", + "auto_many_files": "自动选择:文件较多({{fileCount}} 个),使用 tar 减少逐文件传输开销。", "auto_default": "自动:此集合使用逐文件 SFTP。" }, "methodTar": "Tar 归档", @@ -471,11 +507,11 @@ "metricsCompress": "源端压缩:{{duration}}", "metricsExtract": "目标端解压:{{duration}}", "metricsPrepare": "准备目标:{{duration}}", - "metricsRouteBenchmark": "路由探测 — 直接: {{direct}},中继: {{relay}}", + "metricsRouteBenchmark": "路径探测:直连 {{direct}},中转 {{relay}}", "metricsSourceDelete": "从源端删除:{{duration}}", "metricsTotal": "总计:{{duration}}", "metricsTransfer": "端到端:{{throughput}} ({{duration}})", - "metricsVerify": "SHA-256 已验证: {{duration}}", + "metricsVerify": "SHA-256 校验通过:{{duration}}", "moveFolderToHost": "移动文件夹到主机…", "moveItemsToHost": "移动 {{count}} 个项目到主机…", "moveToHost": "移动到主机…", @@ -484,7 +520,7 @@ "parallelSegmentsHint": "大文件会被拆分为 256 MB 的块。多个通道使用独立连接(如同同时进行多个传输),以获得更高的总吞吐量。", "parallelSegmentsLabel": "并行传输通道", "parallelSegmentsOption": "{{count}} 个通道", - "progressBenchmarking": "选择最快的传输路线…", + "progressBenchmarking": "正在选择最快的传输路径……", "progressBytes": "{{transferred}} / {{total}}", "progressCancel": "取消", "progressCancelling": "正在取消…", @@ -496,7 +532,7 @@ "progressTotalSpeed": "{{speed}} 总计({{lanes}} 通道)", "progressTransferring": "正在传输数据…", "progressTransferringItems": "正在传输文件({{current}}/{{total}})…", - "progressVerifying": "正在验证文件完整性…", + "progressVerifying": "正在校验文件完整性……", "recentDestinations": "最近目标", "resumedHint": "已重新连接到在另一个窗口中启动的进行中的传输。", "retryTransfer": "重试", @@ -508,6 +544,12 @@ "transferError": "传输失败", "transferFailedRetryHint": "部分数据已保留在目标位置。连接恢复后重试将继续。", "transferPartialHint": "无法传输:{{paths}}", - "transferSuccess": "传输完成" + "transferSuccess": "传输完成", + "metricsHopSourceRead": "源 → 服务器:{{throughput}}", + "metricsHopDestSftpWrite": "服务器 → 目标 (SFTP):{{throughput}}", + "metricsHopDestLocalWrite": "服务器 → 目标 (本地):{{throughput}}" + }, + "plugin": { + "name": "文件管理器" } } diff --git a/plugins/file-manager/locales/translated/zh_TW.json b/plugins/file-manager/locales/translated/zh_TW.json index a762a3a38..2e2e8c0ca 100644 --- a/plugins/file-manager/locales/translated/zh_TW.json +++ b/plugins/file-manager/locales/translated/zh_TW.json @@ -1,4 +1,42 @@ { + "nav": { + "files": "檔案", + "sftp": "SFTP", + "openFileManager": "開啟檔案管理員" + }, + "permissions": { + "use": { + "title": "Use file manager", + "description": "Browse, edit and transfer files over SFTP." + } + }, + "settings": { + "host": { + "enable": { + "label": "啟用檔案管理員", + "description": "Browse and edit files on this host over SFTP." + }, + "defaultPath": { + "label": "預設路徑" + }, + "scpLegacy": { + "label": "SCP 舊版模式" + } + }, + "user": { + "transferConcurrency": { + "label": "Simultaneous File Transfers", + "description": "How many files the side by side local/remote manager uploads or downloads at the same time. Lower this if your server limits SFTP channels." + }, + "confirmBeforeTrash": { + "label": "Confirm before moving files to trash", + "description": "Ask before moving remote files to trash. Permanent deletion still requires confirmation." + } + } + }, + "hostCapability": { + "label": "檔案管理員" + }, "fileManager": { "noHostSelected": "未選取主機", "initializingEditor": "正在初始化編輯器…", @@ -34,13 +72,14 @@ "rename": "重新命名", "uploading": "上傳中...", "uploadingFile": "正在上傳 {{name}}...", + "uploadingChunk": "Uploading {{name}}: {{percent}}% (part {{chunk}} of {{total}})", "fileName": "檔案名稱", "folderName": "資料夾名稱", "fileUploadedSuccessfully": "檔案「{{name}}」上傳成功", "failedToUploadFile": "上傳檔案失敗", - "uploadingFolderFiles": "正在上傳 {{count}} 檔案...", - "uploadedFolderFiles": "已成功上傳 {{count}} 個文件", - "uploadedFolderPartial": "上傳了 {{uploaded}} 個文件, {{failed}} 個文件失敗", + "uploadingFolderFiles": "Uploading {{count}} file(s)...", + "uploadedFolderFiles": "Uploaded {{count}} file(s) successfully", + "uploadedFolderPartial": "Uploaded {{uploaded}} file(s), {{failed}} failed", "fileDownloadedSuccessfully": "檔案「{{name}}」下載成功", "failedToDownloadFile": "下載檔案失敗", "fileCreatedSuccessfully": "檔案「{{name}}」建立成功", @@ -56,58 +95,58 @@ "sudoOperationFailed": "Sudo 操作失敗", "sudoAuthFailed": "Sudo 驗證失敗", "dragFilesToUpload": "拖放檔案至此以上傳", - "dropToUploadHere": "在此處上傳", - "dropToDownloadHere": "點此下載", - "localFiles": "當地的", - "showLocalFiles": "顯示本地文件(分割畫面顯示)", - "hideLocalFiles": "隱藏本地文件", - "localHome": "首頁", - "localPathPlaceholder": "本機資料夾路徑", - "localShowHidden": "顯示隱藏文件", - "localHideHidden": "隱藏隱藏文件", - "localRevealInFileManager": "在系統檔案管理器中顯示", - "localCannotOpenFolder": "無法開啟資料夾", - "localItemCount": "{{count}} 項目", - "localSelectedCount": "{{count}} 已選擇", - "back": "後退", - "forward": "向前", - "up": "向上", - "kind": "種類", - "localUploadingProgress": "正在上傳 {{current}} 中的 {{total}}", - "localDownloadingProgress": "正在下載 {{current}} 中的 {{total}}", - "localTransferInFlight": "{{count}} 立刻", - "localPreparingDownload": "正在準備下載…", - "localTransferCancelled": "轉帳已取消", - "localNothingToTransfer": "無需轉移", - "localUploadComplete": "已上傳 {{count}} 個文件", - "localUploadFailed": "上傳失敗", - "localUploadPartial": "上傳了 {{done}} 個文件, {{failed}} 個文件失敗", - "localDownloadComplete": "已下載 {{count}} 個文件", + "dropToUploadHere": "Drop to upload here", + "dropToDownloadHere": "Drop to download here", + "localFiles": "本機", + "showLocalFiles": "Show local files (split view)", + "hideLocalFiles": "Hide local files", + "localHome": "Home folder", + "localPathPlaceholder": "Local folder path", + "localShowHidden": "Show hidden files", + "localHideHidden": "Hide hidden files", + "localRevealInFileManager": "Reveal in system file manager", + "localCannotOpenFolder": "Cannot open folder", + "localItemCount": "{{count}} 個項目", + "localSelectedCount": "已選取 {{count}} 個", + "back": "返回", + "forward": "Forward", + "up": "Up", + "kind": "Kind", + "localUploadingProgress": "Uploading {{current}} of {{total}}", + "localDownloadingProgress": "Downloading {{current}} of {{total}}", + "localTransferInFlight": "{{count}} at once", + "localPreparingDownload": "Preparing download...", + "localTransferCancelled": "傳輸已取消", + "localNothingToTransfer": "Nothing to transfer", + "localUploadComplete": "Uploaded {{count}} file(s)", + "localUploadFailed": "Upload failed", + "localUploadPartial": "Uploaded {{done}} file(s), {{failed}} failed", + "localDownloadComplete": "Downloaded {{count}} file(s)", "localDownloadFailed": "下載失敗", - "localDownloadPartial": "下載了 {{done}} 個文件, {{failed}} 個文件失敗", - "localReplaceExistingPrompt": "此資料夾中已存在 {{count}} 個項目。是否替換它們?", - "localReplace": "代替", - "localSkipExisting": "跳過", - "localSkippedExisting": "已跳過 {{count}} 個現有項目", - "localUnsafeNamesSkipped": "已跳過 {{count}} 個名稱無法在此電腦上使用的項目。", - "localOpen": "打開", - "localOpenFolder": "打開資料夾", - "localUploadToRemote": "上傳到伺服器", - "localUploadToRemoteMany": "上傳 {{count}} 項目到伺服器", - "localMoveToTrash": "移至垃圾桶", - "localMoveToTrashMany": "將 {{count}} 個物品移至垃圾桶", - "localTrashConfirmSingle": "將「{{name}}」移至回收站?", - "localTrashConfirmFolder": "將資料夾「{{name}}」及其所有內容移至回收站?", - "localTrashConfirmMany": "將 {{count}} 個項目移至回收站?", - "localTrashed": "已將 {{count}} 個項目移至回收站", - "localTrashFailed": "無法移至垃圾桶", - "localRenameFailed": "重新命名失敗", - "localCreateFailed": "無法建立專案", - "goToParentFolder": "轉到上資料夾", - "resizeSidebar": "拖曳即可調整側邊欄大小(雙擊即可重設)", - "resizeLocalPane": "拖曳即可調整本機窗格大小(雙擊可重設)", - "columns": "列", - "columnsHint": "右鍵單擊選擇列", + "localDownloadPartial": "Downloaded {{done}} file(s), {{failed}} failed", + "localReplaceExistingPrompt": "{{count}} item(s) already exist in this folder. Replace them?", + "localReplace": "取代", + "localSkipExisting": "Skip", + "localSkippedExisting": "Skipped {{count}} existing item(s)", + "localUnsafeNamesSkipped": "Skipped {{count}} item(s) whose names cannot be used on this computer", + "localOpen": "開啟", + "localOpenFolder": "Open folder", + "localUploadToRemote": "Upload to server", + "localUploadToRemoteMany": "Upload {{count}} items to server", + "localMoveToTrash": "Move to Trash", + "localMoveToTrashMany": "Move {{count}} items to Trash", + "localTrashConfirmSingle": "Move \"{{name}}\" to the Trash?", + "localTrashConfirmFolder": "Move the folder \"{{name}}\" and all its contents to the Trash?", + "localTrashConfirmMany": "Move {{count}} items to the Trash?", + "localTrashed": "Moved {{count}} item(s) to the Trash", + "localTrashFailed": "Could not move to the Trash", + "localRenameFailed": "Rename failed", + "localCreateFailed": "Could not create item", + "goToParentFolder": "Go to parent folder", + "resizeSidebar": "Drag to resize the sidebar (double-click to reset)", + "resizeLocalPane": "Drag to resize the local pane (double-click to reset)", + "columns": "欄", + "columnsHint": "Right-click to choose columns", "emptyFolder": "此資料夾為空", "searchFiles": "搜尋檔案...", "upload": "上傳", @@ -163,26 +202,26 @@ "confirmDeleteMultipleItemsWithFolders": "確定要永久刪除 {{count}} 個項目嗎?這包含資料夾及其內容。", "confirmDeleteFolder": "確定要永久刪除資料夾「{{name}}」及其所有內容嗎?", "permanentDeleteWarning": "此動作無法復原。項目將從伺服器永久刪除。", - "moveToTrashWarning": "該物品將移至 Termix 回收站,可在保留期到期前恢復。", - "itemsMovedToTrash": "{{count}} 項已移至回收站", - "trash": "垃圾", - "trashDescription": "已刪除的項目將保留在本主機上 {{days}} 天。", - "trashLoadFailed": "載入回收站失敗", - "trashEmpty": "垃圾桶是空的", - "trashRestore": "恢復", - "trashRestored": "已恢復 {{name}}", - "trashRestoreFailed": "恢復專案失敗。原始路徑可能已存在。", - "trashDeletePermanently": "永久刪除", - "trashDeleteConfirm": "永久刪除 {{name}}?此操作無法撤銷。", - "trashPermanentlyDeleted": "永久刪除 {{name}}", - "trashDeleteFailed": "無法永久刪除項目", - "trashEmptyAction": "清空垃圾桶", - "trashEmptyConfirm": "永久刪除回收站中的所有項目?此操作無法撤銷。", - "trashEmptied": "垃圾已清空", - "trashRetention": "自動清理(天數)後", - "trashRetentionSaved": "垃圾保留狀況更新", - "trashRetentionFailed": "更新垃圾回收站保留策略失敗", - "trashUnavailableConfirm": "此項目無法移至回收站,通常是因為它位於其他檔案系統或需要更高的權限。是否將其永久刪除?", + "moveToTrashWarning": "The item(s) will be moved to the Termix Trash and can be restored before the retention period expires.", + "itemsMovedToTrash": "{{count}} item(s) moved to Trash", + "trash": "Trash", + "trashDescription": "Deleted items are retained for {{days}} day(s) on this host.", + "trashLoadFailed": "Failed to load Trash", + "trashEmpty": "Trash is empty", + "trashRestore": "還原", + "trashRestored": "Restored {{name}}", + "trashRestoreFailed": "Failed to restore item. The original path may already exist.", + "trashDeletePermanently": "Delete permanently", + "trashDeleteConfirm": "Permanently delete {{name}}? This cannot be undone.", + "trashPermanentlyDeleted": "Permanently deleted {{name}}", + "trashDeleteFailed": "Failed to permanently delete item", + "trashEmptyAction": "Empty Trash", + "trashEmptyConfirm": "Permanently delete every item in Trash? This cannot be undone.", + "trashEmptied": "Trash emptied", + "trashRetention": "Automatic cleanup after (days)", + "trashRetentionSaved": "Trash retention updated", + "trashRetentionFailed": "Failed to update Trash retention", + "trashUnavailableConfirm": "This item cannot be moved to Trash, usually because it is on another filesystem or requires elevated permissions. Delete it permanently instead?", "recent": "最近", "pinned": "已釘選", "folderShortcuts": "資料夾捷徑", @@ -264,7 +303,7 @@ "operationCompleted": "{{operation}} {{count}} 個項目", "downloadFileSuccess": "檔案 {{name}} 已成功下載", "downloadFileFailed": "下載失敗", - "downloadingFile": "正在下載 {{name}}…", + "downloadingFile": "Downloading {{name}}…", "downloadProgressBytes": "{{transferred}} / {{total}}", "moveTo": "移動至 {{name}}", "diffCompareWith": "與 {{name}} 進行差異比對", @@ -290,6 +329,7 @@ "connecting": "連線中...", "connectedSuccessfully": "已成功連線", "totpVerificationFailed": "TOTP 驗證失敗", + "browserSignInFailed": "Sign-in failed. Please try again.", "authenticationFailed": "驗證失敗", "incorrectPassphrase": "密碼片語錯誤。請再試一次。", "verificationCodePrompt": "驗證碼:", @@ -321,98 +361,85 @@ "used": "已使用", "of": " / ", "toggleSidebar": "切換側邊欄", - "compactLayout": "採用緊湊型佈局", - "comfortableLayout": "採用舒適的佈局", + "compactLayout": "Use compact layout", + "comfortableLayout": "Use comfortable layout", "cannotLoadPdf": "無法載入 PDF", "pdfLoadError": "載入此 PDF 檔案時發生錯誤。", "loadingPdf": "正在載入 PDF...", - "loadingPage": "正在載入頁面..." + "loadingPage": "正在載入頁面...", + "cancel": "取消", + "copiedItems_one": "Copied {{count}} item", + "copiedItems_other": "Copied {{count}} items", + "deleteCopiedFileFailed": "Could not delete the copy of {{name}}: {{error}}", + "dragMovedItems_one": "Moved {{count}} item to {{target}}", + "dragMovedItems_other": "Moved {{count}} items to {{target}}", + "moveBackFileFailed": "Could not move {{name}} back: {{error}}", + "terminal": "Terminal: {{host}} ({{path}})", + "dragToDesktop": "Dragging {{name}} to the desktop", + "dragFilesToDesktop": "Dragging {{count}} files to the desktop", + "folderDragUnsupported": "Dragging folders to the desktop is not supported yet", + "saveToDesktopFailed": "Save failed: {{error}}", + "dragFailedDetail": "Drag failed: {{error}}", + "videoUnsupported": "Your browser cannot play this video format.", + "downloadToPlay": "Download to play it elsewhere", + "cannotPreviewType": "Cannot preview this file type", + "cannotPreviewTypeHint": "This file type has no preview. Download it to open it in another app." }, "sftpTransfer": { "title": "SFTP", - "description": "在兩台SSH主機之間傳輸檔案。", - "sourceServer": "來源伺服器", - "destinationServer": "目標伺服器", - "selectHost": "選擇主機", + "description": "Transfer files between two SSH hosts.", + "sourceServer": "Source Server", + "destinationServer": "Destination Server", + "selectHost": "Select host", "noHostSelected": "未選擇主機", "move": "移動", "copy": "複製", "upload": "上傳", - "itemsSelected": "{{count}} 已選擇項目", - "itemsSelected_other": "{{count}} 已選擇項目", - "ready": "準備好", - "loadingHosts": "正在加載主機...", - "name": "姓名", - "modified": "修改的", - "size": "尺寸", - "noFiles": "沒有文件", - "open": "打開", - "up": "向上", + "itemsSelected": "{{count}} item selected", + "itemsSelected_other": "{{count}} items selected", + "ready": "就緒", + "loadingHosts": "正在載入主機...", + "name": "名稱", + "modified": "修改時間", + "size": "大小", + "noFiles": "No files", + "open": "開啟", + "up": "Up", "refresh": "重新整理", - "copyToTarget": "複製到目標目錄", + "copyToTarget": "Copy to Target Directory", "rename": "重新命名", "delete": "刪除", - "editPermissions": "編輯權限", - "createNewFolder": "建立新資料夾", - "deleteSelectedItems": "刪除選定項目", - "deleteConfirm": "刪除 {{count}} 選取項目?", - "deleteConfirm_other": "刪除 {{count}} 選取項目?", + "editPermissions": "Edit Permissions", + "createNewFolder": "Create New Folder", + "deleteSelectedItems": "Delete Selected Items", + "deleteConfirm": "Delete {{count}} selected item?", + "deleteConfirm_other": "Delete {{count}} selected items?", "cancel": "取消", - "save": "節省", - "folderCreated": "已建立資料夾", - "itemRenamed": "項目已重新命名", + "save": "儲存", + "folderCreated": "Folder created", + "itemRenamed": "Item renamed", "actionFailed": "操作失敗", - "itemsDeleted": "{{count}} 項目已刪除", - "itemsDeleted_other": "{{count}} 項目已刪除", - "deleteFailed": "刪除失敗", - "permissionsUpdated": "權限已更新", - "noRemoteSessionConnected": "未連接遠端會話", - "failedToListFiles": "文件列表失敗", - "failedToRefresh": "刷新失敗", - "destinationInsideSource": "目標路徑不能位於所選來源路徑內。", - "sameHostNoOp": "來源資料夾和目標資料夾是同一個資料夾。" + "itemsDeleted": "{{count}} item deleted", + "itemsDeleted_other": "{{count}} items deleted", + "deleteFailed": "Delete failed", + "permissionsUpdated": "Permissions updated", + "noRemoteSessionConnected": "No remote session connected", + "failedToListFiles": "檔案列表失敗", + "failedToRefresh": "Failed to refresh", + "destinationInsideSource": "Destination cannot be inside the selected source path.", + "sameHostNoOp": "Source and destination are the same folder." }, "hosts": { "fileManager": "檔案管理員", - "tabFiles": "檔案", - "enableFileManagerMonitor": "啟用檔案管理員", - "enableFileManagerMonitorDesc": "透過 SFTP 瀏覽並管理此主機上的檔案", - "scpLegacyLabel": "SCP 舊版模式", - "scpLegacyDesc": "對不支援 SFTP 子系統的伺服器(例如嵌入式或精簡型 SSH 伺服器)使用舊版檔案傳輸。", - "defaultPathLabel": "預設路徑", - "fileManagerPathHint": "啟動此主機的檔案管理員時開啟的目錄。", "fileManagerUrlCopied": "檔案管理員 URL 已複製", "copyFileManagerUrlAction": "複製檔案管理員 URL", "docsLink": "檢視文件", "hostNotFound": "找不到主機", "loadingHost": "正在載入主機..." }, - "settings": { - "host": { - "enable": { - "label": "啟用檔案管理員" - }, - "defaultPath": { - "label": "預設路徑" - }, - "scpLegacy": { - "label": "SCP 舊版模式" - } - }, - "user": { - "transferConcurrency": { - "label": "同時文件傳輸", - "description": "本機/遠端並排管理器同時上傳或下載的檔案數量。如果您的伺服器限制 SFTP 通道,請降低此值。" - } - } - }, - "nav": { - "sftp": "SFTP", - "files": "檔案" - }, "onboarding": { - "feature_files": "文件管理器", - "feature_files_desc": "無需離開應用程序,即可透過 SFTP 瀏覽、上傳、下載和編輯檔案。" + "feature_files": "File manager", + "feature_files_desc": "Browse, upload, download and edit files over SFTP without leaving the app." }, "terminal": { "runTitle": "正在執行 {{command}} - {{host}}", @@ -437,7 +464,7 @@ "destinationPath": "目標路徑", "destMustBeDirectory": "多項目傳送時,目標必須是資料夾", "goUp": "向上", - "hostAuthRequired": "需要驗證 — 請先在此主機上開啟檔案管理員", + "hostAuthRequired": "Authentication required. Open File Manager on this host first", "hostConnecting": "連線中…", "hostConnectionFailed": "連線失敗", "hostDisconnected": "未連線", @@ -458,12 +485,12 @@ "methodReason": { "user_item_sftp": "您選擇了逐檔 SFTP。", "user_tar": "您選擇了 tar 封存。", - "tar_unavailable": "一或多部主機無法使用 tar,將改用逐檔 SFTP。", - "windows_host": "涉及 Windows 主機,因此不使用 tar。", - "auto_multi_large": "自動:多個檔案中包含一個具可壓縮資料的大型檔案 ({{largestSize}}),tar 會將所有檔案封裝成單一傳輸。", - "auto_single_large_in_archive": "自動:此集合中有一個大型檔案 ({{largestSize}}) — 逐檔 SFTP。", - "auto_many_incompressible": "自動:多為不可壓縮資料 — 逐檔 SFTP。", - "auto_many_files": "自動:多個檔案 ({{fileCount}}) — tar 可減少逐檔傳輸的額外負擔。", + "tar_unavailable": "Tar is not available on one or both hosts, so per-file SFTP will be used instead.", + "windows_host": "A Windows host is involved, so tar is not used.", + "auto_multi_large": "Auto: multiple files including a large file ({{largestSize}}) with compressible data. Tar bundles them into one transfer.", + "auto_single_large_in_archive": "Auto: one large file ({{largestSize}}) in this set, so per-file SFTP.", + "auto_many_incompressible": "Auto: mostly incompressible data, so per-file SFTP.", + "auto_many_files": "Auto: many files ({{fileCount}}), tar cuts the per-file overhead.", "auto_default": "自動:此集合使用逐檔 SFTP。" }, "methodTar": "Tar 封存", @@ -471,11 +498,11 @@ "metricsCompress": "在來源主機壓縮: {{duration}}", "metricsExtract": "在目標主機解壓縮: {{duration}}", "metricsPrepare": "準備目標:{{duration}}", - "metricsRouteBenchmark": "路由探測 — 直接: {{direct}},中繼: {{relay}}", + "metricsRouteBenchmark": "Route probe: direct {{direct}}, relay {{relay}}", "metricsSourceDelete": "從來源主機刪除: {{duration}}", "metricsTotal": "總計: {{duration}}", "metricsTransfer": "端對端: {{throughput}} ({{duration}})", - "metricsVerify": "SHA-256 已驗證: {{duration}}", + "metricsVerify": "SHA-256 verified: {{duration}}", "moveFolderToHost": "移動資料夾至主機…", "moveItemsToHost": "將 {{count}} 個項目移至主機…", "moveToHost": "移動到主機…", @@ -484,7 +511,7 @@ "parallelSegmentsHint": "大型檔案會分割成 256 MB 區塊。多個通道會使用獨立的連線(如同啟動多個傳輸作業)以獲取更高的總傳輸速率。", "parallelSegmentsLabel": "平行傳輸通道", "parallelSegmentsOption": "{{count}} 個通道", - "progressBenchmarking": "選擇最快的傳輸路線…", + "progressBenchmarking": "Selecting the fastest transfer route…", "progressBytes": "{{transferred}} / {{total}}", "progressCancel": "取消", "progressCancelling": "正在取消…", @@ -496,7 +523,7 @@ "progressTotalSpeed": "總計 {{speed}}({{lanes}} 個通道)", "progressTransferring": "傳輸資料中…", "progressTransferringItems": "傳輸檔案中({{current}} / {{total}})…", - "progressVerifying": "正在驗證檔案完整性…", + "progressVerifying": "Verifying file integrity…", "recentDestinations": "最近使用的目的地", "resumedHint": "已重新連線至在另一個視窗中啟動的進行中傳輸。", "retryTransfer": "重試", @@ -508,6 +535,9 @@ "transferError": "傳送失敗", "transferFailedRetryHint": "部分資料已保留在目的地。重新連線後,重試將從斷點繼續。", "transferPartialHint": "無法傳送:{{paths}}", - "transferSuccess": "傳送完成" + "transferSuccess": "傳送完成", + "metricsHopSourceRead": "來源主機 → 伺服器: {{throughput}}", + "metricsHopDestSftpWrite": "伺服器 → 目標主機 (SFTP): {{throughput}}", + "metricsHopDestLocalWrite": "伺服器 → 目標主機 (本機): {{throughput}}" } } diff --git a/plugins/file-manager/src/backend/operation-routes.ts b/plugins/file-manager/src/backend/operation-routes.ts index 19fd1fa05..b2a3edc38 100644 --- a/plugins/file-manager/src/backend/operation-routes.ts +++ b/plugins/file-manager/src/backend/operation-routes.ts @@ -1,5 +1,6 @@ import type { Express, Request, Response } from "express"; import type { PluginContext } from "@termix/plugin-sdk/backend"; +import type { SFTPWrapper } from "ssh2"; import { execChannel, execWithSudo, @@ -24,6 +25,8 @@ type FileOperationRoutesDeps = { const TRASH_RETENTION_DAYS_KEY = "trashRetentionDays"; +const TRASH_PURGE_INTERVAL_MS = 60 * 60 * 1000; + export function registerFileOperationRoutes( app: Express, { ctx, sshSessions, verifySessionOwnership }: FileOperationRoutesDeps, @@ -39,6 +42,22 @@ export function registerFileOperationRoutes( } }; + // Deleting used to purge expired trash first, reading every trash entry + // before answering. Do it after the response, at most hourly per session. + const lastPurge = new WeakMap(); + const purgeExpiredTrash = (session: SSHSession, sftp: SFTPWrapper) => { + const now = Date.now(); + if (now - (lastPurge.get(session) ?? 0) < TRASH_PURGE_INTERVAL_MS) return; + lastPurge.set(session, now); + void getTrashRetentionDays() + .then((days) => listTrash(sftp, days)) + .catch((error) => + ctx.log.warn( + `Could not purge expired trash: ${(error as Error).message}`, + ), + ); + }; + async function ownedSession( req: Request, res: Response, @@ -494,9 +513,8 @@ export function registerFileOperationRoutes( if (!permanent) { try { const sftp = await getSessionSftp(sshConn); - const retentionDays = await getTrashRetentionDays(); - await listTrash(sftp, retentionDays); const item = await moveToTrash(sftp, itemPath); + purgeExpiredTrash(sshConn, sftp); ctx.log.info( `Item moved to trash: ${sessionId} (${itemPath}, trashId=${item.id})`, ); diff --git a/plugins/file-manager/src/backend/trash-service.ts b/plugins/file-manager/src/backend/trash-service.ts index 6b0705df4..bf09e8e66 100644 --- a/plugins/file-manager/src/backend/trash-service.ts +++ b/plugins/file-manager/src/backend/trash-service.ts @@ -70,6 +70,8 @@ async function exists(sftp: SFTPWrapper, target: string) { } async function ensureDirectory(sftp: SFTPWrapper, target: string) { + // Usually there already: one round trip instead of one per segment. + if (await exists(sftp, target)) return; const normalized = target.replace(/\\/g, "/"); const root = normalized.startsWith("/") ? "/" : ""; const parts = normalized.split("/").filter(Boolean); @@ -95,13 +97,32 @@ async function removeTree(sftp: SFTPWrapper, target: string): Promise { await rmdir(sftp, target); } -async function trashPaths(sftp: SFTPWrapper) { +type TrashDirs = { root: string; files: string; info: string }; + +// The trash folders of a channel do not move while it is open, and finding +// them costs several round trips, which made every delete slow on a remote +// host (#1390). +const trashDirsByChannel = new WeakMap>(); + +function trashPaths(sftp: SFTPWrapper): Promise { + let dirs = trashDirsByChannel.get(sftp); + if (!dirs) { + dirs = findTrashPaths(sftp); + trashDirsByChannel.set(sftp, dirs); + dirs.catch(() => trashDirsByChannel.delete(sftp)); + } + return dirs; +} + +async function findTrashPaths(sftp: SFTPWrapper): Promise { const home = await call((done) => sftp.realpath(".", done)); const root = path.posix.join(home.replace(/\\/g, "/"), TRASH_DIR); const files = path.posix.join(root, "files"); const info = path.posix.join(root, "info"); - await ensureDirectory(sftp, files); - await ensureDirectory(sftp, info); + await Promise.all([ + ensureDirectory(sftp, files), + ensureDirectory(sftp, info), + ]); return { root, files, info }; } @@ -124,7 +145,7 @@ function publicItem(item: StoredTrashItem): TrashItem { async function readStoredItem( sftp: SFTPWrapper, - dirs: { root: string; files: string; info: string }, + dirs: TrashDirs, id: string, ): Promise { if (!ID_PATTERN.test(id)) throw new Error("Invalid trash item id"); diff --git a/plugins/file-manager/src/frontend/FileManager.tsx b/plugins/file-manager/src/frontend/FileManager.tsx index c234717ac..9d10f5ff9 100644 --- a/plugins/file-manager/src/frontend/FileManager.tsx +++ b/plugins/file-manager/src/frontend/FileManager.tsx @@ -1416,10 +1416,13 @@ function FileManagerContent({ const { downloadSSHFileStream } = await import("./api/ssh-file-operations-api"); - toast.loading(, { - id: toastId, - duration: Infinity, - }); + toast.loading( + , + { + id: toastId, + duration: Infinity, + }, + ); await downloadSSHFileStream( sshSessionId, @@ -1438,6 +1441,7 @@ function FileManagerContent({ toast.loading( { const toastId = toast.loading( - , + , { duration: Infinity }, ); try { @@ -145,6 +145,7 @@ export function DiffViewer({ ({ loaded, total }) => { toast.loading( 0 ? Math.min(100, Math.round((loaded / total) * 100)) diff --git a/plugins/file-manager/src/frontend/components/FileViewer.tsx b/plugins/file-manager/src/frontend/components/FileViewer.tsx index edca6e27f..3d0d1e685 100644 --- a/plugins/file-manager/src/frontend/components/FileViewer.tsx +++ b/plugins/file-manager/src/frontend/components/FileViewer.tsx @@ -350,7 +350,9 @@ export function FileViewer({
-

Loading file...

+

+ {t("fileManager.loadingFile")} +

); @@ -446,7 +448,7 @@ export function FileViewer({ className="flex items-center gap-2" > - Revert + {t("fileManager.revert")} )} @@ -647,14 +649,12 @@ export function FileViewer({ {isTooLarge ? (

- File is too large (> 10MB) and cannot be opened as - text for security reasons. + {t("fileManager.fileTooLarge")}

) : (

- Do you want to continue opening this file as text? This - may slow down your browser. + {t("fileManager.confirmOpenAsText")}

)} @@ -669,7 +669,7 @@ export function FileViewer({ className="flex items-center gap-2" > - Open as Text + {t("fileManager.openAsText")} )} @@ -694,7 +694,9 @@ export function FileViewer({ )} {fileTypeInfo.type === "image" && !showLargeFileWarning && ( - }> + } + > {isEditable ? ( } + fallback={ + + } > + } > @@ -872,7 +880,11 @@ export function FileViewer({
} + fallback={ + + } > @@ -885,7 +897,7 @@ export function FileViewer({ {fileTypeInfo.type === "pdf" && !showLargeFileWarning && ( } + fallback={} > } + fallback={} > {file.path} {hasChanges && ( - ● Unsaved changes + ● {t("common.unsavedChanges")} )}
diff --git a/plugins/file-manager/src/frontend/components/FileWindow.tsx b/plugins/file-manager/src/frontend/components/FileWindow.tsx index 2db6bad3e..e727e6527 100644 --- a/plugins/file-manager/src/frontend/components/FileWindow.tsx +++ b/plugins/file-manager/src/frontend/components/FileWindow.tsx @@ -483,7 +483,7 @@ export function FileWindow({ const handleDownload = async () => { const toastId = toast.loading( - , + , { duration: Infinity }, ); try { @@ -495,6 +495,7 @@ export function FileWindow({ ({ loaded, total }) => { toast.loading(
-

Loading image...

+

+ {t("fileManager.loadingImage")} +

)} diff --git a/plugins/file-manager/src/frontend/components/LocalTransferProgressToast.tsx b/plugins/file-manager/src/frontend/components/LocalTransferProgressToast.tsx index 8151a91fe..5f6b2dbaf 100644 --- a/plugins/file-manager/src/frontend/components/LocalTransferProgressToast.tsx +++ b/plugins/file-manager/src/frontend/components/LocalTransferProgressToast.tsx @@ -1,5 +1,5 @@ import { Button } from "@termix/plugin-sdk/ui"; -import { useTranslation } from "@termix/plugin-sdk/frontend"; +import type { TranslateFn } from "@termix/plugin-sdk/frontend"; import { formatFileSize } from "../file-manager-utils.ts"; export interface LocalTransferBatchStatus { @@ -16,15 +16,16 @@ export interface LocalTransferBatchStatus { } interface LocalTransferProgressToastProps { + t: TranslateFn; status: LocalTransferBatchStatus; onCancel?: () => void; } export function LocalTransferProgressToast({ + t, status, onCancel, }: LocalTransferProgressToastProps) { - const { t } = useTranslation(); const percent = status.totalBytes > 0 ? Math.min(100, Math.round((status.bytesDone / status.totalBytes) * 100)) diff --git a/plugins/file-manager/src/frontend/components/TransferProgressToast.tsx b/plugins/file-manager/src/frontend/components/TransferProgressToast.tsx index 830b143f8..4a85f1b9e 100644 --- a/plugins/file-manager/src/frontend/components/TransferProgressToast.tsx +++ b/plugins/file-manager/src/frontend/components/TransferProgressToast.tsx @@ -4,7 +4,7 @@ import { getTransferProgressPercent, type TransferProgressResponse, } from "../api/transfer-api"; -import { useTranslation } from "@termix/plugin-sdk/frontend"; +import type { TranslateFn } from "@termix/plugin-sdk/frontend"; import { Archive, ArchiveRestore, @@ -16,6 +16,7 @@ import { import { TransferProgressBar } from "./TransferProgressBar"; interface TransferProgressToastProps { + t: TranslateFn; status: TransferProgressResponse; liveMbPerSec?: number; stalled?: boolean; @@ -25,6 +26,7 @@ interface TransferProgressToastProps { } export function TransferProgressToast({ + t, status, liveMbPerSec, stalled = false, @@ -32,7 +34,6 @@ export function TransferProgressToast({ onCancel, cancelling = false, }: TransferProgressToastProps) { - const { t } = useTranslation(); const percent = getTransferProgressPercent(status); let title = t("transfer.progressTransferring"); diff --git a/plugins/file-manager/src/frontend/hooks/useLocalTransfers.ts b/plugins/file-manager/src/frontend/hooks/useLocalTransfers.ts index 3ea737781..1ac7541c5 100644 --- a/plugins/file-manager/src/frontend/hooks/useLocalTransfers.ts +++ b/plugins/file-manager/src/frontend/hooks/useLocalTransfers.ts @@ -193,6 +193,7 @@ export function useLocalTransfers({ const render = () => { toast.loading( createElement(LocalTransferProgressToast, { + t, status: { ...status, cancelling }, onCancel: () => { cancelled = true; diff --git a/plugins/file-manager/src/frontend/transferProgressMonitor.tsx b/plugins/file-manager/src/frontend/transferProgressMonitor.tsx index ae1b742bf..8c86f3e30 100644 --- a/plugins/file-manager/src/frontend/transferProgressMonitor.tsx +++ b/plugins/file-manager/src/frontend/transferProgressMonitor.tsx @@ -38,6 +38,7 @@ function formatFileSize(bytes?: number): string { } function renderTransferProgressToast( + t: TFunction, toastId: string | number, status: TransferProgressResponse, liveMbPerSec?: number, @@ -47,6 +48,7 @@ function renderTransferProgressToast( ): void { toast.loading( , @@ -279,6 +282,7 @@ export function beginTransferProgressMonitoring( if (cancelling) return; cancelling = true; renderTransferProgressToast( + t, progressToast, { ...initialStatus, transferId }, undefined, @@ -294,6 +298,7 @@ export function beginTransferProgressMonitoring( options.onProgress?.(status); const { rate, stalled } = progressTracker.update(status); renderTransferProgressToast( + t, progressToast, status, rate, @@ -333,6 +338,7 @@ export function beginTransferProgressMonitoring( }); renderTransferProgressToast( + t, progressToast, initialStatus, undefined, diff --git a/plugins/file-manager/tests/backend/download-stream.test.ts b/plugins/file-manager/tests/backend/download-stream.test.ts index 6aa694431..f44456539 100644 --- a/plugins/file-manager/tests/backend/download-stream.test.ts +++ b/plugins/file-manager/tests/backend/download-stream.test.ts @@ -58,9 +58,13 @@ describe("SFTP download stream", () => { const data = Buffer.alloc(1024 * 1024 + 123); for (let i = 0; i < data.length; i++) data[i] = (i * 13 + (i >>> 8)) % 256; const remote = source(data); - expect( - await contents(createDownloadStream(remote.sftp, "/file", data.length)), - ).toEqual(data); + const received = await contents( + createDownloadStream(remote.sftp, "/file", data.length), + ); + // toEqual walks a 1 MB buffer byte by byte, slow enough to time out + // when every plugin suite runs at once. + expect(received.length).toBe(data.length); + expect(received.equals(data)).toBe(true); expect(remote.peak()).toBe(8); expect(remote.closedWithPending).toEqual([0]); }); diff --git a/plugins/file-manager/tests/backend/trash-service.test.ts b/plugins/file-manager/tests/backend/trash-service.test.ts new file mode 100644 index 000000000..fcfa37bc5 --- /dev/null +++ b/plugins/file-manager/tests/backend/trash-service.test.ts @@ -0,0 +1,95 @@ +import { describe, expect, it, vi } from "vitest"; +import type { SFTPWrapper } from "ssh2"; +import { listTrash, moveToTrash } from "../../src/backend/trash-service.js"; + +/** An in-memory SFTP channel that counts every request. */ +function fakeSftp() { + const dirs = new Set(["/", "/home", "/home/me"]); + const files = new Map([["/home/me/a.txt", Buffer.from("a")]]); + const calls: string[] = []; + const stats = (target: string) => + dirs.has(target) || files.has(target) + ? { + isDirectory: () => dirs.has(target), + size: files.get(target)?.length ?? 0, + } + : null; + const sftp = { + realpath: vi.fn((_p: string, done: (e?: Error, v?: string) => void) => { + calls.push("realpath"); + done(undefined, "/home/me"); + }), + stat: vi.fn((target: string, done: (e?: Error, v?: unknown) => void) => { + calls.push("stat"); + const found = stats(target); + done(found ? undefined : new Error("ENOENT"), found ?? undefined); + }), + lstat: vi.fn((target: string, done: (e?: Error, v?: unknown) => void) => { + calls.push("lstat"); + const found = stats(target); + done(found ? undefined : new Error("ENOENT"), found ?? undefined); + }), + mkdir: vi.fn((target: string, done: (e?: Error) => void) => { + calls.push("mkdir"); + dirs.add(target); + done(); + }), + rename: vi.fn((from: string, to: string, done: (e?: Error) => void) => { + calls.push("rename"); + files.set(to, files.get(from)!); + files.delete(from); + done(); + }), + writeFile: vi.fn( + (target: string, data: string, done: (e?: Error) => void) => { + calls.push("writeFile"); + files.set(target, Buffer.from(data)); + done(); + }, + ), + readdir: vi.fn((target: string, done: (e?: Error, v?: unknown) => void) => { + calls.push("readdir"); + const prefix = `${target}/`; + done( + undefined, + [...files.keys()] + .filter((name) => name.startsWith(prefix)) + .map((name) => ({ filename: name.slice(prefix.length) })), + ); + }), + readFile: vi.fn((target: string, done: (e?: Error, v?: Buffer) => void) => { + calls.push("readFile"); + done(undefined, files.get(target)); + }), + unlink: vi.fn((target: string, done: (e?: Error) => void) => { + calls.push("unlink"); + files.delete(target); + done(); + }), + }; + return { sftp: sftp as unknown as SFTPWrapper, calls, files }; +} + +describe("trash", () => { + it("finds the trash folders once per channel", async () => { + const { sftp, calls, files } = fakeSftp(); + files.set("/home/me/b.txt", Buffer.from("b")); + + await moveToTrash(sftp, "/home/me/a.txt"); + const first = calls.length; + calls.length = 0; + await moveToTrash(sftp, "/home/me/b.txt"); + + expect(calls.filter((call) => call === "realpath")).toHaveLength(0); + expect(calls.filter((call) => call === "mkdir")).toHaveLength(0); + // lstat, rename and the metadata write. + expect(calls.length).toBeLessThan(first); + expect(calls).toEqual(["lstat", "rename", "writeFile"]); + }); + + it("lists what was moved", async () => { + const { sftp } = fakeSftp(); + const item = await moveToTrash(sftp, "/home/me/a.txt"); + expect(await listTrash(sftp, 7)).toEqual([item]); + }); +}); diff --git a/plugins/file-manager/tests/frontend/progress-toast-context.test.tsx b/plugins/file-manager/tests/frontend/progress-toast-context.test.tsx new file mode 100644 index 000000000..4032b6644 --- /dev/null +++ b/plugins/file-manager/tests/frontend/progress-toast-context.test.tsx @@ -0,0 +1,54 @@ +import { cleanup, fireEvent, render, screen } from "@testing-library/react"; +import { afterEach, expect, it, vi } from "vitest"; +vi.mock("@termix/plugin-sdk/frontend", () => ({ + useTranslation: () => { + throw Error("No plugin scope in the global toaster"); + }, +})); +import { DownloadProgressToast } from "../../src/frontend/components/DownloadProgressToast"; +import { TransferProgressToast } from "../../src/frontend/components/TransferProgressToast"; +import { LocalTransferProgressToast } from "../../src/frontend/components/LocalTransferProgressToast"; +afterEach(cleanup); +const t = (key: string) => key; +it("renders download progress outside plugin scope", () => { + render( + , + ); + expect(screen.getByRole("progressbar").getAttribute("aria-valuenow")).toBe( + "50", + ); +}); +it("renders host transfer progress outside plugin scope", () => { + render( + , + ); + expect(screen.getByRole("progressbar")).toBeTruthy(); +}); +it("preserves cancellation on local transfers outside plugin scope", () => { + const cancel = vi.fn(); + render( + , + ); + fireEvent.click(screen.getByRole("button")); + expect(cancel).toHaveBeenCalledOnce(); +}); diff --git a/plugins/fleets/locales/translated/af_ZA.json b/plugins/fleets/locales/translated/af_ZA.json index f8a428ba9..9c3d93c32 100644 --- a/plugins/fleets/locales/translated/af_ZA.json +++ b/plugins/fleets/locales/translated/af_ZA.json @@ -1,4 +1,18 @@ { + "permissions": { + "view": { + "title": "Bekyk vlote", + "description": "Sien vlote, hul lede en inventaris." + }, + "manage": { + "title": "Bestuur vlote", + "description": "Skep, wysig en verwyder vlote, verander lidmaatskap en deel vlote met ander gebruikers of rolle." + }, + "execute": { + "title": "Voer vlootaksies uit", + "description": "Voer bevele en pakketaksies oor 'n vloot uit, en dra lêers na en van sy lidgashere oor." + } + }, "newUi": { "sidebar": { "fleets": { @@ -22,7 +36,7 @@ "saveFailed": "Kon nie vloot stoor nie", "deleteFailed": "Kon nie vloot uitvee nie", "loadFailed": "Kon nie vlote laai nie", - "deleteFleetTitle": "Vee vloot uit", + "deleteFleetTitle": "Vee Vloot uit", "deleteFleetDescription": "Is jy seker jy wil \"{{name}}\" verwyder? Dit verwyder nie die lidgashere self nie.", "searchFleets": "Soek vlote...", "noFleets": "Geen vlote nog nie. Skep een om te begin.", @@ -79,7 +93,14 @@ "packageUpgradeAll": "Gradeer alle pakkette op", "packageNameLabel": "Pakketnaam", "packageNameRequired": "'n Pakketnaam word vereis", - "packageHint": "Vereis bestuursvlaktoegang per gasheer en verhoog met behulp van die gasheer se gestoorde sudo-wagwoord." + "packageHint": "Vereis bestuursvlaktoegang per gasheer en verhoog met behulp van die gasheer se gestoorde sudo-wagwoord.", + "shareFleet": "Deel Vloot", + "shareFleetTitle": "Deel \"{{name}}\"", + "shareFleetDescription": "Deel hierdie vloot se huidige lid-gashere met die gekose gebruikers of rolle. Gashere wat later by die vloot gevoeg word, word nie outomaties gedeel nie - deel weer om hulle in te sluit.", + "shareSelectionRequired": "Kies ten minste een gebruiker of rol", + "fleetSharedSuccessfully": "Gedeelde {{shared}} van {{total}} gasheer(s) in hierdie vloot", + "failedToShareFleet": "Kon nie vloot deel nie", + "noMembersToShare": "Hierdie vloot het nog geen lidgashere om te deel nie." } } }, diff --git a/plugins/fleets/locales/translated/ar_SA.json b/plugins/fleets/locales/translated/ar_SA.json index 5e2c1d03e..1cc595c61 100644 --- a/plugins/fleets/locales/translated/ar_SA.json +++ b/plugins/fleets/locales/translated/ar_SA.json @@ -1,4 +1,18 @@ { + "permissions": { + "view": { + "title": "عرض الأساطيل", + "description": "اطلع على الأساطيل وأعضائها ومخزونها." + }, + "manage": { + "title": "إدارة الأساطيل", + "description": "إنشاء الأساطيل وتعديلها وحذفها، وتغيير العضوية، ومشاركة الأساطيل مع مستخدمين أو أدوار أخرى." + }, + "execute": { + "title": "نفّذ عمليات الأسطول", + "description": "قم بتشغيل الأوامر وإجراءات الحزم عبر مجموعة من الأجهزة، ونقل الملفات من وإلى مضيفيها الأعضاء." + } + }, "newUi": { "sidebar": { "fleets": { @@ -7,12 +21,12 @@ "createFleetTitle": "إنشاء أسطول", "editFleetTitle": "تعديل الأسطول", "createFleetDescription": "الأسطول عبارة عن مجموعة محددة من المضيفين يمكنك شنّ عمليات ضدهم كوحدة واحدة.", - "nameLabel": "اسم", + "nameLabel": "الاسم", "namePlaceholder": "مثال: خوادم الويب", "nameRequired": "اسم الأسطول مطلوب", - "descriptionLabel": "وصف", + "descriptionLabel": "الوصف", "descriptionPlaceholder": "وصف اختياري", - "colorLabel": "لون", + "colorLabel": "اللون", "tagRulesLabel": "قواعد الوسوم", "tagRulesPlaceholder": "موقع الإنتاج، الحافة", "tagRulesHint": "يتم تضمين المضيفين الذين يحملون أيًا من هذه العلامات تلقائيًا، بالإضافة إلى المضيفين الذين تمت إضافتهم يدويًا.", @@ -27,11 +41,11 @@ "searchFleets": "أساطيل البحث...", "noFleets": "لا توجد أساطيل حتى الآن. أنشئ أسطولاً للبدء.", "memberCount": "{{count}} المضيف", - "memberCount_other": "{{count}} المضيفون", + "memberCount_other": "{{count}} مضيفات", "manageMembers": "إدارة الأعضاء", "manageMembersTitle": "إدارة أعضاء الأسطول", "manageMembersDescription": "قم بتفعيل أو تعطيل عضوية المضيفين في هذه المجموعة الثابتة. يتم تضمين المضيفين الذين تتطابق قواعد الوسوم معهم دائمًا.", - "searchHosts": "ابحث عن المضيفين...", + "searchHosts": "ابحث عن مضيفين...", "noHostsFound": "لم يتم العثور على مضيفين", "noMembers": "لا يوجد أعضاء في هذا الأسطول حتى الآن. أضف مضيفين أو حدد قاعدة للوسوم.", "membersLoadFailed": "فشل تحميل أعضاء الأسطول", @@ -40,7 +54,7 @@ "tabTransfer": "نقل الملفات", "tabInventory": "جرد", "openInventoryTab": "افتح في علامة تبويب كاملة", - "tabPackages": "الطرود", + "tabPackages": "الحزم", "runOnFleet": "انطلق على الأسطول", "commandPlaceholder": "وقت التشغيل && df -h", "commandRequired": "يلزم إصدار أمر", @@ -52,34 +66,41 @@ "resultFailed": "فشل", "push": "يدفع", "pull": "يحذب", - "remotePathLabel": "مسار بعيد", + "remotePathLabel": "المسار البعيد", "remotePathRequired": "يلزم وجود مسار بعيد", "fileLabel": "ملف", "fileRequired": "الملف مطلوب", "pushHint": "يتم كتابة الملف المحدد في هذا المسار المحدد على كل مضيف في الأسطول.", "pullHint": "يتم قراءة الملف الموجود في هذا المسار من كل مضيف وتنزيله كملف مضغوط واحد، مجلد واحد لكل مضيف.", - "transferComplete": "اكتملت عملية النقل", - "transferFailed": "فشلت عملية النقل", + "transferComplete": "اكتمل النقل", + "transferFailed": "فشل النقل", "refreshInventory": "تحديث المخزون", "inventoryLoadFailed": "فشل تحميل المخزون", "inventoryRefreshed": "تم تحديث المخزون", "inventoryRefreshFailed": "فشل تحديث المخزون", "inventoryNoData": "لا توجد بيانات جرد حتى الآن - قم بتحديث الصفحة لجمعها.", - "inventoryHost": "يستضيف", + "inventoryHost": "المضيف", "inventoryCollectedCount": "تم جمع {{count}}/{{total}}", "inventoryOs": "نظام التشغيل", "inventoryKernel": "النواة", "inventoryArch": "قوس", - "inventoryUptime": "وقت التشغيل", + "inventoryUptime": "مدة التشغيل", "inventoryPackageManager": "مدير الحزم", "inventoryCollectedAt": "تم جمعها", - "packageActionLabel": "فعل", + "packageActionLabel": "الإجراء", "packageInstall": "ثَبَّتَ", - "packageRemove": "يزيل", + "packageRemove": "إزالة", "packageUpgradeAll": "قم بترقية جميع الحزم", "packageNameLabel": "اسم الحزمة", "packageNameRequired": "اسم الحزمة مطلوب", - "packageHint": "يتطلب الوصول على مستوى الإدارة لكل مضيف ويتم رفعه باستخدام كلمة مرور sudo المخزنة للمضيف." + "packageHint": "يتطلب الوصول على مستوى الإدارة لكل مضيف ويتم رفعه باستخدام كلمة مرور sudo المخزنة للمضيف.", + "shareFleet": "أسطول مشترك", + "shareFleetTitle": "شارك \"{{name}}\"", + "shareFleetDescription": "يُشارك هذا الأمر أجهزة الأعضاء الحالية في هذه المجموعة مع المستخدمين أو الأدوار المُحددة. لا تتم مشاركة الأجهزة التي تُضاف إلى المجموعة لاحقًا تلقائيًا - يُرجى إعادة المشاركة لإضافتها.", + "shareSelectionRequired": "اختر مستخدمًا واحدًا أو دورًا واحدًا على الأقل", + "fleetSharedSuccessfully": "مشترك {{shared}} من {{total}} مضيف (مضيفين) في هذه المجموعة", + "failedToShareFleet": "فشل في مشاركة الأسطول", + "noMembersToShare": "لا يوجد لدى هذا الأسطول مضيفون أعضاء للمشاركة حتى الآن." } } }, diff --git a/plugins/fleets/locales/translated/bg_BG.json b/plugins/fleets/locales/translated/bg_BG.json index 41029c287..3a507829a 100644 --- a/plugins/fleets/locales/translated/bg_BG.json +++ b/plugins/fleets/locales/translated/bg_BG.json @@ -1,4 +1,18 @@ { + "permissions": { + "view": { + "title": "Преглед на автопаркове", + "description": "Вижте автопаркове, техните членове и инвентар." + }, + "manage": { + "title": "Управление на автопаркове", + "description": "Създавайте, редактирайте и изтривайте автопаркове, променяйте членството и споделяйте автопаркове с други потребители или роли." + }, + "execute": { + "title": "Изпълняване на действия за флотилия", + "description": "Изпълнявайте команди и действия за пакетиране в рамките на флотилия и прехвърляйте файлове към и от нейните хостове-членки." + } + }, "newUi": { "sidebar": { "fleets": { @@ -79,7 +93,14 @@ "packageUpgradeAll": "Надстройте всички пакети", "packageNameLabel": "Име на пакета", "packageNameRequired": "Изисква се име на пакета", - "packageHint": "Изисква достъп на ниво управление за всеки хост и повишава правата, използвайки съхранената парола за sudo на хоста." + "packageHint": "Изисква достъп на ниво управление за всеки хост и повишава правата, използвайки съхранената sudo парола на хоста.", + "shareFleet": "Споделяне на флота", + "shareFleetTitle": "Сподели „{{name}}“", + "shareFleetDescription": "Споделя текущите хостове-членове на този флот с избраните потребители или роли. Хостовете, добавени към флота по-късно, не се споделят автоматично - споделете отново, за да ги включите.", + "shareSelectionRequired": "Изберете поне един потребител или роля", + "fleetSharedSuccessfully": "Споделени {{shared}} от {{total}} хост(а) в този флот", + "failedToShareFleet": "Споделянето на автопарка не бе успешно", + "noMembersToShare": "Този флот все още няма хостове-членове за споделяне." } } }, diff --git a/plugins/fleets/locales/translated/bn_BD.json b/plugins/fleets/locales/translated/bn_BD.json index f399b73c5..18ffb4fa6 100644 --- a/plugins/fleets/locales/translated/bn_BD.json +++ b/plugins/fleets/locales/translated/bn_BD.json @@ -1,129 +1,150 @@ { + "permissions": { + "view": { + "title": "View fleets", + "description": "See fleets, their members and inventory." + }, + "manage": { + "title": "Manage fleets", + "description": "Create, edit and delete fleets, change membership, and share fleets with other users or roles." + }, + "execute": { + "title": "Run fleet actions", + "description": "Run commands and package actions across a fleet, and transfer files to and from its member hosts." + } + }, "newUi": { "sidebar": { "fleets": { - "title": "ফ্লিট", - "createFleet": "ফ্লিট তৈরি করুন", - "createFleetTitle": "ফ্লিট তৈরি করুন", - "editFleetTitle": "ফ্লিট সম্পাদনা করুন", - "createFleetDescription": "ফ্লিট হলো নামযুক্ত হোস্টদের একটি দল, যাদের বিরুদ্ধে আপনি একটি ইউনিট হিসেবে বিভিন্ন অ্যাকশন চালাতে পারেন।", - "nameLabel": "নাম", - "namePlaceholder": "যেমন, ওয়েব সার্ভার", - "nameRequired": "ফ্লিটের নাম প্রয়োজন", - "descriptionLabel": "বর্ণনা", - "descriptionPlaceholder": "ঐচ্ছিক বিবরণ", - "colorLabel": "রঙ", - "tagRulesLabel": "ট্যাগ নিয়ম", - "tagRulesPlaceholder": "প্রোড-ওয়েব, এজ", - "tagRulesHint": "ম্যানুয়ালি যোগ করা হোস্টগুলোর পাশাপাশি, এই ট্যাগগুলোর যেকোনো একটি থাকা হোস্টগুলো স্বয়ংক্রিয়ভাবে অন্তর্ভুক্ত হয়ে যায়।", - "fleetCreated": "ফ্লিট তৈরি করা হয়েছে", - "fleetUpdated": "ফ্লিট আপডেট করা হয়েছে", - "fleetDeleted": "ফ্লিট মুছে ফেলা হয়েছে", - "saveFailed": "বহর সংরক্ষণ করতে ব্যর্থ হয়েছে", - "deleteFailed": "ফ্লিট মুছে ফেলতে ব্যর্থ হয়েছে", - "loadFailed": "ফ্লিট লোড করতে ব্যর্থ হয়েছে", - "deleteFleetTitle": "ফ্লিট মুছুন", - "deleteFleetDescription": "আপনি কি \"{{name}}\" মুছে ফেলতে নিশ্চিত? এটি সদস্য হোস্টদেরকে মুছে ফেলে না।", - "searchFleets": "নৌবহর অনুসন্ধান করুন...", - "noFleets": "এখনো কোনো ফ্লিট নেই। শুরু করার জন্য একটি তৈরি করুন।", - "memberCount": "{{count}} হোস্ট", - "memberCount_other": "{{count}} হোস্ট", - "manageMembers": "সদস্যদের পরিচালনা করুন", - "manageMembersTitle": "ফ্লিট সদস্যদের পরিচালনা করুন", - "manageMembersDescription": "এই ফ্লিটের স্ট্যাটিক সদস্যপদে হোস্টদের অন্তর্ভুক্ত বা বহির্ভূত করুন। ট্যাগ নিয়ম দ্বারা মেলানো হোস্টরা সর্বদা অন্তর্ভুক্ত থাকে।", - "searchHosts": "হোস্ট অনুসন্ধান করুন...", - "noHostsFound": "কোন হোস্ট খুঁজে পাওয়া যায়নি", - "noMembers": "এই ফ্লিটে এখনও কোনো সদস্য নেই। হোস্ট যোগ করুন অথবা একটি ট্যাগ নিয়ম সেট করুন।", - "membersLoadFailed": "ফ্লিট সদস্যদের লোড করতে ব্যর্থ হয়েছে", - "memberUpdateFailed": "ফ্লিট সদস্যপদ আপডেট করতে ব্যর্থ হয়েছে", - "tabRun": "রান কমান্ড", - "tabTransfer": "ফাইল স্থানান্তর করুন", - "tabInventory": "ইনভেন্টরি", - "openInventoryTab": "সম্পূর্ণ ট্যাবে খুলুন", - "tabPackages": "প্যাকেজ", - "runOnFleet": "ফ্লিটে চালান", - "commandPlaceholder": "আপটাইম && df -h", - "commandRequired": "একটি কমান্ড প্রয়োজন", - "commandInputsLabel": "কমান্ড ইনপুট", - "commandSucceeded": "সকল হোস্টে কমান্ড সফল হয়েছে।", - "commandPartialFailure": "{{failed}} এর {{total}} হোস্ট ব্যর্থ হয়েছে", - "commandFailed": "কমান্ড চালাতে ব্যর্থ হয়েছে", - "resultSuccess": "সাফল্য", - "resultFailed": "ব্যর্থ", - "push": "ধাক্কা দিন", - "pull": "টান", - "remotePathLabel": "দূরবর্তী পথ", - "remotePathRequired": "একটি দূরবর্তী পথের প্রয়োজন", - "fileLabel": "ফাইল", - "fileRequired": "একটি ফাইল প্রয়োজন", - "pushHint": "নির্বাচিত ফাইলটি ফ্লিটের প্রতিটি হোস্টের এই নির্দিষ্ট পাথে লেখা হয়।", - "pullHint": "এই পাথের ফাইলটি প্রতিটি হোস্ট থেকে পড়া হয় এবং একটি একক জিপ ফাইল হিসেবে ডাউনলোড করা হয়, যা প্রতি হোস্টে একটি করে ফোল্ডারে বিভক্ত থাকে।", - "transferComplete": "স্থানান্তর সম্পন্ন হয়েছে", - "transferFailed": "স্থানান্তর ব্যর্থ হয়েছে", - "refreshInventory": "ইনভেন্টরি রিফ্রেশ করুন", - "inventoryLoadFailed": "ইনভেন্টরি লোড করতে ব্যর্থ হয়েছে", - "inventoryRefreshed": "ইনভেন্টরি রিফ্রেশ করা হয়েছে", - "inventoryRefreshFailed": "ইনভেন্টরি রিফ্রেশ করতে ব্যর্থ হয়েছে", - "inventoryNoData": "এখনও কোনো ইনভেন্টরি ডেটা নেই - এটি সংগ্রহ করতে রিফ্রেশ করুন।", - "inventoryHost": "হোস্ট", - "inventoryCollectedCount": "{{count}}/{{total}} সংগৃহীত", - "inventoryOs": "ওএস", - "inventoryKernel": "কার্নেল", - "inventoryArch": "খিলান", - "inventoryUptime": "আপটাইম", - "inventoryPackageManager": "প্যাকেজ ম্যানেজার", - "inventoryCollectedAt": "সংগৃহীত", - "packageActionLabel": "পদক্ষেপ", - "packageInstall": "ইনস্টল করুন", - "packageRemove": "অপসারণ করুন", - "packageUpgradeAll": "সমস্ত প্যাকেজ আপগ্রেড করুন", - "packageNameLabel": "প্যাকেজের নাম", - "packageNameRequired": "একটি প্যাকেজের নাম প্রয়োজন", - "packageHint": "প্রতিটি হোস্টের জন্য ম্যানেজ-লেভেল অ্যাক্সেস প্রয়োজন এবং হোস্টের সংরক্ষিত sudo পাসওয়ার্ড ব্যবহার করে অ্যাক্সেস উন্নত করা হয়।" + "title": "Fleets", + "createFleet": "Create Fleet", + "createFleetTitle": "Create Fleet", + "editFleetTitle": "Edit Fleet", + "createFleetDescription": "A fleet is a named group of hosts you can run actions against as a unit.", + "nameLabel": "Name", + "namePlaceholder": "e.g., Web Servers", + "nameRequired": "Fleet name is required", + "descriptionLabel": "Description", + "descriptionPlaceholder": "Optional description", + "colorLabel": "Color", + "tagRulesLabel": "Tag rules", + "tagRulesPlaceholder": "prod-web, edge", + "tagRulesHint": "Hosts with any of these tags are automatically included, in addition to hosts added manually.", + "fleetCreated": "Fleet created", + "fleetUpdated": "Fleet updated", + "fleetDeleted": "Fleet deleted", + "saveFailed": "Failed to save fleet", + "deleteFailed": "Failed to delete fleet", + "loadFailed": "Failed to load fleets", + "deleteFleetTitle": "Delete Fleet", + "deleteFleetDescription": "Are you sure you want to delete \"{{name}}\"? This does not delete the member hosts themselves.", + "searchFleets": "Search fleets...", + "noFleets": "No fleets yet. Create one to get started.", + "memberCount": "{{count}} host", + "memberCount_other": "{{count}} hosts", + "manageMembers": "Manage Members", + "manageMembersTitle": "Manage Fleet Members", + "manageMembersDescription": "Toggle hosts in or out of this fleet's static membership. Hosts matched by tag rules are always included.", + "searchHosts": "Search hosts...", + "noHostsFound": "No hosts found", + "noMembers": "This fleet has no members yet. Add hosts or set a tag rule.", + "membersLoadFailed": "Failed to load fleet members", + "memberUpdateFailed": "Failed to update fleet membership", + "tabRun": "Run Command", + "tabTransfer": "Transfer Files", + "tabInventory": "Inventory", + "openInventoryTab": "Open in full tab", + "tabPackages": "Packages", + "runOnFleet": "Run on Fleet", + "commandPlaceholder": "uptime && df -h", + "commandRequired": "A command is required", + "commandInputsLabel": "Command inputs", + "commandSucceeded": "Command succeeded on all hosts", + "commandPartialFailure": "{{failed}} of {{total}} hosts failed", + "commandFailed": "Failed to run command", + "resultSuccess": "Success", + "resultFailed": "Failed", + "push": "Push", + "pull": "Pull", + "remotePathLabel": "Remote path", + "remotePathRequired": "A remote path is required", + "fileLabel": "File", + "fileRequired": "A file is required", + "pushHint": "The selected file is written to this exact path on every host in the fleet.", + "pullHint": "The file at this path is read from every host and downloaded as a single zip, one folder per host.", + "transferComplete": "Transfer complete", + "transferFailed": "Transfer failed", + "refreshInventory": "Refresh Inventory", + "inventoryLoadFailed": "Failed to load inventory", + "inventoryRefreshed": "Inventory refreshed", + "inventoryRefreshFailed": "Failed to refresh inventory", + "inventoryNoData": "No inventory data yet - refresh to collect it.", + "inventoryHost": "Host", + "inventoryCollectedCount": "{{count}}/{{total}} collected", + "inventoryOs": "OS", + "inventoryKernel": "Kernel", + "inventoryArch": "Arch", + "inventoryUptime": "Uptime", + "inventoryPackageManager": "Package manager", + "inventoryCollectedAt": "Collected", + "packageActionLabel": "Action", + "packageInstall": "Install", + "packageRemove": "Remove", + "packageUpgradeAll": "Upgrade all packages", + "packageNameLabel": "Package name", + "packageNameRequired": "A package name is required", + "packageHint": "Requires manage-level access per host and elevates using the host's stored sudo password.", + "shareFleet": "Share Fleet", + "shareFleetTitle": "Share \"{{name}}\"", + "shareFleetDescription": "Shares this fleet's current member hosts with the selected users or roles. Hosts added to the fleet later are not shared automatically - share again to include them.", + "shareSelectionRequired": "Select at least one user or role", + "fleetSharedSuccessfully": "Shared {{shared}} of {{total}} host(s) in this fleet", + "failedToShareFleet": "Failed to share fleet", + "noMembersToShare": "This fleet has no member hosts to share yet." } } }, "nav": { - "fleets": "ফ্লিট" + "fleets": "Fleets" }, "hosts": { - "docsLink": "নথি দেখুন", + "docsLink": "View docs", "sharing": { - "customHoursPlaceholder": "অ্যাক্সেসের মেয়াদ শেষ হতে বাকি ঘন্টা", + "customHoursPlaceholder": "Hours until access expires", "expiry": { - "never": "কখনো না", - "oneHour": "১ ঘন্টা", - "oneDay": "২৪ ঘন্টা", - "sevenDays": "৭ দিন", - "thirtyDays": "৩০ দিন", - "custom": "কাস্টম" + "never": "Never", + "oneHour": "1 hour", + "oneDay": "24 hours", + "sevenDays": "7 days", + "thirtyDays": "30 days", + "custom": "Custom" }, - "expiryLabel": "অ্যাক্সেসের মেয়াদ শেষ", + "expiryLabel": "Access expiry", "levels": { "connect": { - "label": "সংযোগ করুন", - "description": "শুধুমাত্র টার্মিনাল, রিমোট ডেস্কটপ, ফাইল ম্যানেজার, টানেল এবং ডকার সেশনগুলো খোলা থাকবে। হোস্ট কনফিগারেশনে কোনো অ্যাক্সেস নেই।" + "label": "Connect", + "description": "Open sessions only: terminal, remote desktop, file manager, tunnels and Docker. No access to the host configuration." }, "view": { - "label": "দেখুন", - "description": "সংযোগ করুন, এবং হোস্ট কনফিগারেশন দেখুন। গোপনীয় তথ্য কখনোই দেখানো হয় না।" + "label": "View", + "description": "Connect, plus see the host configuration. Secrets are never shown." }, "edit": { - "label": "সম্পাদনা", - "description": "নন-অথেনটিকেশন হোস্ট সেটিংস দেখুন এবং পরিবর্তন করুন। মালিকের SSH অথেনটিকেশন ব্যক্তিগত এবং শুধুমাত্র মালিকের জন্যই সংরক্ষিত থাকে।" + "label": "Edit", + "description": "View, plus modify non-authentication host settings. The owner's SSH authentication stays private and owner-only." }, "manage": { - "label": "পরিচালনা করুন", - "description": "সম্পাদনা করুন, সেইসাথে অন্যদের সাথে হোস্টটি শেয়ার করুন, অনুমতির স্তর পরিবর্তন করুন এবং অ্যাক্সেস প্রত্যাহার করুন।" + "label": "Manage", + "description": "Edit, plus share the host with others, change permission levels and revoke access." } }, - "noMatches": "কোনো মিল খুঁজে পাওয়া যায়নি", - "permissionLevelLabel": "অনুমতি স্তর", - "rolesTab": "ভূমিকা", - "searchPlaceholder": "ব্যবহারকারী বা ভূমিকা অনুসন্ধান করুন...", - "shareButton": "শেয়ার", - "shareWithCount": "শেয়ার করুন ({{count}})", - "usersTab": "ব্যবহারকারীরা" + "noMatches": "No matches found", + "permissionLevelLabel": "Permission level", + "rolesTab": "Roles", + "searchPlaceholder": "Search users or roles...", + "shareButton": "Share", + "shareWithCount": "Share ({{count}})", + "usersTab": "Users" } } } diff --git a/plugins/fleets/locales/translated/ca_ES.json b/plugins/fleets/locales/translated/ca_ES.json index 9906e2a2a..f458e6aba 100644 --- a/plugins/fleets/locales/translated/ca_ES.json +++ b/plugins/fleets/locales/translated/ca_ES.json @@ -1,4 +1,18 @@ { + "permissions": { + "view": { + "title": "Veure flotes", + "description": "Veure flotes, els seus membres i l'inventari." + }, + "manage": { + "title": "Gestionar flotes", + "description": "Crea, edita i elimina flotes, canvia la pertinença i comparteix flotes amb altres usuaris o rols." + }, + "execute": { + "title": "Executar accions de flota", + "description": "Executa ordres i crea accions de paquets a través d'una flota i transfereix fitxers des de i cap als seus amfitrions membres." + } + }, "newUi": { "sidebar": { "fleets": { @@ -79,7 +93,14 @@ "packageUpgradeAll": "Actualitza tots els paquets", "packageNameLabel": "Nom del paquet", "packageNameRequired": "Cal un nom de paquet", - "packageHint": "Requereix accés de nivell d'administració per host i eleva els privilegis mitjançant la contrasenya sudo emmagatzemada per l'host." + "packageHint": "Requereix accés de nivell d'administració per host i eleva els privilegis mitjançant la contrasenya sudo emmagatzemada per l'host.", + "shareFleet": "Comparteix flota", + "shareFleetTitle": "Comparteix \"{{name}}\"", + "shareFleetDescription": "Comparteix els amfitrions membres actuals d'aquesta flota amb els usuaris o rols seleccionats. Els amfitrions afegits a la flota més tard no es comparteixen automàticament; torneu a compartir per incloure'ls.", + "shareSelectionRequired": "Seleccioneu com a mínim un usuari o rol", + "fleetSharedSuccessfully": "S'han compartit {{shared}} de {{total}} hosts en aquesta flota", + "failedToShareFleet": "No s'ha pogut compartir la flota", + "noMembersToShare": "Aquesta flota encara no té amfitrions membres per compartir." } } }, diff --git a/plugins/fleets/locales/translated/cs_CZ.json b/plugins/fleets/locales/translated/cs_CZ.json index 42b7d5318..77d02ce30 100644 --- a/plugins/fleets/locales/translated/cs_CZ.json +++ b/plugins/fleets/locales/translated/cs_CZ.json @@ -1,4 +1,18 @@ { + "permissions": { + "view": { + "title": "Zobrazit flotily", + "description": "Prohlédněte si flotily, jejich členy a inventář." + }, + "manage": { + "title": "Správa vozových parků", + "description": "Vytvářejte, upravujte a mazejte flotily, měňte členství a sdílejte flotily s ostatními uživateli nebo rolemi." + }, + "execute": { + "title": "Spouštění akcí flotily", + "description": "Spouštět příkazy a akce balíčků napříč flotilou a přenášet soubory do a z jejích členských hostitelů." + } + }, "newUi": { "sidebar": { "fleets": { @@ -31,7 +45,7 @@ "manageMembers": "Spravovat členy", "manageMembersTitle": "Správa členů vozového parku", "manageMembersDescription": "Přepíná hostitele do statického členství této flotily nebo z něj. Hostitelé odpovídající pravidlům tagů jsou vždy zahrnuti.", - "searchHosts": "Hledat hostitele...", + "searchHosts": "Hledat hostitele…", "noHostsFound": "Nenalezeny žádné hostitele", "noMembers": "Tato flotila zatím nemá žádné členy. Přidejte hostitele nebo nastavte pravidlo pro tagy.", "membersLoadFailed": "Nepodařilo se načíst členy flotily", @@ -79,7 +93,14 @@ "packageUpgradeAll": "Aktualizujte všechny balíčky", "packageNameLabel": "Název balíčku", "packageNameRequired": "Je vyžadován název balíčku.", - "packageHint": "Vyžaduje přístup na úrovni správy pro každého hostitele a zvyšuje oprávnění pomocí uloženého hesla sudo hostitele." + "packageHint": "Vyžaduje přístup na úrovni správy pro každého hostitele a zvyšuje oprávnění pomocí uloženého hesla sudo hostitele.", + "shareFleet": "Sdílení flotily", + "shareFleetTitle": "Sdílet „{{name}}“", + "shareFleetDescription": "Sdílí aktuální členské hostitele této flotily s vybranými uživateli nebo rolemi. Hostitelé přidaní do flotily později se nesdílejí automaticky – chcete-li je zahrnout, sdílejte je znovu.", + "shareSelectionRequired": "Vyberte alespoň jednoho uživatele nebo roli", + "fleetSharedSuccessfully": "Sdílený {{shared}} z {{total}} hostitel(ů) v této flotile", + "failedToShareFleet": "Sdílení flotily se nezdařilo", + "noMembersToShare": "Tato flotila zatím nemá žádné členské hostitele, o které by se dalo sdílet." } } }, @@ -106,7 +127,7 @@ }, "view": { "label": "Pohled", - "description": "Připojte se a podívejte se na konfiguraci hostitele. Tajné kódy se nikdy nezobrazují." + "description": "Připojení a zobrazení konfigurace hostitele. Tajné kódy se nikdy nezobrazují." }, "edit": { "label": "Upravit", diff --git a/plugins/fleets/locales/translated/da_DK.json b/plugins/fleets/locales/translated/da_DK.json index 609429c7f..54faef24e 100644 --- a/plugins/fleets/locales/translated/da_DK.json +++ b/plugins/fleets/locales/translated/da_DK.json @@ -1,4 +1,18 @@ { + "permissions": { + "view": { + "title": "Se flåder", + "description": "Se flåder, deres medlemmer og inventar." + }, + "manage": { + "title": "Administrer flåder", + "description": "Opret, rediger og slet flåder, skift medlemskab og del flåder med andre brugere eller roller." + }, + "execute": { + "title": "Kør flådehandlinger", + "description": "Kør kommandoer og pakkehandlinger på tværs af en flåde, og overfør filer til og fra dens medlemsværter." + } + }, "newUi": { "sidebar": { "fleets": { @@ -79,7 +93,14 @@ "packageUpgradeAll": "Opgrader alle pakker", "packageNameLabel": "Pakkenavn", "packageNameRequired": "Et pakkenavn er påkrævet", - "packageHint": "Kræver adgang på administratorniveau pr. vært og hæver ved hjælp af værtens gemte sudo-adgangskode." + "packageHint": "Kræver adgang på administratorniveau pr. vært og hæver ved hjælp af værtens gemte sudo-adgangskode.", + "shareFleet": "Del flåde", + "shareFleetTitle": "Del \"{{name}}\"", + "shareFleetDescription": "Deler denne flådes nuværende medlemsværter med de valgte brugere eller roller. Værter, der tilføjes til flåden senere, deles ikke automatisk - del igen for at inkludere dem.", + "shareSelectionRequired": "Vælg mindst én bruger eller rolle", + "fleetSharedSuccessfully": "Delt {{shared}} af {{total}} vært(er) i denne flåde", + "failedToShareFleet": "Kunne ikke dele flåden", + "noMembersToShare": "Denne flåde har endnu ingen medlemsværter at dele." } } }, diff --git a/plugins/fleets/locales/translated/de_DE.json b/plugins/fleets/locales/translated/de_DE.json index a411e05af..f34bf7fe4 100644 --- a/plugins/fleets/locales/translated/de_DE.json +++ b/plugins/fleets/locales/translated/de_DE.json @@ -1,4 +1,18 @@ { + "permissions": { + "view": { + "title": "Flotten ansehen", + "description": "Flotten, ihre Mitglieder und ihren Bestand ansehen." + }, + "manage": { + "title": "Flottenmanagement", + "description": "Flotten erstellen, bearbeiten und löschen, Mitgliedschaften ändern und Flotten mit anderen Benutzern oder Rollen teilen." + }, + "execute": { + "title": "Flottenaktionen durchführen", + "description": "Führe Befehle und Paketaktionen über eine ganze Flotte hinweg aus und übertrage Dateien zu und von den Mitgliedshosts." + } + }, "newUi": { "sidebar": { "fleets": { @@ -48,7 +62,7 @@ "commandSucceeded": "Der Befehl wurde auf allen Hosts erfolgreich ausgeführt.", "commandPartialFailure": "{{failed}} von {{total}} Hosts fehlgeschlagen", "commandFailed": "Befehl konnte nicht ausgeführt werden", - "resultSuccess": "Erfolg", + "resultSuccess": "Erfolgreich", "resultFailed": "Fehlgeschlagen", "push": "Drücken", "pull": "Ziehen", @@ -63,9 +77,9 @@ "refreshInventory": "Inventar aktualisieren", "inventoryLoadFailed": "Fehler beim Laden des Inventars", "inventoryRefreshed": "Bestand aktualisiert", - "inventoryRefreshFailed": "Fehler beim Aktualisieren des Inventars", + "inventoryRefreshFailed": "Aktualisierung des Inventars fehlgeschlagen", "inventoryNoData": "Noch keine Bestandsdaten vorhanden – aktualisieren Sie die Seite, um sie abzurufen.", - "inventoryHost": "Gastgeber", + "inventoryHost": "Host", "inventoryCollectedCount": "{{count}}/{{total}} gesammelt", "inventoryOs": "Betriebssystem", "inventoryKernel": "Kernel", @@ -79,7 +93,14 @@ "packageUpgradeAll": "Alle Pakete aktualisieren", "packageNameLabel": "Paketname", "packageNameRequired": "Ein Paketname ist erforderlich.", - "packageHint": "Erfordert Administratorrechte pro Host und verwendet das gespeicherte sudo-Passwort des Hosts für die Rechteerweiterung." + "packageHint": "Erfordert Administratorrechte pro Host und verwendet das gespeicherte sudo-Passwort des Hosts für die Rechteerweiterung.", + "shareFleet": "Flotte teilen", + "shareFleetTitle": "Teilen \"{{name}}\"", + "shareFleetDescription": "Teilt die aktuellen Hosts dieser Flotte mit den ausgewählten Benutzern oder Rollen. Hosts, die später zur Flotte hinzugefügt werden, werden nicht automatisch geteilt – teilen Sie die Flotte erneut, um sie einzubeziehen.", + "shareSelectionRequired": "Wählen Sie mindestens einen Benutzer oder eine Rolle aus.", + "fleetSharedSuccessfully": "Gemeinsam genutzte {{shared}} von {{total}} Hosts in dieser Flotte", + "failedToShareFleet": "Flottenteilung gescheitert", + "noMembersToShare": "Diese Flotte hat noch keine Mitgliedshosts, die geteilt werden können." } } }, diff --git a/plugins/fleets/locales/translated/el_GR.json b/plugins/fleets/locales/translated/el_GR.json index b4667290e..68f2102a0 100644 --- a/plugins/fleets/locales/translated/el_GR.json +++ b/plugins/fleets/locales/translated/el_GR.json @@ -1,4 +1,18 @@ { + "permissions": { + "view": { + "title": "Δείτε στόλους", + "description": "Δείτε τους στόλους, τα μέλη τους και το απόθεμά τους." + }, + "manage": { + "title": "Διαχείριση στόλων", + "description": "Δημιουργήστε, επεξεργαστείτε και διαγράψτε στόλους, αλλάξτε μέλη και μοιραστείτε στόλους με άλλους χρήστες ή ρόλους." + }, + "execute": { + "title": "Εκτέλεση ενεργειών στόλου", + "description": "Εκτελέστε εντολές και κάντε πακέτα ενεργειών σε ένα στόλο και μεταφέρετε αρχεία από και προς τους κεντρικούς υπολογιστές-μέλη του." + } + }, "newUi": { "sidebar": { "fleets": { @@ -79,7 +93,14 @@ "packageUpgradeAll": "Αναβάθμιση όλων των πακέτων", "packageNameLabel": "Όνομα πακέτου", "packageNameRequired": "Απαιτείται όνομα πακέτου", - "packageHint": "Απαιτείται πρόσβαση σε επίπεδο διαχείρισης ανά κεντρικό υπολογιστή και αναβαθμίζεται χρησιμοποιώντας τον αποθηκευμένο κωδικό πρόσβασης sudo του κεντρικού υπολογιστή." + "packageHint": "Απαιτείται πρόσβαση σε επίπεδο διαχείρισης ανά κεντρικό υπολογιστή και αναβαθμίζεται χρησιμοποιώντας τον αποθηκευμένο κωδικό πρόσβασης sudo του κεντρικού υπολογιστή.", + "shareFleet": "Κοινόχρηστος στόλος", + "shareFleetTitle": "Κοινή χρήση \"{{name}}\"", + "shareFleetDescription": "Κοινοποιεί τους τρέχοντες κεντρικούς υπολογιστές-μέλη αυτού του στόλου με τους επιλεγμένους χρήστες ή ρόλους. Οι κεντρικοί υπολογιστές που προστίθενται στον στόλο αργότερα δεν κοινοποιούνται αυτόματα - κοινοποιήστε τους ξανά για να τους συμπεριλάβετε.", + "shareSelectionRequired": "Επιλέξτε τουλάχιστον έναν χρήστη ή ρόλο", + "fleetSharedSuccessfully": "Κοινόχρηστο {{shared}} από {{total}} κεντρικούς υπολογιστές σε αυτόν τον στόλο", + "failedToShareFleet": "Αποτυχία κοινής χρήσης στόλου", + "noMembersToShare": "Αυτός ο στόλος δεν έχει ακόμη μέλη-οικοδεσπότες για κοινή χρήση." } } }, diff --git a/plugins/fleets/locales/translated/es_ES.json b/plugins/fleets/locales/translated/es_ES.json index 47888c03d..59c5a085d 100644 --- a/plugins/fleets/locales/translated/es_ES.json +++ b/plugins/fleets/locales/translated/es_ES.json @@ -1,4 +1,18 @@ { + "permissions": { + "view": { + "title": "Ver flotas", + "description": "Consulta las flotas, sus miembros y su inventario." + }, + "manage": { + "title": "Gestionar flotas", + "description": "Crea, edita y elimina flotas, cambia la membresía y comparte flotas con otros usuarios o roles." + }, + "execute": { + "title": "Ejecutar acciones de flota", + "description": "Ejecuta comandos y acciones de paquetes en toda una flota, y transfiere archivos hacia y desde sus hosts miembros." + } + }, "newUi": { "sidebar": { "fleets": { @@ -27,12 +41,12 @@ "searchFleets": "Buscar flotas...", "noFleets": "Aún no hay flotas. Crea una para empezar.", "memberCount": "{{count}} anfitrión", - "memberCount_other": "{{count}} anfitriones", + "memberCount_other": "{{count}} hosts", "manageMembers": "Gestionar miembros", "manageMembersTitle": "Gestionar los miembros de la flota", "manageMembersDescription": "Activa o desactiva la pertenencia estática de esta flota a hosts. Los hosts que coincidan con las reglas de etiquetas siempre se incluirán.", "searchHosts": "Buscar hosts...", - "noHostsFound": "No se encontraron hosts", + "noHostsFound": "No se encontraron equipos", "noMembers": "Esta flota aún no tiene miembros. Añade anfitriones o establece una regla de etiquetas.", "membersLoadFailed": "No se pudo cargar a los miembros de la flota.", "memberUpdateFailed": "No se pudo actualizar la membresía de la flota.", @@ -59,16 +73,16 @@ "pushHint": "El archivo seleccionado se escribe en esta ruta exacta en cada host de la flota.", "pullHint": "El archivo ubicado en esta ruta se lee desde cada host y se descarga como un único archivo zip, una carpeta por host.", "transferComplete": "Transferencia completada", - "transferFailed": "La transferencia falló.", + "transferFailed": "Transferencia fallida", "refreshInventory": "Actualizar inventario", "inventoryLoadFailed": "No se pudo cargar el inventario.", "inventoryRefreshed": "Inventario actualizado", "inventoryRefreshFailed": "No se pudo actualizar el inventario.", "inventoryNoData": "Aún no hay datos de inventario; actualice la página para recopilarlos.", - "inventoryHost": "Anfitrión", + "inventoryHost": "Host", "inventoryCollectedCount": "{{count}}/{{total}} recopilado", - "inventoryOs": "Sistema operativo", - "inventoryKernel": "Núcleo", + "inventoryOs": "SO", + "inventoryKernel": "Kernel", "inventoryArch": "Arco", "inventoryUptime": "Tiempo de actividad", "inventoryPackageManager": "gestor de paquetes", @@ -79,7 +93,14 @@ "packageUpgradeAll": "Actualizar todos los paquetes", "packageNameLabel": "Nombre del paquete", "packageNameRequired": "Se requiere un nombre de paquete.", - "packageHint": "Requiere acceso de nivel de administrador por host y eleva los privilegios utilizando la contraseña sudo almacenada en el host." + "packageHint": "Requiere acceso de nivel de administrador por host y eleva los privilegios utilizando la contraseña sudo almacenada en el host.", + "shareFleet": "Compartir flota", + "shareFleetTitle": "Compartir \"{{name}}\"", + "shareFleetDescription": "Comparte los hosts miembros actuales de esta flota con los usuarios o roles seleccionados. Los hosts que se agreguen a la flota posteriormente no se comparten automáticamente; vuelva a compartir para incluirlos.", + "shareSelectionRequired": "Seleccione al menos un usuario o rol.", + "fleetSharedSuccessfully": "Host(s) compartido(s) en esta flota {{shared}} de {{total}} host(s) en esta flota", + "failedToShareFleet": "No se compartió la flota", + "noMembersToShare": "Esta flota aún no tiene anfitriones miembros para compartir." } } }, diff --git a/plugins/fleets/locales/translated/fi_FI.json b/plugins/fleets/locales/translated/fi_FI.json index 536a93516..70c375dba 100644 --- a/plugins/fleets/locales/translated/fi_FI.json +++ b/plugins/fleets/locales/translated/fi_FI.json @@ -1,4 +1,18 @@ { + "permissions": { + "view": { + "title": "Näytä laivastot", + "description": "Katso laivastot, niiden jäsenet ja varastot." + }, + "manage": { + "title": "Hallitse ajoneuvokalustoja", + "description": "Luo, muokkaa ja poista ajoneuvokantoja, muuta jäsenyyksiä ja jaa ajoneuvokantoja muiden käyttäjien tai roolien kanssa." + }, + "execute": { + "title": "Suorita laivaston toiminnot", + "description": "Suorita komentoja ja paketoi toimintoja koko laivastossa ja siirrä tiedostoja sen jäsenpalvelimiin ja niistä pois." + } + }, "newUi": { "sidebar": { "fleets": { @@ -79,7 +93,14 @@ "packageUpgradeAll": "Päivitä kaikki paketit", "packageNameLabel": "Paketin nimi", "packageNameRequired": "Paketin nimi on pakollinen", - "packageHint": "Vaatii hallintatason käyttöoikeudet isäntäkohtaisesti ja nostaa käyttöoikeuksia isännän tallennetulla sudo-salasanalla." + "packageHint": "Vaatii hallintatason käyttöoikeudet isäntäkohtaisesti ja nostaa käyttöoikeuksia isännän tallennetulla sudo-salasanalla.", + "shareFleet": "Jaa laivasto", + "shareFleetTitle": "Jaa \"{{name}}\"", + "shareFleetDescription": "Jakaa tämän laivaston nykyiset jäsenisännät valittujen käyttäjien tai roolien kanssa. Myöhemmin laivastoon lisättyjä isäntiä ei jaeta automaattisesti – jaa uudelleen sisällyttääksesi ne.", + "shareSelectionRequired": "Valitse vähintään yksi käyttäjä tai rooli", + "fleetSharedSuccessfully": "Jaettu {{shared}} / {{total}} isäntäkoneesta tässä laivastossa", + "failedToShareFleet": "Kaluston jakaminen epäonnistui", + "noMembersToShare": "Tällä laivueella ei ole vielä jaettavia jäsenisäntiä." } } }, diff --git a/plugins/fleets/locales/translated/fr_FR.json b/plugins/fleets/locales/translated/fr_FR.json index 09c3279d8..7b842e07f 100644 --- a/plugins/fleets/locales/translated/fr_FR.json +++ b/plugins/fleets/locales/translated/fr_FR.json @@ -1,4 +1,18 @@ { + "permissions": { + "view": { + "title": "Consulter les flottes", + "description": "Consultez les flottes, leurs membres et leur inventaire." + }, + "manage": { + "title": "Gérer les flottes", + "description": "Créer, modifier et supprimer des flottes, changer les membres et partager des flottes avec d'autres utilisateurs ou rôles." + }, + "execute": { + "title": "Actions de la flotte", + "description": "Exécutez des commandes et des actions de paquetage sur l'ensemble d'une flotte, et transférez des fichiers vers et depuis ses hôtes membres." + } + }, "newUi": { "sidebar": { "fleets": { @@ -40,7 +54,7 @@ "tabTransfer": "Transférer des fichiers", "tabInventory": "Inventaire", "openInventoryTab": "Ouvrir dans l'onglet complet", - "tabPackages": "Colis", + "tabPackages": "Paquets", "runOnFleet": "Exécuter sur la flotte", "commandPlaceholder": "disponibilité && df -h", "commandRequired": "Une commande est requise", @@ -49,12 +63,12 @@ "commandPartialFailure": "{{failed}} des hôtes {{total}} ont échoué", "commandFailed": "Échec de l'exécution de la commande", "resultSuccess": "Succès", - "resultFailed": "Échoué", + "resultFailed": "Échec", "push": "Pousser", "pull": "Tirer", "remotePathLabel": "Chemin distant", "remotePathRequired": "Un chemin distant est nécessaire", - "fileLabel": "Déposer", + "fileLabel": "Fichier", "fileRequired": "Un fichier est requis", "pushHint": "Le fichier sélectionné est enregistré à cet emplacement précis sur chaque hôte du parc.", "pullHint": "Le fichier situé à cet emplacement est lu depuis chaque hôte et téléchargé sous forme d'un seul fichier zip, un dossier par hôte.", @@ -67,7 +81,7 @@ "inventoryNoData": "Aucune donnée d'inventaire pour le moment - actualisez la page pour la récupérer.", "inventoryHost": "Hôte", "inventoryCollectedCount": "{{count}}/{{total}} collecté", - "inventoryOs": "Système d'exploitation", + "inventoryOs": "OS", "inventoryKernel": "Noyau", "inventoryArch": "Cambre", "inventoryUptime": "Disponibilité", @@ -75,11 +89,18 @@ "inventoryCollectedAt": "Collecté", "packageActionLabel": "Action", "packageInstall": "Installer", - "packageRemove": "Retirer", + "packageRemove": "Supprimer", "packageUpgradeAll": "Mettez à niveau tous les forfaits", "packageNameLabel": "Nom du paquet", "packageNameRequired": "Un nom de paquet est requis.", - "packageHint": "Nécessite un accès de niveau administrateur par hôte et élève les privilèges à l'aide du mot de passe sudo stocké sur l'hôte." + "packageHint": "Nécessite un accès de niveau administrateur par hôte et élève les privilèges à l'aide du mot de passe sudo stocké sur l'hôte.", + "shareFleet": "Flotte partagée", + "shareFleetTitle": "Partager \"{{name}}\"", + "shareFleetDescription": "Permet de partager les hôtes membres actuels de cette flotte avec les utilisateurs ou rôles sélectionnés. Les hôtes ajoutés ultérieurement à la flotte ne sont pas partagés automatiquement ; veuillez renouveler le partage pour les inclure.", + "shareSelectionRequired": "Sélectionnez au moins un utilisateur ou un rôle", + "fleetSharedSuccessfully": "Partagé {{shared}} de {{total}} hôtes dans cette flotte", + "failedToShareFleet": "Échec du partage de la flotte", + "noMembersToShare": "Cette flotte ne compte pas encore d'hôtes membres à partager." } } }, diff --git a/plugins/fleets/locales/translated/he_IL.json b/plugins/fleets/locales/translated/he_IL.json index 4a515854d..5780c5a41 100644 --- a/plugins/fleets/locales/translated/he_IL.json +++ b/plugins/fleets/locales/translated/he_IL.json @@ -1,4 +1,18 @@ { + "permissions": { + "view": { + "title": "צפה בציי רכב", + "description": "ראה ציי רכב, חבריהם ומלאי." + }, + "manage": { + "title": "ניהול ציי רכב", + "description": "צור, ערוך ומחק ציי רכב, שנה חברות ושתף ציי רכב עם משתמשים או תפקידים אחרים." + }, + "execute": { + "title": "הפעל פעולות צי", + "description": "הפעל פקודות ופעולות חבילה ברחבי צי, והעבר קבצים אל המארחים החברים בו וממנה." + } + }, "newUi": { "sidebar": { "fleets": { @@ -79,7 +93,14 @@ "packageUpgradeAll": "שדרגו את כל החבילות", "packageNameLabel": "שם החבילה", "packageNameRequired": "נדרש שם חבילה", - "packageHint": "דורש גישת ניהול לכל מחשב מארח ועולה באמצעות סיסמת ה-sudo המאוחסנת של המארח." + "packageHint": "דורש גישת ניהול לכל מחשב מארח ועולה באמצעות סיסמת ה-sudo המאוחסנת של המארח.", + "shareFleet": "שתף צי", + "shareFleetTitle": "שתף \"{{name}}\"", + "shareFleetDescription": "משתף את המארחים החברים הנוכחיים של צי זה עם המשתמשים או התפקידים שנבחרו. מארחים שנוספו לצי מאוחר יותר לא ישותפו אוטומטית - שתף שוב כדי לכלול אותם.", + "shareSelectionRequired": "בחר לפחות משתמש או תפקיד אחד", + "fleetSharedSuccessfully": "משותף {{shared}} של {{total}} מארח(ים) בצי זה", + "failedToShareFleet": "שיתוף הצי נכשל", + "noMembersToShare": "לצי הזה עדיין אין מארחים חברים לשיתוף." } } }, diff --git a/plugins/fleets/locales/translated/hi_IN.json b/plugins/fleets/locales/translated/hi_IN.json index 6b06d0547..0c51d8703 100644 --- a/plugins/fleets/locales/translated/hi_IN.json +++ b/plugins/fleets/locales/translated/hi_IN.json @@ -1,90 +1,111 @@ { + "permissions": { + "view": { + "title": "View fleets", + "description": "See fleets, their members and inventory." + }, + "manage": { + "title": "Manage fleets", + "description": "Create, edit and delete fleets, change membership, and share fleets with other users or roles." + }, + "execute": { + "title": "Run fleet actions", + "description": "Run commands and package actions across a fleet, and transfer files to and from its member hosts." + } + }, "newUi": { "sidebar": { "fleets": { - "title": "बेड़े", - "createFleet": "बेड़ा बनाएं", - "createFleetTitle": "बेड़ा बनाएं", - "editFleetTitle": "बेड़े को संपादित करें", - "createFleetDescription": "फ्लीट होस्ट का एक नामित समूह है जिसके विरुद्ध आप एक इकाई के रूप में कार्रवाई कर सकते हैं।", + "title": "Fleets", + "createFleet": "Create Fleet", + "createFleetTitle": "Create Fleet", + "editFleetTitle": "Edit Fleet", + "createFleetDescription": "A fleet is a named group of hosts you can run actions against as a unit.", "nameLabel": "नाम", - "namePlaceholder": "उदाहरण के लिए, वेब सर्वर", - "nameRequired": "बेड़े का नाम आवश्यक है", + "namePlaceholder": "e.g., Web Servers", + "nameRequired": "Fleet name is required", "descriptionLabel": "विवरण", "descriptionPlaceholder": "वैकल्पिक विवरण", "colorLabel": "रंग", - "tagRulesLabel": "टैग नियम", - "tagRulesPlaceholder": "प्रोड-वेब, एज", - "tagRulesHint": "मैन्युअल रूप से जोड़े गए होस्ट के अतिरिक्त, इनमें से किसी भी टैग वाले होस्ट स्वचालित रूप से शामिल हो जाते हैं।", - "fleetCreated": "बेड़ा बनाया गया", - "fleetUpdated": "बेड़े को अपडेट किया गया", - "fleetDeleted": "बेड़ा हटा दिया गया", - "saveFailed": "बेड़े को बचाने में विफल", - "deleteFailed": "बेड़ा हटाने में विफल", - "loadFailed": "फ्लीट लोड करने में विफल", - "deleteFleetTitle": "बेड़ा हटाएं", - "deleteFleetDescription": "क्या आप वाकई \"{{name}}\" को हटाना चाहते हैं? इससे सदस्य होस्ट स्वयं नहीं हटेंगे।", - "searchFleets": "खोज बेड़े...", - "noFleets": "अभी तक कोई बेड़ा नहीं है। शुरुआत करने के लिए एक बेड़ा बनाएं।", - "memberCount": "{{count}} होस्ट", - "memberCount_other": "{{count}} मेजबान", - "manageMembers": "सदस्यों का प्रबंधन करें", - "manageMembersTitle": "बेड़े के सदस्यों का प्रबंधन करें", - "manageMembersDescription": "इस फ्लीट की स्थायी सदस्यता में होस्ट को शामिल या बाहर करें। टैग नियमों द्वारा मेल खाने वाले होस्ट हमेशा शामिल होते हैं।", + "tagRulesLabel": "Tag rules", + "tagRulesPlaceholder": "prod-web, edge", + "tagRulesHint": "Hosts with any of these tags are automatically included, in addition to hosts added manually.", + "fleetCreated": "Fleet created", + "fleetUpdated": "Fleet updated", + "fleetDeleted": "Fleet deleted", + "saveFailed": "Failed to save fleet", + "deleteFailed": "Failed to delete fleet", + "loadFailed": "Failed to load fleets", + "deleteFleetTitle": "Delete Fleet", + "deleteFleetDescription": "Are you sure you want to delete \"{{name}}\"? This does not delete the member hosts themselves.", + "searchFleets": "Search fleets...", + "noFleets": "No fleets yet. Create one to get started.", + "memberCount": "{{count}} host", + "memberCount_other": "{{count}} होस्ट", + "manageMembers": "Manage Members", + "manageMembersTitle": "Manage Fleet Members", + "manageMembersDescription": "Toggle hosts in or out of this fleet's static membership. Hosts matched by tag rules are always included.", "searchHosts": "होस्ट खोजें...", "noHostsFound": "कोई होस्ट नहीं मिला", - "noMembers": "इस फ्लीट में अभी कोई सदस्य नहीं है। होस्ट जोड़ें या टैग नियम सेट करें।", - "membersLoadFailed": "फ्लीट सदस्यों को लोड करने में विफल", - "memberUpdateFailed": "फ्लीट सदस्यता को अपडेट करने में विफल", - "tabRun": "कमांड चलाएँ", - "tabTransfer": "फ़ाइलें स्थानांतरित करें", - "tabInventory": "भंडार", - "openInventoryTab": "पूरे टैब में खोलें", - "tabPackages": "संकुल", - "runOnFleet": "फ्लीट पर चलाएँ", - "commandPlaceholder": "अपटाइम && df -h", - "commandRequired": "एक आदेश आवश्यक है", - "commandInputsLabel": "कमांड इनपुट", - "commandSucceeded": "सभी होस्ट पर कमांड सफलतापूर्वक संचालित हुई।", - "commandPartialFailure": "{{failed}} में से {{total}} होस्ट विफल हो गए", - "commandFailed": "कमांड चलाने में विफल", - "resultSuccess": "सफलता", + "noMembers": "This fleet has no members yet. Add hosts or set a tag rule.", + "membersLoadFailed": "Failed to load fleet members", + "memberUpdateFailed": "Failed to update fleet membership", + "tabRun": "Run Command", + "tabTransfer": "Transfer Files", + "tabInventory": "Inventory", + "openInventoryTab": "Open in full tab", + "tabPackages": "पैकेजेस", + "runOnFleet": "Run on Fleet", + "commandPlaceholder": "uptime && df -h", + "commandRequired": "A command is required", + "commandInputsLabel": "Command inputs", + "commandSucceeded": "Command succeeded on all hosts", + "commandPartialFailure": "{{failed}} of {{total}} hosts failed", + "commandFailed": "Failed to run command", + "resultSuccess": "सफल", "resultFailed": "असफल", - "push": "धकेलना", - "pull": "खींचो", - "remotePathLabel": "दूरस्थ पथ", - "remotePathRequired": "एक दूरस्थ मार्ग आवश्यक है", + "push": "Push", + "pull": "Pull", + "remotePathLabel": "Remote path", + "remotePathRequired": "A remote path is required", "fileLabel": "फ़ाइल", - "fileRequired": "एक फ़ाइल आवश्यक है", - "pushHint": "चयनित फ़ाइल को फ्लीट में मौजूद प्रत्येक होस्ट पर ठीक इसी पथ पर लिखा जाता है।", - "pullHint": "इस पथ पर स्थित फ़ाइल को प्रत्येक होस्ट से पढ़ा जाता है और एक ही ज़िप फ़ाइल के रूप में डाउनलोड किया जाता है, जिसमें प्रत्येक होस्ट के लिए एक फ़ोल्डर होता है।", - "transferComplete": "स्थानांतरण पूरा हुआ", + "fileRequired": "A file is required", + "pushHint": "The selected file is written to this exact path on every host in the fleet.", + "pullHint": "The file at this path is read from every host and downloaded as a single zip, one folder per host.", + "transferComplete": "स्थानांतरण पूर्ण", "transferFailed": "स्थानांतरण विफल", - "refreshInventory": "इन्वेंट्री रीफ़्रेश करें", - "inventoryLoadFailed": "इन्वेंट्री लोड करने में विफल", - "inventoryRefreshed": "इन्वेंट्री अपडेट हो गई", - "inventoryRefreshFailed": "इन्वेंट्री को रीफ़्रेश करने में विफल", - "inventoryNoData": "अभी तक कोई इन्वेंट्री डेटा उपलब्ध नहीं है - इसे प्राप्त करने के लिए पेज को रिफ्रेश करें।", - "inventoryHost": "मेज़बान", - "inventoryCollectedCount": "{{count}}/{{total}} एकत्रित", + "refreshInventory": "Refresh Inventory", + "inventoryLoadFailed": "Failed to load inventory", + "inventoryRefreshed": "Inventory refreshed", + "inventoryRefreshFailed": "Failed to refresh inventory", + "inventoryNoData": "No inventory data yet - refresh to collect it.", + "inventoryHost": "होस्ट", + "inventoryCollectedCount": "{{count}}/{{total}} collected", "inventoryOs": "ओएस", - "inventoryKernel": "गुठली", - "inventoryArch": "मेहराब", + "inventoryKernel": "कर्नेल", + "inventoryArch": "Arch", "inventoryUptime": "अपटाइम", - "inventoryPackageManager": "पैकेज प्रबंधक", - "inventoryCollectedAt": "एकत्र किया हुआ", - "packageActionLabel": "कार्रवाई", - "packageInstall": "स्थापित करना", - "packageRemove": "निकालना", - "packageUpgradeAll": "सभी पैकेजों को अपग्रेड करें", - "packageNameLabel": "पैकेज का नाम", - "packageNameRequired": "पैकेज का नाम आवश्यक है", - "packageHint": "प्रत्येक होस्ट के लिए प्रबंधन-स्तर की पहुँच आवश्यक है और होस्ट के संग्रहीत सूडो पासवर्ड का उपयोग करके पहुँच को बढ़ाया जा सकता है।" + "inventoryPackageManager": "Package manager", + "inventoryCollectedAt": "Collected", + "packageActionLabel": "क्रिया", + "packageInstall": "Install", + "packageRemove": "हटाएँ", + "packageUpgradeAll": "Upgrade all packages", + "packageNameLabel": "Package name", + "packageNameRequired": "A package name is required", + "packageHint": "Requires manage-level access per host and elevates using the host's stored sudo password.", + "shareFleet": "Share Fleet", + "shareFleetTitle": "Share \"{{name}}\"", + "shareFleetDescription": "Shares this fleet's current member hosts with the selected users or roles. Hosts added to the fleet later are not shared automatically - share again to include them.", + "shareSelectionRequired": "Select at least one user or role", + "fleetSharedSuccessfully": "Shared {{shared}} of {{total}} host(s) in this fleet", + "failedToShareFleet": "Failed to share fleet", + "noMembersToShare": "This fleet has no member hosts to share yet." } } }, "nav": { - "fleets": "बेड़े" + "fleets": "Fleets" }, "hosts": { "docsLink": "दस्तावेज़ देखें", @@ -110,7 +131,7 @@ }, "edit": { "label": "संपादित करें", - "description": "आप बिना प्रमाणीकरण वाले होस्ट की सेटिंग्स देख सकते हैं और उनमें बदलाव कर सकते हैं। मालिक का SSH प्रमाणीकरण गोपनीय रहता है और केवल मालिक के लिए ही उपलब्ध होता है।" + "description": "View, plus modify non-authentication host settings. The owner's SSH authentication stays private and owner-only." }, "manage": { "label": "प्रबंधित करें", diff --git a/plugins/fleets/locales/translated/hu_HU.json b/plugins/fleets/locales/translated/hu_HU.json index d44a8dabb..b801a95d6 100644 --- a/plugins/fleets/locales/translated/hu_HU.json +++ b/plugins/fleets/locales/translated/hu_HU.json @@ -1,4 +1,18 @@ { + "permissions": { + "view": { + "title": "Flották megtekintése", + "description": "Tekintse meg a flottákat, azok tagjait és a készletet." + }, + "manage": { + "title": "Flották kezelése", + "description": "Flották létrehozása, szerkesztése és törlése, tagság módosítása, valamint flották megosztása más felhasználókkal vagy szerepkörökkel." + }, + "execute": { + "title": "Flotta műveletek futtatása", + "description": "Parancsok és csomagműveletek futtatása egy flottán belül, fájlok átvitele a taggépekre és a taggépekről." + } + }, "newUi": { "sidebar": { "fleets": { @@ -67,7 +81,7 @@ "inventoryNoData": "Még nincsenek készletadatok – frissítse az oldalt az összegyűjtéséhez.", "inventoryHost": "Házigazda", "inventoryCollectedCount": "{{count}}/{{total}} begyűjtött", - "inventoryOs": "Operációs rendszer", + "inventoryOs": "operációs rendszer", "inventoryKernel": "Kernel", "inventoryArch": "Boltív", "inventoryUptime": "Üzemidő", @@ -79,7 +93,14 @@ "packageUpgradeAll": "Az összes csomag frissítése", "packageNameLabel": "Csomag neve", "packageNameRequired": "Csomagnév megadása kötelező", - "packageHint": "Gazdagépenként felügyeleti szintű hozzáférést igényel, és a gazdagép tárolt sudo jelszavával emeli ki a jogosultságokat." + "packageHint": "Gazdagépenként felügyeleti szintű hozzáférést igényel, és a gazdagép tárolt sudo jelszavával emeli ki a jogosultságokat.", + "shareFleet": "Megosztási flotta", + "shareFleetTitle": "Megosztás \"{{name}}\"", + "shareFleetDescription": "Megosztja a flotta jelenlegi tag hosztjait a kiválasztott felhasználókkal vagy szerepkörökkel. A flottához később hozzáadott hosztok nem kerülnek automatikusan megosztásra – ossza meg újra, hogy belefoglalja őket.", + "shareSelectionRequired": "Válasszon ki legalább egy felhasználót vagy szerepkört", + "fleetSharedSuccessfully": "Megosztott {{shared}} a {{total}} hosztból ebben a flottában", + "failedToShareFleet": "Nem sikerült megosztani a flottát", + "noMembersToShare": "Ennek a flottának még nincsenek megosztható tag hosztjai." } } }, diff --git a/plugins/fleets/locales/translated/id_ID.json b/plugins/fleets/locales/translated/id_ID.json index 9fc9dc2d4..18ffb4fa6 100644 --- a/plugins/fleets/locales/translated/id_ID.json +++ b/plugins/fleets/locales/translated/id_ID.json @@ -1,129 +1,150 @@ { + "permissions": { + "view": { + "title": "View fleets", + "description": "See fleets, their members and inventory." + }, + "manage": { + "title": "Manage fleets", + "description": "Create, edit and delete fleets, change membership, and share fleets with other users or roles." + }, + "execute": { + "title": "Run fleet actions", + "description": "Run commands and package actions across a fleet, and transfer files to and from its member hosts." + } + }, "newUi": { "sidebar": { "fleets": { - "title": "Armada", - "createFleet": "Buat Armada", - "createFleetTitle": "Buat Armada", - "editFleetTitle": "Edit Armada", - "createFleetDescription": "Armada adalah kelompok host bernama yang dapat Anda serang sebagai satu unit.", - "nameLabel": "Nama", - "namePlaceholder": "misalnya, Server Web", - "nameRequired": "Nama armada wajib diisi.", - "descriptionLabel": "Keterangan", - "descriptionPlaceholder": "Deskripsi opsional", - "colorLabel": "Warna", - "tagRulesLabel": "Aturan tag", - "tagRulesPlaceholder": "prod-web, tepi", - "tagRulesHint": "Host yang memiliki salah satu tag ini akan disertakan secara otomatis, di samping host yang ditambahkan secara manual.", - "fleetCreated": "Armada yang dibuat", - "fleetUpdated": "Armada diperbarui", - "fleetDeleted": "Armada dihapus", - "saveFailed": "Gagal menyelamatkan armada.", - "deleteFailed": "Gagal menghapus armada", - "loadFailed": "Gagal memuat armada", - "deleteFleetTitle": "Hapus Armada", - "deleteFleetDescription": "Apakah Anda yakin ingin menghapus \"{{name}}\"? Ini tidak menghapus host anggota itu sendiri.", - "searchFleets": "Armada pencarian...", - "noFleets": "Belum ada armada. Buat satu untuk memulai.", - "memberCount": "{{count}} tuan rumah", - "memberCount_other": "{{count}} tuan rumah", - "manageMembers": "Kelola Anggota", - "manageMembersTitle": "Mengelola Anggota Armada", - "manageMembersDescription": "Aktifkan atau nonaktifkan keanggotaan statis host dalam armada ini. Host yang cocok dengan aturan tag akan selalu disertakan.", - "searchHosts": "Cari host...", - "noHostsFound": "Tidak ada host yang ditemukan.", - "noMembers": "Armada ini belum memiliki anggota. Tambahkan host atau tetapkan aturan tag.", - "membersLoadFailed": "Gagal memuat anggota armada", - "memberUpdateFailed": "Gagal memperbarui keanggotaan armada.", - "tabRun": "Jalankan Perintah", - "tabTransfer": "Transfer File", - "tabInventory": "Inventaris", - "openInventoryTab": "Buka di tab penuh", - "tabPackages": "Paket", - "runOnFleet": "Lari di Armada", - "commandPlaceholder": "waktu aktif && df -h", - "commandRequired": "Diperlukan sebuah perintah.", - "commandInputsLabel": "Masukan perintah", - "commandSucceeded": "Perintah berhasil dijalankan di semua host.", - "commandPartialFailure": "{{failed}} dari {{total}} host gagal", - "commandFailed": "Perintah gagal dijalankan.", - "resultSuccess": "Kesuksesan", - "resultFailed": "Gagal", - "push": "Dorongan", - "pull": "Menarik", - "remotePathLabel": "Jalur jarak jauh", - "remotePathRequired": "Diperlukan jalur jarak jauh.", - "fileLabel": "Mengajukan", - "fileRequired": "Diperlukan sebuah berkas.", - "pushHint": "File yang dipilih akan ditulis ke jalur persis ini di setiap host dalam armada.", - "pullHint": "Berkas di jalur ini dibaca dari setiap host dan diunduh sebagai satu file zip, satu folder per host.", - "transferComplete": "Transfer selesai", - "transferFailed": "Transfer gagal", - "refreshInventory": "Perbarui Inventaris", - "inventoryLoadFailed": "Gagal memuat inventaris", - "inventoryRefreshed": "Persediaan diperbarui", - "inventoryRefreshFailed": "Gagal memperbarui inventaris", - "inventoryNoData": "Belum ada data inventaris - segarkan halaman untuk mengumpulkannya.", - "inventoryHost": "Tuan rumah", - "inventoryCollectedCount": "{{count}}/{{total}} dikumpulkan", - "inventoryOs": "Sistem Operasi", - "inventoryKernel": "Inti", - "inventoryArch": "Lengkungan", - "inventoryUptime": "Waktu aktif", - "inventoryPackageManager": "Pengelola paket", - "inventoryCollectedAt": "Dikumpulkan", - "packageActionLabel": "Tindakan", - "packageInstall": "Memasang", - "packageRemove": "Menghapus", - "packageUpgradeAll": "Tingkatkan semua paket", - "packageNameLabel": "Nama paket", - "packageNameRequired": "Nama paket wajib diisi.", - "packageHint": "Membutuhkan akses tingkat pengelola per host dan ditingkatkan menggunakan kata sandi sudo yang tersimpan di host tersebut." + "title": "Fleets", + "createFleet": "Create Fleet", + "createFleetTitle": "Create Fleet", + "editFleetTitle": "Edit Fleet", + "createFleetDescription": "A fleet is a named group of hosts you can run actions against as a unit.", + "nameLabel": "Name", + "namePlaceholder": "e.g., Web Servers", + "nameRequired": "Fleet name is required", + "descriptionLabel": "Description", + "descriptionPlaceholder": "Optional description", + "colorLabel": "Color", + "tagRulesLabel": "Tag rules", + "tagRulesPlaceholder": "prod-web, edge", + "tagRulesHint": "Hosts with any of these tags are automatically included, in addition to hosts added manually.", + "fleetCreated": "Fleet created", + "fleetUpdated": "Fleet updated", + "fleetDeleted": "Fleet deleted", + "saveFailed": "Failed to save fleet", + "deleteFailed": "Failed to delete fleet", + "loadFailed": "Failed to load fleets", + "deleteFleetTitle": "Delete Fleet", + "deleteFleetDescription": "Are you sure you want to delete \"{{name}}\"? This does not delete the member hosts themselves.", + "searchFleets": "Search fleets...", + "noFleets": "No fleets yet. Create one to get started.", + "memberCount": "{{count}} host", + "memberCount_other": "{{count}} hosts", + "manageMembers": "Manage Members", + "manageMembersTitle": "Manage Fleet Members", + "manageMembersDescription": "Toggle hosts in or out of this fleet's static membership. Hosts matched by tag rules are always included.", + "searchHosts": "Search hosts...", + "noHostsFound": "No hosts found", + "noMembers": "This fleet has no members yet. Add hosts or set a tag rule.", + "membersLoadFailed": "Failed to load fleet members", + "memberUpdateFailed": "Failed to update fleet membership", + "tabRun": "Run Command", + "tabTransfer": "Transfer Files", + "tabInventory": "Inventory", + "openInventoryTab": "Open in full tab", + "tabPackages": "Packages", + "runOnFleet": "Run on Fleet", + "commandPlaceholder": "uptime && df -h", + "commandRequired": "A command is required", + "commandInputsLabel": "Command inputs", + "commandSucceeded": "Command succeeded on all hosts", + "commandPartialFailure": "{{failed}} of {{total}} hosts failed", + "commandFailed": "Failed to run command", + "resultSuccess": "Success", + "resultFailed": "Failed", + "push": "Push", + "pull": "Pull", + "remotePathLabel": "Remote path", + "remotePathRequired": "A remote path is required", + "fileLabel": "File", + "fileRequired": "A file is required", + "pushHint": "The selected file is written to this exact path on every host in the fleet.", + "pullHint": "The file at this path is read from every host and downloaded as a single zip, one folder per host.", + "transferComplete": "Transfer complete", + "transferFailed": "Transfer failed", + "refreshInventory": "Refresh Inventory", + "inventoryLoadFailed": "Failed to load inventory", + "inventoryRefreshed": "Inventory refreshed", + "inventoryRefreshFailed": "Failed to refresh inventory", + "inventoryNoData": "No inventory data yet - refresh to collect it.", + "inventoryHost": "Host", + "inventoryCollectedCount": "{{count}}/{{total}} collected", + "inventoryOs": "OS", + "inventoryKernel": "Kernel", + "inventoryArch": "Arch", + "inventoryUptime": "Uptime", + "inventoryPackageManager": "Package manager", + "inventoryCollectedAt": "Collected", + "packageActionLabel": "Action", + "packageInstall": "Install", + "packageRemove": "Remove", + "packageUpgradeAll": "Upgrade all packages", + "packageNameLabel": "Package name", + "packageNameRequired": "A package name is required", + "packageHint": "Requires manage-level access per host and elevates using the host's stored sudo password.", + "shareFleet": "Share Fleet", + "shareFleetTitle": "Share \"{{name}}\"", + "shareFleetDescription": "Shares this fleet's current member hosts with the selected users or roles. Hosts added to the fleet later are not shared automatically - share again to include them.", + "shareSelectionRequired": "Select at least one user or role", + "fleetSharedSuccessfully": "Shared {{shared}} of {{total}} host(s) in this fleet", + "failedToShareFleet": "Failed to share fleet", + "noMembersToShare": "This fleet has no member hosts to share yet." } } }, "nav": { - "fleets": "Armada" + "fleets": "Fleets" }, "hosts": { - "docsLink": "Lihat dokumen", + "docsLink": "View docs", "sharing": { - "customHoursPlaceholder": "Waktu hingga akses berakhir", + "customHoursPlaceholder": "Hours until access expires", "expiry": { - "never": "Tidak pernah", - "oneHour": "1 jam", - "oneDay": "24 jam", - "sevenDays": "7 hari", - "thirtyDays": "30 hari", - "custom": "Kebiasaan" + "never": "Never", + "oneHour": "1 hour", + "oneDay": "24 hours", + "sevenDays": "7 days", + "thirtyDays": "30 days", + "custom": "Custom" }, - "expiryLabel": "Kedaluwarsa akses", + "expiryLabel": "Access expiry", "levels": { "connect": { - "label": "Menghubungkan", - "description": "Hanya sesi yang diizinkan untuk dibuka: terminal, desktop jarak jauh, pengelola file, terowongan, dan Docker. Tidak ada akses ke konfigurasi host." + "label": "Connect", + "description": "Open sessions only: terminal, remote desktop, file manager, tunnels and Docker. No access to the host configuration." }, "view": { - "label": "Melihat", - "description": "Hubungkan, dan lihat konfigurasi host. Rahasia tidak akan pernah ditampilkan." + "label": "View", + "description": "Connect, plus see the host configuration. Secrets are never shown." }, "edit": { "label": "Edit", - "description": "Lihat, dan ubah pengaturan host non-autentikasi. Autentikasi SSH pemilik tetap bersifat pribadi dan hanya untuk pemilik." + "description": "View, plus modify non-authentication host settings. The owner's SSH authentication stays private and owner-only." }, "manage": { - "label": "Mengelola", - "description": "Edit, bagikan host dengan orang lain, ubah tingkat izin, dan cabut akses." + "label": "Manage", + "description": "Edit, plus share the host with others, change permission levels and revoke access." } }, - "noMatches": "Tidak ditemukan kecocokan.", - "permissionLevelLabel": "Tingkat izin", - "rolesTab": "Peran", - "searchPlaceholder": "Cari pengguna atau peran...", - "shareButton": "Membagikan", - "shareWithCount": "Bagikan ({{count}})", - "usersTab": "Pengguna" + "noMatches": "No matches found", + "permissionLevelLabel": "Permission level", + "rolesTab": "Roles", + "searchPlaceholder": "Search users or roles...", + "shareButton": "Share", + "shareWithCount": "Share ({{count}})", + "usersTab": "Users" } } } diff --git a/plugins/fleets/locales/translated/it_IT.json b/plugins/fleets/locales/translated/it_IT.json index 58ae5aa58..1809f3edf 100644 --- a/plugins/fleets/locales/translated/it_IT.json +++ b/plugins/fleets/locales/translated/it_IT.json @@ -1,4 +1,18 @@ { + "permissions": { + "view": { + "title": "Visualizza le flotte", + "description": "Visualizza le flotte, i loro membri e l'inventario." + }, + "manage": { + "title": "Gestire le flotte", + "description": "Crea, modifica ed elimina flotte, cambia i membri e condividi le flotte con altri utenti o ruoli." + }, + "execute": { + "title": "Esegui azioni della flotta", + "description": "Esegui comandi e azioni sui pacchetti su un'intera flotta e trasferisci file da e verso gli host membri." + } + }, "newUi": { "sidebar": { "fleets": { @@ -11,7 +25,7 @@ "namePlaceholder": "ad esempio, server web", "nameRequired": "Il nome della flotta è obbligatorio", "descriptionLabel": "Descrizione", - "descriptionPlaceholder": "Descrizione facoltativa", + "descriptionPlaceholder": "Descrizione opzionale", "colorLabel": "Colore", "tagRulesLabel": "Regole dei tag", "tagRulesPlaceholder": "prod-web, edge", @@ -65,21 +79,28 @@ "inventoryRefreshed": "Inventario aggiornato", "inventoryRefreshFailed": "Impossibile aggiornare l'inventario", "inventoryNoData": "Nessun dato di inventario disponibile al momento: aggiorna la pagina per visualizzarlo.", - "inventoryHost": "Ospite", + "inventoryHost": "Host", "inventoryCollectedCount": "{{count}}/{{total}} raccolto", - "inventoryOs": "Sistema operativo", + "inventoryOs": "OS", "inventoryKernel": "Kernel", "inventoryArch": "Arco", - "inventoryUptime": "Tempo di attività", + "inventoryUptime": "Uptime", "inventoryPackageManager": "Responsabile del pacchetto", "inventoryCollectedAt": "Raccolto", "packageActionLabel": "Azione", "packageInstall": "Installare", - "packageRemove": "Rimuovere", + "packageRemove": "Rimuovi", "packageUpgradeAll": "Aggiorna tutti i pacchetti", "packageNameLabel": "Nome del pacchetto", "packageNameRequired": "È richiesto un nome per il pacchetto", - "packageHint": "Richiede l'accesso a livello di gestione per host ed eleva i privilegi utilizzando la password sudo memorizzata sull'host." + "packageHint": "Richiede l'accesso a livello di gestione per host ed eleva i privilegi utilizzando la password sudo memorizzata sull'host.", + "shareFleet": "Condividi la flotta", + "shareFleetTitle": "Condividi \"{{name}}\"", + "shareFleetDescription": "Condivide gli host attualmente membri di questa flotta con gli utenti o i ruoli selezionati. Gli host aggiunti alla flotta in un secondo momento non vengono condivisi automaticamente: è necessario ripetere la condivisione per includerli.", + "shareSelectionRequired": "Seleziona almeno un utente o un ruolo", + "fleetSharedSuccessfully": "Condiviso {{shared}} di {{total}} host(i) in questa flotta", + "failedToShareFleet": "Impossibile condividere la flotta", + "noMembersToShare": "Questa flotta non ha ancora host membri da condividere." } } }, diff --git a/plugins/fleets/locales/translated/ja_JP.json b/plugins/fleets/locales/translated/ja_JP.json index 0fbd8aed6..aace4ec77 100644 --- a/plugins/fleets/locales/translated/ja_JP.json +++ b/plugins/fleets/locales/translated/ja_JP.json @@ -1,4 +1,18 @@ { + "permissions": { + "view": { + "title": "車両一覧を見る", + "description": "艦隊、その構成員、および保有資産をご覧ください。" + }, + "manage": { + "title": "車両群を管理する", + "description": "艦隊の作成、編集、削除、メンバーシップの変更、および他のユーザーや役割との艦隊の共有が可能です。" + }, + "execute": { + "title": "艦隊作戦を実行する", + "description": "フリート全体でコマンドやパッケージアクションを実行し、メンバーホストとの間でファイルを転送します。" + } + }, "newUi": { "sidebar": { "fleets": { @@ -11,12 +25,12 @@ "namePlaceholder": "例:Webサーバー", "nameRequired": "艦隊名は必須です", "descriptionLabel": "説明", - "descriptionPlaceholder": "オプションの説明", + "descriptionPlaceholder": "任意の説明", "colorLabel": "色", "tagRulesLabel": "タグルール", "tagRulesPlaceholder": "プロダクションウェブ、エッジ", "tagRulesHint": "これらのタグのいずれかが付いているホストは、手動で追加されたホストに加えて、自動的に含まれます。", - "fleetCreated": "艦隊が創設されました", + "fleetCreated": "艦隊が編成されました", "fleetUpdated": "艦隊情報更新", "fleetDeleted": "艦隊削除", "saveFailed": "艦隊の救出に失敗しました", @@ -32,7 +46,7 @@ "manageMembersTitle": "フリートメンバーの管理", "manageMembersDescription": "このフリートの静的メンバーシップにホストを追加または削除する切り替えを行います。タグルールに一致するホストは常に含まれます。", "searchHosts": "ホストを検索...", - "noHostsFound": "ホストが見つかりませんでした", + "noHostsFound": "ホストが見つかりません", "noMembers": "この艦隊にはまだメンバーがいません。ホストを追加するか、タグルールを設定してください。", "membersLoadFailed": "艦隊メンバーの読み込みに失敗しました", "memberUpdateFailed": "艦隊メンバーシップの更新に失敗しました", @@ -49,7 +63,7 @@ "commandPartialFailure": "{{failed}} の {{total}} ホストが失敗しました", "commandFailed": "コマンドの実行に失敗しました", "resultSuccess": "成功", - "resultFailed": "失敗した", + "resultFailed": "失敗", "push": "押す", "pull": "引く", "remotePathLabel": "リモートパス", @@ -58,7 +72,7 @@ "fileRequired": "ファイルが必要です", "pushHint": "選択されたファイルは、艦隊内のすべてのホスト上のこの正確なパスに書き込まれます。", "pullHint": "このパスにあるファイルは、すべてのホストから読み込まれ、ホストごとに1つのフォルダ、つまり単一のzipファイルとしてダウンロードされます。", - "transferComplete": "転送完了", + "transferComplete": "転送が完了しました", "transferFailed": "転送に失敗しました", "refreshInventory": "在庫を更新", "inventoryLoadFailed": "在庫の読み込みに失敗しました", @@ -70,16 +84,23 @@ "inventoryOs": "OS", "inventoryKernel": "カーネル", "inventoryArch": "アーチ", - "inventoryUptime": "稼働時間", + "inventoryUptime": "アップタイム", "inventoryPackageManager": "パッケージマネージャー", "inventoryCollectedAt": "収集済み", "packageActionLabel": "アクション", "packageInstall": "インストール", - "packageRemove": "取り除く", + "packageRemove": "削除", "packageUpgradeAll": "すべてのパッケージをアップグレードする", "packageNameLabel": "パッケージ名", "packageNameRequired": "パッケージ名は必須です。", - "packageHint": "ホストごとに管理者レベルのアクセス権限が必要で、ホストに保存されているsudoパスワードを使用して権限を昇格します。" + "packageHint": "ホストごとに管理者レベルのアクセス権限が必要で、ホストに保存されているsudoパスワードを使用して権限を昇格します。", + "shareFleet": "シェアフリート", + "shareFleetTitle": "「{{name}} を共有する」", + "shareFleetDescription": "このフリートの現在のメンバーホストを、選択したユーザーまたはロールと共有します。後からフリートに追加されたホストは自動的に共有されません。それらを含めるには、再度共有を実行してください。", + "shareSelectionRequired": "少なくとも1人のユーザーまたは役割を選択してください。", + "fleetSharedSuccessfully": "Shared {{shared}} of {{total}} host(s) in this fleet", + "failedToShareFleet": "車両共有に失敗しました", + "noMembersToShare": "この艦隊には、まだ共有できるメンバーホストがいません。" } } }, diff --git a/plugins/fleets/locales/translated/ko_KR.json b/plugins/fleets/locales/translated/ko_KR.json index 71ca1f048..6e19ec6ca 100644 --- a/plugins/fleets/locales/translated/ko_KR.json +++ b/plugins/fleets/locales/translated/ko_KR.json @@ -1,4 +1,18 @@ { + "permissions": { + "view": { + "title": "함대 보기", + "description": "함대, 구성원 및 보유 자산을 확인하세요." + }, + "manage": { + "title": "차량 관리", + "description": "함대를 생성, 편집 및 삭제하고, 구성원을 변경하고, 다른 사용자 또는 역할과 함대를 공유할 수 있습니다." + }, + "execute": { + "title": "함대 작업 실행", + "description": "여러 호스트로 구성된 네트워크에서 명령을 실행하고 패키지 작업을 수행하며, 구성원 호스트 간에 파일을 전송합니다." + } + }, "newUi": { "sidebar": { "fleets": { @@ -11,7 +25,7 @@ "namePlaceholder": "예: 웹 서버", "nameRequired": "함대 이름은 필수 입력 사항입니다.", "descriptionLabel": "설명", - "descriptionPlaceholder": "선택적 설명", + "descriptionPlaceholder": "선택 사항 설명", "colorLabel": "색상", "tagRulesLabel": "태그 규칙", "tagRulesPlaceholder": "프로드웹, 엣지", @@ -27,12 +41,12 @@ "searchFleets": "함대를 검색하세요...", "noFleets": "아직 함대가 없습니다. 시작하려면 함대를 생성하세요.", "memberCount": "{{count}} 호스트", - "memberCount_other": "{{count}} 호스트", + "memberCount_other": "호스트 {{count}}개", "manageMembers": "회원 관리", "manageMembersTitle": "함대 구성원 관리", "manageMembersDescription": "호스트를 이 함대의 고정 멤버십에 추가하거나 제외할 수 있습니다. 태그 규칙에 따라 일치하는 호스트는 항상 포함됩니다.", - "searchHosts": "호스트를 검색하세요...", - "noHostsFound": "호스트를 찾을 수 없습니다.", + "searchHosts": "호스트 검색...", + "noHostsFound": "호스트를 찾을 수 없습니다", "noMembers": "이 함대에는 아직 멤버가 없습니다. 호스트를 추가하거나 태그 규칙을 설정하세요.", "membersLoadFailed": "함대 구성원을 불러오는 데 실패했습니다.", "memberUpdateFailed": "함대 구성원 정보 업데이트에 실패했습니다.", @@ -49,7 +63,7 @@ "commandPartialFailure": "{{failed}} 의 {{total}} 호스트가 실패했습니다.", "commandFailed": "명령 실행에 실패했습니다.", "resultSuccess": "성공", - "resultFailed": "실패한", + "resultFailed": "실패", "push": "푸시", "pull": "당기다", "remotePathLabel": "원격 경로", @@ -58,28 +72,35 @@ "fileRequired": "파일이 필요합니다", "pushHint": "선택한 파일은 전체 호스트의 정확히 이 경로에 기록됩니다.", "pullHint": "이 경로에 있는 파일은 모든 호스트에서 읽어와 호스트당 하나의 폴더로 구성된 단일 zip 파일로 다운로드됩니다.", - "transferComplete": "이체 완료", + "transferComplete": "전송 완료", "transferFailed": "전송 실패", "refreshInventory": "재고 새로 고침", "inventoryLoadFailed": "재고 불러오기에 실패했습니다", "inventoryRefreshed": "재고가 갱신되었습니다", "inventoryRefreshFailed": "재고 새로 고침에 실패했습니다.", "inventoryNoData": "아직 재고 데이터가 없습니다. 새로 고침하여 데이터를 수집하세요.", - "inventoryHost": "주인", + "inventoryHost": "호스트", "inventoryCollectedCount": "{{count}}/{{total}} 수집됨", "inventoryOs": "OS", - "inventoryKernel": "핵심", + "inventoryKernel": "커널", "inventoryArch": "아치", - "inventoryUptime": "가동 시간", + "inventoryUptime": "업타임", "inventoryPackageManager": "패키지 관리자", "inventoryCollectedAt": "모은", - "packageActionLabel": "행동", + "packageActionLabel": "작업", "packageInstall": "설치하다", - "packageRemove": "제거하다", + "packageRemove": "제거", "packageUpgradeAll": "모든 패키지 업그레이드", "packageNameLabel": "패키지 이름", "packageNameRequired": "패키지 이름은 필수 입력 사항입니다.", - "packageHint": "호스트별 관리자 권한 접근이 필요하며, 호스트에 저장된 sudo 암호를 사용하여 권한을 상승시킵니다." + "packageHint": "호스트별 관리자 권한 접근이 필요하며, 호스트에 저장된 sudo 암호를 사용하여 권한을 상승시킵니다.", + "shareFleet": "공유 차량", + "shareFleetTitle": "\"{{name}} \" 공유", + "shareFleetDescription": "선택한 사용자 또는 역할과 이 플릿의 현재 멤버 호스트를 공유합니다. 나중에 플릿에 추가된 호스트는 자동으로 공유되지 않습니다. 포함시키려면 다시 공유해야 합니다.", + "shareSelectionRequired": "사용자 또는 역할을 하나 이상 선택하세요.", + "fleetSharedSuccessfully": "이 함대에서 {{shared}} 개의 {{total}} 호스트가 공유됩니다.", + "failedToShareFleet": "함대 공유에 실패했습니다", + "noMembersToShare": "이 함대에는 아직 공유할 호스트 회원이 없습니다." } } }, @@ -110,7 +131,7 @@ }, "edit": { "label": "편집", - "description": "인증이 필요하지 않은 호스트 설정을 보고 수정할 수 있습니다. 소유자의 SSH 인증 정보는 비공개로 유지되며 소유자만 볼 수 있습니다." + "description": "인증이 필요하지 않은 호스트 설정을 보고 수정할 수 있습니다. 소유자의 SSH 인증 정보는 비공개로 유지되며 소유자만 접근할 수 있습니다." }, "manage": { "label": "관리", diff --git a/plugins/fleets/locales/translated/nl_NL.json b/plugins/fleets/locales/translated/nl_NL.json index 18399634c..072d96434 100644 --- a/plugins/fleets/locales/translated/nl_NL.json +++ b/plugins/fleets/locales/translated/nl_NL.json @@ -1,4 +1,18 @@ { + "permissions": { + "view": { + "title": "Bekijk vloten", + "description": "Bekijk de vloten, hun leden en inventaris." + }, + "manage": { + "title": "Vlootbeheer", + "description": "Vloten aanmaken, bewerken en verwijderen, het lidmaatschap wijzigen en vloten delen met andere gebruikers of rollen." + }, + "execute": { + "title": "Voer vlootacties uit", + "description": "Voer opdrachten en pakketacties uit op een hele vloot en breng bestanden over van en naar de hosts die lid zijn van de vloot." + } + }, "newUi": { "sidebar": { "fleets": { @@ -31,7 +45,7 @@ "manageMembers": "Leden beheren", "manageMembersTitle": "Vlootleden beheren", "manageMembersDescription": "Voeg hosts toe aan of verwijder ze uit het statische lidmaatschap van deze vloot. Hosts die overeenkomen met tagregels zijn altijd inbegrepen.", - "searchHosts": "Zoek hosts...", + "searchHosts": "Hosts zoeken...", "noHostsFound": "Geen hosts gevonden", "noMembers": "Deze vloot heeft nog geen leden. Voeg hosts toe of stel een tagregel in.", "membersLoadFailed": "Het laden van de vlootleden is mislukt.", @@ -57,7 +71,7 @@ "fileLabel": "Bestand", "fileRequired": "Een bestand is vereist.", "pushHint": "Het geselecteerde bestand wordt op elke host in de vloot naar precies dit pad geschreven.", - "pullHint": "Het bestand op dit pad wordt van elke host gelezen en gedownload als één zip-bestand, één map per host.", + "pullHint": "Het bestand op dit pad wordt van elke host gelezen en gedownload als één zipbestand, één map per host.", "transferComplete": "Overdracht voltooid", "transferFailed": "Overdracht mislukt", "refreshInventory": "Voorraad vernieuwen", @@ -79,7 +93,14 @@ "packageUpgradeAll": "Upgrade alle pakketten", "packageNameLabel": "Pakketnaam", "packageNameRequired": "Een pakketnaam is vereist.", - "packageHint": "Vereist beheerrechten per host en verhoogt deze rechten met behulp van het opgeslagen sudo-wachtwoord van de host." + "packageHint": "Vereist beheerrechten per host en verhoogt deze rechten met behulp van het opgeslagen sudo-wachtwoord van de host.", + "shareFleet": "Deel vloot", + "shareFleetTitle": "Delen \"{{name}}\"", + "shareFleetDescription": "Deelt de huidige hosts van deze vloot met de geselecteerde gebruikers of rollen. Hosts die later aan de vloot worden toegevoegd, worden niet automatisch gedeeld; deel ze opnieuw om ze toe te voegen.", + "shareSelectionRequired": "Selecteer ten minste één gebruiker of rol.", + "fleetSharedSuccessfully": "Gedeelde {{shared}} van {{total}} host(s) in deze vloot", + "failedToShareFleet": "Het delen van de vloot is mislukt.", + "noMembersToShare": "Deze vloot heeft nog geen leden die de diensten van andere beheerders kunnen aanbieden." } } }, diff --git a/plugins/fleets/locales/translated/no_NO.json b/plugins/fleets/locales/translated/no_NO.json index 9dcc31581..7ae1226eb 100644 --- a/plugins/fleets/locales/translated/no_NO.json +++ b/plugins/fleets/locales/translated/no_NO.json @@ -1,128 +1,149 @@ { + "permissions": { + "view": { + "title": "View fleets", + "description": "See fleets, their members and inventory." + }, + "manage": { + "title": "Manage fleets", + "description": "Create, edit and delete fleets, change membership, and share fleets with other users or roles." + }, + "execute": { + "title": "Run fleet actions", + "description": "Run commands and package actions across a fleet, and transfer files to and from its member hosts." + } + }, "newUi": { "sidebar": { "fleets": { - "title": "Flåter", - "createFleet": "Opprett flåte", - "createFleetTitle": "Opprett flåte", - "editFleetTitle": "Rediger flåte", - "createFleetDescription": "En flåte er en navngitt gruppe verter du kan kjøre handlinger mot som en enhet.", + "title": "Fleets", + "createFleet": "Create Fleet", + "createFleetTitle": "Create Fleet", + "editFleetTitle": "Edit Fleet", + "createFleetDescription": "A fleet is a named group of hosts you can run actions against as a unit.", "nameLabel": "Navn", - "namePlaceholder": "f.eks. webservere", - "nameRequired": "Flåtenavn er obligatorisk", + "namePlaceholder": "e.g., Web Servers", + "nameRequired": "Fleet name is required", "descriptionLabel": "Beskrivelse", "descriptionPlaceholder": "Valgfri beskrivelse", - "colorLabel": "Farge", - "tagRulesLabel": "Taggregler", - "tagRulesPlaceholder": "prod-web, kant", - "tagRulesHint": "Verter med noen av disse taggene inkluderes automatisk, i tillegg til verter som legges til manuelt.", - "fleetCreated": "Flåte opprettet", - "fleetUpdated": "Flåten er oppdatert", - "fleetDeleted": "Flåten er slettet", - "saveFailed": "Kunne ikke lagre flåten", - "deleteFailed": "Kunne ikke slette flåten", - "loadFailed": "Kunne ikke laste inn flåter", - "deleteFleetTitle": "Slett flåte", - "deleteFleetDescription": "Er du sikker på at du vil slette «{{name}}»? Dette sletter ikke selve medlemsvertene.", - "searchFleets": "Søk etter flåter...", - "noFleets": "Ingen flåter ennå. Opprett en for å komme i gang.", - "memberCount": "{{count}} vert", + "colorLabel": "Color", + "tagRulesLabel": "Tag rules", + "tagRulesPlaceholder": "prod-web, edge", + "tagRulesHint": "Hosts with any of these tags are automatically included, in addition to hosts added manually.", + "fleetCreated": "Fleet created", + "fleetUpdated": "Fleet updated", + "fleetDeleted": "Fleet deleted", + "saveFailed": "Failed to save fleet", + "deleteFailed": "Failed to delete fleet", + "loadFailed": "Failed to load fleets", + "deleteFleetTitle": "Delete Fleet", + "deleteFleetDescription": "Are you sure you want to delete \"{{name}}\"? This does not delete the member hosts themselves.", + "searchFleets": "Search fleets...", + "noFleets": "No fleets yet. Create one to get started.", + "memberCount": "{{count}} host", "memberCount_other": "{{count}} verter", - "manageMembers": "Administrer medlemmer", - "manageMembersTitle": "Administrer flåtemedlemmer", - "manageMembersDescription": "Veksle verter inn eller ut av denne flåtens statiske medlemskap. Verter som samsvarer med tagregler er alltid inkludert.", - "searchHosts": "Søk etter verter...", - "noHostsFound": "Ingen verter funnet", - "noMembers": "Denne flåten har ingen medlemmer ennå. Legg til verter eller angi en tagregel.", - "membersLoadFailed": "Kunne ikke laste inn flåtemedlemmer", - "memberUpdateFailed": "Kunne ikke oppdatere flåtemedlemskapet", - "tabRun": "Kjør kommando", - "tabTransfer": "Overfør filer", - "tabInventory": "Inventar", - "openInventoryTab": "Åpne i full fane", - "tabPackages": "Pakker", - "runOnFleet": "Kjør på flåten", - "commandPlaceholder": "oppetid og df -h", - "commandRequired": "En kommando er nødvendig", - "commandInputsLabel": "Kommandoinnganger", - "commandSucceeded": "Kommandoen lyktes på alle verter", - "commandPartialFailure": "{{failed}} av {{total}} verter mislyktes", - "commandFailed": "Kunne ikke kjøre kommandoen", + "manageMembers": "Manage Members", + "manageMembersTitle": "Manage Fleet Members", + "manageMembersDescription": "Toggle hosts in or out of this fleet's static membership. Hosts matched by tag rules are always included.", + "searchHosts": "Search hosts...", + "noHostsFound": "No hosts found", + "noMembers": "This fleet has no members yet. Add hosts or set a tag rule.", + "membersLoadFailed": "Failed to load fleet members", + "memberUpdateFailed": "Failed to update fleet membership", + "tabRun": "Run Command", + "tabTransfer": "Transfer Files", + "tabInventory": "Inventory", + "openInventoryTab": "Open in full tab", + "tabPackages": "Packages", + "runOnFleet": "Run on Fleet", + "commandPlaceholder": "uptime && df -h", + "commandRequired": "A command is required", + "commandInputsLabel": "Command inputs", + "commandSucceeded": "Command succeeded on all hosts", + "commandPartialFailure": "{{failed}} of {{total}} hosts failed", + "commandFailed": "Failed to run command", "resultSuccess": "Suksess", "resultFailed": "Mislyktes", - "push": "Trykk", - "pull": "Dra", - "remotePathLabel": "Fjernbane", - "remotePathRequired": "En ekstern sti er nødvendig", + "push": "Push", + "pull": "Pull", + "remotePathLabel": "Remote path", + "remotePathRequired": "A remote path is required", "fileLabel": "Fil", - "fileRequired": "En fil er nødvendig", - "pushHint": "Den valgte filen skrives til denne nøyaktige banen på alle verter i flåten.", - "pullHint": "Filen på denne banen leses fra hver vert og lastes ned som en enkelt zip-fil, én mappe per vert.", - "transferComplete": "Overføringen er fullført", - "transferFailed": "Overføringen mislyktes", - "refreshInventory": "Oppdater beholdningen", - "inventoryLoadFailed": "Kunne ikke laste inn beholdningen", - "inventoryRefreshed": "Lagerbeholdningen er oppdatert", - "inventoryRefreshFailed": "Kunne ikke oppdatere beholdningen", - "inventoryNoData": "Ingen lagerdata ennå – oppdater for å samle dem inn.", - "inventoryHost": "Vert", - "inventoryCollectedCount": "{{count}}/{{total}} samlet", + "fileRequired": "A file is required", + "pushHint": "The selected file is written to this exact path on every host in the fleet.", + "pullHint": "The file at this path is read from every host and downloaded as a single zip, one folder per host.", + "transferComplete": "Transfer complete", + "transferFailed": "Transfer failed", + "refreshInventory": "Refresh Inventory", + "inventoryLoadFailed": "Failed to load inventory", + "inventoryRefreshed": "Inventory refreshed", + "inventoryRefreshFailed": "Failed to refresh inventory", + "inventoryNoData": "No inventory data yet - refresh to collect it.", + "inventoryHost": "Host", + "inventoryCollectedCount": "{{count}}/{{total}} collected", "inventoryOs": "OS", "inventoryKernel": "Kjerne", - "inventoryArch": "Buen", + "inventoryArch": "Arch", "inventoryUptime": "Oppetid", - "inventoryPackageManager": "Pakkebehandler", - "inventoryCollectedAt": "Samlet", - "packageActionLabel": "Handling", - "packageInstall": "Installer", - "packageRemove": "Fjerne", - "packageUpgradeAll": "Oppgrader alle pakker", - "packageNameLabel": "Pakkenavn", - "packageNameRequired": "Et pakkenavn er obligatorisk", - "packageHint": "Krever tilgang på administratornivå per vert og heves ved hjelp av vertens lagrede sudo-passord." + "inventoryPackageManager": "Package manager", + "inventoryCollectedAt": "Collected", + "packageActionLabel": "Action", + "packageInstall": "Install", + "packageRemove": "Fjern", + "packageUpgradeAll": "Upgrade all packages", + "packageNameLabel": "Package name", + "packageNameRequired": "A package name is required", + "packageHint": "Requires manage-level access per host and elevates using the host's stored sudo password.", + "shareFleet": "Share Fleet", + "shareFleetTitle": "Share \"{{name}}\"", + "shareFleetDescription": "Shares this fleet's current member hosts with the selected users or roles. Hosts added to the fleet later are not shared automatically - share again to include them.", + "shareSelectionRequired": "Select at least one user or role", + "fleetSharedSuccessfully": "Shared {{shared}} of {{total}} host(s) in this fleet", + "failedToShareFleet": "Failed to share fleet", + "noMembersToShare": "This fleet has no member hosts to share yet." } } }, "nav": { - "fleets": "Flåter" + "fleets": "Fleets" }, "hosts": { - "docsLink": "Vis dokumenter", + "docsLink": "View docs", "sharing": { - "customHoursPlaceholder": "Timer til tilgangen utløper", + "customHoursPlaceholder": "Hours until access expires", "expiry": { - "never": "Aldri", - "oneHour": "1 time", - "oneDay": "24 timer", - "sevenDays": "7 dager", - "thirtyDays": "30 dager", - "custom": "Skikk" + "never": "Never", + "oneHour": "1 hour", + "oneDay": "24 hours", + "sevenDays": "7 days", + "thirtyDays": "30 days", + "custom": "Custom" }, - "expiryLabel": "Utløpsdato for tilgang", + "expiryLabel": "Access expiry", "levels": { "connect": { "label": "Koble til", - "description": "Kun åpne økter: terminal, eksternt skrivebord, filbehandler, tunneler og Docker. Ingen tilgang til vertskonfigurasjonen." + "description": "Open sessions only: terminal, remote desktop, file manager, tunnels and Docker. No access to the host configuration." }, "view": { - "label": "Utsikt", - "description": "Koble til, pluss se vertskonfigurasjonen. Hemmeligheter vises aldri." + "label": "View", + "description": "Connect, plus see the host configuration. Secrets are never shown." }, "edit": { - "label": "Redigere", - "description": "Vis og endre innstillinger for verter uten autentisering. Eierens SSH-autentisering forblir privat og kun for eieren." + "label": "Rediger", + "description": "View, plus modify non-authentication host settings. The owner's SSH authentication stays private and owner-only." }, "manage": { - "label": "Administrer", - "description": "Rediger, pluss del verten med andre, endre tillatelsesnivåer og tilbakekall tilgang." + "label": "Manage", + "description": "Edit, plus share the host with others, change permission levels and revoke access." } }, - "noMatches": "Ingen treff funnet", - "permissionLevelLabel": "Tillatelsesnivå", - "rolesTab": "Roller", - "searchPlaceholder": "Søk etter brukere eller roller...", - "shareButton": "Dele", - "shareWithCount": "Del ({{count}})", + "noMatches": "No matches found", + "permissionLevelLabel": "Permission level", + "rolesTab": "Roles", + "searchPlaceholder": "Search users or roles...", + "shareButton": "Share", + "shareWithCount": "Share ({{count}})", "usersTab": "Brukere" } } diff --git a/plugins/fleets/locales/translated/pl_PL.json b/plugins/fleets/locales/translated/pl_PL.json index 6634ddc65..2eff54dea 100644 --- a/plugins/fleets/locales/translated/pl_PL.json +++ b/plugins/fleets/locales/translated/pl_PL.json @@ -1,4 +1,18 @@ { + "permissions": { + "view": { + "title": "View fleets", + "description": "See fleets, their members and inventory." + }, + "manage": { + "title": "Manage fleets", + "description": "Create, edit and delete fleets, change membership, and share fleets with other users or roles." + }, + "execute": { + "title": "Run fleet actions", + "description": "Run commands and package actions across a fleet, and transfer files to and from its member hosts." + } + }, "newUi": { "sidebar": { "fleets": { @@ -79,7 +93,14 @@ "packageUpgradeAll": "Uaktualnij wszystkie pakiety", "packageNameLabel": "Nazwa pakietu", "packageNameRequired": "Wymagana jest nazwa pakietu", - "packageHint": "Wymaga dostępu na poziomie zarządzania na każdym hoście i podnosi uprawnienia zapisanym hasłem sudo hosta." + "packageHint": "Wymaga dostępu na poziomie zarządzania na każdym hoście i podnosi uprawnienia zapisanym hasłem sudo hosta.", + "shareFleet": "Share Fleet", + "shareFleetTitle": "Share \"{{name}}\"", + "shareFleetDescription": "Shares this fleet's current member hosts with the selected users or roles. Hosts added to the fleet later are not shared automatically - share again to include them.", + "shareSelectionRequired": "Select at least one user or role", + "fleetSharedSuccessfully": "Shared {{shared}} of {{total}} host(s) in this fleet", + "failedToShareFleet": "Failed to share fleet", + "noMembersToShare": "This fleet has no member hosts to share yet." } } }, diff --git a/plugins/fleets/locales/translated/pt_BR.json b/plugins/fleets/locales/translated/pt_BR.json index bab04d4ce..b907aaed6 100644 --- a/plugins/fleets/locales/translated/pt_BR.json +++ b/plugins/fleets/locales/translated/pt_BR.json @@ -1,129 +1,150 @@ { + "permissions": { + "view": { + "title": "View fleets", + "description": "See fleets, their members and inventory." + }, + "manage": { + "title": "Manage fleets", + "description": "Create, edit and delete fleets, change membership, and share fleets with other users or roles." + }, + "execute": { + "title": "Run fleet actions", + "description": "Run commands and package actions across a fleet, and transfer files to and from its member hosts." + } + }, "newUi": { "sidebar": { "fleets": { - "title": "Frotas", - "createFleet": "Criar Frota", - "createFleetTitle": "Criar Frota", - "editFleetTitle": "Editar frota", - "createFleetDescription": "Uma frota é um grupo nomeado de hosts contra os quais você pode executar ações como uma unidade.", - "nameLabel": "Nome", - "namePlaceholder": "Por exemplo, servidores web", - "nameRequired": "É necessário nomear a frota.", - "descriptionLabel": "Descrição", - "descriptionPlaceholder": "Descrição opcional", - "colorLabel": "Cor", - "tagRulesLabel": "Regras de etiqueta", + "title": "Fleets", + "createFleet": "Create Fleet", + "createFleetTitle": "Create Fleet", + "editFleetTitle": "Edit Fleet", + "createFleetDescription": "A fleet is a named group of hosts you can run actions against as a unit.", + "nameLabel": "Name", + "namePlaceholder": "e.g., Web Servers", + "nameRequired": "Fleet name is required", + "descriptionLabel": "Description", + "descriptionPlaceholder": "Optional description", + "colorLabel": "Color", + "tagRulesLabel": "Tag rules", "tagRulesPlaceholder": "prod-web, edge", - "tagRulesHint": "Os hosts com qualquer uma dessas tags são incluídos automaticamente, além dos hosts adicionados manualmente.", - "fleetCreated": "Frota criada", - "fleetUpdated": "Frota atualizada", - "fleetDeleted": "Frota excluída", - "saveFailed": "Não conseguiram salvar a frota.", - "deleteFailed": "Falha ao excluir a frota", - "loadFailed": "Falha ao carregar as frotas", - "deleteFleetTitle": "Excluir frota", - "deleteFleetDescription": "Tem certeza de que deseja excluir \"{{name}}\"? Isso não exclui os próprios hosts membros.", - "searchFleets": "Pesquisar frotas...", - "noFleets": "Ainda não há frotas. Crie uma para começar.", - "memberCount": "{{count}} anfitrião", - "memberCount_other": "{{count}} anfitriões", - "manageMembers": "Gerenciar membros", - "manageMembersTitle": "Gerenciar membros da frota", - "manageMembersDescription": "Ative ou desative a inclusão de hosts nesta frota estática. Os hosts que corresponderem às regras de tags serão sempre incluídos.", - "searchHosts": "Pesquisar hosts...", - "noHostsFound": "Nenhum host encontrado", - "noMembers": "Esta frota ainda não tem membros. Adicione anfitriões ou defina uma regra de etiqueta.", - "membersLoadFailed": "Falha ao carregar membros da frota", - "memberUpdateFailed": "Falha na atualização da associação à frota", - "tabRun": "Executar comando", - "tabTransfer": "Transferir arquivos", - "tabInventory": "Inventário", - "openInventoryTab": "Abrir em aba inteira", - "tabPackages": "Pacotes", - "runOnFleet": "Executar na frota", - "commandPlaceholder": "tempo de atividade e df -h", - "commandRequired": "É necessário um comando.", - "commandInputsLabel": "Entradas de comando", - "commandSucceeded": "O comando foi executado com sucesso em todos os hosts.", - "commandPartialFailure": "{{failed}} de {{total}} hosts falharam", - "commandFailed": "Falha ao executar o comando", - "resultSuccess": "Sucesso", - "resultFailed": "Fracassado", - "push": "Empurrar", - "pull": "Puxar", - "remotePathLabel": "Caminho remoto", - "remotePathRequired": "É necessário um caminho remoto.", - "fileLabel": "Arquivo", - "fileRequired": "É necessário um arquivo.", - "pushHint": "O arquivo selecionado é gravado exatamente nesse caminho em todos os hosts da frota.", - "pullHint": "O arquivo neste caminho é lido de cada host e baixado como um único arquivo zip, uma pasta por host.", - "transferComplete": "Transferência concluída", - "transferFailed": "A transferência falhou", - "refreshInventory": "Atualizar inventário", - "inventoryLoadFailed": "Falha ao carregar o inventário", - "inventoryRefreshed": "Inventário atualizado", - "inventoryRefreshFailed": "Falha ao atualizar o inventário", - "inventoryNoData": "Ainda não há dados de estoque - atualize a página para coletá-los.", - "inventoryHost": "Hospedar", - "inventoryCollectedCount": "{{count}}/{{total}} coletado", - "inventoryOs": "SO", + "tagRulesHint": "Hosts with any of these tags are automatically included, in addition to hosts added manually.", + "fleetCreated": "Fleet created", + "fleetUpdated": "Fleet updated", + "fleetDeleted": "Fleet deleted", + "saveFailed": "Failed to save fleet", + "deleteFailed": "Failed to delete fleet", + "loadFailed": "Failed to load fleets", + "deleteFleetTitle": "Delete Fleet", + "deleteFleetDescription": "Are you sure you want to delete \"{{name}}\"? This does not delete the member hosts themselves.", + "searchFleets": "Search fleets...", + "noFleets": "No fleets yet. Create one to get started.", + "memberCount": "{{count}} host", + "memberCount_other": "{{count}} hosts", + "manageMembers": "Manage Members", + "manageMembersTitle": "Manage Fleet Members", + "manageMembersDescription": "Toggle hosts in or out of this fleet's static membership. Hosts matched by tag rules are always included.", + "searchHosts": "Search hosts...", + "noHostsFound": "No hosts found", + "noMembers": "This fleet has no members yet. Add hosts or set a tag rule.", + "membersLoadFailed": "Failed to load fleet members", + "memberUpdateFailed": "Failed to update fleet membership", + "tabRun": "Run Command", + "tabTransfer": "Transfer Files", + "tabInventory": "Inventory", + "openInventoryTab": "Open in full tab", + "tabPackages": "Packages", + "runOnFleet": "Run on Fleet", + "commandPlaceholder": "uptime && df -h", + "commandRequired": "A command is required", + "commandInputsLabel": "Command inputs", + "commandSucceeded": "Command succeeded on all hosts", + "commandPartialFailure": "{{failed}} of {{total}} hosts failed", + "commandFailed": "Failed to run command", + "resultSuccess": "Success", + "resultFailed": "Failed", + "push": "Push", + "pull": "Pull", + "remotePathLabel": "Remote path", + "remotePathRequired": "A remote path is required", + "fileLabel": "File", + "fileRequired": "A file is required", + "pushHint": "The selected file is written to this exact path on every host in the fleet.", + "pullHint": "The file at this path is read from every host and downloaded as a single zip, one folder per host.", + "transferComplete": "Transfer complete", + "transferFailed": "Transfer failed", + "refreshInventory": "Refresh Inventory", + "inventoryLoadFailed": "Failed to load inventory", + "inventoryRefreshed": "Inventory refreshed", + "inventoryRefreshFailed": "Failed to refresh inventory", + "inventoryNoData": "No inventory data yet - refresh to collect it.", + "inventoryHost": "Host", + "inventoryCollectedCount": "{{count}}/{{total}} collected", + "inventoryOs": "OS", "inventoryKernel": "Kernel", - "inventoryArch": "Arco", - "inventoryUptime": "Tempo de atividade", - "inventoryPackageManager": "Gerenciador de pacotes", - "inventoryCollectedAt": "Coletado", - "packageActionLabel": "Ação", - "packageInstall": "Instalar", + "inventoryArch": "Arch", + "inventoryUptime": "Uptime", + "inventoryPackageManager": "Package manager", + "inventoryCollectedAt": "Collected", + "packageActionLabel": "Action", + "packageInstall": "Install", "packageRemove": "Remover", - "packageUpgradeAll": "Atualize todos os pacotes", - "packageNameLabel": "Nome do pacote", - "packageNameRequired": "É necessário informar o nome do pacote.", - "packageHint": "Requer acesso de nível de gerenciamento por host e eleva os privilégios usando a senha sudo armazenada no host." + "packageUpgradeAll": "Upgrade all packages", + "packageNameLabel": "Package name", + "packageNameRequired": "A package name is required", + "packageHint": "Requires manage-level access per host and elevates using the host's stored sudo password.", + "shareFleet": "Share Fleet", + "shareFleetTitle": "Share \"{{name}}\"", + "shareFleetDescription": "Shares this fleet's current member hosts with the selected users or roles. Hosts added to the fleet later are not shared automatically - share again to include them.", + "shareSelectionRequired": "Select at least one user or role", + "fleetSharedSuccessfully": "Shared {{shared}} of {{total}} host(s) in this fleet", + "failedToShareFleet": "Failed to share fleet", + "noMembersToShare": "This fleet has no member hosts to share yet." } } }, "nav": { - "fleets": "Frotas" + "fleets": "Fleets" }, "hosts": { - "docsLink": "Ver documentos", + "docsLink": "Documentação", "sharing": { - "customHoursPlaceholder": "Horas restantes até o acesso expirar", + "customHoursPlaceholder": "Hours until access expires", "expiry": { - "never": "Nunca", - "oneHour": "1 hora", - "oneDay": "24 horas", - "sevenDays": "7 dias", - "thirtyDays": "30 dias", - "custom": "Personalizado" + "never": "Never", + "oneHour": "1 hour", + "oneDay": "24 hours", + "sevenDays": "7 days", + "thirtyDays": "30 days", + "custom": "Custom" }, - "expiryLabel": "Expiração do acesso", + "expiryLabel": "Access expiry", "levels": { "connect": { "label": "Conectar", - "description": "Somente sessões abertas: terminal, área de trabalho remota, gerenciador de arquivos, túneis e Docker. Sem acesso à configuração do host." + "description": "Open sessions only: terminal, remote desktop, file manager, tunnels and Docker. No access to the host configuration." }, "view": { - "label": "Visualizar", - "description": "Conecte-se e veja a configuração do host. Os segredos nunca são exibidos." + "label": "View", + "description": "Connect, plus see the host configuration. Secrets are never shown." }, "edit": { "label": "Editar", - "description": "Visualize e modifique as configurações do host que não exigem autenticação. A autenticação SSH do proprietário permanece privada e restrita ao proprietário." + "description": "View, plus modify non-authentication host settings. The owner's SSH authentication stays private and owner-only." }, "manage": { - "label": "Gerenciar", - "description": "Edite, compartilhe o host com outras pessoas, altere os níveis de permissão e revogue o acesso." + "label": "Manage", + "description": "Edit, plus share the host with others, change permission levels and revoke access." } }, - "noMatches": "Nenhuma correspondência encontrada", - "permissionLevelLabel": "Nível de permissão", - "rolesTab": "Funções", - "searchPlaceholder": "Pesquisar usuários ou funções...", - "shareButton": "Compartilhar", - "shareWithCount": "Compartilhar ({{count}})", - "usersTab": "Usuários" + "noMatches": "No matches found", + "permissionLevelLabel": "Permission level", + "rolesTab": "Roles", + "searchPlaceholder": "Search users or roles...", + "shareButton": "Share", + "shareWithCount": "Share ({{count}})", + "usersTab": "Users" } } } diff --git a/plugins/fleets/locales/translated/pt_PT.json b/plugins/fleets/locales/translated/pt_PT.json index ee9667283..394fcf86b 100644 --- a/plugins/fleets/locales/translated/pt_PT.json +++ b/plugins/fleets/locales/translated/pt_PT.json @@ -1,90 +1,111 @@ { + "permissions": { + "view": { + "title": "View fleets", + "description": "See fleets, their members and inventory." + }, + "manage": { + "title": "Manage fleets", + "description": "Create, edit and delete fleets, change membership, and share fleets with other users or roles." + }, + "execute": { + "title": "Run fleet actions", + "description": "Run commands and package actions across a fleet, and transfer files to and from its member hosts." + } + }, "newUi": { "sidebar": { "fleets": { - "title": "Frotas", - "createFleet": "Criar Frota", - "createFleetTitle": "Criar Frota", - "editFleetTitle": "Editar frota", - "createFleetDescription": "Uma frota é um grupo nomeado de hosts contra os quais pode executar ações como uma unidade.", + "title": "Fleets", + "createFleet": "Create Fleet", + "createFleetTitle": "Create Fleet", + "editFleetTitle": "Edit Fleet", + "createFleetDescription": "A fleet is a named group of hosts you can run actions against as a unit.", "nameLabel": "Nome", - "namePlaceholder": "Por exemplo, os servidores web", - "nameRequired": "É necessário dar um nome à frota.", + "namePlaceholder": "e.g., Web Servers", + "nameRequired": "Fleet name is required", "descriptionLabel": "Descrição", "descriptionPlaceholder": "Descrição opcional", "colorLabel": "Cor", - "tagRulesLabel": "Regras de etiqueta", + "tagRulesLabel": "Tag rules", "tagRulesPlaceholder": "prod-web, edge", - "tagRulesHint": "Os hosts com qualquer uma destas etiquetas são incluídos automaticamente, para além dos hosts adicionados manualmente.", - "fleetCreated": "Frota criada", - "fleetUpdated": "Frota atualizada", - "fleetDeleted": "Frota excluída", - "saveFailed": "Não conseguiram salvar a frota.", - "deleteFailed": "Falha ao eliminar a frota", - "loadFailed": "Falha ao carregar as frotas", - "deleteFleetTitle": "Excluir frota", - "deleteFleetDescription": "Tem a certeza que pretende eliminar \"{{name}}\"? Isto não exclui os próprios hosts membros.", - "searchFleets": "Pesquisar frotas...", - "noFleets": "Ainda não há frotas. Crie uma para começar.", - "memberCount": "{{count}} anfitrião", - "memberCount_other": "{{count}} anfitriões", - "manageMembers": "Gerir membros", - "manageMembersTitle": "Gerir membros da frota", - "manageMembersDescription": "Ative ou desative a inclusão de hosts nesta frota estática. Os hosts que corresponderem às regras das tags serão sempre incluídos.", + "tagRulesHint": "Hosts with any of these tags are automatically included, in addition to hosts added manually.", + "fleetCreated": "Fleet created", + "fleetUpdated": "Fleet updated", + "fleetDeleted": "Fleet deleted", + "saveFailed": "Failed to save fleet", + "deleteFailed": "Failed to delete fleet", + "loadFailed": "Failed to load fleets", + "deleteFleetTitle": "Delete Fleet", + "deleteFleetDescription": "Are you sure you want to delete \"{{name}}\"? This does not delete the member hosts themselves.", + "searchFleets": "Search fleets...", + "noFleets": "No fleets yet. Create one to get started.", + "memberCount": "{{count}} host", + "memberCount_other": "{{count}} máquinas", + "manageMembers": "Manage Members", + "manageMembersTitle": "Manage Fleet Members", + "manageMembersDescription": "Toggle hosts in or out of this fleet's static membership. Hosts matched by tag rules are always included.", "searchHosts": "Pesquisar hosts...", "noHostsFound": "Nenhum host encontrado", - "noMembers": "Esta frota ainda não tem membros. Adicione anfitriões ou defina uma regra de etiqueta.", - "membersLoadFailed": "Falha ao carregar membros da frota", - "memberUpdateFailed": "Falha na atualização da adesão à frota", - "tabRun": "Executar comando", - "tabTransfer": "Transferir ficheiros", - "tabInventory": "Inventário", - "openInventoryTab": "Abrir em separador inteiro", + "noMembers": "This fleet has no members yet. Add hosts or set a tag rule.", + "membersLoadFailed": "Failed to load fleet members", + "memberUpdateFailed": "Failed to update fleet membership", + "tabRun": "Run Command", + "tabTransfer": "Transfer Files", + "tabInventory": "Inventory", + "openInventoryTab": "Open in full tab", "tabPackages": "Pacotes", - "runOnFleet": "Executar na frota", - "commandPlaceholder": "tempo de atividade e df -h", - "commandRequired": "É necessário um comando.", - "commandInputsLabel": "Entradas de comando", - "commandSucceeded": "O comando foi executado com sucesso em todos os hosts.", - "commandPartialFailure": "{{failed}} de {{total}} os hosts falharam", - "commandFailed": "Falha ao executar o comando", + "runOnFleet": "Run on Fleet", + "commandPlaceholder": "uptime && df -h", + "commandRequired": "A command is required", + "commandInputsLabel": "Command inputs", + "commandSucceeded": "Command succeeded on all hosts", + "commandPartialFailure": "{{failed}} of {{total}} hosts failed", + "commandFailed": "Failed to run command", "resultSuccess": "Sucesso", "resultFailed": "Falhou", - "push": "Pressionar", - "pull": "Puxar", - "remotePathLabel": "Caminho remoto", - "remotePathRequired": "É necessário um caminho remoto.", + "push": "Push", + "pull": "Pull", + "remotePathLabel": "Remote path", + "remotePathRequired": "A remote path is required", "fileLabel": "Ficheiro", - "fileRequired": "É necessário um ficheiro.", - "pushHint": "O ficheiro selecionado é gravado exatamente nesse caminho em todos os hosts da frota.", - "pullHint": "O ficheiro neste caminho é lido de cada host e descarregado como um único ficheiro zip, uma pasta por host.", + "fileRequired": "A file is required", + "pushHint": "The selected file is written to this exact path on every host in the fleet.", + "pullHint": "The file at this path is read from every host and downloaded as a single zip, one folder per host.", "transferComplete": "Transferência concluída", - "transferFailed": "A transferência falhou", - "refreshInventory": "Atualizar inventário", - "inventoryLoadFailed": "Falha ao carregar o inventário", - "inventoryRefreshed": "Inventário atualizado", - "inventoryRefreshFailed": "Falha ao atualizar o inventário", - "inventoryNoData": "Ainda não há dados de stock - atualize a página para os recolher.", - "inventoryHost": "Anfitrião", - "inventoryCollectedCount": "{{count}}/{{total}} recolhido", + "transferFailed": "Transferência falhou", + "refreshInventory": "Refresh Inventory", + "inventoryLoadFailed": "Failed to load inventory", + "inventoryRefreshed": "Inventory refreshed", + "inventoryRefreshFailed": "Failed to refresh inventory", + "inventoryNoData": "No inventory data yet - refresh to collect it.", + "inventoryHost": "Host", + "inventoryCollectedCount": "{{count}}/{{total}} collected", "inventoryOs": "SO", "inventoryKernel": "Kernel", - "inventoryArch": "Arco", - "inventoryUptime": "Tempo de atividade", - "inventoryPackageManager": "Gestor de pacotes", - "inventoryCollectedAt": "Coletado", + "inventoryArch": "Arch", + "inventoryUptime": "Tempo de Atividade", + "inventoryPackageManager": "Package manager", + "inventoryCollectedAt": "Collected", "packageActionLabel": "Ação", - "packageInstall": "Instalar", + "packageInstall": "Install", "packageRemove": "Remover", - "packageUpgradeAll": "Atualize todos os pacotes", - "packageNameLabel": "Nome do pacote", - "packageNameRequired": "É necessário informar o nome do pacote.", - "packageHint": "Requer acesso de nível de gestão por host e eleva os privilégios utilizando a palavra-passe sudo armazenada no host." + "packageUpgradeAll": "Upgrade all packages", + "packageNameLabel": "Package name", + "packageNameRequired": "A package name is required", + "packageHint": "Requires manage-level access per host and elevates using the host's stored sudo password.", + "shareFleet": "Share Fleet", + "shareFleetTitle": "Share \"{{name}}\"", + "shareFleetDescription": "Shares this fleet's current member hosts with the selected users or roles. Hosts added to the fleet later are not shared automatically - share again to include them.", + "shareSelectionRequired": "Select at least one user or role", + "fleetSharedSuccessfully": "Shared {{shared}} of {{total}} host(s) in this fleet", + "failedToShareFleet": "Failed to share fleet", + "noMembersToShare": "This fleet has no member hosts to share yet." } } }, "nav": { - "fleets": "Frotas" + "fleets": "Fleets" }, "hosts": { "docsLink": "Ver documentação", @@ -110,7 +131,7 @@ }, "edit": { "label": "Editar", - "description": "Visualize e modifique as definições do host que não requerem autenticação. A autenticação SSH do proprietário permanece privada e restrita ao proprietário." + "description": "View, plus modify non-authentication host settings. The owner's SSH authentication stays private and owner-only." }, "manage": { "label": "Gerir", diff --git a/plugins/fleets/locales/translated/ro_RO.json b/plugins/fleets/locales/translated/ro_RO.json index ecbc40b83..010c8e2bf 100644 --- a/plugins/fleets/locales/translated/ro_RO.json +++ b/plugins/fleets/locales/translated/ro_RO.json @@ -1,4 +1,18 @@ { + "permissions": { + "view": { + "title": "Vizualizați flotele", + "description": "Vedeți flotele, membrii și inventarul acestora." + }, + "manage": { + "title": "Gestionați flotele", + "description": "Creați, editați și ștergeți flote, modificați calitatea de membru și partajați flote cu alți utilizatori sau roluri." + }, + "execute": { + "title": "Execută acțiuni de flotă", + "description": "Execută comenzi și acțiuni de pachete într-o flotă și transferă fișiere către și de la gazdele membre." + } + }, "newUi": { "sidebar": { "fleets": { @@ -79,7 +93,14 @@ "packageUpgradeAll": "Actualizați toate pachetele", "packageNameLabel": "Numele pachetului", "packageNameRequired": "Este necesar un nume de pachet", - "packageHint": "Necesită acces la nivel de administrare per gazdă și ridică privilegiile folosind parola sudo stocată a gazdei." + "packageHint": "Necesită acces la nivel de administrare per gazdă și ridică privilegiile folosind parola sudo stocată a gazdei.", + "shareFleet": "Flotă partajată", + "shareFleetTitle": "Distribuie „{{name}}”", + "shareFleetDescription": "Partajează gazdele membre actuale ale acestei flote cu utilizatorii sau rolurile selectate. Gazdele adăugate ulterior la flotă nu sunt partajate automat - partajați din nou pentru a le include.", + "shareSelectionRequired": "Selectați cel puțin un utilizator sau un rol", + "fleetSharedSuccessfully": "Gazdă(e) {{shared}} partajată din {{total}} din această flotă", + "failedToShareFleet": "Nu s-a putut partaja flota", + "noMembersToShare": "Această flotă nu are încă gazde membre de partajat." } } }, diff --git a/plugins/fleets/locales/translated/ru_RU.json b/plugins/fleets/locales/translated/ru_RU.json index fdc5d652e..e8d15834b 100644 --- a/plugins/fleets/locales/translated/ru_RU.json +++ b/plugins/fleets/locales/translated/ru_RU.json @@ -1,90 +1,111 @@ { + "permissions": { + "view": { + "title": "View fleets", + "description": "See fleets, their members and inventory." + }, + "manage": { + "title": "Manage fleets", + "description": "Create, edit and delete fleets, change membership, and share fleets with other users or roles." + }, + "execute": { + "title": "Run fleet actions", + "description": "Run commands and package actions across a fleet, and transfer files to and from its member hosts." + } + }, "newUi": { "sidebar": { "fleets": { - "title": "Флоты", - "createFleet": "Создать флот", - "createFleetTitle": "Создать флот", - "editFleetTitle": "Редактировать флот", - "createFleetDescription": "Флот — это именованная группа хостов, против которых можно выполнять действия как единое целое.", - "nameLabel": "Имя", - "namePlaceholder": "например, веб-серверы", - "nameRequired": "Название флота обязательно.", + "title": "Fleets", + "createFleet": "Create Fleet", + "createFleetTitle": "Create Fleet", + "editFleetTitle": "Edit Fleet", + "createFleetDescription": "A fleet is a named group of hosts you can run actions against as a unit.", + "nameLabel": "Название", + "namePlaceholder": "e.g., Web Servers", + "nameRequired": "Fleet name is required", "descriptionLabel": "Описание", - "descriptionPlaceholder": "Дополнительное описание", + "descriptionPlaceholder": "Необязательное описание", "colorLabel": "Цвет", - "tagRulesLabel": "Правила тегирования", - "tagRulesPlaceholder": "прод-веб, граничный", - "tagRulesHint": "В дополнение к хостам, добавленным вручную, автоматически включаются хосты, имеющие любой из этих тегов.", - "fleetCreated": "Создан флот", - "fleetUpdated": "Обновление флота", - "fleetDeleted": "Флот уничтожен", - "saveFailed": "Не удалось спасти флот", - "deleteFailed": "Не удалось удалить флот", - "loadFailed": "Не удалось загрузить флот.", - "deleteFleetTitle": "Удалить флот", - "deleteFleetDescription": "Вы уверены, что хотите удалить \"{{name}}\"? Это не удалит сами хосты-участники.", - "searchFleets": "Поиск флотов...", - "noFleets": "Пока нет флотов. Создайте свой, чтобы начать.", - "memberCount": "{{count}} хост", - "memberCount_other": "{{count}} хосты", - "manageMembers": "Управление участниками", - "manageMembersTitle": "Управление членами автопарка", - "manageMembersDescription": "Добавляйте или исключайте хосты из статического членства в этом флоте. Хосты, соответствующие правилам тегов, всегда включаются.", + "tagRulesLabel": "Tag rules", + "tagRulesPlaceholder": "prod-web, edge", + "tagRulesHint": "Hosts with any of these tags are automatically included, in addition to hosts added manually.", + "fleetCreated": "Fleet created", + "fleetUpdated": "Fleet updated", + "fleetDeleted": "Fleet deleted", + "saveFailed": "Failed to save fleet", + "deleteFailed": "Failed to delete fleet", + "loadFailed": "Failed to load fleets", + "deleteFleetTitle": "Delete Fleet", + "deleteFleetDescription": "Are you sure you want to delete \"{{name}}\"? This does not delete the member hosts themselves.", + "searchFleets": "Search fleets...", + "noFleets": "No fleets yet. Create one to get started.", + "memberCount": "{{count}} host", + "memberCount_other": "{{count}} хостов", + "manageMembers": "Manage Members", + "manageMembersTitle": "Manage Fleet Members", + "manageMembersDescription": "Toggle hosts in or out of this fleet's static membership. Hosts matched by tag rules are always included.", "searchHosts": "Поиск хостов...", "noHostsFound": "Хосты не найдены", - "noMembers": "В этом флоте пока нет участников. Добавьте хостов или установите правило тегов.", - "membersLoadFailed": "Не удалось загрузить членов флота.", - "memberUpdateFailed": "Не удалось обновить данные о членстве в автопарке.", - "tabRun": "Выполнить команду", - "tabTransfer": "Передача файлов", - "tabInventory": "Инвентаризация", - "openInventoryTab": "Открыть в полноэкранном режиме", + "noMembers": "This fleet has no members yet. Add hosts or set a tag rule.", + "membersLoadFailed": "Failed to load fleet members", + "memberUpdateFailed": "Failed to update fleet membership", + "tabRun": "Run Command", + "tabTransfer": "Transfer Files", + "tabInventory": "Inventory", + "openInventoryTab": "Open in full tab", "tabPackages": "Пакеты", "runOnFleet": "Run on Fleet", "commandPlaceholder": "uptime && df -h", - "commandRequired": "Требуется команда", - "commandInputsLabel": "Ввод команд", - "commandSucceeded": "Команда успешно выполнена на всех хостах.", - "commandPartialFailure": "{{failed}} из {{total}} хостов не удалось", - "commandFailed": "Не удалось выполнить команду.", + "commandRequired": "A command is required", + "commandInputsLabel": "Command inputs", + "commandSucceeded": "Command succeeded on all hosts", + "commandPartialFailure": "{{failed}} of {{total}} hosts failed", + "commandFailed": "Failed to run command", "resultSuccess": "Успех", - "resultFailed": "Неуспешный", - "push": "Толкать", - "pull": "Тянуть", - "remotePathLabel": "Удаленный путь", - "remotePathRequired": "Требуется удаленный путь", + "resultFailed": "Ошибка", + "push": "Push", + "pull": "Pull", + "remotePathLabel": "Remote path", + "remotePathRequired": "A remote path is required", "fileLabel": "Файл", - "fileRequired": "Требуется файл", - "pushHint": "Выбранный файл записывается точно по этому пути на каждом хосте в сети.", - "pullHint": "Файл по этому пути считывается с каждого хоста и загружается в виде единого ZIP-архива, по одной папке на каждый хост.", + "fileRequired": "A file is required", + "pushHint": "The selected file is written to this exact path on every host in the fleet.", + "pullHint": "The file at this path is read from every host and downloaded as a single zip, one folder per host.", "transferComplete": "Передача завершена", - "transferFailed": "Перевод не удался", - "refreshInventory": "Обновить инвентарь", - "inventoryLoadFailed": "Не удалось загрузить товарные запасы.", - "inventoryRefreshed": "Инвентарь обновлен", - "inventoryRefreshFailed": "Не удалось обновить данные об остатках на складе.", - "inventoryNoData": "Данные об остатках товара пока отсутствуют — обновите страницу, чтобы получить их.", - "inventoryHost": "Хозяин", - "inventoryCollectedCount": "{{count}}/{{total}} собрано", + "transferFailed": "Ошибка передачи", + "refreshInventory": "Refresh Inventory", + "inventoryLoadFailed": "Failed to load inventory", + "inventoryRefreshed": "Inventory refreshed", + "inventoryRefreshFailed": "Failed to refresh inventory", + "inventoryNoData": "No inventory data yet - refresh to collect it.", + "inventoryHost": "Хост", + "inventoryCollectedCount": "{{count}}/{{total}} collected", "inventoryOs": "ОС", "inventoryKernel": "Ядро", - "inventoryArch": "Арка", - "inventoryUptime": "Время безотказной работы", - "inventoryPackageManager": "Менеджер пакетов", - "inventoryCollectedAt": "Собрано", + "inventoryArch": "Arch", + "inventoryUptime": "Время работы", + "inventoryPackageManager": "Package manager", + "inventoryCollectedAt": "Collected", "packageActionLabel": "Действие", - "packageInstall": "Установить", - "packageRemove": "Удалять", - "packageUpgradeAll": "Обновить все пакеты", - "packageNameLabel": "Название пакета", - "packageNameRequired": "Требуется указать имя пакета.", - "packageHint": "Для работы требуется доступ уровня администратора для каждого хоста, повышение прав осуществляется с помощью сохраненного пароля sudo для данного хоста." + "packageInstall": "Install", + "packageRemove": "Удалить", + "packageUpgradeAll": "Upgrade all packages", + "packageNameLabel": "Package name", + "packageNameRequired": "A package name is required", + "packageHint": "Requires manage-level access per host and elevates using the host's stored sudo password.", + "shareFleet": "Share Fleet", + "shareFleetTitle": "Share \"{{name}}\"", + "shareFleetDescription": "Shares this fleet's current member hosts with the selected users or roles. Hosts added to the fleet later are not shared automatically - share again to include them.", + "shareSelectionRequired": "Select at least one user or role", + "fleetSharedSuccessfully": "Shared {{shared}} of {{total}} host(s) in this fleet", + "failedToShareFleet": "Failed to share fleet", + "noMembersToShare": "This fleet has no member hosts to share yet." } } }, "nav": { - "fleets": "Флоты" + "fleets": "Fleets" }, "hosts": { "docsLink": "Документация", @@ -110,7 +131,7 @@ }, "edit": { "label": "Редактирование", - "description": "Просмотр и изменение настроек хоста без аутентификации. SSH-аутентификация владельца остается конфиденциальной и доступна только владельцу." + "description": "View, plus modify non-authentication host settings. The owner's SSH authentication stays private and owner-only." }, "manage": { "label": "Управление", diff --git a/plugins/fleets/locales/translated/sr_SP.json b/plugins/fleets/locales/translated/sr_SP.json index 29926b140..18ffb4fa6 100644 --- a/plugins/fleets/locales/translated/sr_SP.json +++ b/plugins/fleets/locales/translated/sr_SP.json @@ -1,129 +1,150 @@ { + "permissions": { + "view": { + "title": "View fleets", + "description": "See fleets, their members and inventory." + }, + "manage": { + "title": "Manage fleets", + "description": "Create, edit and delete fleets, change membership, and share fleets with other users or roles." + }, + "execute": { + "title": "Run fleet actions", + "description": "Run commands and package actions across a fleet, and transfer files to and from its member hosts." + } + }, "newUi": { "sidebar": { "fleets": { - "title": "Флоте", - "createFleet": "Креирај флоту", - "createFleetTitle": "Креирај флоту", - "editFleetTitle": "Уреди флоту", - "createFleetDescription": "Флота је именована група хостова против којих можете извршавати акције као јединицу.", - "nameLabel": "Име", - "namePlaceholder": "нпр. веб сервери", - "nameRequired": "Назив флоте је обавезан", - "descriptionLabel": "Опис", - "descriptionPlaceholder": "Опциони опис", - "colorLabel": "Боја", - "tagRulesLabel": "Правила за ознаке", + "title": "Fleets", + "createFleet": "Create Fleet", + "createFleetTitle": "Create Fleet", + "editFleetTitle": "Edit Fleet", + "createFleetDescription": "A fleet is a named group of hosts you can run actions against as a unit.", + "nameLabel": "Name", + "namePlaceholder": "e.g., Web Servers", + "nameRequired": "Fleet name is required", + "descriptionLabel": "Description", + "descriptionPlaceholder": "Optional description", + "colorLabel": "Color", + "tagRulesLabel": "Tag rules", "tagRulesPlaceholder": "prod-web, edge", - "tagRulesHint": "Домаћини са било којом од ових ознака се аутоматски укључују, поред домаћина додатих ручно.", - "fleetCreated": "Флота је створена", - "fleetUpdated": "Ажурирана флота", - "fleetDeleted": "Флота је обрисана", - "saveFailed": "Чување флоте није успело", - "deleteFailed": "Брисање флоте није успело", - "loadFailed": "Учитавање возних паркова није успело", - "deleteFleetTitle": "Обриши флоту", - "deleteFleetDescription": "Да ли сте сигурни да желите да обришете „{{name}}“? Овим се не бришу сами чланови хостови.", - "searchFleets": "Претражи флоте...", - "noFleets": "Још нема флота. Направите једну да бисте започели.", - "memberCount": "{{count}} домаћин", - "memberCount_other": "{{count}} домаћини", - "manageMembers": "Управљање члановима", - "manageMembersTitle": "Управљајте члановима флоте", - "manageMembersDescription": "Укључите или искључите хостове из статичког чланства ове флоте. Хостови који се подударају са правилима ознака су увек укључени.", - "searchHosts": "Претражи хостове...", - "noHostsFound": "Нису пронађени хостови", - "noMembers": "Ова флота још нема чланова. Додајте хостове или поставите правило за ознаке.", - "membersLoadFailed": "Учитавање чланова флоте није успело", - "memberUpdateFailed": "Ажурирање чланства у флоти није успело", - "tabRun": "Покрени команду", - "tabTransfer": "Пренос датотека", - "tabInventory": "Инвентар", - "openInventoryTab": "Отвори у целој картици", - "tabPackages": "Пакети", - "runOnFleet": "Трчи на флоти", - "commandPlaceholder": "време непрекидног рада && df -h", - "commandRequired": "Потребна је команда", - "commandInputsLabel": "Уноси команди", - "commandSucceeded": "Команда је успела на свим хостовима", - "commandPartialFailure": "{{failed}} од {{total}} хостова није успело", - "commandFailed": "Није успело покретање команде", - "resultSuccess": "Успех", - "resultFailed": "Неуспешно", - "push": "Гурај", - "pull": "Повуци", - "remotePathLabel": "Удаљена путања", - "remotePathRequired": "Потребна је удаљена путања", - "fileLabel": "Датотека", - "fileRequired": "Потребна је датотека", - "pushHint": "Изабрана датотека се уписује на ову тачну путању на сваком хосту у флоти.", - "pullHint": "Датотека на овој путањи се чита са сваког хоста и преузима као један zip фасцикла, једна фасцикла по хосту.", - "transferComplete": "Пренос завршен", - "transferFailed": "Пренос није успео", - "refreshInventory": "Освежи инвентар", - "inventoryLoadFailed": "Учитавање инвентара није успело", - "inventoryRefreshed": "Инвентар освежен", - "inventoryRefreshFailed": "Освежавање инвентара није успело", - "inventoryNoData": "Још нема података о залихама - освежите да бисте их прикупили.", - "inventoryHost": "Домаћин", - "inventoryCollectedCount": "{{count}}/{{total}} сакупљено", - "inventoryOs": "ОС", - "inventoryKernel": "Језгро", - "inventoryArch": "Лук", - "inventoryUptime": "Време непрекидног рада", - "inventoryPackageManager": "Менаџер пакета", - "inventoryCollectedAt": "Сакупљено", - "packageActionLabel": "Акција", - "packageInstall": "Инсталирај", - "packageRemove": "Уклони", - "packageUpgradeAll": "Надоградите све пакете", - "packageNameLabel": "Назив пакета", - "packageNameRequired": "Потребно је име пакета", - "packageHint": "Захтева приступ на нивоу управљања по хосту и подиже привилегије користећи сачувану sudo лозинку хоста." + "tagRulesHint": "Hosts with any of these tags are automatically included, in addition to hosts added manually.", + "fleetCreated": "Fleet created", + "fleetUpdated": "Fleet updated", + "fleetDeleted": "Fleet deleted", + "saveFailed": "Failed to save fleet", + "deleteFailed": "Failed to delete fleet", + "loadFailed": "Failed to load fleets", + "deleteFleetTitle": "Delete Fleet", + "deleteFleetDescription": "Are you sure you want to delete \"{{name}}\"? This does not delete the member hosts themselves.", + "searchFleets": "Search fleets...", + "noFleets": "No fleets yet. Create one to get started.", + "memberCount": "{{count}} host", + "memberCount_other": "{{count}} hosts", + "manageMembers": "Manage Members", + "manageMembersTitle": "Manage Fleet Members", + "manageMembersDescription": "Toggle hosts in or out of this fleet's static membership. Hosts matched by tag rules are always included.", + "searchHosts": "Search hosts...", + "noHostsFound": "No hosts found", + "noMembers": "This fleet has no members yet. Add hosts or set a tag rule.", + "membersLoadFailed": "Failed to load fleet members", + "memberUpdateFailed": "Failed to update fleet membership", + "tabRun": "Run Command", + "tabTransfer": "Transfer Files", + "tabInventory": "Inventory", + "openInventoryTab": "Open in full tab", + "tabPackages": "Packages", + "runOnFleet": "Run on Fleet", + "commandPlaceholder": "uptime && df -h", + "commandRequired": "A command is required", + "commandInputsLabel": "Command inputs", + "commandSucceeded": "Command succeeded on all hosts", + "commandPartialFailure": "{{failed}} of {{total}} hosts failed", + "commandFailed": "Failed to run command", + "resultSuccess": "Success", + "resultFailed": "Failed", + "push": "Push", + "pull": "Pull", + "remotePathLabel": "Remote path", + "remotePathRequired": "A remote path is required", + "fileLabel": "File", + "fileRequired": "A file is required", + "pushHint": "The selected file is written to this exact path on every host in the fleet.", + "pullHint": "The file at this path is read from every host and downloaded as a single zip, one folder per host.", + "transferComplete": "Transfer complete", + "transferFailed": "Transfer failed", + "refreshInventory": "Refresh Inventory", + "inventoryLoadFailed": "Failed to load inventory", + "inventoryRefreshed": "Inventory refreshed", + "inventoryRefreshFailed": "Failed to refresh inventory", + "inventoryNoData": "No inventory data yet - refresh to collect it.", + "inventoryHost": "Host", + "inventoryCollectedCount": "{{count}}/{{total}} collected", + "inventoryOs": "OS", + "inventoryKernel": "Kernel", + "inventoryArch": "Arch", + "inventoryUptime": "Uptime", + "inventoryPackageManager": "Package manager", + "inventoryCollectedAt": "Collected", + "packageActionLabel": "Action", + "packageInstall": "Install", + "packageRemove": "Remove", + "packageUpgradeAll": "Upgrade all packages", + "packageNameLabel": "Package name", + "packageNameRequired": "A package name is required", + "packageHint": "Requires manage-level access per host and elevates using the host's stored sudo password.", + "shareFleet": "Share Fleet", + "shareFleetTitle": "Share \"{{name}}\"", + "shareFleetDescription": "Shares this fleet's current member hosts with the selected users or roles. Hosts added to the fleet later are not shared automatically - share again to include them.", + "shareSelectionRequired": "Select at least one user or role", + "fleetSharedSuccessfully": "Shared {{shared}} of {{total}} host(s) in this fleet", + "failedToShareFleet": "Failed to share fleet", + "noMembersToShare": "This fleet has no member hosts to share yet." } } }, "nav": { - "fleets": "Флоте" + "fleets": "Fleets" }, "hosts": { - "docsLink": "Прикажи документе", + "docsLink": "View docs", "sharing": { - "customHoursPlaceholder": "Сати до истека приступа", + "customHoursPlaceholder": "Hours until access expires", "expiry": { - "never": "Никад", - "oneHour": "1 сат", - "oneDay": "24 сата", - "sevenDays": "7 дана", - "thirtyDays": "30 дана", - "custom": "Прилагођено" + "never": "Never", + "oneHour": "1 hour", + "oneDay": "24 hours", + "sevenDays": "7 days", + "thirtyDays": "30 days", + "custom": "Custom" }, - "expiryLabel": "Истек приступа", + "expiryLabel": "Access expiry", "levels": { "connect": { - "label": "Повежи се", - "description": "Само отворене сесије: терминал, удаљена радна површина, менаџер датотека, тунели и Докер. Нема приступа конфигурацији хоста." + "label": "Connect", + "description": "Open sessions only: terminal, remote desktop, file manager, tunnels and Docker. No access to the host configuration." }, "view": { - "label": "Поглед", - "description": "Повежите се, плус погледајте конфигурацију хоста. Тајне се никада не приказују." + "label": "View", + "description": "Connect, plus see the host configuration. Secrets are never shown." }, "edit": { - "label": "Измени", - "description": "Прегледајте и мењајте подешавања хоста која не захтевају аутентификацију. SSH аутентификација власника остаје приватна и доступна само власнику." + "label": "Edit", + "description": "View, plus modify non-authentication host settings. The owner's SSH authentication stays private and owner-only." }, "manage": { - "label": "Управљај", - "description": "Уредите, плус делите хост са другима, мењајте нивое дозвола и опозовите приступ." + "label": "Manage", + "description": "Edit, plus share the host with others, change permission levels and revoke access." } }, - "noMatches": "Није пронађено ниједно подударање", - "permissionLevelLabel": "Ниво дозволе", - "rolesTab": "Улоге", - "searchPlaceholder": "Претражите кориснике или улоге...", - "shareButton": "Дели", - "shareWithCount": "Подели ({{count}})", - "usersTab": "Корисници" + "noMatches": "No matches found", + "permissionLevelLabel": "Permission level", + "rolesTab": "Roles", + "searchPlaceholder": "Search users or roles...", + "shareButton": "Share", + "shareWithCount": "Share ({{count}})", + "usersTab": "Users" } } } diff --git a/plugins/fleets/locales/translated/sv_SE.json b/plugins/fleets/locales/translated/sv_SE.json index 844457231..18ffb4fa6 100644 --- a/plugins/fleets/locales/translated/sv_SE.json +++ b/plugins/fleets/locales/translated/sv_SE.json @@ -1,129 +1,150 @@ { + "permissions": { + "view": { + "title": "View fleets", + "description": "See fleets, their members and inventory." + }, + "manage": { + "title": "Manage fleets", + "description": "Create, edit and delete fleets, change membership, and share fleets with other users or roles." + }, + "execute": { + "title": "Run fleet actions", + "description": "Run commands and package actions across a fleet, and transfer files to and from its member hosts." + } + }, "newUi": { "sidebar": { "fleets": { - "title": "Flottor", - "createFleet": "Skapa flotta", - "createFleetTitle": "Skapa flotta", - "editFleetTitle": "Redigera flotta", - "createFleetDescription": "En flotta är en namngiven grupp av värdar som du kan köra åtgärder mot som en enhet.", - "nameLabel": "Namn", - "namePlaceholder": "t.ex. webbservrar", - "nameRequired": "Flottans namn krävs", - "descriptionLabel": "Beskrivning", - "descriptionPlaceholder": "Valfri beskrivning", - "colorLabel": "Färg", - "tagRulesLabel": "Taggregler", - "tagRulesPlaceholder": "prod-web, kant", - "tagRulesHint": "Värdar med någon av dessa taggar inkluderas automatiskt, utöver värdar som läggs till manuellt.", - "fleetCreated": "Flotta skapad", - "fleetUpdated": "Flottan uppdaterad", - "fleetDeleted": "Flottan raderad", - "saveFailed": "Misslyckades med att spara flottan", - "deleteFailed": "Misslyckades med att ta bort flottan", - "loadFailed": "Misslyckades med att ladda flottor", - "deleteFleetTitle": "Ta bort flotta", - "deleteFleetDescription": "Är du säker på att du vill ta bort \"{{name}}\"? Detta tar inte bort själva medlemsvärdarna.", - "searchFleets": "Sök flottor...", - "noFleets": "Inga flottor ännu. Skapa en för att komma igång.", - "memberCount": "{{count}} värd", - "memberCount_other": "{{count}} värdar", - "manageMembers": "Hantera medlemmar", - "manageMembersTitle": "Hantera flottmedlemmar", - "manageMembersDescription": "Växla mellan att visa eller avaktivera värdar i flottans statiska medlemskap. Värdar som matchas av taggregler inkluderas alltid.", - "searchHosts": "Sök värdar...", - "noHostsFound": "Inga värdar hittades", - "noMembers": "Den här flottan har inga medlemmar ännu. Lägg till värdar eller ange en taggregel.", - "membersLoadFailed": "Misslyckades med att ladda flottmedlemmar", - "memberUpdateFailed": "Misslyckades med att uppdatera flottmedlemskapet", - "tabRun": "Kör kommando", - "tabTransfer": "Överför filer", - "tabInventory": "Lager", - "openInventoryTab": "Öppna i hela fliken", - "tabPackages": "Paket", - "runOnFleet": "Kör på flottan", - "commandPlaceholder": "drifttid && df -h", - "commandRequired": "Ett kommando krävs", - "commandInputsLabel": "Kommandoingångar", - "commandSucceeded": "Kommandot lyckades på alla värdar", - "commandPartialFailure": "{{failed}} av {{total}} värdar misslyckades", - "commandFailed": "Misslyckades med att köra kommandot", - "resultSuccess": "Framgång", - "resultFailed": "Misslyckades", - "push": "Tryck", - "pull": "Dra", - "remotePathLabel": "Fjärrväg", - "remotePathRequired": "En fjärrsökväg krävs", - "fileLabel": "Fil", - "fileRequired": "En fil krävs", - "pushHint": "Den valda filen skrivs till exakt denna sökväg på varje värd i flottan.", - "pullHint": "Filen på den här sökvägen läses från varje värd och laddas ner som en enda zip-fil, en mapp per värd.", - "transferComplete": "Överföringen är klar", - "transferFailed": "Överföringen misslyckades", - "refreshInventory": "Uppdatera lagret", - "inventoryLoadFailed": "Misslyckades med att ladda lagret", - "inventoryRefreshed": "Inventariet uppdaterat", - "inventoryRefreshFailed": "Misslyckades med att uppdatera lagret", - "inventoryNoData": "Ingen lagerdata ännu – uppdatera för att samla in den.", - "inventoryHost": "Värd", - "inventoryCollectedCount": "{{count}}/{{total}} samlade", - "inventoryOs": "operativsystem", - "inventoryKernel": "Kärna", - "inventoryArch": "Båge", - "inventoryUptime": "Drifttid", - "inventoryPackageManager": "Pakethanterare", - "inventoryCollectedAt": "Insamlad", - "packageActionLabel": "Handling", - "packageInstall": "Installera", - "packageRemove": "Ta bort", - "packageUpgradeAll": "Uppgradera alla paket", - "packageNameLabel": "Paketnamn", - "packageNameRequired": "Ett paketnamn krävs", - "packageHint": "Kräver åtkomst på hanteringsnivå per värd och höjs med hjälp av värdens lagrade sudo-lösenord." + "title": "Fleets", + "createFleet": "Create Fleet", + "createFleetTitle": "Create Fleet", + "editFleetTitle": "Edit Fleet", + "createFleetDescription": "A fleet is a named group of hosts you can run actions against as a unit.", + "nameLabel": "Name", + "namePlaceholder": "e.g., Web Servers", + "nameRequired": "Fleet name is required", + "descriptionLabel": "Description", + "descriptionPlaceholder": "Optional description", + "colorLabel": "Color", + "tagRulesLabel": "Tag rules", + "tagRulesPlaceholder": "prod-web, edge", + "tagRulesHint": "Hosts with any of these tags are automatically included, in addition to hosts added manually.", + "fleetCreated": "Fleet created", + "fleetUpdated": "Fleet updated", + "fleetDeleted": "Fleet deleted", + "saveFailed": "Failed to save fleet", + "deleteFailed": "Failed to delete fleet", + "loadFailed": "Failed to load fleets", + "deleteFleetTitle": "Delete Fleet", + "deleteFleetDescription": "Are you sure you want to delete \"{{name}}\"? This does not delete the member hosts themselves.", + "searchFleets": "Search fleets...", + "noFleets": "No fleets yet. Create one to get started.", + "memberCount": "{{count}} host", + "memberCount_other": "{{count}} hosts", + "manageMembers": "Manage Members", + "manageMembersTitle": "Manage Fleet Members", + "manageMembersDescription": "Toggle hosts in or out of this fleet's static membership. Hosts matched by tag rules are always included.", + "searchHosts": "Search hosts...", + "noHostsFound": "No hosts found", + "noMembers": "This fleet has no members yet. Add hosts or set a tag rule.", + "membersLoadFailed": "Failed to load fleet members", + "memberUpdateFailed": "Failed to update fleet membership", + "tabRun": "Run Command", + "tabTransfer": "Transfer Files", + "tabInventory": "Inventory", + "openInventoryTab": "Open in full tab", + "tabPackages": "Packages", + "runOnFleet": "Run on Fleet", + "commandPlaceholder": "uptime && df -h", + "commandRequired": "A command is required", + "commandInputsLabel": "Command inputs", + "commandSucceeded": "Command succeeded on all hosts", + "commandPartialFailure": "{{failed}} of {{total}} hosts failed", + "commandFailed": "Failed to run command", + "resultSuccess": "Success", + "resultFailed": "Failed", + "push": "Push", + "pull": "Pull", + "remotePathLabel": "Remote path", + "remotePathRequired": "A remote path is required", + "fileLabel": "File", + "fileRequired": "A file is required", + "pushHint": "The selected file is written to this exact path on every host in the fleet.", + "pullHint": "The file at this path is read from every host and downloaded as a single zip, one folder per host.", + "transferComplete": "Transfer complete", + "transferFailed": "Transfer failed", + "refreshInventory": "Refresh Inventory", + "inventoryLoadFailed": "Failed to load inventory", + "inventoryRefreshed": "Inventory refreshed", + "inventoryRefreshFailed": "Failed to refresh inventory", + "inventoryNoData": "No inventory data yet - refresh to collect it.", + "inventoryHost": "Host", + "inventoryCollectedCount": "{{count}}/{{total}} collected", + "inventoryOs": "OS", + "inventoryKernel": "Kernel", + "inventoryArch": "Arch", + "inventoryUptime": "Uptime", + "inventoryPackageManager": "Package manager", + "inventoryCollectedAt": "Collected", + "packageActionLabel": "Action", + "packageInstall": "Install", + "packageRemove": "Remove", + "packageUpgradeAll": "Upgrade all packages", + "packageNameLabel": "Package name", + "packageNameRequired": "A package name is required", + "packageHint": "Requires manage-level access per host and elevates using the host's stored sudo password.", + "shareFleet": "Share Fleet", + "shareFleetTitle": "Share \"{{name}}\"", + "shareFleetDescription": "Shares this fleet's current member hosts with the selected users or roles. Hosts added to the fleet later are not shared automatically - share again to include them.", + "shareSelectionRequired": "Select at least one user or role", + "fleetSharedSuccessfully": "Shared {{shared}} of {{total}} host(s) in this fleet", + "failedToShareFleet": "Failed to share fleet", + "noMembersToShare": "This fleet has no member hosts to share yet." } } }, "nav": { - "fleets": "Flottor" + "fleets": "Fleets" }, "hosts": { - "docsLink": "Visa dokument", + "docsLink": "View docs", "sharing": { - "customHoursPlaceholder": "Timmar tills åtkomsten upphör", + "customHoursPlaceholder": "Hours until access expires", "expiry": { - "never": "Aldrig", - "oneHour": "1 timme", - "oneDay": "24 timmar", - "sevenDays": "7 dagar", - "thirtyDays": "30 dagar", - "custom": "Beställnings" + "never": "Never", + "oneHour": "1 hour", + "oneDay": "24 hours", + "sevenDays": "7 days", + "thirtyDays": "30 days", + "custom": "Custom" }, - "expiryLabel": "Åtkomstutgång", + "expiryLabel": "Access expiry", "levels": { "connect": { - "label": "Ansluta", - "description": "Endast öppna sessioner: terminal, fjärrskrivbord, filhanterare, tunnlar och Docker. Ingen åtkomst till värdkonfigurationen." + "label": "Connect", + "description": "Open sessions only: terminal, remote desktop, file manager, tunnels and Docker. No access to the host configuration." }, "view": { - "label": "Se", - "description": "Anslut, plus se värdkonfigurationen. Hemligheter visas aldrig." + "label": "View", + "description": "Connect, plus see the host configuration. Secrets are never shown." }, "edit": { - "label": "Redigera", - "description": "Visa och ändra inställningar för icke-autentiseringsvärdar. Ägarens SSH-autentisering förblir privat och endast för ägaren." + "label": "Edit", + "description": "View, plus modify non-authentication host settings. The owner's SSH authentication stays private and owner-only." }, "manage": { - "label": "Hantera", - "description": "Redigera, plus dela värden med andra, ändra behörighetsnivåer och återkalla åtkomst." + "label": "Manage", + "description": "Edit, plus share the host with others, change permission levels and revoke access." } }, - "noMatches": "Inga träffar hittades", - "permissionLevelLabel": "Behörighetsnivå", - "rolesTab": "Roller", - "searchPlaceholder": "Sök användare eller roller...", - "shareButton": "Dela", - "shareWithCount": "Dela ({{count}})", - "usersTab": "Användare" + "noMatches": "No matches found", + "permissionLevelLabel": "Permission level", + "rolesTab": "Roles", + "searchPlaceholder": "Search users or roles...", + "shareButton": "Share", + "shareWithCount": "Share ({{count}})", + "usersTab": "Users" } } } diff --git a/plugins/fleets/locales/translated/th_TH.json b/plugins/fleets/locales/translated/th_TH.json index cc89cedeb..18ffb4fa6 100644 --- a/plugins/fleets/locales/translated/th_TH.json +++ b/plugins/fleets/locales/translated/th_TH.json @@ -1,129 +1,150 @@ { + "permissions": { + "view": { + "title": "View fleets", + "description": "See fleets, their members and inventory." + }, + "manage": { + "title": "Manage fleets", + "description": "Create, edit and delete fleets, change membership, and share fleets with other users or roles." + }, + "execute": { + "title": "Run fleet actions", + "description": "Run commands and package actions across a fleet, and transfer files to and from its member hosts." + } + }, "newUi": { "sidebar": { "fleets": { - "title": "กองเรือ", - "createFleet": "สร้างกลุ่มยานพาหนะ", - "createFleetTitle": "สร้างกลุ่มยานพาหนะ", - "editFleetTitle": "แก้ไขข้อมูลกองเรือ", - "createFleetDescription": "กลุ่มโฮสต์ (Fleet) คือกลุ่มของโฮสต์ที่มีชื่อ ซึ่งคุณสามารถเรียกใช้คำสั่งต่างๆ กับกลุ่มนั้นได้ในฐานะหน่วยเดียวกัน", - "nameLabel": "ชื่อ", - "namePlaceholder": "เช่น เว็บเซิร์ฟเวอร์", - "nameRequired": "ต้องระบุชื่อกองเรือ", - "descriptionLabel": "คำอธิบาย", - "descriptionPlaceholder": "คำอธิบายเพิ่มเติม (ไม่บังคับ)", - "colorLabel": "สี", - "tagRulesLabel": "กฎการติดแท็ก", - "tagRulesPlaceholder": "โปรด-เว็บ, เอดจ์", - "tagRulesHint": "โฮสต์ที่มีแท็กใดแท็กหนึ่งเหล่านี้จะถูกรวมไว้โดยอัตโนมัติ นอกเหนือจากโฮสต์ที่เพิ่มเข้ามาด้วยตนเอง", - "fleetCreated": "กองเรือสร้าง", - "fleetUpdated": "อัปเดตฝูงบินแล้ว", - "fleetDeleted": "กองเรือถูกลบ", - "saveFailed": "ไม่สามารถช่วยกองเรือได้", - "deleteFailed": "ไม่สามารถลบกลุ่มยานพาหนะได้", - "loadFailed": "ไม่สามารถโหลดข้อมูลยานพาหนะได้", - "deleteFleetTitle": "ลบกลุ่มยานพาหนะ", - "deleteFleetDescription": "คุณแน่ใจหรือไม่ว่าต้องการลบ \"{{name}}\"? การดำเนินการนี้ไม่ได้ลบโฮสต์สมาชิกเอง", - "searchFleets": "ค้นหากองเรือ...", - "noFleets": "ยังไม่มีกลุ่มเรือ สร้างกลุ่มเรือเพื่อเริ่มต้นใช้งานได้เลย", - "memberCount": "{{count}} โฮสต์", - "memberCount_other": "{{count}} โฮสต์", - "manageMembers": "จัดการสมาชิก", - "manageMembersTitle": "จัดการสมาชิกกลุ่มยานพาหนะ", - "manageMembersDescription": "สลับการเพิ่มหรือลบโฮสต์ออกจากการเป็นสมาชิกแบบคงที่ของกลุ่มโฮสต์นี้ โฮสต์ที่ตรงกับกฎแท็กจะถูกรวมอยู่เสมอ", - "searchHosts": "ค้นหาโฮสต์...", - "noHostsFound": "ไม่พบโฮสต์", - "noMembers": "กลุ่มเรือนี้ยังไม่มีสมาชิก เพิ่มโฮสต์หรือตั้งค่ากฎแท็ก", - "membersLoadFailed": "ไม่สามารถโหลดสมาชิกกองเรือได้", - "memberUpdateFailed": "ไม่สามารถอัปเดตข้อมูลสมาชิกกลุ่มยานพาหนะได้", - "tabRun": "เรียกใช้คำสั่ง", - "tabTransfer": "โอนไฟล์", - "tabInventory": "รายการสิ่งของ", - "openInventoryTab": "เปิดในแท็บเต็ม", - "tabPackages": "แพ็คเกจ", - "runOnFleet": "วิ่งบนกองเรือ", + "title": "Fleets", + "createFleet": "Create Fleet", + "createFleetTitle": "Create Fleet", + "editFleetTitle": "Edit Fleet", + "createFleetDescription": "A fleet is a named group of hosts you can run actions against as a unit.", + "nameLabel": "Name", + "namePlaceholder": "e.g., Web Servers", + "nameRequired": "Fleet name is required", + "descriptionLabel": "Description", + "descriptionPlaceholder": "Optional description", + "colorLabel": "Color", + "tagRulesLabel": "Tag rules", + "tagRulesPlaceholder": "prod-web, edge", + "tagRulesHint": "Hosts with any of these tags are automatically included, in addition to hosts added manually.", + "fleetCreated": "Fleet created", + "fleetUpdated": "Fleet updated", + "fleetDeleted": "Fleet deleted", + "saveFailed": "Failed to save fleet", + "deleteFailed": "Failed to delete fleet", + "loadFailed": "Failed to load fleets", + "deleteFleetTitle": "Delete Fleet", + "deleteFleetDescription": "Are you sure you want to delete \"{{name}}\"? This does not delete the member hosts themselves.", + "searchFleets": "Search fleets...", + "noFleets": "No fleets yet. Create one to get started.", + "memberCount": "{{count}} host", + "memberCount_other": "{{count}} hosts", + "manageMembers": "Manage Members", + "manageMembersTitle": "Manage Fleet Members", + "manageMembersDescription": "Toggle hosts in or out of this fleet's static membership. Hosts matched by tag rules are always included.", + "searchHosts": "Search hosts...", + "noHostsFound": "No hosts found", + "noMembers": "This fleet has no members yet. Add hosts or set a tag rule.", + "membersLoadFailed": "Failed to load fleet members", + "memberUpdateFailed": "Failed to update fleet membership", + "tabRun": "Run Command", + "tabTransfer": "Transfer Files", + "tabInventory": "Inventory", + "openInventoryTab": "Open in full tab", + "tabPackages": "Packages", + "runOnFleet": "Run on Fleet", "commandPlaceholder": "uptime && df -h", - "commandRequired": "จำเป็นต้องมีคำสั่ง", - "commandInputsLabel": "อินพุตคำสั่ง", - "commandSucceeded": "คำสั่งทำงานสำเร็จบนโฮสต์ทั้งหมด", - "commandPartialFailure": "โฮสต์ {{failed}} ล้มเหลว {{total}}", - "commandFailed": "ไม่สามารถเรียกใช้คำสั่งได้", - "resultSuccess": "ความสำเร็จ", - "resultFailed": "ล้มเหลว", - "push": "ดัน", - "pull": "ดึง", - "remotePathLabel": "เส้นทางระยะไกล", - "remotePathRequired": "จำเป็นต้องใช้เส้นทางระยะไกล", - "fileLabel": "ไฟล์", - "fileRequired": "จำเป็นต้องมีไฟล์", - "pushHint": "ไฟล์ที่เลือกจะถูกเขียนไปยังพาธที่ระบุไว้นี้บนทุกเครื่องในระบบเครือข่าย", - "pullHint": "ไฟล์ที่อยู่ในพาธนี้จะถูกอ่านจากทุกโฮสต์และดาวน์โหลดเป็นไฟล์ซิปเดียว โดยมีหนึ่งโฟลเดอร์ต่อหนึ่งโฮสต์", - "transferComplete": "การโอนเสร็จสมบูรณ์", - "transferFailed": "การโอนล้มเหลว", - "refreshInventory": "รีเฟรชสินค้าคงคลัง", - "inventoryLoadFailed": "ไม่สามารถโหลดสินค้าคงคลังได้", - "inventoryRefreshed": "อัปเดตสินค้าคงคลังแล้ว", - "inventoryRefreshFailed": "ไม่สามารถรีเฟรชสินค้าคงคลังได้", - "inventoryNoData": "ยังไม่มีข้อมูลสินค้าคงคลัง โปรดรีเฟรชหน้าเว็บเพื่อดูข้อมูล", - "inventoryHost": "เจ้าภาพ", - "inventoryCollectedCount": "{{count}}/{{total}} รวบรวมแล้ว", - "inventoryOs": "โอเอส", - "inventoryKernel": "เคอร์เนล", - "inventoryArch": "โค้ง", - "inventoryUptime": "เวลาใช้งาน", - "inventoryPackageManager": "ตัวจัดการแพ็กเกจ", - "inventoryCollectedAt": "รวบรวม", - "packageActionLabel": "การกระทำ", - "packageInstall": "ติดตั้ง", - "packageRemove": "ลบ", - "packageUpgradeAll": "อัปเกรดแพ็กเกจทั้งหมด", - "packageNameLabel": "ชื่อแพ็คเกจ", - "packageNameRequired": "จำเป็นต้องระบุชื่อแพ็กเกจ", - "packageHint": "ต้องมีสิทธิ์การเข้าถึงระดับจัดการต่อโฮสต์ และยกระดับสิทธิ์โดยใช้รหัสผ่าน sudo ที่บันทึกไว้ของโฮสต์" + "commandRequired": "A command is required", + "commandInputsLabel": "Command inputs", + "commandSucceeded": "Command succeeded on all hosts", + "commandPartialFailure": "{{failed}} of {{total}} hosts failed", + "commandFailed": "Failed to run command", + "resultSuccess": "Success", + "resultFailed": "Failed", + "push": "Push", + "pull": "Pull", + "remotePathLabel": "Remote path", + "remotePathRequired": "A remote path is required", + "fileLabel": "File", + "fileRequired": "A file is required", + "pushHint": "The selected file is written to this exact path on every host in the fleet.", + "pullHint": "The file at this path is read from every host and downloaded as a single zip, one folder per host.", + "transferComplete": "Transfer complete", + "transferFailed": "Transfer failed", + "refreshInventory": "Refresh Inventory", + "inventoryLoadFailed": "Failed to load inventory", + "inventoryRefreshed": "Inventory refreshed", + "inventoryRefreshFailed": "Failed to refresh inventory", + "inventoryNoData": "No inventory data yet - refresh to collect it.", + "inventoryHost": "Host", + "inventoryCollectedCount": "{{count}}/{{total}} collected", + "inventoryOs": "OS", + "inventoryKernel": "Kernel", + "inventoryArch": "Arch", + "inventoryUptime": "Uptime", + "inventoryPackageManager": "Package manager", + "inventoryCollectedAt": "Collected", + "packageActionLabel": "Action", + "packageInstall": "Install", + "packageRemove": "Remove", + "packageUpgradeAll": "Upgrade all packages", + "packageNameLabel": "Package name", + "packageNameRequired": "A package name is required", + "packageHint": "Requires manage-level access per host and elevates using the host's stored sudo password.", + "shareFleet": "Share Fleet", + "shareFleetTitle": "Share \"{{name}}\"", + "shareFleetDescription": "Shares this fleet's current member hosts with the selected users or roles. Hosts added to the fleet later are not shared automatically - share again to include them.", + "shareSelectionRequired": "Select at least one user or role", + "fleetSharedSuccessfully": "Shared {{shared}} of {{total}} host(s) in this fleet", + "failedToShareFleet": "Failed to share fleet", + "noMembersToShare": "This fleet has no member hosts to share yet." } } }, "nav": { - "fleets": "กองเรือ" + "fleets": "Fleets" }, "hosts": { - "docsLink": "ดูเอกสาร", + "docsLink": "View docs", "sharing": { - "customHoursPlaceholder": "เหลือเวลาอีกกี่ชั่วโมงก่อนที่สิทธิ์การเข้าถึงจะหมดอายุ", + "customHoursPlaceholder": "Hours until access expires", "expiry": { - "never": "ไม่เคย", - "oneHour": "1 ชั่วโมง", - "oneDay": "24 ชั่วโมง", - "sevenDays": "7 วัน", - "thirtyDays": "30 วัน", - "custom": "กำหนดเอง" + "never": "Never", + "oneHour": "1 hour", + "oneDay": "24 hours", + "sevenDays": "7 days", + "thirtyDays": "30 days", + "custom": "Custom" }, - "expiryLabel": "วันหมดอายุการเข้าถึง", + "expiryLabel": "Access expiry", "levels": { "connect": { - "label": "เชื่อมต่อ", - "description": "อนุญาตเฉพาะเซสชันที่เปิดใช้งานเท่านั้น: เทอร์มินัล, เดสก์ท็อประยะไกล, ตัวจัดการไฟล์, อุโมงค์ และ Docker ไม่สามารถเข้าถึงการกำหนดค่าโฮสต์ได้" + "label": "Connect", + "description": "Open sessions only: terminal, remote desktop, file manager, tunnels and Docker. No access to the host configuration." }, "view": { - "label": "ดู", - "description": "เชื่อมต่อและดูการตั้งค่าโฮสต์ ข้อมูลลับจะไม่ถูกเปิดเผย" + "label": "View", + "description": "Connect, plus see the host configuration. Secrets are never shown." }, "edit": { - "label": "แก้ไข", - "description": "ดูและแก้ไขการตั้งค่าโฮสต์ที่ไม่ต้องยืนยันตัวตน การยืนยันตัวตน SSH ของเจ้าของจะยังคงเป็นส่วนตัวและเข้าถึงได้เฉพาะเจ้าของเท่านั้น" + "label": "Edit", + "description": "View, plus modify non-authentication host settings. The owner's SSH authentication stays private and owner-only." }, "manage": { - "label": "จัดการ", - "description": "แก้ไข รวมถึงแชร์โฮสต์กับผู้อื่น เปลี่ยนระดับสิทธิ์ และเพิกถอนการเข้าถึงได้" + "label": "Manage", + "description": "Edit, plus share the host with others, change permission levels and revoke access." } }, - "noMatches": "ไม่พบผลลัพธ์ที่ตรงกัน", - "permissionLevelLabel": "ระดับการอนุญาต", - "rolesTab": "บทบาท", - "searchPlaceholder": "ค้นหาผู้ใช้หรือบทบาท...", - "shareButton": "แบ่งปัน", - "shareWithCount": "แชร์ ({{count}})", - "usersTab": "ผู้ใช้" + "noMatches": "No matches found", + "permissionLevelLabel": "Permission level", + "rolesTab": "Roles", + "searchPlaceholder": "Search users or roles...", + "shareButton": "Share", + "shareWithCount": "Share ({{count}})", + "usersTab": "Users" } } } diff --git a/plugins/fleets/locales/translated/tr_TR.json b/plugins/fleets/locales/translated/tr_TR.json index f79a16d34..0326df9ca 100644 --- a/plugins/fleets/locales/translated/tr_TR.json +++ b/plugins/fleets/locales/translated/tr_TR.json @@ -1,90 +1,111 @@ { + "permissions": { + "view": { + "title": "View fleets", + "description": "See fleets, their members and inventory." + }, + "manage": { + "title": "Manage fleets", + "description": "Create, edit and delete fleets, change membership, and share fleets with other users or roles." + }, + "execute": { + "title": "Run fleet actions", + "description": "Run commands and package actions across a fleet, and transfer files to and from its member hosts." + } + }, "newUi": { "sidebar": { "fleets": { - "title": "Filolar", - "createFleet": "Filo Oluştur", - "createFleetTitle": "Filo Oluştur", - "editFleetTitle": "Filoyu Düzenle", - "createFleetDescription": "Filo, birim olarak eylemler gerçekleştirebileceğiniz, adlandırılmış bir sunucu grubudur.", - "nameLabel": "İsim", - "namePlaceholder": "Örneğin, Web Sunucuları", - "nameRequired": "Filo adı zorunludur.", - "descriptionLabel": "Tanım", + "title": "Fleets", + "createFleet": "Create Fleet", + "createFleetTitle": "Create Fleet", + "editFleetTitle": "Edit Fleet", + "createFleetDescription": "A fleet is a named group of hosts you can run actions against as a unit.", + "nameLabel": "Ad", + "namePlaceholder": "e.g., Web Servers", + "nameRequired": "Fleet name is required", + "descriptionLabel": "Açıklama", "descriptionPlaceholder": "İsteğe bağlı açıklama", "colorLabel": "Renk", - "tagRulesLabel": "Etiket kuralları", + "tagRulesLabel": "Tag rules", "tagRulesPlaceholder": "prod-web, edge", - "tagRulesHint": "Bu etiketlerden herhangi birine sahip sunucular, manuel olarak eklenen sunuculara ek olarak otomatik olarak dahil edilir.", - "fleetCreated": "Filo oluşturuldu", - "fleetUpdated": "Filo güncellendi", - "fleetDeleted": "Filo silindi", - "saveFailed": "Filoyu kurtaramadık", - "deleteFailed": "Filoyu silme işlemi başarısız oldu.", - "loadFailed": "Filoların yüklenmesi başarısız oldu.", - "deleteFleetTitle": "Filoyu Sil", - "deleteFleetDescription": "\"{{name}}\" öğesini silmek istediğinizden emin misiniz? Bu işlem üye sunucuların kendilerini silmez.", - "searchFleets": "Filoları arayın...", - "noFleets": "Henüz filo yok. Başlamak için bir tane oluşturun.", - "memberCount": "{{count}} sunucu", - "memberCount_other": "{{count}} sunucular", - "manageMembers": "Üyeleri Yönet", - "manageMembersTitle": "Filo Üyelerini Yönetin", - "manageMembersDescription": "Sunucuları bu filonun statik üyeliğine dahil edin veya çıkarın. Etiket kurallarına göre eşleşen sunucular her zaman dahil edilir.", - "searchHosts": "Sunucu ara...", - "noHostsFound": "Hiçbir sunucu bulunamadı.", - "noMembers": "Bu filonun henüz üyesi yok. Sunucu ekleyin veya etiket kuralı belirleyin.", - "membersLoadFailed": "Filo üyeleri yüklenemedi.", - "memberUpdateFailed": "Filo üyeliği güncellenemedi.", - "tabRun": "Komutu Çalıştır", - "tabTransfer": "Dosya Aktarımı", - "tabInventory": "Envanter", - "openInventoryTab": "Tam sekmede aç", + "tagRulesHint": "Hosts with any of these tags are automatically included, in addition to hosts added manually.", + "fleetCreated": "Fleet created", + "fleetUpdated": "Fleet updated", + "fleetDeleted": "Fleet deleted", + "saveFailed": "Failed to save fleet", + "deleteFailed": "Failed to delete fleet", + "loadFailed": "Failed to load fleets", + "deleteFleetTitle": "Delete Fleet", + "deleteFleetDescription": "Are you sure you want to delete \"{{name}}\"? This does not delete the member hosts themselves.", + "searchFleets": "Search fleets...", + "noFleets": "No fleets yet. Create one to get started.", + "memberCount": "{{count}} host", + "memberCount_other": "{{count}} ana makine", + "manageMembers": "Manage Members", + "manageMembersTitle": "Manage Fleet Members", + "manageMembersDescription": "Toggle hosts in or out of this fleet's static membership. Hosts matched by tag rules are always included.", + "searchHosts": "Host ara...", + "noHostsFound": "Hiç sunucu bulunamadı", + "noMembers": "This fleet has no members yet. Add hosts or set a tag rule.", + "membersLoadFailed": "Failed to load fleet members", + "memberUpdateFailed": "Failed to update fleet membership", + "tabRun": "Run Command", + "tabTransfer": "Transfer Files", + "tabInventory": "Inventory", + "openInventoryTab": "Open in full tab", "tabPackages": "Paketler", - "runOnFleet": "Filoda Çalıştır", - "commandPlaceholder": "çalışma süresi && df -h", - "commandRequired": "Bir komut gereklidir.", - "commandInputsLabel": "Komut girişleri", - "commandSucceeded": "Komut tüm sunucularda başarıyla tamamlandı.", - "commandPartialFailure": "{{failed}} / {{total}} sunucu başarısız oldu", - "commandFailed": "Komut çalıştırma başarısız oldu.", - "resultSuccess": "Başarı", - "resultFailed": "Arızalı", - "push": "İtmek", - "pull": "Çekmek", - "remotePathLabel": "Uzak yol", - "remotePathRequired": "Uzak bir yol gereklidir.", + "runOnFleet": "Run on Fleet", + "commandPlaceholder": "uptime && df -h", + "commandRequired": "A command is required", + "commandInputsLabel": "Command inputs", + "commandSucceeded": "Command succeeded on all hosts", + "commandPartialFailure": "{{failed}} of {{total}} hosts failed", + "commandFailed": "Failed to run command", + "resultSuccess": "Başarılı", + "resultFailed": "Başarısız", + "push": "Push", + "pull": "Pull", + "remotePathLabel": "Remote path", + "remotePathRequired": "A remote path is required", "fileLabel": "Dosya", - "fileRequired": "Bir dosya gereklidir.", - "pushHint": "Seçilen dosya, filodaki her sunucuda tam olarak bu yola yazılır.", - "pullHint": "Bu yoldaki dosya her sunucudan okunur ve her sunucu için bir klasör olmak üzere tek bir zip dosyası olarak indirilir.", - "transferComplete": "Transfer tamamlandı", - "transferFailed": "Aktarım başarısız oldu", - "refreshInventory": "Envanteri Yenile", - "inventoryLoadFailed": "Envanter yüklenemedi.", - "inventoryRefreshed": "Stok güncellendi", - "inventoryRefreshFailed": "Envanter yenileme işlemi başarısız oldu.", - "inventoryNoData": "Henüz envanter verisi yok - verileri toplamak için sayfayı yenileyin.", - "inventoryHost": "Ev sahibi", - "inventoryCollectedCount": "{{count}}/{{total}} toplandı", - "inventoryOs": "İşletim sistemi", + "fileRequired": "A file is required", + "pushHint": "The selected file is written to this exact path on every host in the fleet.", + "pullHint": "The file at this path is read from every host and downloaded as a single zip, one folder per host.", + "transferComplete": "Aktarım tamamlandı", + "transferFailed": "Aktarım başarısız", + "refreshInventory": "Refresh Inventory", + "inventoryLoadFailed": "Failed to load inventory", + "inventoryRefreshed": "Inventory refreshed", + "inventoryRefreshFailed": "Failed to refresh inventory", + "inventoryNoData": "No inventory data yet - refresh to collect it.", + "inventoryHost": "Ana Bilgisayar", + "inventoryCollectedCount": "{{count}}/{{total}} collected", + "inventoryOs": "İşletim Sistemi", "inventoryKernel": "Çekirdek", - "inventoryArch": "Kemer", - "inventoryUptime": "Çalışma süresi", - "inventoryPackageManager": "Paket yöneticisi", - "inventoryCollectedAt": "Toplandı", - "packageActionLabel": "Aksiyon", - "packageInstall": "Düzenlemek", - "packageRemove": "Kaldırmak", - "packageUpgradeAll": "Tüm paketleri yükseltin", - "packageNameLabel": "Paket adı", - "packageNameRequired": "Paket adı gereklidir.", - "packageHint": "Her sunucu için yönetim düzeyinde erişim gerektirir ve sunucunun kayıtlı sudo şifresi kullanılarak yetki yükseltilir." + "inventoryArch": "Arch", + "inventoryUptime": "Çalışma Süresi", + "inventoryPackageManager": "Package manager", + "inventoryCollectedAt": "Collected", + "packageActionLabel": "İşlem", + "packageInstall": "Install", + "packageRemove": "Kaldır", + "packageUpgradeAll": "Upgrade all packages", + "packageNameLabel": "Package name", + "packageNameRequired": "A package name is required", + "packageHint": "Requires manage-level access per host and elevates using the host's stored sudo password.", + "shareFleet": "Share Fleet", + "shareFleetTitle": "Share \"{{name}}\"", + "shareFleetDescription": "Shares this fleet's current member hosts with the selected users or roles. Hosts added to the fleet later are not shared automatically - share again to include them.", + "shareSelectionRequired": "Select at least one user or role", + "fleetSharedSuccessfully": "Shared {{shared}} of {{total}} host(s) in this fleet", + "failedToShareFleet": "Failed to share fleet", + "noMembersToShare": "This fleet has no member hosts to share yet." } } }, "nav": { - "fleets": "Filolar" + "fleets": "Fleets" }, "hosts": { "docsLink": "Dokümanları görüntüle", @@ -110,7 +131,7 @@ }, "edit": { "label": "Düzenle", - "description": "Kimlik doğrulaması gerektirmeyen sunucu ayarlarını görüntüleyin ve değiştirin. Sahibin SSH kimlik doğrulaması gizli kalır ve yalnızca sahibine özeldir." + "description": "View, plus modify non-authentication host settings. The owner's SSH authentication stays private and owner-only." }, "manage": { "label": "Yönet", diff --git a/plugins/fleets/locales/translated/uk_UA.json b/plugins/fleets/locales/translated/uk_UA.json index 9f019732c..18ffb4fa6 100644 --- a/plugins/fleets/locales/translated/uk_UA.json +++ b/plugins/fleets/locales/translated/uk_UA.json @@ -1,129 +1,150 @@ { + "permissions": { + "view": { + "title": "View fleets", + "description": "See fleets, their members and inventory." + }, + "manage": { + "title": "Manage fleets", + "description": "Create, edit and delete fleets, change membership, and share fleets with other users or roles." + }, + "execute": { + "title": "Run fleet actions", + "description": "Run commands and package actions across a fleet, and transfer files to and from its member hosts." + } + }, "newUi": { "sidebar": { "fleets": { - "title": "Флоти", - "createFleet": "Створити флот", - "createFleetTitle": "Створити флот", - "editFleetTitle": "Редагувати флот", - "createFleetDescription": "Флот — це іменована група хостів, проти яких можна виконувати дії як проти єдиного цілого.", - "nameLabel": "Ім'я", - "namePlaceholder": "наприклад, веб-сервери", - "nameRequired": "Потрібно вказати назву флоту", - "descriptionLabel": "Опис", - "descriptionPlaceholder": "Додатковий опис", - "colorLabel": "Колір", - "tagRulesLabel": "Правила тегів", - "tagRulesPlaceholder": "prod-web, край", - "tagRulesHint": "Хости з будь-яким із цих тегів додаються автоматично, окрім хостів, доданих вручну.", - "fleetCreated": "Створено флот", - "fleetUpdated": "Оновлено автопарк", - "fleetDeleted": "Флот видалено", - "saveFailed": "Не вдалося зберегти флот", - "deleteFailed": "Не вдалося видалити автопарк", - "loadFailed": "Не вдалося завантажити автопарки", - "deleteFleetTitle": "Видалити автопарк", - "deleteFleetDescription": "Ви впевнені, що хочете видалити \"{{name}}\"? Це не видаляє самі хости-учасники.", - "searchFleets": "Пошук автопарків...", - "noFleets": "Поки що немає автопарків. Створіть його, щоб розпочати.", - "memberCount": "{{count}} хост", - "memberCount_other": "{{count}} хости", - "manageMembers": "Керування учасниками", - "manageMembersTitle": "Керування членами автопарку", - "manageMembersDescription": "Вмикати або вимикати хости зі списку статичного членства цього флоту. Хости, що відповідають правилам тегів, завжди враховуються.", - "searchHosts": "Пошук хостів...", - "noHostsFound": "Хости не знайдено", - "noMembers": "Цей флот ще не має учасників. Додайте хостів або встановіть правило тегу.", - "membersLoadFailed": "Не вдалося завантажити учасників автопарку", - "memberUpdateFailed": "Не вдалося оновити членство в автопарку", - "tabRun": "Виконати команду", - "tabTransfer": "Передача файлів", - "tabInventory": "Інвентаризація", - "openInventoryTab": "Відкрити у повній вкладці", - "tabPackages": "Пакети", - "runOnFleet": "Запустити флот", - "commandPlaceholder": "час безперебійної роботи && df -h", - "commandRequired": "Потрібна команда", - "commandInputsLabel": "Вхідні команди", - "commandSucceeded": "Команда успішно виконана на всіх хостах", - "commandPartialFailure": "{{failed}} з {{total}} хостів не вдалося", - "commandFailed": "Не вдалося виконати команду", - "resultSuccess": "Успіх", - "resultFailed": "Не вдалося", - "push": "Натисніть", - "pull": "Тягнути", - "remotePathLabel": "Віддалений шлях", - "remotePathRequired": "Потрібен віддалений шлях", - "fileLabel": "Файл", - "fileRequired": "Потрібен файл", - "pushHint": "Вибраний файл записується саме за цим шляхом на кожному хості парку.", - "pullHint": "Файл за цим шляхом зчитується з кожного хоста та завантажується як один zip-архів, одна папка на хост.", - "transferComplete": "Перенесення завершено", - "transferFailed": "Передача не вдалася", - "refreshInventory": "Оновити інвентар", - "inventoryLoadFailed": "Не вдалося завантажити інвентар", - "inventoryRefreshed": "Інвентар оновлено", - "inventoryRefreshFailed": "Не вдалося оновити інвентар", - "inventoryNoData": "Даних про інвентаризацію ще немає – оновіть сторінку, щоб зібрати їх.", - "inventoryHost": "Хост", - "inventoryCollectedCount": "{{count}}/{{total}} зібрано", - "inventoryOs": "ОС", - "inventoryKernel": "Ядро", - "inventoryArch": "Арка", - "inventoryUptime": "Час безперебійної роботи", - "inventoryPackageManager": "Менеджер пакетів", - "inventoryCollectedAt": "Зібрано", - "packageActionLabel": "Дія", - "packageInstall": "Встановити", - "packageRemove": "Видалити", - "packageUpgradeAll": "Оновіть усі пакети", - "packageNameLabel": "Назва пакета", - "packageNameRequired": "Потрібна назва пакета", - "packageHint": "Потрібен доступ на рівні керування для кожного хоста та підвищення прав за допомогою збереженого пароля sudo хоста." + "title": "Fleets", + "createFleet": "Create Fleet", + "createFleetTitle": "Create Fleet", + "editFleetTitle": "Edit Fleet", + "createFleetDescription": "A fleet is a named group of hosts you can run actions against as a unit.", + "nameLabel": "Name", + "namePlaceholder": "e.g., Web Servers", + "nameRequired": "Fleet name is required", + "descriptionLabel": "Description", + "descriptionPlaceholder": "Optional description", + "colorLabel": "Color", + "tagRulesLabel": "Tag rules", + "tagRulesPlaceholder": "prod-web, edge", + "tagRulesHint": "Hosts with any of these tags are automatically included, in addition to hosts added manually.", + "fleetCreated": "Fleet created", + "fleetUpdated": "Fleet updated", + "fleetDeleted": "Fleet deleted", + "saveFailed": "Failed to save fleet", + "deleteFailed": "Failed to delete fleet", + "loadFailed": "Failed to load fleets", + "deleteFleetTitle": "Delete Fleet", + "deleteFleetDescription": "Are you sure you want to delete \"{{name}}\"? This does not delete the member hosts themselves.", + "searchFleets": "Search fleets...", + "noFleets": "No fleets yet. Create one to get started.", + "memberCount": "{{count}} host", + "memberCount_other": "{{count}} hosts", + "manageMembers": "Manage Members", + "manageMembersTitle": "Manage Fleet Members", + "manageMembersDescription": "Toggle hosts in or out of this fleet's static membership. Hosts matched by tag rules are always included.", + "searchHosts": "Search hosts...", + "noHostsFound": "No hosts found", + "noMembers": "This fleet has no members yet. Add hosts or set a tag rule.", + "membersLoadFailed": "Failed to load fleet members", + "memberUpdateFailed": "Failed to update fleet membership", + "tabRun": "Run Command", + "tabTransfer": "Transfer Files", + "tabInventory": "Inventory", + "openInventoryTab": "Open in full tab", + "tabPackages": "Packages", + "runOnFleet": "Run on Fleet", + "commandPlaceholder": "uptime && df -h", + "commandRequired": "A command is required", + "commandInputsLabel": "Command inputs", + "commandSucceeded": "Command succeeded on all hosts", + "commandPartialFailure": "{{failed}} of {{total}} hosts failed", + "commandFailed": "Failed to run command", + "resultSuccess": "Success", + "resultFailed": "Failed", + "push": "Push", + "pull": "Pull", + "remotePathLabel": "Remote path", + "remotePathRequired": "A remote path is required", + "fileLabel": "File", + "fileRequired": "A file is required", + "pushHint": "The selected file is written to this exact path on every host in the fleet.", + "pullHint": "The file at this path is read from every host and downloaded as a single zip, one folder per host.", + "transferComplete": "Transfer complete", + "transferFailed": "Transfer failed", + "refreshInventory": "Refresh Inventory", + "inventoryLoadFailed": "Failed to load inventory", + "inventoryRefreshed": "Inventory refreshed", + "inventoryRefreshFailed": "Failed to refresh inventory", + "inventoryNoData": "No inventory data yet - refresh to collect it.", + "inventoryHost": "Host", + "inventoryCollectedCount": "{{count}}/{{total}} collected", + "inventoryOs": "OS", + "inventoryKernel": "Kernel", + "inventoryArch": "Arch", + "inventoryUptime": "Uptime", + "inventoryPackageManager": "Package manager", + "inventoryCollectedAt": "Collected", + "packageActionLabel": "Action", + "packageInstall": "Install", + "packageRemove": "Remove", + "packageUpgradeAll": "Upgrade all packages", + "packageNameLabel": "Package name", + "packageNameRequired": "A package name is required", + "packageHint": "Requires manage-level access per host and elevates using the host's stored sudo password.", + "shareFleet": "Share Fleet", + "shareFleetTitle": "Share \"{{name}}\"", + "shareFleetDescription": "Shares this fleet's current member hosts with the selected users or roles. Hosts added to the fleet later are not shared automatically - share again to include them.", + "shareSelectionRequired": "Select at least one user or role", + "fleetSharedSuccessfully": "Shared {{shared}} of {{total}} host(s) in this fleet", + "failedToShareFleet": "Failed to share fleet", + "noMembersToShare": "This fleet has no member hosts to share yet." } } }, "nav": { - "fleets": "Флоти" + "fleets": "Fleets" }, "hosts": { - "docsLink": "Переглянути документи", + "docsLink": "View docs", "sharing": { - "customHoursPlaceholder": "Години до закінчення терміну дії доступу", + "customHoursPlaceholder": "Hours until access expires", "expiry": { - "never": "Ніколи", - "oneHour": "1 година", - "oneDay": "24 години", - "sevenDays": "7 днів", - "thirtyDays": "30 днів", - "custom": "Користувацька" + "never": "Never", + "oneHour": "1 hour", + "oneDay": "24 hours", + "sevenDays": "7 days", + "thirtyDays": "30 days", + "custom": "Custom" }, - "expiryLabel": "Термін дії доступу", + "expiryLabel": "Access expiry", "levels": { "connect": { - "label": "Підключитися", - "description": "Тільки відкриті сеанси: термінал, віддалений робочий стіл, файловий менеджер, тунелі та Docker. Без доступу до конфігурації хоста." + "label": "Connect", + "description": "Open sessions only: terminal, remote desktop, file manager, tunnels and Docker. No access to the host configuration." }, "view": { - "label": "Переглянути", - "description": "Підключитися, а також переглянути конфігурацію хоста. Секрети ніколи не відображаються." + "label": "View", + "description": "Connect, plus see the host configuration. Secrets are never shown." }, "edit": { - "label": "Редагувати", - "description": "Переглядайте та змінюйте налаштування хоста без автентифікації. SSH-автентифікація власника залишається приватною та доступною лише для власника." + "label": "Edit", + "description": "View, plus modify non-authentication host settings. The owner's SSH authentication stays private and owner-only." }, "manage": { - "label": "Керувати", - "description": "Редагувати, а також ділитися хостом з іншими, змінювати рівні дозволів та скасовувати доступ." + "label": "Manage", + "description": "Edit, plus share the host with others, change permission levels and revoke access." } }, - "noMatches": "Збігів не знайдено", - "permissionLevelLabel": "Рівень дозволів", - "rolesTab": "Ролі", - "searchPlaceholder": "Пошук користувачів або ролей...", - "shareButton": "Поділитися", - "shareWithCount": "Поділитися ({{count}})", - "usersTab": "Користувачі" + "noMatches": "No matches found", + "permissionLevelLabel": "Permission level", + "rolesTab": "Roles", + "searchPlaceholder": "Search users or roles...", + "shareButton": "Share", + "shareWithCount": "Share ({{count}})", + "usersTab": "Users" } } } diff --git a/plugins/fleets/locales/translated/vi_VN.json b/plugins/fleets/locales/translated/vi_VN.json index 4a206c866..8445f108e 100644 --- a/plugins/fleets/locales/translated/vi_VN.json +++ b/plugins/fleets/locales/translated/vi_VN.json @@ -1,90 +1,111 @@ { + "permissions": { + "view": { + "title": "View fleets", + "description": "See fleets, their members and inventory." + }, + "manage": { + "title": "Manage fleets", + "description": "Create, edit and delete fleets, change membership, and share fleets with other users or roles." + }, + "execute": { + "title": "Run fleet actions", + "description": "Run commands and package actions across a fleet, and transfer files to and from its member hosts." + } + }, "newUi": { "sidebar": { "fleets": { - "title": "Hạm đội", - "createFleet": "Tạo đội tàu", - "createFleetTitle": "Tạo đội tàu", - "editFleetTitle": "Chỉnh sửa đội xe", - "createFleetDescription": "Hạm đội là một nhóm máy chủ được đặt tên mà bạn có thể thực hiện các hành động chống lại chúng như một đơn vị.", + "title": "Fleets", + "createFleet": "Create Fleet", + "createFleetTitle": "Create Fleet", + "editFleetTitle": "Edit Fleet", + "createFleetDescription": "A fleet is a named group of hosts you can run actions against as a unit.", "nameLabel": "Tên", - "namePlaceholder": "Ví dụ: Máy chủ web", - "nameRequired": "Tên đội xe là bắt buộc", - "descriptionLabel": "Sự miêu tả", + "namePlaceholder": "e.g., Web Servers", + "nameRequired": "Fleet name is required", + "descriptionLabel": "Mô tả", "descriptionPlaceholder": "Mô tả tùy chọn", "colorLabel": "Màu sắc", - "tagRulesLabel": "Quy tắc gắn thẻ", - "tagRulesPlaceholder": "web sản xuất, cạnh", - "tagRulesHint": "Các máy chủ có bất kỳ thẻ nào trong số này sẽ tự động được thêm vào, bên cạnh các máy chủ được thêm thủ công.", - "fleetCreated": "Hạm đội đã tạo ra", - "fleetUpdated": "Đội tàu được cập nhật", - "fleetDeleted": "Hạm đội đã bị xóa", - "saveFailed": "Không thể cứu hạm đội.", - "deleteFailed": "Không thể xóa đội tàu", - "loadFailed": "Không thể tải đội xe", - "deleteFleetTitle": "Xóa hạm đội", - "deleteFleetDescription": "Bạn có chắc chắn muốn xóa \"{{name}}\" không? Thao tác này không xóa các máy chủ thành viên.", - "searchFleets": "Các hạm đội tìm kiếm...", - "noFleets": "Chưa có hạm đội nào. Hãy tạo một hạm đội để bắt đầu.", - "memberCount": "{{count}} máy chủ", + "tagRulesLabel": "Tag rules", + "tagRulesPlaceholder": "prod-web, edge", + "tagRulesHint": "Hosts with any of these tags are automatically included, in addition to hosts added manually.", + "fleetCreated": "Fleet created", + "fleetUpdated": "Fleet updated", + "fleetDeleted": "Fleet deleted", + "saveFailed": "Failed to save fleet", + "deleteFailed": "Failed to delete fleet", + "loadFailed": "Failed to load fleets", + "deleteFleetTitle": "Delete Fleet", + "deleteFleetDescription": "Are you sure you want to delete \"{{name}}\"? This does not delete the member hosts themselves.", + "searchFleets": "Search fleets...", + "noFleets": "No fleets yet. Create one to get started.", + "memberCount": "{{count}} host", "memberCount_other": "{{count}} máy chủ", - "manageMembers": "Quản lý thành viên", - "manageMembersTitle": "Quản lý thành viên đội xe", - "manageMembersDescription": "Cho phép thêm hoặc xóa các máy chủ khỏi tư cách thành viên cố định của nhóm này. Các máy chủ phù hợp với quy tắc gắn thẻ luôn được bao gồm.", + "manageMembers": "Manage Members", + "manageMembersTitle": "Manage Fleet Members", + "manageMembersDescription": "Toggle hosts in or out of this fleet's static membership. Hosts matched by tag rules are always included.", "searchHosts": "Tìm kiếm máy chủ...", - "noHostsFound": "Không tìm thấy máy chủ nào", - "noMembers": "Hạm đội này chưa có thành viên nào. Thêm máy chủ hoặc thiết lập quy tắc gắn thẻ.", - "membersLoadFailed": "Không thể tải thông tin thành viên đội xe", - "memberUpdateFailed": "Không thể cập nhật thông tin thành viên đội tàu", - "tabRun": "Chạy lệnh", - "tabTransfer": "Chuyển tập tin", - "tabInventory": "Hàng tồn kho", - "openInventoryTab": "Mở ở chế độ toàn màn hình", - "tabPackages": "Gói hàng", - "runOnFleet": "Chạy trên Fleet", - "commandPlaceholder": "thời gian hoạt động && df -h", - "commandRequired": "Cần có lệnh", - "commandInputsLabel": "Đầu vào lệnh", - "commandSucceeded": "Lệnh đã được thực thi thành công trên tất cả các máy chủ.", - "commandPartialFailure": "{{failed}} trong số {{total}} máy chủ đã bị lỗi", - "commandFailed": "Không thể chạy lệnh.", + "noHostsFound": "Không tìm thấy máy chủ", + "noMembers": "This fleet has no members yet. Add hosts or set a tag rule.", + "membersLoadFailed": "Failed to load fleet members", + "memberUpdateFailed": "Failed to update fleet membership", + "tabRun": "Run Command", + "tabTransfer": "Transfer Files", + "tabInventory": "Inventory", + "openInventoryTab": "Open in full tab", + "tabPackages": "Gói", + "runOnFleet": "Run on Fleet", + "commandPlaceholder": "uptime && df -h", + "commandRequired": "A command is required", + "commandInputsLabel": "Command inputs", + "commandSucceeded": "Command succeeded on all hosts", + "commandPartialFailure": "{{failed}} of {{total}} hosts failed", + "commandFailed": "Failed to run command", "resultSuccess": "Thành công", "resultFailed": "Thất bại", - "push": "Xô", - "pull": "Sự lôi kéo", - "remotePathLabel": "Đường dẫn từ xa", - "remotePathRequired": "Cần có một đường dẫn từ xa.", - "fileLabel": "Tài liệu", - "fileRequired": "Cần có một tập tin.", - "pushHint": "Tệp đã chọn sẽ được ghi vào đúng đường dẫn này trên mọi máy chủ trong hệ thống.", - "pullHint": "Tệp tại đường dẫn này được đọc từ mọi máy chủ và tải xuống dưới dạng một tệp zip duy nhất, mỗi máy chủ một thư mục.", - "transferComplete": "Giao dịch hoàn tất", - "transferFailed": "Giao dịch chuyển khoản thất bại", - "refreshInventory": "Làm mới kho hàng", - "inventoryLoadFailed": "Không thể tải kho hàng", - "inventoryRefreshed": "Hàng tồn kho được cập nhật", - "inventoryRefreshFailed": "Không thể làm mới kho hàng", - "inventoryNoData": "Chưa có dữ liệu tồn kho - hãy làm mới trang để thu thập dữ liệu.", - "inventoryHost": "Chủ nhà", - "inventoryCollectedCount": "{{count}}/{{total}} đã thu thập", + "push": "Push", + "pull": "Pull", + "remotePathLabel": "Remote path", + "remotePathRequired": "A remote path is required", + "fileLabel": "Tệp", + "fileRequired": "A file is required", + "pushHint": "The selected file is written to this exact path on every host in the fleet.", + "pullHint": "The file at this path is read from every host and downloaded as a single zip, one folder per host.", + "transferComplete": "Truyền tải hoàn tất", + "transferFailed": "Truyền tải thất bại", + "refreshInventory": "Refresh Inventory", + "inventoryLoadFailed": "Failed to load inventory", + "inventoryRefreshed": "Inventory refreshed", + "inventoryRefreshFailed": "Failed to refresh inventory", + "inventoryNoData": "No inventory data yet - refresh to collect it.", + "inventoryHost": "Máy chủ", + "inventoryCollectedCount": "{{count}}/{{total}} collected", "inventoryOs": "Hệ điều hành", - "inventoryKernel": "Hạt nhân", - "inventoryArch": "Vòm", + "inventoryKernel": "Nhân", + "inventoryArch": "Arch", "inventoryUptime": "Thời gian hoạt động", - "inventoryPackageManager": "Trình quản lý gói", - "inventoryCollectedAt": "Đã thu thập", - "packageActionLabel": "Hoạt động", - "packageInstall": "Cài đặt", - "packageRemove": "Di dời", - "packageUpgradeAll": "Nâng cấp tất cả các gói", - "packageNameLabel": "Tên gói", - "packageNameRequired": "Cần phải có tên gói.", - "packageHint": "Yêu cầu quyền truy cập cấp quản trị cho mỗi máy chủ và nâng quyền bằng mật khẩu sudo được lưu trữ trên máy chủ đó." + "inventoryPackageManager": "Package manager", + "inventoryCollectedAt": "Collected", + "packageActionLabel": "Hành động", + "packageInstall": "Install", + "packageRemove": "Xóa", + "packageUpgradeAll": "Upgrade all packages", + "packageNameLabel": "Package name", + "packageNameRequired": "A package name is required", + "packageHint": "Requires manage-level access per host and elevates using the host's stored sudo password.", + "shareFleet": "Share Fleet", + "shareFleetTitle": "Share \"{{name}}\"", + "shareFleetDescription": "Shares this fleet's current member hosts with the selected users or roles. Hosts added to the fleet later are not shared automatically - share again to include them.", + "shareSelectionRequired": "Select at least one user or role", + "fleetSharedSuccessfully": "Shared {{shared}} of {{total}} host(s) in this fleet", + "failedToShareFleet": "Failed to share fleet", + "noMembersToShare": "This fleet has no member hosts to share yet." } } }, "nav": { - "fleets": "Hạm đội" + "fleets": "Fleets" }, "hosts": { "docsLink": "Xem tài liệu", @@ -110,7 +131,7 @@ }, "edit": { "label": "Chỉnh sửa", - "description": "Xem và chỉnh sửa cài đặt máy chủ không yêu cầu xác thực. Thông tin xác thực SSH của chủ sở hữu vẫn được giữ kín và chỉ dành riêng cho chủ sở hữu." + "description": "View, plus modify non-authentication host settings. The owner's SSH authentication stays private and owner-only." }, "manage": { "label": "Quản lý", diff --git a/plugins/fleets/locales/translated/zh_CN.json b/plugins/fleets/locales/translated/zh_CN.json index 1fb6e8cd4..83f335c69 100644 --- a/plugins/fleets/locales/translated/zh_CN.json +++ b/plugins/fleets/locales/translated/zh_CN.json @@ -1,63 +1,77 @@ { + "permissions": { + "view": { + "title": "查看主机组", + "description": "查看主机组、成员及资产信息。" + }, + "manage": { + "title": "管理主机组", + "description": "创建、编辑和删除主机组,调整成员,并与其他用户或角色共享主机组。" + }, + "execute": { + "title": "执行主机组操作", + "description": "在主机组内批量执行命令、软件包操作,以及与成员主机传输文件。" + } + }, "newUi": { "sidebar": { "fleets": { - "title": "舰队", - "createFleet": "创建舰队", - "createFleetTitle": "创建舰队", - "editFleetTitle": "编辑舰队", - "createFleetDescription": "舰队是一个命名的主机组,你可以将其作为一个整体来执行操作。", + "title": "主机组", + "createFleet": "创建主机组", + "createFleetTitle": "创建主机组", + "editFleetTitle": "编辑主机组", + "createFleetDescription": "主机组是一组已命名的主机,可作为整体执行操作。", "nameLabel": "名称", "namePlaceholder": "例如:Web 服务器", - "nameRequired": "需要填写舰队名称。", + "nameRequired": "需要填写主机组名称。", "descriptionLabel": "描述", "descriptionPlaceholder": "可选描述", "colorLabel": "颜色", "tagRulesLabel": "标签规则", "tagRulesPlaceholder": "prod-web, edge", - "tagRulesHint": "带有这些标签的主机将自动包含在内,此外还可以手动添加主机。", - "fleetCreated": "舰队已创建", - "fleetUpdated": "舰队已更新", - "fleetDeleted": "舰队已删除", - "saveFailed": "保存舰队失败", - "deleteFailed": "删除舰队失败", - "loadFailed": "舰队加载失败", - "deleteFleetTitle": "删除舰队", - "deleteFleetDescription": "您确定要删除“{{name}}”吗?此操作不会删除成员主机本身。", - "searchFleets": "搜索舰队……", - "noFleets": "暂无舰队。创建舰队即可开始。", + "tagRulesHint": "除手动添加的主机外,具有任一指定标签的主机也会自动加入。", + "fleetCreated": "主机组已创建", + "fleetUpdated": "主机组已更新", + "fleetDeleted": "主机组已删除", + "saveFailed": "保存主机组失败", + "deleteFailed": "删除主机组失败", + "loadFailed": "加载主机组失败", + "deleteFleetTitle": "删除主机组", + "deleteFleetDescription": "确定删除“{{name}}”?此操作不会删除成员主机本身。", + "searchFleets": "搜索主机组……", + "noFleets": "暂无主机组,请创建一个以开始使用。", "memberCount": "{{count}} 台主机", "memberCount_other": "{{count}} 台主机", "manageMembers": "管理成员", - "manageMembersTitle": "管理舰队成员", - "manageMembersDescription": "切换主机是否加入此舰队的静态成员列表。符合标签规则的主机始终包含在内。", + "manageMembersTitle": "管理主机组成员", + "manageMembersDescription": "将主机加入或移出此主机组的固定成员列表。匹配标签规则的主机始终包含在内。", "searchHosts": "搜索主机...", "noHostsFound": "未找到主机", - "noMembers": "此舰队目前尚无成员。请添加主机或设置标签规则。", - "membersLoadFailed": "加载舰队成员失败", - "memberUpdateFailed": "舰队成员信息更新失败", - "tabRun": "运行命令", + "noMembers": "此主机组暂无成员,请添加主机或设置标签规则。", + "membersLoadFailed": "加载主机组成员失败", + "memberUpdateFailed": "更新主机组成员失败", + "tabRun": "执行命令", "tabTransfer": "传输文件", "tabInventory": "清单", - "openInventoryTab": "在新标签页中打开", + "openInventoryTab": "在完整标签页中打开", "tabPackages": "软件包", - "runOnFleet": "在舰队上运行", + "runOnFleet": "在主机组上运行", "commandPlaceholder": "uptime && df -h", - "commandRequired": "需要一条命令", + "commandRequired": "必须填写命令", "commandInputsLabel": "命令输入", - "commandSucceeded": "命令在所有主机上均已成功执行。", + "commandSucceeded": "命令已在所有主机上执行成功", "commandPartialFailure": "{{total}} 台主机中有 {{failed}} 台失败", - "commandFailed": "命令运行失败", + "commandFailed": "执行命令失败", "resultSuccess": "成功", - "resultFailed": "失败的", + "resultFailed": "失败", "push": "推送", "pull": "拉取", "remotePathLabel": "远程路径", - "remotePathRequired": "需要远程路径", + "remotePathRequired": "必须填写远程路径", "fileLabel": "文件", "fileRequired": "需要选择文件", - "pushHint": "选定的文件将被写入舰队中每台主机上的指定路径。", - "pullHint": "从每个主机读取此路径下的文件,并将其下载为单个 zip 文件,每个主机一个文件夹。", + "pushHint": "选定的文件将被写入主机组中每台主机上的指定路径。", + "pullHint": "从每台主机读取此路径下的文件,按主机分文件夹打包为一个 ZIP 文件下载。", "transferComplete": "传输完成", "transferFailed": "传输失败", "refreshInventory": "刷新清单", @@ -72,19 +86,26 @@ "inventoryArch": "架构", "inventoryUptime": "运行时间", "inventoryPackageManager": "软件包管理器", - "inventoryCollectedAt": "集", - "packageActionLabel": "行动", + "inventoryCollectedAt": "已收集", + "packageActionLabel": "操作", "packageInstall": "安装", "packageRemove": "移除", "packageUpgradeAll": "升级所有软件包", "packageNameLabel": "软件包名称", - "packageNameRequired": "必须提供软件包名称。", - "packageHint": "需要对每台主机具有管理级别的访问权限,并使用主机存储的 sudo 密码提升权限。" + "packageNameRequired": "必须填写软件包名称", + "packageHint": "需要对每台主机具有管理级别权限,并使用主机保存的 sudo 密码提升权限。", + "shareFleet": "共享主机组", + "shareFleetTitle": "共享“{{name}}”", + "shareFleetDescription": "将此主机组当前的成员主机共享给所选用户或角色。后续加入的主机不会自动共享,需要再次执行共享操作。", + "shareSelectionRequired": "请至少选择一个用户或角色", + "fleetSharedSuccessfully": "已共享此主机组中的 {{shared}}/{{total}} 台主机", + "failedToShareFleet": "共享主机组失败", + "noMembersToShare": "此主机组尚无可共享的成员主机。" } } }, "nav": { - "fleets": "舰队" + "fleets": "主机组" }, "hosts": { "docsLink": "查看文档", @@ -110,7 +131,7 @@ }, "edit": { "label": "编辑", - "description": "查看并修改无需身份验证的主机设置。所有者的 SSH 身份验证信息将保持私密,仅限所有者本人查看。" + "description": "允许查看和修改与身份验证无关的主机设置。所有者的 SSH 身份验证信息保持私密,仅供所有者使用。" }, "manage": { "label": "管理", diff --git a/plugins/fleets/locales/translated/zh_TW.json b/plugins/fleets/locales/translated/zh_TW.json index e43d969d2..c07f11aa1 100644 --- a/plugins/fleets/locales/translated/zh_TW.json +++ b/plugins/fleets/locales/translated/zh_TW.json @@ -1,90 +1,111 @@ { + "permissions": { + "view": { + "title": "View fleets", + "description": "See fleets, their members and inventory." + }, + "manage": { + "title": "Manage fleets", + "description": "Create, edit and delete fleets, change membership, and share fleets with other users or roles." + }, + "execute": { + "title": "Run fleet actions", + "description": "Run commands and package actions across a fleet, and transfer files to and from its member hosts." + } + }, "newUi": { "sidebar": { "fleets": { - "title": "艦隊", - "createFleet": "創建艦隊", - "createFleetTitle": "創建艦隊", - "editFleetTitle": "編輯艦隊", - "createFleetDescription": "艦隊是指你可以作為一個整體對一組主機執行操作的指定名稱的主機群組。", - "nameLabel": "姓名", - "namePlaceholder": "例如,Web伺服器", - "nameRequired": "必須填寫艦隊名稱。", - "descriptionLabel": "描述", - "descriptionPlaceholder": "選用描述", + "title": "Fleets", + "createFleet": "Create Fleet", + "createFleetTitle": "Create Fleet", + "editFleetTitle": "Edit Fleet", + "createFleetDescription": "A fleet is a named group of hosts you can run actions against as a unit.", + "nameLabel": "名稱", + "namePlaceholder": "e.g., Web Servers", + "nameRequired": "Fleet name is required", + "descriptionLabel": "說明", + "descriptionPlaceholder": "選用說明", "colorLabel": "顏色", - "tagRulesLabel": "標籤規則", - "tagRulesPlaceholder": "生產網絡,邊緣", - "tagRulesHint": "帶有這些標籤的主機將自動包含在內,此外還可以手動新增主機。", - "fleetCreated": "艦隊創建", - "fleetUpdated": "艦隊更新", - "fleetDeleted": "艦隊已刪除", - "saveFailed": "未能拯救艦隊", - "deleteFailed": "刪除艦隊失敗", - "loadFailed": "艦隊載入失敗", - "deleteFleetTitle": "刪除艦隊", - "deleteFleetDescription": "您確定要刪除“{{name}}”嗎?此操作不會刪除成員主機本身。", - "searchFleets": "搜索艦隊…", - "noFleets": "暫無艦隊。創建艦隊即可開始。", - "memberCount": "{{count}} 主機", - "memberCount_other": "{{count}} 主機", - "manageMembers": "管理成員", - "manageMembersTitle": "管理車隊成員", - "manageMembersDescription": "切換主機是否加入此艦隊的靜態成員清單。符合標籤規則的主機始終包含在內。", + "tagRulesLabel": "Tag rules", + "tagRulesPlaceholder": "prod-web, edge", + "tagRulesHint": "Hosts with any of these tags are automatically included, in addition to hosts added manually.", + "fleetCreated": "Fleet created", + "fleetUpdated": "Fleet updated", + "fleetDeleted": "Fleet deleted", + "saveFailed": "Failed to save fleet", + "deleteFailed": "Failed to delete fleet", + "loadFailed": "Failed to load fleets", + "deleteFleetTitle": "Delete Fleet", + "deleteFleetDescription": "Are you sure you want to delete \"{{name}}\"? This does not delete the member hosts themselves.", + "searchFleets": "Search fleets...", + "noFleets": "No fleets yet. Create one to get started.", + "memberCount": "{{count}} host", + "memberCount_other": "{{count}} 台主機", + "manageMembers": "Manage Members", + "manageMembersTitle": "Manage Fleet Members", + "manageMembersDescription": "Toggle hosts in or out of this fleet's static membership. Hosts matched by tag rules are always included.", "searchHosts": "搜尋主機...", - "noHostsFound": "未找到主機", - "noMembers": "此艦隊目前尚無成員。請新增主機或設定標籤規則。", - "membersLoadFailed": "載入艦隊成員失敗", - "memberUpdateFailed": "艦隊成員資訊更新失敗", - "tabRun": "運行命令", - "tabTransfer": "傳輸檔案", - "tabInventory": "存貨", - "openInventoryTab": "在新分頁中開啟", - "tabPackages": "包裹", - "runOnFleet": "艦隊運行", + "noHostsFound": "找不到主機", + "noMembers": "This fleet has no members yet. Add hosts or set a tag rule.", + "membersLoadFailed": "Failed to load fleet members", + "memberUpdateFailed": "Failed to update fleet membership", + "tabRun": "Run Command", + "tabTransfer": "Transfer Files", + "tabInventory": "Inventory", + "openInventoryTab": "Open in full tab", + "tabPackages": "套件", + "runOnFleet": "Run on Fleet", "commandPlaceholder": "uptime && df -h", - "commandRequired": "需要一條命令", - "commandInputsLabel": "命令輸入", - "commandSucceeded": "指令在所有主機上均已成功執行。", - "commandPartialFailure": "{{failed}} 中的 {{total}} 台主機失敗", - "commandFailed": "命令運行失敗", + "commandRequired": "A command is required", + "commandInputsLabel": "Command inputs", + "commandSucceeded": "Command succeeded on all hosts", + "commandPartialFailure": "{{failed}} of {{total}} hosts failed", + "commandFailed": "Failed to run command", "resultSuccess": "成功", - "resultFailed": "失敗的", - "push": "推", - "pull": "拉", - "remotePathLabel": "遠端路徑", - "remotePathRequired": "需要遠端路徑", - "fileLabel": "文件", - "fileRequired": "需要提交文件", - "pushHint": "選定的檔案將被寫入叢集中每台主機上的指定路徑。", - "pullHint": "從每個主機讀取此路徑下的文件,並將其下載為單一 zip 文件,每個主機一個資料夾。", - "transferComplete": "轉帳完成", - "transferFailed": "轉帳失敗", - "refreshInventory": "刷新庫存", - "inventoryLoadFailed": "庫存載入失敗", - "inventoryRefreshed": "庫存已刷新", - "inventoryRefreshFailed": "刷新庫存失敗", - "inventoryNoData": "暫無庫存資料 - 請重新整理頁面以取得資料。", - "inventoryHost": "主持人", - "inventoryCollectedCount": "{{count}}/{{total}} 收集", + "resultFailed": "失敗", + "push": "Push", + "pull": "Pull", + "remotePathLabel": "Remote path", + "remotePathRequired": "A remote path is required", + "fileLabel": "檔案", + "fileRequired": "A file is required", + "pushHint": "The selected file is written to this exact path on every host in the fleet.", + "pullHint": "The file at this path is read from every host and downloaded as a single zip, one folder per host.", + "transferComplete": "傳送完成", + "transferFailed": "傳送失敗", + "refreshInventory": "Refresh Inventory", + "inventoryLoadFailed": "Failed to load inventory", + "inventoryRefreshed": "Inventory refreshed", + "inventoryRefreshFailed": "Failed to refresh inventory", + "inventoryNoData": "No inventory data yet - refresh to collect it.", + "inventoryHost": "主機", + "inventoryCollectedCount": "{{count}}/{{total}} collected", "inventoryOs": "作業系統", "inventoryKernel": "核心", - "inventoryArch": "拱", - "inventoryUptime": "正常運作時間", - "inventoryPackageManager": "軟體套件管理器", - "inventoryCollectedAt": "集", - "packageActionLabel": "行動", - "packageInstall": "安裝", - "packageRemove": "消除", - "packageUpgradeAll": "升級所有套餐", - "packageNameLabel": "軟體包名稱", - "packageNameRequired": "必須提供軟體包名稱。", - "packageHint": "需要對每台主機具有管理層級的存取權限,並使用主機儲存的 sudo 密碼提升權限。" + "inventoryArch": "Arch", + "inventoryUptime": "運行時間", + "inventoryPackageManager": "Package manager", + "inventoryCollectedAt": "Collected", + "packageActionLabel": "動作", + "packageInstall": "Install", + "packageRemove": "移除", + "packageUpgradeAll": "Upgrade all packages", + "packageNameLabel": "Package name", + "packageNameRequired": "A package name is required", + "packageHint": "Requires manage-level access per host and elevates using the host's stored sudo password.", + "shareFleet": "Share Fleet", + "shareFleetTitle": "Share \"{{name}}\"", + "shareFleetDescription": "Shares this fleet's current member hosts with the selected users or roles. Hosts added to the fleet later are not shared automatically - share again to include them.", + "shareSelectionRequired": "Select at least one user or role", + "fleetSharedSuccessfully": "Shared {{shared}} of {{total}} host(s) in this fleet", + "failedToShareFleet": "Failed to share fleet", + "noMembersToShare": "This fleet has no member hosts to share yet." } } }, "nav": { - "fleets": "艦隊" + "fleets": "Fleets" }, "hosts": { "docsLink": "檢視文件", @@ -110,7 +131,7 @@ }, "edit": { "label": "編輯", - "description": "查看並修改無需身份驗證的主機設定。所有者的 SSH 身份驗證資訊將保持私密,僅限所有者本人查看。" + "description": "View, plus modify non-authentication host settings. The owner's SSH authentication stays private and owner-only." }, "manage": { "label": "管理", diff --git a/plugins/fleets/manifest.json b/plugins/fleets/manifest.json index 5d0ded88f..e11eab9d8 100644 --- a/plugins/fleets/manifest.json +++ b/plugins/fleets/manifest.json @@ -18,6 +18,7 @@ "hosts:read", "hosts:write", "credentials:use", + "credentials:read", "ssh:connect", "db:own", "network:serve", diff --git a/plugins/fleets/src/backend/routes.ts b/plugins/fleets/src/backend/routes.ts index 99d91f77c..857a291ae 100644 --- a/plugins/fleets/src/backend/routes.ts +++ b/plugins/fleets/src/backend/routes.ts @@ -1357,9 +1357,9 @@ export function registerFleetRoutes( fleetId, "manage", async (host) => { - // Package actions need the host's sudo password, an operational - // secret ctx.hosts.get() leaves out. ctx.ssh.connect resolves the - // full host the connect pipeline uses, which carries it. + // Package actions need the host's sudo password. connect() hands + // back a redacted host, so read it through resolveHost. + const full = await ctx.ssh.resolveHost(host.id); const connection = await ctx.ssh.connect(host.id, { purpose: "fleet", }); @@ -1388,7 +1388,7 @@ export function registerFleetRoutes( const result = await execElevated( sshClient, cmd, - connection.host.sudoPassword as string | undefined, + full?.sudoPassword as string | undefined, { forceSudo: true, timeoutMs: 600000 }, ); return { diff --git a/plugins/fleets/tests/backend/sudo-capability.test.ts b/plugins/fleets/tests/backend/sudo-capability.test.ts new file mode 100644 index 000000000..ab3f3d7a1 --- /dev/null +++ b/plugins/fleets/tests/backend/sudo-capability.test.ts @@ -0,0 +1,17 @@ +import { describe, expect, it } from "vitest"; +import fs from "node:fs"; +import path from "node:path"; + +// Elevated commands read the host's sudo password, which core only hands to +// a plugin holding credentials:read. +describe("sudo password access", () => { + it("declares credentials:read", () => { + const manifest = JSON.parse( + fs.readFileSync( + path.resolve(import.meta.dirname, "../../manifest.json"), + "utf8", + ), + ); + expect(manifest.capabilities).toContain("credentials:read"); + }); +}); diff --git a/plugins/homepage/locales/en.json b/plugins/homepage/locales/en.json index 760b3a445..9835baa55 100644 --- a/plugins/homepage/locales/en.json +++ b/plugins/homepage/locales/en.json @@ -169,7 +169,139 @@ "noServices": "No services set up", "configureLocation": "Set a location in the widget settings", "bannerTextPlaceholder": "Banner text", - "serviceNamePlaceholder": "My service" + "serviceNamePlaceholder": "My service", + "emptyNote": "Empty note...", + "weatherLoadFailed": "Could not load weather for \"{{location}}\"", + "feelsLike": "Feels like {{temperature}}", + "timezonePlaceholder": "America/New_York (leave blank for local)", + "notesPlaceholder": "Write your notes here...", + "locationPlaceholder": "New York, London, Tokyo...", + "widgets": { + "bookmark_list": { + "name": "Bookmarks", + "description": "A list of quick links" + }, + "calendar": { + "name": "Calendar", + "description": "A month calendar with today highlighted" + }, + "clock": { + "name": "Clock", + "description": "A live clock with configurable timezone" + }, + "countdown": { + "name": "Countdown", + "description": "Counts down to a target date and time" + }, + "custom_api": { + "name": "Custom API", + "description": "Fetch and display data from any JSON API" + }, + "dashboard_links": { + "name": "Dashboard Links", + "description": "Shows your saved dashboard service links" + }, + "folder": { + "name": "Folder", + "description": "A background card for grouping widgets visually" + }, + "host_grid": { + "name": "Host Grid", + "description": "Live status overview grid for all your SSH hosts" + }, + "host_status": { + "name": "Host Status", + "description": "Shows live status and metrics for an SSH host" + }, + "iframe_embed": { + "name": "iFrame Embed", + "description": "Embed any URL in an iframe" + }, + "image_widget": { + "name": "Image", + "description": "Display any image from a URL" + }, + "link_tree": { + "name": "Link Tree", + "description": "Grouped links organized into labeled sections" + }, + "markdown_notes": { + "name": "Markdown Notes", + "description": "Notes with optional Markdown rendering and inline editing" + }, + "notes": { + "name": "Notes", + "description": "A text notes widget" + }, + "ping_status": { + "name": "Ping Status", + "description": "Check if URLs or services are reachable" + }, + "quick_connect": { + "name": "Quick Connect", + "description": "Launch terminal, files, docker, tunnels, and more for your hosts" + }, + "recent_activity": { + "name": "Recent Activity", + "description": "Shows recent terminal, Docker, file, and tunnel activity" + }, + "rss_feed": { + "name": "RSS Feed", + "description": "Display items from an RSS or Atom feed" + }, + "search_bar": { + "name": "Search Bar", + "description": "Quick search with Google, DuckDuckGo, Bing, or a custom engine" + }, + "search_links": { + "name": "Search Shortcuts", + "description": "Quick buttons to search different engines" + }, + "service_grid": { + "name": "Service Grid", + "description": "A grid of service tiles with icons and links" + }, + "service_link": { + "name": "Service Link", + "description": "A clickable tile linking to a service URL" + }, + "ssh_terminal": { + "name": "SSH Terminal", + "description": "An inline SSH terminal connected to a configured host" + }, + "system_overview": { + "name": "System Overview", + "description": "Termix version, database health, and uptime at a glance" + }, + "termix_uptime": { + "name": "Termix Uptime", + "description": "Shows how long the Termix server has been running" + }, + "text_banner": { + "name": "Text Banner", + "description": "A styled text label for sections and headings" + }, + "weather": { + "name": "Weather", + "description": "Live weather for any location" + }, + "docker_widget": { + "name": "Docker Manager", + "description": "Embedded Docker container manager for a configured host" + }, + "file_manager_widget": { + "name": "File Manager", + "description": "Embedded SFTP file manager for a configured host" + }, + "tunnel_widget": { + "name": "Tunnel Manager", + "description": "Embedded SSH tunnel manager for a configured host" + }, + "metrics_chart": { + "name": "Metrics Chart", + "description": "Historical CPU, memory, disk, or network chart for a host" + } + } }, "permissions": { "use": { @@ -186,5 +318,8 @@ "label": "Private certificate authority (PEM)", "description": "Optional trusted CA bundle for allowlisted hosts. Certificate verification remains enabled. Leave empty to use the system trust store." } + }, + "plugin": { + "name": "Homepage" } } diff --git a/plugins/homepage/locales/translated/af_ZA.json b/plugins/homepage/locales/translated/af_ZA.json index 4fea30376..59a7eaa40 100644 --- a/plugins/homepage/locales/translated/af_ZA.json +++ b/plugins/homepage/locales/translated/af_ZA.json @@ -18,6 +18,7 @@ "homepage": { "title": "Tuisblad", "addWidget": "Voeg Widget by", + "noWidgetsInCategory": "Geen widgets in hierdie kategorie nie", "editWidget": "Wysig Widget", "zoomIn": "Inzoem", "zoomOut": "Uitzoom", @@ -59,6 +60,9 @@ "maxItems": "Maksimum items", "showDescription": "Wys Beskrywing", "widgetRssName": "RSS-voer", + "rssNoFeedUrl": "Konfigureer 'n voer-URL in widget-instellings", + "rssLoadError": "Kon nie voer laai nie", + "rssNoItems": "Geen items nie", "noHostSelected": "Geen gasheer gekies nie", "displayedMetrics": "Vertoonde Metrieke", "metricCpu": "SVE", @@ -157,6 +161,30 @@ "compactMode": "Kompakte modus", "selectHosts": "Kies gashere", "listLayout": "Lys", - "gridLayout": "Rooster" + "gridLayout": "Rooster", + "configureUrl": "Stel 'n URL in die widget-instellings", + "embeddedContent": "Ingeslote inhoud", + "noBookmarks": "Geen boekmerke nie", + "noSections": "Geen afdelings opgestel nie", + "noServices": "Geen dienste opgestel nie", + "configureLocation": "Stel 'n ligging in die widget-instellings", + "bannerTextPlaceholder": "Banier teks", + "serviceNamePlaceholder": "My diens" + }, + "permissions": { + "use": { + "title": "Gebruik die tuisblad", + "description": "Bekyk en wysig die tuisblad-doek en dashboarddiensskakels." + } + }, + "settings": { + "privateEndpoints": { + "label": "Toegelate privaat gashere", + "description": "Presiese private of teruglus-gasheername/IP's vir Ping Status en Pasgemaakte API-widgets. Skei inskrywings met kommas of nuwe reëls; laat skemas, poorte en paaie weg. Maak private bestemmings leeg." + }, + "privateCertificateAuthority": { + "label": "Privaat sertifikaatowerheid (PEM)", + "description": "Opsionele vertroude CA-bundel vir gashere op die toelaatlys. Sertifikaatverifikasie bly geaktiveer. Los leeg om die stelselvertrouensberging te gebruik." + } } } diff --git a/plugins/homepage/locales/translated/ar_SA.json b/plugins/homepage/locales/translated/ar_SA.json index d1322f2b4..60d453c87 100644 --- a/plugins/homepage/locales/translated/ar_SA.json +++ b/plugins/homepage/locales/translated/ar_SA.json @@ -18,6 +18,7 @@ "homepage": { "title": "الصفحة الرئيسية", "addWidget": "إضافة ويدجت", + "noWidgetsInCategory": "لا توجد أدوات في هذه الفئة", "editWidget": "تعديل ويدجت", "zoomIn": "تكبير", "zoomOut": "تصغير", @@ -59,6 +60,9 @@ "maxItems": "الحد الأقصى للعناصر", "showDescription": "إظهار الوصف", "widgetRssName": "تغذية RSS", + "rssNoFeedUrl": "قم بتكوين عنوان URL للتغذية في إعدادات الأداة", + "rssLoadError": "تعذر تحميل التغذية", + "rssNoItems": "لا يوجد منتج", "noHostSelected": "لم يتم تحديد أي مضيف", "displayedMetrics": "المقاييس المعروضة", "metricCpu": "CPU", @@ -157,6 +161,30 @@ "compactMode": "الوضع المضغوط", "selectHosts": "اختيار المضيفين", "listLayout": "قائمة", - "gridLayout": "شبكة" + "gridLayout": "شبكة", + "configureUrl": "قم بتعيين عنوان URL في إعدادات الأداة", + "embeddedContent": "المحتوى المضمن", + "noBookmarks": "لا توجد إشارات مرجعية", + "noSections": "لم يتم إعداد أي أقسام", + "noServices": "لم يتم إعداد أي خدمات", + "configureLocation": "حدد موقعًا في إعدادات الأداة", + "bannerTextPlaceholder": "نص الشعار", + "serviceNamePlaceholder": "خدمتي" + }, + "permissions": { + "use": { + "title": "استخدم الصفحة الرئيسية", + "description": "عرض وتعديل روابط خدمة لوحة التحكم ولوحة الصفحة الرئيسية." + } + }, + "settings": { + "privateEndpoints": { + "label": "المضيفون الخاصون المسموح بهم", + "description": "أدخل أسماء المضيفين/عناوين IP الخاصة أو عناوين الاسترجاع لعناصر واجهة برمجة التطبيقات (API) الخاصة بحالة الاتصال (Ping Status) وواجهة برمجة التطبيقات المخصصة (Custom API). افصل بين الإدخالات بفواصل أو أسطر جديدة؛ احذف المخططات والمنافذ والمسارات. اترك خانات فارغة للوجهات الخاصة." + }, + "privateCertificateAuthority": { + "label": "هيئة إصدار الشهادات الخاصة (PEM)", + "description": "حزمة شهادات المصادقة الموثوقة اختيارية للأجهزة المضيفة المدرجة في القائمة المسموح بها. يبقى التحقق من الشهادات مُفعّلاً. اترك هذا الحقل فارغًا لاستخدام مخزن شهادات النظام الموثوقة." + } } } diff --git a/plugins/homepage/locales/translated/bg_BG.json b/plugins/homepage/locales/translated/bg_BG.json index 318922bad..db688c497 100644 --- a/plugins/homepage/locales/translated/bg_BG.json +++ b/plugins/homepage/locales/translated/bg_BG.json @@ -18,6 +18,7 @@ "homepage": { "title": "Начална страница", "addWidget": "Добавяне на джаджа", + "noWidgetsInCategory": "Няма джаджи в тази категория", "editWidget": "Редактиране на уиджет", "zoomIn": "Увеличаване на мащаба", "zoomOut": "Намаляване на мащаба", @@ -59,6 +60,9 @@ "maxItems": "Максимален брой елементи", "showDescription": "Покажи описание", "widgetRssName": "RSS емисия", + "rssNoFeedUrl": "Конфигурирайте URL адрес на емисията в настройките на уиджета", + "rssLoadError": "Не можа да се зареди емисията", + "rssNoItems": "Няма артикули", "noHostSelected": "Няма избран хост", "displayedMetrics": "Показани показатели", "metricCpu": "Процесор", @@ -157,6 +161,30 @@ "compactMode": "Компактен режим", "selectHosts": "Изберете хостове", "listLayout": "Списък", - "gridLayout": "Решетка" + "gridLayout": "Решетка", + "configureUrl": "Задайте URL адрес в настройките на джаджата", + "embeddedContent": "Вградено съдържание", + "noBookmarks": "Няма отметки", + "noSections": "Няма настроени секции", + "noServices": "Няма настроени услуги", + "configureLocation": "Задайте местоположение в настройките на джаджата", + "bannerTextPlaceholder": "Текст на банера", + "serviceNamePlaceholder": "Моята услуга" + }, + "permissions": { + "use": { + "title": "Използвайте началната страница", + "description": "Преглеждайте и редактирайте връзките към услугите на началната страница и таблото за управление." + } + }, + "settings": { + "privateEndpoints": { + "label": "Разрешени частни хостове", + "description": "Точни частни или loopback имена/IP адреси на хостове за Ping Status и Custom API джаджи. Разделете записите със запетаи или нови редове; пропуснете схеми, портове и пътища. Празните полета блокират частни дестинации." + }, + "privateCertificateAuthority": { + "label": "Частен сертифициращ орган (PEM)", + "description": "Незадължителен пакет с доверени CA за хостове от разрешения списък. Проверката на сертификата остава активирана. Оставете празно, за да използвате хранилището за доверени сертификати на системата." + } } } diff --git a/plugins/homepage/locales/translated/bn_BD.json b/plugins/homepage/locales/translated/bn_BD.json index c0c29c6cc..760b3a445 100644 --- a/plugins/homepage/locales/translated/bn_BD.json +++ b/plugins/homepage/locales/translated/bn_BD.json @@ -1,162 +1,190 @@ { "nav": { - "homepage": "হোমপেজ" + "homepage": "Homepage" }, "dashboard": { - "serviceLinks": "পরিষেবা লিঙ্ক", - "homepagePreview": "হোমপেজ প্রিভিউ" + "serviceLinks": "Service Links", + "homepagePreview": "Homepage Preview" }, "dashboardTab": { - "serviceLinksTitle": "পরিষেবা লিঙ্ক", - "serviceLinksEmpty": "এখনও কোনো পরিষেবা লিঙ্ক নেই", - "serviceLinksAdd": "যোগ করুন", - "serviceLinksLabelPlaceholder": "আমার পরিষেবা", + "serviceLinksTitle": "Service Links", + "serviceLinksEmpty": "No service links yet", + "serviceLinksAdd": "Add", + "serviceLinksLabelPlaceholder": "My Service", "serviceLinksUrlPlaceholder": "http://192.168.1.10:8080", - "serviceLinksInvalidUrl": "একটি বৈধ ওয়েব ঠিকানা লিখুন", - "serviceLinksAddFailed": "পরিষেবা লিঙ্ক যোগ করতে ব্যর্থ হয়েছে" + "serviceLinksInvalidUrl": "Enter a valid web address", + "serviceLinksAddFailed": "Failed to add service link" }, "homepage": { - "title": "হোমপেজ", - "addWidget": "উইজেট যোগ করুন", - "editWidget": "উইজেট সম্পাদনা করুন", - "zoomIn": "জুম ইন", - "zoomOut": "জুম আউট", - "resetView": "দৃশ্য রিসেট করুন", - "lockLayout": "লক লেআউট", - "unlockLayout": "লেআউট আনলক করুন", - "noWidgets": "আপনার প্রথম উইজেট যোগ করতে ডান-ক্লিক করুন অথবা + এ ক্লিক করুন।", - "openFullView": "সম্পূর্ণ দৃশ্য খুলুন", - "previewTitle": "হোমপেজ প্রিভিউ", - "cancel": "বাতিল করুন", - "save": "সংরক্ষণ করুন", - "title_label": "শিরোনাম", - "widgetTitlePlaceholder": "উইজেটের শিরোনাম (ঐচ্ছিক)", - "url": "ইউআরএল", - "imageUrl": "কাস্টম ইমেজ ইউআরএল", - "imageUrlHint": "সাইটের ফেভিকন স্বয়ংক্রিয়ভাবে ব্যবহার করতে খালি রাখুন।", - "showImage": "ছবি দেখান", - "description": "বর্ণনা", - "color": "রঙ", - "timezone": "সময় অঞ্চল", - "invalidTimezone": "অবৈধ টাইমজোন। America/New_York-এর মতো একটি IANA নাম ব্যবহার করুন।", - "showSeconds": "সেকেন্ড দেখান", - "format12h": "১২ ঘন্টা", - "content": "বিষয়বস্তু", - "backgroundColor": "পটভূমির রঙ", - "links": "লিঙ্ক", - "addLink": "লিঙ্ক যোগ করুন", - "linkLabel": "লেবেল", - "categoryLinks": "লিঙ্ক", - "categoryInfo": "তথ্য", - "categorySystem": "সিস্টেম", - "copyLink": "লিঙ্ক কপি করুন", - "linkCopied": "লিঙ্ক কপি করা হয়েছে!", - "location": "অবস্থান", - "temperatureUnit": "তাপমাত্রা ইউনিট", - "showForecast": "তিন দিনের পূর্বাভাস দেখান", - "scrolling": "স্ক্রোল করার অনুমতি দিন", - "feedUrl": "ফিড ইউআরএল", - "maxItems": "সর্বোচ্চ আইটেম", - "showDescription": "বিবরণ দেখান", - "widgetRssName": "আরএসএস ফিড", - "noHostSelected": "কোন হোস্ট নির্বাচন করা হয়নি", - "displayedMetrics": "প্রদর্শিত মেট্রিক্স", - "metricCpu": "সিপিইউ", - "metricMemory": "স্মৃতি", - "metricDisk": "ডিস্ক", - "metricUptime": "আপটাইম", - "metricSystem": "সিস্টেম", - "metricNetwork": "নেটওয়ার্ক", - "metricProcesses": "প্রক্রিয়া", - "categoryMonitoring": "পর্যবেক্ষণ", - "noPingUrls": "কোন URL কনফিগার করা নেই", - "pingLabel": "লেবেল", - "addPingUrl": "URL যোগ করুন", - "showLatency": "লেটেন্সি দেখান", - "refreshInterval": "রিফ্রেশ ব্যবধান", - "seconds": "সেকেন্ড", - "filterActivityTypes": "ফিল্টারের প্রকারভেদ", - "filterTypesHint": "সবগুলো দেখাতে খালি রাখুন", - "showTimestamp": "টাইমস্ট্যাম্প দেখান", - "uptimeUnavailable": "আপটাইম অনুপলব্ধ", - "uptimeLabel": "আপটাইম", - "overviewVersion": "সংস্করণ", - "overviewUpdateLabel": "আপডেট", - "overviewUpdateAvailable": "আপডেট উপলব্ধ", - "overviewDatabase": "ডাটাবেস", - "overviewUptime": "আপটাইম", - "noHosts": "কোন হোস্ট কনফিগার করা নেই", - "hostGridHosts": "হোস্টরা", - "hostGridAllHint": "সমস্ত হোস্ট দেখানোর জন্য খালি রাখুন", - "columns": "কলাম", - "showIp": "আইপি ঠিকানা দেখান", - "layout": "লেআউট", - "showStatus": "অবস্থা দেখান", - "noActivity": "কোন কার্যকলাপ নেই", - "widgetPingStatusName": "পিং স্ট্যাটাস", - "widgetRecentActivityName": "সাম্প্রতিক কার্যকলাপ", - "sshTerminalNoHost": "কোন হোস্ট কনফিগার করা নেই", - "sshTerminalConnect": "সংযোগ করুন", - "sshTerminalAutoConnect": "লোড হলে স্বয়ংক্রিয়ভাবে সংযোগ স্থাপন", - "connectionTypes": "সংযোগের প্রকারভেদ", - "calMon": "মো", - "calTue": "তু", - "calWed": "আমরা", - "calThu": "থ", - "calFri": "ফ্র", - "calSat": "সা", - "calSun": "সু", - "startOnMonday": "সোমবার থেকে সপ্তাহ শুরু করুন", - "countdownNoDate": "কোনো নির্দিষ্ট তারিখ নির্ধারণ করা হয়নি।", - "countdownPast": "অনুষ্ঠানটি শেষ হয়ে গেছে।", - "countdownDays": "দিন", - "countdownHours": "ঘন্টা", - "countdownMinutes": "মিনিট", - "countdownSeconds": "সেকেন্ড", - "countdownLabel": "লেবেল", - "countdownLabelPlaceholder": "যেমন লঞ্চের দিন", - "countdownShowDays": "শো ডেজ", - "countdownShowHours": "শো আওয়ার্স", - "targetDate": "লক্ষ্য তারিখ", - "searchEngine": "সার্চ ইঞ্জিন", - "customSearchUrl": "কাস্টম সার্চ ইউআরএল", - "searchPlaceholder": "অনুসন্ধান করুন...", - "searchGo": "যান", - "searchPlaceholderLabel": "স্থানধারক পাঠ্য", - "searchPlaceholderHint": "সার্চ ইনপুটের ভিতরে দেখানো টেক্সট", - "openInNewTab": "নতুন ট্যাবে খুলুন", - "searchQueryPlaceholder": "প্রশ্ন লিখুন...", - "noSearchShortcuts": "কোন শর্টকাট কনফিগার করা নেই", - "addSearchShortcut": "শর্টকাট যোগ করুন", - "fontSize": "ফন্ট সাইজ", - "textAlign": "টেক্সট অ্যালাইন", - "fontWeight": "ফন্ট ওজন", - "clearColor": "পরিষ্কার রঙ", - "imageFit": "ইমেজ ফিট", - "imageLinkUrl": "লিঙ্ক ইউআরএল", - "noImage": "কোন ছবির ইউআরএল সেট করা হয়নি", - "altText": "বিকল্প পাঠ্য", - "altTextPlaceholder": "ছবিটি বর্ণনা করুন", - "renderMarkdown": "রেন্ডার মার্কডাউন", - "displayMode": "ডিসপ্লে মোড", - "displayField": "ডিসপ্লে ফিল্ড", - "jsonPath": "JSON পাথ", - "customApiLabel": "লেবেল", - "customApiLabelPlaceholder": "যেমন তাপমাত্রা", - "customApiUnit": "ইউনিট", - "customApiNoUrl": "কোন API URL কনফিগার করা নেই", - "customApiError": "আনতে ব্যর্থ হয়েছে", - "customApiNotArray": "প্রতিক্রিয়া একটি অ্যারে নয়", - "addService": "পরিষেবা যোগ করুন", - "showLabels": "লেবেল দেখান", - "iconSize": "আইকনের আকার", - "noDashboardLinks": "কোন ড্যাশবোর্ড লিঙ্ক কনফিগার করা নেই", - "noLimit": "কোনো সীমা নেই", - "sectionHeading": "বিভাগ শিরোনাম", - "addSection": "বিভাগ যোগ করুন", - "compactMode": "কমপ্যাক্ট মোড", - "selectHosts": "হোস্ট নির্বাচন করুন", - "listLayout": "তালিকা", - "gridLayout": "গ্রিড" + "title": "Homepage", + "addWidget": "Add Widget", + "noWidgetsInCategory": "No widgets in this category", + "editWidget": "Edit Widget", + "zoomIn": "Zoom In", + "zoomOut": "Zoom Out", + "resetView": "Reset View", + "lockLayout": "Lock Layout", + "unlockLayout": "Unlock Layout", + "noWidgets": "Right-click or click + to add your first widget", + "openFullView": "Open Full View", + "previewTitle": "Homepage Preview", + "cancel": "Cancel", + "save": "Save", + "title_label": "Title", + "widgetTitlePlaceholder": "Widget title (optional)", + "url": "URL", + "imageUrl": "Custom Image URL", + "imageUrlHint": "Leave blank to use the site favicon automatically", + "showImage": "Show Image", + "description": "Description", + "color": "Color", + "timezone": "Timezone", + "invalidTimezone": "Invalid timezone. Use an IANA name such as America/New_York", + "showSeconds": "Show seconds", + "format12h": "12-hour", + "content": "Content", + "backgroundColor": "Background Color", + "links": "Links", + "addLink": "Add Link", + "linkLabel": "Label", + "categoryLinks": "Links", + "categoryInfo": "Info", + "categorySystem": "System", + "copyLink": "Copy Link", + "linkCopied": "Link copied!", + "location": "Location", + "temperatureUnit": "Temperature Unit", + "showForecast": "Show 3-day forecast", + "scrolling": "Allow Scrolling", + "feedUrl": "Feed URL", + "maxItems": "Max Items", + "showDescription": "Show Description", + "widgetRssName": "RSS Feed", + "rssNoFeedUrl": "Configure a feed URL in widget settings", + "rssLoadError": "Could not load feed", + "rssNoItems": "No items", + "noHostSelected": "No host selected", + "displayedMetrics": "Displayed Metrics", + "metricCpu": "CPU", + "metricMemory": "Memory", + "metricDisk": "Disk", + "metricUptime": "Uptime", + "metricSystem": "System", + "metricNetwork": "Network", + "metricProcesses": "Processes", + "categoryMonitoring": "Monitoring", + "noPingUrls": "No URLs configured", + "pingLabel": "Label", + "addPingUrl": "Add URL", + "showLatency": "Show Latency", + "refreshInterval": "Refresh Interval", + "seconds": "seconds", + "filterActivityTypes": "Filter Types", + "filterTypesHint": "Leave empty to show all", + "showTimestamp": "Show Timestamp", + "uptimeUnavailable": "Uptime unavailable", + "uptimeLabel": "Uptime", + "overviewVersion": "Version", + "overviewUpdateLabel": "Update", + "overviewUpdateAvailable": "Update available", + "overviewDatabase": "Database", + "overviewUptime": "Uptime", + "noHosts": "No hosts configured", + "hostGridHosts": "Hosts", + "hostGridAllHint": "Leave empty to show all hosts", + "columns": "Columns", + "showIp": "Show IP Address", + "layout": "Layout", + "showStatus": "Show Status", + "noActivity": "No activity", + "widgetPingStatusName": "Ping Status", + "widgetRecentActivityName": "Recent Activity", + "sshTerminalNoHost": "No host configured", + "sshTerminalConnect": "Connect", + "sshTerminalAutoConnect": "Auto-connect on load", + "connectionTypes": "Connection Types", + "calMon": "Mo", + "calTue": "Tu", + "calWed": "We", + "calThu": "Th", + "calFri": "Fr", + "calSat": "Sa", + "calSun": "Su", + "startOnMonday": "Start week on Monday", + "countdownNoDate": "No target date set", + "countdownPast": "Event has passed", + "countdownDays": "days", + "countdownHours": "hrs", + "countdownMinutes": "min", + "countdownSeconds": "sec", + "countdownLabel": "Label", + "countdownLabelPlaceholder": "e.g. Launch Day", + "countdownShowDays": "Show Days", + "countdownShowHours": "Show Hours", + "targetDate": "Target Date", + "searchEngine": "Search Engine", + "customSearchUrl": "Custom Search URL", + "searchPlaceholder": "Search...", + "searchGo": "Go", + "searchPlaceholderLabel": "Placeholder Text", + "searchPlaceholderHint": "Text shown inside the search input", + "openInNewTab": "Open in New Tab", + "searchQueryPlaceholder": "Enter query...", + "noSearchShortcuts": "No shortcuts configured", + "addSearchShortcut": "Add Shortcut", + "fontSize": "Font Size", + "textAlign": "Text Align", + "fontWeight": "Font Weight", + "clearColor": "Clear Color", + "imageFit": "Image Fit", + "imageLinkUrl": "Link URL", + "noImage": "No image URL set", + "altText": "Alt Text", + "altTextPlaceholder": "Describe the image", + "renderMarkdown": "Render Markdown", + "displayMode": "Display Mode", + "displayField": "Display Field", + "jsonPath": "JSON Path", + "customApiLabel": "Label", + "customApiLabelPlaceholder": "e.g. Temperature", + "customApiUnit": "Unit", + "customApiNoUrl": "No API URL configured", + "customApiError": "Failed to fetch", + "customApiNotArray": "Response is not an array", + "addService": "Add Service", + "showLabels": "Show Labels", + "iconSize": "Icon Size", + "noDashboardLinks": "No dashboard links configured", + "noLimit": "No limit", + "sectionHeading": "Section Heading", + "addSection": "Add Section", + "compactMode": "Compact Mode", + "selectHosts": "Select Hosts", + "listLayout": "List", + "gridLayout": "Grid", + "configureUrl": "Set a URL in the widget settings", + "embeddedContent": "Embedded content", + "noBookmarks": "No bookmarks", + "noSections": "No sections set up", + "noServices": "No services set up", + "configureLocation": "Set a location in the widget settings", + "bannerTextPlaceholder": "Banner text", + "serviceNamePlaceholder": "My service" + }, + "permissions": { + "use": { + "title": "Use the homepage", + "description": "View and edit the homepage canvas and dashboard service links." + } + }, + "settings": { + "privateEndpoints": { + "label": "Allowed private hosts", + "description": "Exact private or loopback hostnames/IPs for Ping Status and Custom API widgets. Separate entries with commas or newlines; omit schemes, ports and paths. Empty blocks private destinations." + }, + "privateCertificateAuthority": { + "label": "Private certificate authority (PEM)", + "description": "Optional trusted CA bundle for allowlisted hosts. Certificate verification remains enabled. Leave empty to use the system trust store." + } } } diff --git a/plugins/homepage/locales/translated/ca_ES.json b/plugins/homepage/locales/translated/ca_ES.json index e5dcb1ed0..8016ee023 100644 --- a/plugins/homepage/locales/translated/ca_ES.json +++ b/plugins/homepage/locales/translated/ca_ES.json @@ -18,6 +18,7 @@ "homepage": { "title": "Pàgina d'inici", "addWidget": "Afegeix un widget", + "noWidgetsInCategory": "No hi ha widgets en aquesta categoria", "editWidget": "Edita el widget", "zoomIn": "Ampliar zoom", "zoomOut": "Allunyar", @@ -59,6 +60,9 @@ "maxItems": "Màxim d'elements", "showDescription": "Mostra la descripció", "widgetRssName": "Canal RSS", + "rssNoFeedUrl": "Configura una URL de feed a la configuració del widget", + "rssLoadError": "No s'ha pogut carregar el feed", + "rssNoItems": "Sense elements", "noHostSelected": "No s'ha seleccionat cap amfitrió", "displayedMetrics": "Mètriques mostrades", "metricCpu": "CPU", @@ -157,6 +161,30 @@ "compactMode": "Mode compacte", "selectHosts": "Selecciona els amfitrions", "listLayout": "Llista", - "gridLayout": "Graella" + "gridLayout": "Graella", + "configureUrl": "Defineix una URL a la configuració del widget", + "embeddedContent": "Contingut incrustat", + "noBookmarks": "Sense marcadors", + "noSections": "No s'han configurat seccions", + "noServices": "No hi ha serveis configurats", + "configureLocation": "Defineix una ubicació a la configuració del widget", + "bannerTextPlaceholder": "Text del bàner", + "serviceNamePlaceholder": "El meu servei" + }, + "permissions": { + "use": { + "title": "Utilitzeu la pàgina d'inici", + "description": "Visualitza i edita els enllaços del servei de llenç i tauler de control de la pàgina d'inici." + } + }, + "settings": { + "privateEndpoints": { + "label": "Amfitrions privats permesos", + "description": "Noms d'amfitrió/IP privats o de bucle exactes per als widgets d'estat del ping i de l'API personalitzada. Separeu les entrades amb comes o salts de línia; ometeu esquemes, ports i camins. Els blocs buits bloquegen les destinacions privades." + }, + "privateCertificateAuthority": { + "label": "Autoritat de certificació privada (PEM)", + "description": "Paquet opcional de CA de confiança per a amfitrions de la llista permesa. La verificació del certificat roman habilitada. Deixeu-ho en blanc per utilitzar el magatzem de confiança del sistema." + } } } diff --git a/plugins/homepage/locales/translated/cs_CZ.json b/plugins/homepage/locales/translated/cs_CZ.json index 2438fe1e4..2de6e1574 100644 --- a/plugins/homepage/locales/translated/cs_CZ.json +++ b/plugins/homepage/locales/translated/cs_CZ.json @@ -18,6 +18,7 @@ "homepage": { "title": "Domovská stránka", "addWidget": "Přidat widget", + "noWidgetsInCategory": "V této kategorii nejsou žádné widgety", "editWidget": "Upravit widget", "zoomIn": "Přiblížit", "zoomOut": "Oddálit", @@ -59,6 +60,9 @@ "maxItems": "Maximální počet položek", "showDescription": "Zobrazit popis", "widgetRssName": "RSS kanál", + "rssNoFeedUrl": "Konfigurace adresy URL kanálu v nastavení widgetu", + "rssLoadError": "Nepodařilo se načíst zdroj", + "rssNoItems": "Žádné položky", "noHostSelected": "Nebyl vybrán žádný hostitel", "displayedMetrics": "Zobrazené metriky", "metricCpu": "Procesor", @@ -157,6 +161,30 @@ "compactMode": "Kompaktní režim", "selectHosts": "Vyberte hostitele", "listLayout": "Seznam", - "gridLayout": "Mřížka" + "gridLayout": "Mřížka", + "configureUrl": "Nastavte URL adresu v nastavení widgetu", + "embeddedContent": "Vložený obsah", + "noBookmarks": "Žádné záložky", + "noSections": "Žádné sekce nejsou nastaveny", + "noServices": "Žádné služby nejsou nastaveny", + "configureLocation": "Nastavte umístění v nastavení widgetu", + "bannerTextPlaceholder": "Text banneru", + "serviceNamePlaceholder": "Moje služba" + }, + "permissions": { + "use": { + "title": "Použijte domovskou stránku", + "description": "Zobrazte a upravte odkazy na služby na domovské stránce a na řídicím panelu." + } + }, + "settings": { + "privateEndpoints": { + "label": "Povolení soukromí hostitelé", + "description": "Přesné soukromé nebo zpětně smyčkové názvy hostitelů/IP adresy pro widgety Ping Status a Custom API. Oddělte položky čárkami nebo znaky nového řádku; vynechte schémata, porty a cesty. Prázdné pole blokuje soukromé cíle." + }, + "privateCertificateAuthority": { + "label": "Soukromá certifikační autorita (PEM)", + "description": "Volitelný balíček důvěryhodných certifikačních autorit pro hostitele na seznamu povolených. Ověřování certifikátů zůstává povoleno. Pro použití systémového úložiště důvěryhodných certifikátů ponechte pole prázdné." + } } } diff --git a/plugins/homepage/locales/translated/da_DK.json b/plugins/homepage/locales/translated/da_DK.json index 7bb8f3dc7..4d698ed92 100644 --- a/plugins/homepage/locales/translated/da_DK.json +++ b/plugins/homepage/locales/translated/da_DK.json @@ -18,6 +18,7 @@ "homepage": { "title": "Hjemmeside", "addWidget": "Tilføj widget", + "noWidgetsInCategory": "Ingen widgets i denne kategori", "editWidget": "Rediger widget", "zoomIn": "Zoom ind", "zoomOut": "Zoom ud", @@ -59,6 +60,9 @@ "maxItems": "Maks. antal varer", "showDescription": "Vis beskrivelse", "widgetRssName": "RSS-feed", + "rssNoFeedUrl": "Konfigurer en feed-URL i widgetindstillinger", + "rssLoadError": "Kunne ikke indlæse feedet", + "rssNoItems": "Ingen varer", "noHostSelected": "Ingen vært valgt", "displayedMetrics": "Viste målinger", "metricCpu": "CPU", @@ -157,6 +161,30 @@ "compactMode": "Kompakt tilstand", "selectHosts": "Vælg værter", "listLayout": "Liste", - "gridLayout": "Gitter" + "gridLayout": "Gitter", + "configureUrl": "Angiv en URL i widgetindstillingerne", + "embeddedContent": "Indlejret indhold", + "noBookmarks": "Ingen bogmærker", + "noSections": "Ingen sektioner er oprettet", + "noServices": "Ingen tjenester konfigureret", + "configureLocation": "Angiv en placering i widgetindstillingerne", + "bannerTextPlaceholder": "Bannertekst", + "serviceNamePlaceholder": "Min tjeneste" + }, + "permissions": { + "use": { + "title": "Brug hjemmesiden", + "description": "Se og rediger links til startsidens lærred og dashboardtjenester." + } + }, + "settings": { + "privateEndpoints": { + "label": "Tilladte private værter", + "description": "Præcise private eller loopback-værtsnavne/IP'er for Ping-status og brugerdefinerede API-widgets. Adskil poster med kommaer eller nye linjer; udelad skemaer, porte og stier. Tøm blokering af private destinationer." + }, + "privateCertificateAuthority": { + "label": "Privat certifikatmyndighed (PEM)", + "description": "Valgfri pakke med betroede CA'er til værter på tilladelseslisten. Certifikatbekræftelse forbliver aktiveret. Lad være tomt for at bruge systemets tillidslager." + } } } diff --git a/plugins/homepage/locales/translated/de_DE.json b/plugins/homepage/locales/translated/de_DE.json index d522c2c60..3efc033a1 100644 --- a/plugins/homepage/locales/translated/de_DE.json +++ b/plugins/homepage/locales/translated/de_DE.json @@ -18,6 +18,7 @@ "homepage": { "title": "Startseite", "addWidget": "Widget hinzufügen", + "noWidgetsInCategory": "Keine Widgets in dieser Kategorie", "editWidget": "Widget bearbeiten", "zoomIn": "Vergrößern", "zoomOut": "Verkleinern", @@ -59,6 +60,9 @@ "maxItems": "Max. Einträge", "showDescription": "Beschreibung anzeigen", "widgetRssName": "RSS-Feed", + "rssNoFeedUrl": "Konfigurieren Sie eine Feed-URL in den Widget-Einstellungen.", + "rssLoadError": "Zuführung konnte nicht geladen werden", + "rssNoItems": "Keine Artikel", "noHostSelected": "Kein Host ausgewählt", "displayedMetrics": "Angezeigte Metriken", "metricCpu": "CPU", @@ -157,6 +161,30 @@ "compactMode": "Kompaktmodus", "selectHosts": "Hosts auswählen", "listLayout": "Liste", - "gridLayout": "Raster" + "gridLayout": "Raster", + "configureUrl": "Legen Sie in den Widget-Einstellungen eine URL fest.", + "embeddedContent": "Eingebetteter Inhalt", + "noBookmarks": "Keine Lesezeichen", + "noSections": "Keine Abschnitte eingerichtet", + "noServices": "Keine Dienste eingerichtet", + "configureLocation": "Legen Sie in den Widget-Einstellungen einen Standort fest.", + "bannerTextPlaceholder": "Bannertext", + "serviceNamePlaceholder": "Mein Service" + }, + "permissions": { + "use": { + "title": "Nutzen Sie die Startseite", + "description": "Homepage-Canvas und Dashboard-Servicelinks anzeigen und bearbeiten." + } + }, + "settings": { + "privateEndpoints": { + "label": "Zulässige private Gastgeber", + "description": "Exakte private oder Loopback-Hostnamen/IPs für Ping-Status- und benutzerdefinierte API-Widgets. Einträge durch Kommas oder Zeilenumbrüche trennen; Schemas, Ports und Pfade weglassen. Leere Blöcke private Ziele." + }, + "privateCertificateAuthority": { + "label": "Private Zertifizierungsstelle (PEM)", + "description": "Optionales Paket vertrauenswürdiger Zertifizierungsstellen für zugelassene Hosts. Die Zertifikatsprüfung bleibt aktiviert. Lassen Sie dieses Feld leer, um den System-Truststore zu verwenden." + } } } diff --git a/plugins/homepage/locales/translated/el_GR.json b/plugins/homepage/locales/translated/el_GR.json index b86b901fb..0f15655dc 100644 --- a/plugins/homepage/locales/translated/el_GR.json +++ b/plugins/homepage/locales/translated/el_GR.json @@ -18,6 +18,7 @@ "homepage": { "title": "Αρχική σελίδα", "addWidget": "Προσθήκη γραφικού στοιχείου", + "noWidgetsInCategory": "Δεν υπάρχουν γραφικά στοιχεία σε αυτήν την κατηγορία", "editWidget": "Επεξεργασία γραφικού στοιχείου", "zoomIn": "Μεγέθυνση", "zoomOut": "Σμίκρυνση", @@ -59,6 +60,9 @@ "maxItems": "Μέγιστος αριθμός στοιχείων", "showDescription": "Εμφάνιση περιγραφής", "widgetRssName": "Ροή RSS", + "rssNoFeedUrl": "Διαμόρφωση URL ροής στις ρυθμίσεις γραφικού στοιχείου", + "rssLoadError": "Δεν ήταν δυνατή η φόρτωση της ροής δεδομένων", + "rssNoItems": "Δεν υπάρχουν στοιχεία", "noHostSelected": "Δεν έχει επιλεγεί κεντρικός υπολογιστής", "displayedMetrics": "Εμφανιζόμενες μετρήσεις", "metricCpu": "ΚΜΕ", @@ -157,6 +161,30 @@ "compactMode": "Συμπαγής λειτουργία", "selectHosts": "Επιλέξτε κεντρικούς υπολογιστές", "listLayout": "Λίστα", - "gridLayout": "Πλέγμα" + "gridLayout": "Πλέγμα", + "configureUrl": "Ορίστε μια διεύθυνση URL στις ρυθμίσεις του γραφικού στοιχείου", + "embeddedContent": "Ενσωματωμένο περιεχόμενο", + "noBookmarks": "Δεν υπάρχουν σελιδοδείκτες", + "noSections": "Δεν έχουν ρυθμιστεί τμήματα", + "noServices": "Δεν έχουν ρυθμιστεί υπηρεσίες", + "configureLocation": "Ορίστε μια τοποθεσία στις ρυθμίσεις του γραφικού στοιχείου", + "bannerTextPlaceholder": "Κείμενο banner", + "serviceNamePlaceholder": "Η υπηρεσία μου" + }, + "permissions": { + "use": { + "title": "Χρησιμοποιήστε την αρχική σελίδα", + "description": "Προβολή και επεξεργασία των συνδέσμων υπηρεσίας καμβά αρχικής σελίδας και πίνακα ελέγχου." + } + }, + "settings": { + "privateEndpoints": { + "label": "Επιτρεπόμενοι ιδιωτικοί οικοδεσπότες", + "description": "Ακριβή ιδιωτικά ή loopback ονόματα κεντρικών υπολογιστών/IP για τα γραφικά στοιχεία Ping Status και Custom API. Διαχωρίστε τις καταχωρήσεις με κόμματα ή νέες γραμμές. Παραλείψτε σχήματα, θύρες και διαδρομές. Κενά μπλοκ ιδιωτικών προορισμών." + }, + "privateCertificateAuthority": { + "label": "Ιδιωτική αρχή έκδοσης πιστοποιητικών (PEM)", + "description": "Προαιρετικό πακέτο αξιόπιστης έκδοσης πιστοποιητικών (CA) για κεντρικούς υπολογιστές που έχουν καταχωρηθεί στη λίστα επιτρεπόμενων. Η επαλήθευση πιστοποιητικών παραμένει ενεργοποιημένη. Αφήστε το κενό για να χρησιμοποιήσετε το χώρο αποθήκευσης αξιοπιστίας του συστήματος." + } } } diff --git a/plugins/homepage/locales/translated/es_ES.json b/plugins/homepage/locales/translated/es_ES.json index 6f3374ae9..27d769120 100644 --- a/plugins/homepage/locales/translated/es_ES.json +++ b/plugins/homepage/locales/translated/es_ES.json @@ -18,6 +18,7 @@ "homepage": { "title": "Inicio", "addWidget": "Añadir widget", + "noWidgetsInCategory": "No hay widgets en esta categoría.", "editWidget": "Editar widget", "zoomIn": "Acercar", "zoomOut": "Alejar", @@ -59,6 +60,9 @@ "maxItems": "Máx. de elementos", "showDescription": "Mostrar descripción", "widgetRssName": "Fuente RSS", + "rssNoFeedUrl": "Configure una URL de feed en la configuración del widget.", + "rssLoadError": "No se pudo cargar la fuente", + "rssNoItems": "No hay artículos", "noHostSelected": "Ningún host seleccionado", "displayedMetrics": "Métricas mostradas", "metricCpu": "CPU", @@ -157,6 +161,30 @@ "compactMode": "Modo compacto", "selectHosts": "Seleccionar hosts", "listLayout": "Lista", - "gridLayout": "Cuadrícula" + "gridLayout": "Cuadrícula", + "configureUrl": "Establezca una URL en la configuración del widget.", + "embeddedContent": "Contenido incrustado", + "noBookmarks": "Sin marcadores", + "noSections": "No hay secciones configuradas", + "noServices": "No hay servicios configurados", + "configureLocation": "Establezca una ubicación en la configuración del widget.", + "bannerTextPlaceholder": "Texto del banner", + "serviceNamePlaceholder": "Mi servicio" + }, + "permissions": { + "use": { + "title": "Utilice la página de inicio", + "description": "Visualiza y edita el lienzo de la página de inicio y los enlaces de servicio del panel de control." + } + }, + "settings": { + "privateEndpoints": { + "label": "Anfitriones privados permitidos", + "description": "Nombres de host/direcciones IP privadas o de bucle invertido exactas para los widgets de estado de ping y API personalizadas. Separe las entradas con comas o saltos de línea; omita esquemas, puertos y rutas. Los bloques vacíos representan destinos privados." + }, + "privateCertificateAuthority": { + "label": "Autoridad de certificación privada (PEM)", + "description": "Paquete de certificados CA de confianza opcional para los hosts permitidos. La verificación de certificados permanece habilitada. Déjelo en blanco para usar el almacén de certificados de confianza del sistema." + } } } diff --git a/plugins/homepage/locales/translated/fi_FI.json b/plugins/homepage/locales/translated/fi_FI.json index 24ae25dfd..625693f8e 100644 --- a/plugins/homepage/locales/translated/fi_FI.json +++ b/plugins/homepage/locales/translated/fi_FI.json @@ -18,6 +18,7 @@ "homepage": { "title": "Etusivu", "addWidget": "Lisää widget", + "noWidgetsInCategory": "Ei widgettejä tässä kategoriassa", "editWidget": "Muokkaa widgetiä", "zoomIn": "Lähennä", "zoomOut": "Loitonna", @@ -59,6 +60,9 @@ "maxItems": "Kohteiden enimmäismäärä", "showDescription": "Näytä kuvaus", "widgetRssName": "RSS-syöte", + "rssNoFeedUrl": "Syötteen URL-osoitteen määrittäminen widgetin asetuksissa", + "rssLoadError": "Syötettä ei voitu ladata", + "rssNoItems": "Ei kohteita", "noHostSelected": "Ei valittua isäntää", "displayedMetrics": "Näytetyt mittarit", "metricCpu": "Suoritin", @@ -157,6 +161,30 @@ "compactMode": "Kompakti tila", "selectHosts": "Valitse isännät", "listLayout": "Lista", - "gridLayout": "Ruudukko" + "gridLayout": "Ruudukko", + "configureUrl": "Aseta URL-osoite widgetin asetuksissa", + "embeddedContent": "Upotettu sisältö", + "noBookmarks": "Ei kirjanmerkkejä", + "noSections": "Ei osioita määritettynä", + "noServices": "Ei palveluita määritettynä", + "configureLocation": "Aseta sijainti widgetin asetuksissa", + "bannerTextPlaceholder": "Banneriteksti", + "serviceNamePlaceholder": "Palveluni" + }, + "permissions": { + "use": { + "title": "Käytä kotisivua", + "description": "Tarkastele ja muokkaa kotisivun kanvasta ja kojelaudan palvelulinkkejä." + } + }, + "settings": { + "privateEndpoints": { + "label": "Sallitut yksityiset isännät", + "description": "Tarkat yksityiset tai loopback-isäntänimet/IP-osoitteet Ping Status- ja Custom API -widgeteille. Erota merkinnät pilkuilla tai rivinvaihdoilla; jätä pois skeema, portit ja polut. Tyhjät lohkot yksityisiä kohteita." + }, + "privateCertificateAuthority": { + "label": "Yksityinen varmentaja (PEM)", + "description": "Valinnainen luotettujen varmenteiden paketti sallittujen isäntien luettelosta. Varmenteiden vahvistus pysyy käytössä. Jätä tyhjäksi käyttääksesi järjestelmän luotettujen varmenteiden säilöä." + } } } diff --git a/plugins/homepage/locales/translated/fr_FR.json b/plugins/homepage/locales/translated/fr_FR.json index 439517497..91fa269c6 100644 --- a/plugins/homepage/locales/translated/fr_FR.json +++ b/plugins/homepage/locales/translated/fr_FR.json @@ -18,6 +18,7 @@ "homepage": { "title": "Accueil", "addWidget": "Ajouter un widget", + "noWidgetsInCategory": "Aucun widget dans cette catégorie", "editWidget": "Modifier le widget", "zoomIn": "Zoom avant", "zoomOut": "Zoom arrière", @@ -59,6 +60,9 @@ "maxItems": "Nombre max d'éléments", "showDescription": "Afficher la description", "widgetRssName": "Flux RSS", + "rssNoFeedUrl": "Configurez l'URL du flux dans les paramètres du widget.", + "rssLoadError": "Impossible de charger le flux", + "rssNoItems": "Aucun article", "noHostSelected": "Aucun hôte sélectionné", "displayedMetrics": "Métriques affichées", "metricCpu": "CPU", @@ -81,7 +85,7 @@ "uptimeUnavailable": "Uptime non disponible", "uptimeLabel": "Uptime", "overviewVersion": "Version", - "overviewUpdateLabel": "Mise à jour", + "overviewUpdateLabel": "Mettre à jour", "overviewUpdateAvailable": "Mise à jour disponible", "overviewDatabase": "Base de données", "overviewUptime": "Uptime", @@ -157,6 +161,30 @@ "compactMode": "Mode compact", "selectHosts": "Sélectionner les hôtes", "listLayout": "Liste", - "gridLayout": "Grille" + "gridLayout": "Grille", + "configureUrl": "Définissez une URL dans les paramètres du widget", + "embeddedContent": "Contenu intégré", + "noBookmarks": "Aucun signet", + "noSections": "Aucune section n'est configurée.", + "noServices": "Aucun service configuré", + "configureLocation": "Définissez un emplacement dans les paramètres du widget", + "bannerTextPlaceholder": "Texte de la bannière", + "serviceNamePlaceholder": "Mon service" + }, + "permissions": { + "use": { + "title": "Utilisez la page d'accueil", + "description": "Afficher et modifier les liens vers le canevas de la page d'accueil et le tableau de bord." + } + }, + "settings": { + "privateEndpoints": { + "label": "Hôtes privés autorisés", + "description": "Noms d'hôtes/adresses IP privés ou de bouclage exacts pour les widgets d'état Ping et d'API personnalisée. Séparez les entrées par des virgules ou des sauts de ligne ; omettez les schémas, les ports et les chemins. Laissez des blocs vides pour les destinations privées." + }, + "privateCertificateAuthority": { + "label": "Autorité de certification privée (PEM)", + "description": "Ensemble d'autorités de certification de confiance optionnel pour les hôtes autorisés. La vérification des certificats reste activée. Laissez ce champ vide pour utiliser le magasin de certificats système." + } } } diff --git a/plugins/homepage/locales/translated/he_IL.json b/plugins/homepage/locales/translated/he_IL.json index ff26b754d..c93eaff70 100644 --- a/plugins/homepage/locales/translated/he_IL.json +++ b/plugins/homepage/locales/translated/he_IL.json @@ -18,6 +18,7 @@ "homepage": { "title": "דף הבית", "addWidget": "הוסף ווידג'ט", + "noWidgetsInCategory": "אין ווידג'טים בקטגוריה זו", "editWidget": "עריכת ווידג'ט", "zoomIn": "לְהִתְמַקֵד", "zoomOut": "התקרבות", @@ -55,10 +56,13 @@ "temperatureUnit": "יחידת טמפרטורה", "showForecast": "הצג תחזית ל-3 ימים", "scrolling": "אפשר גלילה", - "feedUrl": "כתובת אתר של הזנה", + "feedUrl": "כתובת אתר של הפיד", "maxItems": "מקסימום פריטים", "showDescription": "הצג תיאור", "widgetRssName": "עדכון RSS", + "rssNoFeedUrl": "הגדרת כתובת URL של פיד בהגדרות הווידג'ט", + "rssLoadError": "לא ניתן היה לטעון את הפיד", + "rssNoItems": "אין פריטים", "noHostSelected": "לא נבחר מארח", "displayedMetrics": "מדדים מוצגים", "metricCpu": "מעבד", @@ -157,6 +161,30 @@ "compactMode": "מצב קומפקטי", "selectHosts": "בחר מארחים", "listLayout": "רְשִׁימָה", - "gridLayout": "רֶשֶׁת" + "gridLayout": "רֶשֶׁת", + "configureUrl": "הגדר כתובת URL בהגדרות הווידג'ט", + "embeddedContent": "תוכן מוטמע", + "noBookmarks": "אין סימניות", + "noSections": "לא הוגדרו מדורים", + "noServices": "לא הוגדרו שירותים", + "configureLocation": "הגדרת מיקום בהגדרות הווידג'ט", + "bannerTextPlaceholder": "טקסט באנר", + "serviceNamePlaceholder": "השירות שלי" + }, + "permissions": { + "use": { + "title": "השתמש בדף הבית", + "description": "הצג וערוך את הקישורים של בד הציור של דף הבית ושירות לוח המחוונים." + } + }, + "settings": { + "privateEndpoints": { + "label": "מארחים פרטיים מורשים", + "description": "שמות מארחים/כתובות IP פרטיות או לולאה חוזרת מדויקות עבור סטטוס פינג ווידג'טים של API מותאם אישית. הפרד ערכים באמצעות פסיקים או שורות חדשות; השמט סכמות, יציאות ונתיבים. ריקון חסימות יעדים פרטיים." + }, + "privateCertificateAuthority": { + "label": "רשות אישורים פרטית (PEM)", + "description": "חבילת CA מהימנה אופציונלית עבור מארחים ברשימת היתרים. אימות אישורים נשאר מופעל. השאר ריק כדי להשתמש במאגר האמון של המערכת." + } } } diff --git a/plugins/homepage/locales/translated/hi_IN.json b/plugins/homepage/locales/translated/hi_IN.json index 01df2c25f..8e1e88ce8 100644 --- a/plugins/homepage/locales/translated/hi_IN.json +++ b/plugins/homepage/locales/translated/hi_IN.json @@ -18,6 +18,7 @@ "homepage": { "title": "होमपेज", "addWidget": "विजेट जोड़ें", + "noWidgetsInCategory": "No widgets in this category", "editWidget": "विजेट संपादित करें", "zoomIn": "ज़ूम इन", "zoomOut": "ज़ूम आउट", @@ -38,7 +39,7 @@ "description": "विवरण", "color": "रंग", "timezone": "समय क्षेत्र", - "invalidTimezone": "समय क्षेत्र अमान्य है। कृपया IANA नाम का उपयोग करें, जैसे कि America/New_York", + "invalidTimezone": "Invalid timezone. Use an IANA name such as America/New_York", "showSeconds": "सेकंड दिखाएँ", "format12h": "12-घंटे", "content": "सामग्री", @@ -59,6 +60,9 @@ "maxItems": "अधिकतम आइटम", "showDescription": "विवरण दिखाएं", "widgetRssName": "RSS फ़ीड", + "rssNoFeedUrl": "Configure a feed URL in widget settings", + "rssLoadError": "Could not load feed", + "rssNoItems": "No items", "noHostSelected": "कोई होस्ट चयनित नहीं", "displayedMetrics": "प्रदर्शित मेट्रिक्स", "metricCpu": "CPU", @@ -81,7 +85,7 @@ "uptimeUnavailable": "अपटाइम अनुपलब्ध", "uptimeLabel": "अपटाइम", "overviewVersion": "संस्करण", - "overviewUpdateLabel": "अद्यतन", + "overviewUpdateLabel": "अपडेट करें", "overviewUpdateAvailable": "अपडेट उपलब्ध है", "overviewDatabase": "डेटाबेस", "overviewUptime": "अपटाइम", @@ -157,6 +161,30 @@ "compactMode": "संक्षिप्त मोड", "selectHosts": "होस्ट चुनें", "listLayout": "सूची", - "gridLayout": "ग्रिड" + "gridLayout": "ग्रिड", + "configureUrl": "Set a URL in the widget settings", + "embeddedContent": "Embedded content", + "noBookmarks": "No bookmarks", + "noSections": "No sections set up", + "noServices": "No services set up", + "configureLocation": "Set a location in the widget settings", + "bannerTextPlaceholder": "Banner text", + "serviceNamePlaceholder": "My service" + }, + "permissions": { + "use": { + "title": "Use the homepage", + "description": "View and edit the homepage canvas and dashboard service links." + } + }, + "settings": { + "privateEndpoints": { + "label": "Allowed private hosts", + "description": "Exact private or loopback hostnames/IPs for Ping Status and Custom API widgets. Separate entries with commas or newlines; omit schemes, ports and paths. Empty blocks private destinations." + }, + "privateCertificateAuthority": { + "label": "Private certificate authority (PEM)", + "description": "Optional trusted CA bundle for allowlisted hosts. Certificate verification remains enabled. Leave empty to use the system trust store." + } } } diff --git a/plugins/homepage/locales/translated/hu_HU.json b/plugins/homepage/locales/translated/hu_HU.json index 7c752c224..3b4d397eb 100644 --- a/plugins/homepage/locales/translated/hu_HU.json +++ b/plugins/homepage/locales/translated/hu_HU.json @@ -18,6 +18,7 @@ "homepage": { "title": "Kezdőlap", "addWidget": "Widget hozzáadása", + "noWidgetsInCategory": "Nincsenek widgetek ebben a kategóriában", "editWidget": "Widget szerkesztése", "zoomIn": "Nagyítás", "zoomOut": "Kicsinyítés", @@ -59,6 +60,9 @@ "maxItems": "Max. tételek", "showDescription": "Leírás megjelenítése", "widgetRssName": "RSS-hírcsatorna", + "rssNoFeedUrl": "Hírcsatorna URL-címének konfigurálása a widget beállításaiban", + "rssLoadError": "Nem sikerült betölteni a hírcsatornát", + "rssNoItems": "Nincsenek elemek", "noHostSelected": "Nincs kiválasztva gazdagép", "displayedMetrics": "Megjelenített mutatók", "metricCpu": "CPU", @@ -157,6 +161,30 @@ "compactMode": "Kompakt mód", "selectHosts": "Válasszon hosztokat", "listLayout": "Lista", - "gridLayout": "Rács" + "gridLayout": "Rács", + "configureUrl": "URL-cím beállítása a widget beállításaiban", + "embeddedContent": "Beágyazott tartalom", + "noBookmarks": "Nincsenek könyvjelzők", + "noSections": "Nincsenek beállított szakaszok", + "noServices": "Nincsenek szolgáltatások beállítva", + "configureLocation": "Helyszín beállítása a widget beállításaiban", + "bannerTextPlaceholder": "Banner szöveg", + "serviceNamePlaceholder": "A szolgáltatásom" + }, + "permissions": { + "use": { + "title": "Használja a kezdőlapot", + "description": "A kezdőlap vásznának és az irányítópult szolgáltatáshivatkozásainak megtekintése és szerkesztése." + } + }, + "settings": { + "privateEndpoints": { + "label": "Engedélyezett privát tárhelyszolgáltatók", + "description": "Pontos privát vagy loopback hostnevek/IP-címek a Ping Status és az Egyéni API widgetekhez. A bejegyzéseket vesszővel vagy új sorral válassza el; hagyja ki a sémákat, portokat és elérési utakat. Üres blokkok a privát célállomások." + }, + "privateCertificateAuthority": { + "label": "Magán hitelesítésszolgáltató (PEM)", + "description": "Opcionális megbízható CA csomag az engedélyezőlistán szereplő gazdagépekhez. A tanúsítvány-ellenőrzés továbbra is engedélyezve marad. Hagyja üresen a rendszer megbízható tárolójának használatához." + } } } diff --git a/plugins/homepage/locales/translated/id_ID.json b/plugins/homepage/locales/translated/id_ID.json index 1e7abe956..760b3a445 100644 --- a/plugins/homepage/locales/translated/id_ID.json +++ b/plugins/homepage/locales/translated/id_ID.json @@ -1,162 +1,190 @@ { "nav": { - "homepage": "Beranda" + "homepage": "Homepage" }, "dashboard": { - "serviceLinks": "Tautan Layanan", - "homepagePreview": "Pratinjau Halaman Utama" + "serviceLinks": "Service Links", + "homepagePreview": "Homepage Preview" }, "dashboardTab": { - "serviceLinksTitle": "Tautan Layanan", - "serviceLinksEmpty": "Belum ada tautan layanan.", - "serviceLinksAdd": "Menambahkan", - "serviceLinksLabelPlaceholder": "Layanan Saya", + "serviceLinksTitle": "Service Links", + "serviceLinksEmpty": "No service links yet", + "serviceLinksAdd": "Add", + "serviceLinksLabelPlaceholder": "My Service", "serviceLinksUrlPlaceholder": "http://192.168.1.10:8080", - "serviceLinksInvalidUrl": "Masukkan alamat web yang valid", - "serviceLinksAddFailed": "Gagal menambahkan tautan layanan" + "serviceLinksInvalidUrl": "Enter a valid web address", + "serviceLinksAddFailed": "Failed to add service link" }, "homepage": { - "title": "Beranda", - "addWidget": "Tambahkan Widget", + "title": "Homepage", + "addWidget": "Add Widget", + "noWidgetsInCategory": "No widgets in this category", "editWidget": "Edit Widget", - "zoomIn": "Perbesar", - "zoomOut": "Perkecil tampilan", - "resetView": "Atur Ulang Tampilan", - "lockLayout": "Tata Letak Kunci", - "unlockLayout": "Buka Tata Letak", - "noWidgets": "Klik kanan atau klik + untuk menambahkan widget pertama Anda.", - "openFullView": "Buka Tampilan Penuh", - "previewTitle": "Pratinjau Halaman Utama", - "cancel": "Membatalkan", - "save": "Menyimpan", - "title_label": "Judul", - "widgetTitlePlaceholder": "Judul widget (opsional)", + "zoomIn": "Zoom In", + "zoomOut": "Zoom Out", + "resetView": "Reset View", + "lockLayout": "Lock Layout", + "unlockLayout": "Unlock Layout", + "noWidgets": "Right-click or click + to add your first widget", + "openFullView": "Open Full View", + "previewTitle": "Homepage Preview", + "cancel": "Cancel", + "save": "Save", + "title_label": "Title", + "widgetTitlePlaceholder": "Widget title (optional)", "url": "URL", - "imageUrl": "URL Gambar Kustom", - "imageUrlHint": "Biarkan kosong untuk menggunakan favicon situs secara otomatis.", - "showImage": "Tampilkan Gambar", - "description": "Keterangan", - "color": "Warna", - "timezone": "Zona waktu", - "invalidTimezone": "Zona waktu tidak valid. Gunakan nama IANA seperti America/New_York.", - "showSeconds": "Tampilkan detik", - "format12h": "12 jam", - "content": "Isi", - "backgroundColor": "Warna Latar Belakang", - "links": "Tautan", - "addLink": "Tambahkan Tautan", + "imageUrl": "Custom Image URL", + "imageUrlHint": "Leave blank to use the site favicon automatically", + "showImage": "Show Image", + "description": "Description", + "color": "Color", + "timezone": "Timezone", + "invalidTimezone": "Invalid timezone. Use an IANA name such as America/New_York", + "showSeconds": "Show seconds", + "format12h": "12-hour", + "content": "Content", + "backgroundColor": "Background Color", + "links": "Links", + "addLink": "Add Link", "linkLabel": "Label", - "categoryLinks": "Tautan", - "categoryInfo": "Informasi", - "categorySystem": "Sistem", - "copyLink": "Salin Tautan", - "linkCopied": "Tautan berhasil disalin!", - "location": "Lokasi", - "temperatureUnit": "Satuan Suhu", - "showForecast": "Tampilkan ramalan cuaca 3 hari ke depan", - "scrolling": "Izinkan Pengguliran", - "feedUrl": "URL Umpan", - "maxItems": "Jumlah Item Maksimum", - "showDescription": "Tampilkan Deskripsi", - "widgetRssName": "Umpan RSS", - "noHostSelected": "Tidak ada pembawa acara yang dipilih.", - "displayedMetrics": "Metrik yang Ditampilkan", + "categoryLinks": "Links", + "categoryInfo": "Info", + "categorySystem": "System", + "copyLink": "Copy Link", + "linkCopied": "Link copied!", + "location": "Location", + "temperatureUnit": "Temperature Unit", + "showForecast": "Show 3-day forecast", + "scrolling": "Allow Scrolling", + "feedUrl": "Feed URL", + "maxItems": "Max Items", + "showDescription": "Show Description", + "widgetRssName": "RSS Feed", + "rssNoFeedUrl": "Configure a feed URL in widget settings", + "rssLoadError": "Could not load feed", + "rssNoItems": "No items", + "noHostSelected": "No host selected", + "displayedMetrics": "Displayed Metrics", "metricCpu": "CPU", - "metricMemory": "Ingatan", + "metricMemory": "Memory", "metricDisk": "Disk", - "metricUptime": "Waktu aktif", - "metricSystem": "Sistem", - "metricNetwork": "Jaringan", - "metricProcesses": "Proses", - "categoryMonitoring": "Pemantauan", - "noPingUrls": "Tidak ada URL yang dikonfigurasi", + "metricUptime": "Uptime", + "metricSystem": "System", + "metricNetwork": "Network", + "metricProcesses": "Processes", + "categoryMonitoring": "Monitoring", + "noPingUrls": "No URLs configured", "pingLabel": "Label", - "addPingUrl": "Tambahkan URL", - "showLatency": "Tampilkan Latensi", - "refreshInterval": "Interval Penyegaran", - "seconds": "detik", - "filterActivityTypes": "Jenis Filter", - "filterTypesHint": "Biarkan kosong untuk menampilkan semua", - "showTimestamp": "Tampilkan Cap Waktu", - "uptimeUnavailable": "Waktu aktif tidak tersedia", - "uptimeLabel": "Waktu aktif", - "overviewVersion": "Versi", - "overviewUpdateLabel": "Memperbarui", - "overviewUpdateAvailable": "Pembaruan tersedia", - "overviewDatabase": "Basis data", - "overviewUptime": "Waktu aktif", - "noHosts": "Tidak ada host yang dikonfigurasi.", - "hostGridHosts": "Tuan rumah", - "hostGridAllHint": "Biarkan kosong untuk menampilkan semua host", - "columns": "Kolom", - "showIp": "Tampilkan Alamat IP", - "layout": "Tata Letak", - "showStatus": "Tampilkan Status", - "noActivity": "Tidak ada kegiatan", - "widgetPingStatusName": "Status Ping", - "widgetRecentActivityName": "Aktivitas Terkini", - "sshTerminalNoHost": "Tidak ada host yang dikonfigurasi.", - "sshTerminalConnect": "Menghubungkan", - "sshTerminalAutoConnect": "Terhubung otomatis saat dimuat", - "connectionTypes": "Jenis Koneksi", + "addPingUrl": "Add URL", + "showLatency": "Show Latency", + "refreshInterval": "Refresh Interval", + "seconds": "seconds", + "filterActivityTypes": "Filter Types", + "filterTypesHint": "Leave empty to show all", + "showTimestamp": "Show Timestamp", + "uptimeUnavailable": "Uptime unavailable", + "uptimeLabel": "Uptime", + "overviewVersion": "Version", + "overviewUpdateLabel": "Update", + "overviewUpdateAvailable": "Update available", + "overviewDatabase": "Database", + "overviewUptime": "Uptime", + "noHosts": "No hosts configured", + "hostGridHosts": "Hosts", + "hostGridAllHint": "Leave empty to show all hosts", + "columns": "Columns", + "showIp": "Show IP Address", + "layout": "Layout", + "showStatus": "Show Status", + "noActivity": "No activity", + "widgetPingStatusName": "Ping Status", + "widgetRecentActivityName": "Recent Activity", + "sshTerminalNoHost": "No host configured", + "sshTerminalConnect": "Connect", + "sshTerminalAutoConnect": "Auto-connect on load", + "connectionTypes": "Connection Types", "calMon": "Mo", "calTue": "Tu", - "calWed": "Kami", + "calWed": "We", "calThu": "Th", "calFri": "Fr", "calSat": "Sa", "calSun": "Su", - "startOnMonday": "Minggu dimulai pada hari Senin.", - "countdownNoDate": "Tidak ada tanggal target yang ditetapkan.", - "countdownPast": "Acara telah berlalu", - "countdownDays": "hari", - "countdownHours": "jam", - "countdownMinutes": "menit", - "countdownSeconds": "detik", + "startOnMonday": "Start week on Monday", + "countdownNoDate": "No target date set", + "countdownPast": "Event has passed", + "countdownDays": "days", + "countdownHours": "hrs", + "countdownMinutes": "min", + "countdownSeconds": "sec", "countdownLabel": "Label", - "countdownLabelPlaceholder": "misalnya Hari Peluncuran", - "countdownShowDays": "Hari Pertunjukan", - "countdownShowHours": "Jam Pertunjukan", - "targetDate": "Tanggal Target", - "searchEngine": "Mesin Pencari", - "customSearchUrl": "URL Pencarian Kustom", - "searchPlaceholder": "Mencari...", - "searchGo": "Pergi", - "searchPlaceholderLabel": "Teks Placeholder", - "searchPlaceholderHint": "Teks yang ditampilkan di dalam kolom pencarian", - "openInNewTab": "Buka di Tab Baru", - "searchQueryPlaceholder": "Masukkan pertanyaan...", - "noSearchShortcuts": "Tidak ada pintasan yang dikonfigurasi.", - "addSearchShortcut": "Tambahkan Pintasan", - "fontSize": "Ukuran Huruf", - "textAlign": "Perataan Teks", - "fontWeight": "Ketebalan Huruf", - "clearColor": "Warna Bening", - "imageFit": "Pencocokan Gambar", - "imageLinkUrl": "Tautan URL", - "noImage": "Tidak ada URL gambar yang ditetapkan.", - "altText": "Teks Alternatif", - "altTextPlaceholder": "Jelaskan gambar tersebut", + "countdownLabelPlaceholder": "e.g. Launch Day", + "countdownShowDays": "Show Days", + "countdownShowHours": "Show Hours", + "targetDate": "Target Date", + "searchEngine": "Search Engine", + "customSearchUrl": "Custom Search URL", + "searchPlaceholder": "Search...", + "searchGo": "Go", + "searchPlaceholderLabel": "Placeholder Text", + "searchPlaceholderHint": "Text shown inside the search input", + "openInNewTab": "Open in New Tab", + "searchQueryPlaceholder": "Enter query...", + "noSearchShortcuts": "No shortcuts configured", + "addSearchShortcut": "Add Shortcut", + "fontSize": "Font Size", + "textAlign": "Text Align", + "fontWeight": "Font Weight", + "clearColor": "Clear Color", + "imageFit": "Image Fit", + "imageLinkUrl": "Link URL", + "noImage": "No image URL set", + "altText": "Alt Text", + "altTextPlaceholder": "Describe the image", "renderMarkdown": "Render Markdown", - "displayMode": "Mode Tampilan", - "displayField": "Bidang Tampilan", - "jsonPath": "Jalur JSON", + "displayMode": "Display Mode", + "displayField": "Display Field", + "jsonPath": "JSON Path", "customApiLabel": "Label", - "customApiLabelPlaceholder": "misalnya Suhu", - "customApiUnit": "Satuan", - "customApiNoUrl": "Tidak ada URL API yang dikonfigurasi.", - "customApiError": "Gagal mengambil", - "customApiNotArray": "Respons bukanlah sebuah array.", - "addService": "Tambahkan Layanan", - "showLabels": "Tampilkan Label", - "iconSize": "Ukuran Ikon", - "noDashboardLinks": "Tidak ada tautan dasbor yang dikonfigurasi.", - "noLimit": "Tidak ada batasan", - "sectionHeading": "Judul Bagian", - "addSection": "Tambahkan Bagian", - "compactMode": "Mode Ringkas", - "selectHosts": "Pilih Host", - "listLayout": "Daftar", - "gridLayout": "Jaringan" + "customApiLabelPlaceholder": "e.g. Temperature", + "customApiUnit": "Unit", + "customApiNoUrl": "No API URL configured", + "customApiError": "Failed to fetch", + "customApiNotArray": "Response is not an array", + "addService": "Add Service", + "showLabels": "Show Labels", + "iconSize": "Icon Size", + "noDashboardLinks": "No dashboard links configured", + "noLimit": "No limit", + "sectionHeading": "Section Heading", + "addSection": "Add Section", + "compactMode": "Compact Mode", + "selectHosts": "Select Hosts", + "listLayout": "List", + "gridLayout": "Grid", + "configureUrl": "Set a URL in the widget settings", + "embeddedContent": "Embedded content", + "noBookmarks": "No bookmarks", + "noSections": "No sections set up", + "noServices": "No services set up", + "configureLocation": "Set a location in the widget settings", + "bannerTextPlaceholder": "Banner text", + "serviceNamePlaceholder": "My service" + }, + "permissions": { + "use": { + "title": "Use the homepage", + "description": "View and edit the homepage canvas and dashboard service links." + } + }, + "settings": { + "privateEndpoints": { + "label": "Allowed private hosts", + "description": "Exact private or loopback hostnames/IPs for Ping Status and Custom API widgets. Separate entries with commas or newlines; omit schemes, ports and paths. Empty blocks private destinations." + }, + "privateCertificateAuthority": { + "label": "Private certificate authority (PEM)", + "description": "Optional trusted CA bundle for allowlisted hosts. Certificate verification remains enabled. Leave empty to use the system trust store." + } } } diff --git a/plugins/homepage/locales/translated/it_IT.json b/plugins/homepage/locales/translated/it_IT.json index 9dd2df8d3..de1a95336 100644 --- a/plugins/homepage/locales/translated/it_IT.json +++ b/plugins/homepage/locales/translated/it_IT.json @@ -18,6 +18,7 @@ "homepage": { "title": "Pagina iniziale", "addWidget": "Aggiungi widget", + "noWidgetsInCategory": "Nessun widget in questa categoria", "editWidget": "Modifica widget", "zoomIn": "Ingrandisci", "zoomOut": "Rimpicciolisci", @@ -59,6 +60,9 @@ "maxItems": "Numero massimo di elementi", "showDescription": "Mostra descrizione", "widgetRssName": "Feed RSS", + "rssNoFeedUrl": "Configura l'URL del feed nelle impostazioni del widget.", + "rssLoadError": "Impossibile caricare il feed", + "rssNoItems": "Nessun articolo", "noHostSelected": "Nessun host selezionato", "displayedMetrics": "Metriche visualizzate", "metricCpu": "CPU", @@ -81,7 +85,7 @@ "uptimeUnavailable": "Uptime non disponibile", "uptimeLabel": "Uptime", "overviewVersion": "Versione", - "overviewUpdateLabel": "Aggiornamento", + "overviewUpdateLabel": "Aggiorna", "overviewUpdateAvailable": "Aggiornamento disponibile", "overviewDatabase": "Database", "overviewUptime": "Uptime", @@ -157,6 +161,30 @@ "compactMode": "Modalità compatta", "selectHosts": "Seleziona host", "listLayout": "Elenco", - "gridLayout": "Griglia" + "gridLayout": "Griglia", + "configureUrl": "Imposta un URL nelle impostazioni del widget", + "embeddedContent": "Contenuto incorporato", + "noBookmarks": "Nessun segnalibro", + "noSections": "Nessuna sezione impostata", + "noServices": "Nessun servizio configurato", + "configureLocation": "Imposta una posizione nelle impostazioni del widget", + "bannerTextPlaceholder": "Testo del banner", + "serviceNamePlaceholder": "Il mio servizio" + }, + "permissions": { + "use": { + "title": "Utilizzare la homepage", + "description": "Visualizza e modifica i collegamenti ai servizi della pagina iniziale e della dashboard." + } + }, + "settings": { + "privateEndpoints": { + "label": "Host privati autorizzati", + "description": "Nomi host/IP privati o di loopback esatti per i widget Ping Status e API personalizzate. Separare le voci con virgole o interruzioni di riga; omettere schemi, porte e percorsi. I blocchi vuoti devono essere dedicati a destinazioni private." + }, + "privateCertificateAuthority": { + "label": "Autorità di certificazione privata (PEM)", + "description": "Pacchetto CA attendibile opzionale per gli host consentiti. La verifica del certificato rimane abilitata. Lasciare vuoto per utilizzare l'archivio di certificati attendibili del sistema." + } } } diff --git a/plugins/homepage/locales/translated/ja_JP.json b/plugins/homepage/locales/translated/ja_JP.json index 7fb77fec2..a6fc864f3 100644 --- a/plugins/homepage/locales/translated/ja_JP.json +++ b/plugins/homepage/locales/translated/ja_JP.json @@ -18,6 +18,7 @@ "homepage": { "title": "ホームページ", "addWidget": "ウィジェットを追加", + "noWidgetsInCategory": "このカテゴリにはウィジェットがありません", "editWidget": "ウィジェットを編集", "zoomIn": "拡大", "zoomOut": "縮小", @@ -59,6 +60,9 @@ "maxItems": "最大アイテム数", "showDescription": "説明を表示", "widgetRssName": "RSSフィード", + "rssNoFeedUrl": "ウィジェット設定でフィードURLを設定する", + "rssLoadError": "フィードを読み込むことができませんでした", + "rssNoItems": "商品なし", "noHostSelected": "ホストが選択されていません", "displayedMetrics": "表示メトリクス", "metricCpu": "CPU", @@ -81,7 +85,7 @@ "uptimeUnavailable": "稼働時間は利用できません", "uptimeLabel": "稼働時間", "overviewVersion": "バージョン", - "overviewUpdateLabel": "アップデート", + "overviewUpdateLabel": "更新", "overviewUpdateAvailable": "アップデートあり", "overviewDatabase": "データベース", "overviewUptime": "稼働時間", @@ -157,6 +161,30 @@ "compactMode": "コンパクトモード", "selectHosts": "ホストを選択", "listLayout": "リスト", - "gridLayout": "グリッド" + "gridLayout": "グリッド", + "configureUrl": "ウィジェット設定でURLを設定してください", + "embeddedContent": "埋め込みコンテンツ", + "noBookmarks": "ブックマークなし", + "noSections": "セクションは設定されていません", + "noServices": "サービスが設定されていません", + "configureLocation": "ウィジェットの設定で場所を設定してください", + "bannerTextPlaceholder": "バナーテキスト", + "serviceNamePlaceholder": "私のサービス" + }, + "permissions": { + "use": { + "title": "ホームページを使用する", + "description": "ホームページのキャンバスとダッシュボードのサービスリンクを表示および編集します。" + } + }, + "settings": { + "privateEndpoints": { + "label": "プライベートホストを許可", + "description": "PingステータスおよびカスタムAPIウィジェットに使用する、正確なプライベートホスト名またはループバックホスト名/IPアドレス。エントリはカンマまたは改行で区切り、スキーム、ポート、パスは省略してください。空欄はプライベート宛先を示します。" + }, + "privateCertificateAuthority": { + "label": "民間認証局(PEM)", + "description": "許可リストに登録されたホスト用のオプションの信頼できる認証局(CA)バンドル。証明書の検証は引き続き有効です。システムトラストストアを使用する場合は、空欄のままにしてください。" + } } } diff --git a/plugins/homepage/locales/translated/ko_KR.json b/plugins/homepage/locales/translated/ko_KR.json index 5fb45206f..7652c9b25 100644 --- a/plugins/homepage/locales/translated/ko_KR.json +++ b/plugins/homepage/locales/translated/ko_KR.json @@ -18,6 +18,7 @@ "homepage": { "title": "홈페이지", "addWidget": "위젯 추가", + "noWidgetsInCategory": "이 카테고리에는 위젯이 없습니다.", "editWidget": "위젯 편집", "zoomIn": "확대", "zoomOut": "축소", @@ -59,6 +60,9 @@ "maxItems": "최대 항목 수", "showDescription": "설명 표시", "widgetRssName": "RSS 피드", + "rssNoFeedUrl": "위젯 설정에서 피드 URL을 구성하세요", + "rssLoadError": "피드를 로드할 수 없습니다.", + "rssNoItems": "품목 없음", "noHostSelected": "선택된 호스트 없음", "displayedMetrics": "표시된 메트릭", "metricCpu": "CPU", @@ -157,6 +161,30 @@ "compactMode": "간결 모드", "selectHosts": "호스트 선택", "listLayout": "목록", - "gridLayout": "그리드" + "gridLayout": "그리드", + "configureUrl": "위젯 설정에서 URL을 설정하세요", + "embeddedContent": "삽입된 콘텐츠", + "noBookmarks": "책갈피 없음", + "noSections": "섹션이 설정되어 있지 않습니다.", + "noServices": "설정된 서비스가 없습니다", + "configureLocation": "위젯 설정에서 위치를 지정하세요", + "bannerTextPlaceholder": "배너 텍스트", + "serviceNamePlaceholder": "내 서비스" + }, + "permissions": { + "use": { + "title": "홈페이지를 이용하세요", + "description": "홈페이지 캔버스와 대시보드 서비스 링크를 보고 편집할 수 있습니다." + } + }, + "settings": { + "privateEndpoints": { + "label": "허용된 개인 호스트", + "description": "핑 상태 및 사용자 지정 API 위젯에 사용할 정확한 개인 또는 루프백 호스트 이름/IP 주소를 입력하십시오. 항목은 쉼표 또는 줄 바꿈으로 구분하고, 스키마, 포트 및 경로는 생략하십시오. 빈 칸은 개인 대상 주소입니다." + }, + "privateCertificateAuthority": { + "label": "민간 인증 기관(PEM)", + "description": "허용 목록에 있는 호스트에 대한 선택적 신뢰 CA 번들입니다. 인증서 검증은 계속 활성화됩니다. 시스템 신뢰 저장소를 사용하려면 비워 두십시오." + } } } diff --git a/plugins/homepage/locales/translated/nl_NL.json b/plugins/homepage/locales/translated/nl_NL.json index 70b81bf58..aabf00f45 100644 --- a/plugins/homepage/locales/translated/nl_NL.json +++ b/plugins/homepage/locales/translated/nl_NL.json @@ -18,6 +18,7 @@ "homepage": { "title": "Startpagina", "addWidget": "Widget toevoegen", + "noWidgetsInCategory": "Geen widgets in deze categorie", "editWidget": "Widget bewerken", "zoomIn": "Inzoomen", "zoomOut": "Uitzoomen", @@ -59,6 +60,9 @@ "maxItems": "Max. aantal items", "showDescription": "Beschrijving weergeven", "widgetRssName": "RSS-feed", + "rssNoFeedUrl": "Configureer een feed-URL in de widgetinstellingen.", + "rssLoadError": "De feed kon niet worden geladen.", + "rssNoItems": "Geen artikelen", "noHostSelected": "Geen host geselecteerd", "displayedMetrics": "Weergegeven statistieken", "metricCpu": "CPU", @@ -157,6 +161,30 @@ "compactMode": "Compacte modus", "selectHosts": "Selecteer hosts", "listLayout": "Lijst", - "gridLayout": "Rooster" + "gridLayout": "Rooster", + "configureUrl": "Stel een URL in in de widgetinstellingen.", + "embeddedContent": "Ingesloten inhoud", + "noBookmarks": "Geen bladwijzers", + "noSections": "Geen secties ingesteld", + "noServices": "Geen services ingesteld", + "configureLocation": "Stel een locatie in in de widgetinstellingen.", + "bannerTextPlaceholder": "Bannertekst", + "serviceNamePlaceholder": "Mijn service" + }, + "permissions": { + "use": { + "title": "Gebruik de homepage", + "description": "Bekijk en bewerk de links naar de homepage-canvas en dashboardservices." + } + }, + "settings": { + "privateEndpoints": { + "label": "Toegestane particuliere hosts", + "description": "Gebruik de exacte privé- of loopback-hostnamen/IP-adressen voor de widgets Pingstatus en Aangepaste API. Scheid de gegevens met komma's of nieuwe regels; laat schema's, poorten en paden weg. Lege blokken geven privébestemmingen aan." + }, + "privateCertificateAuthority": { + "label": "Particuliere certificeringsinstantie (PEM)", + "description": "Optioneel pakket met vertrouwde CA's voor hosts op de whitelist. Certificaatverificatie blijft ingeschakeld. Laat dit veld leeg om de systeemvertrouwensarchief te gebruiken." + } } } diff --git a/plugins/homepage/locales/translated/no_NO.json b/plugins/homepage/locales/translated/no_NO.json index 87e60a5bf..f6883a6e7 100644 --- a/plugins/homepage/locales/translated/no_NO.json +++ b/plugins/homepage/locales/translated/no_NO.json @@ -1,162 +1,190 @@ { "nav": { - "homepage": "Hjemmeside" + "homepage": "Homepage" }, "dashboard": { - "serviceLinks": "Tjenestelenker", - "homepagePreview": "Forhåndsvisning av hjemmeside" + "serviceLinks": "Service Links", + "homepagePreview": "Homepage Preview" }, "dashboardTab": { - "serviceLinksTitle": "Tjenestelenker", - "serviceLinksEmpty": "Ingen tjenestelenker ennå", - "serviceLinksAdd": "Legge til", - "serviceLinksLabelPlaceholder": "Min tjeneste", + "serviceLinksTitle": "Service Links", + "serviceLinksEmpty": "No service links yet", + "serviceLinksAdd": "Legg til", + "serviceLinksLabelPlaceholder": "My Service", "serviceLinksUrlPlaceholder": "http://192.168.1.10:8080", - "serviceLinksInvalidUrl": "Skriv inn en gyldig nettadresse", - "serviceLinksAddFailed": "Kunne ikke legge til tjenestelenke" + "serviceLinksInvalidUrl": "Enter a valid web address", + "serviceLinksAddFailed": "Failed to add service link" }, "homepage": { - "title": "Hjemmeside", + "title": "Homepage", "addWidget": "Legg til widget", - "editWidget": "Rediger widget", + "noWidgetsInCategory": "No widgets in this category", + "editWidget": "Edit Widget", "zoomIn": "Zoom inn", "zoomOut": "Zoom ut", - "resetView": "Tilbakestill visning", - "lockLayout": "Låseoppsett", - "unlockLayout": "Lås opp oppsett", - "noWidgets": "Høyreklikk eller klikk på + for å legge til din første widget", - "openFullView": "Åpne fullvisning", - "previewTitle": "Forhåndsvisning av hjemmeside", - "cancel": "Kansellere", - "save": "Spare", - "title_label": "Tittel", - "widgetTitlePlaceholder": "Widgettittel (valgfritt)", - "url": "URL-adresse", - "imageUrl": "Tilpasset bilde-URL", - "imageUrlHint": "La feltet stå tomt for å bruke nettstedets favicon automatisk", - "showImage": "Vis bilde", + "resetView": "Reset View", + "lockLayout": "Lock Layout", + "unlockLayout": "Unlock Layout", + "noWidgets": "Right-click or click + to add your first widget", + "openFullView": "Open Full View", + "previewTitle": "Homepage Preview", + "cancel": "Avbryt", + "save": "Lagre", + "title_label": "Title", + "widgetTitlePlaceholder": "Widget title (optional)", + "url": "URL", + "imageUrl": "Custom Image URL", + "imageUrlHint": "Leave blank to use the site favicon automatically", + "showImage": "Show Image", "description": "Beskrivelse", - "color": "Farge", - "timezone": "Tidssone", - "invalidTimezone": "Ugyldig tidssone. Bruk et IANA-navn, for eksempel America/New_York.", - "showSeconds": "Vis sekunder", - "format12h": "12-timers", - "content": "Innhold", - "backgroundColor": "Bakgrunnsfarge", + "color": "Color", + "timezone": "Timezone", + "invalidTimezone": "Invalid timezone. Use an IANA name such as America/New_York", + "showSeconds": "Show seconds", + "format12h": "12-hour", + "content": "Content", + "backgroundColor": "Background Color", "links": "Lenker", - "addLink": "Legg til lenke", - "linkLabel": "Merkelapp", + "addLink": "Add Link", + "linkLabel": "Label", "categoryLinks": "Lenker", "categoryInfo": "Info", "categorySystem": "System", - "copyLink": "Kopier lenke", - "linkCopied": "Lenken er kopiert!", - "location": "Sted", - "temperatureUnit": "Temperaturenhet", - "showForecast": "Vis 3-dagers værmelding", - "scrolling": "Tillat rulling", - "feedUrl": "Nettadresse for feeden", - "maxItems": "Maksimalt antall varer", - "showDescription": "Vis beskrivelse", - "widgetRssName": "RSS-feed", + "copyLink": "Copy Link", + "linkCopied": "Link copied!", + "location": "Location", + "temperatureUnit": "Temperature Unit", + "showForecast": "Show 3-day forecast", + "scrolling": "Allow Scrolling", + "feedUrl": "Feed URL", + "maxItems": "Max Items", + "showDescription": "Show Description", + "widgetRssName": "RSS Feed", + "rssNoFeedUrl": "Configure a feed URL in widget settings", + "rssLoadError": "Could not load feed", + "rssNoItems": "No items", "noHostSelected": "Ingen vert valgt", - "displayedMetrics": "Viste målinger", + "displayedMetrics": "Displayed Metrics", "metricCpu": "CPU", - "metricMemory": "Hukommelse", + "metricMemory": "Minne", "metricDisk": "Disk", "metricUptime": "Oppetid", "metricSystem": "System", "metricNetwork": "Nettverk", "metricProcesses": "Prosesser", - "categoryMonitoring": "Overvåking", - "noPingUrls": "Ingen nettadresser konfigurert", - "pingLabel": "Merkelapp", - "addPingUrl": "Legg til nettadresse", - "showLatency": "Vis latens", - "refreshInterval": "Oppdateringsintervall", + "categoryMonitoring": "Monitoring", + "noPingUrls": "No URLs configured", + "pingLabel": "Label", + "addPingUrl": "Add URL", + "showLatency": "Show Latency", + "refreshInterval": "Refresh Interval", "seconds": "sekunder", - "filterActivityTypes": "Filtertyper", - "filterTypesHint": "La stå tomt for å vise alle", - "showTimestamp": "Vis tidsstempel", - "uptimeUnavailable": "Oppetid utilgjengelig", + "filterActivityTypes": "Filter Types", + "filterTypesHint": "Leave empty to show all", + "showTimestamp": "Show Timestamp", + "uptimeUnavailable": "Uptime unavailable", "uptimeLabel": "Oppetid", "overviewVersion": "Versjon", - "overviewUpdateLabel": "Oppdatering", - "overviewUpdateAvailable": "Oppdatering tilgjengelig", + "overviewUpdateLabel": "Update", + "overviewUpdateAvailable": "Update available", "overviewDatabase": "Database", "overviewUptime": "Oppetid", - "noHosts": "Ingen verter konfigurert", + "noHosts": "No hosts configured", "hostGridHosts": "Verter", - "hostGridAllHint": "La stå tomt for å vise alle verter", - "columns": "Kolonner", - "showIp": "Vis IP-adresse", - "layout": "Oppsett", - "showStatus": "Vis status", - "noActivity": "Ingen aktivitet", - "widgetPingStatusName": "Ping-status", + "hostGridAllHint": "Leave empty to show all hosts", + "columns": "Columns", + "showIp": "Show IP Address", + "layout": "Layout", + "showStatus": "Show Status", + "noActivity": "No activity", + "widgetPingStatusName": "Ping Status", "widgetRecentActivityName": "Nylig aktivitet", - "sshTerminalNoHost": "Ingen vert konfigurert", + "sshTerminalNoHost": "No host configured", "sshTerminalConnect": "Koble til", - "sshTerminalAutoConnect": "Automatisk tilkobling ved lasting", - "connectionTypes": "Tilkoblingstyper", + "sshTerminalAutoConnect": "Auto-connect on load", + "connectionTypes": "Connection Types", "calMon": "Mo", - "calTue": "Ti", - "calWed": "Vi", - "calThu": "To", + "calTue": "Tu", + "calWed": "We", + "calThu": "Th", "calFri": "Fr", - "calSat": "Lø", - "calSun": "Søn", - "startOnMonday": "Start uken på mandag", - "countdownNoDate": "Ingen måldato angitt", - "countdownPast": "Arrangementet har gått", - "countdownDays": "dager", - "countdownHours": "timer", + "calSat": "Sa", + "calSun": "Su", + "startOnMonday": "Start week on Monday", + "countdownNoDate": "No target date set", + "countdownPast": "Event has passed", + "countdownDays": "days", + "countdownHours": "hrs", "countdownMinutes": "min", - "countdownSeconds": "sek", - "countdownLabel": "Merkelapp", - "countdownLabelPlaceholder": "f.eks. lanseringsdag", - "countdownShowDays": "Vis dager", - "countdownShowHours": "Åpningstider", - "targetDate": "Måldato", - "searchEngine": "Søkemotor", - "customSearchUrl": "Tilpasset søke-URL", - "searchPlaceholder": "Søk...", - "searchGo": "Gå", - "searchPlaceholderLabel": "Plassholdertekst", - "searchPlaceholderHint": "Tekst vist i søkefeltet", - "openInNewTab": "Åpne i ny fane", - "searchQueryPlaceholder": "Skriv inn spørring...", - "noSearchShortcuts": "Ingen snarveier konfigurert", - "addSearchShortcut": "Legg til snarvei", + "countdownSeconds": "sec", + "countdownLabel": "Label", + "countdownLabelPlaceholder": "e.g. Launch Day", + "countdownShowDays": "Show Days", + "countdownShowHours": "Show Hours", + "targetDate": "Target Date", + "searchEngine": "Search Engine", + "customSearchUrl": "Custom Search URL", + "searchPlaceholder": "Search...", + "searchGo": "Go", + "searchPlaceholderLabel": "Placeholder Text", + "searchPlaceholderHint": "Text shown inside the search input", + "openInNewTab": "Open in New Tab", + "searchQueryPlaceholder": "Enter query...", + "noSearchShortcuts": "No shortcuts configured", + "addSearchShortcut": "Add Shortcut", "fontSize": "Skriftstørrelse", - "textAlign": "Tekstjustering", - "fontWeight": "Skriftvekt", - "clearColor": "Klar farge", - "imageFit": "Bildetilpasning", - "imageLinkUrl": "Lenke-URL", - "noImage": "Ingen bilde-URL angitt", - "altText": "Alternativ tekst", - "altTextPlaceholder": "Beskriv bildet", - "renderMarkdown": "Gjengivelsesmarkering", - "displayMode": "Visningsmodus", - "displayField": "Visningsfelt", - "jsonPath": "JSON-sti", - "customApiLabel": "Merkelapp", - "customApiLabelPlaceholder": "f.eks. Temperatur", - "customApiUnit": "Enhet", - "customApiNoUrl": "Ingen API-URL konfigurert", - "customApiError": "Kunne ikke hente", - "customApiNotArray": "Responsen er ikke en matrise", - "addService": "Legg til tjeneste", - "showLabels": "Vis etiketter", - "iconSize": "Ikonstørrelse", - "noDashboardLinks": "Ingen dashbordlenker konfigurert", - "noLimit": "Ingen grense", - "sectionHeading": "Seksjonsoverskrift", - "addSection": "Legg til seksjon", - "compactMode": "Kompakt modus", - "selectHosts": "Velg verter", + "textAlign": "Text Align", + "fontWeight": "Font Weight", + "clearColor": "Clear Color", + "imageFit": "Image Fit", + "imageLinkUrl": "Link URL", + "noImage": "No image URL set", + "altText": "Alt Text", + "altTextPlaceholder": "Describe the image", + "renderMarkdown": "Render Markdown", + "displayMode": "Display Mode", + "displayField": "Display Field", + "jsonPath": "JSON Path", + "customApiLabel": "Label", + "customApiLabelPlaceholder": "e.g. Temperature", + "customApiUnit": "Unit", + "customApiNoUrl": "No API URL configured", + "customApiError": "Failed to fetch", + "customApiNotArray": "Response is not an array", + "addService": "Add Service", + "showLabels": "Show Labels", + "iconSize": "Icon Size", + "noDashboardLinks": "No dashboard links configured", + "noLimit": "No limit", + "sectionHeading": "Section Heading", + "addSection": "Add Section", + "compactMode": "Compact Mode", + "selectHosts": "Select Hosts", "listLayout": "Liste", - "gridLayout": "Rutenett" + "gridLayout": "Grid", + "configureUrl": "Set a URL in the widget settings", + "embeddedContent": "Embedded content", + "noBookmarks": "No bookmarks", + "noSections": "No sections set up", + "noServices": "No services set up", + "configureLocation": "Set a location in the widget settings", + "bannerTextPlaceholder": "Banner text", + "serviceNamePlaceholder": "My service" + }, + "permissions": { + "use": { + "title": "Use the homepage", + "description": "View and edit the homepage canvas and dashboard service links." + } + }, + "settings": { + "privateEndpoints": { + "label": "Allowed private hosts", + "description": "Exact private or loopback hostnames/IPs for Ping Status and Custom API widgets. Separate entries with commas or newlines; omit schemes, ports and paths. Empty blocks private destinations." + }, + "privateCertificateAuthority": { + "label": "Private certificate authority (PEM)", + "description": "Optional trusted CA bundle for allowlisted hosts. Certificate verification remains enabled. Leave empty to use the system trust store." + } } } diff --git a/plugins/homepage/locales/translated/pl_PL.json b/plugins/homepage/locales/translated/pl_PL.json index 6e8babdc5..df69b4d43 100644 --- a/plugins/homepage/locales/translated/pl_PL.json +++ b/plugins/homepage/locales/translated/pl_PL.json @@ -18,6 +18,7 @@ "homepage": { "title": "Strona główna", "addWidget": "Dodaj widżet", + "noWidgetsInCategory": "No widgets in this category", "editWidget": "Edytuj widżet", "zoomIn": "Powiększ", "zoomOut": "Oddal", @@ -38,7 +39,7 @@ "description": "Opis", "color": "Kolor", "timezone": "Strefa czasowa", - "invalidTimezone": "Nieprawidłowa strefa czasowa. Użyj nazwy IANA, takiej jak America/New_York", + "invalidTimezone": "Invalid timezone. Use an IANA name such as America/New_York", "showSeconds": "Pokaż sekundy", "format12h": "12-godzinny", "content": "Treść", @@ -59,6 +60,9 @@ "maxItems": "Maksymalna liczba elementów", "showDescription": "Pokaż opis", "widgetRssName": "Kanał RSS", + "rssNoFeedUrl": "Configure a feed URL in widget settings", + "rssLoadError": "Could not load feed", + "rssNoItems": "No items", "noHostSelected": "Nie wybrano hosta", "displayedMetrics": "Wyświetlane metryki", "metricCpu": "Procesor", @@ -157,6 +161,30 @@ "compactMode": "Tryb kompaktowy", "selectHosts": "Wybierz hosty", "listLayout": "Lista", - "gridLayout": "Siatka" + "gridLayout": "Siatka", + "configureUrl": "Set a URL in the widget settings", + "embeddedContent": "Embedded content", + "noBookmarks": "No bookmarks", + "noSections": "No sections set up", + "noServices": "No services set up", + "configureLocation": "Set a location in the widget settings", + "bannerTextPlaceholder": "Banner text", + "serviceNamePlaceholder": "My service" + }, + "permissions": { + "use": { + "title": "Use the homepage", + "description": "View and edit the homepage canvas and dashboard service links." + } + }, + "settings": { + "privateEndpoints": { + "label": "Allowed private hosts", + "description": "Exact private or loopback hostnames/IPs for Ping Status and Custom API widgets. Separate entries with commas or newlines; omit schemes, ports and paths. Empty blocks private destinations." + }, + "privateCertificateAuthority": { + "label": "Private certificate authority (PEM)", + "description": "Optional trusted CA bundle for allowlisted hosts. Certificate verification remains enabled. Leave empty to use the system trust store." + } } } diff --git a/plugins/homepage/locales/translated/pt_BR.json b/plugins/homepage/locales/translated/pt_BR.json index 33c8eba0d..5ec42844c 100644 --- a/plugins/homepage/locales/translated/pt_BR.json +++ b/plugins/homepage/locales/translated/pt_BR.json @@ -1,162 +1,190 @@ { "nav": { - "homepage": "Página inicial" + "homepage": "Homepage" }, "dashboard": { - "serviceLinks": "Links de serviço", - "homepagePreview": "Pré-visualização da página inicial" + "serviceLinks": "Service Links", + "homepagePreview": "Homepage Preview" }, "dashboardTab": { - "serviceLinksTitle": "Links de serviço", - "serviceLinksEmpty": "Ainda não há links de serviço.", + "serviceLinksTitle": "Service Links", + "serviceLinksEmpty": "No service links yet", "serviceLinksAdd": "Adicionar", - "serviceLinksLabelPlaceholder": "Meu Serviço", + "serviceLinksLabelPlaceholder": "My Service", "serviceLinksUrlPlaceholder": "http://192.168.1.10:8080", - "serviceLinksInvalidUrl": "Insira um endereço web válido.", - "serviceLinksAddFailed": "Falha ao adicionar o link de serviço" + "serviceLinksInvalidUrl": "Enter a valid web address", + "serviceLinksAddFailed": "Failed to add service link" }, "homepage": { - "title": "Página inicial", - "addWidget": "Adicionar widget", - "editWidget": "Widget de edição", - "zoomIn": "Ampliar", - "zoomOut": "Diminuir o zoom", - "resetView": "Redefinir visualização", - "lockLayout": "Configuração de fechadura", - "unlockLayout": "Desbloquear layout", - "noWidgets": "Clique com o botão direito do mouse ou clique em + para adicionar seu primeiro widget.", - "openFullView": "Abrir visualização completa", - "previewTitle": "Pré-visualização da página inicial", + "title": "Homepage", + "addWidget": "Add Widget", + "noWidgetsInCategory": "No widgets in this category", + "editWidget": "Edit Widget", + "zoomIn": "Zoom In", + "zoomOut": "Zoom Out", + "resetView": "Reset View", + "lockLayout": "Lock Layout", + "unlockLayout": "Unlock Layout", + "noWidgets": "Right-click or click + to add your first widget", + "openFullView": "Open Full View", + "previewTitle": "Homepage Preview", "cancel": "Cancelar", "save": "Salvar", - "title_label": "Título", - "widgetTitlePlaceholder": "Título do widget (opcional)", + "title_label": "Title", + "widgetTitlePlaceholder": "Widget title (optional)", "url": "URL", - "imageUrl": "URL da imagem personalizada", - "imageUrlHint": "Deixe em branco para usar o favicon do site automaticamente.", - "showImage": "Mostrar imagem", - "description": "Descrição", - "color": "Cor", - "timezone": "Fuso horário", - "invalidTimezone": "Fuso horário inválido. Use um nome IANA, como America/New_York.", - "showSeconds": "Mostrar segundos", - "format12h": "12 horas", - "content": "Contente", - "backgroundColor": "Cor de fundo", + "imageUrl": "Custom Image URL", + "imageUrlHint": "Leave blank to use the site favicon automatically", + "showImage": "Show Image", + "description": "Description", + "color": "Color", + "timezone": "Timezone", + "invalidTimezone": "Invalid timezone. Use an IANA name such as America/New_York", + "showSeconds": "Show seconds", + "format12h": "12-hour", + "content": "Content", + "backgroundColor": "Background Color", "links": "Links", - "addLink": "Adicionar link", - "linkLabel": "Rótulo", + "addLink": "Add Link", + "linkLabel": "Label", "categoryLinks": "Links", - "categoryInfo": "Informações", - "categorySystem": "Sistema", - "copyLink": "Copiar link", - "linkCopied": "Link copiado!", - "location": "Localização", - "temperatureUnit": "Unidade de temperatura", - "showForecast": "Mostrar previsão para 3 dias", - "scrolling": "Permitir rolagem", - "feedUrl": "URL do feed", - "maxItems": "Número máximo de itens", - "showDescription": "Descrição do programa", - "widgetRssName": "Feed RSS", - "noHostSelected": "Nenhum host selecionado", - "displayedMetrics": "Métricas exibidas", + "categoryInfo": "Info", + "categorySystem": "System", + "copyLink": "Copy Link", + "linkCopied": "Link copied!", + "location": "Location", + "temperatureUnit": "Temperature Unit", + "showForecast": "Show 3-day forecast", + "scrolling": "Allow Scrolling", + "feedUrl": "Feed URL", + "maxItems": "Max Items", + "showDescription": "Show Description", + "widgetRssName": "RSS Feed", + "rssNoFeedUrl": "Configure a feed URL in widget settings", + "rssLoadError": "Could not load feed", + "rssNoItems": "No items", + "noHostSelected": "No host selected", + "displayedMetrics": "Displayed Metrics", "metricCpu": "CPU", - "metricMemory": "Memória", - "metricDisk": "Disco", - "metricUptime": "Tempo de atividade", - "metricSystem": "Sistema", - "metricNetwork": "Rede", - "metricProcesses": "Processos", - "categoryMonitoring": "Monitoramento", - "noPingUrls": "Nenhuma URL configurada", - "pingLabel": "Rótulo", - "addPingUrl": "Adicionar URL", - "showLatency": "Mostrar latência", - "refreshInterval": "Intervalo de atualização", - "seconds": "segundos", - "filterActivityTypes": "Tipos de filtro", - "filterTypesHint": "Deixe em branco para mostrar tudo", - "showTimestamp": "Mostrar carimbo de data/hora", - "uptimeUnavailable": "Tempo de atividade indisponível", - "uptimeLabel": "Tempo de atividade", - "overviewVersion": "Versão", + "metricMemory": "Memory", + "metricDisk": "Disk", + "metricUptime": "Uptime", + "metricSystem": "System", + "metricNetwork": "Network", + "metricProcesses": "Processes", + "categoryMonitoring": "Monitoring", + "noPingUrls": "No URLs configured", + "pingLabel": "Label", + "addPingUrl": "Add URL", + "showLatency": "Show Latency", + "refreshInterval": "Refresh Interval", + "seconds": "seconds", + "filterActivityTypes": "Filter Types", + "filterTypesHint": "Leave empty to show all", + "showTimestamp": "Show Timestamp", + "uptimeUnavailable": "Uptime unavailable", + "uptimeLabel": "Uptime", + "overviewVersion": "Version", "overviewUpdateLabel": "Atualizar", - "overviewUpdateAvailable": "Atualização disponível", - "overviewDatabase": "Banco de dados", - "overviewUptime": "Tempo de atividade", - "noHosts": "Nenhum host configurado", - "hostGridHosts": "Anfitriões", - "hostGridAllHint": "Deixe em branco para mostrar todos os hosts.", - "columns": "Colunas", - "showIp": "Mostrar endereço IP", + "overviewUpdateAvailable": "Update available", + "overviewDatabase": "Database", + "overviewUptime": "Uptime", + "noHosts": "No hosts configured", + "hostGridHosts": "Hosts", + "hostGridAllHint": "Leave empty to show all hosts", + "columns": "Columns", + "showIp": "Show IP Address", "layout": "Layout", - "showStatus": "Mostrar status", - "noActivity": "Nenhuma atividade", - "widgetPingStatusName": "Status do ping", - "widgetRecentActivityName": "Atividade recente", - "sshTerminalNoHost": "Nenhum host configurado", + "showStatus": "Show Status", + "noActivity": "No activity", + "widgetPingStatusName": "Ping Status", + "widgetRecentActivityName": "Recent Activity", + "sshTerminalNoHost": "No host configured", "sshTerminalConnect": "Conectar", - "sshTerminalAutoConnect": "Conexão automática sob carga", - "connectionTypes": "Tipos de conexão", + "sshTerminalAutoConnect": "Auto-connect on load", + "connectionTypes": "Connection Types", "calMon": "Mo", "calTue": "Tu", - "calWed": "Nós", - "calThu": "O", - "calFri": "Padre", + "calWed": "We", + "calThu": "Th", + "calFri": "Fr", "calSat": "Sa", "calSun": "Su", - "startOnMonday": "Comece a semana na segunda-feira", - "countdownNoDate": "Nenhuma data-alvo definida.", - "countdownPast": "O evento já aconteceu.", - "countdownDays": "dias", - "countdownHours": "horas", + "startOnMonday": "Start week on Monday", + "countdownNoDate": "No target date set", + "countdownPast": "Event has passed", + "countdownDays": "days", + "countdownHours": "hrs", "countdownMinutes": "min", - "countdownSeconds": "seg", - "countdownLabel": "Rótulo", - "countdownLabelPlaceholder": "Exemplo: Dia do Lançamento", - "countdownShowDays": "Dias de exibição", - "countdownShowHours": "Horário de funcionamento", - "targetDate": "Data-alvo", - "searchEngine": "Mecanismo de busca", - "customSearchUrl": "URL de pesquisa personalizada", - "searchPlaceholder": "Procurar...", - "searchGo": "Ir", - "searchPlaceholderLabel": "Texto de espaço reservado", - "searchPlaceholderHint": "Texto exibido dentro do campo de pesquisa", - "openInNewTab": "Abrir em nova aba", - "searchQueryPlaceholder": "Digite a consulta...", - "noSearchShortcuts": "Nenhum atalho configurado", - "addSearchShortcut": "Adicionar atalho", - "fontSize": "Tamanho da fonte", - "textAlign": "Alinhamento de texto", - "fontWeight": "Peso da fonte", - "clearColor": "Cor transparente", - "imageFit": "Ajuste de imagem", - "imageLinkUrl": "URL do link", - "noImage": "Nenhuma URL de imagem definida.", - "altText": "Texto alternativo", - "altTextPlaceholder": "Descreva a imagem", - "renderMarkdown": "Renderizar Markdown", - "displayMode": "Modo de exibição", - "displayField": "Campo de exibição", - "jsonPath": "Caminho JSON", - "customApiLabel": "Rótulo", - "customApiLabelPlaceholder": "Exemplo: Temperatura", - "customApiUnit": "Unidade", - "customApiNoUrl": "Nenhuma URL de API configurada", - "customApiError": "Falha ao buscar", - "customApiNotArray": "A resposta não é uma matriz.", - "addService": "Adicionar serviço", - "showLabels": "Mostrar rótulos", - "iconSize": "Tamanho do ícone", - "noDashboardLinks": "Nenhum link para o painel de controle configurado", - "noLimit": "Sem limite", - "sectionHeading": "Título da seção", - "addSection": "Adicionar seção", - "compactMode": "Modo compacto", - "selectHosts": "Selecionar anfitriões", - "listLayout": "Lista", - "gridLayout": "Grade" + "countdownSeconds": "sec", + "countdownLabel": "Label", + "countdownLabelPlaceholder": "e.g. Launch Day", + "countdownShowDays": "Show Days", + "countdownShowHours": "Show Hours", + "targetDate": "Target Date", + "searchEngine": "Search Engine", + "customSearchUrl": "Custom Search URL", + "searchPlaceholder": "Search...", + "searchGo": "Go", + "searchPlaceholderLabel": "Placeholder Text", + "searchPlaceholderHint": "Text shown inside the search input", + "openInNewTab": "Abrir em Nova Aba", + "searchQueryPlaceholder": "Enter query...", + "noSearchShortcuts": "No shortcuts configured", + "addSearchShortcut": "Add Shortcut", + "fontSize": "Tamanho da Fonte", + "textAlign": "Text Align", + "fontWeight": "Font Weight", + "clearColor": "Clear Color", + "imageFit": "Image Fit", + "imageLinkUrl": "Link URL", + "noImage": "No image URL set", + "altText": "Alt Text", + "altTextPlaceholder": "Describe the image", + "renderMarkdown": "Render Markdown", + "displayMode": "Display Mode", + "displayField": "Display Field", + "jsonPath": "JSON Path", + "customApiLabel": "Label", + "customApiLabelPlaceholder": "e.g. Temperature", + "customApiUnit": "Unit", + "customApiNoUrl": "No API URL configured", + "customApiError": "Failed to fetch", + "customApiNotArray": "Response is not an array", + "addService": "Add Service", + "showLabels": "Show Labels", + "iconSize": "Icon Size", + "noDashboardLinks": "No dashboard links configured", + "noLimit": "No limit", + "sectionHeading": "Section Heading", + "addSection": "Add Section", + "compactMode": "Compact Mode", + "selectHosts": "Select Hosts", + "listLayout": "List", + "gridLayout": "Grid", + "configureUrl": "Set a URL in the widget settings", + "embeddedContent": "Embedded content", + "noBookmarks": "No bookmarks", + "noSections": "No sections set up", + "noServices": "No services set up", + "configureLocation": "Set a location in the widget settings", + "bannerTextPlaceholder": "Banner text", + "serviceNamePlaceholder": "My service" + }, + "permissions": { + "use": { + "title": "Use the homepage", + "description": "View and edit the homepage canvas and dashboard service links." + } + }, + "settings": { + "privateEndpoints": { + "label": "Allowed private hosts", + "description": "Exact private or loopback hostnames/IPs for Ping Status and Custom API widgets. Separate entries with commas or newlines; omit schemes, ports and paths. Empty blocks private destinations." + }, + "privateCertificateAuthority": { + "label": "Private certificate authority (PEM)", + "description": "Optional trusted CA bundle for allowlisted hosts. Certificate verification remains enabled. Leave empty to use the system trust store." + } } } diff --git a/plugins/homepage/locales/translated/pt_PT.json b/plugins/homepage/locales/translated/pt_PT.json index 66504ced0..effbb6df2 100644 --- a/plugins/homepage/locales/translated/pt_PT.json +++ b/plugins/homepage/locales/translated/pt_PT.json @@ -18,6 +18,7 @@ "homepage": { "title": "Página Inicial", "addWidget": "Adicionar widget", + "noWidgetsInCategory": "No widgets in this category", "editWidget": "Editar widget", "zoomIn": "Ampliar", "zoomOut": "Reduzir", @@ -38,7 +39,7 @@ "description": "Descrição", "color": "Cor", "timezone": "Fuso Horário", - "invalidTimezone": "Fuso horário inválido. Utilize um nome IANA, como America/New_York.", + "invalidTimezone": "Invalid timezone. Use an IANA name such as America/New_York", "showSeconds": "Mostrar segundos", "format12h": "12 horas", "content": "Conteúdo", @@ -59,6 +60,9 @@ "maxItems": "Itens máx.", "showDescription": "Mostrar descrição", "widgetRssName": "Feed RSS", + "rssNoFeedUrl": "Configure a feed URL in widget settings", + "rssLoadError": "Could not load feed", + "rssNoItems": "No items", "noHostSelected": "Nenhum anfitrião selecionado", "displayedMetrics": "Métricas Exibidas", "metricCpu": "CPU", @@ -81,7 +85,7 @@ "uptimeUnavailable": "Tempo de atividade indisponível", "uptimeLabel": "Tempo de atividade", "overviewVersion": "Versão", - "overviewUpdateLabel": "Atualização", + "overviewUpdateLabel": "Atualizar", "overviewUpdateAvailable": "Atualização disponível", "overviewDatabase": "Base de dados", "overviewUptime": "Tempo de atividade", @@ -157,6 +161,30 @@ "compactMode": "Modo Compacto", "selectHosts": "Selecionar Hosts", "listLayout": "Lista", - "gridLayout": "Grelha" + "gridLayout": "Grelha", + "configureUrl": "Set a URL in the widget settings", + "embeddedContent": "Embedded content", + "noBookmarks": "No bookmarks", + "noSections": "No sections set up", + "noServices": "No services set up", + "configureLocation": "Set a location in the widget settings", + "bannerTextPlaceholder": "Banner text", + "serviceNamePlaceholder": "My service" + }, + "permissions": { + "use": { + "title": "Use the homepage", + "description": "View and edit the homepage canvas and dashboard service links." + } + }, + "settings": { + "privateEndpoints": { + "label": "Allowed private hosts", + "description": "Exact private or loopback hostnames/IPs for Ping Status and Custom API widgets. Separate entries with commas or newlines; omit schemes, ports and paths. Empty blocks private destinations." + }, + "privateCertificateAuthority": { + "label": "Private certificate authority (PEM)", + "description": "Optional trusted CA bundle for allowlisted hosts. Certificate verification remains enabled. Leave empty to use the system trust store." + } } } diff --git a/plugins/homepage/locales/translated/ro_RO.json b/plugins/homepage/locales/translated/ro_RO.json index 610a7e5cc..8270c7bb9 100644 --- a/plugins/homepage/locales/translated/ro_RO.json +++ b/plugins/homepage/locales/translated/ro_RO.json @@ -18,6 +18,7 @@ "homepage": { "title": "Pagina principală", "addWidget": "Adăugați widget", + "noWidgetsInCategory": "Niciun widget în această categorie", "editWidget": "Editare widget", "zoomIn": "Mărire", "zoomOut": "Micșorare", @@ -59,6 +60,9 @@ "maxItems": "Articole maxime", "showDescription": "Afișați descrierea", "widgetRssName": "Flux RSS", + "rssNoFeedUrl": "Configurați o adresă URL de flux în setările widgetului", + "rssLoadError": "Nu s-a putut încărca feedul", + "rssNoItems": "Niciun articol", "noHostSelected": "Nicio gazdă selectată", "displayedMetrics": "Metrici afișate", "metricCpu": "CPU", @@ -78,7 +82,7 @@ "filterActivityTypes": "Tipuri de filtre", "filterTypesHint": "Lăsați gol pentru a afișa toate", "showTimestamp": "Afișați marcajul temporal", - "uptimeUnavailable": "Disponibilitate indisponibilă", + "uptimeUnavailable": "Timp de funcționare indisponibil", "uptimeLabel": "Timp de funcționare", "overviewVersion": "Versiune", "overviewUpdateLabel": "Actualizare", @@ -157,6 +161,30 @@ "compactMode": "Mod compact", "selectHosts": "Selectați gazdele", "listLayout": "Listă", - "gridLayout": "Grilă" + "gridLayout": "Grilă", + "configureUrl": "Setați o adresă URL în setările widgetului", + "embeddedContent": "Conținut încorporat", + "noBookmarks": "Fără marcaje", + "noSections": "Nicio secțiune configurată", + "noServices": "Niciun serviciu configurat", + "configureLocation": "Setați o locație în setările widgetului", + "bannerTextPlaceholder": "Textul bannerului", + "serviceNamePlaceholder": "Serviciul meu" + }, + "permissions": { + "use": { + "title": "Folosește pagina principală", + "description": "Vizualizați și editați linkurile către serviciul canvas și tabloul de bord al paginii principale." + } + }, + "settings": { + "privateEndpoints": { + "label": "Gazde private permise", + "description": "Nume de gazdă/IP-uri private sau loopback exacte pentru widget-urile Ping Status și Custom API. Separați intrările cu virgule sau linii noi; omiteți schemele, porturile și căile. Spațiile goale blochează destinațiile private." + }, + "privateCertificateAuthority": { + "label": "Autoritate de certificare privată (PEM)", + "description": "Pachet CA opțional de încredere pentru gazdele din lista permisă. Verificarea certificatelor rămâne activată. Lăsați câmpul gol pentru a utiliza depozitul de încredere al sistemului." + } } } diff --git a/plugins/homepage/locales/translated/ru_RU.json b/plugins/homepage/locales/translated/ru_RU.json index 07c086dd3..b1f1c03b8 100644 --- a/plugins/homepage/locales/translated/ru_RU.json +++ b/plugins/homepage/locales/translated/ru_RU.json @@ -18,6 +18,7 @@ "homepage": { "title": "Главная страница", "addWidget": "Добавить виджет", + "noWidgetsInCategory": "No widgets in this category", "editWidget": "Изменить виджет", "zoomIn": "Приблизить", "zoomOut": "Отдалить", @@ -38,7 +39,7 @@ "description": "Описание", "color": "Цвет", "timezone": "Часовой пояс", - "invalidTimezone": "Неверный часовой пояс. Используйте название IANA, например, America/New_York.", + "invalidTimezone": "Invalid timezone. Use an IANA name such as America/New_York", "showSeconds": "Показывать секунды", "format12h": "12-часовой", "content": "Содержимое", @@ -59,6 +60,9 @@ "maxItems": "Макс. элементов", "showDescription": "Показывать описание", "widgetRssName": "RSS-лента", + "rssNoFeedUrl": "Configure a feed URL in widget settings", + "rssLoadError": "Could not load feed", + "rssNoItems": "No items", "noHostSelected": "Хост не выбран", "displayedMetrics": "Отображаемые метрики", "metricCpu": "ЦП", @@ -81,7 +85,7 @@ "uptimeUnavailable": "Время работы недоступно", "uptimeLabel": "Время работы", "overviewVersion": "Версия", - "overviewUpdateLabel": "Обновлять", + "overviewUpdateLabel": "Обновить", "overviewUpdateAvailable": "Доступно обновление", "overviewDatabase": "База данных", "overviewUptime": "Время работы", @@ -157,6 +161,30 @@ "compactMode": "Компактный режим", "selectHosts": "Выбрать хосты", "listLayout": "Список", - "gridLayout": "Сетка" + "gridLayout": "Сетка", + "configureUrl": "Set a URL in the widget settings", + "embeddedContent": "Embedded content", + "noBookmarks": "No bookmarks", + "noSections": "No sections set up", + "noServices": "No services set up", + "configureLocation": "Set a location in the widget settings", + "bannerTextPlaceholder": "Banner text", + "serviceNamePlaceholder": "My service" + }, + "permissions": { + "use": { + "title": "Use the homepage", + "description": "View and edit the homepage canvas and dashboard service links." + } + }, + "settings": { + "privateEndpoints": { + "label": "Allowed private hosts", + "description": "Exact private or loopback hostnames/IPs for Ping Status and Custom API widgets. Separate entries with commas or newlines; omit schemes, ports and paths. Empty blocks private destinations." + }, + "privateCertificateAuthority": { + "label": "Private certificate authority (PEM)", + "description": "Optional trusted CA bundle for allowlisted hosts. Certificate verification remains enabled. Leave empty to use the system trust store." + } } } diff --git a/plugins/homepage/locales/translated/sr_SP.json b/plugins/homepage/locales/translated/sr_SP.json index 80d62fc96..760b3a445 100644 --- a/plugins/homepage/locales/translated/sr_SP.json +++ b/plugins/homepage/locales/translated/sr_SP.json @@ -1,162 +1,190 @@ { "nav": { - "homepage": "Почетна страница" + "homepage": "Homepage" }, "dashboard": { - "serviceLinks": "Линкови услуга", - "homepagePreview": "Преглед почетне странице" + "serviceLinks": "Service Links", + "homepagePreview": "Homepage Preview" }, "dashboardTab": { - "serviceLinksTitle": "Линкови услуга", - "serviceLinksEmpty": "Још нема линкова за услуге", - "serviceLinksAdd": "Додај", - "serviceLinksLabelPlaceholder": "Моја услуга", - "serviceLinksUrlPlaceholder": "хттп://192.168.1.10:8080", - "serviceLinksInvalidUrl": "Унесите важећу веб адресу", - "serviceLinksAddFailed": "Додавање линка услуге није успело" + "serviceLinksTitle": "Service Links", + "serviceLinksEmpty": "No service links yet", + "serviceLinksAdd": "Add", + "serviceLinksLabelPlaceholder": "My Service", + "serviceLinksUrlPlaceholder": "http://192.168.1.10:8080", + "serviceLinksInvalidUrl": "Enter a valid web address", + "serviceLinksAddFailed": "Failed to add service link" }, "homepage": { - "title": "Почетна страница", - "addWidget": "Додај виџет", - "editWidget": "Измени виџет", - "zoomIn": "Увећај", - "zoomOut": "Умањи", - "resetView": "Ресетуј приказ", - "lockLayout": "Закључај распоред", - "unlockLayout": "Откључај распоред", - "noWidgets": "Кликните десним тастером миша или кликните на + да бисте додали свој први виџет", - "openFullView": "Отвори цео приказ", - "previewTitle": "Преглед почетне странице", - "cancel": "Откажи", - "save": "Сачувај", - "title_label": "Наслов", - "widgetTitlePlaceholder": "Наслов виџета (опционо)", + "title": "Homepage", + "addWidget": "Add Widget", + "noWidgetsInCategory": "No widgets in this category", + "editWidget": "Edit Widget", + "zoomIn": "Zoom In", + "zoomOut": "Zoom Out", + "resetView": "Reset View", + "lockLayout": "Lock Layout", + "unlockLayout": "Unlock Layout", + "noWidgets": "Right-click or click + to add your first widget", + "openFullView": "Open Full View", + "previewTitle": "Homepage Preview", + "cancel": "Cancel", + "save": "Save", + "title_label": "Title", + "widgetTitlePlaceholder": "Widget title (optional)", "url": "URL", - "imageUrl": "Прилагођени URL слике", - "imageUrlHint": "Оставите празно да бисте аутоматски користили фавикон сајта", - "showImage": "Прикажи слику", - "description": "Опис", - "color": "Боја", - "timezone": "Временска зона", - "invalidTimezone": "Неважећа временска зона. Користите IANA назив као што је Америка/Њујорк", - "showSeconds": "Прикажи секунде", - "format12h": "12 сати", - "content": "Садржај", - "backgroundColor": "Боја позадине", - "links": "Линкови", - "addLink": "Додај линк", - "linkLabel": "Ознака", - "categoryLinks": "Линкови", - "categoryInfo": "Информације", - "categorySystem": "Систем", - "copyLink": "Копирај линк", - "linkCopied": "Линк копиран!", - "location": "Локација", - "temperatureUnit": "Јединица за температуру", - "showForecast": "Прикажи тродневну прогнозу", - "scrolling": "Дозволи скроловање", - "feedUrl": "URL фида", - "maxItems": "Максималан број ставки", - "showDescription": "Прикажи опис", - "widgetRssName": "RSS фид", - "noHostSelected": "Није изабран домаћин", - "displayedMetrics": "Приказане метрике", - "metricCpu": "Процесор", - "metricMemory": "Памћење", - "metricDisk": "Диск", - "metricUptime": "Време непрекидног рада", - "metricSystem": "Систем", - "metricNetwork": "Мрежа", - "metricProcesses": "Процеси", - "categoryMonitoring": "Праћење", - "noPingUrls": "Није конфигурисан ниједан URL", - "pingLabel": "Ознака", - "addPingUrl": "Додај URL", - "showLatency": "Прикажи латенцију", - "refreshInterval": "Интервал освежавања", - "seconds": "секунде", - "filterActivityTypes": "Типови филтера", - "filterTypesHint": "Оставите празно да бисте видели све", - "showTimestamp": "Прикажи временску ознаку", - "uptimeUnavailable": "Време непрекидног рада није доступно", - "uptimeLabel": "Време непрекидног рада", - "overviewVersion": "Верзија", - "overviewUpdateLabel": "Ажурирање", - "overviewUpdateAvailable": "Ажурирање је доступно", - "overviewDatabase": "База података", - "overviewUptime": "Време непрекидног рада", - "noHosts": "Ниједан хост није конфигурисан", - "hostGridHosts": "Домаћини", - "hostGridAllHint": "Оставите празно да бисте приказали све хостове", - "columns": "Колоне", - "showIp": "Прикажи ИП адресу", - "layout": "Распоред", - "showStatus": "Прикажи статус", - "noActivity": "Нема активности", - "widgetPingStatusName": "Статус пинга", - "widgetRecentActivityName": "Недавне активности", - "sshTerminalNoHost": "Није конфигурисан хост", - "sshTerminalConnect": "Повежи се", - "sshTerminalAutoConnect": "Аутоматско повезивање при учитавању", - "connectionTypes": "Типови повезивања", - "calMon": "Мо", - "calTue": "Уто", - "calWed": "Ми", - "calThu": "Чет", - "calFri": "Пет", - "calSat": "Са", - "calSun": "Су", - "startOnMonday": "Почетак недеље у понедељак", - "countdownNoDate": "Није одређен циљни датум", - "countdownPast": "Догађај је прошао", - "countdownDays": "дана", - "countdownHours": "сати", - "countdownMinutes": "мин", - "countdownSeconds": "сек", - "countdownLabel": "Ознака", - "countdownLabelPlaceholder": "нпр. Дан лансирања", - "countdownShowDays": "Дани емисије", - "countdownShowHours": "Радно време емисије", - "targetDate": "Циљни датум", - "searchEngine": "Претраживач", - "customSearchUrl": "URL прилагођене претраге", - "searchPlaceholder": "Претрага...", - "searchGo": "Иди", - "searchPlaceholderLabel": "Текст резервисаног места", - "searchPlaceholderHint": "Текст приказан унутар поља за претрагу", - "openInNewTab": "Отвори у новој картици", - "searchQueryPlaceholder": "Унесите упит...", - "noSearchShortcuts": "Ниједна пречица није конфигурисана", - "addSearchShortcut": "Додај пречицу", - "fontSize": "Величина фонта", - "textAlign": "Поравнање текста", - "fontWeight": "Дебљина фонта", - "clearColor": "Чиста боја", - "imageFit": "Уклапање слике", - "imageLinkUrl": "URL линка", - "noImage": "Није подешен URL слике", - "altText": "Алтернативни текст", - "altTextPlaceholder": "Опишите слику", - "renderMarkdown": "Рендеровање маркдауна", - "displayMode": "Режим приказа", - "displayField": "Поље за приказ", - "jsonPath": "JSON путања", - "customApiLabel": "Ознака", - "customApiLabelPlaceholder": "нпр. Температура", - "customApiUnit": "Јединица", - "customApiNoUrl": "Није конфигурисан API URL", - "customApiError": "Преузимање није успело", - "customApiNotArray": "Одговор није низ", - "addService": "Додај услугу", - "showLabels": "Прикажи ознаке", - "iconSize": "Величина иконе", - "noDashboardLinks": "Није конфигурисан ниједан линк до контролне табле", - "noLimit": "Без ограничења", - "sectionHeading": "Наслов одељка", - "addSection": "Додај одељак", - "compactMode": "Компактни режим", - "selectHosts": "Изаберите хостове", - "listLayout": "Листа", - "gridLayout": "Мрежа" + "imageUrl": "Custom Image URL", + "imageUrlHint": "Leave blank to use the site favicon automatically", + "showImage": "Show Image", + "description": "Description", + "color": "Color", + "timezone": "Timezone", + "invalidTimezone": "Invalid timezone. Use an IANA name such as America/New_York", + "showSeconds": "Show seconds", + "format12h": "12-hour", + "content": "Content", + "backgroundColor": "Background Color", + "links": "Links", + "addLink": "Add Link", + "linkLabel": "Label", + "categoryLinks": "Links", + "categoryInfo": "Info", + "categorySystem": "System", + "copyLink": "Copy Link", + "linkCopied": "Link copied!", + "location": "Location", + "temperatureUnit": "Temperature Unit", + "showForecast": "Show 3-day forecast", + "scrolling": "Allow Scrolling", + "feedUrl": "Feed URL", + "maxItems": "Max Items", + "showDescription": "Show Description", + "widgetRssName": "RSS Feed", + "rssNoFeedUrl": "Configure a feed URL in widget settings", + "rssLoadError": "Could not load feed", + "rssNoItems": "No items", + "noHostSelected": "No host selected", + "displayedMetrics": "Displayed Metrics", + "metricCpu": "CPU", + "metricMemory": "Memory", + "metricDisk": "Disk", + "metricUptime": "Uptime", + "metricSystem": "System", + "metricNetwork": "Network", + "metricProcesses": "Processes", + "categoryMonitoring": "Monitoring", + "noPingUrls": "No URLs configured", + "pingLabel": "Label", + "addPingUrl": "Add URL", + "showLatency": "Show Latency", + "refreshInterval": "Refresh Interval", + "seconds": "seconds", + "filterActivityTypes": "Filter Types", + "filterTypesHint": "Leave empty to show all", + "showTimestamp": "Show Timestamp", + "uptimeUnavailable": "Uptime unavailable", + "uptimeLabel": "Uptime", + "overviewVersion": "Version", + "overviewUpdateLabel": "Update", + "overviewUpdateAvailable": "Update available", + "overviewDatabase": "Database", + "overviewUptime": "Uptime", + "noHosts": "No hosts configured", + "hostGridHosts": "Hosts", + "hostGridAllHint": "Leave empty to show all hosts", + "columns": "Columns", + "showIp": "Show IP Address", + "layout": "Layout", + "showStatus": "Show Status", + "noActivity": "No activity", + "widgetPingStatusName": "Ping Status", + "widgetRecentActivityName": "Recent Activity", + "sshTerminalNoHost": "No host configured", + "sshTerminalConnect": "Connect", + "sshTerminalAutoConnect": "Auto-connect on load", + "connectionTypes": "Connection Types", + "calMon": "Mo", + "calTue": "Tu", + "calWed": "We", + "calThu": "Th", + "calFri": "Fr", + "calSat": "Sa", + "calSun": "Su", + "startOnMonday": "Start week on Monday", + "countdownNoDate": "No target date set", + "countdownPast": "Event has passed", + "countdownDays": "days", + "countdownHours": "hrs", + "countdownMinutes": "min", + "countdownSeconds": "sec", + "countdownLabel": "Label", + "countdownLabelPlaceholder": "e.g. Launch Day", + "countdownShowDays": "Show Days", + "countdownShowHours": "Show Hours", + "targetDate": "Target Date", + "searchEngine": "Search Engine", + "customSearchUrl": "Custom Search URL", + "searchPlaceholder": "Search...", + "searchGo": "Go", + "searchPlaceholderLabel": "Placeholder Text", + "searchPlaceholderHint": "Text shown inside the search input", + "openInNewTab": "Open in New Tab", + "searchQueryPlaceholder": "Enter query...", + "noSearchShortcuts": "No shortcuts configured", + "addSearchShortcut": "Add Shortcut", + "fontSize": "Font Size", + "textAlign": "Text Align", + "fontWeight": "Font Weight", + "clearColor": "Clear Color", + "imageFit": "Image Fit", + "imageLinkUrl": "Link URL", + "noImage": "No image URL set", + "altText": "Alt Text", + "altTextPlaceholder": "Describe the image", + "renderMarkdown": "Render Markdown", + "displayMode": "Display Mode", + "displayField": "Display Field", + "jsonPath": "JSON Path", + "customApiLabel": "Label", + "customApiLabelPlaceholder": "e.g. Temperature", + "customApiUnit": "Unit", + "customApiNoUrl": "No API URL configured", + "customApiError": "Failed to fetch", + "customApiNotArray": "Response is not an array", + "addService": "Add Service", + "showLabels": "Show Labels", + "iconSize": "Icon Size", + "noDashboardLinks": "No dashboard links configured", + "noLimit": "No limit", + "sectionHeading": "Section Heading", + "addSection": "Add Section", + "compactMode": "Compact Mode", + "selectHosts": "Select Hosts", + "listLayout": "List", + "gridLayout": "Grid", + "configureUrl": "Set a URL in the widget settings", + "embeddedContent": "Embedded content", + "noBookmarks": "No bookmarks", + "noSections": "No sections set up", + "noServices": "No services set up", + "configureLocation": "Set a location in the widget settings", + "bannerTextPlaceholder": "Banner text", + "serviceNamePlaceholder": "My service" + }, + "permissions": { + "use": { + "title": "Use the homepage", + "description": "View and edit the homepage canvas and dashboard service links." + } + }, + "settings": { + "privateEndpoints": { + "label": "Allowed private hosts", + "description": "Exact private or loopback hostnames/IPs for Ping Status and Custom API widgets. Separate entries with commas or newlines; omit schemes, ports and paths. Empty blocks private destinations." + }, + "privateCertificateAuthority": { + "label": "Private certificate authority (PEM)", + "description": "Optional trusted CA bundle for allowlisted hosts. Certificate verification remains enabled. Leave empty to use the system trust store." + } } } diff --git a/plugins/homepage/locales/translated/sv_SE.json b/plugins/homepage/locales/translated/sv_SE.json index 668ffc8c6..760b3a445 100644 --- a/plugins/homepage/locales/translated/sv_SE.json +++ b/plugins/homepage/locales/translated/sv_SE.json @@ -1,162 +1,190 @@ { "nav": { - "homepage": "Hemsida" + "homepage": "Homepage" }, "dashboard": { - "serviceLinks": "Servicelänkar", - "homepagePreview": "Förhandsvisning av startsidan" + "serviceLinks": "Service Links", + "homepagePreview": "Homepage Preview" }, "dashboardTab": { - "serviceLinksTitle": "Servicelänkar", - "serviceLinksEmpty": "Inga tjänstelänkar ännu", - "serviceLinksAdd": "Tillägga", - "serviceLinksLabelPlaceholder": "Min tjänst", + "serviceLinksTitle": "Service Links", + "serviceLinksEmpty": "No service links yet", + "serviceLinksAdd": "Add", + "serviceLinksLabelPlaceholder": "My Service", "serviceLinksUrlPlaceholder": "http://192.168.1.10:8080", - "serviceLinksInvalidUrl": "Ange en giltig webbadress", - "serviceLinksAddFailed": "Misslyckades med att lägga till tjänstelänk" + "serviceLinksInvalidUrl": "Enter a valid web address", + "serviceLinksAddFailed": "Failed to add service link" }, "homepage": { - "title": "Hemsida", - "addWidget": "Lägg till widget", - "editWidget": "Redigera widget", - "zoomIn": "Zooma in", - "zoomOut": "Zooma ut", - "resetView": "Återställ vy", - "lockLayout": "Låslayout", - "unlockLayout": "Lås upp layouten", - "noWidgets": "Högerklicka eller klicka på + för att lägga till din första widget", - "openFullView": "Öppna helvy", - "previewTitle": "Förhandsvisning av startsidan", - "cancel": "Avboka", - "save": "Spara", - "title_label": "Titel", - "widgetTitlePlaceholder": "Widgettitel (valfritt)", + "title": "Homepage", + "addWidget": "Add Widget", + "noWidgetsInCategory": "No widgets in this category", + "editWidget": "Edit Widget", + "zoomIn": "Zoom In", + "zoomOut": "Zoom Out", + "resetView": "Reset View", + "lockLayout": "Lock Layout", + "unlockLayout": "Unlock Layout", + "noWidgets": "Right-click or click + to add your first widget", + "openFullView": "Open Full View", + "previewTitle": "Homepage Preview", + "cancel": "Cancel", + "save": "Save", + "title_label": "Title", + "widgetTitlePlaceholder": "Widget title (optional)", "url": "URL", - "imageUrl": "Anpassad bild-URL", - "imageUrlHint": "Lämna tomt för att använda webbplatsens favicon automatiskt", - "showImage": "Visa bild", - "description": "Beskrivning", - "color": "Färg", - "timezone": "Tidszon", - "invalidTimezone": "Ogiltig tidszon. Använd ett IANA-namn som America/New_York", - "showSeconds": "Visa sekunder", - "format12h": "12-timmars", - "content": "Innehåll", - "backgroundColor": "Bakgrundsfärg", - "links": "Länkar", - "addLink": "Lägg till länk", - "linkLabel": "Märka", - "categoryLinks": "Länkar", + "imageUrl": "Custom Image URL", + "imageUrlHint": "Leave blank to use the site favicon automatically", + "showImage": "Show Image", + "description": "Description", + "color": "Color", + "timezone": "Timezone", + "invalidTimezone": "Invalid timezone. Use an IANA name such as America/New_York", + "showSeconds": "Show seconds", + "format12h": "12-hour", + "content": "Content", + "backgroundColor": "Background Color", + "links": "Links", + "addLink": "Add Link", + "linkLabel": "Label", + "categoryLinks": "Links", "categoryInfo": "Info", "categorySystem": "System", - "copyLink": "Kopiera länk", - "linkCopied": "Länk kopierad!", - "location": "Plats", - "temperatureUnit": "Temperaturenhet", - "showForecast": "Visa 3-dagarsprognos", - "scrolling": "Tillåt rullning", - "feedUrl": "Flödes-URL", - "maxItems": "Max antal artiklar", - "showDescription": "Visa beskrivning", - "widgetRssName": "RSS-flöde", - "noHostSelected": "Ingen värd vald", - "displayedMetrics": "Visade mätvärden", + "copyLink": "Copy Link", + "linkCopied": "Link copied!", + "location": "Location", + "temperatureUnit": "Temperature Unit", + "showForecast": "Show 3-day forecast", + "scrolling": "Allow Scrolling", + "feedUrl": "Feed URL", + "maxItems": "Max Items", + "showDescription": "Show Description", + "widgetRssName": "RSS Feed", + "rssNoFeedUrl": "Configure a feed URL in widget settings", + "rssLoadError": "Could not load feed", + "rssNoItems": "No items", + "noHostSelected": "No host selected", + "displayedMetrics": "Displayed Metrics", "metricCpu": "CPU", - "metricMemory": "Minne", + "metricMemory": "Memory", "metricDisk": "Disk", - "metricUptime": "Drifttid", + "metricUptime": "Uptime", "metricSystem": "System", - "metricNetwork": "Nätverk", - "metricProcesses": "Processer", - "categoryMonitoring": "Övervakning", - "noPingUrls": "Inga webbadresser konfigurerade", - "pingLabel": "Märka", - "addPingUrl": "Lägg till URL", - "showLatency": "Visa latens", - "refreshInterval": "Uppdateringsintervall", - "seconds": "sekunder", - "filterActivityTypes": "Filtertyper", - "filterTypesHint": "Lämna tomt för att visa alla", - "showTimestamp": "Visa tidsstämpel", - "uptimeUnavailable": "Drifttid otillgänglig", - "uptimeLabel": "Drifttid", + "metricNetwork": "Network", + "metricProcesses": "Processes", + "categoryMonitoring": "Monitoring", + "noPingUrls": "No URLs configured", + "pingLabel": "Label", + "addPingUrl": "Add URL", + "showLatency": "Show Latency", + "refreshInterval": "Refresh Interval", + "seconds": "seconds", + "filterActivityTypes": "Filter Types", + "filterTypesHint": "Leave empty to show all", + "showTimestamp": "Show Timestamp", + "uptimeUnavailable": "Uptime unavailable", + "uptimeLabel": "Uptime", "overviewVersion": "Version", - "overviewUpdateLabel": "Uppdatera", - "overviewUpdateAvailable": "Uppdatering tillgänglig", - "overviewDatabase": "Databas", - "overviewUptime": "Drifttid", - "noHosts": "Inga värdar konfigurerade", - "hostGridHosts": "Värdar", - "hostGridAllHint": "Lämna tomt för att visa alla värdar", - "columns": "Kolumner", - "showIp": "Visa IP-adress", + "overviewUpdateLabel": "Update", + "overviewUpdateAvailable": "Update available", + "overviewDatabase": "Database", + "overviewUptime": "Uptime", + "noHosts": "No hosts configured", + "hostGridHosts": "Hosts", + "hostGridAllHint": "Leave empty to show all hosts", + "columns": "Columns", + "showIp": "Show IP Address", "layout": "Layout", - "showStatus": "Visa status", - "noActivity": "Ingen aktivitet", - "widgetPingStatusName": "Pingstatus", - "widgetRecentActivityName": "Senaste aktivitet", - "sshTerminalNoHost": "Ingen värd konfigurerad", - "sshTerminalConnect": "Ansluta", - "sshTerminalAutoConnect": "Automatisk anslutning vid laddning", - "connectionTypes": "Anslutningstyper", - "calMon": "Må", - "calTue": "Tis", - "calWed": "Vi", - "calThu": "To", + "showStatus": "Show Status", + "noActivity": "No activity", + "widgetPingStatusName": "Ping Status", + "widgetRecentActivityName": "Recent Activity", + "sshTerminalNoHost": "No host configured", + "sshTerminalConnect": "Connect", + "sshTerminalAutoConnect": "Auto-connect on load", + "connectionTypes": "Connection Types", + "calMon": "Mo", + "calTue": "Tu", + "calWed": "We", + "calThu": "Th", "calFri": "Fr", - "calSat": "Lör", - "calSun": "Sö", - "startOnMonday": "Börja veckan på måndag", - "countdownNoDate": "Inget måldatum angivet", - "countdownPast": "Händelsen har passerat", - "countdownDays": "dagar", - "countdownHours": "timmar", + "calSat": "Sa", + "calSun": "Su", + "startOnMonday": "Start week on Monday", + "countdownNoDate": "No target date set", + "countdownPast": "Event has passed", + "countdownDays": "days", + "countdownHours": "hrs", "countdownMinutes": "min", - "countdownSeconds": "sek", - "countdownLabel": "Märka", - "countdownLabelPlaceholder": "t.ex. lanseringsdagen", - "countdownShowDays": "Visa dagar", - "countdownShowHours": "Visa öppettider", - "targetDate": "Måldatum", - "searchEngine": "Sökmotor", - "customSearchUrl": "Anpassad sök-URL", - "searchPlaceholder": "Söka...", - "searchGo": "Gå", - "searchPlaceholderLabel": "Platshållartext", - "searchPlaceholderHint": "Text som visas inuti sökinmatningen", - "openInNewTab": "Öppna i ny flik", - "searchQueryPlaceholder": "Ange fråga...", - "noSearchShortcuts": "Inga genvägar konfigurerade", - "addSearchShortcut": "Lägg till genväg", - "fontSize": "Fontstorlek", - "textAlign": "Textjustering", - "fontWeight": "Teckensnittsvikt", - "clearColor": "Klar färg", - "imageFit": "Bildanpassning", - "imageLinkUrl": "Länk-URL", - "noImage": "Ingen bild-URL angiven", - "altText": "Alternativtext", - "altTextPlaceholder": "Beskriv bilden", - "renderMarkdown": "Rendera Markdown", - "displayMode": "Visningsläge", - "displayField": "Visningsfält", - "jsonPath": "JSON-sökväg", - "customApiLabel": "Märka", - "customApiLabelPlaceholder": "t.ex. temperatur", - "customApiUnit": "Enhet", - "customApiNoUrl": "Ingen API-URL konfigurerad", - "customApiError": "Misslyckades med att hämta", - "customApiNotArray": "Svaret är inte en array", - "addService": "Lägg till tjänst", - "showLabels": "Visa etiketter", - "iconSize": "Ikonstorlek", - "noDashboardLinks": "Inga länkar till instrumentpanelen konfigurerade", - "noLimit": "Ingen gräns", - "sectionHeading": "Avsnittsrubrik", - "addSection": "Lägg till avsnitt", - "compactMode": "Kompaktläge", - "selectHosts": "Välj värdar", - "listLayout": "Lista", - "gridLayout": "Rutnät" + "countdownSeconds": "sec", + "countdownLabel": "Label", + "countdownLabelPlaceholder": "e.g. Launch Day", + "countdownShowDays": "Show Days", + "countdownShowHours": "Show Hours", + "targetDate": "Target Date", + "searchEngine": "Search Engine", + "customSearchUrl": "Custom Search URL", + "searchPlaceholder": "Search...", + "searchGo": "Go", + "searchPlaceholderLabel": "Placeholder Text", + "searchPlaceholderHint": "Text shown inside the search input", + "openInNewTab": "Open in New Tab", + "searchQueryPlaceholder": "Enter query...", + "noSearchShortcuts": "No shortcuts configured", + "addSearchShortcut": "Add Shortcut", + "fontSize": "Font Size", + "textAlign": "Text Align", + "fontWeight": "Font Weight", + "clearColor": "Clear Color", + "imageFit": "Image Fit", + "imageLinkUrl": "Link URL", + "noImage": "No image URL set", + "altText": "Alt Text", + "altTextPlaceholder": "Describe the image", + "renderMarkdown": "Render Markdown", + "displayMode": "Display Mode", + "displayField": "Display Field", + "jsonPath": "JSON Path", + "customApiLabel": "Label", + "customApiLabelPlaceholder": "e.g. Temperature", + "customApiUnit": "Unit", + "customApiNoUrl": "No API URL configured", + "customApiError": "Failed to fetch", + "customApiNotArray": "Response is not an array", + "addService": "Add Service", + "showLabels": "Show Labels", + "iconSize": "Icon Size", + "noDashboardLinks": "No dashboard links configured", + "noLimit": "No limit", + "sectionHeading": "Section Heading", + "addSection": "Add Section", + "compactMode": "Compact Mode", + "selectHosts": "Select Hosts", + "listLayout": "List", + "gridLayout": "Grid", + "configureUrl": "Set a URL in the widget settings", + "embeddedContent": "Embedded content", + "noBookmarks": "No bookmarks", + "noSections": "No sections set up", + "noServices": "No services set up", + "configureLocation": "Set a location in the widget settings", + "bannerTextPlaceholder": "Banner text", + "serviceNamePlaceholder": "My service" + }, + "permissions": { + "use": { + "title": "Use the homepage", + "description": "View and edit the homepage canvas and dashboard service links." + } + }, + "settings": { + "privateEndpoints": { + "label": "Allowed private hosts", + "description": "Exact private or loopback hostnames/IPs for Ping Status and Custom API widgets. Separate entries with commas or newlines; omit schemes, ports and paths. Empty blocks private destinations." + }, + "privateCertificateAuthority": { + "label": "Private certificate authority (PEM)", + "description": "Optional trusted CA bundle for allowlisted hosts. Certificate verification remains enabled. Leave empty to use the system trust store." + } } } diff --git a/plugins/homepage/locales/translated/th_TH.json b/plugins/homepage/locales/translated/th_TH.json index b7d3d8160..760b3a445 100644 --- a/plugins/homepage/locales/translated/th_TH.json +++ b/plugins/homepage/locales/translated/th_TH.json @@ -1,162 +1,190 @@ { "nav": { - "homepage": "หน้าแรก" + "homepage": "Homepage" }, "dashboard": { - "serviceLinks": "ลิงก์บริการ", - "homepagePreview": "ตัวอย่างหน้าแรก" + "serviceLinks": "Service Links", + "homepagePreview": "Homepage Preview" }, "dashboardTab": { - "serviceLinksTitle": "ลิงก์บริการ", - "serviceLinksEmpty": "ยังไม่มีลิงก์บริการ", - "serviceLinksAdd": "เพิ่ม", - "serviceLinksLabelPlaceholder": "บริการของฉัน", + "serviceLinksTitle": "Service Links", + "serviceLinksEmpty": "No service links yet", + "serviceLinksAdd": "Add", + "serviceLinksLabelPlaceholder": "My Service", "serviceLinksUrlPlaceholder": "http://192.168.1.10:8080", - "serviceLinksInvalidUrl": "ป้อนที่อยู่เว็บที่ถูกต้อง", - "serviceLinksAddFailed": "ไม่สามารถเพิ่มลิงก์บริการได้" + "serviceLinksInvalidUrl": "Enter a valid web address", + "serviceLinksAddFailed": "Failed to add service link" }, "homepage": { - "title": "หน้าแรก", - "addWidget": "เพิ่มวิดเจ็ต", - "editWidget": "แก้ไขวิดเจ็ต", - "zoomIn": "ซูมเข้า", - "zoomOut": "ซูมออก", - "resetView": "รีเซ็ตมุมมอง", - "lockLayout": "การจัดวางล็อค", - "unlockLayout": "ปลดล็อกเค้าโครง", - "noWidgets": "คลิกขวาหรือคลิก + เพื่อเพิ่มวิดเจ็ตแรกของคุณ", - "openFullView": "เปิดดูแบบเต็มหน้าจอ", - "previewTitle": "ตัวอย่างหน้าแรก", - "cancel": "ยกเลิก", - "save": "บันทึก", - "title_label": "ชื่อ", - "widgetTitlePlaceholder": "ชื่อวิดเจ็ต (ไม่บังคับ)", + "title": "Homepage", + "addWidget": "Add Widget", + "noWidgetsInCategory": "No widgets in this category", + "editWidget": "Edit Widget", + "zoomIn": "Zoom In", + "zoomOut": "Zoom Out", + "resetView": "Reset View", + "lockLayout": "Lock Layout", + "unlockLayout": "Unlock Layout", + "noWidgets": "Right-click or click + to add your first widget", + "openFullView": "Open Full View", + "previewTitle": "Homepage Preview", + "cancel": "Cancel", + "save": "Save", + "title_label": "Title", + "widgetTitlePlaceholder": "Widget title (optional)", "url": "URL", - "imageUrl": "URL รูปภาพแบบกำหนดเอง", - "imageUrlHint": "เว้นว่างไว้เพื่อใช้ไอคอนเว็บไซต์โดยอัตโนมัติ", - "showImage": "แสดงภาพ", - "description": "คำอธิบาย", - "color": "สี", - "timezone": "เขตเวลา", - "invalidTimezone": "เขตเวลาไม่ถูกต้อง กรุณาใช้ชื่อ IANA เช่น America/New_York", - "showSeconds": "แสดงวินาที", - "format12h": "12 ชั่วโมง", - "content": "เนื้อหา", - "backgroundColor": "สีพื้นหลัง", - "links": "ลิงก์", - "addLink": "เพิ่มลิงก์", - "linkLabel": "ฉลาก", - "categoryLinks": "ลิงก์", - "categoryInfo": "ข้อมูล", - "categorySystem": "ระบบ", - "copyLink": "คัดลอกลิงก์", - "linkCopied": "คัดลอกลิงก์เรียบร้อยแล้ว!", - "location": "ที่ตั้ง", - "temperatureUnit": "หน่วยอุณหภูมิ", - "showForecast": "แสดงพยากรณ์อากาศ 3 วัน", - "scrolling": "อนุญาตให้เลื่อน", - "feedUrl": "URL ฟีด", - "maxItems": "ไอเทมสูงสุด", - "showDescription": "แสดงคำอธิบาย", - "widgetRssName": "ฟีด RSS", - "noHostSelected": "ไม่ได้เลือกโฮสต์", - "displayedMetrics": "ตัวชี้วัดที่แสดงผล", - "metricCpu": "ซีพียู", - "metricMemory": "หน่วยความจำ", - "metricDisk": "ดิสก์", - "metricUptime": "เวลาใช้งาน", - "metricSystem": "ระบบ", - "metricNetwork": "เครือข่าย", - "metricProcesses": "กระบวนการ", - "categoryMonitoring": "การตรวจสอบ", - "noPingUrls": "ไม่มีการกำหนดค่า URL", - "pingLabel": "ฉลาก", - "addPingUrl": "เพิ่ม URL", - "showLatency": "แสดงค่าความหน่วง", - "refreshInterval": "ช่วงเวลาการรีเฟรช", - "seconds": "วินาที", - "filterActivityTypes": "ประเภทตัวกรอง", - "filterTypesHint": "เว้นว่างไว้เพื่อแสดงทั้งหมด", - "showTimestamp": "แสดงเวลา", - "uptimeUnavailable": "ไม่สามารถระบุเวลาใช้งานได้", - "uptimeLabel": "เวลาใช้งาน", - "overviewVersion": "เวอร์ชั่น", - "overviewUpdateLabel": "อัปเดต", - "overviewUpdateAvailable": "มีการอัปเดตแล้ว", - "overviewDatabase": "ฐานข้อมูล", - "overviewUptime": "เวลาใช้งาน", - "noHosts": "ไม่มีการกำหนดค่าโฮสต์", - "hostGridHosts": "โฮสต์", - "hostGridAllHint": "เว้นว่างไว้เพื่อแสดงโฮสต์ทั้งหมด", - "columns": "คอลัมน์", - "showIp": "แสดงที่อยู่ IP", - "layout": "เค้าโครง", - "showStatus": "แสดงสถานะ", - "noActivity": "ไม่มีกิจกรรม", - "widgetPingStatusName": "สถานะการปิง", - "widgetRecentActivityName": "กิจกรรมล่าสุด", - "sshTerminalNoHost": "ไม่มีการกำหนดค่าโฮสต์", - "sshTerminalConnect": "เชื่อมต่อ", - "sshTerminalAutoConnect": "เชื่อมต่ออัตโนมัติเมื่อโหลดเสร็จ", - "connectionTypes": "ประเภทการเชื่อมต่อ", - "calMon": "โม", - "calTue": "ตู", - "calWed": "เรา", - "calThu": "ไทย", - "calFri": "ฟร", - "calSat": "ซา", - "calSun": "ซู", - "startOnMonday": "เริ่มต้นสัปดาห์ในวันจันทร์", - "countdownNoDate": "ยังไม่ได้กำหนดวันเป้าหมาย", - "countdownPast": "กิจกรรมได้จบลงแล้ว", - "countdownDays": "วัน", - "countdownHours": "ชั่วโมง", - "countdownMinutes": "นาที", - "countdownSeconds": "วินาที", - "countdownLabel": "ฉลาก", - "countdownLabelPlaceholder": "เช่น วันเปิดตัว", - "countdownShowDays": "วันแสดง", - "countdownShowHours": "เวลาทำการ", - "targetDate": "วันที่เป้าหมาย", - "searchEngine": "เครื่องมือค้นหา", - "customSearchUrl": "URL ค้นหาแบบกำหนดเอง", - "searchPlaceholder": "ค้นหา...", - "searchGo": "ไป", - "searchPlaceholderLabel": "ข้อความตัวอย่าง", - "searchPlaceholderHint": "ข้อความที่แสดงอยู่ภายในช่องค้นหา", - "openInNewTab": "เปิดในแท็บใหม่", - "searchQueryPlaceholder": "ป้อนคำค้นหา...", - "noSearchShortcuts": "ไม่ได้ตั้งค่าทางลัดใดๆ", - "addSearchShortcut": "เพิ่มทางลัด", - "fontSize": "ขนาดตัวอักษร", - "textAlign": "จัดแนวข้อความ", - "fontWeight": "น้ำหนักตัวอักษร", - "clearColor": "สีใส", - "imageFit": "ภาพที่พอดี", - "imageLinkUrl": "ลิงก์ URL", - "noImage": "ไม่ได้ตั้งค่า URL รูปภาพ", - "altText": "ข้อความแสดงแทน (Alt Text)", - "altTextPlaceholder": "อธิบายภาพ", - "renderMarkdown": "แสดงผลมาร์คดาวน์", - "displayMode": "โหมดการแสดงผล", - "displayField": "ช่องแสดงผล", - "jsonPath": "เส้นทาง JSON", - "customApiLabel": "ฉลาก", - "customApiLabelPlaceholder": "เช่น อุณหภูมิ", - "customApiUnit": "หน่วย", - "customApiNoUrl": "ไม่ได้กำหนดค่า URL API ไว้", - "customApiError": "ไม่สามารถดึงข้อมูลได้", - "customApiNotArray": "คำตอบไม่ใช่อาร์เรย์", - "addService": "เพิ่มบริการ", - "showLabels": "แสดงป้ายกำกับ", - "iconSize": "ขนาดไอคอน", - "noDashboardLinks": "ไม่มีการกำหนดค่าลิงก์แดชบอร์ด", - "noLimit": "ไม่มีขีดจำกัด", - "sectionHeading": "หัวข้อส่วน", - "addSection": "เพิ่มส่วน", - "compactMode": "โหมดกะทัดรัด", - "selectHosts": "เลือกโฮสต์", - "listLayout": "รายการ", - "gridLayout": "ตาราง" + "imageUrl": "Custom Image URL", + "imageUrlHint": "Leave blank to use the site favicon automatically", + "showImage": "Show Image", + "description": "Description", + "color": "Color", + "timezone": "Timezone", + "invalidTimezone": "Invalid timezone. Use an IANA name such as America/New_York", + "showSeconds": "Show seconds", + "format12h": "12-hour", + "content": "Content", + "backgroundColor": "Background Color", + "links": "Links", + "addLink": "Add Link", + "linkLabel": "Label", + "categoryLinks": "Links", + "categoryInfo": "Info", + "categorySystem": "System", + "copyLink": "Copy Link", + "linkCopied": "Link copied!", + "location": "Location", + "temperatureUnit": "Temperature Unit", + "showForecast": "Show 3-day forecast", + "scrolling": "Allow Scrolling", + "feedUrl": "Feed URL", + "maxItems": "Max Items", + "showDescription": "Show Description", + "widgetRssName": "RSS Feed", + "rssNoFeedUrl": "Configure a feed URL in widget settings", + "rssLoadError": "Could not load feed", + "rssNoItems": "No items", + "noHostSelected": "No host selected", + "displayedMetrics": "Displayed Metrics", + "metricCpu": "CPU", + "metricMemory": "Memory", + "metricDisk": "Disk", + "metricUptime": "Uptime", + "metricSystem": "System", + "metricNetwork": "Network", + "metricProcesses": "Processes", + "categoryMonitoring": "Monitoring", + "noPingUrls": "No URLs configured", + "pingLabel": "Label", + "addPingUrl": "Add URL", + "showLatency": "Show Latency", + "refreshInterval": "Refresh Interval", + "seconds": "seconds", + "filterActivityTypes": "Filter Types", + "filterTypesHint": "Leave empty to show all", + "showTimestamp": "Show Timestamp", + "uptimeUnavailable": "Uptime unavailable", + "uptimeLabel": "Uptime", + "overviewVersion": "Version", + "overviewUpdateLabel": "Update", + "overviewUpdateAvailable": "Update available", + "overviewDatabase": "Database", + "overviewUptime": "Uptime", + "noHosts": "No hosts configured", + "hostGridHosts": "Hosts", + "hostGridAllHint": "Leave empty to show all hosts", + "columns": "Columns", + "showIp": "Show IP Address", + "layout": "Layout", + "showStatus": "Show Status", + "noActivity": "No activity", + "widgetPingStatusName": "Ping Status", + "widgetRecentActivityName": "Recent Activity", + "sshTerminalNoHost": "No host configured", + "sshTerminalConnect": "Connect", + "sshTerminalAutoConnect": "Auto-connect on load", + "connectionTypes": "Connection Types", + "calMon": "Mo", + "calTue": "Tu", + "calWed": "We", + "calThu": "Th", + "calFri": "Fr", + "calSat": "Sa", + "calSun": "Su", + "startOnMonday": "Start week on Monday", + "countdownNoDate": "No target date set", + "countdownPast": "Event has passed", + "countdownDays": "days", + "countdownHours": "hrs", + "countdownMinutes": "min", + "countdownSeconds": "sec", + "countdownLabel": "Label", + "countdownLabelPlaceholder": "e.g. Launch Day", + "countdownShowDays": "Show Days", + "countdownShowHours": "Show Hours", + "targetDate": "Target Date", + "searchEngine": "Search Engine", + "customSearchUrl": "Custom Search URL", + "searchPlaceholder": "Search...", + "searchGo": "Go", + "searchPlaceholderLabel": "Placeholder Text", + "searchPlaceholderHint": "Text shown inside the search input", + "openInNewTab": "Open in New Tab", + "searchQueryPlaceholder": "Enter query...", + "noSearchShortcuts": "No shortcuts configured", + "addSearchShortcut": "Add Shortcut", + "fontSize": "Font Size", + "textAlign": "Text Align", + "fontWeight": "Font Weight", + "clearColor": "Clear Color", + "imageFit": "Image Fit", + "imageLinkUrl": "Link URL", + "noImage": "No image URL set", + "altText": "Alt Text", + "altTextPlaceholder": "Describe the image", + "renderMarkdown": "Render Markdown", + "displayMode": "Display Mode", + "displayField": "Display Field", + "jsonPath": "JSON Path", + "customApiLabel": "Label", + "customApiLabelPlaceholder": "e.g. Temperature", + "customApiUnit": "Unit", + "customApiNoUrl": "No API URL configured", + "customApiError": "Failed to fetch", + "customApiNotArray": "Response is not an array", + "addService": "Add Service", + "showLabels": "Show Labels", + "iconSize": "Icon Size", + "noDashboardLinks": "No dashboard links configured", + "noLimit": "No limit", + "sectionHeading": "Section Heading", + "addSection": "Add Section", + "compactMode": "Compact Mode", + "selectHosts": "Select Hosts", + "listLayout": "List", + "gridLayout": "Grid", + "configureUrl": "Set a URL in the widget settings", + "embeddedContent": "Embedded content", + "noBookmarks": "No bookmarks", + "noSections": "No sections set up", + "noServices": "No services set up", + "configureLocation": "Set a location in the widget settings", + "bannerTextPlaceholder": "Banner text", + "serviceNamePlaceholder": "My service" + }, + "permissions": { + "use": { + "title": "Use the homepage", + "description": "View and edit the homepage canvas and dashboard service links." + } + }, + "settings": { + "privateEndpoints": { + "label": "Allowed private hosts", + "description": "Exact private or loopback hostnames/IPs for Ping Status and Custom API widgets. Separate entries with commas or newlines; omit schemes, ports and paths. Empty blocks private destinations." + }, + "privateCertificateAuthority": { + "label": "Private certificate authority (PEM)", + "description": "Optional trusted CA bundle for allowlisted hosts. Certificate verification remains enabled. Leave empty to use the system trust store." + } } } diff --git a/plugins/homepage/locales/translated/tr_TR.json b/plugins/homepage/locales/translated/tr_TR.json index 2d7415210..f58ea49d8 100644 --- a/plugins/homepage/locales/translated/tr_TR.json +++ b/plugins/homepage/locales/translated/tr_TR.json @@ -18,6 +18,7 @@ "homepage": { "title": "Ana Sayfa", "addWidget": "Bileşen Ekle", + "noWidgetsInCategory": "No widgets in this category", "editWidget": "Bileşeni Düzenle", "zoomIn": "Yakınlaştır", "zoomOut": "Uzaklaştır", @@ -38,7 +39,7 @@ "description": "Açıklama", "color": "Renk", "timezone": "Zaman Dilimi", - "invalidTimezone": "Geçersiz saat dilimi. Lütfen America/New_York gibi bir IANA adı kullanın.", + "invalidTimezone": "Invalid timezone. Use an IANA name such as America/New_York", "showSeconds": "Saniyeleri göster", "format12h": "12 saatlik", "content": "İçerik", @@ -59,6 +60,9 @@ "maxItems": "Maksimum Öğe Sayısı", "showDescription": "Açıklamayı Göster", "widgetRssName": "RSS Akışı", + "rssNoFeedUrl": "Configure a feed URL in widget settings", + "rssLoadError": "Could not load feed", + "rssNoItems": "No items", "noHostSelected": "Sunucu seçilmedi", "displayedMetrics": "Gösterilen Metrikler", "metricCpu": "CPU", @@ -81,7 +85,7 @@ "uptimeUnavailable": "Çalışma süresi kullanılamıyor", "uptimeLabel": "Çalışma Süresi", "overviewVersion": "Sürüm", - "overviewUpdateLabel": "Güncelleme", + "overviewUpdateLabel": "Güncelle", "overviewUpdateAvailable": "Güncelleme mevcut", "overviewDatabase": "Veritabanı", "overviewUptime": "Çalışma Süresi", @@ -157,6 +161,30 @@ "compactMode": "Kompakt Mod", "selectHosts": "Sunucuları Seç", "listLayout": "Liste", - "gridLayout": "Izgara" + "gridLayout": "Izgara", + "configureUrl": "Set a URL in the widget settings", + "embeddedContent": "Embedded content", + "noBookmarks": "No bookmarks", + "noSections": "No sections set up", + "noServices": "No services set up", + "configureLocation": "Set a location in the widget settings", + "bannerTextPlaceholder": "Banner text", + "serviceNamePlaceholder": "My service" + }, + "permissions": { + "use": { + "title": "Use the homepage", + "description": "View and edit the homepage canvas and dashboard service links." + } + }, + "settings": { + "privateEndpoints": { + "label": "Allowed private hosts", + "description": "Exact private or loopback hostnames/IPs for Ping Status and Custom API widgets. Separate entries with commas or newlines; omit schemes, ports and paths. Empty blocks private destinations." + }, + "privateCertificateAuthority": { + "label": "Private certificate authority (PEM)", + "description": "Optional trusted CA bundle for allowlisted hosts. Certificate verification remains enabled. Leave empty to use the system trust store." + } } } diff --git a/plugins/homepage/locales/translated/uk_UA.json b/plugins/homepage/locales/translated/uk_UA.json index 9deab06e8..760b3a445 100644 --- a/plugins/homepage/locales/translated/uk_UA.json +++ b/plugins/homepage/locales/translated/uk_UA.json @@ -1,162 +1,190 @@ { "nav": { - "homepage": "Домашня сторінка" + "homepage": "Homepage" }, "dashboard": { - "serviceLinks": "Посилання на сервіси", - "homepagePreview": "Попередній перегляд головної сторінки" + "serviceLinks": "Service Links", + "homepagePreview": "Homepage Preview" }, "dashboardTab": { - "serviceLinksTitle": "Посилання на сервіси", - "serviceLinksEmpty": "Поки що немає посилань на сервіси", - "serviceLinksAdd": "Додати", - "serviceLinksLabelPlaceholder": "Моя послуга", + "serviceLinksTitle": "Service Links", + "serviceLinksEmpty": "No service links yet", + "serviceLinksAdd": "Add", + "serviceLinksLabelPlaceholder": "My Service", "serviceLinksUrlPlaceholder": "http://192.168.1.10:8080", - "serviceLinksInvalidUrl": "Введіть дійсну веб-адресу", - "serviceLinksAddFailed": "Не вдалося додати посилання на послугу" + "serviceLinksInvalidUrl": "Enter a valid web address", + "serviceLinksAddFailed": "Failed to add service link" }, "homepage": { - "title": "Домашня сторінка", - "addWidget": "Додати віджет", - "editWidget": "Редагувати віджет", - "zoomIn": "Збільшити масштаб", - "zoomOut": "Зменшити масштаб", - "resetView": "Скинути вигляд", - "lockLayout": "Макет замка", - "unlockLayout": "Розблокувати макет", - "noWidgets": "Клацніть правою кнопкою миші або натисніть кнопку +, щоб додати свій перший віджет", - "openFullView": "Відкрити повний перегляд", - "previewTitle": "Попередній перегляд головної сторінки", - "cancel": "Скасувати", - "save": "Зберегти", - "title_label": "Назва", - "widgetTitlePlaceholder": "Назва віджета (необов'язково)", - "url": "URL-адреса", - "imageUrl": "URL-адреса користувацького зображення", - "imageUrlHint": "Залиште поле порожнім, щоб автоматично використовувати фавіконку сайту", - "showImage": "Показати зображення", - "description": "Опис", - "color": "Колір", - "timezone": "Часовий пояс", - "invalidTimezone": "Недійсний часовий пояс. Використайте назву IANA, наприклад, America/New_York.", - "showSeconds": "Показати секунди", - "format12h": "12-годинний", - "content": "Зміст", - "backgroundColor": "Колір фону", - "links": "Посилання", - "addLink": "Додати посилання", - "linkLabel": "Мітка", - "categoryLinks": "Посилання", - "categoryInfo": "Інформація", - "categorySystem": "Система", - "copyLink": "Копіювати посилання", - "linkCopied": "Посилання скопійовано!", - "location": "Розташування", - "temperatureUnit": "Одиниця вимірювання температури", - "showForecast": "Показати 3-денний прогноз", - "scrolling": "Дозволити прокручування", - "feedUrl": "URL-адреса стрічки", - "maxItems": "Макс. кількість елементів", - "showDescription": "Показати опис", - "widgetRssName": "RSS-канал", - "noHostSelected": "Хост не вибрано", - "displayedMetrics": "Відображені показники", - "metricCpu": "Процесор", - "metricMemory": "Пам'ять", - "metricDisk": "Диск", - "metricUptime": "Час безперебійної роботи", - "metricSystem": "Система", - "metricNetwork": "Мережа", - "metricProcesses": "Процеси", - "categoryMonitoring": "Моніторинг", - "noPingUrls": "URL-адреси не налаштовано", - "pingLabel": "Мітка", - "addPingUrl": "Додати URL-адресу", - "showLatency": "Показати затримку", - "refreshInterval": "Інтервал оновлення", - "seconds": "секунди", - "filterActivityTypes": "Типи фільтрів", - "filterTypesHint": "Залиште порожнім, щоб показати всі", - "showTimestamp": "Показати позначку часу", - "uptimeUnavailable": "Час безперебійної роботи недоступний", - "uptimeLabel": "Час безперебійної роботи", - "overviewVersion": "Версія", - "overviewUpdateLabel": "Оновлення", - "overviewUpdateAvailable": "Доступне оновлення", - "overviewDatabase": "База даних", - "overviewUptime": "Час безперебійної роботи", - "noHosts": "Немає налаштованих хостів", - "hostGridHosts": "Хости", - "hostGridAllHint": "Залиште порожнім, щоб показати всіх хостів", - "columns": "Колонки", - "showIp": "Показати IP-адресу", - "layout": "Макет", - "showStatus": "Показати статус", - "noActivity": "Немає активності", - "widgetPingStatusName": "Стан пінгу", - "widgetRecentActivityName": "Нещодавня активність", - "sshTerminalNoHost": "Хост не налаштовано", - "sshTerminalConnect": "Підключитися", - "sshTerminalAutoConnect": "Автоматичне підключення під час завантаження", - "connectionTypes": "Типи з'єднань", - "calMon": "Мо", - "calTue": "Вт", - "calWed": "Ми", - "calThu": "Чт", - "calFri": "Пт", - "calSat": "Сб", - "calSun": "Су", - "startOnMonday": "Початок тижня в понеділок", - "countdownNoDate": "Цільова дата не встановлена", - "countdownPast": "Подія пройшла", - "countdownDays": "дні", - "countdownHours": "год.", - "countdownMinutes": "хв", - "countdownSeconds": "сек", - "countdownLabel": "Мітка", - "countdownLabelPlaceholder": "наприклад, день запуску", - "countdownShowDays": "Дні показу", - "countdownShowHours": "Години роботи шоу", - "targetDate": "Цільова дата", - "searchEngine": "Пошукова система", - "customSearchUrl": "URL-адреса користувацького пошуку", - "searchPlaceholder": "Пошук...", - "searchGo": "Іти", - "searchPlaceholderLabel": "Текст-заповнювач", - "searchPlaceholderHint": "Текст, що відображається всередині пошукового поля", - "openInNewTab": "Відкрити в новій вкладці", - "searchQueryPlaceholder": "Введіть запит...", - "noSearchShortcuts": "Немає налаштованих комбінацій клавіш", - "addSearchShortcut": "Додати ярлик", - "fontSize": "Розмір шрифту", - "textAlign": "Вирівнювання тексту", - "fontWeight": "Вага шрифту", - "clearColor": "Чіткий колір", - "imageFit": "Розмір зображення", - "imageLinkUrl": "URL-адреса посилання", - "noImage": "URL-адреса зображення не встановлена", - "altText": "Альтернативний текст", - "altTextPlaceholder": "Опишіть зображення", - "renderMarkdown": "Рендеринг Markdown", - "displayMode": "Режим відображення", - "displayField": "Поле відображення", - "jsonPath": "Шлях JSON", - "customApiLabel": "Мітка", - "customApiLabelPlaceholder": "наприклад, температура", - "customApiUnit": "Одиниця", - "customApiNoUrl": "URL-адреса API не налаштована", - "customApiError": "Не вдалося отримати", - "customApiNotArray": "Відповідь не є масивом", - "addService": "Додати послугу", - "showLabels": "Показати мітки", - "iconSize": "Розмір значка", - "noDashboardLinks": "Посилання на інформаційну панель не налаштовано", - "noLimit": "Без обмежень", - "sectionHeading": "Заголовок розділу", - "addSection": "Додати розділ", - "compactMode": "Компактний режим", - "selectHosts": "Виберіть хости", - "listLayout": "Список", - "gridLayout": "Сітка" + "title": "Homepage", + "addWidget": "Add Widget", + "noWidgetsInCategory": "No widgets in this category", + "editWidget": "Edit Widget", + "zoomIn": "Zoom In", + "zoomOut": "Zoom Out", + "resetView": "Reset View", + "lockLayout": "Lock Layout", + "unlockLayout": "Unlock Layout", + "noWidgets": "Right-click or click + to add your first widget", + "openFullView": "Open Full View", + "previewTitle": "Homepage Preview", + "cancel": "Cancel", + "save": "Save", + "title_label": "Title", + "widgetTitlePlaceholder": "Widget title (optional)", + "url": "URL", + "imageUrl": "Custom Image URL", + "imageUrlHint": "Leave blank to use the site favicon automatically", + "showImage": "Show Image", + "description": "Description", + "color": "Color", + "timezone": "Timezone", + "invalidTimezone": "Invalid timezone. Use an IANA name such as America/New_York", + "showSeconds": "Show seconds", + "format12h": "12-hour", + "content": "Content", + "backgroundColor": "Background Color", + "links": "Links", + "addLink": "Add Link", + "linkLabel": "Label", + "categoryLinks": "Links", + "categoryInfo": "Info", + "categorySystem": "System", + "copyLink": "Copy Link", + "linkCopied": "Link copied!", + "location": "Location", + "temperatureUnit": "Temperature Unit", + "showForecast": "Show 3-day forecast", + "scrolling": "Allow Scrolling", + "feedUrl": "Feed URL", + "maxItems": "Max Items", + "showDescription": "Show Description", + "widgetRssName": "RSS Feed", + "rssNoFeedUrl": "Configure a feed URL in widget settings", + "rssLoadError": "Could not load feed", + "rssNoItems": "No items", + "noHostSelected": "No host selected", + "displayedMetrics": "Displayed Metrics", + "metricCpu": "CPU", + "metricMemory": "Memory", + "metricDisk": "Disk", + "metricUptime": "Uptime", + "metricSystem": "System", + "metricNetwork": "Network", + "metricProcesses": "Processes", + "categoryMonitoring": "Monitoring", + "noPingUrls": "No URLs configured", + "pingLabel": "Label", + "addPingUrl": "Add URL", + "showLatency": "Show Latency", + "refreshInterval": "Refresh Interval", + "seconds": "seconds", + "filterActivityTypes": "Filter Types", + "filterTypesHint": "Leave empty to show all", + "showTimestamp": "Show Timestamp", + "uptimeUnavailable": "Uptime unavailable", + "uptimeLabel": "Uptime", + "overviewVersion": "Version", + "overviewUpdateLabel": "Update", + "overviewUpdateAvailable": "Update available", + "overviewDatabase": "Database", + "overviewUptime": "Uptime", + "noHosts": "No hosts configured", + "hostGridHosts": "Hosts", + "hostGridAllHint": "Leave empty to show all hosts", + "columns": "Columns", + "showIp": "Show IP Address", + "layout": "Layout", + "showStatus": "Show Status", + "noActivity": "No activity", + "widgetPingStatusName": "Ping Status", + "widgetRecentActivityName": "Recent Activity", + "sshTerminalNoHost": "No host configured", + "sshTerminalConnect": "Connect", + "sshTerminalAutoConnect": "Auto-connect on load", + "connectionTypes": "Connection Types", + "calMon": "Mo", + "calTue": "Tu", + "calWed": "We", + "calThu": "Th", + "calFri": "Fr", + "calSat": "Sa", + "calSun": "Su", + "startOnMonday": "Start week on Monday", + "countdownNoDate": "No target date set", + "countdownPast": "Event has passed", + "countdownDays": "days", + "countdownHours": "hrs", + "countdownMinutes": "min", + "countdownSeconds": "sec", + "countdownLabel": "Label", + "countdownLabelPlaceholder": "e.g. Launch Day", + "countdownShowDays": "Show Days", + "countdownShowHours": "Show Hours", + "targetDate": "Target Date", + "searchEngine": "Search Engine", + "customSearchUrl": "Custom Search URL", + "searchPlaceholder": "Search...", + "searchGo": "Go", + "searchPlaceholderLabel": "Placeholder Text", + "searchPlaceholderHint": "Text shown inside the search input", + "openInNewTab": "Open in New Tab", + "searchQueryPlaceholder": "Enter query...", + "noSearchShortcuts": "No shortcuts configured", + "addSearchShortcut": "Add Shortcut", + "fontSize": "Font Size", + "textAlign": "Text Align", + "fontWeight": "Font Weight", + "clearColor": "Clear Color", + "imageFit": "Image Fit", + "imageLinkUrl": "Link URL", + "noImage": "No image URL set", + "altText": "Alt Text", + "altTextPlaceholder": "Describe the image", + "renderMarkdown": "Render Markdown", + "displayMode": "Display Mode", + "displayField": "Display Field", + "jsonPath": "JSON Path", + "customApiLabel": "Label", + "customApiLabelPlaceholder": "e.g. Temperature", + "customApiUnit": "Unit", + "customApiNoUrl": "No API URL configured", + "customApiError": "Failed to fetch", + "customApiNotArray": "Response is not an array", + "addService": "Add Service", + "showLabels": "Show Labels", + "iconSize": "Icon Size", + "noDashboardLinks": "No dashboard links configured", + "noLimit": "No limit", + "sectionHeading": "Section Heading", + "addSection": "Add Section", + "compactMode": "Compact Mode", + "selectHosts": "Select Hosts", + "listLayout": "List", + "gridLayout": "Grid", + "configureUrl": "Set a URL in the widget settings", + "embeddedContent": "Embedded content", + "noBookmarks": "No bookmarks", + "noSections": "No sections set up", + "noServices": "No services set up", + "configureLocation": "Set a location in the widget settings", + "bannerTextPlaceholder": "Banner text", + "serviceNamePlaceholder": "My service" + }, + "permissions": { + "use": { + "title": "Use the homepage", + "description": "View and edit the homepage canvas and dashboard service links." + } + }, + "settings": { + "privateEndpoints": { + "label": "Allowed private hosts", + "description": "Exact private or loopback hostnames/IPs for Ping Status and Custom API widgets. Separate entries with commas or newlines; omit schemes, ports and paths. Empty blocks private destinations." + }, + "privateCertificateAuthority": { + "label": "Private certificate authority (PEM)", + "description": "Optional trusted CA bundle for allowlisted hosts. Certificate verification remains enabled. Leave empty to use the system trust store." + } } } diff --git a/plugins/homepage/locales/translated/vi_VN.json b/plugins/homepage/locales/translated/vi_VN.json index 778079e34..c4fa125f1 100644 --- a/plugins/homepage/locales/translated/vi_VN.json +++ b/plugins/homepage/locales/translated/vi_VN.json @@ -18,6 +18,7 @@ "homepage": { "title": "Trang chủ", "addWidget": "Thêm widget", + "noWidgetsInCategory": "No widgets in this category", "editWidget": "Sửa widget", "zoomIn": "Phóng to", "zoomOut": "Thu nhỏ", @@ -38,7 +39,7 @@ "description": "Mô tả", "color": "Màu sắc", "timezone": "Múi giờ", - "invalidTimezone": "Múi giờ không hợp lệ. Hãy sử dụng tên IANA như America/New_York.", + "invalidTimezone": "Invalid timezone. Use an IANA name such as America/New_York", "showSeconds": "Hiển thị giây", "format12h": "12 giờ", "content": "Nội dung", @@ -59,6 +60,9 @@ "maxItems": "Số mục tối đa", "showDescription": "Hiển thị mô tả", "widgetRssName": "Nguồn RSS", + "rssNoFeedUrl": "Configure a feed URL in widget settings", + "rssLoadError": "Could not load feed", + "rssNoItems": "No items", "noHostSelected": "Chưa chọn máy chủ", "displayedMetrics": "Chỉ số hiển thị", "metricCpu": "CPU", @@ -157,6 +161,30 @@ "compactMode": "Chế độ thu gọn", "selectHosts": "Chọn máy chủ", "listLayout": "Danh sách", - "gridLayout": "Lưới" + "gridLayout": "Lưới", + "configureUrl": "Set a URL in the widget settings", + "embeddedContent": "Embedded content", + "noBookmarks": "No bookmarks", + "noSections": "No sections set up", + "noServices": "No services set up", + "configureLocation": "Set a location in the widget settings", + "bannerTextPlaceholder": "Banner text", + "serviceNamePlaceholder": "My service" + }, + "permissions": { + "use": { + "title": "Use the homepage", + "description": "View and edit the homepage canvas and dashboard service links." + } + }, + "settings": { + "privateEndpoints": { + "label": "Allowed private hosts", + "description": "Exact private or loopback hostnames/IPs for Ping Status and Custom API widgets. Separate entries with commas or newlines; omit schemes, ports and paths. Empty blocks private destinations." + }, + "privateCertificateAuthority": { + "label": "Private certificate authority (PEM)", + "description": "Optional trusted CA bundle for allowlisted hosts. Certificate verification remains enabled. Leave empty to use the system trust store." + } } } diff --git a/plugins/homepage/locales/translated/zh_CN.json b/plugins/homepage/locales/translated/zh_CN.json index 3dfacbcda..509e59a17 100644 --- a/plugins/homepage/locales/translated/zh_CN.json +++ b/plugins/homepage/locales/translated/zh_CN.json @@ -18,6 +18,7 @@ "homepage": { "title": "主页", "addWidget": "添加小部件", + "noWidgetsInCategory": "此分类没有组件", "editWidget": "编辑小部件", "zoomIn": "放大", "zoomOut": "缩小", @@ -38,7 +39,7 @@ "description": "描述", "color": "颜色", "timezone": "时区", - "invalidTimezone": "时区无效。请使用 IANA 名称,例如 America/New_York。", + "invalidTimezone": "时区无效,请使用 America/New_York 等 IANA 时区名称", "showSeconds": "显示秒", "format12h": "12 小时制", "content": "内容", @@ -59,6 +60,9 @@ "maxItems": "最大条目数", "showDescription": "显示描述", "widgetRssName": "RSS 订阅源", + "rssNoFeedUrl": "请在组件设置中配置订阅源 URL", + "rssLoadError": "无法加载订阅源", + "rssNoItems": "暂无项目", "noHostSelected": "未选择主机", "displayedMetrics": "显示指标", "metricCpu": "CPU", @@ -157,16 +161,165 @@ "compactMode": "紧凑模式", "selectHosts": "选择主机", "listLayout": "列表", - "gridLayout": "网格" + "gridLayout": "网格", + "configureUrl": "请在组件设置中填写 URL", + "embeddedContent": "嵌入内容", + "noBookmarks": "暂无书签", + "noSections": "尚未设置分区", + "noServices": "尚未设置服务", + "configureLocation": "请在组件设置中选择位置", + "bannerTextPlaceholder": "横幅文字", + "serviceNamePlaceholder": "我的服务", + "emptyNote": "暂无笔记内容……", + "weatherLoadFailed": "无法加载“{{location}}”的天气", + "feelsLike": "体感温度 {{temperature}}", + "timezonePlaceholder": "Asia/Shanghai(留空使用本地时区)", + "notesPlaceholder": "在此填写笔记……", + "locationPlaceholder": "北京、上海、东京……", + "widgets": { + "bookmark_list": { + "name": "书签", + "description": "显示快捷链接列表" + }, + "calendar": { + "name": "日历", + "description": "显示月历并突出显示今天" + }, + "clock": { + "name": "时钟", + "description": "显示实时时钟,可配置时区" + }, + "countdown": { + "name": "倒计时", + "description": "距离目标日期和时间的倒计时" + }, + "custom_api": { + "name": "自定义 API", + "description": "获取并展示 JSON API 数据" + }, + "dashboard_links": { + "name": "仪表盘链接", + "description": "显示已保存的仪表盘服务链接" + }, + "folder": { + "name": "文件夹", + "description": "用于对组件进行视觉分组的背景卡片" + }, + "host_grid": { + "name": "主机网格", + "description": "以网格展示所有 SSH 主机的实时状态" + }, + "host_status": { + "name": "主机状态", + "description": "显示 SSH 主机的实时状态和指标" + }, + "iframe_embed": { + "name": "嵌入网页", + "description": "通过 iframe 嵌入指定 URL" + }, + "image_widget": { + "name": "图片", + "description": "显示指定 URL 的图片" + }, + "link_tree": { + "name": "链接树", + "description": "按分组展示链接与服务入口" + }, + "markdown_notes": { + "name": "Markdown 笔记", + "description": "支持 Markdown 渲染和行内编辑的笔记" + }, + "notes": { + "name": "笔记", + "description": "显示文本笔记" + }, + "ping_status": { + "name": "连通性状态", + "description": "检查 URL 或服务是否可访问" + }, + "quick_connect": { + "name": "快速连接", + "description": "为主机打开终端、文件、Docker、隧道等功能" + }, + "recent_activity": { + "name": "最近活动", + "description": "显示最近的终端、Docker、文件和隧道活动" + }, + "rss_feed": { + "name": "RSS 订阅源", + "description": "显示 RSS 或 Atom 订阅源的内容" + }, + "search_bar": { + "name": "搜索栏", + "description": "快速使用 Google、DuckDuckGo、Bing 或自定义搜索引擎" + }, + "search_links": { + "name": "搜索快捷方式", + "description": "快速使用不同搜索引擎" + }, + "service_grid": { + "name": "服务网格", + "description": "以包含图标和链接的网格展示服务" + }, + "service_link": { + "name": "服务链接", + "description": "点击卡片即可打开服务 URL" + }, + "ssh_terminal": { + "name": "SSH 终端", + "description": "连接到指定主机的内嵌 SSH 终端" + }, + "system_overview": { + "name": "系统概览", + "description": "显示 Termix 系统状态概览" + }, + "termix_uptime": { + "name": "Termix 运行时间", + "description": "显示 Termix 服务器已运行的时长" + }, + "text_banner": { + "name": "文字横幅", + "description": "用于分区和标题的样式化文字标签" + }, + "weather": { + "name": "天气", + "description": "显示指定地点的实时天气" + }, + "docker_widget": { + "name": "Docker 管理器", + "description": "用于管理指定主机 Docker 容器的内嵌管理器" + }, + "file_manager_widget": { + "name": "文件管理器", + "description": "用于管理指定主机文件的内嵌 SFTP 管理器" + }, + "tunnel_widget": { + "name": "隧道管理器", + "description": "用于管理指定主机 SSH 隧道的内嵌管理器" + }, + "metrics_chart": { + "name": "指标图表", + "description": "显示主机 CPU、内存、磁盘或网络的历史指标图表" + } + } + }, + "permissions": { + "use": { + "title": "使用首页", + "description": "查看和编辑首页画布及仪表盘服务链接。" + } }, "settings": { "privateEndpoints": { - "label": "允许访问的私网主机", - "description": "允许 Ping 状态和自定义 API 组件访问的私网或回环主机名/IP。用逗号或换行分隔,不包含协议、端口或路径。留空则禁止访问私网。" + "label": "允许访问的内网主机", + "description": "供连通性状态和自定义 API 组件使用的精确内网或回环主机名/IP。用逗号或换行分隔,不包含协议、端口和路径。留空会阻止访问内网目标。" }, "privateCertificateAuthority": { - "label": "私网证书颁发机构(PEM)", - "description": "可选的可信 CA 证书,仅用于白名单中的主机。仍会验证证书;留空使用系统信任库。" + "label": "私有证书颁发机构(PEM)", + "description": "可选的受信任 CA 证书包,用于允许列表中的主机。证书验证保持开启,留空则使用系统信任库。" } + }, + "plugin": { + "name": "首页" } } diff --git a/plugins/homepage/locales/translated/zh_TW.json b/plugins/homepage/locales/translated/zh_TW.json index bbb938a72..127fd17a5 100644 --- a/plugins/homepage/locales/translated/zh_TW.json +++ b/plugins/homepage/locales/translated/zh_TW.json @@ -18,6 +18,7 @@ "homepage": { "title": "首頁", "addWidget": "新增小工具", + "noWidgetsInCategory": "No widgets in this category", "editWidget": "編輯小工具", "zoomIn": "放大", "zoomOut": "縮小", @@ -38,7 +39,7 @@ "description": "描述", "color": "顏色", "timezone": "時區", - "invalidTimezone": "時區無效。請使用 IANA 名稱,例如 America/New_York。", + "invalidTimezone": "Invalid timezone. Use an IANA name such as America/New_York", "showSeconds": "顯示秒數", "format12h": "12 小時制", "content": "內容", @@ -59,6 +60,9 @@ "maxItems": "最大項目數", "showDescription": "顯示描述", "widgetRssName": "RSS 摘要", + "rssNoFeedUrl": "Configure a feed URL in widget settings", + "rssLoadError": "Could not load feed", + "rssNoItems": "No items", "noHostSelected": "未選取主機", "displayedMetrics": "顯示的指標", "metricCpu": "CPU", @@ -157,6 +161,30 @@ "compactMode": "精簡模式", "selectHosts": "選取主機", "listLayout": "清單", - "gridLayout": "格線" + "gridLayout": "格線", + "configureUrl": "Set a URL in the widget settings", + "embeddedContent": "Embedded content", + "noBookmarks": "No bookmarks", + "noSections": "No sections set up", + "noServices": "No services set up", + "configureLocation": "Set a location in the widget settings", + "bannerTextPlaceholder": "Banner text", + "serviceNamePlaceholder": "My service" + }, + "permissions": { + "use": { + "title": "Use the homepage", + "description": "View and edit the homepage canvas and dashboard service links." + } + }, + "settings": { + "privateEndpoints": { + "label": "Allowed private hosts", + "description": "Exact private or loopback hostnames/IPs for Ping Status and Custom API widgets. Separate entries with commas or newlines; omit schemes, ports and paths. Empty blocks private destinations." + }, + "privateCertificateAuthority": { + "label": "Private certificate authority (PEM)", + "description": "Optional trusted CA bundle for allowlisted hosts. Certificate verification remains enabled. Leave empty to use the system trust store." + } } } diff --git a/plugins/homepage/src/frontend/dialogs/AddWidgetMenu.tsx b/plugins/homepage/src/frontend/dialogs/AddWidgetMenu.tsx index 53e1d8773..8a3763674 100644 --- a/plugins/homepage/src/frontend/dialogs/AddWidgetMenu.tsx +++ b/plugins/homepage/src/frontend/dialogs/AddWidgetMenu.tsx @@ -140,14 +140,18 @@ export function AddWidgetMenu({ state, onAdd, onClose }: AddWidgetMenuProps) { {type.labelComponent ? ( ) : ( - type.name + t(`homepage.widgets.${type.id}.name`, { + defaultValue: type.name, + }) )} {type.labelComponent ? ( ) : ( - type.description + t(`homepage.widgets.${type.id}.description`, { + defaultValue: type.description, + }) )} diff --git a/plugins/homepage/src/frontend/dialogs/ClockEditForm.tsx b/plugins/homepage/src/frontend/dialogs/ClockEditForm.tsx index 7a1833739..5d306fb47 100644 --- a/plugins/homepage/src/frontend/dialogs/ClockEditForm.tsx +++ b/plugins/homepage/src/frontend/dialogs/ClockEditForm.tsx @@ -23,7 +23,7 @@ export function ClockEditForm({ onChange={(e) => onChange({ ...config, timezone: e.target.value || undefined }) } - placeholder="America/New_York (leave blank for local)" + placeholder={t("homepage.timezonePlaceholder")} aria-invalid={invalidTimezone} className={ invalidTimezone ? "h-8 text-sm border-destructive" : "h-8 text-sm" diff --git a/plugins/homepage/src/frontend/dialogs/NotesEditForm.tsx b/plugins/homepage/src/frontend/dialogs/NotesEditForm.tsx index c75e3b476..61195b04a 100644 --- a/plugins/homepage/src/frontend/dialogs/NotesEditForm.tsx +++ b/plugins/homepage/src/frontend/dialogs/NotesEditForm.tsx @@ -16,7 +16,7 @@ export function NotesEditForm({