From 5741e7bc651b36533fe527397043aa29a9dc40e9 Mon Sep 17 00:00:00 2001 From: Kuan-Chieh Huang <7856561+kchuang1015@users.noreply.github.com> Date: Sat, 29 Aug 2026 10:29:59 +0800 Subject: [PATCH 1/3] feat(i18n): add Traditional Chinese (Taiwan) locale --- components/providers/intl-provider.tsx | 1 + components/ui/flag-icons.tsx | 17 + components/ui/language-switcher.tsx | 1 + i18n/__tests__/locale-matcher.test.ts | 46 + i18n/detect-locale.ts | 8 +- i18n/locale-matcher.ts | 54 + i18n/request.ts | 25 +- i18n/routing.ts | 2 +- locales/zh-TW/common.json | 3495 ++++++++++++++++++++++++ 9 files changed, 3624 insertions(+), 25 deletions(-) create mode 100644 i18n/__tests__/locale-matcher.test.ts create mode 100644 i18n/locale-matcher.ts create mode 100644 locales/zh-TW/common.json diff --git a/components/providers/intl-provider.tsx b/components/providers/intl-provider.tsx index 816929c00..e02248037 100644 --- a/components/providers/intl-provider.tsx +++ b/components/providers/intl-provider.tsx @@ -45,6 +45,7 @@ export const LOCALE_LOADERS: Record Promise> = { tr: () => import('@/locales/tr/common.json').then((m) => m.default), uk: () => import('@/locales/uk/common.json').then((m) => m.default), zh: () => import('@/locales/zh/common.json').then((m) => m.default), + 'zh-TW': () => import('@/locales/zh-TW/common.json').then((m) => m.default), }; interface IntlProviderProps { diff --git a/components/ui/flag-icons.tsx b/components/ui/flag-icons.tsx index 6713035a8..f6c2cc285 100644 --- a/components/ui/flag-icons.tsx +++ b/components/ui/flag-icons.tsx @@ -214,6 +214,22 @@ export function FlagCN(props: FlagProps) { ); } +/** Taiwan – Red field with blue canton and twelve-ray white sun */ +export function FlagTW(props: FlagProps) { + return ( + + + + + + + + ); +} + /** Czech Republic - White and red horizontal bands with a blue triangle */ export function FlagCS(props: FlagProps) { return ( @@ -374,6 +390,7 @@ export const flagComponents: Record ReactElement> tr: FlagTR, uk: FlagUA, zh: FlagCN, + 'zh-TW': FlagTW, fa: FlagIR, he: FlagIL, ar: FlagAE, diff --git a/components/ui/language-switcher.tsx b/components/ui/language-switcher.tsx index b6700e355..1abc532b2 100644 --- a/components/ui/language-switcher.tsx +++ b/components/ui/language-switcher.tsx @@ -35,6 +35,7 @@ const languages = [ { value: 'ja', label: '日本語' }, { value: 'mn', label: 'Монгол' }, { value: 'zh', label: '简体中文' }, + { value: 'zh-TW', label: '繁體中文(台灣)' }, ]; function FlagIcon({ locale }: { locale: string }) { diff --git a/i18n/__tests__/locale-matcher.test.ts b/i18n/__tests__/locale-matcher.test.ts new file mode 100644 index 000000000..e5c859638 --- /dev/null +++ b/i18n/__tests__/locale-matcher.test.ts @@ -0,0 +1,46 @@ +import { describe, expect, it } from 'vitest'; +import { localeFromAcceptLanguage, matchSupportedLocale } from '../locale-matcher'; + +const supported = ['en', 'fr', 'zh', 'zh-TW'] as const; + +describe('matchSupportedLocale', () => { + it.each([ + ['zh-TW', 'zh-TW'], + ['zh_Hant', 'zh-TW'], + ['zh-Hant-HK', 'zh-TW'], + ['zh-HK', 'zh-TW'], + ['zh-MO', 'zh-TW'], + ['zh-Hans-TW', 'zh'], + ['zh-Hans', 'zh'], + ['zh-CN', 'zh'], + ['zh-SG', 'zh'], + ['zh', 'zh'], + ['fr-CA', 'fr'], + ])('maps %s to %s', (tag, expected) => { + expect(matchSupportedLocale(tag, supported)).toBe(expected); + }); + + it('returns null for unsupported and wildcard tags', () => { + expect(matchSupportedLocale('eo', supported)).toBeNull(); + expect(matchSupportedLocale('*', supported)).toBeNull(); + }); +}); + +describe('localeFromAcceptLanguage', () => { + it('prefers the highest-quality supported locale', () => { + expect(localeFromAcceptLanguage('zh-CN;q=0.7, zh-TW;q=0.9, fr;q=0.8', supported)).toBe('zh-TW'); + }); + + it('uses original order to break equal q-values', () => { + expect(localeFromAcceptLanguage('fr-CA, zh-Hant', supported)).toBe('fr'); + }); + + it('skips disabled, malformed, wildcard, and unsupported entries', () => { + expect(localeFromAcceptLanguage('zh-TW;q=0, *;q=1, eo;q=0.9, zh-CN;q=oops, en;q=0.5', supported)).toBe('en'); + }); + + it('returns null when no supported preference remains', () => { + expect(localeFromAcceptLanguage('eo, *;q=0', supported)).toBeNull(); + expect(localeFromAcceptLanguage(null, supported)).toBeNull(); + }); +}); diff --git a/i18n/detect-locale.ts b/i18n/detect-locale.ts index a20335847..d9d412c83 100644 --- a/i18n/detect-locale.ts +++ b/i18n/detect-locale.ts @@ -1,4 +1,5 @@ import { routing } from './routing'; +import { matchSupportedLocale } from './locale-matcher'; import { useLocaleStore } from '@/stores/locale-store'; /** @@ -11,13 +12,12 @@ import { useLocaleStore } from '@/stores/locale-store'; */ export function detectBrowserLocale(fallback: string): string { if (typeof navigator === 'undefined') return fallback; - const supported = new Set(routing.locales as readonly string[]); const prefs = navigator.languages?.length ? navigator.languages : [navigator.language]; for (const tag of prefs) { if (!tag) continue; - const base = tag.toLowerCase().split('-')[0]; - if (base === 'en') return fallback; // English is the top preference -> keep default - if (supported.has(base)) return base; // first supported non-English preference wins + const locale = matchSupportedLocale(tag, routing.locales); + if (locale === 'en') return fallback; // English is the top preference -> keep default + if (locale) return locale; // first supported non-English preference wins } return fallback; } diff --git a/i18n/locale-matcher.ts b/i18n/locale-matcher.ts new file mode 100644 index 000000000..cc60e5495 --- /dev/null +++ b/i18n/locale-matcher.ts @@ -0,0 +1,54 @@ +type SupportedLocales = readonly string[]; + +const TRADITIONAL_CHINESE_REGIONS = new Set(['tw', 'hk', 'mo']); + +/** + * Match a BCP-47 language tag to one of the locales shipped by Bulwark. + * Chinese needs script/region-aware matching so Traditional Chinese does not + * silently fall back to the Simplified Chinese catalog. + */ +export function matchSupportedLocale(tag: string, supportedLocales: SupportedLocales): string | null { + const normalized = tag.trim().replace(/_/g, '-').toLowerCase(); + if (!normalized || normalized === '*') return null; + + const supported = new Map(supportedLocales.map((locale) => [locale.toLowerCase(), locale])); + const exact = supported.get(normalized); + if (exact) return exact; + + const parts = normalized.split('-'); + const base = parts[0]; + if (base !== 'zh') return supported.get(base) ?? null; + + const script = parts.find((part) => part === 'hans' || part === 'hant'); + const region = parts.find((part) => TRADITIONAL_CHINESE_REGIONS.has(part)); + const traditional = script === 'hant' || (!script && Boolean(region)); + + if (traditional) return supported.get('zh-tw') ?? supported.get('zh') ?? null; + return supported.get('zh') ?? supported.get('zh-tw') ?? null; +} + +/** Resolve an Accept-Language header by q-value against shipped locales. */ +export function localeFromAcceptLanguage( + header: string | null, + supportedLocales: SupportedLocales +): string | null { + if (!header) return null; + + const ranked = header + .split(',') + .map((part, index) => { + const [rawTag, ...parameters] = part.trim().split(';'); + const qParameter = parameters.find((parameter) => parameter.trim().toLowerCase().startsWith('q=')); + const parsedQ = qParameter ? Number.parseFloat(qParameter.split('=')[1]) : 1; + const q = Number.isFinite(parsedQ) && parsedQ >= 0 && parsedQ <= 1 ? parsedQ : 0; + return { tag: rawTag, q, index }; + }) + .filter(({ tag, q }) => Boolean(tag) && q > 0) + .sort((a, b) => b.q - a.q || a.index - b.index); + + for (const { tag } of ranked) { + const locale = matchSupportedLocale(tag, supportedLocales); + if (locale) return locale; + } + return null; +} diff --git a/i18n/request.ts b/i18n/request.ts index 59f3b3258..04e2fc3d2 100644 --- a/i18n/request.ts +++ b/i18n/request.ts @@ -1,33 +1,15 @@ import { getRequestConfig } from 'next-intl/server'; import { headers } from 'next/headers'; import { mergeMessages } from './merge-messages'; +import { localeFromAcceptLanguage } from './locale-matcher'; import { routing, type Locale } from './routing'; -// Default a first-time visitor (no explicit stored choice) to the best supported -// language from their browser's Accept-Language header, so "Auto" is the real -// default and the first server render already matches the browser language. -function localeFromAcceptLanguage(header: string | null): string | null { - if (!header) return null; - const supported = new Set(routing.locales as readonly string[]); - const ranked = header - .split(',') - .map((part) => { - const [tag, q] = part.trim().split(';q='); - return { base: tag.toLowerCase().split('-')[0], q: q ? parseFloat(q) : 1 }; - }) - .sort((a, b) => b.q - a.q); - for (const { base } of ranked) { - if (supported.has(base)) return base; - } - return null; -} - export default getRequestConfig(async ({ requestLocale }) => { let locale = await requestLocale; if (!locale || !routing.locales.includes(locale as Locale)) { const accept = (await headers()).get('accept-language'); - locale = localeFromAcceptLanguage(accept) ?? routing.defaultLocale; + locale = localeFromAcceptLanguage(accept, routing.locales) ?? routing.defaultLocale; } // Use static imports for better compatibility @@ -108,6 +90,9 @@ export default getRequestConfig(async ({ requestLocale }) => { case 'zh': messages = (await import('../locales/zh/common.json')).default; break; + case 'zh-TW': + messages = (await import('../locales/zh-TW/common.json')).default; + break; default: messages = (await import('../locales/en/common.json')).default; } diff --git a/i18n/routing.ts b/i18n/routing.ts index 9ec39c4cc..72a034721 100644 --- a/i18n/routing.ts +++ b/i18n/routing.ts @@ -12,7 +12,7 @@ const localePrefix = (process.env.NEXT_PUBLIC_LOCALE_PREFIX ?? 'never') as | 'always' | 'as-needed'; -const SUPPORTED_LOCALES = ['ar', 'ca', 'cs', 'da', 'de', 'en', 'es', 'fa', 'fr', 'he', 'hu', 'it', 'ja', 'ko', 'lv', 'mn', 'nb', 'nl', 'pl', 'pt', 'ro', 'ru', 'sk', 'tr', 'uk', 'zh'] as const; +const SUPPORTED_LOCALES = ['ar', 'ca', 'cs', 'da', 'de', 'en', 'es', 'fa', 'fr', 'he', 'hu', 'it', 'ja', 'ko', 'lv', 'mn', 'nb', 'nl', 'pl', 'pt', 'ro', 'ru', 'sk', 'tr', 'uk', 'zh', 'zh-TW'] as const; // Fallback locale used when the visitor's Accept-Language header does not // match any supported locale (and no NEXT_LOCALE cookie is set yet). Admins diff --git a/locales/zh-TW/common.json b/locales/zh-TW/common.json new file mode 100644 index 000000000..aa4bafe2d --- /dev/null +++ b/locales/zh-TW/common.json @@ -0,0 +1,3495 @@ +{ + "meta_description": "使用 JMAP 通訊協定的極簡網頁郵件用戶端", + "login": { + "title": "網頁郵件", + "username_label": "電子郵件地址", + "username_placeholder": "user@example.com", + "password_label": "密碼", + "password_placeholder": "請輸入密碼", + "jmap_endpoint_label": "JMAP 伺服器", + "jmap_endpoint_placeholder": "https://mail.example.com", + "jmap_endpoint_cors_hint": "伺服器必須允許來自此網域的 CORS 請求。", + "jmap_server_label": "伺服器", + "jmap_server_auto_picked": "已根據您的電子郵件網域選擇伺服器。", + "sign_in": "登入", + "signing_in": "正在登入…", + "loading": "正在載入…", + "reconnecting": "連線中斷,正在嘗試重新連線…", + "error": { + "invalid_credentials": "電子郵件地址或密碼不正確。請檢查您的登入資訊後再試一次。", + "connection_failed": "無法連線至伺服器。請檢查網路連線後再試一次。", + "cors_blocked": "可連線至伺服器,但跨來源請求遭到封鎖。請檢查 JMAP 伺服器的 CORS 設定,並允許此網域。", + "server_error": "伺服器目前無法使用,請稍後再試。", + "generic": "發生意外錯誤。如果問題持續存在,請聯絡管理員。", + "totp_required": "需要雙因素驗證碼。請在下方輸入驗證碼。", + "totp_invalid": "驗證碼無效。請檢查驗證器應用程式後再試一次。", + "oauth_discovery_failed": "SSO 已啟用,但無法連線至身分提供者。請檢查 OAuth 設定。" + }, + "show_password": "顯示密碼", + "hide_password": "隱藏密碼", + "totp_toggle": "我有 2FA 驗證碼", + "remember_me": "記住我", + "config_error": { + "title": "設定錯誤", + "fetch_failed": "無法載入應用程式設定。請稍後再試。", + "server_not_configured": "郵件伺服器尚未設定。請聯絡您的管理員。" + }, + "remove_from_history": "從歷史記錄中移除", + "totp_label": "驗證碼", + "totp_placeholder": "000000", + "session_expired": "工作階段已過期,請重新登入。", + "dismiss": "關閉", + "or": "或", + "sign_in_sso": "使用 SSO 登入", + "add_account_title": "新增帳號", + "add_account_subtitle": "使用其他帳號登入", + "cancel": "取消", + "website": "網站", + "imprint": "法律聲明", + "privacy_policy": "隱私權政策", + "try_demo": "試用示範版", + "demo_description": "使用範例資料自由探索,不需要帳號", + "demo_launching": "正在啟動示範版…", + "demo_login_button": "啟動示範版", + "demo_tagline": "體驗功能完整的電子郵件用戶端,不需要帳號。", + "demo_no_signup": "不需要註冊,使用範例資料自由探索", + "oauth_completing": "正在完成登入…", + "oauth_error": { + "title": "驗證失敗", + "invalid_state": "安全驗證失敗。請嘗試重新登入。", + "missing_params": "缺少授權資料。請嘗試重新登入。", + "token_exchange_failed": "無法完成身分驗證。請再試一次。", + "access_denied": "存取遭拒。請聯絡管理員。", + "back_to_login": "返回登入頁面" + } + }, + "sidebar": { + "close": "關閉", + "compose": "撰寫郵件", + "compose_hint": "撰寫郵件 (c)", + "search_placeholder": "搜尋郵件…", + "search_placeholder_hint": "搜尋郵件…(按 /)", + "storage": "儲存空間", + "storage_used": "已使用", + "storage_free": "剩餘", + "storage_total": "總計", + "sign_out": "登出", + "sign_out_of": "登出 {account}", + "sign_out_all": "登出所有帳號", + "add_account": "新增帳號", + "set_as_default": "設為預設", + "switch_account": "切換帳號", + "contacts": "聯絡人", + "calendar": "行事曆", + "settings": "設定", + "admin": "管理", + "files": "檔案", + "loading_mailboxes": "正在載入信件匣…", + "push_connected": "即時更新已啟用", + "push_disconnected": "即時更新未啟用", + "keyboard_shortcuts": "鍵盤快速鍵", + "theme": { + "light": "淺色模式", + "dark": "深色模式", + "system": "系統主題" + }, + "language": { + "title": "語言" + }, + "mailboxes": { + "inbox": "收件匣", + "sent": "寄件備份", + "drafts": "草稿", + "trash": "垃圾桶", + "archive": "封存", + "starred": "已加星號", + "all_mail": "所有郵件", + "spam": "垃圾郵件", + "important": "重要" + }, + "unified_inbox": "整合收件匣", + "unified_sent": "所有寄件備份", + "unified_drafts": "所有草稿", + "unified_trash": "所有垃圾桶", + "unified_archive": "所有封存郵件", + "unified_junk": "所有垃圾郵件", + "all_accounts": "所有帳號", + "unified_mailbox": "整合信箱", + "expand": "展開", + "collapse": "收合", + "expand_tooltip": "展開", + "collapse_tooltip": "收合", + "mobile": { + "search": "搜尋", + "compose": "撰寫郵件", + "go_back": "返回", + "toggle_menu": "切換選單" + }, + "clear_search": "清除搜尋", + "vacation_active": "休假自動回覆已開啟", + "demo_banner": "示範模式", + "demo_reset": "重設", + "demo_tour": "功能導覽", + "tags": "標籤", + "show_all_tags": "顯示全部({count})", + "show_fewer_tags": "顯示較少", + "folders": "信件匣", + "shared": "共用", + "mail": "郵件", + "nav_label": "導覽", + "add_app": "應用程式", + "scheduled": "排程寄送", + "unified_all_unread": "全部未讀", + "unified_all_starred": "全部已加星號", + "unified_all_mail": "全部郵件", + "remove_account": "移除帳號", + "remove_account_confirm": "要從這部裝置移除 {account} 嗎?您稍後仍可重新新增。" + }, + "protocol_handlers": { + "title": "預設應用程式", + "description": "選擇電子郵件與行事曆連結是否要在 Bulwark 開啟。Bulwark 會註冊為 mailto: 與 webcal: 連結的通訊協定處理常式。", + "unsupported": "此瀏覽器或連線不支援手動註冊通訊協定處理常式。您仍可嘗試透過瀏覽器或作業系統設定,使用已安裝的 PWA。", + "mailto_label": "電子郵件連結", + "mailto_description": "使用預先填入的撰寫視窗,在 Bulwark 開啟 mailto: 連結。", + "protocol_open_mode_label": "開啟通訊協定連結時", + "protocol_open_mode_description": "選擇 Bulwark 要在新分頁開啟 mailto: 與 webcal: 連結,或使用現有的工作階段。現有工作階段選項需要通知權限;若瀏覽器阻止視窗取得焦點,您可以點擊備用通知,將 Bulwark 移到最上層。", + "protocol_open_mode_active_session": "盡可能在現有工作階段開啟", + "protocol_open_mode_new_tab": "一律開啟新分頁", + "focus_notification_title": "開啟 Bulwark", + "focus_notification_body": "連結已在 Bulwark 開啟。點擊即可將視窗移到最上層。", + "webcal_label": "行事曆連結", + "webcal_description": "使用預先填入的行事曆訂閱對話方塊,在 Bulwark 開啟 webcal: 連結。", + "register_mailto": "註冊電子郵件應用程式", + "register_webcal": "註冊行事曆應用程式", + "mailto_registered": "已要求註冊電子郵件處理常式", + "webcal_registered": "已要求註冊行事曆處理常式", + "registration_failed": "通訊協定處理常式註冊失敗", + "opening_mailto": "正在開啟撰寫視窗…", + "opening_webcal": "正在開啟行事曆…", + "browser_note": "您的瀏覽器或作業系統可能會要求您確認,而且可能必須先安裝 Bulwark,才能選為預設應用程式。", + "select_account_title": "選擇帳號", + "select_mailto_account": "選擇用於開啟此電子郵件連結的帳號。", + "select_webcal_account": "選擇用於開啟此行事曆連結的帳號。", + "select_account_note": "此選擇僅適用於此協議連結。", + "detail_to": "收件者", + "detail_subject": "主題", + "detail_no_subject": "無主題", + "detail_calendar": "行事曆", + "detail_source": "來源", + "active_account": "使用中", + "switching_account": "正在切換帳號…" + }, + "sidebar_apps": { + "modal_title": "側邊欄應用程式", + "add_new": "新增應用程式", + "edit_app": "編輯應用程式", + "name_label": "名稱", + "name_placeholder": "我的應用程式", + "name_required": "名稱為必填欄位", + "url_label": "URL", + "url_required": "URL 為必填欄位", + "url_invalid": "請輸入有效的 http 或 https URL", + "icon_label": "圖示", + "icon_required": "圖示為必填欄位", + "open_mode_label": "開啟方式", + "open_new_tab": "新分頁", + "open_inline": "內嵌", + "cancel": "取消", + "add": "新增", + "update": "更新", + "delete": "刪除", + "delete_confirm_title": "刪除應用程式", + "delete_confirm": "您確定要刪除「{name}」嗎?", + "no_apps": "尚未新增任何應用程式", + "no_apps_hint": "在側邊欄新增自訂應用程式與連結", + "search_icons": "搜尋圖示…", + "show_popular": "熱門", + "show_all": "全部", + "no_icons_found": "找不到圖示", + "inline_badge": "內嵌", + "tab_badge": "新標籤頁", + "show_on_mobile": "在行動裝置上顯示" + }, + "email_list": { + "no_emails": "找不到郵件", + "no_emails_description": "此信件匣中沒有郵件", + "no_search_results": "找不到結果", + "no_search_results_description": "請調整搜尋條件或篩選器", + "loading": "正在載入郵件…", + "unread": "未讀", + "to_me": "寄給我", + "to_recipients": "致 {count} 收件者", + "and_others": "另有 {count} 人", + "draft": "草稿", + "starred": "已加星號", + "conversations_count": "顯示 {count} 個對話串,共 {total} 個", + "conversations_count_plus": "{count}+ 個對話串", + "conversations_count_simple": "{count} 個對話串", + "no_conversations": "目前沒有對話串", + "loading_more": "正在載入更多郵件…", + "no_more_emails": "沒有更多郵件可載入", + "batch_actions": { + "select": "選取郵件", + "select_all": "全部選取", + "selected_messages": "已選取 {count, plural, one {1} other {#}} 封郵件", + "mark_read": "標示為已讀", + "mark_unread": "標示為未讀", + "delete": "刪除", + "delete_confirm_title": "刪除郵件", + "delete_confirm_message": "您確定要刪除{count, plural, one {1 封郵件} other {# 封郵件}}嗎?", + "clear_selection": "清除選取" + }, + "permanent_delete": "永久刪除", + "permanent_delete_confirm_title": "永久刪除", + "permanent_delete_confirm_message": "這封郵件將永久刪除。此動作無法復原。", + "permanent_delete_confirm_batch_message": "將永久刪除{count, plural, one {1 封郵件} other {# 封郵件}}。此動作無法復原。", + "empty_folder": { + "button": "清空信件匣", + "confirm_title": "清空信件匣", + "confirm_message": "此信件匣中的所有郵件都將永久刪除。此動作無法復原。", + "confirm_button": "清空信件匣", + "junk_hint": "您可以清空垃圾郵件信件匣,永久刪除其中的所有郵件。", + "trash_hint": "您可以清空垃圾桶,永久刪除其中的所有郵件。" + }, + "no_scheduled_emails": "沒有排程寄送的郵件", + "no_scheduled_emails_description": "排定稍後寄送的郵件會顯示在這裡。", + "scheduled_count": "{count, plural, one {1 封排程寄送郵件} other {# 封排程寄送郵件}}", + "scheduled_actions_hint": "排程郵件可從排程動作中取消、重新排程或編輯。", + "cancel_scheduled_send": "取消傳送", + "reschedule_send": "重新排程", + "cancel_and_edit": "取消並編輯", + "cancel_and_compose_again": "取消並重新撰寫", + "reschedule_prompt": "輸入新的日期與時間,例如 2026-05-04T15:30" + }, + "email_viewer": { + "read_receipt": { + "prompt": "寄件者要求在您開啟這封郵件時收到通知。", + "send": "傳送回執", + "ignore": "忽略", + "sent": "已讀回執已傳送。", + "send_failed": "無法傳送已讀回執", + "mdn_subject": "已讀:{subject}", + "mdn_body": "這是您傳送給 {recipient} 的郵件已讀回執。\n\n注意:此回執僅表示郵件已顯示在收件者的電腦上,並不保證收件者已閱讀或理解郵件內容。" + }, + "no_email_selected": "未選取郵件", + "no_email_description": "請從清單選取一封郵件,即可在這裡檢視", + "no_conversation_selected": "未選取對話串", + "no_conversation_description": "請從清單選取一個對話串,即可在這裡閱讀", + "compose": "撰寫郵件", + "compose_hint": "撰寫新郵件", + "no_subject": "(無主題)", + "no_body_content": "(無內文內容)", + "no_preview_available": "無可用預覽", + "show_quoted_text": "顯示引用文字", + "hide_quoted_text": "隱藏引用文字", + "loading_email": "正在載入郵件…", + "loading": "正在載入…", + "reply": "回覆", + "reply_all": "全部回覆", + "forward": "轉寄", + "delete": "刪除", + "archive": "封存", + "star": "加上星號", + "unstar": "移除星號", + "mark_unread": "標示為未讀", + "mark_read": "標示為已讀", + "unread": "未讀", + "read": "已讀", + "spam_short": "垃圾郵件", + "not_spam_short": "非垃圾郵件", + "move": "移動", + "print": "列印", + "view_source": "檢視原始碼", + "fullscreen": "全螢幕", + "exit_fullscreen": "離開全螢幕", + "export_email": "匯出為 .eml", + "forward_as_attachment": "以附件轉寄", + "import_email": "匯入 .eml 或 .zip", + "keyboard_shortcuts": "鍵盤快速鍵 (?)", + "email_source": "郵件原始碼", + "draft_banner": "這是一封草稿郵件", + "edit_draft": "編輯", + "copy_source": "複製到剪貼簿", + "source_copied": "原始碼已複製到剪貼簿", + "attachments": "附件", + "important": "重要", + "download": "下載", + "download_all": "全部下載", + "from": "寄件者", + "to": "收件者", + "cc": "副本", + "bcc": "密件副本", + "date": "日期", + "subject": "主題", + "show_details": "顯示詳細資料", + "hide_details": "隱藏詳細資料", + "external_content_warning": "圖片與外部內容已遭封鎖", + "load_external_content": "載入圖片", + "trust_sender": "一律信任此寄件者", + "back_to_list": "回到清單", + "view_contact": "檢視聯絡人", + "message_details": "郵件詳細資料", + "more_reply_options": "更多回覆選項", + "set_tag": "設定標籤", + "tag": "標籤", + "more_actions": "更多動作", + "previous": "上一封", + "next": "下一封", + "move_to": "移至…", + "remove_tag": "移除標籤", + "tag_filter_placeholder": "篩選標籤", + "tag_no_matches": "沒有相符的標籤", + "more_count": "另有 {count} 個", + "characters_count": "{count} 個字元", + "quick_reply_placeholder": "撰寫快速回覆…", + "more_options": "更多選項", + "sending": "傳送中…", + "security_authentication": "安全性與驗證", + "technical_details": "技術詳細資料", + "message_id_label": "郵件 ID:", + "reply_to_label": "回覆至:", + "delivery_time_label": "送達時間:", + "conversation_part_label": "對話串中的部分:", + "previous_messages": "先前的 {count} 封郵件", + "previous_messages_plural": "先前的 {count} 封郵件", + "time": { + "day": "天", + "days": "天", + "hour": "小時", + "hours": "小時", + "minute": "分鐘", + "minutes": "分鐘" + }, + "unknown_sender": "未知", + "recipient_me": "我", + "recipient_and_others": "{name} 及其他 {count} 人", + "recipient_to_prefix": "收件者:", + "authentication": { + "title": "郵件身分驗證", + "status": { + "verified": "已驗證", + "warning": "警告", + "none": "未驗證" + }, + "spf": { + "pass": "SPF 通過", + "fail": "SPF 失敗", + "none": "無 SPF" + }, + "dkim": { + "pass": "DKIM 有效", + "fail": "DKIM 無效", + "none": "無 DKIM" + }, + "dmarc": { + "pass": "DMARC 通過", + "fail": "DMARC 失敗", + "none": "無 DMARC" + }, + "spam_score": "垃圾郵件評分", + "tooltip_spf": "Sender Policy Framework:驗證傳送伺服器是否有權代表該網域傳送郵件", + "tooltip_dkim": "DomainKeys Identified Mail:使用密碼編譯簽章,確認郵件在傳送過程中未遭竄改", + "tooltip_dmarc": "Domain-based Message Authentication, Reporting & Conformance:確保 SPF 與 DKIM 和寄件者網域一致,並設定驗證失敗時的處理原則", + "policy": "策略", + "result": { + "pass": "通過", + "fail": "失敗", + "softfail": "軟失敗", + "neutral": "中立", + "permerror": "永久錯誤", + "temperror": "暫時性錯誤", + "none": "無" + } + }, + "details": { + "recipients_routing": "收件者與路由", + "authentication_security": "身分驗證與安全", + "identifiers_threading": "識別碼與對話串", + "mailing_list": "郵件清單", + "message_properties": "郵件屬性", + "sent": "傳送時間", + "received": "接收時間", + "delivery_time": "送達時間", + "in_reply_to": "回覆來源", + "references": "引用", + "thread_id": "對話串 ID", + "size": "大小", + "mime_type": "MIME 型別", + "attachments_summary": "{count} 個檔案 · {size}", + "list_id": "清單 ID", + "list_help": "郵件清單說明", + "list_post": "傳送至清單", + "list_unsubscribe": "取消訂閱", + "iprev": "反向 DNS", + "spam_status": "垃圾郵件狀態", + "ai_verdict": "AI 判斷", + "account": "帳號", + "no_subject": "(無主題)" + }, + "headers": { + "routing": "路由", + "received": "接收時間", + "message_id": "訊息 ID", + "list_info": "郵件清單資訊" + }, + "tooltips": { + "reply": "回覆 (r)", + "reply_all": "全部回覆 (a)", + "forward": "轉寄 (f)", + "archive": "封存 (e)", + "delete": "刪除 (# 或 Del)", + "star": "加上星號 (s)", + "unstar": "移除星號 (s)", + "compose": "撰寫郵件 (c)", + "previous": "上一封郵件", + "next": "下一封郵件", + "edit_draft": "編輯草稿" + }, + "spam": { + "button_title": "回報垃圾郵件", + "not_spam_title": "標示為非垃圾郵件", + "toast_success": "已移至垃圾郵件", + "toast_batch": "{count} 封郵件已移至垃圾郵件", + "toast_undo": "撤銷", + "toast_not_spam_success": "已移至收件匣", + "toast_not_spam_batch": "{count} 封郵件已移至收件匣", + "error": "無法回報垃圾郵件", + "error_not_spam": "無法還原郵件" + }, + "unsubscribe_banner": { + "label": "訂閱郵件", + "button": "取消訂閱", + "confirm_title": "要取消訂閱此寄件者嗎?", + "confirm_button": "確認", + "cancel": "取消", + "success_http": "取消訂閱頁面已在新分頁開啟", + "success_mailto": "取消訂閱郵件已傳送", + "confirm_message_http": "取消訂閱頁面將在新分頁開啟。", + "confirm_message_mailto": "將傳送取消訂閱郵件給寄件者。", + "error": "無法取消訂閱", + "dismiss": "關閉" + }, + "calendar_invitation": { + "loading": "正在載入活動詳細資料…", + "title": "行事曆邀請", + "published_title": "已發布的活動", + "response_title": "活動回覆", + "update_title": "活動更新", + "counter_title": "改期建議", + "refresh_title": "重新整理請求", + "declined_counter_title": "改期建議已被拒絕", + "cancelled_title": "活動已取消", + "organizer": "主辦人:{name}", + "organizer_label": "主辦人:", + "attendees": "{count, plural, one {# 位參與者} other {# 位參與者}}", + "accept": "接受", + "maybe": "暫定", + "decline": "拒絕", + "add_to_calendar": "新增到行事曆", + "added": "已新增到行事曆", + "rsvp_sent": "回覆已傳送", + "parse_error": "無法讀取邀請", + "action_failed": "無法完成此行事曆動作。", + "no_calendar": "行事曆無法使用", + "published_info": "此活動已分享,僅供參考。", + "response_info": "這封郵件包含參與者的回覆。", + "response_info_organizer": "此參與者的回覆會更新您的活動。", + "update_info": "這封郵件會更新現有活動。", + "counter_info": "這封郵件建議變更活動。", + "counter_info_organizer": "此參與者建議變更您的活動。", + "refresh_info": "這封郵件要求提供最新的活動詳細資料。", + "refresh_info_organizer": "參與者要求提供最新的活動詳細資料。", + "declined_counter_info": "主辦人拒絕了改期建議。", + "authentication_failed_info": "這封邀請的郵件驗證檢查失敗。請謹慎執行行事曆動作。", + "authentication_missing_info": "這封邀請未包含已驗證的郵件身分驗證資訊。若有任何可疑之處,請向主辦人確認詳細資料。", + "sender_mismatch_info": "這封邀請是由 {sender} 傳送,但行事曆資料中列出的主辦人是 {organizer}。", + "sender_mismatch_unverified_info": "這封邀請是由 {sender} 傳送,但行事曆資料中列出的主辦人是 {organizer},而且無法驗證這封郵件。", + "organizer_role": "您是此活動的主辦人", + "your_response": "您的回覆:{status}", + "response_needed": "待回覆", + "response_accepted": "已接受", + "response_tentative": "暫定", + "response_declined": "已拒絕", + "response_delegated": "已委派", + "actor_sent_info": "由 {name} 傳送。", + "actor_response_info": "{name} 的回覆為{status}。", + "actor_counter_info": "{name} 建議變更此活動。", + "actor_refresh_info": "{name} 要求提供最新的活動詳細資料。", + "actor_declined_counter_info": "{name} 拒絕了改期建議。", + "actor_note": "備註:{comment}", + "actor_unknown": "有人", + "proposed_changes": "建議的更改", + "change_title": "標題", + "change_time": "時間", + "change_location": "地點", + "change_description": "描述", + "change_empty": "無", + "change_from_to": "{before} → {after}", + "apply_proposal": "套用建議的變更", + "proposal_applied": "已套用建議的變更。", + "review_proposal": "檢視建議", + "review_request": "檢視要求", + "view_in_calendar": "在行事曆中檢視", + "select_calendar": "選取行事曆", + "already_in_calendar": "已在您的行事曆中", + "request_info": "您已受邀參加此活動。請回覆,讓主辦人知道您是否能參加。", + "cancel_info": "主辦人已取消此活動。", + "event_updated": "更新 #{sequence}", + "event_status_tentative": "暫定", + "event_status_cancelled": "已取消", + "expand": "顯示詳細資料", + "collapse": "隱藏詳細資料" + }, + "send": "傳送", + "more": "更多", + "scheduled_banner": "排定於 {date} 傳送", + "scheduled_send_created": "郵件已排程寄送", + "cancel_scheduled_send": "取消傳送", + "reschedule_send": "重新排程", + "cancel_and_edit": "取消並編輯", + "cancel_and_compose_again": "取消並重新撰寫", + "reschedule_prompt": "輸入新的日期與時間,例如 2026-05-04T15:30", + "scheduled_actions_only": "此檢視僅支援排程寄送動作", + "undo_send_scheduled": "郵件已排程寄送", + "undo_send": "取消傳送", + "contact_sidebar": { + "title": "聯絡人", + "close": "關閉側邊欄", + "action_email": "郵件", + "action_email_title": "傳送郵件", + "action_copy": "複製", + "action_copy_title": "複製電子郵件地址", + "action_edit_title": "編輯聯絡人", + "section_emails": "電子郵件地址", + "section_phones": "電話", + "section_organizations": "組織", + "section_addresses": "地址", + "section_notes": "備註", + "not_in_contacts": "不在您的聯絡人清單中", + "add_to_contacts": "新增至聯絡人", + "copied": "已複製!", + "copy_failed": "複製失敗" + }, + "send_now": "立即傳送" + }, + "email_composer": { + "read_receipt_on": "已要求傳送已讀回執(點擊以停用)", + "read_receipt_off": "請求已讀回執", + "new_message": "新郵件", + "signature_edit_hint": "點兩下即可編輯簽名檔", + "reply": "回覆", + "reply_all": "全部回覆", + "forward": "轉寄", + "reply_to": "回覆", + "reply_all_to": "全部回覆", + "forward_message": "轉寄", + "from": "寄件者", + "to": "收件者", + "cc": "副本", + "bcc": "密件副本", + "subject": "主題", + "body_placeholder": "撰寫郵件內容…", + "send": "傳送", + "cancel": "取消", + "attach": "附加", + "attach_photos": "照片與影片", + "attach_files": "檔案", + "discard": "捨棄", + "discard_draft_title": "要捨棄草稿嗎?", + "discard_draft_confirm": "您有尚未儲存的變更。要捨棄這封草稿嗎?", + "saving": "正在儲存…", + "sending": "正在傳送…", + "add_link": "新增連結", + "link_url_prompt": "輸入 URL", + "draft_saved": "草稿已儲存", + "save_failed": "儲存失敗", + "to_placeholder": "收件者電子郵件地址", + "cc_placeholder": "副本收件者", + "bcc_placeholder": "密件副本收件者", + "subject_placeholder": "主題", + "cc_label": "副本:", + "bcc_label": "密件副本:", + "subject_label": "主題:", + "file_size_kb": "KB", + "prefix": { + "forward": "Fwd:", + "reply": "Re:" + }, + "no_subject": "(無主題)", + "unknown_sender": "未知", + "quote": { + "reply_header": "在 {date},{sender} 寫道:", + "forward_header": "---------- 轉寄的郵件 ----------", + "from": "寄件者:{sender}", + "date": "日期:{date}", + "subject": "主題:{subject}", + "to": "收件者:{recipients}" + }, + "remove_sub_address": "刪除子地址", + "from_override": { + "toggle_off": "覆寫", + "toggle_on": "取消覆寫", + "toggle_tooltip": "自由編輯寄件者名稱與電子郵件地址。郵件仍會透過您的寄件身分傳送,只有顯示的 From 標頭會變更。", + "name_label": "寄件者姓名", + "name_placeholder": "姓名", + "email_label": "寄件者電子郵件地址", + "email_placeholder": "alias@example.com" + }, + "use_template": "範本", + "save_as_template": "儲存為範本", + "validation": { + "recipient_required": "請新增收件者", + "body_required": "請輸入郵件內容或新增附件", + "attachments_uploading": "附件仍在上傳中,上傳完成後將自動傳送", + "attachment_upload_failed": "未傳送 — 附件上傳失敗。請移除該附件後再試一次。" + }, + "upload_progress": "正在上傳 {uploaded} / {total}", + "upload_cancel": "取消上傳", + "upload_failed": "無法上傳 {filename}", + "drop_files": "拖放要附加的檔案", + "show_less": "顯示較少", + "send_failed": "傳送郵件失敗", + "send_timeout": "伺服器停止回應。再次傳送前,請先檢查「寄件備份」信件匣,因為郵件可能已經寄出。", + "continue_draft": "繼續編輯草稿", + "close_draft_title": "要儲存還是捨棄草稿?", + "close_draft_message": "您有尚未儲存的變更。要將這封郵件儲存為草稿,還是捨棄?", + "smime_sign_on": "S/MIME 簽名已啟用", + "smime_sign_off": "啟用 S/MIME 簽名", + "smime_encrypt_on": "S/MIME 加密已啟用", + "smime_encrypt_off": "啟用 S/MIME 加密", + "smime_encrypt_unavailable": "S/MIME 加密無法使用 — 缺少收件者憑證", + "smime_unlock_title": "解鎖 S/MIME 金鑰", + "smime_unlock_message": "請輸入密碼片語,以解鎖您的 S/MIME 簽章金鑰。", + "smime_unlock_button": "解鎖", + "smime_passphrase_placeholder": "密碼片語", + "forgot_attachment": { + "title": "忘記新增附件了嗎?", + "message": "您的郵件提到「{keyword}」,但沒有附加檔案。仍要傳送嗎?", + "send_anyway": "仍然傳送", + "back": "繼續編輯" + }, + "empty_subject": { + "title": "沒有主題就傳送嗎?", + "message": "此郵件沒有主題。仍要傳送嗎?", + "dont_ask_again": "不再提示", + "send_anyway": "仍然傳送", + "back": "繼續編輯" + }, + "schedule_send": "排程寄送", + "schedule_send_description": "選擇伺服器要在何時送出這封郵件。", + "schedule_send_required": "請選擇日期與時間。", + "schedule_send_invalid": "請輸入有效的日期與時間。", + "schedule_send_future": "請選擇未來的日期與時間。", + "schedule_send_too_late": "此時間超出伺服器允許的範圍。", + "schedule_send_unsupported": "此帳號不支援排程寄送。", + "schedule_send_cleanup_warning": "已建立排程寄送,但清理草稿失敗。", + "send_delay_unsupported": "此帳號不支援傳送延遲。", + "send_delay_unsupported_confirm": "此帳號不支援傳送延遲。是否立即傳送?", + "recipient_edit_email": "編輯電子郵件地址", + "recipient_edit_name": "編輯顯示名稱", + "recipient_email_placeholder": "電子郵件地址", + "recipient_name_placeholder": "顯示名稱", + "autocomplete_search_server": "在伺服器上搜尋", + "autocomplete_searching": "正在搜尋…", + "toolbar": { + "bold": "粗體", + "italic": "斜體", + "underline": "底線", + "strikethrough": "刪除線", + "text_color": "文字顏色", + "remove_color": "移除顏色", + "heading_1": "標題 1", + "heading_2": "標題 2", + "bullet_list": "項目符號清單", + "ordered_list": "編號清單", + "quote": "引用", + "code_block": "程式碼區塊", + "align_left": "左對齊", + "align_center": "置中對齊", + "align_right": "右對齊", + "text_direction": "文字方向 (RTL/LTR)", + "link": "連結", + "table": "表格", + "clear_formatting": "清除格式", + "undo": "撤銷", + "redo": "重做", + "add_row_above": "在上方新增一列", + "add_row_below": "在下方新增一列", + "add_column_before": "在前方新增一欄", + "add_column_after": "在後方新增一欄", + "delete_row": "刪除列", + "delete_column": "刪除欄", + "toggle_header_row": "切換標題列", + "delete_table": "刪除表格", + "pick_size": "選取大小" + }, + "send_filing_warning": "郵件已傳送,但寄送後清理失敗,可能仍保留舊草稿。" + }, + "confirm_dialog": { + "confirm": "確認", + "cancel": "取消" + }, + "common": { + "loading": "正在載入…", + "error": "錯誤", + "success": "成功", + "cancel": "取消", + "save": "儲存", + "delete": "刪除", + "edit": "編輯", + "close": "關閉", + "search": "搜尋", + "refresh": "重新整理", + "settings": "設定", + "help": "說明", + "logout": "登出", + "yes": "是", + "no": "否", + "unknown": "未知", + "app_title": "網頁郵件", + "reconnecting": "連線中斷,正在嘗試重新連線…", + "rate_limited_title": "伺服器驗證目前受到速率限制。", + "rate_limited_detail": "Bulwark 已暫停背景請求,以免帳號遭鎖定。將在 {seconds} 秒後重試。", + "rate_limited_action_title": "已暫停請求,以免帳號遭鎖定。", + "rate_limited_action_detail": "Bulwark 正在等待伺服器的冷卻時間結束,再傳送更多需要驗證的請求。請在 {seconds} 秒後重試。", + "pull_to_refresh": "下拉重新整理", + "release_to_refresh": "鬆開重新整理", + "refreshing": "正在重新整理…" + }, + "notifications": { + "email_sent": "郵件傳送成功", + "email_deleted": "郵件已刪除", + "email_archived": "郵件已封存", + "email_starred": "郵件已加上星號", + "email_unstarred": "郵件已移除星號", + "email_marked_read": "郵件已標示為已讀", + "email_marked_unread": "郵件已標示為未讀", + "copied_to_clipboard": "已複製到剪貼簿", + "source_copied": "原始碼已複製到剪貼簿", + "error_sending": "傳送郵件失敗", + "error_deleting": "刪除郵件失敗", + "error_loading": "無法載入郵件", + "new_email": "新郵件", + "new_email_from": "來自 {sender}", + "click_to_view": "點選檢視", + "email_moved": "郵件已移動", + "emails_moved": "{count} 封郵件已移動", + "moved_to_mailbox": "已移至 {mailbox}", + "move_failed": "移動郵件失敗", + "move_error": "無法將郵件移至選取的信件匣", + "email_tagged": "郵件已加標籤", + "emails_tagged": "{count} 封郵件已加標籤", + "tag_failed": "加上標籤失敗", + "identity_created": "已成功建立寄件身分", + "identity_updated": "已成功更新寄件身分", + "identity_deleted": "已刪除寄件身分", + "identity_set_primary": "已更新主要寄件身分", + "identity_create_failed": "無法建立寄件身分:{error}", + "identity_update_failed": "無法更新寄件身分:{error}", + "identity_delete_failed": "無法刪除寄件身分:{error}", + "identity_unauthorized": "您沒有使用此電子郵件地址寄信的權限", + "identity_not_found": "找不到寄件身分", + "vacation_saved": "休假自動回覆設定已儲存", + "vacation_save_failed": "無法儲存休假自動回覆設定", + "filters_saved": "篩選規則已成功儲存", + "filters_save_failed": "無法儲存篩選規則", + "filters_deleted": "篩選規則已刪除", + "templates_exported": "範本匯出成功", + "templates_imported": "已匯入{count, plural, one {# 個範本} other {# 個範本}}", + "templates_import_errors": "部分範本無法匯入", + "templates_import_empty": "檔案中找不到範本", + "export_email_error": "無法匯出郵件", + "import_email_success": "郵件已成功匯入", + "import_email_error": "無法匯入郵件" + }, + "date": { + "today": "今天", + "yesterday": "昨天", + "this_week": "本週", + "last_week": "上週", + "this_month": "本月", + "older": "更早", + "just_now": "剛剛", + "minutes_ago": "{count} 分鐘前", + "minutes_ago_plural": "{count} 分鐘前", + "hours_ago": "{count} 小時前", + "hours_ago_plural": "{count} 小時前", + "days_ago": "{count} 天前", + "days_ago_plural": "{count} 天前" + }, + "language": { + "title": "語言", + "english": "英文", + "french": "法文", + "japanese": "日文", + "spanish": "西班牙文", + "italian": "義大利文", + "german": "德文", + "dutch": "荷蘭文", + "portuguese": "葡萄牙文", + "russian": "俄文", + "select_language": "選擇語言", + "switch_to_english": "切換成英文", + "switch_to_french": "切換成法文", + "switch_to_japanese": "切換成日文", + "switch_to_spanish": "切換成西班牙文", + "switch_to_italian": "切換成義大利文", + "switch_to_german": "切換成德文", + "switch_to_dutch": "切換成荷蘭文", + "switch_to_portuguese": "切換成葡萄牙文", + "switch_to_russian": "切換成俄文", + "switching": "正在切換語言…", + "switch": "切換語言", + "current": "目前語言", + "polish": "波蘭文", + "switch_to_polish": "切換成波蘭文", + "en": "English", + "fr": "Français", + "de": "Deutsch", + "es": "Español", + "it": "Italiano", + "ja": "日本語", + "ko": "한국어", + "lv": "Latviešu", + "nl": "Nederlands", + "pl": "Polski", + "pt": "Português", + "he": "עברית", + "ru": "Русский", + "sk": "Slovenčina", + "uk": "Українська", + "zh": "簡體中文", + "fa": "فارسی", + "farsi": "فارسی", + "switch_to_farsi": "切換成波斯文", + "mn": "Монгол", + "mongolian": "Монгол", + "switch_to_mongolian": "切換成蒙古文" + }, + "settings": { + "title": "設定", + "back_to_mail": "回到郵件", + "save_success": "設定已成功儲存", + "import_success": "已成功匯入設定", + "import_error": "無法匯入設定", + "reset_confirm": "您確定要將所有設定重設為預設值嗎?", + "unsaved_changes": "您有尚未儲存的變更", + "discard_changes": "要捨棄尚未儲存的變更嗎?", + "discard": "捨棄", + "keep_editing": "繼續編輯", + "search_placeholder": "搜尋設定", + "search_clear": "清除搜尋", + "search_no_results": "找不到相符的設定", + "tabs": { + "appearance": "外觀", + "language": "語言、地區與時間", + "email": "郵件行為", + "composer": "郵件撰寫", + "privacy": "隱私權與安全", + "account": "帳號", + "identities": "寄件身分", + "vacation": "休假自動回覆", + "advanced": "進階", + "calendar": "行事曆", + "filters": "篩選規則", + "templates": "範本", + "folders": "信件匣", + "keywords": "標籤", + "security": "安全", + "files": "檔案", + "contacts": "聯絡人", + "encryption": "加密", + "protocol_handlers": "預設應用程式", + "sidebar_apps": "側邊欄應用程式", + "notifications": "通知", + "layout": "版面配置", + "reading": "閱讀", + "composing": "撰寫", + "downloads": "下載", + "content_senders": "內容與寄件者", + "about_data": "關於與資料", + "debug": "除錯" + }, + "tab_groups": { + "general": "一般", + "account": "帳號與寄件身分", + "organization": "郵件整理", + "apps": "應用程式", + "system": "系統", + "appearance": "外觀", + "mail": "郵件", + "privacy": "隱私權與安全", + "advanced": "進階" + }, + "appearance": { + "message_list_order": { + "label": "郵件清單排序", + "description": "清單中的郵件排序方式。排序由伺服器執行,因此會套用至整個信件匣,而不只是已載入的郵件。", + "preset": { + "chronological": "依時間順序(最新優先)", + "unread_first": "未讀優先", + "starred_first": "已加星號優先", + "tagged_first": "有標籤優先", + "custom": "自訂" + }, + "tag_label": "標籤", + "advanced_show": "進階:編輯排序層級", + "advanced_hide": "隱藏進階設定", + "criterion_label": "第 {n} 級條件", + "direction_label": "第 {n} 級方向", + "criteria": { + "unread": "未讀", + "starred": "已加星號", + "tag": "標籤", + "receivedAt": "接收日期", + "sentAt": "傳送日期", + "from": "寄件者", + "subject": "主題", + "size": "大小" + }, + "direction": { + "unread_first": "未讀在前", + "read_first": "已讀在前", + "starred_first": "已加星號優先", + "unstarred_first": "未加星號優先", + "tagged_first": "有標籤在前", + "untagged_first": "無標籤在前", + "newest_first": "最新在前", + "oldest_first": "最早在前", + "a_to_z": "A → Z", + "z_to_a": "Z → A", + "largest_first": "最大在前", + "smallest_first": "最小在前" + }, + "add_level": "新增層級", + "remove_level": "移除層級", + "move_up": "上移", + "move_down": "下移", + "tiebreak_note": "最多可設定三個層級;後面的層級用來判定同順位的項目。「最新優先」一律最後套用。", + "scope": { + "label": "套用至所有信件匣", + "description": "關閉時,排序只套用至收件匣;其他信件匣仍依時間順序排列。" + }, + "unsupported_note": "您的郵件伺服器不支援依已讀狀態、星號或標籤排序。系統會忽略這些層級,清單仍依時間順序排列。" + }, + "title": "外觀", + "description": "自訂網頁郵件的外觀與使用感受", + "theme": { + "label": "主題", + "description": "選擇您喜歡的配色方案", + "light": "淺色", + "dark": "深色", + "system": "系統" + }, + "language": { + "label": "語言", + "description": "選擇您偏好的語言" + }, + "font_size": { + "label": "字型大小", + "description": "調整文字大小,提升易讀性", + "small": "小", + "medium": "中", + "large": "大" + }, + "list_density": { + "label": "介面密度", + "description": "調整介面元素之間的間距", + "extra_compact": "超緊湊", + "compact": "緊湊", + "regular": "預設", + "comfortable": "寬鬆" + }, + "animations": { + "label": "啟用動畫", + "description": "顯示平順的轉場與效果" + }, + "toolbar_position": { + "label": "工具列位置", + "description": "選擇顯示郵件動作按鈕的位置(回覆、封存、刪除等)", + "top": "頂端", + "below_subject": "主題下方" + }, + "toolbar_labels": { + "label": "顯示工具列標籤", + "description": "在工具列圖示旁顯示文字標籤。熟悉圖示後可停用,以節省空間。" + }, + "hide_account_switcher": { + "label": "隱藏側邊欄帳號切換器", + "description": "隱藏信件匣側邊欄頂端的帳號選取器。您仍可從底部導覽列切換帳號。" + }, + "show_rail_account_list": { + "label": "在導覽列顯示帳號頭像", + "description": "在導覽列底部顯示各帳號的圓形頭像,方便快速切換,並在下方顯示登出按鈕。" + }, + "unified_mailbox": { + "label": "整合信箱", + "description": "顯示使用中帳號及其共用信件匣的整合信件匣(收件匣、寄件備份等)。", + "cross_account": { + "label": "跨所有帳號", + "description": "將整合信箱合併到所有已連線的帳號,而不只限於使用中的帳號。" + }, + "include_group": { + "label": "包含群組收件匣", + "description": "也將共用/群組收件匣合併到整合檢視中。" + } + }, + "all_mail": { + "folders_label": "整合清單中的信件匣", + "folders_description": "選擇要將此帳號的哪些信件匣合併到「所有郵件/未讀/已加星號」清單。", + "account_hint": "套用至 {account}。", + "no_folders": "沒有可用的信件匣。" + }, + "colorful_sidebar_icons": { + "label": "彩色側邊欄圖示", + "description": "依類型為信件匣與標籤圖示上色(藍色收件匣、紅色垃圾郵件、綠色寄件備份等)。停用後側邊欄會以單色顯示。" + }, + "tint_list_rows": { + "label": "依標籤顏色為清單列上色", + "description": "以第一個標籤的顏色為每封郵件列加上底色。停用後郵件列保持無底色,但標籤圓點與標籤仍會顯示該顏色。" + }, + "show_folder_total_count": { + "label": "顯示郵件總數", + "description": "在信件匣與標籤旁顯示郵件總數及未讀數量。停用後只顯示未讀數量。" + }, + "favicon_unread_badge": { + "label": "在分頁圖示顯示未讀數量", + "description": "在瀏覽器分頁圖示顯示收件匣未讀數量徽章,即使分頁不在前景也能看到新郵件。停用後不顯示徽章。" + }, + "pro_interface": { + "label": "Pro 介面(實驗性)", + "description": "適合進階使用者的桌面版配置,支援多分頁郵件瀏覽與跨帳號工作流程。標準介面不受影響,您可隨時切換回來。", + "open_label": "開啟 Pro 介面", + "back_to_standard": "返回標準介面" + }, + "cross_unread": { + "label": "未讀", + "description": "在整合信箱顯示「未讀」項目,列出所選信件匣中的未讀郵件。" + }, + "cross_starred": { + "label": "已加星號", + "description": "在整合信箱顯示「已加星號」項目,列出所選信件匣中已加星號的郵件。" + }, + "cross_all": { + "label": "所有郵件", + "description": "在整合信箱顯示「所有郵件」項目,列出所選信件匣中的所有郵件。" + } + }, + "keywords": { + "title": "電子郵件標籤", + "description": "定義用來整理郵件的標籤。這些標籤會以 JMAP 關鍵字儲存在伺服器上。", + "add_keyword": "新增標籤", + "label_field": "顯示名稱", + "label_placeholder": "例如工作、個人、緊急", + "id_field": "標籤 ID", + "id_placeholder": "例如工作、個人", + "color_field": "顏色", + "id_exists": "此標籤 ID 已存在", + "edit": "編輯標籤", + "delete": "刪除標籤", + "save": "儲存", + "add": "新增", + "cancel": "取消", + "migrating": "正在更新現有郵件的標籤…", + "migration_error": "更新現有郵件的標籤失敗", + "nesting": { + "label": "巢狀標籤", + "description": "將標籤巢狀放在其他標籤下,並在側邊欄以樹狀結構顯示。" + }, + "parent_field": "上層標籤", + "no_parent": "無上層標籤", + "too_long": "此標籤路徑過長(最多 {max} 個字元)", + "has_children_locked": "此標籤下有其他巢狀標籤,因此無法變更名稱與上層標籤。請先移動或移除這些子標籤。", + "has_children_delete": "請先移除此標籤下的巢狀標籤", + "visibility_field": "側邊欄顯示", + "visibility": { + "show": "顯示", + "unread": "有未讀時顯示", + "hide": "隱藏" + }, + "unrecognized": { + "title": "從伺服器復原標籤", + "description": "標籤名稱與顏色儲存在此瀏覽器中,標籤本身則以 JMAP 關鍵字附加在郵件上。掃描郵件以尋找這裡尚未定義的關鍵字,再將它們加回來。", + "scan": "掃描標籤", + "rescan": "重新掃描", + "scanning": "正在掃描… {total} 封郵件中的 {scanned} 封", + "none": "郵件上的所有標籤均已在此定義。", + "messages": "{count, plural, one {# 封郵件} other {# 封郵件}}", + "add_all": "全部新增({count})", + "partial": "僅掃描 {total} 封郵件中最新的 {scanned} 封。只出現在較舊郵件的標籤可能遺漏。", + "error": "無法掃描郵件中的標籤。" + } + }, + "notifications": { + "test_sound": "測試通知聲音", + "sounds": { + "default": "預設(蜂鳴聲)", + "cheerful": "快樂", + "involved": "沉浸", + "swift": "輕快手勢", + "relax": "放鬆" + }, + "push": { + "title": "背景通知", + "description": "網站關閉時仍可接收新郵件的系統通知。通知會透過 Bulwark 推送中繼傳送;中繼不會看到郵件內容。", + "relay_label": "推送中繼", + "relay_desc": "用來傳送通知的伺服器。請從管理員提供的中繼中選擇。", + "relay_locked": "由管理員設定", + "relay_locked_desc": "推送中繼已由管理員設定,無法變更。", + "status_active": "已在此裝置上啟用", + "status_inactive": "在此裝置上未啟用", + "status_unsupported": "此瀏覽器不支援 Web Push", + "status_busy": "工作中…", + "enable": "啟用", + "reenable": "重新註冊", + "disable": "停用", + "confirm_disable_title": "要停用背景通知嗎?", + "confirm_disable_message": "當網站關閉時,此裝置將停止接收提醒。", + "dismiss_aria": "關閉通知提示", + "ios_hint": "在 iOS 上,請先將網站安裝到主畫面;Safari 只會將 Web Push 傳送至已安裝的 PWA。", + "devices_title": "已註冊的裝置", + "devices_desc": "這裡列出為此帳號註冊背景通知的所有裝置。撤銷其中一部裝置的註冊後,該裝置會立即停止接收通知。", + "devices_loading": "正在載入已註冊的裝置…", + "devices_empty": "沒有裝置註冊接收背景通知。", + "devices_error": "無法載入已註冊的裝置。", + "devices_refresh": "重新整理", + "device_this": "此裝置", + "device_other": "其他裝置", + "device_status_active": "正在投遞通知", + "device_status_inactive": "從未投遞過通知", + "device_status_unknown": "此中繼沒有這部裝置的資訊", + "device_expires": "於 {date} 到期", + "revoke": "撤銷", + "confirm_revoke_title": "要撤銷此裝置的註冊嗎?", + "confirm_revoke_message": "此裝置會立即停止接收背景通知。若在該裝置上再次啟用推送,將重新註冊。", + "confirm_revoke_message_this": "此裝置會立即停止接收背景通知。" + }, + "sound_selection": { + "title": "通知聲音", + "description": "選擇通知時播放的聲音", + "choose": "聲音", + "choose_desc": "選擇通知音並點擊揚聲器圖示進行預覽" + }, + "email": { + "title": "郵件通知", + "description": "設定傳入郵件的通知", + "enabled": "郵件通知", + "enabled_desc": "新郵件到達時顯示通知", + "sound": "通知聲音", + "sound_desc": "新郵件到達時播放音訊提醒" + }, + "calendar": { + "title": "行事曆通知", + "description": "設定行事曆活動的通知", + "enabled": "活動通知", + "enabled_desc": "顯示即將開始的行事曆活動提醒", + "sound": "通知聲音", + "sound_desc": "播放行事曆提醒的音訊提醒", + "invitation_parsing": "解析郵件邀請", + "invitation_parsing_desc": "偵測郵件附件中的行事曆邀請,並顯示行事曆動作" + } + }, + "language_region": { + "title": "語言、地區與時間", + "description": "語言、日期格式、時間格式以及其他區域設定", + "language": { + "label": "語言", + "description": "選擇您偏好的語言", + "english": "英文", + "french": "法文" + }, + "date_format": { + "label": "日期格式", + "description": "電子郵件清單中日期的顯示方式", + "smart": "智慧(依地區設定)", + "relative": "相對時間(1 小時前、2 天前)", + "full": "一律顯示完整日期", + "preview_today": "今天:", + "preview_this_week": "本週:", + "preview_older": "更早:" + }, + "date_locale": { + "label": "日期格式地區", + "description": "數字日期的排列順序(日、月、年)", + "auto": "自動(與語言相符)", + "iso": "ISO 8601(YYYY-MM-DD)", + "dmy": "日/月/年", + "mdy": "月/日/年" + }, + "time_format": { + "label": "時間格式", + "description": "選擇 12 小時制或 24 小時制", + "12h": "12 小時制", + "24h": "24 小時制" + }, + "first_day": { + "label": "一週的第一天", + "description": "從週日或週一開始一週", + "sunday": "週日", + "monday": "週一" + }, + "time_zone": { + "label": "時區", + "description": "使用此時區顯示郵件與行事曆時間,而非瀏覽器回報的時區", + "auto": "自動({zone})", + "preview_now": "現在:" + } + }, + "email_behavior": { + "request_read_receipt": { + "label": "預設請求已讀回執", + "description": "撰寫新郵件時預先啟用已讀回執請求。" + }, + "read_receipt_response": { + "label": "回應已讀回執請求", + "description": "當收到的郵件請求已讀回執時的處理方式。", + "ask": "每次詢問", + "always": "一律傳送", + "never": "永不傳送" + }, + "title": "郵件行為", + "description": "設定郵件的處理方式", + "mark_read": { + "label": "標示為已讀", + "description": "開啟郵件後,何時將其標示為已讀", + "instant": "立即", + "delay_3s": "3 秒後", + "delay_5s": "5 秒後", + "never": "從不" + }, + "delete_action": { + "label": "刪除動作", + "description": "刪除郵件後的行為", + "trash": "移至垃圾桶", + "trash_and_read": "移至垃圾桶並標示為已讀", + "permanent": "永久刪除", + "warning": "郵件將永久刪除且無法復原。此動作無法復原。" + }, + "message_spacing": { + "label": "郵件內距", + "description": "閱讀器中郵件內文周圍的留白", + "auto": "自動(建議)", + "always": "一律加入留白", + "edge": "無邊距" + }, + "plain_text_font": { + "label": "純文字字型", + "description": "用於純文字郵件的字型", + "mono": "等寬", + "sans": "一般(與應用程式相同)" + }, + "archive_mode": { + "label": "封存方式", + "description": "封存時如何組織郵件", + "single": "單一信件匣", + "year": "每年一個信件匣", + "month": "每月一個信件匣", + "reorganize": "重新整理現有封存", + "reorganize_success": "{count, plural, =0 {沒有需要整理的郵件} =1 {已整理 1 封郵件} other {已整理 # 封郵件}}", + "reorganize_error": "無法重新整理封存" + }, + "permanently_delete_junk": { + "label": "永久刪除垃圾郵件", + "description": "直接永久刪除垃圾郵件信件匣中的郵件,而不移至垃圾桶" + }, + "mail_layout": { + "label": "郵件版面配置", + "description": "選擇經典分割閱讀窗格、Gmail 風格的專注閱讀流程,或 Zimbra 風格的底部閱讀窗格。", + "split": "分割窗格", + "split_description": "郵件清單與閱讀窗格並排顯示。", + "focus": "專注清單", + "focus_description": "每封郵件顯示一列,開啟郵件時以全寬顯示,同時保留信件匣側邊欄。", + "horizontal": "底部閱讀窗格", + "horizontal_description": "在頂端顯示郵件清單,並在下方閱讀窗格開啟選取的郵件。" + }, + "show_preview": { + "label": "顯示預覽文字", + "description": "在清單中顯示郵件預覽", + "focus_description": "在專注模式的單列郵件清單中顯示行內預覽文字" + }, + "disable_threading": { + "label": "停用對話串群組", + "description": "將郵件個別顯示,而不是依對話串分組" + }, + "plain_text_mode": { + "label": "僅純文字", + "description": "停用富文字編輯器,並將所有郵件(包括回覆和轉寄)以純文字傳送" + }, + "auto_select_reply_identity": { + "label": "使用收件地址回覆", + "description": "回覆時,使用原始郵件的收件地址寄送。系統會先比對寄件身分;若是網域 catch-all 收件,則透過主要寄件身分傳送,但將 From 標頭改寫為別名地址。" + }, + "signature_position": { + "label": "簽名檔位置", + "description": "在回覆與轉寄中插入簽名檔的位置。放在引用文字上方可自然作為回覆結尾;放在下方則能保持原始郵件連續。", + "above_quote": "引用文字之前", + "below_quote": "引用文字之後" + }, + "signature_separator": { + "label": "簽名檔分隔線", + "description": "在簽名檔前加入標準的「-- 」分隔線(RFC 3676)。若希望內文直接接續簽名檔,請停用此選項。" + }, + "sub_address_delimiter": { + "label": "子地址分隔符", + "description": "用於分隔使用者名稱和子地址標籤的字元。請選擇與您的郵件伺服器一致的分隔符(例如 user{delimiter}tag@domain.com)。", + "option": "{delimiter}(user{delimiter}tag@domain.com)", + "custom": "自訂…", + "custom_input_label": "自訂分隔字元" + }, + "attachment_click_action": { + "label": "附件點擊動作", + "description": "選擇點選附件時是預覽還是直接下載", + "preview": "儘可能預覽", + "download": "立即下載" + }, + "attachment_position": { + "label": "附件位置", + "description": "選擇在郵件標頭的哪個位置顯示附件", + "beside-sender": "寄件者旁", + "below-header": "標頭下方" + }, + "emails_per_page": { + "10": "10 封郵件", + "25": "25 封郵件", + "50": "50 封郵件", + "100": "100 封郵件", + "label": "每頁郵件數", + "description": "一次載入的郵件數量" + }, + "always_light_mode": { + "label": "一律以淺色模式顯示郵件", + "description": "即使應用程式使用深色模式,也以淺色模式呈現郵件內容,避免深色模式轉換問題" + }, + "external_content": { + "label": "外部內容", + "description": "選擇如何處理圖片與外部內容", + "ask": "每次詢問", + "block": "一律封鎖", + "allow": "一律允許" + }, + "trusted_senders": { + "label": "受信任寄件者", + "description": "管理可自動載入圖片的寄件者", + "count_zero": "無", + "count_one": "1 位寄件者", + "count_other": "{count} 位寄件者", + "modal_title": "受信任寄件者", + "empty_title": "尚無受信任寄件者", + "empty_description": "檢視包含遭封鎖圖片的郵件時,點擊「一律信任此寄件者」即可新增到這裡。", + "add_manually": "手動新增", + "add_button": "新增", + "add_placeholder": "輸入電子郵件地址", + "search_placeholder": "搜尋寄件者…", + "no_results": "找不到相符的寄件者", + "remove": "移除", + "close": "關閉", + "invalid_email": "請輸入有效的電子郵件地址", + "already_added": "該寄件者已被信任", + "save_error": "儲存失敗 — 請檢視聯絡人除錯記錄以瞭解詳細資料", + "use_address_book_label": "與通訊錄同步", + "use_address_book_description": "將受信任寄件者儲存在專用的「受信任寄件者」通訊錄,以便在所有裝置間同步" + }, + "hover_actions": { + "label": "游標暫留快速動作", + "description": "選擇游標移至清單中的郵件上方時要顯示的快速動作", + "delete": "刪除", + "star": "加上/移除星號", + "mark_read": "標示為已讀/未讀", + "archive": "封存", + "tag": "標籤", + "spam": "標示為垃圾郵件", + "not_spam": "非垃圾郵件", + "none_selected": "未選取任何動作", + "mode_label": "顯示模式", + "mode_inline": "內嵌", + "mode_floating": "浮動", + "corner_label": "浮動位置", + "corner_top-left": "左上", + "corner_top-right": "右上", + "corner_bottom-left": "左下", + "corner_bottom-right": "右下" + }, + "default_mail_program": { + "label": "預設郵件應用程式", + "description": "將 {appName} 註冊為 mailto: 連結的預設郵件應用程式", + "button": "設為預設", + "success": "瀏覽器已提示設定為預設", + "error": "您的瀏覽器不支援此功能" + }, + "attachment_reminder": { + "label": "附件提醒", + "description": "郵件提到附件但沒有附加檔案時,在傳送前發出警告", + "keywords_label": "觸發關鍵字", + "keywords_description": "郵件中出現時會觸發提醒的詞彙或片語", + "add_placeholder": "新增關鍵字…", + "add": "新增", + "remove": "移除" + }, + "empty_subject_warning": { + "label": "空主題提醒", + "description": "傳送沒有主題的郵件前請求確認。" + }, + "hide_inline_image_attachments": { + "label": "在附件清單中隱藏內嵌圖片", + "description": "嵌入到郵件內文中的圖片不會作為單獨的附件顯示" + }, + "attachment_image_previews": { + "label": "在附件中顯示圖片預覽", + "description": "將圖片附件顯示為縮圖卡片,而不是通用檔案圖示" + }, + "send_delay": { + "label": "取消傳送/延遲傳送", + "description": "在伺服器端短暫延遲一般傳送。", + "off": "關閉", + "seconds": "{seconds} 秒", + "unsupported": "目前帳號未宣告支援延遲傳送。該設定仍會為其他帳號儲存。" + }, + "return_to_list_after_action": { + "label": "刪除或標示為未讀後回到清單", + "description": "刪除開啟的郵件或標示為未讀後,回到郵件清單,而不是開啟下一封郵件。" + }, + "swipe_right_action": { + "label": "向右滑動動作(行動裝置)", + "description": "在觸控裝置上,於清單中向右滑動郵件時執行的動作。" + }, + "swipe_left_action": { + "label": "向左滑動動作(行動裝置)", + "description": "在觸控裝置上,於清單中向左滑動郵件時執行的動作。" + }, + "swipe_actions": { + "none": "無", + "archive": "封存", + "delete": "刪除", + "mark_read": "切換已讀/未讀", + "star": "加上/移除星號", + "spam": "標示為垃圾郵件" + }, + "rtl_editing": { + "label": "支援從右至左編輯", + "description": "在編輯器工具列中新增方向按鈕,可將段落設定為從左到右或從右到左" + } + }, + "composer": { + "title": "郵件撰寫", + "description": "設定郵件撰寫偏好", + "autosave": { + "label": "自動儲存間隔", + "description": "自動儲存草稿的頻率", + "30s": "每 30 秒", + "1m": "每分鐘", + "2m": "每 2 分鐘", + "5m": "每 5 分鐘" + }, + "send_confirmation": { + "label": "傳送前確認", + "description": "傳送郵件前要求確認" + }, + "default_reply": { + "label": "預設回覆模式", + "description": "點擊回覆時的預設動作", + "reply": "回覆", + "reply_all": "全部回覆" + } + }, + "privacy": { + "title": "隱私權與安全", + "description": "管理您的隱私權與安全設定", + "external_images": { + "label": "封鎖外部圖片", + "description": "防止透過外部圖片進行追蹤" + }, + "session_timeout": { + "label": "工作階段逾時", + "description": "一段時間未操作後自動登出", + "never": "永不", + "30m": "30 分鐘", + "1h": "1 小時", + "4h": "4 小時" + }, + "clear_cache": { + "label": "清除快取", + "description": "移除快取資料與暫存檔案", + "button": "清除快取", + "confirm": "您確定要清除快取嗎?", + "success": "已成功清除快取" + } + }, + "account": { + "title": "帳號", + "description": "檢視您的帳號資訊", + "name_label": "顯示名稱", + "username_label": "使用者名稱", + "account_type_label": "帳號類型", + "auth_method_label": "驗證方式", + "auth_method_oauth": "單一登入(OAuth/OIDC)", + "auth_method_basic": "密碼", + "demo_account": "示範帳號", + "email": { + "label": "電子郵件地址", + "value": "{email}" + }, + "server": { + "label": "JMAP 伺服器", + "value": "{server}" + }, + "storage": { + "label": "儲存空間使用量", + "used": "已使用 {used} / {total}", + "percentage": "已使用 {percent}%" + }, + "last_sync": { + "label": "上次同步", + "value": "{time}" + }, + "accounts": { + "title": "已登入帳號", + "description": "拖曳以重新排序帳號在帳號下拉選單中的顯示順序", + "active": "使用中的帳號", + "default_badge": "預設帳號", + "set_default": "設為預設", + "switch_to": "切換到此帳號", + "move_up": "上移", + "move_down": "下移", + "drag_handle": "拖曳以重新排序", + "add": "新增帳號" + }, + "shared_accounts": { + "title": "與我共用", + "description": "您可以管理的群組與共用帳號。選取一個帳號,即可編輯其篩選規則、休假自動回覆、行事曆與聯絡人。", + "shared_label": "共用帳號" + } + }, + "scoped": { + "back": "回到我的帳號", + "managing": "正在管理:{name}" + }, + "security": { + "title": "帳號安全", + "description": "管理您的密碼、雙因素驗證與安全設定", + "detecting": "正在偵測伺服器功能…", + "not_available": "此郵件伺服器無法管理帳號安全性。可能已停用必要權限。如需詳細資料,請參閱說明文件。", + "password": { + "title": "變更密碼", + "current": "目前密碼", + "new": "新密碼", + "confirm": "確認新密碼", + "submit": "變更密碼", + "success": "已成功變更密碼", + "error_title": "變更密碼失敗", + "error_mismatch": "兩次輸入的新密碼不相符", + "error_min_length": "密碼必須至少為 8 個字元", + "error_generic": "無法變更密碼" + }, + "display_name": { + "label": "顯示名稱", + "description": "顯示在伺服器上的名稱", + "placeholder": "輸入您的顯示名稱", + "save": "儲存", + "success": "顯示名稱已更新", + "error": "無法更新顯示名稱" + }, + "totp": { + "section_title": "雙因素驗證", + "label": "TOTP 驗證", + "description": "透過基於時間的一次性密碼,增加一層安全保護", + "active": "已啟用", + "inactive": "未啟用", + "enabled": "已啟用雙因素驗證", + "disabled": "已停用雙因素驗證", + "enable_error": "無法啟用 2FA", + "disable_error": "無法停用 2FA", + "setup_instructions": "請將此 URL 複製到驗證器應用程式(Google Authenticator、Authy 等):", + "verification_code": "驗證碼", + "confirm": "確認", + "disable": "停用", + "disable_confirm_prompt": "請輸入密碼以停用雙因素驗證。", + "password_required": "需要密碼", + "code_required": "需要驗證碼", + "code_invalid": "驗證碼無效。請檢查驗證器應用程式後再試一次。" + }, + "app_passwords": { + "title": "應用程式密碼", + "description": "為不支援雙因素驗證的應用程式建立密碼", + "add": "新增", + "create": "建立", + "cancel": "取消", + "done": "完成", + "generate": "產生", + "name_label": "應用程式名稱", + "name_placeholder": "例如 Thunderbird、iPhone 郵件", + "expires_label": "到期日(選填)", + "allowed_ips_label": "允許的 IP(選填)", + "allowed_ips_placeholder": "10.0.0.5, 192.168.1.0/24", + "allowed_ips_hint": "用逗號或空格分隔。留空則允許任意 IP。", + "password_label": "密碼(留空時自動產生)", + "password_placeholder": "留空時自動產生", + "copy_now_warning": "請立即複製此密碼 — 之後將不再顯示。", + "added": "已建立應用程式密碼", + "removed": "已移除應用程式密碼", + "add_error": "無法建立應用程式密碼", + "remove_error": "無法移除應用程式密碼", + "none": "尚未設定應用程式密碼" + }, + "api_keys": { + "title": "API 金鑰", + "description": "為直接與伺服器通訊的指令碼和整合建立 API 金鑰", + "name_label": "金鑰名稱", + "name_placeholder": "例如:備份指令碼、CI 執行器", + "copy_now_warning": "請立即複製此 API 金鑰 — 之後將不再顯示。", + "added": "API 金鑰已建立", + "removed": "API 金鑰已刪除", + "add_error": "建立 API 金鑰失敗", + "remove_error": "刪除 API 金鑰失敗", + "none": "未設定 API 金鑰" + }, + "encryption": { + "section_title": "靜態資料加密", + "label": "郵件加密", + "description": "加密儲存在伺服器上的郵件,提供額外的隱私保障", + "active": "{type} 加密已啟用", + "inactive": "未啟用", + "enabled": "已啟用靜態資料加密", + "disabled_success": "已停用靜態資料加密", + "error": "無法更新加密設定", + "algorithm_label": "加密演算法", + "encrypt_on_append": "上傳時加密新郵件", + "allow_spam_training": "在加密郵件前允許垃圾郵件訓練", + "enable_encryption": "啟用加密", + "enable_tooltip": "使用此金鑰啟用加密", + "configure_title": "使用此金鑰啟用加密", + "enable_button": "啟用", + "disable_tooltip": "停用加密", + "enabled_success": "已啟用靜態資料加密" + }, + "public_keys": { + "name_label": "公鑰名稱", + "name_placeholder": "例如:我的金鑰", + "key_label": "公開金鑰(S/MIME 或 PGP ASCII 裝甲格式)", + "key_placeholder": "在此貼上您的公鑰", + "none": "未設定公鑰" + }, + "email_client": { + "title": "郵件用戶端設定", + "description": "使用以下登入資訊設定桌面版或行動裝置電子郵件用戶端(Thunderbird、Apple Mail、Outlook 等)", + "jmap_username_label": "JMAP 使用者名稱", + "copy": "複製", + "copied": "已複製", + "password_instructions": "使用上方的 JMAP 使用者名稱與應用程式密碼登入電子郵件用戶端。如果尚未建立應用程式密碼,請在上方區段建立一組。" + }, + "link_device": { + "title": "連結行動應用程式", + "description": "不需輸入即可登入 Bulwark Mail 行動應用程式。在這裡產生 QR Code,再從應用程式的登入畫面掃描。", + "generate": "顯示 QR Code", + "regenerate": "顯示新的 QR Code", + "instructions": "開啟 Bulwark Mail 應用程式,在登入畫面點選「掃描 QR Code」,再將相機對準這裡。", + "expires_in": "此 QR Code 將在 {seconds} 秒後到期,且只能使用一次。", + "expired": "此 QR Code 已到期。", + "generating": "正在產生…", + "error": "無法建立配對碼。請再試一次。" + } + }, + "identities": { + "title": "寄件身分", + "description": "管理可用來寄信的電子郵件地址", + "identities_count": { + "label": "您的寄件身分", + "description": "已設定用來寄信的電子郵件地址", + "count_zero": "尚無寄件身分", + "count_one": "1 個寄件身分", + "count_other": "{count} 個寄件身分" + }, + "manage": "管理寄件身分", + "sub_addressing": { + "label": "子地址功能", + "description": "使用 user+tag@domain.com 這類標籤來整理收到的郵件", + "learn_more": "瞭解更多" + } + }, + "vacation": { + "title": "休假自動回覆", + "description": "您不在時,自動回覆收到的郵件", + "loading": "正在載入自動回覆設定…", + "not_supported": "您的郵件伺服器不支援自動回覆功能。", + "fetch_error": "無法載入自動回覆設定。請再試一次。", + "status": { + "label": "休假自動回覆", + "description": "自動回覆寄信給您的人", + "active": "已啟用", + "inactive": "已停用" + }, + "date_range": { + "title": "日期範圍", + "description": "可選擇將自動回覆限制在特定期間", + "start": "開始日期", + "start_description": "留空表示不限制開始時間", + "end": "結束日期", + "end_description": "留空表示不限制結束時間" + }, + "message": { + "title": "自動回覆郵件", + "description": "作為回覆傳送的郵件內容", + "subject_label": "主題", + "subject_description": "自動回覆郵件的主題", + "subject_placeholder": "不在辦公室", + "body_label": "郵件內文", + "body_description": "純文字郵件內容", + "body_placeholder": "感謝您的來信。我目前不在辦公室,返回後會儘快回覆您的郵件。", + "html_label": "格式化郵件(HTML)", + "html_description": "新增包含連結與樣式的富文字版本。若收件者的郵件用戶端無法顯示,則改用上方純文字版本。", + "html_placeholder": "撰寫格式化的不在辦公室回覆…" + }, + "preview": { + "title": "預覽", + "show": "顯示預覽", + "hide": "隱藏預覽" + }, + "save": "儲存變更", + "saving": "正在儲存…", + "warnings": { + "end_before_start": "結束日期必須晚於開始日期", + "start_in_past": "開始日期已在過去", + "empty_body": "郵件內文為空 — 收件者將收到空白回覆" + } + }, + "folders": { + "role_memos": "備忘錄", + "title": "信件匣", + "description": "管理郵件信件匣並指派標準角色", + "folder_list": "您的信件匣", + "folder_list_description": "點擊信件匣圖示即可自訂", + "standard_roles": "標準信件匣角色", + "standard_roles_description": "指派哪些信件匣作為收件匣、寄件備份、垃圾桶等標準角色。", + "role_inbox": "收件匣", + "role_drafts": "草稿", + "role_sent": "寄件備份", + "role_trash": "垃圾桶", + "role_junk": "垃圾郵件", + "role_archive": "封存", + "role_none": "無", + "create_folder": "建立信件匣", + "create_subfolder": "建立子信件匣", + "reorder": "上下拖曳可調整順序,左右拖曳可變更上層信件匣", + "reorder_error": "無法重新排序信件匣", + "move_error": "無法移動信件匣", + "subfolder_of": "位於 {name} 內", + "subfolder_name": "子信件匣名稱", + "new_folder_name": "信件匣名稱", + "rename": "重新命名", + "change_icon": "變更圖示", + "delete": "刪除", + "confirm_delete": "您確定要刪除「{name}」嗎?此信件匣中的郵件將移至垃圾桶。", + "create": "建立", + "cancel": "取消", + "no_folders": "尚無自訂信件匣", + "cannot_delete_role": "無法刪除具有標準角色的信件匣。請先移除該角色。", + "folder_created": "已建立信件匣", + "folder_renamed": "已重新命名信件匣", + "folder_deleted": "已刪除信件匣", + "role_updated": "已更新信件匣角色", + "error_create": "無法建立信件匣", + "error_rename": "無法重新命名信件匣", + "error_delete": "無法刪除信件匣", + "error_delete_has_children": "無法刪除信件匣:其中仍有子信件匣。請先刪除或移動它們。", + "error_delete_has_email": "無法刪除信件匣:其中仍有郵件。請先移動或刪除這些郵件。", + "error_role": "無法更新信件匣角色" + }, + "advanced": { + "title": "進階", + "description": "進階選項與開發者設定", + "debug_mode": { + "label": "除錯模式", + "description": "啟用詳細記錄以進行疑難排解" + }, + "debug_categories": { + "description": "選取要記錄的類別。停用不需要的類別,可減少主控台雜訊。", + "jmap": "JMAP 用戶端", + "jmap_description": "信件匣操作、郵件取得與 JMAP 通訊協定請求", + "calendar": "行事曆", + "calendar_description": "行事曆活動、匯入與排程訊息", + "tasks": "任務", + "tasks_description": "行事曆任務建立、取得和更新", + "auth": "驗證", + "auth_description": "登入、TOTP、權杖交換與工作階段管理", + "filters": "篩選規則", + "filters_description": "Sieve 篩選規則和休假自動回覆指令碼", + "email": "郵件檢視", + "email_description": "郵件呈現、TNEF 處理與標示為已讀", + "push": "推送通知", + "push_description": "推送通知設定和傳送", + "contacts": "聯絡人與通訊錄", + "contacts_description": "聯絡人同步、通訊錄操作與受信任寄件者" + }, + "settings_sync": { + "label": "設定同步", + "description": "跨瀏覽器和裝置同步您的設定" + }, + "sender_favicons": { + "label": "寄件者圖示", + "description": "使用企業寄件者的網站圖示作為頭像" + }, + "show_avatars_in_junk": { + "label": "在垃圾郵件信件匣顯示頭像", + "description": "在垃圾郵件信件匣中顯示寄件者的頭像與網站圖示。預設停用,以免釣魚郵件因熟悉的圖示而顯得可信。" + }, + "keyboard_shortcuts": { + "label": "鍵盤快速鍵", + "description": "檢視可用快速鍵", + "button": "檢視快速鍵" + }, + "refresh_cache": { + "label": "重新整理快取資料", + "description": "從伺服器重新載入聯絡人、行事曆與信件匣。保留帳號與工作階段,不需登出即可修正過時或錯誤的畫面。", + "button": "重新整理" + }, + "reset_settings": { + "label": "重設設定", + "description": "將所有設定還原為預設值", + "button": "重設為預設值" + }, + "export_settings": { + "label": "匯出設定", + "description": "將設定匯出為 JSON 檔案", + "button": "匯出" + }, + "import_settings": { + "label": "匯入設定", + "description": "從 JSON 檔案匯入設定", + "button": "匯入" + }, + "about": { + "title": "Bulwark 網頁郵件" + } + }, + "sidebar_apps": { + "title": "側邊欄應用程式", + "description": "管理側邊欄中的自訂應用程式與連結", + "keep_loaded": "保持應用程式載入", + "keep_loaded_description": "切換內嵌應用程式時,讓其在背景繼續執行,以避免重新載入", + "manage_title": "自訂應用程式", + "manage_description": "在側邊欄新增、編輯或移除自訂應用程式" + }, + "contacts": { + "title": "聯絡人", + "description": "匯入與匯出聯絡人", + "group_by_letter_label": "依首字分組", + "group_by_letter_description": "在聯絡人清單中顯示依字母排列的分節標題", + "import_label": "匯入聯絡人", + "import_description": "從 vCard(.vcf)檔案匯入聯絡人", + "export_label": "匯出聯絡人", + "export_description": "將所有聯絡人匯出為 vCard(.vcf)檔案", + "manage_title": "通訊錄", + "manage_description": "重新命名您的通訊錄", + "no_address_books": "找不到通訊錄", + "categories_title": "類別", + "categories_description": "重新命名聯絡人類別", + "no_categories": "找不到類別" + }, + "downloads": { + "title": "下載", + "description": "自訂下載的郵件和附件的命名方式。", + "reset": "還原預設值", + "preview": "預覽:", + "email_template": { + "label": "電子郵件(.eml)檔名", + "description": "匯出郵件或將其拖到檔案系統時使用的範本。副檔名 .eml 會自動新增。" + }, + "attachment_template": { + "label": "附件檔名", + "description": "下載或拖出附件時使用的範本。如果省略 '{filename}' 和 '{ext}',將保留原始副檔名。" + }, + "bundle_template": { + "label": "多郵件 .zip 檔名", + "description": "將多封選取的郵件拖出或下載為單一 .zip 壓縮檔時使用的範本。系統會自動加上 .zip 副檔名。" + }, + "spaces": { + "label": "空格", + "description": "將產生的檔名中的空格取代為其他字元。", + "keep": "保留空格", + "underscore": "取代為 _", + "dash": "取代為 -" + }, + "lowercase": { + "label": "小寫", + "description": "將整個檔名轉為小寫。" + }, + "strip_diacritics": { + "label": "去除變音符號", + "description": "將帶重音的字母轉換為對應的 ASCII 字元(ä → a、é → e)。適用於無法正確處理 Unicode 檔名的工具。" + }, + "collapse_separators": { + "label": "縮減重複的分隔字元", + "description": "將連續的空格、底線或連字號縮減為單一字元。" + }, + "after_export": { + "label": "匯出後", + "description": "匯出為 .eml 後,可選擇移動郵件。", + "keep": "保留在信件匣", + "archive": "移至封存", + "trash": "移至垃圾桶" + } + }, + "filters": { + "title": "郵件篩選規則", + "description": "建立規則,自動整理、標記和管理收到的郵件", + "add_rule": "新增規則", + "no_rules": "尚無篩選規則", + "no_rules_description": "建立規則以自動整理收到的郵件", + "vacation_active": "休假自動回覆已開啟", + "vacation_active_description": "已啟用收到郵件時的自動回覆", + "vacation_configure": "設定", + "edit_rule": "編輯規則", + "new_rule": "新規則", + "delete_rule": "刪除規則", + "delete_confirm": "您確定要刪除此規則嗎?", + "enable": "啟用", + "disable": "停用", + "raw_editor": "原始 Sieve 編輯器", + "raw_editor_warning": "編輯原始 Sieve 指令碼可能導致視覺化規則編輯失效。這裡的變更會覆寫視覺化建構工具。", + "validate": "驗證", + "validation_success": "指令碼有效", + "validation_error": "指令碼有錯誤", + "save": "儲存規則", + "saving": "正在儲存…", + "saved": "篩選規則已成功儲存", + "save_failed": "無法儲存篩選規則", + "loading": "正在載入篩選規則…", + "not_supported": "您的郵件伺服器不支援郵件篩選規則。", + "rule_name": "規則名稱", + "rule_name_placeholder": "例如,整理訂閱郵件", + "match_all": "符合所有條件", + "match_any": "符合任一條件", + "conditions": "條件", + "add_condition": "新增條件", + "actions": "動作", + "add_action": "新增動作", + "stop_processing": "停止處理後續規則", + "attachment_type_placeholder": "例如:pdf、doc、jpg", + "value_placeholder_multi": "值(多個用逗號分隔)", + "condition_fields": { + "attachment": "附件", + "from": "寄件者", + "to": "收件者", + "cc": "副本", + "subject": "主題", + "header": "自訂標頭", + "size": "大小", + "body": "內文" + }, + "comparators": { + "has_any": "存在", + "has_type": "型別為", + "contains": "包含", + "not_contains": "不包含", + "is": "等於", + "not_is": "不是", + "starts_with": "以…開頭", + "ends_with": "以…結尾", + "matches": "符合模式", + "greater_than": "大於", + "less_than": "小於" + }, + "action_types": { + "move": "移至信件匣", + "copy": "複製到信件匣", + "forward": "轉寄至", + "mark_read": "標示為已讀", + "star": "為郵件加上星號", + "add_label": "新增標籤", + "discard": "捨棄(直接刪除)", + "reject": "附上訊息拒絕", + "keep": "保留在收件匣中", + "stop": "停止處理" + }, + "move_to_folder": "選取信件匣", + "copy_to_folder": "選取信件匣", + "forward_to": "轉寄至電子郵件地址", + "forward_placeholder": "email@example.com", + "reject_message": "拒絕留言", + "reject_placeholder": "您的郵件已被拒絕", + "label_name": "標籤名稱", + "label_placeholder": "選取標籤", + "header_name": "標頭名稱", + "header_placeholder": "例如,X-Mailing-List", + "size_bytes": "大小(以位元組為單位)", + "size_placeholder": "例如,1000000", + "system_managed": "系統管理的規則", + "opaque_warning": "此指令碼是在視覺化建構工具之外編輯的。目前只能使用原始 Sieve 編輯器。", + "open_sieve_editor": "開啟原始 Sieve 編輯器", + "fetch_error": "無法載入篩選規則", + "expanded_view": "展開檢視", + "expanded_view_description": "顯示包含詳細條件與動作區塊的篩選規則", + "if": "如果", + "then": "然後", + "match_all_conditions": "全部符合", + "match_any_condition": "任一符合", + "and": "且", + "or": "或", + "cancel": "取消", + "confirm_delete": "刪除", + "rule_list": "篩選規則", + "drag_to_reorder": "拖曳以重新排序", + "match_type": "比對方式", + "reset_to_visual": "重設為視覺化建構工具", + "reset_warning": "這會捨棄目前的指令碼並重新開始。", + "confirm_reset": "重設", + "validation_empty_name": "規則名稱為必填欄位", + "validation_empty_conditions": "至少需要一個具有值的條件", + "validation_empty_actions": "至少需要一個動作", + "templates_section": "從範本開始", + "template_newsletters": "將訂閱郵件移至信件匣", + "template_receipts": "自動封存收據", + "template_important": "標示重要郵件", + "template_notifications": "篩選通知", + "sieve_editor": { + "title": "Sieve 指令碼編輯器", + "warning": "編輯原始 Sieve 指令碼可能導致視覺化規則編輯失效。這裡的變更會覆寫視覺化建構工具。", + "script_content": "Sieve 指令碼", + "valid": "指令碼有效", + "invalid": "指令碼有錯誤", + "save_warning": "儲存會覆寫所有視覺化規則,且無法復原。請再次點擊「儲存」以確認。", + "validating": "正在驗證…", + "validate": "驗證", + "cancel": "取消", + "save": "儲存", + "confirm_save": "確認儲存", + "validation_failed": "驗證請求失敗" + }, + "rule_summary": { + "conditions_count": "{count, plural, one {# 個條件} other {# 個條件}}", + "actions_count": "{count, plural, one {# 個動作} other {# 個動作}}" + }, + "origin_external": "外部", + "managed_by_tooltip": "由 {source} 管理。請在該應用程式中編輯,或使用原始 Sieve 編輯器。" + }, + "templates": { + "title": "郵件範本", + "description": "使用預留位置變數建立可重用的郵件範本", + "add": "新增範本", + "edit": "編輯範本", + "name": "範本名稱", + "name_placeholder": "例如,後續郵件", + "category": "類別", + "category_placeholder": "例如,工作、個人", + "subject": "主題", + "subject_placeholder": "郵件主題行", + "body": "內文", + "body_placeholder": "郵件內文內容…", + "recipients_placeholder": "email@example.com", + "identity": "寄件身分", + "default_identity": "預設寄件身分", + "favorite": "我的最愛", + "cancel": "取消", + "create": "建立", + "update": "更新", + "confirm_delete": "刪除", + "no_templates": "尚無範本", + "manage": "管理範本", + "count": "{count, plural, one {# 個範本} other {# 個範本}}", + "export_import": "匯出與匯入", + "export_import_description": "備份您的範本,或移轉到其他裝置", + "export": "匯出", + "import": "匯入", + "validation": { + "empty": "範本名稱為必填欄位", + "too_long": "範本名稱不得超過 200 個字元" + } + }, + "files": { + "display": { + "title": "顯示", + "description": "設定檔案和資料夾的顯示方式" + }, + "folder_layout": { + "label": "資料夾導覽", + "description": "選擇資料夾與檔案並列顯示,或在側邊欄以樹狀顯示", + "inline": "內嵌", + "sidebar": "側邊欄" + }, + "default_view": { + "label": "預設檢視", + "description": "選擇網格或清單版面配置", + "list": "清單", + "grid": "網格" + }, + "default_sort": { + "label": "預設排序", + "description": "選擇檔案的預設排序規則", + "name": "名稱", + "size": "大小", + "modified": "修改日期" + }, + "sort_direction": { + "label": "排序方式", + "description": "選擇升序或降序", + "ascending": "遞增", + "descending": "遞減" + }, + "icons": { + "title": "圖示", + "description": "設定檔案圖示外觀" + }, + "show_icons": { + "label": "顯示檔案圖示", + "description": "在檔案和資料夾旁邊顯示圖示" + }, + "colored_icons": { + "label": "彩色圖示", + "description": "使用彩色圖示取代單色圖示" + }, + "show_thumbnails": { + "label": "顯示縮圖", + "description": "圖片檔案顯示預覽,而不是圖示" + }, + "behavior": { + "title": "行為", + "description": "設定檔案瀏覽器行為" + }, + "show_hidden": { + "label": "顯示隱藏檔案", + "description": "顯示名稱以句點開頭的檔案與資料夾" + }, + "preview": { + "label": "預覽" + } + } + }, + "errors": { + "page_error_title": "出了點問題", + "page_error_description": "發生未預期的錯誤。請再試一次或返回首頁。", + "sidebar_error": "無法載入信件匣", + "email_list_error": "無法載入郵件", + "viewer_error_title": "無法顯示郵件", + "viewer_error_description": "呈現此郵件時出現問題。它可能包含不受支援的內容。", + "composer_error": "無法載入郵件撰寫", + "settings_error_title": "無法使用設定", + "settings_error_description": "無法載入設定。您的偏好設定可能不會被儲存。", + "try_again": "再試一次", + "reload": "重新載入", + "reload_emails": "重新載入郵件", + "reload_settings": "重新載入設定", + "retry": "重試", + "go_home": "前往收件匣" + }, + "context_menu": { + "reply": "回覆", + "reply_all": "全部回覆", + "forward": "轉寄", + "mark_read": "標示為已讀", + "mark_unread": "標示為未讀", + "star": "加上星號", + "unstar": "移除星號", + "pin": "固定", + "unpin": "取消固定", + "move_to": "移至…", + "archive": "封存", + "delete": "刪除", + "mark_as_spam": "回報垃圾郵件", + "not_spam": "非垃圾郵件", + "tag": "標籤", + "items_selected": "已選取 {count} 封郵件", + "edit_draft": "編輯草稿", + "cancel_scheduled_send": "取消傳送", + "reschedule_send": "重新排程", + "cancel_and_edit": "取消並編輯", + "cancel_and_compose_again": "取消並重新撰寫" + }, + "mailbox_context_menu": { + "mark_folder_read": "將信件匣標示為已讀", + "mark_folder_tree_read": "將信件匣與子信件匣標示為已讀", + "mark_all_folders_read": "將所有信件匣標示為已讀", + "new_subfolder": "新增子信件匣…", + "new_folder": "新增信件匣…", + "rename": "重新命名…", + "import_email": "匯入 .eml 或 .zip…", + "empty_folder": "清空信件匣", + "empty_folder_generic": "清空信件匣", + "delete_folder": "刪除信件匣", + "refresh": "重新整理", + "mark_all_confirm_title": "將所有信件匣標示為已讀", + "mark_all_confirm_message": "要將您個人帳號中的所有未讀郵件標示為已讀嗎?", + "delete_confirm_title": "刪除信件匣", + "delete_confirm_message": "要永久刪除信件匣「{name}」嗎?此動作無法復原。", + "prompt_new_subfolder": "請輸入新子信件匣的名稱。", + "prompt_new_folder": "請輸入新信件匣的名稱。", + "prompt_rename": "請輸入此信件匣的新名稱。", + "placeholder_folder_name": "信件匣名稱", + "create": "建立", + "rename_confirm": "重新命名", + "toast_marked_read": "信件匣已標示為已讀", + "toast_marked_read_count": "已將 {count, plural, one {1 封郵件} other {# 封郵件}} 標示為已讀", + "toast_already_read": "沒有未讀郵件", + "toast_marked_all_read": "所有信件匣已標示為已讀", + "toast_emptied": "信件匣已清空", + "toast_folder_created": "已建立信件匣", + "toast_folder_renamed": "已重新命名信件匣", + "toast_folder_deleted": "已刪除信件匣", + "toast_error_mark_read": "無法標示為已讀", + "toast_error_empty": "無法清空信件匣", + "toast_error_create": "無法建立信件匣", + "toast_error_rename": "無法重新命名信件匣", + "toast_error_delete": "無法刪除信件匣", + "toast_error_delete_has_children": "信件匣內有子信件匣,請先移除。", + "toast_error_delete_has_email": "信件匣不是空的,請先清空。" + }, + "shortcuts": { + "title": "鍵盤快速鍵", + "tip": "隨時按下 ? 即可顯示此說明", + "sections": { + "navigation": "導覽", + "actions": "郵件動作", + "global": "全域", + "threads": "對話串", + "composer": "郵件撰寫" + }, + "navigation": { + "next_email": "下一封郵件", + "previous_email": "上一封郵件", + "open_email": "開啟郵件", + "close_email": "關閉/取消選取" + }, + "actions": { + "reply": "回覆", + "reply_all": "全部回覆", + "forward": "轉寄", + "star": "加上/移除星號", + "archive": "封存", + "delete": "刪除", + "mark_unread": "標示為未讀", + "mark_read": "標示為已讀", + "toggle_spam": "回報垃圾郵件/非垃圾郵件" + }, + "global": { + "compose": "撰寫新郵件", + "search": "將焦點移至搜尋框", + "help": "顯示快速鍵", + "refresh": "重新整理郵件", + "select_all": "全部選取" + }, + "threads": { + "expand_collapse": "展開/收合對話串" + }, + "composer": { + "send": "傳送郵件", + "schedule_send": "排程寄送", + "template_picker": "開啟範本選取器" + } + }, + "threads": { + "messages_one": "{count} 封郵件", + "messages_other": "{count} 封郵件", + "messages_tooltip": "{count, plural, one {此對話串有 # 封郵件} other {此對話串有 # 封郵件}}", + "expand": "展開對話串", + "collapse": "收合對話串", + "loading": "正在載入對話串…", + "mark_read": "將對話串標示為已讀", + "mark_unread": "將對話串標示為未讀", + "archive": "封存對話串", + "delete": "刪除對話串", + "star": "為對話串加上星號", + "unstar": "移除對話串星號", + "toggle_thread": "展開/收合對話串" + }, + "identities": { + "modal_title": "管理寄件身分", + "create_new": "建立新的寄件身分", + "edit_identity": "編輯寄件身分", + "delete_confirm": "要刪除此寄件身分嗎?此動作無法復原。", + "cannot_delete": "無法刪除此寄件身分", + "primary_identity": "主要", + "set_as_primary": "設為主要", + "no_identities": "找不到寄件身分", + "display": { + "reply_to": "回覆地址:", + "bcc": "密件副本:", + "signature": "簽名檔:", + "preview": "預覽:" + }, + "validation_errors": { + "invalid_emails": "無效電子郵件地址:{emails}", + "unknown_error": "未知錯誤" + }, + "form": { + "name_label": "顯示名稱", + "name_placeholder": "例如,工作信箱、個人信箱", + "name_required": "名稱為必填欄位", + "email_label": "電子郵件地址", + "email_placeholder": "your.email@example.com", + "email_required": "電子郵件地址為必填欄位", + "email_invalid": "請輸入有效的電子郵件地址", + "email_immutable": "寄件身分建立後,無法變更電子郵件地址", + "reply_to_label": "回覆地址(選填)", + "reply_to_placeholder": "reply@example.com", + "bcc_label": "自動密件副本(選填)", + "bcc_placeholder": "archive@example.com", + "text_signature_label": "純文字簽名檔", + "html_signature_label": "HTML 簽名檔", + "signature_byte_counter": "{bytes} / {max} 位元組", + "signature_byte_limit_reached": "已達伺服器限制", + "save": "儲存寄件身分", + "cancel": "取消", + "creating": "正在建立…", + "updating": "正在更新…" + }, + "sub_address": { + "button_tooltip": "使用子地址", + "popover_title": "新增子地址標籤", + "tag_input_placeholder": "輸入標籤(例如購物)", + "preview_label": "預覽:", + "recent_tags": "最近的標籤", + "suggested_tags": "建議", + "use_address": "使用此電子郵件地址", + "invalid_tag": "標籤只能包含英文字母、數字與連字號", + "tag_too_long": "標籤不得超過 30 個字元", + "help_text": "傳送到 user{delimiter}tag@domain.com 的郵件將送達您的收件匣", + "validation": { + "empty": "標籤不能為空", + "too_long": "標籤不得超過 {max} 個字元", + "invalid_chars": "標籤只能包含英文字母、數字與連字號" + } + }, + "badge": { + "sent_via": "透過", + "sub_address_tag": "使用子地址傳送:{tag}", + "identity_name": "使用寄件身分傳送:{name}", + "identity_short": "透過 {name}", + "subaddress_tag": "+{tag}" + }, + "delete_button": "刪除", + "delete_confirm_title": "刪除寄件身分" + }, + "templates": { + "picker_title": "選擇範本", + "search_placeholder": "搜尋範本…", + "section_favorites": "我的最愛", + "section_recent": "最近使用", + "section_uncategorized": "其他", + "no_templates": "尚無範本", + "no_results": "找不到範本", + "fill_placeholders": "填寫預留位置值", + "enter_value": "輸入值…", + "preview": "預覽", + "insert_with_values": "填入值後插入", + "insert_raw": "直接插入範本", + "copy_suffix": "(複製)", + "placeholder": "變數", + "placeholders": { + "recipient_name": "收件者姓名", + "company": "公司名稱", + "date": "目前日期", + "day_of_week": "星期幾", + "sender_name": "您的姓名" + } + }, + "contacts": { + "title": "聯絡人", + "search_placeholder": "搜尋聯絡人…", + "create_new": "新增聯絡人", + "no_category": "無類別", + "rename_category": "重新命名類別", + "category_name_label": "類別名稱", + "category_renamed": "類別已重新命名", + "category_rename_failed": "重新命名類別失敗", + "category_added": "聯絡人已新增至 {name}", + "category_added_plural": "{count} 位聯絡人已新增至 {name}", + "empty_state": "尚無聯絡人", + "empty_state_title": "尚無聯絡人", + "empty_state_subtitle": "建立第一位聯絡人,或從 vCard 檔案匯入", + "empty_search": "沒有符合您搜尋條件的聯絡人", + "empty_search_hint": "嘗試其他搜尋字詞", + "empty_filtered": "沒有符合您篩選條件的聯絡人", + "empty_filtered_hint": "請調整或清除篩選條件", + "clear_search": "清除搜尋", + "import_vcard": "匯入 vCard", + "delete_confirm_title": "刪除聯絡人", + "delete_confirm": "您確定要刪除此聯絡人嗎?", + "local_mode": "聯絡人儲存在本機(伺服器不支援 JMAP 聯絡人)", + "back_to_contacts": "回到聯絡人", + "back_to_email": "回到郵件", + "open_categories": "開啟類別", + "tabs": { + "all": "全部", + "groups": "群組" + }, + "shared": { + "title": "共用" + }, + "address_books": { + "create": "新增通訊錄", + "created": "通訊錄已建立", + "create_failed": "建立通訊錄失敗", + "title": "我的通訊錄", + "shared_prefix": "共用:{name}", + "moved": "聯絡人已移至 {name}", + "moved_plural": "{count} 聯絡人已移至 {name}", + "move_failed": "無法移動聯絡人", + "address_book": "通訊錄", + "rename": "重新命名通訊錄", + "name_label": "通訊錄名稱", + "renamed": "已重新命名通訊錄", + "rename_failed": "無法重新命名通訊錄", + "default": "預設", + "manage": "管理通訊錄", + "share": "分享通訊錄", + "new_contact_in_book": "在此通訊錄中新增聯絡人", + "delete": "刪除通訊錄", + "confirm_delete": "要刪除「{name}」嗎?此通訊錄中的所有聯絡人都會移除。", + "deleted": "通訊錄已刪除", + "delete_failed": "刪除通訊錄失敗" + }, + "detail": { + "emails": "電子郵件地址", + "phones": "電話號碼", + "organizations": "組織", + "addresses": "地址", + "notes": "備註", + "titles": "職稱與角色", + "online_services": "線上服務", + "anniversaries": "週年紀念日", + "personal_info": "個人資訊", + "languages": "語言", + "categories": "類別", + "related_contacts": "相關聯絡人", + "crypto_keys": "加密金鑰", + "cert_issuer": "簽發者", + "cert_expires": "到期日", + "cert_expired": "已到期", + "cert_fingerprint": "指紋", + "cert_algorithm": "演算法", + "import_to_smime": "匯入到 S/MIME", + "cert_already_imported": "已匯入至 S/MIME", + "cert_imported": "憑證已匯入 S/MIME 憑證庫", + "cert_import_failed": "匯入憑證失敗", + "no_contact_selected": "選取一位聯絡人以檢視詳細資料", + "compose_email": "撰寫郵件", + "copy_email": "複製電子郵件地址", + "copy_phone": "複製電話號碼", + "copy_url": "複製 URL", + "copied": "已複製到剪貼簿", + "copy_failed": "無法複製到剪貼簿", + "created": "已建立", + "updated": "上次更新", + "timezone": "時區", + "anniversary_birth": "生日", + "anniversary_death": "已故", + "anniversary_wedding": "週年紀念日", + "anniversary_other": "其他", + "personal_expertise": "專業知識", + "personal_hobby": "嗜好", + "personal_interest": "興趣", + "personal_other": "其他", + "gender": "性別", + "gender_masculine": "男性", + "gender_feminine": "女性", + "gender_other": "其他", + "gender_none": "不適用", + "gender_unknown": "未知", + "calendar": "行事曆", + "calendar_uri": "行事曆 URL", + "scheduling_uri": "排程 URL", + "freebusy_uri": "空閒/忙碌 URL", + "section_contact": "聯絡資訊", + "section_work": "工作", + "section_personal": "個人", + "email_default_label": "電子郵件", + "phone_default_label": "電話", + "address_default_label": "地址", + "online_service_default_label": "線上", + "organization_label": "組織", + "title_label": "職稱", + "role_label": "角色", + "language_label": "語言", + "related_default_label": "相關聯絡人", + "more_actions": "更多動作", + "age_years": "{count} 歲", + "years_since": "{count} 年" + }, + "activity": { + "recent_emails": "最近的郵件", + "upcoming_events": "即將開始的活動", + "no_emails": "最近沒有郵件", + "no_events": "沒有即將開始的活動", + "no_subject": "(無主題)", + "no_title": "(無標題)", + "load_failed": "無法載入", + "unknown_sender": "未知寄件者", + "all_day": "全天" + }, + "form": { + "create_title": "新聯絡人", + "edit_title": "編輯聯絡人", + "section_address_book": "通訊錄", + "select_address_book": "選擇通訊錄…", + "section_identity": "姓名與身分", + "contact_type": "聯絡人類型", + "type_person": "個人", + "type_organization": "組織", + "section_work": "工作與組織", + "prefix": "稱謂", + "prefix_placeholder": "博士、先生、女士", + "given_name": "名", + "middle_name": "中間名", + "surname": "姓", + "suffix": "後綴", + "suffix_placeholder": "Jr.、Sr.、III", + "nickname": "暱稱", + "nickname_placeholder": "暱稱", + "email": "電子郵件地址", + "email_placeholder": "email@example.com", + "phone": "電話", + "phone_placeholder": "+1 234 567 890", + "phone_type": "類型", + "phone_voice": "語音電話", + "phone_cell": "行動電話", + "phone_fax": "傳真", + "phone_pager": "呼叫器", + "phone_video": "視訊", + "phone_text": "簡訊", + "organization": "組織", + "organization_placeholder": "公司名稱", + "department": "部門", + "department_placeholder": "部門", + "job_title": "職稱", + "job_title_placeholder": "例如,軟體工程師", + "role": "角色", + "role_placeholder": "例如,團隊負責人", + "addresses": "地址", + "add_address": "新增地址", + "street": "街道", + "city": "城市", + "region": "州/地區", + "postcode": "郵遞區號", + "country": "國家", + "online_services": "線上服務", + "add_online_service": "新增線上服務", + "url_placeholder": "https://...", + "service_placeholder": "服務", + "anniversaries": "週年紀念日", + "add_anniversary": "新增日期", + "anniversary_birth": "生日", + "anniversary_wedding": "週年紀念日", + "anniversary_death": "忌日", + "anniversary_other": "其他", + "personal_info": "個人資訊", + "add_personal_info": "新增項目", + "personal_info_placeholder": "例如,攝影", + "personal_expertise": "專業知識", + "personal_hobby": "嗜好", + "personal_interest": "興趣", + "personal_other": "其他", + "level": "等級", + "level_high": "高", + "level_medium": "中", + "level_low": "低", + "categories": "類別", + "categories_placeholder": "例如,家人、朋友、同事", + "categories_hint": "輸入搜尋或新增類別", + "category_add": "新增", + "note": "備註", + "note_placeholder": "新增備註…", + "gender": "性別", + "gender_sex": "性別", + "gender_male": "男性", + "gender_female": "女性", + "gender_other": "其他", + "gender_none": "不適用", + "gender_unknown": "未知", + "gender_identity": "性別認同", + "gender_identity_placeholder": "性別認同…", + "calendar": "行事曆", + "calendar_uri": "行事曆 URL", + "scheduling_uri": "排程 URL", + "freebusy_uri": "空閒/忙碌 URL", + "context_work": "工作", + "context_private": "個人", + "add_email": "新增電子郵件地址", + "add_phone": "新增電話", + "save": "儲存", + "cancel": "取消", + "creating": "正在建立…", + "updating": "正在更新…", + "name_required": "請輸入名、姓或組織名稱", + "email_invalid": "請輸入有效的電子郵件地址", + "email_error_inline": "電子郵件地址格式無效", + "save_failed": "儲存聯絡人失敗", + "delete": "刪除", + "upload_photo": "上傳照片", + "remove_photo": "移除照片", + "photo_hint": "JPG 或 PNG,最大 10 MB。圖片會自動調整大小。", + "photo_too_large": "圖片太大(上限 10 MB)", + "photo_invalid": "圖片檔案無效", + "change_photo": "變更" + }, + "groups": { + "create": "新增群組", + "edit": "編輯群組", + "empty": "尚無群組", + "delete_confirm_title": "刪除群組", + "delete_confirm": "您確定要刪除該群組嗎?", + "name_label": "群組名稱", + "name_placeholder": "例如,團隊、家庭", + "name_required": "群組名稱為必填欄位", + "save_failed": "儲存群組失敗", + "members_label": "成員", + "search_members": "搜尋要新增的聯絡人…", + "no_members": "該群組中沒有成員", + "member_count": "{count, plural, =0 {無成員} one {1 位成員} other {# 位成員}}", + "send_email": "傳送郵件給群組", + "send_email_to": "收件者", + "send_email_cc": "副本", + "send_email_bcc": "密件副本", + "no_member_emails": "此群組沒有具有電子郵件地址的成員。" + }, + "import": { + "title": "匯入聯絡人", + "drop_hint": "點擊以選取 vCard 檔案", + "file_types": ".vcf 或 .vcard 檔案", + "no_contacts": "檔案中找不到聯絡人", + "parse_error": "無法解析 vCard 檔案", + "found": "{count, plural, one {找到 1 位聯絡人} other {找到 # 位聯絡人}}", + "duplicate": "重複", + "select_all": "全部選取", + "deselect_all": "全部取消選取", + "selected": "{count, plural, one {已選取 1 項} other {已選取 # 項}}", + "import_button": "匯入", + "importing": "正在匯入…", + "success": "{count, plural, one {已匯入 1 位聯絡人} other {已匯入 # 位聯絡人}}", + "failed": "匯入失敗", + "close": "關閉", + "file_too_large": "檔案太大(最大 5 MB)" + }, + "export": { + "title": "匯出聯絡人", + "success": "{count, plural, one {已匯出 1 位聯絡人} other {已匯出 # 位聯絡人}}" + }, + "bulk": { + "selected": "{count, plural, one {已選取 1 項} other {已選取 # 項}}", + "select_all": "全部選取", + "delete": "刪除", + "delete_confirm_title": "刪除聯絡人", + "delete_confirm": "刪除{count, plural, one {1 位聯絡人} other {# 位聯絡人}}?", + "deleted": "{count, plural, one {已刪除 1 位聯絡人} other {已刪除 # 位聯絡人}}", + "add_to_group": "新增至群組", + "choose_group": "選擇群組", + "adding_contacts": "正在新增{count, plural, one {1 位聯絡人} other {# 位聯絡人}}", + "added_to_group": "聯絡人已新增至群組", + "export": "匯出", + "clear": "清除選取" + }, + "toast": { + "created": "已建立聯絡人", + "updated": "聯絡人已更新", + "deleted": "聯絡人已刪除", + "error_create": "建立聯絡人失敗", + "error_update": "無法更新聯絡人", + "error_delete": "刪除聯絡人失敗" + }, + "context_menu": { + "open": "開啟", + "edit": "編輯", + "send_email": "傳送郵件", + "add_to_group": "新增至群組", + "export_vcard": "匯出為 vCard", + "delete": "刪除", + "call": "撥打電話", + "duplicate": "建立副本", + "print": "列印" + }, + "filters": { + "toggle": "篩選", + "select": "選取", + "clear": "清除", + "close": "關閉", + "title": "進階篩選", + "organization": "公司", + "organization_placeholder": "例如 Acme", + "job_title": "職稱", + "job_title_placeholder": "例如 設計師", + "location": "所在地", + "location_placeholder": "城市或國家", + "email_domain": "電子郵件網域", + "email_domain_placeholder": "example.com", + "birthday_month": "生日月份", + "any_month": "任何月份", + "has_email": "有電子郵件地址", + "has_phone": "有電話", + "has_photo": "有照片" + } + }, + "calendar": { + "title": "行事曆", + "back_to_email": "回到郵件", + "back_to_month": "回到月檢視", + "my_calendars": "行事曆", + "birthday_calendar": "生日", + "mini_calendar_change": "點選更改月份", + "views": { + "month": "月", + "week": "週", + "day": "天", + "agenda": "議程", + "today": "今天", + "month_hint": "月 (m)", + "week_hint": "週 (w)", + "day_hint": "天 (d)", + "agenda_hint": "議程 (a)", + "tasks": "任務", + "tasks_hint": "任務 (k)" + }, + "events": { + "create": "建立活動", + "edit": "編輯活動", + "delete": "刪除活動", + "details": "活動詳細資料", + "no_events": "沒有活動", + "all_day": "全天", + "more": "另有 {count} 個", + "no_title": "(無標題)", + "resize": "調整活動大小", + "duplicate": "建立副本", + "today_header": "今天", + "tomorrow_header": "明天", + "export_ics": "匯出為 .ics", + "copy_title": "複製標題", + "copy_link": "複製會議連結", + "new_event": "新增活動", + "new_all_day_event": "新增全天活動", + "new_task": "新增任務", + "go_to_today": "前往今天" + }, + "detail": { + "add_note": "新增備註…", + "save_note": "儲存", + "note_saved": "已新增備註", + "open_link": "開啟連結", + "meeting_link": "會議連結", + "tentative": "暫定", + "cancelled": "已取消", + "delete_confirm": "刪除這個活動嗎?" + }, + "form": { + "title": "標題", + "description": "描述", + "location": "地點", + "meeting_link": "會議連結", + "start_date": "開始日期", + "end_date": "結束日期", + "start_time": "開始時間", + "end_time": "結束時間", + "all_day_event": "全天活動", + "calendar_select": "行事曆", + "save": "儲存", + "cancel": "取消", + "delete_confirm": "您確定要刪除此活動嗎?", + "color": "顏色" + }, + "participants": { + "title": "參與者", + "add": "新增參與者", + "organizer": "主辦人", + "attendee": "與會者", + "accepted": "已接受", + "declined": "已拒絕", + "tentative": "暫定", + "needs_action": "待處理", + "remove": "移除", + "edit": "編輯", + "email_placeholder": "新增電子郵件地址或搜尋聯絡人", + "send_invitations": "向參與者傳送邀請", + "status_summary": "{accepted} 已接受,{pending} 待處理", + "invited_by": "來自 {name} 的邀請", + "respond_below": "使用下方按鈕回覆", + "rsvp_label": "您的回覆", + "cancel_notification": "參與者將收到取消通知", + "you_organizer": "您是主辦人", + "you_attendee": "您是與會者", + "no_participants": "沒有參與者", + "count": "{count, plural, one {# 位參與者} other {# 位參與者}}" + }, + "recurrence": { + "title": "重複", + "none": "不重複", + "daily": "每天", + "weekly": "每週", + "monthly": "每月", + "yearly": "每年", + "every_n_days": "每 {count} 天", + "every_n_weeks": "每 {count} 週", + "every_n_months": "每 {count} 個月", + "until": "直到", + "occurrences": "{count} 次", + "custom": "自訂…", + "edit_custom": "編輯自訂重複規則", + "every_n_years": "每 {count} 年", + "on_days": "{days}", + "on_day_n": "{day}日", + "on_the_nth": "{nth}{day}", + "in_month": "{month}", + "nth_1": "第一個", + "nth_2": "第二個", + "nth_3": "第三個", + "nth_4": "第四個", + "nth_last": "最後一個", + "editor_freq_day": "天", + "editor_freq_week": "週", + "editor_freq_month": "月", + "editor_freq_year": "年", + "editor_repeats_on": "重複於", + "editor_every": "每", + "editor_unit_days": "天", + "editor_unit_weeks": "週", + "editor_unit_months": "個月", + "editor_unit_years": "年", + "editor_on_day": "指定日期", + "editor_on_the": "指定星期", + "editor_in": "月份", + "editor_ends": "結束", + "editor_never": "永不", + "editor_ends_on": "於", + "editor_ends_after": "經過", + "editor_occurrences": "次後" + }, + "recurrence_scope": { + "edit_title": "編輯重複活動", + "delete_title": "刪除重複活動", + "description": "這是重複活動。您要修改哪些活動?", + "this_event": "僅限本次活動", + "this_and_future": "本次及後續活動", + "all_events": "所有活動", + "cancel": "取消", + "save": "儲存", + "delete": "刪除" + }, + "alerts": { + "title": "提醒", + "none": "無提醒", + "at_time": "活動舉行時", + "minutes_before": "{count, plural, one {提前 # 分鐘} other {提前 # 分鐘}}", + "hours_before": "{count, plural, one {提前 # 小時} other {提前 # 小時}}", + "days_before": "{count, plural, one {提前 # 天} other {提前 # 天}}", + "weeks_before": "{count, plural, one {提前 # 週} other {提前 # 週}}", + "unit_minutes_before": "分鐘前", + "unit_hours_before": "小時前", + "unit_days_before": "天前", + "unit_weeks_before": "週前", + "add": "新增提醒", + "remove": "移除提醒", + "amount": "提醒數量", + "unit": "提醒單位" + }, + "settings": { + "title": "行事曆設定", + "default_view": "預設檢視", + "week_starts_on": "一週開始於", + "time_format": "時間格式", + "default_calendar": "預設行事曆", + "default_reminder": "預設提醒", + "time_format_12h": "12 小時制", + "time_format_24h": "24 小時制", + "notifications_enabled": "活動通知", + "notifications_enabled_desc": "顯示即將開始的行事曆活動提醒", + "notification_sound": "通知聲音", + "notification_sound_desc": "播放行事曆提醒聲音", + "invitation_parsing": "解析郵件邀請", + "invitation_parsing_desc": "偵測郵件附件中的行事曆邀請,並顯示行事曆動作", + "show_time_in_month_view": "在月檢視中顯示時間", + "show_time_in_month_view_desc": "在月檢視中顯示活動時間。小螢幕會顯示完整活動項目,而不只是圓點。", + "show_week_numbers": "顯示週數", + "show_week_numbers_desc": "在迷你行事曆中顯示週數", + "enable_tasks": "啟用任務", + "enable_tasks_desc": "在行事曆中顯示任務檢視以管理待辦事項", + "show_tasks_on_calendar": "在行事曆上顯示任務", + "show_tasks_on_calendar_desc": "在行事曆的日/週檢視中顯示任務標籤", + "hover_preview": "活動游標暫留預覽", + "hover_preview_desc": "游標移至行事曆活動上方時顯示詳細資料浮動視窗", + "hover_preview_instant": "立即", + "hover_preview_delay_500ms": "延遲 0.5 秒", + "hover_preview_delay_1s": "延遲 1 秒", + "hover_preview_delay_2s": "延遲 2 秒", + "hover_preview_off": "停用", + "show_birthday_calendar": "聯絡人生日行事曆", + "show_birthday_calendar_desc": "顯示包含聯絡人生日的虛擬行事曆" + }, + "days": { + "monday": "週一", + "tuesday": "週二", + "wednesday": "週三", + "thursday": "週四", + "friday": "週五", + "saturday": "週六", + "sunday": "週日", + "mon": "週一", + "tue": "週二", + "wed": "週三", + "thu": "週四", + "fri": "週五", + "sat": "週六", + "sun": "週日" + }, + "months": { + "jan": "1月", + "feb": "2月", + "mar": "3月", + "apr": "4月", + "may": "5月", + "jun": "6月", + "jul": "7月", + "aug": "8月", + "sep": "9月", + "oct": "10月", + "nov": "11月", + "dec": "12月", + "far": "Farvardin", + "ord": "Ordibehesht", + "kho": "Khordad", + "tir": "Tir", + "mor": "Mordad", + "sha": "Shahrivar", + "meh": "Mehr", + "aba": "Aban", + "aza": "Azar", + "dey": "Dey", + "bah": "Bahman", + "esf": "Esfand" + }, + "notifications": { + "event_created": "活動已建立", + "event_updated": "活動已更新", + "event_deleted": "活動已刪除", + "calendar_created": "已建立行事曆", + "calendar_deleted": "行事曆已刪除", + "event_move_error": "無法移動活動", + "event_resize_error": "無法調整活動大小", + "alert_title": "即將舉行的活動", + "alert_now": "現在開始", + "alert_in_minutes": "{count} 分鐘後", + "invitation_sent": "已傳送邀請", + "rsvp_updated": "回覆已更新", + "rsvp_error": "無法更新回覆", + "event_duplicated": "已建立活動副本", + "event_error": "無法儲存活動", + "task_due": "任務到期", + "event_exported": "活動已匯出", + "title_copied": "標題已複製", + "link_copied": "連結已複製" + }, + "status": { + "loading_calendars": "正在載入行事曆…", + "loading_events": "正在載入活動…" + }, + "quick_create": { + "placeholder": "新活動標題", + "aria_label": "快速建立活動" + }, + "nav_prev": "上一項", + "nav_next": "下一項", + "nav_open_menu": "開啟選單", + "import": { + "title": "匯入行事曆", + "tab_file": "檔案", + "tab_url": "URL", + "select_file": "選取 .ics 檔案", + "drop_file": "或將檔案拖放到這裡", + "supported_formats": "支援 iCalendar (.ics) 檔案", + "url_description": "輸入外部 iCalendar(.ics)資料來源的 URL,以匯入活動。", + "url_placeholder": "https://example.com/calendar.ics", + "url_hint": "支援 CalDAV 與 iCalendar(.ics)URL", + "fetch": "取得", + "invalid_url": "請輸入有效的 URL", + "url_fetch_failed": "無法從 URL 取得行事曆", + "parsing": "正在解析行事曆檔案…", + "parsed_events": "找到 {count} 個活動", + "no_events": "檔案中找不到活動", + "select_all": "全部選取", + "deselect_all": "全部取消選取", + "target_calendar": "匯入到行事曆", + "import_button": "匯入選取項目", + "importing": "正在匯入活動…", + "success": "{count} 個活動已成功匯入", + "error": "匯入行事曆失敗", + "file_too_large": "檔案超過 10 MB 上限", + "invalid_format": "行事曆檔案格式無效" + }, + "webcal_action": { + "title": "開啟行事曆連結", + "description": "您要如何使用「{name}」?", + "import_title": "匯入一次", + "import_description": "立即取得活動,並複製到您的其中一個行事曆。", + "subscribe_title": "訂閱", + "subscribe_description": "將此行事曆保留為獨立行事曆並自動同步。", + "cancel": "取消" + }, + "management": { + "title": "行事曆管理", + "description": "建立、重新命名與自訂您的行事曆。在側邊欄的行事曆上按一下滑鼠右鍵,可快速變更顏色。", + "name": "名稱", + "name_placeholder": "行事曆名稱", + "color": "顏色", + "change_color": "變更顏色", + "random_color": "隨機新顏色", + "add_calendar": "新增行事曆", + "edit": "編輯", + "delete": "刪除", + "save": "儲存", + "create": "建立", + "cancel": "取消", + "default": "預設", + "confirm_delete": "要刪除「{name}」嗎?此行事曆中的所有活動都會移除。", + "confirm_clear": "要清除「{name}」中的所有活動嗎?此動作無法復原。", + "set_default": "設為預設", + "default_updated": "預設行事曆已更新", + "error_default": "無法設定預設行事曆", + "clear_events": "清除活動", + "events_cleared": "{count} 個活動已清除", + "error_clear": "無法清除行事曆活動", + "calendar_created": "已建立行事曆", + "calendar_updated": "行事曆已更新", + "calendar_deleted": "行事曆已刪除", + "color_updated": "行事曆顏色已更新", + "error_create": "建立行事曆失敗", + "error_update": "更新行事曆失敗", + "error_delete": "刪除行事曆失敗", + "caldav_url": "CalDAV URL", + "copy_url": "複製 CalDAV URL", + "url_copied": "CalDAV URL 已複製到剪貼簿", + "share": "分享行事曆", + "new_event_in_calendar": "在此行事曆中新增活動", + "kind": "內容", + "kind_events": "活動", + "kind_tasks": "任務", + "kind_both": "活動與任務", + "kind_hint": "決定透過 CalDAV 同步時,哪些應用程式可看到此行事曆。此設定之後無法變更。" + }, + "subscription": { + "title": "iCal 訂閱", + "section_title": "iCal 訂閱", + "description": "訂閱外部 iCalendar 資料來源。活動會自動同步到獨立的行事曆。支援 https:// 與 webcal:// URL。", + "url_label": "行事曆 URL", + "url_placeholder": "https://example.com/calendar.ics 或 webcal://...", + "name_label": "行事曆名稱", + "name_placeholder": "例如國定假日", + "color_label": "顏色", + "refresh_interval": "重新整理間隔", + "interval_15": "每 15 分鐘", + "interval_30": "每 30 分鐘", + "interval_60": "每小時", + "interval_360": "每 6 小時", + "interval_1440": "每天", + "subscribe": "訂閱", + "subscribing": "正在訂閱…", + "save": "儲存變更", + "saving": "正在儲存…", + "edit": "編輯", + "edit_title": "編輯訂閱", + "updated": "已更新「{name}」", + "update_error": "更新訂閱失敗", + "invalid_url": "請輸入有效的 URL", + "success": "已訂閱「{name}」", + "error": "新增訂閱失敗", + "refresh": "立即重新整理", + "refresh_success": "訂閱已重新整理", + "refresh_error": "重新整理訂閱失敗", + "unsubscribe": "取消訂閱", + "confirm_delete": "要取消訂閱「{name}」嗎?此行事曆及其所有活動都會移除。", + "deleted": "已移除訂閱", + "delete_error": "無法移除訂閱", + "last_refreshed": "最後更新:{time}" + }, + "tasks": { + "label": "任務", + "no_tasks": "沒有任務", + "no_title": "(無標題)", + "mark_complete": "標示為完成", + "mark_incomplete": "標示為未完成", + "filter_all": "全部", + "filter_pending": "待處理", + "filter_completed": "已完成", + "filter_overdue": "逾期", + "show_completed": "顯示已完成", + "create": "新增任務", + "edit": "編輯任務", + "title_placeholder": "任務標題", + "description_placeholder": "新增描述…", + "due_date": "到期日", + "include_time": "包含時間", + "priority": "優先順序", + "priority_none": "無", + "priority_high": "高", + "priority_medium": "中", + "priority_low": "低", + "progress": "狀態", + "progress_needs_action": "待處理", + "progress_in_process": "進行中", + "progress_completed": "已完成", + "progress_cancelled": "已取消", + "calendar": "行事曆", + "alert": "提醒", + "alert_none": "無", + "alert_at_time": "在到期日時", + "alert_5min": "5 分鐘前", + "alert_15min": "15 分鐘前", + "alert_30min": "30 分鐘前", + "alert_1hr": "1 小時前", + "alert_1day": "1 天前", + "delete": "刪除", + "cancel": "取消", + "save": "儲存", + "quick_add_placeholder": "新增任務…", + "due_today": "今天", + "due_tomorrow": "明天", + "overdue": "逾期" + } + }, + "sharing": { + "title": "分享「{name}」", + "description": "授予此伺服器上的其他使用者或群組存取權。變更會立即生效。", + "no_shares": "尚未與任何人分享。", + "add_person": "新增使用者或群組", + "search_placeholder": "依姓名或電子郵件地址搜尋…", + "loading_principals": "正在載入使用者…", + "no_principals": "找不到其他使用者或群組。", + "no_match": "找不到相符項目。", + "remove": "移除存取權", + "group": "群組", + "share_added": "已授予存取權", + "share_updated": "已更新存取權", + "share_removed": "已移除存取權", + "share_failed": "無法更新分享設定", + "preset": { + "freeBusy": "僅限空閒/忙碌", + "read": "唯讀", + "readWrite": "讀取與寫入", + "manager": "管理員", + "custom": "自訂" + } + }, + "advanced_search": { + "title": "進階搜尋", + "from": "寄件者", + "from_placeholder": "寄件者電子郵件地址或姓名", + "to": "收件者", + "to_placeholder": "收件者電子郵件地址或姓名", + "subject": "主題", + "subject_placeholder": "主題包含…", + "body": "內文", + "body_placeholder": "內文包含…", + "folder": "信件匣", + "all_folders": "所有信件匣", + "has_attachment": "附件", + "date_after": "後", + "date_before": "前", + "starred": "已加星號", + "unread": "未讀", + "read": "已讀", + "yes": "是", + "no": "否", + "clear": "清除", + "clear_all": "全部清除", + "filters_active": "{count} 個篩選條件", + "filters_active_plural": "{count} 個篩選條件", + "toggle_filters": "更多", + "search_hint": "使用進階篩選條件進行精確搜尋", + "advanced_filters_tooltip": "進階搜尋篩選條件", + "results_found": "{count, plural, =0 {找不到結果} one {找到 # 個結果} other {找到 # 個結果}}", + "results_found_more": "找到 {count}+ 個結果", + "suggestions_recent": "最近搜尋", + "suggestions_people": "聯絡人", + "suggestions_from": "搜尋來自 {address} 的郵件", + "suggestions_to": "搜尋寄給 {address} 的郵件", + "suggestions_remove_recent": "從最近搜尋中移除" + }, + "welcome": { + "title": "歡迎使用您的信件匣", + "tip_compose": "按 c 撰寫新郵件", + "tip_shortcuts": "按 ? 檢視所有鍵盤快速鍵", + "tip_sidebar": "可在側邊欄選單找到行事曆、聯絡人與設定", + "tip_settings": "在「設定」中自訂您的使用體驗", + "got_it": "了解", + "settings": "設定", + "dismiss": "關閉", + "start_tour": "開始功能導覽" + }, + "demo_welcome": { + "title": "歡迎使用 Bulwark Mail", + "description": "直接在瀏覽器中探索功能完整的網頁郵件用戶端。所有資料都保留在您的裝置上,請自由測試各項功能。", + "feature_email": "閱讀與撰寫郵件", + "feature_organize": "標籤、星號與信件匣", + "feature_shortcuts": "鍵盤快速鍵", + "feature_privacy": "100% 私密示範", + "hint": "點擊左側任一郵件即可開始,或進行下方的功能導覽。" + }, + "files": { + "open_in_new_tab": "在新分頁開啟", + "title": "檔案", + "search_placeholder": "搜尋檔案…", + "empty_state_title": "尚無檔案", + "empty_state_description": "上傳檔案或建立資料夾以開始", + "upload": "上傳", + "upload_files": "上傳檔案", + "new_folder": "新增資料夾", + "new_folder_name": "資料夾名稱", + "rename": "重新命名", + "rename_title": "重新命名", + "new_name": "新名稱", + "delete": "刪除", + "delete_confirm_title": "刪除項目", + "delete_confirm_message": "您確定要刪除「{name}」嗎?此動作無法復原。", + "download": "下載", + "name": "名稱", + "size": "大小", + "modified": "修改日期", + "type": "類型", + "folder": "資料夾", + "file": "檔案", + "parent_directory": "上層目錄", + "breadcrumb_root": "首頁", + "other_accounts": "其他帳號", + "no_accounts": "沒有已連線的帳號。", + "drop_files_here": "將檔案或資料夾拖放到這裡進行上傳", + "uploading": "正在上傳…", + "upload_success": "{count, plural, one {已上傳 1 個檔案} other {已上傳 # 個檔案}}", + "upload_error": "上傳檔案失敗", + "create_folder_success": "資料夾已建立", + "create_folder_error": "建立資料夾失敗", + "delete_success": "刪除成功", + "delete_error": "刪除失敗", + "rename_success": "重新命名成功", + "rename_error": "重新命名失敗", + "download_error": "下載失敗", + "not_available": "此伺服器無法使用檔案儲存功能", + "cancel": "取消", + "create": "建立", + "save": "儲存", + "no_results": "找不到符合搜尋條件的檔案", + "batch_delete_confirm_message": "您確定要刪除{count, plural, one {1 個項目} other {# 個項目}}嗎?此動作無法復原。", + "batch_delete_success": "{count, plural, one {已刪除 1 個項目} other {已刪除 # 個項目}}", + "grid_view": "網格檢視", + "list_view": "清單檢視", + "details": "詳細資料", + "path": "路徑", + "preview": "預覽", + "preview_error": "載入預覽失敗", + "cut": "剪下", + "copy": "複製", + "paste": "貼上", + "move_success": "{count, plural, one {已移動 1 個項目} other {已移動 # 個項目}}", + "move_error": "移動失敗", + "paste_success": "貼上成功", + "paste_error": "貼上失敗", + "new_text_file": "新增文字檔案", + "file_name": "檔名", + "retry": "重試", + "refresh": "重新整理", + "toggle_favorite": "切換我的最愛", + "duplicate": "建立副本", + "duplicate_success": "已成功建立副本", + "duplicate_error": "無法建立副本", + "share": "分享", + "shared": "已分享", + "shared_with_me": "與我共用", + "shared_by": "由 {name} 分享", + "create_file_success": "檔案已建立", + "create_file_error": "建立檔案失敗", + "favorites": "我的最愛", + "recent": "最近", + "properties": "屬性", + "open_folder": "開啟資料夾", + "upload_folder": "上傳資料夾", + "file_too_large": "「{name}」超過檔案大小上限({max})", + "undo": "復原", + "undo_success": "已復原動作", + "undo_error": "無法復原", + "toolbar": "檔案動作", + "open_folder_tree": "開啟資料夾樹", + "file_list": "檔案與資料夾", + "context_menu": "動作", + "settings_title": "檔案設定", + "settings_display": "顯示", + "settings_default_view": "預設檢視", + "settings_default_view_desc": "選擇網格或清單版面配置", + "settings_default_sort": "預設排序", + "settings_default_sort_desc": "選擇檔案的預設排序規則", + "settings_sort_direction": "排序方式", + "settings_sort_direction_desc": "選擇遞增或遞減順序", + "settings_ascending": "遞增", + "settings_descending": "遞減", + "settings_icons": "圖示", + "settings_show_icons": "顯示檔案圖示", + "settings_show_icons_desc": "在檔案和資料夾旁邊顯示圖示", + "settings_colored_icons": "彩色圖示", + "settings_colored_icons_desc": "使用彩色圖示取代單色圖示", + "settings_show_thumbnails": "顯示縮圖", + "settings_show_thumbnails_desc": "圖片檔案顯示預覽,而不是圖示", + "settings_behavior": "行為", + "settings_show_hidden": "顯示隱藏檔案", + "settings_show_hidden_desc": "顯示名稱以句點開頭的檔案與資料夾", + "settings_folder_layout": "資料夾導覽", + "settings_folder_layout_desc": "選擇資料夾與檔案並列顯示,或在側邊欄以樹狀顯示", + "settings_folder_layout_inline": "內嵌", + "settings_folder_layout_sidebar": "側邊欄", + "disabled_title": "檔案功能已被您的管理員停用", + "disabled_description": "透過 WebDAV 上傳大檔案可能導致 Stalwart/RocksDB 不穩定,包括記憶體不足當機及無法回收的磁碟空間。刪除檔案後,blob 儲存空間可能不會立即清除。本功能不建議用於正式環境。", + "stability_warning": "上傳大檔案可能導致伺服器不穩定。刪除檔案後,儲存空間可能不會立即清除。請謹慎使用。", + "migration_title": "正在更新您的檔案…", + "migration_description": "正在將資料夾與檔案整理成正確結構。這只會執行一次。" + }, + "smime": { + "your_certificates": "您的憑證", + "your_certificates_desc": "匯入與管理用於郵件簽章與加密的 S/MIME 憑證", + "recipient_certificates": "收件者憑證", + "recipient_certificates_desc": "收件者的公開憑證,用於加密寄給他們的郵件", + "identity_bindings": "寄件身分金鑰繫結", + "identity_bindings_desc": "將 S/MIME 憑證繫結至您的寄件身分", + "defaults_title": "預設值", + "defaults_desc": "設定預設的簽章與加密行為", + "import_pkcs12": "匯入 PKCS#12(.p12/.pfx)", + "import_public_cert": "匯入憑證", + "no_certificates": "尚未匯入憑證", + "no_recipient_certs": "無收件者憑證", + "expires": "到期日", + "expired": "已到期", + "bound_to": "繫結至", + "no_key_bound": "無", + "lock": "鎖定金鑰", + "unlock": "解鎖金鑰", + "details": "檢視詳細資料", + "delete": "刪除", + "encrypt_by_default": "預設加密", + "encrypt_by_default_desc": "當所有收件者都有憑證時自動加密郵件", + "remember_unlocked": "記住已解鎖的金鑰", + "remember_unlocked_desc": "在目前的瀏覽器工作階段保持金鑰解鎖", + "sign_default_for": "為以下項目預設簽章", + "enter_p12_passphrase": "輸入 PKCS#12 密碼片語", + "p12_passphrase_desc": "輸入保護此憑證檔案的密碼片語", + "enter_storage_passphrase": "設定儲存密碼片語", + "storage_passphrase_desc": "選擇一組密碼片語,保護此金鑰在瀏覽器中的靜態儲存", + "next": "下一步", + "import": "匯入", + "unlock_key": "解鎖金鑰", + "unlock_key_desc": "輸入儲存密碼片語,以解鎖此金鑰進行簽章或解密", + "passphrase_placeholder": "輸入密碼片語", + "confirm_passphrase_placeholder": "確認密碼片語", + "passphrase_mismatch": "兩次輸入的密碼片語不相符", + "cancel": "取消", + "processing": "處理中…", + "close": "關閉", + "certificate_details": "憑證詳細資料", + "cert_subject": "主體", + "cert_issuer": "簽發者", + "cert_email": "電子郵件地址", + "cert_serial": "序號", + "cert_validity": "有效期限", + "cert_fingerprint": "指紋(SHA-256)", + "cert_algorithm": "演算法", + "cert_capabilities": "功能", + "cert_source": "來源", + "cert_expired": "該憑證已過期", + "cert_not_yet_valid": "該憑證尚未生效", + "cap_sign": "簽章", + "cap_encrypt": "加密", + "cap_none": "無", + "show_passphrase": "顯示密碼片語", + "hide_passphrase": "隱藏密碼片語", + "sign_toggle": "簽章", + "encrypt_toggle": "加密", + "missing_recipient_certs": "缺少以下憑證:{emails}", + "missing_sender_cert": "沒有憑證繫結至此寄件身分", + "status_encrypted_ok": "此郵件已加密", + "status_encrypted_no_key": "此郵件已加密,但找不到相符的金鑰", + "status_encrypted_failed": "無法解密此郵件", + "status_signed_valid": "簽章已驗證", + "status_signed_invalid": "簽章驗證失敗", + "status_signed_expired_cert": "使用已到期的憑證簽章", + "status_signed_self_signed": "簽章有效,但憑證為自我簽署(不受信任)", + "status_signed_mismatch": "簽章有效,但簽署者與寄件者不相符", + "status_unsupported": "不支援的 S/MIME 格式", + "auto_import_signer_certs": "自動匯入簽署者憑證", + "auto_import_signer_certs_desc": "自動儲存已驗證簽章郵件中的憑證,以供日後加密郵件。", + "export": "匯出", + "enter_export_passphrase": "設定匯出密碼片語", + "export_passphrase_desc": "選擇一組密碼片語以保護匯出的 PKCS#12 檔案", + "export_storage_desc": "輸入儲存密碼片語,以解密金鑰並匯出", + "incorrect_passphrase": "密碼片語不正確" + }, + "tour": { + "step_counter": "第 {current} 步,共 {total} 步", + "skip": "跳過導覽", + "back": "上一步", + "next": "下一步", + "finish": "完成", + "take_a_tour": "進行介面功能導覽", + "restart_title": "新手導覽", + "restart_desc": "重新進行介面的逐步功能導覽", + "restart_button": "重新開始導覽", + "show_on_new_devices_title": "在新裝置上顯示", + "show_on_new_devices_desc": "首次在新裝置登入時,重新顯示歡迎橫幅與功能導覽,即使您已在其他裝置完成", + "sidebar_title": "您的信件匣", + "sidebar_desc": "這裡是信件匣側邊欄。點擊任一信件匣即可檢視其中的郵件。您可以建立信件匣、在信件匣之間拖曳郵件,並快速查看未讀數量。", + "compose_title": "撰寫郵件", + "compose_desc": "點擊這裡即可撰寫新郵件。您可以新增收件者、附件,並使用富文字格式。", + "search_title": "搜尋郵件", + "search_desc": "依寄件者、主題或內容搜尋。點擊篩選圖示,可使用日期範圍、附件與已加星號等進階選項。", + "email_list_title": "郵件清單", + "email_list_desc": "郵件會顯示在這裡。點擊一封郵件即可在右側閱讀。使用核取方塊可選取多封郵件,再批次移動、刪除或加上標籤。", + "email_viewer_title": "閱讀區域", + "email_viewer_desc": "選取的郵件會在這裡開啟。使用工具列按鈕回覆、轉寄、封存或刪除。您也可以為郵件加上星號或彩色標籤。", + "keywords_title": "顏色標籤", + "keywords_desc": "使用彩色標籤整理郵件。將郵件拖曳到標籤即可加上標籤,或在郵件上按一下滑鼠右鍵來指派標籤。", + "calendar_title": "行事曆", + "calendar_desc": "切換至行事曆以管理活動。您可以建立活動、設定提醒,並檢視日、週或月版面。", + "contacts_title": "聯絡人", + "contacts_desc": "這裡是您的通訊錄。您可以匯入聯絡人、建立群組,並點擊任一聯絡人以檢視完整詳細資料。", + "settings_title": "設定", + "settings_desc": "在這裡自訂主題、介面密度、簽名檔、篩選規則、鍵盤快速鍵、行事曆預設值等各項設定。", + "shortcuts_title": "鍵盤快速鍵", + "shortcuts_desc": "進階使用者會喜歡這項功能。隨時按下 ? 即可檢視所有可用的快速鍵。您不需使用滑鼠,就能導覽、撰寫與管理郵件。", + "compose_open_title": "郵件編輯器", + "compose_open_desc": "這裡是郵件撰寫器。新增收件者、撰寫內文、附加檔案,並使用富文字格式。您也可以儲存草稿與使用範本。", + "calendar_view_title": "您的行事曆", + "calendar_view_desc": "這裡是包含範例活動的行事曆。您可以使用工具列切換日、週、月或議程檢視。", + "create_event_title": "建立活動", + "create_event_desc": "點擊此按鈕即可建立新的行事曆活動。您可以設定標題、日期、時間並新增參與者。", + "event_modal_title": "活動詳細資料", + "event_modal_desc": "這裡是活動表單。填寫標題、選擇日期與時間,並新增地點或參與者。完成後按下儲存,或關閉並繼續其他操作。", + "contacts_list_title": "聯絡人清單", + "contacts_list_desc": "這裡顯示您的聯絡人。點擊任一聯絡人即可在右側檢視完整詳細資料。您也可以建立聯絡人、匯入 vCard 或將聯絡人整理成群組。", + "settings_tabs_title": "設定選單", + "settings_tabs_desc": "這裡列出所有設定類別。您可以自訂外觀、管理寄件身分、設定郵件篩選規則、設定行事曆等。", + "files_title": "檔案儲存", + "files_desc": "檔案瀏覽器可讓您上傳、整理與分享檔案,就像內建在郵件中的個人雲端硬碟。", + "demo_banner_title": "示範控制", + "demo_banner_desc": "目前處於示範模式,所有資料都保留在瀏覽器中。隨時點擊「重設示範」即可用全新的範例資料重新開始。", + "quota_title": "儲存使用情況", + "quota_desc": "在這裡查看信箱的儲存空間使用量。使用的空間越多,圓形指示器就會填得越滿。" + }, + "unified_mailbox": { + "search_unavailable": "整合檢視中無法使用搜尋" + }, + "quote_header": { + "reply_line": "在 {date},{from} 寫道:", + "forwarded_separator": "---------- 轉寄郵件 ----------", + "from_label": "寄件者", + "date_label": "日期", + "subject_label": "主題" + }, + "pwa_install": { + "title": "安裝 {appName}", + "description": "安裝我們的應用程式,以便快速存取並支援離線使用。", + "not_now": "暫不", + "install": "安裝", + "dont_remind": "不再提醒", + "dismiss_aria": "關閉安裝提示" + }, + "deep_link": { + "message_not_found": "已無法使用此郵件。", + "thread_not_found": "已無法使用此對話串。", + "folder_not_found": "已無法使用此信件匣。", + "event_not_found": "已無法使用此活動。", + "file_not_found": "已無法使用此檔案。", + "account_unavailable": "請登入該帳號以開啟此連結。", + "copy_message": "複製郵件連結", + "copy_conversation": "複製對話串連結", + "copy_event": "複製活動連結", + "copied": "連結已複製", + "copy_failed": "無法複製連結" + } +} From 9fab1d1f4aaa5b0b3fb47e1f03263030a0d095a3 Mon Sep 17 00:00:00 2001 From: Kuan-Chieh Huang <7856561+kchuang1015@users.noreply.github.com> Date: Sat, 29 Aug 2026 11:44:40 +0800 Subject: [PATCH 2/3] fix(i18n): normalize Chinese proxy locale detection --- lib/__tests__/proxy-forwarded-headers.test.ts | 22 +++++++++++++++++++ proxy.ts | 22 +++++++++++++++++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/lib/__tests__/proxy-forwarded-headers.test.ts b/lib/__tests__/proxy-forwarded-headers.test.ts index 00a6385f1..c9d71210c 100644 --- a/lib/__tests__/proxy-forwarded-headers.test.ts +++ b/lib/__tests__/proxy-forwarded-headers.test.ts @@ -28,10 +28,12 @@ vi.mock('@/lib/admin/csp-frame-origins', () => ({ getEnabledPluginFrameOrigins: // forwards the FULL request header set, tagged with the resolved locale. // With localePrefix "always" it redirects to the prefixed path instead. let intlMode: 'rewrite' | 'redirect' = 'rewrite'; +let receivedAcceptLanguage: string | null = null; vi.mock('next-intl/middleware', async () => { const { NextResponse } = await import('next/server'); return { default: () => (request: Request) => { + receivedAcceptLanguage = request.headers.get('accept-language'); const url = new URL(request.url); url.pathname = `/en${url.pathname}`; if (intlMode === 'redirect') return NextResponse.redirect(url); @@ -69,6 +71,7 @@ function nonceFromCsp(response: Response): string | undefined { beforeEach(() => { vi.clearAllMocks(); intlMode = 'rewrite'; + receivedAcceptLanguage = null; }); describe('proxy forwards the request headers it does not own (#919)', () => { @@ -123,3 +126,22 @@ describe('proxy forwards the request headers it does not own (#919)', () => { expect(response.headers.get('x-middleware-request-x-nonce')).toBeNull(); }); }); + +describe('proxy normalizes Chinese Accept-Language before next-intl matching', () => { + it.each([ + ['zh-HK,zh;q=0.9', 'zh-TW'], + ['zh-MO,zh;q=0.9', 'zh-TW'], + ['zh-Hant-HK,zh-Hant;q=0.9', 'zh-TW'], + ['zh-Hans-TW,zh-Hans;q=0.9', 'zh'], + ['zh-CN,zh;q=0.9', 'zh'], + ['fr-CA,zh-HK;q=0.9', 'fr-CA,zh-HK;q=0.9'], + ])('passes %s to next-intl as %s', async (acceptLanguage, expected) => { + await proxy( + new NextRequest('http://localhost:3000/', { + headers: { 'accept-language': acceptLanguage, cookie: 'jmap_session_0=abc' }, + }), + ); + + expect(receivedAcceptLanguage).toBe(expected); + }); +}); diff --git a/proxy.ts b/proxy.ts index 3dc1eb754..d9cd5ddc4 100644 --- a/proxy.ts +++ b/proxy.ts @@ -1,6 +1,7 @@ -import { type NextRequest, NextResponse } from "next/server"; +import { NextRequest, NextResponse } from "next/server"; import createIntlMiddleware from "next-intl/middleware"; import { routing } from "./i18n/routing"; +import { localeFromAcceptLanguage } from "./i18n/locale-matcher"; import { getEnabledPluginFrameOrigins } from "./lib/admin/csp-frame-origins"; import { APP_FRAME_ORIGINS_COOKIE, @@ -11,6 +12,23 @@ import { detectSetupState } from "./lib/setup/state"; const intlMiddleware = createIntlMiddleware(routing); +/** + * next-intl uses best-fit locale matching, which can rank `zh` ahead of + * `zh-TW` for regional Traditional Chinese tags such as `zh-HK`. Collapse a + * Chinese Accept-Language list to the exact locale selected by Bulwark's + * script/region-aware matcher before handing the request to next-intl. URL + * prefixes and the NEXT_LOCALE cookie still keep their higher precedence. + */ +function withMatchedChineseAcceptLanguage(request: NextRequest): NextRequest { + const acceptLanguage = request.headers.get("accept-language"); + const locale = localeFromAcceptLanguage(acceptLanguage, routing.locales); + if (locale !== "zh" && locale !== "zh-TW") return request; + + const headers = new Headers(request.headers); + headers.set("accept-language", locale); + return new NextRequest(request, { headers }); +} + // Next 16's Proxy always runs on Node.js runtime and route-segment config // (e.g. `export const config = { matcher }`) is no longer allowed in the // proxy file. We replicate the previous matcher inline by short-circuiting @@ -214,7 +232,7 @@ export async function proxy(request: NextRequest) { let intlResponse: ReturnType | null = null; if (!isAdminRoute && !isProtocolRoute && !isSetupRoute && !isSandboxRoute && !hasLocalePrefix) { try { - intlResponse = intlMiddleware(request); + intlResponse = intlMiddleware(withMatchedChineseAcceptLanguage(request)); } catch (error) { console.error('Locale middleware error:', error); } From f1736b63c942d222f5e0b075366ed32078e94f8f Mon Sep 17 00:00:00 2001 From: Kuan-Chieh Huang <7856561+kchuang1015@users.noreply.github.com> Date: Sat, 29 Aug 2026 13:04:25 +0800 Subject: [PATCH 3/3] fix(i18n): preserve locale cookie precedence --- lib/__tests__/proxy-forwarded-headers.test.ts | 24 +++++++++++++++++++ proxy.ts | 10 ++++++++ 2 files changed, 34 insertions(+) diff --git a/lib/__tests__/proxy-forwarded-headers.test.ts b/lib/__tests__/proxy-forwarded-headers.test.ts index c9d71210c..87d52f2ef 100644 --- a/lib/__tests__/proxy-forwarded-headers.test.ts +++ b/lib/__tests__/proxy-forwarded-headers.test.ts @@ -144,4 +144,28 @@ describe('proxy normalizes Chinese Accept-Language before next-intl matching', ( expect(receivedAcceptLanguage).toBe(expected); }); + + it.each(['en', 'zh', 'zh-TW'])( + 'leaves Accept-Language untouched when a valid NEXT_LOCALE=%s cookie is present', + async (cookieLocale) => { + const acceptLanguage = 'zh-HK,zh;q=0.9,en;q=0.8'; + await proxy( + new NextRequest('http://localhost:3000/', { + headers: { 'accept-language': acceptLanguage, cookie: `NEXT_LOCALE=${cookieLocale}` }, + }), + ); + + expect(receivedAcceptLanguage).toBe(acceptLanguage); + }, + ); + + it('ignores an invalid locale cookie when normalizing Accept-Language', async () => { + await proxy( + new NextRequest('http://localhost:3000/', { + headers: { 'accept-language': 'zh-HK,zh;q=0.9', cookie: 'NEXT_LOCALE=unsupported' }, + }), + ); + + expect(receivedAcceptLanguage).toBe('zh-TW'); + }); }); diff --git a/proxy.ts b/proxy.ts index d9cd5ddc4..b89217f5d 100644 --- a/proxy.ts +++ b/proxy.ts @@ -20,6 +20,16 @@ const intlMiddleware = createIntlMiddleware(routing); * prefixes and the NEXT_LOCALE cookie still keep their higher precedence. */ function withMatchedChineseAcceptLanguage(request: NextRequest): NextRequest { + const localeCookie = routing.localeCookie; + const localeCookieName = + localeCookie === false + ? null + : typeof localeCookie === "object" && localeCookie.name + ? localeCookie.name + : "NEXT_LOCALE"; + const cookieLocale = localeCookieName ? request.cookies.get(localeCookieName)?.value : undefined; + if (cookieLocale && (routing.locales as readonly string[]).includes(cookieLocale)) return request; + const acceptLanguage = request.headers.get("accept-language"); const locale = localeFromAcceptLanguage(acceptLanguage, routing.locales); if (locale !== "zh" && locale !== "zh-TW") return request;