Files
TREK/shared/src/i18n/vi/admin.ts
T
Maurice b3d69aa760 feat(places): record which search result was picked, on this instance only
The corpus behind "is our own index good enough to replace Nominatim".
When somebody searches and then picks a result, the client posts the query,
the rank and the pick. Nothing else: no user, no trip, no session, and
coordinates only to three decimals.

Deliberately decoupled from the search endpoint. Correlating a response
with a later pick would mean handing out a ticket on POST /api/maps/search
and threading it through all fifteen call sites; the client already holds
everything the row needs at the moment of the pick.

Evaluation happens offline afterwards: export the corpus, run it against a
candidate index, count how often the pick came back in the top five. That
is why collection can start before such an index exists, which is the whole
point, because the corpus needs weeks of real use and the index needs a
server, and those two waits should not be serial.

Off unless an admin switches it on, and it reads === 'true' rather than
!== 'false'. The three older places switches fail open because a migration
backfilled a row for installs already using them; nothing uses this one, so
an instance that upgrades and never visits the admin panel logs nothing.

Reading is admin only, retention is 180 days, and the switch state is on the
unauthenticated app-config endpoint on purpose: whether an instance records
what its users search for is something a visitor may know before logging in.
2026-09-07 14:05:33 +02:00

735 lines
57 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { TranslationStrings } from '../types';
const admin: TranslationStrings = {
'admin.notifications.title': 'Thông báo',
'admin.notifications.hint': 'Chọn một kênh thông báo. Chỉ có một người có thể hoạt động tại một thời điểm.',
'admin.notifications.none': 'Tắt',
'admin.notifications.email': 'Email (SMTP)',
'admin.notifications.webhook': 'Webhook',
'admin.notifications.ntfy': 'Ntfy',
'admin.ntfy.hint':
'Cho phép người dùng định cấu hình chủ đề thú vị của riêng họ cho thông báo đẩy. Đặt máy chủ mặc định bên dưới để điền trước cài đặt người dùng.',
'admin.notifications.save': 'Lưu cài đặt thông báo',
'admin.notifications.saved': 'Đã lưu cài đặt thông báo',
'admin.notifications.testWebhook': 'Gửi webhook thử nghiệm',
'admin.notifications.testWebhookSuccess': 'Kiểm tra webhook đã được gửi thành công',
'admin.notifications.testWebhookFailed': 'Kiểm tra webhook không thành công',
'admin.notifications.testNtfy': 'Gửi bài kiểm tra',
'admin.notifications.testNtfySuccess': 'Kiểm tra ntfy đã được gửi thành công',
'admin.notifications.testNtfyFailed': 'Kiểm tra ntfy không thành công',
'admin.notifications.emailPanel.title': 'Email (SMTP)',
'admin.notifications.webhookPanel.title': 'Webhook',
'admin.notifications.inappPanel.title': 'Trong ứng dụng',
'admin.notifications.inappPanel.hint': 'Thông báo trong ứng dụng luôn hoạt động và không thể tắt trên toàn cầu.',
'admin.notifications.adminWebhookPanel.title': 'Webhook quản trị viên',
'admin.notifications.adminWebhookPanel.hint':
'Webhook này được sử dụng riêng cho thông báo của quản trị viên (ví dụ: cảnh báo phiên bản). Nó tách biệt với webhooks của mỗi người dùng và luôn kích hoạt khi được đặt.',
'admin.notifications.adminWebhookPanel.saved': 'Đã lưu webhook của quản trị viên URL',
'admin.notifications.adminWebhookPanel.testSuccess': 'Kiểm tra webhook đã được gửi thành công',
'admin.notifications.adminWebhookPanel.testFailed': 'Kiểm tra webhook không thành công',
'admin.notifications.adminWebhookPanel.alwaysOnHint': 'Webhook quản trị luôn kích hoạt khi URL được định cấu hình',
'admin.notifications.adminNtfyPanel.title': 'Quản trị viên Ntfy',
'admin.notifications.adminNtfyPanel.hint':
'Chủ đề ntfy này được sử dụng riêng cho thông báo của quản trị viên (ví dụ: cảnh báo phiên bản). Nó tách biệt với các chủ đề của mỗi người dùng và luôn kích hoạt khi được định cấu hình.',
'admin.notifications.adminNtfyPanel.serverLabel': 'Ntfy Máy chủ URL',
'admin.notifications.adminNtfyPanel.serverHint':
'Cũng được sử dụng làm máy chủ mặc định cho thông báo ntfy của người dùng. Để trống để mặc định là ntfy.sh. Người dùng có thể ghi đè điều này trong cài đặt của riêng họ.',
'admin.notifications.adminNtfyPanel.serverPlaceholder': 'https://ntfy.sh',
'admin.notifications.adminNtfyPanel.topicLabel': 'Chủ đề quản trị',
'admin.notifications.adminNtfyPanel.topicPlaceholder': 'trek-admin-cảnh báo',
'admin.notifications.adminNtfyPanel.tokenLabel': 'Mã thông báo truy cập (tùy chọn)',
'admin.notifications.adminNtfyPanel.tokenCleared': 'Đã xóa mã thông báo truy cập của quản trị viên',
'admin.notifications.adminNtfyPanel.saved': 'Đã lưu cài đặt quản trị viên ntfy',
'admin.notifications.adminNtfyPanel.test': 'Gửi bài kiểm tra',
'admin.notifications.adminNtfyPanel.testSuccess': 'Kiểm tra ntfy đã được gửi thành công',
'admin.notifications.adminNtfyPanel.testFailed': 'Kiểm tra ntfy không thành công',
'admin.notifications.adminNtfyPanel.alwaysOnHint': 'Quản trị viên ntfy luôn kích hoạt khi chủ đề được định cấu hình',
'admin.notifications.adminNotificationsHint':
'Định cấu hình kênh nào gửi thông báo chỉ dành cho quản trị viên (ví dụ: cảnh báo phiên bản).',
'admin.notifications.tripReminders.title': 'Lời nhắc chuyến đi',
'admin.notifications.tripReminders.hint':
'Gửi thông báo nhắc nhở trước khi chuyến đi bắt đầu (yêu cầu phải đặt ngày nhắc nhở cho chuyến đi).',
'admin.notifications.tripReminders.enabled': 'Đã bật lời nhắc chuyến đi',
'admin.notifications.tripReminders.disabled': 'Đã tắt lời nhắc chuyến đi',
'admin.smtp.title': 'Email & Thông báo',
'admin.smtp.hint': 'Cấu hình SMTP để gửi thông báo qua email.',
'admin.smtp.testButton': 'Gửi email kiểm tra',
'admin.webhook.hint':
'Cho phép người dùng định cấu hình URL webhook của riêng họ để nhận thông báo (Discord, Slack, v.v.).',
'admin.smtp.testSuccess': 'Email kiểm tra đã được gửi thành công',
'admin.smtp.testFailed': 'Email kiểm tra không thành công',
'admin.title': 'Sự quản lý',
'admin.subtitle': 'Quản lý người dùng và cài đặt hệ thống',
'admin.tabs.users': 'Người dùng',
'admin.tabs.categories': 'Thể loại',
'admin.tabs.backup': 'Sao lưu',
'admin.tabs.notifications': 'Thông báo',
'admin.tabs.audit': 'Lịch sử',
'admin.stats.users': 'Người dùng',
'admin.stats.trips': 'Chuyến đi',
'admin.stats.places': 'Địa điểm',
'admin.stats.photos': 'Ảnh',
'admin.stats.files': 'Tập tin',
'admin.table.user': 'người dùng',
'admin.table.email': 'Email',
'admin.table.role': 'Vai trò',
'admin.table.created': 'Tạo',
'admin.table.lastLogin': 'Đăng nhập lần cuối',
'admin.table.actions': 'hành động',
'admin.you': '(Bạn)',
'admin.editUser': 'Chỉnh sửa người dùng',
'admin.newPassword': 'Mật khẩu mới',
'admin.newPasswordHint': 'Để trống để giữ mật khẩu hiện tại',
'admin.deleteUser': 'Xóa người dùng "{name}"? Tất cả các chuyến đi sẽ bị xóa vĩnh viễn.',
'admin.deleteUserTitle': 'Xóa người dùng',
'admin.newPasswordPlaceholder': 'Nhập mật khẩu mới…',
'admin.toast.loadError': 'Không tải được dữ liệu quản trị viên',
'admin.toast.userUpdated': 'Đã cập nhật người dùng',
'admin.toast.updateError': 'Không thể cập nhật',
'admin.toast.userDeleted': 'Người dùng đã xóa',
'admin.toast.deleteError': 'Không thể xóa',
'admin.toast.cannotDeleteSelf': 'Không thể xóa tài khoản của chính bạn',
'admin.toast.userCreated': 'Người dùng đã tạo',
'admin.toast.createError': 'Không tạo được người dùng',
'admin.toast.fieldsRequired': 'Tên người dùng, email và mật khẩu là bắt buộc',
'admin.createUser': 'Tạo người dùng',
'admin.invite.title': 'Mời liên kết',
'admin.invite.subtitle': 'Tạo liên kết đăng ký một lần',
'admin.invite.create': 'Tạo liên kết',
'admin.invite.createAndCopy': 'Tạo & Sao chép',
'admin.invite.empty': 'Chưa có liên kết mời nào được tạo',
'admin.invite.maxUses': 'Tối đa. Công dụng',
'admin.invite.expiry': 'Hết hạn sau',
'admin.invite.uses': 'đã sử dụng',
'admin.invite.expiresAt': 'hết hạn',
'admin.invite.createdBy': 'qua',
'admin.invite.active': 'Tích cực',
'admin.invite.expired': 'Hết hạn',
'admin.invite.usedUp': 'Đã sử dụng hết',
'admin.invite.copied': 'Đã sao chép liên kết lời mời vào bảng nhớ tạm',
'admin.invite.copyLink': 'Sao chép liên kết',
'admin.invite.deleted': 'Đã xóa liên kết mời',
'admin.invite.createError': 'Không tạo được liên kết mời',
'admin.invite.deleteError': 'Không xóa được liên kết mời',
'admin.tabs.settings': 'Cài đặt',
'admin.allowRegistration': 'Cho phép đăng ký',
'admin.allowRegistrationHint': 'Người dùng mới có thể tự đăng ký',
'admin.authMethods': 'Phương thức xác thực',
'admin.passwordLogin': 'Mật khẩu Đăng nhập',
'admin.passwordLoginHint': 'Cho phép người dùng đăng nhập bằng email và mật khẩu',
'admin.passwordRegistration': 'Đăng ký mật khẩu',
'admin.passwordRegistrationHint': 'Cho phép người dùng mới đăng ký bằng email và mật khẩu',
'admin.oidcLogin': 'SSO Đăng nhập',
'admin.oidcLoginHint': 'Cho phép người dùng đăng nhập bằng SSO',
'admin.oidcRegistration': 'SSO Tự động cấp phép',
'admin.oidcRegistrationHint': 'Tự động tạo tài khoản cho người dùng SSO mới',
'admin.envOverrideHint':
'Cài đặt đăng nhập mật khẩu được kiểm soát bởi biến môi trường OIDC_ONLY và không thể thay đổi tại đây.',
'admin.lockoutWarning': 'Ít nhất một phương thức đăng nhập phải được bật',
'admin.requireMfa': 'Yêu cầu xác thực hai yếu tố (2FA)',
'admin.requireMfaHint': 'Người dùng không có 2FA phải hoàn tất thiết lập trong Cài đặt trước khi sử dụng ứng dụng.',
'admin.apiKeys': 'API Key',
'admin.apiKeysHint': 'Dữ liệu địa điểm đến từ đâu. Chỉ mục TREK không cần khóa; hai nhà cung cấp bên dưới là tùy chọn.',
'admin.trekApi.badgeDefault': 'Nguồn mặc định khuyến nghị',
'admin.googleCaveat.badge': 'Không khuyến nghị',
'admin.googleCaveat.body':
'TREK là phần mềm nguồn mở và ở đây chúng tôi không trung lập. Ở quy mô này, đánh giá và ảnh của các cửa hàng thông thường chỉ có ở Google, và đó là độc quyền. Ô này có mặt vì không có lựa chọn khác, không phải vì chúng tôi khuyến nghị. Khi đó mọi truy vấn đều đi tới Google.',
'admin.trekApi.badgeSoon':
'Sắp có',
'admin.trekApi.badgeActive':
'Đang bật',
'admin.trekApi.tagline':
'Chỉ mục địa điểm của riêng TREK. Tìm kiếm không cần khóa Google, không hạn mức, và không ai đếm lượt tìm của bạn.',
'admin.trekApi.factPlaces':
'73,6 triệu địa điểm trên toàn thế giới',
'admin.trekApi.factNoKey':
'Không khóa, không hạn mức',
'admin.trekApi.factOffline':
'Gói theo quốc gia dùng được ngoại tuyến',
'admin.trekApi.factPrivacy':
'Không bao giờ ghi lại nội dung tìm kiếm',
'admin.trekApi.more':
'Bên trong có gì',
'admin.trekApi.fieldPhone':
'Điện thoại',
'admin.trekApi.fieldStableId':
'Mã định danh ổn định',
'admin.trekApi.includedNote':
'Mô tả lấy từ trang web của chính địa điểm, giờ mở cửa lấy từ OpenStreetMap ở nơi đã được điền.',
'admin.trekApi.notRatings':
'Đánh giá',
'admin.trekApi.notPhotos':
'Ảnh của cửa hàng thông thường',
'admin.trekApi.notIncludedNote':
'Không nguồn mở nào có cả hai, với bất kỳ giá nào. Với hai thứ đó khóa Google vẫn là con đường duy nhất.',
'admin.trekApi.sourcesLabel':
'Nguồn',
'admin.trekApi.sourcesNote':
'Mọi trường trong phản hồi đều cho biết nó đến từ nguồn nào.',
'admin.trekApi.included':
'Có',
'admin.trekApi.notIncluded':
'Không có',
'admin.mapsKey': 'Google Maps API Key',
'admin.mapsKeyHint': 'Cần thiết cho tìm kiếm địa điểm. Truy cập tại console.cloud.google.com',
'admin.mapsKeyHintLong':
'Không có khóa API của Google thì TREK API được khuyến nghị sẽ được dùng. Có khóa thì có thể tải thêm ảnh, đánh giá và giờ mở cửa. Tạo khóa tại console.cloud.google.com.',
'admin.recommended': 'Khuyến khích',
'admin.weatherKey': 'OpenWeatherMap API Key',
'admin.weatherKeyHint': 'Đối với dữ liệu thời tiết. Miễn phí tại openweathermap.org',
'admin.unsplashKey': 'Khóa API Unsplash',
'admin.unsplashKeyHint': 'Đối với tìm kiếm hình ảnh. Miễn phí tại unsplash.com/developers',
'admin.validateKey': 'Bài kiểm tra',
'admin.keyValid': 'Đã kết nối',
'admin.keyInvalid': 'Không hợp lệ',
'admin.keySaved': 'Đã lưu khóa API',
'admin.oidcTitle': 'Đăng nhập một lần (OIDC)',
'admin.oidcSubtitle':
'Cho phép đăng nhập thông qua các nhà cung cấp bên ngoài như Google, Apple, Authentik hoặc Keycloak.',
'admin.oidcDisplayName': 'Tên hiển thị',
'admin.oidcIssuer': 'Nhà phát hành URL',
'admin.oidcIssuerHint': 'Nhà phát hành kết nối OpenID URL của nhà cung cấp. ví dụ. https://accounts.google.com',
'admin.oidcSaved': 'Đã lưu cấu hình OIDC',
'admin.oidcOnlyMode': 'Vô hiệu hóa xác thực mật khẩu',
'admin.oidcOnlyModeHint': 'Khi được bật, chỉ cho phép đăng nhập SSO. Đăng nhập và đăng ký dựa trên mật khẩu bị chặn.',
'admin.fileTypes': 'Các loại tệp được phép',
'admin.fileTypesHint': 'Định cấu hình loại tệp mà người dùng có thể tải lên.',
'admin.fileTypesFormat':
'Các phần mở rộng được phân tách bằng dấu phẩy (ví dụ: jpg,png,pdf,doc). Sử dụng * để cho phép tất cả các loại.',
'admin.fileTypesSaved': 'Đã lưu cài đặt loại tệp',
'admin.googleOptions': 'Khóa được dùng vào việc gì',
'admin.googleOptionsSummary': '{on}/{total} đang bật',
'admin.placesPhotos.title': 'Đặt ảnh',
'admin.placesPhotos.subtitle':
'Tìm nạp ảnh từ Google Địa điểm API. Tắt để lưu hạn ngạch API. Hình ảnh của Wikimedia không bị ảnh hưởng.',
'admin.placesAutocomplete.title': 'Đặt Tự động hoàn thành',
'admin.placesAutocomplete.subtitle':
'Sử dụng Google Địa điểm API để có các đề xuất tìm kiếm. Tắt để lưu hạn ngạch API.',
'admin.placesDetails.title': 'Chi tiết địa điểm',
'admin.placesDetails.subtitle':
'Tìm nạp thông tin chi tiết về địa điểm (giờ, xếp hạng, trang web) từ Google Địa điểm API. Tắt để lưu hạn ngạch API.',
'admin.placesEnrich.title': 'Làm giàu địa điểm',
'admin.placesEnrich.subtitle':
'Hiển thị hình ảnh và mô tả khi thêm địa điểm. Wikipedia và OpenStreetMap luôn được dùng; Google được thêm vào khi bật Ảnh địa điểm hoặc Chi tiết địa điểm.',
'admin.transitProvider.title': 'Nhà cung cấp giao thông công cộng',
'admin.transitProvider.subtitle': 'Dịch vụ nào trả lời tìm kiếm giao thông công cộng.',
'admin.transitProvider.transitous': 'Transitous (miễn phí)',
'admin.transitProvider.google': 'Google',
'admin.transitProvider.transitousHint': 'Nguồn GTFS cộng đồng. Miễn phí và không cần khóa, phủ sóng tốt nhất ở châu Âu.',
'admin.transitProvider.googleHint': 'Dùng khóa Google ở trên, cho những khu vực Transitous không có dữ liệu. Tính phí theo mỗi lượt tìm kiếm — khi chưa đặt khóa thì vẫn dùng Transitous.',
'admin.transitProvider.noKeyWarning': 'Đã chọn Google, nhưng chưa cấu hình khóa Google — tìm kiếm giao thông vẫn dùng Transitous. Thêm khóa ở mục Khóa API phía trên.',
'admin.transitProvider.personalKeyWarning': 'Chỉ khóa Google của riêng bạn được đặt, nên tìm kiếm của các thành viên khác vẫn quay về Transitous. Lưu khóa ở trên với quyền quản trị để áp dụng cho toàn bộ máy chủ.',
'admin.placeShadow.title': 'Nhật ký tìm kiếm địa điểm',
'admin.placeShadow.subtitle':
'Ghi lại kết quả tìm kiếm nào đã được chọn, để sau này có thể đánh giá một chỉ mục địa điểm khác bằng những lượt tìm kiếm thật. Không có gì rời khỏi máy chủ này, và quản trị viên có thể xuất hoặc xóa nhật ký bất cứ lúc nào.',
'admin.bagTracking.title': 'Theo dõi túi',
'admin.bagTracking.subtitle': 'Cho phép phân bổ trọng lượng và túi để đóng gói các mặt hàng',
'admin.collab.chat.title': 'Trò chuyện',
'admin.collab.chat.subtitle': 'Nhắn tin theo thời gian thực để cộng tác trong chuyến đi',
'admin.collab.notes.title': 'Ghi chú',
'admin.collab.notes.subtitle': 'Ghi chú và tài liệu được chia sẻ',
'admin.collab.polls.title': 'Thăm dò ý kiến',
'admin.collab.polls.subtitle': 'Thăm dò ý kiến ​​​​nhóm và bỏ phiếu',
'admin.collab.whatsnext.title': 'Tiếp theo là gì',
'admin.collab.whatsnext.subtitle': 'Đề xuất hoạt động và các bước tiếp theo',
'admin.tabs.config': 'Cá nhân hóa',
'admin.tabs.defaults': 'Mặc định của người dùng',
'admin.defaultSettings.title': 'Cài đặt người dùng mặc định',
'admin.defaultSettings.description':
'Đặt mặc định cho toàn phiên bản. Người dùng chưa thay đổi cài đặt sẽ thấy các giá trị này. Những thay đổi của riêng họ luôn được ưu tiên.',
'admin.defaultSettings.saved': 'Đã lưu mặc định',
'admin.defaultSettings.reset': 'Đặt lại về mặc định tích hợp',
'admin.defaultSettings.resetToBuiltIn': 'cài lại',
'admin.defaultSettings.mapProvider': 'Công cụ bản đồ',
'admin.defaultSettings.mapProviderHint':
'Bản đồ mặc định cho mọi người trong trường hợp này. Mỗi người dùng vẫn có thể ghi đè nó trong cài đặt của riêng họ.',
'admin.defaultSettings.providerLeaflet': 'Tiêu chuẩn (miễn phí)',
'admin.defaultSettings.providerMapbox': 'Mapbox (3D)',
'admin.defaultSettings.providerMapLibre': 'MapLibre (OpenFreeMap)',
'admin.defaultSettings.mapboxToken': 'Mã thông báo Mapbox được chia sẻ',
'admin.defaultSettings.mapboxTokenHint':
'Được sử dụng cho mọi người dùng chưa nhập mã thông báo của riêng họ — vì vậy toàn bộ phiên bản sẽ nhận được Mapbox mà không chia sẻ khóa riêng lẻ. Được lưu trữ được mã hóa.',
'admin.defaultSettings.mapboxStyle': 'Kiểu bản đồ',
'admin.defaultSettings.mapboxStylePlaceholder': 'Chọn một phong cách…',
'admin.defaultSettings.mapbox3d': 'Tòa nhà và địa hình 3D',
'admin.defaultSettings.mapboxQuality': 'Chế độ chất lượng cao',
'admin.defaultSettings.cartoKey': 'Khóa CARTO được chia sẻ',
'admin.defaultSettings.cartoKeyHint':
'Được sử dụng cho mọi người dùng chưa nhập khóa của riêng họ, vì vậy toàn bộ phiên bản nhận được ô bản đồ CARTO không có hình mờ. Được lưu trữ dưới dạng mã hóa.',
'admin.tabs.templates': 'Mẫu đóng gói',
'admin.packingTemplates.title': 'Mẫu đóng gói',
'admin.packingTemplates.subtitle': 'Tạo danh sách đóng gói có thể tái sử dụng cho chuyến đi của bạn',
'admin.packingTemplates.create': 'Mẫu mới',
'admin.packingTemplates.namePlaceholder': 'Tên mẫu (ví dụ: Kỳ nghỉ ở bãi biển)',
'admin.packingTemplates.empty': 'Chưa có mẫu nào được tạo',
'admin.packingTemplates.items': 'mặt hàng',
'admin.packingTemplates.categories': 'Thể loại',
'admin.packingTemplates.itemName': 'Tên mặt hàng',
'admin.packingTemplates.itemCategory': 'Loại',
'admin.packingTemplates.categoryName': 'Tên danh mục (ví dụ: Quần áo)',
'admin.packingTemplates.addCategory': 'Thêm danh mục',
'admin.packingTemplates.created': 'Đã tạo mẫu',
'admin.packingTemplates.deleted': 'Đã xóa mẫu',
'admin.packingTemplates.loadError': 'Không tải được mẫu',
'admin.packingTemplates.createError': 'Không tạo được mẫu',
'admin.packingTemplates.deleteError': 'Không xóa được mẫu',
'admin.packingTemplates.deleteCategoryError': 'Không thể xóa danh mục',
'admin.packingTemplates.deleteItemError': 'Không thể xóa mục',
'admin.packingTemplates.saveError': 'Không lưu được',
'admin.tabs.addons': 'Tiện ích bổ sung',
'admin.tabs.plugins': 'Plugins',
'admin.tabs.storage': 'Lưu trữ',
'admin.plugins.rescan': 'Quét lại',
'admin.plugins.rescanned': 'Đã quét lại thư mục plugin',
'admin.plugins.upload': 'Tải plugin lên',
'admin.plugins.dropToUpload': 'Thả tệp .zip plugin để cài đặt',
'admin.plugins.uploaded': 'Đã tải lên plugin “{name}” — kích hoạt để chạy',
'admin.plugins.sideloaded': 'Tải thủ công',
'admin.plugins.devLinkBadge': 'Dev-Link',
'admin.plugins.devLinkHint':
'Được tải từ thư mục build cục bộ và tải lại nóng với dữ liệu thật — chỉ dành cho phát triển',
'admin.plugins.devLinkTitle': 'Liên kết plugin cục bộ',
'admin.plugins.devLinkPathPlaceholder': '/absolute/path/to/your/plugin',
'admin.plugins.devLinkButton': 'Liên kết',
'admin.plugins.devLinkLinked': '{id} đã liên kết — kích hoạt để chạy',
'admin.plugins.sideloadedHint': 'Đã tải lên thủ công — không từ kho đăng ký, chưa ký và chưa duyệt',
'admin.plugins.browse': 'Duyệt plugin',
'admin.plugins.installed': 'Đã cài đặt',
'admin.plugins.install': 'Cài đặt',
'admin.plugins.registryEmpty': 'Chưa có plugin nào trong kho đăng ký.',
'admin.plugins.actionError': 'Thao tác không thành công',
'admin.plugins.activate': 'Kích hoạt',
'admin.plugins.activated': 'Đã kích hoạt plugin',
'admin.plugins.deactivate': 'Hủy kích hoạt',
'admin.plugins.deactivated': 'Đã hủy kích hoạt plugin',
'admin.plugins.viewErrors': 'Xem nhật ký lỗi',
'admin.plugins.errorLog': 'Nhật ký lỗi',
'admin.plugins.allowedHosts': 'Máy chủ được phép',
'admin.plugins.allowedHosts.hint':
'Plugin này kết nối tới một dịch vụ mà chỉ bạn mới biết tên (máy chủ tự lưu trữ). Hãy thêm các máy chủ mà nó được phép truy cập — ngoài ra không có gì khác.',
'admin.plugins.allowedHosts.none': 'Chưa thêm máy chủ nào.',
'admin.plugins.allowedHosts.unsupported':
'Plugin này không dùng máy chủ do người vận hành cung cấp. Danh sách được cố định trong manifest.',
'admin.plugins.allowedHosts.restartNote': 'Lưu sẽ khởi động lại plugin để nó dùng danh sách mới.',
'admin.plugins.allowedHosts.add': 'Thêm máy chủ được phép',
'admin.plugins.allowedHosts.count': '{n} máy chủ được phép',
'admin.plugins.operatorEgressPill': '+ máy chủ bạn thêm',
'admin.plugins.operatorEgressHint':
'Plugin này kết nối tới một dịch vụ mà chỉ bạn mới biết tên (máy chủ tự lưu trữ). Sau khi cài, hãy thêm máy chủ tại ⋯ → Máy chủ được phép. Ngoài ra không có gì khác.',
'admin.plugins.noErrors': 'Chưa ghi nhận lỗi nào.',
'admin.plugins.uninstalled': 'Đã gỡ cài đặt plugin',
'admin.plugins.uninstallTitle': 'Gỡ cài đặt plugin?',
'admin.plugins.uninstallBody':
'Thao tác này sẽ dừng plugin, xóa mã nguồn và toàn bộ dữ liệu của nó. Không thể hoàn tác.',
'admin.plugins.status.starting': 'Đang khởi động…',
'admin.plugins.type.widget': 'Widget',
'admin.plugins.type.page': 'Trang',
'admin.plugins.type.integration': 'Tích hợp',
'admin.plugins.type.trip-page': 'Trang chuyến đi',
'admin.plugins.reviewed': 'Đã kiểm duyệt',
'admin.plugins.unreviewed': 'Chưa kiểm duyệt',
'admin.plugins.updated': 'Đã cập nhật plugin',
'admin.plugins.updateTo': 'Cập nhật → v{version}',
'admin.plugins.enabledToggle': 'Bật plugin',
'plugins.notFound': 'Không tìm thấy plugin',
'plugins.frameLoadFailed': 'This plugin could not be loaded.',
'admin.plugins.title': 'Plugins',
'admin.plugins.subtitle': 'Cài đặt và quản lý các plugin bên thứ ba trên hệ thống của bạn.',
'admin.plugins.disabledTitle': 'Plugin đang bị tắt',
'admin.plugins.disabledBody':
'Môi trường chạy plugin đang bị tắt (TREK_PLUGINS_ENABLED). Không plugin nào có thể chạy cho đến khi quản trị viên bật nó trong cấu hình máy chủ.',
'admin.plugins.empty': 'Chưa cài đặt plugin nào.',
'admin.plugins.loadError': 'Không thể tải danh sách plugin.',
'admin.plugins.scaffoldNote':
'Tính năng cài đặt và kích hoạt plugin sẽ có trong bản cập nhật sau. Hiện bảng này chỉ liệt kê các plugin đã cài đặt.',
'admin.plugins.status.active': 'Đang hoạt động',
'admin.plugins.status.inactive': 'Không hoạt động',
'admin.plugins.status.disabled': 'Đã tắt',
'admin.plugins.status.error': 'Lỗi',
'admin.plugins.status.incompatible': 'Không tương thích',
'admin.plugins.details': 'Chi tiết',
'admin.plugins.detailError': 'Không thể tải chi tiết plugin.',
'admin.plugins.permissionsTitle': 'Quyền',
'admin.plugins.noPermissions': 'Plugin này không yêu cầu quyền đặc biệt nào.',
'admin.plugins.egressNote': 'Có thể kết nối tới: {hosts}',
'admin.plugins.setupTitle': 'Thiết lập',
'admin.plugins.noSetup': 'Hoạt động ngay — không cần cấu hình gì.',
'admin.plugins.scope.instance': 'Toàn hệ thống',
'admin.plugins.scope.user': 'Theo từng người dùng',
'admin.plugins.fieldRequired': 'Bắt buộc',
'admin.plugins.sourceRepo': 'Kho mã nguồn',
'admin.plugins.reportIssue': 'Báo cáo sự cố',
'admin.plugins.homepage': 'Trang chủ',
'admin.plugins.requiresTrek': 'Yêu cầu TREK {version}+',
'admin.plugins.reviewedOn': 'Đã kiểm duyệt {date}',
'admin.plugins.perm.db:own': 'Lưu trữ dữ liệu riêng trong một cơ sở dữ liệu cách ly',
'admin.plugins.perm.db:read:trips': 'Đọc các chuyến đi mà người dùng hiện tại có quyền truy cập',
'admin.plugins.perm.db:read:users':
'Đọc thông tin hồ sơ cơ bản (tên, ảnh đại diện — không bao giờ là thông tin đăng nhập)',
'admin.plugins.perm.ws:broadcast:trip': 'Gửi cập nhật thời gian thực đến các thành viên',
'admin.plugins.perm.ws:broadcast:user': 'Gửi cập nhật thời gian thực đến từng người dùng',
'admin.plugins.perm.hook:photo-provider': 'Cung cấp ảnh cho tính năng Ảnh',
'admin.plugins.perm.hook:calendar-source': 'Cung cấp sự kiện cho lịch',
'admin.plugins.perm.hook:place-detail-provider':
'Đóng góp thêm thông tin chi tiết (đánh giá, xếp hạng, liên kết) cho một địa điểm',
'admin.plugins.perm.hook:trip-warning-provider':
'Đưa ra cảnh báo xác thực trên một chuyến đi (hiển thị trong trình lập kế hoạch)',
'admin.plugins.perm.hook:table-contributor':
'Thêm cột và hành động vào các chế độ xem chuyến đi (đặt chỗ, địa điểm, ngày)',
'admin.plugins.perm.hook:map-marker-provider':
'Thêm điểm đánh dấu vào bản đồ chuyến đi (vd. hiển thị đặt chỗ hoặc POI)',
'admin.plugins.perm.hook:map-layer-provider': 'Vẽ tuyến đường, hành lang và khu vực trên bản đồ chuyến đi',
'admin.plugins.perm.hook:route-provider':
'Cung cấp các hồ sơ định tuyến để trình lập kế hoạch tính lộ trình cho các ngày (vd. định tuyến xe điện với điểm dừng sạc)',
'admin.plugins.perm.hook:day-schedule-provider':
'Gắn các mục thời gian vào kế hoạch ngày (điểm dừng sạc, thời gian đệm an ninh)',
'admin.plugins.perm.hook:day-tint-provider':
'Tô màu các ngày trong kế hoạch ngày (ví dụ ngày đó thuộc chặng nào của chuyến đi)',
'admin.plugins.cap.mcpTools': 'Xuất bản công cụ AI',
'admin.plugins.mcpToolsTitle': 'Công cụ AI được xuất bản',
'admin.plugins.mcpToolsHint': 'Trợ lý có thể chạy chúng thay cho người dùng. Mỗi công cụ hoạt động với quyền được cấp ở trên.',
'admin.plugins.perm.mcp:tools':
'Xuất bản các công cụ mà trợ lý AI có thể chạy thay bạn (nó hoạt động với quyền bạn cấp cho tiện ích tại đây, không phải quyền của trợ lý)',
'admin.plugins.perm.geolocation:read':
'Hỏi vị trí trực tiếp của bạn khi một trong các chế độ xem của nó đang mở (TREK đọc vị trí bằng quyền vị trí của trang này, không phải quyền riêng của plugin)',
'admin.plugins.perm.hook:pdf-section-provider': 'Thêm các phần văn bản vào bản xuất PDF của chuyến đi',
'admin.plugins.perm.hook:atlas-layer-provider':
'Làm nổi bật các quốc gia trên bản đồ thế giới Atlas (vd. danh sách mong muốn hoặc cảnh báo du lịch)',
'admin.plugins.perm.hook:journal-entry-provider': 'Thêm các dòng bổ sung (liên kết, thống kê) vào các mục nhật ký',
'admin.plugins.perm.hook:user-data':
'Xóa hoặc xuất dữ liệu mà nó lưu về một người dùng (GDPR: xóa tài khoản và yêu cầu dữ liệu)',
'admin.plugins.perm.hook:trip-card-provider':
'Thêm huy hiệu nhỏ (trạng thái, số đếm) vào thẻ chuyến đi trên bảng điều khiển',
'admin.plugins.perm.hook:notification-channel': 'Gửi thông báo của bạn qua một kênh bổ sung',
'admin.plugins.perm.events:subscribe':
'Phản hồi các sự kiện hoạt động cốt lõi (chỉ tên sự kiện + chuyến đi, không bao giờ là nội dung)',
'admin.plugins.perm.http:outbound': 'Gửi yêu cầu ra ngoài đến các máy chủ đã khai báo',
'admin.plugins.perm.db:read:collab':
'Đọc ghi chú, bình chọn và tin nhắn trò chuyện của các chuyến đi mà người dùng hiện tại có quyền truy cập (cần add-on Collab)',
'admin.plugins.perm.db:read:files:content':
'Đọc nội dung (byte) tệp của các chuyến đi mà người dùng hiện tại có quyền truy cập',
'admin.plugins.perm.db:create:trips': 'Tạo chuyến đi mới thuộc sở hữu của người dùng hiện tại',
'admin.plugins.perm.rates:read': 'Đọc tỷ giá hối đoái đã lưu cache của máy chủ',
'admin.plugins.updateConsentTitle': 'Bản cập nhật này cần các quyền mới',
'admin.plugins.updateConsentBody':
'{name} v{version} đang yêu cầu các quyền mà bạn chưa cấp. Phiên bản mới đã được cài đặt nhưng vẫn tắt cho đến khi bạn phê duyệt.',
'admin.plugins.updateNewPermissions': 'Các quyền mới được yêu cầu',
'admin.plugins.updateNewEgress': 'Các kết nối ra ngoài mới',
'admin.plugins.updateApprove': 'Phê duyệt & bật',
'admin.plugins.updateLater': 'Tạm thời để tắt',
'admin.plugins.updateKeptOff': 'Đã cài đặt bản cập nhật — vẫn tắt cho đến khi bạn phê duyệt các quyền mới',
'admin.plugins.reviewedMeaning':
'"Đã kiểm duyệt" nghĩa là một người bảo trì TREK đã quét plugin này để tìm mã độc trên mỗi phiên bản — không phải về chất lượng hay việc nó có hoạt động hay không. Đây không phải là bảo đảm rằng plugin vô hại.',
'admin.plugins.security.title': 'Cách plugin được cô lập — và những giới hạn',
'admin.plugins.security.isolationTitle': 'Mọi plugin đều chạy trong hộp cách ly',
'admin.plugins.security.isolationBody':
'Plugin chạy như một tiến trình bị khóa riêng, chỉ có thể đọc các tệp của chính nó. Nó không thể đọc cơ sở dữ liệu, khóa bí mật đăng nhập hay khóa mã hóa của bạn, không thể khởi chạy chương trình khác và không thể ghi tệp ở bất kỳ đâu. Giao diện của nó chạy trong một khung trình duyệt được niêm phong, không thể đọc cookie phiên của bạn hay tác động đến trang TREK xung quanh.',
'admin.plugins.security.permsTitle': 'Các quyền có ý nghĩa gì',
'admin.plugins.security.permsBody':
'Các quyền hiển thị trước khi bạn cài đặt là một giới hạn cứng mà TREK thực thi trong khi plugin chạy — nó thực sự không thể làm bất cứ điều gì không có trong danh sách. Nhưng chúng cho bạn biết một plugin có thể làm gì, chứ không phải nó thực sự làm gì. Một plugin được phép đọc các chuyến đi của bạn và kết nối tới một máy chủ có thể gửi các chuyến đi của bạn đến máy chủ đó, vì vậy hãy đọc các quyền và các máy chủ ra ngoài, chứ không chỉ phần mô tả.',
'admin.plugins.security.limitsTitle': 'Những điều chúng tôi không thể hứa',
'admin.plugins.security.limitsBody':
'Sự cô lập là một ranh giới phần mềm mạnh mẽ, chứ không tuyệt đối. Một plugin hoạt động với đúng các quyền mà bạn phê duyệt, vì vậy trong phạm vi các quyền đó nó có thể hành xử khác với mô tả của nó, và nó có thể gửi dữ liệu mà nó nắm giữ hợp lệ đến các máy chủ mà nó đã khai báo. TREK không đọc hay đánh giá những gì mã của một plugin thực sự làm.',
'admin.plugins.security.worstTitle': 'Trường hợp xấu nhất',
'admin.plugins.security.worstBody':
'Một plugin độc hại mà bạn bật lên có thể lạm dụng dữ liệu và các kết nối mà bạn đã cấp cho nó — ví dụ, làm rò rỉ các chuyến đi mà nó được phép đọc. Nó không thể đánh cắp mật khẩu, giả mạo đăng nhập quản trị viên, chạy lệnh trên máy chủ của bạn hay truy cập dữ liệu mà bạn không cấp. Thiệt hại chỉ nằm trong phạm vi những gì bạn đã phê duyệt, và việc tắt plugin sẽ dừng nó lại.',
'admin.plugins.security.reviewedTitle': '"Đã kiểm duyệt" nghĩa là gì',
'admin.plugins.security.reviewedBody':
'Một plugin đã kiểm duyệt đã được người bảo trì TREK quét thủ công để tìm mã độc trên mỗi phiên bản — được kiểm tra về mã độc hại, chứ không phải về việc nó có hoạt động tốt hay không. Đây không phải là lời hứa rằng plugin vô hại.',
'admin.plugins.security.signedTitle': '"Đã ký" nghĩa là gì',
'admin.plugins.security.signedBody':
'Giá trị kiểm tra (checksum) mà TREK xác minh ở mỗi lần cài đặt chứng minh rằng các tệp đúng là những gì kho đăng ký bảo chứng. Chữ ký chứng minh một điều khác: rằng chúng đến từ tác giả, được ký bằng một khóa chỉ mình họ nắm giữ. Một plugin đã ký có cả hai. Một plugin chưa ký không phải là không an toàn — nó chỉ mang ít hơn một bảo đảm, và hiện nay phần lớn plugin trong kho đăng ký đều chưa ký.',
'admin.plugins.signed': 'Đã ký',
'admin.plugins.signedHint': 'Đã được xác minh với khóa ký của tác giả khi cài đặt',
'admin.plugins.unsigned': 'Chưa ký',
'admin.plugins.unsignedHint':
'Các tệp khớp với những gì kho đăng ký bảo chứng, nhưng không có gì gắn chúng với tác giả. Ít hơn một bảo đảm — không phải là không an toàn.',
'admin.plugins.updateBlocked': 'Cập nhật bị chặn — {reason}',
'admin.plugins.reviewBlock': 'Xem lại',
'admin.plugins.retrusted': 'Đã tin cậy khóa ký mới — plugin đã được cập nhật',
'admin.plugins.sig.title': 'Không thể xác minh chữ ký của "{name}"',
'admin.plugins.sig.keyChangedBody':
'Khóa ký của tác giả không phải là khóa mà plugin này đã được cài đặt cùng. Các tác giả đôi khi có xoay vòng khóa — nhưng một kẻ tấn công đã chiếm quyền plugin cũng sẽ trông y hệt như vậy.',
'admin.plugins.sig.invalidBody':
'Các tệp không khớp với chữ ký của tác giả. Chúng không phải là những gì tác giả đã ký — hoặc chúng bị hỏng, hoặc chúng đã bị can thiệp. Không thể bỏ qua điều này.',
'admin.plugins.sig.missingBody':
'Plugin này đã được ký khi bạn cài đặt, nhưng phiên bản mới không kèm chữ ký nào. TREK sẽ không lặng lẽ chấp nhận bước lùi đó. Không thể bỏ qua điều này.',
'admin.plugins.sig.incompleteBody':
'Mục trong kho đăng ký chỉ được ký một nửa: nó khai báo khóa của tác giả nhưng phiên bản lại không có chữ ký (hoặc ngược lại). Đó là một sai sót từ phía plugin. Không thể bỏ qua điều này.',
'admin.plugins.sig.pinnedKey': 'Khóa đã dùng khi cài đặt',
'admin.plugins.sig.newKey': 'Khóa nó đang đưa ra hiện giờ',
'admin.plugins.sig.confirmOutOfBand':
'TREK không thể phân biệt một lần xoay khóa hợp lệ với một vụ chiếm quyền — nhìn từ đây, cả hai giống hệt nhau. Hãy xác nhận khóa mới với tác giả qua một kênh mà bạn đã tin tưởng trước khi chấp nhận nó. Khi bạn chấp nhận, plugin sẽ được cập nhật và khóa mới sẽ được ghi nhớ.',
'admin.plugins.sig.retrustConfirm': 'Tin cậy khóa mới & cập nhật',
'admin.plugins.sig.cancel': 'Không tin cậy',
'admin.plugins.sig.consentUnsigned':
'Không có gì gắn phiên bản này với tác giả của nó — các tệp khớp với kho đăng ký, nhưng chúng không mang chữ ký của tác giả.',
'admin.plugins.security.trustTitle': 'Điểm mấu chốt',
'admin.plugins.security.trustBody':
'Cài đặt một plugin cũng giống như cài đặt bất kỳ ứng dụng bên thứ ba nào: chỉ cài đặt mã từ những tác giả bạn tin tưởng, và khi còn nghi ngờ, hãy tự kiểm tra nó trước. TREK không chịu trách nhiệm về các plugin của bên thứ ba.',
'admin.plugins.runtimeOn': 'Runtime đang bật',
'admin.plugins.tabDiscover': 'Khám phá',
'admin.plugins.searchPlaceholder': 'Tìm kiếm plugin…',
'admin.plugins.filterType': 'Loại',
'admin.plugins.filterStatus': 'Trạng thái',
'admin.plugins.sortBy': 'Sắp xếp',
'admin.plugins.allTypes': 'Tất cả loại',
'admin.plugins.allStatuses': 'Tất cả',
'admin.plugins.stateOff': 'Tắt',
'admin.plugins.filterUpdate': 'Có bản cập nhật',
'admin.plugins.sortName': 'Tên',
'admin.plugins.sortRecent': 'Cập nhật gần đây',
'admin.plugins.sortUpdates': 'Ưu tiên bản cập nhật',
'admin.plugins.sortDownloads': 'Tải nhiều nhất',
'admin.plugins.updatesAvailable': 'Có {count} bản cập nhật cho các plugin của bạn.',
'admin.plugins.newerNeedsTrek': 'Đã có v{version} — cần TREK {range}',
'admin.plugins.versionsTitle': 'Phiên bản',
'admin.plugins.versionPickerTitle': 'Đổi phiên bản — {name}',
'admin.plugins.versionSwitch': 'Chuyển sang {version}',
'admin.plugins.versionNeedsTrek': 'cần TREK {range}',
'admin.plugins.changeVersion': 'Đổi phiên bản…',
'admin.plugins.noVersions': 'Không tìm thấy phiên bản đã xuất bản trong sổ đăng ký.',
'admin.plugins.downgradeTitle': 'Quay lại phiên bản cũ của plugin này?',
'admin.plugins.downgradeBody': 'Chuyển từ v{from} sang v{to}: dữ liệu do phiên bản mới hơn ghi vẫn còn nguyên, và phiên bản cũ hơn có thể không hiểu được.',
'admin.plugins.downgradeConfirm': 'Quay lại',
'admin.plugins.updatesHeld': 'Đã tạm dừng cập nhật ở v{version}',
'admin.plugins.resumeUpdates': 'Tiếp tục cập nhật',
'admin.plugins.updatesResumed': 'Đã tiếp tục cập nhật',
'admin.plugins.updateAll': 'Cập nhật tất cả',
'admin.plugins.noMatchInstalled': 'Không có plugin đã cài đặt nào khớp với tìm kiếm của bạn.',
'admin.plugins.noMatchRegistry': 'Không có plugin nào trong kho đăng ký khớp với tìm kiếm của bạn.',
'admin.plugins.restart': 'Khởi động lại',
'admin.plugins.restarted': 'Đã khởi động lại plugin',
'admin.plugins.instanceSettings': 'Cài đặt toàn hệ thống',
'admin.plugins.settingsSaved': 'Đã lưu cài đặt',
'admin.plugins.settingsSavedRestarted': 'Đã lưu cài đặt — đã khởi động lại plugin',
'admin.plugins.actions': 'Hành động',
'admin.plugins.actions.confirm': 'Chạy hành động này?',
'admin.plugins.actions.inactive': 'Kích hoạt plugin để chạy các hành động của nó',
'admin.plugins.requiredMissing': '"{field}" là bắt buộc',
'admin.plugins.cap.readsTrips': 'Đọc chuyến đi của bạn',
'admin.plugins.cap.readsUsers': 'Đọc hồ sơ cơ bản',
'admin.plugins.cap.readsCosts': 'Đọc chi phí của bạn',
'admin.plugins.cap.readsPacking': 'Đọc danh sách hành lý',
'admin.plugins.cap.readsFiles': 'Đọc tệp chuyến đi',
'admin.plugins.cap.writesCosts': 'Thêm chi phí',
'admin.plugins.cap.writesPlaces': 'Chỉnh sửa địa điểm',
'admin.plugins.cap.writesDays': 'Chỉnh sửa ngày',
'admin.plugins.cap.writesItinerary': 'Chỉnh sửa lịch trình',
'admin.plugins.cap.writesTrips': 'Chỉnh sửa chuyến đi',
'admin.plugins.cap.metadata': 'Thêm siêu dữ liệu',
'admin.plugins.cap.widget': 'Widget bảng điều khiển',
'admin.plugins.cap.heroWidget': 'Widget thẻ lên máy bay',
'admin.plugins.cap.placeSlot': 'Chi tiết địa điểm',
'admin.plugins.cap.daySlot': 'Chi tiết ngày',
'admin.plugins.cap.reservationSlot': 'Chi tiết đặt chỗ',
'admin.plugins.cap.replacesTabs': 'Thay thế các tab trình lập kế hoạch',
'admin.plugins.cap.realtime': 'Cập nhật thời gian thực',
'admin.plugins.cap.notificationChannel': 'Kênh thông báo',
'admin.plugins.cap.photos': 'Cung cấp ảnh',
'admin.plugins.cap.calendar': 'Cung cấp sự kiện lịch',
'admin.plugins.cap.placeDetails': 'Làm phong phú địa điểm',
'admin.plugins.cap.warnings': 'Gắn cờ vấn đề',
'admin.plugins.cap.mapLayers': 'Vẽ trên bản đồ',
'admin.plugins.cap.routing': 'Cung cấp định tuyến',
'admin.plugins.cap.daySchedule': 'Thêm giờ kế hoạch',
'admin.plugins.cap.dayTint': 'Tô màu ngày',
'admin.plugins.cap.geolocation': 'Đọc vị trí của bạn',
'admin.plugins.cap.events': 'Phản hồi hoạt động',
'admin.plugins.cap.requiresAddon': 'Cần {addon}',
'admin.plugins.cap.dependsOn': 'Cần {id} {version}',
'admin.plugins.dep.addonDisabledToast': 'Trước tiên hãy bật các tiện ích bổ sung cần thiết: {addons}',
'admin.plugins.dep.autoEnabled': 'Đã bật các plugin cần thiết trước: {plugins}',
'admin.plugins.dep.downloaded': 'Đã tải xuống {id}',
'admin.plugins.dep.resolveTitle': 'Thiếu phần phụ thuộc',
'admin.plugins.dep.resolveBody': '“{name}” cần cài đặt các plugin này trước khi có thể bật.',
'admin.plugins.dep.requires': 'Cần {version}',
'admin.plugins.dep.mismatch': 'Cần {wanted} — đã cài {installed}',
'admin.plugins.dep.download': 'Tải xuống',
'admin.plugins.dep.update': 'Cập nhật',
'admin.plugins.dep.resolveHint': 'Tải phiên bản tương thích mới nhất, bao gồm cả các phần phụ thuộc của nó.',
'admin.plugins.dep.trekIncompatible': 'Cần TREK {range} — máy chủ này đang chạy {host}',
'admin.plugins.dep.trekUnknown': 'Không nêu rõ hỗ trợ những phiên bản TREK nào',
'admin.plugins.installCompatible': 'Cài đặt {version}',
'admin.plugins.installAnyway': 'Vẫn cài đặt',
'admin.plugins.rangeBypass.pill': 'Đã tắt kiểm tra phiên bản',
'admin.plugins.rangeBypass.pillHint':
'TREK_PLUGINS_IGNORE_TREK_RANGE đã được đặt — plugin có thể được cài đặt và chạy ngoài các phiên bản TREK mà tác giả đã khai báo',
'admin.plugins.rangeBypass.title': 'Ngoài các phiên bản TREK được hỗ trợ',
'admin.plugins.rangeBypass.noticeTitle': 'Đã cài đặt ngoài các phiên bản TREK được hỗ trợ',
'admin.plugins.rangeBypass.body':
'“{name}” khai báo hỗ trợ TREK {range}, còn máy chủ này đang chạy {host}. TREK chỉ cho phép vì TREK_PLUGINS_IGNORE_TREK_RANGE đã được đặt. Tác giả chưa cập nhật phạm vi phiên bản của plugin cho TREK này, nên không có gì đảm bảo nó hoạt động — và trong một số ít trường hợp, plugin không tương thích có thể làm hỏng dữ liệu TREK. Chỉ tiếp tục nếu bạn chấp nhận rủi ro đó.',
'admin.plugins.rangeBypass.bodyUnknown':
'“{name}” không khai báo hỗ trợ phiên bản TREK nào; máy chủ này đang chạy {host}. TREK chỉ cho phép vì TREK_PLUGINS_IGNORE_TREK_RANGE đã được đặt. Không có dấu hiệu nào cho thấy tác giả đã thử nghiệm trên TREK này, nên không có gì đảm bảo nó hoạt động — và trong một số ít trường hợp, plugin không tương thích có thể làm hỏng dữ liệu TREK. Chỉ tiếp tục nếu bạn chấp nhận rủi ro đó.',
'admin.plugins.dep.trekBypassed':
'Ngoài phạm vi TREK của nó ({range}) — đã tắt kiểm tra phiên bản',
'admin.plugins.dep.trekBypassedUnknown': 'Không khai báo phạm vi TREK — đã tắt kiểm tra phiên bản',
'admin.plugins.incompatible': 'Không tương thích',
'admin.plugins.accessTitle': 'Những gì có thể truy cập',
'admin.plugins.connectsTitle': 'Kết nối tới',
'admin.plugins.detailsTitle': 'Chi tiết',
'admin.plugins.noAccess': 'Không cần quyền truy cập đặc biệt nào.',
'admin.plugins.metaVersion': 'Phiên bản',
'admin.plugins.metaSize': 'Kích thước',
'admin.plugins.metaRequires': 'Yêu cầu',
'admin.plugins.metaReviewed': 'Đã kiểm duyệt vào',
'admin.plugins.downloads': 'Lượt tải',
'admin.addons.title': 'Tiện ích bổ sung',
'admin.addons.subtitle': 'Bật hoặc tắt các tính năng để tùy chỉnh trải nghiệm TREK của bạn.',
'admin.addons.catalog.packing.name': 'Danh sách',
'admin.addons.catalog.packing.description': 'Danh sách đóng gói và nhiệm vụ cần làm cho chuyến đi của bạn',
'admin.addons.catalog.budget.name': 'Chi phí',
'admin.addons.catalog.budget.description': 'Theo dõi chi phí chuyến đi và chia cho những người cùng đi',
'admin.addons.catalog.documents.name': 'Tài liệu',
'admin.addons.catalog.documents.description': 'Lưu trữ và quản lý tài liệu du lịch',
'admin.addons.catalog.vacay.name': 'Kỳ nghỉ',
'admin.addons.catalog.vacay.description': 'Kế hoạch kỳ nghỉ cá nhân với chế độ xem lịch',
'admin.addons.catalog.atlas.name': 'Bản đồ',
'admin.addons.catalog.atlas.description': 'Bản đồ thế giới với các quốc gia đã ghé thăm và số liệu thống kê du lịch',
'admin.addons.catalog.collab.name': 'Cộng tác',
'admin.addons.catalog.collab.description': 'Ghi chú, bình chọn, trò chuyện và gợi ý để cùng lên kế hoạch',
'admin.addons.catalog.memories.name': 'Hình ảnh (Immich)',
'admin.addons.catalog.memories.description': 'Chia sẻ ảnh chuyến đi qua phiên bản Immich của bạn',
'admin.addons.catalog.mcp.name': 'MCP',
'admin.addons.catalog.mcp.description': 'Giao thức ngữ cảnh mẫu để tích hợp trợ lý AI',
'admin.addons.subtitleBefore': 'Bật hoặc tắt các tính năng để tùy chỉnh',
'admin.addons.subtitleAfter': 'kinh nghiệm.',
'admin.addons.catalog.naver_list_import.name': 'Naver List Import',
'admin.addons.catalog.naver_list_import.description': 'Nhập địa điểm từ danh sách Naver Maps được chia sẻ',
'admin.addons.catalog.airtrail.name': 'AirTrail',
'admin.addons.catalog.airtrail.description': 'Đồng bộ chuyến bay từ máy chủ AirTrail của bạn',
'admin.addons.catalog.llm_parsing.name': 'Phân tích bằng AI',
'admin.addons.catalog.llm_parsing.description': 'Đọc các đặt chỗ mà bộ phân tích tích hợp không hiểu, bằng mô hình AI bạn chọn',
'admin.addons.enabled': 'Đã bật',
'admin.addons.disabled': 'Tắt',
'admin.addons.type.trip': 'Chuyến đi',
'admin.addons.type.global': 'Toàn cầu',
'admin.addons.type.integration': 'Tích hợp',
'admin.addons.tripHint': 'Có sẵn dưới dạng một tab trong mỗi chuyến đi',
'admin.addons.globalHint': 'Có sẵn dưới dạng một phần độc lập trong điều hướng chính',
'admin.addons.integrationHint': 'Dịch vụ phụ trợ và tích hợp API không có trang chuyên dụng',
'admin.addons.toast.updated': 'Đã cập nhật tiện ích bổ sung',
'admin.addons.toast.error': 'Không thể cập nhật tiện ích bổ sung',
'admin.addons.group.count': '{enabled} trên {total} đã bật',
'admin.addons.noAddons': 'Không có tiện ích bổ sung nào',
'admin.weather.title': 'Dữ liệu thời tiết',
'admin.weather.badge': 'Kể từ ngày 24 tháng 3 năm 2026',
'admin.weather.description':
'TREK sử dụng Open-Meteo làm nguồn dữ liệu thời tiết. Open-Meteo là dịch vụ thời tiết nguồn mở, miễn phí — không yêu cầu khóa API.',
'admin.weather.forecast': 'dự báo 16 ngày',
'admin.weather.forecastDesc': 'Trước đây 5 ngày (OpenWeatherMap)',
'admin.weather.climate': 'Dữ liệu khí hậu lịch sử',
'admin.weather.climateDesc': 'Trung bình từ 85 năm qua cho những ngày vượt quá dự báo 16 ngày',
'admin.weather.requests': '10.000 yêu cầu/ngày',
'admin.weather.requestsDesc': 'Miễn phí, không cần khóa API',
'admin.weather.locationHint':
'Thời tiết dựa trên địa điểm đầu tiên có tọa độ mỗi ngày. Nếu không có địa điểm nào được chỉ định cho một ngày thì bất kỳ địa điểm nào trong danh sách địa điểm đều được sử dụng làm tham chiếu.',
'admin.tabs.mcpTokens': 'MCP Truy cập',
'admin.mcpTokens.title': 'MCP Truy cập',
'admin.mcpTokens.subtitle': 'Quản lý phiên OAuth và mã thông báo API trên tất cả người dùng',
'admin.mcpTokens.sectionTitle': 'API Mã thông báo',
'admin.mcpTokens.owner': 'Người sở hữu',
'admin.mcpTokens.tokenName': 'Tên mã thông báo',
'admin.mcpTokens.created': 'Tạo',
'admin.mcpTokens.lastUsed': 'Được sử dụng lần cuối',
'admin.mcpTokens.never': 'Không bao giờ',
'admin.mcpTokens.empty': 'Chưa có mã thông báo MCP nào được tạo',
'admin.mcpTokens.deleteTitle': 'Xóa mã thông báo',
'admin.mcpTokens.deleteMessage':
'Điều này sẽ thu hồi mã thông báo ngay lập tức. Người dùng sẽ mất quyền truy cập MCP thông qua mã thông báo này.',
'admin.mcpTokens.deleteSuccess': 'Đã xóa mã thông báo',
'admin.mcpTokens.deleteError': 'Không xóa được mã thông báo',
'admin.mcpTokens.loadError': 'Không thể tải mã thông báo',
'admin.oauthSessions.sectionTitle': 'OAuth Phiên',
'admin.oauthSessions.clientName': 'Client',
'admin.oauthSessions.owner': 'Người sở hữu',
'admin.oauthSessions.scopes': 'Phạm vi',
'admin.oauthSessions.created': 'Tạo',
'admin.oauthSessions.empty': 'Không có phiên OAuth nào hoạt động',
'admin.oauthSessions.revokeTitle': 'Thu hồi phiên',
'admin.oauthSessions.revokeMessage':
'Thao tác này sẽ thu hồi phiên OAuth ngay lập tức. Client sẽ mất quyền truy cập MCP.',
'admin.oauthSessions.revokeSuccess': 'Phiên bị thu hồi',
'admin.oauthSessions.revokeError': 'Không thể thu hồi phiên',
'admin.oauthSessions.loadError': 'Không tải được OAuth phiên',
'admin.tabs.github': 'GitHub',
'admin.audit.subtitle': 'Các sự kiện quản trị và nhạy cảm về bảo mật (sao lưu, người dùng, MFA, cài đặt).',
'admin.audit.empty': 'Chưa có mục kiểm toán nào.',
'admin.audit.refresh': 'Làm mới',
'admin.audit.loadMore': 'Tải thêm',
'admin.audit.showing': '{count} đã tải · tổng cộng {total}',
'admin.audit.col.time': 'Thời gian',
'admin.audit.col.user': 'người dùng',
'admin.audit.col.action': 'Hoạt động',
'admin.audit.col.resource': 'Tài nguyên',
'admin.audit.col.ip': 'IP',
'admin.audit.col.details': 'Chi tiết',
'admin.github.title': 'Lịch sử phát hành',
'admin.github.subtitle': 'Cập nhật mới nhất từ ​​{repo}',
'admin.github.latest': 'Mới nhất',
'admin.github.prerelease': 'Phát hành trước',
'admin.github.showDetails': 'Hiển thị chi tiết',
'admin.github.hideDetails': 'Ẩn chi tiết',
'admin.github.loadMore': 'Tải thêm',
'admin.github.loading': 'Đang tải...',
'admin.github.error': 'Không tải được bản phát hành',
'admin.github.by': 'qua',
'admin.github.support': 'Giúp tôi tiếp tục xây dựng TREK',
'admin.update.available': 'Đã có bản cập nhật',
'admin.update.text': 'TREK {version} có sẵn. Bạn đang chạy {current}.',
'admin.update.button': 'Xem trên GitHub',
'admin.update.install': 'Cài đặt bản cập nhật',
'admin.update.confirmTitle': 'Cài đặt bản cập nhật?',
'admin.update.confirmText':
'TREK sẽ được cập nhật từ {current} lên {version}. Máy chủ sẽ tự động khởi động lại sau đó.',
'admin.update.dataInfo':
'Tất cả dữ liệu của bạn (chuyến đi, người dùng, khóa API, nội dung tải lên, Vacay, Atlas, ngân sách) sẽ được giữ nguyên.',
'admin.update.warning': 'Ứng dụng sẽ không khả dụng trong thời gian ngắn khi khởi động lại.',
'admin.update.confirm': 'Cập nhật ngay',
'admin.update.installing': 'Đang cập nhật…',
'admin.update.success': 'Đã cài đặt bản cập nhật! Máy chủ đang khởi động lại…',
'admin.update.failed': 'Cập nhật không thành công',
'admin.update.backupHint': 'Chúng tôi khuyên bạn nên tạo bản sao lưu trước khi cập nhật.',
'admin.update.backupLink': 'Đi tới Sao lưu',
'admin.update.howTo': 'Cách cập nhật',
'admin.update.dockerText':
'Phiên bản TREK của bạn chạy trong Docker. Để cập nhật lên {version}, hãy chạy các lệnh sau trên máy chủ của bạn:',
'admin.update.nonDockerText':
'Phiên bản TREK này không chạy trong Docker. Để cập nhật lên {version}, hãy chạy lại phương pháp cài đặt hoặc cập nhật mà bạn đã sử dụng — ví dụ: trên Proxmox Community Script chạy bản cập nhật từ bảng điều khiển LXC:',
'admin.update.wikiLink': 'Mở hướng dẫn cập nhật',
'admin.update.reloadHint': 'Vui lòng tải lại trang sau vài giây.',
'admin.tabs.permissions': 'Quyền',
'admin.addons.catalog.journey.name': 'Hành trình',
'admin.addons.catalog.journey.description':
'Theo dõi chuyến đi & nhật ký du lịch với nhận phòng, ảnh và câu chuyện hàng ngày',
'admin.addons.catalog.collections.name': 'Bộ sưu tập',
'admin.addons.catalog.collections.description': 'Gom địa điểm từ mọi chuyến đi vào danh sách có tên và dùng lại',
'admin.passkey.title': 'Đăng nhập bằng mật mã',
'admin.passkey.cardHint': 'Cho phép người dùng đăng nhập bằng mật mã (WebAuthn). Tắt theo mặc định.',
'admin.passkey.login': 'Kích hoạt đăng nhập bằng mật mã',
'admin.passkey.loginHint':
'Hiển thị tùy chọn "Đăng nhập bằng mật mã" và cho phép người dùng đăng ký mật mã trong cài đặt của họ.',
'admin.passkey.notConfigured':
'Chưa có miền WebAuthn nào giải quyết được việc triển khai này. Đặt APP_URL hoặc Relying Party ID bên dưới — mật mã sẽ được ẩn cho đến lúc đó.',
'admin.passkey.rpId': 'Đảng dựa vào ID (miền)',
'admin.passkey.rpIdHint':
'Các mật khẩu tên miền trần bị ràng buộc, ví dụ: didau.vn. Để trống để lấy nó từ APP_URL. Việc thay đổi nó sau này sẽ làm mất hiệu lực các mật mã hiện có.',
'admin.passkey.origins': 'Nguồn gốc được phép',
'admin.passkey.originsHint':
'Nguồn gốc đầy đủ được phân tách bằng dấu phẩy, ví dụ: https://didau.vn. Để trống để sử dụng APP_URL.',
'admin.passkey.reset': 'Đặt lại mật khẩu',
'admin.passkey.resetHint':
'Xóa tất cả mật mã của người dùng này (ví dụ: trên thiết bị bị mất). Họ vẫn có thể đăng nhập bằng mật khẩu của mình.',
'admin.passkey.resetConfirm': 'Xóa tất cả mật mã cho {name}?',
'admin.passkey.resetDone': 'Đã xóa {count} mật mã',
'admin.group.users': 'Người dùng',
'admin.group.config': 'Cấu hình',
'admin.group.integration': 'Tích hợp',
'admin.group.maintenance': 'Bảo trì',
'admin.invite.tripLabel': 'Thêm vào chuyến đi (tùy chọn)',
'admin.invite.tripNone': 'Không có chuyến đi',
'admin.invite.tripHint': 'Người dùng mới sẽ tự động được thêm vào chuyến đi này khi họ đăng ký qua liên kết.',
'admin.invite.boundTo': 'thêm vào {trip}',
};
export default admin;