panatgithub_AnkiHeadingSync/src/presentation/i18n/messages/zh.ts
Dusk 911949bedc fix(sync): make saved field mappings authoritative
中文: 统一已保存字段映射为同步权威来源,移除填空题对 isCloze 与命名猜测的阻断,并让多级列表问答按已保存 titleField 与 slots 同步。

English: Makes saved field mappings the sync authority, removes cloze blocking based on isCloze and name heuristics, and syncs QA Group cards with saved title and slot mappings.
2026-04-26 11:47:11 +08:00

472 lines
27 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type { en } from "./en";
export const zh = {
commands: {
syncCurrentFileToAnki: "同步当前文件到 Anki",
syncVaultToAnki: "同步全库到 Anki",
rebuildCardIndex: "重建卡片索引",
clearCurrentFileSyncedCards: "清空当前文件已同步卡片",
cleanupEmptyDecks: "清理空牌组",
},
settings: {
pluginTitle: "Anki Heading Sync",
ankiConnectUrl: {
name: "AnkiConnect URL",
desc: "默认是 http://127.0.0.1:8765",
placeholder: "http://127.0.0.1:8765",
},
qaHeadingLevel: {
name: "QA 标题层级",
desc: "默认是 H4",
},
clozeHeadingLevel: {
name: "填空题标题层级",
desc: "默认是 H5",
},
cardAnswerCutoffMode: {
name: "卡片正文截止模式",
desc: "有效同步标记始终优先。没有有效标记时,选择继续到整个标题块末尾,或在首个 2+ 连续空行前截止。",
options: {
headingBlock: "heading-block整个标题块",
doubleBlankLines: "double-blank-lines在首个 2+ 连续空行前截止",
},
},
qaGroup: {
title: "QA Group 12",
marker: {
name: "QA Group 标记",
desc: "当 QA 标题以这个 hashtag 标记结尾时,整个标题块会作为一张 ObsiAnki QA Group 12 笔记同步。",
placeholder: "#anki-list",
},
managedNoteType: "托管笔记类型:{{modelName}}。QA Group 同步会直接写入 Stem / GroupId / Src / S01..S12。如果你想在其他同步路径里复用它它也会出现在下面的字段映射面板中。",
managedModelContract: "托管模型约束:同步时会自动检查 {{fieldCount}} 个字段和 {{templateCount}} 个模板。",
},
semanticQa: {
title: "语义 QA",
marker: {
name: "语义 QA 标记",
desc: "当 QA 标题以这个 hashtag 标记结尾时,带缩进子内容的一级列表项会拆分成独立卡片。",
placeholder: "#anki-list-qa",
},
previewTitle: "语义 QA 预览",
triggerHeadingExample: "触发标题示例:{{heading}}",
previewUnavailable: "当前无法生成预览。请使用类似 #anki-list-qa 的尾随 hashtag 标记。",
questionPreview: "问题预览:{{question}}",
answerPreview: "答案预览:{{answer}}",
},
syncOptions: {
addObsidianBacklink: {
name: "添加 Obsidian 回链",
desc: "把来源标题的回链追加到同步后的卡片中。",
},
obsidianBacklinkLabel: {
name: "Obsidian 回链显示名称",
desc: "设置回链显示的文字。留空或只填空格时会回退为 Open in Obsidian。",
placeholder: "Open in Obsidian",
},
obsidianBacklinkPlacement: {
name: "Obsidian 回链放置位置",
desc: "选择把回链追加到问题栏最后一行,或放到答案正文的第一行 / 最后一行。",
options: {
questionLastLine: "问题栏的最后一行",
answerFirstLine: "答案正文的第一行",
answerLastLine: "答案正文的最后一行",
},
},
highlightsToCloze: {
name: "高亮转填空题",
desc: "把 ==highlight== 片段转换成填空题使用的挖空格式。",
},
syncObsidianTagsToAnki: {
name: "同步 Obsidian 标签到 Anki",
desc: "将当前笔记中 Obsidian 识别到的标签同步为 Anki 笔记标签,支持嵌套标签。每次同步时,这些标签都会以当前 Obsidian 内容为准覆盖 Anki。",
},
keepPureTagLinesInCardBody: {
name: "在卡片正文中保留纯标签行",
desc: "关闭后,会删除正文中所有只包含标签的整行,例如 “#项目A #重点/案例”。像“这是 #标签 的案例”这类行内标签,或“标签:#项目A”这类带普通文字的行不会被删除。删除后会自动清理多余空行。",
},
},
mapping: {
title: "笔记类型字段映射",
refresh: {
name: "从 Anki 刷新笔记类型",
button: "刷新笔记类型",
},
status: {
idle: "请先从 Anki 刷新笔记类型,以加载可用的笔记类型列表。",
loadedCount: "已从 Anki 加载 {{count}} 个笔记类型。",
empty: "Anki 没有返回任何笔记类型。",
failedLoadNoteTypes: "从 Anki 加载笔记类型失败。",
loadedSavedMapping: "已加载 {{modelName}} 的已保存映射。",
selectedModel: "已选择 {{modelName}}。请从 Anki 读取字段以创建或刷新它的映射。",
loadedFieldsForModel: "已加载 {{modelName}} 的字段。请检查建议映射后保存。",
failedLoadFields: "加载 {{modelName}} 的字段失败。",
noLoadedFields: "{{modelName}} 还没有已加载字段。请先从 Anki 读取字段。",
savedMapping: "已保存 {{modelName}} 的映射。",
failedSaveMapping: "保存 {{modelName}} 的映射失败。",
savedMappingReady: "{{title}} 的已保存映射已就绪。",
noSavedMapping: "{{title}} 还没有已保存映射。请先从 Anki 读取字段。",
},
section: {
basic: {
title: "QA / 基础卡",
description: "选择 QA 笔记类型,从 Anki 读取字段,然后确认标题/正文映射。",
},
cloze: {
title: "填空题",
description: "选择填空题笔记类型,从 Anki 读取字段,然后确认主字段映射。",
},
semanticQa: {
title: "语义 QA",
description: "选择语义 QA 笔记类型,从 Anki 读取字段,然后确认子卡片的标题/正文映射。",
},
},
noteTypeLabel: "{{title}} 笔记类型",
noteTypeDesc: "从 Anki 的笔记类型列表加载。如果最新模型没有显示,请先刷新。",
fieldsLabel: "{{title}} 字段",
fieldsDesc: "从 Anki 读取当前笔记类型的字段,然后检查建议映射。",
readFieldsButton: "从 Anki 读取字段",
loadedFields: "已加载字段:{{fields}}",
loadedFieldsNone: "已加载字段:无。请先从 Anki 读取字段。",
mappingLabel: "{{title}} 映射",
mappingDesc: "保存当前笔记类型的字段映射。",
saveMappingButton: "保存映射",
titleFieldLabel: "{{title}} 标题字段",
titleFieldDesc: "选择接收标题片段的 Anki 字段。",
bodyFieldLabel: "{{title}} 正文字段",
bodyFieldDesc: "选择接收正文片段的 Anki 字段。",
mainField: {
name: "填空题主字段",
desc: "同步时,所选字段会接收 标题 + <br><br> + 正文。",
},
selectFieldPlaceholder: "-- 选择字段 --",
},
deck: {
defaultSectionTitle: "默认牌组",
defaultDeck: {
name: "默认牌组",
desc: "优先级最低:当文件级自定义牌组与文件夹映射牌组都未命中时使用。",
},
fileDeckSectionTitle: "文件级自定义牌组",
fileDeckEnabled: {
name: "开启文件级自定义牌组",
desc: "开启后,可在 YAML 或正文中用统一识别名为整篇笔记指定一个牌组。",
},
marker: {
name: "牌组识别名",
desc: "YAML key 与正文标记共用同一个识别名。默认值是 TARGET DECK。",
},
template: {
name: "默认牌组模板",
desc: "只支持 filename 变量。插入时会展开为当前文件名(不含 .md。",
},
insertLocation: {
name: "模板插入位置",
desc: "选择将牌组模板写入 YAML frontmatter 还是正文前部。",
options: {
body: "正文前部",
yaml: "YAML frontmatter",
},
},
insertTemplate: {
name: "向当前文件插入牌组模板",
desc: "按当前识别名、模板和插入位置,把牌组声明写入当前活动 Markdown 文件。",
button: "插入牌组模板",
},
folderMappingSectionTitle: "高级:文件夹映射牌组",
folderDeckMode: {
name: "文件夹映射模式",
desc: "关闭 / 仅父文件夹 / 文件夹及文件名。",
options: {
off: "关闭",
folder: "文件夹级映射",
folderAndFile: "文件夹及文件名级映射",
},
},
examplesTitle: "示例:",
folderExample: "文件夹映射牌组示例:数学/第一章/第一节.md -> 数学::第一章",
folderAndFileExample: "文件夹及文件名映射牌组示例:数学/第一章/第一节.md -> 数学::第一章::第一节",
fallbackDesc: "若均不打开「文件夹及文件名」及「文件级」牌组,则以「默认牌组名称」作为 Anki 的牌组名。",
priorityTitle: "最终牌组优先级说明",
priorityDesc: "最终牌组优先级:文件级自定义牌组 > 文件夹映射牌组 > 默认牌组。",
},
scope: {
name: "插件运行范围",
summary: {
all: "处理整个 vault 中的 Markdown 文件",
include: "仅处理下方勾选文件夹中的 Markdown 文件",
exclude: "处理整个 vault但跳过下方勾选文件夹中的 Markdown 文件",
},
option: {
all: "全部文件",
include: "仅在指定文件夹",
exclude: "排除指定文件夹",
},
treeDescription: {
include: "仅在指定文件夹:只处理下方勾选文件夹中的 Markdown 文件",
exclude: "排除指定文件夹:处理整个 vault但跳过下方勾选文件夹中的 Markdown 文件",
},
loading: "正在读取当前 vault 文件夹...",
empty: "当前 vault 中没有可选文件夹。",
failedLoad: "读取当前 vault 文件夹失败。",
expandFolder: "展开 {{name}}",
collapseFolder: "收起 {{name}}",
},
cards: {
cardTypes: {
title: "卡片类型及基础设置",
desc: "直接编辑识别规则,修改后自动保存。",
advancedHint: "高级项:将 AnkiConnect URL 保留在这里,不单独做连接状态卡片。",
markerPlaceholder: "/",
fieldsUnavailable: "-- 请先读取字段 --",
autoManagedField: "自动维护",
autoComposedAnswer: "自动拼接",
qaGroupManagedNoteType: "{{modelName}}(自动维护)",
statusLabel: "状态:",
cacheEmpty: "当前没有已缓存的 Anki 笔记模板。请手动读取 Anki 里的模板配置。",
cacheSummary: "当前使用缓存的 {{noteTypeCount}} 个笔记模板,已选择并配置 {{configuredCount}} 个卡片模式。",
cacheChanged: "检测到 Anki 当前有 {{liveCount}} 个笔记模板,和本页缓存的 {{cachedCount}} 个模板不一致。当前仍在使用缓存,已选择并配置 {{configuredCount}} 个卡片模式;如需更新请手动读取 Anki 里的模板配置。",
cacheCheckFailed: "当前继续使用缓存的 {{noteTypeCount}} 个笔记模板,已选择并配置 {{configuredCount}} 个卡片模式;后台检查最新模板列表失败,如需更新请手动读取 Anki 里的模板配置。",
loadedSummary: "已获取 {{noteTypeCount}} 个笔记模板,已选择并配置 {{configuredCount}} 个卡片模式。",
loadedFieldsStatus: "已刷新 {{count}} 个当前所选模板的字段。",
failedLoad: "从 Anki 读取模板或字段失败。",
failedSave: "保存卡片类型设置失败。",
loadAnki: {
button: "手动读取 Anki 里的模板配置",
loading: "正在读取 Anki 模板和字段...",
},
columns: {
enabled: "启用",
type: "卡片类型",
headingLevel: "卡片标记",
extraMarker: "额外标记",
noteType: "Anki 笔记模板",
questionField: "问题字段",
answerField: "答案字段",
},
labels: {
headingLevel: "卡片标记:",
extraMarker: "额外标记:",
noteType: "Anki 笔记模板:",
questionField: "问题字段:",
answerField: "答案字段:",
mainField: "主字段:",
fields: "字段:",
qaGroupTitleField: "题目字段:",
qaGroupSlotFields: "问题/答案字段:",
qaGroupWarnings: "警告:",
},
qaGroup: {
noModel: "请先选择 Anki 笔记模板",
unavailable: "请先手动读取字段",
detectedSlots: "已识别 {{count}} 组",
acceptWarnings: "我已确认忽略当前警告,并允许同步",
warning: {
missingAnswer: "第 {{index}} 组缺少答案字段,已忽略 {{questionField}} / {{answerField}}。",
missingQuestion: "第 {{index}} 组缺少问题字段,已忽略 {{questionField}} / {{answerField}}。",
},
},
rows: {
basic: "问答题(常规段落形式)",
qaGroup: "问答题(多级列表形式)",
cloze: "填空题",
semanticQa: "语义问答题",
},
},
syncContent: {
title: "卡片正文同步内容",
desc: "这些选项只影响卡片渲染内容,修改后仅刷新这一张卡片。",
sections: {
bodyRange: "1. 确定「卡片正文」范围",
backlink: "2. 确定是否增加回链,方便从 Anki「卡片级跳转」回 Obsidian",
tags: "3. 确定是否读取「标签」",
clozeSpecial: "4. 「填空题」专项",
},
},
scope: {
title: "插件运行范围",
desc: "保留现有作用范围和文件夹树逻辑;文件夹树按需加载,并支持局部刷新。",
refreshFolders: "刷新文件夹列表",
},
deck: {
title: "卡片牌组设置",
desc: "卡片牌组设置按推荐路径分组展示。",
sections: {
folderMapping: "1推荐用「文件夹及文件名」作为「Anki牌组」",
fileDeck: "2可打开「文件级自定义牌组」作为个性化定制",
defaultDeck: "3默认牌组作为兜底",
},
},
commands: {
title: "命令说明",
desc: "下面展示当前命令面板中可用的插件命令。",
items: {
syncCurrentFile: "只把当前活动 Markdown 文件同步到 Anki。",
syncVault: "把全库中所有处于作用范围内的 Markdown 文件同步到 Anki。",
rebuildIndex: "只重建本地卡片索引,不创建或更新远端笔记。",
clearCurrentFile: "清空当前文件的已同步标记和本地跟踪状态。",
cleanupDecks: "从 Anki 删除所选空牌组。",
},
},
},
},
modal: {
emptyDeck: {
title: "清理空牌组",
description: "勾选要删除的空牌组。只有删除时仍为空的牌组会被真正删除。",
selectAll: "全选全部",
clearAll: "全部不选",
invert: "反选",
cancel: "取消",
deleteSelected: "删除所选空牌组",
selectionCount: "已选 {{selected}} / 共 {{total}} 个空牌组",
},
},
notice: {
invalidSettingsRestored: "检测到无效的插件设置,已在内存中恢复默认设置。",
failedSavePluginSettings: "保存插件设置失败。",
noActiveMarkdownForSync: "当前没有可用于同步的活动 Markdown 文件。",
syncUseCaseNotInitialized: "同步用例尚未初始化。",
currentFileSyncFailed: "当前文件同步失败。",
vaultSyncFailed: "全库同步失败。",
rebuildFailed: "卡片索引重建失败。",
noActiveMarkdownForDeckTemplateInsertion: "当前没有可用于插入牌组模板的活动 Markdown 文件。",
vaultGatewayNotInitialized: "Vault 网关尚未初始化。",
markdownFileNotFound: "未找到 Markdown 文件:{{filePath}}",
deckTemplateAlreadyCurrent: "当前文件中的牌组模板已是最新,无需重复写入。",
deckTemplateInserted: "已向当前文件写入牌组模板:{{deck}}",
deckTemplateInsertionFailed: "插入牌组模板失败。",
noActiveMarkdownForReset: "当前没有可用于重置的活动 Markdown 文件。",
clearCurrentFileUseCaseNotInitialized: "清空当前文件用例尚未初始化。",
noTrackedCardsInCurrentFile: "当前文件没有已同步卡片。",
clearCurrentFileFailed: "清空当前文件已同步卡片失败。",
cleanupEmptyDecksUseCaseNotInitialized: "空牌组清理用例尚未初始化。",
noEmptyDeckCandidates: "未发现可清理的空牌组。",
cleanupEmptyDecksCancelled: "已取消空牌组清理。",
cleanupEmptyDecksFailed: "清理空牌组失败。",
summary: {
currentFileSync: "当前文件同步完成:文件 {{scannedFiles}},卡片 {{scannedCards}},新建 {{created}},更新 {{updated}},迁移模板 {{migratedNoteTypes}},迁移牌组 {{migratedDecks}},孤儿 {{orphaned}},媒体 {{uploadedMedia}},跳过 {{skippedUnchangedCards}}。",
vaultSync: "全库同步完成:文件 {{scannedFiles}},卡片 {{scannedCards}},新建 {{created}},更新 {{updated}},迁移模板 {{migratedNoteTypes}},迁移牌组 {{migratedDecks}},孤儿 {{orphaned}},媒体 {{uploadedMedia}},跳过 {{skippedUnchangedCards}}。",
rebuild: "卡片索引重建完成:文件 {{scannedFiles}},卡片 {{scannedCards}},迁移牌组 {{migratedDecks}},孤儿 {{orphaned}},重写标记 {{rewrittenMarkers}},跳过 {{skippedUnchangedCards}}。",
clearCurrentFile: "当前文件已同步卡片清空完成:已跟踪卡片 {{trackedCards}},已跟踪分组 {{trackedGroups}},删除笔记 {{deletedNotes}},移除标记 {{removedMarkers}},移除 ID 标记 {{removedCardMarkers}},移除 GI 标记 {{removedGroupMarkers}},删除本地记录 {{deletedLocalRecords}}。",
cleanupEmptyDecks: "空牌组清理完成:候选 {{candidateCount}},已选 {{selectedCount}},已删 {{deletedCount}},跳过 {{skippedCount}}。",
markerWriteConflicts: "标记写回冲突:{{files}}。",
warningsCount: "警告:{{count}}。",
markerRemovalConflicts: "标记移除冲突:{{files}}。",
failures: "失败项:{{items}}。",
skippedDecks: "跳过的牌组:{{decks}}。",
},
},
errors: {
currentFileOutOfScope: "当前文件不在插件作用范围内:{{filePath}}",
deck: {
emptyName: "牌组不能为空,请检查文件级牌组声明或默认牌组设置。",
},
settings: {
headingLevelsRange: "标题层级必须是 1 到 6 之间的整数。",
headingLevelsDifferent: "QA 和填空题的标题层级必须不同。",
cardTypeConfigsObject: "卡片类型配置必须是对象。",
cardTypeEnabledBoolean: "每种卡片类型的启用状态必须是布尔值。",
cardTypeExtraMarkerString: "每种卡片类型的额外标记必须是字符串。",
cardTypeDefaultConflict: "同一个 H{{headingLevel}} 只能有一个启用的默认卡片类型。",
cardAnswerCutoffModeInvalid: "卡片正文截止模式只能是 heading-block 或 double-blank-lines。",
qaNoteTypeRequired: "QA 笔记类型不能为空。",
qaGroupMarkerRequired: "QA Group 标记不能为空。",
qaGroupMarkerInvalid: "QA Group 标记必须是类似 #anki-list 的 hashtag 样式 token。",
clozeNoteTypeRequired: "填空题笔记类型不能为空。",
semanticQaMarkerRequired: "语义 QA 标记不能为空。",
semanticQaMarkerInvalid: "语义 QA 标记必须是类似 #anki-list-qa 的 hashtag 样式 token。",
qaGroupMarkerConflict: "QA Group 标记必须和语义 QA 标记不同。",
semanticQaNoteTypeRequired: "语义 QA 笔记类型不能为空。",
defaultDeckRequired: "默认牌组不能为空。",
fileDeckEnabledBoolean: "文件级牌组开关必须是布尔值。",
syncObsidianTagsToAnkiBoolean: "同步 Obsidian 标签到 Anki 开关必须是布尔值。",
keepPureTagLinesInCardBodyBoolean: "保留正文纯标签行开关必须是布尔值。",
fileDeckMarkerString: "文件级牌组识别名必须是字符串。",
fileDeckTemplateString: "文件级牌组模板必须是字符串。",
fileDeckInsertLocationInvalid: "文件级牌组模板插入位置只能是 yaml 或 body。",
folderDeckModeInvalid: "文件夹牌组模式只能是 off、folder 或 folder-and-file。",
scopeModeInvalid: "运行范围模式只能是 all、include 或 exclude。",
obsidianBacklinkPlacementInvalid: "Obsidian 回链放置位置只能是 question-last-line、answer-first-line 或 answer-last-line。",
includeFoldersArray: "包含文件夹必须是数组。",
includeFoldersStrings: "包含文件夹列表中只能包含字符串。",
excludeFoldersArray: "排除文件夹必须是数组。",
excludeFoldersStrings: "排除文件夹列表中只能包含字符串。",
ankiConnectUrlRequired: "AnkiConnect URL 不能为空。",
ankiNoteTypeCacheArray: "Anki 笔记模板缓存必须是数组。",
ankiNoteTypeCacheStrings: "Anki 笔记模板缓存中只能包含字符串。",
ankiModelFieldCacheObject: "Anki 模板字段缓存必须是对象。",
ankiModelFieldCacheEntryObject: "每个 Anki 模板字段缓存项都必须是对象。",
ankiModelFieldCacheFieldNamesArray: "Anki 模板字段缓存中的 fieldNames 必须是数组。",
ankiModelFieldCacheFieldNamesStrings: "Anki 模板字段缓存中的 fieldNames 只能包含字符串。",
ankiModelFieldCacheLoadedAt: "Anki 模板字段缓存中的 loadedAt 必须是有限数字。",
noteFieldMappingsObject: "字段映射必须是对象。",
noteFieldMappingsCardType: "字段映射必须使用受支持的卡片类型。",
noteFieldMappingsModelName: "字段映射必须包含模型名称。",
noteFieldMappingsLoadedFieldNames: "字段映射必须包含已加载字段名。",
noteFieldMappingsLoadedAt: "字段映射必须包含已加载时间戳。",
noteFieldMappingsQaGroupSlotsArray: "QA Group 字段映射中的 slots 必须是数组。",
noteFieldMappingsQaGroupSlotObject: "QA Group 字段映射中的每个 slot 都必须是对象。",
noteFieldMappingsQaGroupSlotIndex: "QA Group 字段映射中的 slot.index 必须是大于 0 的整数。",
noteFieldMappingsQaGroupSlotQuestionField: "QA Group 字段映射中的 slot.questionField 必须是字符串。",
noteFieldMappingsQaGroupSlotAnswerField: "QA Group 字段映射中的 slot.answerField 必须是字符串。",
noteFieldMappingsQaGroupWarningsArray: "QA Group 字段映射中的 warnings 必须是数组。",
noteFieldMappingsQaGroupWarningsStrings: "QA Group 字段映射中的 warnings 只能包含字符串。",
noteFieldMappingsQaGroupAcceptedWarningsArray: "QA Group 字段映射中的 acceptedWarnings 必须是数组。",
noteFieldMappingsQaGroupAcceptedWarningsStrings: "QA Group 字段映射中的 acceptedWarnings 只能包含字符串。",
},
noteFieldMapping: {
noteTypeNotSelected: {
basic: "基础卡尚未选择 Anki 笔记模板。请先在设置页选择模板后再同步。",
cloze: "填空题尚未选择 Anki 笔记模板。请先在设置页选择模板后再同步。",
semanticQa: "语义 QA 尚未选择 Anki 笔记模板。请先在设置页选择模板后再同步。",
qaGroup: "问答题(多级列表)尚未选择 Anki 笔记模板。请先在设置页选择模板后再同步。",
},
missingSavedMapping: {
basic: "找不到基础卡笔记类型 \"{{modelName}}\" 的已保存字段映射。请打开插件设置并先从 Anki 读取字段。",
cloze: "找不到填空题笔记类型 \"{{modelName}}\" 的已保存字段映射。请打开插件设置并先从 Anki 读取字段。",
semanticQa: "找不到语义 QA 笔记类型 \"{{modelName}}\" 的已保存字段映射。请打开插件设置并先从 Anki 读取字段。",
qaGroup: "找不到问答题(多级列表)笔记模板 \"{{modelName}}\" 的已保存字段映射。请先在设置页从 Anki 读取字段并保存映射。",
},
incompleteSavedMapping: {
basic: "基础卡笔记类型 \"{{modelName}}\" 的已保存字段映射不完整。请打开插件设置并保存标题字段和正文字段。",
semanticQa: "语义 QA 笔记类型 \"{{modelName}}\" 的已保存字段映射不完整。请打开插件设置并保存标题字段和正文字段。",
cloze: "填空题笔记类型 \"{{modelName}}\" 的已保存字段映射不完整。请打开插件设置并保存主字段。",
},
titleBodyMustDiffer: {
basic: "基础卡笔记类型 \"{{modelName}}\" 的标题字段和正文字段必须不同。",
semanticQa: "语义 QA 笔记类型 \"{{modelName}}\" 的标题字段和正文字段必须不同。",
},
stale: "笔记类型 \"{{modelName}}\" 的已保存字段映射已过期,因为这些字段在 Anki 中已不存在:{{fields}}。请重新从 Anki 读取字段。",
clozeIncompatible: "填空题笔记类型 \"{{modelName}}\" 在 Anki 中不是填空题兼容模型。",
qaGroupMissingTitle: "问答题(多级列表)笔记模板 \"{{modelName}}\" 的已保存字段映射不完整,缺少标题字段。请在设置页重新保存字段映射。",
qaGroupNoCompleteSlots: "问答题(多级列表)笔记模板 \"{{modelName}}\" 的已保存字段映射不完整,至少需要一组问题/答案字段。请在设置页重新保存字段映射。",
qaGroupNonContinuousSlots: "问答题(多级列表)笔记模板 \"{{modelName}}\" 的第一组问题/答案字段不是从第 {{firstIndex}} 组开始连续编号。请从第 1 组开始。",
qaGroupWarningsUnaccepted: "问答题(多级列表)笔记模板 \"{{modelName}}\" 仍有未确认的字段警告。请先在设置页确认后再同步。",
qaGroupSlotCapacityExceeded: "问答题(多级列表)笔记模板 \"{{modelName}}\" 的已保存字段映射只包含 {{capacity}} 组问题/答案字段,但当前块有 {{itemCount}} 项:{{filePath}}:{{blockStartLine}}。",
},
noteTypeMigration: {
failed: "无法将 Anki 笔记 {{noteId}} 从“{{fromModel}}”迁移到“{{toModel}}”{{location}}{{reason}}",
unsupported: "当前 AnkiConnect 不支持将 Anki 笔记 {{noteId}} 从“{{fromModel}}”迁移到“{{toModel}}”{{location}}。请升级 AnkiConnect或清理该卡片的 Anki ID 后重新同步。原因:{{reason}}",
},
writeBack: {
summary: "Markdown 标记写回失败,共 {{fileCount}} 个文件。",
markdownFileNotFound: "Markdown 文件不存在。",
missingSourceContent: "缺少用于写回标记的扫描源码内容。",
noteIdMissing: "无法为第 {{blockStartLine}} 行所在块写入标记,因为缺少 note ID。",
},
markerRemoval: {
markdownFileNotFound: "Markdown 文件不存在。",
},
},
warnings: {
deck: {
conflictYamlBody: "检测到 YAML 和正文中的 {{marker}} 声明互相冲突,本次同步已使用 YAML 的值。",
multipleBodyDeclarations: "检测到文件中存在多个 {{marker}} 声明,本次同步只使用第一个正文声明。",
invalidFolderSegment: "检测到文件夹名或文件名包含 ::,已跳过文件夹映射并回退到默认牌组。",
fallbackDefault: "该文件没有显式牌组,且无法生成文件夹映射牌组,已回退到默认牌组。",
},
},
} satisfies typeof en;
export default zh;