diff --git a/src/components/LanguageToggle.tsx b/src/components/LanguageToggle.tsx index c4a9efd..ea0d6bc 100644 --- a/src/components/LanguageToggle.tsx +++ b/src/components/LanguageToggle.tsx @@ -32,6 +32,7 @@ const languages: LanguageOption[] = [ { code: 'ja', name: 'Japanese', nativeName: '日本語', flag: '🇯🇵' }, { code: 'zh-CN', name: 'Chinese (Simplified)', nativeName: '简体中文', flag: '🇨🇳' }, { code: 'zh-TW', name: 'Chinese (Traditional)', nativeName: '繁體中文', flag: '🇹🇼' }, + { code: 'vi', name: 'Vietnamese', nativeName: 'Tiếng Việt', flag: '🇻🇳' }, { code: 'tr', name: 'Turkish', nativeName: 'Türkçe', flag: '🇹🇷' }, ]; diff --git a/src/i18n/vi/batch1.ts b/src/i18n/vi/batch1.ts index 7850130..90f877f 100644 --- a/src/i18n/vi/batch1.ts +++ b/src/i18n/vi/batch1.ts @@ -1,4 +1,290 @@ -/** vi — batch 1. Filled by the translation pass; empty until then. */ -const viBatch1 = {}; +/** vi — batch 1. */ +const viBatch1 = { + common: { + loading: "Đang tải...", + error: "Lỗi", + save: "Lưu", + cancel: "Hủy", + delete: "Xóa", + edit: "Sửa", + add: "Thêm", + remove: "Gỡ", + create: "Tạo", + submit: "Gửi", + close: "Đóng", + back: "Quay lại", + next: "Tiếp", + done: "Xong", + search: "Tìm kiếm", + filter: "Lọc", + sort: "Sắp xếp", + share: "Chia sẻ", + more: "Thêm", + copy: "Sao chép", + copied: "Đã sao chép!", + viewAll: "Xem tất cả", + seeMore: "Xem thêm", + showMore: "Hiện thêm", + showLess: "Thu gọn", + noResults: "Không tìm thấy kết quả", + tryAgain: "Thử lại", + learnMore: "Tìm hiểu thêm", + getStarted: "Bắt đầu", + yes: "Có", + no: "Không", + or: "hoặc", + and: "và", + free: "Miễn phí", + new: "Mới", + popular: "Phổ biến", + featured: "Nổi bật", + verified: "Đã xác minh", + sats: "sats", + clear: "Xóa", + clearFilters: "Xóa bộ lọc", + clearAll: "Xóa tất cả", + hide: "Ẩn", + undo: "Hoàn tác" + }, + nav: { + home: "Trang chủ", + map: "Spots", + lab: "The Lab", + events: "Sự kiện", + crews: "Crews", + wallet: "Ví", + settings: "Cài đặt", + more: "Thêm", + rewards: "Phần thưởng", + stats: "Thống kê cộng đồng", + about: "Giới thiệu", + food: "Đồ ăn", + marketplace: "Chợ", + mints: "Mints", + appShop: "Cửa hàng ứng dụng", + diy: "DIY", + trades: "Chợ", + stash: "Stash", + collections: "Bộ sưu tập", + contacts: "Danh bạ", + messages: "Tin nhắn", + skaters: "Người trượt ván", + glossary: "Thuật ngữ", + riderCard: "Thẻ Rider", + supporters: "Người ủng hộ ⚡", + newsletter: "Bản tin", + viewProfile: "Xem hồ sơ", + leaderboards: "Bảng xếp hạng" + }, + chromeUi: { + skipToContent: "Chuyển đến nội dung", + menu: "Menu", + inBadge: "In", + loggedIn: "Đã đăng nhập", + profile: "Hồ sơ", + logIn: "Đăng nhập", + logOut: "Đăng xuất", + notLoggedIn: "Chưa đăng nhập", + loggedOutPrompt: "Đăng nhập để thêm spot, zap skater và lưu mục yêu thích", + accounts: "Tài khoản", + addAnotherAccount: "Thêm tài khoản khác", + setStatus: "Đặt trạng thái", + setYourStatus: "Đặt trạng thái của bạn", + status: "Trạng thái", + addSpot: "Thêm Spot", + myData: "Dữ liệu của tôi", + myStash: "Stash của tôi", + myCollections: "Bộ sưu tập của tôi", + viewMyProfile: "Xem hồ sơ của tôi", + customizeNavBar: "Tùy chỉnh thanh điều hướng", + ecash: "Ecash", + madeWith: "Được tạo bằng", + forSkateCommunity: "cho cộng đồng trượt ván", + beta: "Beta", + license: "Giấy phép", + privacy: "Quyền riêng tư", + collaborators: "Cộng tác viên & Bạn bè", + notSponsoredBy: "Không được tài trợ bởi", + errorTitle: "Không thể tải nội dung này", + errorDescription: "Yêu cầu mạng thất bại. Kiểm tra kết nối và thử lại.", + tryAgain: "Thử lại", + weatherOn: "Bật thời tiết", + weatherOff: "Tắt thời tiết", + trustFilter: "Bộ lọc tin cậy", + filterByTrustLevel: "Lọc theo mức độ tin cậy", + trust: { + all: "Tất cả người dùng", + allDesc: "Hiển thị nội dung từ mọi người", + verified: "Đã xác minh", + verifiedDesc: "Bạn theo dõi họ hoặc họ đã được xác minh (tin cậy ≥90)", + trusted: "Đáng tin cậy", + trustedDesc: "Bạn của bạn bè hoặc đã xác minh NIP-05 (tin cậy ≥60)", + following: "Chỉ đang theo dõi", + followingDesc: "Chỉ hiển thị nội dung từ người bạn theo dõi", + followingShort: "Đang theo dõi" + }, + sort: { + recent: "Gần đây nhất", + recentDesc: "Mới nhất trước", + trust: "Tin cậy cao nhất", + trustDesc: "Nhà sáng tạo đáng tin cậy nhất", + proximity: "Gần tôi nhất", + proximityDesc: "Địa điểm gần nhất", + popular: "Phổ biến nhất", + popularDesc: "Nhiều bình luận/cảm xúc nhất", + zaps: "Được Zap nhiều nhất", + zapsDesc: "Giá trị nhận được cao nhất" + }, + spotType: { + street: "Đường phố", + transition: "Transition", + park: "Park", + plaza: "Quảng trường", + diy: "DIY", + bowl: "Bowl", + vert: "Vert", + indoor: "Trong nhà", + skatepark: "Skatepark", + miniramp: "Mini Ramp" + } + }, + desktopNav: { + title: "Điều hướng máy tính", + desc: "Chọn các tab hiển thị trên thanh trên cùng và thứ tự của chúng. Các tab bị ẩn vẫn nằm trong menu “Thêm”.", + fixed: "Cố định", + shownInTopBar: "Hiển thị trên thanh trên cùng ({{count}})", + noExtraTabs: "Không có tab thêm nào được hiển thị — mọi thứ đều nằm trong menu “Thêm”. Thêm một số bên dưới.", + inMoreMenu: "Trong menu “Thêm” ({{count}})", + moveUp: "Di chuyển {{name}} lên", + moveDown: "Di chuyển {{name}} xuống", + hide: "Ẩn {{name}}", + moveToMore: "Chuyển vào menu Thêm", + show: "Hiện", + showInTopBar: "Hiện {{name}} trên thanh trên cùng", + showInTopBarTitle: "Hiện trên thanh trên cùng", + reset: "Đặt lại mặc định" + }, + navSheet: { + title: "Tùy chỉnh thanh của bạn", + desc: "Chọn {{count}} tab bạn dùng nhiều nhất. Mọi thứ khác vẫn ở trong menu.", + preview: "Xem trước", + empty: "Trống", + order: "Thứ tự ({{done}}/{{total}})", + available: "Tab khả dụng", + full: "Thanh đã đầy — xóa một tab để thay", + moveUp: "Di chuyển {{name}} lên", + moveDown: "Di chuyển {{name}} xuống", + login: "Đăng nhập", + profile: "Hồ sơ", + reset: "Đặt lại", + done: "Xong" + }, + pwa: { + installTitle: "Cài đặt SkateSpots", + installSubtitle: "Trải nghiệm ứng dụng đầy đủ", + addToHomeScreen: "Thêm vào Màn hình chính", + installApp: "Cài đặt ứng dụng", + maybeLater: "Để sau", + gotIt: "Đã hiểu!", + benefits: { + fast: "Nhanh như Lightning", + offline: "Hoạt động ngoại tuyến", + fullAccess: "Truy cập đầy đủ" + }, + iosStep1: "Nhấn nút Chia sẻ", + iosStep1Hint: "ở cuối Safari", + iosStep2: "Cuộn và nhấn \"Thêm vào Màn hình chính\"", + iosStep2Hint: "trong menu chia sẻ", + iosStep3: "Nhấn \"Thêm\" để cài đặt", + iosStep3Hint: "Ứng dụng sẽ xuất hiện trên màn hình chính của bạn", + androidStep1: "Nhấn nút menu", + androidStep1Hint: "(ba dấu chấm) trong trình duyệt của bạn", + androidStep2: "Chọn \"Thêm vào Màn hình chính\"", + androidStep2Hint: "hoặc \"Cài đặt ứng dụng\"", + androidStep3: "Xác nhận để cài đặt", + androidStep3Hint: "Ứng dụng sẽ xuất hiện trên màn hình chính của bạn", + tagline: "Miễn phí • Hoạt động ngoại tuyến • Nhanh & đáng tin cậy" + }, + home: { + tagline: "Do cộng đồng vận hành • Dựa trên Relay", + title: "SKATE SPOTS", + subtitle: "Khám phá Spots • Gặp gỡ • Học trick • Ủng hộ địa phương", + description: "Trượt ván thật diễn ra ngoài đời - công cụ này giúp bạn tìm thấy nó.", + betaWarning: "BETA - Đang xây dựng • Dùng với rủi ro của riêng bạn", + pwaHint: "Ứng dụng web tiến bộ - Cài đặt trên thiết bị của bạn", + exploreMap: "Khám phá bản đồ", + addSpot: "Thêm Spot", + globalSpots: "Spots toàn cầu", + openCommunity: "Cộng đồng mở", + lightningZaps: "Lightning Zaps", + featuredSpots: "Spots nổi bật", + featuredSpotsDesc: "Các spot trượt ván được cộng đồng xác minh từ khắp thế giới", + upcomingEvents: "Sự kiện sắp tới", + upcomingEventsDesc: "Cuộc thi, buổi gặp mặt và buổi trượt sắp diễn ra", + noSpotsYet: "Chưa tìm thấy spot nào", + noSpotsHint: "Hãy là người đầu tiên thêm một spot trượt ván!", + noEventsYet: "Không có sự kiện sắp tới", + noEventsHint: "Quay lại sau hoặc tạo một sự kiện!", + theLab: "The Lab", + theLabDesc: "Học trick, tìm huấn luyện viên và nâng cao trình độ trượt ván", + coaches: "Huấn luyện viên", + coachesDesc: "Học từ những skater giàu kinh nghiệm có thể giúp bạn tiến bộ", + filmers: "Người quay phim", + filmersDesc: "Kết nối với người quay phim để ghi lại những clip đẹp nhất của bạn", + findCoach: "Tìm huấn luyện viên", + becomeCoach: "Trở thành huấn luyện viên", + findFilmer: "Tìm người quay phim", + becomeFilmer: "Trở thành người quay phim", + viewAllSpots: "Xem tất cả Spots", + viewAllEvents: "Xem tất cả sự kiện", + createEvent: "Tạo sự kiện", + readyToShare: "Sẵn sàng chia sẻ?", + readyToShareDesc: "Giúp cộng đồng trượt ván phát triển bằng cách thêm những spot yêu thích của bạn. Mỗi địa điểm bạn chia sẻ giúp những skater khác khám phá địa điểm mới để trượt." + }, + about: { + title: "Giới thiệu về SkateSpots", + subtitle: "Cộng đồng trượt ván phi tập trung", + whatIs: "SkateSpots là gì?", + whatIsDesc: "SkateSpots là nền tảng do cộng đồng vận hành để khám phá các địa điểm trượt ván trên toàn thế giới. Được xây dựng trên Nostr, nó trao cho skater quyền sở hữu thực sự đối với dữ liệu của họ.", + features: "Tính năng", + featuresDesc: "Tìm spot, tạo sự kiện, kết nối với huấn luyện viên và ủng hộ các cửa hàng trượt ván địa phương—tất cả ở một nơi.", + nostr: "Xây dựng trên Nostr", + nostrDesc: "Nostr là một giao thức mở, đơn giản cho phép giao tiếp toàn cầu thực sự chống kiểm duyệt. Tài khoản và dữ liệu của bạn thuộc về bạn.", + openSource: "Mã nguồn mở", + openSourceDesc: "SkateSpots hoàn toàn là mã nguồn mở. Hãy đóng góp, fork hoặc chạy phiên bản của riêng bạn.", + lightning: "Thanh toán Lightning", + lightningDesc: "Zap những skater, huấn luyện viên và nhà sáng tạo nội dung yêu thích của bạn bằng thanh toán Bitcoin Lightning." + }, + faq: { + title: "Câu hỏi thường gặp", + subtitle: "Mọi điều bạn cần biết về SkateSpots", + whatIsNostr: "Nostr là gì?", + whatIsNostrAnswer: "Nostr là một giao thức mở cho mạng xã hội phi tập trung. Không giống các nền tảng truyền thống, bạn sở hữu dữ liệu và danh tính của mình.", + howToStart: "Làm thế nào để bắt đầu?", + howToStartAnswer: "Nhấn \"Đăng ký\" để tạo tài khoản Nostr mới, hoặc \"Đăng nhập\" nếu bạn đã có. Bạn có thể dùng tiện ích trình duyệt, ứng dụng di động hoặc khóa bí mật.", + whatAreZaps: "Zaps là gì?", + whatAreZapsAnswer: "Zaps là tiền tip Bitcoin Lightning bạn có thể gửi cho người dùng khác. Chúng là cách để thể hiện sự trân trọng với nội dung hay hoặc ủng hộ nhà sáng tạo.", + howToAddSpot: "Làm thế nào để thêm một spot?", + howToAddSpotAnswer: "Đăng nhập vào tài khoản, nhấn \"Thêm Spot\" và điền thông tin bao gồm vị trí, ảnh và mô tả.", + isItFree: "SkateSpots có miễn phí không?", + isItFreeAnswer: "Có! SkateSpots hoàn toàn miễn phí sử dụng. Bạn có thể tùy chọn gửi Zaps (tiền tip Bitcoin) cho người dùng khác.", + canIEditSpot: "Tôi có thể sửa hoặc xóa spot của mình không?", + canIEditSpotAnswer: "Có, bạn có thể sửa spot mình đã tạo. Do tính phi tập trung của Nostr, yêu cầu xóa sẽ được gửi đi nhưng một số relay có thể vẫn giữ dữ liệu." + }, + onboarding: { + welcome: "Chào mừng đến với SkateSpots!", + welcomeDesc: "Hãy thiết lập chỉ trong vài bước.", + step1Title: "Tạo tài khoản của bạn", + step1Desc: "Khóa Nostr của bạn đang được tạo. Nó giống như một mật khẩu do bạn kiểm soát.", + step2Title: "Sao lưu khóa của bạn", + step2Desc: "Lưu cụm từ khôi phục ở nơi an toàn. Đây là cách duy nhất để khôi phục tài khoản của bạn!", + step3Title: "Thiết lập hồ sơ của bạn", + step3Desc: "Giới thiệu về bản thân với cộng đồng.", + step4Title: "Bạn đã sẵn sàng!", + step4Desc: "Bắt đầu khám phá spot, sự kiện và kết nối với các skater.", + skipForNow: "Bỏ qua lúc này", + continueToApp: "Tiếp tục đến ứng dụng" + } +}; export default viBatch1; diff --git a/src/i18n/vi/batch2.ts b/src/i18n/vi/batch2.ts index 2f5dc2e..85674c3 100644 --- a/src/i18n/vi/batch2.ts +++ b/src/i18n/vi/batch2.ts @@ -1,4 +1,1652 @@ -/** vi — batch 2. Filled by the translation pass; empty until then. */ -const viBatch2 = {}; +/** vi — batch 2: bản đồ, spot, DIY, nhãn dữ liệu, phí, thẻ, chỉ đường và trợ lý Sasquatch. Từ vựng trượt ván giữ tiếng Anh; tên trick giữ tiếng Anh. Giữ nguyên {{placeholder}}/markdown/URL. */ +const viBatch2 = { + mapUi: { + mapFooter: { + links: 'Liên kết', + hide: 'Ẩn thanh liên kết bản đồ', + }, + findingSpots: 'Đang tìm spot', + loadingSpots: 'Đang tải spot', + loadingMap: 'Đang tải bản đồ...', + mapViewAria: 'Chế độ bản đồ', + listViewAria: 'Chế độ danh sách', + layers: 'Lớp', + mapLayers: 'Các lớp bản đồ', + showOnMap: 'Hiện trên bản đồ', + showResults: 'Hiện kết quả', + quickActions: 'Thao tác nhanh', + spots: 'Spot', + shops: 'Cửa hàng', + gear: 'Đồ nghề', + tours: 'Tour', + events: 'Sự kiện', + crews: 'Crew', + spotType: 'Loại spot', + sortBy: 'Sắp xếp theo', + trustLevel: 'Mức độ tin cậy', + weather: 'Thời tiết', + buySellGear: 'Mua/Bán đồ nghề', + stash: 'Stash', + more: 'Thêm', + newHere: 'Mới đến?', + welcomeDesc: 'Khám phá spot trượt, sự kiện & cộng đồng.', + getOnZapstore: 'Tải trên Zapstore', + dismiss: 'Bỏ qua', + addedBy: 'Thêm bởi', + directions: 'Chỉ đường', + viewDetails: 'Xem chi tiết', + viewDetailsArrow: 'Xem chi tiết →', + spotDetails: 'Chi tiết spot', + skateShop: 'Cửa hàng trượt ván', + skateSpot: 'Spot trượt ván', + youAreHere: 'Bạn đang ở đây', + conditions: 'Điều kiện', + weatherScoreSuffix: '{{score}}/100 thời tiết', + wind: 'Gió', + humidity: 'Độ ẩm', + airQuality: 'Chất lượng không khí', + threeDayForecast: 'Dự báo 3 ngày', + gearForSale: 'Đồ nghề đang bán ({{count}})', + viewItems: 'Xem đồ →', + viewAllItems: 'Xem tất cả {{count}} đồ →', + viewGear: 'Xem đồ nghề →', + localTour: 'Tour địa phương', + meetAt: 'Gặp tại: {{place}}', + hours: '{{count}} giờ', + level: 'Trình độ {{level}}', + viewTour: 'Xem tour →', + upcomingEvent: 'Sự kiện sắp tới', + viewEvent: 'Xem sự kiện →', + skateCrew: 'Crew trượt ván', + members: '{{count}} thành viên', + since: 'Từ {{year}}', + viewCrew: 'Xem crew →', + acceptsBitcoin: 'Chấp nhận Bitcoin', + boosted: 'Đã đẩy', + website: 'Trang web', + offlineSavedSpots: 'Ngoại tuyến · đang hiện spot đã lưu', + cantReachRelays: 'Không kết nối được relay', + relayOnlineNoAnswer: 'Bạn đang trực tuyến, nhưng relay cộng đồng hiện không phản hồi.', + youreOffline: 'Bạn đang ngoại tuyến.', + savedOnDevice: 'Những spot bạn đã từng xem được lưu trên thiết bị này và sẽ hiện ở đây.', + noSpotsMatchTitle: 'Không có spot nào khớp', + noSpotsMatchDesc: 'Thử tìm từ khóa khác hoặc xóa bộ lọc.', + noSpotsMappedYet: 'Chưa có spot nào trên bản đồ', + noSpotsMappedDesc: 'Hãy là người đầu tiên đánh dấu công viên của bạn — chỉ mất một phút, là của bạn, và người trượt kế tiếp sẽ cảm ơn bạn.', + addFirstSpot: 'Thêm spot đầu tiên', + findSpotsNearMe: 'Tìm spot gần tôi', + locating: 'Đang định vị…', + refiningLocation: 'Đang tinh chỉnh vị trí của bạn…', + refiningLocationDesc: 'Lấy tâm từ spot gần nhất — đang lấy tín hiệu GPS mới.', + locatingYou: 'Đang định vị bạn…', + locatingDesc: 'Đang lấy tín hiệu GPS. Lần đầu có thể mất tới một phút.', + foundYou: 'Đã tìm thấy bạn', + foundYouDesc: 'Đã căn bản đồ theo vị trí của bạn.', + locationPermissionNeeded: 'Cần quyền truy cập vị trí', + permissionNeededDesc: 'Cho phép SkateSpots truy cập vị trí trong Cài đặt → Ứng dụng → SkateSpots → Quyền, rồi nhấn Gần tôi lần nữa.', + locationTimedOut: 'Định vị quá thời gian', + timeoutNativeDesc: 'Không lấy được vị trí kịp lúc. Nếu bạn ở trong nhà, GPS không thấy được vệ tinh — hãy bật Định vị qua mạng (Cài đặt → Vị trí) hoặc ra ngoài rồi thử lại.', + timeoutWebDesc: 'Không lấy được vị trí của bạn kịp lúc. Kiểm tra tín hiệu và thử lại.', + noLocationProvider: 'Không có dịch vụ định vị', + noProviderNativeDesc: 'Điện thoại của bạn không cung cấp vị trí. Trên các ROM chú trọng quyền riêng tư (ví dụ GrapheneOS), hãy bật Định vị qua mạng trong Cài đặt → Vị trí, hoặc đảm bảo GPS đang bật và thử ở ngoài trời.', + noProviderWebDesc: 'Không có dịch vụ định vị nào khả dụng. Bật dịch vụ vị trí và thử lại.', + locationUnavailable: 'Vị trí không khả dụng', + unavailableNativeDesc: 'Bật Vị trí/GPS trong cài đặt điện thoại, cho phép SkateSpots truy cập vị trí (Cài đặt → Ứng dụng → SkateSpots → Quyền), rồi thử lại.', + unavailableWebDesc: 'Không xác định được vị trí của bạn. Hãy đảm bảo dịch vụ vị trí đã được bật.', + locationBlocked: 'Vị trí bị chặn', + locationBlockedDesc: 'Trình duyệt của bạn đã chặn truy cập vị trí cho trang này. Đây là cách bật lại:', + locationPlatformAndroid: 'Android Chrome', + locationPlatformIos: 'iOS Safari', + locationPlatformDesktop: 'Chrome trên máy tính', + locationPlatformFirefox: 'Firefox', + locationStepsAndroid: 'Nhấn biểu tượng ổ khóa trên thanh địa chỉ → Cài đặt trang web → Vị trí → Cho phép', + locationStepsIos: 'Ứng dụng Cài đặt → Safari → Vị trí → Cho phép (hoặc nhấn nút "AA" trên thanh địa chỉ của Safari)', + locationStepsDesktop: 'Nhấn biểu tượng ổ khóa → Cài đặt trang web → Vị trí → Cho phép', + locationStepsFirefox: 'Nhấn biểu tượng ổ khóa → Kết nối an toàn → Thông tin thêm → Quyền → Truy cập vị trí của bạn → Cho phép', + gotIt: 'Đã hiểu', + addSpot: 'Thêm spot', + addShop: 'Thêm cửa hàng', + addEvent: 'Thêm sự kiện', + addSpotHereTitle: 'Thêm spot ở đây?', + addSpotHereDesc: 'Thả ghim tại nơi bạn nhấn', + sellGear: 'Bán đồ nghề', + offerTour: 'Đăng tour', + closeAddMenu: 'Đóng menu thêm', + addMenuAria: 'Thêm spot, cửa hàng, sự kiện, đồ nghề hoặc tour', + localChat: 'Chat địa phương', + localChatDesc: 'Chat trực tiếp cho nơi bản đồ đang căn giữa. Chọn độ rộng kênh.', + btcMapShowing: 'Đang hiện {{count}} nơi bạn có thể Spedn sats ở gần đây', + btcMapShow: 'Hiện nơi bạn có thể Spedn sats (qua BTC Map)', + yourPrivateStash: 'Stash riêng của bạn', + stashIntro: 'Theo dõi đồ nghề, đặt giá và tìm người trao đổi với skater khác.', + encryptionRequired: 'Cần mã hóa', + encryptionRequiredDesc: 'Dùng signer hỗ trợ NIP-44 (Alby, nos2x, Amber).', + myStash: 'Stash của tôi', + encrypted: 'Đã mã hóa', + itemsCount: '{{count}} món', + items: 'Món', + wishlist: 'Danh sách mong muốn', + types: 'Loại', + stashEmpty: 'Stash của bạn đang trống', + addFirstItem: 'Thêm món đầu tiên', + wishlistCount: 'Danh sách mong muốn ({{count}})', + myGearCount: 'Đồ nghề của tôi ({{count}})', + openFullStash: 'Mở toàn bộ Stash', + addItem: 'Thêm món', + searchSpotsPlaceholder: 'Tìm spot...', + selected: 'Đã chọn', + noSpotsFound: 'Không tìm thấy spot nào. Thử từ khóa khác.', + addingSpotsHint: 'Thêm spot giúp người dùng tìm thấy bạn khi duyệt các địa điểm cụ thể', + report: 'Báo cáo', + spotSingular: '1 spot', + spotPlural: '{{count}} spot', + view: 'Xem', + myCollections: 'Bộ sưu tập của tôi', + collectionsSubtitle: 'Sắp xếp spot yêu thích thành các danh sách cá nhân', + newCollection: 'Bộ sưu tập mới', + loginToCreate: 'Đăng nhập để tạo bộ sưu tập', + loginToCreateDesc: 'Lưu spot yêu thích vào danh sách cá nhân như "Chuyến Barcelona 2024" hay "Rail đẹp nhất LA"', + noCollections: 'Chưa có bộ sưu tập nào', + noCollectionsDesc: 'Tạo bộ sưu tập đầu tiên để bắt đầu sắp xếp spot', + createFirstCollection: 'Tạo bộ sưu tập đầu tiên', + createNewCollection: 'Tạo bộ sưu tập mới', + createCollectionDesc: 'Đặt tên và mô tả tùy chọn cho bộ sưu tập', + collectionName: 'Tên bộ sưu tập', + collectionNamePlaceholder: 'Chuyến Barcelona 2024', + descriptionOptional: 'Mô tả (tùy chọn)', + descriptionPlaceholder: 'Những spot yêu thích trong chuyến đi Barcelona của tôi...', + creating: 'Đang tạo...', + createCollection: 'Tạo bộ sưu tập', + editCollection: 'Sửa bộ sưu tập', + saving: 'Đang lưu...', + saveChanges: 'Lưu thay đổi', + deleteCollectionTitle: 'Xóa bộ sưu tập?', + deleteCollectionDesc: 'Thao tác này sẽ xóa vĩnh viễn "{{title}}". Bản thân các spot không bị ảnh hưởng.', + deleting: 'Đang xóa...', + collectionCreated: 'Đã tạo bộ sưu tập!', + collectionCreatedDesc: '"{{title}}" đã sẵn sàng cho spot', + collectionCreateFailed: 'Tạo bộ sưu tập thất bại', + collectionUpdated: 'Đã cập nhật bộ sưu tập!', + changesSaved: 'Thay đổi của bạn đã được lưu', + collectionUpdateFailed: 'Cập nhật bộ sưu tập thất bại', + collectionDeleted: 'Đã xóa bộ sưu tập', + collectionDeletedDesc: '"{{title}}" đã bị gỡ', + collectionDeleteFailed: 'Xóa bộ sưu tập thất bại', + somethingWentWrong: 'Đã xảy ra lỗi', + }, + mapPage: { + title: 'Cửa hàng & Spot', + spots: 'Spot', + shops: 'Cửa hàng', + filters: 'Bộ lọc', + listView: 'Danh sách', + mapView: 'Bản đồ', + nearMe: 'Gần tôi', + searchPlaceholder: 'Tìm spot...', + noSpotsInArea: 'Không có spot trong khu vực này', + zoomIn: 'Phóng to', + zoomOut: 'Thu nhỏ', + myLocation: 'Vị trí của tôi', + locationsFound: 'Tìm thấy {{count}} địa điểm', + spotsOnly: 'Chỉ spot', + shopsOnly: 'Chỉ cửa hàng', + spotsAndShops: 'Spot & Cửa hàng', + noSpotsMatch: 'Không có spot nào khớp bộ lọc của bạn.', + noSpotsYet: 'Chưa có spot nào được thêm.', + addFirstSpot: 'Thêm spot đầu tiên', + }, + spotUi: { + claim: { + areYouOwner: 'Đây có phải spot của bạn?', + privateDesc: 'Spot này được đánh dấu riêng tư. Nếu bạn sở hữu hoặc quản lý nó, hãy nhận — một kiểm duyệt viên SkateSpots xác nhận quyền sở hữu, sau đó bạn tiếp quản danh sách.', + claimSpot: 'Nhận spot này', + nip05Required: 'Bạn cần handle NIP-05 đã xác minh để nhận một spot riêng tư (bằng chứng bạn kiểm soát một danh tính Nostr). Thêm vào hồ sơ của bạn, rồi quay lại.', + addNip05: 'Thêm NIP-05 trong Cài đặt', + pendingTitle: 'Yêu cầu nhận đang chờ duyệt', + pendingDesc: 'Yêu cầu nhận của bạn đã được gửi. Một kiểm duyệt viên SkateSpots sẽ xem xét — bạn có thể hoàn tất nhận spot sau khi được chấp thuận.', + approvedTitle: 'Yêu cầu nhận đã được duyệt', + approvedDesc: 'Một kiểm duyệt viên đã duyệt yêu cầu của bạn. Hoàn tất để trở thành chủ sở hữu spot này.', + complete: 'Hoàn tất nhận spot', + submitted: 'Đã gửi yêu cầu nhận', + submittedDesc: 'Một kiểm duyệt viên sẽ xem xét yêu cầu của bạn. Bạn sẽ tiếp quản spot sau khi được chấp thuận.', + submitFailed: 'Không gửi được yêu cầu nhận', + submit: 'Gửi yêu cầu nhận', + submitting: 'Đang gửi…', + confirmTitle: 'Nhận "{{title}}"?', + confirmIntro: 'Bạn đang yêu cầu trở thành chủ sở hữu spot riêng tư này.', + confirmBullet1: 'Một kiểm duyệt viên SkateSpots xem xét yêu cầu (chúng tôi không thể xác minh quyền sở hữu, chỉ khóa Nostr)', + confirmBullet2: 'Nếu được duyệt, bạn hoàn tất nhận để trở thành chủ sở hữu và có thể sửa spot', + confirmBullet3: 'Spot gốc vẫn ở lại trên Nostr — mạng lưới là phi tập trung', + adminTitle: 'Yêu cầu nhận quyền sở hữu đang chờ', + adminApprove: 'Duyệt', + adminApproved: 'Đã duyệt', + adminApprovedDesc: 'Họ giờ có thể hoàn tất nhận spot.', + adminApproveFailed: 'Không duyệt được yêu cầu nhận', + loginRequired: 'Đăng nhập để nhận spot riêng tư này, hoặc để yêu cầu quyền sở hữu.', + }, + abandonedDesc: 'Cập nhật lần cuối {{time}}. Nếu chủ sở hữu gốc không hoạt động, bạn có thể nhận spot này để duy trì và cải thiện nó.', + claimedNotice: 'Danh sách đã được nhận', + claimedNoticeDesc: 'Spot này đã được chủ sở hữu mới đăng lại sau khi nhận. Danh sách gốc có thể vẫn tồn tại riêng.', + abandonedLoginDesc: 'Cập nhật lần cuối {{time}}. Đăng nhập để nhận và duy trì spot này.', + accessDeniedDesc: 'Bạn chỉ có thể sửa những spot do bạn tạo.', + accessDeniedTitle: 'Truy cập bị từ chối', + addAtLeastOneTag: 'Vui lòng thêm ít nhất một tag.', + additionalDetails: 'Chi tiết bổ sung (tùy chọn)', + additionalDetailsPlaceholder: 'Cung cấp bất kỳ ngữ cảnh bổ sung nào có thể hữu ích...', + addNewTags: 'Thêm tag mới:', + addNip05InSettings: 'Thêm NIP-05 trong Cài đặt', + addPhoto: 'Thêm ảnh', + addPhotoDesc: 'Đóng góp một bức ảnh để giúp người khác khám phá spot này.', + addPhotoOrDescription: 'Thêm ảnh hoặc mô tả', + addPhotoOrDescriptionDesc: 'Cho skater thứ gì đó để nắm — một bức ảnh, hoặc một dòng về địa điểm.', + addPhotos: 'Thêm ảnh', + addPhotoToSpot: 'Thêm ảnh vào spot', + adminDeleteDialogDesc: 'Là quản trị viên SkateSpots, bạn đang gỡ "{{title}}". Nó sẽ bị ẩn trên toàn ứng dụng cho mọi người và một yêu cầu xóa sẽ được gửi tới relay.', + adminDeleteReason: 'Quản trị viên SkateSpots đã gỡ spot "{{title}}"', + airQuality: 'Chất lượng không khí', + altSkateSpot: 'Spot trượt ván: {{title}}', + areYouShopOwner: 'Bạn có phải chủ cửa hàng?', + askBeforeSkating: 'Hỏi trước khi trượt', + backToSpot: 'Quay lại spot', + beFirstToListGear: 'Hãy là người đầu tiên đăng bán đồ nghề tại spot này!', + beFirstToSay: 'Hãy là người đầu tiên nói gì đó.', + byAuthor: 'bởi {{name}}', + captionPlaceholder: 'Thêm chú thích (tùy chọn) - mô tả nội dung trong ảnh, thời điểm chụp, v.v.', + chatPublicNote: 'Ai cũng đọc được — tin nhắn công khai & tạm thời. Muốn chat riêng, dùng Tin nhắn trực tiếp.', + checkPinBelow: 'Kiểm tra ghim bên dưới trước khi thêm bản trùng.', + claimBullet1: 'Bạn trở thành chủ sở hữu và có thể sửa spot', + claimBullet2: 'Spot gốc vẫn còn (Nostr là phi tập trung)', + claimBullet3: 'Bản của bạn có thể xuất hiện bên cạnh bản gốc', + claimFailed: 'Nhận spot thất bại', + claiming: 'Đang nhận...', + claimIntro: 'Bạn sắp nhận quyền sở hữu spot này. Thao tác này sẽ tạo bản spot của riêng bạn để bạn có thể sửa và duy trì.', + claimSpot: 'Nhận spot', + claimThisSpot: 'Nhận spot này', + claimTitle: 'Nhận "{{title}}"?', + claimWhatHappens: 'Điều gì xảy ra khi bạn nhận:', + coachesAndFilmersAvailable: 'Coach và filmer có sẵn tại spot này', + coachesCount: 'Coach ({{count}})', + coachHere: 'Có coach ở đây', + community: 'Cộng đồng', + communityVerified: 'Cộng đồng đã xác minh', + communityVerifiedTitle: 'Một skater khác đã đóng góp ở đây (ảnh hoặc báo cáo trạng thái).', + conditions: 'Điều kiện', + contactForPermission: 'Liên hệ để xin phép', + contactInfo: 'Thông tin liên hệ', + contributePhoto: 'Đóng góp ảnh', + contributing: 'Đang đóng góp...', + couldNotSendMessage: 'Không gửi được tin nhắn.', + couldNotSubmit: 'Không gửi được', + couldNotUploadPhoto: 'Không tải lên được ảnh. Bạn có thể thêm một ảnh bên dưới.', + crewsThatSkateHere: 'Crew trượt ở đây', + current: 'Hiện tại:', + currentTags: 'Tag hiện có trên spot này:', + daysAgo: '{{count}} ngày trước', + daysAgoPlural: '{{count}} ngày trước', + deleteDialogDesc: 'Thao tác này sẽ xóa vĩnh viễn "{{title}}" khỏi mọi relay. Không thể hoàn tác.', + deletedSpotReason: 'Spot đã bị xóa', + deleteFailed: 'Xóa thất bại', + deleteSpot: 'Xóa spot', + deleteSpotTitle: 'Xóa spot?', + differentSpotPublishAnyway: 'Đây là spot khác — vẫn đăng', + dragDropOrClick: 'Kéo & thả hoặc nhấn', + dropPhotos: 'Thả ảnh', + duplicateOne: 'Có một spot trong vòng 60 m quanh ghim của bạn. Nếu cùng địa điểm, hãy thêm ảnh hoặc báo cáo trạng thái ở đó thay vì tạo bản trùng.', + duplicateOther: 'Có các spot trong vòng 60 m quanh ghim của bạn. Nếu cùng địa điểm, hãy thêm ảnh hoặc báo cáo trạng thái ở đó thay vì tạo bản trùng.', + editSpotSeoDesc: 'Sửa spot trượt ván của bạn.', + failedToContribute: 'Đóng góp thất bại', + failedToPublish: 'Đăng thất bại', + failedToPublishDesc: 'Đã xảy ra lỗi. Kiểm tra console để biết chi tiết.', + failedToSubmitReport: 'Gửi báo cáo thất bại', + failedToSuggestTags: 'Gợi ý tag thất bại', + failedToUpdate: 'Cập nhật thất bại', + failedToUploadImage: 'Tải ảnh lên thất bại', + failedToUploadPhoto: 'Tải ảnh lên thất bại', + feelsLikeTemp: 'Cảm giác như {{temp}}°C', + filmersCount: 'Filmer ({{count}})', + filmHere: 'Quay phim ở đây', + gearSwap: 'Trao đổi đồ nghề', + geolocationNotSupported: 'Không hỗ trợ định vị', + geolocationNotSupportedDesc: 'Trình duyệt của bạn không hỗ trợ định vị.', + getDirections: 'Chỉ đường', + hangTight: 'Chờ chút', + hangTightDesc: 'Ảnh của bạn vẫn đang tải lên. Nó sẽ được đính kèm trong giây lát.', + helpImproveSpot: 'Giúp cải thiện spot này bằng cách thêm ảnh hoặc gợi ý tag', + hiddenByModerator: 'Bị kiểm duyệt viên ẩn', + hiddenByModeratorDesc: 'Spot này không hiện trên bản đồ hay trong tìm kiếm. Bạn vẫn thấy được vì nó là của bạn. Sửa nó sẽ không bỏ ẩn — nó vẫn bị ẩn cho tới khi kiểm duyệt viên thu hồi phán quyết.', + humidity: 'Độ ẩm', + imageUploaded: 'Đã tải ảnh lên', + imageUploadedDesc: 'Ảnh của bạn đã được tải lên thành công.', + imHere: '"Tôi ở đây"', + invalidCoordinates: 'Tọa độ không hợp lệ', + invalidCoordinatesDesc: 'Vui lòng nhập vĩ độ (-90 đến 90) và kinh độ (-180 đến 180) hợp lệ.', + invalidNpub: 'npub không hợp lệ', + invalidNpubDesc: 'Vui lòng nhập địa chỉ npub hợp lệ.', + lastReported: 'lần cuối {{time}}', + listGear: 'Đăng bán đồ nghề', + listYourGearHere: 'Đăng bán đồ nghề của bạn ở đây', + loadingChat: 'Đang tải chat…', + locationError: 'Lỗi vị trí', + locationFound: 'Đã tìm thấy vị trí', + locationFoundDesc: 'Vị trí hiện tại của bạn đã được đặt.', + locationRequired: 'Cần vị trí', + locationRequiredDesc: 'Vui lòng nhập tọa độ hoặc dùng vị trí hiện tại của bạn.', + loginRequiredTitle: 'Cần đăng nhập', + logInToChat: 'Đăng nhập để tham gia chat địa phương.', + logInToContributePhotos: 'Đăng nhập để đóng góp ảnh', + loginToEditSpot: 'Bạn cần đăng nhập để sửa spot này.', + logInToReport: 'Bạn cần đăng nhập để báo cáo nội dung.', + logInToReportStatus: 'Đăng nhập để báo cáo trạng thái spot này.', + logInToSuggestTags: 'Đăng nhập để gợi ý tag', + manageNip05ToClaim: 'Quản lý NIP-05 để nhận spot', + meetAtSpotForPickup: '💡 Gặp tại spot này để nhận hàng an toàn', + memberOne: '{{count}} thành viên', + memberOther: '{{count}} thành viên', + messageFailed: 'Gửi tin nhắn thất bại', + messageMapper: 'Người vẽ bản đồ', + messagePlaceholder: 'Nhắn cho spot này… (thử /me hoặc /who)', + messagesHiddenOne: '{{count}} tin nhắn bị ẩn bởi bộ lọc tin cậy của bạn. Hạ bộ lọc để xem thêm.', + messagesHiddenOther: '{{count}} tin nhắn bị ẩn bởi bộ lọc tin cậy của bạn. Hạ bộ lọc để xem thêm.', + messagesHiddenShortOne: '{{count}} tin nhắn bị ẩn bởi bộ lọc tin cậy của bạn', + messagesHiddenShortOther: '{{count}} tin nhắn bị ẩn bởi bộ lọc tin cậy của bạn', + metresAway: 'cách {{distance}} m', + moderatorVouchedDesc: 'Một kiểm duyệt viên đã xem xét spot này và bảo chứng cho nó. Tuyệt vời.', + monthsAgo: '{{count}} tháng trước', + monthsAgoPlural: '{{count}} tháng trước', + newOwnerNpub: 'npub của chủ sở hữu mới', + newOwnerNpubHint: 'Nhập npub của người dùng bạn muốn chuyển spot này cho.', + nip05RequiredToClaim: '⚠️ Cần xác minh NIP-05 để nhận cửa hàng', + noCommunitySignalTitle: 'Chưa có ảnh cộng đồng hay báo cáo trạng thái — chưa ai xác nhận địa điểm này.', + breakdownPhotos: '{{count}} ảnh', + breakdownStatus: '{{count}} báo cáo trạng thái', + breakdownComments: '{{count}} bình luận', + breakdownReactions: '{{count}} cảm xúc', + breakdownCollections: '{{count}} lượt lưu', + breakdownZaps: '{{count}} zap', + breakdownTags: '{{count}} gợi ý tag', + breakdownCrews: '{{count}} crew', + breakdownLab: '{{count}} liên kết pro', + verifyNudgeTitle: 'Hãy là người đầu tiên xác nhận spot này', + verifyNudgeBody: 'Một bức ảnh hoặc một câu “Tôi đã trượt ở đây” là cách một spot được xác minh — giúp skater kế tiếp.', + verifyNudgeStatus: 'Tôi đã trượt ở đây', + communityChip: 'Cộng đồng', + seenChip: 'Đã thấy', + noGearListedYet: 'Chưa có đồ nghề nào được đăng', + noMessagesYet: 'Chưa có tin nhắn nào trong kênh địa phương này. Chào một câu — "tối nay có ai trượt không?"', + noPhoto: 'Không có ảnh', + noReportsYet: 'Chưa có báo cáo nào', + noTags: 'Không có tag', + notASkateSpot: 'Không phải spot trượt ván', + offerServicesHere: '💡 Cung cấp dịch vụ của bạn tại spot này', + photoCaptured: 'Đã chụp ảnh!', + photoCapturedDesc: 'Ảnh của bạn đã được tải lên thành công.', + photoContributed: 'Đã đóng góp ảnh!', + photoContributedDesc: 'Ảnh của bạn đã được thêm vào spot này.', + photosAdded: 'Ảnh của bạn đã được thêm.', + photosRecommended: 'rất khuyến khích — spot không có ảnh vẫn bị đánh dấu Chưa xác minh', + photosUploaded: 'Đã tải lên {{count}} ảnh', + photoUploaded: 'Đã tải ảnh lên', + photoUploadedDesc: 'Thêm chú thích và gửi để đóng góp!', + photoUploadFailed: 'Tải ảnh lên thất bại', + pleaseTryAgain: 'Vui lòng thử lại', + public: 'Công khai', + publicChatTitle: 'Ai cũng đọc được tin nhắn trong kênh này — nó công khai và không mã hóa.', + recentReports: 'Báo cáo gần đây', + recipientRequired: 'Cần người nhận', + recipientRequiredDesc: 'Vui lòng nhập npub của chủ sở hữu mới.', + removeAdmin: 'Gỡ (quản trị)', + removeSpot: 'Gỡ spot', + removeSpotAdminTitle: 'Gỡ spot này? (quản trị)', + reportOne: 'báo cáo', + reportContent: 'Báo cáo nội dung', + reportContentDesc: 'Giúp cộng đồng an toàn bằng cách báo cáo nội dung không phù hợp.', + reportedBySkaters: ' bởi {{count}} skater — đang xem xét. Nếu đây là spot thật, hãy thêm ảnh hoặc báo cáo trạng thái để xác nhận.', + reportedNotASpot: 'Bị báo cáo là không phải spot trượt ván', + reportingType: 'Đang báo cáo {{type}}', + reports: 'báo cáo', + reportShop: 'Báo cáo cửa hàng', + reportSpot: 'Báo cáo spot', + reportStatus: 'Báo cáo trạng thái', + reportSubmitted: 'Đã gửi báo cáo', + reportSubmittedDesc: 'Cảm ơn bạn đã giúp giữ SkateSpots an toàn.', + reportSubmittedLong: 'Cảm ơn bạn đã giúp giữ SkateSpots an toàn và chính xác. Báo cáo của bạn sẽ được các thành viên cộng đồng đáng tin cậy xem xét.', + reportSubmittedTitle: 'Đã gửi báo cáo', + report: { + notASkateSpot: { + label: 'Không phải spot trượt ván', + description: 'Một mục thử nghiệm, hoặc nơi hoàn toàn không dành cho trượt ván', + }, + fakeSpot: { + label: 'Spot giả/không tồn tại', + description: 'Spot này không tồn tại hoặc vị trí sai', + }, + stolenPhotos: { + label: 'Ảnh giả/đánh cắp', + description: 'Ảnh là ảnh stock hoặc lấy từ nơi khác', + }, + spamAd: { + label: 'Spam hoặc quảng cáo', + description: 'Nội dung quảng cáo hoặc danh sách trùng lặp', + }, + dangerousLocation: { + label: 'Địa điểm nguy hiểm', + description: 'Tài sản riêng, không an toàn hoặc bất hợp pháp để tiếp cận', + }, + inappropriateContent: { + label: 'Nội dung không phù hợp', + description: 'Chứa nội dung xúc phạm hoặc người lớn', + }, + impersonation: { + label: 'Mạo danh', + description: 'Ai đó giả làm người khác', + }, + other: { + label: 'Khác', + description: 'Điều gì đó khác không được liệt kê ở trên', + }, + }, + targetType: { + spot: 'Spot', + event: 'Sự kiện', + tour: 'Tour', + shop: 'Cửa hàng', + user: 'Người dùng', + listing: 'Tin đăng', + coach: 'Coach', + filmer: 'Filmer', + }, + sameOwner: 'Cùng chủ sở hữu', + sameOwnerDesc: 'Không thể chuyển cho chủ sở hữu hiện tại.', + saveChanges: 'Lưu thay đổi', + saving: 'Đang lưu...', + services: 'Dịch vụ', + shareSpotText: 'Xem spot trượt ván này: {{title}}', + shelter: 'Mái che', + shelterHint: 'Spot này có bị ảnh hưởng bởi thời tiết không? Giúp skater tìm chỗ khô ráo khi mưa.', + shopClaimDesc: 'Nếu bạn sở hữu hoặc quản lý cửa hàng này, bạn có thể nhận để xác minh quyền sở hữu và quản lý danh sách.', + shopClaimNip05Hint: 'Để nhận cửa hàng này, hãy thêm mã NIP-05 khớp với tên miền website của cửa hàng.', + skatersActiveDesc: 'Những người đã đăng trong kênh này trong 24 giờ qua.', + skatersActiveOne: '{{count}} skater đang hoạt động ở đây', + skatersActiveOther: '{{count}} skater đang hoạt động ở đây', + skatersSellingGear: 'Skater tại spot này đang bán đồ nghề', + skateSpot: 'Spot trượt ván', + somethingWentWrong: 'Đã xảy ra lỗi', + spot: 'Spot', + spotAdded: 'Đã thêm spot!', + spotAddedDesc: 'Spot trượt ván của bạn đã được đăng lên mạng lưới.', + spotAddedNoPhoto: 'Đã đăng — và bị đánh dấu Chưa xác minh cho tới khi ai đó thêm ảnh. Một bức ảnh về spot có giá trị lớn.', + spotChat: 'Chat của spot', + spotClaimed: 'Đã nhận spot!', + spotClaimedDesc: 'Bạn giờ là chủ sở hữu spot này. Bạn có thể sửa nó từ hồ sơ của mình.', + spotDeleted: 'Đã xóa spot', + spotDeletedDesc: 'Yêu cầu xóa đã được gửi tới relay. Hầu hết relay sẽ gỡ nội dung này.', + spotMayAlreadyBeOnMap: 'Spot đó có thể đã ở trên bản đồ', + spotMayAlreadyExist: 'Spot này có thể đã tồn tại', + spotMayBeAbandoned: 'Spot có thể đã bị bỏ hoang', + spotPhotoAlt: 'Spot', + spotRemoved: 'Đã gỡ spot', + spotRemovedDesc: 'Spot này đã bị gỡ và sẽ bị ẩn trên toàn SkateSpots.', + spotSeoDesc: 'Xem spot trượt ván này trên SkateSpots.', + spotStatus: 'Trạng thái spot', + spotStatusDesc: 'Liệu "{{title}}" còn trượt được không? Cho cộng đồng biết tình trạng hiện tại của nó.', + spotTypeRequired: 'Cần loại spot', + spotTypeRequiredDesc: 'Vui lòng chọn loại spot để skater biết họ đang đến chỗ nào.', + spotUpdated: 'Đã cập nhật spot!', + spotUpdatedDesc: 'Thay đổi của bạn đã được đăng lên mạng lưới.', + staffVerifiedTitle: 'Một quản trị viên SkateSpots đã xem xét và bảo chứng cho spot này.', + statusNotePlaceholder: 'Tùy chọn: thêm chi tiết (ví dụ "có chốt mới trên ledge", "bảo vệ đuổi sau 6 giờ chiều")', + statusReported: 'Đã báo cáo trạng thái', + statusReportedDesc: 'Cảm ơn bạn đã giữ bản đồ luôn mới. Báo cáo của bạn đã được đăng.', + submitReport: 'Gửi báo cáo', + submitting: 'Đang gửi...', + suggestedByUser: 'Được gợi ý bởi {{count}} người dùng', + suggestedByUsers: 'Được gợi ý bởi {{count}} người dùng', + suggestedTagsContent: 'Tag được gợi ý cho {{title}}: {{tags}}', + suggestNTags: 'Gợi ý {{count}} tag', + suggestOneTag: 'Gợi ý 1 tag', + suggestTags: 'Gợi ý tag', + suggestTagsDesc: 'Giúp phân loại spot này bằng cách gợi ý các tag phù hợp.', + tags: 'Tag', + tagsHint: 'Thêm tag cho đặc điểm, bề mặt, không khí (tối đa {{max}})', + tagsSuggested: 'Đã gợi ý tag!', + tagsSuggestedDesc: 'Các gợi ý tag của bạn đã được gửi.', + takePhoto: 'Chụp ảnh', + threeDayForecast: 'Dự báo 3 ngày', + tipTheMapper: 'Tip người vẽ bản đồ', + tipTheMapperDesc: 'Thấy spot này hữu ích? Gửi một zap để cảm ơn người vẽ bản đồ!', + titleRequired: 'Cần tiêu đề', + titleRequiredDesc: 'Vui lòng nhập tên cho spot này.', + today: 'Hôm nay', + tomorrow: 'Ngày mai', + transferDesc: 'Chuyển "{{title}}" cho người dùng khác. Không thể hoàn tác.', + transferFailed: 'Chuyển thất bại', + transferOwnership: 'Chuyển quyền sở hữu', + transferRequestContent: 'Yêu cầu chuyển quyền sở hữu cho spot "{{title}}"', + transferRequested: 'Đã yêu cầu chuyển', + transferRequestedDesc: 'Chủ sở hữu mới sẽ cần nhận spot để hoàn tất chuyển giao.', + transferring: 'Đang chuyển...', + transferSpotOwnership: 'Chuyển quyền sở hữu spot', + transferWarningDesc: 'Sau khi chuyển, bạn sẽ không thể sửa hoặc xóa spot này nữa.', + typeToSearchTags: 'Nhập để tìm hoặc thêm tag...', + underReview: ' — đang xem xét. Nếu đây là spot thật, hãy thêm ảnh hoặc báo cáo trạng thái để xác nhận.', + untitledSpot: 'Spot chưa có tên', + unverified: 'Chưa xác minh', + updateDetailsFor: 'Cập nhật chi tiết cho {{title}}', + updateSpotDesc: 'Cập nhật thông tin về spot này. Mọi trường có dấu * là bắt buộc.', + uploadAPhoto: 'Tải lên một ảnh', + uploadAPhotoHint: 'Kéo & thả hoặc nhấn · JPG, PNG, WebP', + uploadedAlt: 'Đã tải lên', + uploadFailed: 'Tải lên thất bại', + uploadingPhoto: 'Đang tải ảnh lên…', + uploadPhotoFirst: 'Vui lòng tải lên một ảnh trước.', + uvIndex: 'Chỉ số UV', + verifiedBySkateSpots: 'Được SkateSpots xác minh', + viewPhotoFullScreen: 'Xem ảnh toàn màn hình', + viewPhotoOf: 'Xem ảnh {{n}} / {{total}}', + warning: 'Cảnh báo', + weatherConditions: 'Điều kiện thời tiết', + weatherOnly: 'chỉ thời tiết', + weatherOnlyUnconfirmed: 'Chỉ thời tiết. Chưa ai xác nhận đây là spot trượt ván, nên không có điểm điều kiện — hãy thêm ảnh hoặc báo cáo trạng thái để xác nhận.', + whyReporting: 'Tại sao bạn báo cáo điều này?', + wind: 'Gió', + yearsAgo: '{{count}} năm trước', + yearsAgoPlural: '{{count}} năm trước', + }, + diyUi: { + title: 'DIY — Tự làm đồ của bạn', + tagline: 'Hướng dẫn, công cụ mở và bản thiết kế để bạn tự làm deck, ramp và spot bê tông — rồi tìm người, địa điểm và thị trường phù hợp.', + doItWithPeople: 'Làm cùng mọi người', + backToDiy: 'Quay lại DIY', + calc: { + title: 'Máy tính chi phí deck', + intro: 'Chi phí để làm một deck — công, thiết bị, vật liệu, thời gian xử lý, đóng gói và biên lợi nhuận — và giá bán hợp lý. Lưu trên thiết bị này.', + }, + designer: { + title: 'Trình thiết kế deck', + intro: 'Vẽ đường viền ván trượt hoặc longboard, rồi xuất mẫu in 1:1, SVG hoặc DXF cho CNC. Lưu trên thiết bị này.', + presets: 'Cài đặt sẵn', + dimensions: 'Kích thước', + shape: 'Hình dạng', + kicks: 'Kick', + hardware: 'Lỗ trucks', + width: 'Chiều rộng tối đa', + wheelbase: 'Khoảng cách trục', + nose: 'Chiều dài nose', + tail: 'Chiều dài tail', + length: 'Tổng chiều dài', + waist: 'Eo', + endRound: 'Độ tròn đầu', + concave: 'Concave', + thickness: 'Độ dày', + tailKick: 'Tail kick', + noseKick: 'Nose kick', + holeNew: 'New school (2.125″)', + holeOld: 'Old school (2.5″)', + holeSpacing: 'New school là 2.125″ × 1.625″ (54 × 41 mm); old school là 2.5″ × 1.625″. Lỗ bắt vít 3/16″.', + topView: 'Nhìn từ trên', + sideView: 'Mặt bên', + concaveSection: 'Mặt cắt concave', + export: 'Xuất', + pdfA4: 'PDF 1:1 · A4', + pdfLetter: 'PDF 1:1 · Letter', + printNote: 'In PDF ở 100% (không “fit to page”), rồi ghép các trang bằng dấu chữ thập ở góc. SVG cũng đúng kích thước thật.', + note: 'Đây là đường viền 2D để bạn đồ và cắt. Với hình dạng 3D đầy đủ và thiết kế khuôn, một công cụ CAD thực thụ vẫn là lựa chọn đúng.', + }, + source: 'Nguồn', + comingSoon: 'Sắp ra mắt', + footer: 'Hướng dẫn từng bước đang được chuẩn bị. Trong lúc chờ: tìm những người chế tạo trong The Lab, đánh dấu spot của bạn, và mua bán ở Chợ. Làm việc an toàn — mang đệm, găng và kính bảo hộ.', + categories: { + boards: 'Ván', + ramps: 'Ramp & chướng ngại bằng gỗ', + concrete: 'Bê tông & spot DIY', + repairs: 'Sửa chữa & tinh chỉnh', + tools: 'Công cụ & bản thiết kế', + }, + cards: { + ossBuild: { + title: 'Làm một ván trượt', + blurb: 'Chế tạo deck từng bước — veneer, khuôn, máy ép và hoàn thiện.', + }, + sk8cad: { + title: 'SK8CAD', + blurb: 'CAD mã nguồn mở cho hình dạng deck, concave và thiết kế khuôn.', + }, + deckCost: { + title: 'Chi phí & giá deck', + blurb: 'Tính vật liệu, công và giá bán hợp lý trước khi làm.', + }, + deckDesigner: { + title: 'Trình thiết kế deck', + blurb: 'Vẽ đường viền và in mẫu 1:1 — hoặc xuất SVG/DXF cho CNC.', + }, + ledgeBox: { + title: 'Làm ledge hoặc box', + blurb: 'Chướng ngại bằng gỗ thân thiện cho người mới, làm được trong một cuối tuần.', + }, + quarterpipe: { + title: 'Làm quarterpipe', + blurb: 'Bản thiết kế ramp, transition và coping cho mini sân sau.', + }, + flatbar: { + title: 'Làm flatbar', + blurb: 'Rẻ, dễ mang theo và là cách tốt nhất để học rail.', + }, + concreteBasics: { + title: 'Kiến thức bê tông cơ bản', + blurb: 'Trộn, tạo khuôn và hoàn thiện một ledge hoặc bank bền lâu.', + }, + coping: { + title: 'Coping & cạnh', + blurb: 'Cách lắp coping và hoàn thiện transition để grind mượt.', + }, + buyParts: { + title: 'Mua phụ tùng & đồ nghề', + blurb: 'Mua deck, phụ tùng và dụng cụ từ người bán ở Chợ.', + }, + mapSpot: { + title: 'Đánh dấu spot DIY của bạn', + blurb: 'Đã làm gì đó? Thêm lên bản đồ để người khác tìm và trượt.', + }, + regrip: { + title: 'Dán lại griptape cho ván', + blurb: 'Bóc grip cũ và dán grip mới gọn gàng.', + }, + tune: { + title: 'Tinh chỉnh bearings & trucks', + blurb: 'Vệ sinh bearings, thay bushing và chỉnh hình học trucks.', + }, + printMolds: { + title: 'Khuôn in 3D', + blurb: 'Tệp khuôn và đế căn chỉnh có thể in từ cộng đồng.', + }, + sk8cadTools: { + title: 'Công cụ khuôn & căn chỉnh', + blurb: 'Thiết kế khuôn với đế căn chỉnh tích hợp.', + }, + }, + actions: { + findBuilder: { + title: 'Tìm thợ chế tạo', + blurb: 'Thợ làm ramp và DIY trong The Lab có thể thiết kế hoặc đổ bê tông cho bạn.', + }, + findCrew: { + title: 'Tìm crew DIY', + blurb: 'Các crew chuyên chế tạo — tham gia những nhóm biến spot thành hiện thực.', + }, + mapSpot: { + title: 'Đánh dấu spot DIY', + blurb: 'Thêm spot bạn đã làm để nó tồn tại trên bản đồ.', + }, + sellBuilds: { + title: 'Bán thành phẩm của bạn', + blurb: 'Đăng bán deck, ramp hoặc phụ tùng bạn làm ở Chợ.', + }, + findCoach: { + title: 'Tìm coach', + blurb: 'Coach dạy các mô-đun DIY và xây spot.', + }, + }, + }, + labelsUi: { + spotCategory: { + street: { + label: 'Street', + description: 'Spot tình cờ, địa hình đô thị', + }, + transition: { + label: 'Transition', + description: 'Bề mặt cong/ramp', + }, + park: { + label: 'Park', + description: 'Skatepark được xây dựng', + }, + plaza: { + label: 'Plaza', + description: 'Quảng trường đô thị (như MACBA, Love Park)', + }, + }, + spotFeature: { + wallrides: 'Wallrides', + stairs: 'Cầu thang & Tay vịn', + rails: 'Rail', + ledges: 'Ledge & Lề đường', + gaps: 'Gap', + flatground: 'Đất phẳng', + 'manual-pads': 'Manual Pad', + 'half-pipes': 'Half Pipe', + 'quarter-pipes': 'Quarter Pipe', + 'mini-ramps': 'Mini Ramp', + bowls: 'Bowl', + vert: 'Vert Ramp', + 'mega-ramps': 'Mega Ramp', + hubbas: 'Hubba', + 'euro-gaps': 'Euro Gap', + banks: 'Bank', + 'spine-ramps': 'Spine Ramp', + 'roll-ins': 'Roll-in', + hips: 'Hip', + volcano: 'Volcano', + pyramids: 'Pyramid / Funbox', + 'snake-runs': 'Snake Run', + 'pump-track': 'Pump Track', + 'flat-bars': 'Flat Bar', + }, + spotType: { + street: 'Street', + transition: 'Transition', + park: 'Park', + plaza: 'Plaza', + wallrides: 'Wallrides', + stairs: 'Cầu thang & Tay vịn', + rails: 'Rail', + ledges: 'Ledge & Lề đường', + gaps: 'Gap', + flatground: 'Đất phẳng', + 'manual-pads': 'Manual Pad', + 'half-pipes': 'Half Pipe', + 'quarter-pipes': 'Quarter Pipe', + 'mini-ramps': 'Mini Ramp', + bowls: 'Bowl', + vert: 'Vert Ramp', + 'mega-ramps': 'Mega Ramp', + hubbas: 'Hubba', + 'euro-gaps': 'Euro Gap', + banks: 'Bank', + 'spine-ramps': 'Spine Ramp', + 'roll-ins': 'Roll-in', + hips: 'Hip', + volcano: 'Volcano', + pyramids: 'Pyramid / Funbox', + 'snake-runs': 'Snake Run', + 'pump-track': 'Pump Track', + 'flat-bars': 'Flat Bar', + diy: 'DIY', + rail: 'Rail', + ledge: 'Ledge', + gap: 'Gap', + bowl: 'Bowl', + stall: 'Stall', + slappy: 'Slappy', + }, + access: { + public: { + label: 'Công khai - Mở cho mọi người', + }, + private: { + label: 'Tài sản riêng - Cần xin phép', + }, + locals: { + label: 'Hỏi người địa phương trước', + }, + }, + shelter: { + outdoor: { + label: 'Ngoài trời', + short: 'Ngoài trời', + description: 'Hoàn toàn lộ thiên — mưa là nghỉ', + }, + partial: { + label: 'Che một phần', + short: 'Che một phần', + description: 'Một số chướng ngại vẫn khô', + }, + covered: { + label: 'Có mái che', + short: 'Có mái', + description: 'Ngoài trời nhưng dưới mái', + }, + indoor: { + label: 'Trong nhà', + short: 'Trong nhà', + description: 'Kín hoàn toàn — trượt mưa hay nắng đều được', + }, + }, + eventType: { + contest: 'Cuộc thi', + demo: 'Demo', + session: 'Session', + workshop: 'Workshop', + premiere: 'Công chiếu', + tradeshow: 'Hội chợ', + gameskate: 'Game of Skate', + concert: '🎸 Hòa nhạc', + jam: '🎵 Jam', + festival: '🎪 Lễ hội', + popup: '🎯 Pop-Up', + }, + gearCategory: { + deck: 'Deck', + trucks: 'Trucks', + wheels: 'Wheels', + bearings: 'Bearings', + shoes: 'Giày trượt', + clothing: 'Quần áo', + protective: 'Đồ bảo hộ', + stickers: 'Sticker', + wax: 'Sáp', + tools: 'Dụng cụ', + griptape: 'Griptape', + rubbrick: 'Rub Brick', + }, + gearCondition: { + new: { + label: 'Mới', + description: 'Chưa dùng, còn nguyên bao bì', + }, + like_new: { + label: 'Như mới', + description: 'Hầu như chưa dùng, tình trạng tuyệt vời', + }, + good: { + label: 'Tốt', + description: 'Mòn thông thường, hoạt động hoàn hảo', + }, + well_used: { + label: 'Đã dùng nhiều', + description: 'Có dấu hiệu mòn nhưng vẫn dùng được', + }, + }, + priceType: { + fixed: { + label: 'Giá cố định', + description: 'Đặt giá bằng USD hoặc sats', + }, + free: { + label: 'Miễn phí', + description: 'Cho tặng', + }, + trade: { + label: 'Trao đổi', + description: 'Muốn đổi', + }, + offer: { + label: 'Trả giá', + description: 'Giá thương lượng', + }, + }, + listingType: { + selling: { + label: 'Đang bán', + description: 'Đăng bán đồ nghề', + }, + wtb: { + label: 'Cần mua', + description: 'Đang tìm đồ nghề cụ thể', + }, + }, + tour: { + spotType: { + street: 'Street', + park: 'Park', + diy: 'DIY', + transition: 'Transition', + hidden: 'Viên ngọc ẩn', + }, + category: { + local: { + label: 'Tour địa phương', + description: 'Cho thấy spot ẩn trong thành phố của bạn', + }, + national: { + label: 'Tour quốc gia', + description: 'Chuyến đi nhiều thành phố khắp đất nước', + }, + international: { + label: 'Tour quốc tế', + description: 'Phiêu lưu xuyên biên giới qua nhiều quốc gia', + }, + destruction: { + label: 'World Destruction', + description: 'Cuộc thi đồng đội toàn cầu kiểu KOTR', + }, + }, + }, + crew: { + vibe: { + street: 'Street', + transition: 'Transition / Vert', + park: 'Park', + diy: 'DIY', + cruising: 'Cruising / Quay phim', + oldschool: 'Old School', + allterrain: 'Mọi địa hình', + girls: 'Nữ', + youth: 'Thiếu niên / Grom', + adaptive: 'Adaptive', + punk: 'Punk', + hiphop: 'Rap / Hip-Hop', + }, + focus: { + mixed: 'Hỗn hợp / Chung', + builder: 'DIY & Thợ chế tạo', + photo: 'Ảnh & Phim', + coaching: 'Huấn luyện', + art: 'Nghệ thuật & Thiết kế', + music: 'Ban nhạc & Âm nhạc', + wellness: 'Tập luyện & Vật lý trị liệu', + }, + focusDescription: { + mixed: 'Một crew trượt ván thông thường — chỉ hiện trên trang Crew.', + builder: 'Crew DIY / xây park — cũng hiện trong The Lab ở mục Thợ chế tạo.', + photo: 'Crew quay phim, chụp ảnh hoặc dựng phim — cũng hiện trong The Lab ở mục Ảnh & Phim.', + coaching: 'Crew huấn luyện / dạy học — cũng hiện trong The Lab ở mục Huấn luyện.', + art: 'Tập thể nghệ thuật, thiết kế, graffiti hoặc tattoo — cũng hiện trong The Lab ở mục Nghệ thuật & Thiết kế.', + music: 'Ban nhạc hoặc tập thể âm nhạc — cũng hiện trong The Lab ở mục Âm nhạc.', + wellness: 'Crew tập luyện, thể hình hoặc vật lý trị liệu — cũng hiện trong The Lab ở mục Tập luyện.', + }, + lookingFor: { + filmer: 'Filmer', + photographer: 'Nhiếp ảnh gia', + editor: 'Dựng phim', + coach: 'Coach', + builder: 'Thợ làm ramp', + artist: 'Nghệ sĩ / Nhà thiết kế', + musician: 'Nhạc sĩ / Ban nhạc', + members: 'Thành viên mới', + }, + role: { + filmer: 'Filmer', + photographer: 'Nhiếp ảnh gia', + editor: 'Dựng phim', + coach: 'Coach', + builder: 'Thợ chế tạo', + artist: 'Nghệ sĩ', + graffiti: 'Graffiti', + tattoo: 'Tattoo', + trainer: 'Huấn luyện viên', + musician: 'Nhạc sĩ', + judge: 'Giám khảo', + manager: 'Quản lý đội', + og: 'OG', + }, + }, + memberVisibility: { + public: { + label: 'Công khai', + description: 'Ai cũng thấy bạn trong crew này — trên trang crew công khai và trong mục tìm bạn cùng crew.', + }, + crew: { + label: 'Chỉ crew', + description: 'Chỉ thành viên đã xác nhận và người sáng lập thấy bạn ở đây. Với mọi người khác, bạn hiện là “thành viên ẩn” nặc danh. Lưu ý: đây là quyền riêng tư ở cấp ứng dụng — tag thành viên của bạn vẫn công khai trên relay, chỉ là không bao giờ hiện cho người ngoài.', + }, + }, + tagCategory: { + features: { + name: 'Đặc điểm', + description: 'Chướng ngại và địa hình', + }, + surfaces: { + name: 'Bề mặt', + description: 'Vật liệu và kết cấu', + }, + sizes: { + name: 'Kích thước', + description: 'Kích cỡ và quy mô', + }, + stairs: { + name: 'Số bậc thang', + description: 'Số bậc thang', + }, + vibes: { + name: 'Không khí', + description: 'Bầu không khí và tình trạng', + }, + location: { + name: 'Vị trí', + description: 'Ngữ cảnh địa điểm', + }, + tricks: { + name: 'Trick', + description: 'Phù hợp cho các trick cụ thể', + }, + }, + spotTagCategory: { + street: { + label: 'Street', + description: 'Spot đường phố - cầu thang, rail, ledge', + }, + park: { + label: 'Park', + description: 'Skatepark - công khai hoặc riêng tư', + }, + diy: { + label: 'DIY', + description: 'Spot DIY/tự làm', + }, + plaza: { + label: 'Plaza', + description: 'Quảng trường công cộng với kiến trúc thân thiện trượt ván', + }, + }, + status: { + active: { + label: 'Hoạt động', + description: 'Trượt được — cứ đi.', + }, + bust: { + label: 'Dễ bị đuổi', + description: 'Nguy cơ bị đuổi cao — bảo vệ hoặc công an.', + }, + skate_stopped: { + label: 'Bị chặn trượt', + description: 'Có chốt/nắp, nhưng vẫn trượt được một phần.', + }, + closed: { + label: 'Đóng', + description: 'Tạm đóng — thi công hoặc sự kiện.', + }, + gone: { + label: 'Không còn', + description: 'Bị phá, lấp hoặc rào kín vĩnh viễn.', + }, + }, + price: { + free: 'MIỄN PHÍ', + trade: 'Trao đổi', + makeOffer: 'Trả giá', + offer: 'Giá', + }, + }, + feesUi: { + feeFeaturedEventLabel: 'Sự kiện nổi bật', + feeFeaturedEventDesc: 'Đưa sự kiện của bạn lên nổi bật trên SkateSpots', + feeFeaturedEventBenefit: 'Sự kiện của bạn xuất hiện ở đầu trang sự kiện', + feeLabProfileLabel: 'Hồ sơ Pro trong The Lab', + feeLabProfileDesc: 'Đưa dịch vụ của bạn lên nổi bật trong The Lab', + feeLabProfileBenefit: 'Huy hiệu Pro + vị trí nổi bật khi skater duyệt The Lab', + feeFeaturedShopLabel: 'Cửa hàng nổi bật', + feeFeaturedShopDesc: 'Đưa cửa hàng trượt ván của bạn lên bản đồ và danh bạ', + feeFeaturedShopBenefit: 'Huy hiệu đã xác minh + ghim nổi bật trên bản đồ', + feeFeaturedTourLabel: 'Tour nổi bật', + feeFeaturedTourDesc: 'Đưa tour của bạn lên nổi bật trên SkateSpots', + feeFeaturedTourBenefit: 'Huy hiệu Pro + vị trí đầu khi skater duyệt tour', + duration7d: '7 ngày', + duration30d: '1 tháng', + duration90d: '3 tháng', + duration365d: '12 tháng', + metaActive: '{{label}} — Đang hoạt động', + daysRemainingOne: 'Còn {{count}} ngày', + daysRemainingMany: 'Còn {{count}} ngày', + zapRequestContent: 'SkateSpots {{label}} ({{tier}})', + errGenerate: 'Tạo hóa đơn thất bại', + paymentReceived: '⚡ Đã nhận thanh toán!', + paymentReceivedDesc: '{{amount}} sats — {{label}} giờ đang hoạt động.', + autoPayFailed: 'Tự động thanh toán thất bại', + autoPayFailedDesc: 'Thanh toán thủ công bằng mã QR hoặc hóa đơn bên dưới.', + payStatusUnknown: 'Không rõ trạng thái thanh toán — giao dịch có thể đã thành công. Kiểm tra ví trước khi trả lại.', + invoiceCopied: 'Đã sao chép hóa đơn!', + activeBang: '{{label}} đang hoạt động!', + chooseDuration: 'Chọn thời hạn', + bestValue: 'Đáng giá nhất', + perDay: '{{price}}/ngày', + validFor: 'Có hiệu lực trong', + amountLine: '~${{usd}} USD · tới {{name}} · {{tier}}', + payToContinue: 'Trả {{amount}} sats để tiếp tục', + generating: 'Đang tạo hóa đơn…', + processing: 'Đang xử lý thanh toán…', + invoiceQrAlt: 'Mã QR hóa đơn Lightning', + copyInvoice: 'Sao chép hóa đơn', + openWallet: 'Mở ví', + payConnected: 'Trả bằng ví đã kết nối', + scanAny: 'Quét bằng bất kỳ ví Lightning nào', + tryAgain: 'Thử lại', + proReceiptTitle: '🦧⚡ Sasquatch Pro — bạn đã vào!', + proReceiptPass: 'Thẻ: {{pass}} ({{sats}} sats)', + proReceiptActiveUntil: 'Hoạt động đến: {{until}}', + proReceiptUnlocked: 'Bạn đã mở khóa:', + proReceiptBullet1: '• Trợ lý cá nhân — tôi đọc Stash, crew, spot & tin đăng của bạn', + proReceiptBullet2: '• Bản nháp hành động — đăng bán đồ, đăng trạng thái spot, lên kế hoạch chuyến đi (bạn xác nhận)', + proReceiptBullet3: '• Câu trả lời dùng ngữ cảnh cá nhân của bạn, không chỉ dữ liệu công khai', + proReceiptBullet4: '• ⚡ Bạn đang trực tiếp ủng hộ SkateSpots & giữ nó miễn phí + không quảng cáo', + proReceiptThanks: 'Cảm ơn bạn đã giữ SkateSpots miễn phí & không quảng cáo. Giờ thì đi trượt thôi. 🛹', + proReceiptSubject: 'Hóa đơn Sasquatch Pro', + receiptContent: 'Sasquatch Pro — thẻ ủng hộ hạng {{tier}} 🦧⚡', + receiptAlt: 'Thẻ ủng hộ Sasquatch Pro ({{tier}}), có hiệu lực đến {{until}}', + purchaseComment: 'Sasquatch Pro — {{tier}} 🦧', + errLogin: 'Đăng nhập để nâng cấp lên Pro.', + errStart: 'Không bắt đầu được giao dịch.', + errRecord: 'Không ghi lại được thẻ của bạn.', + }, + cardUi: { + save: 'Lưu thẻ lên Nostr', + saved: 'Đã lưu thẻ', + savedDesc: 'Thẻ của bạn giờ đã được ký và có thể xác minh.', + saveFailed: 'Không lưu được thẻ', + notPublished: 'Chưa đăng', + titleNeon: 'Rider', + titleRest: 'Card', + saveFrontPng: 'Lưu mặt trước (PNG)', + expired: 'HẾT HẠN', + logoUploaded: 'Đã tải logo lên', + logoUploadFailed: 'Không tải được logo lên', + venue: 'Địa điểm liên kết (tùy chọn)', + venueNone: 'Không có địa điểm', + venueHint: 'Chọn một trong các spot của riêng bạn để gắn thẻ này với một địa điểm. Người xác minh sẽ xác nhận bạn sở hữu nó.', + venuePick: 'Chọn địa điểm của bạn', + parkNoVenue: 'Thẻ Park chỉ có thể được phát hành bởi chủ sở hữu địa điểm — hãy đánh dấu một spot bạn sở hữu trước.', + parkAddVenue: 'Thêm một spot', + parkNeedsVenue: 'Chọn một địa điểm bạn sở hữu', + parkIssued: 'Thẻ đã phát hành', + parkRevoke: 'Thu hồi', + parkRevoked: 'Đã thu hồi', + parkRevokeFailed: 'Không thu hồi được', + v: { + valid: 'Hợp lệ', + validDesc: 'Chữ ký hợp lệ và được phát hành bởi địa điểm.', + expired: 'Hết hạn', + expiredDesc: 'Đã quá ngày hết hiệu lực.', + revoked: 'Đã thu hồi', + revokedDesc: 'Bên phát hành đã hủy thẻ này — đừng chấp nhận.', + invalid: 'Không hợp lệ', + invalidDesc: 'Chữ ký không xác minh được. Đừng tin.', + notFound: 'Không tìm thấy', + notFoundDesc: 'Không có bản ghi khớp trên relay.', + unverifiedIssuer: 'Bên phát hành chưa xác minh', + unverifiedIssuerDesc: 'Thẻ này ghi tên một địa điểm không thuộc khóa của bên phát hành.', + notBound: 'Chưa liên kết', + notBoundDesc: 'Không gắn với địa điểm — không chứng minh gì về quyền truy cập.', + noRsvp: 'Không có RSVP', + noRsvpDesc: 'Người giữ thẻ không có RSVP nào cho sự kiện này.', + admitted: 'Được nhận vào', + admittedDesc: 'Sự kiện của ban tổ chức + người giữ đã RSVP.', + noHolder: 'Không có người giữ trong liên kết', + noHolderDesc: 'Mã QR này không có người giữ vé (`?h=`), nên không kiểm tra được người giữ.', + }, + passes: { + tab: 'Thẻ của tôi', + pass: 'Thẻ ra vào', + none: 'Chưa có thẻ nào. Khi một địa điểm hoặc ban tổ chức phát cho bạn, nó sẽ hiện ở đây.', + }, + facets: { + title: 'Hiện các khía cạnh danh tính', + crews: 'Crew', + local: 'Địa phương', + roles: 'Vai trò The Lab', + }, + roles: { + coach: 'Coach', + filmer: 'Filmer', + editor: 'Dựng phim', + photographer: 'Nhiếp ảnh gia', + builder: 'Thợ chế tạo', + artist: 'Nghệ sĩ', + graffiti: 'Graffiti', + tattoo: 'Tattoo', + trainer: 'Huấn luyện viên', + musician: 'Nhạc sĩ', + judge: 'Giám khảo', + organizer: 'Ban tổ chức', + barber: 'Thợ cắt tóc', + }, + crew: { + crewCard: 'THẺ CREW', + crewSub: 'Crew của bạn, trên một tấm thẻ', + pick: 'Chọn một crew', + none: 'Bạn chưa ở trong crew nào — hãy tham gia hoặc tạo trước.', + hint: 'Thẻ được tạo từ dữ liệu đã ký của chính crew. Sửa crew trên trang của nó để thay đổi.', + members: 'THÀNH VIÊN', + spots: 'SPOT', + est: 'Thành lập {{year}}', + openCall: 'Đang tuyển', + verifiedCrew: 'Crew đã xác minh', + viewCrew: 'Xem crew', + }, + event: { + pass: 'THẺ SỰ KIỆN', + passSub: 'Thẻ cho một sự kiện bạn sẽ tham dự', + pick: 'Chọn một sự kiện', + none: 'Chưa có sự kiện nào — hãy tạo một cái, hoặc RSVP một cái trước.', + hint: 'Thẻ được tạo từ dữ liệu đã ký của chính sự kiện. Chỉ ban tổ chức có thể thay đổi.', + admits: 'NHẬN VÀO', + going: '{{count}} người tham dự', + verifiedEvent: 'Sự kiện đã xác minh', + viewEvent: 'Xem sự kiện', + issuePass: 'Phát thẻ check-in', + issuePassBtn: 'Phát thẻ', + issuePassHint: 'Một thẻ đã ký cho một người tham dự cụ thể — họ xuất trình ở cửa.', + notOrganiser: 'Chỉ ban tổ chức mới phát được thẻ', + passIssued: 'Đã phát thẻ', + issueFailed: 'Không phát được thẻ', + issuedPasses: 'Thẻ check-in đã phát', + }, + studio: { + unsaved: 'Thay đổi chưa lưu', + saved: 'Đã lưu', + saveChanges: 'Lưu thay đổi', + allSaved: 'Đã lưu — cập nhật', + showOnCard: 'Hiện trên thẻ', + derived: 'Từ hồ sơ Skater của bạn', + noSkaterProfile: 'Chưa có hồ sơ Skater —', + editSkaterProfile: 'thêm phong cách & trình độ của bạn', + noPhoto: 'Chưa có ảnh hồ sơ —', + addPhoto: 'thêm một ảnh trong hồ sơ của bạn', + finishTitle: 'Hoàn thiện thẻ của bạn', + finishDesc: 'Một bức ảnh và hồ sơ Skater sẽ làm nó trông thật.', + checkPhoto: 'Ảnh hồ sơ', + checkName: 'Tên hiển thị', + checkProfile: 'Phong cách & trình độ', + checkCrew: 'Tham gia một crew', + moreTypes: 'Thêm loại thẻ được mở khóa khi bạn đánh dấu spot bạn sở hữu, tham gia crew, hoặc RSVP sự kiện.', + accent: 'Màu nhấn', + accentHint: 'Ghi đè màu nhấn của chủ đề', + accentClear: 'Dùng màu chủ đề', + logo: 'Logo / huy hiệu tùy chỉnh', + logoAdd: 'Tải lên', + logoChange: 'Đổi', + logoClear: 'Gỡ', + }, + back: { + title: 'Mặt sau in được', + desc: 'Crew, vai trò, nhà tài trợ & liên kết ở mặt sau', + showBack: 'Hiện mặt sau', + showFront: 'Hiện mặt trước', + empty: 'Chưa có gì ở đây — thêm crew, vai trò hoặc nhà tài trợ.', + }, + verify: { + checking: 'Đang kiểm tra thẻ…', + notFound: 'Không tìm thấy thẻ', + notFoundDesc: 'Không tìm thấy sự kiện khớp trên relay. Nó có thể đã bị xóa, hoặc liên kết sai.', + invalid: 'Chữ ký không hợp lệ', + invalidDesc: 'Sự kiện này tồn tại nhưng chữ ký không xác minh được. Đừng tin.', + authentic: 'Chính hãng', + authenticDesc: 'Chữ ký của bên phát hành hợp lệ.', + kind: 'Loại', + kindPark: 'Thẻ ra vào Park', + kindRider: 'Thẻ Rider', + kindCrew: 'Thẻ Crew', + kindEvent: 'Thẻ sự kiện', + organiser: 'Ban tổ chức', + expired: 'Hết hạn', + valid: 'Hợp lệ', + holder: 'Người giữ', + ticketHolder: 'Người giữ vé', + rsvp: 'RSVP', + rsvpGoing: 'Sẽ tham dự', + rsvpInterested: 'Quan tâm', + rsvpNone: 'Không tìm thấy RSVP', + revoked: 'Thẻ đã thu hồi', + revokedDesc: 'Bên phát hành đã hủy thẻ này — đừng chấp nhận.', + issuedBy: 'Phát hành bởi', + accessLevel: 'Mức truy cập', + validThru: 'Hiệu lực đến', + selfIssued: 'Trạng thái', + selfIssuedDesc: 'Thẻ danh tính tự phát hành', + venue: 'Địa điểm', + venueVerified: 'Đã xác minh — khóa chủ sở hữu địa điểm khớp với bên phát hành.', + venueMismatch: 'Thẻ này ghi tên một địa điểm không thuộc khóa của bên phát hành.', + venueNone: 'Không gắn với địa điểm.', + viewCard: 'Xem thẻ', + disclaimer: 'Chữ ký hợp lệ chứng minh ai đã ký thẻ này — không phải bằng chứng về kỹ năng hay quyền truy cập ngoài những gì địa điểm đã phát hành.', + details: 'Chi tiết', + invalidLink: 'Liên kết không hợp lệ', + invalidLinkDesc: 'Đó có vẻ không phải liên kết thẻ hợp lệ.', + }, + public: { + invalid: 'Đó có vẻ không phải liên kết thẻ hợp lệ.', + createYourOwn: 'Tạo thẻ của riêng bạn', + editYourCard: 'Sửa thẻ của bạn', + backToEditor: 'Quay lại trình chỉnh sửa', + backHome: 'Về trang chủ', + notCustomised: 'Skater này chưa tùy chỉnh thẻ của họ — đây là giao diện mặc định.', + verifyNote: 'Quét mã QR trên thẻ để xác minh nó.', + }, + }, + routeUi: { + destination: 'Điểm đến', + routeTo: 'Chỉ đường tới {{label}}', + routeToLabel: 'Chỉ đường tới', + search: 'Tìm kiếm', + description: 'Tùy chọn tuyến đường và chỉ đường trong ứng dụng.', + routeMapAria: 'Bản đồ tuyến đường', + findingLocation: 'Đang tìm vị trí của bạn…', + plottingRoute: 'Đang vẽ tuyến đường…', + refiningLocation: 'Đang tinh chỉnh vị trí…', + offlineSavedRoute: 'Ngoại tuyến · tuyến đã lưu {{age}}', + tapMapStart: 'Nhấn bản đồ để đặt điểm xuất phát', + fitRouteAria: 'Vừa toàn bộ tuyến đường trên bản đồ', + wholeRoute: 'Toàn bộ tuyến', + next: 'Tiếp', + nextStep: 'Tiếp · bước {{n}}', + followTheLine: 'Đi theo đường', + toTheTurn: 'tới chỗ rẽ', + toGo: 'còn lại', + tryAgain: 'Thử lại', + mode: { + foot: 'Trượt / Đi bộ', + bike: 'Xe đạp', + moto: 'Xe máy', + car: 'Ô tô', + transit: 'Công cộng', + }, + from: 'Từ', + myLocation: 'Vị trí của tôi', + tapTheMap: 'Nhấn bản đồ…', + chooseOnMap: 'Chọn trên bản đồ', + direct: 'trực tiếp', + transferOne: '1 lần chuyển tuyến', + transfers: '{{count}} lần chuyển tuyến', + options: '{{count}} tùy chọn', + ride: 'chạy', + arrive: 'đến', + speedAvg: 'trung bình {{speed}} km/h', + stepsCount: '{{count}} bước', + onABoard: 'trên ván', + usesDrivingRoads: 'dùng đường cho xe', + drivingEstimate: 'ước tính lái xe', + updating: 'đang cập nhật…', + pickMode: 'Chọn phương tiện để xem tuyến đường.', + waitingLocation: 'Đang chờ vị trí của bạn…', + routeSteps: 'Các bước tuyến đường', + walkingRoute: 'tuyến đi bộ — nhanh hơn khi trượt ván', + planningView: 'Chế độ lập kế hoạch — nhấn Bắt đầu để theo dõi với chỉ đường trực tiếp, giọng nói và điểm đến.', + leaveNow: 'Đi ngay', + departAt: 'Khởi hành lúc', + arriveBy: 'Đến trước', + departureTime: 'Giờ khởi hành', + arrivalTime: 'Giờ đến', + only: 'Chỉ', + clear: 'xóa', + itinerary: 'Lịch trình', + group: { + bus: 'Xe buýt', + tram: 'Tàu điện', + metro: 'Tàu điện ngầm', + train: 'Tàu hỏa', + ferry: 'Phà', + }, + walk: 'Đi bộ', + rideVerb: 'Chạy', + walkLower: 'đi bộ', + rideLower: 'chạy', + toStop: 'tới', + track: 'đường ray {{track}}', + stopOne: '1 điểm dừng', + stopsCount: '{{count}} điểm dừng', + tickets: 'vé ↗', + done: 'Xong', + stop: 'Dừng', + start: 'Bắt đầu', + arrived: 'Bạn đã đến. 🛹', + voiceOnNote: 'Màn hình luôn sáng · giọng nói bật — chỗ rẽ và điểm đến được đọc lên.', + voiceOffNote: 'Màn hình luôn sáng · giọng nói tắt.', + followNote: 'Chỗ rẽ, giọng nói và điểm đến khi bạn lăn bánh. Giữ màn hình sáng.', + voiceOffAria: 'Tắt hướng dẫn giọng nói', + voiceOnAria: 'Bật hướng dẫn giọng nói', + voiceStart: 'Bắt đầu điều hướng', + voiceArrived: 'Bạn đã đến', + voiceIn: 'Còn {{metres}} mét, {{instruction}}', + voiceContinue: 'tiếp tục', + voiceContinueCaps: 'Tiếp tục', + errPermissionDenied: 'Quyền truy cập vị trí bị từ chối.', + errWaitingGps: 'Đang chờ tín hiệu GPS…', + errPermissionDeniedLong: 'Quyền truy cập vị trí bị từ chối. Bật vị trí để chỉ đường từ nơi bạn đang ở.', + errNoLocation: 'Không lấy được vị trí của bạn. Thử lại.', + errNoLocationShort: 'Không lấy được vị trí của bạn.', + errTransitNoRouteFiltered: 'Không có tuyến cho thời gian hoặc phương tiện đó — thử thời gian khác, hoặc thêm phương tiện.', + errTransitNoRoute: 'Không tìm thấy tuyến giao thông công cộng ở đây — khu vực này có thể không công bố thời gian biểu mở.', + errTransitUnreachable: 'Không kết nối được dịch vụ công cộng. Kiểm tra kết nối và thử lại.', + errRoutingBusy: 'Dịch vụ chỉ đường đang bận — thử lại sau lát nữa.', + errNoRouteMode: 'Không có tuyến cho phương tiện này — điểm đến có thể nằm ngoài mạng lưới đường. Thử phương tiện khác.', + errRoutingUnreachable: 'Không kết nối được dịch vụ chỉ đường. Kiểm tra kết nối và thử lại.', + departures: 'Chuyến khởi hành', + upcomingFrom: 'Chuyến sắp khởi hành từ {{stop}}', + loadingDepartures: 'Đang tải chuyến khởi hành…', + noDepartures: 'Không có chuyến nào sắp khởi hành tại điểm dừng này.', + live: 'trực tiếp', + cancelled: 'đã hủy', + refresh: 'Làm mới', + tripLoginTitle: 'Đăng nhập để lưu', + tripLoginDesc: 'Đăng nhập để giữ chuyến đi này thành một Bộ sưu tập.', + tripCollectionTitle: 'Chuyến trượt {{destination}} 🛹', + tripCollectionDesc: 'Kế hoạch chuyến đi bởi The Sasquatch — {{count}} ngày ở {{destination}}.', + tripCollectionDescOne: 'Kế hoạch chuyến đi bởi The Sasquatch — {{count}} ngày ở {{destination}}.', + tripSavedTitle: 'Đã lưu vào Bộ sưu tập 🦧', + tripSavedDesc: 'Chuyến đi {{destination}} của bạn đã được đánh dấu.', + tripSaveFailed: 'Không lưu được', + tripSaveFailedDesc: 'Thử lại sau một giây.', + daysInDestinationOne: '{{count}} ngày ở {{destination}}', + daysInDestination: '{{count}} ngày ở {{destination}}', + wetForecast: 'Dự báo mưa — tìm crew địa phương để có lựa chọn có mái/trong nhà.', + dayLabel: 'Ngày {{n}}', + freeSkate: 'Trượt tự do — khám phá & quay phim. 🎥', + tapToBook: 'nhấn để đặt / zap ⚡', + localCrews: 'Crew địa phương', + saving: 'Đang lưu…', + savedToCollections: 'Đã lưu vào Bộ sưu tập', + saveSpotOne: 'Lưu {{count}} spot vào một Bộ sưu tập', + saveSpots: 'Lưu {{count}} spot vào một Bộ sưu tập', + flights: 'Chuyến bay', + stays: 'Chỗ ở', + gettingAround: 'Đi lại', + noMiddleman: 'Tôi lên kế hoạch trượt — chuyến bay & chỗ ở mở trên các trang thật (không KYC, không trung gian).', + ageJustNow: 'vừa xong', + ageMinAgo: '{{count}} phút trước', + ageHourAgo: '{{count}} giờ trước', + ageDayAgo: '{{count}} ngày trước', + skateRightHere: 'ngay đây', + skateMin: '~{{count}} phút trượt', + skateHours: '~{{hours}} giờ trượt', + maneuver: { + headOut: 'Xuất phát', + arrive: 'Đến spot', + continueStraight: 'Đi thẳng', + bearLeft: 'Chếch trái', + bearRight: 'Chếch phải', + turnLeft: 'Rẽ trái', + turnRight: 'Rẽ phải', + sharpLeft: 'Rẽ gắt sang trái', + sharpRight: 'Rẽ gắt sang phải', + turn: 'Rẽ', + keepLeft: 'Giữ bên trái', + keepRight: 'Giữ bên phải', + takeFork: 'Đi theo ngã ba', + merge: 'Nhập làn', + roundabout: 'Đi vào vòng xuyến', + takeRamp: 'Đi theo đường dốc', + takeExit: 'Đi theo lối ra', + }, + maneuverOnto: '{{instruction}} vào {{road}}', + }, + sasquatchUi: { + live: 'trực tiếp', + offline: 'ngoại tuyến', + genericTitle: 'Trợ lý SkateSpots 🦧', + genericGreeting: 'Chào! Tôi là The Sasquatch. Hỏi tôi bất cứ điều gì về spot, sự kiện, coach, đồ nghề, hoặc cách ứng dụng hoạt động. Tôi có dữ liệu trực tiếp từ relay SkateSpots!', + q1: 'Lên kế hoạch 3 ngày ở Lisbon cho tôi', + q2: 'Tìm spot gần tôi', + q3: 'Có sự kiện nào sắp tới không?', + q4: 'Crew là gì?', + q5: 'Zap hoạt động thế nào?', + q6: 'Nostr là gì?', + q7: 'My Stash là gì?', + q8: 'Cái này miễn phí chứ?', + bubbleTitle: 'Nhấn và kéo để di chuyển · Nhấn để mở', + openGuideAria: 'Mở hướng dẫn Sasquatch', + hideAria: 'Ẩn trợ lý Sasquatch', + hide: 'Ẩn trợ lý', + showAria: 'Hiện trợ lý Sasquatch', + activeUntil: 'Hoạt động đến {{date}}', + platformOwner: 'Chủ nền tảng', + upgradeTitle: 'Nâng cấp lên Sasquatch Pro', + goPro: 'Lên Pro', + goProBlurb: 'AI cá nhân · từ 2k sats', + aiBalanceTitle: 'Số dư tín dụng Sasquatch AI (chỉ chủ sở hữu) — nạp thêm tại {{provider}}', + aiChip: '⚡ AI {{balance}}', + minimizeToBubbleAria: 'Thu nhỏ thành bong bóng', + minimize: 'Thu nhỏ', + closePanelAria: 'Đóng bảng', + close: 'Đóng', + askLab: 'Hỏi về Huấn luyện & Quay phim', + askMap: 'Hỏi về Spot, Cửa hàng & Đồ nghề', + askAnything: 'Hỏi tôi bất cứ điều gì 🛹', + quickQuestions: 'Câu hỏi nhanh:', + you: '🧑 Bạn', + thinking: 'đang suy nghĩ...', + inputPlaceholder: 'Hỏi về spot, sự kiện, coach...', + liveDataFrom: 'Dữ liệu trực tiếp từ', + nostrRelays: 'relay Nostr', + clear: 'xóa', + gettingLocation: '📍 Đang lấy vị trí của bạn…', + findingClosest: '🔍 Đang tìm spot gần nhất…', + checkingLive: '🔍 Đang kiểm tra dữ liệu trực tiếp…', + planningTrip: '🗺️ Đang lên kế hoạch chuyến đi {{destination}}...', + searchingRelays: '🔍 Đang tìm {{tool}} trên relay...', + perk1: 'Trợ lý cá nhân — Sasquatch đọc Stash, crew, spot & tin đăng của riêng bạn', + perk2: 'Bản nháp hành động: đăng bán đồ, đăng trạng thái trượt, lên kế hoạch chuyến đi — bạn xác nhận trước khi đăng bất cứ gì', + perk3: 'Câu trả lời dùng ngữ cảnh cá nhân của bạn, không chỉ dữ liệu công khai', + perk4: '⚡ Trực tiếp ủng hộ SkateSpots & giữ nó miễn phí và không quảng cáo', + welcomeTitle: 'Cảm ơn bạn đã ủng hộ Sasquatch Pro! 🦧⚡', + welcomeDesc: 'Đã gửi thanh toán — thẻ của bạn kích hoạt khi nhà cung cấp xác nhận (thường trong vòng một phút). Cảm ơn bạn đã giữ đường phố tự do.', + invoiceCopied: 'Đã sao chép hóa đơn', + dialogDesc: 'Tăng sức mạnh cho hướng dẫn AI trượt ván của bạn. 100% kinh phí cho một ứng dụng cộng đồng miễn phí, không quảng cáo.', + proSupporter: 'Bạn là người ủng hộ Pro ⚡', + extendPrompt: 'Muốn gia hạn? Chọn một hạng bên dưới để thêm thời gian.', + scanToPayPre: 'Quét để trả', + scanToPayAmount: '{{sats}} sats', + scanToPayPost: 'cho {{label}} của Pro', + invoiceQrAlt: 'Mã QR hóa đơn Lightning', + copyInvoice: 'Sao chép hóa đơn', + ivePaid: 'Tôi đã trả', + ivePaidHint: 'Nhấn "Tôi đã trả" sau khi ví xác nhận — thao tác này ghi thẻ của bạn vào danh tính Nostr của bạn.', + freeStaysPre: 'Sasquatch miễn phí vẫn miễn phí — tìm spot/sự kiện/coach công khai, lập kế hoạch chuyến đi + toàn bộ bảng thuật ngữ trick. Pro thêm lớp ', + freeStaysEmphasis: 'cá nhân + hành động', + freeStaysPost: '.', + loginFirst: 'Đăng nhập trước để nâng cấp.', + paysTo: 'Trả cho', + overLightning: 'qua Lightning. Gắn với npub của bạn.', + popular: 'Phổ biến', + sats: 'sats', + extend: 'Gia hạn', + done: 'Xong!', + cancelledNothing: 'Đã hủy — không có gì được đăng.', + draftReview: 'Bản nháp — xem lại & xác nhận', + statusTextPlaceholder: 'Nội dung trạng thái', + titlePlaceholder: 'Tiêu đề', + priceSatsPlaceholder: 'Giá (sats)', + conditionPlaceholder: 'Tình trạng', + cancel: 'Hủy', + aiTitle: 'Sasquatch AI', + owner: 'Chủ sở hữu', + notConfigured: 'chưa cấu hình', + unavailable: 'không khả dụng', + satsValue: '{{balance}} sats', + theNode: 'nút', + lowBalance: 'Sắp hết — nạp thêm tại {{provider}} hoặc AI sẽ chuyển sang nhà cung cấp không cần khóa.', + aiDesc: 'AI trả phí theo yêu cầu, nạp bằng sats qua Routstr. Tự nạp khi sắp hết.', + tier7d: '7 ngày', + tier1m: '1 tháng', + tier3m: '3 tháng', + tier1y: '1 năm', + badgeTry: 'Dùng thử', + badgeOff20: 'Giảm 20%', + badgeBest: 'Đáng giá nhất · giảm 40%', + draftPostStatusTitle: 'Đăng trạng thái trượt ván', + draftAutoExpires: 'Tự hết hạn sau {{count}} phút', + draftPostStatusCta: 'Đăng trạng thái', + draftCategory: 'Danh mục: {{value}}', + draftSize: 'Kích cỡ: {{value}}', + draftCondition: 'Tình trạng: {{value}}', + draftMaxPrice: 'Giá tối đa: {{price}} {{currency}}', + draftPriceOpen: 'Giá: thỏa thuận', + draftLookingForTitle: 'Đang tìm "{{title}}"', + draftWantedCta: 'Đăng tin cần mua', + draftPrice: 'Giá: {{price}} {{currency}}', + draftPriceOffer: 'Giá: trả giá', + draftListTitle: 'Đăng bán "{{title}}"', + draftPublishCta: 'Đăng tin', + statusPosted: 'Đã đăng trạng thái 🛹', + wantedPublished: 'Đã đăng tin cần mua 🔎', + listingPublished: 'Đã đăng tin bán 💸', + mustBeLoggedIn: 'Bạn phải đăng nhập.', + }, + sasquatchChat: { + faq: { + hi: 'Chào! Tôi là The Sasquatch 🦧 Hướng dẫn trượt ván AI của bạn. Hỏi tôi về spot, sự kiện, coach, đồ nghề — hoặc bất cứ điều gì về ứng dụng. Bạn cần gì?', + hello: 'Có gì đó! 🛹 Tôi là The Sasquatch. Hỏi tôi về spot trượt ván, sự kiện, coach, hoặc cách ứng dụng hoạt động. Có gì hay không?', + hey: 'Chào skater! 🤙 Hỏi tôi về spot gần bạn, sự kiện sắp tới, coach, hoặc bất cứ điều gì về SkateSpots.', + whoAreYou: 'Tôi là The Sasquatch 🦧 — hướng dẫn AI của SkateSpots. Tôi có thể tìm spot trượt ván trên toàn thế giới, tra cứu sự kiện, coach, filmer và tin đăng đồ nghề. Tất cả nhờ dữ liệu Nostr trực tiếp. Hỏi thoải mái!', + whatCanYouDo: 'Tôi có thể tìm spot trượt ván theo thành phố hoặc quốc gia, tra cứu sự kiện sắp tới, tìm coach và filmer trong The Lab, tìm tin đăng đồ nghề, và trả lời câu hỏi về cách ứng dụng hoạt động. Thử: \'spot ở Bangkok\' hoặc \'tìm coach\'! 🛹', + whatIsNostr: 'Nostr là một giao thức đơn giản, mở cho mạng xã hội phi tập trung. Giống Twitter, nhưng không công ty nào kiểm soát — bạn dùng khóa mật mã thay cho tên người dùng, chọn relay nào lưu dữ liệu của bạn (hoặc tự vận hành), và một tài khoản dùng được trên mọi ứng dụng Nostr! 🔑', + isThisPrivate: 'Đây là tóm tắt thật thà 🛡️\n\n• **Vị trí GPS của bạn ở lại trên thiết bị** — \'Gần tôi\' chỉ căn giữa bản đồ. Nó không bao giờ được gửi cho chúng tôi hay công bố.\n• **Spot bạn thêm là công khai** (đó chính là mục đích của bản đồ chung) — nên đừng đặt ghim trên cửa nhà bạn.\n• **Tin nhắn riêng & chat crew được mã hóa đầu-cuối** — chỉ thành viên đọc được.\n• Như mọi website, máy chủ bạn kết nối (ảnh bản đồ, relay) có thể thấy **IP** của bạn. Muốn giấu luôn? Dùng VPN hoặc Tor.\n\nChi tiết đầy đủ ở [trang Quyền riêng tư](/privacy). 🛹', + privacy: 'Bản ngắn 🛡️: GPS của bạn không bao giờ rời thiết bị, spot bạn đăng công khai theo thiết kế, và tin nhắn riêng/chat crew được mã hóa đầu-cuối. Máy chủ vẫn có thể thấy IP của bạn (bình thường với mọi website) — VPN hoặc Tor sẽ giấu nếu bạn muốn. Phân tích đầy đủ ở [trang Quyền riêng tư](/privacy).', + amITracked: 'SkateSpots không theo dõi bạn — không quảng cáo, không phân tích hồ sơ, không bán dữ liệu, và không có máy chủ SkateSpots nào thu thập vị trí của bạn. GPS của bạn ở lại trên thiết bị. Thứ duy nhất máy chủ thấy (ảnh bản đồ, relay) là **IP** của bạn — giống mọi website. Dùng VPN hoặc Tor để giấu. Thêm ở [trang Quyền riêng tư](/privacy). 🛡️', + doYouTrack: 'Không — không theo dõi, không quảng cáo, không thu hoạch dữ liệu. GPS của bạn ở lại thiết bị và không có máy chủ trung tâm nào ghi lại bạn. Máy chủ bạn kết nối có thể thấy IP của bạn (như mọi trang); VPN/Tor sẽ giấu. Xem [trang Quyền riêng tư](/privacy). 🛹', + vpn: 'Hoàn toàn tùy chọn, nhưng rất đáng nếu bạn muốn thêm quyền riêng tư 🛡️. VPN giấu **IP** (vị trí gần đúng) khỏi các máy chủ SkateSpots liên lạc — ảnh bản đồ, relay, v.v. Chọn nhà cung cấp không lưu log mà bạn tin (ví dụ Mullvad); tránh mấy cái miễn phí đáng ngờ.\n\nLưu ý: VPN **không** giấu những spot bạn đăng (chúng công khai), và đừng bật GPS trình duyệt nếu bạn đang cố ẩn danh. Chi tiết ở [trang Quyền riêng tư](/privacy).', + tor: 'Tor Browser cho bạn quyền riêng tư IP mạnh nhất — nó định tuyến bạn qua nhiều relay nên máy chủ không thấy IP thật của bạn 🧅. Đánh đổi: chậm hơn, và bản đồ + một số relay Nostr có thể chậm hoặc chặn đầu ra Tor. Tuyệt cho người cực kỳ cẩn trọng.\n\nNhớ rằng: Tor giấu IP của bạn, không giấu spot bạn đăng, và đừng bật GPS trình duyệt nếu mục tiêu là ẩn danh. Thêm ở [trang Quyền riêng tư](/privacy).', + hideMyIp: 'Hai lựa chọn miễn phí 🛡️: một **VPN uy tín** (dễ, nhanh — giấu IP sau máy chủ của họ) hoặc **Tor Browser** (riêng tư tối đa, chậm hơn). Cả hai đều ngăn máy chủ SkateSpots kết nối thấy IP thật của bạn. Lưu ý chúng không giấu spot bạn đăng. Xem [trang Quyền riêng tư](/privacy).', + isMyLocation: 'Vị trí của bạn an toàn 📍 — \'Gần tôi\' chỉ đọc GPS trên thiết bị để căn giữa bản đồ và sắp xếp spot gần đó. Nó không bao giờ được công bố lên Nostr, không gửi cho chúng tôi, không chia sẻ. Chỉ spot bạn cố ý thêm là công khai. Chi tiết ở [trang Quyền riêng tư](/privacy).', + whatAreZaps: 'Zap là tip Bitcoin Lightning tức thì gửi qua Nostr! Nhấn ⚡ trên bất kỳ nội dung nào, gửi sats thẳng tới ví của người tạo. Giống nhấn \'thích\' nhưng bằng tiền thật. Tức thì, ngang hàng, không trung gian. ⚡', + howToLogin: 'Hai cách:\n1. **Tiện ích trình duyệt** (máy tính): Cài Alby hoặc nos2x, rồi nhấn \'Đăng nhập\'\n2. **Người dùng mới**: Nhấn \'Đăng ký\' để tạo khóa. Tải nsec (khóa bí mật) và LƯU LẠI — đây là tài khoản của bạn mãi mãi!', + whatIsCashu: 'Ví Bitcoin tích hợp! Token ecash Cashu được Lightning bảo chứng — hoạt động ngoại tuyến ở spot trượt, chú trọng quyền riêng tư (mint không theo dõi được thanh toán). Vào Ví trong Cài đặt để dùng. 🥜', + whatIsNwc: 'Nostr Wallet Connect — như USB-C cho ví Lightning. Kết nối Alby, Minibits, Zeus hoặc Coinos một lần, và zap bằng một nhấn mãi mãi. Được mã hóa, bạn kiểm soát hạn mức chi tiêu. 🔌⚡', + isItFree: 'Miễn phí 100%. Không quảng cáo, không đăng ký, không trò công ty. Do skater làm cho skater. Cộng đồng tài trợ qua Angor — xem trang Người ủng hộ. Bạn cũng có thể kiếm Bitcoin qua zap cộng đồng khi đóng góp spot chất lượng. 🛹', + whatCanIDo: 'Khám phá spot toàn thế giới trên bản đồ, thuê chuyên gia trong The Lab (coach, filmer, nhiếp ảnh gia, dựng phim, thợ làm ramp), lăn cùng một crew, tham gia sự kiện, đi tour, mua/bán đồ nghề, theo dõi Stash riêng, zap người tạo, xem thời tiết spot, và xây dựng cộng đồng trượt ván phi tập trung!', + whatIsTheLab: 'The Lab là nơi bạn thuê chuyên gia của giới trượt ván: Coach, Filmer, Nhiếp ảnh gia, Dựng phim, và Thợ làm ramp/park/DIY. Mỗi người có thể là một cá nhân hoặc một tập thể (crew/studio) — thành viên xác nhận bằng khóa riêng nên rất chính danh. Tất cả trên Nostr, không tài khoản giả. 🎓', + whatIsACrew: 'Crew là gia đình trượt ván neo trên bản đồ của bạn — người bạn trượt CÙNG, không phải người bạn thuê. Mỗi crew có địa bàn trên bản đồ (ghim xanh ngọc), spot nhà, thành viên, phong cách và một tuyên ngôn. Thành viên xác nhận bằng khóa riêng. Tạo một cái ở Crew → \'Tạo Crew\'. 🤘', + whatAreCrews: 'Crew là gia đình trượt ván neo trên bản đồ của bạn — người bạn trượt CÙNG, không phải người bạn thuê. Mỗi crew có địa bàn trên bản đồ (ghim xanh ngọc), spot nhà, thành viên và một tuyên ngôn. Thành viên xác nhận bằng khóa riêng. Vào tab Crew để bắt đầu hoặc tham gia! 🤘', + howToStartACrew: 'Vào tab Crew → \'Tạo Crew\'. Đặt tên, thả địa bàn lên bản đồ, thêm phong cách (hoặc #hashtag tùy chỉnh của bạn), liên kết spot nhà, và thêm thành viên bằng npub. Mỗi thành viên xác nhận bằng khóa riêng nên danh sách rất chính danh. 🤘', + whatIsMyStash: 'My Stash là tủ đồ nghề RIÊNG TƯ, được mã hóa của bạn (mã hóa NIP-44). Theo dõi deck, trucks, wheels, giày — kèm nơi lưu, tình trạng, độ hiếm và giá. Chỉ BẠN đọc được trừ khi bạn đánh dấu món đó công khai. Tuyệt cho bảo hiểm hoặc lên kế hoạch đổi đồ. 🎒', + whatIsStash: 'My Stash là kho đồ nghề RIÊNG TƯ, được mã hóa của bạn. Ghi lại mọi thứ bạn có — tình trạng, nơi lưu, giá trị — tất cả được mã hóa nên chỉ bạn thấy. Đánh dấu công khai nếu bạn muốn bán hoặc khoe. 🎒', + whatIsABuilder: 'Thợ chế tạo là các crew làm ramp/park/DIY trong The Lab mà bạn có thể thuê để làm transition, bowl, rail, hoặc cả một park. Họ liệt kê thứ họ làm, vật liệu, quy mô dự án, và có thể có giấy phép/bảo hiểm. Thường là tập thể — và họ có thể liên kết các spot đã làm lên bản đồ. 🏗️', + whatIsANutzap: 'Nutzap (NIP-61) là tip ecash gửi qua Nostr — token Cashu riêng tư được zap thẳng cho ai đó. Bạn có thể thiết lập NHẬN nutzap trong Ví. (Gửi nutzap đầy đủ đang được triển khai — hiện tại dùng zap Lightning.) 🥜⚡', + whatIsClink: 'CLINK là mã thanh toán gốc Nostr (một \'noffer\'). Cửa hàng, crew và chuyên gia The Lab có thể thêm một cái để bạn trả tiền mà không cần địa chỉ Lightning — bạn sẽ thấy nút \'Trả qua CLINK\' kèm mã QR. Quét bằng ví CLINK như ShockWallet. 🔗⚡ [thông số](https://clinkme.dev/specs.html) [ứng dụng](https://clinkme.dev/apps.html)', + whatIsNoffer: 'Noffer là mã thanh toán CLINK — cách gốc Nostr, dùng lại được để nhận tiền mà không cần máy chủ web hay địa chỉ Lightning. Thêm cái của bạn vào hồ sơ cửa hàng/crew/Lab và mọi người trả trực tiếp cho bạn. 🔗', + whatAreTours: 'Tour là các chuyến trượt ván có hướng dẫn — session địa phương, chuyến đi quốc gia, hoặc tour world destruction. Tìm chúng trên bản đồ hoặc mục Tour, gặp gỡ, và trượt địa hình mới cùng dân địa phương. 🗺️🛹', + whatIsAShop: 'Cửa hàng trượt ván là các shop địa phương được liệt kê trên bản đồ. Khám phá và ủng hộ shop trượt ván thật (hoặc online) trong khu vực bạn — một số còn nhận Bitcoin. 🏪', + howToSellGear: 'Vào Trao đổi đồ nghề / Chợ và tạo tin đăng (NIP-99). Thêm ảnh, giá bằng sats, tình trạng, và tùy chọn ghim vào một spot để hiện trên bản đồ. Người mua zap hoặc nhắn trực tiếp cho bạn. 🛹💸', + supporters: 'SkateSpots được cộng đồng tài trợ qua Angor (gây quỹ Bitcoin phi tập trung) — không quảng cáo, không nhà đầu tư, không bán dữ liệu. Xem trang Người ủng hộ để hậu thuẫn dự án và giữ đường phố tự do. ❤️⚡', + trustScore: 'Điểm tin cậy (0-100) do Relatr cung cấp. Phân tích mạng lưới Nostr của bạn: người theo dõi, hoạt động, tương tác, zap. Càng cao = càng đáng tin. Giúp lọc bot và spam. Xem hồ sơ bất kỳ để thấy điểm. 🛡️', + whatRelay: 'SkateSpots dùng: 🛹 goskatespots.nostr1.com (chính, nằm trong danh sách cho phép để đảm bảo chất lượng) + relay.ditto.pub (toàn cầu) + purplepag.es (tổng hợp hồ sơ). Dữ liệu của bạn được nhân bản trên tất cả để dự phòng.', + tripPlanner: 'Cho tôi một thành phố và tôi sẽ dựng chuyến trượt từng ngày 🗺️ — spot, sự kiện, coach và crew địa phương, có tính đến thời tiết (ngày mưa = gợi ý crew chỗ có mái). Thử \'lên kế hoạch 3 ngày ở Lisbon\'. Tôi có thể lưu tất cả vào một Bộ sưu tập, và chuyển bạn sang chuyến bay/chỗ ở trên các trang thật (không KYC, không trung gian). 🛹', + planATrip: 'Chỉ cần nói \'lên kế hoạch 3 ngày ở Barcelona\' (hoặc bất kỳ thành phố nào) và tôi sẽ vạch ra spot, session, coach và crew địa phương cho mỗi ngày. Lưu thành một Bộ sưu tập và đi trượt. 🗺️🛹', + sasquatchPro: '**Sasquatch Pro** 🦧⚡ là thẻ ủng hộ bằng Lightning mở khóa mặt cá nhân của tôi:\n\n• 🧠 **Trợ lý cá nhân** — tôi đọc Stash, crew, spot & tin đăng của chính bạn\n• ✨ **Bản nháp hành động** — đăng bán đồ, đăng trạng thái trượt, lên kế hoạch chuyến đi (bạn luôn xác nhận trước khi đăng)\n• 💬 **Ngữ cảnh cá nhân** — câu trả lời của tôi dùng dữ liệu của bạn, không chỉ kết quả công khai\n• ⚡ **Ủng hộ dự án** — bạn giữ SkateSpots miễn phí và không quảng cáo\n\nSasquatch miễn phí vẫn miễn phí: tìm spot/sự kiện/coach/crew công khai, bảng thuật ngữ & lập kế hoạch chuyến đi đều hoạt động không cần Pro. Pro chỉ thêm phần *cá nhân*. Nhấn **⚡ Lên Pro** ở trên cùng. Các hạng: 7 ngày ~2k sats, 1 tháng ~5k, 3 tháng ~12k, 1 năm ~36k.', + proPerks: 'Quyền lợi Pro 🦧⚡: trợ lý cá nhân (đọc Stash/crew/spot/tin đăng của bạn), bản nháp hành động (đăng bán đồ, đăng trạng thái, lên kế hoạch chuyến đi — bạn xác nhận), và câu trả lời dùng ngữ cảnh cá nhân của bạn. Cộng thêm bạn đang trực tiếp ủng hộ SkateSpots và giữ nó miễn phí + không quảng cáo. Miễn phí vẫn miễn phí — Pro thêm lớp cá nhân. Nhấn **⚡ Lên Pro** ở trên cùng.', + proVersion: 'Phiên bản Pro của tôi 🦧⚡ thêm một **trợ lý cá nhân**: tôi có thể đọc Stash, crew, spot & tin đăng của chính bạn, soạn hành động cho bạn (đăng bán đồ, đăng trạng thái, lên kế hoạch chuyến đi — bạn luôn xác nhận trước), và dùng ngữ cảnh cá nhân của bạn trong câu trả lời. Nó cũng trực tiếp ủng hộ dự án. Sasquatch miễn phí (tìm spot/sự kiện/coach/crew, bảng thuật ngữ, lập kế hoạch chuyến đi) vẫn miễn phí. Nhấn **⚡ Lên Pro** ở trên cùng.', + perks: 'Quyền lợi Pro 🦧⚡: trợ lý cá nhân (Stash/crew/spot/tin đăng của bạn), bản nháp hành động bạn xác nhận, và câu trả lời dùng ngữ cảnh của bạn — cộng thêm bạn giữ ứng dụng miễn phí & không quảng cáo. Nhấn **⚡ Lên Pro** ở trên cùng.', + goPro: 'Nhấn nút **⚡ Lên Pro** ở trên cùng để mở bảng nâng cấp. Pro mở khóa trợ lý cá nhân của tôi (Stash/crew/spot/tin đăng) và bản nháp hành động, đồng thời trực tiếp ủng hộ dự án. Trả bằng Lightning — 7 ngày ~2k sats đến 1 năm ~36k sats. Tính năng miễn phí vẫn miễn phí. 🦧', + proPricing: 'Các hạng Pro (trả bằng Lightning ⚡): **7 ngày** ~2,000 sats (~$1.20), **1 tháng** ~5,000 sats (~$3), **3 tháng** ~12,000 sats (~$7, giảm 20%), **1 năm** ~36,000 sats (~$21, đáng giá nhất). Nhấn **⚡ Lên Pro** ở trên cùng.', + howMuchIsPro: 'Các hạng Pro: 7 ngày ~2,000 sats, 1 tháng ~5,000 sats, 3 tháng ~12,000 sats (giảm 20%), 1 năm ~36,000 sats (đáng giá nhất). Trả bằng Lightning ⚡. Nhấn **⚡ Lên Pro** ở trên cùng.', + upgrade: 'Để nâng cấp lên Sasquatch Pro, nhấn nút **⚡ Lên Pro** ở trên cùng. Trả bằng Lightning (7 ngày ~2k sats đến 1 năm ~36k). Pro mở khóa trợ lý cá nhân và bản nháp hành động, đồng thời trực tiếp ủng hộ dự án. 🦧⚡', + }, + statsTitle: '📊 **SkateSpots qua những con số**', + weatherTemp: '• {{temp}}°C (cảm giác {{feels}}°C)', + weatherSkateability: '• Khả năng trượt: **{{label}}** ({{score}}/100)', + weatherError: 'Không đọc được thời tiết ngay bây giờ. Thử lại sau một giây. 🌧️', + labelSpots: 'spot', + labelEvents: 'sự kiện', + labelLabPros: 'chuyên gia The Lab', + labelCrews: 'crew', + labelShops: 'cửa hàng trượt ván', + labelTours: 'tour', + labelGear: 'tin đăng đồ nghề', + unnamed: 'Chưa có tên', + emptyWhere: ' ở **{{place}}**', + emptyResult: 'Không tìm thấy {{label}} nào{{where}} ngay bây giờ 🦧\n\nCó thể chưa có cái nào được liệt kê — hoặc relay phản hồi chậm. Thử lại sau giây lát, kiểm tra lại chính tả, hoặc [thêm cái đầu tiên lên bản đồ](https://skate-spots.org/map). 🛹', + foundTitle: '{{emoji}} Tìm thấy **{{count}}** {{label}}:\n{{lines}}{{more}}', + moreResults: '\n\n…và **{{count}}** nữa — [xem tất cả trên bản đồ](https://skate-spots.org/map) 🗺️', + locationDenied: 'Tôi không thấy được vị trí của bạn — không có gì rời khỏi thiết bị của bạn cả; tôi chỉ đọc cục bộ khi bạn yêu cầu, và trình duyệt vừa từ chối. Nhấn 🎯 **Gần tôi** trên bản đồ, hoặc cho tôi một thành phố: "spot ở Bangkok". 🛹', + noNearbySpots: 'Chưa có spot nào gần bạn 🦧 — [hãy là người đầu tiên thả một cái](https://skate-spots.org/create-spot). 🛹', + closestTitle: 'Gần bạn nhất ngay bây giờ:', + closestFooter: '_Tính trên thiết bị của bạn — vị trí của bạn không hề rời đi._', + proNudge: 'Đó là tính năng **Sasquatch Pro** 🦧⚡ — với Pro tôi có thể đọc Stash, crew, spot và tin đăng của bạn, soạn tin bán đồ, tin cần mua và trạng thái trượt, và lên kế hoạch chuyến đi. Đó là thẻ ủng hộ bằng Lightning giúp giữ SkateSpots miễn phí & không quảng cáo. Nhấn nút **⚡ Lên Pro** ở trên cùng để mở khóa. 🛹', + draftingProPerk: 'Soạn hành động (đăng trạng thái, đăng bán đồ) là đặc quyền **Sasquatch Pro** 🦧⚡ — nhấn **⚡ Lên Pro** ở trên cùng để mở khóa.', + draftIntro: 'Đây là bản nháp — xem lại và nhấn để đăng. Không có gì lên sóng cho tới khi bạn xác nhận. 🛹', + draftFailed: 'Tôi chưa dựng được bản nháp đó — thử cho tôi biết chi tiết lần nữa (ví dụ "đăng bán wheels Spitfire của tôi với giá 8000 sats").', + tripAskCity: 'Đi đâu? Cho tôi một thành phố (ví dụ "lên kế hoạch 3 ngày ở Lisbon") và tôi sẽ dựng một chuyến đi. 🗺️', + tripEmptyMap: 'Chưa có gì trên bản đồ cho **{{destination}}** 🦧 — hãy là người đầu tiên thả spot ở [skate-spots.org](https://skate-spots.org). Khi dân địa phương thêm spot, crew & sự kiện, tôi sẽ dựng cho bạn một chuyến đi đầy đủ.', + tripLocked: 'Đã chốt cho bạn một nhiệm vụ ở **{{destination}}** 🛹 — spot, session và dân địa phương bên dưới. Chỉnh lại hoặc lưu nó.', + tripFailed: 'Không kết nối được dữ liệu trực tiếp để lên kế hoạch ngay bây giờ. Thử lại sau giây lát! 🛹', + tripEmptyMapLocal: 'Chưa có gì trên bản đồ cho **{{destination}}** 🦧 — hãy là người đầu tiên ở [skate-spots.org](https://skate-spots.org).', + tripMissionLocal: 'Đây là nhiệm vụ ở **{{destination}}** 🛹 — spot, session & dân địa phương bên dưới.', + relayFailed: 'Relay không phản hồi kịp ngay bây giờ 🛰️ — thường là do kết nối chậm, không phải thiếu spot. Thử lại sau giây lát. 🛹', + couldNotProcess: 'Hmm, không xử lý được cái đó. Thử diễn đạt lại!', + freeTierFallback: 'Cái đó cần suy luận AI — một tính năng **Sasquatch Pro** ⚡🦧\n\nTôi vẫn có thể tìm **spot, sự kiện, coach, crew, cửa hàng, tour và đồ nghề** trực tiếp từ relay — hỏi tôi ví dụ "spot ở Barcelona" — và [Bảng thuật ngữ](/glossary) bao gồm hơn 150 trick & thuật ngữ. Nhấn **⚡ Lên Pro** ở trên cùng để mở khóa câu trả lời AI.', + aiDownFallback: 'Não AI của tôi đang bay hơi ngay bây giờ 🦧 — nhưng tôi vẫn lo được cho bạn:\n\n• 🗺️ [Bản đồ](/) — spot, cửa hàng, sự kiện gần bạn\n• 🧪 [The Lab](/lab) — coach, filmer, dựng phim\n• 📖 [Bảng thuật ngữ](/glossary) — hơn 150 trick & thuật ngữ\n• 👥 [Crew](/crews) — tìm người của bạn\n\nHoặc chỉ cần cho tôi một **thành phố** ("spot ở Barcelona") hay một **trick** ("nollie là gì") và tôi sẽ trả lời ngay. 🛹', + wentWrong: 'Có gì đó trục trặc ở phía tôi. Thử lại sau một giây! 🦧', + publishError: 'Không đăng được cái đó: {{error}}. Thử lại sau một giây.', + unknownError: 'lỗi không xác định', + }, +}; export default viBatch2; diff --git a/src/i18n/vi/batch3.ts b/src/i18n/vi/batch3.ts index e8cf8d2..f7d4aa7 100644 --- a/src/i18n/vi/batch3.ts +++ b/src/i18n/vi/batch3.ts @@ -1,4 +1,1294 @@ -/** vi — batch 3. Filled by the translation pass; empty until then. */ -const viBatch3 = {}; +/** vi — batch 3 (namespace: settingsUi). */ +const viBatch3 = { + settingsUi: { + proSupport: { + title: "Pro & Hỗ trợ", + subtitle: "Các tiện ích tùy chọn giúp SkateSpots miễn phí", + prepaidTitle: "Trả trước, không phải đăng ký định kỳ", + prepaidBody: "Mỗi giao dịch là một khoản thanh toán Bitcoin/Lightning một lần — không tài khoản, không phí định kỳ, không giữ hộ. Trả thêm sẽ gia hạn thời gian của bạn.", + sasquatchTitle: "Sasquatch Pro", + sasquatchBenefit: "Mở khóa trợ lý AI cá nhân — nó có thể đọc Stash, Crew và tin đăng của chính bạn — và góp phần tài trợ cho dự án.", + active: "Đang hoạt động", + activeUntil: "Hoạt động đến {{date}}", + daysLeft: "Còn {{count}} ngày", + notActive: "Không hoạt động", + goPro: "Nâng cấp Pro", + extend: "Gia hạn Pro", + day: "ngày", + featuredTitle: "Vị trí nổi bật", + featuredBenefit: "Đẩy một tin đăng lên đầu với huy hiệu Pro — dành cho hồ sơ The Lab, sự kiện, Shop và tour.", + featuredHow: "Các mức thời hạn áp dụng cho mọi loại; cam kết dài hơn tốn ít hơn mỗi ngày. Bạn đặt nổi bật một tin đăng khi tạo hoặc chỉnh sửa nó.", + featuredUntil: "Đến {{date}}", + yourFeatured: "Tin đăng nổi bật của bạn", + noneFeatured: "Không có vị trí nổi bật nào đang hoạt động.", + freeTitle: "Các cách miễn phí", + freeBody: "FAQ AI và tìm kiếm cục bộ luôn miễn phí, và bạn có thể đăng một tin marketplace bằng proof-of-work miễn phí thay vì phí sats." + }, + notFound: { + seoTitle: "404 - Không tìm thấy trang", + seoDescription: "Không tìm thấy trang bạn đang tìm. Quay lại trang chủ để tiếp tục duyệt.", + message: "Ối! Không tìm thấy trang", + returnHome: "Về Trang chủ" + }, + loginArea: { + signUp: "Đăng ký", + logIn: "Đăng nhập" + }, + accountSwitcher: { + switchAccount: "Chuyển tài khoản", + walletSettings: "Cài đặt ví", + addAccount: "Thêm tài khoản khác", + logout: "Đăng xuất" + }, + amberHint: { + defaultAction: "gửi", + multiBefore: "Signer của bạn sẽ yêu cầu bạn phê duyệt", + multiTimes: "{{approvals}} lần", + multiAfter: "để {{action}} — điều đó là bình thường với tin nhắn mã hóa (mỗi người nhận một lần phê duyệt). Hãy phê duyệt từng lần.", + single: "Signer của bạn sẽ yêu cầu bạn phê duyệt để {{action}}." + }, + amberCallback: { + processing: "Đang xử lý đăng nhập Amber...", + gotResult: "Đã nhận kết quả: {{result}}", + noResultDebug: "Không có kết quả từ Amber", + noResultToast: "Không nhận được kết quả từ Amber. Thao tác có thể đã bị hủy.", + validPubkey: "Pubkey hợp lệ! Đang đăng nhập...", + loginSuccessful: "Đăng nhập thành công!", + loginErrorDebug: "Lỗi đăng nhập: {{error}}", + invalidResultDebug: "Định dạng kết quả không hợp lệ: {{result}}", + loggedInTitle: "Đã đăng nhập", + amberLoginDesc: "Đăng nhập thành công bằng Amber!", + loginFailedTitle: "Đăng nhập thất bại", + loginFailedDesc: "Không thể hoàn tất đăng nhập Amber. Vui lòng thử lại.", + invalidPubkeyDesc: "Nhận được pubkey không hợp lệ từ Amber.", + sessionLostToast: "Dữ liệu phiên đã mất. Vui lòng thử lại.", + eventSignedTitle: "Đã ký sự kiện", + eventSignedDesc: "Sự kiện của bạn đã được Amber ký.", + signingFailedTitle: "Ký thất bại", + signingFailedDesc: "Không thể xử lý sự kiện đã ký từ Amber.", + operationCompleteTitle: "Thao tác hoàn tất", + operationCompleteDesc: "{{op}} đã hoàn tất." + }, + loginDialog: { + loginWithAmber: "Đăng nhập bằng Amber (Android)", + welcomeTitle: "Chào mừng đến SkateSpots", + welcomeSubtitle: "Đăng ký hoặc đăng nhập để tiếp tục", + newHere: "Mới đến đây?", + createFree: "Tạo tài khoản miễn phí. Không cần email.", + createAccount: "Tạo tài khoản", + orLogIn: "Hoặc đăng nhập", + loggedInTitle: "🛹 Đã đăng nhập!", + loggedIn: "Đã đăng nhập!", + connectedAmber: "Đã kết nối qua Amber!", + amberLoginFailed: "Đăng nhập Amber thất bại", + amberCancelled: "Đã hủy đăng nhập. Nhấn \"Mở Amber\" để thử lại.", + amberNotFound: "Không tìm thấy Amber. Hãy chắc chắn Amber đã được cài từ ZapStore.", + loginFailed: "Đăng nhập thất bại", + pubkeyError: "Dán hex pubkey (64 ký tự) hoặc npub của bạn từ Amber", + pairedSigner: "Đã ghép nối với signer của bạn.", + connectFailed: "Không thể kết nối với signer của bạn.", + openedEncrypted: "Đã mở khóa mã hóa của bạn.", + openKeyFailed: "Không thể mở khóa đó.", + bunkerPrefix: "Phải bắt đầu bằng bunker://", + connectedBunker: "Đã kết nối qua bunker!", + bunkerFailed: "Thất bại: {{error}}", + checkBunkerUri: "Kiểm tra URI bunker của bạn", + nsecPrefix: "Phải bắt đầu bằng nsec1", + invalidNsec: "nsec không hợp lệ: {{error}}", + checkKey: "Kiểm tra khóa của bạn", + noExtensionTitle: "Không tìm thấy tiện ích mở rộng", + noExtensionDesc: "Cài Alby hoặc một tiện ích NIP-07 khác.", + amberIdleDesc: "Khóa của bạn ở lại trong Amber. Một lần nhấn — phê duyệt trong Amber và bạn quay lại đây, đã đăng nhập. Không cần sao chép gì.", + continueWithAmber: "Tiếp tục với Amber", + noAmberGetIt: "Chưa có Amber? Tải ngay →", + waitingAmberTitle: "Đang chờ Amber…", + waitingAmberDesc: "Phê duyệt yêu cầu trong Amber. Bạn sẽ được đăng nhập tự động ngay khi quay lại.", + openAmberAgain: "Mở Amber lại", + havingTrouble: "Gặp trục trặc? Nhập khóa thủ công", + enterPublicKey: "Nhập khóa công khai của bạn", + enterPublicKeyDescBefore: "Chỉ khi luồng tự động không hoạt động. Trong Amber: nhấn hồ sơ của bạn →", + copyPublicKey: "Sao chép khóa công khai", + enterPublicKeyDescAfter: "rồi dán vào đây.", + connect: "Kết nối", + back: "← Quay lại", + signInWithPhone: "Đăng nhập bằng điện thoại", + signInWithPhoneDesc: "Quét bằng ứng dụng signer (Amber, nsec.app). Khóa của bạn không bao giờ rời khỏi điện thoại.", + showPairingCode: "Hiện mã ghép nối", + waitingSigner: "Đang chờ signer của bạn…", + copyLink: "Sao chép liên kết", + orPasteBunker: "hoặc dán URL bunker", + bunkerTitle: "Bunker (NIP-46)", + bunkerPasteBefore: "Dán", + bunkerPasteAfter: "URI của bạn.", + amberInstructions: "Cài đặt → NIP-46 Bunker → Tạo → Sao chép", + nsecAppInstructions: "Kết nối ứng dụng → Sao chép URI bunker", + secretKeyTitle: "Khóa bí mật", + secretKeyRawDesc: "Dán trực tiếp khóa bí mật Nostr của bạn.", + secretKeyEncDesc: "Mở bản sao khóa được bảo vệ bằng mật khẩu.", + rawNsec: "nsec thô", + encryptedNip49: "Đã mã hóa (NIP-49)", + nsecWarning: "⚠️ Chỉ dùng điều này trên thiết bị tin cậy. Không bao giờ chia sẻ nsec của bạn.", + login: "Đăng nhập", + encSaferDesc: "An toàn hơn: khóa vẫn được mã hóa cho đến khi bạn nhập mật khẩu, nên bản sao an toàn để giữ trong lưu trữ đám mây hoặc trình quản lý mật khẩu.", + password: "Mật khẩu", + openEncryptedKey: "Mở khóa đã mã hóa", + browserExtensionTitle: "Tiện ích mở rộng trình duyệt (NIP-07)", + browserExtensionDesc: "Tốt nhất cho máy tính để bàn. Hoạt động với Alby, nos2x, Flamingo.", + loginWithExtension: "Đăng nhập bằng tiện ích mở rộng" + }, + signupDialog: { + download: "Tải xuống", + stepChoose: "Chọn", + stepProfile: "Hồ sơ", + stepSaveKey: "Lưu khóa", + somethingWrong: "Đã xảy ra lỗi", + createFailed: "Không thể tạo tài khoản của bạn. Vui lòng thử lại.", + keySavedTitle: "Đã lưu khóa bí mật!", + keySavedDesc: "Khóa của bạn đã được lưu an toàn.", + downloadFailedTitle: "Tải xuống thất bại", + downloadFailedDesc: "Không thể tải tệp khóa. Vui lòng sao chép thủ công.", + encSavedTitle: "Đã lưu bản sao mã hóa 🔐", + encSavedDesc: "Giữ cả tệp VÀ mật khẩu — bạn cần cả hai để đăng nhập lại.", + encFailed: "Không thể mã hóa khóa đó.", + invalidFileTitle: "Loại tệp không hợp lệ", + invalidFileDesc: "Vui lòng chọn một tệp hình ảnh cho ảnh đại diện của bạn.", + fileTooLargeTitle: "Tệp quá lớn", + fileTooLargeDesc: "Ảnh đại diện phải nhỏ hơn 5MB.", + avatarUploadedTitle: "Đã tải ảnh đại diện!", + avatarUploadedDesc: "Ảnh đại diện của bạn đã được tải lên thành công.", + uploadFailedTitle: "Tải lên thất bại", + uploadFailedDesc: "Không thể tải ảnh đại diện lên. Vui lòng thử lại.", + nameRequiredTitle: "Cần tên hiển thị", + nameRequiredDesc: "Chọn một tên hiển thị để các skater khác biết bạn là ai. Bạn có thể đổi bất cứ lúc nào.", + reserveFailedTitle: "Không thể giữ tên đó", + reserveFailedDesc: "{{error}} Bạn có thể nhận một tên sau trong Cài đặt.", + profileCreatedTitle: "Đã tạo hồ sơ!", + profileCreatedDesc: "Hồ sơ của bạn đã được thiết lập.", + profileFailedTitle: "Thiết lập hồ sơ thất bại", + profileFailedDesc: "Tài khoản của bạn đã được tạo nhưng thiết lập hồ sơ thất bại. Bạn có thể cập nhật sau.", + welcomeToastTitle: "Chào mừng!", + welcomeToastDesc: "Tài khoản của bạn đã sẵn sàng.", + titleWelcome: "Tham gia SkateSpots", + titleProfile: "Thiết lập hồ sơ của bạn", + titleDone: "Chào mừng!", + createFreeAccount: "Tạo tài khoản miễn phí", + createFreeAccountDesc: "Không email, không điện thoại, không mật khẩu. Tài khoản của bạn là một khóa Nostr — chọn nơi nó lưu trú.", + recommended: "Đề xuất", + signUpWithAmber: "Đăng ký bằng Amber", + signUpWithAmberDesc: "Khóa của bạn được tạo và lưu bên trong ứng dụng Amber — SkateSpots không bao giờ chạm tới. An toàn nhất. Một lần nhấn để phê duyệt.", + continueWithAmber: "Tiếp tục với Amber", + orQuickWay: "hoặc cách nhanh", + quickAccount: "Tài khoản nhanh trên thiết bị này", + quickAccountDesc: "Chúng tôi tạo một khóa sống trên thiết bị này. Khởi đầu nhanh nhất — chúng tôi sẽ giúp bạn lưu bản sao ngay sau đó.", + createQuickAccount: "Tạo tài khoản nhanh", + quickReassurance: "Mất 5 giây · sống trên thiết bị này · chúng tôi sẽ giúp bạn sao lưu tiếp theo", + preferAnotherSigner: "Muốn dùng signer khác?", + iosDesktopNudge: "Trên iOS hay máy tính để bàn? Ứng dụng signer hoặc tiện ích trình duyệt là lựa chọn an toàn nhất —", + seeAllOptions: "Xem tất cả tùy chọn", + youreInPickName: "Bạn đã vào! 🛹 Chọn tên hiển thị để các skater biết bạn là ai", + changeAnytime: "Bạn có thể đổi bất cứ lúc nào sau này. Tiểu sử và ảnh đại diện là tùy chọn.", + publishingProfile: "Đang công bố hồ sơ của bạn...", + displayName: "Tên hiển thị", + displayNamePlaceholder: "ví dụ: Tony, gnarlyGrind, hoặc tên Crew của bạn", + displayNameHint: "Bắt buộc — cách bạn xuất hiện trên khắp SkateSpots. Đổi bất cứ lúc nào.", + skateName: "Tên SkateSpots của bạn", + skateNameHint: "Miễn phí và tùy chọn — một handle đã xác minh hiển thị ✓ trên hồ sơ của bạn.", + bio: "Tiểu sử", + bioPlaceholder: "Kể cho người khác về bạn...", + avatar: "Ảnh đại diện", + uploadAvatar: "Tải ảnh đại diện lên", + saving: "Đang lưu...", + saveAndStart: "Lưu & Bắt đầu trượt", + addNameToContinue: "Thêm tên hiển thị để tiếp tục.", + savingPublishesNote: "Lưu sẽ công bố hồ sơ của bạn lên Nostr — signer của bạn có thể yêu cầu bạn phê duyệt một lần.", + youreIn: "Bạn đã vào! 🛹", + oneQuickThing: "Một điều nhanh trước khi bạn nhập cuộc…", + saveLoginKey: "Lưu khóa đăng nhập của bạn", + saveLoginKeyBefore: "Đây là", + only: "cách duy nhất", + saveLoginKeyAfter: "quay lại tài khoản của bạn — không email, không đặt lại mật khẩu. Lưu ngay và bạn có thể đăng nhập trên bất kỳ thiết bị nào, ở bất cứ đâu bạn trượt.", + revealSaveKey: "Hiện & lưu khóa của tôi", + recoveryCopied: "Đã sao chép mã khôi phục. Giữ nó ở nơi an toàn.", + saved: "Đã lưu", + treatLikeBoardKeys: "Hãy coi nó như chìa khóa ván của bạn — ai có mã này đều điều khiển được tài khoản của bạn. Không bao giờ chia sẻ.", + hideEncBackup: "Ẩn bản sao mã hóa", + saveEncBackup: "Lưu bản sao mã hóa", + encBackupBefore: "Một bản sao được bảo vệ bằng mật khẩu — an toàn để giữ trong lưu trữ đám mây hoặc trình quản lý mật khẩu. Bạn sẽ cần tệp", + and: "và", + encBackupAfter: "mật khẩu.", + choosePassword: "Chọn mật khẩu", + saveEncBackupCta: "Lưu bản sao mã hóa", + savedCodeAria: "Tôi đã lưu mã khôi phục của mình", + savedCodeLabel: "Tôi đã lưu mã khôi phục của mình ở nơi an toàn — trình quản lý mật khẩu, hoặc viết ra ngoài giấy.", + letsSkate: "Cùng trượt nào", + saveLater: "Tôi sẽ lưu sau từ Cài đặt", + advancedSigner: "Nâng cao: dùng ứng dụng signer thay thế" + }, + mnemonic: { + generatedTitle: "Đã tạo cụm từ khôi phục! 🎉", + generatedDesc: "Viết ra 12 từ này theo đúng thứ tự. Chúng là chìa khóa tài khoản của bạn!", + savedTitle: "Đã lưu cụm từ khôi phục!", + savedDesc: "Giữ tệp này ở nơi an toàn.", + downloadFailedTitle: "Tải xuống thất bại", + downloadFailedDesc: "Không thể tải tệp xuống. Vui lòng sao chép thủ công.", + copiedTitle: "Đã sao chép vào clipboard!", + copiedDesc: "Cụm từ khôi phục của bạn đã được sao chép.", + qrWindowTitle: "Mã QR cụm từ khôi phục", + qrHeading: "Mã QR cụm từ khôi phục của bạn", + qrAlt: "Mã QR cụm từ khôi phục", + qrWarning: "Giữ mã QR này riêng tư và an toàn!", + qrPrint: "In mã QR", + qrFailedTitle: "Mã QR thất bại", + qrFailedDesc: "Không thể tạo mã QR.", + accountCreatedTitle: "Đã tạo tài khoản! 🎉", + accountCreatedDesc: "Bạn đã sẵn sàng! Cụm từ khôi phục của bạn an toàn.", + loginFailedTitle: "Đăng nhập thất bại", + loginFailedDesc: "Không thể tạo tài khoản. Vui lòng thử lại.", + verifyFailedTitle: "Xác minh thất bại", + verifyFailedDesc: "Các từ không khớp. Vui lòng kiểm tra và thử lại.", + titlePrefix: "Tạo tài khoản bằng", + titleSuffix: "Cụm từ khôi phục", + twelveWordTitle: "Cụm từ khôi phục 12 từ", + twelveWordDesc: "Cụm từ khôi phục của bạn giống như một mật khẩu chủ. Viết nó ra giấy và giữ an toàn. Bạn sẽ cần nó để truy cập tài khoản từ thiết bị khác hoặc nếu xóa dữ liệu trình duyệt.", + generate: "Tạo cụm từ khôi phục", + useNsecInstead: "Dùng khóa nsec nâng cao thay thế", + yourPhrase: "Cụm từ khôi phục của bạn", + copy: "Sao chép", + download: "Tải xuống", + qrCode: "Mã QR", + criticalWarning: "Cảnh báo bảo mật nghiêm trọng", + warnWriteStrong: "Viết nó ra", + warnWrite: "giấy và cất an toàn", + warnNeverShareStrong: "Không bao giờ chia sẻ", + warnNeverShare: "cụm từ khôi phục của bạn với bất kỳ ai", + warnBackupsStrong: "Giữ nhiều bản sao", + warnBackups: "ở những nơi an toàn khác nhau", + warnAnyoneStrong: "Ai có cụm từ này", + warnAnyone: "đều điều khiển tài khoản của bạn mãi mãi", + warnLoseStrong: "Nếu bạn mất nó", + warnLose: "bạn mất tài khoản vĩnh viễn", + savedSecurely: "Tôi đã lưu nó an toàn", + verifyTitle: "Xác minh cụm từ khôi phục của bạn", + verifyDesc: "Để chắc chắn bạn đã lưu đúng, vui lòng nhập những từ này:", + wordLabel: "Từ #{{n}}", + wordPlaceholder: "Nhập từ #{{n}}", + goBack: "Quay lại", + verifyCreate: "Xác minh & Tạo tài khoản", + completeTitle: "Đã tạo tài khoản!", + completeDesc: "Tài khoản Nostr của bạn đã sẵn sàng!", + signerTitle: "Đề xuất: Thiết lập ứng dụng signer", + signerSubtitle: "Giữ khóa của bạn an toàn hơn", + signerDesc: "Để bảo mật tốt hơn, hãy dùng ứng dụng signer chuyên dụng thay vì dán cụm từ khôi phục ở khắp nơi. Ứng dụng signer giữ khóa an toàn đồng thời cho phép bạn dùng bất kỳ ứng dụng Nostr nào.", + signerCta: "Tìm hiểu về ứng dụng signer", + skip: "Bỏ qua lúc này" + }, + signupMethod: { + titlePrefix: "Chọn", + titleSuffix: "Cách đăng ký", + subtitle: "Cả hai cách đều an toàn. Chọn cách phù hợp nhất với bạn!", + recommended: "Đề xuất", + mnemonicTitle: "Cụm từ khôi phục", + mnemonicDesc: "12 từ dễ nhớ. Tiêu chuẩn ngành được Bitcoin, Ethereum và hầu hết ví crypto sử dụng.", + mnemonicF1: "Dễ viết ra giấy", + mnemonicF2: "Hoạt động với các ứng dụng Nostr khác (NIP-06)", + mnemonicF3: "Có thể tạo nhiều tài khoản", + mnemonicF4: "Quen thuộc với người dùng crypto", + useMnemonic: "Dùng cụm từ khôi phục", + advanced: "Nâng cao", + nsecTitle: "Khóa bí mật (nsec)", + nsecDesc: "Khóa mật mã thô. Thiên về kỹ thuật hơn nhưng cho bạn quyền truy cập trực tiếp vào danh tính Nostr của mình.", + nsecF1: "Kiểm soát mật mã trực tiếp", + nsecF2: "Tương thích với mọi ứng dụng Nostr", + nsecF3: "Một chuỗi duy nhất để sao lưu", + nsecF4: "Không có lớp dẫn xuất", + useNsec: "Dùng khóa bí mật", + footer: "🔒 Cả hai cách đều an toàn như nhau. Chọn theo sở thích của bạn!" + }, + skateNip05: { + placeholder: "têncủabạn", + claimedSuffix: "là của bạn — lưu hồ sơ để công bố nó.", + checking: "Đang kiểm tra tính khả dụng…", + available: "{{name}}@{{domain}} khả dụng", + claim: "Nhận nó", + hint: "Chữ cái, số, dấu gạch ngang. Miễn phí, và hiển thị như huy hiệu ✓ trên hồ sơ của bạn." + }, + nip05Required: { + getFree: "Nhận NIP-05 miễn phí / giá rẻ", + paid: "Trả phí", + requiredTitle: "Cần xác minh NIP-05", + bannerReason: "Để ngăn spam và xây dựng niềm tin, {{role}} cần một địa chỉ Nostr đã xác minh (NIP-05).", + gateReason: "Để ngăn spam và xây dựng niềm tin, {{role}} phải có xác minh NIP-05.", + addInSettings: "Thêm NIP-05 trong Cài đặt", + explainer: "NIP-05 chứng minh danh tính của bạn bằng cách liên kết hồ sơ Nostr với một tên miền — như", + updateProfile: "Cập nhật hồ sơ của bạn" + }, + editProfile: { + uploadSuccessTitle: "Thành công", + uploadSuccessDesc: "Đã tải {{field}} lên thành công", + uploadErrorDesc: "Không thể tải {{field}} lên. Vui lòng thử lại.", + mustBeLoggedIn: "Bạn phải đăng nhập để cập nhật hồ sơ", + invalidClinkTitle: "Mã CLINK không hợp lệ", + invalidClinkDesc: "Đó có vẻ không phải mã noffer1… hợp lệ. Xóa nó hoặc dán một mã hợp lệ.", + invalidLightningTitle: "Địa chỉ Lightning không hợp lệ", + invalidLightningDesc: "Dùng địa chỉ dạng email như you@walletofsatoshi.com.", + invalidSpTitle: "Địa chỉ Silent Payment không hợp lệ", + invalidSpDesc: "Địa chỉ Silent Payment bắt đầu bằng \"sp1\" và khá dài. Xóa nó hoặc dán một địa chỉ hợp lệ.", + invalidCordnTitle: "Liên kết Cordn không hợp lệ", + invalidCordnDesc: "Dán liên kết liên hệ Cordn đầy đủ https://….", + updateSuccessTitle: "Thành công", + updateSuccessDesc: "Hồ sơ của bạn đã được cập nhật", + updateErrorDesc: "Không thể công bố hồ sơ. Kiểm tra kết nối Relay của bạn trong Cài đặt > Relay", + identityTitle: "Danh tính", + identityDesc: "Cách bạn xuất hiện trên khắp SkateSpots.", + displayName: "Tên hiển thị", + displayNamePlaceholder: "Tên của bạn", + bio: "Tiểu sử", + bioPlaceholder: "Vài lời về bạn và việc trượt ván của bạn…", + profilePicture: "Ảnh hồ sơ", + pictureDesc: "Tải lên hoặc dán một hình vuông.", + bannerImage: "Ảnh bìa", + bannerDesc: "Một hình rộng cho phần trên hồ sơ của bạn.", + website: "Trang web", + bitcoinTitle: "Bitcoin & Thanh toán", + bitcoinDesc: "Để mọi người zap, tip và trả tiền trực tiếp cho bạn — không trung gian.", + lightningAddress: "Địa chỉ Lightning", + lud16Invalid: "Dùng địa chỉ dạng email, ví dụ: you@yourdomain.com.", + lud16Ok: "Cung cấp năng lượng cho nút “Zap” trên hồ sơ của bạn.", + lud16Hint: "Tip Bitcoin tức thì. Cung cấp năng lượng cho nút “Zap” trên hồ sơ của bạn.", + silentPaymentAddress: "Địa chỉ Silent Payment", + spInvalid: "Nên bắt đầu bằng “sp1” và khá dài.", + spOk: "Hợp lệ — một địa chỉ on-chain riêng tư, tái sử dụng được.", + spHint: "Địa chỉ on-chain tĩnh tái sử dụng được (BIP-352). Chia sẻ một lần; mọi khoản thanh toán đều không thể liên kết.", + clinkTipCode: "Mã tip CLINK", + nofferInvalid: "Đó có vẻ không phải mã noffer1… hợp lệ.", + nofferOk: "Hợp lệ — một nút “Tip in Bitcoin” sẽ hiện trên hồ sơ của bạn.", + nofferHint: "Mã CLINK tự giữ khóa để bất kỳ ai cũng có thể tip bạn qua Nostr — không trung gian.", + skateProfileTitle: "Hồ sơ trượt ván", + skateProfileDesc: "Đại diện cho các nhà tài trợ của bạn và cách Crew liên hệ với bạn.", + badges: "Huy hiệu", + badgesHint: "(nhãn + liên kết tùy chọn)", + badgeExample: "ví dụ: Independent Trucks", + badgeLabelPlaceholder: "Nhãn huy hiệu…", + badgeUrlPlaceholder: "https://… (tùy chọn)", + removeBadge: "Xóa huy hiệu", + addBadge: "Thêm huy hiệu", + badgesDescBefore: "Nhà tài trợ, Shop hoặc những người ủng hộ việc trượt ván của bạn — và bất cứ điều gì khác bạn muốn khoe. Mỗi cái trở thành một chip có thể nhấp trên hồ sơ của bạn.", + badgesDescAfter: "huy hiệu thành viên được thêm tự động.", + coordinator: "Điều phối viên", + cordnInvalid: "Đó có vẻ không phải điều phối viên. Dán nprofile, liên kết cordn.net, hoặc URL https://.", + cordnOk: "Hiển thị trên hồ sơ của bạn — người khác có thể thêm chỉ với một lần nhấn.", + cordnHint: "Điều phối viên Cordn mà người khác dùng để nhắn cho bạn. Riêng tư, mã hóa, thuộc về bạn.", + useMyCoordinator: "Dùng điều phối viên của tôi", + accountTitle: "Tài khoản", + accountDesc: "Cài đặt tài khoản bổ sung.", + botAccount: "Tài khoản bot", + botAccountDesc: "Đánh dấu tài khoản này là tự động hoặc bot.", + saving: "Đang lưu…", + saveProfile: "Lưu hồ sơ", + nip05VerifiedHandle: "Handle đã xác minh NIP-05", + nip05How: "Bằng cách nào?", + extraHandles: "Handle bổ sung", + extraHandlesHint: "tùy chọn — thêm tối đa 5", + nip05HintEmpty: "Một handle đã xác minh như you@yourdomain.com — phiên bản dấu tick xanh của Nostr. Hiển thị huy hiệu ✓ trên hồ sơ của bạn và mở khóa bộ lọc “Đã xác minh” trong danh bạ Skater.", + nip05Invalid: "Dùng handle dạng email, ví dụ: you@yourdomain.com — không có “https://” hay dấu cách.", + nip05Checking: "Đang kiểm tra tên miền của bạn…", + nip05Verified: "Đã xác minh — tên miền của bạn xác nhận handle này thuộc về bạn. ✓", + nip05Mismatch: "Tên miền của bạn ánh xạ handle này tới một khóa KHÁC. Sửa .well-known/nostr.json để nó trỏ tới tài khoản này.", + nip05Unreachable: "Chưa thể truy cập /.well-known/nostr.json của tên miền bạn. Các handle đã lưu vẫn hoạt động khi tên miền của bạn được thiết lập đúng.", + nip05Enter: "Nhập handle NIP-05 của bạn.", + freeHandleBefore: "Không có tên miền riêng? Nhận miễn phí một", + freeHandleAfter: "handle từ SkateSpots.", + uploadLabel: "Tải {{label}} lên", + previewLabel: "Xem trước {{label}}" + }, + security: { + recoveryCopied: "Đã sao chép mã khôi phục. Cất nó ở nơi an toàn.", + savedTitle: "Đã lưu!", + recoveryDownloaded: "Đã tải mã khôi phục xuống. Giữ nó ở nơi an toàn.", + downloadFailedTitle: "Tải xuống thất bại", + downloadFailedDesc: "Vui lòng sao chép thủ công thay thế.", + loginRequired: "Cần đăng nhập", + loginRequiredDesc: "Đăng nhập để truy cập cài đặt bảo mật.", + backupConfirmedTitle: "Đã xác nhận sao lưu! ✅", + backupConfirmedDesc: "Tuyệt! Khóa của bạn an toàn.", + yourRecoveryCode: "Mã khôi phục của bạn", + recoveryCodeDesc: "Không lưu nó khi đăng ký? Bạn có thể lấy ở đây bất cứ lúc nào.", + recoveryCodeBefore: "Mã này là", + only: "cách duy nhất", + recoveryCodeAfter: "để đăng nhập lại trên thiết bị hoặc trình duyệt mới. Lưu nó ở nơi an toàn (trình quản lý mật khẩu, hoặc viết ra giấy). Ai có nó đều điều khiển được tài khoản của bạn — không bao giờ chia sẻ.", + revealRecovery: "Hiện mã khôi phục của tôi", + qrHint: "Quét bằng ứng dụng Nostr khác để đăng nhập. Giữ màn hình này riêng tư.", + neverShareHide: "⚠️ Không bao giờ chia sẻ điều này. Ẩn nó khi bạn xong.", + hide: "Ẩn", + amberNoteBefore: "Bạn đang đăng nhập bằng", + amberNoteAfter: ". Mã khôi phục của bạn nằm trong Amber — mở ứng dụng Amber để sao lưu nó. SkateSpots không bao giờ thấy khóa của bạn.", + bunkerNoteBefore: "Bạn đang đăng nhập bằng", + remoteSigner: "signer từ xa (bunker)", + bunkerNoteAfter: ". Mã khôi phục của bạn do dịch vụ signer giữ, không phải SkateSpots. Sao lưu nó ở đó.", + extensionNoteBefore: "Bạn đang đăng nhập bằng", + browserExtension: "tiện ích mở rộng trình duyệt", + extensionNoteAfter: ". Mã khôi phục của bạn nằm trong tiện ích — dùng tùy chọn sao lưu/xuất riêng của nó. SkateSpots không bao giờ thấy khóa của bạn.", + otherNote: "Mã khôi phục của bạn do ứng dụng signer quản lý, không phải SkateSpots. Sao lưu nó ở đó.", + backupWarningTitle: "⚠️ Bạn đã sao lưu cụm từ khôi phục hoặc khóa bí mật chưa?", + backupWarningBody: "Khóa của bạn là cách DUY NHẤT để truy cập tài khoản. Nếu mất chúng, bạn mất tất cả - không có đặt lại mật khẩu!", + iveBackedUp: "Tôi đã sao lưu khóa của mình", + backupConfirmed: "✅ Đã xác nhận sao lưu", + backupNotConfirmed: "⚠️ Chưa xác nhận sao lưu", + backupConfirmedStatusDesc: "Bạn đã xác nhận rằng khóa của mình được sao lưu an toàn.", + backupNotConfirmedDesc: "Hãy chắc chắn sao lưu cụm từ khôi phục hoặc khóa bí mật của bạn!", + notSavedYetBefore: "Chưa lưu mã khôi phục? Không vấn đề — lấy nó từ mục", + notSavedYetAfter: "ở trên, cất ở nơi an toàn, rồi xác nhận bên dưới.", + yesBackedUp: "Có, tôi đã sao lưu khóa của mình", + bestPracticesTitle: "Thực hành bảo mật khóa tốt nhất", + bestPracticesDesc: "Cách giữ tài khoản Nostr của bạn an toàn", + bp1Title: "Viết nó ra giấy", + bp1Desc: "Sao lưu vật lý là an toàn nhất. Cất ở nơi an toàn như két sắt.", + bp2Title: "Nhiều bản sao", + bp2Desc: "Giữ các bản sao ở những nơi an toàn khác nhau (két ở nhà, hộp ký gửi ngân hàng, v.v.)", + bp3Title: "Không bao giờ chia sẻ khóa", + bp3Desc: "Ứng dụng Nostr thật KHÔNG BAO GIỜ hỏi nsec hay cụm từ khôi phục của bạn sau lần đăng nhập đầu tiên", + bp4Title: "Đừng lưu trên đám mây không mã hóa", + bp4Desc: "Tránh Google Docs, bản nháp email, hoặc lưu trữ đám mây văn bản thuần", + bp5Title: "Cân nhắc dùng tiện ích mở rộng trình duyệt", + bp5Desc: "Alby, nos2x, hoặc Flamingo giữ khóa của bạn an toàn và không bao giờ để lộ chúng cho trang web", + importantReminders: "⚠️ Lời nhắc quan trọng", + rem1: "Nếu mất khóa, bạn mất tài khoản vĩnh viễn", + rem2: "Không công ty hay cá nhân nào đặt lại được mật khẩu của bạn - kể cả chúng tôi", + rem3: "Ai có khóa của bạn đều có toàn quyền kiểm soát tài khoản", + rem4: "Khóa của bạn điều khiển mọi dữ liệu Nostr trên TẤT CẢ ứng dụng", + recommendedSigners: "🔌 Signer Nostr được đề xuất", + recommendedSignersDesc: "Dùng signer Nostr để bảo mật và tiện lợi hơn", + recommended: "Đề xuất", + amberDesc: "Signer Nostr an toàn cho Android. Giữ khóa an toàn trên điện thoại và ký sự kiện mà không để lộ chúng.", + albyDesc: "Tiện ích mở rộng đầy đủ tính năng với ví Lightning, WebLN và hỗ trợ NWC.", + flamingoDesc: "Giao diện đơn giản, gọn gàng. Tập trung vào ký Nostr không có tính năng ví.", + nos2xDesc: "Tiện ích mở rộng tối giản, nhẹ cho người dùng nâng cao.", + nostrConnectTitle: "☁️ Nostr Connect (Signer từ xa)", + nostrConnectDesc: "Dùng signer từ xa để truy cập tài khoản từ bất kỳ thiết bị nào", + nostrConnectBody: "Nostr Connect (còn gọi là \"bunker\") cho phép bạn lưu khóa trên một máy chủ an toàn và đăng nhập từ bất kỳ thiết bị nào. Khóa của bạn không bao giờ rời máy chủ, nhưng bạn có thể dùng tài khoản ở mọi nơi!", + nsecAppDesc: "Signer từ xa miễn phí, an toàn. Tạo URI bunker:// và dán khi đăng nhập.", + nostrumDesc: "Một lựa chọn signer từ xa khác có hỗ trợ di động.", + howToUse: "💡 Cách sử dụng:", + howToUseDesc: "Tạo tài khoản trên một trong các dịch vụ này, lấy chuỗi kết nối bunker://, rồi dán nó vào tab \"Nostr Connect\" khi đăng nhập." + }, + relayList: { + connected: "Đã kết nối", + connecting: "Đang kết nối…", + offline: "Ngoại tuyến", + removeUrl: "Xóa {{url}}", + add: "Thêm", + publishedTitle: "Đã công bố danh sách Relay", + publishedDesc: "Đã đồng bộ lên Nostr (kind 10002).", + publishFailedTitle: "Công bố danh sách Relay thất bại", + invalidUrlTitle: "URL Relay không hợp lệ", + invalidUrlDesc: "Thử một cái gì đó như wss://relay.example.com", + alreadyInList: "Relay đã có trong danh sách của bạn", + keepReadWriteTitle: "Giữ đọc hoặc ghi trên", + keepReadWriteDesc: "Một Relay cần ít nhất một trong hai: đọc/ghi.", + alreadyInThisList: "Relay đã có trong danh sách này", + dmPublishedTitle: "Đã công bố Relay DM", + dmPublishedDesc: "Đã cập nhật hộp thư đến NIP-17.", + dmPublishFailedTitle: "Công bố Relay DM thất bại", + nip65Title: "Relay (NIP-65)", + nip65DescUser: "Nhấn Đọc / Ghi để bật tắt. Được công bố lên Nostr dưới dạng danh sách kind 10002 của bạn.", + nip65DescLoggedOut: "Nhấn Đọc / Ghi để bật tắt. Đăng nhập để công bố danh sách lên Nostr.", + noRelays: "Chưa có Relay nào — thêm một cái bên dưới.", + local: "Cục bộ", + read: "Đọc", + readHint: "Lấy nội dung từ Relay này", + write: "Ghi", + writeHint: "Công bố sự kiện của bạn lên Relay này", + dmTitle: "Relay hộp thư đến DM", + dmDesc: "Nơi bạn nhận tin nhắn trực tiếp NIP-17 (kind 10050). Khi trống sẽ dùng Relay ghi của bạn.", + localTitle: "Relay cục bộ", + localDesc: "Chỉ trong ứng dụng (ví dụ: một node LAN). Dùng để đọc và ghi; không bao giờ được công bố.", + blockedTitle: "Relay bị chặn", + blockedDesc: "Không bao giờ kết nối tới những cái này — bị loại khỏi mọi lần đọc và ghi." + }, + relatr: { + searchingTitle: "Đang tìm dịch vụ Relatr...", + searchingDesc: "Đang truy vấn Nostr để tìm hồ sơ Relatr", + foundTitle: "Đã tìm thấy dịch vụ Relatr!", + foundDesc: "Dịch vụ: {{name}}", + unknown: "Không rõ", + notFoundTitle: "Không tìm thấy dịch vụ Relatr", + notFoundDesc: "Thử nhập pubkey thủ công hoặc kiểm tra https://www.relatr.xyz/", + searchFailedTitle: "Tìm kiếm thất bại", + searchFailedDesc: "Không thể truy vấn Nostr để tìm hồ sơ Relatr", + invalidPubkeyTitle: "Pubkey không hợp lệ", + invalidPubkeyDesc: "Vui lòng nhập pubkey hex 64 ký tự hợp lệ", + enabledTitle: "Đã bật Relatr!", + enabledDesc: "Điểm tin cậy toàn cầu hiện đã hoạt động.", + disabledTitle: "Đã tắt Relatr", + disabledDesc: "Điểm tin cậy không còn được tải về nữa.", + title: "Điểm tin cậy Relatr", + desc: "Điểm tin cậy toàn cầu giúp nhận diện người dùng đáng tin cậy và giảm spam", + status: "Trạng thái", + active: "Đang hoạt động", + disabled: "Đã tắt", + activeStrong: "Relatr đang hoạt động.", + activeDesc: "Điểm tin cậy từ phân tích mạng toàn cầu của ContextVM giúp nhận diện skater đáng tin cậy và giảm spam.", + disabledStrong: "Relatr đã tắt.", + disabledHint: "Bật nó để nhận điểm tin cậy từ mạng Nostr toàn cầu.", + disable: "Tắt Relatr", + enable: "Bật Relatr", + advancedSettings: "Cài đặt nâng cao", + servicePubkey: "Pubkey dịch vụ Relatr", + pubkeyPlaceholder: "Nhập pubkey hex 64 ký tự...", + searching: "Đang tìm kiếm...", + autoDiscover: "Tự động tìm", + pubkeyDefault: "Mặc định: dịch vụ Relatr chính thức của ContextVM (npub1dvmc...)", + relayLabel: "Relay (nơi Relatr công bố điểm số)", + relayDefault: "Mặc định: wss://relay.contextvm.org (Relay chính thức của ContextVM)", + applyChanges: "Áp dụng thay đổi", + learnMore: "Tìm hiểu thêm:", + website: "Trang web Relatr", + github: "GitHub Relatr", + nip85Spec: "Đặc tả NIP-85" + }, + followList: { + unfollow: "Bỏ theo dõi", + title: "Mạng lưới Nostr của bạn", + desc: "Quản lý những người bạn theo dõi. Theo dõi người dùng giúp xây dựng Web of Trust và quyết định Spot nào hiển thị huy hiệu tin cậy.", + following: "Đang theo dõi ({{count}})", + followers: "Người theo dõi ({{count}})", + follow: "Theo dõi", + followHint: "💡 Dán pubkey Nostr (npub1...), địa chỉ NIP-05 (user@domain.com), hoặc pubkey hex", + notFollowing: "Bạn chưa theo dõi ai", + notFollowingHint: "Theo dõi các skater để xem Spot của họ với huy hiệu ✅ VERIFIED", + trustActiveStrong: "✅ Huy hiệu tin cậy đang hoạt động:", + trustActive: "Spot do người bạn theo dõi tạo sẽ hiển thị huy hiệu VERIFIED. Spot của bạn bè họ sẽ hiển thị huy hiệu TRUSTED.", + noFollowers: "Chưa có người theo dõi", + noFollowersHint: "Chia sẻ hồ sơ Nostr của bạn để có người theo dõi!", + howTitle: "💡 Việc theo dõi ảnh hưởng thế nào đến huy hiệu tin cậy", + verifiedStrong: "✅ VERIFIED (Xanh lá):", + verifiedDesc: "Spot do người bạn trực tiếp theo dõi tạo", + trustedStrong: "🟡 TRUSTED (Vàng):", + trustedDesc: "Spot do người mà bạn bè bạn theo dõi tạo (2 bước)", + unverifiedStrong: "⚪ Chưa xác minh:", + unverifiedDesc: "Spot của người dùng không có kết nối nào với mạng lưới của bạn", + tip: "💡 Mẹo: Theo dõi những người trượt ván năng động để thấy nhiều Spot đã xác minh hơn và xây dựng mạng lưới tin cậy của bạn!" + }, + notify: { + enableTitle: "Bật thông báo", + enableDesc: "Rung thiết bị này khi có việc cần bạn.", + checkingPermission: "Đang kiểm tra quyền…", + unsupported: "Thiết bị này không hỗ trợ thông báo ở đây. Xây dựng lại ứng dụng Android để bật chúng trên điện thoại của bạn.", + denied: "Thông báo bị chặn cho trang này. Cho phép chúng trong cài đặt trình duyệt/HĐH, rồi thử lại.", + backgroundTitle: "Thông báo nền", + backgroundDesc: "Nhận thông báo cho tin nhắn và giao dịch ngay cả khi SkateSpots đã đóng.", + pushUnsupported: "Trình duyệt này không hỗ trợ push nền. Trên di động, thêm SkateSpots vào màn hình chính.", + pushPrivacy: "Để liên lạc với bạn khi ứng dụng đóng, máy chủ thông báo SkateSpots nhận một ping từ Relay khi có gì đó đến cho khóa của bạn và chuyển nó tới dịch vụ push của điện thoại. Nó chỉ thấy rằng khóa của bạn có gì đó — không bao giờ thấy ai gửi hay nội dung gì, và nó không thể giải mã tin nhắn của bạn. Chọn tham gia theo từng thiết bị.", + bgDeliveryTitle: "Gửi nền (Android)", + bgDeliveryDesc: "Kiểm tra tin nhắn, ưu đãi và giao dịch mới khi ứng dụng đóng — không cần dịch vụ Google.", + off: "Tắt", + standard: "Tiêu chuẩn (~15 phút)", + fast: "Nhanh (~5 phút)", + bgDeliveryNote: "Tiêu chuẩn là nỗ lực tối đa — Android có thể hoãn nó dưới Doze. Nhanh hiển thị thông báo thường trực và dùng nhiều pin hơn. Không có gì được giải mã trên máy chủ của chúng tôi.", + notifyMeAbout: "Thông báo cho tôi về", + couldNotEnable: "Không thể bật", + sendTest: "Gửi thông báo thử", + testTitle: "Thông báo SkateSpots đã bật 🛹", + testBody: "Đây là cách một DM, zap hay lời mời Crew sẽ hiển thị.", + footerBefore: "Cảnh báo được tạo trên thiết bị của bạn từ dữ liệu ứng dụng đã có, và cảnh báo tin nhắn trực tiếp không bao giờ giải mã tin nhắn của bạn — nên Amber không bao giờ bị yêu cầu mở chúng. Với", + footerAfter: "tắt, ứng dụng đã đóng hoàn toàn không thể liên lạc được, nên cảnh báo sẽ đến vào lần tới bạn mở SkateSpots.", + cat_dms_label: "Tin nhắn trực tiếp", + cat_dms_hint: "Ai đó gửi cho bạn tin nhắn riêng", + cat_crew_label: "Crew", + cat_crew_hint: "Lời mời, yêu cầu tham gia và xác nhận thành viên", + cat_social_label: "Zap, trả lời & nhắc đến", + cat_social_hint: "Cảm xúc, đăng lại, zap, trả lời và cập nhật sự kiện", + cat_newsletter_label: "Bản tin", + cat_newsletter_hint: "Các bản tin mới của SkateSpots (chỉ người đăng ký)", + cat_trades_label: "Ưu đãi & giao dịch", + cat_trades_hint: "Ưu đãi, phản đề nghị và xác nhận giao dịch", + cat_reminders_label: "Nhắc nhở sự kiện", + cat_reminders_hint: "Nhắc một giờ trước sự kiện bạn sẽ tham dự (ứng dụng Android)" + }, + regionBackfill: { + taggedTitle: "Đã gắn thẻ {{count}} vị trí{{s}}", + taggedSkipped: "{{count}} bị bỏ qua (không có tọa độ hoặc không khớp geocoder).", + taggedOk: "Thẻ vùng đã được ghi vào Relay cộng đồng.", + nothingTitle: "Không có gì để gắn thẻ", + nothingDesc: "Không có ghim nào có thể geocode. Thử lại sau.", + failedTitle: "Backfill thất bại", + title: "Backfill thẻ vùng", + admin: "Quản trị", + descBefore: "Các ghim được tạo trước khi có geocoding có tọa độ nhưng không có thẻ thành phố/quốc gia, nên bản đồ vẽ chúng trong khi Thống kê cộng đồng chỉ có thể nói “Chưa phân loại”. Việc này tạo lại thẻ từ mỗi ghim và công bố lại", + descStrong: "của chính bạn", + descAfter: "các Spot & Shop chưa gắn thẻ.", + scanning: "Đang quét Spot của bạn…", + allTagged: "Mọi Spot & Shop bạn sở hữu đều đã có thẻ vùng. 🎉 Bất kỳ ghim “Chưa phân loại” nào còn lại thuộc về các mapper khác — chỉ khóa của họ mới gắn thẻ được.", + countLine: "{{count}} trong số Spot{{s}}/Shop của bạn không có thẻ vùng. Signer của bạn có thể yêu cầu phê duyệt từng cái.", + tagging: "Đang gắn thẻ {{done}}/{{total}}…", + run: "Backfill thẻ vùng", + summary: "{{updated}} đã cập nhật · {{skipped}} bỏ qua · {{failed}} thất bại" + }, + adminReview: { + title: "Hàng đợi duyệt", + flagged: "{{count}} Spot{{s}} có dấu hiệu rác — ẩn hoặc bỏ qua.", + clean: "Spot trông giống mục thử nghiệm hoặc ghim lạc đề." + }, + grantPro: { + invalidNpub: "Nhập npub hợp lệ (hoặc pubkey hex)", + invalidDays: "Số ngày phải là số dương", + grantedTitle: "Đã cấp Pro ⚡", + grantedDesc: "{{npub}} đến {{date}}", + failedTitle: "Cấp thất bại", + title: "Cấp Sasquatch Pro", + owner: "Chủ sở hữu", + desc: "Phương án dự phòng thủ công cho một khoản thanh toán đã xác minh mà biên lai zap bỏ lỡ. Công bố một khoản cấp do chủ sở hữu ký; người dùng không thể làm giả nó.", + targetPlaceholder: "npub1… (hoặc hex)", + grant: "Cấp" + }, + myData: { + reactionTitle: "Cảm xúc {{emoji}}", + deleting: "Đang xóa...", + requestDeletion: "Yêu cầu xóa", + selectContentTitle: "Chọn nội dung để xóa", + selectContentDesc: "Chọn các mục cụ thể bạn muốn yêu cầu xóa.", + all: "Tất cả", + spots: "Spot", + events: "Sự kiện", + shops: "Shop", + listings: "Tin đăng", + collections: "Bộ sưu tập", + lab: "Lab", + posts: "Bài viết", + reactions: "Cảm xúc", + selectAll: "Chọn tất cả", + selectAllVisible: "Chọn tất cả đang hiển thị", + selectedCount: "Đã chọn {{count}}", + noItemsCategory: "Không có mục nào trong danh mục này", + decentralizedStrong: "Quan trọng:", + decentralizedNote: "Nostr là phi tập trung. Các Relay nên tuân thủ yêu cầu xóa, nhưng một số có thể không. Đây không phải là xóa vĩnh viễn được đảm bảo.", + deleteCount: "Xóa {{count}} mục{{s}}", + noDataTitle: "Không có dữ liệu để xuất", + noDataDesc: "Bạn chưa công bố sự kiện nào.", + exportedTitle: "Đã xuất dữ liệu!", + exportedDesc: "Đã tải {{count}} sự kiện dưới dạng JSON.", + deletionRequestedTitle: "Đã yêu cầu xóa", + deletionRequestedDesc: "Yêu cầu xóa đã được công bố lên các Relay.", + deletionRequestedMany: "Đã yêu cầu xóa {{count}} mục. Lưu ý: Một số Relay có thể không tuân thủ yêu cầu này.", + deletionFailedTitle: "Xóa thất bại", + deletionFailedDesc: "Không thể công bố yêu cầu xóa. Vui lòng thử lại.", + loginRequired: "Cần đăng nhập", + loginRequiredDesc: "Đăng nhập để xem và quản lý dữ liệu của bạn.", + title: "Dữ liệu của tôi", + desc: "Nội dung của bạn trên mạng Nostr. Bạn sở hữu dữ liệu này - xuất nó bất cứ lúc nào hoặc yêu cầu xóa.", + coachFilmer: "Huấn luyện viên/Quay phim", + zaps: "Zap", + received: "Đã nhận", + exportAll: "Xuất tất cả dữ liệu", + recentActivity: "Hoạt động gần đây", + viewAll: "Xem tất cả ({{count}})", + noDataPublished: "Chưa công bố dữ liệu nào", + startBy: "Bắt đầu bằng", + addingASpot: "thêm một Spot", + aboutYourData: "Về dữ liệu của bạn", + ownDataStrong: "Bạn sở hữu dữ liệu của mình.", + ownData: "Mọi nội dung đều được ký bằng khóa mật mã của bạn và lưu trên các Relay Nostr. Không công ty nào kiểm soát nó.", + exportAnytimeStrong: "Xuất bất cứ lúc nào", + exportAnytime: "- Tải tất cả sự kiện của bạn dưới dạng JSON", + portableStrong: "Di động", + portable: "- Dùng khóa của bạn trong bất kỳ ứng dụng Nostr nào", + selectiveStrong: "Xóa có chọn lọc", + selective: "- Chọn chính xác những gì cần xóa", + caveatStrong: "Lưu ý phi tập trung", + caveat: "- Một số Relay có thể giữ dữ liệu bất chấp yêu cầu xóa" + }, + settingsPage: { + seoTitle: "Cài đặt - SkateSpots", + seoDescription: "Quản lý cài đặt tài khoản SkateSpots của bạn.", + heading: "CÀI ĐẶT", + subtitle: "Tài khoản và tùy chọn ứng dụng", + editProfile: "Chỉnh sửa hồ sơ", + profileRefreshed: "Đã làm mới hồ sơ!", + found: "Đã tìm thấy: {{name}}", + unnamed: "chưa có tên", + profileNotFound: "Không tìm thấy hồ sơ", + notFoundOnRelay: "Không tìm thấy trên bất kỳ Relay nào.", + refreshFailed: "Làm mới thất bại", + refreshFailedDesc: "Không thể kết nối với các Relay.", + loginToEdit: "Đăng nhập để chỉnh sửa hồ sơ của bạn", + noProfileRelays: "Chúng tôi không tìm thấy hồ sơ nào trên các Relay. Nếu bạn đã thiết lập trước đây, hãy thử làm mới.", + checkDisplayName: "tên hiển thị", + checkPhoto: "ảnh hồ sơ", + checkBio: "tiểu sử ngắn", + checkLightning: "địa chỉ Lightning để mọi người zap bạn", + checkHandle: "handle @skate-spots.org miễn phí", + finishProfile: "Hoàn thiện hồ sơ của bạn", + addItem: "Thêm {{item}}", + nip05Title: "Xác minh NIP-05", + nip05Desc: "Nhận một địa chỉ Nostr đã xác minh (như name@domain.com) để xây dựng niềm tin. Cần thiết để tạo sự kiện, hồ sơ huấn luyện và Shop.", + freeFromSkateSpots: "Miễn phí từ SkateSpots", + claimHandleBefore: "Nhận một handle như", + claimHandleAfter: "— không đăng ký, không tốn phí, không cần chạy tên miền. Nhận nó trong tab Hồ sơ, rồi lưu.", + claimInProfile: "Nhận trong Hồ sơ", + nip05Footer: "Sau khi có NIP-05, thêm nó vào trường Hồ sơ và lưu.", + localRelayOn: "Relay cục bộ đã bật", + localRelayOff: "Relay cục bộ đã tắt", + lookingForCitrine: "Đang tìm Citrine trên thiết bị này…", + noLongerUsing: "Không còn dùng Relay trên thiết bị nữa.", + localRelay: "Relay cục bộ", + citrineOff: "Đọc nhanh hơn & sao lưu ngoại tuyến trên thiết bị này", + citrineSearching: "Đang tìm Citrine trên thiết bị này…", + citrineLive: "Đã kết nối — đang đọc & sao lưu cục bộ", + citrineWaiting: "Đã bật — khởi động Citrine để kết nối", + toggleCitrine: "Bật/tắt Relay Citrine cục bộ", + citrineDetected: "Đã phát hiện Relay Citrine", + citrineLooking: "Đang tìm Citrine…", + citrineNotDetected: "Không phát hiện Citrine", + recheckCitrine: "Kiểm tra lại Relay Citrine", + checking: "Đang kiểm tra", + recheck: "Kiểm tra lại", + chipInstantReads: "Đọc tức thì", + chipWorksOffline: "Hoạt động ngoại tuyến", + chipOnDeviceBackup: "Sao lưu trên thiết bị", + cantReachStrong: "Không thể kết nối Citrine.", + cantReachBefore: "Hãy chắc chắn ứng dụng Citrine miễn phí đã được cài và Relay của nó đã", + started: "khởi động", + cantReachAfter: ", rồi nhấn Kiểm tra lại. Nó chạy một Relay Nostr riêng tư trên điện thoại của bạn để đọc tức thì và sao lưu ngoại tuyến.", + citrineStep1Before: "Mở Citrine → nhấn", + start: "Bắt đầu", + citrineStep2Before: "Quay lại đây → nhấn", + getCitrine: "Tải Citrine", + citrinePrivacy: "Stash và tin nhắn của bạn vẫn được mã hóa đầu-cuối ở đây, y như mọi nơi khác. Relay cục bộ chỉ tăng tốc mọi thứ và giữ một bản sao trên thiết bị của bạn — nó không bao giờ thay thế mã hóa.", + communityRelayDisabled: "Đã tắt Relay cộng đồng", + communityRelayEnabled: "Đã bật Relay cộng đồng", + usingOnlyPersonal: "Chỉ dùng các Relay bạn đã cấu hình.", + skateRelayIncluded: "Đã bao gồm Relay SkateSpots.", + relays: "Relay", + relayPrivacyBefore: "Relay có thể thấy", + ipAddress: "Địa chỉ IP", + relayPrivacyAfter: "của bạn khi bạn kết nối. Tor che nó đi — và hãy coi một VPN \"miễn phí\" là dấu hiệu cảnh báo; chúng thường kiếm tiền từ lưu lượng của bạn.", + communityRelay: "Relay cộng đồng", + syncingGlobal: "Đang đồng bộ với cộng đồng trượt ván toàn cầu", + usingOnlyPersonalShort: "Chỉ dùng Relay cá nhân", + appearance: "Giao diện", + language: "Ngôn ngữ", + darkModeOnly: "Chỉ chế độ tối", + darkModeDesc: "SkateSpots chạy phong cách neon tối lấy cảm hứng từ văn hóa trượt ván. Nền đen, hồng neon, xanh chanh và cam.", + navigation: "Điều hướng", + sasquatchExpanded: "Sasquatch đã được mở rộng! 🦧 Làm mới trang để thấy anh ấy.", + advanced: "Nâng cao", + sasquatchGuide: "🦧 Hướng dẫn Sasquatch", + sasquatchResetDesc: "Đặt lại hướng dẫn nhập môn về chế độ mở rộng", + expandSasquatch: "Mở rộng The Sasquatch", + wallet: "Ví", + loginToWallet: "Đăng nhập để quản lý ví của bạn", + openWallet: "Mở ví", + balanceSendReceive: "Số dư, gửi, nhận", + connectNwc: "Kết nối ví NWC", + account: "Tài khoản", + security: "Bảo mật", + securitySub: "Khóa, ký, Amber", + nip05Sub: "Nhận địa chỉ Nostr đã xác minh", + app: "Ứng dụng", + myStash: "Stash của tôi", + myStashSub: "Kho Gear riêng tư", + relaysSub: "Kết nối Relay Nostr", + appearanceSub: "Ngôn ngữ và chủ đề", + assistant: "Trợ lý", + showSasquatch: "Hiện trợ lý Sasquatch", + showSasquatchDesc: "Hiển thị nút Sasquatch nổi trên bản đồ và các màn hình khác.", + showMapFooter: "Hiện thanh liên kết bản đồ", + showMapFooterDesc: "Hiển thị dải liên kết mỏng ở cuối bản đồ.", + notifications: "Thông báo", + notificationsSub: "Cảnh báo cho DM, Crew và zap", + coordinator: "Điều phối viên", + coordinatorSub: "Máy chủ nhóm Cordn của bạn", + data: "Dữ liệu", + myData: "Dữ liệu của tôi", + myDataSub: "Xuất, nhập, quản lý", + advancedSub: "Relatr, Sasquatch, công cụ", + notLoaded: "Chưa tải", + notLoggedIn: "Chưa đăng nhập" + }, + onboarding: { + seoTitle: "Bắt đầu — SkateSpots", + seoDescription: "Tham gia cộng đồng trượt ván phi tập trung. Tìm Spot, kết nối với huấn luyện viên, gửi zap. Miễn phí mãi mãi.", + homeSetTitle: "Đã đặt nhà 🛹", + homeSetDesc: "Bản đồ giờ sẽ mở ở khu vực của bạn.", + locationFailedTitle: "Không thể lấy vị trí của bạn", + locationFailedDesc: "Kiểm tra quyền vị trí, hoặc chọn khu vực của bạn trên bản đồ.", + niceTitle: "🎉 Tuyệt!", + niceDesc: "Bạn đã hiểu cách Nostr hoạt động. Đi trượt thôi!", + npubCopied: "Đã sao chép npub vào clipboard.", + saveLoginNow: "Lưu thông tin đăng nhập — làm ngay bây giờ", + saveLoginNowDesc: "Mã khôi phục của bạn là cách duy nhất quay lại tài khoản. Không email, không đặt lại mật khẩu.", + betaBadge: "Beta — Mở cho skater toàn thế giới", + headline1: "TRƯỢT", + headline2: "THẾ GIỚI CỦA BẠN", + heroBefore: "Một", + decentralized: "phi tập trung", + heroAfter: "cộng đồng trượt ván. Không công ty nào sở hữu nó. Không thuật toán chôn Spot của bạn. Không búa cấm. Chỉ có skater.", + pillMap: "Bản đồ Spot", + pillCoaches: "Huấn luyện viên & quay phim", + pillEvents: "Sự kiện", + pillGear: "Mua/bán Gear", + pillZaps: "Zap Bitcoin", + pillStash: "Kho Gear", + pillCrews: "Crew", + createFreeAccount: "Tạo tài khoản miễn phí", + noEmailNoPassword: "Không email. Không mật khẩu. Sở hữu danh tính của bạn mãi mãi.", + findSpots: "Tìm Spot gần bạn", + addFirstSpot: "Thêm Spot đầu tiên của bạn", + accountCreated: "Bạn đã vào! Đã tạo tài khoản ✓", + identityYours: "Danh tính là của bạn — lưu trong khóa của bạn, không phải trên máy chủ của chúng tôi.", + whereSkate: "Bạn trượt ở đâu?", + whereSkateDesc: "Đặt khu vực nhà một lần và bản đồ mở trên Spot của bạn mỗi lần. GPS của bạn không bao giờ rời khỏi thiết bị.", + useMyLocation: "Dùng vị trí của tôi", + pickOnMap: "Chọn trên bản đồ", + loginSaved: "Đã lưu thông tin đăng nhập — tài khoản của bạn an toàn để khôi phục.", + whyBother: "Tại sao phải bận tâm?", + why1Title: "Mọi Spot, một bản đồ", + why1Body: "Ledge, rail, DIY, công viên — được lập bản đồ bởi những skater thực sự trượt chúng. Kiểm tra trạng thái trước khi lăn bánh để không phí một buổi trượt vì bị đuổi.", + why2Title: "Do skater xây, không phải do doanh nghiệp", + why2Body: "Không quảng cáo, không thuật toán nhồi nhét rác vào mặt bạn, không thu thập dữ liệu. Mã nguồn mở. Bản đồ thuộc về cộng đồng — kể cả bạn.", + why3Title: "Được trả tiền để thể hiện", + why3Body: "Lập bản đồ một viên ngọc, quay một pha đỉnh, tổ chức một buổi trượt — và nhận zap Bitcoin thật thẳng vào ví. Không cắt phế nền tảng, không trung gian.", + why4Title: "Tài khoản của bạn thực sự là của bạn", + why4Body: "Một khóa đăng nhập bạn vào mọi ứng dụng Nostr. Không công ty nào khóa bạn ra ngoài hay xóa tài khoản tùy hứng. Mang danh tính đi khắp nơi.", + everythingFree: "Mọi thứ bạn có thể làm — miễn phí", + featSpots: "Khám phá Spot", + featSpotsDesc: "Bản đồ tương tác với hàng nghìn Spot trên toàn thế giới", + featLab: "The Lab", + featLabDesc: "Tìm huấn luyện viên, quay phim & dựng video gần bạn", + featEvents: "Sự kiện", + featEventsDesc: "Cuộc thi, buổi trượt, gặp gỡ", + featGear: "Mua / Bán Gear", + featGearDesc: "Chợ ngang hàng cho Gear trượt ván đã qua sử dụng", + featStash: "Stash của tôi", + featStashDesc: "Kho mã hóa riêng tư của mọi thứ bạn sở hữu", + featCrews: "Crew", + featCrewsDesc: "Lăn cùng Crew của bạn — Spot chia sẻ, trò chuyện & buổi trượt", + whatIsNostr: "Nostr là gì?", + whatIsNostrSub: "Giao thức vận hành SkateSpots", + nostrBefore: "Nostr là một giao thức mở — như email, nhưng cho ứng dụng xã hội. Tài khoản của bạn là một", + cryptoKeyPair: "cặp khóa mật mã", + nostrAfter: "mà bạn sở hữu. Không công ty nào kiểm soát tài khoản hay dữ liệu của bạn — bạn chọn Relay nào lưu nó, và bạn thậm chí có thể tự chạy một cái. Danh tính của bạn hoạt động trên mọi ứng dụng Nostr.", + nostrPoint1: "Bạn sở hữu dữ liệu & khóa của mình", + nostrPoint2: "Không công ty nào cấm được bạn", + nostrPoint3: "Danh tính hoạt động ở mọi nơi", + nostrPoint4: "Tip Bitcoin trực tiếp", + deepDive: "Tìm hiểu sâu: Nostr hoạt động thế nào", + privacyTip: "Mẹo riêng tư: GPS của bạn không bao giờ rời khỏi thiết bị. Các máy chủ bạn kết nối (như map tile) vẫn có thể thấy IP của bạn — nếu muốn ẩn cả điều đó, VPN hoặc Tor đều được. Hoàn toàn tùy chọn.", + readPrivacy: "Đọc trang riêng tư của chúng tôi", + zapsWallet: "⚡ Zap & Ví", + optional: "Tùy chọn", + walletDesc: "Zap là tip Bitcoin bạn gửi trực tiếp cho một skater đã đăng một Spot ngầu, quay một clip đỉnh, hoặc tổ chức một buổi trượt tuyệt vời. Không phí nền tảng. Không trung gian. 100% thuộc về họ.", + builtInWallet: "Ví Cashu tích hợp", + builtInWalletDesc: "Nhận thanh toán Lightning ngay trong ứng dụng. Không cần thiết lập.", + balance: "Số dư", + connectExternal: "Kết nối ví bên ngoài", + connectExternalDesc: "Có Alby, Mutiny hay ví khác? Kết nối nó qua NWC.", + connectViaNwc: "Kết nối qua NWC", + loginToConnect: "Đăng nhập để kết nối ví của riêng bạn.", + fiveDollars: "💡 $5 Bitcoin = hàng trăm zap để lan tỏa khắp cộng đồng", + commonQuestions: "Câu hỏi thường gặp", + faq1Q: "SkateSpots có miễn phí không?", + faq1A: "Miễn phí 100%. Duyệt Spot, thêm vị trí, tìm huấn luyện viên, tạo sự kiện, tham gia buổi trượt — tất cả miễn phí, mãi mãi. Bitcoin (zap) là tùy chọn nếu bạn muốn tip người sáng tạo.", + faq2Q: "Nostr là gì và tại sao SkateSpots dùng nó?", + faq2Before: "Nostr là một giao thức mở cho ứng dụng phi tập trung — hãy nghĩ về nó như chính internet, không thuộc sở hữu của công ty nào. Tài khoản SkateSpots của bạn là một cặp khóa mật mã mà", + faq2Strong: "bạn sở hữu", + faq2After: ". Không công ty nào cấm được tài khoản hay giữ dữ liệu của bạn làm con tin — bạn chọn Relay nào lưu dữ liệu, và bạn thậm chí có thể tự chạy một cái. Danh tính của bạn cũng hoạt động trên các ứng dụng Nostr khác như Primal, Damus hay Amethyst.", + faq3Q: "nsec là gì và tại sao nó quan trọng?", + faq3Before: "Của bạn", + faq3Mid: "là khóa riêng — bằng chứng duy nhất rằng bạn sở hữu tài khoản. Không giống mật khẩu, ở đây", + faq3Strong: "không có \"quên mật khẩu\"", + faq3After: ". Nếu mất nsec, tài khoản của bạn mất vĩnh viễn. Khi tạo tài khoản, hãy tải bản sao của bạn ngay và cất ở nơi an toàn (trình quản lý mật khẩu, viết ra ngoài giấy).", + faq4Q: "Signer / ứng dụng nào hoạt động với SkateSpots?", + faq4Desktop: "Trên máy tính để bàn:", + faq4Extensions: "tiện ích mở rộng trình duyệt.", + faq4Android: "Trên Android:", + faq4AndroidAfter: "(trải nghiệm tốt nhất với ứng dụng gốc).", + faq4Ios: "Trên iOS:", + faq4IosAfter: "hoặc dán nsec trực tiếp (kém an toàn hơn).", + faq4Note: "Bạn cũng có thể đăng nhập bằng cách dán nsec trực tiếp — nhưng dùng tiện ích signer an toàn hơn.", + faq5Q: "Tôi có thể dùng SkateSpots trên điện thoại không?", + faq5Before: "Có! SkateSpots là một PWA (Progressive Web App). Truy cập", + faq5Mid: "trong trình duyệt điện thoại và nhấn", + faq5Em: "\"Thêm vào màn hình chính\"", + faq5After: "để có trải nghiệm ứng dụng đầy đủ. Hoặc tải nó từ", + faq5End: "— một cửa hàng ứng dụng phi tập trung.", + faq6Q: "zap là gì?", + faq6A: "Zap là một tip Bitcoin tức thì gửi qua Lightning Network. Khi bạn zap một skater, sats vào ví của họ trong vài giây — không PayPal, không Venmo, không cắt phế. Người đã quay pha 4-stair đó được người hâm mộ trả tiền trực tiếp.", + faq7Q: "Spot của tôi có bị xóa nếu SkateSpots đóng cửa không?", + faq7A: "Không. Spot của bạn được công bố lên các Relay Nostr — những máy chủ phân tán mà ai cũng có thể chạy. Kể cả nếu SkateSpots với tư cách sản phẩm biến mất vào ngày mai, dữ liệu của bạn vẫn tồn tại trên các Relay và bất kỳ client Nostr nào cũng có thể hiển thị nó.", + faq8Q: "Tôi có thể thêm Spot nằm trên đất tư nhân không?", + faq8A: "Bạn có thể, nhưng hãy dùng lẽ thường. Spot trên đất tư nhân nên được đánh dấu phù hợp để skater biết tình hình. SkateSpots không chịu trách nhiệm cho việc xâm phạm — luôn tôn trọng chủ sở hữu và người địa phương.", + faq9Q: "Làm sao để báo lỗi hoặc góp ý?", + faq9Before: "Nhắn trực tiếp cho đội SkateSpots trên Nostr, hoặc liên hệ điều phối viên beta của chúng tôi:", + faq9Link: "Phản hồi beta → cordn.net", + readyToShred: "SẴN SÀNG XÉ GIÓ?", + stopScrolling: "Ngừng lướt. Tải ứng dụng. Tìm một Spot. Trượt nó.", + exploreSpots: "Khám phá Spot", + betaFeedbackTitle: "Beta — Chúng tôi muốn phản hồi của bạn", + betaFeedbackDesc: "SkateSpots đang được phát triển tích cực. Bạn có thể gặp những chỗ chưa mượt — đó là lỗi của chúng tôi, không phải của bạn. Báo lỗi, gợi ý tính năng, nói cho chúng tôi biết điều gì chưa ổn.", + betaCoordinator: "Điều phối viên Beta", + betaCoordinatorDesc: "cordn.net → nhắn cho chúng tôi", + dmOnNostr: "DM trên Nostr", + fixSameDay: "Tìm thấy lỗi? Chúng tôi sửa trong cùng ngày. Báo cáo của bạn làm ứng dụng tốt hơn cho mọi skater.", + relaySetup: "Thiết lập Relay" + }, + relayEdu: { + understandingNostr: "Hiểu về Nostr", + stepOf: "Bước {{current}} / {{total}}", + step1Title: "Hiểu về Relay", + step1Desc: "Hãy nghĩ về Relay như những Shop trượt ván chia sẻ tin tức về Spot", + you: "Bạn", + relays: "Relay", + skaters: "Skater", + s1Good1: "Không công ty nào sở hữu tài khoản của bạn", + s1Good1Desc: "Danh tính của bạn sống trên nhiều máy chủ Relay", + s1Good2: "Bạn kiểm soát nơi dữ liệu của mình sống", + s1Good2Desc: "Bài đăng của bạn đồng bộ trên các Relay bạn chọn — chọn của riêng bạn, hoặc tự chạy một cái", + s1Warn: "Người vận hành Relay có thể thấy bài đăng công khai", + s1WarnDesc: "Hãy nghĩ về nó như đăng trên bảng tin", + step2Title: "Công khai và Riêng tư", + step2Desc: "Biết điều gì hiển thị và điều gì được mã hóa", + publicTitle: "Công khai (ai cũng thấy)", + pub1: "Spot bạn thêm lên bản đồ", + pub2: "Đánh giá và bình luận", + pub3: "Thông tin hồ sơ của bạn (tên, ảnh)", + pub4: "Người bạn theo dõi", + privateTitle: "Riêng tư (mã hóa)", + priv1: "Tin nhắn trực tiếp", + priv2: "Liên lạc ví", + noteStrong: "Lưu ý:", + note: "Bài đăng có thể được lưu vĩnh viễn trên Relay. Hãy nghĩ trước khi đăng - giống như đời thực!", + step3Title: "Khóa của bạn = Tài khoản của bạn", + step3Desc: "Đây là điều quan trọng nhất cần hiểu", + secretKeyTitle: "Khóa bí mật của bạn (nsec)", + secretKeyDesc: "Hãy nghĩ về nó như ván trượt của bạn - không bao giờ cho ai mượn. Nó chứng minh bạn sở hữu tài khoản.", + s3Bad1: "Nếu mất, tài khoản của bạn không thể khôi phục", + s3Bad2: "Không có \"quên mật khẩu\" - không ai đặt lại được", + s3Good: "Sao lưu và cất ở nơi an toàn", + publicKeyTitle: "Khóa công khai của bạn (npub)", + publicKeyDesc: "Cái này giống tên người dùng của bạn - chia sẻ thoải mái để người khác tìm thấy bạn!", + inControl: "🔐 Bạn nắm quyền - không công ty nào khóa bạn ra ngoài được!", + skip: "Bỏ qua", + gotIt: "Hiểu rồi!" + }, + about: { + seoTitle: "Giới thiệu - SkateSpots", + seoDescription: "Tìm hiểu về SkateSpots và sứ mệnh xây dựng cộng đồng trượt ván phi tập trung.", + npubCopied: "Đã sao chép npub vào clipboard. Dán nó vào client Nostr yêu thích của bạn để gửi DM.", + bugReport: "🐛 Báo lỗi", + bugWhatHappened: "Điều gì đã xảy ra:", + bugExpected: "Điều tôi mong đợi:", + bugSteps: "Các bước tái hiện:", + aboutWord: "GIỚI THIỆU", + heroBefore: "Kết nối với các cảnh trượt ván địa phương trên toàn thế giới.", + skaterOwned: "Dữ liệu do skater sở hữu", + heroAfter: ", các Relay do cộng đồng vận hành.", + viewStats: "Xem Thống kê cộng đồng", + missionTitle: "Sứ mệnh của chúng tôi", + mission1: "SkateSpots giúp người trượt ván khám phá Spot, kết nối với chuyên gia tại The Lab, và tổ chức buổi trượt - tất cả mà không có sự kiểm soát của doanh nghiệp. Việc trượt thật diễn ra ngoài đời, công cụ này chỉ kết nối bạn với nó.", + mission2: "Kiến thức trượt ván nên sống cùng cộng đồng, không bị khóa trong các ứng dụng doanh nghiệp. Đó là lý do SkateSpots chạy trên Nostr - một hệ thống dựa trên Relay nơi skater kiểm soát dữ liệu của chính mình, chọn Relay nào lưu nó, và thậm chí có thể tự chạy một cái. Không công ty nào sở hữu bản đồ.", + whyNostr: "Tại sao là Nostr?", + why1Title: "Cộng đồng kiểm soát", + why1Desc: "Spot của bạn sống trên các Relay cộng đồng. Skater vận hành máy chủ, không phải tập đoàn.", + why2Title: "Bạn sở hữu dữ liệu của mình", + why2Desc: "Danh tính Nostr của bạn là của bạn. Mang nó đến bất kỳ ứng dụng Nostr nào - không bị trói buộc.", + why3Title: "Tích hợp Bitcoin", + why3Desc: "Zap trực tiếp cho người sáng tạo bằng Bitcoin. Không nền tảng nào lấy 30%.", + why4Title: "Mã nguồn mở", + why4Desc: "Được xây dựng công khai. Ai cũng có thể đóng góp hoặc fork mã nguồn.", + getInvolved: "Tham gia", + getInvolvedDesc: "SkateSpots là mã nguồn mở và do cộng đồng dẫn dắt. Đóng góp mã, chia sẻ Spot, hoặc giúp người khác bắt đầu.", + betaTitle: "Thử nghiệm Beta", + betaDesc: "Bạn thân mến! Cảm ơn bạn đã thử nghiệm SkateSpots. Xin lưu ý ứng dụng vẫn đang trong giai đoạn beta, và có thể có lỗi hoặc vấn đề bảo mật. Nếu gặp bất kỳ vấn đề gì hoặc muốn báo lỗi/sự cố, hãy liên hệ!", + giveFeedback: "Gửi phản hồi cho chúng tôi:", + copyNpub: "Sao chép npub", + reportBug: "Báo lỗi", + viewProfile: "Xem hồ sơ", + downloadApp: "Tải ứng dụng", + downloadAppDesc: "Cài SkateSpots trên Android qua Zapstore — cửa hàng ứng dụng mã nguồn mở, bản địa Bitcoin.", + getOnZapstore: "Tải trên Zapstore", + credits: "Ghi công", + creditPoweredBy: "Vận hành bởi", + creditNostr: "Giao thức phi tập trung", + creditCrewChat: "Trò chuyện Crew qua", + creditCordn: "Trò chuyện nhóm mã hóa đầu-cuối", + creditEcash: "Ecash qua", + creditCashu: "Ecash Chaumian cho Lightning", + creditWalletConnect: "Kết nối ví qua", + creditNwc: "Nostr Wallet Connect (NIP-47)", + creditSigning: "Ký trên Android bằng", + creditAmber: "Signer Nostr cho Android", + creditMapData: "Dữ liệu bản đồ Bitcoin từ", + creditBtcmap: "Những nơi chấp nhận Bitcoin", + creditCrowdfunding: "Gây quỹ cộng đồng", + creditAngor: "Gây quỹ Bitcoin phi tập trung", + creditDistributed: "Phân phối trên", + creditZapstore: "Cửa hàng ứng dụng mã nguồn mở", + creditTrust: "Tin cậy & trò chuyện Crew qua", + creditContextvm: "Điểm tin cậy Relatr & điều phối trò chuyện Crew mã hóa", + stillQuestions: "Vẫn còn thắc mắc?", + stillQuestionsDesc: "Sasquatch là hướng dẫn viên AI của chúng tôi — vận hành bằng dữ liệu SkateSpots trực tiếp. Hỏi anh ấy về Spot, sự kiện, huấn luyện viên, Gear, hoặc cách mọi thứ hoạt động.", + askSasquatch: "Hỏi The Sasquatch", + poweredBy: "Vận hành bởi", + decentralized: "Phi tập trung", + communityOwned: "Cộng đồng sở hữu" + }, + faq: { + seoTitle: "FAQ - SkateSpots", + seoDescription: "Hỏi The Sasquatch bất cứ điều gì về SkateSpots.", + greeting: "Chào! Tôi là The Sasquatch 🦧 — hỏi tôi bất cứ điều gì về SkateSpots. Spot, sự kiện, Gear, ví, quyền riêng tư, Nostr — tôi lo được hết. Bạn muốn biết gì?", + gotQuestions: "Có thắc mắc?", + heroDesc: "Hỏi The Sasquatch — anh ấy biết mọi thứ về SkateSpots, Nostr, Bitcoin và trượt ván.", + askTitle: "Hỏi The Sasquatch", + askDesc: "The Sasquatch đang mở ở góc dưới bên trái màn hình — chỉ cần nhấp vào và gõ câu hỏi. Anh ấy có quyền truy cập trực tiếp vào Spot, sự kiện, huấn luyện viên và thời tiết.", + askQuestion: "Bạn có thể giúp tôi gì trên SkateSpots?", + openSasquatch: "Mở The Sasquatch", + commonQuestions: "Câu hỏi thường gặp — nhấn để hỏi", + quickAnswers: "Câu trả lời nhanh", + footerHint: "The Sasquatch dùng dữ liệu Nostr trực tiếp từ Relay SkateSpots + AI để trả lời câu hỏi của bạn. 🛹", + chip1Label: "SkateSpots là gì?", + chip1Q: "SkateSpots là gì và nó hoạt động thế nào?", + chip2Label: "Làm sao để thêm Spot?", + chip2Q: "Làm sao để thêm một Spot trượt ván lên bản đồ?", + chip3Label: "Zap là gì?", + chip3Q: "Zap là gì?", + chip4Label: "Có miễn phí không?", + chip4Q: "SkateSpots có miễn phí sử dụng không?", + chip5Label: "Stash của tôi là gì?", + chip5Q: "Stash của tôi là gì?", + chip6Label: "Làm sao để đăng nhập?", + chip6Q: "Làm sao để đăng nhập hoặc tạo tài khoản?", + chip7Label: "Nostr là gì?", + chip7Q: "Nostr là gì?", + chip8Label: "Quyền riêng tư & Dữ liệu", + chip8Q: "Dữ liệu nào công khai và dữ liệu nào riêng tư trên SkateSpots?", + chip9Label: "Làm sao để bán Gear?", + chip9Q: "Làm sao để bán Gear trên SkateSpots?", + chip10Label: "The Lab là gì?", + chip10Q: "The Lab là gì?", + fact1Label: "Spot trượt ván toàn cầu", + fact1Value: "Khám phá & thêm", + fact2Label: "Zap Bitcoin Lightning", + fact2Value: "Miễn phí 100%", + fact3Label: "Phi tập trung trên Nostr", + fact3Value: "Bạn sở hữu dữ liệu", + fact4Label: "Kho Gear riêng tư", + fact4Value: "Stash mã hóa", + s1Q: "SkateSpots là gì?", + s1A: "Một bản đồ và cộng đồng phi tập trung cho trượt ván, xây trên Nostr. Khám phá Spot, tìm huấn luyện viên và quay phim, tham gia Crew, đăng sự kiện, và mua/bán Gear — không có công ty nào ở giữa.", + s2Q: "Làm sao để thêm Spot?", + s2A: "Nhấn vào bản đồ, hoặc dùng nút + / \"Thêm Spot\", rồi thả một ghim và điền thông tin chi tiết. Bạn cần một tài khoản Nostr miễn phí (nhấn Đăng nhập → Tạo tài khoản — không cần email).", + s3Q: "Zap là gì?", + s3A: "Zap là tip Bitcoin Lightning. Bạn có thể zap Spot, sự kiện, Crew và những người bạn trân trọng. Chúng đi thẳng đến người nhận qua Lightning — SkateSpots không bao giờ giữ tiền của bạn.", + s4Q: "Có miễn phí không?", + s4A: "Có. Tạo tài khoản, thêm Spot và duyệt đều miễn phí. Các tiện ích trả phí tùy chọn (như tin đăng nổi bật) và tip (zap) được trả trực tiếp giữa mọi người.", + s5Q: "Dữ liệu nào công khai?", + s5A: "Bất cứ thứ gì bạn công bố — Spot, sự kiện, hồ sơ của bạn — đều công khai trên các Relay Nostr. Tin nhắn riêng và Stash của bạn được mã hóa đầu-cuối. Xem trang Quyền riêng tư để biết chi tiết.", + s6Q: "The Lab là gì?", + s6A: "The Lab là nơi bạn tìm người để thuê hoặc học hỏi: huấn luyện viên, người đào tạo, quay phim, dựng video, nhiếp ảnh gia, thợ xây, nghệ sĩ và hơn thế nữa." + }, + privacy: { + seoTitle: "Quyền riêng tư — SkateSpots", + seoDescription: "Cách SkateSpots xử lý dữ liệu của bạn: GPS ở lại trên thiết bị, Spot bạn công bố là công khai, và cách ẩn IP bằng VPN hoặc Tor nếu bạn muốn.", + heroBefore: "Quyền", + heroHighlight: "riêng tư của bạn", + heroDesc: "Không theo dõi, không quảng cáo, không bán dữ liệu. Đây chính xác là những gì ở lại trên thiết bị, những gì công khai, và cách khóa chặt hơn nếu bạn muốn.", + locationTitle: "Vị trí của bạn ở lại trên thiết bị", + locationBefore: "Khi bạn nhấn", + nearMe: "\"Gần tôi,\"", + locationAfter: "vị trí GPS của bạn được đọc trên thiết bị và chỉ dùng để căn giữa bản đồ và sắp xếp các Spot gần đó.", + locationGood1: "Nó không bao giờ được công bố lên Nostr.", + locationGood2: "Nó không bao giờ được gửi đến SkateSpots — không có máy chủ SkateSpots nào thu thập nó.", + locationGood3: "Nó không bao giờ được chia sẻ với bất kỳ bên thứ ba nào.", + locationGood4: "Trên ứng dụng gốc, chúng tôi dùng trực tiếp hệ thống vị trí của điện thoại và bỏ qua Google Play Services — nên nó hoạt động trên điện thoại đã gỡ Google (GrapheneOS, /e/OS) và Google không bao giờ thấy nó.", + weatherBefore: "Thời tiết mặc định tắt. Khi bạn bật, nó tra cứu điều kiện cho", + weatherEm: "vị trí", + weatherAfter: "công khai của Spot — không phải của bạn.", + publicTitle: "Những gì công khai theo thiết kế", + publicDesc: "SkateSpots là một bản đồ chia sẻ, nên một số thứ được thiết kế để mọi người thấy. Khi bạn chọn công bố chúng, chúng công khai trên mạng Nostr:", + public1Strong: "Spot bạn thêm", + public1: "— bao gồm tọa độ của chúng. Nếu bạn thêm Spot tại vị trí chính xác của mình, vị trí đó trở thành công khai. Hãy nghĩ trước khi thả ghim ngay trên sân nhà bạn.", + public2Strong: "Đánh giá, bình luận và hồ sơ công khai của bạn", + public2: "(tên, ảnh).", + public3: "Người bạn theo dõi, và các cảm xúc công khai.", + public4Strong: "Zap", + public4: "mặc định công khai: một zap gắn tài khoản của bạn — thường là địa chỉ Lightning của bạn — với bài đăng bạn đã trả và với chính khoản tip. Ví của bạn có thể gửi ẩn danh nếu bạn không muốn điều đó.", + publicNoteBefore: "VPN hoặc Tor", + notWord: "không", + publicNoteAfter: "ẩn nội dung bạn công bố — tọa độ của một Spot là công khai bất kể thế nào. Công cụ riêng tư ẩn danh tính mạng của bạn (IP), không ẩn những gì bạn chọn đăng.", + encryptedTitle: "Những gì riêng tư & mã hóa", + enc1Strong: "Tin nhắn trực tiếp", + enc1Mid: "và", + enc1Strong2: "trò chuyện Crew", + enc1: "được mã hóa đầu-cuối (NIP-17). Chỉ những người tham gia đọc được.", + enc2Strong: "Stash của tôi", + enc2: "— kho Gear riêng tư của bạn — được mã hóa bằng khóa của chính bạn.", + enc3Strong: "Thành viên chỉ trong Crew", + enc3: "có thể chọn chỉ hiển thị với bạn cùng Crew.", + ipTitle: "Những gì rời khỏi thiết bị: IP của bạn", + ipBefore: "Như mọi trang web, các máy chủ SkateSpots liên lạc có thể thấy", + ipAddress: "địa chỉ IP", + ipAfter: "(một chỉ báo thô về khu vực của bạn). Điều này bình thường với mọi ứng dụng web hay bản đồ và không riêng gì chúng tôi. Các máy chủ đó là:", + ipTileStrong: "Map tile", + ipTile: "(OpenStreetMap) — thấy IP của bạn và khu vực bản đồ bạn xem.", + ipGeoStrong: "Geocode Spot/Shop", + ipGeo: "— khi bạn tạo hoặc chỉnh sửa Spot hay Shop, tọa độ của nó được gửi đến OpenStreetMap Nominatim để điền thẻ thành phố/quốc gia. Khi bạn mở Thống kê cộng đồng, tọa độ của các ghim không có thẻ vị trí được gửi đến BigDataCloud để nhóm theo vùng (được lưu trên thiết bị của bạn — tối đa một lần mỗi ghim). Cả hai đều thấy IP của bạn. Đây là ghim bạn đặt / tọa độ ghim công khai, không bao giờ là GPS trực tiếp của thiết bị bạn.", + ipPushStrong: "Thông báo nền", + ipPush: "(tùy chọn) — nếu bạn bật chúng, máy chủ push SkateSpots thấy rằng khóa của bạn đã nhận gì đó và khi nào (không bao giờ thấy ai gửi hay nội dung gì — tin nhắn vẫn mã hóa), và dịch vụ push của HĐH (Google/Mozilla/Apple) gửi cảnh báo.", + ipBtcStrong: "Địa điểm Bitcoin", + ipBtc: "(BTCMap, khi bạn bật lớp đó) — thấy IP của bạn và khu vực bạn đang xem.", + ipRelayStrong: "Relay Nostr", + ipRelay: "— thấy IP của bạn khi ứng dụng đọc hoặc công bố.", + ipMintStrong: "Mint Cashu", + ipMint: "— thấy IP của bạn mỗi khi ví gửi, nhận hoặc melt.", + ipRouteStrong: "Chỉ đường", + ipRoute: "(OSRM, và Transitous cho giao thông công cộng) — nhận điểm đầu và điểm cuối của bất kỳ lộ trình nào bạn yêu cầu, không chỉ IP của bạn. Việc định tuyến ở trong ứng dụng: điểm đầu và điểm đến của bạn không bao giờ được chuyển cho Google hay Apple Maps.", + ipWeatherStrong: "Thời tiết", + ipWeatherMid: "(Open-Meteo, tùy chọn) và", + ipUploadStrong: "tải ảnh lên", + ipWeather: "(Blossom), khi bạn dùng chúng.", + ipAiStrong: "AI Sasquatch", + ipAi: "— tin nhắn của bạn đi đến máy chủ của chúng tôi, rồi đến nhà cung cấp mô hình.", + ipLink1: "Vì bạn gửi khóa công khai (npub) trên cùng kết nối, một Relay có thể liên kết IP với bạn — không chỉ \"ai đó đã kết nối\", mà là \"người này, từ địa chỉ này\".", + ipShieldBefore: "Một điều chúng tôi che chắn:", + ipMintsStrong: "danh mục mint", + ipShieldAfter: "được tải qua máy chủ của chúng tôi, nên MintRadar không bao giờ thấy IP của bạn.", + vpnTitle: "Muốn riêng tư hơn? VPN hoặc Tor (tùy chọn)", + vpnDesc: "Với hầu hết skater điều này không cần thiết — nhưng nếu bạn muốn ẩn IP và vị trí tương đối khỏi các máy chủ trên, bạn có hai lựa chọn miễn phí:", + vpnReputable: "🛡️ Một VPN đáng tin cậy", + vpnReputableDesc: "Ẩn IP của bạn sau máy chủ VPN. Dễ và nhanh. Dùng một cái bạn trả tiền và tin tưởng; VPN miễn phí thường kiếm tiền từ lưu lượng của bạn, nên hãy coi \"miễn phí\" là dấu hiệu cảnh báo.", + torBrowser: "🧅 Trình duyệt Tor", + torDesc: "Miễn phí, riêng tư IP tối đa, định tuyến qua nhiều Relay. Chậm hơn — bản đồ và một số Relay Nostr có thể bị trễ hoặc chặn node thoát Tor. Tuyệt vời cho người cực kỳ cẩn trọng.", + readThis: "Đọc điều này để không bị lừa", + caveat1Before: "VPN/Tor ẩn", + ipWord: "IP", + caveat1: "của bạn — không ẩn Spot bạn công bố. Một ghim tại nhà bạn là công khai dù bạn có dùng VPN hay không.", + caveat2Before: "Đừng bật", + nearMeGps: "\"Gần tôi\" / GPS trình duyệt", + caveat2: "nếu mục tiêu của bạn là ẩn danh — GPS chính xác vượt qua mọi việc ẩn IP.", + caveat3: "Không công cụ nào khiến bạn hoàn toàn \"ẩn danh.\" Những thứ này giảm bớt điều máy chủ có thể suy ra về vị trí mạng của bạn — chỉ vậy thôi.", + keysTitle: "Khóa của bạn, tài khoản của bạn", + keysBefore: "Tài khoản của bạn là một cặp khóa mật mã bạn sở hữu. Cách đăng nhập an toàn nhất là một", + signer: "signer", + keysAfter: "(Alby, nos2x, hoặc Amber trên Android) để khóa bí mật của bạn không bao giờ bị dán vào ứng dụng.", + keysCaveatBefore: "Nếu bạn dán", + keysCaveatAfter: "trực tiếp, nó được lưu trong trình duyệt của bạn. Hãy dùng tiện ích signer khi có thể, và giữ bản sao nsec ở nơi an toàn ngoại tuyến.", + footerBefore: "Thắc mắc? Hỏi", + sasquatchName: "The Sasquatch", + footerMid: "trong ứng dụng, hoặc đọc", + gettingStarted: "hướng dẫn bắt đầu", + about: "Giới thiệu" + }, + license: { + seoTitle: "Giấy phép - SkateSpots", + seoDescription: "Giấy phép SkateSpots. Bạn được tự do trượt ván.", + tagline: "Trượt, kiếm, vui vẻ và tiêu Sats ở bất cứ đâu bạn đến.", + copyright: "Những người đóng góp SkateSpots & cộng đồng", + licenseLabel: "Giấy phép", + freeLine1: "BẠN ĐƯỢC TỰ DO", + freeLine2: "TRƯỢT VÁN", + body: "Dự án này mở. Chia sẻ nó, fork nó, xây trên nó, trượt nó. Đường phố thuộc về mọi người. Mã này cũng vậy. Tiếp tục trượt, vui vẻ, học trick, ủng hộ những người xây dựng và trượt tiếp lần nữa.", + builtBefore: "Xây bằng ❤️ trên", + builtMid: "· Vận hành bởi", + lightning: "Bitcoin Lightning ⚡", + viewSource: "Xem mã nguồn", + aboutSkateSpots: "Giới thiệu SkateSpots", + supporters: "Người ủng hộ" + }, + glossary: { + seoTitle: "Từ điển Trick · SkateSpots", + seoDescription: "Từ điển trượt ván đầy đủ — {{count}} mục bao gồm flip, grind, slide, grab, air, lip trick, handplant, freestyle, thuật ngữ transition, stance & dụng cụ, cùng các tên gọi khác.", + heading: "TỪ ĐIỂN TRICK", + subheading: "{{count}} mục · trick, transition, freestyle, stance & dụng cụ", + searchPlaceholder: "Tìm trick hoặc biệt danh — tre flip, crooks, method…", + clearSearch: "Xóa tìm kiếm", + all: "Tất cả", + results: "{{count}} kết quả{{s}} cho", + noMatch: "Không có trick nào khớp. Thử biệt danh như “tre flip”, “crooks”, hoặc “melon”.", + tricksCount: "{{count}} trick", + footerBefore: "Biết một trick hay biệt danh mà chúng tôi bỏ sót? Trick có tên khác nhau ở mỗi cảnh — hãy nhắn", + sasquatch: "The Sasquatch 🦧", + footerAfter: "và cho chúng tôi biết." + }, + signers: { + seoTitle: "Ứng dụng Signer - Bảo vệ khóa Nostr của bạn | SkateSpots", + seoDescription: "Tìm hiểu về các ứng dụng signer giúp giữ khóa Nostr an toàn. Tìm lựa chọn tốt nhất cho Android, iOS hoặc trình duyệt máy tính.", + securityGuide: "Hướng dẫn bảo mật", + protect: "Bảo vệ", + nostrKeys: "Khóa Nostr", + heroDesc: "Ứng dụng signer giữ khóa riêng an toàn bằng cách ký sự kiện mà không để lộ chúng. Thay vì dán khóa vào mọi ứng dụng, hãy để signer xử lý an toàn.", + whySignerStrong: "Tại sao dùng signer?", + whySigner: "Khóa riêng Nostr của bạn giống như một mật khẩu không bao giờ đổi được. Ứng dụng signer giữ nó an toàn đồng thời cho phép bạn dùng bất kỳ ứng dụng Nostr nào.", + androidTitle: "Signer Android", + androidDesc: "Ứng dụng signer gốc cho thiết bị Android, bao gồm GrapheneOS.", + iosTitle: "Signer iOS", + iosDesc: "Các lựa chọn signer cho người dùng iPhone và iPad.", + browserTitle: "Tiện ích mở rộng trình duyệt", + browserDesc: "Tiện ích mở rộng trình duyệt máy tính để ký trên ứng dụng web.", + recommended: "Đề xuất", + yourPlatform: "Nền tảng của bạn", + get: "Tải {{name}}", + protocolsTitle: "Hiểu về giao thức", + nip07Desc: "Tiêu chuẩn tiện ích mở rộng trình duyệt. Tiện ích đưa khả năng ký vào ứng dụng web. Được Alby, nos2x, Flamingo và các tiện ích tương tự sử dụng.", + nip46Desc: "Giao thức ký từ xa (\"bunker\"). Ứng dụng signer của bạn phê duyệt yêu cầu từ ứng dụng khác mà không chia sẻ khóa. Được Nsec.app, Nostria và Nowser sử dụng.", + nip55Desc: "Giao thức signer riêng cho Android. Ứng dụng gốc có thể yêu cầu chữ ký từ Amber mà không để lộ khóa. Trải nghiệm Android liền mạch nhất.", + whichChoose: "Chọn cái nào?", + chooseAndroid: "Android:", + chooseAndroidDesc: "Amber (NIP-55) cho ứng dụng gốc", + chooseIos: "iOS:", + chooseIosDesc: "Nsec.app (NIP-46) để tương thích tốt nhất", + chooseDesktop: "Máy tính để bàn:", + chooseDesktopDesc: "Alby, nos2x, hoặc Flamingo (NIP-07)", + amberDesc: "Signer Android gốc tập trung vào bảo mật và dễ sử dụng. Lựa chọn tốt nhất cho người dùng Android.", + nsecAppDesc: "Signer từ xa đa nền tảng hoạt động như một kho an toàn cho khóa của bạn.", + nostriaDesc: "Ứng dụng signer từ xa với khóa lưu trong bộ nhớ an toàn của thiết bị.", + nowserDesc: "Signer đa xác thực hỗ trợ cả tiện ích mở rộng trình duyệt và giao thức ký từ xa.", + nsecAppIosDesc: "Lựa chọn tốt nhất cho iOS. Dùng nó như signer từ xa với bất kỳ client Nostr nào.", + nowserTfDesc: "Signer iOS có sẵn qua TestFlight với khả năng ký tương tự Android.", + nostriaIosDesc: "Signer từ xa với lưu trữ khóa an toàn trên thiết bị của bạn.", + nos2xDesc: "Tiện ích mở rộng trình duyệt đơn giản và đáng tin cậy để ký sự kiện Nostr.", + albyDesc: "Ví Bitcoin Lightning với quản lý khóa Nostr tích hợp và WebLN.", + flamingoDesc: "Tiện ích mở rộng trình duyệt tập trung vào Nostr với giao diện gọn gàng.", + kiwiDesc: "Trên Android/GrapheneOS, dùng Kiwi Browser để tải tiện ích nos2x hoặc Alby.", + fNativeApp: "Ứng dụng gốc", + fMultiKey: "Hỗ trợ nhiều khóa", + fEventSigning: "Ký sự kiện", + fSecureStorage: "Lưu trữ khóa an toàn", + fRemoteSigning: "Ký từ xa", + fAnyClient: "Hoạt động với mọi client", + fCrossDevice: "Đồng bộ đa thiết bị", + fMultiKeySupport: "Hỗ trợ nhiều khóa", + fNip07: "Hỗ trợ NIP-07", + fNip46: "Hỗ trợ NIP-46", + fFlexibleSigning: "Ký linh hoạt", + fNativeIos: "Ứng dụng iOS gốc", + fLightweight: "Nhẹ", + fEasyToUse: "Dễ sử dụng", + fChromeSupport: "Hỗ trợ Chrome/Brave/Edge", + fLightningPayments: "Thanh toán Lightning", + fNostrSigning: "Ký Nostr", + fWebln: "Hỗ trợ WebLN", + fNwc: "Hỗ trợ NWC", + fCleanUi: "Giao diện gọn gàng", + fPrivacyFocused: "Tập trung vào riêng tư", + fExtensionMobile: "Hỗ trợ tiện ích mở rộng trên di động", + fFullBrowser: "Trải nghiệm trình duyệt đầy đủ", + fGraphene: "Hoạt động trên GrapheneOS" + }, + betaDisclaimer: { + title: "Lưu ý — đây là bản beta", + subtitle: "Vài lời trước khi bạn nhập cuộc.", + ossTitle: "Mã nguồn mở & thử nghiệm", + ossBody: "Được xây công khai bởi cộng đồng. Cứ khám phá, fork nó, phá nó.", + betaTitle: "Đang beta — chưa được kiểm toán", + betaBody: "Mã chưa trải qua kiểm toán bảo mật chính thức. Lỗi vẫn xảy ra.", + moneyTitle: "Xử lý Bitcoin & Lightning thật", + moneyBody: "Dùng tiền trên đó với rủi ro của riêng bạn. Chỉ nạp số bạn có thể mất.", + finePrint: "Không bảo hành dưới bất kỳ hình thức nào. Bạn hoàn toàn chịu trách nhiệm cho tiền và khóa của mình.", + viewCode: "Xem mã nguồn", + accept: "Hiểu rồi, cho tôi vào" + }, + } +}; export default viBatch3; diff --git a/src/i18n/vi/batch4.ts b/src/i18n/vi/batch4.ts index 2793db8..3b0d86a 100644 --- a/src/i18n/vi/batch4.ts +++ b/src/i18n/vi/batch4.ts @@ -1,4 +1,1123 @@ -/** vi — batch 4. Filled by the translation pass; empty until then. */ -const viBatch4 = {}; +/** + * Vietnamese (Tiếng Việt) — batch 4: namespace walletUi (ví Bitcoin + * Lightning + Cashu, zap, ký quỹ, mint, quyền riêng tư, Stash, thống kê + * cộng đồng, bản tin và những người ủng hộ). + * + * Tên giao thức và thương hiệu (Nostr, Lightning, Cashu, Zap, Relay, NWC, + * Stash, The Lab, Angor, sats, Lightning Address) giữ nguyên tiếng Anh; tên + * các trick giữ nguyên tiếng Anh. + */ +const viBatch4 = { + walletUi: { + page: { + title: 'Ví', + subtitle: 'Bitcoin Lightning + Cashu', + manage: 'Quản lý', + getAWallet: 'Tải ví', + learnPlanB: 'Tìm hiểu thêm tại Plan B Academy', + walletMinibits: 'Cashu di động · NWC', + walletAlby: 'Tiện ích trình duyệt · WebLN + NWC', + walletZeus: 'Lightning tự quản lý khóa', + walletCoinos: 'Trên web · chạy mọi nơi', + whatAreZaps: 'Zap là gì?', + whatAreZapsShort: 'Zap là gì?', + zapsDesc: 'Thanh toán Bitcoin Lightning tức thì. Gửi sats cho bất kỳ skater, người tạo spot hay coach nào — không qua trung gian, không bị nền tảng cắt phế.', + instant: 'Tức thì', + instantDesc: 'Hoàn tất trong vài giây', + flexible: 'Linh hoạt', + flexibleDesc: 'Ví của bạn, khóa của bạn', + private: 'Riêng tư', + privateDesc: 'Cashu che giấu người trả tiền', + direct: 'Trực tiếp', + directDesc: 'Giá trị đến tay người sáng tạo', + loginRequired: 'Cần đăng nhập', + loginRequiredDesc: 'Đăng nhập bằng tài khoản Nostr để kết nối ví Lightning và bắt đầu zap.', + browseMints: 'Xem các mint Cashu', + }, + modal: { + walletName: 'Tên ví (không bắt buộc)', + walletNamePlaceholder: 'Ví Lightning của tôi', + connectionUri: 'URI kết nối', + spendLimitTitle: 'Đặt giới hạn chi tiêu trước', + spendLimitBody1: 'Chuỗi này cho phép SkateSpots thanh toán hóa đơn Lightning từ ví của bạn. Trong ứng dụng ví, hãy cấp cho kết nối này một', + dailyBudget: 'ngân sách hằng ngày', + spendLimitBody2: '(ví dụ vài nghìn sats) và chỉ bật', + spendLimitBody3: 'Tuyệt đối không dán kết nối có ngân sách không giới hạn. Bạn có thể thu hồi bất cứ lúc nào trong ví.', + addWallet: 'Thêm ví', + nwcConnection: 'Kết nối NWC', + lightningWallet: 'Ví Lightning', + pasteNwc: 'Dán chuỗi kết nối NWC để gửi zap', + connectWallet: 'Kết nối ví', + browserExtension: 'Tiện ích trình duyệt (WebLN)', + autoDetected: 'Tự phát hiện nếu đã cài', + ready: 'Sẵn sàng', + notFound: 'Không tìm thấy', + getNwcFrom: 'Lấy NWC từ:', + connectionRequired: 'Cần URI kết nối', + connectionRequiredDesc: 'Vui lòng nhập URI kết nối NWC hợp lệ.', + activeChanged: 'Đã đổi ví đang dùng', + activeChangedDesc: 'Ví được chọn giờ đang hoạt động cho zap.', + connectNwc: 'Kết nối ví NWC', + connectNwcDesc: 'Nhập chuỗi kết nối từ ví tương thích.', + connect: 'Kết nối', + connecting: 'Đang kết nối...', + walletSettings: 'Cài đặt ví', + connectDesc: 'Kết nối ví Lightning để gửi zap tức thì.', + }, + cashu: { + title: 'Ví Cashu', + desc: 'Ví ecash tích hợp — không cần thiết lập bên ngoài', + initializing: 'Đang khởi tạo ví...', + walletError: 'Lỗi ví', + balance: 'Số dư', + balanceAria: 'Số dư ví {{amount}} sats', + activeMint: 'Mint đang dùng', + selectMint: 'Chọn một mint', + receive: 'Nhận', + send: 'Gửi', + receiveViaLightning: '⚡ Nhận qua Lightning', + amountSats: 'Số tiền theo sats', + generateInvoice: 'Tạo hóa đơn', + generating: 'Đang tạo…', + or: 'Hoặc', + receiveCashu: '🥜 Nhận token Cashu', + scanQr: 'Quét QR', + pasteCashu: 'Dán token Cashu (cashu...)', + receiveToken: 'Nhận token', + receiving: 'Đang nhận…', + createCashu: '🥜 Tạo token Cashu', + createToken: 'Tạo token', + creating: 'Đang tạo…', + payInvoice: '⚡ Thanh toán hóa đơn Lightning', + pasteInvoice: 'Dán hóa đơn Lightning (lnbc...)', + payInvoiceBtn: 'Thanh toán hóa đơn', + processing: 'Đang xử lý...', + payAddress: '📧 Thanh toán Lightning Address', + sendToAddress: 'Gửi đến địa chỉ', + sending: 'Đang gửi…', + recentActivity: 'Hoạt động gần đây', + receivedLightning: 'Đã nhận ⚡ Lightning', + sentLightning: 'Đã gửi ⚡ Lightning', + sentToken: 'Đã gửi 🥜 token', + receivedToken: 'Đã nhận 🥜 token', + whatIsCashu: 'Cashu là gì?', + whatIsCashuDesc: 'Cashu là tiền kỹ thuật số được đảm bảo bằng Bitcoin Lightning. Hãy coi nó như những token Bitcoin bạn giữ trong trình duyệt.', + benefitOffline: 'Hoạt động ngoại tuyến tại các spot', + benefitInstant: 'Thanh toán ngang hàng tức thì', + benefitPrivacy: 'Tập trung vào quyền riêng tư (mint không thể theo dõi bạn)', + benefitRedeemable: 'Luôn có thể đổi lấy sats Lightning', + findMints: 'Tìm mint tại mintradar.pedani.eu', + backupTitle: 'Sao lưu ví của bạn', + backupDesc: 'Ví của bạn được bảo vệ bằng cụm 12 từ khôi phục. Hãy cất giữ an toàn — bạn sẽ cần nó để khôi phục số dư nếu xóa dữ liệu trình duyệt.', + viewRecovery: 'Xem cụm từ khôi phục', + backupNote: 'Giống như nsec Nostr của bạn — hãy giữ bí mật và sao lưu!', + tokenReceived: 'Đã nhận token', + tokenReceivedDesc: 'Đã đổi token Cashu thành công!', + receiveFailed: 'Nhận thất bại', + unknownError: 'Lỗi không xác định', + requestUnsupported: 'Chưa hỗ trợ yêu cầu Cashu', + requestUnsupportedDesc: 'Ví này chưa thể thanh toán yêu cầu Cashu (creq) — hãy yêu cầu hóa đơn hoặc địa chỉ Lightning.', + onchainUnsupported: 'Không hỗ trợ on-chain ở đây', + onchainUnsupportedDesc: 'Đó là địa chỉ Bitcoin. Ví này chỉ gửi token Cashu và thanh toán Lightning.', + nostrProfile: 'Đó là hồ sơ Nostr', + nostrProfileDesc: 'Quét token Cashu, hóa đơn Lightning hoặc Lightning Address để thanh toán.', + clinkUnsupported: 'Chưa hỗ trợ mã thanh toán', + clinkUnsupportedDesc: 'Ví này chưa thể thanh toán mã CLINK. Hãy dùng hóa đơn hoặc địa chỉ Lightning.', + unrecognizedQr: 'Mã QR không nhận diện được', + unrecognizedQrDesc: 'Quét token Cashu, hóa đơn Lightning hoặc Lightning Address.', + invalidAmount: 'Số tiền không hợp lệ', + invalidAmountDesc: 'Vui lòng nhập số tiền hợp lệ', + paymentSent: 'Đã gửi thanh toán', + paymentSentDesc: 'Đã gửi {{amount}} sats đến {{address}}', + paymentFailed: 'Thanh toán thất bại', + copied: 'Đã sao chép', + copiedDesc: 'Đã sao chép {{label}} vào clipboard', + receiveSats: 'Nhận {{amount}} sats', + payInvoiceHint: 'Thanh toán hóa đơn này từ bất kỳ ví Lightning nào', + invoiceQrAlt: 'Mã QR hóa đơn', + lightningInvoice: 'Hóa đơn Lightning', + invoiceLabel: 'Hóa đơn', + waiting: '⏳ Đang chờ thanh toán...', + tokenReady: 'Token sẵn sàng để gửi', + shareToken: 'Chia sẻ token này với người nhận', + tokenQrAlt: 'Mã QR token', + cashuToken: 'Token Cashu', + tokenLabel: 'Token', + copyToken: 'Sao chép token', + tokenWarning: 'Bất kỳ ai có token này đều có thể đổi nó - hãy coi như tiền mặt!', + browser: { + title: 'Ví ecash tích hợp', + appOnly: 'Chỉ trên ứng dụng', + desc: 'Cashu ecash tự quản lý khóa, vận hành bằng Bitcoin Lightning', + unlockTitle: 'Mở khóa ví đầy đủ trong ứng dụng SkateSpots', + unlockDesc: 'Ví ecash tích hợp cho phép bạn mint, gửi và đổi token Cashu ngay tại spot. Nó nằm trong ứng dụng gốc, nơi có thể kết nối trực tiếp với các mint — trình duyệt chặn những kết nối đó để bảo vệ bạn.', + zapTipTitle: 'Zap & tip — hoạt động ngay trên trình duyệt', + zapTipDesc: 'Gửi sats đến spot, sự kiện, coach và crew hoạt động ngay tại đây. Chỉ cần kết nối ví Lightning bên dưới — Nostr Wallet Connect hoặc tiện ích trình duyệt như Alby. Không cần mint Cashu.', + }, + }, + escrow: { + title: 'Ký quỹ', + desc: 'Bán an toàn: bật ký quỹ và người mua có thể khóa sats cho bạn để giao dịch. Bạn giải phóng khi giao hàng — nếu không, người mua có thể đòi lại sau thời gian đã thỏa thuận.', + active: 'Ký quỹ đang bật', + publish: 'Bật ký quỹ', + published: 'Ký quỹ đang bật', + publishedDesc: 'Người mua giờ có thể khóa tiền cho bạn để giao dịch.', + failed: 'Không thể bật ký quỹ', + }, + escrowSettings: { + title: 'Cài đặt ký quỹ', + desc: 'Mặc định cho giao dịch ký quỹ Cashu. Lưu trên thiết bị.', + lockWindow: 'Thời gian khóa mặc định', + lockWindowHint: 'Thời gian tiền bị khóa trước khi người mua có thể đòi lại. Càng dài càng an toàn cho người bán.', + days: 'ngày', + preferredMint: 'Mint cho ký quỹ', + activeMint: 'Mint đang dùng', + preferredMintHint: 'Mint nào tài trợ ký quỹ. Hãy dùng mint đáng tin cậy.', + requireListings: 'Bắt buộc ký quỹ cho tin đăng mới', + requireListingsHint: 'Tự động chọn “Bắt buộc ký quỹ” khi bạn đăng bán.', + }, + privacy: { + title: 'Mẹo riêng tư', + subtitle: 'Tìm hiểu cách bảo vệ quyền riêng tư tài chính của bạn', + cashuRecommended: 'CASHU (Khuyến nghị)', + anon: 'Giao dịch ẩn danh', + blind: 'Chữ ký mù che giấu hoạt động', + noIp: 'Không lộ IP', + trustMint: 'Phải tin mint giữ tiền', + lightningAddress: 'LIGHTNING ADDRESS', + linked: 'Có thể bị liên kết với danh tính', + traceable: 'Lịch sử thanh toán có thể truy vết', + ipVisible: 'Lộ IP khi tạo hóa đơn', + selfCustody: 'Có thể tự quản lý khóa', + bestPractices: 'Thực hành tốt nhất', + tip1Title: 'Dùng Cashu để nhận tip', + tip1Desc: 'Ví Cashu tích hợp là cách riêng tư nhất để nhận zap', + tip2Title: 'Dùng ví riêng cho SkateSpots', + tip2Desc: 'Đừng dùng ví tiết kiệm chính - hãy tách tiền của ứng dụng', + tip3Title: 'Cân nhắc dùng VPN hoặc Tor', + tip3Desc: 'Che giấu địa chỉ IP khi thực hiện giao dịch', + tip4Title: 'Tránh địa chỉ Lightning gắn với danh tính', + tip4Desc: 'Dùng địa chỉ ẩn danh không gắn với tên thật của bạn', + proTip: 'Mẹo hay:', + proTipDesc: 'Hãy nhận thanh toán vào ví Cashu trước, rồi định kỳ chuyển số lớn hơn sang ví cá nhân qua VPN.', + warnTitle: 'Lưu ý riêng tư', + warnDesc: 'Địa chỉ Lightning có thể liên kết hoạt động SkateSpots của bạn với danh tính thật.', + betterPrivacy: 'Để riêng tư hơn:', + bullet1: 'Dùng ví riêng cho ứng dụng này', + bullet2: 'Cân nhắc dùng ví Cashu thay thế', + bullet3: 'Dùng VPN/Tor khi giao dịch', + useCashu: 'Dùng Cashu thay thế', + understand: 'Tôi hiểu', + }, + mintPrivacy: { + title: 'Riêng tư mint', + desc: 'Dùng nhiều mint giúp tăng quyền riêng tư vì không mint nào thấy hết giao dịch của bạn', + distribution: 'Phân bổ tiền', + singleWarning: 'Chỉ dùng một mint nghĩa là mint đó thấy hết thời điểm và số tiền giao dịch của bạn. Cân nhắc thêm mint để riêng tư hơn.', + yourMints: 'Mint của bạn ({{count}})', + default: 'Mặc định', + addMint: 'Thêm mint', + addMintDesc: 'Thêm mint Cashu mới vào ví', + mintUrl: 'URL mint', + add: 'Thêm', + adding: 'Đang thêm...', + orChoose: 'Hoặc chọn từ danh sách', + recommended: 'Mint được khuyến nghị', + allMints: 'Tất cả mint (danh bạ)', + searchMints: 'Tìm mint…', + noDirectoryMints: 'Không có mint nào khớp tìm kiếm.', + directoryHint: 'Từ danh bạ MintRadar cộng đồng — không chính thức và có thể lỗi thời.', + added: 'Đã thêm', + soon: 'Sắp có', + autoDistribute: 'Tự động phân bổ tiền', + autoDesc: 'Trải tiền nhận được ra nhiều mint', + autoAria: 'Tự động phân bổ tiền (sắp ra mắt)', + tip1: 'Dùng tối thiểu 2-3 mint khác nhau để riêng tư hơn', + tip2: 'Đừng để hết tiền trong một mint - hãy trải ra', + tip3: 'Cân nhắc thẩm quyền pháp lý của mint (quốc gia khác nhau = quyền truy cập pháp lý khác nhau)', + tip4: 'Mint thấy thời điểm giao dịch nhưng KHÔNG thấy bạn trả cho ai (chữ ký mù)', + future: 'Tính năng tương lai: luân chuyển mint và chấm điểm riêng tư - hãy chờ nhé!', + findMore: 'Tìm thêm mint tại mintradar.pedani.eu', + trustWarning: 'Cảnh báo tin cậy:', + trustWarningDesc: 'Mint là dịch vụ giữ hộ - họ giữ tiền của bạn. Chỉ dùng mint bạn tin. Nếu mint biến mất, tiền của bạn có thể mất. Trải tiền ra nhiều mint giúp giảm rủi ro.', + removeTitle: 'Xóa mint?', + removeDesc: 'Bạn chắc chắn muốn xóa {{name}}?', + removeMint: 'Xóa mint', + warning: 'Cảnh báo:', + withdrawWarning: 'Mint này có {{amount}} sats. Hãy rút tiền trước khi xóa!', + invalidUrl: 'URL không hợp lệ', + invalidUrlDesc: 'URL mint phải bắt đầu bằng https://', + mintAdded: 'Đã thêm mint', + mintAddedDesc: 'Đã thêm mint mới thành công', + mintAddedNamed: 'Đã thêm {{name}} thành công', + failedAdd: 'Thêm mint thất bại', + failed: 'Thất bại', + noMints: 'Không có mint', + singleMint: 'Một mint', + concentrated: 'Tập trung', + moderate: 'Vừa phải', + wellDistributed: 'Phân bổ tốt', + mintCoinosWebDesc: 'Mint thân thiện web (khuyến nghị cho trình duyệt)', + mintMinibitsWebDesc: '⚠ Chỉ ứng dụng gốc — không truy cập được từ trình duyệt web', + mintMinibitsNativeDesc: 'Mint của SkateSpots — khuyến nghị', + mintCoinosDesc: 'Mint thân thiện web', + mintLnbitsDesc: 'Mint cộng đồng trên LNbits', + }, + nwc: { + title: 'Ví Lightning', + noConnection: 'Ví NWC', + refresh: 'Làm mới số dư', + createInvoice: 'Tạo hóa đơn', + copyInvoice: 'Sao chép hóa đơn', + pasteInvoice: 'Dán hóa đơn Lightning (lnbc…)', + amount: 'Số tiền: {{amount}} sats', + pasteToSee: 'Dán hóa đơn để xem số tiền', + pay: 'Thanh toán', + invoiceQrAlt: 'Mã QR hóa đơn Lightning', + enterAmount: 'Nhập số tiền theo sats', + readBalanceFailed: 'Không đọc được số dư', + readBalanceFailedDesc: 'Ví của bạn không phản hồi.', + createInvoiceFailed: 'Không tạo được hóa đơn', + createInvoiceFailedDesc: 'Thử lại sau giây lát.', + paymentSent: 'Đã gửi thanh toán', + paidAmount: 'Đã trả {{amount}} sats.', + paid: 'Đã trả.', + paymentRejected: 'Ví từ chối thanh toán.', + }, + qr: { + title: 'Quét mã QR', + desc: 'Đưa mã QR vào khung camera để quét', + paste: 'Dán từ clipboard', + hint: 'Quét token Cashu, hóa đơn Lightning hoặc Lightning Address', + clipboardEmpty: 'Clipboard trống', + clipboardEmptyDesc: 'Không tìm thấy văn bản trong clipboard', + pasteFailed: 'Dán thất bại', + pasteFailedDesc: 'Không đọc được từ clipboard', + }, + recovery: { + title: 'Cụm từ khôi phục', + desc: '12 từ này là cách duy nhất khôi phục số dư ecash. Hãy ghi lại theo đúng thứ tự và cất ngoại tuyến — tuyệt đối không chia sẻ với ai.', + tapReveal: 'Chạm để hiện', + noWatching: 'Đảm bảo không ai đang nhìn', + hide: 'Ẩn', + reveal: 'Hiện', + paperHint: 'Ghi ra giấy là an toàn nhất — sao chép vào clipboard có thể lộ sang ứng dụng khác.', + written: 'Tôi đã ghi lại', + revealFirst: 'Hãy hiện các từ trước', + copiedDesc: 'Đã sao chép cụm từ khôi phục — dán vào nơi an toàn, rồi xóa clipboard.', + copyFailed: 'Sao chép thất bại', + copyFailedDesc: 'Vui lòng ghi các từ ra giấy thay vì sao chép.', + }, + guide: { + quickGuide: 'Hướng dẫn nhanh', + fullGuide: 'Hướng dẫn ví (bản cho skater)', + cashuSummary: 'Riêng tư + Tiện lợi', + mintHoldsFunds: '(mint giữ tiền)', + lightningSummary: 'Kiểm soát + An toàn', + youHoldKeys: '(bạn giữ khóa)', + useBoth: 'Dùng cả hai: Cashu để tip, Lightning để tiết kiệm', + cashuTitle: 'VÍ CASHU', + cashuTagline: 'Như tiền mặt trong túi bạn ở skatepark', + cashuBullet1: 'Rút ra tip nhanh chóng', + cashuBullet2: 'Đừng mang theo toàn bộ tiền tiết kiệm ở đây', + cashuBullet3: 'Nếu mint biến mất, tiền có thể mất', + cashuBullet4: 'Không ai biết bạn có bao nhiêu (riêng tư!)', + cashuPerfectFor: 'Ăn vặt buổi chơi, zap clip, tip nhỏ', + lightningTitle: 'VÍ LIGHTNING', + lightningTagline: 'Như tài khoản ngân hàng - bạn nắm quyền', + lightningBullet1: 'An toàn, bạn kiểm soát khóa', + lightningBullet2: 'Mất chút thời gian thiết lập', + lightningBullet3: 'Lịch sử giao dịch đầy đủ', + lightningBullet4: 'Tốt hơn cho số tiền lớn', + lightningPerfectFor: 'Mua gear, tiết kiệm, zap lớn', + perfectFor: 'Hoàn hảo cho:', + proTips: 'MẸO HAY', + tip1Title: 'Dùng cả hai ví', + tip1Desc: 'Để tiền đi chơi trong Cashu, tiền tiết kiệm trong Lightning', + tip2Title: 'Thử các ví khác nhau', + tip2Desc: 'Thử nghiệm để tìm cái phù hợp. Mỗi ví có tính năng và đánh đổi khác nhau', + tip3Title: 'Riêng tư hơn', + tip3Desc: 'Dùng nhiều ví nghĩa là không ứng dụng nào thấy hết hoạt động của bạn', + tip4Title: 'Tích lũy kinh nghiệm', + tip4Desc: 'Bạn càng biết nhiều công cụ, càng có nhiều lựa chọn. Bắt đầu nhỏ, học dần', + tldr: 'Tóm lại:', + tldrDesc: 'Không có ví "tốt nhất" - còn tùy nhu cầu. Hãy thử cả hai, dùng cái thấy phù hợp, và đừng để hết sats ở một chỗ!', + }, + zap: { + count: '{{count}} zap', + connectFirst: 'Kết nối ví trước', + connectFirstDesc: 'Để gửi zap (tip Bitcoin), bạn cần kết nối ví Lightning.', + quickSetup: 'Thiết lập nhanh (30 giây)', + quickSetupDesc: 'Kết nối ví Lightning hiện có bằng Nostr Wallet Connect (NWC). Không cần thêm tài khoản.', + connectNwc: 'Kết nối ví bằng NWC', + noWallet: 'Chưa có ví? Tìm hiểu cách', + skip: 'Bỏ qua lúc này (hóa đơn thủ công)', + note: 'ℹ️ Lưu ý:', + noteDesc: 'Bạn vẫn có thể tạo hóa đơn mà không cần kết nối ví, nhưng phải tự sao chép để thanh toán.', + payWithWebln: 'Thanh toán bằng WebLN', + processing: 'Đang xử lý...', + openInWallet: 'Mở trong ví Lightning', + scanHint: 'Quét mã QR hoặc sao chép hóa đơn để thanh toán bằng bất kỳ ví Lightning nào.', + cashuInstant: 'Thanh toán tức thì bằng ví tích hợp', + satsAvailable: 'sats khả dụng', + or: 'HOẶC', + customAmount: 'Số tiền tùy chọn', + addComment: 'Thêm bình luận (không bắt buộc)', + insufficientBanner: '⚠️ Số dư Cashu không đủ. Bạn cần thêm {{amount}} sats. Hãy chuyển sang Lightning hoặc nạp thêm ví Cashu.', + creatingInvoice: 'Đang tạo hóa đơn...', + zapAmount: 'Zap {{amount}} sats', + zapAmountCashu: 'Zap {{amount}} sats bằng Cashu', + lightningInvoice: 'Hóa đơn Lightning', + qrAlt: 'Mã QR hóa đơn Lightning', + enterAmount: 'Nhập số tiền', + enterAmountDesc: 'Chọn mức đặt sẵn hoặc nhập số sats hợp lệ.', + cashuUnavailable: 'Ví Cashu không khả dụng', + cashuUnavailableDesc: 'Ví Cashu chưa sẵn sàng. Hãy chuyển sang Lightning hoặc mở ví trước.', + insufficientCashu: 'Số dư Cashu không đủ', + insufficientCashuDesc: 'Bạn cần thêm {{amount}} sats. Hãy chuyển sang Lightning hoặc nạp thêm.', + zapSentCashu: 'Đã gửi zap! 🥜', + zapSentCashuDesc: 'Đã zap {{amount}} sats từ ví Cashu.', + cashuFailed: 'Thanh toán Cashu thất bại', + cashuFailedDesc: 'Không thể thanh toán bằng ví Cashu.', + invoiceCopied: 'Đã sao chép hóa đơn', + invoiceCopiedDesc: 'Đã sao chép hóa đơn Lightning vào clipboard', + defaultComment: 'Đã zap trên SkateSpots! 🛹', + titleConnect: 'Kết nối ví', + titlePayment: 'Thanh toán Lightning', + titleZap: 'Gửi zap', + descConnect: 'Kết nối ví Lightning để gửi zap', + descPayment: 'Thanh toán bằng Bitcoin Lightning Network', + descZap: 'Zap là khoản thanh toán Bitcoin nhỏ để ủng hộ người tạo nội dung này. Nếu bạn thấy thích, hãy cân nhắc gửi một zap!', + descZapShort: 'Zap là khoản thanh toán Bitcoin nhỏ để ủng hộ người sáng tạo. Hãy cân nhắc gửi một zap!', + }, + zapCrew: { + title: 'Zap cả crew', + desc: 'Chia đều một zap cho {{count}} thành viên crew có Lightning Address.', + noMembers: 'Hiện không có thành viên crew nào khác để zap.', + totalAmount: 'Tổng số tiền', + customTotal: 'Tổng tùy chọn', + each: 'sats mỗi người', + rounded: '(đã làm tròn)', + noWallet: 'Chưa kết nối ví — bạn sẽ nhận một hóa đơn cho mỗi thành viên để trả thủ công. Kết nối ví để chia chỉ với một chạm.', + zapAcross: 'Zap {{amount}} sats cho {{count}} người', + sentTo: '⚡ Đã gửi đến {{done}}/{{total}}', + none: 'Không có thanh toán tự động nào hoàn tất', + copyPending: 'Sao chép các hóa đơn còn lại để trả thủ công.', + thanks: 'Cảm ơn đã ủng hộ crew!', + payingCrew: 'Đang trả cho crew…', + defaultComment: 'Đã zap crew {{crew}}! 🤘', + sent: 'Đã gửi', + paying: 'Đang trả', + resolving: 'Đang xử lý', + skipped: 'Đã bỏ qua', + failed: 'Thất bại', + waiting: 'Đang chờ', + copyInvoice: 'Sao chép hóa đơn', + invoiceCopied: 'Đã sao chép hóa đơn', + invoiceCopiedDesc: 'Dán vào bất kỳ ví Lightning nào', + }, + zapBadges: { + title: 'Huy hiệu zap', + zaps: 'zap', + satsSent: 'sats đã gửi', + rank: 'hạng', + footnote: 'Dựa trên 30 ngày zap gần nhất.', + first: 'Zap đầu tiên', + firstHint: 'Gửi zap đầu tiên của bạn', + regular: 'Thường xuyên', + regularHint: 'Gửi 10 zap', + generous: 'Hào phóng', + generousHint: 'Gửi 10.000 sats', + patron: 'Mạnh thường quân', + patronHint: 'Gửi 100.000 sats', + top10: 'Top 10', + top10Hint: 'Lọt vào top 10 người ủng hộ', + }, + trust: { + unavailable: 'Không có điểm tin cậy', + yourContent: 'Đây là nội dung của bạn', + following: 'Bạn theo dõi người dùng này', + friendOfFriend: 'Bạn của bạn (2 bước)', + nip05: 'Người dùng đã xác minh NIP-05', + unknown: 'Người dùng không xác định', + help: 'Điểm tin cậy giúp nhận diện những người đóng góp đáng tin trong cộng đồng trượt ván.', + }, + share: { + title: 'Chia sẻ hồ sơ', + desc: 'Hướng camera điện thoại vào mã để mở hồ sơ của {{name}}.', + qrAlt: 'Mã QR hồ sơ', + copyLink: 'Sao chép liên kết', + copyFailed: 'Sao chép thất bại', + copyFailedDesc: 'Không thể sao chép liên kết.', + shareEllipsis: 'Chia sẻ…', + }, + addToCollection: { + title: 'Lưu vào bộ sưu tập', + desc: 'Lưu "{{spot}}" vào một trong các bộ sưu tập của bạn', + loginRequired: 'Vui lòng đăng nhập để lưu spot vào bộ sưu tập', + noCollections: 'Bạn chưa có bộ sưu tập nào', + createFirst: 'Tạo bộ sưu tập đầu tiên bên dưới!', + spotCount: '{{count}} spot', + alreadySavedTag: 'Đã lưu', + alreadySaved: 'Đã lưu', + alreadySavedDesc: '“{{spot}}” đã có trong “{{collection}}”', + saved: 'Đã lưu spot!', + savedDesc: 'Đã thêm "{{spot}}" vào "{{collection}}"', + saveFailed: 'Lưu thất bại', + somethingWrong: 'Đã xảy ra lỗi', + created: 'Đã tạo bộ sưu tập!', + createdDesc: 'Đã thêm "{{spot}}" vào bộ sưu tập mới "{{collection}}"', + createFailed: 'Tạo bộ sưu tập thất bại', + name: 'Tên bộ sưu tập', + descriptionOptional: 'Mô tả (không bắt buộc)', + creating: 'Đang tạo...', + createAndSave: 'Tạo & Lưu', + createNew: 'Tạo bộ sưu tập mới', + }, + collection: { + back: 'Quay lại Bộ sưu tập', + created: 'Đã tạo {{date}}', + deleteTitle: 'Xóa bộ sưu tập?', + deleteDesc: 'Thao tác này sẽ xóa vĩnh viễn "{{title}}". Bản thân các spot không bị ảnh hưởng.', + deleting: 'Đang xóa...', + deleteFailed: 'Xóa bộ sưu tập thất bại', + deleted: 'Đã xóa bộ sưu tập', + deletedDesc: 'Đã xóa "{{title}}"', + empty: 'Không có spot trong bộ sưu tập này', + emptyOwner: 'Thêm spot vào bộ sưu tập bằng cách nhấn "Lưu vào bộ sưu tập" trên bất kỳ spot nào', + emptyOther: 'Bộ sưu tập này trống', + browseSpots: 'Xem các spot', + linkCopied: 'Đã sao chép liên kết!', + linkCopiedDesc: 'Đã sao chép liên kết bộ sưu tập vào clipboard', + map: 'Bản đồ bộ sưu tập', + removeFailed: 'Xóa spot thất bại', + shareText: 'Xem bộ sưu tập spot này: {{title}}', + spotRemoved: 'Đã xóa spot', + spotRemovedDesc: 'Đã xóa "{{title}}" khỏi bộ sưu tập này', + }, + mints: { + title: 'Mint', + subtitle: 'Xem các mint Cashu và tình trạng hoạt động. Thao tác ví Cashu chạy trong ứng dụng SkateSpots.', + searchPlaceholder: 'Tìm mint theo tên hoặc URL…', + onlineOnly: 'Chỉ trực tuyến', + count: '{{filtered}} trên {{total}} mint', + directoryError: 'Không tải được danh bạ mint.', + directoryHint: 'Danh bạ do cộng đồng vận hành và bị giới hạn tần suất — có thể tạm thời không khả dụng.', + goToWallet: 'Đến Ví', + appOnly: 'Việc thêm mint diễn ra trong ứng dụng SkateSpots (Cashu chỉ chạy trên ứng dụng).', + noMatch: 'Không có mint nào khớp “{{query}}”.', + footer: 'Dữ liệu tình trạng từ dự án MintRadar cộng đồng — không chính thức và có thể lỗi thời. Luôn xem điều khoản của mint trước khi tin tưởng giao tiền.', + archived: 'Đã lưu trữ', + degraded: 'Suy giảm', + offline: 'Ngoại tuyến', + online: 'Trực tuyến', + terms: 'Điều khoản', + reliability: 'độ tin cậy', + add: 'Thêm', + addToWallet: 'Thêm vào ví', + copyUrl: 'Sao chép URL', + openMint: 'Mở mint', + inWallet: 'Trong ví của bạn', + addedBadge: 'Đã thêm', + urlCopied: 'Đã sao chép URL mint', + added: 'Đã thêm mint', + addedDesc: '{{host}} giờ đã có trong ví của bạn.', + couldNotAdd: 'Không thể thêm mint', + communityRating: 'Đánh giá cộng đồng', + reliabilityLabel: 'Độ tin cậy', + uptime: 'Thời gian hoạt động 24h / 7d', + location: 'Vị trí', + latency: 'Độ trễ', + nuts: 'NUT được hỗ trợ', + units: 'Đơn vị', + version: 'Phiên bản', + ratedBy: 'Được {{count}} người chấm {{rating}}/5 trên MintRadar.', + noRating: 'Chưa có đánh giá cộng đồng trên MintRadar.', + reviewsNote1: 'Đánh giá bằng văn bản không thuộc danh bạ —', + openMintRadar: 'mở MintRadar', + reviewsNote2: 'để đọc hoặc để lại một đánh giá.', + liveness: 'Kiểm tra hoạt động: đã thử {{mints}} mint và {{melts}} melt', + livenessErrors: ' · {{errors}}/{{total}} lỗi gần đây', + whatsAMint: 'Mint là gì?', + whatsAMintDesc: 'Một mint Cashu phát hành và đổi ecash trong ví của bạn. Nó giữ Bitcoin đảm bảo cho token của bạn — nên mint bạn không tự vận hành là mint bạn phải tin.', + mintWarning: 'Mint có thể ngừng hoạt động, đổi điều khoản hoặc biến mất cùng tiền. Chỉ giữ số dư nhỏ trừ khi bạn tin người vận hành.', + healthDisclaimer: 'Dữ liệu tình trạng do cộng đồng vận hành (MintRadar) — không chính thức và có thể lỗi thời.', + }, + appShop: { + title: 'App Shop', + subtitle: 'Đồ SkateSpots cho những người giữ sân chơi luôn lăn bánh.', + comingSoon: 'Sắp ra mắt', + wearThe: 'Mặc lấy', + scene: 'Cộng đồng', + heroDesc1: 'Đồ cho những người giữ thứ này lăn bánh — bán', + locally: 'tại địa phương, theo yêu cầu', + heroDesc2: '. Bạn nhắn cho tôi, chúng ta sắp xếp chi tiết, và bạn trả bằng', + heroDesc3: '— Lightning hoặc Cashu — khi nhận hàng. Không thẻ, không tài khoản, không robot thanh toán, không trung gian ăn chênh.', + requestItem: 'Yêu cầu một món', + dmHint: 'Mở tin nhắn riêng tư, mã hóa với tôi.', + lightning: 'Lightning', + cashu: 'Cashu', + localHandover: 'Trao tay tại địa phương', + inTheWorks: 'Đang làm', + notForSale: 'chưa bán', + soon: 'sắp có', + tees: 'Áo thun & hoodie', + decks: 'Deck', + shopTools: 'Dụng cụ làm shop', + stickerPacks: 'Bộ sticker', + stickerPacksDesc: 'Các bộ đang tới. Nhưng thiết kế thì có — in hai cái này ngay bây giờ, miễn phí.', + sticker: 'Sticker', + stickerTip: 'Cắt màu đen. In trên giấy sticker, cắt theo viền đen.', + poster: 'Poster', + posterTip: 'In trên A3; thu nhỏ về A4 (50%) vẫn quét tốt.', + printableAlt: 'SkateSpots {{title}} — bản in được', + print: 'In', + printNote1: 'In ở', + actualSize: '100% / “Kích thước thực”', + printNote2: 'để kích thước chính xác và mã QR sắc nét — nó trỏ đến skate-spots.org. Tệp vector nên phóng to không bị mờ.', + howBuying: 'Cách mua hoạt động', + dmNotCart: 'đây là tin nhắn, không phải giỏ hàng', + step1Title: 'Nhắn cho tôi', + step1Desc: 'Gửi tin nhắn với món bạn muốn — món, cỡ, màu, bất cứ gì bạn cần.', + step2Title: 'Chúng ta sắp xếp', + step2Desc: 'Giá bằng sats, và địa điểm, thời gian gặp. Đây là trò chuyện, không phải thanh toán.', + step3Title: 'Trả bằng sats', + step3Desc: 'Lightning hoặc Cashu khi trao hàng, thế là của bạn. Không giao hàng, không phòng chờ.', + }, + newsletter: { + newIssue: 'Số mới', + composerTitle: 'Xuất bản một số bản tin', + composerDesc: 'Xuất bản dưới dạng bài NIP-23 (kind 30023) trên relay cộng đồng. Người đăng ký nhận trong chuông thông báo. Nội dung hỗ trợ Markdown.', + fieldTitle: 'Tiêu đề', + identifier: 'Định danh (slug)', + leaveBlank: 'để trống để tự tạo', + reusingSlug: 'Dùng lại slug có sẵn sẽ sửa số đó thay vì tạo số mới.', + summary: 'Tóm tắt', + optional: 'không bắt buộc', + coverImage: 'URL ảnh bìa', + bodyMarkdown: 'Nội dung (Markdown)', + characters: '{{count}} ký tự', + publishIssue: 'Xuất bản số', + issuePublished: 'Đã xuất bản số! 🛹', + issuePublishedDesc: 'Người đăng ký sẽ thấy trong chuông thông báo.', + publishFailed: 'Xuất bản thất bại', + couldNotReachRelay: 'Không kết nối được relay nào — kiểm tra kết nối và thử lại.', + tryAgain: 'Vui lòng thử lại.', + publishedToNostr: 'Đã xuất bản lên Nostr', + publishedToast: 'Đã xuất bản!', + postedToNostr: 'Drop {{number}} đã đăng lên Nostr.', + postToNostr: 'Đăng lên Nostr', + previewLabel: 'Xem trước', + editFirst: 'Sửa trước', + previewNoteDesc: 'Đây là cách ghi chú sẽ hiển thị trên hầu hết client Nostr. Định dạng tùy client.', + editNoteDesc: 'Sửa nội dung ghi chú bên dưới. Thay đổi chỉ ảnh hưởng lần xuất bản này — tệp nguồn giữ nguyên.', + dropNumber: 'Drop {{number}}', + publish: 'Xuất bản', + publishing: 'Đang xuất bản...', + dropIsOut: 'Drop {{number}} đã ra', + daysAgo: '{{count}} ngày trước', + dismiss: 'Bỏ qua', + itsMonday: 'Hôm nay là thứ Hai', + mondayDesc: 'Đến lúc phát bản tin hằng tuần. Một cú nhấn và AI viết từ git log.', + writeDrop: 'Viết Drop {{number}}', + dismissReminder: 'Bỏ qua nhắc nhở', + loginPrompt: 'Đăng nhập bằng Nostr để nhận drop mới vào hộp thư.', + subscribedToast: 'Bạn đã đăng ký! 🛹', + subscribedToastDesc: 'Drop mới sẽ vào chuông thông báo trong mục "News".', + unsubscribed: 'Đã hủy đăng ký', + unsubscribedDesc: 'Bạn vẫn có thể đọc mọi số ở đây bất cứ lúc nào.', + checking: 'Đang kiểm tra…', + subscribed: 'Đã đăng ký', + unsubscribe: 'Hủy đăng ký', + subscribeCta: 'Đăng ký bản tin', + archiveSynced: 'Kho lưu đã đồng bộ lên Nostr', + missingCount: '{{count}} số lưu trữ chưa có trên Nostr', + backfillDesc: 'Xuất bản {{list}} dưới dạng bài NIP-23 để người đăng ký và người đọc bài dài thấy toàn bộ kho lưu. Trang vẫn giữ bố cục phong phú.', + backfill: 'Điền bù {{count}} lên Nostr', + publishing2: 'Đang xuất bản…', + publishingLabel: 'Đang xuất bản…', + backfilled: 'Đã điền bù {{count}} số 🛹', + backfilledDesc: 'Kho lưu giờ đã có trên Nostr cho người đăng ký và độc giả.', + partialBackfill: 'Đã xuất bản {{published}}, {{failed}} thất bại', + retryFinish: 'Thử lại để hoàn tất: {{list}}.', + notLoggedIn: 'Chưa đăng nhập', + allIssues: 'Tất cả số', + brand: 'Bản tin SkateSpots', + digTheDrop: 'Thích drop này? Hãy zap và đừng bỏ lỡ số tới.', + sectionStats: 'Cộng đồng qua những con số', + sectionWhatsNew: 'Có gì mới', + sectionSpotOfWeek: 'Spot của tuần', + sectionCommunity: 'Cộng đồng', + sectionSupport: 'Ủng hộ dự án', + sectionLatestDrops: 'Drop mới nhất · Trực tiếp từ Nostr', + mappedBy: 'Được vẽ bởi', + viewOnMap: 'Xem trên bản đồ', + noSpotPicked: 'Tuần này chưa chọn spot. Gửi spot của bạn, biết đâu vào số tới.', + browseMap: 'Xem bản đồ', + spotMap: 'Bản đồ spot', + statsBadge: 'Thống kê', + supportDesc: '100% mã nguồn mở, do cộng đồng tài trợ, không quảng cáo, không nhà đầu tư. Nếu thấy hữu ích, hãy zap hoặc ủng hộ trên Angor.', + readFull: 'Đọc toàn bộ số', + joinSkaters: 'Tham gia cùng {{count}} skater nhận drop', + weeklyDrops: 'Drop hằng tuần', + tagline: 'Bản tin hằng tuần · phát bất cứ khi nào chúng tôi muốn', + freeNote: 'Miễn phí. Vận hành bằng Nostr — đăng ký của bạn nằm trên khóa của bạn và theo bạn qua mọi thiết bị. Drop mới vào chuông thông báo.', + live: 'Trực tiếp', + builtOn: 'Xây trên', + openSource: 'Mã nguồn mở', + supportUs: 'Ủng hộ chúng tôi', + freeToSkate: 'Bạn được tự do trượt ván', + }, + stats: { + subtitle: 'Chỉ số trực tiếp lấy từ mạng Nostr. Minh bạch, phi tập trung, ai cũng kiểm chứng được.', + dataSource: 'Nguồn dữ liệu:', + updated: 'cập nhật {{age}}', + refresh: 'Làm mới', + partial: 'Không kết nối được mọi relay — những con số này có thể chưa đầy đủ.', + error: 'Hiện không kết nối được relay. Thống kê sẽ tải khi kết nối được khôi phục.', + atAGlance: 'Cộng đồng trong nháy mắt', + skateSpots: 'Skate Spot', + listedShops: 'Shop niêm yết', + events: 'Sự kiện', + mappers: 'Người vẽ bản đồ', + uniqueContributors: 'người đóng góp riêng biệt', + labHeader: 'The Lab · Người sáng tạo & Dịch vụ', + total: '{{count}} tổng cộng', + coaches: 'Coach', + filmers: 'Filmer', + editors: 'Editor', + photographers: 'Nhiếp ảnh gia', + builders: 'Thợ làm', + artists: 'Nghệ sĩ', + graffiti: 'Graffiti', + tattoo: 'Hình xăm', + trainers: 'Huấn luyện viên', + musicians: 'Nhạc sĩ', + judges: 'Giám khảo', + organizers: 'Nhà tổ chức', + barbers: 'Thợ cắt tóc', + showFewer: 'Hiện ít hơn', + showAllCrafts: 'Hiện cả 13 nghề', + community: 'Cộng đồng', + tours: 'Tour', + crews: 'Crew', + marketplace: 'Chợ', + liveListings: 'Tin đăng đang hoạt động', + tradesRecorded: 'Giao dịch đã ghi', + satsTraded: 'Sats đã giao dịch', + zapsToMappers: 'Zap cho người vẽ bản đồ', + tradesNote1: 'giao dịch tương hỗ giữa', + tradesNote2: 'người. Sats do người giao dịch tự khai — ứng dụng không thể quan sát khoản trả ngoài ứng dụng — nên con số chính chỉ đếm các', + mutual: 'giao dịch tương hỗ', + tradesNote3: 'với giới hạn mỗi cặp; con số thô là', + tradesNote4: 'sats. "Zap cho người vẽ bản đồ" chỉ đếm biên lai gửi đến những người đóng góp hàng đầu của chúng ta — đây', + not: 'không phải', + tradesNote5: 'tổng khối lượng zap toàn cầu.', + byRegion: 'Spot & Shop theo khu vực', + resolving: 'Đang phân giải {{count}} vị trí chưa gắn thẻ từ tọa độ… một lần, rồi lưu trên thiết bị này.', + topCountries: 'Quốc gia hàng đầu', + topCities: 'Thành phố hàng đầu', + other: 'Khác', + otherCountriesTitle: 'Quốc gia ngoài top 6', + otherCitiesTitle: 'Thành phố ngoài top 6', + uncategorised: 'Chưa phân loại', + uncategorisedTitle: 'Không có thẻ thành phố/quốc gia', + regionNote1: 'Đếm', + spotsAndShops: 'spot & shop', + regionNote2: ', không phải skater — từ thẻ thành phố/quốc gia của chính mỗi mục, hoặc suy ra từ tọa độ ghim khi không có (lưu trên thiết bị; quốc gia nhóm theo mã ISO nếu có), chỉ relay cộng đồng, loại trừ nội dung bị kiểm duyệt ẩn.', + ofTotal: '{{count}} trên {{total}}', + regionNote3: 'vị trí không có thẻ vị trí và hiện là "Chưa phân loại".', + growth: 'Tăng trưởng theo thời gian', + chartCumulativeTitle: 'Spot đã vẽ (lũy kế)', + chartCumulativeDesc: 'Tổng số spot thêm vào bản đồ theo thời gian', + chartMonthlyTitle: 'Hoạt động hằng tháng', + chartMonthlyDesc: 'Nội dung mới xuất bản mỗi tháng', + chartMappersTitle: 'Người vẽ tích cực / tháng', + chartMappersDesc: 'Người đóng góp riêng biệt xuất bản mỗi tháng', + chartMixTitle: 'Cơ cấu nội dung', + chartMixDesc: 'Phân tích theo loại nội dung (mọi thời gian)', + noData: 'Chưa có dữ liệu', + topMappers: 'Người vẽ hàng đầu', + mostSpots: '— thêm nhiều spot nhất', + noMapperData: 'Chưa có dữ liệu người vẽ', + topShops: 'Shop hàng đầu', + mostShops: '— thêm nhiều shop nhất', + shopCount: '{{count}} shop', + noShopData: 'Chưa có dữ liệu shop', + supporters: 'Người ủng hộ cộng đồng', + fundedTitle: 'Được cộng đồng tài trợ', + fundedDesc1: 'Gây quỹ Bitcoin phi tập trung qua Angor.', + fundedDesc2: 'Không quảng cáo, không nhà đầu tư, không bán dữ liệu.', + backAngor: 'Ủng hộ trên Angor', + communityLink: 'Cộng đồng →', + footer1: 'Mọi dữ liệu được lấy trực tiếp từ', + footer2: '— một relay Nostr công khai.', + footer3: 'Mọi sự kiện đều được người tạo ký và kiểm chứng bằng mật mã.', + footer4: 'Không con số nào có thể bị làm giả.', + spots: 'Spot', + shops: 'Shop', + lab: 'Lab', + thisMonth: '+{{count}} tháng này', + fromActive: '{{count}} từ tài khoản hoạt động', + viewAll: 'Xem tất cả', + spotCount: '{{count}} spot', + }, + leaderboard: { + mapEarn: 'Vẽ bản đồ & Nhận thưởng', + helpMap: 'GIÚP VẼ BẢN ĐỒ THẾ GIỚI', + intro: 'Thêm spot và shop, nhận zap từ những skater biết ơn. Người đóng góp hàng đầu có thể nhận thưởng thêm!', + howItWorks: 'Cách hoạt động', + step1Title: '1. Vẽ bản đồ', + step1Desc: 'Thêm spot & shop kèm ảnh và chi tiết', + step2Title: '2. Nhận zap', + step2Desc: 'Skaters thấy spot của bạn hữu ích sẽ tip bạn', + step3Title: '3. Thưởng thêm', + step3Desc: 'Người vẽ hàng đầu có thể nhận thưởng thêm từ quỹ của chúng tôi', + proTips: '💡 Mẹo hay để nhận nhiều zap hơn:', + tipPhotos: 'Thêm 3+ ảnh', + tipDescriptions: 'Viết mô tả chi tiết', + tipLocation: 'Vị trí chính xác', + mapShop: 'Vẽ một shop', + mapShopDesc: 'Skate shop, cửa hàng ván', + mapSpot: 'Vẽ một spot', + mapSpotDesc: 'Công viên, spot đường phố, DIY', + shops: 'Shop', + spotsLower: 'spot', + shopsLower: 'shop', + contributions: 'đóng góp', + yourRanking: 'Xếp hạng của bạn', + spotsShops: '{{spots}} spot • {{shops}} shop', + totalLower: 'tổng', + overall: 'Tổng thể', + noContributions: 'Chưa có đóng góp. Hãy là người đầu tiên!', + addFirstSpot: 'Thêm spot đầu tiên', + noShops: 'Chưa có shop nào được vẽ', + addFirstShop: 'Thêm shop đầu tiên', + noSpots: 'Chưa có spot nào được vẽ', + poweredBy: 'Vận hành bởi Zap cộng đồng', + poweredByDesc: 'Khi bạn thấy một spot hữu ích, hãy zap người vẽ! Đó là cách cảm ơn tốt nhất và khích lệ thêm đóng góp.', + you: 'Bạn', + zapTitle: 'Bảng xếp hạng zap', + zapSubtitle: 'Những spot được yêu thích nhất — và những skater trao đi.', + thisWeek: 'Tuần này', + thisMonth: 'Tháng này', + allTime: 'Mọi thời gian', + topZappedSpots: 'Spot được zap nhiều nhất', + noZaps: 'Chưa có zap trong kỳ này. Hãy là người đầu tiên — nhấn ⚡ trên spot bạn thích.', + topSupporters: 'Người ủng hộ hàng đầu', + noZapsSent: 'Chưa ai gửi zap trong kỳ này.', + fromTop10: '⚡ {{amount}} sats từ top 10', + supporter: 'Người ủng hộ', + skateShop: 'Skate shop', + skateSpot: 'Skate spot', + }, + supporters: { + our: 'CỦA CHÚNG TÔI', + community: 'CỘNG ĐỒNG', + heroDesc: 'SkateSpots được xây bởi và vì cộng đồng. Những người ủng hộ, cộng tác viên, đối tác và bạn bè cùng giữ điều này miễn phí và phi tập trung.', + backAngor: 'Ủng hộ trên Angor', + backers: 'Người ủng hộ', + backersDesc: 'Những skater đã ủng hộ SkateSpots — tài trợ on-chain qua Angor, và zap Lightning cho dự án.', + sourceAngor: 'Angor', + supportersTotals: '{{count}} người ủng hộ · {{angor}} sats qua Angor · {{zap}} sats đã zap', + quietNote: 'Cùng tất cả những ai ủng hộ âm thầm — cảm ơn bạn. ❤️', + silentTitle: 'Riêng tư on-chain (silent payments)', + silentDesc: 'Một tên, một địa chỉ mới cho mỗi lần trả — on-chain qua silent payments, hoặc Lightning từ cùng bản ghi. Không gì để dùng lại, không gì để liên kết.', + silentCopyName: 'Sao chép tên', + silentCopied: 'Đã sao chép', + silentWallets: 'Cần ví hỗ trợ payment names / silent payments: Sparrow, Cake, Dana, Phoenix, BlueWallet, Wasabi, Nunchuk hoặc BitBox02.', + wayLightningTitle: 'Tức thì & công khai', + wayLightningDesc: 'Zap SkateSpots, hoặc trả âm thầm. Hoạt động cả khi chưa đăng nhập.', + waySilentTitle: 'Riêng tư on-chain', + waySilentDesc: 'Một tên silent-payments — địa chỉ mới cho mỗi lần trả.', + wayAngorTitle: 'Tài trợ việc xây dựng', + wayAngorDesc: 'Angor — giải ngân theo giai đoạn, hoàn lại khi trên 100k sats.', + donateTitle: 'Ủng hộ SkateSpots', + donateDesc: 'Ba kênh, ba lý do — chọn cái hợp với bạn. Mỗi sat giữ bản đồ miễn phí, không quảng cáo và mã nguồn mở.', + donatePageLink: 'Mở trang quyên góp đơn giản', + updatedAt: 'Cập nhật {{when}}', + tiersNote: 'Cấp bậc: Người ủng hộ dưới 100k sats · Mạnh thường quân 100k–1M · Huyền thoại 1M+', + tierEmpty: 'Chưa có ai — hãy là người đầu tiên.', + joinSupporters: 'Tham gia cùng {{count}} người ủng hộ', + showAll: 'Hiện tất cả {{count}}', + showLess: 'Hiện ít hơn', + impactSeeStats: 'Xem bức tranh đầy đủ →', + impactAsOf: 'trực tiếp từ các relay cộng đồng', + anonymousBacker: 'Người ủng hộ ẩn danh', + beFirstBacker: 'Chưa có người ủng hộ công khai — hãy là người đầu tiên.', + backersTotal: '{{count}} người ủng hộ · {{amount}} sats đã gây quỹ', + verifiedOnChain: 'Đã xác minh on-chain', + supportedBy: 'Được {{count}} ủng hộ', + tierSupporter: 'Người ủng hộ', + tierPatron: 'Mạnh thường quân', + tierLegend: 'Huyền thoại', + topZappers: 'Đã zap SkateSpots', + topZappersDesc: 'Những skater đã gửi zap công khai thẳng cho dự án. Các khoản trả âm thầm không được liệt kê.', + paysFor: 'Sự ủng hộ của bạn chi trả cho gì', + paysForDesc: 'Mỗi sat đi đâu — không lương, không văn phòng, không quảng cáo.', + payRelay: 'Lưu trữ relay', + payDomain: 'Tên miền & TLS', + payAi: 'Nút AI / ContextVM', + payDev: 'Thời gian phát triển', + payOps: 'Vận hành', + payMarketing: 'Tiếp thị', + payRelayDesc: 'Giữ bản đồ luôn hoạt động và bền bỉ.', + payDomainDesc: 'Tên miền, chứng chỉ, kết nối an toàn.', + payAiDesc: 'Sasquatch, người hướng dẫn cộng đồng.', + payDevDesc: 'Xây dựng và sửa SkateSpots.', + payOpsDesc: 'Công việc âm thầm giữ mọi thứ chạy.', + payMarketingDesc: 'Vươn tới các sân chơi địa phương và skateshop mới.', + impact: 'Tác động đến nay', + impactDesc: 'Những gì cộng đồng đã xây — tài trợ bởi skater.', + impactSpots: 'Spot', + impactCrews: 'Crew', + impactEvents: 'Sự kiện', + impactLab: 'Lab pro', + impactShops: 'Shop', + impactMappers: 'Người vẽ', + support: 'Ủng hộ', + supportDesc: 'Tài trợ SkateSpots trên Angor — gây quỹ Bitcoin phi tập trung, on-chain. Không trung gian, không KYC.', + collaborators: 'Cộng tác viên', + collaboratorsDesc: 'Những người đang tích cực xây SkateSpots — lập trình viên, nhà thiết kế, người vận hành relay.', + partners: 'Đối tác', + partnersDesc: 'Các tổ chức và dự án chúng tôi hợp tác chặt chẽ.', + friends: 'Bạn bè', + friendsDesc: 'Những người chúng tôi hợp gu.', + backTitle: 'Ủng hộ dự án trên Angor', + backDesc: 'Angor là hình thức tài trợ Bitcoin on-chain phi tập trung xây trên Nostr — tiền của bạn vẫn trong tầm kiểm soát, giải ngân theo giai đoạn, không bên giữ hộ nào giữ quỹ. Khoản góp tới 100.000 sats hoạt động như quyên góp (không cần handshake thu hồi); khoản lớn hơn là đầu tư và phần chưa dùng có thể thu hồi. Mỗi sat đi vào phát triển, lưu trữ relay và giữ SkateSpots miễn phí cho mọi skater trên trái đất.', + donateNote: 'Thích quyên góp thẳng hơn? ⚡ Zap bên dưới — không gì phải hoàn, không gì phải thu hồi.', + openAngor: 'Mở Angor', + orZap: 'hoặc ⚡ zap trực tiếp bất kỳ spot, crew hay người sáng tạo nào trong ứng dụng', + wantCollaborate: 'Muốn cộng tác?', + wantCollaborateDesc: 'Lập trình viên, nhà thiết kế, skater có kỹ năng — hãy liên hệ.', + viewNostrHub: 'Xem trên NostrHub', + wantPartner: 'Muốn hợp tác với SkateSpots? Hãy liên hệ trên Nostr.', + comingSoon: 'Sắp ra mắt', + wantListed: 'Muốn được liệt kê ở đây?', + wantListedDesc: 'Gửi logo (PNG/WebP, nền trong suốt, tối thiểu 200×200px) và URL qua tin nhắn riêng trên Nostr, nếu bạn thấy hợp gu.', + whyTitle1: 'Vì sao chúng tôi cần', + whyTitle2: 'Sự ủng hộ', + whyDesc: 'SkateSpots hoàn toàn miễn phí, mã nguồn mở, xây trên Nostr — giao thức phi tập trung không có server trung tâm để đóng. Không quảng cáo, không bán dữ liệu, không nhà đầu tư. Mỗi sat đi thẳng vào phát triển, lưu trữ relay và giữ điều này miễn phí cho mọi skater trên trái đất.', + why1Title: 'Thuần Nostr', + why1Desc: 'Không server trung tâm. Dữ liệu của bạn nằm trên relay bạn chọn.', + why2Title: 'Vận hành bằng Bitcoin', + why2Desc: 'Kiếm sats từ việc vẽ bản đồ. Tiêu chúng ở shop địa phương.', + why3Title: 'Miễn phí mãi mãi', + why3Desc: 'Mã nguồn mở, không paywall, không theo dõi, không vốn đầu tư mạo hiểm.', + thankYou: 'Cảm ơn bạn. Mỗi sat giữ các spot trên bản đồ. 🛹⚡', + license: 'Giấy phép', + faq: 'FAQ', + }, + admin: { + confirmed: 'Đã xác nhận', + title: 'Hàng chờ duyệt', + subtitle: 'Spot, shop, sự kiện, tour và gear vi phạm tín hiệu rác. Ẩn và Xác nhận là nhãn mềm, có thể đảo ngược; báo cáo xếp trước. Không gì bị xóa.', + tabReports: 'Báo cáo', + tabSpots: 'Spot', + tabShops: 'Shop', + tabEvents: 'Sự kiện', + tabTours: 'Tour', + tabGear: 'Gear', + tabCrews: 'Crew', + tabLab: 'Lab', + tabClaims: 'Yêu cầu', + nothingToReview: 'Không có gì để duyệt — không có mục nào loại này vi phạm tín hiệu rác.', + hideActioned: 'Ẩn mục đã xử lý', + showActioned: 'Hiện mục đã xử lý ({{count}})', + undoAll: 'Hoàn tác tất cả {{count}}', + undoAllTitle: 'Hoàn tác mọi phán quyết trong tab này?', + undoAllDesc: 'Thao tác này đưa từng mục về trung lập — không ẩn, không xác nhận. Nó xuất bản một nhãn công khai cho mỗi mục, nên với Amber bạn sẽ nhận {{count}} màn hình phê duyệt.', + undoCount: 'Hoàn tác {{count}}', + undo: 'Hoàn tác', + confirm: 'Xác nhận', + hide: 'Ẩn', + hideIt: 'Ẩn nó', + hideForEveryone: 'Ẩn điều này với mọi người?', + hideForEveryoneDesc: 'Thao tác này xóa mục khỏi duyệt và tìm kiếm với mọi người dùng SkateSpots. Đây là nhãn công khai, có thể đảo ngược — bạn có thể Hoàn tác từ hàng chờ này.', + hidden: 'Đã ẩn', + hiddenDesc: 'Đã xóa khỏi ứng dụng bằng nhãn công khai. Có thể đảo ngược.', + couldNotHide: 'Không thể ẩn', + notASpot: 'Không phải skate spot', + lookAtIt: 'Xem nó', + }, + profile: { + nip05Verified: 'Đã xác minh NIP-05', + nip05NotVerified: 'NIP-05 chưa được xác minh với khóa này', + message: 'Nhắn tin', + zapsReceived: 'zap đã nhận', + memberSince: 'Thành viên từ', + badges: 'Huy hiệu', + sponsorsSupport: 'Nhà tài trợ & ủng hộ', + skater: 'Skater', + stance: 'Tư thế', + skating: 'Trượt ván', + homeSpot: 'Spot nhà', + basedIn: 'Ở tại', + addSkateDetails: 'Thêm chi tiết trượt ván của bạn', + addSkateDetailsDesc: 'Đặt tư thế, phong cách & trình độ để xuất hiện trong danh bạ Skater.', + spotsAdded: 'Spot đã thêm', + shopsAdded: 'Shop đã thêm', + noSpots: 'Bạn chưa thêm spot nào', + noSpotsDesc: 'Đưa spot địa phương của bạn lên bản đồ →', + stash: 'Stash', + gear: 'Gear', + crews: 'Crew', + info: 'Thông tin', + lightning: 'Lightning', + silentPayment: 'Silent Payment', + coordinator: 'Coordinator', + coordinatorAdded: 'Đã thêm coordinator', + add: 'Thêm', + messagePrivately: 'Nhắn riêng', + founder: 'Người sáng lập', + member: 'Thành viên', + supportSkater: 'Ủng hộ skater này', + supportSkaterDesc: 'Gửi tip để cảm ơn những đóng góp của họ', + }, + index: { + joinCommunity: 'Tham gia cộng đồng để thêm spot, tạo sự kiện & hơn nữa', + topZapped: 'ZAP NHIỀU NHẤT', + topZappedDesc: 'Spot được ủng hộ nhiều nhất tháng này', + leaderboard: 'Bảng xếp hạng', + newHere: 'MỚI ĐẾN?', + newHereDesc: 'Tạo tài khoản miễn phí để thêm spot, tham gia sự kiện, kết nối với skater và trở thành một phần của cộng đồng. Không cần email.', + followFounder: 'Theo dõi Người sáng lập', + followFounderDesc: 'Giữ avatar 3 giây để theo dõi và cập nhật tính năng, sự kiện mới!', + createAccount: 'Tạo tài khoản', + accountWorks: 'Tài khoản của bạn hoạt động trên mọi ứng dụng trong mạng lưới', + footerTagline: 'Mã nguồn mở • Cộng đồng sở hữu • Không quảng cáo', + }, + stash: { + title: 'Stash của tôi', + loginDesc: 'Kho gear riêng tư của bạn. Theo dõi những gì bạn có, đặt giá, và chia sẻ chọn lọc với người giao dịch.', + encrypted: 'Đã mã hóa', + syncsEverywhere: 'Đồng bộ mọi nơi', + p2pTrading: 'Giao dịch P2P', + encryptionRequired: 'Cần mã hóa', + encryptionRequiredDesc: 'Stash của bạn được mã hóa để riêng tư. Vui lòng dùng signer hỗ trợ mã hóa NIP-44 (như Alby, nos2x hoặc Amber).', + learnSigners: 'Tìm hiểu về Signer', + select: 'Chọn', + stash: 'Stash', + wishlist: 'Danh sách mong muốn', + allCategories: 'Mọi danh mục', + sortNewest: 'Mới nhất', + sortValue: 'Giá trị', + sortCondition: 'Tình trạng', + sortAz: 'A–Z', + friendsOnly: 'Chỉ bạn bè', + addToWishlist: 'Thêm vào danh sách mong muốn', + addItemToStash: 'Thêm món vào Stash', + addItem: 'Thêm món', + editItem: 'Sửa món', + publicStash: 'Stash công khai', + listView: 'Xem dạng danh sách', + gridView: 'Xem dạng lưới', + uploading: 'Đang tải lên...', + addPhotos: 'Thêm ảnh', + wishlistReqPlaceholder: 'Yêu cầu cụ thể nào...', + itemDescPlaceholder: 'Mô tả món, hư hỏng...', + itemsCount: '{{count}} món', + wishlistEmpty: 'Danh sách mong muốn trống', + wishlistEmptyDesc: 'Thêm gear bạn đang tìm — chúng tôi sẽ ghép bạn với stash của bạn bè.', + stashEmpty: 'Stash của bạn trống', + stashEmptyDesc: 'Bắt đầu theo dõi gear. Deck, truck, giày — thêm một lần, truy cập mọi nơi qua Nostr.', + noMatch: 'Không có món nào khớp', + noMatchDesc: 'Thử điều chỉnh bộ lọc.', + backupTransfer: 'Sao lưu & chuyển', + backupDesc: 'Stash của bạn được mã hóa trên Nostr. Giữ một bản bạn kiểm soát — relay chết hay tài khoản mới không thể làm mất danh sách gear.', + exportTitle: 'Sao lưu mã hóa', + exportDialogDesc: 'Lưu {{count}} món vào tệp. Mã hóa để tệp bị lộ không thành rò rỉ.', + modePassword: 'Mật khẩu', + modeKey: 'Khóa của tôi', + password: 'Mật khẩu', + confirmPassword: 'Xác nhận mật khẩu', + passwordHint: 'Dùng ít nhất 8 ký tự. Không có cách khôi phục — đừng quên.', + keyModeHint: 'Mã hóa bằng khóa Nostr của bạn. Chỉ khóa đó mở được — không cần nhớ gì.', + exportPlaintext: 'Xuất không mã hóa', + pwTooShort: 'Dùng ít nhất 8 ký tự.', + pwMismatch: 'Mật khẩu không khớp.', + exportFailed: 'Không thể tạo bản sao lưu.', + unlockTitle: 'Mở khóa bản sao lưu', + unlockDesc: 'Bản sao lưu này được bảo vệ bằng mật khẩu.', + unlock: 'Mở khóa', + unlockFailed: 'Không thể mở khóa bản sao lưu.', + show: 'Hiện', + hide: 'Ẩn', + strength: 'Độ mạnh mật khẩu', + strengthWeak: 'Yếu', + strengthFair: 'Tạm', + strengthGood: 'Tốt', + strengthStrong: 'Mạnh', + filenameWillSave: 'Sẽ lưu thành {{name}}', + export: 'Xuất', + import: 'Nhập', + exported: 'Đã xuất Stash', + exportedDesc: 'Đã lưu {{count}} món vào tệp.', + noItemsInFile: 'Không tìm thấy món nào trong tệp đó.', + noValidItems: 'Không tìm thấy món hợp lệ trong tệp đó.', + imported: 'Đã nhập {{count}} món', + importSkipped: '{{count}} bị bỏ qua (đã có trong stash).', + importAdded: 'Đã thêm vào stash.', + importFailed: 'Nhập thất bại', + couldNotRead: 'Không đọc được tệp đó.', + updateFailed: 'Không thể cập nhật stash', + updatedCount: 'Đã cập nhật {{count}} món', + markedForSale: 'Đã đánh dấu bán {{count}} món', + unmarkedCount: 'Đã bỏ đánh dấu {{count}}', + removedCount: 'Đã xóa {{count}} món', + selectedCount: 'Đã chọn {{count}}', + selectAll: 'Chọn tất cả', + visibilityPublic: 'Công khai', + visibilityPrivate: 'Riêng tư', + forSale: 'Đang bán', + remove: 'Xóa', + bulkDeleteTitle: 'Xóa {{count}} món?', + bulkDeleteDesc: 'Thao tác này viết lại stash đã mã hóa bằng một chữ ký và không thể hoàn tác ở đây. Hãy xuất sao lưu trước nếu chưa chắc.', + deleteTitle: 'Xóa khỏi stash?', + deleteDesc: '“{{title}}” sẽ bị xóa khỏi stash', + deleteDescPublic: ' và bỏ niêm yết khỏi gian hàng công khai', + deleteUndone: '. Không thể hoàn tác.', + deleteDescGeneric: 'Món này sẽ bị xóa khỏi stash. Không thể hoàn tác.', + listOnMarketplace: 'Đăng lên Chợ', + noPriceSet: 'Chưa đặt giá', + categoryLabel: 'Danh mục', + photosLabel: 'Ảnh', + willingToSell: 'Sẵn sàng bán', + willingToTrade: 'Sẵn sàng trao đổi', + whereIsThisItem: 'Món này ở đâu?', + visibilityLabel: 'Hiển thị', + visibilityPrivateOnlyYou: 'Riêng tư - Chỉ bạn', + visibilityFriendsMutual: 'Bạn bè - Theo dõi lẫn nhau', + visibilityPublicAnyone: 'Công khai - Mọi người', + visibilityFriends: 'Bạn bè', + brandLabel: 'Thương hiệu', + sizeLabel: 'Cỡ', + descriptionLabel: 'Mô tả', + conditionLabel: 'Tình trạng', + itemName: 'Tên món', + saveChanges: 'Lưu thay đổi', + listItemDialogTitle: 'Đăng "{{title}}"', + pickUpWhere: 'Người mua có thể nhận món này ở đâu?', + linkToSpot: 'Liên kết với một Skate Spot', + linkToSpotDesc: 'Tốt nhất cho bán địa phương • Hiện trên trang spot & bản đồ', + recommended: 'Khuyến nghị', + noSpecificSpot: 'Không có spot cụ thể', + noSpecificSpotDesc: 'Chỉ hiện trên trang Chợ', + tipLinkedSpots: '💡 Mẹo: Tin đăng liên kết với spot dễ tìm hơn cho skater địa phương.', + anyoneCanSee: 'Mọi người đều thấy những mục này trên hồ sơ của bạn.', + seeWhatOthersSee: 'Xem như người khác thấy', + inventory: 'Kho', + publicWantsNote: 'Mong muốn công khai được đăng lên Chợ dưới dạng tin "cần mua", để người bán tìm thấy bạn.', + howItWorks: 'Cách hoạt động', + tapToMarketplace: 'Nhấn để đến Chợ →', + viewWishlist: 'Xem danh sách mong muốn', + tipEditItems: 'Sửa món bằng nút bút', + tipListForSale: 'Đăng bán bằng nút cửa hàng', + tipAddPhotos: 'Thêm ảnh để nhận đề nghị trao đổi tốt hơn', + tipKeySyncs: 'Khóa Nostr đồng bộ mọi thiết bị', + itemsReadyToSell: '{{count}} món sẵn sàng bán', + }, + }, +}; export default viBatch4; diff --git a/src/i18n/vi/batch5.ts b/src/i18n/vi/batch5.ts index 7489991..12c0ea3 100644 --- a/src/i18n/vi/batch5.ts +++ b/src/i18n/vi/batch5.ts @@ -1,4 +1,1605 @@ -/** vi — batch 5. Filled by the translation pass; empty until then. */ -const viBatch5 = {}; +/** + * Vietnamese (Tiếng Việt) — batch 5: The Lab service directory (labUi) + social + * (socialUi): crew chat, DMs, collectives, coordinators and vouches. + * + * Protocol and brand names (The Lab, Nostr, Lightning, Zap, sats, DM, NWC, + * NIP-05, Cordn, ContextVM, Cashu) stay English; Coach, Filmer, Photographer, + * Editor, Builder, Crew, Spot stay English; trick names stay English. + * Placeholders ({{...}}) and markdown/URLs are preserved. + */ +const viBatch5 = { + labUi: { + activeCount: '{{count}} đang hoạt động', + addMusicProfile: 'Thêm hồ sơ âm nhạc', + all: 'Tất cả', + clearAll: 'Xóa tất cả', + collective: 'Tập thể', + filters: 'Bộ lọc', + following: 'Đang theo dõi', + getRiderCard: 'Nhận thẻ Rider', + judgeEvents: 'Chấm sự kiện', + justASkater: 'Chỉ là một', + labForServices: "The Lab dành cho các dịch vụ. Duyệt & tham gia toàn bộ cộng đồng skater", + loginToOffer: 'Đăng nhập để cung cấp dịch vụ', + newest: 'Mới nhất', + noResults: 'Không có kết quả', + offer: 'Cung cấp', + offerBuilding: 'Cung cấp Xây dựng', + offerCoaching: 'Cung cấp Coaching', + offerCuts: 'Cung cấp Cắt tóc', + offerDesignArt: 'Cung cấp Thiết kế / Nghệ thuật', + offerEditing: 'Cung cấp Dựng phim', + offerFilming: 'Cung cấp Quay phim', + offerGraffiti: 'Cung cấp Graffiti', + offerPhotography: 'Cung cấp Nhiếp ảnh', + offerServices: 'Cung cấp dịch vụ', + yourProfiles: 'Hồ sơ Lab của bạn', + preview: { + button: 'Xem trước', + title: 'Xem trước trực tiếp', + desc: 'Đây là cách hồ sơ {{noun}} của bạn sẽ hiển thị sau khi xuất bản.', + untitled: 'Tên của bạn', + noBio: 'Chưa có tiểu sử — thêm một dòng về những gì bạn cung cấp.', + years: '{{count}} năm kinh nghiệm', + portfolio: 'Portfolio', + note: 'Chỉ xem trước — chưa có gì được xuất bản.', + }, + draft: { + title: 'Bạn có bản nháp chưa lưu', + body: 'Tiếp tục từ chỗ bạn dừng lại — không có gì được xuất bản cho đến khi bạn nhấn Xuất bản.', + resume: 'Tiếp tục bản nháp', + discard: 'Bỏ bản nháp', + }, + progress: { + title: 'Độ hoàn thiện hồ sơ', + count: 'Đã xong {{done}} trên {{total}}', + photo: 'Ảnh', + bio: 'Tiểu sử', + skills: 'Kỹ năng', + rate: 'Giá', + location: 'Vị trí', + contact: 'Liên hệ', + }, + wizard: { + identity: 'Danh tính', + offer: 'Những gì bạn cung cấp', + rates: 'Giá cả', + contact: 'Liên hệ', + media: 'Phương tiện', + }, + offerTattoo: 'Cung cấp Xăm', + offerTraining: 'Cung cấp Huấn luyện / Vật lý trị liệu', + organizeEvents: 'Tổ chức sự kiện', + resultsMany: '{{count}} kết quả', + resultsOne: '{{count}} kết quả', + searchCityPlaceholder: 'Thành phố…', + searchNamePlaceholder: 'Tên, tiểu sử…', + showResults: 'Hiện kết quả', + showResultsActive: 'Hiện kết quả · {{count}} đang hoạt động', + skaterWord: 'skater', + sortBy: 'Sắp xếp theo', + theCrew: 'Crew', + topRated: 'Đánh giá cao nhất', + trusted: 'Đáng tin cậy', + trustLevel: 'Mức độ tin cậy', + yearsExp: '{{count}} năm kinh nghiệm', + tabCoaches: 'Coach', + tabFilmers: 'Filmer', + tabPhoto: 'Nhiếp ảnh', + tabEditors: 'Editor', + tabBuilders: 'Builder', + tabArtists: 'Nghệ sĩ', + tabGraffiti: 'Graffiti', + tabTattoo: 'Xăm', + tabTrainers: 'Huấn luyện viên', + tabMusic: 'Âm nhạc', + tabJudges: 'Giám khảo', + tabOrganizers: 'Ban tổ chức', + tabBarbers: 'Thợ cắt tóc', + filterSkillsToLearn: 'Kỹ năng muốn học', + filterContentType: 'Loại nội dung', + filterEquipmentStyle: 'Thiết bị & Phong cách', + filterServices: 'Dịch vụ', + filterCamera: 'Camera', + filterLenses: 'Ống kính', + filterLighting: 'Ánh sáng', + filterSupportRig: 'Hỗ trợ & Giá đỡ', + filterStyle: 'Phong cách', + filterWhatTheyBuild: 'Họ xây dựng gì', + filterMaterialsTrade: 'Vật liệu & Nghề', + filterProjectScale: 'Quy mô dự án', + filterWhatTheyMake: 'Họ làm gì', + filterMedium: 'Chất liệu', + filterSoftwareTools: 'Phần mềm & Công cụ', + filterWorkContext: 'Bối cảnh làm việc', + filterMethod: 'Phương pháp', + filterFocus: 'Trọng tâm', + filterInjuriesTreated: 'Chấn thương điều trị', + filterCredentialsSetting: 'Bằng cấp & Bối cảnh', + filterGenre: 'Thể loại', + filterInstrumentsRole: 'Nhạc cụ & Vai trò', + filterEventFormats: 'Định dạng sự kiện', + filterSpecialty: 'Chuyên môn', + filterLevelCircuit: 'Cấp độ / Giải đấu', + filterEventTypes: 'Loại sự kiện', + filterWhatYouHandle: 'Bạn đảm nhận gì', + filterScale: 'Quy mô', + filterWhatTheyOffer: 'Họ cung cấp gì', + filterSignatureStyles: 'Phong cách đặc trưng', + filterSetting: 'Bối cảnh', + filterEditType: 'Loại dựng phim', + role: { + coach: 'Coach', + filmer: 'Filmer', + builder: 'Builder', + editor: 'Editor', + photographer: 'Photographer', + skater: 'Skater', + }, + empty: { + footer: 'Có thắc mắc? Xem FAQ →', + loginSuffix: 'để tạo hồ sơ.', + coachesTitle: 'Chưa có Coach nào', + coachesBody: 'Hãy là người đầu tiên cung cấp dịch vụ huấn luyện skateboard trong khu vực của bạn.', + filmersTitle: 'Chưa có Filmer nào', + filmersBody: 'Hãy là người đầu tiên cung cấp dịch vụ quay phim skate — clip, full part, đưa tin cuộc thi và hơn thế nữa.', + photographersTitle: 'Chưa có Photographer nào', + photographersBody: 'Hãy là người đầu tiên cung cấp dịch vụ nhiếp ảnh skate trong khu vực của bạn — ảnh hành động, chuỗi ảnh, ảnh biên tập và hơn thế nữa.', + editorsTitle: 'Chưa có Editor nào', + editorsBody: 'Hãy là người đầu tiên cung cấp dịch vụ dựng video skate.', + buildersTitle: 'Chưa có Builder nào', + buildersBody: 'Hãy là người đầu tiên đăng dịch vụ xây dựng ramp, park hay DIY của bạn — bê tông, gỗ, thanh trượt và hơn thế nữa.', + artistsTitle: 'Chưa có nghệ sĩ nào', + artistsBody: 'Hãy là người đầu tiên cung cấp thiết kế ván, logo, poster và đồ lưu niệm cho cộng đồng.', + graffitiTitle: 'Chưa có nghệ sĩ graffiti nào', + graffitiBody: 'Hãy là người đầu tiên cung cấp tranh tường, mural và nghệ thuật skatepark trong khu vực của bạn.', + tattooTitle: 'Chưa có nghệ sĩ xăm nào', + tattooBody: 'Hãy là nghệ sĩ xăm văn hóa skate đầu tiên đăng ký — flash, thiết kế riêng, fine line và hơn thế nữa.', + trainersTitle: 'Chưa có huấn luyện viên nào', + trainersBody: 'Hãy là huấn luyện viên hay chuyên viên vật lý trị liệu đầu tiên giúp skater khỏe mạnh và bền bỉ.', + musiciansTitle: 'Chưa có nhạc sĩ nào', + musiciansBody: 'Vừa trượt ván vừa làm nhạc? Thêm ban nhạc hay dự án solo của bạn — thể loại, nhạc cụ và liên kết.', + judgesTitle: 'Chưa có giám khảo nào', + judgesBody: 'Bạn tổ chức cuộc thi công bằng? Hãy đăng ký làm giám khảo Game of S.K.A.T.E., best trick jam, cuộc thi và các điểm lưu diễn.', + organizersTitle: 'Chưa có ban tổ chức nào', + organizersBody: 'Bạn tổ chức jam, cuộc thi, buổi gặp mặt hay demo? Hãy đăng ký để skater có thể tìm và đặt bạn.', + barbersTitle: 'Chưa có thợ cắt tóc nào', + barbersBody: 'Bạn cắt tóc cho skater? Hãy đăng ghế hoặc dịch vụ lưu động để cộng đồng có được kiểu tóc mới.', + }, + become: { + addNip05: 'Thêm NIP-05 trong Cài đặt', + backToLab: 'Quay lại The Lab', + bioWorkLabel: 'Tiểu sử / Về công việc của bạn', + checkContact: 'Kiểm tra thông tin liên hệ của bạn', + cityArea: 'Thành phố / Khu vực', + cityCountry: 'Thành phố, Quốc gia', + connectWallet: 'Kết nối ví', + connectWalletNwc: 'Kết nối ví với NWC', + contactInfo: 'Thông tin liên hệ', + contactInfoDesc: 'Cách khách hàng liên hệ với bạn (tất cả đều tùy chọn, nhưng nên điền)', + coordinatesOptional: 'Tọa độ (tùy chọn)', + email: 'Email', + failedToPublish: 'Xuất bản thất bại', + fromNostrProfile: 'Từ hồ sơ Nostr của bạn', + geolocationUnsupported: 'Không hỗ trợ định vị', + getting: 'Đang lấy…', + headline: 'Tiêu đề', + headlineHint: 'Hiển thị làm tiêu đề trên thẻ Lab của bạn — ví dụ “{{example}}”. Mặc định là tên của bạn.', + imageUploaded: 'Đã tải ảnh lên', + instagram: 'Instagram', + invalidEmail: 'Nhập địa chỉ email hợp lệ.', + invalidPortfolio: 'Nhập URL portfolio hợp lệ.', + invalidWebsite: 'Nhập URL website hợp lệ.', + latitude: 'Vĩ độ', + learnHow: 'Tìm hiểu cách', + locationError: 'Lỗi vị trí', + locationFound: 'Đã tìm thấy vị trí', + loginRequired: 'Cần đăng nhập', + loginRequiredDesc: 'Bạn cần đăng nhập để tạo hồ sơ {{role}}.', + loginRequiredDescCraft: 'Bạn cần đăng nhập để tạo hồ sơ {{noun}}.', + longitude: 'Kinh độ', + nip05Recommended: 'Nên xác minh NIP-05', + nip05RecommendedDesc: 'Xác minh danh tính của bạn để tạo niềm tin với khách hàng.', + noWallet: 'Chưa kết nối ví', + otherSocial: 'Mạng xã hội khác', + paymentSetup: '⚡ Cần thiết lập thanh toán', + phoneNumber: 'Số điện thoại', + profilePhoto: 'Ảnh hồ sơ', + profilePublished: 'Hồ sơ của bạn đã được xuất bản.', + publishing: 'Đang xuất bản...', + socialMedia: 'Mạng xã hội', + tip: '💡 Mẹo: Hầu hết ví Lightning đều hỗ trợ NWC (Alby, Minibits, Zeus, Coinos).', + tipWithTime: '💡 Mẹo: Hầu hết ví Lightning đều hỗ trợ NWC (Alby, Minibits, Zeus, Coinos). Chỉ mất 30 giây để thiết lập.', + upload: 'Tải lên', + uploadFailed: 'Tải lên thất bại', + uploadImage: 'Tải ảnh lên', + uploading: 'Đang tải lên…', + useCurrentLocation: 'Dùng vị trí hiện tại', + useMyLocation: 'Dùng vị trí của tôi', + usingNwc: 'Đang dùng Nostr Wallet Connect', + usingWebln: 'Đang dùng tiện ích trình duyệt WebLN', + walletConnected: 'Đã kết nối ví — Sẵn sàng nhận thanh toán!', + website: 'Website', + yearsExperience: 'Số năm kinh nghiệm', + }, + coachForm: { + anonymous: 'Coach ẩn danh', + bioLabel: 'Tiểu sử / Triết lý huấn luyện', + bioPlaceholder: 'Nền tảng của bạn, phong cách giảng dạy...', + create: 'TẠO HỒ SƠ COACH', + created: 'Đã tạo hồ sơ Coach!', + createPro: 'TẠO HỒ SƠ COACH PRO', + dmNote: "💬 Học viên có thể nhắn tin trực tiếp cho bạn qua tính năng nhắn tin mã hóa của SkateSpots", + heading: 'Trở thành Coach', + headlineExample: 'Skate Coach Berlin', + hourlyRate: 'Giá theo giờ', + identity: 'Danh tính Coach của bạn', + nip05Reason: "Thêm mã định danh NIP-05 để xác minh danh tính và tạo niềm tin với học viên — điều đó cho thấy bạn là một Coach chính danh.", + paymentDesc: 'Để nhận thanh toán buổi học từ học viên, bạn cần kết nối ví Lightning. Học viên sẽ Zap trực tiếp cho bạn cho các buổi huấn luyện.', + profileDesc: 'Cho học viên biết về kinh nghiệm của bạn', + profileTitle: 'Hồ sơ Coach', + ratePlaceholder: '5000 sats/giờ', + selectSkill: 'Chọn ít nhất một kỹ năng.', + skillsLabel: 'Kỹ năng tôi dạy * (chọn ít nhất một)', + skillsRequired: 'Cần có kỹ năng', + formatsLabel: 'Hình thức buổi học', + formatsHint: 'Cách bạn truyền đạt huấn luyện.', + levelsLabel: 'Cấp độ giảng dạy', + agesLabel: 'Nhóm tuổi', + credentialsLabel: 'Bằng cấp & an toàn', + credentialsHint: 'Tự công bố — SkateSpots không xác minh những điều này.', + languagesLabel: 'Ngôn ngữ sử dụng', + languagesHint: 'Thêm những ngôn ngữ bạn có thể huấn luyện.', + languagePlaceholder: 'ví dụ: English, Español', + availabilityLabel: 'Thời gian rảnh', + bookingLabel: 'Liên kết đặt lịch', + bookingHint: 'Tùy chọn — trang để học viên đặt lịch và thanh toán.', + galleryLabel: 'Ảnh portfolio', + galleryHint: 'Cho thấy các buổi học, học viên và Spot thực tế (tối đa 12).', + galleryAdd: 'Thêm ảnh portfolio', + galleryUploaded: 'Đã tải lên {{count}} ảnh', + videoLabel: 'Video nổi bật', + videoHint: 'Tùy chọn — video YouTube hoặc Instagram về buổi huấn luyện của bạn.', + formatOneOnOne: '1 kèm 1', + formatGroup: 'Nhóm', + formatCamp: 'Trại', + formatVideo: 'Phân tích video', + formatContestPrep: 'Chuẩn bị cuộc thi', + formatParkLesson: 'Buổi học tại park', + formatAdaptive: 'Thích ứng', + formatGirls: 'Buổi học cho nữ', + formatAfterSchool: 'Sau giờ học', + levelBeginner: 'Mới bắt đầu', + levelIntermediate: 'Trung cấp', + levelAdvanced: 'Nâng cao', + levelCompetition: 'Thi đấu', + ageKids: 'Trẻ em', + ageTeens: 'Thiếu niên', + ageAdults: 'Người lớn', + ageSeniors: 'Người cao tuổi', + certFirstAid: 'Sơ cứu', + certCpr: 'CPR', + certSafeguarding: 'Bảo vệ trẻ em', + certBackgroundCheck: 'Kiểm tra lý lịch', + certInsured: 'Có bảo hiểm', + certFederation: 'Coach liên đoàn quốc gia', + certQualification: 'Chứng chỉ huấn luyện', + certJudge: 'Giám khảo cuộc thi', + certNoteLabel: 'Bằng cấp khác (tùy chọn)', + certNotePlaceholder: 'ví dụ: Skateboard GB Level 2, 8 năm huấn luyện…', + availWeekdays: 'Ngày trong tuần', + availWeekends: 'Cuối tuần', + availEvenings: 'Buổi tối', + availAfterSchool: 'Sau giờ học', + availHolidays: 'Kỳ nghỉ học', + availSeasonal: 'Theo mùa', + sectionWhatYouCoach: 'Bạn huấn luyện gì', + sectionCredentials: 'Bằng cấp & an toàn', + sectionAvailability: 'Thời gian rảnh & đặt lịch', + sectionWhereYouCoach: 'Bạn huấn luyện ở đâu', + sectionPortfolio: 'Portfolio', + rateAmountLabel: 'Giá', + rateCurrencySats: 'sats', + rateCurrencyUsd: 'USD', + rateCurrencyEur: 'EUR', + rateCurrencyGbp: 'GBP', + perHour: 'mỗi giờ', + perSession: 'mỗi buổi', + perHalfDay: 'mỗi nửa ngày', + perDay: 'mỗi ngày', + perCamp: 'mỗi trại', + perProject: 'mỗi dự án', + perEvent: 'mỗi sự kiện', + perGig: 'mỗi buổi diễn', + perShoot: 'mỗi buổi chụp', + perPiece: 'mỗi tác phẩm', + perCut: 'mỗi lần cắt', + perMonth: 'mỗi tháng', + availByAppointment: 'Theo hẹn', + rateNotesLabel: 'Ghi chú về giá (tùy chọn)', + rateNotesPlaceholder: 'Thang giá linh hoạt, buổi đầu miễn phí, đã gồm di chuyển…', + sectionPayments: 'Thanh toán', + paymentMethodsHint: 'Cách khách hàng thanh toán cho bạn. Đây chỉ là tuyên bố — SkateSpots không bao giờ giữ tiền.', + payMethodCash: 'Tiền mặt tại chỗ', + payMethodLightning: 'Lightning', + payMethodCashu: 'Cashu', + payMethodBank: 'Chuyển khoản ngân hàng', + payMethodOther: 'Khác', + payWhatYouCanLabel: 'Thang giá linh hoạt / trả tùy khả năng', + bookingFeeLabel: 'Phí đặt lịch (tùy chọn)', + bookingFeeHint: 'Một khoản phí nhỏ trả trực tiếp cho bạn để xác nhận đặt lịch. SkateSpots không giữ hay hoàn lại khoản này.', + paymentNoteLabel: 'Ghi chú thanh toán (tùy chọn)', + paymentNotePlaceholder: 'Buổi đầu miễn phí, đã gồm di chuyển, trả sau buổi học…', + spotsDesc: 'Chọn Spot nơi bạn cung cấp các buổi huấn luyện', + spotsLabel: 'Spot nơi bạn huấn luyện', + tagline: 'Chia sẻ kiến thức skateboard của bạn', + update: 'CẬP NHẬT HỒ SƠ COACH', + updated: 'Đã cập nhật hồ sơ Coach!', + }, + filmerForm: { + anonymous: 'Filmer ẩn danh', + bioPlaceholder: 'Nền tảng của bạn, phong cách, thiết bị...', + camerasLabel: 'Máy quay & Thiết bị * (chọn ít nhất một)', + create: 'TẠO HỒ SƠ QUAY PHIM', + created: 'Đã tạo hồ sơ quay phim!', + createPro: 'TẠO HỒ SƠ QUAY PHIM PRO', + dmNote: "💬 Khách hàng có thể nhắn tin trực tiếp cho bạn qua tính năng nhắn tin mã hóa của SkateSpots", + gearHelper: 'Liệt kê chính xác máy quay, ống kính và giá đỡ của bạn — skater quan tâm đến bộ thiết bị.', + gearLabel: 'Đồ nghề của bạn (tùy chọn)', + gearPlaceholder: 'ví dụ: Sony VX1000 + MK1 fisheye, Panasonic HVX200, gimbal DJI RS3, GoPro Hero 12, mic Sennheiser...', + heading: 'Trở thành Filmer', + headlineExample: 'Skate Filmer Berlin', + identity: 'Danh tính Filmer của bạn', + nip05Reason: "Thêm mã định danh NIP-05 để xác minh danh tính và tạo niềm tin với khách hàng — điều đó cho thấy bạn là một Filmer chính danh.", + paymentDesc: 'Để nhận thanh toán từ khách hàng cho dịch vụ quay phim, bạn cần kết nối ví Lightning. Khách hàng sẽ Zap trực tiếp cho bạn cho tác phẩm của bạn.', + profileDesc: 'Cho khách hàng biết về chuyên môn quay phim của bạn', + profileTitle: 'Hồ sơ Quay phim', + rate: 'Giá', + ratePlaceholder: '10000 sats/video', + reelLabel: 'Reel / Portfolio', + selectService: 'Chọn ít nhất một dịch vụ.', + selectSkill: 'Chọn ít nhất một kỹ năng quay phim.', + servicesLabel: 'Dịch vụ cung cấp * (chọn ít nhất một)', + servicesRequired: 'Cần có dịch vụ', + skillsRequired: 'Cần có kỹ năng', + spotsDesc: 'Chọn Spot nơi bạn cung cấp dịch vụ quay phim', + spotsLabel: 'Spot nơi bạn quay phim', + tagline: 'Cung cấp dịch vụ quay video skate của bạn — clip, line, full part & đưa tin cuộc thi', + update: 'CẬP NHẬT HỒ SƠ QUAY PHIM', + updated: 'Đã cập nhật hồ sơ quay phim!', + }, + editorForm: { + anonymous: 'Editor ẩn danh', + bioPlaceholder: 'Phong cách dựng phim, nền tảng, các dự án nổi bật…', + contactPortfolio: 'Liên hệ & Portfolio', + create: 'Xuất bản hồ sơ Editor', + created: 'Đã tạo hồ sơ Editor!', + createPro: 'Xuất bản hồ sơ Editor Pro', + editTypes: 'Loại dựng phim cung cấp * (chọn ít nhất một)', + hardware: 'Phần cứng', + hardwarePlaceholder: 'ví dụ: MacBook Pro M3, Sony FX3', + heading: 'Trở thành Editor', + headlineExample: 'Skate Video Editor', + identity: 'Danh tính của bạn', + locationOptional: 'Vị trí (tùy chọn)', + loginDesc: 'Đăng nhập để tạo hồ sơ Editor của bạn.', + phoneTelegram: 'Điện thoại / Telegram', + portfolioPlaceholder: 'Portfolio (Vimeo, YouTube…)', + profileDesc: 'Cho cộng đồng biết về phong cách và kỹ năng dựng phim của bạn', + profileTitle: 'Hồ sơ Editor', + published: 'Hồ sơ của bạn đã được xuất bản lên SkateSpots.', + rate: 'Giá / Báo giá', + ratePlaceholder: 'ví dụ: 50k sats/phút, DM để báo giá', + selectService: 'Chọn ít nhất một loại dựng phim.', + servicesRequired: 'Cần có dịch vụ', + socialPlaceholder: 'Instagram / tên mạng xã hội', + software: 'Phần mềm', + softwareHardware: 'Kỹ năng Phần mềm & Phần cứng', + softwarePlaceholder: 'ví dụ: DaVinci Resolve, Premiere', + tagline: 'Cung cấp dịch vụ dựng video của bạn cho cộng đồng skate', + thumbnail: 'Ảnh hồ sơ / Ảnh thu nhỏ showreel', + update: 'Cập nhật hồ sơ Editor', + updated: 'Đã cập nhật hồ sơ Editor!', + walletConnected: 'Đã kết nối ví ✓', + walletDesc: 'Nhận thanh toán Bitcoin ⚡ trực tiếp từ khách hàng cho công việc dựng phim của bạn.', + walletTitle: '⚡ Ví Lightning để nhận thanh toán', + yearsExperience: 'Số năm kinh nghiệm', + yearsPlaceholder: 'ví dụ: 5 năm', + }, + photoForm: { + anonymous: 'Photographer ẩn danh', + bioPlaceholder: 'Nền tảng của bạn, phong cách, điều bạn thích chụp...', + cameraLabel: 'Thân máy ảnh * (chọn ít nhất một)', + cameraRequired: 'Cần có máy ảnh', + contactDesc: 'Cách rider có thể xem tác phẩm và liên hệ với bạn (tất cả đều tùy chọn, nhưng nên điền)', + create: 'TẠO HỒ SƠ NHIẾP ẢNH', + created: 'Đã tạo hồ sơ nhiếp ảnh!', + createPro: 'TẠO HỒ SƠ NHIẾP ẢNH PRO', + dmNote: "💬 Rider có thể nhắn tin trực tiếp cho bạn qua tính năng nhắn tin mã hóa của SkateSpots", + gearHelper: 'Liệt kê chính xác thân máy, ống kính và đèn — rider rất thích biết bộ thiết bị.', + gearPlaceholder: 'ví dụ: Canon R6 II, 8-15mm fisheye, 70-200mm f/2.8, 2× Godox AD200, trigger từ xa, chân máy Manfrotto...', + heading: 'Trở thành Photographer', + headlineExample: 'Nhiếp ảnh Skate', + identity: 'Danh tính Photographer của bạn', + lensesLabel: 'Ống kính', + lightingLabel: 'Thiết bị ánh sáng', + nip05Reason: 'Thêm mã định danh NIP-05 để xác minh danh tính và tạo niềm tin với khách hàng.', + paymentDesc: 'Để được trả tiền cho các buổi chụp, hãy kết nối ví Lightning. Khách hàng Zap trực tiếp cho bạn cho tác phẩm của bạn.', + portfolioLabel: 'Portfolio / Instagram', + profileDesc: 'Cho rider biết về con mắt, thiết bị và dịch vụ của bạn', + profileTitle: 'Hồ sơ Nhiếp ảnh', + ratePlaceholder: '20000 sats/buổi chụp', + selectCamera: 'Chọn ít nhất một loại máy ảnh bạn dùng để chụp.', + selectService: 'Chọn ít nhất một dịch vụ bạn cung cấp.', + servicesLabel: 'Dịch vụ cung cấp * (chọn ít nhất một)', + servicesRequired: 'Cần có dịch vụ', + spotsDesc: 'Chọn Spot nơi bạn cung cấp dịch vụ nhiếp ảnh', + spotsLabel: 'Spot nơi bạn chụp ảnh', + styleLabel: 'Phong cách chụp', + supportLabel: 'Hỗ trợ & Giá đỡ', + tagline: 'Chụp các buổi trượt — cung cấp dịch vụ nhiếp ảnh skate của bạn', + update: 'CẬP NHẬT HỒ SƠ NHIẾP ẢNH', + updated: 'Đã cập nhật hồ sơ nhiếp ảnh!', + }, + builderForm: { + anonymous: 'Builder ẩn danh', + bioLabel: 'Tiểu sử / Về các công trình của bạn', + bioPlaceholder: 'Crew của bạn, các công trình nổi bật, cách bạn tiếp cận dự án...', + buildTypesLabel: 'Bạn xây dựng gì * (chọn ít nhất một)', + buildTypesRequired: 'Cần có loại công trình', + cityBase: 'Thành phố / Căn cứ', + contactPortfolio: 'Liên hệ & Portfolio', + contactPortfolioDesc: 'Cách cộng đồng có thể xem công trình và liên hệ với bạn (tất cả đều tùy chọn, nhưng nên điền)', + create: 'TẠO HỒ SƠ BUILDER', + created: 'Đã tạo hồ sơ Builder!', + createPro: 'TẠO HỒ SƠ BUILDER PRO', + dmNote: "💬 Khách hàng có thể nhắn tin trực tiếp cho bạn qua tính năng nhắn tin mã hóa của SkateSpots", + gearHelper: 'Crew và khách hàng rất thích biết thiết bị và quy trình của bạn.', + gearLabel: 'Cách bạn làm việc / Thiết bị (tùy chọn)', + gearPlaceholder: 'ví dụ: Đội bê tông đầy đủ, máy trộn + dàn phun bê tông riêng, hàn lưu động, chúng tôi lo giấy phép và thoát nước...', + heading: 'Trở thành Builder', + headlineExample: 'Thợ xây Ramp & Park', + identity: 'Danh tính Builder của bạn', + insured: 'Có giấy phép / Bảo hiểm', + insuredHelper: 'Quan trọng với công trình park công cộng & hội đồng', + logoPhoto: 'Logo / Ảnh', + materialsLabel: 'Vật liệu & Kỹ năng nghề', + nip05Reason: 'Thêm mã định danh NIP-05 để xác minh danh tính và tạo niềm tin với khách hàng.', + pastBuilds: 'Công trình đã làm / Instagram', + paymentDesc: 'Để được trả tiền cho các công trình, hãy kết nối ví Lightning. Khách hàng Zap trực tiếp cho bạn cho công việc của bạn.', + profileDesc: 'Cho cộng đồng biết bạn xây dựng gì và làm việc thế nào', + profileTitle: 'Hồ sơ Builder', + rateLabel: 'Giá / Cơ sở báo giá', + ratePlaceholder: 'mỗi m² / theo dự án', + scaleLabel: 'Quy mô dự án', + selectBuild: 'Chọn ít nhất một thứ bạn xây dựng.', + serviceArea: 'Khu vực phục vụ', + serviceAreaPlaceholder: 'ví dụ: Catalonia, sẽ đi khắp EU', + spotsDesc: 'Liên kết các Spot và park bạn đã xây để mọi người thấy công trình của bạn trên bản đồ', + spotsLabel: 'Spot bạn đã xây', + tagline: 'Đổ bê tông, hàn, xây dựng — đăng dịch vụ xây ramp & park của bạn', + update: 'CẬP NHẬT HỒ SƠ BUILDER', + updated: 'Đã cập nhật hồ sơ Builder!', + yearsBuilding: 'Số năm xây dựng', + }, + skaterForm: { + backToSkaters: 'Quay lại Skater', + bioHelperPulled: 'Lấy từ hồ sơ của bạn — chỉnh cho thẻ skater của bạn, hoặc để nguyên.', + bioHelperShort: 'Giới thiệu ngắn cho thẻ skater của bạn.', + bioPlaceholder: 'Bạn trượt đã bao lâu, bạn thích gì, đang luyện gì…', + browseSpots: 'Duyệt Spot', + changePhoto: 'Đổi ảnh hồ sơ', + chipBio: 'Tiểu sử', + chipPhoto: 'Ảnh', + cityArea: 'Thành phố / khu vực', + created: 'Bạn đã lên bản đồ! 🛹', + custom: 'Tùy chỉnh', + customHelper: 'Nhãn của riêng bạn — hiển thị trên thẻ skater thay cho mặc định.', + customPlaceholder: 'ví dụ: OG, Weekend Warrior, Retired…', + discoverable: 'Skater khác giờ có thể tìm thấy bạn.', + editFullProfile: 'chỉnh sửa toàn bộ hồ sơ của bạn', + fromProfile: 'Từ hồ sơ của bạn', + heroEditPrefix: 'Chỉnh sửa', + heroJoinPrefix: 'Tham gia', + heroSuffix: 'Danh bạ', + homeHelper: 'Nhập tự do, hoặc liên kết một Spot thật từ bản đồ để mọi người có thể đến đó.', + homePlaceholder: 'Park / quảng trường địa phương — hoặc nhấn “Duyệt Spot”', + homeSpot: 'Spot nhà', + layerEnd: 'để thay đổi chúng ở mọi nơi.', + layerIntro: 'Đây là', + layerMid: ', được xây trên hồ sơ Nostr của bạn. Tên, ảnh, tiểu sử, lightning & xác minh đến từ đó —', + layerWord: 'lớp skate', + level: 'Cấp độ', + linked: 'Đã liên kết với một Spot trên bản đồ', + loadingProfile: 'Đang tải hồ sơ của bạn…', + loadingSpots: 'Đang tải Spot…', + locationHelper: 'Giúp người khác tìm skater gần họ. Chỉ khu vực thô được chia sẻ.', + loginToJoin: 'Đăng nhập để tham gia', + loginToJoinDesc: 'Tạo hồ sơ skater để cộng đồng có thể tìm thấy bạn.', + mappedSpot: 'Spot trên bản đồ', + noSpots: 'Chưa tìm thấy Spot nào.', + noSpotsMatch: 'Không có Spot nào khớp tìm kiếm của bạn.', + openMap: 'Mở bản đồ', + pickEverything: 'Chọn mọi thứ phù hợp với phong cách của bạn.', + pickHomeSpot: 'Chọn Spot nhà của bạn', + pickStyles: 'Chọn phong cách của bạn', + pickStylesDesc: 'Chọn ít nhất một thứ bạn trượt.', + profilePic: 'Ảnh hồ sơ', + profilePicHelper: 'Thẻ skater của bạn dùng ảnh hồ sơ Nostr — cùng một ảnh ở mọi nơi.', + publishingAs: 'Xuất bản với tên', + putOnMap: 'Đưa tôi lên bản đồ', + searchSpots: 'Tìm Spot theo tên hoặc thành phố…', + skateStory: 'Câu chuyện skate của bạn', + stance: 'Tư thế', + unlinkSpot: 'Bỏ liên kết Spot', + updateButton: 'Cập nhật hồ sơ của tôi', + updated: 'Đã cập nhật hồ sơ!', + whatYouSkate: 'Bạn trượt gì *', + yearsPlaceholder: 'ví dụ: 8', + yearsSkating: 'Số năm trượt', + yourProfilePic: 'Ảnh hồ sơ của bạn', + zapsOn: 'Bật Zap', + }, + skaters: { + clearSearch: 'Xóa tìm kiếm', + community: 'Cộng đồng', + countMany: 'skater', + countOne: 'skater', + editProfile: 'Chỉnh sửa hồ sơ skater của tôi', + heroDesc: 'Tìm đồng đội của bạn. Duyệt đội ngũ skater đại diện SkateSpots — theo phong cách, tư thế, cấp độ và thành phố.', + nip05Verified: 'Đã xác minh NIP-05', + noMatches: 'Không có kết quả', + noneDesc: 'Hãy là người đầu tiên tham gia danh bạ và đưa SkateSpots lên bản đồ.', + noneTitle: 'Chưa có skater nào', + noVerifiedMatch: 'Không có skater đã xác minh nào khớp', + searchPlaceholder: 'Tìm theo tên, thành phố hoặc npub…', + tryDifferentSearch: 'Thử tìm kiếm khác hoặc xóa bộ lọc.', + tryTurnOffVerified: 'Thử tắt bộ lọc “Đã xác minh” để xem mọi người.', + verifiedFilterTitle: 'Chỉ hiện skater có danh tính NIP-05 đã xác minh', + }, + skaterCard: { + inDirectory: 'Bạn đã có trong Danh bạ Skater', + joinDesc: 'Thêm tư thế, phong cách & cấp độ để skater tìm thấy bạn.', + joinTitle: 'Tham gia Danh bạ Skater', + }, + crewsStrip: { + allCrews: 'Tất cả Crew', + memberMany: '{{count}} thành viên', + memberOne: '{{count}} thành viên', + title: 'Crew trong cộng đồng này', + }, + labLink: { + coach: 'Coach', + filmer: 'Filmer', + editor: 'Editor', + photographer: 'Photographer', + builder: 'Builder', + artist: 'Nghệ sĩ', + graffiti: 'Graffiti', + tattoo: 'Xăm', + trainer: 'Huấn luyện viên', + musician: 'Nhạc sĩ', + judge: 'Giám khảo', + barber: 'Thợ cắt tóc', + organizer: 'Ban tổ chức', + lab: 'Lab', + linkedProfiles: 'Hồ sơ Lab đã liên kết', + desc: 'Bạn cũng điều hành studio, dịch vụ huấn luyện hay xây dựng? Liên kết các trang Lab của bạn để mọi người có thể thuê crew của bạn. Tùy chọn. Khi hồ sơ Lab cũng liên kết ngược lại crew này, cả hai sẽ hiện huy hiệu xanh', + descEnd: '.', + empty: 'Bạn chưa có hồ sơ Lab nào. Tạo một cái trong The Lab để liên kết tại đây.', + }, + proUpgrade: { + goPro: 'Nâng cấp Pro', + optional: '· tùy chọn', + freeTo: 'Đăng miễn phí. Pro thêm', + proBadge: 'huy hiệu Pro', + featuredPlacement: 'vị trí nổi bật', + atTop: 'ở đầu The Lab.', + active: 'Đang hoạt động', + benefit1: 'Huy hiệu "Pro" vàng trên hồ sơ & thẻ của bạn', + benefit2: 'Được ưu tiên hiển thị khi skater duyệt The Lab', + benefit3: 'Ủng hộ SkateSpots — không quảng cáo, không trung gian', + platformOwner: 'Chủ nền tảng — Pro luôn bật.', + proActiveOne: 'Pro đang hoạt động · còn {{count}} ngày. Hồ sơ của bạn sẽ được nổi bật.', + proActiveMany: 'Pro đang hoạt động · còn {{count}} ngày. Hồ sơ của bạn sẽ được nổi bật.', + context: 'Hồ sơ của bạn vẫn hoạt động miễn phí sau khi Pro hết hạn — bạn chỉ mất huy hiệu & ưu tiên.', + }, + profilePreview: { + viewPublic: 'Xem công khai', + unnamed: 'Skater chưa có tên', + noHandle: 'Chưa có tên định danh', + }, + pyramid: { + pyramidWord: 'KIM TỰ THÁP', + rankingsWord: 'BẢNG XẾP HẠNG', + subtitle: 'Những người đóng góp hàng đầu ở thành phố của bạn', + yourRank: 'Thứ hạng của bạn', + keepContributing: 'Tiếp tục đóng góp để leo cao hơn!', + topContributors: 'Người đóng góp hàng đầu', + noContributors: 'Chưa có người đóng góp nào. Hãy là người đầu tiên thêm Spot hoặc tạo sự kiện!', + spots: 'Spot', + events: 'Sự kiện', + total: 'Tổng', + trust: 'Tin cậy', + }, + detail: { + joined: 'Đã tham gia', + about: 'Giới thiệu', + howWeWork: 'Cách chúng tôi làm việc', + inTheBag: 'Đồ nghề', + hardware: 'Phần cứng', + software: 'Phần mềm', + eventsJudged: 'Sự kiện đã chấm', + eventsOrganized: 'Sự kiện đã tổ chức', + spots: 'Spot', + viewSpot: 'Xem Spot', + credentialsTitle: 'Bằng cấp & an toàn', + selfAttested: 'Do Coach tự công bố — SkateSpots không xác minh.', + formats: 'Hình thức', + levels: 'Cấp độ', + ages: 'Độ tuổi', + languages: 'Ngôn ngữ', + availability: 'Thời gian rảnh', + bookSession: 'Đặt một buổi', + portfolio: 'Portfolio', + watchReel: 'Xem trên {{platform}}', + paymentsTitle: 'Thanh toán', + payWhatYouCan: 'Trả tùy khả năng', + bookingFee: 'Phí đặt lịch', + payBookingFee: 'Trả phí đặt lịch', + bookingFeeNote: 'Trả trực tiếp cho Coach. SkateSpots không giữ hay hoàn lại.', + bookingFeeNoRail: 'Coach này chưa đặt địa chỉ Lightning, nên không thể thanh toán trong ứng dụng — hãy liên hệ họ để sắp xếp thanh toán.', + serviceArea: 'Khu vực phục vụ', + licensedInsured: 'Có giấy phép / Bảo hiểm', + studio: 'Studio', + shopStudio: 'Cửa hàng / Studio', + booksOpen: 'Đang nhận lịch', + credentials: 'Bằng cấp', + remoteOnline: 'Có thể từ xa / Trực tuyến', + graffitiCrew: 'Crew Graffiti', + act: 'Tiết mục', + listen: 'Nghe', + upcomingGigs: 'Buổi diễn sắp tới', + past: 'Đã qua', + experience: 'Kinh nghiệm', + yearsCount: '{{count}} năm', + rate: 'Giá', + contact: 'Liên hệ', + sendMessage: 'Gửi tin nhắn', + bookGig: 'Đặt buổi diễn', + portfolioDomain: 'Portfolio · {{domain}}', + manage: 'Quản lý', + admin: 'Quản trị', + editProfile: 'Chỉnh sửa hồ sơ', + publishedTitle: 'Bạn đã lên sóng', + publishedBody: 'Hồ sơ của bạn đã được xuất bản lên The Lab. Chia sẻ để skater có thể tìm thấy bạn.', + manageRemove: 'Xóa hồ sơ {{noun}} của bạn khỏi The Lab.', + adminTakeDown: 'Gỡ hồ sơ {{noun}} này. Nó sẽ bị ẩn trên toàn SkateSpots.', + entityLabel: 'hồ sơ {{noun}}', + deleteProfile: 'Xóa hồ sơ', + location: 'Vị trí', + servicesSkills: 'Dịch vụ & Kỹ năng', + noun: { + coach: 'Coach', + filmer: 'Filmer', + editor: 'Editor', + photographer: 'Photographer', + builder: 'Builder', + artist: 'nghệ sĩ', + graffiti: 'nghệ sĩ graffiti', + tattoo: 'nghệ sĩ xăm', + trainer: 'huấn luyện viên', + musician: 'nhạc sĩ', + judge: 'giám khảo sự kiện', + organizer: 'ban tổ chức sự kiện', + barber: 'thợ cắt tóc', + profile: 'hồ sơ', + }, + skillsTitle: { + skills: 'Kỹ năng', + servicesGear: 'Dịch vụ & Thiết bị', + whatWeBuild: 'Chúng tôi xây gì', + whatTheyMake: 'Họ làm gì', + stylesWork: 'Phong cách & Tác phẩm', + styles: 'Phong cách', + focusSpecialties: 'Trọng tâm & Chuyên môn', + genresInstruments: 'Thể loại & Nhạc cụ', + formatsSpecialties: 'Hình thức & Chuyên môn', + servicesStyles: 'Dịch vụ & Phong cách', + eventTypesServices: 'Loại sự kiện & Dịch vụ', + }, + }, + rider: { + heroDesc: 'Danh tính skater có thể xác minh của bạn. Ký bằng Nostr, sẵn sàng in, không thể làm giả.', + heroDesc2: 'Nhận huy hiệu kỹ năng có chứng kiến từ skater khác. Nhận thẻ vào park. Chia sẻ thẻ của bạn ở mọi nơi.', + headerTagline: 'Ký bằng Nostr · Sẵn sàng in · Xác minh bằng QR', + tabCard: 'Thẻ của tôi', + tabBadges: 'Huy hiệu', + tabAward: 'Trao tặng', + rendering: 'Đang kết xuất…', + shareCard: 'Chia sẻ thẻ', + savePng: 'Lưu PNG', + print: 'In', + copyId: 'Sao chép ID', + cardType: 'Loại thẻ', + licenseLabel: 'Giấy phép Skater', + licenseSub: 'Danh tính rider cá nhân của bạn', + parkLabel: 'Vào Park', + parkSub: 'Phát thẻ với tư cách chủ park', + theme: 'Chủ đề', + holoTitle: 'Ánh kim Holographic', + holoDesc: 'Hiệu ứng lá kim động', + cardDetails: 'Chi tiết thẻ', + skateStyle: 'Phong cách Skate', + ridesFor: 'Trượt cho', + ridesForPlaceholder: 'Cửa hàng địa phương…', + sponsors: 'Nhà tài trợ', + sponsorsPlaceholder: 'Thương hiệu…', + showOnCard: 'Hiện trên thẻ', + zaps: 'Zap ⚡', + skills: 'Kỹ năng', + selected: 'Đã chọn {{count}}/6', + goldBadgesHint1: 'Huy hiệu vàng trên thẻ đến từ skater khác chứng kiến bạn — xem', + goldBadgesHint2: '.', + parkOwnersOnly: 'Chỉ dành cho chủ park.', + parkOwnersDesc: 'Phát thẻ này bằng đúng khóa Nostr đã xuất bản trang park của bạn. Ai cũng có thể quét QR và xác minh chữ ký trên chuỗi — không cần cơ quan trung ương.', + parkDetails: 'Chi tiết Park', + parkName: 'Tên Park', + parkNamePlaceholder: 'The Berrics…', + riderName: 'Tên Rider', + riderNamePlaceholder: 'Tên trên thẻ', + riderNpub: 'Nostr ID của Rider (npub)', + accessLevel: 'Mức truy cập', + validThru: 'Có hiệu lực đến', + publishToNostr: 'Xuất bản lên Nostr', + badgesIntro: 'Những huy hiệu này được skater khác chứng kiến và ký trên Nostr. Chúng hiện dưới dạng chip vàng ⭐ trên thẻ của bạn.', + earnMore: 'Muốn kiếm thêm? Hãy trượt trước mặt ai đó và nhờ họ chứng kiến trick của bạn.', + awardSomeone: 'Trao huy hiệu cho người khác', + youSawIt: 'Bạn đã tận mắt thấy', + youSawItDesc: 'Ký bằng chứng trên Nostr. Nó trở thành một phần hồ sơ vĩnh viễn của họ — gắn chặt bằng mật mã với khóa của bạn.', + skillsWitnessed: 'Kỹ năng bạn đã chứng kiến', + whereSeen: 'Bạn thấy ở đâu?', + optional: '(tùy chọn)', + signingOnNostr: 'Đang ký trên Nostr…', + awardBadge: 'Trao huy hiệu', + addRiderSkill: 'Thêm npub rider + ít nhất một kỹ năng', + invalidNpub: 'npub không hợp lệ', + badgeAwarded: '🏅 Đã trao huy hiệu!', + badgeSent: 'Đã gửi {{skills}}.', + failed: 'Thất bại', + couldNotRender: 'Không thể kết xuất thẻ', + popupBlocked: 'Popup bị chặn', + popupBlockedDesc: 'Cho phép popup cho trang này.', + linkCopied: '🔗 Đã sao chép liên kết!', + enterRiderNpub: 'Nhập npub của rider', + parkPublished: '✅ Đã xuất bản thẻ Vào Park!', + publishFailed: 'Xuất bản thất bại', + noBadges: 'Chưa có huy hiệu nào. Hãy trượt trước mặt ai đó và nhờ họ chứng kiến trick của bạn!', + showMore: 'Hiện thêm {{count}}', + witnessedBy: 'Được chứng kiến bởi', + at: 'tại', + previewLicense: 'Giấy phép Skater', + previewSince: 'Từ {{year}}', + previewEvts: 'Sự kiện', + previewScan: 'Quét để xác minh', + previewSkatepark: 'Skatepark', + previewAccessPass: 'Thẻ vào', + previewMemberName: 'Tên thành viên', + previewIssuedBy: 'Phát bởi chủ park · Ký bằng Nostr', + previewValidThru: 'Có hiệu lực đến', + previewNostrVerified: 'Đã xác minh Nostr', + }, + craftFields: { + detailsTitle: 'Chi tiết bổ sung', + deliverables: 'Sản phẩm bàn giao', + turnaround: 'Thời gian hoàn thành', + surfaces: 'Bề mặt / Tường', + maxSize: 'Kích thước tối đa', + setLength: 'Thời lượng set', + techRider: 'Yêu cầu kỹ thuật', + travel: 'Di chuyển', + certifications: 'Chứng nhận', + insurance: 'Bảo hiểm', + permits: 'Giấy phép', + deposit: 'Đặt cọc', + minimum: 'Tối thiểu', + modalities: 'Hình thức', + duration: 'Thời lượng hẹn', + drone: 'Drone', + leadTime: 'Thời gian chờ', + warranty: 'Bảo hành', + }, + craftForm: { + profileImage: 'Ảnh hồ sơ', + nameHeadline: 'Tên / tiêu đề', + about: 'Giới thiệu', + aboutPlaceholder: 'Cho skater biết về công việc {{noun}} của bạn…', + required: 'bắt buộc', + nip05Title: 'Thêm NIP-05 để tạo niềm tin', + nip05Desc: 'Mã định danh NIP-05 giúp skater xác minh bạn là người thật. Rất nên có trước khi đăng.', + editingNote: 'Đang chỉnh sửa hồ sơ {{noun}} hiện có — xuất bản sẽ thay thế nó.', + location: 'Vị trí', + pinned: '📍 Đã ghim lên bản đồ ({{lat}}, {{lng}})', + experienceYears: 'Kinh nghiệm (năm)', + expPlaceholder: 'ví dụ: 5', + ratePlaceholder: 'ví dụ: 20k sats / theo dự án', + contactLinks: 'Liên hệ & Liên kết', + phoneOptional: 'Điện thoại (tùy chọn)', + emailOptional: 'Email (tùy chọn)', + socialPlaceholder: 'Mạng xã hội (Instagram, v.v.)', + gettingPaid: 'Nhận thanh toán', + updateProfile: 'Cập nhật hồ sơ', + publishProfile: 'Xuất bản hồ sơ', + rateLeftBlankNote: 'Tùy chọn — để trống nếu mức giá ở trên đã đủ.', + sectionRequired: 'Cần có {{section}}', + sectionRequiredDesc: 'Chọn ít nhất một tùy chọn trong "{{section}}".', + updated: 'Đã cập nhật hồ sơ!', + created: 'Đã tạo hồ sơ!', + headlineExample: 'Skate Coach Berlin', + }, + }, + socialUi: { + agentPanel: { + spot: 'Spot', + event: 'Sự kiện', + labPro: 'Lab pro', + gear: 'Đồ nghề', + crew: 'Crew', + description: 'Biết rõ Crew này — các jam, đội hình & lời kêu gọi — cùng toàn cảnh cộng đồng với dữ liệu trực tiếp.', + greeting: 'Chào! Tôi là Sasquatch, hướng dẫn viên của {{crew}}. Hỏi tôi về Crew — jam tiếp theo, ai điều hành, chúng tôi đang tìm gì — hoặc toàn cảnh cộng đồng.', + suggestion1: 'Jam tiếp theo của chúng ta là gì?', + suggestion2: 'Ai điều hành Crew này?', + suggestion3: 'Chúng ta đang tìm gì?', + suggestion4: 'Spot tốt nhất gần chúng ta?', + suggestion5: 'Thời tiết để trượt thế nào?', + thinking: 'Sasquatch đang suy nghĩ…', + placeholder: 'Hỏi về cộng đồng địa phương của bạn…', + disclaimer: 'AI có thể sai — liên kết dẫn đến trang thật.', + }, + badge: { + upcomingOne: '{{count}} sự kiện sắp tới', + upcomingMany: '{{count}} sự kiện sắp tới', + comingOne: '{{count}} sự kiện sắp diễn ra', + comingMany: '{{count}} sự kiện sắp diễn ra', + }, + bell: { + youAreIn: 'Bạn đã ở trong {{crew}}! 🛹', + membershipConfirmed: 'Đã xác nhận thành viên.', + couldNotConfirm: 'Không thể xác nhận', + addedYouTo: 'đã thêm bạn vào', + confirmToAppear: 'Xác nhận để xuất hiện như một thành viên.', + notifications: 'Thông báo', + notificationsNew: 'Thông báo ({{count}} mới)', + unreadCount: '{{count}} thông báo chưa đọc', + markRead: 'Đánh dấu đã đọc', + allClear: 'Đã xem hết', + tabAll: 'Tất cả', + tabTrades: 'Giao dịch', + tabSocial: 'Xã hội', + tabNews: 'Tin tức', + tabCrews: 'Crew', + checkingUpdates: 'Đang kiểm tra cập nhật…', + checkingTrades: 'Đang kiểm tra ưu đãi và giao dịch…', + loadingDrops: 'Đang tải các bản tin mới nhất…', + emptyAll: 'Ưu đãi, giao dịch, zap, trả lời, bản tin và hoạt động Crew sẽ xuất hiện ở đây.', + emptyTrades: 'Ưu đãi, phản đề xuất và xác nhận giao dịch đều ở đây — dù bạn đang bán, mua hay trao đổi.', + emptySocial: 'Zap, cảm xúc, đăng lại, nhắc đến, trả lời, RSVP sự kiện và cập nhật từ host đều ở đây.', + emptyNews: 'Bản tin SkateSpots sẽ xuất hiện ở đây. Đăng ký tại trang Newsletter.', + emptyCrews: 'Lời mời Crew, yêu cầu tập thể và yêu cầu thành viên sẽ xuất hiện ở đây.', + subscribeBanner: 'Đăng ký để nhận bản tin mới trong chuông', + read: 'Đọc', + allCaughtUp: 'Bạn đã xem hết', + }, + chat: { + hidden: 'Đã ẩn', + hideMessageAria: 'Ẩn tin nhắn này', + hideMessageTitle: 'Ẩn tin nhắn (quản trị)', + messageHidden: 'Đã ẩn tin nhắn', + messageHiddenDesc: 'Đã ẩn khỏi chat Crew cho mọi người.', + messageHideFailed: 'Không thể ẩn tin nhắn', + encryptionUnavailable: 'Không khả dụng mã hóa', + encryptionUnavailableDesc: 'Trình ký của bạn không hỗ trợ mã hóa NIP-44. Vui lòng cập nhật tiện ích.', + messageFailed: 'Gửi tin nhắn thất bại', + couldNotSend: 'Không thể gửi tin nhắn.', + noOneToMessage: 'Chưa có ai để nhắn', + noOneToMessageDesc: 'Crew này không có thành viên nào khác để trò chuyện.', + subject: 'Chat Crew {{crew}}', + title: 'Chat Crew', + cordnBadgeTitle: 'Định tuyến qua điều phối viên Cordn của Crew này qua ContextVM. Mã hóa đầu cuối.', + private: 'Riêng tư', + privateBadgeTitle: 'Mã hóa đầu cuối — chỉ thành viên Crew đọc được những tin nhắn này.', + encryptedCordn: 'Đã mã hóa & định tuyến qua điều phối viên Crew (Cordn) — không tin nhắn nào đến relay công khai.', + encryptedNip17: 'Chat nhóm mã hóa cho người sáng lập & tất cả thành viên Crew được liệt kê.', + moderatorNote: ' Bạn có thể ẩn tin nhắn khỏi Crew với tư cách kiểm duyệt viên.', + loginToSee: 'Đăng nhập để xem bạn có thể tham gia chat Crew không.', + membersOnly: 'Chat này riêng tư cho thành viên Crew. Nhờ người sáng lập thêm bạn vào Crew để tham gia trò chuyện.', + noMessages: 'Chưa có tin nhắn nào. Hãy bắt đầu chat Crew — lên kế hoạch buổi trượt, chia sẻ Spot, khuấy động một clip.', + newMessages: 'Tin nhắn mới', + new: 'Mới', + placeholder: 'Nhắn cho Crew của bạn…', + sendAria: 'Gửi tin nhắn', + }, + collectiveJoinRequest: { + addedTitle: 'Đã thêm {{name}} vào {{collective}} 🛹', + addedDesc: 'Họ sẽ xác nhận từ phía họ để xuất hiện như thành viên đã xác minh.', + couldNotAdd: 'Không thể thêm thành viên', + couldNotDismiss: 'Không thể bỏ qua', + addedDone: 'Đã thêm', + addedTo: 'vào', + dismissedDone: 'Đã bỏ qua yêu cầu từ {{name}}', + wantsToJoin: 'muốn tham gia', + alreadyOnRoster: 'Đã có trong danh sách', + openCollective: 'Mở tập thể', + dismiss: 'Bỏ qua', + addToCollective: 'Thêm vào tập thể', + }, + collectiveMembers: { + confirmed: 'Đã xác nhận', + pending: 'Đang chờ', + pendingTooltip: 'Được tập thể liệt kê — đang chờ thành viên này xác nhận.', + crewOnly: 'Chỉ Crew', + crewOnlyTooltip: 'Thành viên này chọn chỉ hiển thị với đồng đội Crew. Bạn thấy họ vì bạn ở trong Crew.', + hiddenMember: 'Thành viên ẩn', + title: 'Thành viên', + verifiedOf: '{{confirmed}} trên {{total}} đã xác minh — mỗi thành viên đã xác nhận đều ký bằng khóa Nostr của riêng họ.', + verifiedPerMember: 'Tư cách thành viên được xác minh theo từng người. Mỗi thành viên xác nhận bằng khóa Nostr của riêng họ.', + adminsOne: '{{count}} quản trị viên giúp điều hành Crew.', + adminsMany: '{{count}} quản trị viên giúp điều hành Crew.', + }, + confirmMembership: { + public: 'Công khai', + crewOnly: 'Chỉ Crew', + confirmedTitle: 'Đã xác nhận thành viên!', + confirmedCrew: 'Bạn đã được xác minh trong {{name}} — chỉ hiển thị với đồng đội Crew.', + confirmedPublic: 'Bạn giờ hiển thị như thành viên đã xác minh của {{name}}.', + failed: 'Xác nhận thất bại', + addedTo: 'Bạn đã được thêm vào {{name}}', + addedDesc: 'Xác nhận tư cách thành viên để nó hiển thị là đã xác minh trên hồ sơ của bạn và của họ.', + yourVisibility: 'Chế độ hiển thị của bạn', + confirming: 'Đang xác nhận…', + confirmButton: 'Xác nhận thành viên', + }, + contacts: { + message: 'Nhắn tin', + removePrivate: 'Xóa khỏi danh bạ riêng tư', + savePrivate: 'Lưu vào danh bạ riêng tư', + seoTitle: 'Danh bạ - SkateSpots', + seoDescription: 'Cộng đồng của bạn — đồng đội Crew, người bạn theo dõi và các cuộc trò chuyện gần đây, với danh bạ riêng tư mã hóa.', + encryptionUnavailableDesc: 'Trình ký của bạn không hỗ trợ mã hóa NIP-44.', + removed: 'Đã xóa khỏi danh bạ riêng tư', + saved: 'Đã lưu vào danh bạ riêng tư', + savedDesc: 'Chỉ bạn mới thấy danh sách này.', + updateFailed: 'Không thể cập nhật danh bạ', + loginTitle: 'Cộng đồng của bạn, ở một nơi', + loginDesc: 'Đăng nhập để thấy đồng đội Crew, người bạn theo dõi và các cuộc trò chuyện gần đây — và giữ một danh bạ riêng tư, mã hóa.', + title: 'Danh bạ', + subtitle: 'Cộng đồng của bạn — đồng đội Crew, theo dõi & trò chuyện', + filterPlaceholder: 'Lọc theo npub…', + tabCrew: 'Crew', + tabFollows: 'Đang theo dõi', + tabDms: 'DM', + tabSaved: 'Đã lưu', + emptyCrewmates: 'Chưa có đồng đội Crew. Tham gia hoặc tạo một Crew để xây mạng lưới cộng đồng của bạn.', + emptyFollowing: 'Bạn chưa theo dõi ai.', + emptyDms: 'Chưa có cuộc trò chuyện nào. Nhắn cho một skater để bắt đầu.', + savedHint: 'Danh sách này được mã hóa bằng khóa của bạn — chỉ bạn đọc được. Nhấn ngôi sao ở người bất kỳ để thêm họ.', + emptySaved: 'Chưa có liên hệ nào được lưu. Đánh dấu sao cho mọi người từ bất kỳ tab nào để xây danh bạ riêng của bạn.', + }, + conversation: { + unknown: 'Không rõ', + seoTitle: 'Chat với {{name}} - SkateSpots', + seoDescription: 'Cuộc trò chuyện riêng tư đã mã hóa', + sendFailed: 'Gửi tin nhắn thất bại', + sendFailedDesc: 'Vui lòng thử lại sau giây lát.', + tradeConfirmed: 'Đã xác nhận giao dịch', + tradeConfirmedDesc: 'Uy tín đã được cập nhật cho cả hai bạn.', + tradeConfirmFailed: 'Không thể xác nhận giao dịch', + somethingWrong: 'Đã xảy ra lỗi.', + soldNote: 'Đã bán cho {{name}}.', + saleConfirmed: 'Đã xác nhận bán', + saleConfirmedDesc: '{{name}} giờ có thể xác nhận phía họ.', + saleConfirmFailed: 'Không thể xác nhận việc bán', + escrowRedeemed: 'Đã đổi escrow', + escrowRedeemedDesc: 'Tiền giờ đã ở trong ví Cashu của bạn.', + escrowRedeemFailed: 'Không thể đổi escrow', + loginTitle: 'Đăng nhập để xem tin nhắn', + secureLoginTitle: 'Cần đăng nhập bảo mật', + secureLoginDesc: 'Tin nhắn cần ứng dụng ký bảo mật.', + encrypted: 'Đã mã hóa', + refresh: 'Làm mới', + didCompleteTrade: 'Bạn đã hoàn thành giao dịch này chưa?', + recordedSale: '{{name}} đã ghi nhận việc bán. Xác nhận để cập nhật uy tín cho cả hai bạn.', + confirm: 'Xác nhận', + confirmSale: 'Xác nhận việc bán này?', + askedToRecord: '{{name}} đã nhờ bạn ghi nhận. Xác nhận sẽ xây dựng uy tín cho cả hai bạn.', + confirmSaleButton: 'Xác nhận bán', + redeemEscrow: 'Đổi escrow', + escrowAppOnly: 'Escrow Cashu chỉ có trên ứng dụng — mở SkateSpots trên điện thoại để đổi.', + startThread: 'Gửi tin nhắn để bắt đầu cuộc trò chuyện', + placeholder: 'Nhập tin nhắn...', + e2eeNote: 'Tin nhắn được mã hóa đầu cuối bằng NIP-17', + }, + coordinator: { + secondsAgo: '{{count}} giây trước', + minutesAgo: '{{count}} phút trước', + hoursAgo: '{{count}} giờ trước', + daysAgo: '{{count}} ngày trước', + statusIdle: 'Chưa kiểm tra', + statusChecking: 'Đang kiểm tra…', + statusOnline: 'Đã kết nối', + statusStale: 'Yên ắng', + statusOffline: 'Không thấy', + statusError: 'Không thể kết nối', + notACoordinator: 'Đó không phải là điều phối viên', + notACoordinatorDesc: 'Dán một nprofile, một npub, hoặc liên kết cordn.net.', + added: 'Đã thêm điều phối viên', + relayOne: '{{count}} relay', + relayMany: '{{count}} relay', + lastSeen: 'thấy lần cuối {{time}}', + onlineDesc: 'Đang thông báo. Các nhóm dùng nó có thể gửi tin nhắn ngay.', + staleDesc: 'Đã tìm thấy, nhưng nó chưa thông báo gần đây — có thể đang ngủ.', + offlineDesc: 'Không thấy thông báo. Có thể nó riêng tư (điều đó bình thường), hoặc đơn giản là offline.', + errorDesc: 'Không thể kết nối tới các relay.', + idleDesc: 'Đang kiểm tra…', + checkingDesc: 'Đang tìm thông báo của nó…', + eventFoundOne: 'Đã tìm thấy {{count}} sự kiện.', + eventFoundMany: 'Đã tìm thấy {{count}} sự kiện.', + check: 'Kiểm tra', + addLinkCopied: 'Đã sao chép liên kết thêm', + copyFailed: 'Sao chép thất bại', + copyManually: 'Sao chép thủ công.', + addLink: 'Thêm liên kết', + removeConfirm: 'Xóa điều phối viên này khỏi thiết bị này?', + scanToJoin: 'Quét trong Cordn để tham gia điều phối viên này.', + noCoordinator: 'Chưa có điều phối viên', + noCoordinatorDescA: 'Điều phối viên gửi tin nhắn nhóm', + encryptedWord: 'đã mã hóa', + noCoordinatorDescB: 'của Crew bạn theo đúng thứ tự. Nó thấy ai, khi nào và nhóm nào — không bao giờ thấy nội dung. Chọn một cái, hoặc tự vận hành cái của bạn.', + change: 'Đổi điều phối viên', + addTitle: 'Thêm điều phối viên', + add: 'Thêm', + scanQR: 'Quét QR điều phối viên', + inputPlaceholder: 'nprofile… hoặc liên kết cordn.net', + runOwn: 'Tự vận hành', + runOwnDesc: 'Nó có thể chạy trên điện thoại cũ, Raspberry Pi, hay bất kỳ hộp nhỏ nào bạn để bật. Nhóm của bạn vẫn hoạt động khi nó chạy — và bạn có thể chuyển nhóm bất cứ lúc nào.', + onPhone: 'Trên điện thoại', + onPhoneDesc: 'Dùng ứng dụng Cordn Coordinator, rồi quét QR của nó ở đây để thêm.', + openCordn: 'Mở Cordn', + scanItsQR: 'Quét QR của nó', + onServer: 'Trên máy chủ', + commandCopied: 'Đã sao chép lệnh', + copyCommand: 'Sao chép lệnh', + androidSleep: 'Android có thể ngủ điều phối viên trên điện thoại. Hãy chấp nhận việc phải chuyển nhóm thỉnh thoảng.', + privacyNote: '🔒 Điều phối viên chỉ thấy bản mã và metadata — không bao giờ thấy nội dung tin nhắn. Tự vận hành để giữ cả metadata là của bạn.', + customTitle: 'Điều phối viên Chat tùy chỉnh', + customBadge: '· thử nghiệm · relay riêng của bạn', + customDescShort: 'Tùy chọn — Crew của bạn đã có chat mã hóa đầu cuối sẵn, nên bạn không cần cái này. Chỉ đặt nếu bạn tự vận hành', + remove: 'Xóa', + pointerNote: 'Hiện chỉ là con trỏ: một điểm cuối wss:// được dùng làm relay chat của Crew; một điểm https:// dùng qua relay ContextVM chung. Cordn MLS thật chưa được nối.', + cordnCoordinator: 'Điều phối viên Cordn', + invalid: 'Đó không giống điều phối viên. Dán một nprofile, liên kết cordn.net, hoặc URL https/wss.', + useMine: 'Dùng điều phối viên của tôi', + }, + createCrew: { + seoTitle: 'Tạo Crew - SkateSpots', + seoDescription: 'Tạo Crew trượt ván của bạn — sân nhà, thành viên và Spot.', + loginRequired: 'Cần đăng nhập', + loginRequiredDesc: 'Bạn cần đăng nhập để tạo Crew.', + backToCrews: 'Quay lại Crew', + title: 'Tạo Crew', + intro: 'Gia đình trượt ván của bạn — những người bạn trượt cùng. Chỉ cần một cái tên là bắt đầu được; mọi thứ khác đều tùy chọn.', + }, + crew: { + seoTitleNamed: '{{name}} - Crew SkateSpots', + seoTitle: 'Crew - SkateSpots', + seoDescription: 'Một Crew trượt ván trên SkateSpots.', + postHidden: 'Đã ẩn bài đăng', + postHiddenDesc: 'Đã xóa khỏi bảng tin Crew cho mọi người.', + postHideFailed: 'Không thể ẩn bài đăng', + backToCrews: 'Quay lại Crew', + disband: 'Giải tán', + youAreCaptain: 'Bạn là đội trưởng', + member: 'Thành viên', + askSasquatch: 'Hỏi Sasquatch', + agent: 'Trợ lý Crew', + agentDesc: 'Hướng dẫn viên AI của Crew bạn — Spot, sự kiện, Coach & đồ nghề gần đây, với dữ liệu trực tiếp.', + eventsTab: 'Sự kiện', + chatTab: 'Chat', + newMessages: 'Tin nhắn mới', + hostJam: 'Tổ chức jam', + noEvents: 'Chưa có sự kiện Crew. Tổ chức một jam, cuộc thi hay buổi gặp mặt với tư cách Crew — nó kết nối Crew bạn với lịch sự kiện và cho mọi người Zap.', + support: 'Ủng hộ', + zapCrew: 'Zap Crew', + bandTitle: 'Ban nhạc Crew', + bandTagline: 'Nhạc sống · trượt & âm thanh', + listenTitle: 'Nghe: {{domain}}', + listen: 'Nghe nhạc', + setUpGig: 'Tổ chức buổi diễn', + bookGigMessage: 'Này {{crew}} — mình muốn đặt {{band}} biểu diễn. Bạn rảnh để bàn ngày không?', + messageAboutGig: 'Nhắn về buổi diễn', + gigHintA: 'thêm một sự kiện âm nhạc vào lịch do Crew này tổ chức.', + messageShort: 'Nhắn tin', + gigHintB: 'mở DM mã hóa tới Crew để sắp xếp ngày & chi tiết.', + homeSpots: 'Spot nhà', + viewSpot: 'Xem Spot', + seeOnMap: 'Xem trên bản đồ →', + founderLinks: 'Người sáng lập & Liên kết', + startedBy: 'Khởi tạo bởi {{name}}', + opens: 'Mở: {{domain}}', + }, + crews: { + seoTitle: 'Crew - SkateSpots', + seoDescription: 'Tìm đồng đội của bạn. Khám phá các Crew trượt ván, tập thể và cộng đồng địa phương gần bạn.', + videoPartTooltip: 'Crew này có một video part', + part: 'Part', + bandTooltip: 'Ban nhạc Crew: {{name}}', + band: 'Ban nhạc', + focusAll: 'Tất cả', + focusAllShort: 'Tất cả', + focusDiy: 'DIY', + focusPhoto: 'Nhiếp ảnh', + focusCoaching: 'Coaching', + focusArt: 'Nghệ thuật', + focusMusic: 'Âm nhạc', + focusPhysio: 'Vật lý trị liệu', + focusMixed: 'Hỗn hợp', + title: 'Crew', + heroLine: 'Gia đình trượt ván gắn với bản đồ của bạn — những người bạn trượt', + heroWith: 'cùng', + heroRest: ', không phải người bạn thuê (đó là The Lab).', + crewCountOne: '{{count}} Crew', + crewCountMany: '{{count}} Crew', + cityCountOne: '{{count}} thành phố', + cityCountMany: '{{count}} thành phố', + createCrew: 'Tạo Crew', + create: 'Tạo', + searchPlaceholder: 'Tìm Crew theo tên hoặc thành phố…', + filterTitle: 'Lọc Crew', + filterDesc: 'Crew quan tâm đến điều gì.', + nearMe: 'Gần tôi', + emptySearchTitle: 'Không có Crew nào khớp tìm kiếm của bạn', + emptySearchHint: 'Không tìm thấy gì cho “{{query}}”. Thử tên hoặc thành phố khác.', + clearSearch: 'Xóa tìm kiếm', + emptyFocusTitle: 'Chưa có Crew {{label}} nào', + emptyFocusHint: 'Chưa ai giương cao ngọn cờ “{{label}}” ở đây. Hiện mọi Crew, hoặc tự bắt đầu cái này.', + showAll: 'Hiện tất cả Crew', + claimTitle: 'Khẳng định cộng đồng địa phương của bạn', + claimHint: 'Chưa có Crew nào được trồng ở đây. Hãy là người đầu tiên — khởi tạo Crew, liên kết Spot nhà, và đưa cộng đồng của bạn lên bản đồ để mọi người tìm thấy.', + }, + crewCoordinator: { + privateChat: 'Chat Crew Riêng tư', + on: 'Bật', + defaultA: 'Tab', + chatWord: 'Chat', + defaultB: 'là', + e2ee: 'mã hóa đầu cuối', + defaultC: 'cho người sáng lập và tất cả thành viên được liệt kê — không cần thiết lập gì. Tin nhắn được niêm phong bằng khóa của từng thành viên (NIP-17), nên chỉ Crew của bạn đọc được.', + advancedA: 'Nâng cao: tự vận hành', + cordnCoordinator: 'Điều phối viên Cordn', + routeThrough: 'Định tuyến chat qua nó', + coordinator: 'Điều phối viên', + deliveredOver: 'Được chuyển qua', + sharedRelay: '— relay ContextVM chung.', + ownRelay: '— relay riêng của Crew bạn.', + chatLive: 'Chat riêng tư đang hoạt động', + routesA: 'Tab', + routesB: 'định tuyến qua điều phối viên này: tin nhắn được mã hóa đầu cuối (NIP-44, niêm phong cho từng thành viên), nên nó chỉ xử lý lưu lượng đã niêm phong.', + publicWarning: 'Lưu ý: nó được định địa chỉ qua relay ContextVM chung, nên bản mã và metadata (Crew nào, khi nào) hiển thị công khai — chỉ là không đọc được. Hãy trỏ Crew đến một relay wss:// riêng để giữ kín cả điều đó.', + ownRelaySafe: 'Không có gì riêng của Crew rời khỏi relay riêng của Crew bạn.', + manage: 'Quản lý điều phối viên', + open: 'Mở {{domain}}', + runBy: 'Điều phối viên do', + }, + dms: { + securityReminder: 'Nhắc nhở bảo mật', + phishingStrong: 'SkateSpots sẽ không bao giờ DM bạn', + phishingRest: 'để yêu cầu xác minh tài khoản, chia sẻ khóa, hay gửi thanh toán. Nếu ai đó tự nhận là hỗ trợ SkateSpots qua DM — đó là lừa đảo.', + dismissReminder: 'Bỏ qua nhắc nhở bảo mật', + peopleCount: '{{count}} người', + youPrefix: 'Bạn: ', + unreadMessages: 'Tin nhắn chưa đọc', + seoTitle: 'Tin nhắn - SkateSpots', + seoDescription: 'Tin nhắn riêng tư đã mã hóa với cộng đồng trượt ván', + loginTitle: 'Đăng nhập để truy cập tin nhắn', + loginDesc: 'Nhắn tin riêng tư, mã hóa với skater trong cộng đồng', + secureLoginTitle: 'Cần đăng nhập bảo mật', + secureLoginDesc: 'Tin nhắn riêng tư cần ứng dụng ký bảo mật để mã hóa cuộc trò chuyện của bạn.', + onAndroid: 'Trên Android:', + useAmber: 'Dùng ứng dụng Amber', + getAmber: 'Tải Amber →', + onIOS: 'Trên iOS:', + iosHint: 'Thử đăng nhập bằng kết nối bunker (nsec.app) từ Cài đặt', + browserHint: 'Thử đăng nhập bằng tiện ích trình duyệt như Alby hoặc nos2x có hỗ trợ mã hóa.', + title: 'Tin nhắn', + subtitleFull: 'Mã hóa đầu cuối bằng NIP-17', + subtitleShort: 'Đã mã hóa', + newMessage: 'Tin nhắn mới', + groups: 'Nhóm', + loadFailed: 'Không thể tải tin nhắn', + emptyTitle: 'Chưa có tin nhắn nào', + emptyDesc: 'Bắt đầu cuộc trò chuyện với ai đó trong cộng đồng', + startConversation: 'Bắt đầu cuộc trò chuyện', + undecryptableOne: '{{count}} tin nhắn mã hóa không mở được bằng trình ký của bạn.', + undecryptableMany: '{{count}} tin nhắn mã hóa không mở được bằng trình ký của bạn.', + }, + editCrew: { + seoTitleNamed: 'Chỉnh sửa {{name}} - SkateSpots', + seoTitle: 'Chỉnh sửa Crew - SkateSpots', + seoDescription: 'Chỉnh sửa Crew trượt ván của bạn.', + loginRequired: 'Cần đăng nhập', + notYours: 'Không phải Crew của bạn', + notYoursDesc: 'Chỉ người sáng lập Crew mới chỉnh sửa được Crew này.', + backToCrew: 'Quay lại Crew', + title: 'Chỉnh sửa Crew', + }, + form: { + add: 'Thêm', + added: 'Đã thêm', + addNameInBasicsA: 'Thêm lại tên Crew trong', + addNameInBasicsB: 'để hoàn tất.', + adminsDescA: 'Biến thành viên tin cậy thành', + adminsWord: 'quản trị viên', + adminsDescB: '— họ có thể mời thành viên và kiểm duyệt bảng tin & chat Crew bằng khóa của riêng họ. Bạn (người sáng lập) luôn là chủ sở hữu danh tính của Crew.', + agentDescA: 'Thêm', + agentDescB: ', một hướng dẫn viên AI thực sự biết Crew của bạn. Thành viên có thể hỏi về', + agentDescC: '— cùng Spot, sự kiện, Coach và đồ nghề gần đây từ dữ liệu SkateSpots trực tiếp. Chạy ngay trong trình duyệt; không cần khóa hay thiết lập. Còn sớm (AI bậc miễn phí, nên đôi khi chậm).', + agentDescStrong: 'jam tiếp theo, ai điều hành Crew, bạn đang tìm gì và phong cách của bạn', + agentEnabledNote: 'Sasquatch sẽ xuất hiện trên trang Crew của bạn sau khi bạn lưu.', + bandDesc: 'Có ban nhạc? Cộng đồng trượt ván và nhạc địa phương luôn song hành — ghi tên ban nhạc và liên kết đến nhạc.', + bandFooterA: 'Để có hồ sơ ban nhạc đầy đủ (thể loại, nhạc cụ, buổi diễn), tạo một', + musicianWord: 'Nhạc sĩ', + bandFooterB: 'trong The Lab, rồi liên kết nó trong mục', + linkedLabWord: 'Hồ sơ Lab đã liên kết', + bandFooterC: 'ở trên.', + bandMusicWord: 'Ban nhạc & Âm nhạc', + bandName: 'Tên ban nhạc', + bandNamePlaceholder: 'ví dụ: The Bail Outs', + bandNudgeA: 'Bạn có ban nhạc — nhấn để đặt', + crewTypeWord: 'Loại Crew', + bandNudgeB: 'thành', + bandNudgeC: 'để bạn cũng xuất hiện trong cộng đồng Âm nhạc của The Lab.', + beta: 'Beta', + bioLabel: 'Giới thiệu / Tuyên ngôn', + bioPlaceholder: 'Bạn là ai, bạn trượt gì, câu chuyện của bạn...', + continue: 'Tiếp tục', + crewCreated: 'Đã tạo Crew!', + crewUpdated: 'Đã cập nhật Crew!', + crewName: 'Tên Crew', + crewOnlyWord: 'Chỉ Crew', + crewType: 'Loại Crew', + crewTypeDescA: 'Crew của bạn tập trung vào một nghề? Chọn một để cũng xuất hiện trong cộng đồng đó tại', + theLab: 'The Lab', + crewTypeDescB: '. Các Crew trượt ván thông thường vẫn là', + mixedWord: 'Hỗn hợp', + crewTypeDescC: '.', + customVibeHint: 'Thêm phong cách hoặc trọng tâm của riêng bạn bằng #', + customVibePlaceholder: 'ví dụ: downhill, night-sessions, no-comply', + editDesc: 'Danh tính, sân nhà và thành viên của Crew bạn', + enableAgent: 'Bật Trợ lý Crew', + enableTreasury: 'Bật Quỹ Crew', + failed: 'Thất bại', + founded: 'Thành lập (Năm)', + geolocationUnsupported: 'Không hỗ trợ định vị', + gettingLocation: 'Đang lấy...', + goalHint: 'Đảm bảo hồ sơ Nostr của bạn có địa chỉ Lightning (lud16) để các khoản đóng góp đến được.', + goalPlaceholder: 'ví dụ: Đổ bê tông Spot DIY', + goalTarget: 'Mục tiêu (sats)', + goalWhat: 'Mục tiêu là gì?', + homeSpots: 'Spot nhà', + homeSpotsDesc: 'Liên kết các Spot mà Crew bạn hay lui tới — chúng sẽ kết nối với Crew bạn trên bản đồ', + homeTurf: 'Sân nhà (Thành phố / Khu vực)', + homeTurfPlaceholder: 'Bristol, UK', + instagramDetected: 'Đã phát hiện clip Instagram', + invalidMember: 'Nhập npub, nprofile, hoặc khóa công khai hex hợp lệ.', + latitude: 'Vĩ độ', + leaveBlankLocation: 'Để trống để giữ vị trí sân nhà hiện tại.', + links: 'Liên kết', + locationError: 'Lỗi vị trí', + locationFound: 'Đã tìm thấy vị trí', + logoAlt: 'Crew', + logoHint: 'Logo giúp Crew của bạn dễ nhận ra ngay trên bản đồ và trong bảng tin. Hình vuông là tốt nhất.', + logoLabel: 'Logo / Ảnh Crew', + logoUploaded: 'Đã tải logo lên', + longitude: 'Kinh độ', + looksGood: 'Trông ổn', + makeAdmin: 'Đặt làm quản trị viên', + mapPin: 'Ghim bản đồ', + mapPinHint: 'Đặt Crew của bạn lên bản đồ để người địa phương tìm thấy. Nhấn nút — không cần gõ.', + memberAlreadyAdded: 'Thành viên đó đã được thêm.', + members: 'Thành viên', + membersDesc: 'Thêm tài khoản Nostr của Crew. Mỗi thành viên xác nhận bằng khóa của riêng họ — cho đến lúc đó họ hiển thị là “đang chờ”.', + musicLink: 'Liên kết nhạc', + nameCrew: 'Đặt tên Crew của bạn', + nameCrewDesc: 'Crew cần có tên trước khi bạn tiếp tục.', + nameCrewFirst: 'Đặt tên Crew trước', + nameHint: 'Điều duy nhất bạn thực sự cần. Bạn có thể đổi sau.', + namePlaceholder: 'ví dụ: Backyard Bandits', + nameRequired: 'Cần có tên', + nameRequiredDesc: 'Đặt tên cho Crew của bạn.', + nip05DescA: 'Một tên định danh có thể xác minh mà bạn kiểm soát trên bất kỳ tên miền nào, ví dụ', + nip05DescB: '. Nó được xác minh dựa trên khóa người sáng lập của Crew này, và bạn có thể thêm vài cái — mỗi cái hiện dấu kiểm xanh khi tên miền xác nhận.', + nip05Label: 'NIP-05 của Crew', + nip05Placeholder: 'crew@yourdomain.com', + nip05Add: 'Thêm', + nip05Invalid: 'Nhập tên định danh như crew@yourdomain.com', + nip05TooMany: 'Bạn chỉ có thể thêm tối đa {{count}} tên định danh.', + nip05Unverified: 'Chưa kiểm tra', + nip05Remove: 'Xóa {{handle}}', + notAKeyA: 'Đó vẫn chưa giống khóa Nostr — dán một', + notAKeyB: ',', + notAKeyC: ', hoặc khóa công khai hex.', + onlyYouTubeInstagram: 'Chỉ hỗ trợ liên kết YouTube và Instagram.', + openCall: 'Lời kêu gọi', + openCallDescA: 'Đang tìm Filmer, Editor hay người mới? Hãy đưa ra lời kêu gọi — nó hiện trên trang Crew để những người phù hợp từ', + openCallDescB: 'có thể liên hệ.', + optional: '· tùy chọn', + optionalParen: '(tùy chọn)', + otherSocials: 'Mạng xã hội khác', + otherSocialsDesc: 'Thêm bao nhiêu tùy thích — YouTube, TikTok, Discord, Telegram, v.v.', + ownVisibility: 'chế độ hiển thị của riêng họ', + progress: 'Tiến độ', + publicWord: 'Công khai', + publishedToScene: 'Đã xuất bản lên cộng đồng.', + publishFailed: 'Xuất bản thất bại', + publishing: 'Đang xuất bản...', + ready: 'Sẵn sàng', + readyToRollA: 'Sẵn sàng khởi chạy — nhấn', + readyToRollB: 'bất cứ khi nào bạn muốn.', + removeAdminRole: 'Xóa vai trò quản trị', + removeMember: 'Xóa thành viên', + removeSocial: 'Xóa liên kết mạng xã hội', + removeVibe: 'Xóa {{vibe}}', + roles: 'Vai trò:', + sasquatch: 'Sasquatch', + saveCrew: 'Lưu Crew', + skipToEnd: 'Bỏ qua đến cuối', + socialPlaceholder: '@tên hoặc liên kết', + sponsorDesc: 'Nếu một cửa hàng địa phương tài trợ Crew của bạn, chọn họ ở đây để hiện banner “Được tài trợ bởi” dẫn tới cửa hàng của họ.', + stepAria: 'Bước {{step}}: {{title}}', + stepBasics: 'Điều cơ bản', + stepBasicsShort: 'Cơ bản', + stepBasicsHint: 'Chỉ những thứ thiết yếu — bạn có thể tạo Crew chỉ với bước này.', + stepVibe: 'Danh tính & Phong cách', + stepVibeShort: 'Phong cách', + stepVibeHint: 'Cách Crew của bạn xuất hiện quanh ứng dụng. Tất cả đều tùy chọn.', + stepSquad: 'Đội & Spot', + stepSquadShort: 'Đội', + stepSquadHint: 'Thêm người của bạn và sân nhà. Bạn luôn có thể làm sau.', + stepExtras: 'Bổ sung', + stepExtrasShort: 'Bổ sung', + stepExtrasHint: 'Các nâng cấp cho sau này — bỏ qua bất cứ thứ gì bạn chưa chắc.', + extrasAllOptional: 'Mọi thứ ở bước này đều tùy chọn.', + groupIdentity: 'Danh tính', + groupIdentityHint: 'Tên định danh, liên kết', + groupAi: 'Sasquatch AI', + groupShowcase: 'Trưng bày', + groupPayments: 'Thanh toán & quỹ', + groupIntegrations: 'Tích hợp', + groupAdvanced: 'Nâng cao', + groupAdvancedHint: 'thử nghiệm', + pro: 'Pro', + agentProNote: 'Vận hành bởi Sasquatch. Pro dùng model tốt nhất; không có Pro thì dùng bản dự phòng miễn phí.', + stepOf: 'Bước {{step}} trên {{total}}', + treasuryDescA: 'Gây quỹ sats cho một mục tiêu chung — sửa Spot DIY địa phương, một chuyến đi của Crew, một giải thưởng cuộc thi. Đó là mục tiêu Lightning minh bạch; Zap đi', + treasuryDescStrong: 'thẳng vào ví của bạn', + treasuryDescB: '(qua địa chỉ Lightning trong hồ sơ của bạn). SkateSpots không bao giờ giữ tiền.', + upload: 'Tải lên', + uploadFailed: 'Tải lên thất bại', + useCurrentLocation: 'Dùng vị trí hiện tại', + vibeLabel: 'Phong cách / Trọng tâm', + videoDescA: 'Full part, montage hay clip mới nhất của Crew bạn. Dán một liên kết', + videoDescB: '— nó sẽ phát ngay trên trang Crew của bạn.', + visibilityDescA: 'Mỗi thành viên kiểm soát', + visibilityDescB: '— khi họ xác nhận bằng khóa của mình, họ có thể chọn', + visibilityDescC: '— ẩn khỏi người ngoài). Bạn không thể đặt thay họ; đó là quyền của họ.', + website: 'Website', + yourRoles: 'Vai trò của bạn (Trưởng nhóm)', + youtubeDetected: 'Đã phát hiện video YouTube', + invalidUrl: 'Nhập liên kết hợp lệ (ví dụ: https://example.com).', + }, + groupConversation: { + seoTitle: 'Chat nhóm - SkateSpots', + invalidLink: 'Liên kết chat nhóm này không hợp lệ.', + loginTitle: 'Đăng nhập để xem nhóm này', + secureSignerTitle: 'Cần trình ký bảo mật', + secureSignerDesc: 'Tin nhắn nhóm cần trình ký hỗ trợ NIP-44.', + encryptedGroup: 'Nhóm mã hóa đầu cuối', + empty: 'Chưa có tin nhắn — chào nhóm đi.', + placeholder: 'Nhắn cho nhóm...', + }, + hero: { + established: 'Thành lập {{year}}', + teamLeader: 'Trưởng nhóm: {{name}}', + ledBy: 'Dẫn dắt bởi', + }, + inviteCard: { + acceptedTitle: 'Đã chấp nhận lời mời 🛹', + acceptedDesc: 'Người sáng lập Crew xác nhận thành viên trên {{crew}}. Bạn sẽ xuất hiện trong danh sách sau khi họ phê duyệt.', + couldNotAccept: 'Không thể chấp nhận', + couldNotDecline: 'Không thể từ chối', + acceptedDone: 'Đã chấp nhận —', + confirmsMembers: 'xác nhận thành viên', + declinedDone: 'Đã từ chối lời mời vào {{crew}}', + invitedYou: 'đã mời bạn tham gia', + admin: 'Quản trị', + accept: 'Chấp nhận', + decline: 'Từ chối', + }, + inviteDialog: { + messageIntro: 'Này — tham gia Crew {{crew}} trên SkateSpots 🛹', + messageBody: 'Đăng nhập bằng khóa Nostr của bạn, rồi yêu cầu tham gia từ trang Crew.', + copyFailed: 'Sao chép thất bại', + shareTitle: 'Tham gia {{crew}}', + sentTitle: 'Đã gửi lời mời! 🛹', + sentDesc: 'Họ sẽ nhận thông báo để chấp nhận hoặc từ chối.', + couldNotSend: 'Không thể gửi lời mời', + trigger: 'Mời', + title: 'Mời vào {{crew}}', + description: 'Gửi lời mời tới khóa Nostr của ai đó, hoặc chia sẻ liên kết.', + sendTab: 'Gửi lời mời', + shareTab: 'Chia sẻ liên kết', + npubLabel: 'npub của Skater', + invalidNpub: 'Đó không giống một npub hợp lệ.', + noteLabel: 'Ghi chú', + optional: '(tùy chọn)', + notePlaceholder: 'Đến trượt với chúng tôi…', + inviteAsAdmin: 'Mời làm quản trị viên', + inviteAsAdminDesc: 'Có thể quản lý Crew & mời người khác.', + sendButton: 'Gửi lời mời', + sendFooter: 'Họ sẽ nhận thông báo để chấp nhận hoặc từ chối. Tư cách thành viên chỉ được tính khi họ chấp nhận.', + inviteLink: 'Liên kết mời', + messageLabel: 'Tin nhắn', + copyMessage: 'Sao chép tin nhắn', + founderHint: 'Với tư cách người sáng lập, bạn cũng có thể thêm khóa thành viên trực tiếp, rồi họ xác nhận.', + addMemberSettings: 'Thêm thành viên trong cài đặt Crew', + }, + joinRequest: { + moreCount: '+{{count}} nữa', + addedTitle: 'Đã thêm {{name}} vào {{crew}} 🛹', + addedDesc: 'Họ sẽ xác nhận từ phía họ để xuất hiện như thành viên.', + vouchedTitle: 'Bạn đã bảo chứng cho {{name}} 🤝', + vouchedDesc: 'Người sáng lập {{crew}} sẽ thấy sự ủng hộ của bạn và có thể thêm họ.', + couldNotEndorse: 'Không thể ủng hộ', + endorsedDoneA: 'Bạn đã bảo chứng cho', + endorsedDoneB: '— người sáng lập sẽ xác nhận', + vouchedBy: 'Được bảo chứng bởi', + approveAndAdd: 'Phê duyệt & thêm', + addToCrew: 'Thêm vào Crew', + vouchedWaiting: 'Đã bảo chứng — đang chờ người sáng lập', + vouchForThem: 'Bảo chứng cho họ', + leadershipOnly: 'Chỉ ban lãnh đạo Crew.', + adminHelp: 'Quản trị viên không thể thêm thành viên trực tiếp — bảo chứng cho người sáng lập biết bạn ủng hộ rider này.', + }, + leadership: { + teamLeader: 'Trưởng nhóm', + captain: 'Đội trưởng', + verifiedMember: 'Thành viên đã xác minh', + messageName: 'Nhắn cho {{name}}', + title: 'Ban lãnh đạo', + captainsOne: '{{count}} Đội trưởng', + captainsMany: '{{count}} Đội trưởng', + footer: 'Trưởng nhóm điều hành danh sách; các Đội trưởng giúp mời, tổ chức jam và giữ Crew gọn gàng.', + }, + linkField: { + title: 'Crew đã liên kết', + description: 'Bạn cũng điều hành một Crew? Liên kết nó để mọi người có thể nhảy giữa studio và Crew của bạn. Tùy chọn. Liên kết Crew này ngược lại hồ sơ từ trình chỉnh sửa Crew và nó sẽ hiện huy hiệu xanh', + descriptionRest: 'trên cả hai.', + none: 'Bạn chưa có Crew nào. Tạo một cái ở trang Crew để liên kết tại đây.', + linkedCrew: 'Crew đã liên kết ({{id}})', + }, + lookingFor: { + title: 'Lời kêu gọi', + subtitle: 'Crew này đang tìm:', + }, + memberVisibility: { + updatedTitle: 'Đã cập nhật chế độ hiển thị', + updatedCrew: 'Bạn giờ chỉ hiển thị với đồng đội Crew.', + updatedPublic: 'Bạn giờ hiển thị công khai trong Crew này.', + couldNotUpdate: 'Không thể cập nhật', + title: 'Chế độ hiển thị của bạn trong Crew này', + save: 'Lưu chế độ hiển thị', + }, + newMessage: { + inCrew: 'Trong Crew của bạn: {{crews}}', + crewmate: 'Đồng đội Crew', + following: 'Đang theo dõi', + invalidKey: 'Đó không giống npub hoặc khóa công khai hợp lệ.', + description: 'Tìm người của bạn theo tên, hoặc dán npub để nhắn cho bất kỳ ai. Chọn hai người trở lên để bắt đầu nhóm.', + searchPlaceholder: 'Tìm tên hoặc dán npub1...', + messageThisKey: 'Nhắn cho khóa này', + loadingPeople: 'Đang tải người của bạn...', + noPeople: 'Chưa có đồng đội Crew hay người theo dõi.', + noPeopleHint: 'Dán npub của ai đó ở trên để bắt đầu cuộc trò chuyện.', + yourCrews: 'Crew của bạn', + selected: 'Đã chọn {{count}}', + startGroup: 'Bắt đầu nhóm ({{count}})', + message: 'Nhắn tin', + }, + nip05: { + mismatch: 'Tên miền này trỏ tên định danh tới một khóa Nostr khác với người sáng lập Crew. Chưa xác minh.', + verified: 'Đã xác minh — tên miền xác nhận tên định danh này thuộc khóa người sáng lập Crew.', + }, + requestCollective: { + sentTitle: 'Đã gửi yêu cầu 🤝', + sentDesc: '{{name}} sẽ thấy nó trong thông báo và có thể thêm bạn.', + couldNotSend: 'Không thể gửi yêu cầu', + title: 'Tham gia tập thể này', + waiting: 'Đã gửi yêu cầu — đang chờ {{name}}.', + askA: 'Nhờ Crew đứng sau', + askB: 'thêm bạn vào danh sách. Họ sẽ nhận thông báo và có thể thêm bạn chỉ với một lần nhấn.', + placeholder: 'Tùy chọn: nói lý do bạn phù hợp…', + sendButton: 'Gửi yêu cầu', + }, + requestToJoin: { + sentTitle: 'Đã gửi yêu cầu! 🛹', + sentDesc: 'Ban lãnh đạo {{crew}} sẽ thấy nó trong thông báo của họ.', + couldNotSend: 'Không thể gửi yêu cầu', + trigger: 'Yêu cầu tham gia', + title: 'Tham gia {{crew}}', + description: 'Thông báo cho người sáng lập & quản trị viên Crew để họ có thể thêm bạn.', + placeholder: 'Chào một tiếng — bạn trượt ở đâu, quen ai, vì sao muốn tham gia…', + sending: 'Đang gửi…', + sendButton: 'Gửi yêu cầu tham gia', + }, + sponsorBanner: { + loading: 'Đang tải nhà tài trợ…', + sponsoredBy: 'Được tài trợ bởi', + }, + sponsorPicker: { + selected: 'Đã chọn nhà tài trợ', + setLoading: 'Đã đặt nhà tài trợ (đang tải cửa hàng…)', + set: 'Đã đặt nhà tài trợ', + clearAria: 'Xóa nhà tài trợ', + searchPlaceholder: 'Tìm cửa hàng trượt ván theo tên hoặc thành phố…', + loading: 'Đang tải cửa hàng…', + noMatch: 'Không có cửa hàng nào khớp — thử tìm kiếm khác.', + none: 'Chưa tìm thấy cửa hàng nào.', + }, + treasury: { + title: 'Quỹ Crew', + ofGoal: 'trên mục tiêu {{target}}', + goalReached: 'Đã đạt mục tiêu!', + funded: 'Đã gây quỹ {{percent}}%', + contributionOne: '{{count}} khoản đóng góp', + contributionMany: '{{count}} khoản đóng góp', + daysLeft: 'Còn {{days}} ngày', + closed: 'đã đóng', + nonCustodial: 'Phi tập trung · Zap đi thẳng vào ví Lightning của Crew', + }, + userStatus: { + atSpot: '📍 Đang ở một Spot', + autoClears: '⏱️ Tự xóa sau {{min}} phút', + }, + video: { + title: 'The Part', + fullVideo: 'Video đầy đủ · montage', + latestClip: 'Clip mới nhất', + watch: 'Xem', + iframeTitle: '{{crew}} — video', + playAria: 'Phát video {{crew}}', + thumbAlt: 'Ảnh thu nhỏ video {{crew}}', + instagramTitle: 'Clip Instagram', + }, + vouch: { + removedTitle: 'Đã xóa bảo chứng', + vouchedTitle: 'Đã bảo chứng!', + removedDesc: 'Bạn không còn bảo chứng cho {{name}}.', + vouchedDesc: 'Bạn đã bảo chứng cho {{name}}. Cộng đồng tin nhau.', + couldNotVouch: 'Không thể bảo chứng', + title: 'Bảo chứng cộng đồng', + sceneVerified: 'Cộng đồng xác minh', + vouched: 'Đã bảo chứng', + newUnvouched: 'Mới · chưa bảo chứng', + checking: 'Đang kiểm tra cộng đồng…', + empty: 'Chưa có bảo chứng nào. Bảo chứng từ skater trong vòng kết nối của bạn là tín hiệu tốt nhất cho thấy ai đó là người thật — không phải kẻ lạ vô tình ghé vào.', + countOne: '{{count}} bảo chứng', + countMany: '{{count}} bảo chứng', + trusted: '{{count}} từ skater trong mạng lưới tin cậy của bạn', + remove: 'Xóa bảo chứng', + vouchFor: 'Bảo chứng cho {{name}}', + ownerNote: 'Những skater biết công việc của bạn có thể bảo chứng cho bạn ở đây.', + }, + }, +}; export default viBatch5; diff --git a/src/i18n/vi/batch6.ts b/src/i18n/vi/batch6.ts index aa02432..54afe0f 100644 --- a/src/i18n/vi/batch6.ts +++ b/src/i18n/vi/batch6.ts @@ -1,4 +1,1948 @@ -/** vi — batch 6. Filled by the translation pass; empty until then. */ -const viBatch6 = {}; +/** vi — batch 6: placesUi, marketUi, labOptions. */ +const viBatch6 = { + placesUi: { + addToCalendar: { + add: "Thêm vào Lịch", + appleOutlook: "Apple / Outlook (.ics)", + google: "Google Calendar", + }, + attendees: { + goingCount: "sẽ tham dự", + goingTab: "Sẽ tham dự ({{count}})", + interestedTab: "Quan tâm ({{count}})", + nobodyGoing: "Chưa ai xác nhận.", + nobodyInterested: "Chưa ai đánh dấu quan tâm.", + noRsvps: "Chưa có RSVP nào — hãy là người đầu tiên xác nhận tham dự.", + trusted: "Đáng tin cậy", + trustedTitle: "Người bạn theo dõi hoặc một người đóng góp đáng tin cậy", + youTrust: "bạn tin tưởng", + }, + bounty: { + addressCoords: "Địa chỉ & tọa độ", + basic: "Cơ bản", + contactInfo: "Thông tin liên hệ", + description: "Mô tả", + earningPotential: "Tiềm năng kiếm được", + excellent: "Xuất sắc!", + gettingStarted: "Bắt đầu", + good: "Tốt", + onePhoto: "Ít nhất 1 ảnh", + openingHours: "Giờ mở cửa", + shopName: "Tên Shop", + threePhotos: "3+ ảnh", + tip: "💡 Chất lượng cao hơn = Nhiều zap hơn từ cộng đồng!", + }, + calendar: { + allDay: "Cả ngày", + eventDay: "Ngày diễn ra Event", + eventsOnDay: "{{count}} event", + eventsThisMonth: "event trong tháng này", + going: "sẽ tham dự", + months: { + january: "Tháng Một", + february: "Tháng Hai", + march: "Tháng Ba", + april: "Tháng Tư", + may: "Tháng Năm", + june: "Tháng Sáu", + july: "Tháng Bảy", + august: "Tháng Tám", + september: "Tháng Chín", + october: "Tháng Mười", + november: "Tháng Mười Một", + december: "Tháng Mười Hai", + }, + nextMonth: "Tháng sau", + nothingOnDay: "Không có gì vào ngày này.", + prevMonth: "Tháng trước", + tapHighlighted: "Nhấn vào một ngày được tô sáng để xem có gì.", + today: "Hôm nay", + tourDay: "Ngày Tour", + toursOnDay: "{{count}} tour", + toursThisMonth: "tour trong tháng này", + weekdays: { + sun: "CN", + mon: "T2", + tue: "T3", + wed: "T4", + thu: "T5", + fri: "T6", + sat: "T7", + }, + weekdaysShort: { + sun: "C", + mon: "2", + tue: "3", + wed: "4", + thu: "5", + fri: "6", + sat: "7", + }, + }, + countdown: { + ended: "Đã kết thúc", + happeningNow: "Đang diễn ra", + inDays: "Còn {{count}} ngày", + inHoursMins: "Còn {{hours}}g {{mins}}p", + inMins: "Còn {{count}} phút", + startingNow: "Bắt đầu ngay", + tomorrow: "Ngày mai", + }, + createEvent: { + add: "Thêm", + addNewSpot: "Thêm spot mới →", + changeSpot: "Đổi Spot", + created: "Đã tạo Event!", + createdDesc: "Event của bạn đã được đăng lên mạng lưới.", + entryFee: "Phí vào cửa", + entryFeeHint: "(tùy chọn — ví dụ \"500 sats\" hoặc \"£10\")", + entryFeePlaceholder: "Để trống nếu event miễn phí", + featuring: "Có sự góp mặt của {{name}}", + featuringDesc: "Tiết mục này sẽ được gắn thẻ live music và hiển thị trong danh sách gig của họ.", + fundingGoal: "Mục tiêu gây quỹ", + fundingGoalHint: "(tùy chọn — sats để gây quỹ qua zap)", + fundingGoalPlaceholder: "ví dụ 50000", + geoNotSupported: "Không hỗ trợ định vị", + geoNotSupportedDesc: "Trình duyệt của bạn không hỗ trợ định vị.", + hideSpots: "Ẩn Spots", + hostingAs: "Tổ chức với tư cách {{name}}", + hostingAsDesc: "Event này sẽ hiển thị trên trang crew của bạn và được gắn thẻ do crew tổ chức.", + imageUploaded: "Đã tải ảnh lên", + imageUploadedDesc: "Ảnh của bạn đã được tải lên thành công.", + invalidDate: "Ngày không hợp lệ", + invalidDateDesc: "Vui lòng nhập ngày và giờ bắt đầu hợp lệ.", + invalidEnd: "Giờ kết thúc không hợp lệ", + invalidEndDesc: "Giờ kết thúc phải sau giờ bắt đầu.", + linkedTo: "Đã liên kết với: {{title}}", + linkToSpot: "Liên kết với một Skate Spot", + linkToShop: "Liên kết với một Shop", + selectedShop: "Đã liên kết với {{name}}", + selectShopHint: "Tùy chọn — tổ chức tại hoặc bởi một shop trượt ván.", + selectShop: "Chọn shop", + changeShop: "Đổi shop", + hideShops: "Ẩn shops", + searchShops: "Tìm shops…", + noShopsMatch: "Không có shop nào khớp với tìm kiếm của bạn.", + noShopsAvailable: "Chưa có shop nào.", + linkToTour: "Liên kết với một Tour (Tùy chọn)", + linkTourDesc: "Liên kết event này với một tour để cho thấy nó thuộc một chuỗi lớn hơn. Tuyệt vời cho các tour quốc gia, hành trình quốc tế, hoặc những ngày thi đấu World Destruction Tour.", + loadingSpots: "Đang tải spots...", + loadingTours: "Đang tải tours...", + locationError: "Lỗi vị trí", + locationFound: "Đã tìm thấy vị trí", + locationFoundDesc: "Vị trí hiện tại của bạn đã được đặt.", + logoUrl: "URL Logo (tùy chọn)", + noSpotsAvailable: "Không có spot nào", + noSpotsMatch: "Không có spot nào khớp với tìm kiếm của bạn", + noTourLinked: "Chưa liên kết tour", + optional: "(tùy chọn)", + pastDesc: "Chọn một ngày và giờ trong tương lai để các skater có thể RSVP và đến tham dự.", + pastTitle: "Giờ bắt đầu đó đã qua", + publishFailed: "Đăng thất bại", + publishFeatured: "Đăng Featured Event", + removeSponsor: "Xóa nhà tài trợ", + searchSpots: "Tìm spots theo tên, vị trí hoặc danh mục...", + selectedSpot: "Đã chọn: {{name}}", + selectSpot: "Chọn Spot", + selectSpotHint: "Chọn một spot từ bản đồ nơi event này diễn ra", + selectTour: "Chọn Tour", + somethingWrong: "Đã xảy ra lỗi", + sponsorName: "Tên nhà tài trợ", + sponsors: "Nhà tài trợ", + sponsorsHint: "Có shop hoặc thương hiệu nào hậu thuẫn không? Thêm logo của họ — nó hiển thị như một dải \"Presented by\" trên event.", + startRequired: "Cần giờ bắt đầu", + startRequiredDesc: "Vui lòng nhập thời điểm event bắt đầu.", + titleRequired: "Cần tiêu đề", + titleRequiredDesc: "Vui lòng nhập tên cho event này.", + uploadFailed: "Tải lên thất bại", + uploadFailedDesc: "Không tải được ảnh lên", + websiteUrl: "URL Website (tùy chọn)", + }, + createShop: { + address: "Địa chỉ Shop", + addressPlaceholder: "ví dụ 411 N Fairfax Ave, Los Angeles, CA 90036", + addressRequired: "Cần địa chỉ", + addressRequiredDesc: "Vui lòng nhập địa chỉ shop của bạn.", + contactHint: "Giúp khách hàng liên hệ với bạn (nên có ít nhất một cách liên hệ)", + contactInfo: "Thông tin liên hệ", + created: "🎉 Đã thêm Shop!", + createdDesc: "Skate shop của bạn đã có trên bản đồ. Các skater có thể zap bạn để cảm ơn!", + descriptionPlaceholder: "Cho mọi người biết về shop của bạn, bạn bán gì, điểm đặc biệt...", + detailsDesc: "Cho cộng đồng biết về shop của bạn. Mọi trường có dấu * là bắt buộc.", + email: "Email", + hoursOfOperation: "Giờ hoạt động", + hoursPlaceholder: "ví dụ T2-T7 10:00-20:00, CN 12:00-18:00", + instagram: "Instagram", + invalidCoords: "Tọa độ không hợp lệ", + invalidCoordsDesc: "Vui lòng nhập vĩ độ (-90 đến 90) và kinh độ (-180 đến 180) hợp lệ.", + latPlaceholder: "Vĩ độ (ví dụ 34.0737)", + lngPlaceholder: "Kinh độ (ví dụ -118.3614)", + locationRequired: "Cần vị trí", + locationRequiredDesc: "Vui lòng nhập tọa độ hoặc dùng vị trí hiện tại của bạn.", + loginToAdd: "Bạn cần đăng nhập để thêm một skate shop.", + namePlaceholder: "ví dụ Supreme Los Angeles", + nameRequired: "Cần tên Shop", + nameRequiredDesc: "Vui lòng nhập tên cho shop của bạn.", + phoneNumber: "Số điện thoại", + publishFailedDesc: "Đã xảy ra lỗi. Kiểm tra console để biết chi tiết.", + shopPhotoAlt: "Shop", + shopPhotos: "Ảnh Shop", + subtitle: "Đưa shop của bạn lên bản đồ và kết nối với cộng đồng", + upload: "Tải lên", + }, + createTour: { + acceptedClipSources: "Nguồn clip được chấp nhận", + acceptedClipSourcesDesc: "Bạn sẽ chấp nhận những định dạng nào cho clip gửi lên?", + accommodationInfo: "Thông tin chỗ ở", + accommodationPlaceholder: "Gợi ý hoặc sắp xếp chỗ ở, ví dụ 'Hostel bình dân dọc đường', 'Cần đồ cắm trại', 'Đã bao gồm Airbnb'", + addChallenge: "Thêm Thử thách", + addCity: "Thêm thành phố...", + addCountry: "Thêm quốc gia...", + addShopFirst: "Thêm shop trước", + alsoSelected: "Cũng đã chọn:", + availabilityPlaceholder: "ví dụ Cuối tuần, Chỉ buổi sáng, Theo lịch hẹn", + availabilityQuestion: "Bạn thường rảnh khi nào?", + availableShops: "Skate Shop có sẵn ({{count}})", + challengeDescPlaceholder: "Mô tả tùy chọn...", + challenges: "Thử thách", + challengesRequired: "Cần thử thách", + challengesRequiredDesc: "Vui lòng thêm ít nhất một thử thách để các đội hoàn thành.", + challengesSecret: "Tất cả thử thách là BÍ MẬT cho đến ngày bắt đầu cuộc thi. Các đội sẽ không thấy chúng cho đến lúc đó!", + challengeTitlePlaceholder: "Tiêu đề thử thách, ví dụ 'Kickflip xuống 10 bậc'", + citiesLabel: "Thành phố", + citiesOnTour: "Các thành phố trong Tour", + cityPlaceholder: "ví dụ Berlin, Đức", + cityRegion: "Thành phố / Vùng", + cityRequired: "Cần thành phố/vùng", + cityRequiredDesc: "Vui lòng nhập thành phố hoặc vùng của bạn.", + clipAnyUrl: "🔗 Bất kỳ URL nào", + clipBlossom: "📦 Tải lên Blossom", + clipInstagram: "📸 Instagram", + clipYouTube: "▶️ YouTube", + competitionDates: "Ngày thi đấu", + competitionDatesWarning: "⚠️ Tất cả thử thách là BÍ MẬT cho đến ngày bắt đầu! Các đội sẽ không thấy thử thách cho đến khi cuộc thi bắt đầu.", + competitionLocations: "Địa điểm thi đấu", + competitionLocationsDesc: "Các đội sẽ thi đấu ở đâu? Thêm tất cả thành phố và quốc gia liên quan.", + coordsHint: "Tọa độ là tùy chọn. Thêm chúng để ghim điểm hẹn của bạn lên bản đồ.", + countriesLabel: "Quốc gia", + countriesRequired: "Cần quốc gia", + countriesRequiredDesc: "Vui lòng thêm ít nhất một quốc gia cho tour quốc tế của bạn.", + createdDestruction: "💀 ĐÃ TẠO WORLD DESTRUCTION TOUR!", + createdDestructionDesc: "Các đội có thể đăng ký. Thử thách được tiết lộ vào ngày bắt đầu!", + createDestructionTour: "Tạo World Destruction Tour", + createdInternational: "✈️ Đã tạo Tour Quốc tế!", + createdInternationalDesc: "Hành trình toàn cầu của bạn đã được đăng! Kết nối với các skater trên toàn thế giới.", + createdLocal: "🏠 Đã tạo Tour Địa phương!", + createdLocalDesc: "Tour của bạn đã hiển thị. Các skater có thể đặt qua DM!", + createdNational: "🚐 Đã tạo Tour Quốc gia!", + createdNationalDesc: "Chuyến đi đường của bạn đã hoạt động! Bắt đầu phối hợp với các skater quan tâm.", + departure: "Khởi hành *", + departureRequired: "Cần ngày khởi hành", + departureRequiredDesc: "Đặt thời điểm chuyến đi khởi hành để các skater có thể lên kế hoạch và đặt chỗ.", + descriptionPlaceholder: "Mô tả những gì các skater sẽ trải nghiệm: những spot bạn sẽ ghé, không khí, điều làm tour của bạn độc đáo...", + destructionDesc: "Thiết lập cuộc thi toàn cầu kiểu KOTR của bạn - bạn định nghĩa MỌI THỨ!", + discountHint: "Người tham gia tour có thể xuất trình xác nhận đặt chỗ tại shop để nhận ưu đãi này", + discountPercentage: "Phần trăm ưu đãi", + dropTour: "Đăng một Tour", + duration: "Thời lượng", + durationHintDestruction: "Cuộc thi kéo dài bao lâu? (1-12 tháng)", + durationHintInternational: "Hành trình kéo dài bao nhiêu tuần? (tối đa 2 tháng)", + durationHintLocal: "Tour thường của bạn kéo dài bao lâu?", + durationHintNational: "Chuyến đi đường kéo dài bao nhiêu ngày?", + durationWeeksMonths: "{{weeks}} tuần (~{{months}} tháng)", + editTour: "Sửa Tour", + enable: "Bật", + enabled: "Đã bật", + endBeforeStart: "Kết thúc trước khi bắt đầu", + endBeforeStartDesc: "Ngày kết thúc cuộc thi phải bằng hoặc sau ngày bắt đầu.", + endDate: "Ngày kết thúc", + entryFeeHint: "Bạn giữ 95% • Nền tảng lấy 5% • Để trống nếu vào cửa miễn phí", + entryFeePerTeam: "Phí vào cửa mỗi Đội (sats)", + entryFeePlaceholder: "ví dụ 100000", + entryPrizes: "Vào cửa & Giải thưởng", + filmPremieres: "Công chiếu Phim của Đội", + filmPremieresDesc: "Sau cuộc thi, clip của mỗi đội trở thành một bộ phim hoàn chỉnh có thể công chiếu tại các skate shop địa phương trên toàn thế giới.", + filmPremieresInfo: "🎥 Các đội tổng hợp clip thử thách thành một bộ phim cuối. Các shop có thể tổ chức buổi công chiếu, kết nối cuộc thi toàn cầu với cộng đồng địa phương.", + filmReleaseDate: "Ngày phát hành Phim (Tùy chọn)", + filmReleaseDateHint: "Thời điểm phim sẽ có. Để trống để phát hành ngay sau khi cuộc thi kết thúc.", + fixedSession: "Buổi cố định", + fixedSessionDesc: "Một ngày & giờ ấn định", + flexible: "Linh hoạt", + flexibleDesc: "Đặt bất cứ lúc nào qua DM", + hide: "Ẩn", + howDestruction1: "• Cuộc thi đội toàn cầu - kéo dài tới 12 tháng", + howDestruction2: "• BẠN định nghĩa thử thách, điểm, giải thưởng - chúng tôi chỉ cung cấp nền tảng", + howDestruction3: "• Tất cả thử thách là BÍ MẬT cho đến ngày bắt đầu cuộc thi", + howDestruction4: "• Clip qua tải lên Blossom HOẶC liên kết ngoài (YouTube, Instagram, bất kỳ URL nào)", + howDestruction5: "• Chỉ trình độ nâng cao - mọi loại spot đều được bao gồm tự động", + howDestruction6: "• Nền tảng chỉ lấy 5% phí vào cửa (KHÔNG phải quỹ giải thưởng)", + howDestructionTitle: "💀 WORLD DESTRUCTION TOUR - Kiểu KOTR", + howInternational1: "• Hành trình xuyên biên giới qua nhiều quốc gia", + howInternational2: "• Bạn đặt giá — nền tảng chỉ lấy 5%", + howInternational3: "• Đặt ngày khởi hành & trở về để crew có thể đặt vé máy bay", + howInternational4: "• Kết nối các skater từ khắp nơi trên thế giới", + howInternational5: "• Tạo những trải nghiệm toàn cầu khó quên!", + howInternationalTitle: "Tour Quốc tế hoạt động thế nào", + howItWorks: "Cách hoạt động:", + howLocal1: "• Bạn đặt giá — nền tảng lấy 10%", + howLocal2: "• Spot ẩn vẫn ẩn — bạn dẫn họ đến tận nơi", + howLocal3: "• Tổ chức một buổi theo lịch hoặc để linh hoạt / theo hẹn", + howLocal4: "• Các skater đặt qua DM, trả bằng Lightning & có thể thêm vào lịch của họ", + howLocal5: "• Xây dựng uy tín với đánh giá và zap", + howLocalTitle: "Tour Địa phương hoạt động thế nào", + howNational1: "• Chuyến đi đường nhiều thành phố khắp quốc gia của bạn", + howNational2: "• Bạn đặt giá — nền tảng chỉ lấy 7%", + howNational3: "• Đặt ngày chuyến đi để các skater có thể sắp xếp thời gian & đi lại", + howNational4: "• Bao gồm thông tin di chuyển / chỗ ở cho crew", + howNational5: "• Xây dựng những chuyến phiêu lưu trượt ván huyền thoại!", + howNationalTitle: "Tour Quốc gia hoạt động thế nào", + imageUploadedDesc: "Ảnh tour của bạn đã được tải lên.", + incompleteCoords: "Tọa độ chưa đầy đủ", + incompleteCoordsDesc: "Vui lòng nhập cả vĩ độ và kinh độ, hoặc để trống cả hai.", + internationalDetails: "Chi tiết Hành trình Quốc tế", + languagesSelected: "Đã chọn {{count}}", + languagesSpoken: "Ngôn ngữ sử dụng", + latOptional: "Vĩ độ (tùy chọn)", + lngOptional: "Kinh độ (tùy chọn)", + loadingProfile: "Đang tải Hồ sơ...", + loadingProfileDesc: "Đang kiểm tra trạng thái xác minh NIP-05 của bạn.", + loadingShops: "Đang tải shops...", + localShopPremieres: "Công chiếu tại Shop Địa phương", + localShopPremieresDesc: "Các skate shop trên toàn thế giới có thể tổ chức đêm chiếu phim", + loginToCreate: "Bạn cần đăng nhập để tạo một tour.", + maxGroupSize: "Kích thước nhóm tối đa", + maxTeams: "Số đội tối đa", + maxTeamSize: "Kích thước đội tối đa", + meetingLocationSet: "Vị trí hiện tại của bạn đã được đặt làm điểm hẹn.", + meetingPointDesc: "Bạn sẽ gặp người tham gia tour ở đâu? Chọn một spot công cộng, dễ nhận biết.", + meetingPointLabel: "Điểm hẹn", + meetingPointPlaceholder: "ví dụ Ga Warschauer Straße", + meetingPointRequired: "Cần điểm hẹn", + meetingPointRequiredDesc: "Vui lòng nhập nơi bạn sẽ gặp người tham gia tour.", + minTeamSize: "Kích thước đội tối thiểu", + noChallenges: "Chưa có thử thách", + noChallengesDesc: "Thêm thử thách để các đội hoàn thành", + noPartnerShop: "Không có shop đối tác", + noShopsFound: "Chưa tìm thấy skate shop nào trên mạng lưới.", + noShopsRegistered: "Chưa có skate shop nào đăng ký", + onlineRelease: "Phát hành trực tuyến", + onlineReleaseDesc: "Cũng phát hành phim trên YouTube/Nostr", + organizerContact: "Thông tin liên hệ Ban tổ chức", + organizerContactHint: "Thông tin này sẽ hiển thị cho các đội đã đăng ký", + organizerContactPlaceholder: "Các đội liên hệ bạn thế nào? ví dụ Nostr npub, email, Telegram, v.v.", + partnerDiscountDesc: "Ưu đãi cho người tham gia tour tại một skate shop địa phương", + partnerStep1: "1. Hợp tác với một skate shop địa phương bạn tin tưởng", + partnerStep2: "2. Đặt phần trăm ưu đãi cho người tham gia tour", + partnerStep3: "3. Sau tour, đưa người tham gia xác nhận để xuất trình tại shop", + partnerStep4: "4. Shop tôn trọng ưu đãi - xây dựng cộng đồng & thu hút khách!", + percentOff: "GIẢM {{percent}}%", + photoHint: "Thêm ảnh bạn đang trượt hoặc một spot ngầu trong tour của bạn.", + pickRide: "Chọn chuyến đi của bạn", + place1: "🥇 Nhất", + place2: "🥈 Nhì", + place3: "🥉 Ba", + platformFee: "Bạn đặt giá • Nền tảng lấy {{percent}}", + points: "Điểm:", + pricePerPerson: "Giá mỗi Người (sats)", + pricePlaceholder: "ví dụ 25000", + prizeDistribution: "Phân bổ giải thưởng", + prizePoolHint: "Tùy chọn - tổng giải thưởng có sẵn", + prizePoolPlaceholder: "ví dụ 2000000", + proTipDesc: "Trước khi đăng ưu đãi đối tác, hãy liên hệ chủ shop qua DM để thống nhất phần trăm ưu đãi. Điều này đảm bảo họ đồng ý và sẽ tôn trọng ưu đãi cho người tham gia tour của bạn.", + proTipTitle: "💡 Mẹo hay: Phối hợp với shop trước!", + return: "Trở về", + returnBeforeDeparture: "Trở về trước khi khởi hành", + returnBeforeDepartureDesc: "Ngày trở về phải bằng hoặc sau ngày khởi hành.", + roadTripDetails: "Chi tiết Chuyến đi đường", + schedule: "Lịch trình", + scheduleDesc: "Tổ chức như một buổi theo lịch một lần, hoặc để linh hoạt và cho các skater đặt thời gian qua DM.", + secretUntilStart: "Bí mật cho đến khi bắt đầu", + selectPartnerShop: "Chọn Shop Đối tác", + sessionDateRequired: "Cần ngày buổi", + sessionDateRequiredDesc: "Chọn ngày và giờ cho buổi theo lịch của bạn, hoặc chuyển sang lịch linh hoạt.", + sessionDateTime: "Ngày & giờ buổi", + sessionDateTimeHint: "Các skater sẽ thấy thời gian này và có thể thêm vào lịch của họ từ trang tour.", + shopPremieresContact: "Liên hệ trực tiếp các shop này để sắp xếp đêm công chiếu phim. Mọi sắp xếp là riêng tư.", + shopPremieresHow: "💡 Cách Công chiếu tại Shop hoạt động: Liên hệ trực tiếp các shop để sắp xếp đêm công chiếu. Mọi sắp xếp là riêng tư giữa bạn và các shop.", + shopsCanRegister: "Các shop có thể đăng ký tại /create-shop", + show: "Hiện", + showAllLanguages: "Hiện tất cả {{count}} ngôn ngữ", + somethingWrong: "Đã xảy ra lỗi.", + spotTypes: "Các loại Spot", + spotTypesRequired: "Cần loại spot", + spotTypesRequiredDesc: "Vui lòng chọn ít nhất một loại spot bạn sẽ giới thiệu.", + startDate: "Ngày bắt đầu", + startDateRequired: "Cần ngày bắt đầu", + startDateRequiredDesc: "Vui lòng đặt thời điểm cuộc thi bắt đầu (thử thách sẽ được tiết lộ vào ngày này).", + startingCity: "Thành phố khởi hành", + startingCityPlaceholder: "ví dụ Los Angeles, Hoa Kỳ", + teamSettings: "Cài đặt Đội", + teamsCount: "{{count}} đội", + titlePlaceholder: "ví dụ Berlin Kreuzberg - Tour Spot Ngầm", + titleRequired: "Cần tiêu đề Tour", + titleRequiredDesc: "Vui lòng nhập tên cho tour của bạn.", + totalPercent: "Tổng: {{percent}}%", + totalPrizePool: "Tổng Quỹ Giải thưởng (sats)", + tourDesc: "Cho các skater biết sẽ trải nghiệm gì trong tour của bạn", + tourDetails: "Chi tiết Tour", + tourPhoto: "Ảnh Tour", + tourTitle: "Tiêu đề Tour", + transportDestructionPlaceholder: "Các đội sẽ di chuyển giữa các địa điểm thế nào? Có phương tiện nào được cung cấp hoặc gợi ý không?", + transportInfo: "Thông tin di chuyển", + transportPlaceholder: "Người tham gia sẽ di chuyển thế nào? ví dụ 'Có xe van', 'Bay đến Barcelona, chúng tôi thuê xe van', 'Tàu giữa các thành phố'", + tripDatesDesc: "Chốt ngày để các skater có thể xin nghỉ, đặt vé máy bay và lên kế hoạch cho chuyến đi.", + tripDatesTitle: "Ngày Chuyến đi", + updated: "Đã cập nhật Tour!", + updatedDesc: "Các thay đổi của bạn đã được đăng.", + upload: "Tải lên", + view: "Xem →", + worldDestruction: "World Destruction Tour", + youReceive: "Bạn nhận: {{amount}} sats mỗi người", + }, + editEvent: { + accessDenied: "Truy cập bị từ chối", + accessDeniedDesc: "Bạn chỉ có thể sửa các event do bạn tạo.", + backToEvent: "Về Event", + detailsDesc: "Cập nhật thông tin về event này. Mọi trường có dấu * là bắt buộc.", + eventCover: "Ảnh bìa event", + locationUpdated: "Đã cập nhật vị trí.", + loginToEdit: "Bạn cần đăng nhập để sửa event này.", + newSpot: "Spot mới: {{location}}.", + newTime: "Giờ mới: {{date}} lúc {{time}}.", + saveChanges: "Lưu Thay đổi", + saving: "Đang lưu...", + title: "Sửa Event", + updated: "Đã cập nhật Event!", + updatedDesc: "Các thay đổi của bạn đã được đăng lên mạng lưới.", + updateDetails: "Cập nhật chi tiết cho {{title}}", + updatedNotified: "Đã đăng thay đổi — {{count}} người tham dự đã được thông báo.", + updateFailed: "Cập nhật thất bại", + updateMessage: "{{parts}} — xem event để biết chi tiết.", + }, + editShop: { + accessDeniedDesc: "Bạn chỉ có thể sửa các shop do bạn tạo.", + backToShop: "Về Shop", + detailsDesc: "Cập nhật thông tin shop của bạn. Mọi trường có dấu * là bắt buộc.", + loginToEdit: "Bạn cần đăng nhập để sửa shop này.", + updated: "Đã cập nhật Shop!", + updateDetails: "Cập nhật chi tiết cho {{name}}", + }, + editTour: { + accessDeniedDesc: "Bạn chỉ có thể sửa các tour do bạn tạo.", + loginToEdit: "Bạn cần đăng nhập để sửa tour này.", + }, + eventCard: { + report: "Báo cáo", + }, + eventDetail: { + aCrew: "một crew", + addToCalendar: "Thêm vào lịch", + backToEvents: "Về Events", + cancelled: "Event này đã bị hủy", + checkUpdate: "— xem cập nhật", + copyFailed: "Sao chép thất bại", + date: "Ngày", + editEvent: "Sửa event", + eventFallback: "Event", + eventOrganizer: "Ban tổ chức Event", + getDirections: "Chỉ đường", + linkCopied: "Đã sao chép liên kết", + linkCopiedDesc: "Đã sao chép liên kết event vào clipboard — dán ở bất cứ đâu.", + live: "Trực tiếp:", + liveMusic: "live music", + location: "Vị trí", + newLocation: "Vị trí mới", + noRsvps: "Không có RSVP nào được ghi nhận.", + organizer: "Ban tổ chức", + rsvpsClosed: "RSVP đã đóng — event này đã bị chủ nhà hủy.", + seeMap: "Xem bản đồ", + shareEvent: "Chia sẻ event", + shareText: "{{title}} — một event trượt ván trên SkateSpots", + shareTextFallback: "Xem event trượt ván này trên SkateSpots", + time: "Giờ", + timeChanged: "Đã đổi giờ", + updatesFromHost: "Cập nhật từ chủ nhà", + where: "Ở đâu", + whoCame: "Ai đã đến", + whosGoing: "Ai sẽ tham dự", + }, + events: { + calendar: "Lịch", + createTour: "Tạo Tour", + events: "Events", + faqFooter: "Có câu hỏi? Xem FAQ →", + hosting: "Đang tổ chức", + hostingSubtitle: "Events của bạn — RSVP, cập nhật & chỉnh sửa nhanh", + list: "Danh sách", + noEventsMatchFilters: "Không có event nào khớp với bộ lọc. Thử điều chỉnh hoặc xóa chúng.", + noPast: "Không có event đã qua", + noPastBody: "Không tìm thấy event trượt ván nào đã qua trong bộ lọc hiện tại.", + noTours: "Không tìm thấy tour", + noToursBody: "Chưa có tour trượt ván. Tạo cái đầu tiên và đưa các skater khám phá spot!", + noToursMatchFilters: "Không có tour nào khớp với bộ lọc. Thử điều chỉnh hoặc xóa chúng.", + noUpcoming: "Không có event sắp tới", + noUpcomingBody: "Không tìm thấy event trượt ván nào sắp tới. Hãy là người đầu tiên tạo!", + past: "Đã qua", + resultsCount: "{{count}} kết quả", + searchCity: "Thành phố…", + searchEvent: "Tên event…", + searchTour: "Tên tour…", + tours: "Tours", + toursSubtitle: "Hướng dẫn viên địa phương, chuyến đi đường & cuộc thi world destruction", + upcoming: "Sắp tới", + }, + eventTypes: { + contest: "Cuộc thi", + demo: "Demo", + jam: "Jam", + meetup: "Gặp mặt", + premiere: "Công chiếu", + session: "Buổi", + workshop: "Hội thảo", + }, + featured: { + active: "Đang hoạt động", + bodyEvent: "Đăng miễn phí. Featured event nhận huy hiệu và nằm đầu trang events.", + bodyTour: "Đăng miễn phí. Featured tour nhận huy hiệu và nằm đầu danh sách tours.", + contextEvent: "Event của bạn vẫn được đăng miễn phí dù thế nào — featured chỉ thêm huy hiệu & đẩy lên.", + contextTour: "Tour của bạn vẫn được đăng miễn phí dù thế nào — featured chỉ thêm huy hiệu & đẩy lên.", + daysRemaining: "Featured đang hoạt động · còn {{count}} ngày.", + headingEvent: "Đưa event này lên featured", + headingTour: "Đưa tour này lên featured", + optional: "tùy chọn", + platformOwner: "Chủ nền tảng — featured luôn bật.", + }, + filters: { + activeCount: "{{count}} đang bật", + all: "Tất cả", + allLevels: "Mọi trình độ", + eventType: "Loại Event", + following: "Đang theo dõi", + newest: "Mới nhất", + popular: "Phổ biến", + showResults: "Hiện Kết quả", + showResultsActive: "Hiện Kết quả · {{count}} đang bật", + skillLevel: "Trình độ", + sortBy: "Sắp xếp theo", + topRated: "Đánh giá cao nhất", + tourCategory: "Danh mục Tour", + trusted: "Đáng tin cậy", + trustLevel: "Mức độ tin cậy", + verified: "Đã xác minh", + }, + food: { + bar: "Quán bar", + cafe: "Quán cà phê", + call: "Gọi", + chooseSpot: "Chọn một spot...", + directions: "Chỉ đường", + fastFood: "Đồ ăn nhanh", + foodCourt: "Khu ăn uống", + locationLabel: "Vị trí:", + noneFound: "Không tìm thấy Địa điểm Ăn uống", + noneFoundDesc: "Chúng tôi không tìm thấy nhà hàng hoặc quán cà phê nào trong bán kính 1km từ spot này. Thử chọn một vị trí khác.", + placesFound: "Tìm thấy {{count}} địa điểm trong bán kính 1km từ {{spot}}", + pub: "Quán rượu", + restaurant: "Nhà hàng", + selectSpot: "Chọn một skate spot", + selectSpotDesc: "Chọn một skate spot từ menu thả xuống ở trên để tìm nhà hàng, quán cà phê và các lựa chọn ăn uống gần đó.", + selectSpotTitle: "Chọn một Skate Spot", + subtitle: "Tìm nơi ăn uống gần các skate spot yêu thích của bạn", + title: "Đồ ăn gần Spot", + unknown: "Không rõ", + website: "Website", + }, + rsvp: { + areYouGoing: "Bạn có tham dự không?", + cant: "Không thể", + cantMakeIt: "Không thể tham dự", + going: "Tôi sẽ tham dự", + goingCount: "sẽ tham dự", + goingShort: "Sẽ tham dự", + hostNote: "Bạn đang tổ chức event này — nhưng bạn vẫn có thể đặt trạng thái của mình.", + interested: "Quan tâm", + interestedCount: "quan tâm", + loginToRsvp: "Đăng nhập để RSVP.", + maybe: "Có thể", + toastError: "Không thể RSVP", + toastGoing: "Bạn sẽ tham dự! 🛹", + toastInterested: "Đã đánh dấu quan tâm.", + toastNotGoing: "Đã đánh dấu không tham dự.", + tryAgain: "Vui lòng thử lại.", + }, + shop: { + addNip05Settings: "Thêm NIP-05 trong Cài đặt", + adminRemovedReason: "Quản trị viên SkateSpots đã xóa shop \"{{name}}\"", + areYouOwner: "Bạn có phải Chủ Shop không?", + backToMap: "Về Bản đồ", + claimDesc: "Nếu bạn sở hữu hoặc quản lý shop này, bạn có thể nhận nó để xác minh quyền sở hữu bằng NIP-05.", + claimNip05Intro: "Để nhận shop này, hãy thêm một định danh NIP-05 khớp với tên miền website của shop. Ví dụ, nếu website shop là", + claimNip05Your: "NIP-05 của bạn nên là", + contactShop: "Liên hệ Shop", + deleted: "Đã xóa Shop", + deletedDesc: "Yêu cầu xóa đã được gửi đến các relay. Hầu hết relay sẽ xóa nội dung này.", + deleteDialogDesc: "Thao tác này sẽ xóa vĩnh viễn \"{{name}}\" khỏi tất cả relay. Không thể hoàn tác.", + deleteDialogTitle: "Xóa Shop?", + deletedReason: "Đã xóa shop", + deleteFailed: "Xóa thất bại", + deleteShop: "Xóa Shop", + linkCopied: "Đã sao chép liên kết!", + linkCopiedDesc: "Đã sao chép liên kết shop vào clipboard.", + nip05Required: "⚠️ Cần xác minh NIP-05 để nhận shop", + opens: "Mở: {{domain}}", + removeAdmin: "Xóa (quản trị)", + removed: "Đã xóa Shop", + removedDesc: "Shop này đã bị gỡ và sẽ bị ẩn trên toàn SkateSpots.", + removeDialogDesc: "Với tư cách quản trị viên SkateSpots, bạn đang gỡ \"{{name}}\". Nó sẽ bị ẩn trên toàn ứng dụng cho mọi người và một yêu cầu xóa sẽ được gửi đến các relay.", + removeDialogTitle: "Gỡ shop này? (quản trị)", + removeShop: "Gỡ Shop", + tipMapper: "Tip cho Người đóng góp", + tipMapperDesc: "Shop này được thêm bởi một thành viên cộng đồng. Zap họ để cảm ơn!", + updateNip05: "Cập nhật NIP-05 để Nhận", + viewPhotoFull: "Xem ảnh toàn màn hình", + viewPhotoOf: "Xem ảnh {{index}} / {{total}}", + }, + sponsors: { + presentedBy: "Được trình bày bởi", + }, + tourCard: { + active: "Đang hoạt động", + completed: "Đã hoàn thành", + contactForPrice: "Liên hệ để biết giá", + durationDays: "{{count}} ngày", + durationHours: "{{count}} giờ", + durationMonths: "{{count}} tháng", + durationWeeks: "{{count}} tuần", + entry: "Vào cửa: {{amount}} sats", + happeningNow: "Đang diễn ra", + inDays: "Còn {{count}} ngày", + inHours: "Còn {{count}}g", + inMonths: "Còn {{count}} tháng", + inWeeks: "Còn {{count}} tuần", + maxGroup: "Tối đa {{count}}", + price: "{{amount}} sats", + prizePool: "{{amount}} sats", + registrationOpen: "Đang mở đăng ký", + startingSoon: "Sắp bắt đầu", + teamsMax: "Tối đa {{count}} đội", + tomorrow: "Ngày mai", + worldwide: "Toàn cầu", + }, + tourDetail: { + about: "Giới thiệu về Tour này", + availability: "Thời gian rảnh", + competitionWindow: "Thời gian thi đấu", + contactToBook: "Liên hệ Hướng dẫn viên để Đặt", + discountAt: "GIẢM {{percent}}% tại {{shop}}", + duration: "Thời lượng", + languages: "Ngôn ngữ", + loginToBook: "Đăng nhập để Đặt", + loginToBookDesc: "Đăng nhập để liên hệ hướng dẫn viên và đặt tour này", + maxGroup: "Nhóm tối đa", + meetingPoint: "Điểm hẹn", + notFound: "Không tìm thấy Tour", + notFoundDesc: "Tour này có thể đã bị gỡ hoặc không tồn tại.", + organizer: "Ban tổ chức", + partnerDiscount: "Ưu đãi Shop Đối tác", + partnerDiscountDesc: "Đặt tour này để nhận ưu đãi tại skate shop đối tác. Xuất trình xác nhận đặt chỗ cho nhân viên shop.", + people: "{{count}} người", + perPerson: "mỗi người", + price: "Giá", + runsAbout: "Kéo dài khoảng {{duration}}", + scheduledSession: "Buổi theo lịch", + shareText: "Xem tour trượt ván địa phương này: {{title}}", + skillLevel: "Trình độ", + spotTypes: "Các loại Spot", + tourGuide: "Hướng dẫn viên Tour", + tourSponsors: "Nhà tài trợ Tour", + tripDates: "Ngày Chuyến đi", + viewProfile: "Xem Hồ sơ", + }, + updates: { + admin: "Quản trị", + adminNote: "Bạn đang đăng với tư cách quản trị viên SkateSpots. Nó sẽ được ghi rõ là thông báo quản trị, không phải từ chủ nhà.", + kindCancelled: "Đã hủy", + kindNewSpot: "Spot mới", + kindNewTime: "Giờ mới", + kindUpdate: "Cập nhật", + loading: "Đang tải cập nhật…", + notifiedCount: "{{count}} người đã được thông báo.", + notifiedEveryone: "Mọi người sẽ thấy nó trên event.", + notifiesRsvps: "Thông báo {{count}} RSVP", + noUpdates: "Chưa có cập nhật từ chủ nhà. RSVP và bạn sẽ được thông báo nếu có gì thay đổi.", + placeholder: "Mưa — dời sang Chủ nhật 2 giờ chiều. Gặp ở gờ sau…", + post: "Đăng", + postAdminUpdate: "Đăng cập nhật quản trị", + posted: "Đã đăng cập nhật", + postError: "Không thể đăng cập nhật", + postUpdate: "Đăng cập nhật", + tryAgain: "Vui lòng thử lại.", + visibleToEveryone: "Hiển thị cho mọi người trong event này", + }, + destination: { + bitcoin: "Bitcoin", + closeSearch: "Đóng tìm kiếm", + nothingMatches: "Không có gì khớp với “{{query}}”.", + placeholder: "Tìm spots, shops, thương nhân Bitcoin…", + shop: "Shop", + spot: "Spot", + typeChars: "Nhập ít nhất 2 ký tự. Tìm kiếm skate spot, skate shop và thương nhân Bitcoin.", + typeCharsNear: "Nhập ít nhất 2 ký tự. Tìm kiếm skate spot, skate shop và thương nhân Bitcoin gần đây.", + }, + dateWindow: { + any: "Bất kỳ", + anytime: "Bất cứ lúc nào", + month: "Tháng này", + monthShort: "Tháng", + today: "Hôm nay", + todayShort: "Hôm nay", + week: "Tuần này", + weekend: "Cuối tuần", + weekendShort: "Cuối tuần", + weekShort: "Tuần", + }, + }, + marketUi: { + gearSwap: { + title: "Gear Swap", + subtitle: "Mua & bán gear trượt ván đã qua sử dụng với các skater khác", + listGear: "Đăng Gear", + searchPlaceholder: "Tìm gear...", + allCategories: "Mọi danh mục", + forSale: "Đang bán", + wtb: "WTB", + trust: "Tin cậy", + filterByTrust: "Lọc theo Tin cậy", + allSellers: "Mọi người bán", + verifiedOnly: "Chỉ đã xác minh", + trustedPlus: "Trusted+", + followingOnly: "Chỉ đang theo dõi", + pickupOrShip: "Tự lấy hoặc gửi", + localPickup: "Tự lấy tại địa phương", + ships: "Gửi hàng", + sortBy: "Sắp xếp theo", + newest: "Mới nhất", + priceLowHigh: "Giá: Thấp → Cao", + priceHighLow: "Giá: Cao → Thấp", + trustScore: "Điểm tin cậy", + nearest: "Gần nhất (địa phương)", + listingFound: "Tìm thấy {{count}} tin đăng", + listingsFound: "Tìm thấy {{count}} tin đăng", + loadFailed: "Không tải được tin đăng", + tryLater: "Vui lòng thử lại sau.", + noneTitle: "Không tìm thấy tin đăng nào", + noneFiltered: "Không có gear nào khớp với bộ lọc hiện tại. Thử xóa chúng hoặc tìm thứ khác.", + noneFirst: "Hãy là người đầu tiên đăng gear của bạn — deck, trucks, wheels, giày, bất cứ thứ gì trượt ván!", + listYourGear: "Đăng Gear của bạn", + faqLink: "Có câu hỏi? Xem FAQ →", + }, + hub: { + browse: "Duyệt", + selling: "Đang bán", + myTrades: "Giao dịch của tôi", + reputation: "Uy tín", + loginListings: "Đăng nhập để quản lý tin đăng của bạn.", + loginReputation: "Đăng nhập để xem uy tín và đánh giá của bạn.", + }, + marketplace: { + heroTitle: "Shops & Marketplace", + heroBefore: "Marketplace của chúng tôi được vận hành bởi", + heroAfter: "- một marketplace phi tập trung trên Nostr. Các skate shop có thể đăng sản phẩm của họ, và bạn có thể mua/bán gear đã qua sử dụng trực tiếp bằng Bitcoin.", + whatIsTitle: "Plebeian Market là gì?", + whatIsBody: "Plebeian Market là một marketplace phi tập trung xây dựng trên Nostr. Mua và bán gear trượt ván trực tiếp với các skater khác bằng Bitcoin. Không trung gian, không phí, tự do hoàn toàn.", + noFeesTitle: "Không phí", + noFeesBody: "Không nền tảng nào lấy 30%. Bán trực tiếp ngang hàng.", + bitcoinTitle: "Thanh toán Bitcoin", + bitcoinBody: "Trả bằng Bitcoin. Nhanh, an toàn, toàn cầu.", + decentralizedTitle: "Phi tập trung", + decentralizedBody: "Xây dựng trên Nostr. Không công ty nào kiểm soát.", + visit: "Ghé thăm Plebeian Market", + buySellTitle: "Bạn có thể Mua & Bán gì", + catCompletes: "Complete Deck", + preBuilt: "Complete dựng sẵn", + customSetups: "Setup tùy chỉnh", + beginnerBoards: "Boards cho người mới", + catParts: "Phụ tùng Deck", + decks: "Decks", + trucks: "Trucks", + wheels: "Wheels", + bearings: "Bearings", + gripTape: "Griptape", + hardware: "Phụ kiện kim khí", + catApparel: "Trang phục & Bảo hộ", + skateShoes: "Giày trượt ván", + clothing: "Quần áo", + helmets: "Mũ bảo hiểm", + pads: "Đệm bảo hộ", + backpacks: "Ba lô", + catAccessories: "Phụ kiện", + tools: "Dụng cụ", + wax: "Sáp", + rails: "Rails", + stickers: "Sticker", + videos: "Video", + magazines: "Tạp chí", + howItWorks: "Cách hoạt động", + step1Title: "Duyệt Sản phẩm", + step1Body: "Ghé thăm Plebeian Market và duyệt gear trượt ván từ các shop và cá nhân trên toàn thế giới.", + step2Title: "Liên hệ Người bán", + step2Body: "Nhắn tin trực tiếp cho người bán qua Nostr. Thương lượng giá, đặt câu hỏi, sắp xếp vận chuyển.", + step3Title: "Trả bằng Bitcoin", + step3Body: "Hoàn tất mua hàng bằng Bitcoin Lightning để thanh toán tức thì, phí thấp.", + step4Title: "Để lại Phản hồi", + step4Body: "Đánh giá trải nghiệm của bạn và xây dựng uy tín người bán trên Nostr. Đánh giá của bạn giúp cộng đồng.", + needBitcoinTitle: "Cần Bitcoin?", + needBitcoinBefore: "Bạn sẽ cần một ví Lightning có sats để mua hàng. Xem", + onboardingGuide: "hướng dẫn nhập môn", + needBitcoinAfter: "để được gợi ý ví.", + ownShopTitle: "Bạn có Skate Shop?", + ownShopBody: "Đưa shop của bạn lên SkateSpots và bán sản phẩm trên Plebeian Market. Tiếp cận khách hàng toàn cầu với phí nền tảng bằng không.", + addShop: "Thêm Shop của bạn", + startSelling: "Bắt đầu Bán", + }, + listingDetail: { + notFound: "Không tìm thấy tin đăng", + notFoundBody: "Nó có thể đã bị xóa, hoặc liên kết bị sai.", + backToGearSwap: "Về Gear Swap", + gearSwap: "Gear Swap", + viewPhoto: "Xem ảnh {{n}}", + photoAlt: "{{title}} — ảnh {{n}}", + wantToBuy: "MUỐN MUA", + sold: "ĐÃ BÁN", + description: "Mô tả", + usuallyHere: "Thường có mặt {{availability}}", + listed: "Đăng ngày {{date}}", + listingCountOne: "{{count}} tin đăng · {{age}} ngày tuổi", + listingCountMany: "{{count}} tin đăng · {{age}} ngày tuổi", + relistActive: "Đăng lại thành đang hoạt động", + markSold: "Đánh dấu đã bán", + deleteListing: "Xóa tin đăng", + makeOffer: "Đưa ra đề nghị", + shareListing: "Chia sẻ tin đăng", + unknown: "Không rõ", + linkCopied: "Đã sao chép liên kết", + linkCopiedBody: "Chia sẻ nó với một skater.", + copyFailed: "Không thể sao chép liên kết", + relisted: "Đã đăng lại", + relistedBody: "Tin đăng của bạn đã hoạt động trở lại.", + couldNotUpdate: "Không thể cập nhật", + somethingWrong: "Đã xảy ra lỗi", + }, + create: { + imageUploaded: "Đã tải ảnh lên", + uploadFailed: "Tải lên thất bại", + failed: "Thất bại", + cooldownActive: "Đang trong thời gian chờ", + cooldownWait: "Vui lòng đợi {{time}} trước khi tạo tin đăng khác", + limitReached: "Đã đạt giới hạn tin đăng", + limitReachedBody: "Bạn đã đạt giới hạn {{limit}} tin đăng hàng tháng", + feeRequired: "Cần trả phí", + feeRequiredBody: "Vui lòng trả phí chống spam để tiếp tục", + titleRequired: "Cần tiêu đề", + categoryRequired: "Cần danh mục", + photoRequired: "Cần ảnh", + photoRequiredBody: "Cần ít nhất một ảnh khi bán gear", + nip05Required: "Cần xác minh NIP-05", + nip05RequiredBody: "Bạn cần một địa chỉ Nostr đã xác minh để đăng gear", + priceRequired: "Cần giá cho tin đăng giá cố định", + sizeRequired: "Cần kích thước", + sizeRequiredBody: "Vui lòng chọn kích thước cho {{category}}", + conditionRequired: "Cần tình trạng", + conditionRequiredBody: "Vui lòng chọn tình trạng của {{category}} của bạn", + wtbPosted: "Đã đăng Muốn Mua!", + wtbPostedBody: "Người bán sẽ có thể tìm thấy yêu cầu của bạn.", + listingCreated: "Đã tạo tin đăng!", + listingCreatedBody: "Gear của bạn đã được đăng.", + publishFailed: "Đăng thất bại", + loginRequired: "Cần đăng nhập", + loginRequiredBody: "Bạn cần đăng nhập để đăng gear.", + backToStash: "Về Stash", + backToSpot: "Về {{title}}", + backToMarketplace: "Về Marketplace", + backToMap: "Về Bản đồ", + wantToBuy: "Muốn Mua", + listYourGear: "Đăng Gear của bạn", + wtbSubtitle: "Cho cộng đồng biết bạn đang tìm gear gì", + sellSubtitle: "Bán gear trượt ván cho cộng đồng", + fromStashTitle: "Đăng từ Stash của bạn", + fromStashBody: "Đã điền sẵn chi tiết vật phẩm trong stash của bạn. Xem lại và chọn điểm hẹn!", + nip05Banner: "Để chống spam và bảo vệ người mua, bạn cần một địa chỉ Nostr đã xác minh (NIP-05) để đăng gear.", + verifiedLabel: "Đã xác minh:", + checkingTrust: "Đang kiểm tra mức độ tin cậy của bạn...", + trustLevel: "Mức độ tin cậy:", + trusted: "Đáng tin cậy", + active: "Đang hoạt động", + newcomer: "Người mới", + newUser: "Người dùng mới", + remaining: "Còn {{remaining}} / {{limit}} tin đăng trong tháng này", + cooldownBody: "Người dùng mới có 24 giờ chờ giữa các tin đăng.", + timeRemaining: "Thời gian còn lại: {{time}}", + monthlyLimitTitle: "Đã đạt Giới hạn Hàng tháng", + monthlyLimitBody: "Bạn đã đạt giới hạn {{limit}} tin đăng trong tháng này. Xây dựng uy tín bằng cách tạo spot hoặc hoàn tất giao dịch để tăng giới hạn.", + powAccepted: "Đã chấp nhận proof of work!", + feePaid: "Đã trả phí!", + canCreateNow: "Bây giờ bạn có thể tạo tin đăng.", + whatDoTitle: "Bạn muốn làm gì?", + sellGear: "BÁN GEAR", + categoryTitle: "Danh mục *", + categoryHint: "Loại gear gì?", + detailsTitle: "Chi tiết Gear", + detailsWtbHint: "Mô tả thứ bạn đang tìm", + detailsSellHint: "Cho người mua biết về vật phẩm của bạn", + titleLabel: "Tiêu đề *", + titlePlaceholderWtb: "Đang tìm deck 8.0\"", + titlePlaceholderSell: "Deck Palace gần như mới 8.25\"", + summaryLabel: "Tóm tắt ngắn", + summaryPlaceholderWtb: "Bất kỳ thương hiệu nào, thích hình ít", + summaryPlaceholderSell: "Tình trạng tốt, hầu như chưa dùng", + descriptionLabel: "Mô tả", + descriptionPlaceholderWtb: "Mô tả chính xác thứ bạn đang tìm - thương hiệu ưa thích, yêu cầu tình trạng, v.v.", + descriptionPlaceholderSell: "Nhận deck này dịp Giáng sinh nhưng thích cỡ nhỏ hơn. Sẵn lòng cho bạn thử trước khi mua!", + fulfilmentLabel: "Giao nhận thế nào?", + pickup: "Tự lấy", + pickupHint: "Gặp tại địa phương", + ships: "Gửi hàng", + shipsHint: "Gửi bưu điện", + both: "Cả hai", + bothHint: "Một trong hai", + addressNote: "Chúng tôi không bao giờ thu thập địa chỉ của bạn — để gửi hàng, chia sẻ riêng trong chat giao dịch.", + postageLabel: "Ai trả phí vận chuyển?", + requireEscrow: "Yêu cầu escrow", + requireEscrowHint: "Yêu cầu người mua thanh toán qua Cashu escrow.", + postageBuyer: "Người mua trả", + postageSeller: "Tôi trả", + postageSplit: "Chia đôi", + sizeLabel: "Kích thước", + selectSize: "Chọn kích thước", + truckHeight: "Chiều cao Truck", + selectHeight: "Chọn chiều cao", + wheelHardness: "Độ cứng Wheel", + selectHardness: "Chọn độ cứng", + pricingTitle: "Định giá", + pricingWtbHint: "Bạn muốn trả thế nào?", + pricingSellHint: "Bạn muốn bán thế nào?", + priceLabel: "Giá *", + currencyLabel: "Tiền tệ", + photosTitle: "Ảnh", + photosSellHint: "Cần ít nhất một ảnh", + photosWtbHint: "Tùy chọn - thêm ảnh tham khảo", + productPhoto: "Sản phẩm {{n}}", + upload: "Tải lên", + photosNote: "Thêm tối đa 5 ảnh. Ảnh đầu tiên sẽ là ảnh chính.", + pickupLocationTitle: "Địa điểm Tự lấy", + pickupLocationHint: "Liên kết với một skate spot để dễ gặp mặt", + searchSpots: "Tìm spots...", + noSpotsFound: "Không tìm thấy spot nào. Thử tìm khác.", + availabilityLabel: "Bạn thường rảnh khi nào?", + availabilityPlaceholder: "Cuối tuần 10:00-14:00, tối Thứ Ba/Năm", + availabilityHint: "Giúp người mua sắp xếp gặp mặt với bạn", + durationTitle: "Thời hạn Tin đăng", + durationHint: "Tin đăng này nên hoạt động bao lâu?", + publishing: "Đang đăng...", + checkingEligibility: "Đang kiểm tra điều kiện...", + cooldownButton: "CHỜ: {{time}}", + limitReachedButton: "ĐÃ ĐẠT GIỚI HẠN", + payFeeButton: "TRẢ PHÍ ĐỂ TIẾP TỤC", + postWtbButton: "ĐĂNG MUỐN MUA", + listForSaleButton: "ĐĂNG GEAR ĐỂ BÁN", + }, + trades: { + title: "Giao dịch của tôi", + loginBody: "Đăng nhập để quản lý giao dịch và uy tín marketplace của bạn.", + subtitle: "Xác nhận, yêu cầu và uy tín chúng xây dựng. Thanh toán được thỏa thuận với skater kia — ứng dụng chỉ ghi lại thỏa thuận.", + actionNeeded: "Cần hành động", + askedToConfirmSale: "đã yêu cầu bạn xác nhận một giao dịch bán", + recordedSale: "đã ghi nhận một giao dịch bán — xác nhận phía bạn", + confirmSale: "Xác nhận bán", + confirm: "Xác nhận", + nothingWaiting: "Hiện không có gì đang chờ bạn. 🛹", + yourRecords: "Hồ sơ giao dịch của bạn", + noTrades: "Chưa có giao dịch nào. Hoàn tất một thỏa thuận và xác nhận nó để bắt đầu xây dựng uy tín.", + browseGearSwap: "Duyệt Gear Swap", + roleSold: "Đã bán", + roleBought: "Đã mua", + roleTrade: "Trao đổi", + with: "với", + viewListing: "Xem tin đăng", + revoke: "Thu hồi", + revokeTitle: "Thu hồi hồ sơ giao dịch này?", + revokeBody: "Nó sẽ ngừng tính vào uy tín của bạn. Bên kia giữ chứng thực riêng của họ. Dùng khi giao dịch bị tranh chấp hoặc nhầm lẫn.", + revokeNote: "Đã rút lại bởi tác giả.", + revoked: "Đã thu hồi hồ sơ giao dịch", + revokedBody: "Nó không còn tính vào uy tín nữa.", + revokeFailed: "Không thể thu hồi giao dịch", + saleConfirmed: "Đã xác nhận bán", + saleConfirmedBody: "Họ giờ có thể xác nhận phía của họ.", + saleConfirmFailed: "Không thể xác nhận giao dịch bán", + tradeConfirmed: "Đã xác nhận giao dịch", + tradeConfirmedBody: "Uy tín đã cập nhật cho cả hai bạn.", + tradeConfirmFailed: "Không thể xác nhận giao dịch", + somethingWrong: "Đã xảy ra lỗi.", + }, + card: { + listingDeleted: "Đã xóa tin đăng", + listingRemoved: "Đã gỡ tin đăng", + listingDeletedBody: "Tin đăng của bạn đã bị gỡ. Các relay tôn trọng yêu cầu xóa sẽ ngừng phục vụ nó.", + listingRemovedBody: "Tin đăng này đã bị gỡ và sẽ bị ẩn trên toàn SkateSpots.", + removeFailed: "Gỡ thất bại", + somethingWrong: "Đã xảy ra lỗi", + markedSold: "Đã đánh dấu đã bán", + markedSoldBody: "Tin đăng của bạn giờ hiển thị là đã bán.", + couldNotUpdate: "Không thể cập nhật", + relisted: "Đã đăng lại", + relistedBody: "Tin đăng của bạn đã hoạt động trở lại.", + listingOptions: "Tùy chọn tin đăng", + report: "Báo cáo", + removeAdmin: "Gỡ (quản trị)", + postage: "phí vận chuyển", + newSeller: "Người bán mới", + saleOne: "{{count}} giao dịch bán", + saleMany: "{{count}} giao dịch bán", + iHaveThis: "Tôi có cái này!", + deleteTitle: "Xóa \"{{title}}\"?", + adminRemoveTitle: "Gỡ tin đăng này? (quản trị)", + deleteBody: "Thao tác này yêu cầu các relay xóa tin đăng \"{{title}}\" của bạn. Không thể hoàn tác từ đây — bạn sẽ phải tạo cái mới.", + adminRemoveBody: "Với tư cách quản trị viên SkateSpots, bạn đang gỡ \"{{title}}\". Nó sẽ bị ẩn trên toàn ứng dụng cho mọi người và một yêu cầu xóa sẽ được gửi đến các relay.", + deleting: "Đang xóa…", + removing: "Đang gỡ…", + deleteListing: "Xóa Tin đăng", + removeListing: "Gỡ Tin đăng", + reportCount: "{{count}} báo cáo", + reports: "{{count}} báo cáo", + viewTitle: "Xem {{title}}", + reportListing: "Báo cáo Tin đăng", + manageListing: "Quản lý tin đăng", + trusted: "Đáng tin cậy", + daysOld: "{{n}} ngày tuổi", + monthsOld: "{{n}} tháng tuổi", + yearsOld: "{{n}} năm tuổi", + listingsCount: "{{count}} tin đăng", + postageBuyer: "phí vận chuyển: người mua", + postageSeller: "phí vận chuyển: người bán", + postageSplit: "phí vận chuyển: chia đôi", + powTitle: "NIP-13 proof of work — chống spam miễn phí", + verifiedTradeOne: "{{count}} giao dịch đã xác minh", + verifiedTrades: "{{count}} giao dịch đã xác minh", + reportSubmitted: "Đã gửi báo cáo", + reportSubmittedBody: "Cảm ơn bạn đã giúp giữ marketplace an toàn.", + reportFailed: "Gửi báo cáo thất bại", + selectReason: "Vui lòng chọn lý do", + reportDialogBody: "Giúp giữ marketplace an toàn bằng cách báo cáo các tin đăng không phù hợp hoặc gây nhầm lẫn.", + reasonLabel: "Lý do báo cáo *", + detailsLabel: "Chi tiết bổ sung (tùy chọn)", + detailsPlaceholder: "Cung cấp bất kỳ ngữ cảnh bổ sung nào có thể hữu ích...", + reportNote: "Báo cáo được đăng lên Nostr và giúp cộng đồng nhận diện các tin đăng có vấn đề. Tin đăng có nhiều báo cáo có thể tự động bị ẩn.", + submitting: "Đang gửi...", + submitReport: "Gửi Báo cáo", + }, + tradeActions: { + tradeConfirmed: "Đã xác nhận giao dịch", + tradeConfirmedWithProof: "Đã đính kèm biên lai có thể xác minh — điều này tính vào giao dịch đã xác minh.", + tradeConfirmedBody: "Uy tín đã cập nhật cho cả hai bạn.", + tradeConfirmFailed: "Không thể xác nhận giao dịch", + somethingWrong: "Đã xảy ra lỗi.", + requestNote: "Vui lòng xác nhận giao dịch của chúng ta cho \"{{title}}\".", + requestSent: "Đã yêu cầu xác nhận", + requestSentBody: "Người bán giờ có thể xác nhận giao dịch bán và xây dựng uy tín cho cả hai.", + requestFailed: "Không thể gửi yêu cầu", + escrowRefunded: "Đã hoàn tiền escrow", + escrowRefundedBody: "Tiền đã trở lại ví Cashu của bạn.", + escrowRefundFailed: "Không thể hoàn tiền escrow", + confirmThisTrade: "Xác nhận giao dịch này", + escrowAndRequest: "Escrow & yêu cầu", + shipsEscrowHint: "Giao dịch gửi hàng — dùng escrow để không bên nào gửi vào hư không. Chia sẻ địa chỉ của bạn riêng tư trong chat giao dịch, đừng bao giờ ở đây.", + shipsHint: "Giao dịch gửi hàng — ưu tiên escrow nếu người bán cung cấp, và chỉ chia sẻ địa chỉ trong chat.", + askSeller: "Yêu cầu người bán xác nhận", + waitingSeller: "Đã yêu cầu xác nhận — đang chờ người bán.", + refundEscrow: "Hoàn tiền escrow", + buyWithSats: "Mua bằng sats", + depositTitle: "Tiền đặt cọc thiện chí (tùy chọn)", + payDeposit: "Trả tiền cọc", + depositBefore: "Một cuộc trao đổi không có hóa đơn, nên đây là cách nó có một", + verifiableCost: "chi phí có thể xác minh", + depositAfter: ". Hoàn tiền khi giao hàng (hoặc dùng Cashu escrow để hoàn tiền tự động). ⚠️ Chứng minh cam kết, không phải giao hàng.", + depositPaid: "Đã trả tiền cọc", + depositPaidBody: "Đã lưu — nó sẽ được đính kèm khi giao dịch được xác nhận.", + paid: "Đã trả ⚡", + paidWithProof: "Đã lưu biên lai có thể xác minh — xác nhận giao dịch để nó được tính.", + paidBody: "Yêu cầu người bán xác nhận giao dịch để nó được tính cho cả hai bạn.", + }, + offers: { + accepted: "Đã chấp nhận", + declined: "Đã từ chối", + withdrawn: "Đã rút", + open: "Đang mở", + noAmount: "không có số tiền", + titleOwner: "Đề nghị ({{count}})", + titleBuyer: "Thương lượng của bạn", + you: "Bạn", + them: "Họ", + paidAskConfirm: "Đã trả — yêu cầu người bán xác nhận giao dịch.", + payWithSats: "Trả bằng sats", + accept: "Chấp nhận", + decline: "Từ chối", + counter: "Phản đề nghị", + counterPlaceholder: "Phản đề nghị của bạn (sats)", + send: "Gửi", + counterItemPlaceholder: "…hoặc phản đề nghị bằng một vật phẩm để trao đổi (tùy chọn)", + waitingOn: "Đang chờ", + waitingOnSuffix: "— lượt của bạn sẽ trở lại nếu họ phản đề nghị.", + withdraw: "Rút", + dmAccepted: "✅ Đề nghị của bạn đã được chấp nhận! Nhắn tin để sắp xếp giao nhận.", + dmDeclined: "❌ Đề nghị của bạn đã bị từ chối.", + offerAccepted: "Đã chấp nhận đề nghị", + offerDeclined: "Đã từ chối đề nghị", + respondFailed: "Không thể phản hồi", + somethingWrong: "Đã xảy ra lỗi.", + offerWithdrawn: "Đã rút đề nghị", + withdrawFailed: "Không thể rút", + enterAmountOrItem: "Nhập số tiền hoặc một vật phẩm để trao đổi", + counterDm: "Phản đề nghị", + counterSent: "Đã gửi phản đề nghị", + counterSentBody: "Giờ đến lượt họ.", + counterFailed: "Không thể gửi phản đề nghị", + }, + offer: { + validAmount: "Nhập số tiền hợp lệ", + describeOffer: "Mô tả đề nghị của bạn", + describeOfferBody: "Thêm số tiền, một vật phẩm để trao đổi, hoặc tin nhắn.", + dmAmount: " với giá {{amount}} sats", + dmItem: " (đề nghị: {{item}})", + dmBody: "🛹 Đề nghị mới cho tin đăng \"{{title}}\" của bạn{{amount}}{{item}}.{{note}}", + sent: "Đã gửi đề nghị", + sentBody: "{{sellerName}} có thể chấp nhận hoặc từ chối.", + sendFailed: "Không thể gửi đề nghị", + somethingWrong: "Đã xảy ra lỗi.", + title: "Đưa ra đề nghị", + description: "Đề nghị sats, hoặc đổi thứ gì đó — {{sellerName}} có thể chấp nhận, từ chối hoặc phản đề nghị. Bạn tự sắp xếp việc giao nhận.", + amountLabel: "Số tiền (sats, tùy chọn)", + amountPlaceholder: "ví dụ 45000", + itemLabel: "Hoặc trao đổi thứ gì đó (tùy chọn)", + itemPlaceholder: "ví dụ deck 8.25 của tôi + wheels dự phòng", + itemHint: "Đổi đồ? Ghi thứ bạn đang đề nghị ở đây — bạn có thể kết hợp với sats.", + messageLabel: "Tin nhắn (tùy chọn)", + messagePlaceholder: "Bất cứ điều gì người bán nên biết…", + send: "Gửi đề nghị", + }, + markSold: { + enterBuyer: "Nhập npub của người mua", + dealClosed: "Đã chốt thỏa thuận 🎉", + dealClosedBody: "Tin đăng đã đánh dấu đã bán và giao dịch đã được đăng cho uy tín.", + closeFailed: "Không thể chốt thỏa thuận", + somethingWrong: "Đã xảy ra lỗi.", + title: "Chốt thỏa thuận", + description: "Đánh dấu tin đăng này đã bán và ghi lại chứng thực giao dịch có chữ ký cho bạn và người mua.", + buyerLabel: "npub của người mua", + methodLabel: "Đã thanh toán thế nào? (tự khai)", + amountLabel: "Số tiền bằng sats (tùy chọn)", + submit: "Đánh dấu đã bán", + }, + handoff: { + title: "Sắp xếp giao nhận", + suggest: "Gợi ý thời gian & địa điểm", + suggestDm: "Chào! Tôi muốn mua \"{{title}}\". Gợi ý thời gian và địa điểm gặp — tôi sẵn lòng gặp tại một skate spot công cộng.", + orMeetAt: "Hoặc gặp tại một spot công cộng gần đây:", + spotDm: "Chào! Tôi muốn mua \"{{title}}\". Gặp tại {{spot}} được không? {{url}}", + shareDelivery: "Chia sẻ chi tiết giao hàng", + deliveryDm: "Chào! Tôi muốn mua \"{{title}}\". Đây là chi tiết giao hàng của tôi:\n\nTên:\nĐịa chỉ:\n\n(Chỉ chia sẻ những gì đơn vị vận chuyển cần.)", + useLocker: "Dùng tủ khóa / điểm nhận hàng", + lockerDm: "Chào! Tôi muốn mua \"{{title}}\". Chúng ta có thể dùng tủ khóa / điểm nhận hàng thay vì địa chỉ nhà không?", + noteBefore: "Những chi tiết này nằm trong chat riêng tư — SkateSpots không bao giờ thấy chúng. Với giao dịch gửi hàng, ưu tiên", + escrow: "escrow", + noteMiddle: ", và", + neverPay: "đừng bao giờ trả ngoài kênh của ứng dụng", + noteAfter: ". Gặp ở nơi công cộng.", + }, + shipping: { + noCounterparty: "Chưa có đối tác", + noCounterpartyBody: "Người bán nên ghi lại giao dịch bán (nêu tên người mua) trước.", + markedShipped: "Đã đánh dấu đã gửi", + markedReceived: "Đã đánh dấu đã nhận", + issueReported: "Đã báo cáo vấn đề", + receivedBody: "Cảm ơn — điều này không giải phóng escrow; hãy thanh toán trực tiếp với người bán.", + notifiedBody: "Bên kia đã được thông báo.", + updateFailed: "Không thể cập nhật", + somethingWrong: "Đã xảy ra lỗi.", + title: "Vận chuyển", + shipped: "đã gửi", + received: "đã nhận", + issue: "vấn đề", + trackingPlaceholder: "Số theo dõi (tùy chọn)", + iShipped: "Tôi đã gửi hàng", + iReceived: "Tôi đã nhận hàng", + reportIssue: "Báo cáo vấn đề", + noteBefore: "Tự khai — một ghi chú logistics,", + notProof: "không phải bằng chứng", + noteAfter: ". Đánh dấu \"đã nhận\" không giải phóng escrow. ⚠️ Đừng chụp ảnh bưu kiện có địa chỉ lộ rõ, và chỉ chia sẻ số theo dõi nếu bạn thấy thoải mái khi nó công khai.", + }, + pay: { + sent: "Đã gửi thanh toán ⚡", + sentWithProof: "Đã lưu biên lai thanh toán có thể xác minh — nó sẽ được tính là đã xác minh thanh toán.", + sentBody: "Cho người bán biết — họ có thể xác nhận giao dịch để nó được tính cho cả hai bạn.", + failed: "Thanh toán thất bại", + title: "Trả bằng sats", + descSendPrefix: "Gửi", + descSendSuffix: "cho {{sellerName}} để thanh toán thỏa thuận này.", + descSettle: "Thanh toán thỏa thuận này trực tiếp với {{sellerName}}.", + paid: "Đã trả!", + paidBody: "Yêu cầu người bán xác nhận giao dịch — hai xác nhận xây dựng uy tín cho cả hai.", + noMethod: "{{sellerName}} chưa đặt phương thức thanh toán (không có hóa đơn Lightning hoặc địa chỉ). Nhắn tin cho họ để sắp xếp thanh toán.", + ownListing: "Đây là tin đăng của chính bạn.", + paying: "Đang trả…", + pay: "Trả", + payAmount: "Trả {{amount}} sats", + footnote: "Thanh toán từ ví đã kết nối của bạn (NWC, WebLN hoặc Cashu) trực tiếp cho {{sellerName}} — SkateSpots không bao giờ giữ tiền.", + }, + spamFee: { + invoiceComment: "Phí tin đăng SkateSpots", + generateFailed: "Tạo hóa đơn thất bại", + paymentSuccess: "Thanh toán thành công!", + satsSent: "Đã gửi {{amount}} sats cho {{name}}", + autoPayFailed: "Tự động thanh toán thất bại", + autoPayFailedBody: "Vui lòng thanh toán thủ công bằng mã QR hoặc hóa đơn", + invoiceCopied: "Đã sao chép hóa đơn!", + copyFailed: "Sao chép thất bại", + received: "Đã nhận thanh toán!", + receivedBody: "Phí {{amount}} sat của bạn đã được trả. Bây giờ bạn có thể tạo tin đăng.", + title: "Phí Tin đăng Một lần", + subtitle: "Là thành viên mới, cần một khoản phí nhỏ cho tin đăng đầu tiên của bạn.", + whyTitle: "Tại sao tôi cần trả?", + spamLabel: "Chống spam:", + spamBody: "Khoản phí này ngăn bot và kẻ lừa đảo làm ngập marketplace bằng tin đăng giả.", + trustLabel: "Xây dựng uy tín:", + trustBody: "Tài khoản mới cần chứng minh cam kết trước khi đăng. Sau vài tin đăng thành công, khoản phí này được miễn.", + supportsLabel: "Hỗ trợ cộng đồng:", + supportsPrefix: "Phí thuộc về", + supportsSpotOwner: " — người đã tạo spot này!", + supportsPlatform: " — giúp SkateSpots tiếp tục hoạt động.", + oneTimeFee: "~${{usd}} USD • Phí một lần", + payToContinue: "Trả {{amount}} sats để Tiếp tục", + proveWork: "Chứng minh bằng công việc thay vì trả phí — miễn phí", + proveWorkBody: "Dùng vài giây CPU thay vì {{amount}} sats. Không tiền, không ví — một loại thuế spam, không phải thanh toán.", + generating: "Đang tạo hóa đơn...", + processing: "Đang xử lý thanh toán...", + qrAlt: "Mã QR Thanh toán", + copyInvoice: "Sao chép Hóa đơn", + openWallet: "Mở Ví", + payWithWallet: "Trả bằng Ví đã Kết nối", + scanHint: "Quét mã QR bằng ví Lightning hoặc dùng các nút ở trên", + skipTitle: "Cách bỏ qua khoản phí này trong tương lai:", + skip1: "Thêm một skate spot vào bản đồ", + skip2: "Hoàn thành 2-3 tin đăng thành công", + skip3: "Xây dựng uy tín cộng đồng của bạn", + skipNote: "Thành viên đáng tin cậy được đăng miễn phí không giới hạn!", + }, + reputation: { + highlyTrusted: "Người giao dịch rất đáng tin cậy", + building: "Đang xây dựng uy tín", + newTrader: "Người giao dịch mới", + title: "Giao dịch", + verified: "Đã xác minh", + sales: "Đã bán", + purchases: "Đã mua", + tradeConfirmedOne: "giao dịch được xác nhận lẫn nhau", + tradeConfirmedMany: "giao dịch được xác nhận lẫn nhau", + with: "với", + personOne: "người", + personMany: "người", + awaiting: "Đang chờ xác nhận lẫn nhau", + withPaymentProof: "có đính kèm bằng chứng thanh toán", + selfReported: "(tự khai — chưa xác minh)", + paymentVerified: "đã xác minh thanh toán", + zapReceipt: "(biên lai zap)", + singlePartnerWarning: "Mọi xác nhận đều với cùng một tài khoản. Xác nhận lẫn nhau là tự khai, nên hãy xem xét hồ sơ này cẩn thận.", + lowDiversityWarning: "Hầu hết xác nhận đến từ rất ít tài khoản. Một nhóm nhỏ bảo chứng cho nhau có thể trông sôi động — hãy xem xét hồ sơ này cẩn thận.", + ringWarning: "Các tài khoản này chủ yếu giao dịch với nhau — một cụm khép kín. Xác nhận lẫn nhau trong một vòng là bằng chứng yếu.", + weighted: "Có trọng số theo tin cậy & hoạt động", + footnote: "Tự khai và được ký lẫn nhau — một tín hiệu, không phải bằng chứng thanh toán.", + }, + reputationPanel: { + reviewOfYou: "Đánh giá về bạn", + yourRecord: "hồ sơ của bạn", + listing: "Tin đăng", + averageOne: "trung bình từ {{count}} đánh giá", + averageMany: "trung bình từ {{count}} đánh giá", + reviewsTitle: "Đánh giá & hồ sơ giao dịch", + fromOthers: "{{count}} từ người khác", + emptyBefore: "Chưa có hồ sơ giao dịch. Hoàn tất một thỏa thuận và xác nhận nó trong", + emptyAfter: "— mỗi xác nhận trở thành một đánh giá trên cả hai hồ sơ.", + }, + recommendations: { + published: "Đã đăng đề xuất", + publishedBody: "Cảm ơn bạn đã bảo chứng.", + failed: "Không thể đề xuất", + somethingWrong: "Đã xảy ra lỗi.", + title: "Người giao dịch đáng tin cậy", + recommendedBy: "Được đề xuất bởi", + skaterOne: "skater", + skaterMany: "skater", + none: "Chưa có đề xuất nào.", + youRecommend: "Bạn đề xuất người giao dịch này ✓", + recommend: "Đề xuất là người giao dịch đáng tin cậy", + }, + notification: { + newOffer: "Đề nghị mới", + counterOffer: "Phản đề nghị", + offerAccepted: "Đề nghị được chấp nhận", + offerDeclined: "Đề nghị bị từ chối", + offerWithdrawn: "Đề nghị đã rút", + confirmTrade: "Xác nhận một giao dịch", + tradeConfirmed: "Đã xác nhận giao dịch", + reviewOffer: "Xem xét đề nghị", + openListing: "Mở tin đăng", + }, + confirmRow: { + rateTrade: "Đánh giá giao dịch:", + }, + deckRating: { + title: "{{value}}/10 deck", + aria: "{{n}} trên 10", + }, + clink: { + tip: "Tip bằng Bitcoin", + copiedBody: "Đã sao chép mã CLINK vào clipboard.", + copyFailed: "Sao chép thất bại", + copyFailedBody: "Không thể truy cập clipboard.", + whatIs: "CLINK là gì?", + tooltipTitle: "Thanh toán trực tiếp bằng Bitcoin qua Nostr", + tooltipBody: "CLINK là một mã thanh toán tự quản — không tài khoản ứng dụng, không trung gian. Quét nó bằng ví Lightning tương thích và tiền tip sẽ đến thẳng họ.", + descRecipient: "Gửi thanh toán Bitcoin (Lightning) tự quản cho {{recipientName}} — không trung gian.", + descGeneric: "Gửi thanh toán Bitcoin (Lightning) tự quản qua Nostr — không trung gian.", + qrAlt: "Mã QR CLINK Offer", + copyCode: "Sao chép mã CLINK", + openWallet: "Mở trong ví CLINK", + copyToWallet: "Sao chép mã cho ví của bạn", + priceFixed: "Cố định — {{amount}} sats", + priceFixedShort: "Giá cố định", + priceVariable: "Giá linh hoạt", + priceVariableCurrency: "Định giá bằng {{currency}}", + priceSpontaneous: "Bạn chọn số tiền", + footnote: "Quét bằng ví tương thích CLINK (ví dụ ShockWallet). Nếu không mở được gì, hãy sao chép mã ở trên — có thể bạn chưa cài ví tương thích CLINK. Không người giữ hộ, không máy chủ web: hóa đơn được yêu cầu trực tiếp qua Nostr.", + }, + paymentReadiness: { + ready: "Bạn có thể được trả tiền", + notReady: "Thiết lập thanh toán để được trả tiền", + readyBefore: "Địa chỉ Lightning của bạn", + readyAfter: " đã có trên hồ sơ — mọi người có thể zap và trả tiền trực tiếp cho bạn.", + silentSet: " Một địa chỉ Bitcoin Silent Payment cũng đã được đặt.", + notReadyBefore: "Thêm địa chỉ Lightning (và tùy chọn địa chỉ Bitcoin Silent Payment) vào", + nostrProfile: "hồ sơ Nostr", + notReadyAfter: "để các skater có thể trả tiền cho bạn. Chỉ cần đặt một lần và hoạt động trên mọi hồ sơ bạn có ở đây.", + }, + seller: { + trade: "Trao đổi", + active: "Đang hoạt động", + markSold: "Đánh dấu đã bán", + yourListings: "Tin đăng của bạn", + activeCount: "{{count}} đang hoạt động", + listItem: "Đăng một vật phẩm", + loading: "Đang tải tin đăng của bạn…", + empty: "Bạn chưa có tin đăng nào.", + listFirst: "Đăng vật phẩm đầu tiên của bạn", + }, + noffer: { + label: "Mã CLINK Offer", + optional: "(tùy chọn, nâng cao)", + offerId: "Offer: {{id}}", + relay: "Relay: {{relay}}", + invalidBefore: "Đó có vẻ không phải là", + invalidAfter: "hợp lệ.", + valid: "Mã CLINK hợp lệ — nút \"Trả qua CLINK\" sẽ hiển thị trên hồ sơ của bạn.", + help: "Dán một mã thanh toán CLINK tự quản (ví dụ từ ShockWallet / Lightning.Pub) để nhận thanh toán Lightning gốc Nostr — không máy chủ web hay người giữ hộ.", + learnSpecs: "Tìm hiểu thông số", + }, + escrowPanel: { + escrowed: "Đã escrow {{amount}} sats", + mint: "Mint", + refundSinceBefore: "Người mua có thể hoàn tiền từ", + redeemBefore: "Người bán có thể đổi ngay · người mua hoàn tiền sau", + noExpiry: "Token này không đặt ngày hết hạn.", + }, + escrowRequest: { + enterAmount: "Nhập số tiền escrow", + minLock: "Khóa ít nhất {{days}} ngày", + requestNote: "Đã escrow {{amount}} sats cho giao dịch của chúng ta — vui lòng xác nhận giao dịch bán.", + created: "Đã tạo escrow 🎉", + createdBody: "Đã khóa {{amount}} sats trong {{days}} ngày. {{sellerName}} có thể đổi khi giao hàng.", + createFailed: "Không thể tạo escrow", + somethingWrong: "Đã xảy ra lỗi.", + title: "Escrow giao dịch này", + description: "Tiền được khóa cho {{sellerName}} và bạn có thể hoàn lại nếu thỏa thuận đổ vỡ sau hạn chót. Cần một ví Lightning đã kết nối.", + amountLabel: "Số tiền (sats)", + daysLabel: "Người mua hoàn tiền sau (ngày)", + daysHint: "Sau ngần này ngày bạn có thể đòi lại tiền nếu người bán chưa giao hàng.", + nativeOnly: "Cashu escrow chỉ có trong ứng dụng SkateSpots (không có trong bản web).", + lockAndRequest: "Khóa & yêu cầu", + }, + }, + labOptions: { + coach: { + skill: { + basics: "Cơ bản", + ollies: "Ollies", + kickflips: "Kickflips", + grinds: "Grinds & Slides", + manuals: "Manuals", + inverts: "Inverts", + vert: "Vert/Ramp", + bowl: "Bowl", + street: "Street", + freestyle: "Freestyle", + safety: "An toàn", + diy: "Mô-đun DIY Skate", + }, + skillDesc: { + basics: "Đẩy, tư thế, thăng bằng, xoay", + ollies: "Ollie và các biến thể (nollie, fakie)", + kickflips: "Kickflip, heelflip và các biến thể", + grinds: "50-50, 5-0, boardslide và hơn thế", + manuals: "Manual, nose manual, combo", + inverts: "Invert, handplant, eggplant, andrecht", + vert: "Half-pipe, quarter-pipe, drop-in", + bowl: "Lướt bowl, pumping, line", + street: "Chướng ngại vật đường phố và sáng tạo", + freestyle: "Trick mặt phẳng và mạch chảy", + safety: "Cách ngã, đồ bảo hộ, phòng tránh chấn thương", + diy: "Xây ramp, rail, ledge và các chướng ngại vật trượt ván khác", + }, + }, + filmer: { + service: { + miniclips: "Clip ngắn", + longparts: "Video Part dài", + koth: "Kiểu King of the Road", + documentaries: "Phim tài liệu", + contests: "Quay cho Cuộc thi", + raw: "Footage thô", + followlines: "Quay Follow / Line", + lines: "Quay Line & B-Roll", + }, + serviceDesc: { + miniclips: "Clip 15-60 giây cho mạng xã hội", + longparts: "Video part đầy đủ 3-10 phút kèm nhạc", + koth: "Video trượt ván kiểu phiêu lưu/thử thách", + documentaries: "Nội dung về văn hóa trượt ván và kể chuyện", + contests: "Đưa tin cuộc thi và giải đấu chuyên nghiệp", + raw: "Footage nhiều góc chưa dựng", + followlines: "Follow-cam fisheye cho line", + lines: "Line ống kính dài và b-roll điện ảnh", + }, + skill: { + vx1000: "VX1000", + hvx: "HVX / HPX", + cinema: "Máy quay Cinema", + dslr: "DSLR / Mirrorless", + actioncam: "GoPro / Action Cam", + phone: "Quay bằng điện thoại", + drone: "Drone / Trên không", + gimbal: "Gimbal / Chống rung", + fisheye: "Ống kính Fisheye", + longlens: "Ống kính dài", + "4k": "4K / Tốc độ khung hình cao", + editing: "Dựng video", + color: "Chỉnh màu", + }, + skillDesc: { + vx1000: "Thẩm mỹ trượt ván VX1000 cổ điển", + hvx: "Phong cách Panasonic HVX/HPX độ nét thấp / HD", + cinema: "Máy quay cinema (FX3, dòng C, RED, BMPCC)", + dslr: "Máy ảnh DSLR hoặc mirrorless chất lượng cao", + actioncam: "GoPro / action cam góc nhìn POV và ngàm gắn", + phone: "Quay bằng điện thoại thông minh hiện đại", + drone: "Footage trên không và drone", + gimbal: "Chuyển động gimbal ổn định", + fisheye: "Cảnh ống kính fisheye góc rộng", + longlens: "Ống kính dài cho cảnh chi tiết", + "4k": "Độ phân giải 4K và slow-mo tốc độ khung hình cao", + editing: "Dựng video và hậu kỳ chuyên nghiệp", + color: "Chỉnh và phân loại màu", + }, + }, + editor: { + service: { + parts: "Video Part", + montages: "Montage", + reels: "Reels / Clip ngắn", + documentaries: "Phim tài liệu", + contest: "Dựng clip Cuộc thi", + brand: "Video Thương hiệu / Quảng cáo", + motion: "Motion Graphics", + colorgrade: "Chỉ Chỉnh màu", + }, + serviceDesc: { + parts: "Video part trượt ván đầy đủ kèm nhạc nền", + montages: "Dựng tổng hợp từ footage thô", + reels: "Clip & reel mạng xã hội 15–60 giây", + documentaries: "Phim về văn hóa trượt ván kể chuyện", + contest: "Dựng recap cho cuộc thi và event", + brand: "Nội dung quảng bá cho thương hiệu và shop", + motion: "Tiêu đề, chuyển cảnh, hiệu ứng và đồ họa", + colorgrade: "Chỉnh màu và phân loại dựa trên LUT", + }, + skill: { + premiere: "Adobe Premiere", + resolve: "DaVinci Resolve", + finalcut: "Final Cut Pro", + aftereffects: "After Effects", + luts: "LUT tùy chỉnh", + vhs: "Thẩm mỹ VHS / Retro", + "4k": "Quy trình 4K & RAW", + sound: "Thiết kế âm thanh / Mix", + }, + skillDesc: { + premiere: "Dựng bằng Adobe Premiere Pro", + resolve: "Dựng & chỉnh màu bằng DaVinci Resolve", + finalcut: "Dựng bằng Final Cut Pro", + aftereffects: "Motion graphics và compositing", + luts: "Phát triển tông màu tùy chỉnh", + vhs: "Lỗi VHS, super-8, tông phim retro", + "4k": "Quy trình máy quay RAW/LOG độ phân giải cao", + sound: "Đồng bộ nhạc, SFX, master âm thanh", + }, + }, + photo: { + service: { + action: "Ảnh Hành động / Trick", + sequence: "Ảnh Chuỗi", + portraits: "Chân dung", + editorial: "Biên tập / Tạp chí", + product: "Ảnh Sản phẩm / Shop", + events: "Đưa tin Event", + lifestyle: "Phong cách sống / Tài liệu", + prints: "Bản in & Zines", + }, + serviceDesc: { + action: "Ảnh đỉnh hành động của trick và line", + sequence: "Chuỗi trick nhiều khung hình", + portraits: "Chân dung rider và ảnh đội", + editorial: "Trang biên tập sẵn sàng cho tạp chí", + product: "Ảnh sản phẩm deck, gear và shop", + events: "Đưa tin cuộc thi, jam và công chiếu", + lifestyle: "Hậu trường và tài liệu văn hóa", + prints: "Bản in vật lý, zines và sách ảnh", + }, + camera: { + dslr: "DSLR", + mirrorless: "Mirrorless", + medium: "Khổ trung", + film35: "Phim 35mm", + filmmedium: "Phim khổ trung", + point: "Point & Shoot", + phone: "Điện thoại", + }, + lens: { + fisheye: "Fisheye", + wide: "Góc rộng", + standard: "Tiêu chuẩn / Prime", + telephoto: "Telephoto / Ống kính dài", + macro: "Macro", + zoom: "Zoom", + }, + lighting: { + strobes: "Đèn Studio Strobes", + speedlights: "Speedlights / Đèn flash", + profoto: "Profoto", + elinchrom: "Elinchrom", + godox: "Godox", + triggers: "Bộ kích hoạt từ xa", + continuous: "Đèn liên tục / LED", + reflectors: "Tấm phản / Tán sáng", + naturallight: "Chỉ ánh sáng tự nhiên", + }, + support: { + tripod: "Chân máy", + monopod: "Chân máy đơn", + lightstands: "Chân đèn", + gimbal: "Gimbal", + bag: "Rig di động / Túi", + laptop: "Tethering tại chỗ", + }, + style: { + flashfisheye: "Flash Fisheye", + natural: "Ánh sáng tự nhiên", + bw: "Đen & trắng", + film: "Thẩm mỹ phim", + longlens: "Ống kính dài", + studio: "Studio / Có đèn", + street: "Đường phố / Tài liệu", + }, + }, + builder: { + service: { + diy: "Spot DIY", + concrete: "Công viên bê tông", + wood: "Ramp gỗ", + bowls: "Bowl & Pool", + transitions: "Transition & Quarter", + rails: "Rail & Ledge", + boxes: "Manny Pad & Box", + minis: "Mini Ramp", + pumptrack: "Pump Track", + foam: "Hố xốp / Trong nhà", + repairs: "Sửa chữa & Làm mới bề mặt", + design: "Thiết kế & Tư vấn", + }, + serviceDesc: { + diy: "Spot DIY cộng đồng và xây dựng tự phát", + concrete: "Skatepark và hạng mục bê tông đổ", + wood: "Ramp gỗ, launch box và chướng ngại vật", + bowls: "Bowl, pool và transition sâu", + transitions: "Quarterpipe, bank và transition", + rails: "Rail thép, ledge và hạng mục grind", + boxes: "Manny pad, funbox và hạng mục đường phố", + minis: "Mini ramp và setup sân sau", + pumptrack: "Pump track và line chảy", + foam: "Hố xốp, resi và hạng mục luyện trong nhà", + repairs: "Sửa, vá và làm mới bề mặt spot hiện có", + design: "Bản vẽ, thiết kế và tư vấn xây dựng", + }, + skill: { + concretework: "Bê tông / Shotcrete", + welding: "Hàn / Gia công thép", + carpentry: "Mộc / Đồ gỗ", + formwork: "Cốp pha & Cốt thép", + masonry: "Xây / Khối", + coping: "Coping (pool / thép)", + surfacing: "Skatelite / Bề mặt", + earthworks: "San lấp / Đào", + }, + scale: { + backyard: "Sân sau / Mini", + diycommunity: "DIY Cộng đồng", + publicpark: "Công viên công cộng đầy đủ", + indoor: "Cơ sở trong nhà", + event: "Sân Event / Cuộc thi", + }, + }, + artist: { + service: { + boardart: "Họa tiết Board", + logos: "Logo & Nhận diện", + posters: "Poster & Tờ rơi", + merch: "Merch & Trang phục", + zines: "Zines & In ấn", + illustration: "Minh họa", + stickers: "Sticker & Decal", + webdesign: "Web / Kỹ thuật số", + typography: "Typography / Chữ vẽ tay", + animation: "Hoạt hình / Motion", + }, + serviceDesc: { + boardart: "Họa tiết deck và nghệ thuật griptape", + logos: "Nhận diện thương hiệu, logo và wordmark", + posters: "Poster event, tờ rơi và nghệ thuật gig", + merch: "Đồ họa áo thun, hoodie và trang phục", + zines: "Zines, biên tập và dàn trang in", + illustration: "Minh họa tùy chỉnh và nhân vật", + stickers: "Bộ sticker, decal và slaps", + webdesign: "Website, kỹ thuật số và UI", + typography: "Chữ vẽ tay và kiểu chữ tùy chỉnh", + animation: "Motion graphics và hoạt hình", + }, + medium: { + digital: "Kỹ thuật số / Vector", + handdrawn: "Vẽ tay", + screenprint: "In lụa", + paint: "Sơn / Acrylic", + collage: "Collage / Hỗn hợp", + photo: "Ảnh / Photoshop", + "3d": "3D / Render", + }, + tool: { + illustrator: "Adobe Illustrator", + photoshop: "Adobe Photoshop", + procreate: "Procreate", + affinity: "Affinity", + figma: "Figma", + blender: "Blender", + aftereffects: "After Effects", + clipstudio: "Clip Studio", + }, + }, + graffiti: { + style: { + throwups: "Throw-up", + pieces: "Piece / Burner", + murals: "Tranh tường", + characters: "Nhân vật", + lettering: "Chữ / Wildstyle", + stencil: "Stencil", + handstyles: "Handstyle / Tag", + "3dstyle": "Phong cách 3D", + abstract: "Trừu tượng", + }, + styleDesc: { + throwups: "Tô nhanh hai màu", + pieces: "Piece và burner đủ màu", + murals: "Tranh tường quy mô lớn và production", + characters: "Tác phẩm nhân vật và hình thể", + lettering: "Wildstyle và cấu trúc chữ", + stencil: "Stencil và street art", + handstyles: "Tag và handstyle", + "3dstyle": "Chữ 3D và anamorphic", + abstract: "Trừu tượng và tự do", + }, + medium: { + spray: "Bình xịt", + rollers: "Con lăn / Emulsion", + markers: "Bút lông / Mực", + brush: "Cọ / Sơn", + digital: "Kỹ thuật số / Procreate", + }, + context: { + legalwalls: "Tường hợp pháp", + commissions: "Đặt hàng", + liveart: "Vẽ trực tiếp", + skateparks: "Tranh tường Skatepark", + interiors: "Nội thất / Shop", + workshops: "Hội thảo", + }, + }, + tattoo: { + style: { + traditional: "Traditional / Old School", + neotraditional: "Neo-Traditional", + fineline: "Fine Line", + blackwork: "Blackwork", + realism: "Tả thực", + lettering: "Chữ / Script", + illustrative: "Minh họa", + skateflash: "Skate Flash", + ignorant: "Ignorant / Kiểu Handpoke", + japanese: "Nhật / Irezumi", + }, + styleDesc: { + traditional: "Nét đậm, Americana cổ điển", + neotraditional: "Traditional với chi tiết hiện đại", + fineline: "Tác phẩm kim đơn tinh tế", + blackwork: "Đen đặc và họa tiết", + realism: "Tả thực như ảnh và chân dung", + lettering: "Script, chữ và câu trích dẫn", + illustrative: "Minh họa và đồ họa", + skateflash: "Mẫu flash văn hóa trượt ván", + ignorant: "Phong cách ignorant / handpoke ngây ngô", + japanese: "Nhật truyền thống / irezumi", + }, + method: { + machine: "Máy", + handpoke: "Hand-Poke / Stick & Poke", + flash: "Có Flash", + custom: "Thiết kế tùy chỉnh", + coverup: "Che hình cũ", + }, + }, + trainer: { + focus: { + strength: "Sức mạnh & Thể lực", + mobility: "Linh hoạt & Mềm dẻo", + injuryprevention: "Phòng tránh chấn thương", + rehab: "Phục hồi / Vật lý trị liệu", + recovery: "Hồi phục & Bodywork", + balance: "Thăng bằng & Ổn định", + cardio: "Cardio / Sức bền", + nutrition: "Hướng dẫn dinh dưỡng", + }, + focusDesc: { + strength: "Xây dựng sức mạnh và sức bật cho trượt ván", + mobility: "Biên độ chuyển động và độ mềm dẻo", + injuryprevention: "Prehab và giảm nguy cơ chấn thương", + rehab: "Vật lý trị liệu và phục hồi sau chấn thương", + recovery: "Mát-xa, bodywork và hồi phục", + balance: "Cảm nhận vị trí, thăng bằng và ổn định", + cardio: "Thể lực và sức bền", + nutrition: "Tư vấn nạp năng lượng và dinh dưỡng", + }, + injury: { + ankles: "Cổ chân", + knees: "Đầu gối", + wrists: "Cổ tay", + hips: "Hông", + back: "Lưng / Cột sống", + shoulders: "Vai", + heelbruise: "Bầm gót chân", + concussion: "Phác đồ chấn động não", + }, + credential: { + physio: "Bác sĩ Vật lý trị liệu có phép", + osteo: "Chuyên gia Xương khớp", + certtrainer: "Huấn luyện viên có chứng chỉ", + sportstherapist: "Chuyên viên Trị liệu Thể thao", + massage: "Chuyên viên Mát-xa", + inperson: "Trực tiếp", + remote: "Từ xa / Trực tuyến", + }, + }, + musician: { + genre: { + punk: "Punk", + hardcore: "Hardcore", + metal: "Metal", + rock: "Rock", + indie: "Indie / Alt", + hiphop: "Hip-Hop / Rap", + electronic: "Electronic", + lofi: "Lo-Fi / Beats", + reggae: "Reggae / Dub", + ska: "Ska", + jazz: "Jazz", + funk: "Funk / Soul", + flamenco: "Flamenco", + folk: "Folk / Acoustic", + experimental: "Thử nghiệm", + grunge: "Grunge", + }, + instrument: { + vocals: "Giọng hát", + guitar: "Guitar", + bass: "Bass", + drums: "Trống", + keys: "Keys / Synth", + dj: "DJ / Bàn xoay", + producer: "Producer / Beats", + sax: "Sax / Kèn đồng", + strings: "Đàn dây", + other: "Khác", + }, + act: { + solo: "Nghệ sĩ Solo", + band: "Ban nhạc", + dj: "DJ", + producer: "Producer", + collective: "Tập thể", + }, + }, + judge: { + format: { + game_of_skate: "Game of S.K.A.T.E.", + best_trick: "Best Trick", + jam: "Hình thức Jam", + contest: "Cuộc thi / Comp", + street_league: "Kiểu Street League", + bowl: "Bowl / Vert", + mini_ramp: "Mini Ramp", + park: "Park", + street: "Street", + freestyle: "Freestyle", + world_tour: "World Destruction Tour", + am_series: "Am Series / Vòng loại", + local_jam: "Jam Địa phương / Phong trào", + online: "Trực tuyến / Cuộc thi IG", + }, + specialty: { + head_judge: "Trưởng Ban giám khảo", + scoring: "Chấm điểm / Tổng hợp", + mc: "MC / Người dẫn", + format_design: "Thiết kế thể thức", + rules: "Luật / Điều hành", + brackets: "Nhánh đấu / Lượt", + livestream: "Chấm qua livestream", + am_scout: "Tuyển chọn Am", + }, + level: { + local: "Địa phương", + regional: "Vùng", + national: "Quốc gia", + international: "Quốc tế", + pro: "Pro Circuit", + }, + }, + organizer: { + event: { + street_jam: "Street Jam", + best_trick: "Best Trick", + game_of_skate: "Game of S.K.A.T.E.", + contest: "Cuộc thi / Comp", + bowl: "Bowl / Vert", + mini_ramp: "Mini Ramp", + park: "Buổi Park", + demo: "Pro Demo", + clinic: "Clinic / Hội thảo", + meetup: "Gặp mặt / Cruise", + downhill: "Downhill / Đua", + slalom: "Slalom", + kids: "Trẻ em / Thanh thiếu niên", + charity: "Từ thiện / Gây quỹ", + tour_stop: "Chặng Tour", + premiere: "Công chiếu Video", + market: "Chợ / Triển lãm Nghệ thuật", + }, + service: { + organizing: "Tổ chức Toàn bộ", + hosting: "Dẫn chương trình / MC", + permits: "Giấy phép & Chính quyền", + sponsorship: "Tài trợ / Thỏa thuận Thương hiệu", + promotion: "Quảng bá & Marketing", + livestream: "Livestream / Đưa tin", + sound: "Âm thanh & Nhạc", + ramps: "Ramp & Chướng ngại vật", + safety: "An toàn & Sơ cứu", + vendors: "Đồ ăn & Gian hàng", + media: "Ảnh / Video đưa tin", + registration: "Đăng ký & Nhánh đấu", + }, + scale: { + grassroots: "Phong trào", + local: "Địa phương", + regional: "Vùng", + national: "Quốc gia", + international: "Quốc tế", + pro: "Pro Circuit", + }, + }, + barber: { + service: { + haircut: "Cắt tóc", + fade: "Fade", + beard: "Tỉa râu", + lineup: "Line-up / Shape-up", + colour: "Nhuộm & Tẩy màu", + kids: "Cắt cho trẻ", + }, + serviceDesc: { + haircut: "Kiểu cắt cổ điển — tông đơ và kéo.", + fade: "Fade chuyển bậc — thấp, vừa hoặc cao.", + beard: "Tỉa, tạo hình và gọn gàng râu.", + lineup: "Đường viền sạch quanh chân tóc và gáy.", + colour: "Nhuộm, tẩy, nhuộm màu và toning.", + kids: "Cắt kiên nhẫn cho các skater nhỏ tuổi.", + }, + style: { + skin_fade: "Skin Fade", + taper: "Taper", + buzz: "Buzz Cut", + mohawk: "Mohawk", + mullet: "Mullet", + curly: "Xoăn / Afro", + long: "Tóc dài / Tỉa lớp", + classic: "Cắt kéo cổ điển", + }, + setting: { + shop: "Shop / Tiệm cắt tóc", + mobile: "Di động / Đến nhà", + event: "Event & Cuộc thi Trượt ván", + }, + }, + tour: { + skill: { + beginner: { + label: "Người mới", + description: "Mới trượt ván hoặc trick cơ bản", + }, + intermediate: { + label: "Trung cấp", + description: "Thoải mái với hầu hết địa hình", + }, + advanced: { + label: "Nâng cao", + description: "Skater dày dặn, spot hiểm", + }, + all: { + label: "Mọi trình độ", + description: "Phù hợp với mọi người", + }, + }, + }, + }, +}; export default viBatch6; diff --git a/src/i18n/vi/batch7.ts b/src/i18n/vi/batch7.ts index ee76955..9526cfb 100644 --- a/src/i18n/vi/batch7.ts +++ b/src/i18n/vi/batch7.ts @@ -1,4 +1,908 @@ -/** vi — batch 7. Filled by the translation pass; empty until then. */ -const viBatch7 = {}; +/** vi — batch 7. Translated from the English source. */ +const viBatch7 = { + events: { + title: 'Sự kiện trượt ván', + createEvent: 'Tạo sự kiện', + editEvent: 'Chỉnh sửa sự kiện', + eventDetails: 'Chi tiết sự kiện', + eventName: 'Tên sự kiện', + eventType: 'Loại sự kiện', + date: 'Ngày', + time: 'Giờ', + startDate: 'Ngày bắt đầu', + endDate: 'Ngày kết thúc', + venue: 'Địa điểm', + organizer: 'Người tổ chức', + attendees: 'Người tham dự', + going: 'Sẽ tham gia', + interested: 'Quan tâm', + rsvp: 'RSVP', + ticketPrice: 'Giá vé', + freeEntry: 'Vào cửa miễn phí', + register: 'Đăng ký', + moreInfo: 'Thêm thông tin', + upcomingEvents: 'Sắp tới', + pastEvents: 'Đã qua', + noEvents: 'Không tìm thấy sự kiện', + findEvents: 'Tìm cuộc thi, demo, buổi trượt và hơn thế nữa', + searchPlaceholder: 'Tìm kiếm sự kiện...', + loginToCreate: 'Đăng nhập để tạo sự kiện', + noEventsMatch: 'Không có sự kiện sắp tới nào khớp với bộ lọc của bạn.', + noUpcoming: 'Không tìm thấy sự kiện sắp tới.', + noPast: 'Không tìm thấy sự kiện đã qua.', + types: { + contest: 'Cuộc thi', + session: 'Buổi trượt', + meetup: 'Gặp gỡ', + premiere: 'Công chiếu video', + workshop: 'Hội thảo', + demo: 'Demo', + jam: 'Jam', + }, + }, + wallet: { + title: 'Ví', + balance: 'Số dư', + send: 'Gửi', + receive: 'Nhận', + transactions: 'Giao dịch', + history: 'Lịch sử', + noTransactions: 'Chưa có giao dịch', + sendSats: 'Gửi Sats', + receiveSats: 'Nhận Sats', + amount: 'Số tiền', + recipient: 'Người nhận', + lightning: 'Lightning', + onChain: 'On-chain', + invoice: 'Hóa đơn', + address: 'Địa chỉ', + scanQR: 'Quét QR', + paste: 'Dán', + payInvoice: 'Thanh toán hóa đơn', + createInvoice: 'Tạo hóa đơn', + copied: 'Đã sao chép vào clipboard!', + insufficientFunds: 'Không đủ tiền', + paymentSent: 'Đã gửi thanh toán!', + paymentReceived: 'Đã nhận thanh toán!', + cashu: { + title: 'Ví Cashu', + tokens: 'Token', + mint: 'Mint', + mints: 'Mints', + manageMints: 'Quản lý Mints', + addMint: 'Thêm Mint', + removeMint: 'Xóa Mint', + defaultMint: 'Mint mặc định', + backup: 'Sao lưu', + restore: 'Khôi phục', + recoveryPhrase: 'Cụm từ khôi phục', + viewRecoveryPhrase: 'Xem cụm từ khôi phục', + seedWarning: 'Điều này giống như nsec Nostr của bạn - hãy giữ bí mật và sao lưu cẩn thận!', + }, + }, + spots: { + addSpot: 'Thêm Spot', + editSpot: 'Chỉnh sửa Spot', + spotDetails: 'Chi tiết Spot', + spotName: 'Tên Spot', + spotType: 'Loại Spot', + description: 'Mô tả', + location: 'Vị trí', + address: 'Địa chỉ', + photos: 'Ảnh', + addPhotos: 'Thêm ảnh', + obstacles: 'Chướng ngại vật', + features: 'Đặc điểm', + bustLevel: 'Mức độ bị đuổi', + bestTime: 'Thời điểm đẹp nhất', + tips: 'Mẹo', + reviews: 'Đánh giá', + addReview: 'Thêm đánh giá', + reportSpot: 'Báo cáo Spot', + directions: 'Chỉ đường', + shareSpot: 'Chia sẻ Spot', + createdBy: 'Tạo bởi', + lastUpdated: 'Cập nhật lần cuối', + types: { + park: 'Công viên trượt ván', + street: 'Spot đường phố', + diy: 'Spot DIY', + plaza: 'Quảng trường', + indoor: 'Trong nhà', + bowl: 'Bowl', + vert: 'Vert', + miniramp: 'Mini Ramp', + }, + bustLevels: { + chill: 'Thoải mái', + moderate: 'Trung bình', + sketchy: 'Rủi ro', + heavy: 'Gay gắt', + }, + }, + settings: { + title: 'Cài đặt', + profile: 'Hồ sơ', + editProfile: 'Chỉnh sửa hồ sơ', + account: 'Tài khoản', + security: 'Bảo mật', + relays: 'Relay', + appearance: 'Giao diện', + language: 'Ngôn ngữ', + notifications: 'Thông báo', + privacy: 'Quyền riêng tư', + about: 'Giới thiệu', + help: 'Trợ giúp', + feedback: 'Phản hồi', + version: 'Phiên bản', + displayName: 'Tên hiển thị', + username: 'Tên người dùng', + bio: 'Tiểu sử', + website: 'Trang web', + lightningAddress: 'Địa chỉ Lightning', + profilePicture: 'Ảnh đại diện', + banner: 'Ảnh bìa', + saveProfile: 'Lưu hồ sơ', + backupKeys: 'Sao lưu khóa', + exportKeys: 'Xuất khóa', + secretKey: 'Khóa bí mật', + publicKey: 'Khóa công khai', + showSecretKey: 'Hiện khóa bí mật', + hideSecretKey: 'Ẩn khóa bí mật', + copyKey: 'Sao chép khóa', + keysBackedUp: 'Bạn đã xác nhận rằng khóa của mình được sao lưu an toàn.', + keysNotBackedUp: 'Hãy đảm bảo sao lưu cụm từ khôi phục hoặc khóa bí mật của bạn!', + selectLanguage: 'Chọn ngôn ngữ', + english: 'Tiếng Anh', + spanish: 'Tiếng Tây Ban Nha', + }, + createSpot: { + title: 'Thêm một Spot trượt ván', + subtitle: 'Chia sẻ một Spot trượt ván với cộng đồng', + backToMap: 'Quay lại bản đồ', + namePlaceholder: 'ví dụ: Trường Trung học Hollywood', + descriptionPlaceholder: 'Mô tả Spot, chướng ngại vật, thời điểm trượt tốt nhất, thông tin an ninh, v.v.', + addressPlaceholder: 'ví dụ: 1521 N Highland Ave, Los Angeles, CA', + selectType: 'Chọn loại Spot', + selectBustLevel: 'Chọn mức độ bị đuổi', + uploadPhotos: 'Tải lên', + dragDrop: 'Kéo thả hoặc nhấp để tải lên', + maxPhotos: 'Tối đa 5 ảnh', + publishing: 'Đang đăng...', + success: 'Đã đăng Spot thành công!', + error: 'Không thể đăng Spot', + locationRequired: 'Vui lòng chọn một vị trí trên bản đồ', + useCurrentLocation: 'Dùng vị trí hiện tại của tôi', + pickOnMap: 'Chọn vị trí trên bản đồ', + loginToAdd: 'Bạn cần đăng nhập để thêm Spot trượt ván.', + locationLabel: 'Vị trí', + tapToPlace: 'Nhấp vào bản đồ để đặt ghim, hoặc kéo để điều chỉnh.', + manualCoords: 'Nhập tọa độ thủ công', + moreDetails: 'Thêm chi tiết (không bắt buộc)', + photoHint: 'cần có ảnh để đăng', + nameRequired: 'Vui lòng nhập tên cho Spot này.', + descriptionRequired: 'Vui lòng mô tả Spot này.', + addressRequired: 'Vui lòng thêm địa chỉ hoặc tên khu vực.', + photoRequired: 'Vui lòng thêm ít nhất một ảnh.', + draftTitle: 'Bạn có một bản nháp chưa lưu', + draftBody: 'Tiếp tục từ chỗ bạn dừng lại, hoặc hủy bỏ.', + draftResume: 'Tiếp tục', + draftDiscard: 'Hủy bản nháp', + requiredFields: 'Hãy cho chúng tôi biết về Spot này. Tất cả các trường có dấu * là bắt buộc.', + coordinates: 'Tọa độ', + latitudePlaceholder: 'Vĩ độ (ví dụ: 34.1012)', + longitudePlaceholder: 'Kinh độ (ví dụ: -118.3389)', + gettingLocation: 'Đang lấy vị trí...', + accessType: 'Loại truy cập', + publicTitle: 'Công khai - Mở cho mọi người', + publicDesc: 'Công viên trượt ván, quảng trường công cộng, Spot đường phố', + privateTitle: 'Tài sản riêng - Cần xin phép', + privateDesc: 'Ramp sân sau, đất riêng, Spot có cổng', + localsTitle: 'Hỏi người địa phương trước', + localsDesc: 'Tôn trọng Spot, đừng làm lộ nó', + contactInfo: 'Thông tin liên hệ', + contactPlaceholder: 'ví dụ: Số điện thoại, Instagram, email...', + contactHintPrivate: 'Mọi người nên liên hệ với bạn thế nào để xin phép?', + contactHintLocals: 'Mọi người nên liên hệ thế nào để hỏi về Spot?', + }, + marketplace: { + title: 'Chợ', + subtitle: 'Mua, bán và trao đổi Gear trượt ván', + addListing: 'Thêm tin đăng', + condition: 'Tình trạng', + conditions: { + new: 'Mới', + likeNew: 'Như mới', + good: 'Tốt', + fair: 'Khá', + poor: 'Kém', + }, + categories: { + all: 'Tất cả', + decks: 'Ván', + trucks: 'Trucks', + wheels: 'Bánh xe', + bearings: 'Vòng bi', + shoes: 'Giày', + clothing: 'Quần áo', + protection: 'Bảo hộ', + other: 'Khác', + }, + priceRange: 'Khoảng giá', + location: 'Vị trí', + seller: 'Người bán', + contact: 'Liên hệ người bán', + makeOffer: 'Đưa ra đề nghị', + sold: 'Đã bán', + available: 'Còn hàng', + gear: 'Gear', + sellGear: 'Bán Gear', + wantToBuy: 'Muốn mua', + }, + auth: { + login: 'Đăng nhập', + logout: 'Đăng xuất', + signUp: 'Đăng ký', + signUpTitle: 'Mới với Nostr?', + signUpDesc: 'Tạo tài khoản mới để bắt đầu. Miễn phí và mở.', + orLogIn: 'Hoặc đăng nhập', + loginWithExtension: 'Đăng nhập bằng Tiện ích mở rộng', + loginWithAmber: 'Đăng nhập bằng Amber (Android)', + loginWithKey: 'Khóa bí mật (nsec) hoặc Cụm từ khôi phục', + loginWithBunker: 'Đăng nhập bằng Nostr Connect', + bunkerUri: 'Chuỗi kết nối Bunker', + openAmber: 'Mở Amber', + connectToBunker: 'Kết nối với Bunker', + noExtension: 'Không phát hiện tiện ích mở rộng nào.', + extensionHelp: 'Thử dùng nút Đăng ký ở trên để tạo tài khoản mới, hoặc dùng các tab Amber, Khóa hoặc Bunker nếu bạn đã có thông tin đăng nhập.', + amberDesc: 'Amber là ứng dụng ký Nostr an toàn cho thiết bị Android. Nhấp vào nút bên dưới để mở Amber và cấp quyền truy cập.', + bunkerDesc: 'Truy cập tài khoản của bạn từ bất kỳ thiết bị nào bằng trình ký từ xa (bunker). Khóa của bạn vẫn an toàn trên máy chủ, không bao giờ lộ ra cho trang web.', + keyPlaceholder: 'nsec1... hoặc cụm từ khôi phục 12 từ của bạn', + keyHint: 'Bạn có thể dán khóa nsec hoặc cụm từ khôi phục 12 từ', + uploadKeyFile: 'Tải lên tệp khóa của bạn', + loggingIn: 'Đang đăng nhập...', + connecting: 'Đang kết nối...', + verifying: 'Đang xác minh...', + }, + createEvent: { + title: 'Tạo một sự kiện', + subtitle: 'Tổ chức một sự kiện trượt ván cho cộng đồng', + backToEvents: 'Quay lại sự kiện', + namePlaceholder: 'ví dụ: Buổi trượt ván hè', + descriptionPlaceholder: 'Mô tả sự kiện, những gì sẽ diễn ra, luật lệ, giải thưởng, v.v.', + selectType: 'Chọn loại sự kiện', + venuePlaceholder: 'ví dụ: Skatepark Venice Beach, CA', + selectDate: 'Chọn ngày', + selectTime: 'Chọn giờ', + ticketPricePlaceholder: 'Để trống cho sự kiện miễn phí', + publishing: 'Đang đăng...', + success: 'Đã đăng sự kiện thành công!', + error: 'Không thể đăng sự kiện', + loginToCreate: 'Bạn cần đăng nhập để tạo sự kiện.', + requiredFields: 'Hãy cho chúng tôi biết về sự kiện này. Tất cả các trường có dấu * là bắt buộc.', + startDateTime: 'Ngày & Giờ bắt đầu', + endDateTime: 'Ngày & Giờ kết thúc (không bắt buộc)', + coordinatesOptional: 'Tọa độ (không bắt buộc)', + coverImage: 'Ảnh bìa', + uploadCover: 'Tải lên ảnh bìa', + nip05Recommended: 'Nên xác minh NIP-05', + nip05Desc: 'Thêm định danh NIP-05 vào hồ sơ của bạn để xác minh danh tính và tạo dựng niềm tin với người tham dự.', + addNip05: 'Thêm NIP-05 trong Cài đặt', + }, + labPage: { + title: 'The Lab', + subtitle: 'Học kỹ thuật. Ghi lại khoảnh khắc. Kết nối với những Skater khác', + coachesTab: 'Huấn luyện', + filmersTab: 'Quay phim', + offerCoaching: 'CUNG CẤP HUẤN LUYỆN', + offerFilming: 'CUNG CẤP DỊCH VỤ QUAY PHIM', + loginToOffer: 'Đăng nhập để cung cấp dịch vụ', + whatToLearn: 'BẠN MUỐN HỌC GÌ?', + whatContent: 'BẠN MUỐN LOẠI NỘI DUNG NÀO?', + selectSkillsDesc: 'Chọn kỹ năng và chúng tôi sẽ ghép bạn với huấn luyện viên', + selectFilmingDesc: 'Chọn dịch vụ quay phim bạn đang tìm', + searchPlaceholder: 'Tìm theo tên, vị trí hoặc kỹ năng...', + noServicesYet: 'CHƯA CÓ DỊCH VỤ NÀO', + beFirstToOffer: 'Hãy là người đầu tiên cung cấp dịch vụ huấn luyện hoặc quay phim cho cộng đồng!', + skills: 'Kỹ năng', + rate: 'Giá', + perHour: '/giờ', + contact: 'Liên hệ', + viewProfile: 'Xem hồ sơ', + noProfilesYet: 'Chưa có hồ sơ nào', + beFirstCoach: 'Hãy là người đầu tiên đăng ký làm huấn luyện viên!', + beFirstFilmer: 'Hãy là người đầu tiên đăng ký làm filmer!', + yearsExperience: 'năm kinh nghiệm', + }, + skills: { + kickflip: 'Kickflip', + heelflip: 'Heelflip', + ollie: 'Ollie', + treflip: '360 Flip', + shuvit: 'Shuvit', + hardflip: 'Hardflip', + varial: 'Varial', + nollie: 'Nollie', + fakie: 'Fakie', + switch: 'Switch', + grind: 'Grind', + slide: 'Slide', + manual: 'Manual', + transition: 'Transition', + bowl: 'Bowl', + vert: 'Vert', + street: 'Street', + flatground: 'Flatground', + }, + lab: { + title: 'The Lab', + subtitle: 'Nâng tầm kỹ năng trượt ván của bạn', + coaches: 'Huấn luyện viên', + filmers: 'Filmer', + findCoach: 'Tìm huấn luyện viên', + becomeCoach: 'Trở thành huấn luyện viên', + findFilmer: 'Tìm filmer', + becomeFilmer: 'Trở thành filmer', + hourlyRate: 'Giá theo giờ', + experience: 'Kinh nghiệm', + specialties: 'Chuyên môn', + availability: 'Thời gian rảnh', + bookSession: 'Đặt buổi học', + contactCoach: 'Liên hệ huấn luyện viên', + noCoaches: 'Không tìm thấy huấn luyện viên trong khu vực của bạn', + noFilmers: 'Không tìm thấy filmer trong khu vực của bạn', + }, + shops: { + title: 'Shop trượt ván', + addShop: 'Thêm Shop', + editShop: 'Chỉnh sửa Shop', + shopDetails: 'Chi tiết Shop', + shopName: 'Tên Shop', + hours: 'Giờ mở cửa', + phone: 'Điện thoại', + website: 'Trang web', + services: 'Dịch vụ', + brands: 'Thương hiệu', + supportLocal: 'Ủng hộ địa phương', + nip05: 'NIP-05 của Shop', + nip05Hint: 'Một định danh tùy chọn do bạn kiểm soát cho Shop này (ví dụ: shop@yourdomain.com), được xác minh với khóa của bạn. Thêm tối đa 5.', + }, + becomeFilmer: { + title: 'Trở thành filmer', + subtitle: 'Ghi lại những clip đỉnh nhất cho cộng đồng', + bioPlaceholder: 'Cho chúng tôi biết về kinh nghiệm quay phim và thiết bị của bạn...', + specialtiesPlaceholder: 'ví dụ: mắt cá, ống kính dài, drone, dựng phim', + selectSpecialties: 'Chọn chuyên môn của bạn', + hourlyRate: 'Giá theo giờ (sats)', + ratePlaceholder: 'ví dụ: 5000', + locationPlaceholder: 'Thành phố hoặc khu vực của bạn', + portfolioUrl: 'URL portfolio', + portfolioPlaceholder: 'Liên kết đến tác phẩm của bạn (YouTube, Instagram, v.v.)', + publishing: 'Đang đăng hồ sơ...', + success: 'Đã tạo hồ sơ filmer!', + error: 'Không thể tạo hồ sơ', + }, + food: { + title: 'Điểm ăn uống', + subtitle: 'Nạp năng lượng trước hoặc sau buổi trượt', + addFood: 'Thêm điểm ăn uống', + categories: { + all: 'Tất cả', + burgers: 'Burger', + pizza: 'Pizza', + tacos: 'Tacos', + coffee: 'Cà phê', + drinks: 'Đồ uống', + snacks: 'Đồ ăn vặt', + }, + skaterFriendly: 'Thân thiện với skater', + nearSpots: 'Gần các Spot trượt ván', + }, + profile: { + posts: 'Bài đăng', + spots: 'Spot', + events: 'Sự kiện', + following: 'Đang theo dõi', + followers: 'Người theo dõi', + editProfile: 'Chỉnh sửa hồ sơ', + follow: 'Theo dõi', + unfollow: 'Bỏ theo dõi', + noPostsYet: 'Chưa có bài đăng nào', + noBio: 'Chưa có tiểu sử', + zapProfile: 'Zap skater này', + }, + becomeCoach: { + title: 'Trở thành huấn luyện viên', + subtitle: 'Chia sẻ kỹ năng của bạn và giúp các skater khác tiến bộ', + bioPlaceholder: 'Cho chúng tôi biết về nền tảng trượt ván và phong cách dạy của bạn...', + skillsPlaceholder: 'ví dụ: kickflip, heelflip, grind, bowl', + selectSkills: 'Chọn kỹ năng bạn có thể dạy', + hourlyRate: 'Giá theo giờ (sats)', + ratePlaceholder: 'ví dụ: 5000', + locationPlaceholder: 'Thành phố hoặc khu vực của bạn', + publishing: 'Đang đăng hồ sơ...', + success: 'Đã tạo hồ sơ huấn luyện viên!', + error: 'Không thể tạo hồ sơ', + }, + weather: { + title: 'Thời tiết', + current: 'Điều kiện hiện tại', + forecast: 'Dự báo', + humidity: 'Độ ẩm', + wind: 'Gió', + feelsLike: 'Cảm giác như', + goodForSkating: 'Tốt để trượt ván!', + notIdeal: 'Điều kiện không lý tưởng', + allWeather: 'Mọi thời tiết', + goodWeather: 'Thời tiết tốt', + perfectWeather: 'Thời tiết hoàn hảo', + }, + errors: { + somethingWentWrong: 'Đã xảy ra lỗi', + tryAgainLater: 'Vui lòng thử lại sau', + notFound: 'Không tìm thấy', + pageNotFound: 'Không tìm thấy trang', + unauthorized: 'Không được phép', + loginRequired: 'Vui lòng đăng nhập để tiếp tục', + networkError: 'Lỗi mạng', + checkConnection: 'Vui lòng kiểm tra kết nối internet của bạn', + invalidInput: 'Dữ liệu nhập không hợp lệ', + requiredField: 'Trường này là bắt buộc', + }, + time: { + today: 'Hôm nay', + yesterday: 'Hôm qua', + tomorrow: 'Ngày mai', + thisWeek: 'Tuần này', + nextWeek: 'Tuần sau', + thisMonth: 'Tháng này', + justNow: 'Vừa xong', + minutesAgo: '{{count}} phút trước', + hoursAgo: '{{count}} giờ trước', + daysAgo: '{{count}} ngày trước', + }, + spotDetail: { + postedBy: 'Đăng bởi', + getDirections: 'Chỉ đường', + reviews: 'Đánh giá', + noReviews: 'Chưa có đánh giá', + beFirstReview: 'Hãy là người đầu tiên đánh giá Spot này!', + writeReview: 'Viết đánh giá', + submitReview: 'Gửi đánh giá', + rating: 'Xếp hạng', + reviewPlaceholder: 'Chia sẻ trải nghiệm của bạn tại Spot này...', + relatedSpots: 'Spot gần đây', + }, + eventDetail: { + organizedBy: 'Tổ chức bởi', + eventInfo: 'Thông tin sự kiện', + location: 'Địa điểm', + dateTime: 'Ngày & Giờ', + price: 'Giá', + attendeeCount: '{{count}} người tham gia', + interested: 'Quan tâm', + going: 'Sẽ tham gia', + notGoing: 'Không tham gia', + share: 'Chia sẻ sự kiện', + }, + venueAccess: { + title: 'Thẻ ra vào', + desc: 'Phát một thẻ đã ký cho người trượt để họ chứng minh quyền ra vào tại cửa — họ xuất trình thẻ và bất kỳ ai cũng có thể quét QR để xác minh.', + active: '{{count}} đang hoạt động', + revoked: '{{count}} đã thu hồi', + issue: 'Phát một thẻ', + verifyHint: 'Được xác minh bằng cách quét — không cần ứng dụng hay tài khoản để kiểm tra.', + publicTitle: 'Thẻ ra vào', + publicDesc: 'Địa điểm này phát thẻ ra vào. Quét thẻ của người trượt tại cửa để xác minh.', + badge: 'Thẻ', + sellerHint: 'Địa điểm của người bán này phát thẻ ra vào', + }, + zaps: { + zapButton: 'Zap', + sendZap: 'Gửi Zap', + zapAmount: 'Số lượng Zap', + customAmount: 'Số tiền tùy chỉnh', + addMessage: 'Thêm tin nhắn (không bắt buộc)', + sending: 'Đang gửi...', + sent: 'Đã gửi Zap!', + failed: 'Zap thất bại', + received: 'Bạn đã nhận được một Zap!', + }, + rewards: { + title: 'Phần thưởng', + yourPoints: 'Điểm của bạn', + earnPoints: 'Kiếm điểm', + redeemPoints: 'Đổi điểm', + leaderboard: 'Bảng xếp hạng', + achievements: 'Thành tích', + dailyTasks: 'Nhiệm vụ hàng ngày', + weeklyTasks: 'Nhiệm vụ hàng tuần', + }, + errorsUi: { + slammedTitle: 'Ngã đau', + slammedBody: 'Có gì đó làm màn hình này gặp trục trặc. Tài khoản và dữ liệu của bạn vẫn an toàn — hãy để chúng tôi giúp bạn lăn bánh trở lại.', + tryAgain: 'Thử lại', + reloadApp: 'Tải lại ứng dụng', + pageSlammedTitle: 'Trang này bị ngã', + pageSlammedBody: 'Có gì đó trên màn hình này gặp trục trặc. Tài khoản và dữ liệu của bạn vẫn an toàn. Thường thì tải lại nhanh là xong.', + reload: 'Tải lại', + goBack: 'Quay lại', + }, + backup: { + title: 'Lưu đăng nhập của bạn', + subtitle: 'Chỉ mất 10 giây — làm một lần thôi', + message: 'Mã khôi phục của bạn là cách duy nhất để quay lại tài khoản. Hãy lưu nó và bạn có thể đăng nhập trên bất kỳ thiết bị nào.', + warning: 'Nếu mất, sẽ không có cách đặt lại — không email, không khôi phục mật khẩu.', + backupNow: 'Lưu ngay', + confirmed: 'Tôi đã lưu rồi', + remindLater: 'Để sau', + }, + bootUi: { + ariaLoading: 'Đang tải SkateSpots', + ariaReady: 'SkateSpots sẵn sàng', + ready: 'Sẵn sàng', + statusWaking: 'Đang đánh thức mạng lưới', + statusTuning: 'Đang điều chỉnh Relay', + statusPulling: 'Đang kéo các Spot', + statusDropping: 'Đang hạ cánh', + }, + footer: { + vibedWith: 'Làm với cảm hứng cùng', + poweredBy: 'Vận hành bởi', + openSource: 'Mã nguồn mở', + contribute: 'Đóng góp', + decentralized: 'Phi tập trung', + communityOwned: 'Cộng đồng sở hữu', + }, + role: { + owner: 'Chủ sở hữu', + admin: 'Quản trị viên', + organiser: 'Người tổ chức', + verifiedOwner: 'Chủ sở hữu đã xác minh', + }, + nfc: { + write: 'Ghi vào thẻ NFC', + written: 'Đã ghi thẻ', + writtenDesc: 'Chạm thẻ vào điện thoại để mở trang xác minh.', + failed: 'Không thể ghi thẻ', + }, + collectionUi: { + namePlaceholder: 'Chuyến đi Barcelona 2024', + descriptionPlaceholder: 'Những Spot yêu thích của tôi từ chuyến đi Barcelona...', + }, + toastsUi: { + followingSuccess: 'Theo dõi thành công', + followingSuccessDesc: 'Người dùng này giờ đã ở trong mạng lưới của bạn', + followFailed: 'Theo dõi thất bại', + unfollowSuccess: 'Bỏ theo dõi thành công', + unfollowSuccessDesc: 'Đã xóa khỏi mạng lưới của bạn', + unfollowFailed: 'Bỏ theo dõi thất bại', + reportThanks: 'Cảm ơn — đã gửi để xem xét', + reportFailed: 'Không thể gửi báo cáo', + savedOffline: 'Đã lưu ngoại tuyến', + savedOfflineDesc: 'Chúng tôi sẽ tự động đăng khi bạn online trở lại.', + cacheCleaned: 'Đã dọn bộ nhớ đệm', + cacheCleanedDesc: 'Đã xóa {{count}} Spot cũ khỏi bộ nhớ đệm', + cacheCleared: 'Đã xóa bộ nhớ đệm', + cacheClearedDesc: 'Tất cả Spot đã lưu trong bộ nhớ đệm đã được xóa', + backOnline: 'Đã online trở lại', + backOnlineDesc: 'Đã gửi {{count}} hành động đã lưu.', + postQueued: 'Bài đăng đã xếp hàng', + postQueuedDesc: 'Bài đăng của bạn sẽ được đăng khi bạn online trở lại', + invalidIdentifier: 'Định danh không hợp lệ. Dùng npub1..., user@domain.com, hoặc khóa công khai hex', + notASpotThanks: 'Cảm ơn — đã gửi để xem xét', + notASpotThanksDesc: 'Không có gì để giận: điều này đánh dấu ghim là lạc đề để mọi người tự quyết định.', + notASpotFailed: 'Không thể gửi báo cáo', + pleaseTryAgain: 'Vui lòng thử lại.', + relayUnreachable: 'Không thể kết nối với Relay nào — kiểm tra kết nối và thử lại.', + loginToReport: 'Đăng nhập để báo cáo Spot.', + zapLoginRequired: 'Cần đăng nhập', + zapLoginRequiredDesc: 'Bạn phải đăng nhập để gửi Zap.', + zapEventNotFound: 'Không tìm thấy sự kiện', + zapEventNotFoundDesc: 'Không thể tìm thấy sự kiện để Zap.', + zapAuthorNotFound: 'Không tìm thấy tác giả', + zapAuthorNotFoundDesc: 'Không thể tìm thấy tác giả của mục này.', + zapSuccess: 'Zap thành công!', + zapSuccessNwcDesc: 'Bạn đã gửi {{amount}} sats qua NWC cho tác giả.', + zapSuccessDesc: 'Bạn đã gửi {{amount}} sats cho tác giả.', + zapStatusUnknown: 'Không rõ trạng thái thanh toán', + zapStatusUnknownDesc: 'Ví của bạn có thể vẫn đang xử lý Zap này. Kiểm tra ví trước khi thử lại — đừng trả hai lần.', + zapNwcFailed: 'Thanh toán NWC thất bại', + zapWeblnFailed: 'Thanh toán WebLN thất bại', + zapFallingBack: '{{error}}. Đang chuyển sang các phương thức thanh toán khác...', + zapFailed: 'Zap thất bại', + zapUnknownNwcError: 'Lỗi NWC không xác định', + zapUnknownWeblnError: 'Lỗi WebLN không xác định', + nwcInvalidUri: 'URI NWC không hợp lệ', + nwcInvalidUriDesc: 'Vui lòng kiểm tra chuỗi kết nối và thử lại.', + nwcExists: 'Kết nối đã tồn tại', + nwcExistsDesc: 'Ví này đã được kết nối.', + nwcConnected: 'Đã kết nối ví', + nwcConnectedDesc: 'Đã kết nối thành công với {{alias}}.', + nwcFailed: 'Kết nối thất bại', + nwcFailedDesc: 'Không thể kết nối với ví: {{error}}', + nwcUnknownError: 'Đã xảy ra lỗi không xác định', + nwcDisconnected: 'Đã ngắt kết nối ví', + nwcDisconnectedDesc: 'Kết nối ví đã được gỡ bỏ.', + deleteApproveAmber: 'Phê duyệt trong Amber', + deleteApproveAmberDesc: 'Amber sẽ mở — nhấn Phê duyệt để xác nhận xóa.', + deleteCancelled: 'Đã hủy', + deleteCancelledDesc: 'Bạn đã từ chối yêu cầu trong Amber.', + deleteCouldntSign: 'Không thể ký', + deletePublishing: 'Bước 2/2: Đang đăng…', + deletePublishingDesc: 'Đang gửi yêu cầu xóa tới các Relay.', + deleteStuck: 'Kẹt ở bước ĐANG ĐĂNG', + deleteStuckDesc: 'Bước Relay thất bại: {{error}}. Nó đã được ký ổn; Relay không xác nhận.', + stashMerged: 'Đã gộp thay đổi từ thiết bị khác', + stashMergedDesc: 'Stash của bạn đã được chỉnh sửa ở nơi khác — cả hai bộ thay đổi đều được giữ lại.', + statusUpdated: 'Đã cập nhật trạng thái!', + statusUpdatedDesc: 'Trạng thái trượt ván của bạn giờ đã hiển thị với người khác.', + statusFailed: 'Không thể đặt trạng thái', + statusCleared: 'Đã xóa trạng thái', + statusClearedDesc: 'Trạng thái của bạn đã được gỡ bỏ.', + statusClearFailed: 'Không thể xóa trạng thái', + nutzapEnabled: 'Đã bật nhận Nutzap', + nutzapEnabledDesc: 'Giờ bạn có thể nhận Zap ecash!', + nutzapSetupFailed: 'Thiết lập thất bại', + nutzapUnavailable: 'Không thể gửi Nutzap', + tokenReceived: 'Đã nhận token', + tokenReceivedDesc: 'Đã đổi token Cashu thành công!', + receiveFailed: 'Nhận thất bại', + invalidAmount: 'Số tiền không hợp lệ', + invalidAmountDesc: 'Vui lòng nhập một số tiền hợp lệ', + tokenCreated: 'Đã tạo token', + sendFailed: 'Gửi thất bại', + mintAdded: 'Đã thêm Mint', + mintAddedDesc: 'Đã thêm và tin cậy Mint thành công', + mintAddFailed: 'Không thể thêm Mint', + mintRemoved: 'Đã xóa Mint', + mintRemoveFailed: 'Không thể xóa Mint', + paymentReceived: 'Đã nhận thanh toán', + paymentReceivedDesc: 'Đã nhận thành công {{amount}} sats!', + paymentSent: 'Đã gửi thanh toán', + paymentSentDesc: 'Thanh toán Lightning đã hoàn tất thành công', + loginRequired: 'Cần đăng nhập', + loginToFollowFounder: 'Vui lòng đăng nhập để theo dõi người sáng lập', + alreadyFollowing: 'Đã theo dõi rồi', + alreadyFollowingDesc: 'Bạn đã theo dõi {{name}} rồi!', + couldNotComplete: 'Không thể hoàn tất thao tác đó', + tryAgainLower: 'Thử lại.', + couldNotLoadProfile: 'Không thể tải hồ sơ', + couldNotLoadProfileDesc: 'Kiểm tra kết nối internet và thử tải lại.', + undone: 'Đã hoàn tác', + undoneDesc: 'Trở lại trung lập — không ẩn, không bảo chứng.', + confirmed: 'Đã xác nhận', + confirmedDesc: 'Đã bảo chứng — mục này rời khỏi hàng đợi.', + hiddenToast: 'Đã ẩn', + couldNotUndo: 'Không thể hoàn tác', + couldNotConfirm: 'Không thể xác nhận', + deleteFailed: 'Xóa thất bại', + somethingWentWrong: 'Đã xảy ra lỗi', + }, + seoUi: { + becomeBuilderTitle: 'Trở thành thợ xây - SkateSpots', + becomeBuilderDesc: 'Đăng dịch vụ xây dựng ramp, công viên và DIY của bạn — bạn xây gì, vật liệu và quy mô.', + tradesTitle: 'Giao dịch của tôi — SkateSpots', + tradesDesc: 'Quản lý giao dịch trên chợ, xác nhận và uy tín của bạn.', + eventsTitle: 'Sự kiện & Tour trượt ván - SkateSpots', + eventsDesc: 'Khám phá các sự kiện, cuộc thi, tour và buổi trượt ván gần bạn.', + editShopDesc: 'Chỉnh sửa Shop trượt ván của bạn.', + createTourDesc: 'Tổ chức các tour trượt ván - tour khám phá điểm ẩn địa phương, road trip quốc gia, phiêu lưu quốc tế, hoặc các cuộc thi phá hoại kiểu KOTR.', + deckDesignerTitle: 'Thiết kế ván — SkateSpots DIY', + deckDesignerDesc: 'Thiết kế đường viền skateboard hoặc longboard, rồi xuất bản mẫu in 1:1, SVG hoặc DXF — bao gồm độ lõm, mũi ván, khoảng cách bánh và lỗ truck.', + createEventTitle: 'Tạo sự kiện trượt ván - SkateSpots', + createEventDesc: 'Tạo một sự kiện trượt ván mới cho cộng đồng.', + editTourDesc: 'Chỉnh sửa tour trượt ván của bạn — cập nhật điểm dừng, ngày và chi tiết.', + walletTitle: 'Ví - SkateSpots', + walletDesc: 'Kết nối ví Lightning để gửi Zap cho các skater và người tạo Spot.', + becomePhotographerTitle: 'Trở thành nhiếp ảnh gia - SkateSpots', + becomePhotographerDesc: 'Tạo hồ sơ nhiếp ảnh trượt ván của bạn — máy ảnh, ống kính, ánh sáng và dịch vụ.', + newsletterTitle: 'Bản tin - SkateSpots', + newsletterDesc: 'Bản tin hàng tuần từ cộng đồng SkateSpots. Cập nhật ứng dụng, Spot mới, sự kiện và những người giữ cho trượt ván luôn sống động.', + homeTitle: 'SkateSpots - Khám phá địa điểm trượt ván trên toàn thế giới', + zapLeaderboardTitle: 'Bảng xếp hạng Zap - SkateSpots', + zapLeaderboardDesc: 'Những Spot trượt ván được Zap nhiều nhất và các thành viên cộng đồng ủng hộ chúng.', + adminReviewTitle: 'Hàng đợi duyệt — SkateSpots', + gearSwapTitle: 'Trao đổi Gear - SkateSpots', + gearSwapDesc: 'Mua & bán Gear trượt ván đã qua sử dụng với các skater khác. Ván, trucks, bánh xe, giày và hơn thế nữa.', + donateTitle: 'Quyên góp — SkateSpots', + donateDesc: 'Ủng hộ SkateSpots — Lightning, on-chain riêng tư (thanh toán im lặng), hoặc tài trợ xây dựng trên Angor.', + verifyCardTitle: 'Xác minh — SkateSpots', + verifyCardDesc: 'Xác minh thẻ SkateSpots hoặc thẻ ra vào.', + mapTitle: 'Bản đồ Spot trượt ván - SkateSpots', + mapDesc: 'Khám phá các Spot trượt ván trên khắp thế giới trên bản đồ tương tác của chúng tôi.', + diyTitle: 'DIY — Tự làm của bạn | SkateSpots', + diyDesc: 'Hướng dẫn, công cụ mở và bản thiết kế để tự làm skateboard, ramp và Spot bê tông của riêng bạn — cùng những người và địa điểm để làm điều đó.', + appShopTitle: 'Shop ứng dụng — SkateSpots', + becomeSkaterTitle: 'Tham gia Danh bạ Skater - SkateSpots', + becomeSkaterDesc: 'Tạo hồ sơ skater của bạn để cộng đồng có thể tìm thấy bạn.', + marketplaceTitle: 'Chợ - SkateSpots', + marketplaceDesc: 'Mua và bán Gear trượt ván trên Plebeian Market phi tập trung.', + becomeEditorTitle: 'Trở thành biên tập viên video - SkateSpots', + becomeEditorDesc: 'Tạo hồ sơ biên tập viên video trượt ván của bạn trên SkateSpots.', + amberCallbackTitle: 'Đăng nhập bằng Amber - SkateSpots', + amberCallbackDesc: 'Hoàn tất đăng nhập Amber (NIP-55) của bạn.', + supportersTitle: 'Người ủng hộ - SkateSpots', + supportersDesc: 'Cộng đồng giữ cho SkateSpots tồn tại — người ủng hộ, cộng tác viên, đối tác và bạn bè.', + becomeCoachTitle: 'Trở thành huấn luyện viên - SkateSpots', + becomeCoachDesc: 'Tạo hồ sơ huấn luyện viên trượt ván của bạn.', + riderCardTitle: 'Thẻ Skater — SkateSpots', + riderCardDesc: 'Tạo Giấy phép Skater hoặc Thẻ ra vào công viên SkateSpots có thể in của bạn.', + editEventDesc: 'Chỉnh sửa sự kiện trượt ván của bạn.', + createShopTitle: 'Thêm Shop trượt ván - SkateSpots', + createShopDesc: 'Thêm Shop trượt ván của bạn vào cộng đồng.', + deckCostTitle: 'Máy tính chi phí ván — SkateSpots DIY', + deckCostDesc: 'Tính toán chi phí làm một tấm ván — nhân công, thiết bị, vật liệu, thời gian xử lý, đóng gói và lợi nhuận — và một giá bán hợp lý.', + pyramidTitle: 'Xếp hạng Pyramid - SkateSpots', + pyramidDesc: 'Những người đóng góp hàng đầu và lãnh đạo cộng đồng.', + foodTitle: 'Đồ ăn gần Spot - SkateSpots', + foodDesc: 'Tìm nhà hàng, quán cà phê và lựa chọn đồ ăn gần các Spot trượt ván.', + createListingTitle: 'Đăng bán Gear - SkateSpots', + createListingDesc: 'Đăng bán Gear trượt ván hoặc tìm Gear bạn muốn mua.', + becomeFilmerTitle: 'Trở thành filmer - SkateSpots', + becomeFilmerDesc: 'Tạo hồ sơ quay phim trượt ván của bạn.', + skatersTitle: 'Skater - SkateSpots', + skatersDesc: 'Khám phá các skater trong cộng đồng SkateSpots. Duyệt theo phong cách, tư thế, trình độ và vị trí.', + communityStatsTitle: 'Thống kê cộng đồng — SkateSpots', + communityStatsDesc: 'Số liệu cộng đồng trực tiếp của SkateSpots — Spot, sự kiện, huấn luyện viên, filmer, biên tập viên, tour và tăng trưởng theo thời gian. Lấy trực tiếp từ Nostr.', + labTitle: 'The Lab - SkateSpots', + labDesc: 'Tìm huấn luyện viên, filmer, nhiếp ảnh gia và biên tập viên video trượt ván.', + stashTitle: 'Stash của tôi - SkateSpots', + stashDesc: 'Quản lý kho Gear riêng tư của bạn. Theo dõi những gì bạn sở hữu, muốn bán hoặc trao đổi.', + bountyLeaderboardTitle: 'Lập bản đồ & Kiếm thưởng - SkateSpots', + bountyLeaderboardDesc: 'Lập bản đồ Spot trượt ván và Shop, kiếm Zap từ cộng đồng. Xem những người đóng góp hàng đầu.', + spotCollectionsTitle: 'Bộ sưu tập Spot của tôi - SkateSpots', + spotCollectionsDesc: 'Sắp xếp các Spot trượt ván yêu thích của bạn thành các bộ sưu tập cá nhân hóa', + mintsTitle: 'Cashu Mints — SkateSpots', + mintsDesc: 'Duyệt các Cashu mint, kiểm tra tình trạng và thêm một cái vào ví của bạn.', + }, + miscUi: { + openingCamera: 'Đang mở camera…', + usePhoneCamera: 'Dùng camera điện thoại, rồi quay lại đây', + startingCamera: 'Đang khởi động camera...', + cameraAccessRequired: 'Cần quyền truy cập camera', + cameraAccessHint: 'Cho phép truy cập camera trong cài đặt trình duyệt, hoặc dùng trình chọn tệp bên dưới.', + cameraErrorTitle: 'Lỗi camera', + cameraErrorDesc: 'Không thể mở camera. Vui lòng kiểm tra quyền ứng dụng trong Cài đặt.', + cameraDeniedTitle: 'Quyền truy cập camera bị từ chối', + cameraDeniedDesc: 'Vui lòng cho phép truy cập camera trong cài đặt trình duyệt.', + uploadFromGallery: 'Tải lên từ thư viện', + uploading: 'Đang tải lên...', + usePhoto: 'Dùng ảnh', + earningPotential: 'Tiềm năng kiếm thưởng', + qualityExcellent: 'Xuất sắc!', + qualityGood: 'Tốt', + qualityBasic: 'Cơ bản', + qualityGettingStarted: 'Mới bắt đầu', + qualityLocationAdded: 'Đã thêm vị trí', + qualityOnePhoto: 'Ít nhất 1 ảnh', + qualityThreePhotos: '3+ ảnh', + qualityMoreAngles: 'Nhiều góc hơn = tốt hơn', + qualityDescription: 'Mô tả', + qualityDetailedDesc: 'Mô tả chi tiết (100+ ký tự)', + qualityContact: 'Thông tin liên hệ', + qualityPhoneOrWebsite: 'Điện thoại hoặc trang web', + qualityHours: 'Giờ mở cửa', + qualitySpotType: 'Đã chọn loại Spot', + failedToLoadComments: 'Không thể tải bình luận', + commentsTitle: 'Bình luận', + noCommentsYet: 'Chưa có bình luận nào', + beFirstComment: 'Hãy là người đầu tiên chia sẻ suy nghĩ của bạn!', + removeMember: 'Xóa thành viên', + whoIsThisFor: 'Hồ sơ này dành cho ai?', + individual: 'Cá nhân', + individualDesc: 'Một người', + collective: 'Tập thể', + collectiveDesc: 'Crew, studio hoặc công ty', + membersLabel: 'Thành viên', + dismissReport: 'Bỏ qua báo cáo', + reportedBy: 'báo cáo bởi', + completingLoginAmber: 'Đang hoàn tất đăng nhập bằng Amber...', + entityMembersHint: 'Thêm tài khoản Nostr của Crew bạn. Mỗi thành viên xác nhận Spot của riêng họ bằng khóa của mình — cho đến lúc đó họ hiển thị là “đang chờ”.', + entityVerifiedHint: 'Tư cách thành viên được xác minh theo từng thành viên — không ai có thể được thêm vào Crew của bạn mà không xác nhận từ tài khoản của chính họ.', + entityInvalidPubkey: 'Nhập npub, nprofile, hoặc khóa công khai hex 64 ký tự hợp lệ.', + entityAlreadyAdded: 'Thành viên đó đã được thêm rồi.', + offline: 'Ngoại tuyến', + connected: 'Đã kết nối', + offlineMode: 'Chế độ ngoại tuyến', + allFeaturesAvailable: 'Tất cả tính năng đều khả dụng', + browsingCachedSpots: 'Đang duyệt các Spot đã lưu đệm', + queuedActions: '{{count}} hành động đang chờ', + syncing: 'Đang đồng bộ', + publishingWhenStable: 'Sẽ đăng khi kết nối ổn định...', + willPublishOnline: 'Sẽ được đăng khi online trở lại', + availableOffline: 'Khả dụng ngoại tuyến:', + offlineBrowseSpots: 'Duyệt các Spot đã xem trước đó', + offlineViewDetails: 'Xem chi tiết Spot đã lưu đệm', + offlineKeepActing: 'Cứ tiếp tục — bài đăng, RSVP, tin đăng và tin nhắn sẽ được xếp hàng và gửi khi bạn kết nối lại', + }, + sasquatchGuide: { + homeTitle: 'Chào mừng đến với SkateSpots! 🦧', + homeMessage: 'Yo, tôi là The Sasquatch. Người giữ ván, đường mòn và những chuyến đi hoang dã. Chào mừng đến với thế giới trượt ván hoang dã trên Nostr—không vest, không quảng cáo, chỉ có những skater tự vẽ con đường riêng. Ở đây, bạn sở hữu kỹ thuật của mình, dữ liệu của mình, và thậm chí kiếm Bitcoin khi để lại dấu ấn. Kết nối với các skater trong khu bạn hoặc trên khắp thế giới. Không luật lệ nào ngoài trượt ván, không dấu chân nào ngoài của bạn.', + homeQ1: 'Lên kế hoạch 3 ngày ở Barcelona cho tôi', + homeQ2: 'Tìm Spot cho người mới', + homeQ3: 'Có sự kiện nào sắp tới không?', + homeQ4: 'Thống kê cộng đồng', + homeQ5: 'Tìm huấn luyện viên gần tôi', + homeQ6: 'Có Gear để bán không?', + homeQ7: 'Nostr là gì?', + homeQ8: 'Cái này miễn phí không?', + homeLearnMore: 'Tìm hiểu thêm', + onboardingTitle: 'Bắt đầu 🚀', + onboardingMessage: 'Để tôi giúp bạn hiểu những điều cơ bản! Nostr là danh tính của bạn, Bitcoin Lightning cho phép bạn kiếm sats từ đóng góp, và Zap là tiền tip tức thì. Hỏi tôi bất cứ điều gì về cách bắt đầu!', + onboardingQ1: 'Làm sao để đăng nhập?', + onboardingQ2: 'Nostr là gì?', + onboardingQ3: 'Nostr hoạt động thế nào?', + onboardingQ4: 'Cashu là gì?', + onboardingQ5: 'Làm sao dùng ví Cashu?', + onboardingQ6: 'Mints là gì?', + onboardingQ7: 'Zap là gì?', + onboardingQ8: 'NWC là gì?', + onboardingStart: 'Bắt đầu khám phá', + onboardingLogin: 'Đăng nhập để bắt đầu', + labTitle: 'Chào mừng đến với The Lab! 🎓', + labMessage: 'Đây là nơi điều kỳ diệu xảy ra! Tìm huấn luyện viên có thể dạy bạn mọi thứ từ kickflip đến darkslide, hoặc kết nối với filmer để ghi lại những buổi trượt đỉnh nhất. Lọc theo kỹ năng, xem kinh nghiệm của họ và đặt buổi học. Nhớ nhé - ai cũng từng bắt đầu từ đâu đó!', + labQ1: 'Tìm huấn luyện viên', + labQ2: 'Tìm filmer', + labQ3: 'Tìm nhiếp ảnh gia', + labQ4: 'Tìm biên tập viên video', + labQ5: 'Tìm thợ xây ramp', + labQ6: 'The Lab là gì?', + labQ7: 'Builder là gì?', + labQ8: 'Làm sao để cung cấp dịch vụ huấn luyện?', + labLogin: 'Đăng nhập để cung cấp dịch vụ', + crewsTitle: 'Crew 🤘', + crewsMessage: 'Crew là gia đình trượt ván gắn với bản đồ của bạn — những người bạn trượt CÙNG, không phải người bạn thuê. Mỗi Crew có sân nhà trên bản đồ, Spot nhà, thành viên và tuyên ngôn. Thành viên xác nhận bằng khóa của chính họ, nên danh sách là chính danh. Hãy lập Crew của riêng bạn hoặc tìm những người bạn của mình!', + crewsQ1: 'Crew là gì?', + crewsQ2: 'Làm sao để lập Crew?', + crewsQ3: 'Crew khác gì The Lab?', + crewsQ4: 'Thành viên xác nhận thế nào?', + crewsQ5: 'Nostr là gì?', + crewsQ6: 'Zap hoạt động thế nào?', + crewsLogin: 'Đăng nhập để tạo Crew', + }, + supportUi: { + keepMapFree: 'Giữ bản đồ miễn phí', + keepMapFreeDesc: 'Không quảng cáo, không theo dõi, không VC. Sats của bạn trả cho hosting, node AI và Relay.', + thankYou: 'Cảm ơn bạn! ⚡', + satsKeepMapFree: 'Sats của bạn giữ bản đồ miễn phí.', + keptFreeNext: 'Bạn vừa giữ SkateSpots miễn phí cho skater tiếp theo.', + scanToPay: 'Quét để thanh toán', + zapSkateSpots: 'Zap SkateSpots', + payQuietly: 'Thanh toán im lặng', + pickAmount: 'Chọn một số tiền', + enterAmount: 'Nhập số sats bạn muốn gửi.', + couldNotStartPayment: 'Không thể bắt đầu thanh toán.', + customAmountAria: 'Số tiền tùy chỉnh bằng sats', + commentPlaceholder: 'Nói gì đó (không bắt buộc — chỉ Zap công khai)', + publicZapTitle: 'Zap công khai kèm bình luận của bạn', + loginToZapTitle: 'Đăng nhập để gửi Zap công khai', + anonymousTitle: 'Ẩn danh — không đăng nhập, không lưu lại', + copyLightningTitle: 'Sao chép địa chỉ Lightning', + copiedSuffix: 'Đã sao chép {{label}}', + invoiceLabel: 'Hóa đơn', + addressLabel: 'Địa chỉ', + notAPurchase: 'Ủng hộ, không phải mua hàng — nó không mua gì và không có hoàn tiền. Hàng hóa và Sasquatch Pro là riêng biệt. Vị trí và danh tính của bạn không bao giờ liên quan đến một khoản thanh toán im lặng.', + }, + statusUi: { + quickStatus: 'Trạng thái nhanh', + skating: 'Đang trượt', + skatingDesc: 'Đang trượt ván', + filming: 'Đang quay phim', + filmingDesc: 'Đang quay kỹ thuật', + lookingForSesh: 'Tìm bạn trượt chung', + lookingForSeshDesc: 'Muốn trượt cùng người khác', + coaching: 'Đang huấn luyện', + coachingDesc: 'Đang dạy/huấn luyện', + chilling: 'Đang thư giãn', + chillingDesc: 'Đang ở Spot chơi', + onMyWay: 'Đang trên đường tới', + onMyWayDesc: 'Đang tới một Spot', + takingABreak: 'Đang nghỉ', + takingABreakDesc: 'Nghỉ ngơi/bổ sung nước', + doneForToday: 'Xong cho hôm nay', + doneForTodayDesc: 'Đã trượt xong', + }, +}; export default viBatch7; diff --git a/src/i18n/vi/batch8.ts b/src/i18n/vi/batch8.ts index 783b409..99f5b8b 100644 --- a/src/i18n/vi/batch8.ts +++ b/src/i18n/vi/batch8.ts @@ -1,4 +1,631 @@ -/** vi — batch 8. Filled by the translation pass; empty until then. */ -const viBatch8 = {}; +/** + * Vietnamese (Tiếng Việt) — batch 8: hardcoded-string sweep namespaces + * (deckCostUi, becomeRolesUi, weatherUi, skaterLabelsUi, notifyUi, + * legacyMiscUi). + * + * Skate/brand vocabulary follows the Vietnamese conventions: Deck, Trucks, + * Wheels, Bearings, Griptape, Spot, Park, Bowl, Vert, Crew, Stash, The Lab, + * sats, Nostr, Lightning, brand names and trick names stay English. + * `{{placeholders}}` are preserved verbatim. + */ +const viBatch8 = { + deckCostUi: { + presetPrompt: 'Đặt tên cho preset này', + presetDefaultName: 'Preset {{n}}', + summaryCopied: 'Đã sao chép bản tóm tắt', + couldNotCopy: 'Không thể sao chép', + resetConfirm: 'Đặt lại mọi thứ về giá trị ví dụ?', + logoTooLarge: 'Logo quá lớn (tối đa 500 KB)', + loginToFill: 'Đăng nhập để điền từ hồ sơ Nostr của bạn', + filledFromProfile: 'Đã điền từ hồ sơ Nostr của bạn', + warnRetailBelowOne: 'Mức markup bán lẻ dưới 1× — bạn sẽ bán lỗ.', + warnWholesaleAboveRetail: 'Markup bán buôn phải thấp hơn markup bán lẻ.', + warnZeroBoards: '{{count}} hàng dùng 0 deck — chi phí của hàng đó bị bỏ qua.', + warnFixedNoBoards: 'Đã đặt chi phí cố định hàng tháng nhưng số deck/tháng là 0, nên chi phí vận hành bị bỏ qua.', + warnNoMaterials: 'Không có chi phí vật liệu — thêm ít nhất một vật liệu.', + warnEquipmentOverhead: 'Thiết bị + chi phí chung chiếm hơn 60% chi phí — mô hình này giả định sản lượng cao; hãy kiểm tra số deck của bạn.', + warnOneBoard: 'Một số thiết bị được dàn trải trên một deck duy nhất — hãy tăng số deck để phân bổ.', + templateStarterName: 'Khởi đầu sở thích', + templateStarterBlurb: 'Một vài hàng, không có chi phí cố định', + templateShopName: 'Cửa hàng nhỏ', + templateShopBlurb: 'Bảng đầy đủ với tiền thuê & chi phí chung', + currency: 'Tiền tệ', + noCurrencyMatches: 'Không có tiền tệ nào khớp.', + ratesUnavailable: 'Tỷ giá trực tiếp không khả dụng — chuyển đổi chỉ đổi nhãn.', + liveRates: 'tỷ giá BTC trực tiếp · đã gồm sats', + chipCost: 'giá vốn', + chipSell: 'bán', + chipTotal: 'tổng', + startFrom: 'Bắt đầu từ', + advancedToggleHint: 'Hiện tỷ lệ và phế liệu theo từng công đoạn, thiết lập lô, thuế và đường cong chi phí theo số lượng', + advanced: 'Nâng cao', + simple: 'Đơn giản', + sectionLabor: 'Nhân công', + sectionEquipment: 'Thiết bị', + sectionOperations: 'Chi phí vận hành', + sectionMaterials: 'Vật liệu', + sectionProcesses: 'Chi phí công đoạn', + sectionPackaging: 'Đóng gói', + sectionMargins: 'Biên lợi nhuận', + subtotalLoaded: '{{value}}/giờ đã gồm phụ phí', + subtotalPerBoard: '{{value}}/deck', + hourlyRate: 'Lương theo giờ ({{unit}})', + labourBurden: 'Phụ phí nhân công (×)', + loadedRate: 'Lương đã gồm phụ phí', + loadedRateHintBefore: 'Lương đã gồm phụ phí = lương × phụ phí (thuế và bảo hiểm người sử dụng lao động trên nhân công). Tiền thuê và hóa đơn nằm ở mục ', + loadedRateHintAfter: ' — đừng tính chúng ở cả hai nơi.', + colEquipment: 'Thiết bị', + colCostUnit: 'Chi phí ({{unit}})', + colCost: 'Chi phí', + colSetupH: 'Thiết lập (giờ)', + colLifetimeBoards: 'Deck trong vòng đời', + colPerBoard: 'Mỗi deck', + colMaterial: 'Vật liệu', + colOrderUnit: 'Đặt hàng ({{unit}})', + colShipUnit: 'Vận chuyển ({{unit}})', + colBoardsOrder: 'Deck / đơn hàng', + colOrderM: 'Đặt hàng (m)', + colUnloadM: 'Dỡ hàng (m)', + colOrder: 'Đặt hàng', + colShipping: 'Vận chuyển', + colOrderMin: 'Đặt hàng (phút)', + colUnloadMin: 'Dỡ hàng (phút)', + colProcess: 'Công đoạn', + colTimeM: 'Thời gian (phút)', + colBoardsRun: 'Deck / lần chạy', + colRateHr: 'Tỷ lệ/giờ (0 = cửa hàng)', + colRateHrShort: 'Tỷ lệ/giờ', + colScrapPct: 'Phế liệu %', + colTimeMin: 'Thời gian (phút)', + colPackaging: 'Đóng gói', + colTimeBoardM: 'Thời gian/deck (phút)', + colTimeBoardMin: 'Thời gian/deck (phút)', + colMaterialsBoardUnit: 'Vật liệu/deck ({{unit}})', + colMaterialsBoard: 'Vật liệu/deck', + equipmentPerBoard: 'Thiết bị mỗi deck:', + materialsPerBoard: 'Vật liệu mỗi deck:', + processesPerBoard: 'Công đoạn mỗi deck:', + packagingPerBoard: 'Đóng gói mỗi deck:', + perBoard: 'Mỗi deck:', + addEquipment: 'Thêm thiết bị', + addMaterial: 'Thêm vật liệu', + addProcess: 'Thêm công đoạn', + addPackagingStep: 'Thêm bước đóng gói', + duplicate: 'Nhân bản', + remove: 'Xóa', + boardsPerMonth: 'Deck / tháng', + rentPerMonth: 'Tiền thuê / tháng', + utilitiesPerMonth: 'Tiện ích / tháng', + subscriptionsPerMonth: 'Đăng ký / tháng', + markup: 'Markup (×)', + wholesaleMarkup: 'Markup bán buôn (×)', + scrapWaste: 'Phế liệu / hao hụt (%)', + quantityDecks: 'Số lượng (deck)', + targetMonthlyProfit: 'Lợi nhuận hàng tháng mục tiêu ({{unit}})', + costNoPackaging: 'Chi phí / deck (không đóng gói)', + costWithPackaging: 'Chi phí / deck (có đóng gói)', + batchSetupHours: 'Thiết lập lô (giờ / lần chạy)', + batchSetupCost: 'Chi phí thiết lập lô ({{unit}} / lần chạy)', + taxVat: 'Thuế / VAT (%)', + quoteTax: 'Thuế báo giá', + includedInPrice: 'Đã gồm trong giá', + addedOnTop: 'Cộng thêm vào', + setupPerBoard: 'Thiết lập / deck', + marginNoteBefore: 'Markup {{markup}}× ≈ ', + grossMargin: 'biên lợi nhuận gộp {{pct}}%', + marginNoteAfter: ' · hao hụt {{waste}}% được dàn trải trên các deck đạt chuẩn.', + sellingPriceNoPackaging: 'Giá bán · không đóng gói', + sellingPriceWithPackaging: 'Giá bán · có đóng gói', + profitPerDeck: 'Lợi nhuận / deck', + wholesalePerDeck: 'Bán buôn / deck', + orderTotalQty: 'Tổng đơn hàng ({{qty}})', + orderTotal: 'Tổng đơn hàng', + breakeven: 'Hòa vốn', + breakevenPerMonth: '{{count}}/tháng', + targetDecksHint: 'Để đạt {{amount}}/tháng trên chi phí cố định, hãy bán {{decks}} deck/tháng.', + priceIncludesTax: 'Giá đã gồm thuế {{pct}}%: {{amount}} trong tổng số.', + plusTax: 'Cộng thuế {{pct}}%: {{amount}} → tổng {{total}}.', + costVsQuantity: 'Chi phí theo số lượng (thiết lập được phân bổ)', + deckOne: 'deck', + deckOther: 'deck', + perDeckSuffix: '/ deck', + orderSuffix: 'đơn hàng {{amount}}', + shippingNotIncluded: 'Không bao gồm phí vận chuyển đến người mua.', + clientQuoteDetails: 'Chi tiết báo giá khách hàng (cho PDF)', + fillFromProfileTitle: 'Điền tên, website, NIP-05, Lightning và npub từ hồ sơ Nostr của bạn', + fillFromProfile: 'Điền từ hồ sơ', + businessName: 'Tên doanh nghiệp / cửa hàng', + email: 'Email', + phone: 'Điện thoại', + website: 'Website', + address: 'Địa chỉ', + quoteNumber: 'Báo giá #', + nextNumber: 'Số tiếp theo', + validDays: 'Hiệu lực (ngày)', + nip05: 'NIP-05', + lightningAddress: 'Địa chỉ Lightning', + nostrNpub: 'Nostr (npub)', + depositPct: 'Đặt cọc trả trước (%)', + deliveryTerms: 'Điều khoản giao hàng (Incoterm, tùy chọn)', + paymentMethods: 'Phương thức thanh toán', + paymentTerms: 'Điều khoản thanh toán', + paymentDetails: 'Chi tiết thanh toán', + notesTerms: 'Ghi chú / điều khoản', + changeLogo: 'Đổi logo', + addLogo: 'Thêm logo', + incotermNone: 'Không', + incotermExw: 'EXW — người mua đến lấy tại người bán', + incotermFca: 'FCA — giao cho hãng vận tải của người mua', + incotermDap: 'DAP — giao đến địa chỉ người mua', + incotermDdp: 'DDP — đã giao, đã trả thuế', + payMethodCash: 'Tiền mặt', + payMethodLightning: 'Lightning', + payMethodCashu: 'Cashu', + payMethodBank: 'Chuyển khoản ngân hàng', + payMethodCard: 'Thẻ', + payMethodOther: 'Khác', + listDeckAtPrice: 'Đăng bán deck ở mức giá này', + getItMade: 'Đặt làm — tìm thợ đóng', + savePreset: 'Lưu preset', + load: 'Tải', + export: 'Xuất', + import: 'Nhập', + reset: 'Đặt lại', + deletePreset: 'Xóa preset', + exportPdfFull: 'PDF — bảng đầy đủ', + exportPdfQuote: 'PDF — báo giá khách hàng', + exportPng: 'Ảnh PNG', + exportXlsx: 'Bảng tính XLSX', + exportCsv: 'CSV (bảng tính)', + exportMarkdown: 'Markdown', + exportJson: 'JSON (sao lưu)', + exportCopySummary: 'Sao chép tóm tắt', + }, + becomeRolesUi: { + artist: { + seoTitle: 'Trở thành Nhà thiết kế / Nghệ sĩ - SkateSpots', + seoDescription: 'Đăng thiết kế & nghệ thuật skate của bạn — hình deck, logo, poster, merch và hơn thế.', + heading: 'Nhà thiết kế / Nghệ sĩ', + tagline: 'Hình deck, logo, poster, merch — đưa nghệ thuật của bạn vào giới skate', + noun: 'nghệ sĩ', + rateLabel: 'Mức giá', + portfolioLabel: 'Liên kết hồ sơ / Cửa hàng', + sectionWhatYouMake: 'Bạn tạo ra gì', + sectionMedium: 'Chất liệu', + sectionSoftwareTools: 'Phần mềm & Công cụ', + deliverablesPlaceholder: 'ví dụ: tệp sẵn sàng in, tệp nguồn, hình deck', + turnaroundPlaceholder: 'ví dụ: 3–5 ngày', + }, + graffiti: { + seoTitle: 'Cung cấp Graffiti / Tranh tường - SkateSpots', + seoDescription: 'Đăng tác phẩm graffiti & tranh tường của bạn — piece, mural, nghệ thuật công viên skate và hơn thế.', + heading: 'Nghệ sĩ Graffiti / Tranh tường', + tagline: 'Piece, mural, nghệ thuật công viên skate — sơn giới skate', + noun: 'nghệ sĩ graffiti', + rateLabel: 'Mức giá', + portfolioLabel: 'Liên kết hồ sơ (IG, web)', + sectionStyle: 'Phong cách', + sectionMedium: 'Chất liệu', + sectionWorkContext: 'Bối cảnh làm việc', + crewLabel: 'Graffiti Crew', + crewPlaceholder: 'Crew viết của bạn (tùy chọn)', + crewHelper: 'Tách biệt với Crew skate của bạn — những writer bạn cùng vẽ.', + surfacesPlaceholder: 'ví dụ: bê tông, gạch, tường được phép', + maxSizePlaceholder: 'ví dụ: tối đa 10 m', + }, + musician: { + seoTitle: 'Thêm hồ sơ âm nhạc - SkateSpots', + seoDescription: 'Trượt ván và làm nhạc? Đăng ban nhạc hoặc dự án solo của bạn — thể loại, nhạc cụ và liên kết.', + heading: 'Nhạc sĩ / Ban nhạc', + tagline: 'Trượt ván và làm nhạc? Nhận đặt biểu diễn cho demo, jam & after-party', + noun: 'nhạc sĩ', + rateLabel: 'Giá đặt biểu diễn', + portfolioLabel: 'Liên kết website / EPK', + sectionGenre: 'Thể loại', + sectionInstruments: 'Nhạc cụ & Vai trò', + actLabel: 'Loại hình biểu diễn', + actPlaceholder: 'solo / band / dj / producer', + spotifyLabel: 'Spotify', + spotifyPlaceholder: 'https://open.spotify.com/…', + bandcampLabel: 'Bandcamp', + bandcampPlaceholder: 'https://…bandcamp.com', + soundcloudLabel: 'SoundCloud', + soundcloudPlaceholder: 'https://soundcloud.com/…', + youtubeLabel: 'YouTube', + youtubePlaceholder: 'https://youtube.com/…', + setLengthPlaceholder: 'ví dụ: 30–45 phút', + techRiderPlaceholder: 'ví dụ: PA, mic, backline', + }, + judge: { + seoTitle: 'Làm giám khảo sự kiện skate - SkateSpots', + seoDescription: 'Đăng bản thân là giám khảo sự kiện skate — Game of S.K.A.T.E., best trick jam, cuộc thi, am series và các chặng world tour. Được đặt để điều hành sự kiện công bằng, đáng tin.', + heading: 'Giám khảo sự kiện skate', + tagline: 'Từ Game of S.K.A.T.E. trên mặt phẳng đến World Destruction Tour — điều hành công bằng, đáng tin', + noun: 'giám khảo', + rateLabel: 'Giá theo ngày / Phí', + portfolioLabel: 'Liên kết kho kết quả / hồ sơ', + sectionEventFormats: 'Hình thức sự kiện', + sectionSpecialty: 'Chuyên môn', + sectionLevelCircuit: 'Cấp độ / Hệ thống', + eventsJudgedLabel: 'Số sự kiện đã chấm', + eventsJudgedPlaceholder: 'ví dụ: 40+ cuộc thi, 3 chặng World Tour', + eventsJudgedHelper: 'Các sự kiện, cuộc thi hoặc tour đáng chú ý bạn từng điều hành.', + travelPlaceholder: 'ví dụ: khu vực / toàn quốc / quốc tế', + certificationsPlaceholder: 'ví dụ: khóa chấm thi quốc gia', + }, + organizer: { + seoTitle: 'Tổ chức sự kiện skate - SkateSpots', + seoDescription: 'Đăng bản thân là nhà tổ chức sự kiện skate — street jam, best trick, cuộc thi, meetup, demo và các chặng tour. Được khám phá và đặt để điều hành buổi chơi.', + heading: 'Nhà tổ chức sự kiện', + tagline: 'Jam, cuộc thi, meetup & demo — tổ chức buổi chơi và gắn kết cộng đồng', + noun: 'nhà tổ chức', + rateLabel: 'Phí / Ngân sách sự kiện', + portfolioLabel: 'Liên kết sự kiện đã qua / kết quả', + sectionEventTypes: 'Loại sự kiện', + sectionWhatYouHandle: 'Bạn phụ trách gì', + sectionScale: 'Quy mô', + eventsHostedLabel: 'Số sự kiện đã tổ chức', + eventsHostedPlaceholder: 'ví dụ: 25 jam, 3 cuộc thi thành phố', + eventsHostedHelper: 'Các sự kiện, cuộc thi hoặc meetup đáng chú ý bạn từng tổ chức.', + insurancePlaceholder: 'ví dụ: đã gồm bảo hiểm trách nhiệm công cộng', + permitsPlaceholder: 'ví dụ: đã xử lý giấy phép chính quyền', + }, + tattoo: { + seoTitle: 'Trở thành nghệ sĩ xăm - SkateSpots', + seoDescription: 'Đăng tác phẩm xăm của bạn cho giới skate — phong cách, flash, custom và hơn thế.', + heading: 'Nghệ sĩ xăm', + tagline: 'Mực cho giới skate — flash, custom, fine line & hơn thế', + noun: 'nghệ sĩ xăm', + rateLabel: 'Mức giá / Theo giờ', + portfolioLabel: 'Liên kết hồ sơ (IG, web)', + sectionStyles: 'Phong cách', + sectionMethod: 'Phương pháp', + studioLabel: 'Studio / Tiệm', + studioPlaceholder: 'Tên studio (tùy chọn)', + booksOpenLabel: 'Đang nhận đặt lịch', + booksOpenHelper: 'Bạn hiện có nhận đặt lịch không?', + depositPlaceholder: 'ví dụ: 50 EUR không hoàn lại', + minimumPlaceholder: 'ví dụ: 80 EUR', + }, + trainer: { + seoTitle: 'Trở thành Huấn luyện viên / Vật lý trị liệu - SkateSpots', + seoDescription: 'Giúp người trượt ván khỏe mạnh — sức mạnh, linh hoạt, phòng chấn thương và hồi phục.', + heading: 'Huấn luyện viên / Vật lý trị liệu', + tagline: 'Sức mạnh, linh hoạt, phòng chấn thương & hồi phục cho người trượt ván', + noun: 'huấn luyện viên', + rateLabel: 'Mức giá / Buổi', + portfolioLabel: 'Liên kết hồ sơ / đặt lịch', + sectionFocus: 'Trọng tâm', + sectionInjuries: 'Chấn thương bạn xử lý', + sectionCredentialsSetting: 'Bằng cấp & Bối cảnh', + credentialsPlaceholder: 'ví dụ: BSc Vật lý trị liệu, CSCS…', + credentialsHelper: 'Liệt kê bằng cấp thật — người trượt ván tin vào chứng chỉ có thể xác minh.', + remoteLabel: 'Từ xa / Trực tuyến', + remoteHelper: 'Bạn có cung cấp huấn luyện hoặc tư vấn trực tuyến không?', + modalitiesPlaceholder: 'ví dụ: thao tác tay, S&C, châm cứu khô', + }, + barber: { + seoTitle: 'Trở thành Thợ cắt tóc / Nhà tạo mẫu tóc - SkateSpots', + seoDescription: 'Đăng tiệm cắt tóc hoặc ghế của bạn cho giới skate — cắt, fade, tỉa râu, nhuộm và hơn thế. Được người trượt ván đặt lịch.', + heading: 'Thợ cắt tóc / Nhà tạo mẫu tóc', + tagline: 'Cắt, fade & tỉa râu cho giới skate — tại tiệm hoặc di động', + noun: 'thợ cắt tóc', + rateLabel: 'Giá / Lần cắt', + portfolioLabel: 'Liên kết thư viện ảnh / IG', + sectionWhatYouOffer: 'Bạn cung cấp gì', + sectionSignatureStyles: 'Phong cách đặc trưng', + sectionSetting: 'Bối cảnh', + studioLabel: 'Tiệm / Studio', + studioPlaceholder: 'Tên tiệm hoặc studio (tùy chọn)', + booksOpenLabel: 'Đang nhận đặt lịch', + booksOpenHelper: 'Bạn hiện có nhận đặt lịch không?', + durationPlaceholder: 'ví dụ: 30–45 phút', + }, + }, + weatherUi: { + condition: { + clearSky: 'Trời quang', + mainlyClear: 'Chủ yếu quang', + partlyCloudy: 'Có mây một phần', + overcast: 'U ám', + foggy: 'Có sương mù', + depositingRimeFog: 'Sương mù đọng giá', + lightDrizzle: 'Mưa phùn nhẹ', + moderateDrizzle: 'Mưa phùn vừa', + denseDrizzle: 'Mưa phùn dày', + lightFreezingDrizzle: 'Mưa phùn đóng băng nhẹ', + denseFreezingDrizzle: 'Mưa phùn đóng băng dày', + slightRain: 'Mưa nhẹ', + moderateRain: 'Mưa vừa', + heavyRain: 'Mưa to', + lightFreezingRain: 'Mưa đóng băng nhẹ', + heavyFreezingRain: 'Mưa đóng băng lớn', + slightSnow: 'Tuyết nhẹ', + moderateSnow: 'Tuyết vừa', + heavySnow: 'Tuyết dày', + snowGrains: 'Hạt tuyết', + slightRainShowers: 'Mưa rào nhẹ', + moderateRainShowers: 'Mưa rào vừa', + violentRainShowers: 'Mưa rào dữ dội', + slightSnowShowers: 'Mưa tuyết nhẹ', + heavySnowShowers: 'Mưa tuyết dày', + thunderstorm: 'Giông bão', + thunderstormSlightHail: 'Giông bão kèm mưa đá nhẹ', + thunderstormHeavyHail: 'Giông bão kèm mưa đá lớn', + unknown: 'Không xác định', + }, + aqi: { + good: 'Tốt', + moderate: 'Trung bình', + unhealthySensitive: 'Có hại cho nhóm nhạy cảm', + unhealthy: 'Có hại cho sức khỏe', + veryUnhealthy: 'Rất có hại cho sức khỏe', + hazardous: 'Nguy hiểm', + }, + skateability: { + perfect: 'Hoàn hảo', + good: 'Tốt', + okay: 'Tạm được', + poor: 'Kém', + bad: 'Xấu', + unrideable: 'Không thể trượt', + }, + reason: { + currentlyRaining: 'Đang mưa', + raining: 'Mưa', + snowing: 'Đang có tuyết', + thunderstorm: 'Giông bão', + freezingTemperature: 'Nhiệt độ đóng băng', + veryCold: 'Rất lạnh', + extremelyHot: 'Cực nóng', + veryHot: 'Rất nóng', + veryStrongWind: 'Gió rất mạnh', + strongWind: 'Gió mạnh', + moderateWind: 'Gió vừa', + veryUnhealthyAir: 'Không khí rất có hại cho sức khỏe', + unhealthyAir: 'Không khí có hại cho sức khỏe', + moderateAirQuality: 'Chất lượng không khí trung bình', + veryHumid: 'Rất ẩm', + humid: 'Ẩm', + extremeUv: 'Tia UV cực cao - hãy dùng kem chống nắng', + highUv: 'Tia UV cao - nên bảo vệ da', + perfectConditions: 'Điều kiện trượt hoàn hảo', + }, + }, + skaterLabelsUi: { + stance: { + regular: 'Regular', + goofy: 'Goofy', + }, + style: { + street: 'Street', + park: 'Park', + vert: 'Vert', + transition: 'Transition', + bowl: 'Bowl', + cruising: 'Cruising', + downhill: 'Downhill', + freestyle: 'Freestyle', + ledges: 'Ledges', + stairs: 'Stairs', + diy: 'DIY', + }, + level: { + grom: 'Grom', + intermediate: 'Intermediate', + advanced: 'Advanced', + ripper: 'Ripper', + }, + sponsor: { + title: 'Nhà tài trợ chính', + gold: 'Gold', + silver: 'Silver', + partner: 'Đối tác', + }, + }, + notifyUi: { + activity: { + zappedWithAmount: 'Bạn được zap {{sats}} sats', + zapped: 'Bạn được zap', + liked: 'Có người thích bài đăng của bạn', + reposted: 'Có người đăng lại bài của bạn', + mentioned: 'Có người nhắc đến bạn', + replied: 'Có người trả lời bạn', + rsvp: 'Có người RSVP sự kiện của bạn', + eventUpdated: 'Sự kiện bạn sắp tham dự đã được cập nhật', + newActivity: 'Hoạt động mới', + tapToOpen: 'Nhấn để mở SkateSpots', + }, + crew: { + inviteTitle: 'Lời mời vào Crew', + inviteBody: 'Bạn được mời vào {{crew}}', + addedTitle: 'Bạn đã được thêm vào một Crew', + addedBody: '{{crew}} — xác nhận để tham gia', + joinRequestTitle: 'Yêu cầu tham gia', + joinRequestBody: 'Có người muốn tham gia {{name}}', + }, + dm: { + title: 'Tin nhắn trực tiếp mới', + body: 'Nhấn để đọc', + }, + trade: { + confirm: 'Xác nhận giao dịch', + confirmed: 'Giao dịch đã được xác nhận', + newOffer: 'Đề nghị mới cho tin đăng của bạn', + counter: 'Đề nghị đối ứng', + accepted: 'Đề nghị đã được chấp nhận 🎉', + declined: 'Đề nghị đã bị từ chối', + withdrawn: 'Đề nghị đã được rút', + }, + newsletter: { + drop: 'Bản tin SkateSpots mới', + }, + summary: { + moreUpdates: '{{count}} cập nhật nữa', + openToCatchUp: 'Mở SkateSpots để xem', + }, + }, + legacyMiscUi: { + hostingGoing: '{{count}} người tham dự', + hostingInterested: '{{count}} người quan tâm', + hostingPostUpdate: 'Đăng cập nhật', + hostingEdit: 'Chỉnh sửa', + hostingLoginToSee: 'Đăng nhập để xem các sự kiện bạn đang tổ chức.', + hostingEmptyTitle: 'Bạn chưa tổ chức sự kiện nào', + hostingEmptyBody: 'Tổ chức một jam, cuộc thi hoặc buổi chơi. Tạo sự kiện để người trượt ván có thể RSVP, nhận cập nhật và ghé qua.', + hostingCreateEvent: 'Tạo sự kiện', + hostingUpcoming: 'Sắp tới · {{count}}', + hostingPast: 'Đã qua · {{count}}', + sponsorPartners: 'Đối tác', + sponsorTitleSponsor: 'Nhà tài trợ chính', + sponsorPlatformPartners: 'Đối tác nền tảng', + reportsUntitled: '(không có tiêu đề)', + reportsResolveFailed: 'Không thể xác minh sự kiện bị báo cáo (có thể đã bị xóa, hoặc báo cáo nhắm vào hồ sơ chứ không phải bài đăng).', + reportsLookAtIt: 'Xem thử', + reportsNoReports: 'Chưa có báo cáo nào. Hoặc mọi thứ đều ổn, hoặc chưa ai tìm thấy nút báo cáo.', + statusSetYourStatus: 'Đặt trạng thái', + statusSetDesc: 'Cho người khác biết bạn đang làm gì. Trạng thái sẽ hiển thị trên hồ sơ và tại các Spot được liên kết.', + statusClear: 'Xóa', + statusOrWriteOwn: 'Hoặc tự viết', + statusCustomPlaceholder: 'Bạn đang làm gì?', + statusLinkToSpot: 'Liên kết tới một Spot (tùy chọn)', + statusSpotSelected: 'Đã chọn Spot', + statusSearchSpots: 'Tìm Spot...', + statusNoSpotsFound: 'Không tìm thấy Spot nào.', + statusSelectSpot: 'Chọn một Spot', + statusAutoClearAfter: 'Tự động xóa sau: {{time}}', + statusExpMin: '{{count}} phút', + statusExpOneHour: '1 giờ', + statusExpHours: '{{count}} giờ', + statusExpOneDay: '1 ngày', + statusExpDays: '{{count}} ngày', + statusSlider15: '15 phút', + statusSlider1h: '1 giờ', + statusSlider4h: '4 giờ', + statusSlider24h: '24 giờ', + statusSetting: 'Đang đặt trạng thái...', + statusSet: 'Đặt trạng thái', + statusSomethingWrong: 'Đã xảy ra lỗi', + seoProfileTitle: 'Hồ sơ - SkateSpots', + seoViewProfile: 'Xem hồ sơ.', + bannerAlt: 'Banner', + openInCordn: 'Mở trong Cordn', + modHelp: 'Ẩn sẽ đăng org.skatespots.moderation / hidden; Xác nhận sẽ đăng … / verified; Hoàn tác sẽ đăng … / cleared (trở về trung lập). Cả ba đều là nhãn công khai, có thể đảo ngược — không có gì bị xóa khỏi relay.', + zapNoActiveMint: 'Không tìm thấy mint Cashu đang hoạt động.', + altProfile: 'Hồ sơ', + altCardPreview: 'Xem trước thẻ', + altCard: 'Thẻ', + altCaptured: 'Đã chụp', + ariaPrevPhoto: 'Ảnh trước', + ariaNextPhoto: 'Ảnh tiếp theo', + ariaCommentOptions: 'Tùy chọn bình luận', + ariaMessageConversation: 'Cuộc trò chuyện tin nhắn', + exportTitle: 'SkateSpots — Máy tính chi phí deck', + exportQuoteTitle: 'BÁO GIÁ', + exportPngTitle: 'Chi phí deck', + exportMarkdownTitle: 'Máy tính chi phí deck', + exportSectionLabor: 'Nhân công', + exportSectionEquipment: 'Thiết bị', + exportSectionOperations: 'Chi phí vận hành', + exportSectionMaterials: 'Vật liệu', + exportSectionProcesses: 'Chi phí công đoạn', + exportSectionPackaging: 'Đóng gói', + exportSectionResult: 'Kết quả', + exportLabelOperations: 'Vận hành', + exportLabelProcesses: 'Công đoạn', + exportKvHourlyRate: 'Lương theo giờ', + exportKvLabourBurden: 'Phụ phí nhân công', + exportKvLoadedRate: 'Lương đã gồm phụ phí', + exportKvEquipmentPerBoard: 'Thiết bị mỗi deck', + exportKvBoardsPerMonth: 'Deck / tháng', + exportKvRentPerMonth: 'Tiền thuê / tháng', + exportKvUtilitiesPerMonth: 'Tiện ích / tháng', + exportKvSubscriptionsPerMonth: 'Đăng ký / tháng', + exportKvPerBoard: 'Mỗi deck', + exportKvMaterialsPerBoard: 'Vật liệu mỗi deck', + exportKvProcessesPerBoard: 'Công đoạn mỗi deck', + exportKvPackagingPerBoard: 'Đóng gói mỗi deck', + exportKvMarkup: 'Markup', + exportMarkupValue: '{{markup}}× (≈ biên lợi nhuận gộp {{pct}}%)', + exportKvWasteEffective: 'Hao hụt (thực tế)', + exportKvCostNoPack: 'Chi phí / deck (không đóng gói)', + exportKvCostWithPack: 'Chi phí / deck (có đóng gói)', + exportKvBatchSetupPerBoard: 'Thiết lập lô / deck', + exportKvTax: 'Thuế ({{pct}}%)', + exportKvTaxIncluded: 'Thuế ({{pct}}%, đã gồm)', + exportKvSellingNoPack: 'Giá bán (không đóng gói)', + exportKvSellingWithPack: 'Giá bán (có đóng gói)', + exportShippingNote: 'Không bao gồm phí vận chuyển đến người mua.', + exportGeneratedBy: 'Được tạo bởi SkateSpots · skate-spots.org', + exportGeneratedWith: 'Được tạo với SkateSpots · skate-spots.org', + exportDetailSetup: '+ {{hours}} giờ thiết lập', + exportDetailBoards: '{{boards}} deck', + exportDetailShip: '+ {{amount}} vận chuyển', + exportDetailMinutes: '{{minutes}} phút', + exportDetailPerBoards: '/ {{boards}} deck', + exportDetailScrap: '{{pct}}% phế liệu', + exportDetailMaterials: '{{materials}} vật liệu', + exportQuoteRef: 'Mã {{ref}}', + exportQuoteLineItem: 'Deck trượt ván tùy chỉnh', + exportQuoteLineItemQty: 'Deck trượt ván tùy chỉnh × {{qty}}', + exportQuoteLineDesc: 'Đóng thủ công, hoàn thiện và đóng gói. Số lượng 1.', + exportQuoteLineDescQty: 'Đóng thủ công, hoàn thiện và đóng gói. {{price}} mỗi cái.', + exportQuoteSubtotal: 'Tạm tính', + exportQuoteSubtotalQty: 'Tạm tính ({{qty}} deck)', + exportQuoteTax: 'Thuế / VAT ({{pct}}%)', + exportQuoteTotal: 'Tổng cộng', + exportQuoteTotalQty: 'Tổng cộng ({{qty}} deck)', + exportQuoteIncludesTax: 'Đã gồm thuế {{pct}}% ({{amount}})', + exportQuoteDeposit: 'Đặt cọc trả ngay ({{pct}}%)', + exportQuoteBalance: 'Số còn lại khi hoàn thành', + exportQuotePayment: 'Thanh toán: {{value}}', + exportQuoteLightning: 'Lightning: {{value}}', + exportQuoteDetails: 'Chi tiết: {{value}}', + exportQuoteTerms: 'Điều khoản: {{value}}', + exportQuoteDelivery: 'Giao hàng: {{value}}', + exportQuoteValidUntil: 'Không bao gồm phí vận chuyển. Báo giá có hiệu lực đến {{date}}.', + exportPngSellingWith: 'GIÁ BÁN · CÓ ĐÓNG GÓI', + exportPngSellingNo: 'GIÁ BÁN · KHÔNG ĐÓNG GÓI', + exportPngCostWith: 'CHI PHÍ / DECK (CÓ ĐÓNG GÓI)', + exportPngDeposit: 'Đặt cọc {{pct}}%: {{amount}}', + exportXlsxSummary: 'Tóm tắt', + exportXlsxCurrency: 'Tiền tệ', + exportXlsxDate: 'Ngày', + exportXlsxOperationsPerBoard: 'Vận hành mỗi deck', + exportColCost: 'Chi phí', + exportColSetupH: 'Thiết lập (giờ)', + exportColBoards: 'Deck', + exportColPerBoard: 'Mỗi deck', + exportColMaterial: 'Vật liệu', + exportColOrderCost: 'Chi phí đặt hàng', + exportColShipping: 'Vận chuyển', + exportColOrderMin: 'Đặt hàng (phút)', + exportColUnloadMin: 'Dỡ hàng (phút)', + exportColProcess: 'Công đoạn', + exportColTimeMin: 'Thời gian (phút)', + exportColTimeBoardMin: 'Thời gian/deck (phút)', + exportColMaterialsBoard: 'Vật liệu/deck', + exportCopyTitle: 'Chi phí deck — {{currency}}', + exportCopyCostWith: 'Chi phí / deck (có đóng gói): {{amount}}', + exportCopySellingNo: 'Giá bán (không đóng gói): {{amount}}', + exportCopySellingWith: 'Giá bán (có đóng gói): {{amount}}', + exportCopyBreakdown: 'Thiết bị {{equipment}} · Vận hành {{operations}} · Vật liệu {{materials}} · Công đoạn {{processes}} · Đóng gói {{packaging}}', + exportMdHourlyRate: 'Lương theo giờ: {{value}}', + exportMdLabourBurden: 'Phụ phí nhân công: {{value}}', + exportMdLoadedRate: 'Lương đã gồm phụ phí: {{value}}', + exportMdBoardsPerMonth: 'Deck/tháng: {{value}}', + exportMdRent: 'Tiền thuê: {{value}}', + exportMdUtilities: 'Tiện ích: {{value}}', + exportMdSubscriptions: 'Đăng ký: {{value}}', + exportMdPerBoard: 'Mỗi deck: {{value}}', + exportMdMarkupWaste: 'Markup: {{markup}}× (≈ biên lợi nhuận gộp {{pct}}%) · Hao hụt: {{waste}}%', + exportMdCostNoPack: 'Chi phí/deck (không đóng gói): {{value}}', + exportMdCostWithPack: 'Chi phí/deck (có đóng gói): {{value}}', + exportMdBatchSetup: 'Thiết lập lô/deck: {{value}}', + exportMdSellingNo: 'Giá bán (không đóng gói): {{value}}', + exportMdSellingWith: 'Giá bán (có đóng gói): {{value}}', + exportMdDisclaimer: 'Không bao gồm phí vận chuyển đến người mua. Được tạo bởi SkateSpots.', + }, +}; export default viBatch8; diff --git a/src/pages/CreateTourPage.tsx b/src/pages/CreateTourPage.tsx index c56c656..df00ed4 100644 --- a/src/pages/CreateTourPage.tsx +++ b/src/pages/CreateTourPage.tsx @@ -38,6 +38,7 @@ const COMMON_LANGUAGES = [ { code: 'ja', label: 'Japanese', flag: '🇯🇵' }, { code: 'zh-CN', label: 'Chinese (Simplified)', flag: '🇨🇳' }, { code: 'zh-TW', label: 'Chinese (Traditional)', flag: '🇹🇼' }, + { code: 'vi', label: 'Vietnamese', flag: '🇻🇳' }, { code: 'tr', label: 'Turkish', flag: '🇹🇷' }, { code: 'zh', label: 'Chinese', flag: '🇨🇳' }, ];