/* PhotoPick i18n: zh-Hans / zh-Hant / en / ja / ko */
const SUPPORTED_LANGS = ["zh-Hans", "zh-Hant", "en", "ja", "ko"];
const SETTINGS_KEY = "photopick-settings";

const I18N = {
  "zh-Hans": {
    "settings.title": "设置",
    "settings.hint": "偏好会保存在本机，之后可在这里继续添加选项。",
    "settings.language": "语言",
    "settings.theme": "主题",
    "settings.theme.dark": "深色",
    "settings.theme.light": "浅色",
    "settings.close": "完成",
    "settings.open": "设置",
    "settings.version": "版本",
    "settings.checkUpdate": "检查更新",
    "settings.checkingUpdate": "检查中…",
    "update.available": "有新版本 {version} 可下载",
    "update.banner": "PhotoPick {version} 已推出",
    "update.download": "下载更新",
    "update.dismiss": "稍后",
    "update.dismissTitle": "稍后提醒",
    "update.upToDate": "已是最新版本",
    "update.checkFailed": "无法检查更新",
    "account.menu": "账户",
    "account.profile": "账户",
    "account.plans": "方案",
    "account.settings": "设置",
    "profile.hint": "管理本机授权与装置状态。",
    "profile.close": "完成",
    "license.title": "授权",
    "license.mode.trial": "试用版",
    "license.mode.licensed": "已启用正式版",
    "license.usage.trial": "照片 {photos} · 项目 {projects}",
    "license.usage.licensed": "已解锁全部功能",
    "license.key": "授权码",
    "license.email": "电子邮件",
    "license.keyHint": "授权码",
    "license.emailUnknown": "—",
    "license.keyPlaceholder": "贴上购买后收到的授权码",
    "license.activate": "启用",
    "license.purchase": "购买正式版",
    "license.success": "授权已启用",
    "license.error.empty": "请输入授权码",
    "license.deactivate": "解除本机授权",
    "license.deactivate.hint": "换电脑前请先解除本机，以释出装置名额（同一授权码最多 2 台 Mac）。",
    "license.deactivate.confirm": "确定解除本机授权？此 Mac 将恢复为试用版，授权码可在其他电脑重新启用。",
    "license.deactivate.success": "已解除本机授权",
    "license.active.hint": "此 Mac 已启用。重装 App 或换电脑后，可重新输入同一组授权码。",
    "license.active.hintWithKey": "授权码 {key} 已在此 Mac 启用。",
    "license.reactivate": "重新激活",
    "license.reactivate.cancel": "取消",
    "license.deviceName": "本机名称",
    "license.machineId": "Machine ID",
    "license.machineIdHint": "联系支持时可提供此 ID，以便在后台对照装置。",
    "license.machineIdCopied": "已复制 Machine ID",
    "license.machineIdCopyHint": "点击复制",
    "license.locked.title": "试用版尚未解锁：",
    "license.locked.batchRename": "批次重新命名",
    "license.locked.batchDelete": "批次移至垃圾桶",
    "license.locked.defectDetection": "失焦／手震侦测",
    "license.locked.exposureDetection": "曝光侦测",
    "license.locked.editing": "裁切／水平校正",
    "license.locked.export": "转档导出",
    "license.locked.qualityRescan": "手动全部重扫（已用完试用次数）",
    "license.badge.trial": "试用 · {photos} 张",
    "license.badge.trialTitle": "试用版 — 点击管理授权",
    "license.badge.licensed": "正式版",
    "license.upgrade.title": "试用版功能限制",
    "license.upgrade.body": "「{feature}」需要购买 PhotoPick 才能使用。",
    "license.upgrade.hint": "购买 PhotoPick 即可解锁。",
    "license.upgradeHint": "购买 PhotoPick 解锁",
    "license.upgrade.settings": "输入授权码",
    "license.upgrade.close": "关闭",
    "plans.title": "方案比较",
    "plans.subtitle": "一次升级解锁全部功能。",
    "plans.open": "查看方案",
    "plans.close": "关闭",
    "plans.col.feature": "项目",
    "plans.col.trial": "试用",
    "plans.col.standard": "正式版",
    "plans.row.price": "价格",
    "plans.row.projects": "项目数",
    "plans.row.photos": "每项目照片",
    "plans.row.defectDetection": "失焦／手震侦测",
    "plans.row.exposureDetection": "曝光侦测",
    "plans.row.editing": "裁切／水平校正",
    "plans.row.rotate": "旋转／翻转",
    "plans.row.batchRename": "批次重新命名",
            "plans.row.export": "转档导出",
    "plans.row.devices": "可启用装置",
    "plans.trial.price": "免费",
    "plans.trial.projects": "1",
    "plans.trial.photos": "100",
    "plans.trial.devices": "本机",
    "plans.standard.price": "$19 · 约 NT$590",
    "plans.standard.unlimited": "不限",
    "plans.standard.devices": "2 台 Mac",
    "plans.yes": "✓",
    "plans.no": "—",
    "plans.footnote": "一次付费，终身使用，之后新增的付费功能更新也都包含在内。",
    "project.label": "项目",
    "project.empty": "（尚未创建项目）",
    "project.emptyHint": "（尚未创建项目 — 请选择文件夹）",
    "project.pickFolder": "选择文件夹…",
    "project.openFolder": "打开文件夹",
    "project.delete": "从列表移除项目",
    "project.deleteTitle": "只移除 PhotoPick 中的项目记录，不会删除文件夹内的照片",
    "project.deleteConfirm": "确定从列表移除此项目？\n\n{label}\n\n只会移除 PhotoPick 中的索引、状态与 preview，不会删除磁盘上的原始照片。",
    "project.deleteFail": "移除项目失败：{message}",
    "project.missingRoot": "（文件夹不存在）",
    "project.photos": "{n} 张",
    "scan.quality": "重新扫描失焦／手震／曝光",
    "scan.qualityTitle": "导入时会自动扫描；此按钮可强制重扫全部",
    "analyze": "AI 分析（选用）",
    "tab.all": "全部",
    "tab.keep": "保留",
    "tab.starred": "已加星",
    "tab.soft": "失焦",
    "tab.shake": "手震",
    "tab.blur": "模糊",
    "tab.exposure": "曝光",
    "tab.reject": "待删除",
    "defect.filter": "程度",
    "defect.filterAbove": "以上",
    "defect.type.all": "全部",
    "defect.filterTitle": "显示所选程度以上的照片",
    "defect.tier.low": "低",
    "defect.tier.medium": "中",
    "defect.tier.high": "高",
    "grid.size": "缩图大小",
    "purge.missing": "重新整理",
    "purge.reject": "清空待删除文件",
    "select.all": "全选",
    "select.none": "取消全选",
    "select.count": "已选 {n} 张",
    "select.countOf": "已选 {n} / {total} 张",
    "star.add": "加星号",
    "star.remove": "取消加星号",
    "reject.set": "设为待删除",
    "reject.unset": "取消待删除",
    "reject.action": "待删除",
    "rotate.ccw": "向左旋转",
    "rotate.cw": "向右旋转",
    "flip.horizontal": "水平翻转",
    "crop.edit": "裁切／校正",
    "crop.aspect.free": "自由",
    "crop.aspect.original": "原始比例",
    "crop.aspect.square": "1:1",
    "crop.straighten": "水平校正",
    "crop.resetAngle": "归零",
    "crop.cancel": "取消",
    "crop.reset": "重设",
    "crop.preview": "预览",
    "crop.previewHint": "这是套用后的结果",
    "crop.backToEdit": "返回编辑",
    "crop.saveAs": "另存新档",
    "crop.overwrite": "存档（覆盖原始档）",
    "exposure.overexposed": "偏亮",
    "exposure.underexposed": "偏暗",
    "exposure.normal": "曝光正常",
    "histogram.label": "直方图",
    "rename.batch": "批量重命名…",
    "export.batch": "转档导出…",
    "export.quality": "画质",
    "export.qualityHint": "画质越低，档案越小",
    "export.estimating": "正在估算…",
    "export.estimateResult": "预估空间：{current} → {estimated}",
    "export.dimensionChangeHeader": "{n} 张照片会因裁切缩小尺寸：",
    "export.dimensionChangeLine": "{filename}：{ow}×{oh} → {nw}×{nh}",
    "export.dimensionChangeMore": "…等共 {n} 张",
    "export.estimateFailed": "无法估算大小",
    "export.outputPath": "输出文件夹",
    "export.browse": "浏览…",
    "select.clear": "清除选取",
    "grid.empty": "这个分类目前没有照片",
    "stats.total": "总容量 <b>{size}</b>（{count} 张）",
    "stats.starred": " · 已加星 <b>{n}</b>",
    "stats.rejectFree": " · 待删除可释放 <b>{size}</b>",
    "stats.missing": " · <span class=\"stats-missing\">遗失 {n}</span>",
    "soft": "失焦",
    "shake": "手震",
    "lang.zhHans": "简体中文",
    "lang.zhHant": "繁體中文",
    "lang.en": "English",
    "lang.ja": "日本語",
    "lang.ko": "한국어",
  },
  "zh-Hant": {
    "settings.title": "設定",
    "settings.hint": "偏好會保存在本機，之後可在這裡繼續加選項。",
    "settings.language": "語言",
    "settings.theme": "主題",
    "settings.theme.dark": "深色",
    "settings.theme.light": "淺色",
    "settings.close": "完成",
    "settings.open": "設定",
    "settings.version": "版本",
    "settings.checkUpdate": "檢查更新",
    "settings.checkingUpdate": "檢查中…",
    "update.available": "有新版本 {version} 可下載",
    "update.banner": "PhotoPick {version} 已推出",
    "update.download": "下載更新",
    "update.dismiss": "稍後",
    "update.dismissTitle": "稍後提醒",
    "update.upToDate": "已是最新版本",
    "update.checkFailed": "無法檢查更新",
    "account.menu": "帳戶",
    "account.profile": "帳戶",
    "account.plans": "方案",
    "account.settings": "設定",
    "profile.hint": "管理本機授權與裝置狀態。",
    "profile.close": "完成",
    "license.title": "授權",
    "license.mode.trial": "試用版",
    "license.mode.licensed": "已啟用正式版",
    "license.usage.trial": "照片 {photos} · 專案 {projects}",
    "license.usage.licensed": "已解鎖全部功能",
    "license.key": "授權碼",
    "license.email": "電子郵件",
    "license.keyHint": "授權碼",
    "license.emailUnknown": "—",
    "license.keyPlaceholder": "貼上購買後收到的授權碼",
    "license.activate": "啟用",
    "license.purchase": "購買正式版",
    "license.success": "授權已啟用",
    "license.error.empty": "請輸入授權碼",
    "license.deactivate": "解除本機授權",
    "license.deactivate.hint": "換電腦前請先解除本機，以釋出裝置名額（同一授權碼最多 2 台 Mac）。",
    "license.deactivate.confirm": "確定解除本機授權？此 Mac 將恢復為試用版，授權碼可在其他電腦重新啟用。",
    "license.deactivate.success": "已解除本機授權",
    "license.active.hint": "此 Mac 已啟用。重裝 App 或換電腦後，可重新輸入同一組授權碼。",
    "license.active.hintWithKey": "授權碼 {key} 已在此 Mac 啟用。",
    "license.reactivate": "重新激活",
    "license.reactivate.cancel": "取消",
    "license.deviceName": "本機名稱",
    "license.machineId": "Machine ID",
    "license.machineIdHint": "聯絡支援時可提供此 ID，以便在後台對照裝置。",
    "license.machineIdCopied": "已複製 Machine ID",
    "license.machineIdCopyHint": "點擊複製",
    "license.locked.title": "試用版尚未解鎖：",
    "license.locked.batchRename": "批次重新命名",
    "license.locked.batchDelete": "批次移至垃圾桶",
    "license.locked.defectDetection": "失焦／手震偵測",
    "license.locked.exposureDetection": "曝光偵測",
    "license.locked.editing": "裁切／水平校正",
    "license.locked.export": "轉檔匯出",
    "license.locked.qualityRescan": "手動全部重掃（已用完試用次數）",
    "license.badge.trial": "試用 · {photos} 張",
    "license.badge.trialTitle": "試用版 — 點擊管理授權",
    "license.badge.licensed": "正式版",
    "license.upgrade.title": "試用版功能限制",
    "license.upgrade.body": "「{feature}」需要購買 PhotoPick 才能使用。",
    "license.upgrade.hint": "購買 PhotoPick 即可解鎖。",
    "license.upgradeHint": "購買 PhotoPick 解鎖",
    "license.upgrade.settings": "輸入授權碼",
    "license.upgrade.close": "關閉",
    "plans.title": "方案比較",
    "plans.subtitle": "一次升級解鎖全部功能。",
    "plans.open": "查看方案",
    "plans.close": "關閉",
    "plans.col.feature": "項目",
    "plans.col.trial": "試用",
    "plans.col.standard": "正式版",
    "plans.row.price": "價格",
    "plans.row.projects": "專案數",
    "plans.row.photos": "每專案照片",
    "plans.row.defectDetection": "失焦／手震偵測",
    "plans.row.exposureDetection": "曝光偵測",
    "plans.row.editing": "裁切／水平校正",
    "plans.row.rotate": "旋轉／翻轉",
    "plans.row.batchRename": "批次重新命名",
            "plans.row.export": "轉檔匯出",
    "plans.row.devices": "可啟用裝置",
    "plans.trial.price": "免費",
    "plans.trial.projects": "1",
    "plans.trial.photos": "100",
    "plans.trial.devices": "本機",
    "plans.standard.price": "$19 · 約 NT$590",
    "plans.standard.unlimited": "不限",
    "plans.standard.devices": "2 台 Mac",
    "plans.yes": "✓",
    "plans.no": "—",
    "plans.footnote": "一次付費，終身使用，之後新增的付費功能更新也都包含在內。",
    "project.label": "專案",
    "project.empty": "（尚未建立專案）",
    "project.emptyHint": "（尚未建立專案 — 請選擇資料夾）",
    "project.pickFolder": "選擇資料夾…",
    "project.openFolder": "開啟資料夾",
    "project.delete": "從列表移除專案",
    "project.deleteTitle": "只移除 PhotoPick 中的專案記錄，不會刪除資料夾內的照片",
    "project.deleteConfirm": "確定從列表移除此專案？\n\n{label}\n\n只會移除 PhotoPick 中的索引、狀態與 preview，不會刪除磁碟上的原始照片。",
    "project.deleteFail": "移除專案失敗：{message}",
    "project.missingRoot": "（資料夾不存在）",
    "project.photos": "{n} 張",
    "scan.quality": "重新掃描失焦／手震／曝光",
    "scan.qualityTitle": "匯入時會自動掃描；此按鈕可強制重掃全部",
    "analyze": "AI 分析（選用）",
    "tab.all": "全部",
    "tab.keep": "保留",
    "tab.starred": "已加星",
    "tab.soft": "失焦",
    "tab.shake": "手震",
    "tab.blur": "模糊",
    "tab.exposure": "曝光",
    "tab.reject": "待刪除",
    "defect.filter": "程度",
    "defect.filterAbove": "以上",
    "defect.type.all": "全部",
    "defect.filterTitle": "顯示所選程度以上的相片",
    "defect.tier.low": "低",
    "defect.tier.medium": "中",
    "defect.tier.high": "高",
    "grid.size": "縮圖大小",
    "purge.missing": "重新整理",
    "purge.reject": "清空待刪除檔案",
    "select.all": "全選",
    "select.none": "取消全選",
    "select.count": "已選 {n} 張",
    "select.countOf": "已選 {n} / {total} 張",
    "star.add": "加星號",
    "star.remove": "取消加星號",
    "reject.set": "設為待刪除",
    "reject.unset": "取消待刪除",
    "reject.action": "待刪除",
    "rotate.ccw": "向左旋轉",
    "rotate.cw": "向右旋轉",
    "flip.horizontal": "水平翻轉",
    "crop.edit": "裁切／校正",
    "crop.aspect.free": "自由",
    "crop.aspect.original": "原始比例",
    "crop.aspect.square": "1:1",
    "crop.straighten": "水平校正",
    "crop.resetAngle": "歸零",
    "crop.cancel": "取消",
    "crop.reset": "重設",
    "crop.preview": "預覽",
    "crop.previewHint": "這是套用後的結果",
    "crop.backToEdit": "返回編輯",
    "crop.saveAs": "另存新檔",
    "crop.overwrite": "存檔（覆蓋原始檔）",
    "exposure.overexposed": "偏亮",
    "exposure.underexposed": "偏暗",
    "exposure.normal": "曝光正常",
    "histogram.label": "直方圖",
    "rename.batch": "批次重新命名…",
    "export.batch": "轉檔匯出…",
    "export.quality": "畫質",
    "export.qualityHint": "畫質越低，檔案越小",
    "export.estimating": "正在估算…",
    "export.estimateResult": "預估空間：{current} → {estimated}",
    "export.dimensionChangeHeader": "{n} 張照片會因裁切縮小尺寸：",
    "export.dimensionChangeLine": "{filename}：{ow}×{oh} → {nw}×{nh}",
    "export.dimensionChangeMore": "…等共 {n} 張",
    "export.estimateFailed": "無法估算大小",
    "export.outputPath": "輸出資料夾",
    "export.browse": "瀏覽…",
    "select.clear": "清除選取",
    "grid.empty": "這個分類目前沒有照片",
    "stats.total": "總容量 <b>{size}</b>（{count} 張）",
    "stats.starred": " · 已加星 <b>{n}</b>",
    "stats.rejectFree": " · 待刪除可釋放 <b>{size}</b>",
    "stats.missing": " · <span class=\"stats-missing\">遺失 {n}</span>",
    "soft": "失焦",
    "shake": "手震",
    "lang.zhHans": "简体中文",
    "lang.zhHant": "繁體中文",
    "lang.en": "English",
    "lang.ja": "日本語",
    "lang.ko": "한국어",
  },
  en: {
    "settings.title": "Settings",
    "settings.hint": "Preferences are saved on this Mac. More options can be added here later.",
    "settings.language": "Language",
    "settings.theme": "Theme",
    "settings.theme.dark": "Dark",
    "settings.theme.light": "Light",
    "settings.close": "Done",
    "settings.open": "Settings",
    "settings.version": "Version",
    "settings.checkUpdate": "Check for updates",
    "settings.checkingUpdate": "Checking…",
    "update.available": "Version {version} is available",
    "update.banner": "PhotoPick {version} is available",
    "update.download": "Download update",
    "update.dismiss": "Later",
    "update.dismissTitle": "Remind me later",
    "update.upToDate": "You're up to date",
    "update.checkFailed": "Could not check for updates",
    "account.menu": "Account",
    "account.profile": "Profile",
    "account.plans": "Pricing plans",
    "account.settings": "Settings",
    "profile.hint": "Manage license and device status on this Mac.",
    "profile.close": "Done",
    "license.title": "License",
    "license.mode.trial": "Trial",
    "license.mode.licensed": "Licensed",
    "license.usage.trial": "Photos {photos} · Projects {projects}",
    "license.usage.licensed": "All features unlocked",
    "license.key": "License key",
    "license.email": "Email",
    "license.keyHint": "License key",
    "license.emailUnknown": "—",
    "license.keyPlaceholder": "Paste the key from your purchase email",
    "license.activate": "Activate",
    "license.purchase": "Buy Standard",
    "license.success": "License activated",
    "license.error.empty": "Enter a license key",
    "license.deactivate": "Deactivate this Mac",
    "license.deactivate.hint": "Deactivate before switching computers to free a device slot (up to 2 Macs per key).",
    "license.deactivate.confirm": "Deactivate license on this Mac? It will return to trial mode. You can activate the same key on another Mac.",
    "license.deactivate.success": "This Mac has been deactivated",
    "license.active.hint": "This Mac is licensed. Re-enter the same key after reinstalling or on a new Mac.",
    "license.active.hintWithKey": "Key {key} is active on this Mac.",
    "license.reactivate": "Reactivate",
    "license.reactivate.cancel": "Cancel",
    "license.deviceName": "Device name",
    "license.machineId": "Machine ID",
    "license.machineIdHint": "Provide this ID when contacting support to match your device in our system.",
    "license.machineIdCopied": "Machine ID copied",
    "license.machineIdCopyHint": "Click to copy",
    "license.locked.title": "Not included in trial:",
    "license.locked.batchRename": "Batch rename",
    "license.locked.batchDelete": "Move rejects to Trash",
    "license.locked.defectDetection": "Soft focus / shake detection",
    "license.locked.exposureDetection": "Exposure detection",
    "license.locked.editing": "Crop / straighten",
    "license.locked.export": "Batch export / convert",
    "license.locked.qualityRescan": "Manual full rescan (trial limit used)",
    "license.badge.trial": "Trial · {photos} photos",
    "license.badge.trialTitle": "Trial — click to manage license",
    "license.badge.licensed": "Licensed",
    "license.upgrade.title": "Trial limitation",
    "license.upgrade.body": "\"{feature}\" requires a PhotoPick license.",
    "license.upgrade.hint": "Purchase PhotoPick to unlock.",
    "license.upgradeHint": "Purchase PhotoPick to unlock",
    "license.upgrade.settings": "Enter license key",
    "license.upgrade.close": "Close",
    "plans.title": "Compare plans",
    "plans.subtitle": "One upgrade unlocks everything.",
    "plans.open": "View plans",
    "plans.close": "Close",
    "plans.col.feature": "Feature",
    "plans.col.trial": "Trial",
    "plans.col.standard": "Standard",
    "plans.row.price": "Price",
    "plans.row.projects": "Projects",
    "plans.row.photos": "Photos per project",
    "plans.row.defectDetection": "Soft focus / shake",
    "plans.row.exposureDetection": "Exposure detection",
    "plans.row.editing": "Crop / straighten",
    "plans.row.rotate": "Rotate / flip",
    "plans.row.batchRename": "Batch rename",
            "plans.row.export": "Batch export / convert",
    "plans.row.devices": "Devices",
    "plans.trial.price": "Free",
    "plans.trial.projects": "1",
    "plans.trial.photos": "100",
    "plans.trial.devices": "This Mac",
    "plans.standard.price": "$19 · ≈ NT$590",
    "plans.standard.unlimited": "Unlimited",
    "plans.standard.devices": "2 Macs",
    "plans.yes": "✓",
    "plans.no": "—",
    "plans.footnote": "Pay once, use forever — includes all future paid-feature updates too.",
    "project.label": "Project",
    "project.empty": "(No project yet)",
    "project.emptyHint": "(No project yet — choose a folder)",
    "project.pickFolder": "Choose folder…",
    "project.openFolder": "Open folder",
    "project.delete": "Remove from list",
    "project.deleteTitle": "Removes the project from PhotoPick only; does not delete photos in the folder",
    "project.deleteConfirm": "Remove this project from the list?\n\n{label}\n\nThis only removes indexes, status, and previews in PhotoPick—not the original files on disk.",
    "project.deleteFail": "Could not remove project: {message}",
    "project.missingRoot": "(folder missing)",
    "project.photos": "{n} photos",
    "scan.quality": "Rescan soft focus / shake / exposure",
    "scan.qualityTitle": "Import scans automatically; use this to force a full rescan",
    "analyze": "AI analysis (optional)",
    "tab.all": "All",
    "tab.keep": "Keep",
    "tab.starred": "Starred",
    "tab.soft": "Soft focus",
    "tab.shake": "Shake",
    "tab.blur": "Blur",
    "tab.exposure": "Exposure",
    "tab.reject": "Reject",
    "defect.filter": "Severity",
    "defect.filterAbove": "+",
    "defect.type.all": "All",
    "defect.filterTitle": "Show photos at this severity or higher",
    "defect.tier.low": "Low",
    "defect.tier.medium": "Med",
    "defect.tier.high": "High",
    "grid.size": "Thumb size",
    "purge.missing": "Refresh",
    "purge.reject": "Delete rejected files",
    "select.all": "Select all",
    "select.none": "Deselect all",
    "select.count": "{n} selected",
    "select.countOf": "{n} / {total} selected",
    "star.add": "Star",
    "star.remove": "Unstar",
    "reject.set": "Mark reject",
    "reject.unset": "Undo reject",
    "reject.action": "Reject",
    "rotate.ccw": "Rotate left",
    "rotate.cw": "Rotate right",
    "flip.horizontal": "Flip horizontal",
    "crop.edit": "Crop / Straighten",
    "crop.aspect.free": "Free",
    "crop.aspect.original": "Original",
    "crop.aspect.square": "1:1",
    "crop.straighten": "Straighten",
    "crop.resetAngle": "Reset",
    "crop.cancel": "Cancel",
    "crop.reset": "Reset",
    "crop.preview": "Preview",
    "crop.previewHint": "This is the result after applying",
    "crop.backToEdit": "Back to edit",
    "crop.saveAs": "Save As",
    "crop.overwrite": "Save (overwrite original)",
    "exposure.overexposed": "Bright",
    "exposure.underexposed": "Dark",
    "exposure.normal": "Normal exposure",
    "histogram.label": "Histogram",
    "rename.batch": "Batch rename…",
    "export.batch": "Export / convert…",
    "export.quality": "Quality",
    "export.qualityHint": "Lower quality makes smaller files",
    "export.estimating": "Estimating…",
    "export.estimateResult": "Estimated size: {current} → {estimated}",
    "export.dimensionChangeHeader": "{n} photo(s) will shrink from cropping:",
    "export.dimensionChangeLine": "{filename}: {ow}×{oh} → {nw}×{nh}",
    "export.dimensionChangeMore": "…and {n} more",
    "export.estimateFailed": "Couldn't estimate size",
    "export.outputPath": "Output folder",
    "export.browse": "Browse…",
    "select.clear": "Clear selection",
    "grid.empty": "No photos in this category",
    "stats.total": "Total <b>{size}</b> ({count} photos)",
    "stats.starred": " · Starred <b>{n}</b>",
    "stats.rejectFree": " · Rejects freeable <b>{size}</b>",
    "stats.missing": " · <span class=\"stats-missing\">Missing {n}</span>",
    "soft": "Soft",
    "shake": "Shake",
    "lang.zhHans": "简体中文",
    "lang.zhHant": "繁體中文",
    "lang.en": "English",
    "lang.ja": "日本語",
    "lang.ko": "한국어",
  },
  ja: {
    "settings.title": "設定",
    "settings.hint": "設定はこの Mac に保存されます。今後ここで項目を追加できます。",
    "settings.language": "言語",
    "settings.theme": "テーマ",
    "settings.theme.dark": "ダーク",
    "settings.theme.light": "ライト",
    "settings.close": "完了",
    "settings.open": "設定",
    "settings.version": "バージョン",
    "settings.checkUpdate": "更新を確認",
    "settings.checkingUpdate": "確認中…",
    "update.available": "新しいバージョン {version} があります",
    "update.banner": "PhotoPick {version} が利用可能です",
    "update.download": "更新をダウンロード",
    "update.dismiss": "後で",
    "update.dismissTitle": "後で通知",
    "update.upToDate": "最新バージョンです",
    "update.checkFailed": "更新を確認できませんでした",
    "account.menu": "アカウント",
    "account.profile": "アカウント",
    "account.plans": "プラン",
    "account.settings": "設定",
    "profile.hint": "この Mac のライセンスと端末状態を管理します。",
    "profile.close": "完了",
    "license.title": "ライセンス",
    "license.mode.trial": "試用版",
    "license.mode.licensed": "正式版",
    "license.usage.trial": "写真 {photos} · プロジェクト {projects}",
    "license.usage.licensed": "全機能が利用可能",
    "license.key": "ライセンスキー",
    "license.email": "メール",
    "license.keyHint": "ライセンスキー",
    "license.emailUnknown": "—",
    "license.keyPlaceholder": "購入メールのキーを貼り付け",
    "license.activate": "有効化",
    "license.purchase": "正式版を購入",
    "license.success": "ライセンスを有効化しました",
    "license.error.empty": "キーを入力してください",
    "license.deactivate": "この Mac の認証を解除",
    "license.deactivate.hint": "別の Mac に移す前に解除してください（1 キーあたり最大 2 台）。",
    "license.deactivate.confirm": "この Mac のライセンスを解除しますか？試用版に戻り、同じキーを別の Mac で有効化できます。",
    "license.deactivate.success": "この Mac の認証を解除しました",
    "license.active.hint": "この Mac は有効化済みです。再インストールや別の Mac では同じキーを再入力してください。",
    "license.active.hintWithKey": "キー {key} がこの Mac で有効です。",
    "license.reactivate": "再激活",
    "license.reactivate.cancel": "キャンセル",
    "license.deviceName": "デバイス名",
    "license.machineId": "Machine ID",
    "license.machineIdHint": "サポート連絡時にこの ID を伝えると、管理画面の端末と照合できます。",
    "license.machineIdCopied": "Machine ID をコピーしました",
    "license.machineIdCopyHint": "クリックでコピー",
    "license.locked.title": "試用版では利用できません：",
    "license.locked.batchRename": "一括リネーム",
    "license.locked.batchDelete": "ゴミ箱へ移動",
    "license.locked.defectDetection": "ピンボケ／手ブレ検出",
    "license.locked.exposureDetection": "露出検出",
    "license.locked.editing": "切り抜き／水平補正",
    "license.locked.export": "一括書き出し／変換",
    "license.locked.qualityRescan": "手動フル再スキャン（試用回数使用済み）",
    "license.badge.trial": "試用 · {photos} 枚",
    "license.badge.trialTitle": "試用版 — クリックでライセンス管理",
    "license.badge.licensed": "正式版",
    "license.upgrade.title": "試用版の制限",
    "license.upgrade.body": "「{feature}」は PhotoPick の購入が必要です。",
    "license.upgrade.hint": "PhotoPick を購入すると解除されます。",
    "license.upgradeHint": "PhotoPick を購入して解除",
    "license.upgrade.settings": "ライセンスキーを入力",
    "license.upgrade.close": "閉じる",
    "plans.title": "プラン比較",
    "plans.subtitle": "アップグレードですべての機能が使えます。",
    "plans.open": "プランを見る",
    "plans.close": "閉じる",
    "plans.col.feature": "項目",
    "plans.col.trial": "試用",
    "plans.col.standard": "正式版",
    "plans.row.price": "価格",
    "plans.row.projects": "プロジェクト数",
    "plans.row.photos": "プロジェクトあたりの写真",
    "plans.row.defectDetection": "ピンボケ／手ブレ検出",
    "plans.row.exposureDetection": "露出検出",
    "plans.row.editing": "切り抜き／水平補正",
    "plans.row.rotate": "回転／反転",
    "plans.row.batchRename": "一括リネーム",
            "plans.row.export": "一括書き出し／変換",
    "plans.row.devices": "利用できる端末",
    "plans.trial.price": "無料",
    "plans.trial.projects": "1",
    "plans.trial.photos": "100",
    "plans.trial.devices": "この Mac",
    "plans.standard.price": "$19 · 約 NT$590",
    "plans.standard.unlimited": "無制限",
    "plans.standard.devices": "Mac 2台",
    "plans.yes": "✓",
    "plans.no": "—",
    "plans.footnote": "一度の購入で、ずっと使えます。今後追加される有料機能のアップデートも含まれます。",
    "project.label": "プロジェクト",
    "project.empty": "（プロジェクト未作成）",
    "project.emptyHint": "（プロジェクト未作成 — フォルダを選択）",
    "project.pickFolder": "フォルダを選択…",
    "project.openFolder": "フォルダを開く",
    "project.delete": "リストから削除",
    "project.deleteTitle": "PhotoPick からプロジェクトを外すだけで、フォルダ内の写真は削除しません",
    "project.deleteConfirm": "リストからこのプロジェクトを削除しますか？\n\n{label}\n\nPhotoPick 内の索引・状態・プレビューのみ削除し、ディスク上の原本は削除しません。",
    "project.deleteFail": "プロジェクトを削除できませんでした：{message}",
    "project.missingRoot": "（フォルダがありません）",
    "project.photos": "{n} 枚",
    "scan.quality": "ピンボケ／手ブレ／露出を再スキャン",
    "scan.qualityTitle": "読み込み時に自動スキャン。全件を強制再実行します",
    "analyze": "AI 分析（任意）",
    "tab.all": "すべて",
    "tab.keep": "キープ",
    "tab.starred": "スター付き",
    "tab.soft": "ピンボケ",
    "tab.shake": "手ブレ",
    "tab.blur": "ブレ",
    "tab.exposure": "露出",
    "tab.reject": "却下",
    "defect.filter": "程度",
    "defect.filterAbove": "以上",
    "defect.type.all": "すべて",
    "defect.filterTitle": "選択した程度以上の写真を表示",
    "defect.tier.low": "低",
    "defect.tier.medium": "中",
    "defect.tier.high": "高",
    "grid.size": "サムネイルサイズ",
    "purge.missing": "更新",
    "purge.reject": "却下ファイルを削除",
    "select.all": "すべて選択",
    "select.none": "選択解除",
    "select.count": "{n} 枚選択中",
    "select.countOf": "{n} / {total} 枚選択中",
    "star.add": "スター",
    "star.remove": "スター解除",
    "reject.set": "却下にする",
    "reject.unset": "却下を取り消す",
    "reject.action": "却下",
    "rotate.ccw": "左に回転",
    "rotate.cw": "右に回転",
    "flip.horizontal": "左右反転",
    "crop.edit": "切り抜き／水平補正",
    "crop.aspect.free": "自由",
    "crop.aspect.original": "元の比率",
    "crop.aspect.square": "1:1",
    "crop.straighten": "水平補正",
    "crop.resetAngle": "リセット",
    "crop.cancel": "キャンセル",
    "crop.reset": "リセット",
    "crop.preview": "プレビュー",
    "crop.previewHint": "適用後の結果です",
    "crop.backToEdit": "編集に戻る",
    "crop.saveAs": "名前を付けて保存",
    "crop.overwrite": "保存（元ファイルを上書き）",
    "exposure.overexposed": "明るめ",
    "exposure.underexposed": "暗め",
    "exposure.normal": "適正露出",
    "histogram.label": "ヒストグラム",
    "rename.batch": "一括リネーム…",
    "export.batch": "書き出し／変換…",
    "export.quality": "画質",
    "export.qualityHint": "画質が低いほどファイルが小さくなります",
    "export.estimating": "見積もり中…",
    "export.estimateResult": "予想サイズ：{current} → {estimated}",
    "export.dimensionChangeHeader": "{n} 枚がトリミングでサイズが小さくなります：",
    "export.dimensionChangeLine": "{filename}：{ow}×{oh} → {nw}×{nh}",
    "export.dimensionChangeMore": "…他 {n} 枚",
    "export.estimateFailed": "サイズを見積もれませんでした",
    "export.outputPath": "出力先フォルダ",
    "export.browse": "参照…",
    "select.clear": "選択をクリア",
    "grid.empty": "この分類に写真はありません",
    "stats.total": "合計 <b>{size}</b>（{count} 枚）",
    "stats.starred": " · スター <b>{n}</b>",
    "stats.rejectFree": " · 却下で解放可能 <b>{size}</b>",
    "stats.missing": " · <span class=\"stats-missing\">欠損 {n}</span>",
    "soft": "ピンボケ",
    "shake": "手ブレ",
    "lang.zhHans": "简体中文",
    "lang.zhHant": "繁體中文",
    "lang.en": "English",
    "lang.ja": "日本語",
    "lang.ko": "한국어",
  },
  ko: {
    "settings.title": "설정",
    "settings.hint": "환경설정은 이 Mac에 저장됩니다. 나중에 여기서 항목을 추가할 수 있습니다.",
    "settings.language": "언어",
    "settings.theme": "테마",
    "settings.theme.dark": "어두운 모드",
    "settings.theme.light": "밝은 모드",
    "settings.close": "완료",
    "settings.open": "설정",
    "settings.version": "버전",
    "settings.checkUpdate": "업데이트 확인",
    "settings.checkingUpdate": "확인 중…",
    "update.available": "새 버전 {version} 사용 가능",
    "update.banner": "PhotoPick {version} 출시",
    "update.download": "업데이트 다운로드",
    "update.dismiss": "나중에",
    "update.dismissTitle": "나중에 알림",
    "update.upToDate": "최신 버전입니다",
    "update.checkFailed": "업데이트를 확인할 수 없습니다",
    "account.menu": "계정",
    "account.profile": "프로필",
    "account.plans": "요금제",
    "account.settings": "설정",
    "profile.hint": "이 Mac의 라이선스와 기기 상태를 관리합니다.",
    "profile.close": "완료",
    "license.title": "라이선스",
    "license.mode.trial": "체험판",
    "license.mode.licensed": "정식 버전",
    "license.usage.trial": "사진 {photos} · 프로젝트 {projects}",
    "license.usage.licensed": "모든 기능 사용 가능",
    "license.key": "라이선스 키",
    "license.email": "이메일",
    "license.keyHint": "라이선스 키",
    "license.emailUnknown": "—",
    "license.keyPlaceholder": "구매 이메일의 키를 붙여넣기",
    "license.activate": "활성화",
    "license.purchase": "정식판 구매",
    "license.success": "라이선스가 활성화되었습니다",
    "license.error.empty": "키를 입력하세요",
    "license.deactivate": "이 Mac 인증 해제",
    "license.deactivate.hint": "다른 Mac으로 옮기기 전에 해제하세요(키당 최대 2대).",
    "license.deactivate.confirm": "이 Mac의 라이선스를 해제할까요? 체험판으로 돌아가며 같은 키를 다른 Mac에서 활성화할 수 있습니다.",
    "license.deactivate.success": "이 Mac의 인증이 해제되었습니다",
    "license.active.hint": "이 Mac은 활성화되어 있습니다. 재설치나 다른 Mac에서는 같은 키를 다시 입력하세요.",
    "license.active.hintWithKey": "키 {key}가 이 Mac에서 활성화되어 있습니다.",
    "license.reactivate": "다시 활성화",
    "license.reactivate.cancel": "취소",
    "license.deviceName": "기기 이름",
    "license.machineId": "Machine ID",
    "license.machineIdHint": "지원 문의 시 이 ID를 알려주시면 관리 화면의 기기와 대조할 수 있습니다.",
    "license.machineIdCopied": "Machine ID가 복사되었습니다",
    "license.machineIdCopyHint": "클릭하여 복사",
    "license.locked.title": "체험판에서 제한됨:",
    "license.locked.batchRename": "일괄 이름 변경",
    "license.locked.batchDelete": "휴지통으로 이동",
    "license.locked.defectDetection": "초점 흐림／손떨림 감지",
    "license.locked.exposureDetection": "노출 감지",
    "license.locked.editing": "자르기／수평 보정",
    "license.locked.export": "일괄 내보내기／변환",
    "license.locked.qualityRescan": "수동 전체 재스캔(체험 횟수 소진)",
    "license.badge.trial": "체험 · {photos}장",
    "license.badge.trialTitle": "체험판 — 클릭하여 라이선스 관리",
    "license.badge.licensed": "정식",
    "license.upgrade.title": "체험판 제한",
    "license.upgrade.body": "「{feature}」는 PhotoPick 구매 후 사용할 수 있습니다.",
    "license.upgrade.hint": "PhotoPick을 구매하면 잠금이 해제됩니다.",
    "license.upgradeHint": "PhotoPick 구매로 해제",
    "license.upgrade.settings": "라이선스 키 입력",
    "license.upgrade.close": "닫기",
    "plans.title": "요금제 비교",
    "plans.subtitle": "한 번 업그레이드로 모든 기능을 사용할 수 있습니다.",
    "plans.open": "요금제 보기",
    "plans.close": "닫기",
    "plans.col.feature": "항목",
    "plans.col.trial": "체험",
    "plans.col.standard": "정식판",
    "plans.row.price": "가격",
    "plans.row.projects": "프로젝트 수",
    "plans.row.photos": "프로젝트당 사진",
    "plans.row.defectDetection": "초점 흐림／손떨림 감지",
    "plans.row.exposureDetection": "노출 감지",
    "plans.row.editing": "자르기／수평 보정",
    "plans.row.rotate": "회전／반전",
    "plans.row.batchRename": "일괄 이름 변경",
            "plans.row.export": "일괄 내보내기／변환",
    "plans.row.devices": "사용 가능 기기",
    "plans.trial.price": "무료",
    "plans.trial.projects": "1",
    "plans.trial.photos": "100",
    "plans.trial.devices": "이 Mac",
    "plans.standard.price": "$19 · 약 NT$590",
    "plans.standard.unlimited": "무제한",
    "plans.standard.devices": "Mac 2대",
    "plans.yes": "✓",
    "plans.no": "—",
    "plans.footnote": "한 번 결제로 평생 사용 — 앞으로 추가되는 유료 기능 업데이트도 모두 포함됩니다.",
    "project.label": "프로젝트",
    "project.empty": "(프로젝트 없음)",
    "project.emptyHint": "(프로젝트 없음 — 폴더를 선택하세요)",
    "project.pickFolder": "폴더 선택…",
    "project.openFolder": "폴더 열기",
    "project.delete": "목록에서 제거",
    "project.deleteTitle": "PhotoPick에서만 프로젝트를 제거하며, 폴더 안 사진은 삭제하지 않습니다",
    "project.deleteConfirm": "목록에서 이 프로젝트를 제거할까요?\n\n{label}\n\nPhotoPick의 색인·상태·미리보기만 제거하며, 디스크의 원본 파일은 삭제하지 않습니다.",
    "project.deleteFail": "프로젝트를 제거하지 못했습니다: {message}",
    "project.missingRoot": "(폴더 없음)",
    "project.photos": "{n}장",
    "scan.quality": "초점 흐림／손떨림／노출 다시 스캔",
    "scan.qualityTitle": "가져오기 시 자동 스캔합니다. 전체를 강제 재실행합니다",
    "analyze": "AI 분석（선택）",
    "tab.all": "전체",
    "tab.keep": "보관",
    "tab.starred": "별표",
    "tab.soft": "초점 흐림",
    "tab.shake": "손떨림",
    "tab.blur": "흐림",
    "tab.exposure": "노출",
    "tab.reject": "제외",
    "defect.filter": "정도",
    "defect.type.all": "전체",
    "defect.filterAbove": "이상",
    "defect.filterTitle": "선택한 정도 이상의 사진만 표시",
    "defect.tier.low": "낮음",
    "defect.tier.medium": "보통",
    "defect.tier.high": "높음",
    "grid.size": "썸네일 크기",
    "purge.missing": "새로고침",
    "purge.reject": "제외 파일 삭제",
    "select.all": "모두 선택",
    "select.none": "선택 해제",
    "select.count": "{n}장 선택됨",
    "select.countOf": "{n} / {total}장 선택됨",
    "star.add": "별표",
    "star.remove": "별표 해제",
    "reject.set": "제외로 표시",
    "reject.unset": "제외 취소",
    "reject.action": "제외",
    "rotate.ccw": "왼쪽으로 회전",
    "rotate.cw": "오른쪽으로 회전",
    "flip.horizontal": "좌우 반전",
    "crop.edit": "자르기／수평 보정",
    "crop.aspect.free": "자유",
    "crop.aspect.original": "원본 비율",
    "crop.aspect.square": "1:1",
    "crop.straighten": "수평 보정",
    "crop.resetAngle": "초기화",
    "crop.cancel": "취소",
    "crop.reset": "초기화",
    "crop.preview": "미리보기",
    "crop.previewHint": "적용 후 결과입니다",
    "crop.backToEdit": "편집으로 돌아가기",
    "crop.saveAs": "다른 이름으로 저장",
    "crop.overwrite": "저장（원본 덮어쓰기）",
    "exposure.overexposed": "밝은 편",
    "exposure.underexposed": "어두운 편",
    "exposure.normal": "노출 정상",
    "histogram.label": "히스토그램",
    "rename.batch": "일괄 이름 변경…",
    "export.batch": "내보내기／변환…",
    "export.quality": "화질",
    "export.qualityHint": "화질이 낮을수록 파일이 작아집니다",
    "export.estimating": "예상 크기 계산 중…",
    "export.estimateResult": "예상 용량: {current} → {estimated}",
    "export.dimensionChangeHeader": "{n}장은 자르기로 크기가 줄어듭니다:",
    "export.dimensionChangeLine": "{filename}: {ow}×{oh} → {nw}×{nh}",
    "export.dimensionChangeMore": "…외 {n}장",
    "export.estimateFailed": "크기를 예상할 수 없습니다",
    "export.outputPath": "출력 폴더",
    "export.browse": "찾아보기…",
    "select.clear": "선택 지우기",
    "grid.empty": "이 분류에 사진이 없습니다",
    "stats.total": "전체 <b>{size}</b>（{count}장）",
    "stats.starred": " · 별표 <b>{n}</b>",
    "stats.rejectFree": " · 제외로 확보 가능 <b>{size}</b>",
    "stats.missing": " · <span class=\"stats-missing\">누락 {n}</span>",
    "soft": "초점 흐림",
    "shake": "손떨림",
    "lang.zhHans": "简体中文",
    "lang.zhHant": "繁體中文",
    "lang.en": "English",
    "lang.ja": "日本語",
    "lang.ko": "한국어",
  },
};

function normalizeLang(code) {
  return SUPPORTED_LANGS.includes(code) ? code : null;
}

function detectBrowserLanguage() {
  const candidates = [];
  try {
    if (Array.isArray(navigator.languages)) candidates.push(...navigator.languages);
    if (navigator.language) candidates.push(navigator.language);
  } catch {
    /* ignore */
  }
  for (const raw of candidates) {
    const tag = String(raw || "").toLowerCase().replace(/_/g, "-");
    if (!tag) continue;
    if (tag.startsWith("zh")) {
      if (
        tag.includes("hant") ||
        tag.includes("-tw") ||
        tag.includes("-hk") ||
        tag.includes("-mo")
      ) {
        return "zh-Hant";
      }
      // zh, zh-CN, zh-SG, zh-Hans …
      return "zh-Hans";
    }
    if (tag.startsWith("ja")) return "ja";
    if (tag.startsWith("ko")) return "ko";
    if (tag.startsWith("en")) return "en";
  }
  return "en";
}

function loadSettings() {
  try {
    const raw = JSON.parse(localStorage.getItem(SETTINGS_KEY) || "{}");
    const theme = raw.theme === "light" ? "light" : "dark";
    // 使用者曾存過語言 → 沿用；否則偵測系統語言；無法辨識則英文
    const saved = typeof raw.lang === "string" ? normalizeLang(raw.lang) : null;
    return {
      lang: saved || detectBrowserLanguage(),
      theme,
    };
  } catch {
    return { lang: detectBrowserLanguage(), theme: "dark" };
  }
}

function saveSettings(settings) {
  localStorage.setItem(SETTINGS_KEY, JSON.stringify(settings));
  try {
    fetch("/api/settings", {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        theme: settings.theme,
        lang: settings.lang,
      }),
    }).catch(() => {});
  } catch {
    /* ignore */
  }
}

async function loadSettingsFromServer() {
  try {
    const res = await fetch("/api/settings");
    if (!res.ok) throw new Error("settings fetch failed");
    const raw = await res.json();
    const theme = raw.theme === "light" ? "light" : "dark";
    const saved = typeof raw.lang === "string" ? normalizeLang(raw.lang) : null;
    return {
      lang: saved || detectBrowserLanguage(),
      theme,
    };
  } catch {
    return loadSettings();
  }
}

function t(key, vars) {
  const lang = (window.__photopickSettings && window.__photopickSettings.lang) || "en";
  const table = I18N[lang] || I18N.en;
  let text = table[key] || I18N.en[key] || key;
  if (vars) {
    for (const [k, v] of Object.entries(vars)) {
      text = text.split(`{${k}}`).join(String(v));
    }
  }
  return text;
}

function applyTheme(theme) {
  document.documentElement.dataset.theme = theme === "light" ? "light" : "dark";
}

function applyLanguage(lang) {
  const code = normalizeLang(lang) || "en";
  document.documentElement.lang = code;
  document.querySelectorAll("[data-i18n]").forEach((node) => {
    const key = node.getAttribute("data-i18n");
    if (!key) return;
    node.textContent = t(key);
  });
  document.querySelectorAll("[data-i18n-title]").forEach((node) => {
    const key = node.getAttribute("data-i18n-title");
    if (!key) return;
    node.title = t(key);
  });
  document.querySelectorAll("[data-i18n-placeholder]").forEach((node) => {
    const key = node.getAttribute("data-i18n-placeholder");
    if (!key) return;
    node.setAttribute("placeholder", t(key));
  });
  const accountBtn = document.getElementById("account-menu-btn");
  if (accountBtn) {
    accountBtn.setAttribute("aria-label", t("account.menu"));
    accountBtn.title = t("account.menu");
  }
}

function applySettings(settings, { refreshUi } = { refreshUi: true }) {
  const next = {
    lang: normalizeLang(settings.lang) || "en",
    theme: settings.theme === "light" ? "light" : "dark",
  };
  window.__photopickSettings = next;
  saveSettings(next);
  applyTheme(next.theme);
  applyLanguage(next.lang);
  if (refreshUi && typeof window.__photopickOnSettingsChange === "function") {
    window.__photopickOnSettingsChange();
  }
}
