import type { AppLocale } from "./types"; /** 扁平 key → 字串;{name} 可插值 */ export type MessageDict = Record; export const zhTW: MessageDict = { "app.name": "巡樓", "app.nameEn": "Lapras", "app.nameZh": "巡樓", "app.tagline": "Threads 海巡好幫手", "app.taglineEn": "Patrol Threads with ease", "nav.today": "今日", "nav.crew": "帳號", "nav.studio": "創作", "nav.scout": "海巡", "nav.outbox": "發送", "nav.jobs": "任務", "nav.brands": "品牌", "nav.more": "更多", "nav.moreTitle": "更多功能", "nav.users": "島民管理", "nav.usage": "用量與方案", "nav.profile": "會員資料", "nav.invite": "邀請關係", "nav.settings": "系統設定", "nav.logout": "登出", "nav.navigate": "導覽", "common.save": "儲存", "common.cancel": "取消", "common.loading": "載入中…", "common.back": "返回", "common.delete": "刪除", "common.edit": "編輯", "common.search": "搜尋", "common.confirm": "確定", "common.optional": "選填", "common.success": "已儲存", "common.error": "發生錯誤", "common.yes": "是", "common.no": "否", // 後端 envelope code(apps/backend response + middleware) "api.err.unknown": "操作失敗,請稍後再試", "api.err.network": "無法連線後端,請確認網路或服務是否啟動", "api.err.400001": "請求格式不正確", // 與後端 400003 / ValidatePasswordPolicy 同一句(勿各寫各的) "api.err.400003": "密碼須至少 12 碼,且含大寫、小寫、數字與符號", "password.policy.hint": "密碼須至少 12 碼,且含大寫、小寫、數字與符號", "password.policy.minLen": "密碼須至少 12 碼,且含大寫、小寫、數字與符號", "password.policy.needUpper": "密碼須至少 12 碼,且含大寫、小寫、數字與符號", "password.policy.needLower": "密碼須至少 12 碼,且含大寫、小寫、數字與符號", "password.policy.needDigit": "密碼須至少 12 碼,且含大寫、小寫、數字與符號", "password.policy.needSymbol": "密碼須至少 12 碼,且含大寫、小寫、數字與符號", "api.err.400004": "驗證碼無效或已過期", "api.err.400020": "不能停權自己的帳號", "api.err.400021": "不能移除或停權最後一位管理員", "api.err.401001": "請先登入", "api.err.401002": "登入已失效,請重新登入", "api.err.401003": "找不到會員資料,請重新登入", "api.err.401010": "Email 或密碼錯誤", "api.err.403001": "帳號已停權", "api.err.403002": "需要管理員權限", "api.err.404001": "找不到資料", "api.err.404002": "查無此信箱,請確認後再試", "api.err.409001": "此 Email 已被註冊", "api.err.500000": "伺服器發生錯誤,請稍後再試", "api.err.501000": "此功能尚未實作", // 後端 data.message 成功文案 "api.ok.verifySent": "驗證碼已寄出,請查收信箱", "api.ok.verifyIssued": "驗證碼已產生", "api.ok.resetSent": "重設信已寄出,請查收信箱", "api.ok.passwordUpdated": "密碼已更新", "api.ok.loggedOut": "已登出", "api.ok.unbound": "已解除綁定", "topbar.notifications": "通知", "topbar.unread": "{n} 未讀", "topbar.markAllRead": "全已讀", "topbar.noNotifications": "目前沒有通知", "topbar.jobsCenter": "任務中心", "topbar.moreOlder": "還有 {n} 則較舊", "topbar.account": "帳號選單", "role.admin": "管理員", "role.member": "一般會員", "role.verified": "已驗證", "role.unverified": "未驗證", "login.title": "登入巡樓", "login.email": "Email", "login.password": "密碼", "login.submit": "登入", "login.submitting": "登入中…", "login.forgot": "忘記密碼?", "login.mockHint": "管理員 demo@harbor.local / demo · 一般會員 alice@harbor.local / alice", "login.liveHint": "Live 後端:admin@haixun.local / admin123(gateway :8888)", "forgot.title": "忘記密碼", "forgot.submit": "寄送重設連結", "forgot.submitting": "送出中…", "forgot.back": "返回登入", "forgot.hint": "輸入註冊用 Email,我們會寄送重設連結與驗證碼。", "forgot.mockMail": "重設信", "forgot.openReset": "前往輸入驗證碼/重設密碼", "forgot.retry": "再試一次", "forgot.nextStep": "請查收信箱中的驗證碼或連結,再到重設頁完成新密碼。", "reset.title": "設定新密碼", "reset.hint": "請輸入信箱、驗證碼(信內 6 碼或連結參數)與新密碼。", "reset.code": "驗證碼", "reset.codePh": "信內 6 位數字", "reset.needEmail": "請輸入 Email", "reset.needCode": "請輸入驗證碼", "reset.newPassword": "新密碼", "reset.confirm": "確認新密碼", "reset.submit": "更新密碼", "reset.submitting": "更新中…", "reset.missingToken": "連結缺少 token。請從「忘記密碼」重新申請。", "verify.title": "驗證信箱", "verify.pending": "尚未驗證", "verify.body": "帳號已開通登入,但信箱未驗證前無法使用功能。請輸入寄到你信箱的 6 位驗證碼。", "verify.code": "驗證碼", "verify.submit": "完成驗證", "verify.submitting": "驗證中…", "verify.resend": "重新寄送驗證碼", "verify.sending": "寄送中…", "verify.logout": "登出", "verify.mockMail": "驗證信", "verify.mockHint": "請輸入驗證碼:", "verify.after": "驗證完成後即可使用今日、創作、海巡等功能。", "settings.title": "設定", "settings.localeCurrency": "語言與幣別", "settings.locale": "介面語言", "settings.currency": "顯示幣別", "settings.currencyHint": "", "settings.localeSaved": "語言與幣別已更新", "settings.appearance": "外觀", "settings.theme": "主題", "settings.themeLight": "淺色", "settings.themeDark": "深色", "settings.themeSystem": "跟隨系統", "settings.themeHint": "", "settings.themeSaved": "主題已更新", "settings.themeToLight": "切換成淺色", "settings.themeToDark": "切換成深色", "settings.dataSource": "資料來源", "settings.dataSourceHint": "mock = 瀏覽器本機假資料;live = 打 apps/backend gateway。切 live 後請重新登入。", "settings.dataSourceMock": "Mock(本機)", "settings.dataSourceLive": "Live(後端 API)", "settings.dataSourceCurrent": "目前", "settings.dataSourceSwitchedLive": "已切到 Live — 請用後端帳號重新登入(admin@haixun.local / admin123)", "settings.dataSourceSwitchedMock": "已切回 Mock", "settings.dataSourceLiveNeedGateway": "需 gateway 在 :8888(或 Vite proxy /api)", "settings.ai": "AI", "settings.search": "搜尋", "settings.member": "會員與登入", "settings.usageCard": "AI/搜尋額度", "settings.usageCardHint": "", "settings.viewUsage": "查看用量", "settings.editProfile": "編輯會員資料", "settings.mockLogin": "demo@harbor.local / demo", "settings.memberHint": "", "usage.title": "用量與方案", "usage.desc": "", "usage.creditsUsed": "本月已用點數", "usage.remaining": "剩餘 {n} 點", "usage.percentUsed": "{n}% 已使用", "usage.breakdown": "分項用量", "usage.plans": "方案", "usage.current": "目前", "usage.inUse": "使用中", "usage.switchMock": "切換方案", "usage.perMonth": "點/月", "usage.ledger": "最近使用紀錄", "usage.emptyTitle": "本月還沒有扣點", "usage.emptyDesc": "", "usage.planNote": "", "usage.switched": "已切換為 {name}", "usage.meter.times": "{count} 次 · {credits} 點", "usage.meter.cap": "單項參考上限 {count}/{cap} 次", "usage.plan.free.blurb": "試用與個人輕量經營", "usage.plan.starter.blurb": "小團隊日常發文與海巡", "usage.plan.pro.blurb": "多帳、重度 AI 與研究", "profile.title": "會員資料", "profile.desc": "", "profile.accountStatus": "帳號開通狀態", "profile.basic": "基本資料", "profile.avatar": "頭像", "profile.avatarUpload": "上傳頭像", "profile.avatarRemove": "移除頭像", "profile.avatarHint": "JPG/PNG/WebP,5MB 內。選圖後按「儲存基本資料」寫入;「移除頭像」會立刻清除。", "profile.avatarSaved": "頭像已更新", "profile.avatarCleared": "已移除頭像", "profile.avatarFail": "無法讀取圖片", "profile.displayName": "顯示名稱", "profile.bio": "簡介(選填)", "profile.timezone": "時區", "profile.notifyEmail": "Email 通知", "profile.password": "變更密碼(選填)", "profile.currentPassword": "目前密碼", "profile.newPassword": "新密碼", "profile.confirmPassword": "確認新密碼", "profile.emailVerified": "信箱已驗證", "profile.emailUnverified": "信箱未驗證", "profile.roleAdmin": "管理員", "profile.roleMember": "一般會員", "profile.loginEmail": "登入信箱:{email}", "profile.verifiedAt": " · 驗證於 {time}", "profile.goVerify": "去驗證信箱", "profile.roleTags": "權限標籤:{labels}", "profile.roleNote": "角色由系統指派;改信箱後需重新驗證。", "profile.saveBasic": "儲存基本資料", "profile.updatePassword": "更新密碼", "profile.saved": "會員資料已儲存", "profile.savedUnverified": "資料已儲存。信箱尚未驗證或已變更,請完成驗證後才能繼續使用功能。", "profile.saveFail": "儲存失敗", "profile.needNewPassword": "請輸入新密碼", "profile.passwordMismatch": "兩次新密碼不一致", "profile.needCurrentPassword": "請輸入目前密碼", "profile.wrongCurrentPassword": "目前密碼不正確", "profile.passwordUpdated": "密碼已更新", "profile.passwordFail": "變更密碼失敗", "profile.listJoin": "、", "profile.tenantUid": " · tenant {tenant} · uid {uid}", "profile.inviteBadge": "邀請碼", "profile.inviteHint": "分享給朋友加入;日後活動可依邀請關係計算。", "profile.gotoInvite": "查看邀請關係", "invite.title": "邀請關係", "invite.desc": "邀請碼與邀請關係;管理端為樹狀結構。", "invite.tabs": "邀請檢視", "invite.tab.mine": "我的邀請", "invite.tab.tree": "關係樹", "invite.myCode": "我的邀請碼", "invite.codeLabel": "邀請碼", "invite.copyCode": "複製", "invite.copied": "已複製", "invite.copyFail": "複製失敗", "invite.stats": "直邀 {direct} · 延伸 {total}", "invite.upline": "邀請人", "invite.downlines": "直邀成員 · {n}", "invite.noUpline": "無邀請人", "invite.noDownline": "尚無直邀", "invite.directN": "直邀 {n}", "invite.claimHint": "若註冊時沒填,可在此補上邀請人的邀請碼(綁定後不可自行更改)。", "invite.claimLabel": "邀請碼", "invite.claimPh": "例如 HX-DEMO01", "invite.claimSubmit": "確認綁定", "invite.claimOk": "已綁定邀請人:{name}", "invite.claimOkGeneric": "已綁定邀請人", "invite.claimFail": "綁定失敗", "invite.claimLocked": "已綁定,如需調整請聯絡管理員。", "invite.loadFail": "載入失敗", "invite.treeEmpty": "尚無資料", "invite.treeSearch": "搜尋", "invite.treeSearchPh": "名稱 / Email / 邀請碼", "invite.treeCount": "{n} 人", "invite.treeMatchCount": "命中 {n} · 共 {total}", "invite.treeNoMatch": "沒有符合的島民", "invite.treeNoMatchHint": "換個關鍵字試試", "invite.clearSearch": "清除", "invite.moveTitle": "調整歸屬", "invite.newParent": "邀請人", "invite.root": "(無 · 獨立)", "invite.confirmMove": "確認", "invite.moved": "已調整「{name}」→「{parent}」", "invite.moveFail": "調整失敗", "invite.openFromAdmin": "邀請關係", "invite.parentField": "邀請人", "invite.orgPickRoot": "選一個起點(含無人邀請、自己進來的)", "invite.orgRoots": "起點", "invite.orgPath": "路徑", "invite.orgChainN": "延伸 {n}", "invite.orgFocusStats": "直邀 {direct} · 延伸 {total}", "invite.orgDirects": "直邀成員 · {n}", "invite.orgNoDirects": "沒有直邀成員", "invite.err.notFound": "找不到會員", "invite.err.notLoggedIn": "尚未登入", "invite.err.needAdmin": "需要管理員權限", "invite.err.memberNotFound": "找不到島民", "invite.err.selfParent": "不能把自己設為邀請人", "invite.err.parentNotFound": "找不到指定的邀請人", "invite.err.cycle": "不可掛到自己邀請鏈的下層(會形成環)", "invite.err.repoMissing": "邀請資料層尚未載入,請重新整理頁面", "invite.err.alreadyBound": "你已有邀請人,無法再補填", "invite.err.codeRequired": "請輸入邀請碼", "invite.err.codeNotFound": "找不到此邀請碼", "invite.err.codeSelf": "不能填自己的邀請碼", "admin.users.title": "島民管理", "admin.users.desc": "", "admin.users.needAdmin": "需要管理員權限", "admin.users.list": "島民列表 · {n}", "admin.users.detail": "島民詳情", "admin.users.pick": "選擇島民", "admin.users.search": "搜尋名稱 / uid", "admin.users.searchPh": "島民名稱、Email 或 uid", "admin.users.create": "新增島民", "admin.users.suspend": "停權", "admin.users.unsuspend": "復權", "admin.users.suspended": "已停權", "admin.users.active": "正常", "crew.title": "帳號", "crew.tab.accounts": "帳號", "crew.tab.personas": "人設", "crew.connect": "連接帳號", "crew.connecting": "新增中…", "crew.refreshAll": "全部刷新 session", "crew.refreshing": "刷新中…", "crew.empty": "尚無帳號", "crew.unusable": "不可用", "crew.expires": "過期 {time}", "crew.lastRefresh": "上次更新 {time}", "crew.refreshSession": "刷新 session", "crew.session.ok": "session 有效", "crew.session.soon": "即將到期", "crew.session.expired": "session 過期", "crew.session.unknown": "session 未知", "crew.msg.refreshed": "@{user} session 已刷新(延長約 30 天)", "crew.msg.refreshedAll": "已刷新 {n} 個帳號 session", "crew.msg.refreshFail": "刷新失敗", "crew.confirmDelete": "確定刪除帳號 @{user}?\n刪除後無法再選為 lead / cast。", "today.findTopic": "找話題", "today.pendingReplies": "待回覆", "today.pendingRepliesN": "待回覆 · {n}", "today.newThread": "開新串", "today.metricsAria": "今日數值", "today.metric.pending": "待回", "today.metric.pendingHint": "海巡佇列", "today.metric.doneGoal": "已回/目標", "today.metric.sentToday": "今日已發", "today.metric.running": "進行中 {n}", "today.metric.sentDone": "完成的發送", "today.metric.failed": "發送異常", "today.metric.needAction": "需處理", "today.metric.ok": "正常", "today.pending.title": "待回覆 · {n}", "today.pending.empty": "目前沒有待回", "today.goScout": "去海巡", "today.pending.more": "還有 {n} 則 →", "today.pending.handle": "海巡處理", "today.pending.start": "開始處理", "today.topics.title": "找話題", "today.topics.empty": "還沒有話題", "today.goStudio": "去創作", "today.heat": "熱度 {n}", "today.topicAngle": "可當開場角度", "today.moreInspire": "更多靈感", "today.useTopic": "用話題開串", "today.outbox.title": "今日發送", "today.outbox.empty": "還沒有今日發送。可先", "today.outbox.emptyMid": ",完成後會出現在", "today.outbox.emptyEnd": "。", "today.outbox.summary": "已完成 {sent} · 進行中 {running} · 異常 {failed}", "today.badge.failed": "失敗", "today.badge.scheduling": "排程", "today.badge.sending": "發送中", "today.openOutbox": "開啟發送", "today.accounts.title": "帳號成效", "today.accounts.empty": "尚無成效", "today.postsCount": "{n} 則貼文", "today.views": "瀏覽", "today.likes": "讚", "today.repliesShort": "回", "today.fullInsights": "完整成效 · 月比圖", "today.viewPosts": "看已發文", "today.manageAccounts": "管理帳號", "outbox.title": "發送", "outbox.tabsAria": "發送分頁", "outbox.tab.active": "進行中", "outbox.tab.history": "歷史", "outbox.empty": "尚無發送", "outbox.activeEmpty": "進行中是空的", "outbox.historyEmpty": "尚無歷史", "outbox.historyN": "歷史({n})", "outbox.backActive": "回進行中({n})", "outbox.progress": "進度 {progress}", "outbox.detail": "詳情", "outbox.deleting": "刪除中…", "outbox.confirmDelete": "刪除發送項目「{title}」?\n無法復原。", "outbox.deleted": "已刪除「{title}」", "outbox.deleteFail": "刪除失敗", "outbox.status.scheduling": "排程中", "outbox.status.active": "發送中", "outbox.status.completed": "已完成", "outbox.status.partial_failed": "部分失敗", "outbox.status.cancelled": "已取消", "outbox.detail.missingId": "缺少 id", "outbox.detail.notFound": "找不到發送", "outbox.detail.markAllOk": "標記全部成功", "outbox.detail.markRootFail": "標記主貼失敗", "outbox.detail.processing": "處理中…", "outbox.detail.delete": "刪除這筆", "outbox.detail.back": "返回列表", "outbox.detail.root": "主貼", "outbox.detail.replyN": "回覆 {n}", "outbox.detail.retry": "重試", "outbox.detail.opFail": "操作失敗", "studio.title": "創作", "studio.account": "帳號", "studio.persona": "人設", "studio.personaReady": "人設 ready", "studio.personaNotReady": "人設未就緒", "studio.tab.posts": "我的貼文", "studio.tab.mentions": "提及 @", "studio.tab.compose": "寫一則", "studio.tab.plays": "互回方案", "studio.tab.inspire": "靈感", "studio.tab.insights": "成效", "mentions.hint": "誰 @ 你。待回 {n} 則。每則可改帳號/人設(預設用頂部)。", "mentions.scoutLink": "海巡外展", "mentions.empty": "尚無提及", "mentions.status.pending": "待回", "mentions.status.replied": "已回", "mentions.status.skipped": "略過", "mentions.reply": "回覆", "mentions.skip": "略過", "mentions.draftLabel": "回覆草稿", "mentions.repliedPrefix": "已回:{text}", "mentions.needPersona": "請選 ready 人設再 AI 產文", "mentions.fail": "失敗", "mentions.marked": "已標記回覆(帳號 @{user})", "mentions.withImages": " · 附圖 {n}", "compose.hint": "單篇發文(非串場)。互回請用", "compose.hintEnd": "。", "compose.playsLink": "串場", "compose.personaOff": "人設未 ready:仿寫/分析等 AI 工具停用。", "compose.title": "標題(選填)", "compose.titlePh": "方便在 Outbox 辨識", "compose.body": "正文", "compose.bodyPh": "寫下這則貼文…", "compose.tool.mimic": "仿寫", "compose.tool.viral": "爆紅分析", "compose.tool.research": "上網補資料", "compose.tool.image": "產圖", "compose.mimic.title": "仿寫別人貼文", "compose.mimic.source": "參考全文", "compose.mimic.sourcePh": "貼上想仿寫的貼文…", "compose.mimic.running": "仿寫中…", "compose.mimic.run": "依人設仿寫到正文", "compose.mimic.done": "仿寫完成,可再改", "compose.viral.title": "爆紅分析", "compose.viral.hint": "分析參考文或目前正文的鉤子/結構/可複製點。", "compose.viral.source": "分析對象(可空=用正文)", "compose.viral.running": "分析中…", "compose.viral.run": "開始分析", "compose.viral.result": "分析結果", "compose.viral.done": "爆紅分析完成", "compose.viral.needText": "請貼參考文或先寫正文", "compose.research.title": "上網補專業資料", "compose.research.q": "關鍵字", "compose.research.qPh": "例如:無香洗劑 敏感肌", "compose.research.running": "搜尋中…", "compose.research.insert": "插入勾選內容到正文", "compose.research.inserted": "已插入 {n} 條補充", "compose.image.title": "產圖", "compose.image.prompt": "畫面描述", "compose.image.promptPh": "可空=從正文摘要", "compose.image.running": "產圖中…", "compose.image.run": "產生圖片", "compose.image.done": "已產圖", "compose.scheduleAt": "預計發送時間", "compose.scheduleHint": "到點後由 Outbox 依序送出;可選現在。", "compose.scheduleNow": "設為現在", "compose.publish": "送出到 Outbox", "compose.publishing": "送出中…", "compose.publishFail": "送出失敗", "compose.fail": "失敗", "compose.attachN": "附圖 {n}", "compose.personaStatus": "人設:{status}", "compose.ready": "ready", "compose.notReady": "未就緒", "posts.sync": "重新同步 Threads", "posts.syncing": "同步中…", "posts.syncedAt": "同步 {time}", "posts.notSynced": "未同步", "posts.syncDone": "已同步 Threads 成效(讚/回/轉發/引用/瀏覽/分享)", "posts.empty": "尚無貼文", "posts.openThreads": "開 Threads", "posts.insight": "分析洞察:{text}", "posts.review": "覆盤:{text}", "posts.formulaResult": "結構分析結果", "posts.collapseReplies": "收合留言", "posts.repliesBtn": "留言({total})· 未回 {pending}", "posts.replyRoot": "回主貼", "posts.analyzing": "分析中…", "posts.reanalyze": "重新分析結構", "posts.analyze": "分析結構", "posts.mimicThis": "仿寫這則", "posts.rootDraft": "回主貼草稿", "posts.filter.pending": "未回覆({n})", "posts.filter.replied": "已回覆({n})", "posts.filter.all": "全部({n})", "posts.noPending": "沒有未回覆留言", "posts.noReplied": "還沒有已回覆留言", "posts.noReplies": "尚無留言", "posts.status.pending": "未回覆", "posts.status.replied": "已回覆", "posts.likesN": "讚 {n}", "posts.childCount": "{n} 則子留言", "posts.mine": "我方", "posts.replyThis": "回這則", "posts.replyAgain": "再回一則", "posts.replyTo": "回 @{user}", "posts.replyAgainTo": "再回 @{user}", "posts.needPersona": "請先選 ready 人設再 AI 產文", "posts.genFail": "生成失敗", "posts.needText": "請先產生或輸入回覆", "posts.sent": "已用 @{user} 發送", "posts.sentImages": "(附圖 {n})", "posts.accountFallback": "帳號", "posts.sendFail": "發送失敗", "posts.analyzeDone": "結構分析完成(手動觸發)", "posts.analyzeFail": "分析失敗", "wizard.newTitle": "編互回劇本", "wizard.editTitle": "編輯互回劇本", "wizard.prev": "上一步", "wizard.next": "下一步", "wizard.err.topic": "請填主題", "wizard.err.lead": "請選擇主帳號", "wizard.err.leadUnusable": "主帳號不可用", "wizard.submitFail": "提交失敗", "wizard.unnamedPlay": "未命名串場", "wizard.step.topic": "聊什麼", "wizard.step.crew": "誰出場", "wizard.step.script": "誰說什麼", "wizard.step.preview": "預覽", "wizard.step.schedule": "何時發", "wizard.step.submit": "送出", "wizard.stepperAria": "wizard 步驟", "wizard.topic.title": "1. 這串要聊什麼", "wizard.topic.name": "標題(可選)", "wizard.topic.namePh": "例如:週末咖啡", "wizard.topic.topic": "主題一句話", "wizard.topic.topicPh": "這串文想聊什麼?", "wizard.topic.aiView": "AI 視角", "wizard.topic.personaNotReady": "人設未就緒", "wizard.topic.generating": "生成中…", "wizard.topic.aiSuggest": "AI 幫我想", "wizard.topic.quickFill": "快速填入", "wizard.topic.sampleTitle": "週末咖啡話題", "wizard.topic.sampleTopic": "週末想找間不踩雷的咖啡店,插座要多、能坐久。", "wizard.topic.aiTitle": "AI 主題", "wizard.topic.personaOpen": "{name}開場", "wizard.crew.title": "2. 出場", "wizard.crew.lead": "主帳", "wizard.crew.noUsable": "尚無可用帳號", "wizard.crew.unusable": "不可用", "wizard.crew.cast": "配角", "wizard.script.title": "3. 台詞", "wizard.script.persona": "人設", "wizard.script.personaNotReady": "人設未就緒", "wizard.script.root": "主貼", "wizard.script.replyN": "回覆 {n}", "wizard.script.generating": "生成中…", "wizard.script.ai": "AI 產文", "wizard.script.account": "帳號:{name}", "wizard.script.noLead": "(未選 lead)", "wizard.script.speaker": "發言帳號", "wizard.script.leadTag": "(lead)", "wizard.script.text": "文案", "wizard.script.rootPh": "主貼內容…", "wizard.script.replyPh": "回覆內容…", "wizard.script.addReply": "新增回覆步驟", "wizard.preview.title": "4. 預覽這段對話", "wizard.preview.unknown": "未知", "wizard.preview.unknownAccount": "未知帳號", "wizard.preview.root": "主貼", "wizard.preview.leadTalk": "lead 接話", "wizard.preview.empty": "(空白)", "wizard.schedule.title": "5. 何時發出去", "wizard.schedule.start": "第一則(主貼)時間", "wizard.schedule.interval": "回覆間隔(分鐘)", "wizard.schedule.intervalHint": "相對上一步", "wizard.submit.title": "6. 送出排程", "wizard.submit.body": "確認後會把「{title}」這串互回(共 {n} 步)送進 Outbox,依序用各帳號發出。", "wizard.submit.unnamed": "未命名", "wizard.submit.root": "主貼", "wizard.submit.replyN": "回覆 {n}", "wizard.submit.submitting": "提交中…", "wizard.submit.run": "提交到 Outbox", "reply.account": "用哪個帳號回", "reply.persona": "用人設", "reply.notReady": "此人設未 ready,無法 AI 產文(仍可手打後發送)。", "reply.draft": "回覆草稿", "reply.attach": "附圖", "reply.generating": "生成中…", "reply.ai": "AI 產文", "reply.sending": "發送中…", "reply.send": "發送", "image.attach": "附圖", "image.attachFail": "附圖失敗", "image.attachedAria": "已附圖片", "image.alt": "附圖", "image.named": "附圖 {n}", "image.remove": "移除圖片", "image.full": "已滿 {max} 張", "image.more": "再附圖({n}/{max})", "metrics.aria": "貼文成效", "metrics.like": "讚", "metrics.reply": "回覆", "metrics.repost": "轉發", "metrics.quote": "引用", "metrics.view": "瀏覽", "metrics.share": "分享", "metrics.type.quote": "引用貼", "metrics.type.reply": "回覆貼", "metrics.type.image": "圖片", "metrics.type.video": "影片", "metrics.type.carousel": "輪播", "metrics.type.repost": "轉發", "metrics.type.text": "文字", "metrics.type.post": "貼文", "jobs.title": "任務", "jobs.startDemo": "啟動任務", "jobs.empty": "尚無任務", "jobs.total": "共 {n} 筆", "jobs.showing": " · 顯示前 {n}", "jobs.detail": "詳情", "jobs.loadMore": "載入更多(還有 {n})", "jobs.notFound": "找不到任務", "jobs.progress": "進度 {n}%", "jobs.updated": "更新 {time}", "jobs.backList": "返回列表", "plans.title": "變更方案", "plans.current": "目前方案", "plans.perMonth": "/月", "plans.monthlyCredits": "每月 {n} 點", "plans.usageLink": "用量", "plans.inUse": "使用中", "plans.recommended": "推薦", "plans.creditsPerMonth": "每月 {n} 點", "plan.cta.current": "目前方案", "plan.cta.upgrade": "升級", "plan.cta.downgrade": "降級", "plan.cta.switch": "切換", "plan.free.headline": "試用與個人輕量經營", "plan.free.bullet1": "每月 {n} 點 AI/搜尋", "plan.free.bullet2": "完整功能:創作、海巡、發送", "plan.free.bullet3": "適合先熟悉流程", "plan.free.bullet4": "可隨時升級", "plan.free.right1": "可使用完整功能:帳號、創作、海巡、發送、任務與靈感。", "plan.free.right2": "每月固定點數,用在文案、研究、搜尋與生圖。", "plan.free.right3": "達上限後需等下月或升級(除非管理員開不擋額度)。", "plan.free.quota1": "每月配給 {n} 點。", "plan.free.quota2": "參考:文案 {copy}、研究 {research}、搜尋 {search}、生圖 {image} 次。", "plan.free.note1": "無需付款,確認即切換。", "plan.free.note2": "正式金流後的發票規則另訂。", "plan.starter.headline": "小團隊日常發文與海巡", "plan.starter.bullet1": "每月 {n} 點(約 6× Free)", "plan.starter.bullet2": "穩定發文、回覆、海巡", "plan.starter.bullet3": "適合 1~3 人節奏", "plan.starter.bullet4": "付款成功立即生效", "plan.starter.right1": "付款成功後本帳改為 Starter,當月依新額度計算。", "plan.starter.right2": "點數支撐固定發文、回覆草稿與定期海巡。", "plan.starter.right3": "功能與 Free 相同,差在能用多久。", "plan.starter.quota1": "每月 {n} 點 · {price}。", "plan.starter.quota2": "參考:文案 {copy}、研究 {research}、搜尋 {search}、生圖 {image} 次。", "plan.starter.note1": "需付款成功才變更方案。", "plan.starter.note2": "自然月重置,未用完點數不累積至下月。", "plan.pro.headline": "多帳、重度 AI 與研究", "plan.pro.bullet1": "每月 {n} 點(約 4× Starter)", "plan.pro.bullet2": "高頻文案/研究/生圖", "plan.pro.bullet3": "適合代理與多品牌", "plan.pro.bullet4": "付款成功立即生效", "plan.pro.right1": "付款成功後本帳改為 Pro,當月依 Pro 額度計算。", "plan.pro.right2": "適合多帳、大量回覆與深研究,減少中途額度見底。", "plan.pro.right3": "功能相同;買的是容量與節奏。", "plan.pro.quota1": "每月 {n} 點 · {price}。", "plan.pro.quota2": "參考:文案 {copy}、研究 {research}、搜尋 {search}、生圖 {image} 次。", "plan.pro.note1": "付款失敗不會改方案。", "plan.pro.note2": "付款完成後可於帳務紀錄查詢收據。", "checkout.title": "確認方案", "checkout.pickFirst": "請先選擇方案。", "checkout.viewPlans": "看方案", "checkout.cardLast4Required": "請填卡號末四碼", "checkout.cardNameRequired": "請填持卡人", "checkout.fail": "無法完成", "checkout.confirmFree": "確認切換至 Free", "checkout.payAndAction": "{action}並付款 {price}", "checkout.subscribe": "訂閱", "checkout.perMonth": "/月", "checkout.monthlyCredits": "每月 {n} 點", "checkout.youGet": "你會得到", "checkout.quota": "額度", "checkout.notes": "注意", "checkout.cardholder": "持卡人", "checkout.cardLast4": "卡號末四碼", "checkout.amountDue": "應付金額", "checkout.billedMonthly": "{name} · 按月計費", "checkout.already": "已是此方案", "checkout.processing": "處理中…", "checkout.currentPlan": "目前方案", "checkout.pickOther": "改選其他方案", "checkout.cancel": "取消", "usage.widget.titleUsed": "{name} · 已用 {used}/{cap} 點", "usage.widget.titleUnlimited": "{name} · 不擋額度", "usage.widget.ariaUsed": "已用 {used} 點,共 {cap} 點", "usage.widget.dialog": "方案與用量", "usage.widget.currentPlan": "目前方案", "usage.widget.unlimited": "不擋額度", "usage.widget.perMonth": "/月", "usage.widget.monthUsage": "本月用量", "usage.widget.remaining": "還剩 {n} 點", "usage.widget.leftShort": "還剩 {n}", "usage.widget.overShort": "已超額", "usage.widget.upgradeShort": "升級", "usage.widget.upgrade": "升級方案", "usage.widget.includes": "這個方案包含", "usage.widget.nudge": "本月額度快用完了,升級可立刻加大點數。", "usage.widget.changePlan": "變更方案", "usage.widget.usageDetail": "用量明細", "usage.meter.ai_copy": "AI 文案", "usage.meter.ai_research": "AI 研究", "usage.meter.web_search": "搜尋", "usage.meter.ai_image": "AI 生圖", "usage.meter.barAria": "{label} {count} 次 {credits} 點,上限 {cap}", "usage.ledger.costAria": "消耗 {n} 點", "usage.chart.period": "區間", "usage.chart.allocated": "配給", "usage.chart.consumed": "消耗", "usage.chart.pctTitle": "消耗佔配給比例", "usage.chart.aria": "配給與消耗", "usage.chart.colAria": "{label} 配給 {purchased} 消耗 {consumed}", "settings.provider": "Provider", "settings.model": "模型", "settings.aiUnifiedHint": "文案、研究、延伸全部使用同一 provider 與模型。", "settings.fetchModels": "取得模型", "settings.fetchingModels": "讀取中…", "settings.apiKey": "API Key", "settings.configured": "已設定", "settings.notConfigured": "未設定", "settings.modelsLoaded": "已取得 {provider} 模型清單", "settings.aiSaved": "AI 設定已儲存", "settings.searchSaved": "搜尋設定已儲存", "settings.searchProvider": "搜尋 Provider", "settings.expand": "延伸策略", "settings.exaKey": "Exa API Key", "settings.devMode": "開發模式(爬蟲測試海巡)", "settings.devModeHint": "開啟後測試海巡可走 Chrome 爬蟲;正式發文/留言仍走 API。請下載擴充以同步 Threads 登入態。", "settings.ext.title": "Chrome 擴充套件", "settings.ext.desc": "開發模式需安裝此擴充,才能從 Chrome 同步 Threads session 到巡樓。", "settings.ext.step1": "下載並解壓縮 ZIP,得到 haixun-threads-sync 資料夾", "settings.ext.step2": "Chrome 開啟 chrome://extensions,開啟「開發人員模式」", "settings.ext.step3": "點「載入未封裝項目」,選擇解壓後的資料夾", "settings.ext.step4": "在擴充選項填入此站網址,再重新整理巡樓頁", "settings.ext.download": "下載擴充套件(ZIP)", "forgot.fail": "送出失敗", "forgot.mockHint": "正式環境會寄到信箱;此處直接給連結:", "forgot.checkInbox": "請檢查信箱(含垃圾郵件)。", "reset.mismatch": "兩次密碼不一致", "reset.fail": "重設失敗", "reset.cardTitle": "重設密碼", "reset.redirecting": "即將前往登入頁…", "reset.loginNow": "立即登入", "reset.passwordPh": "密碼須至少 12 碼,且含大寫、小寫、數字與符號", "reset.forgotLink": "重新申請重設", "verify.sendFail": "寄送失敗", "verify.fail": "驗證失敗", "verify.success": "信箱已驗證,可以使用巡樓了。", "verify.codePh": "6 位數字", "verify.currentAccount": "目前帳號:{email}", "login.brandTitle": "巡樓 · Lapras", "common.listSep": "、", "common.dash": "—", "scout.title": "海巡", "scout.today": "今日", "scout.purposeValue": "痛點回覆", "scout.purposeActivity": "活躍短回", "scout.goal": "今日目標(則)", "scout.progress": "進度 {done}/{goal}", "scout.intent": "我想找/回應", "scout.keyword": "關鍵字", "scout.intentPh": "例:換季頭皮刺癢、真的無香、週末有插座", "scout.keywordPh": "例:週末 咖啡 遠端", "scout.productOptional": "產品(選填)", "scout.noProduct": "不帶產品", "scout.brandFallback": "品牌", "scout.placement": "置入:{label}", "scout.painPart": " · 痛點「{pain}」", "scout.noProductsBefore": "尚無產品,可到", "scout.noProductsAfter": "新增。", "scout.start": "開始", "scout.startMore": "再撈一批", "scout.fetching": "撈取中…", "scout.runs": "海巡批次", "scout.runCount": "批次({n})", "scout.runSelectAria": "切換海巡批次", "scout.runPending": "待回 {n} · ", "scout.runDone": "已清完 · ", "scout.runTotal": "({n} 則)", "scout.deleteRun": "刪除這一批", "scout.deleting": "刪除中…", "scout.now": "現在這一則", "scout.emptyBatch": "這一批沒有待回", "scout.draft": "回覆草稿", "scout.draftPhActivity": "短回…", "scout.draftPhValue": "共感 → 建議…", "scout.sendAccount": "用哪個帳號送", "scout.noAccount": "無可用帳號", "scout.personaForRegen": "人設(再產用)", "scout.notReady": "(未就緒)", "scout.skip": "略過", "scout.regen": "再產", "scout.send": "發送", "scout.sending": "發送中…", "scout.needAccountBefore": "請先到", "scout.needAccountAfter": "連線可用帳號。", "scout.knowledge": "周邊知識", "scout.knowledgeWithLabel": "周邊知識 · {label}", "scout.knowledgeLearn": "周邊知識 · 可學", "scout.collapseKnowledge": "收合知識", "scout.expandLearn": "展開學習 · {n} 則", "scout.expandKnowledge": "展開知識", "scout.deleteKnowledgeRun": "刪除此批知識與命中", "scout.loadingKnowledge": "正在整理周邊知識…", "scout.notesCount": "{n} 則", "scout.noKnowledge": "尚無周邊知識", "scout.product": "產品", "scout.painsSolved": "能解的痛", "scout.focus": "焦點", "scout.all": "全部", "scout.noWebSummary": "尚無網頁摘要", "scout.queue": "佇列 · {n}", "scout.collapseQueue": "收合佇列", "scout.expandQueue": "展開佇列", "scout.noOtherPending": "沒有其他待回", "scout.learnPoints": "學習重點", "scout.replyHooks": "回帖可借", "scout.badgeCore": "最貼主題", "scout.unnamedRun": "未命名批次", "scout.thisRun": "此批次", "scout.confirmDeleteRun": "刪除海巡批次「{label}」?\\n會一併刪除這批命中與周邊知識,無法復原。", "scout.deletedRun": "已刪除批次「{label}」", "scout.deleteRunFail": "刪除批次失敗", "scout.needKeyword": "先填關鍵字", "scout.needIntent": "先寫這次要找什麼", "scout.productMissing": "所選產品不在列表中,請重新選擇", "scout.defaultLabel": "海巡", "scout.newRunActivity": "新批次「{label}」· {n} 則待回", "scout.newRunValue": "新批次「{label}」· {n} 則 · 請處理「現在這一則」", "scout.knowledgeReady": "「{label}」周邊知識已備好 · {n} 則可學", "scout.patrolFail": "這輪海巡失敗", "scout.draftFail": "產草稿失敗", "scout.skipped": "已略過", "scout.noDraft": "沒有可發送的草稿", "scout.accountFallback": "帳號", "scout.sent": "已發送(@{who})· 今日 {done}/{goal}", "scout.sendFail": "發送失敗", "scout.confirmDeletePost": "刪除這則命中?", "scout.stanceActivity": "短回 · 養活躍", "scout.stanceProduct": "共感 · 可輕帶產品", "scout.stanceRelation": "接話 · 建關係", "scout.tier.core": "最貼主題", "scout.tier.coreHint": "直接對準痛點/關鍵語,優先讀", "scout.tier.adjacent": "相關周邊", "scout.tier.adjacentHint": "鄰近情境,擴搜尋面", "scout.tier.broad": "最廣泛", "scout.tier.broadHint": "背景與對照,選讀即可", "scout.relation.solves_pain": "對準痛點", "scout.relation.nearby_scene": "鄰近場景", "scout.relation.myth": "迷思澄清", "scout.relation.contrast": "對照選購", "scout.relation.background": "背景脈絡", "brands.title": "品牌", "brands.railAria": "品牌列表", "brands.railLabel": "你的牌子", "brands.add": "新增", "brands.brandName": "品牌名稱", "brands.brandNamePh": "例如:自家品牌", "brands.creating": "建立中…", "brands.createBrand": "建立品牌", "brands.searchAria": "搜尋品牌", "brands.searchPh": "搜尋品牌…", "brands.empty": "尚無品牌", "brands.noMatch": "無符合", "brands.selectAria": "選擇品牌", "brands.pickOne": "選一個品牌", "brands.inUseHint": "使用中 · 海巡與創作會套用此牌", "brands.inUse": "使用中", "brands.tabInfo": "牌子資料", "brands.tabProducts": "產品", "brands.tabProductsN": "產品({n})", "brands.displayName": "名稱", "brands.brief": "摘要", "brands.briefPh": "一句話說明這個牌子", "brands.audience": "受眾", "brands.audiencePh": "誰會在意、為什麼", "brands.goals": "目標", "brands.goalsPh": "想在 Threads 達成什麼", "brands.saving": "儲存中…", "brands.deleteBrand": "刪除品牌", "brands.searchProductAria": "搜尋產品", "brands.searchProductPh": "搜尋產品…", "brands.addProduct": "新增產品", "brands.noProducts": "尚無產品", "brands.hasLink": "有連結", "brands.painLabel": "痛點 ", "brands.editProduct": "編輯產品", "brands.newProduct": "新增產品", "brands.importFromUrl": "從商品連結帶入", "brands.fetching": "抓取中…", "brands.fetch": "抓取", "brands.pains": "痛點", "brands.painsPh": "一列一個", "brands.tags": "標籤", "brands.tagsPh": "逗號分隔", "brands.intro": "介紹", "brands.link": "連結", "brands.update": "更新", "brands.createItem": "新增", "brands.needName": "請輸入名稱", "brands.created": "已建立「{name}」", "brands.createFail": "建立失敗", "brands.saved": "已儲存", "brands.saveFail": "儲存失敗", "brands.confirmDelete": "確定刪除「{name}」?", "brands.deleted": "已刪除", "brands.deleteFail": "刪除失敗", "brands.fetchFail": "抓取失敗", "brands.needLabelContext": "名稱與介紹為必填", "brands.productUpdated": "已更新", "brands.productAdded": "已新增", "brands.confirmDeleteProduct": "刪除此產品?", "insights.title": "帳號成效", "insights.account": "帳號", "insights.noAccount": "尚無帳號", "insights.syncing": "同步中…", "insights.syncPosts": "同步貼文", "insights.myPosts": "我的貼文", "insights.pickAccount": "選擇帳號", "insights.goAccounts": "帳號", "insights.kpiMonth": "本月指標", "insights.monthViews": "本月瀏覽", "insights.monthLikes": "本月讚", "insights.monthReplies": "本月回覆", "insights.engRate": "互動率", "insights.vsPrev": "vs 上月", "insights.avgNear": "近帖均 {rate}", "insights.trendTitle": "趨勢與分析 · @{user}", "insights.metricViews": "瀏覽", "insights.metricLikes": "讚", "insights.metricReplies": "回覆", "insights.metricPosts": "貼文", "insights.metricPostsFull": "貼文數", "insights.chartMetrics": "圖表指標", "insights.barsAria": "近月{metric},點柱查看該月分析", "insights.barsLabel": "{metric} · 近 {n} 個月", "insights.clickBar": " · 點柱看分析", "insights.pickMonthAria": "選擇月份", "insights.barTitle": "{label}:{value}{est} · 點看分析", "insights.est": "(估)", "insights.monthSuffix": "{m}月", "insights.sparkAria": "趨勢折線,點節點可選月", "insights.analysisOf": "{label} 分析", "insights.producedAt": "產出於 {time}", "insights.hasEstimate": " · 含估測數據", "insights.viewsVsPrev": " · 瀏覽 vs 前月 {delta}", "insights.statPosts": "貼文", "insights.statViews": "瀏覽", "insights.statLikes": "讚", "insights.statReplies": "回", "insights.conclusions": "結論", "insights.recommendations": "建議", "insights.highlights": "當月亮點", "insights.findTopics": "找話題", "insights.goScout": "去探查", "insights.selectMonth": "選擇月份", "insights.topPosts": "表現較佳貼文", "insights.noPosts": "尚無貼文", "insights.postStats": "瀏覽 {views} · 讚 {likes} · 回 {replies}", "insights.openThreads": "開啟 Threads", "insights.zeroPct": "0%", "plays.tabOwn": "我的貼文", "plays.tabLink": "Threads 連結", "plays.noPosts": "尚無貼文", "plays.targetPost": "目標貼文", "plays.likesSuffix": " (讚{n})", "plays.linkCard": "貼 Threads 連結", "plays.postLink": "貼文連結", "plays.resolving": "解析中…", "plays.resolve": "解析連結", "plays.resolveHint": "解析後可排自家帳號在該則下面回覆。", "plays.targetOwn": "目標貼文(自己的)", "plays.openThreads": "開 Threads", "plays.external": "外站貼", "plays.addScheme": "新增方案", "plays.schemeCount": "此目標目前 {n} 個方案", "plays.noSchemes": "尚無方案", "plays.replyCount": "{n} 則留言", "plays.editTitle": "編輯:{title}", "plays.schemeName": "方案名稱", "plays.schemeNamePh": "例如:方案 A · 溫和接話", "plays.speakersOwn": "可出場帳號(貼主帳固定可回)", "plays.speakers": "可出場帳號", "plays.postOwner": "(貼文主帳)", "plays.noAccounts": "沒有可用帳號,請先到設定連線 Threads。", "plays.interval": "間隔(分)", "plays.applyInterval": "套用間隔", "plays.aiEmpty": "空白則 AI", "plays.aiBusy": "產文中…", "plays.replies": "留言({n})", "plays.stepN": "第 {n} 則", "plays.who": "誰留", "plays.personaOpt": "人設(選填)", "plays.brandOpt": "品牌(選填)", "plays.reply": "留言", "plays.attach": "附圖", "plays.addOne": "加一則", "plays.saving": "儲存中…", "plays.saveScheme": "儲存方案", "plays.submitting": "送出中…", "plays.submitOutbox": "送出到 Outbox", "plays.closeEdit": "關閉編輯", "plays.noTarget": "還沒有目標貼文", "plays.resolved": "已解析連結", "plays.resolveFail": "解析失敗", "plays.filled": "已產 {n} 則", "plays.needTarget": "請先選定目標貼文", "plays.saved": "方案已儲存", "plays.saveFail": "儲存失敗", "plays.submitted": "已送進 Outbox", "plays.submitFail": "送出失敗", "plays.confirmDelete": "刪除此方案?", "plays.accountFallback": "帳號", "inspire.loading": "載入中…", "inspire.trendsAria": "最近 Threads 夯什麼", "inspire.trendsLabel": "最近 Threads 夯", "inspire.refresh": "刷新", "inspire.clearChat": "清空對話", "inspire.pinAsElement": "套用為元素", "inspire.you": "你", "inspire.ai": "AI", "inspire.system": "系統", "inspire.useDraft": "用這則寫", "inspire.openPlay": "開串場", "inspire.generating": "產文中…", "inspire.thinking": "思考中…", "inspire.pinnedAria": "本輪已套用", "inspire.pinned": "已套用", "inspire.pickRight": "右側點選元素", "inspire.unpinTitle": "點擊取消套用", "inspire.inputAria": "跟 AI 說", "inspire.inputPh": "想寫什麼?或改短一點、更口語…", "inspire.send": "送出", "inspire.generate": "產文", "inspire.library": "元素庫", "inspire.addNew": "+ 新增", "inspire.kind": "類型", "inspire.kindRole": "角色指令", "inspire.kindSnippet": "片段", "inspire.kindTrendNote": "熱點備註", "inspire.kindBrand": "品牌", "inspire.kindTrend": "熱點", "inspire.name": "名稱", "inspire.namePh": "例如:專業 Threads 寫手", "inspire.body": "內容(會進 prompt)", "inspire.bodyPh": "你是一位…", "inspire.saveElement": "存進元素庫", "inspire.citeBrand": "引用品牌", "inspire.applied": "已套用", "inspire.clickApply": "點擊套用", "inspire.noBrands": "尚無品牌", "inspire.appliedToggle": "已套用 · 再點取消", "inspire.deleteAria": "刪除", "inspire.needInput": "先輸入一句,或直接產文", "inspire.fail": "失敗", "inspire.wantWrite": "想寫關於 {label}:{summary}", "inspire.trendBody": "主題:{label}。{summary}", "inspire.pinnedTrend": "已套用熱點 {label}", "inspire.needTitleBody": "請填名稱與內容", "inspire.added": "已加入元素庫", "inspire.addFail": "新增失敗", "inspire.confirmRemove": "從元素庫移除此項?", "inspire.confirmClear": "清空對話?(元素庫保留)", "inspire.genMessage": "請依已套用元素寫一則 Threads", "persona.add": "新增人設", "persona.empty": "尚無人設", "persona.emptyDesc": "新增後做分析即可用於產文。", "persona.statusReady": "ready", "persona.statusAnalyzing": "分析中", "persona.statusPending": "待分析", "persona.default": "預設", "persona.backList": "← 人設列表", "persona.tabOverview": "概要", "persona.tabAnalyze": "分析", "persona.tabFingerprint": "指紋", "persona.tabPreview": "試產", "persona.name": "名稱", "persona.brief": "定位 brief", "persona.briefPh": "是誰、對誰說、核心訊息…", "persona.avoid": "護欄 · 禁止詞(逗號分隔)", "persona.guardChars": "{n} 字", "persona.banAi": " · 禁 AI 腔", "persona.notReadySuffix": " · 未就緒", "persona.setDefault": "設為預設", "persona.modeAccount": "公開帳號", "persona.modeText": "貼文字", "persona.username": "Threads username", "persona.fromBound": "從已綁帳號帶入", "persona.select": "選擇…", "persona.crawlAnalyze": "爬公開貼文並分析", "persona.crawlBusy": "爬取/分析中…", "persona.refText": "參考文字(--- 分隔多篇)", "persona.refTextPh": "第一段…\n\n---\n\n第二段…", "persona.sourceLabel": "來源說明(選填)", "persona.sourcePh": "自己的舊文", "persona.analyzeText": "從文字分析", "persona.analyzeBusy": "分析中…", "persona.sampleMeta": "樣本 {n}", "persona.sourceManual": "貼文", "persona.analyzeHint": "完成分析後會顯示 8D 摘要。", "persona.fingerprintHint": "產文主體。可改口頭禪、節奏、禁忌;儲存後 Studio/回覆會吃這份。", "persona.fingerprint": "語言指紋", "persona.fingerprintPh": "分析後自動填入…", "persona.saveFingerprint": "儲存指紋", "persona.tryGen": "試產主貼 + 回覆", "persona.notReadyMsg": "人設未就緒", "persona.rootPost": "主貼", "persona.reply": "回覆", "persona.hidePrompt": "隱藏 prompt block", "persona.showPrompt": "顯示注入的 prompt", "persona.promptBlock": "prompt block(post)", "persona.pickOne": "選一個人設", "persona.pickDesc": "或按新增開始分析。", "persona.created": "已建立,請到「分析」完成帳號爬取或貼文字", "persona.saved": "已儲存", "persona.textDone": "文字分析完成 · {n} 段 → ready", "persona.analyzeFail": "分析失敗", "persona.reading": "正在讀取公開貼文…", "persona.accountDone": "@{user} · {n} 則 → ready", "persona.setDefaultMsg": "「{name}」已設為預設", "persona.confirmDelete": "確定刪除人設「{name}」?", "persona.deleted": "人設已刪除", "persona.needReady": "請先完成分析(ready)", "persona.dim.d1Tone": "D1 語氣人格", "persona.dim.d2Structure": "D2 結構模板", "persona.dim.d3Interaction": "D3 互動方式", "persona.dim.d4Topics": "D4 主題分布", "persona.dim.d5Rhythm": "D5 發文節奏", "persona.dim.d6Visual": "D6 視覺語法", "persona.dim.d7Conversion": "D7 轉換方式", "persona.dim.d8Risk": "D8 風險紅線", "admin.users.loadFail": "載入失敗", "admin.users.created": "已新增島民「{name}」· 請複製下方密碼", "admin.users.createFail": "新增失敗", "admin.users.unlimitedOn": "「{name}」已設不擋額度(用量仍計算)", "admin.users.unlimitedOff": "「{name}」已改回依方案擋額度", "admin.users.updateFail": "更新失敗", "admin.users.planSet": "「{name}」方案 → {plan}", "admin.users.confirmSuspend": "確定停權「{name}」?\\n停權後無法登入。", "admin.users.confirmUnsuspend": "確定復權「{name}」?\\n復權後可重新登入。", "admin.users.didSuspend": "已停權「{name}」", "admin.users.didUnsuspend": "已復權「{name}」", "admin.users.suspendFail": "停權失敗", "admin.users.unsuspendFail": "復權失敗", "admin.users.markedVerified": "已將 {name} 標為信箱已驗證", "admin.users.markedUnverified": "已將 {name} 標為未驗證", "admin.users.rolesUpdated": "已更新 {name} 的權限:{roles}", "admin.users.rolesFail": "權限更新失敗", "admin.users.confirmReset": "確定幫「{name}」重設密碼?\\n臨時密碼會固定顯示直到你按關閉(可重整)。", "admin.users.resetDone": "已重設 {name} 的密碼(下方可持續顯示,請複製後再關閉)", "admin.users.resetFail": "重設失敗", "admin.users.copied": "已複製到剪貼簿", "admin.users.copyFail": "複製失敗,請手動選取密碼", "admin.users.confirmDismissTemp": "關閉後此頁將不再顯示這組臨時密碼(若尚未複製請先複製)。確定關閉?", "admin.users.tempPwNew": "新島民臨時密碼", "admin.users.tempPw": "臨時密碼", "admin.users.tempPwPersist": "(持續顯示 · 可重整)", "admin.users.copyPw": "複製密碼", "admin.users.close": "關閉", "admin.users.createTitle": "新增島民", "admin.users.memberName": "島民名稱", "admin.users.displayNamePh": "顯示名稱", "admin.users.email": "Email", "admin.users.initPassword": "初始密碼(選填)", "admin.users.initPasswordPh": "空白則自動產生;若填寫須符合密碼政策", "admin.users.markVerifiedCheck": "信箱標為已驗證(可直接使用)", "admin.users.alsoAdmin": "同時設為管理員", "admin.users.creating": "建立中…", "admin.users.createSubmit": "建立島民", "admin.users.clear": "清除", "admin.users.searchActive": "搜尋「{query}」· 可匹配名稱、Email、uid", "admin.users.noMatch": "無符合", "admin.users.none": "尚無島民", "admin.users.you": "這是你", "admin.users.status": "狀態", "admin.users.role": "角色", "admin.users.emailVerify": "信箱驗證", "admin.users.bio": "簡介", "admin.users.timezone": "時區", "admin.users.notifyEmail": "Email 通知", "admin.users.on": "開", "admin.users.off": "關", "admin.users.createdAt": "建立", "admin.users.updatedAt": "更新", "admin.users.accountStatus": "帳號狀態", "admin.users.updating": "更新中…", "admin.users.usageTitle": "用量與方案", "admin.users.usageLiveSkip": "方案/額度屬 Usage 域,live 後端尚未接上(M3);此區僅 mock 可改。", "admin.users.plan": "方案", "admin.users.planOption": "{name}({credits} 點/月)", "admin.users.unlimited": "不擋額度", "admin.users.byPlan": "依方案", "admin.users.setUnlimited": "設為不擋額度", "admin.users.setLimited": "改回擋額度", "admin.users.unlimitedHint": "不擋額度:達方案上限仍可繼續用;AI/Search 次數與點數照樣計算。", "admin.users.loadingUsage": "載入用量設定…", "admin.users.assignRoles": "指派權限", "admin.users.memberBase": "{role}(基底,不可關閉)", "admin.users.adminDesc": "{role} — 可管理島民與系統", "admin.users.saving": "儲存中…", "admin.users.saveRoles": "儲存權限", "admin.users.markUnverifiedBtn": "標為未驗證", "admin.users.markVerifiedBtn": "標為已驗證", "admin.users.resetting": "重設中…", "admin.users.resetTemp": "重設密碼(產生臨時)", "admin.users.customPw": "或指定新密碼(選填)", "admin.users.customPwPh": "密碼須至少 12 碼,且含大寫、小寫、數字與符號", "admin.users.resetWithCustom": "用指定密碼重設", "usage.tabMine": "我的用量", "usage.tabTenant": "全體用量", "usage.currentPlan": "目前方案", "usage.planMeta": "/月 · 每月 {n} 點額度", "usage.changePlan": "變更方案", "usage.usedThisMonth": "本月已用", "usage.remainLabel": "剩餘", "usage.ledgerToggle": "使用紀錄", "usage.collapse": "收合", "usage.eventsCount": "{n} 筆", "usage.granularity": "粒度", "usage.day": "日", "usage.monthUnit": "月", "usage.year": "年", "usage.from": "起", "usage.to": "迄", "usage.callCounts": "呼叫次數", "usage.noMembers": "尚無會員", "usage.planAria": "{name} 方案", "usage.unlimitedTitle": "不擋額度", "usage.setLimited": "改回擋額度", "usage.setUnlimited": "設為不擋額度", "usage.limitShort": "擋", "usage.subscribed": "已訂閱 {name}", "usage.unlimitedSet": "已設不擋額度", "usage.limitedSet": "已改回擋額度", "usage.planUpdated": "已更新方案 {name}", "usage.fail": "失敗", "currency.TWD": "新台幣 (TWD)", "currency.USD": "美元 (USD)", "currency.JPY": "日圓 (JPY)", "currency.EUR": "歐元 (EUR)", "currency.HKD": "港幣 (HKD)", "locale.zh-TW": "繁體中文", "locale.en": "English", "pager.nav": "分頁", "pager.pageSize": "每頁筆數", "pager.perPage": "{n}/頁", "pager.prev": "上一頁", "pager.next": "下一頁", "plays.defaultTitle": "新方案", "plays.topicOnPost": "掛在:{snippet}", "plays.topicOnExternal": "掛在:{label} · {snippet}", "plays.externalFallback": "外站貼", "persona.newName": "新人設", "persona.previewTopic": "週末想找能坐久的咖啡店", "persona.previewReplySample": "大安那間還行但人很多", "inspire.playTitle": "靈感串場", "wizard.topic.fallbackTopic": "生活小題", "play.err.needLead": "請選擇主帳號", "play.err.needRoot": "請至少有一則主貼", "play.err.firstMustRoot": "第一則必須是主貼", "play.err.rootMustLead": "主貼必須使用主帳", "play.err.rootEmpty": "主貼文案不可空白", "play.err.replyAccount": "回覆只能用主帳或已選配角", "play.err.replyEmpty": "回覆文案不可空白", "play.err.needTarget": "請選擇自己的貼文,或貼上 Threads 連結", "play.err.needReplies": "請至少排 1 則留言", "play.err.needReplyAccounts": "請至少選一個可回覆帳號", "play.err.stepAccount": "每則留言都要指定可用帳號", "play.err.stepEmpty": "留言內容不可空白", "play.err.notFound": "找不到互回方案", "time.justNow": "剛剛", "time.minAgo": "{n} 分前", "time.hourAgo": "{n} 小時前", "time.dayAgo": "{n} 天前", "time.min": "{n} 分鐘", "time.hour": "{n} 小時", "time.day": "{n} 天", "time.expired": "已過期 {span}", "time.remaining": "剩餘 {span}", "time.sessionUnknown": "Session 未記錄", "time.sessionExpired": "Session 已過期 · {absolute}", "time.sessionSoon": "Session 即將到期 · {relative}({absolute})", "time.sessionOk": "Session 有效 · {relative}({absolute})", }; export const en: MessageDict = { "app.name": "Lapras", "app.nameEn": "Lapras", "app.nameZh": "巡樓", "app.tagline": "Patrol Threads with ease", "app.taglineEn": "Patrol Threads with ease", "nav.today": "Today", "nav.crew": "Accounts", "nav.studio": "Studio", "nav.scout": "Patrol", "nav.outbox": "Outbox", "nav.jobs": "Jobs", "nav.brands": "Brands", "nav.more": "More", "nav.moreTitle": "More", "nav.users": "Islanders", "nav.usage": "Usage & plans", "nav.profile": "Profile", "nav.invite": "Invites", "nav.settings": "Settings", "nav.logout": "Log out", "nav.navigate": "Navigate", "common.save": "Save", "common.cancel": "Cancel", "common.loading": "Loading…", "common.back": "Back", "common.delete": "Delete", "common.edit": "Edit", "common.search": "Search", "common.confirm": "Confirm", "common.optional": "Optional", "common.success": "Saved", "common.error": "Something went wrong", "common.yes": "Yes", "common.no": "No", "api.err.unknown": "Something went wrong. Please try again.", "api.err.network": "Cannot reach the server. Check your network or if the API is running.", "api.err.400001": "Invalid request", // Same sentence as backend 400003 / ValidatePasswordPolicy "api.err.400003": "Password must be at least 12 characters with upper, lower, digit, and symbol", "password.policy.hint": "Password must be at least 12 characters with upper, lower, digit, and symbol", "password.policy.minLen": "Password must be at least 12 characters with upper, lower, digit, and symbol", "password.policy.needUpper": "Password must be at least 12 characters with upper, lower, digit, and symbol", "password.policy.needLower": "Password must be at least 12 characters with upper, lower, digit, and symbol", "password.policy.needDigit": "Password must be at least 12 characters with upper, lower, digit, and symbol", "password.policy.needSymbol": "Password must be at least 12 characters with upper, lower, digit, and symbol", "api.err.400004": "Invalid or expired verification code", "api.err.400020": "You cannot suspend your own account", "api.err.400021": "Cannot demote or suspend the last active admin", "api.err.401001": "Please sign in", "api.err.401002": "Session expired. Please sign in again.", "api.err.401003": "Account not found. Please sign in again.", "api.err.401010": "Invalid email or password", "api.err.403001": "Account suspended", "api.err.403002": "Admin access required", "api.err.404001": "Not found", "api.err.404002": "This email is not registered", "api.err.409001": "This email is already registered", "api.err.500000": "Server error. Please try again later.", "api.err.501000": "This feature is not implemented yet", "api.ok.verifySent": "Verification code sent. Please check your email.", "api.ok.verifyIssued": "Verification code issued", "api.ok.resetSent": "Reset email sent. Please check your inbox.", "api.ok.passwordUpdated": "Password updated", "api.ok.loggedOut": "Signed out", "api.ok.unbound": "Unbound", "topbar.notifications": "Notifications", "topbar.unread": "{n} unread", "topbar.markAllRead": "Mark all read", "topbar.noNotifications": "No notifications", "topbar.jobsCenter": "Job center", "topbar.moreOlder": "{n} older", "topbar.account": "Account menu", "role.admin": "Admin", "role.member": "Member", "role.verified": "Verified", "role.unverified": "Unverified", "login.title": "Sign in to Lapras", "login.email": "Email", "login.password": "Password", "login.submit": "Sign in", "login.submitting": "Signing in…", "login.forgot": "Forgot password?", "login.mockHint": "Admin demo@harbor.local / demo · member alice@harbor.local / alice", "login.liveHint": "Live backend: admin@haixun.local / admin123 (gateway :8888)", "forgot.title": "Forgot password", "forgot.submit": "Send reset link", "forgot.submitting": "Sending…", "forgot.back": "Back to sign in", "forgot.hint": "Enter your registered email. We'll send a reset link and code.", "forgot.mockMail": "Reset email", "forgot.openReset": "Enter code / reset password", "forgot.retry": "Try again", "forgot.nextStep": "Check your email for the code or link, then open the reset page to set a new password.", "reset.title": "Set new password", "reset.hint": "Enter email, verification code (from the email), and a new password.", "reset.code": "Verification code", "reset.codePh": "6-digit code from email", "reset.needEmail": "Email is required", "reset.needCode": "Verification code is required", "reset.newPassword": "New password", "reset.confirm": "Confirm password", "reset.submit": "Update password", "reset.submitting": "Updating…", "reset.missingToken": "Missing token. Please request a new reset link.", "verify.title": "Verify email", "verify.pending": "Not verified", "verify.body": "You're signed in, but features stay locked until you verify your email with the 6-digit code.", "verify.code": "Verification code", "verify.submit": "Verify", "verify.submitting": "Verifying…", "verify.resend": "Resend code", "verify.sending": "Sending…", "verify.logout": "Log out", "verify.mockMail": "Verification email", "verify.mockHint": "Enter the code:", "verify.after": "After verification you can use Today, Studio, Patrol, and more.", "settings.title": "Settings", "settings.localeCurrency": "Language & currency", "settings.locale": "Interface language", "settings.currency": "Display currency", "settings.currencyHint": "", "settings.localeSaved": "Language and currency updated", "settings.appearance": "Appearance", "settings.theme": "Theme", "settings.themeLight": "Light", "settings.themeDark": "Dark", "settings.themeSystem": "System", "settings.themeHint": "", "settings.themeSaved": "Theme updated", "settings.themeToLight": "Switch to light", "settings.themeToDark": "Switch to dark", "settings.dataSource": "Data source", "settings.dataSourceHint": "mock = in-browser fake data; live = apps/backend gateway. Re-login after switching to live.", "settings.dataSourceMock": "Mock (local)", "settings.dataSourceLive": "Live (backend API)", "settings.dataSourceCurrent": "Current", "settings.dataSourceSwitchedLive": "Switched to Live — re-login with backend account (admin@haixun.local / admin123)", "settings.dataSourceSwitchedMock": "Switched back to Mock", "settings.dataSourceLiveNeedGateway": "Requires gateway on :8888 (or Vite proxy /api)", "settings.ai": "AI", "settings.search": "Search", "settings.member": "Account & sign-in", "settings.usageCard": "AI / search quota", "settings.usageCardHint": "", "settings.viewUsage": "View usage", "settings.editProfile": "Edit profile", "settings.mockLogin": "demo@harbor.local / demo", "settings.memberHint": "", "usage.title": "Usage & plans", "usage.desc": "", "usage.creditsUsed": "Credits used this month", "usage.remaining": "{n} left", "usage.percentUsed": "{n}% used", "usage.breakdown": "Breakdown", "usage.plans": "Plans", "usage.current": "Current", "usage.inUse": "Active", "usage.switchMock": "Switch plan", "usage.perMonth": "credits / mo", "usage.ledger": "Recent usage", "usage.emptyTitle": "No usage this month", "usage.emptyDesc": "", "usage.planNote": "", "usage.switched": "Switched to {name}", "usage.meter.times": "{count} runs · {credits} credits", "usage.meter.cap": "Soft cap {count}/{cap} runs", "usage.plan.free.blurb": "Trial and light personal use", "usage.plan.starter.blurb": "Small teams posting and patrolling daily", "usage.plan.pro.blurb": "Multi-account, heavy AI and research", "profile.title": "Profile", "profile.desc": "", "profile.accountStatus": "Account status", "profile.basic": "Basics", "profile.avatar": "Avatar", "profile.avatarUpload": "Upload avatar", "profile.avatarRemove": "Remove avatar", "profile.avatarHint": "JPG / PNG / WebP, up to 5MB. Pick a file then Save basic info; Remove clears immediately.", "profile.avatarSaved": "Avatar updated", "profile.avatarCleared": "Avatar removed", "profile.avatarFail": "Could not read image", "profile.displayName": "Display name", "profile.bio": "Bio (optional)", "profile.timezone": "Timezone", "profile.notifyEmail": "Email notifications", "profile.password": "Change password (optional)", "profile.currentPassword": "Current password", "profile.newPassword": "New password", "profile.confirmPassword": "Confirm new password", "profile.emailVerified": "Email verified", "profile.emailUnverified": "Email not verified", "profile.roleAdmin": "Admin", "profile.roleMember": "Member", "profile.loginEmail": "Sign-in email: {email}", "profile.verifiedAt": " · verified {time}", "profile.goVerify": "Verify email", "profile.roleTags": "Role tags: {labels}", "profile.roleNote": "Roles are assigned by the system; re-verify after changing email.", "profile.saveBasic": "Save profile", "profile.updatePassword": "Update password", "profile.saved": "Profile saved", "profile.savedUnverified": "Saved. Verify your email before using features.", "profile.saveFail": "Could not save", "profile.needNewPassword": "Enter a new password", "profile.passwordMismatch": "New passwords do not match", "profile.needCurrentPassword": "Enter your current password", "profile.wrongCurrentPassword": "Current password is incorrect", "profile.passwordUpdated": "Password updated", "profile.passwordFail": "Could not change password", "profile.listJoin": ", ", "profile.tenantUid": " · tenant {tenant} · uid {uid}", "profile.inviteBadge": "Invite code", "profile.inviteHint": "Share with friends to join; later events can use invite relations.", "profile.gotoInvite": "View invites", "invite.title": "Invites", "invite.desc": "Invite codes and relations; admin view is a tree.", "invite.tabs": "Invite views", "invite.tab.mine": "My invites", "invite.tab.tree": "Tree", "invite.myCode": "My invite code", "invite.codeLabel": "Invite code", "invite.copyCode": "Copy", "invite.copied": "Copied", "invite.copyFail": "Copy failed", "invite.stats": "{direct} direct · {total} in chain", "invite.upline": "Invited by", "invite.downlines": "Direct invites · {n}", "invite.noUpline": "No inviter", "invite.noDownline": "None yet", "invite.directN": "{n} direct", "invite.claimHint": "If you didn’t enter a code at signup, add your inviter’s code here (cannot change later).", "invite.claimLabel": "Invite code", "invite.claimPh": "e.g. HX-DEMO01", "invite.claimSubmit": "Bind", "invite.claimOk": "Bound to {name}", "invite.claimOkGeneric": "Inviter bound", "invite.claimFail": "Could not bind", "invite.claimLocked": "Already bound. Contact an admin to change.", "invite.loadFail": "Failed to load", "invite.treeEmpty": "No data", "invite.treeSearch": "Search", "invite.treeSearchPh": "Name / email / code", "invite.treeCount": "{n} people", "invite.treeMatchCount": "{n} matches · {total} total", "invite.treeNoMatch": "No matches", "invite.treeNoMatchHint": "Try another keyword", "invite.clearSearch": "Clear", "invite.moveTitle": "Reassign", "invite.newParent": "Inviter", "invite.root": "(None · standalone)", "invite.confirmMove": "Confirm", "invite.moved": "Reassigned “{name}” → “{parent}”", "invite.moveFail": "Failed", "invite.openFromAdmin": "Invites", "invite.parentField": "Invited by", "invite.orgPickRoot": "Pick a starting root (includes self-joined)", "invite.orgRoots": "Roots", "invite.orgPath": "Path", "invite.orgChainN": "{n} in chain", "invite.orgFocusStats": "{direct} direct · {total} in chain", "invite.orgDirects": "Direct invites · {n}", "invite.orgNoDirects": "No direct invites", "invite.err.notFound": "Member not found", "invite.err.notLoggedIn": "Not signed in", "invite.err.needAdmin": "Admin access required", "invite.err.memberNotFound": "Islander not found", "invite.err.selfParent": "Cannot set yourself as inviter", "invite.err.parentNotFound": "Inviter not found", "invite.err.cycle": "Cannot place under your own invite chain (would create a cycle)", "invite.err.repoMissing": "Invite data layer not loaded — please refresh the page", "invite.err.alreadyBound": "You already have an inviter", "invite.err.codeRequired": "Enter an invite code", "invite.err.codeNotFound": "Invite code not found", "invite.err.codeSelf": "You can’t use your own code", "admin.users.title": "Islanders", "admin.users.desc": "", "admin.users.needAdmin": "Admin access required", "admin.users.list": "Islanders · {n}", "admin.users.detail": "Islander detail", "admin.users.pick": "Select an islander", "admin.users.search": "Search name / uid", "admin.users.searchPh": "Name, email, or uid", "admin.users.create": "Add islander", "admin.users.suspend": "Suspend", "admin.users.unsuspend": "Restore", "admin.users.suspended": "Suspended", "admin.users.active": "Active", "crew.title": "Accounts", "crew.tab.accounts": "Accounts", "crew.tab.personas": "Personas", "crew.connect": "Connect account", "crew.connecting": "Adding…", "crew.refreshAll": "Refresh all sessions", "crew.refreshing": "Refreshing…", "crew.empty": "No accounts yet", "crew.unusable": "Unavailable", "crew.expires": "Expires {time}", "crew.lastRefresh": "Last refresh {time}", "crew.refreshSession": "Refresh session", "crew.session.ok": "Session valid", "crew.session.soon": "Expiring soon", "crew.session.expired": "Session expired", "crew.session.unknown": "Session unknown", "crew.msg.refreshed": "@{user} session refreshed (~30 days)", "crew.msg.refreshedAll": "Refreshed {n} account sessions", "crew.msg.refreshFail": "Refresh failed", "crew.confirmDelete": "Delete account @{user}?\nIt can no longer be used as lead / cast.", "today.findTopic": "Find topics", "today.pendingReplies": "Pending replies", "today.pendingRepliesN": "Pending · {n}", "today.newThread": "New thread", "today.metricsAria": "Today metrics", "today.metric.pending": "Pending", "today.metric.pendingHint": "Patrol queue", "today.metric.doneGoal": "Done / goal", "today.metric.sentToday": "Sent today", "today.metric.running": "{n} in progress", "today.metric.sentDone": "Completed sends", "today.metric.failed": "Send issues", "today.metric.needAction": "Needs action", "today.metric.ok": "All good", "today.pending.title": "Pending replies · {n}", "today.pending.empty": "Nothing pending", "today.goScout": "Go patrol", "today.pending.more": "{n} more →", "today.pending.handle": "Handle in patrol", "today.pending.start": "Start handling", "today.topics.title": "Find topics", "today.topics.empty": "No topics yet", "today.goStudio": "Go to Studio", "today.heat": "Heat {n}", "today.topicAngle": "Good opening angle", "today.moreInspire": "More inspiration", "today.useTopic": "Start from topic", "today.outbox.title": "Today's outbox", "today.outbox.empty": "No sends today. Try", "today.outbox.emptyMid": ", then check", "today.outbox.emptyEnd": ".", "today.outbox.summary": "Done {sent} · In progress {running} · Issues {failed}", "today.badge.failed": "Failed", "today.badge.scheduling": "Scheduled", "today.badge.sending": "Sending", "today.openOutbox": "Open outbox", "today.accounts.title": "Account performance", "today.accounts.empty": "No stats yet", "today.postsCount": "{n} posts", "today.views": "Views", "today.likes": "Likes", "today.repliesShort": "Replies", "today.fullInsights": "Full insights · MoM charts", "today.viewPosts": "View posts", "today.manageAccounts": "Manage accounts", "outbox.title": "Outbox", "outbox.tabsAria": "Outbox tabs", "outbox.tab.active": "Active", "outbox.tab.history": "History", "outbox.empty": "No outbox items", "outbox.activeEmpty": "Nothing in progress", "outbox.historyEmpty": "No history yet", "outbox.historyN": "History ({n})", "outbox.backActive": "Back to active ({n})", "outbox.progress": "Progress {progress}", "outbox.detail": "Details", "outbox.deleting": "Deleting…", "outbox.confirmDelete": "Delete outbox item “{title}”?\nThis cannot be undone.", "outbox.deleted": "Deleted “{title}”", "outbox.deleteFail": "Delete failed", "outbox.status.scheduling": "Scheduling", "outbox.status.active": "Sending", "outbox.status.completed": "Completed", "outbox.status.partial_failed": "Partial failure", "outbox.status.cancelled": "Cancelled", "outbox.detail.missingId": "Missing id", "outbox.detail.notFound": "Outbox item not found", "outbox.detail.markAllOk": "Mark all success", "outbox.detail.markRootFail": "Mark root failed", "outbox.detail.processing": "Working…", "outbox.detail.delete": "Delete this", "outbox.detail.back": "Back to list", "outbox.detail.root": "Root post", "outbox.detail.replyN": "Reply {n}", "outbox.detail.retry": "Retry", "outbox.detail.opFail": "Action failed", "studio.title": "Studio", "studio.account": "Account", "studio.persona": "Persona", "studio.personaReady": "Persona ready", "studio.personaNotReady": "Persona not ready", "studio.tab.posts": "My posts", "studio.tab.mentions": "Mentions @", "studio.tab.compose": "Compose", "studio.tab.plays": "Plays", "studio.tab.inspire": "Inspire", "studio.tab.insights": "Insights", "mentions.hint": "Who @ you. {n} pending. You can change account/persona per item (defaults from top bar).", "mentions.scoutLink": "Patrol outreach", "mentions.empty": "No mentions", "mentions.status.pending": "Pending", "mentions.status.replied": "Replied", "mentions.status.skipped": "Skipped", "mentions.reply": "Reply", "mentions.skip": "Skip", "mentions.draftLabel": "Reply draft", "mentions.repliedPrefix": "Replied: {text}", "mentions.needPersona": "Pick a ready persona before AI draft", "mentions.fail": "Failed", "mentions.marked": "Marked replied (@{user})", "mentions.withImages": " · {n} images", "compose.hint": "Single post (not a play). For multi-account threads use", "compose.hintEnd": ".", "compose.playsLink": "Plays", "compose.personaOff": "Persona not ready: AI tools (mimic / analyze) disabled.", "compose.title": "Title (optional)", "compose.titlePh": "Helps identify in Outbox", "compose.body": "Body", "compose.bodyPh": "Write your post…", "compose.tool.mimic": "Mimic", "compose.tool.viral": "Viral analysis", "compose.tool.research": "Research", "compose.tool.image": "Image", "compose.mimic.title": "Mimic another post", "compose.mimic.source": "Source text", "compose.mimic.sourcePh": "Paste the post to mimic…", "compose.mimic.running": "Mimicking…", "compose.mimic.run": "Mimic into body", "compose.mimic.done": "Mimic done — edit as needed", "compose.viral.title": "Viral analysis", "compose.viral.hint": "Hooks, structure, and copyable patterns from source or body.", "compose.viral.source": "Target (empty = use body)", "compose.viral.running": "Analyzing…", "compose.viral.run": "Analyze", "compose.viral.result": "Analysis", "compose.viral.done": "Viral analysis done", "compose.viral.needText": "Paste a reference or write the body first", "compose.research.title": "Research notes", "compose.research.q": "Keywords", "compose.research.qPh": "e.g. fragrance-free detergent sensitive skin", "compose.research.running": "Searching…", "compose.research.insert": "Insert selected into body", "compose.research.inserted": "Inserted {n} notes", "compose.image.title": "Generate image", "compose.image.prompt": "Scene description", "compose.image.promptPh": "Empty = summarize from body", "compose.image.running": "Generating…", "compose.image.run": "Generate image", "compose.image.done": "Image added", "compose.scheduleAt": "Publish at", "compose.scheduleHint": "Outbox will send at this time. Use “Now” for ASAP.", "compose.scheduleNow": "Now", "compose.publish": "Send to Outbox", "compose.publishing": "Sending…", "compose.publishFail": "Send failed", "compose.fail": "Failed", "compose.attachN": "{n} images", "compose.personaStatus": "Persona: {status}", "compose.ready": "ready", "compose.notReady": "not ready", "posts.sync": "Resync Threads", "posts.syncing": "Syncing…", "posts.syncedAt": "Synced {time}", "posts.notSynced": "Not synced", "posts.syncDone": "Synced Threads metrics (likes / replies / reposts / quotes / views / shares)", "posts.empty": "No posts yet", "posts.openThreads": "Open Threads", "posts.insight": "Insight: {text}", "posts.review": "Review: {text}", "posts.formulaResult": "Structure analysis", "posts.collapseReplies": "Collapse replies", "posts.repliesBtn": "Replies ({total}) · pending {pending}", "posts.replyRoot": "Reply to post", "posts.analyzing": "Analyzing…", "posts.reanalyze": "Re-analyze structure", "posts.analyze": "Analyze structure", "posts.mimicThis": "Mimic this", "posts.rootDraft": "Root reply draft", "posts.filter.pending": "Pending ({n})", "posts.filter.replied": "Replied ({n})", "posts.filter.all": "All ({n})", "posts.noPending": "No pending replies", "posts.noReplied": "No replied items yet", "posts.noReplies": "No replies yet", "posts.status.pending": "Pending", "posts.status.replied": "Replied", "posts.likesN": "{n} likes", "posts.childCount": "{n} child replies", "posts.mine": "Ours", "posts.replyThis": "Reply", "posts.replyAgain": "Reply again", "posts.replyTo": "Reply to @{user}", "posts.replyAgainTo": "Reply again to @{user}", "posts.needPersona": "Pick a ready persona before AI draft", "posts.genFail": "Generate failed", "posts.needText": "Generate or type a reply first", "posts.sent": "Sent as @{user}", "posts.sentImages": " ({n} images)", "posts.accountFallback": "account", "posts.sendFail": "Send failed", "posts.analyzeDone": "Structure analysis done (manual)", "posts.analyzeFail": "Analyze failed", "wizard.newTitle": "New play", "wizard.editTitle": "Edit play", "wizard.prev": "Back", "wizard.next": "Next", "wizard.err.topic": "Enter a topic", "wizard.err.lead": "Select a lead account", "wizard.err.leadUnusable": "Lead account unavailable", "wizard.submitFail": "Submit failed", "wizard.unnamedPlay": "Untitled play", "wizard.step.topic": "Topic", "wizard.step.crew": "Cast", "wizard.step.script": "Script", "wizard.step.preview": "Preview", "wizard.step.schedule": "Schedule", "wizard.step.submit": "Submit", "wizard.stepperAria": "Wizard steps", "wizard.topic.title": "1. What is this thread about?", "wizard.topic.name": "Title (optional)", "wizard.topic.namePh": "e.g. Weekend coffee", "wizard.topic.topic": "One-line topic", "wizard.topic.topicPh": "What should this thread discuss?", "wizard.topic.aiView": "AI persona view", "wizard.topic.personaNotReady": "Persona not ready", "wizard.topic.generating": "Generating…", "wizard.topic.aiSuggest": "AI suggest", "wizard.topic.quickFill": "Quick fill", "wizard.topic.sampleTitle": "Weekend coffee chat", "wizard.topic.sampleTopic": "Looking for a reliable café this weekend — lots of outlets, stay-all-day friendly.", "wizard.topic.aiTitle": "AI topic", "wizard.topic.personaOpen": "{name} opens", "wizard.crew.title": "2. Cast", "wizard.crew.lead": "Lead", "wizard.crew.noUsable": "No usable accounts", "wizard.crew.unusable": "Unavailable", "wizard.crew.cast": "Supporting", "wizard.script.title": "3. Lines", "wizard.script.persona": "Persona", "wizard.script.personaNotReady": "Persona not ready", "wizard.script.root": "Root post", "wizard.script.replyN": "Reply {n}", "wizard.script.generating": "Generating…", "wizard.script.ai": "AI draft", "wizard.script.account": "Account: {name}", "wizard.script.noLead": "(no lead)", "wizard.script.speaker": "Speaker", "wizard.script.leadTag": "(lead)", "wizard.script.text": "Copy", "wizard.script.rootPh": "Root post text…", "wizard.script.replyPh": "Reply text…", "wizard.script.addReply": "Add reply step", "wizard.preview.title": "4. Preview the thread", "wizard.preview.unknown": "Unknown", "wizard.preview.unknownAccount": "Unknown account", "wizard.preview.root": "Root", "wizard.preview.leadTalk": "lead reply", "wizard.preview.empty": "(empty)", "wizard.schedule.title": "5. When to send", "wizard.schedule.start": "First post (root) time", "wizard.schedule.interval": "Reply interval (minutes)", "wizard.schedule.intervalHint": "Relative to previous step", "wizard.submit.title": "6. Submit schedule", "wizard.submit.body": "Confirm to send “{title}” ({n} steps) to Outbox and publish in order.", "wizard.submit.unnamed": "Untitled", "wizard.submit.root": "Root", "wizard.submit.replyN": "Reply {n}", "wizard.submit.submitting": "Submitting…", "wizard.submit.run": "Submit to Outbox", "reply.account": "Reply as", "reply.persona": "Persona", "reply.notReady": "This persona is not ready for AI draft (you can still type and send).", "reply.draft": "Reply draft", "reply.attach": "Attach", "reply.generating": "Generating…", "reply.ai": "AI draft", "reply.sending": "Sending…", "reply.send": "Send", "image.attach": "Attach", "image.attachFail": "Attach failed", "image.attachedAria": "Attached images", "image.alt": "Attachment", "image.named": "Image {n}", "image.remove": "Remove image", "image.full": "Full ({max})", "image.more": "Add more ({n}/{max})", "metrics.aria": "Post metrics", "metrics.like": "Likes", "metrics.reply": "Replies", "metrics.repost": "Reposts", "metrics.quote": "Quotes", "metrics.view": "Views", "metrics.share": "Shares", "metrics.type.quote": "Quote", "metrics.type.reply": "Reply", "metrics.type.image": "Image", "metrics.type.video": "Video", "metrics.type.carousel": "Carousel", "metrics.type.repost": "Repost", "metrics.type.text": "Text", "metrics.type.post": "Post", "jobs.title": "Jobs", "jobs.startDemo": "Start demo job", "jobs.empty": "No jobs yet", "jobs.total": "{n} total", "jobs.showing": " · showing first {n}", "jobs.detail": "Details", "jobs.loadMore": "Load more ({n} more)", "jobs.notFound": "Job not found", "jobs.progress": "Progress {n}%", "jobs.updated": "Updated {time}", "jobs.backList": "Back to list", "plans.title": "Change plan", "plans.current": "Current plan", "plans.perMonth": "/mo", "plans.monthlyCredits": "{n} credits / month", "plans.usageLink": "Usage", "plans.inUse": "Active", "plans.recommended": "Recommended", "plans.creditsPerMonth": "{n} credits / month", "plan.cta.current": "Current plan", "plan.cta.upgrade": "Upgrade", "plan.cta.downgrade": "Downgrade", "plan.cta.switch": "Switch", "plan.free.headline": "Trial and light personal use", "plan.free.bullet1": "{n} AI/search credits per month", "plan.free.bullet2": "Full product: Studio, Patrol, Outbox", "plan.free.bullet3": "Good for learning the flow", "plan.free.bullet4": "Upgrade anytime", "plan.free.right1": "Full access to accounts, Studio, Patrol, Outbox, jobs, and inspiration.", "plan.free.right2": "Fixed monthly credits for copy, research, search, and images.", "plan.free.right3": "After the cap, wait for next month or upgrade (unless an admin turns off limits).", "plan.free.quota1": "{n} credits allocated each month.", "plan.free.quota2": "Reference: copy {copy}, research {research}, search {search}, image {image} runs.", "plan.free.note1": "No payment required; confirms immediately.", "plan.free.note2": "Invoice rules will be defined when billing goes live.", "plan.starter.headline": "Small teams posting and patrolling daily", "plan.starter.bullet1": "{n} credits / month (about 6× Free)", "plan.starter.bullet2": "Steady posting, replies, and patrol", "plan.starter.bullet3": "Fits a 1–3 person cadence", "plan.starter.bullet4": "Takes effect right after payment", "plan.starter.right1": "After payment this account becomes Starter; the month uses the new quota.", "plan.starter.right2": "Credits support regular posts, reply drafts, and scheduled patrol.", "plan.starter.right3": "Same features as Free; you buy more headroom.", "plan.starter.quota1": "{n} credits / month · {price}.", "plan.starter.quota2": "Reference: copy {copy}, research {research}, search {search}, image {image} runs.", "plan.starter.note1": "Plan changes only after successful payment.", "plan.starter.note2": "Resets on calendar month; unused credits do not roll over.", "plan.pro.headline": "Multi-account, heavy AI and research", "plan.pro.bullet1": "{n} credits / month (about 4× Starter)", "plan.pro.bullet2": "High-volume copy, research, and images", "plan.pro.bullet3": "Built for agencies and multi-brand work", "plan.pro.bullet4": "Takes effect right after payment", "plan.pro.right1": "After payment this account becomes Pro; the month uses Pro quota.", "plan.pro.right2": "Fits multi-account replies and deep research with less risk of running out mid-month.", "plan.pro.right3": "Same features; you buy capacity and pace.", "plan.pro.quota1": "{n} credits / month · {price}.", "plan.pro.quota2": "Reference: copy {copy}, research {research}, search {search}, image {image} runs.", "plan.pro.note1": "Failed payment does not change your plan.", "plan.pro.note2": "After payment you can find receipts in billing history.", "checkout.title": "Confirm plan", "checkout.pickFirst": "Please choose a plan first.", "checkout.viewPlans": "View plans", "checkout.cardLast4Required": "Enter the last 4 digits of your card", "checkout.cardNameRequired": "Enter the cardholder name", "checkout.fail": "Could not complete", "checkout.confirmFree": "Confirm switch to Free", "checkout.payAndAction": "{action} and pay {price}", "checkout.subscribe": "Subscription", "checkout.perMonth": "/mo", "checkout.monthlyCredits": "{n} credits per month", "checkout.youGet": "What you get", "checkout.quota": "Quota", "checkout.notes": "Notes", "checkout.cardholder": "Cardholder", "checkout.cardLast4": "Last 4 digits", "checkout.amountDue": "Amount due", "checkout.billedMonthly": "{name} · billed monthly", "checkout.already": "Already on this plan", "checkout.processing": "Processing…", "checkout.currentPlan": "Current plan", "checkout.pickOther": "Choose another plan", "checkout.cancel": "Cancel", "usage.widget.titleUsed": "{name} · used {used}/{cap} credits", "usage.widget.titleUnlimited": "{name} · unlimited", "usage.widget.ariaUsed": "Used {used} of {cap} credits", "usage.widget.dialog": "Plan and usage", "usage.widget.currentPlan": "Current plan", "usage.widget.unlimited": "Unlimited", "usage.widget.perMonth": "/mo", "usage.widget.monthUsage": "This month", "usage.widget.remaining": "{n} credits left", "usage.widget.leftShort": "{n} left", "usage.widget.overShort": "Over", "usage.widget.upgradeShort": "Upgrade", "usage.widget.upgrade": "Upgrade", "usage.widget.includes": "This plan includes", "usage.widget.nudge": "You're running low this month. Upgrade for more credits right away.", "usage.widget.changePlan": "Change plan", "usage.widget.usageDetail": "Usage details", "usage.meter.ai_copy": "AI copy", "usage.meter.ai_research": "AI research", "usage.meter.web_search": "Search", "usage.meter.ai_image": "AI image", "usage.meter.barAria": "{label} {count} runs, {credits} credits, cap {cap}", "usage.ledger.costAria": "Used {n} credits", "usage.chart.period": "Period", "usage.chart.allocated": "Allocated", "usage.chart.consumed": "Used", "usage.chart.pctTitle": "Usage as share of allocation", "usage.chart.aria": "Allocation and usage", "usage.chart.colAria": "{label}: allocated {purchased}, used {consumed}", "settings.provider": "Provider", "settings.model": "Model", "settings.aiUnifiedHint": "Copy, research, and expand all share one provider and model.", "settings.fetchModels": "Fetch models", "settings.fetchingModels": "Loading…", "settings.apiKey": "API key", "settings.configured": "Configured", "settings.notConfigured": "Not set", "settings.modelsLoaded": "Loaded models for {provider}", "settings.aiSaved": "AI settings saved", "settings.searchSaved": "Search settings saved", "settings.searchProvider": "Search provider", "settings.expand": "Expand strategy", "settings.exaKey": "Exa API key", "settings.devMode": "Developer mode (crawler test patrol)", "settings.devModeHint": "When on, test patrol can use the Chrome crawler; live publish/replies still use the API. Download the extension to sync Threads session.", "settings.ext.title": "Chrome extension", "settings.ext.desc": "Developer mode needs this extension to sync Threads session from Chrome into Lapras.", "settings.ext.step1": "Download and unzip to get the haixun-threads-sync folder", "settings.ext.step2": "Open chrome://extensions and enable Developer mode", "settings.ext.step3": "Click Load unpacked and select the unzipped folder", "settings.ext.step4": "Set this site’s URL in the extension options, then refresh Lapras", "settings.ext.download": "Download extension (ZIP)", "forgot.fail": "Request failed", "forgot.mockHint": "In production this goes to email; here is a direct link:", "forgot.checkInbox": "Please check your inbox (and spam).", "reset.mismatch": "Passwords do not match", "reset.fail": "Reset failed", "reset.cardTitle": "Reset password", "reset.redirecting": "Redirecting to sign in…", "reset.loginNow": "Sign in now", "reset.passwordPh": "Password must be at least 12 characters with upper, lower, digit, and symbol", "reset.forgotLink": "Request a new reset", "verify.sendFail": "Could not send", "verify.fail": "Verification failed", "verify.success": "Email verified. You can use Lapras now.", "verify.codePh": "6-digit code", "verify.currentAccount": "Account: {email}", "login.brandTitle": "巡樓 · Lapras", "common.listSep": ", ", "common.dash": "—", "scout.title": "Patrol", "scout.today": "Today", "scout.purposeValue": "Pain-point replies", "scout.purposeActivity": "Activity short replies", "scout.goal": "Daily goal (posts)", "scout.progress": "Progress {done}/{goal}", "scout.intent": "What to find / reply to", "scout.keyword": "Keywords", "scout.intentPh": "e.g. seasonal scalp itch, truly fragrance-free, outlets on weekends", "scout.keywordPh": "e.g. weekend coffee remote", "scout.productOptional": "Product (optional)", "scout.noProduct": "No product", "scout.brandFallback": "Brand", "scout.placement": "Placement: {label}", "scout.painPart": " · pain “{pain}”", "scout.noProductsBefore": "No products yet. Add some under", "scout.noProductsAfter": ".", "scout.start": "Start", "scout.startMore": "Fetch more", "scout.fetching": "Fetching…", "scout.runs": "Patrol batches", "scout.runCount": "Batch ({n})", "scout.runSelectAria": "Switch patrol batch", "scout.runPending": "{n} pending · ", "scout.runDone": "Cleared · ", "scout.runTotal": " ({n} posts)", "scout.deleteRun": "Delete this batch", "scout.deleting": "Deleting…", "scout.now": "Now this post", "scout.emptyBatch": "Nothing pending in this batch", "scout.draft": "Reply draft", "scout.draftPhActivity": "Short reply…", "scout.draftPhValue": "Empathize → suggest…", "scout.sendAccount": "Send from account", "scout.noAccount": "No usable accounts", "scout.personaForRegen": "Persona (for regen)", "scout.notReady": " (not ready)", "scout.skip": "Skip", "scout.regen": "Regen", "scout.send": "Send", "scout.sending": "Sending…", "scout.needAccountBefore": "Connect a usable account under", "scout.needAccountAfter": "first.", "scout.knowledge": "Related knowledge", "scout.knowledgeWithLabel": "Related · {label}", "scout.knowledgeLearn": "Related · to learn", "scout.collapseKnowledge": "Collapse knowledge", "scout.expandLearn": "Expand · {n} notes", "scout.expandKnowledge": "Expand knowledge", "scout.deleteKnowledgeRun": "Delete this batch's knowledge & hits", "scout.loadingKnowledge": "Preparing related knowledge…", "scout.notesCount": "{n} notes", "scout.noKnowledge": "No related knowledge yet", "scout.product": "Product", "scout.painsSolved": "Pains we solve", "scout.focus": "Focus", "scout.all": "All", "scout.noWebSummary": "No web summaries yet", "scout.queue": "Queue · {n}", "scout.collapseQueue": "Collapse queue", "scout.expandQueue": "Expand queue", "scout.noOtherPending": "No other pending", "scout.learnPoints": "Key takeaways", "scout.replyHooks": "Reply hooks", "scout.badgeCore": "Closest to topic", "scout.unnamedRun": "Unnamed batch", "scout.thisRun": "this batch", "scout.confirmDeleteRun": "Delete patrol batch “{label}”?\\nHits and related knowledge will be removed. This cannot be undone.", "scout.deletedRun": "Deleted batch “{label}”", "scout.deleteRunFail": "Failed to delete batch", "scout.needKeyword": "Enter keywords first", "scout.needIntent": "Write what you're looking for", "scout.productMissing": "Selected product is not in the list. Please reselect.", "scout.defaultLabel": "Patrol", "scout.newRunActivity": "New batch “{label}” · {n} pending", "scout.newRunValue": "New batch “{label}” · {n} posts · handle “Now this post”", "scout.knowledgeReady": "“{label}” knowledge ready · {n} notes", "scout.patrolFail": "This patrol failed", "scout.draftFail": "Draft failed", "scout.skipped": "Skipped", "scout.noDraft": "No draft to send", "scout.accountFallback": "account", "scout.sent": "Sent (@{who}) · today {done}/{goal}", "scout.sendFail": "Send failed", "scout.confirmDeletePost": "Delete this hit?", "scout.stanceActivity": "Short reply · activity", "scout.stanceProduct": "Empathy · soft product", "scout.stanceRelation": "Engage · build rapport", "scout.tier.core": "Closest", "scout.tier.coreHint": "Directly on the pain/keywords — read first", "scout.tier.adjacent": "Adjacent", "scout.tier.adjacentHint": "Nearby context, broaden search", "scout.tier.broad": "Broad", "scout.tier.broadHint": "Background & contrast — optional", "scout.relation.solves_pain": "Hits the pain", "scout.relation.nearby_scene": "Nearby scene", "scout.relation.myth": "Myth-busting", "scout.relation.contrast": "Contrast shopping", "scout.relation.background": "Background", "brands.title": "Brands", "brands.railAria": "Brand list", "brands.railLabel": "Your brands", "brands.add": "Add", "brands.brandName": "Brand name", "brands.brandNamePh": "e.g. your brand", "brands.creating": "Creating…", "brands.createBrand": "Create brand", "brands.searchAria": "Search brands", "brands.searchPh": "Search brands…", "brands.empty": "No brands yet", "brands.noMatch": "No matches", "brands.selectAria": "Select brand", "brands.pickOne": "Pick a brand", "brands.inUseHint": "Active · used for patrol and studio", "brands.inUse": "Active", "brands.tabInfo": "Brand info", "brands.tabProducts": "Products", "brands.tabProductsN": "Products ({n})", "brands.displayName": "Name", "brands.brief": "Summary", "brands.briefPh": "One line about this brand", "brands.audience": "Audience", "brands.audiencePh": "Who cares and why", "brands.goals": "Goals", "brands.goalsPh": "What you want on Threads", "brands.saving": "Saving…", "brands.deleteBrand": "Delete brand", "brands.searchProductAria": "Search products", "brands.searchProductPh": "Search products…", "brands.addProduct": "Add product", "brands.noProducts": "No products yet", "brands.hasLink": "Has link", "brands.painLabel": "Pains ", "brands.editProduct": "Edit product", "brands.newProduct": "New product", "brands.importFromUrl": "Import from product URL", "brands.fetching": "Fetching…", "brands.fetch": "Fetch", "brands.pains": "Pain points", "brands.painsPh": "One per line", "brands.tags": "Tags", "brands.tagsPh": "Comma-separated", "brands.intro": "Description", "brands.link": "Link", "brands.update": "Update", "brands.createItem": "Add", "brands.needName": "Enter a name", "brands.created": "Created “{name}”", "brands.createFail": "Create failed", "brands.saved": "Saved", "brands.saveFail": "Save failed", "brands.confirmDelete": "Delete “{name}”?", "brands.deleted": "Deleted", "brands.deleteFail": "Delete failed", "brands.fetchFail": "Fetch failed", "brands.needLabelContext": "Name and description are required", "brands.productUpdated": "Updated", "brands.productAdded": "Added", "brands.confirmDeleteProduct": "Delete this product?", "insights.title": "Account performance", "insights.account": "Account", "insights.noAccount": "No accounts", "insights.syncing": "Syncing…", "insights.syncPosts": "Sync posts", "insights.myPosts": "My posts", "insights.pickAccount": "Select an account", "insights.goAccounts": "Accounts", "insights.kpiMonth": "This month", "insights.monthViews": "Views this month", "insights.monthLikes": "Likes this month", "insights.monthReplies": "Replies this month", "insights.engRate": "Engagement", "insights.vsPrev": "vs last month", "insights.avgNear": "Recent avg {rate}", "insights.trendTitle": "Trends & analysis · @{user}", "insights.metricViews": "Views", "insights.metricLikes": "Likes", "insights.metricReplies": "Replies", "insights.metricPosts": "Posts", "insights.metricPostsFull": "Posts", "insights.chartMetrics": "Chart metric", "insights.barsAria": "Recent months {metric}; click a bar for analysis", "insights.barsLabel": "{metric} · last {n} months", "insights.clickBar": " · click bar for analysis", "insights.pickMonthAria": "Select month", "insights.barTitle": "{label}: {value}{est} · click for analysis", "insights.est": " (est.)", "insights.monthSuffix": "{m}", "insights.sparkAria": "Trend line; click a node to select month", "insights.analysisOf": "{label} analysis", "insights.producedAt": "Generated {time}", "insights.hasEstimate": " · includes estimates", "insights.viewsVsPrev": " · views vs prev {delta}", "insights.statPosts": "Posts", "insights.statViews": "Views", "insights.statLikes": "Likes", "insights.statReplies": "Replies", "insights.conclusions": "Takeaways", "insights.recommendations": "Recommendations", "insights.highlights": "Month highlights", "insights.findTopics": "Find topics", "insights.goScout": "Go patrol", "insights.selectMonth": "Select a month", "insights.topPosts": "Top posts", "insights.noPosts": "No posts yet", "insights.postStats": "Views {views} · likes {likes} · replies {replies}", "insights.openThreads": "Open Threads", "insights.zeroPct": "0%", "plays.tabOwn": "My posts", "plays.tabLink": "Threads link", "plays.noPosts": "No posts yet", "plays.targetPost": "Target post", "plays.likesSuffix": " ({n} likes)", "plays.linkCard": "Paste Threads link", "plays.postLink": "Post URL", "plays.resolving": "Resolving…", "plays.resolve": "Resolve link", "plays.resolveHint": "After resolve, schedule your accounts to reply under that post.", "plays.targetOwn": "Target post (yours)", "plays.openThreads": "Open Threads", "plays.external": "External post", "plays.addScheme": "New scheme", "plays.schemeCount": "{n} schemes for this target", "plays.noSchemes": "No schemes yet", "plays.replyCount": "{n} replies", "plays.editTitle": "Edit: {title}", "plays.schemeName": "Scheme name", "plays.schemeNamePh": "e.g. Scheme A · soft engage", "plays.speakersOwn": "Accounts (post owner always included)", "plays.speakers": "Accounts", "plays.postOwner": " (post owner)", "plays.noAccounts": "No usable accounts. Connect Threads first.", "plays.interval": "Interval (min)", "plays.applyInterval": "Apply interval", "plays.aiEmpty": "AI fill empty", "plays.aiBusy": "Generating…", "plays.replies": "Replies ({n})", "plays.stepN": "Reply {n}", "plays.who": "Who", "plays.personaOpt": "Persona (optional)", "plays.brandOpt": "Brand (optional)", "plays.reply": "Reply", "plays.attach": "Images", "plays.addOne": "Add one", "plays.saving": "Saving…", "plays.saveScheme": "Save scheme", "plays.submitting": "Submitting…", "plays.submitOutbox": "Submit to Outbox", "plays.closeEdit": "Close editor", "plays.noTarget": "No target post yet", "plays.resolved": "Link resolved", "plays.resolveFail": "Resolve failed", "plays.filled": "Generated {n}", "plays.needTarget": "Select a target post first", "plays.saved": "Scheme saved", "plays.saveFail": "Save failed", "plays.submitted": "Sent to Outbox", "plays.submitFail": "Submit failed", "plays.confirmDelete": "Delete this scheme?", "plays.accountFallback": "account", "inspire.loading": "Loading…", "inspire.trendsAria": "What's hot on Threads", "inspire.trendsLabel": "Hot on Threads", "inspire.refresh": "Refresh", "inspire.clearChat": "Clear chat", "inspire.pinAsElement": "Apply as element", "inspire.you": "You", "inspire.ai": "AI", "inspire.system": "System", "inspire.useDraft": "Use this draft", "inspire.openPlay": "Open play", "inspire.generating": "Generating…", "inspire.thinking": "Thinking…", "inspire.pinnedAria": "Applied this round", "inspire.pinned": "Applied", "inspire.pickRight": "Pick elements on the right", "inspire.unpinTitle": "Click to unapply", "inspire.inputAria": "Talk to AI", "inspire.inputPh": "What to write? Or shorter, more casual…", "inspire.send": "Send", "inspire.generate": "Generate", "inspire.library": "Element library", "inspire.addNew": "+ Add", "inspire.kind": "Type", "inspire.kindRole": "Role prompt", "inspire.kindSnippet": "Snippet", "inspire.kindTrendNote": "Trend note", "inspire.kindBrand": "Brand", "inspire.kindTrend": "Trend", "inspire.name": "Name", "inspire.namePh": "e.g. pro Threads writer", "inspire.body": "Content (goes into prompt)", "inspire.bodyPh": "You are a…", "inspire.saveElement": "Save to library", "inspire.citeBrand": "Cite brand", "inspire.applied": "Applied", "inspire.clickApply": "Click to apply", "inspire.noBrands": "No brands yet", "inspire.appliedToggle": "Applied · click again to remove", "inspire.deleteAria": "Delete", "inspire.needInput": "Type a line first, or generate directly", "inspire.fail": "Failed", "inspire.wantWrite": "Want to write about {label}: {summary}", "inspire.trendBody": "Topic: {label}. {summary}", "inspire.pinnedTrend": "Applied trend {label}", "inspire.needTitleBody": "Name and content required", "inspire.added": "Added to library", "inspire.addFail": "Add failed", "inspire.confirmRemove": "Remove this from the library?", "inspire.confirmClear": "Clear chat? (library kept)", "inspire.genMessage": "Write a Threads post from the applied elements", "persona.add": "New persona", "persona.empty": "No personas yet", "persona.emptyDesc": "Add one and analyze it for drafting.", "persona.statusReady": "ready", "persona.statusAnalyzing": "analyzing", "persona.statusPending": "pending", "persona.default": "Default", "persona.backList": "← Personas", "persona.tabOverview": "Overview", "persona.tabAnalyze": "Analyze", "persona.tabFingerprint": "Fingerprint", "persona.tabPreview": "Preview", "persona.name": "Name", "persona.brief": "Brief", "persona.briefPh": "Who, for whom, core message…", "persona.avoid": "Guardrails · banned words (comma-separated)", "persona.guardChars": "{n} chars", "persona.banAi": " · ban AI tone", "persona.notReadySuffix": " · not ready", "persona.setDefault": "Set as default", "persona.modeAccount": "Public account", "persona.modeText": "Paste text", "persona.username": "Threads username", "persona.fromBound": "From linked account", "persona.select": "Select…", "persona.crawlAnalyze": "Crawl public posts & analyze", "persona.crawlBusy": "Crawling / analyzing…", "persona.refText": "Reference text (--- separates posts)", "persona.refTextPh": "First post…\n\n---\n\nSecond post…", "persona.sourceLabel": "Source note (optional)", "persona.sourcePh": "My old posts", "persona.analyzeText": "Analyze from text", "persona.analyzeBusy": "Analyzing…", "persona.sampleMeta": "Samples {n}", "persona.sourceManual": "Pasted", "persona.analyzeHint": "After analysis, 8D summaries appear here.", "persona.fingerprintHint": "Main voice for drafting. Edit catchphrases, rhythm, bans; Studio/replies use this.", "persona.fingerprint": "Language fingerprint", "persona.fingerprintPh": "Filled after analysis…", "persona.saveFingerprint": "Save fingerprint", "persona.tryGen": "Preview root + reply", "persona.notReadyMsg": "Persona not ready", "persona.rootPost": "Root post", "persona.reply": "Reply", "persona.hidePrompt": "Hide prompt block", "persona.showPrompt": "Show injected prompt", "persona.promptBlock": "prompt block (post)", "persona.pickOne": "Pick a persona", "persona.pickDesc": "Or add one to start analyzing.", "persona.created": "Created — finish account crawl or paste text under Analyze", "persona.saved": "Saved", "persona.textDone": "Text analysis done · {n} segments → ready", "persona.analyzeFail": "Analysis failed", "persona.reading": "Reading public posts…", "persona.accountDone": "@{user} · {n} posts → ready", "persona.setDefaultMsg": "“{name}” set as default", "persona.confirmDelete": "Delete persona “{name}”?", "persona.deleted": "Persona deleted", "persona.needReady": "Finish analysis first (ready)", "persona.dim.d1Tone": "D1 Tone", "persona.dim.d2Structure": "D2 Structure", "persona.dim.d3Interaction": "D3 Interaction", "persona.dim.d4Topics": "D4 Topics", "persona.dim.d5Rhythm": "D5 Rhythm", "persona.dim.d6Visual": "D6 Visual", "persona.dim.d7Conversion": "D7 Conversion", "persona.dim.d8Risk": "D8 Risk", "admin.users.loadFail": "Load failed", "admin.users.created": "Added islander “{name}” · copy the password below", "admin.users.createFail": "Create failed", "admin.users.unlimitedOn": "“{name}” set to unlimited (usage still counted)", "admin.users.unlimitedOff": "“{name}” back to plan limits", "admin.users.updateFail": "Update failed", "admin.users.planSet": "“{name}” plan → {plan}", "admin.users.confirmSuspend": "Suspend “{name}”?\\nThey will not be able to sign in.", "admin.users.confirmUnsuspend": "Restore “{name}”?\\nThey can sign in again.", "admin.users.didSuspend": "Suspended “{name}”", "admin.users.didUnsuspend": "Restored “{name}”", "admin.users.suspendFail": "Suspend failed", "admin.users.unsuspendFail": "Restore failed", "admin.users.markedVerified": "Marked {name} as email verified", "admin.users.markedUnverified": "Marked {name} as unverified", "admin.users.rolesUpdated": "Updated roles for {name}: {roles}", "admin.users.rolesFail": "Role update failed", "admin.users.confirmReset": "Reset password for “{name}”?\\nTemp password stays visible until you close it (survives refresh).", "admin.users.resetDone": "Reset password for {name} (shown below — copy then close)", "admin.users.resetFail": "Reset failed", "admin.users.copied": "Copied to clipboard", "admin.users.copyFail": "Copy failed — select the password manually", "admin.users.confirmDismissTemp": "After close, this temp password won't show again (copy first if needed). Close?", "admin.users.tempPwNew": "New islander temp password", "admin.users.tempPw": "Temp password", "admin.users.tempPwPersist": "(stays visible · survives refresh)", "admin.users.copyPw": "Copy password", "admin.users.close": "Close", "admin.users.createTitle": "Add islander", "admin.users.memberName": "Display name", "admin.users.displayNamePh": "Display name", "admin.users.email": "Email", "admin.users.initPassword": "Initial password (optional)", "admin.users.initPasswordPh": "Leave blank to auto-generate; if set, must meet policy", "admin.users.markVerifiedCheck": "Mark email verified (usable immediately)", "admin.users.alsoAdmin": "Also make admin", "admin.users.creating": "Creating…", "admin.users.createSubmit": "Create islander", "admin.users.clear": "Clear", "admin.users.searchActive": "Search “{query}” · matches name, email, uid", "admin.users.noMatch": "No matches", "admin.users.none": "No islanders yet", "admin.users.you": "You", "admin.users.status": "Status", "admin.users.role": "Roles", "admin.users.emailVerify": "Email verification", "admin.users.bio": "Bio", "admin.users.timezone": "Timezone", "admin.users.notifyEmail": "Email notifications", "admin.users.on": "On", "admin.users.off": "Off", "admin.users.createdAt": "Created", "admin.users.updatedAt": "Updated", "admin.users.accountStatus": "Account status", "admin.users.updating": "Updating…", "admin.users.usageTitle": "Usage & plan", "admin.users.usageLiveSkip": "Plan/quota are Usage domain — not on live backend yet (M3). Editable in mock only.", "admin.users.plan": "Plan", "admin.users.planOption": "{name} ({credits} credits / mo)", "admin.users.unlimited": "Unlimited", "admin.users.byPlan": "By plan", "admin.users.setUnlimited": "Set unlimited", "admin.users.setLimited": "Enforce plan limits", "admin.users.unlimitedHint": "Unlimited: can keep using past plan cap; AI/Search counts and credits still track.", "admin.users.loadingUsage": "Loading usage prefs…", "admin.users.assignRoles": "Assign roles", "admin.users.memberBase": "{role} (base, always on)", "admin.users.adminDesc": "{role} — manage islanders and system", "admin.users.saving": "Saving…", "admin.users.saveRoles": "Save roles", "admin.users.markUnverifiedBtn": "Mark unverified", "admin.users.markVerifiedBtn": "Mark verified", "admin.users.resetting": "Resetting…", "admin.users.resetTemp": "Reset password (temp)", "admin.users.customPw": "Or set a password (optional)", "admin.users.customPwPh": "Password must be at least 12 characters with upper, lower, digit, and symbol", "admin.users.resetWithCustom": "Reset with this password", "usage.tabMine": "My usage", "usage.tabTenant": "All usage", "usage.currentPlan": "Current plan", "usage.planMeta": "/ mo · {n} credits monthly", "usage.changePlan": "Change plan", "usage.usedThisMonth": "Used this month", "usage.remainLabel": "Remaining", "usage.ledgerToggle": "Usage log", "usage.collapse": "Collapse", "usage.eventsCount": "{n} events", "usage.granularity": "Granularity", "usage.day": "Day", "usage.monthUnit": "Month", "usage.year": "Year", "usage.from": "From", "usage.to": "To", "usage.callCounts": "Call counts", "usage.noMembers": "No members yet", "usage.planAria": "{name} plan", "usage.unlimitedTitle": "Unlimited", "usage.setLimited": "Enforce limits", "usage.setUnlimited": "Set unlimited", "usage.limitShort": "Cap", "usage.subscribed": "Subscribed to {name}", "usage.unlimitedSet": "Set unlimited", "usage.limitedSet": "Limits enforced", "usage.planUpdated": "Plan updated to {name}", "usage.fail": "Failed", "currency.TWD": "New Taiwan Dollar (TWD)", "currency.USD": "US Dollar (USD)", "currency.JPY": "Japanese Yen (JPY)", "currency.EUR": "Euro (EUR)", "currency.HKD": "Hong Kong Dollar (HKD)", "locale.zh-TW": "繁體中文", "locale.en": "English", "pager.nav": "Pagination", "pager.pageSize": "Items per page", "pager.perPage": "{n}/page", "pager.prev": "Previous", "pager.next": "Next", "plays.defaultTitle": "New play", "plays.topicOnPost": "On: {snippet}", "plays.topicOnExternal": "On: {label} · {snippet}", "plays.externalFallback": "External post", "persona.newName": "New persona", "persona.previewTopic": "Looking for a café I can sit in for hours", "persona.previewReplySample": "The one in Da’an is fine but crowded", "inspire.playTitle": "Inspired thread", "wizard.topic.fallbackTopic": "Everyday topic", "play.err.needLead": "Pick a lead account", "play.err.needRoot": "Add at least one root post", "play.err.firstMustRoot": "The first step must be the root post", "play.err.rootMustLead": "Root post must use the lead account", "play.err.rootEmpty": "Root post text cannot be empty", "play.err.replyAccount": "Replies can only use lead or selected cast accounts", "play.err.replyEmpty": "Reply text cannot be empty", "play.err.needTarget": "Pick one of your posts, or paste a Threads link", "play.err.needReplies": "Add at least one reply", "play.err.needReplyAccounts": "Pick at least one reply account", "play.err.stepAccount": "Every reply needs a usable account", "play.err.stepEmpty": "Reply text cannot be empty", "play.err.notFound": "Play not found", "time.justNow": "Just now", "time.minAgo": "{n}m ago", "time.hourAgo": "{n}h ago", "time.dayAgo": "{n}d ago", "time.min": "{n} min", "time.hour": "{n} hr", "time.day": "{n} day", "time.expired": "Expired {span}", "time.remaining": "{span} left", "time.sessionUnknown": "Session not recorded", "time.sessionExpired": "Session expired · {absolute}", "time.sessionSoon": "Session expiring · {relative} ({absolute})", "time.sessionOk": "Session OK · {relative} ({absolute})", }; const catalogs: Record = { "zh-TW": zhTW, en, }; export function getCatalog(locale: AppLocale): MessageDict { return catalogs[locale] || zhTW; } export function translate( locale: AppLocale, key: string, params?: Record, ): string { const dict = getCatalog(locale); let s = dict[key] ?? zhTW[key] ?? key; if (params) { for (const [k, v] of Object.entries(params)) { s = s.replace(new RegExp(`\\{${k}\\}`, "g"), String(v)); } } return s; }