{"version":3,"file":"core.umd.cjs","sources":["../../i18n/src/index.ts","../../i18n/src/zh-cn.ts","../../i18n/src/zh-tw.ts","../../i18n/src/en-us.ts","../../i18n/src/ja-jp.ts","../../i18n/src/ko-kr.ts","../../../plugins/docx-editor-schema/src/constants.ts","../../../plugins/docx-editor-schema/src/author-color.ts","../../../plugins/docx-editor-schema/src/revision.ts","../../../node_modules/.pnpm/rfdc@1.4.1/node_modules/rfdc/index.js","../../../plugins/docx-editor-schema/src/walk.ts","../../../plugins/docx-editor-schema/src/control.ts","../../../plugins/docx-editor-schema/src/format.ts","../../../plugins/docx-editor-schema/src/paragraph.ts","../../../plugins/docx-editor-schema/src/export.ts","../../../plugins/docx-editor-schema/src/page-fields.ts","../../../plugins/docx-editor-schema/src/keymap.ts","../../../node_modules/.pnpm/eventemitter3@5.0.4/node_modules/eventemitter3/index.js","../../../plugins/docx-editor-state/src/event-bus.ts","../../../plugins/docx-editor-state/src/listener.ts","../../../plugins/docx-editor-state/src/range-manager.ts","../../../plugins/docx-editor-view/src/text-measure.ts","../../../plugins/docx-editor-view/src/control-presentation.ts","../../../plugins/docx-editor-view/src/east-asian-layout.ts","../../../plugins/docx-editor-view/src/list-bullet.ts","../../../plugins/docx-editor-view/src/block-painter.ts","../../../plugins/docx-editor-view/src/block-signature.ts","../../../plugins/docx-editor-view/src/canvas-renderer.ts","../../../plugins/docx-editor-view/src/layout-engine.ts","../../../plugins/docx-editor-view/src/hit-test.ts","../../../plugins/docx-editor-view/src/caret-rect.ts","../../../plugins/docx-editor-view/src/view-i18n.ts","../../../plugins/docx-editor-view/src/context-menu.ts","../../../plugins/docx-editor-view/src/widgets/handle-position.ts","../../../plugins/docx-editor-view/src/assets/components/table-properties-widget.html?raw","../../../plugins/docx-editor-view/src/widgets/layout/table-properties-widget.ts","../../../plugins/docx-editor-view/src/widgets/table-widget.ts","../../../plugins/docx-editor-view/src/widgets/selection-layer.ts","../../../plugins/docx-editor-view/src/widgets/image-widget.ts","../../../plugins/docx-editor-view/src/widgets/chart-widget.ts","../../../plugins/docx-editor-view/src/assets/components/paragraph-layout-widget.html?raw","../../../plugins/docx-editor-view/src/widgets/layout/paragraph-layout-widget.ts","../../../plugins/docx-editor-view/src/assets/components/font-layout-widget.html?raw","../../../plugins/docx-editor-view/src/widgets/layout/font-layout-widget.ts","../../../plugins/docx-editor-view/src/assets/components/hyperlink-widget.html?raw","../../../plugins/docx-editor-view/src/widgets/layout/hyperlink-widget.ts","../../../plugins/docx-editor-view/src/widgets/paragraph-widget.ts","../../../plugins/docx-editor-view/src/widgets/header-footer-widget.ts","../../../plugins/docx-editor-view/src/widgets/ruler-widget.ts","../../../plugins/docx-editor-view/src/widgets/watermark-widget.ts","../../../plugins/docx-editor-view/src/widgets/watermark-system-widget.ts","../../../plugins/docx-editor-view/src/widgets/selection-toolbar-widget.ts","../../../plugins/docx-editor-view/src/widgets/caret-widget.ts","../../../plugins/docx-editor-view/src/widgets/control-widget.ts","../../../plugins/docx-editor-view/src/render-state.ts","../../../plugins/docx-editor-view/src/layout-query.ts","../../../plugins/docx-editor-view/src/anchor-collector.ts","../../../plugins/docx-editor-view/src/caret-navigation.ts","../../../plugins/docx-editor-view/src/zone-manager.ts","../../../plugins/docx-editor-view/src/draw.ts","../src/command-chain.ts","../../../plugins/docx-editor-transform/src/command-adapt.ts","../../../plugins/docx-editor-transform/src/command.ts","../../../plugins/docx-editor-commands/src/constants.ts","../../../plugins/docx-editor-commands/src/date-picker.ts","../../../plugins/docx-editor-commands/src/date-particle.ts","../../../plugins/docx-editor-commands/src/latex-hershey.ts","../../../plugins/docx-editor-commands/src/latex-symbols.ts","../../../plugins/docx-editor-commands/src/latex-utils.ts","../../../plugins/docx-editor-commands/src/latex-particle.ts","../../../plugins/docx-editor-commands/src/search.ts","../../../plugins/docx-editor-commands/src/block-iframe.ts","../../../plugins/docx-editor-commands/src/block-base.ts","../../../plugins/docx-editor-commands/src/block-particle.ts","../../../plugins/docx-editor-commands/src/control-component.ts","../../../plugins/docx-editor-history/src/history-manager.ts","../../../plugins/docx-editor-history/src/history-component.ts","../../../plugins/docx-editor-keymap/src/shortcut.ts","../src/workers/compute.ts","../src/workers/worker-manager.ts","../src/workers/thumbnail-manager.ts","../src/docx-editor.ts","../src/constants.ts","../src/index.ts"],"sourcesContent":["import zhCN from './zh-cn.js'\r\nimport zhTW from './zh-tw.js'\r\nimport enUS from './en-us.js'\r\nimport jaJP from './ja-jp.js'\r\nimport koKR from './ko-kr.js'\r\n\r\nexport const builtinMessages = { zhCN, zhTW, enUS, jaJP, koKR }\r\nexport type BuiltinLocale = keyof typeof builtinMessages\r\nexport type EditorI18n = I18n<BuiltinLocale>\r\n\r\nexport function createEditorI18n(locale: BuiltinLocale = 'zhCN'): EditorI18n {\r\n  return createI18n(builtinMessages, locale, 'zhCN')\r\n}\r\n\r\nexport type Messages = { [key: string]: string | Messages }\r\nexport type Translate = (key: string, params?: Record<string, string | number>) => string\r\n\r\nexport interface I18n<Locale extends string> {\r\n  readonly locale: Locale\r\n  t: Translate\r\n  setLocale(locale: Locale): void\r\n  subscribe(listener: () => void): () => void\r\n}\r\n\r\nfunction lookup(messages: Messages | undefined, key: string): string | undefined {\r\n  let value: string | Messages | undefined = messages\r\n  for (const segment of key.split('.')) {\r\n    if (typeof value !== 'object' || value === null) return undefined\r\n    value = value[segment]\r\n  }\r\n  return typeof value === 'string' ? value : undefined\r\n}\r\n\r\nexport function createI18n<Locale extends string>(\r\n  bundles: Record<Locale, Messages>,\r\n  initialLocale: Locale,\r\n  fallbackLocale: Locale = initialLocale\r\n): I18n<Locale> {\r\n  let locale = initialLocale\r\n  const listeners = new Set<() => void>()\r\n\r\n  return {\r\n    get locale() { return locale },\r\n    t(key, params) {\r\n      const message = lookup(bundles[locale], key) ?? lookup(bundles[fallbackLocale], key) ?? key\r\n      return message.replace(/\\{(\\w+)\\}/g, (_, name: string) => String(params?.[name] ?? ''))\r\n    },\r\n    setLocale(nextLocale) {\r\n      if (locale === nextLocale) return\r\n      locale = nextLocale\r\n      listeners.forEach(listener => listener())\r\n    },\r\n    subscribe(listener) {\r\n      listeners.add(listener)\r\n      return () => listeners.delete(listener)\r\n    }\r\n  }\r\n}\r\n","export default {\r\n  chart: {\r\n    dialog: { title: '插入图表', settings: '设置', data: '数据', selectType: '选择图表类型', preview: '图表预览', config: '图表配置', clear: '清空', cancel: '取消', confirm: '确定' },\r\n    category: { bar: '柱形图', line: '折线图', pie: '饼图', scatter: '散点图', radar: '雷达图', mixed: '混合图表' },\r\n    preview: { 'bar-basic': '基础柱状图', 'bar-stacked': '堆叠柱状图', 'bar-horizontal': '横向柱状图', 'line-basic': '基础折线图', 'line-smooth': '平滑折线图', 'line-stacked': '堆叠折线图', 'line-area': '堆叠面积图', 'line-step': '阶梯折线图', 'line-dashed': '虚线折线图', 'pie-basic': '基础饼图', 'pie-doughnut': '环形图', 'scatter-basic': '基础散点图', 'radar-basic': '基础雷达图', 'radar-filled': '填充雷达图', 'mixed-line-bar': '折柱混合' },\r\n    config: { showTitle: '显示标题', title: '标题名称', titlePlaceholder: '请输入图表标题', titlePosition: '标题位置', showLegend: '显示图例', legendPosition: '图例位置', xAxisLabel: 'X轴标题', xAxisPlaceholder: '请输入X轴标题', yAxisLabel: 'Y轴标题', yAxisPlaceholder: '请输入Y轴标题', showGrid: '显示网格线', showDataLabel: '显示数据标签', colorScheme: '配色方案' },\r\n    position: { left: '左', center: '中', right: '右', top: '上', bottom: '下' },\r\n    colorScheme: { default: '默认', warm: '暖色调', cool: '冷色调', nature: '自然色' },\r\n    sample: { series: '系列{index}', category: '类别{index}' },\r\n    noData: '暂无数据', data: '数据'\r\n  },\r\n  view: {\r\n    control: { search: '搜索选项', noResults: '无匹配结果', clear: '清空' },\r\n    common: {\r\n      cancel: '取消', confirm: '确定', none: '无', leftAlign: '左对齐', rightAlign: '右对齐',\r\n      center: '居中', justify: '两端对齐', distribute: '分散对齐', preview: '预览',\r\n      color: '颜色', spacing: '间距', points: '磅'\r\n    },\r\n    paragraph: {\r\n      format: '段落格式', body: '正文', heading1: '一级标题', heading2: '二级标题',\r\n      heading3: '三级标题', heading4: '四级标题', heading5: '五级标题', heading6: '六级标题',\r\n      cut: '剪切', copy: '复制', paste: '粘贴', fontSettings: '字体...',\r\n      advancedSettings: '段落高级设置', link: '超链接', comment: '插入批注'\r\n    },\r\n    hyperlink: {\r\n      text: '显示文字', address: '链接地址',\r\n      addressPlaceholder: '请输入完整地址（如 https://example.com）',\r\n      textRequired: '请输入显示文字', addressRequired: '请输入链接地址',\r\n      addressInvalid: '链接地址必须使用 http、https、mailto、tel 或 ftp 协议',\r\n      unsupported: '超链接未插入，未能获取具体原因。请重新选择文字后重试，文档未修改。',\r\n      bookmarkSelection: '选区包含书签标记，当前编辑器暂不支持跨书签插入超链接。请调整选区避开书签边界；原文和书签均未修改。',\r\n      fieldSelection: '选区包含 Word 域标记（如目录或页码），暂不支持插入超链接。请选择域以外的普通文字，文档未修改。',\r\n      existingLink: '选区包含已有超链接，当前暂不支持嵌套或替换链接。请选择尚未添加链接的文字，文档未修改。',\r\n      crossContainer: '选区跨越不同文本容器（如段落或单元格）。请在同一段落内选择文字后重试，文档未修改。',\r\n      crossParagraph: '选区包含换行或段落结束标记。请选择同一段落内不含换行的文字，文档未修改。',\r\n      revisions: '选区包含尚未处理的修订。请先审阅并接受或拒绝相关修订，或选择不含修订的文字，文档未修改。',\r\n      tracking: '当前已开启修订模式，暂不支持插入超链接。请关闭修订模式后重试，文档未修改。',\r\n      readOnly: '文档处于只读模式，无法插入超链接。请切换到可编辑模式后重试，文档未修改。',\r\n      disabled: '编辑功能已被禁用，无法插入超链接。请启用编辑后重试，文档未修改。',\r\n      noSelection: '未找到光标位置或文字选区。请关闭弹窗，在正文中放置光标或选择文字后重试，文档未修改。',\r\n      invalidSelection: '文字选区已失效。请关闭弹窗并重新选择文字后重试，文档未修改。',\r\n      nonText: '选区包含图片、表格等非普通文本内容。请只选择普通文字，文档未修改。',\r\n      invalidText: '显示文字必须为非空的普通文本，且不能包含换行或隐藏控制标记。请修改显示文字后重试，文档未修改。'\r\n    },\r\n    table: {\r\n      insert: '插入', insertLeft: '在左侧插入', insertRight: '在右侧插入',\r\n      insertAbove: '在上方插入', insertBelow: '在下方插入', columnUnit: '列', rowUnit: '行',\r\n      insertCell: '单元格(E)...', splitCell: '拆分单元格', mergeCell: '合并单元格',\r\n      delete: '删除', deleteRow: '删除行', deleteColumn: '删除列', deleteTable: '删除整个表格',\r\n      selectAll: '全选表格', horizontalAlign: '水平对齐方式', centerAlign: '居中对齐',\r\n      verticalAlign: '垂直对齐方式', alignTop: '顶端对齐', alignMiddle: '垂直居中',\r\n      alignBottom: '底端对齐', background: '底纹颜色', repeatHeader: '重复表头行',\r\n      properties: '表格属性', select: '选择表格', addColumn: '添加列', addRow: '添加行'\r\n    },\r\n    font: {\r\n      title: '字体', characterSpacing: '字符间距', cjkFont: '中文字体', style: '字形',\r\n      regular: '常规', italic: '倾斜', bold: '加粗', boldItalic: '加粗倾斜', size: '字号',\r\n      effects: '效果', strikethrough: '删除线', underline: '下划线', superscript: '上标',\r\n      subscript: '下标', doubleStrikethrough: '双删除线', hidden: '隐藏',\r\n      previewText: '字体预览文本 ABCabc 123', scale: '缩放', standard: '标准',\r\n      expanded: '加宽', condensed: '紧缩', position: '位置', raised: '提升', lowered: '降低',\r\n      spacingPreview: '字符间距预览 ABCabc 123', unsupported: '间距与位置功能将在后续版本支持'\r\n    },\r\n    paragraphDialog: {\r\n      title: '段落', indentSpacing: '缩进和间距', linePageBreak: '换行和分页',\r\n      cjkLayout: '中文版式', general: '常规', alignment: '对齐方式', outline: '大纲级别',\r\n      bodyText: '正文文本', level1: '1 级', level2: '2 级', level3: '3 级',\r\n      level4: '4 级', level5: '5 级', level6: '6 级', indent: '缩进',\r\n      beforeText: '文本之前', afterText: '文本之后', special: '特殊格式',\r\n      firstLine: '首行缩进', hanging: '悬挂缩进', measure: '度量值', cm: '厘米',\r\n      adjustRightIndent: '如果定义了文档网格，则自动调整右缩进', before: '段前', after: '段后',\r\n      lineSpacing: '行距', single: '单倍行距', oneHalf: '1.5 倍行距', double: '双倍行距',\r\n      atLeast: '最小值', exact: '固定值', multiple: '多倍行距', setting: '设置值', times: '倍',\r\n      alignGrid: '如果定义了文档网格，则与网格对齐', previewText: '段落预览文本',\r\n      pagination: '分页', widow: '孤行控制', keepNext: '与下段同页', breakBefore: '段前分页',\r\n      lineBreak: '换行', noLineNumber: '取消行号', noHyphen: '取消断字',\r\n      unsupported: '该功能将在后续版本支持', cjkWrap: '按中文习惯换行',\r\n      punctuationOverflow: '允许标点溢出边界', wordBreak: '允许西文在单词中间换行',\r\n      compressPunctuation: '允许行首标点压缩', cjkWesternSpacing: '自动调整中文与西文的间距',\r\n      cjkNumberSpacing: '自动调整中文与数字的间距', textAlignment: '文字对齐方式',\r\n      align: '对齐', auto: '自动', baseline: '基线对齐'\r\n    },\r\n    tableDialog: {\r\n      categories: '属性类别', table: '表格', cell: '单元格',\r\n      presetHint: '预设替换整个表格的边框组合，未选中的边将清除。', border: '边框',\r\n      preset: '预设', unchanged: '保持原样', allBorders: '全部边框',\r\n      outsideBorders: '外侧边框', noBorders: '无边框', insideBorders: '内部边框',\r\n      insideHorizontal: '内部横线', insideVertical: '内部竖线', topBorder: '上边框',\r\n      bottomBorder: '下边框', leftBorder: '左边框', rightBorder: '右边框',\r\n      borderPresets: '边框预设', all: '全部', outside: '外侧', inside: '内部',\r\n      colorFormatTitle: '请输入 #RRGGBB 格式的颜色',\r\n      colorFormatClearTitle: '请输入 #RRGGBB 格式的颜色，留空清除',\r\n      borderColor: '边框颜色', cellColor: '单元格底色', chooseColor: '选择{label}（当前{state}）',\r\n      innerWidth: '内框宽度', outerWidth: '外框宽度', innerWidthAria: '内框宽度（像素）',\r\n      outerWidthAria: '外框宽度（像素）', colorHelp: '颜色格式：#RRGGBB；留空保持原样。',\r\n      borderPreview: '边框示意',\r\n      presetPreview: '边框组合示意；虚线仅标示表格范围。未填写的颜色、宽度保持原样。',\r\n      unchangedPreview: '未选择预设，边框组合保持原样；示意不代表混合样式。',\r\n      cellHint: '以下设置仅应用于当前单元格（右键所在格）。', fill: '底色',\r\n      noFill: '无底色', invalidColor: '颜色格式无效', clearFill: '清除底色',\r\n      fillHelp: '颜色格式：#RRGGBB；留空表示无底色。', verticalAlign: '垂直对齐',\r\n      alignCenter: '居中对齐'\r\n    },\r\n    pageNumber: {\r\n      header: '页眉', footer: '页脚', insert: '插入页码', style: '样式:', position: '位置:',\r\n      left: '左侧', center: '居中', right: '右侧', stylePage: '第1页',\r\n      styleTotal: '第1页共x页', styleFirst: '第一页', styleFirstTotal: '第一页共X页'\r\n    },\r\n    fontFamily: {\r\n      SimSun: '宋体', SimHei: '黑体', KaiTi: '楷体', FangSong: '仿宋',\r\n      MicrosoftYaHei: '微软雅黑', DengXian: '等线', STSong: '华文宋体',\r\n      STHeiti: '华文黑体', STKaiti: '华文楷体', STFangsong: '华文仿宋',\r\n      STZhongsong: '华文中宋', STXihei: '华文细黑', STXingkai: '华文行楷',\r\n      STLiti: '华文隶书', STXinwei: '华文新魏', STCaiyun: '华文彩云'\r\n    },\r\n    fontSize: {\r\n      chuhao: '初号', xiaochu: '小初', yihao: '一号', xiaoyi: '小一',\r\n      erhao: '二号', xiaoer: '小二', sanhao: '三号', xiaosan: '小三',\r\n      sihao: '四号', xiaosi: '小四', wuhao: '五号', xiaowu: '小五',\r\n      liuhao: '六号', xiaoliu: '小六', qihao: '七号', bahao: '八号'\r\n    }\r\n  },\r\n  comment: {\r\n    balloon: {\r\n      edit: '编辑批注', delete: '删除批注', resolve: '解决批注', reopen: '重新打开批注',\r\n      placeholder: '请输入批注内容...', save: '保存', cancel: '取消', source: '取自：',\r\n      addReply: '添加回复', replyPlaceholder: '输入回复...', reply: '回复'\r\n    },\r\n    revision: {\r\n      unknownAuthor: '未知', accept: '接受修订', reject: '拒绝修订', insert: '插入：',\r\n      delete: '删除：', format: '格式：', bold: '加粗', italic: '斜体', underline: '下划线',\r\n      strikeout: '删除线', doubleStrikeout: '双删除线', hidden: '隐藏', superscript: '上标',\r\n      subscript: '下标', color: '字体颜色', size: '字号', font: '字体', highlight: '高亮',\r\n      characterScale: '字符缩放', letterSpacing: '字符间距', textDecoration: '装饰线样式',\r\n      rowFlex: '对齐方式', lineHeight: '行距', lineHeightRule: '行距规则', rowMargin: '行间距',\r\n      paragraphIndentLeft: '左缩进', paragraphIndentRight: '右缩进',\r\n      paragraphFirstLineIndent: '首行缩进', indentHanging: '悬挂缩进',\r\n      paragraphSpacingBefore: '段前间距', paragraphSpacingAfter: '段后间距',\r\n      alignLeft: '左对齐', alignCenter: '居中', alignRight: '右对齐',\r\n      alignJustify: '两端对齐', alignDistribute: '分散对齐', undo: '取消', default: '默认',\r\n      property: '{label}: {value}', formatDescription: '设置格式: {details}',\r\n      setFormat: '设置格式', separator: '，', descriptionSeparator: '；'\r\n    }\r\n  }\r\n}\r\n","export default {\r\n  chart: {\r\n    dialog: { title: '插入圖表', settings: '設定', data: '資料', selectType: '選擇圖表類型', preview: '圖表預覽', config: '圖表設定', clear: '清除', cancel: '取消', confirm: '確定' },\r\n    category: { bar: '直條圖', line: '折線圖', pie: '圓餅圖', scatter: '散佈圖', radar: '雷達圖', mixed: '組合圖' },\r\n    preview: { 'bar-basic': '基本直條圖', 'bar-stacked': '堆疊直條圖', 'bar-horizontal': '橫條圖', 'line-basic': '基本折線圖', 'line-smooth': '平滑折線圖', 'line-stacked': '堆疊折線圖', 'line-area': '堆疊區域圖', 'line-step': '階梯折線圖', 'line-dashed': '虛線折線圖', 'pie-basic': '基本圓餅圖', 'pie-doughnut': '環圈圖', 'scatter-basic': '基本散佈圖', 'radar-basic': '基本雷達圖', 'radar-filled': '填滿雷達圖', 'mixed-line-bar': '折線直條組合圖' },\r\n    config: { showTitle: '顯示標題', title: '標題名稱', titlePlaceholder: '請輸入圖表標題', titlePosition: '標題位置', showLegend: '顯示圖例', legendPosition: '圖例位置', xAxisLabel: 'X 軸標題', xAxisPlaceholder: '請輸入 X 軸標題', yAxisLabel: 'Y 軸標題', yAxisPlaceholder: '請輸入 Y 軸標題', showGrid: '顯示格線', showDataLabel: '顯示資料標籤', colorScheme: '配色方案' },\r\n    position: { left: '左', center: '中', right: '右', top: '上', bottom: '下' },\r\n    colorScheme: { default: '預設', warm: '暖色調', cool: '冷色調', nature: '自然色' },\r\n    sample: { series: '數列{index}', category: '類別{index}' },\r\n    noData: '暫無資料', data: '資料'\r\n  },\r\n  view: {\r\n    control: { search: '搜尋選項', noResults: '無匹配結果', clear: '清空' },\r\n    common: { cancel: '取消', confirm: '確定', none: '無', leftAlign: '靠左對齊', rightAlign: '靠右對齊', center: '置中', justify: '左右對齊', distribute: '分散對齊', preview: '預覽', color: '顏色', spacing: '間距', points: '點' },\r\n    paragraph: { format: '段落格式', body: '內文', heading1: '標題 1', heading2: '標題 2', heading3: '標題 3', heading4: '標題 4', heading5: '標題 5', heading6: '標題 6', cut: '剪下', copy: '複製', paste: '貼上', fontSettings: '字型...', advancedSettings: '進階段落設定', link: '超連結', comment: '插入批註' },\r\n    hyperlink: {\r\n      text: '顯示文字', address: '連結位址', addressPlaceholder: '請輸入完整位址（例如 https://example.com）',\r\n      textRequired: '請輸入顯示文字', addressRequired: '請輸入連結位址',\r\n      addressInvalid: '連結位址必須使用 http、https、mailto、tel 或 ftp 通訊協定',\r\n      unsupported: '未插入超連結，無法取得具體原因。請重新選取文字後重試，文件未修改。',\r\n      bookmarkSelection: '選取範圍包含書籤標記，目前編輯器尚不支援跨書籤插入超連結。請調整選取範圍以避開書籤邊界；原文和書籤均未修改。',\r\n      fieldSelection: '選取範圍包含 Word 功能變數標記（如目錄或頁碼）。請選取功能變數以外的一般文字，文件未修改。',\r\n      existingLink: '選取範圍包含現有超連結，目前尚不支援巢狀或取代連結。請選取尚未加入連結的文字，文件未修改。',\r\n      crossContainer: '選取範圍跨越不同文字容器（如段落或儲存格）。請在同一段落內選取文字，文件未修改。',\r\n      crossParagraph: '選取範圍包含換行或段落結束標記。請選取同一段落內不含換行的文字，文件未修改。',\r\n      revisions: '選取範圍包含尚未處理的修訂。請先檢閱並接受或拒絕相關修訂，或選取不含修訂的文字，文件未修改。',\r\n      tracking: '目前已開啟追蹤修訂，尚不支援插入超連結。請關閉追蹤修訂後重試，文件未修改。',\r\n      readOnly: '文件處於唯讀模式。請切換至可編輯模式後重試，文件未修改。',\r\n      disabled: '編輯功能已停用。請啟用編輯後重試，文件未修改。',\r\n      noSelection: '找不到游標位置或文字選取範圍。請關閉對話方塊，在內文中放置游標或選取文字後重試，文件未修改。',\r\n      invalidSelection: '文字選取範圍已失效。請關閉對話方塊並重新選取文字，文件未修改。',\r\n      nonText: '選取範圍包含圖片、表格等非一般文字內容。請只選取一般文字，文件未修改。',\r\n      invalidText: '顯示文字必須為非空的一般文字，且不能包含換行或隱藏控制標記。請修改顯示文字後重試，文件未修改。'\r\n    },\r\n    table: { insert: '插入', insertLeft: '在左側插入', insertRight: '在右側插入', insertAbove: '在上方插入', insertBelow: '在下方插入', columnUnit: '欄', rowUnit: '列', insertCell: '儲存格(E)...', splitCell: '分割儲存格', mergeCell: '合併儲存格', delete: '刪除', deleteRow: '刪除列', deleteColumn: '刪除欄', deleteTable: '刪除整個表格', selectAll: '選取整個表格', horizontalAlign: '水平對齊方式', centerAlign: '置中對齊', verticalAlign: '垂直對齊方式', alignTop: '靠上對齊', alignMiddle: '垂直置中', alignBottom: '靠下對齊', background: '網底顏色', repeatHeader: '重複標題列', properties: '表格屬性', select: '選取表格', addColumn: '新增欄', addRow: '新增列' },\r\n    font: { title: '字型', characterSpacing: '字元間距', cjkFont: '中文字型', style: '字型樣式', regular: '標準', italic: '斜體', bold: '粗體', boldItalic: '粗斜體', size: '字級', effects: '效果', strikethrough: '刪除線', underline: '底線', superscript: '上標', subscript: '下標', doubleStrikethrough: '雙刪除線', hidden: '隱藏', previewText: '字型預覽文字 ABCabc 123', scale: '縮放', standard: '標準', expanded: '加寬', condensed: '緊縮', position: '位置', raised: '提高', lowered: '降低', spacingPreview: '字元間距預覽 ABCabc 123', unsupported: '間距與位置功能將於後續版本支援' },\r\n    paragraphDialog: { title: '段落', indentSpacing: '縮排與間距', linePageBreak: '分行與分頁', cjkLayout: '中文排版', general: '一般', alignment: '對齊方式', outline: '大綱階層', bodyText: '內文', level1: '第 1 級', level2: '第 2 級', level3: '第 3 級', level4: '第 4 級', level5: '第 5 級', level6: '第 6 級', indent: '縮排', beforeText: '文字之前', afterText: '文字之後', special: '特殊格式', firstLine: '第一行', hanging: '凸排', measure: '位移量', cm: '公分', adjustRightIndent: '若已定義文件格線，自動調整右側縮排', before: '段落前', after: '段落後', lineSpacing: '行距', single: '單行間距', oneHalf: '1.5 倍行高', double: '雙行間距', atLeast: '至少', exact: '固定行高', multiple: '多倍行高', setting: '設定值', times: '倍', alignGrid: '若已定義文件格線，則貼齊格線', previewText: '段落預覽文字', pagination: '分頁', widow: '孤行控制', keepNext: '與下段同頁', breakBefore: '段落前分頁', lineBreak: '分行', noLineNumber: '取消行號', noHyphen: '不要斷字', unsupported: '此功能將於後續版本支援', cjkWrap: '依中文習慣換行', punctuationOverflow: '允許標點符號超出邊界', wordBreak: '允許西文在單字中間換行', compressPunctuation: '允許壓縮行首標點符號', cjkWesternSpacing: '自動調整中文與西文之間的間距', cjkNumberSpacing: '自動調整中文與數字之間的間距', textAlignment: '文字對齊方式', align: '對齊', auto: '自動', baseline: '基準線對齊' },\r\n    tableDialog: { categories: '屬性類別', table: '表格', cell: '儲存格', presetHint: '預設會取代整個表格的框線組合，未選取的框線將被清除。', border: '框線', preset: '預設', unchanged: '維持原狀', allBorders: '所有框線', outsideBorders: '外框線', noBorders: '無框線', insideBorders: '內框線', insideHorizontal: '內部水平線', insideVertical: '內部垂直線', topBorder: '上框線', bottomBorder: '下框線', leftBorder: '左框線', rightBorder: '右框線', borderPresets: '框線預設', all: '全部', outside: '外側', inside: '內側', colorFormatTitle: '請輸入 #RRGGBB 格式的顏色', colorFormatClearTitle: '請輸入 #RRGGBB 格式的顏色；留白可清除', borderColor: '框線顏色', cellColor: '儲存格底色', chooseColor: '選擇{label}（目前為{state}）', innerWidth: '內框線寬度', outerWidth: '外框線寬度', innerWidthAria: '內框線寬度（像素）', outerWidthAria: '外框線寬度（像素）', colorHelp: '顏色格式：#RRGGBB；留白則維持原狀。', borderPreview: '框線預覽', presetPreview: '框線組合預覽；虛線僅標示表格範圍。未指定的顏色及寬度維持原狀。', unchangedPreview: '未選取預設，框線組合維持原狀；預覽不代表混合樣式。', cellHint: '以下設定僅套用至目前的儲存格（按右鍵的儲存格）。', fill: '底色', noFill: '無底色', invalidColor: '顏色格式無效', clearFill: '清除底色', fillHelp: '顏色格式：#RRGGBB；留白表示無底色。', verticalAlign: '垂直對齊', alignCenter: '置中對齊' },\r\n    pageNumber: { header: '頁首', footer: '頁尾', insert: '插入頁碼', style: '樣式：', position: '位置：', left: '左側', center: '置中', right: '右側', stylePage: '第 1 頁', styleTotal: '第 1 頁，共 x 頁', styleFirst: '第一頁', styleFirstTotal: '第一頁，共 X 頁' },\r\n    fontFamily: { SimSun: '宋體', SimHei: '黑體', KaiTi: '楷體', FangSong: '仿宋', MicrosoftYaHei: '微軟雅黑', DengXian: '等線', STSong: '華文宋體', STHeiti: '華文黑體', STKaiti: '華文楷體', STFangsong: '華文仿宋', STZhongsong: '華文中宋', STXihei: '華文細黑', STXingkai: '華文行楷', STLiti: '華文隸書', STXinwei: '華文新魏', STCaiyun: '華文彩雲' },\r\n    fontSize: { chuhao: '初號', xiaochu: '小初', yihao: '一號', xiaoyi: '小一', erhao: '二號', xiaoer: '小二', sanhao: '三號', xiaosan: '小三', sihao: '四號', xiaosi: '小四', wuhao: '五號', xiaowu: '小五', liuhao: '六號', xiaoliu: '小六', qihao: '七號', bahao: '八號' }\r\n  },\r\n  comment: {\r\n    balloon: { edit: '編輯批註', delete: '刪除批註', resolve: '解決批註', reopen: '重新開啟批註', placeholder: '請輸入批註內容...', save: '儲存', cancel: '取消', source: '取自：', addReply: '新增回覆', replyPlaceholder: '輸入回覆...', reply: '回覆' },\r\n    revision: { unknownAuthor: '未知', accept: '接受修訂', reject: '拒絕修訂', insert: '插入：', delete: '刪除：', format: '格式：', bold: '粗體', italic: '斜體', underline: '底線', strikeout: '刪除線', doubleStrikeout: '雙刪除線', hidden: '隱藏', superscript: '上標', subscript: '下標', color: '字型顏色', size: '字級', font: '字型', highlight: '醒目提示', characterScale: '字元縮放', letterSpacing: '字元間距', textDecoration: '裝飾線樣式', rowFlex: '對齊方式', lineHeight: '行距', lineHeightRule: '行距規則', rowMargin: '行間距', paragraphIndentLeft: '左側縮排', paragraphIndentRight: '右側縮排', paragraphFirstLineIndent: '首行縮排', indentHanging: '凸排', paragraphSpacingBefore: '段前間距', paragraphSpacingAfter: '段後間距', alignLeft: '靠左對齊', alignCenter: '置中', alignRight: '靠右對齊', alignJustify: '左右對齊', alignDistribute: '分散對齊', undo: '取消', default: '預設', property: '{label}：{value}', formatDescription: '設定格式：{details}', setFormat: '設定格式', separator: '，', descriptionSeparator: '；' }\r\n  }\r\n}\r\n","export default {\r\n  chart: {\r\n    dialog: { title: 'Insert Chart', settings: 'Settings', data: 'Data', selectType: 'Select Chart Type', preview: 'Chart Preview', config: 'Chart Settings', clear: 'Clear', cancel: 'Cancel', confirm: 'OK' },\r\n    category: { bar: 'Column', line: 'Line', pie: 'Pie', scatter: 'Scatter', radar: 'Radar', mixed: 'Combo' },\r\n    preview: { 'bar-basic': 'Basic Column', 'bar-stacked': 'Stacked Column', 'bar-horizontal': 'Horizontal Bar', 'line-basic': 'Basic Line', 'line-smooth': 'Smooth Line', 'line-stacked': 'Stacked Line', 'line-area': 'Stacked Area', 'line-step': 'Stepped Line', 'line-dashed': 'Dashed Line', 'pie-basic': 'Basic Pie', 'pie-doughnut': 'Doughnut', 'scatter-basic': 'Basic Scatter', 'radar-basic': 'Basic Radar', 'radar-filled': 'Filled Radar', 'mixed-line-bar': 'Line and Column' },\r\n    config: { showTitle: 'Show Title', title: 'Title', titlePlaceholder: 'Enter chart title', titlePosition: 'Title Position', showLegend: 'Show Legend', legendPosition: 'Legend Position', xAxisLabel: 'X-Axis Title', xAxisPlaceholder: 'Enter X-axis title', yAxisLabel: 'Y-Axis Title', yAxisPlaceholder: 'Enter Y-axis title', showGrid: 'Show Gridlines', showDataLabel: 'Show Data Labels', colorScheme: 'Color Scheme' },\r\n    position: { left: 'Left', center: 'Center', right: 'Right', top: 'Top', bottom: 'Bottom' },\r\n    colorScheme: { default: 'Default', warm: 'Warm', cool: 'Cool', nature: 'Natural' },\r\n    sample: { series: 'Series {index}', category: 'Category {index}' },\r\n    noData: 'No data', data: 'Data'\r\n  },\r\n  view: {\r\n    control: { search: 'Search options', noResults: 'No matching options', clear: 'Clear' },\r\n    common: { cancel: 'Cancel', confirm: 'OK', none: 'None', leftAlign: 'Align Left', rightAlign: 'Align Right', center: 'Center', justify: 'Justify', distribute: 'Distributed', preview: 'Preview', color: 'Color', spacing: 'Spacing', points: 'pt' },\r\n    paragraph: { format: 'Paragraph Formatting', body: 'Body Text', heading1: 'Heading 1', heading2: 'Heading 2', heading3: 'Heading 3', heading4: 'Heading 4', heading5: 'Heading 5', heading6: 'Heading 6', cut: 'Cut', copy: 'Copy', paste: 'Paste', fontSettings: 'Font...', advancedSettings: 'Advanced Paragraph Settings', link: 'Hyperlink', comment: 'Insert Comment' },\r\n    hyperlink: {\r\n      text: 'Display Text', address: 'Link Address', addressPlaceholder: 'Enter a full address (e.g. https://example.com)',\r\n      textRequired: 'Please enter display text', addressRequired: 'Please enter a link address',\r\n      addressInvalid: 'The link address must use http, https, mailto, tel, or ftp protocol',\r\n      unsupported: 'The hyperlink was not inserted and no specific reason is available. Select the text again and retry. The document is unchanged.',\r\n      bookmarkSelection: 'The selection contains bookmark markers. This editor does not yet support inserting hyperlinks across bookmark boundaries. Adjust the selection to avoid them. Text and bookmarks are unchanged.',\r\n      fieldSelection: 'The selection contains Word field markers, such as a table of contents or page number. Select ordinary text outside the field. The document is unchanged.',\r\n      existingLink: 'The selection contains an existing hyperlink. Nested links and replacing links are not yet supported. Select text without a link. The document is unchanged.',\r\n      crossContainer: 'The selection spans different text containers, such as paragraphs or cells. Select text within one paragraph. The document is unchanged.',\r\n      crossParagraph: 'The selection contains a line break or paragraph end. Select text without breaks within one paragraph. The document is unchanged.',\r\n      revisions: 'The selection contains pending revisions. Review and accept or reject them first, or select text without revisions. The document is unchanged.',\r\n      tracking: 'Track Changes is enabled. Hyperlink insertion is not yet supported in this mode. Turn off Track Changes and retry. The document is unchanged.',\r\n      readOnly: 'The document is read-only. Switch to an editable mode and retry. The document is unchanged.',\r\n      disabled: 'Editing is disabled. Enable editing and retry. The document is unchanged.',\r\n      noSelection: 'No caret or text selection was found. Close the dialog, place the caret or select text in the document, and retry. The document is unchanged.',\r\n      invalidSelection: 'The text selection is no longer valid. Close the dialog, select the text again, and retry. The document is unchanged.',\r\n      nonText: 'The selection contains non-text content, such as an image or table. Select ordinary text only. The document is unchanged.',\r\n      invalidText: 'Display text must be nonempty plain text without line breaks or hidden control markers. Edit the display text and retry. The document is unchanged.'\r\n    },\r\n    table: { insert: 'Insert', insertLeft: 'Insert Left', insertRight: 'Insert Right', insertAbove: 'Insert Above', insertBelow: 'Insert Below', columnUnit: 'column(s)', rowUnit: 'row(s)', insertCell: 'Cell (E)...', splitCell: 'Split Cells', mergeCell: 'Merge Cells', delete: 'Delete', deleteRow: 'Delete Row', deleteColumn: 'Delete Column', deleteTable: 'Delete Table', selectAll: 'Select Entire Table', horizontalAlign: 'Horizontal Alignment', centerAlign: 'Center', verticalAlign: 'Vertical Alignment', alignTop: 'Align Top', alignMiddle: 'Align Middle', alignBottom: 'Align Bottom', background: 'Shading Color', repeatHeader: 'Repeat Header Row', properties: 'Table Properties', select: 'Select Table', addColumn: 'Add Column', addRow: 'Add Row' },\r\n    font: { title: 'Font', characterSpacing: 'Character Spacing', cjkFont: 'Chinese Font', style: 'Font Style', regular: 'Regular', italic: 'Italic', bold: 'Bold', boldItalic: 'Bold Italic', size: 'Size', effects: 'Effects', strikethrough: 'Strikethrough', underline: 'Underline', superscript: 'Superscript', subscript: 'Subscript', doubleStrikethrough: 'Double Strikethrough', hidden: 'Hidden', previewText: 'Font preview text ABCabc 123', scale: 'Scale', standard: 'Normal', expanded: 'Expanded', condensed: 'Condensed', position: 'Position', raised: 'Raised', lowered: 'Lowered', spacingPreview: 'Character spacing preview ABCabc 123', unsupported: 'Spacing and position will be supported in a future release' },\r\n    paragraphDialog: { title: 'Paragraph', indentSpacing: 'Indents and Spacing', linePageBreak: 'Line and Page Breaks', cjkLayout: 'Asian Typography', general: 'General', alignment: 'Alignment', outline: 'Outline Level', bodyText: 'Body Text', level1: 'Level 1', level2: 'Level 2', level3: 'Level 3', level4: 'Level 4', level5: 'Level 5', level6: 'Level 6', indent: 'Indentation', beforeText: 'Before text', afterText: 'After text', special: 'Special', firstLine: 'First line', hanging: 'Hanging', measure: 'By', cm: 'cm', adjustRightIndent: 'Automatically adjust right indent when document grid is defined', before: 'Before', after: 'After', lineSpacing: 'Line spacing', single: 'Single', oneHalf: '1.5 lines', double: 'Double', atLeast: 'At least', exact: 'Exactly', multiple: 'Multiple', setting: 'At', times: 'times', alignGrid: 'Snap to grid when document grid is defined', previewText: 'Paragraph preview text', pagination: 'Pagination', widow: 'Widow/Orphan control', keepNext: 'Keep with next', breakBefore: 'Page break before', lineBreak: 'Line breaks', noLineNumber: 'Suppress line numbers', noHyphen: 'Do not hyphenate', unsupported: 'This feature will be supported in a future release', cjkWrap: 'Use Chinese line-breaking rules', punctuationOverflow: 'Allow punctuation to extend beyond margins', wordBreak: 'Allow Latin text to break within words', compressPunctuation: 'Compress punctuation at the start of a line', cjkWesternSpacing: 'Automatically adjust spacing between Chinese and Latin text', cjkNumberSpacing: 'Automatically adjust spacing between Chinese and numbers', textAlignment: 'Text alignment', align: 'Alignment', auto: 'Automatic', baseline: 'Align to baseline' },\r\n    tableDialog: { categories: 'Property Categories', table: 'Table', cell: 'Cell', presetHint: 'Presets replace the entire table border configuration. Unselected edges will be cleared.', border: 'Border', preset: 'Preset', unchanged: 'Keep Existing', allBorders: 'All Borders', outsideBorders: 'Outside Borders', noBorders: 'No Borders', insideBorders: 'Inside Borders', insideHorizontal: 'Inside Horizontal', insideVertical: 'Inside Vertical', topBorder: 'Top Border', bottomBorder: 'Bottom Border', leftBorder: 'Left Border', rightBorder: 'Right Border', borderPresets: 'Border Presets', all: 'All', outside: 'Outside', inside: 'Inside', colorFormatTitle: 'Enter a color in #RRGGBB format', colorFormatClearTitle: 'Enter a color in #RRGGBB format; leave blank to clear', borderColor: 'Border Color', cellColor: 'Cell Background', chooseColor: 'Choose {label} (current: {state})', innerWidth: 'Inner Border Width', outerWidth: 'Outer Border Width', innerWidthAria: 'Inner border width (pixels)', outerWidthAria: 'Outer border width (pixels)', colorHelp: 'Color format: #RRGGBB; leave blank to keep existing.', borderPreview: 'Border Preview', presetPreview: 'Border configuration preview; dashed lines show only the table bounds. Unspecified colors and widths stay unchanged.', unchangedPreview: 'No preset selected; borders stay unchanged. The preview does not represent mixed styles.', cellHint: 'These settings apply only to the current cell (the one right-clicked).', fill: 'Fill', noFill: 'No Fill', invalidColor: 'Invalid color format', clearFill: 'Clear Fill', fillHelp: 'Color format: #RRGGBB; leave blank for no fill.', verticalAlign: 'Vertical Alignment', alignCenter: 'Center' },\r\n    pageNumber: { header: 'Header', footer: 'Footer', insert: 'Insert Page Number', style: 'Style:', position: 'Position:', left: 'Left', center: 'Center', right: 'Right', stylePage: 'Page 1', styleTotal: 'Page 1 of x', styleFirst: 'First Page', styleFirstTotal: 'First Page of X' },\r\n    fontFamily: { SimSun: 'SimSun', SimHei: 'SimHei', KaiTi: 'KaiTi', FangSong: 'FangSong', MicrosoftYaHei: 'Microsoft YaHei', DengXian: 'DengXian', STSong: 'STSong', STHeiti: 'STHeiti', STKaiti: 'STKaiti', STFangsong: 'STFangsong', STZhongsong: 'STZhongsong', STXihei: 'STXihei', STXingkai: 'STXingkai', STLiti: 'STLiti', STXinwei: 'STXinwei', STCaiyun: 'STCaiyun' },\r\n    fontSize: { chuhao: 'Chuhao (42 pt)', xiaochu: 'Xiaochu (36 pt)', yihao: 'Yihao (26 pt)', xiaoyi: 'Xiaoyi (24 pt)', erhao: 'Erhao (22 pt)', xiaoer: 'Xiaoer (18 pt)', sanhao: 'Sanhao (16 pt)', xiaosan: 'Xiaosan (15 pt)', sihao: 'Sihao (14 pt)', xiaosi: 'Xiaosi (12 pt)', wuhao: 'Wuhao (10.5 pt)', xiaowu: 'Xiaowu (9 pt)', liuhao: 'Liuhao (7.5 pt)', xiaoliu: 'Xiaoliu (6.5 pt)', qihao: 'Qihao (5.5 pt)', bahao: 'Bahao (5 pt)' }\r\n  },\r\n  comment: {\r\n    balloon: { edit: 'Edit Comment', delete: 'Delete Comment', resolve: 'Resolve Comment', reopen: 'Reopen Comment', placeholder: 'Enter a comment...', save: 'Save', cancel: 'Cancel', source: 'From:', addReply: 'Add Reply', replyPlaceholder: 'Write a reply...', reply: 'Reply' },\r\n    revision: { unknownAuthor: 'Unknown', accept: 'Accept Change', reject: 'Reject Change', insert: 'Inserted:', delete: 'Deleted:', format: 'Formatting:', bold: 'Bold', italic: 'Italic', underline: 'Underline', strikeout: 'Strikethrough', doubleStrikeout: 'Double Strikethrough', hidden: 'Hidden', superscript: 'Superscript', subscript: 'Subscript', color: 'Font Color', size: 'Font Size', font: 'Font', highlight: 'Highlight', characterScale: 'Character Scale', letterSpacing: 'Character Spacing', textDecoration: 'Text Decoration Style', rowFlex: 'Alignment', lineHeight: 'Line Spacing', lineHeightRule: 'Line Spacing Rule', rowMargin: 'Row Spacing', paragraphIndentLeft: 'Left Indent', paragraphIndentRight: 'Right Indent', paragraphFirstLineIndent: 'First Line Indent', indentHanging: 'Hanging Indent', paragraphSpacingBefore: 'Space Before Paragraph', paragraphSpacingAfter: 'Space After Paragraph', alignLeft: 'Align Left', alignCenter: 'Center', alignRight: 'Align Right', alignJustify: 'Justify', alignDistribute: 'Distributed', undo: 'Cancel', default: 'Default', property: '{label}: {value}', formatDescription: 'Set formatting: {details}', setFormat: 'Set Formatting', separator: ', ', descriptionSeparator: '; ' }\r\n  }\r\n}\r\n","export default {\r\n  chart: {\r\n    dialog: { title: 'グラフの挿入', settings: '設定', data: 'データ', selectType: 'グラフの種類を選択', preview: 'グラフのプレビュー', config: 'グラフの設定', clear: 'クリア', cancel: 'キャンセル', confirm: 'OK' },\r\n    category: { bar: '縦棒グラフ', line: '折れ線グラフ', pie: '円グラフ', scatter: '散布図', radar: 'レーダーチャート', mixed: '複合グラフ' },\r\n    preview: { 'bar-basic': '基本の縦棒グラフ', 'bar-stacked': '積み上げ縦棒グラフ', 'bar-horizontal': '横棒グラフ', 'line-basic': '基本の折れ線グラフ', 'line-smooth': '平滑線グラフ', 'line-stacked': '積み上げ折れ線グラフ', 'line-area': '積み上げ面グラフ', 'line-step': '階段状の折れ線グラフ', 'line-dashed': '破線の折れ線グラフ', 'pie-basic': '基本の円グラフ', 'pie-doughnut': 'ドーナツグラフ', 'scatter-basic': '基本の散布図', 'radar-basic': '基本のレーダーチャート', 'radar-filled': '塗りつぶしレーダーチャート', 'mixed-line-bar': '折れ線と縦棒の複合グラフ' },\r\n    config: { showTitle: 'タイトルを表示', title: 'タイトル', titlePlaceholder: 'グラフのタイトルを入力', titlePosition: 'タイトルの位置', showLegend: '凡例を表示', legendPosition: '凡例の位置', xAxisLabel: 'X 軸のタイトル', xAxisPlaceholder: 'X 軸のタイトルを入力', yAxisLabel: 'Y 軸のタイトル', yAxisPlaceholder: 'Y 軸のタイトルを入力', showGrid: '目盛線を表示', showDataLabel: 'データラベルを表示', colorScheme: '配色' },\r\n    position: { left: '左', center: '中央', right: '右', top: '上', bottom: '下' },\r\n    colorScheme: { default: '既定', warm: '暖色', cool: '寒色', nature: '自然色' },\r\n    sample: { series: '系列{index}', category: '分類{index}' },\r\n    noData: 'データがありません', data: 'データ'\r\n  },\r\n  view: {\r\n    control: { search: '選択肢を検索', noResults: '一致する選択肢がありません', clear: 'クリア' },\r\n    common: { cancel: 'キャンセル', confirm: 'OK', none: 'なし', leftAlign: '左揃え', rightAlign: '右揃え', center: '中央揃え', justify: '両端揃え', distribute: '均等割り付け', preview: 'プレビュー', color: '色', spacing: '間隔', points: 'pt' },\r\n    paragraph: { format: '段落の書式', body: '本文', heading1: '見出し 1', heading2: '見出し 2', heading3: '見出し 3', heading4: '見出し 4', heading5: '見出し 5', heading6: '見出し 6', cut: '切り取り', copy: 'コピー', paste: '貼り付け', fontSettings: 'フォント...', advancedSettings: '段落の詳細設定', link: 'ハイパーリンク', comment: 'コメントの挿入' },\r\n    hyperlink: {\r\n      text: '表示文字', address: 'リンク先', addressPlaceholder: '完全なアドレスを入力してください（例: https://example.com）',\r\n      textRequired: '表示文字を入力してください', addressRequired: 'リンク先のアドレスを入力してください',\r\n      addressInvalid: 'リンク先は http、https、mailto、tel、ftp のいずれかのプロトコルを使用する必要があります',\r\n      unsupported: 'リンクは挿入されませんでした。具体的な原因を取得できません。文字を選択し直して再試行してください。文書は変更されていません。',\r\n      bookmarkSelection: '選択範囲にブックマークの境界が含まれています。このエディターでは境界をまたぐリンクの挿入にまだ対応していません。境界を避けて選択してください。文字とブックマークは変更されていません。',\r\n      fieldSelection: '選択範囲に目次やページ番号などの Word フィールドが含まれています。フィールド以外の通常の文字を選択してください。文書は変更されていません。',\r\n      existingLink: '選択範囲に既存のリンクが含まれています。リンクの入れ子や置き換えにはまだ対応していません。リンクのない文字を選択してください。文書は変更されていません。',\r\n      crossContainer: '選択範囲が複数の段落やセルなどにまたがっています。同じ段落内の文字を選択してください。文書は変更されていません。',\r\n      crossParagraph: '選択範囲に改行または段落の終端が含まれています。同じ段落内で改行を含まない文字を選択してください。文書は変更されていません。',\r\n      revisions: '選択範囲に未処理の変更履歴が含まれています。確認して承諾または元に戻すか、変更履歴のない文字を選択してください。文書は変更されていません。',\r\n      tracking: '変更履歴の記録が有効です。このモードではリンクの挿入にまだ対応していません。記録を無効にして再試行してください。文書は変更されていません。',\r\n      readOnly: '文書は読み取り専用です。編集可能なモードに切り替えてください。文書は変更されていません。',\r\n      disabled: '編集機能が無効です。編集を有効にして再試行してください。文書は変更されていません。',\r\n      noSelection: 'カーソル位置または文字の選択範囲がありません。ダイアログを閉じ、本文にカーソルを置くか文字を選択してください。文書は変更されていません。',\r\n      invalidSelection: '文字の選択範囲が無効になりました。ダイアログを閉じ、文字を選択し直してください。文書は変更されていません。',\r\n      nonText: '選択範囲に画像や表などが含まれています。通常の文字のみを選択してください。文書は変更されていません。',\r\n      invalidText: '表示文字は空でない通常の文字列にしてください。改行や非表示の制御マーカーは使用できません。表示文字を修正してください。文書は変更されていません。'\r\n    },\r\n    table: { insert: '挿入', insertLeft: '左に挿入', insertRight: '右に挿入', insertAbove: '上に挿入', insertBelow: '下に挿入', columnUnit: '列', rowUnit: '行', insertCell: 'セル(E)...', splitCell: 'セルの分割', mergeCell: 'セルの結合', delete: '削除', deleteRow: '行の削除', deleteColumn: '列の削除', deleteTable: '表全体の削除', selectAll: '表全体を選択', horizontalAlign: '水平方向の配置', centerAlign: '中央揃え', verticalAlign: '垂直方向の配置', alignTop: '上揃え', alignMiddle: '上下中央揃え', alignBottom: '下揃え', background: '網掛けの色', repeatHeader: 'タイトル行の繰り返し', properties: '表のプロパティ', select: '表を選択', addColumn: '列の追加', addRow: '行の追加' },\r\n    font: { title: 'フォント', characterSpacing: '文字間隔', cjkFont: '中国語用フォント', style: 'スタイル', regular: '標準', italic: '斜体', bold: '太字', boldItalic: '太字斜体', size: 'サイズ', effects: '文字飾り', strikethrough: '取り消し線', underline: '下線', superscript: '上付き', subscript: '下付き', doubleStrikethrough: '二重取り消し線', hidden: '隠し文字', previewText: 'フォントのプレビュー ABCabc 123', scale: '倍率', standard: '標準', expanded: '広く', condensed: '狭く', position: '位置', raised: '上げる', lowered: '下げる', spacingPreview: '文字間隔のプレビュー ABCabc 123', unsupported: '文字間隔と位置は今後のバージョンで対応予定です' },\r\n    paragraphDialog: { title: '段落', indentSpacing: 'インデントと行間隔', linePageBreak: '改ページと改行', cjkLayout: '体裁', general: '全般', alignment: '配置', outline: 'アウトライン レベル', bodyText: '本文', level1: 'レベル 1', level2: 'レベル 2', level3: 'レベル 3', level4: 'レベル 4', level5: 'レベル 5', level6: 'レベル 6', indent: 'インデント', beforeText: '左', afterText: '右', special: '最初の行', firstLine: '字下げ', hanging: 'ぶら下げ', measure: '幅', cm: 'cm', adjustRightIndent: '文書グリッドを定義した場合は右インデントを自動調整する', before: '段落前', after: '段落後', lineSpacing: '行間', single: '1 行', oneHalf: '1.5 行', double: '2 行', atLeast: '最小値', exact: '固定値', multiple: '倍数', setting: '間隔', times: '倍', alignGrid: '文書グリッドを定義した場合はグリッド線に合わせる', previewText: '段落のプレビュー', pagination: '改ページ', widow: '改ページ時 1 行残して段落を区切らない', keepNext: '次の段落と分離しない', breakBefore: '段落前で改ページする', lineBreak: '改行', noLineNumber: '行番号を表示しない', noHyphen: 'ハイフネーションしない', unsupported: 'この機能は今後のバージョンで対応予定です', cjkWrap: '中国語の改行規則を使用する', punctuationOverflow: '句読点のぶら下げを許可する', wordBreak: '欧文を単語の途中で改行する', compressPunctuation: '行頭の句読点を詰める', cjkWesternSpacing: '中国語と欧文の間隔を自動調整する', cjkNumberSpacing: '中国語と数字の間隔を自動調整する', textAlignment: '文字の配置', align: '配置', auto: '自動', baseline: 'ベースラインに揃える' },\r\n    tableDialog: { categories: 'プロパティの種類', table: '表', cell: 'セル', presetHint: 'プリセットを適用すると表全体の罫線構成が置き換わり、選択されていない辺の罫線は消去されます。', border: '罫線', preset: 'プリセット', unchanged: '変更しない', allBorders: 'すべての罫線', outsideBorders: '外枠', noBorders: '罫線なし', insideBorders: '内側の罫線', insideHorizontal: '内側の横線', insideVertical: '内側の縦線', topBorder: '上の罫線', bottomBorder: '下の罫線', leftBorder: '左の罫線', rightBorder: '右の罫線', borderPresets: '罫線のプリセット', all: 'すべて', outside: '外側', inside: '内側', colorFormatTitle: '色を #RRGGBB 形式で入力してください', colorFormatClearTitle: '色を #RRGGBB 形式で入力してください。空欄にすると消去します', borderColor: '罫線の色', cellColor: 'セルの背景色', chooseColor: '{label}を選択（現在：{state}）', innerWidth: '内側の罫線の幅', outerWidth: '外枠の幅', innerWidthAria: '内側の罫線の幅（ピクセル）', outerWidthAria: '外枠の幅（ピクセル）', colorHelp: '色の形式：#RRGGBB。空欄の場合は変更しません。', borderPreview: '罫線のプレビュー', presetPreview: '罫線構成のプレビュー。破線は表の範囲のみを示します。未入力の色と幅は変更しません。', unchangedPreview: 'プリセットが選択されていないため、罫線構成は変更しません。プレビューは混在するスタイルを表しません。', cellHint: '以下の設定は現在のセル（右クリックしたセル）にのみ適用されます。', fill: '塗りつぶし', noFill: '塗りつぶしなし', invalidColor: '色の形式が正しくありません', clearFill: '塗りつぶしをクリア', fillHelp: '色の形式：#RRGGBB。空欄の場合は塗りつぶしなしです。', verticalAlign: '垂直方向の配置', alignCenter: '中央揃え' },\r\n    pageNumber: { header: 'ヘッダー', footer: 'フッター', insert: 'ページ番号の挿入', style: 'スタイル:', position: '位置:', left: '左', center: '中央', right: '右', stylePage: '1 ページ', styleTotal: '1 / x ページ', styleFirst: '最初のページ', styleFirstTotal: '最初のページ / 全 X ページ' },\r\n    fontFamily: { SimSun: 'SimSun（宋体）', SimHei: 'SimHei（黒体）', KaiTi: 'KaiTi（楷体）', FangSong: 'FangSong（仿宋）', MicrosoftYaHei: 'Microsoft YaHei', DengXian: 'DengXian', STSong: 'STSong', STHeiti: 'STHeiti', STKaiti: 'STKaiti', STFangsong: 'STFangsong', STZhongsong: 'STZhongsong', STXihei: 'STXihei', STXingkai: 'STXingkai', STLiti: 'STLiti', STXinwei: 'STXinwei', STCaiyun: 'STCaiyun' },\r\n    fontSize: { chuhao: '初号（42 pt）', xiaochu: '小初（36 pt）', yihao: '一号（26 pt）', xiaoyi: '小一（24 pt）', erhao: '二号（22 pt）', xiaoer: '小二（18 pt）', sanhao: '三号（16 pt）', xiaosan: '小三（15 pt）', sihao: '四号（14 pt）', xiaosi: '小四（12 pt）', wuhao: '五号（10.5 pt）', xiaowu: '小五（9 pt）', liuhao: '六号（7.5 pt）', xiaoliu: '小六（6.5 pt）', qihao: '七号（5.5 pt）', bahao: '八号（5 pt）' }\r\n  },\r\n  comment: {\r\n    balloon: { edit: 'コメントを編集', delete: 'コメントを削除', resolve: 'コメントを解決済みにする', reopen: 'コメントを再開', placeholder: 'コメントを入力してください...', save: '保存', cancel: 'キャンセル', source: '引用元：', addReply: '返信を追加', replyPlaceholder: '返信を入力...', reply: '返信' },\r\n    revision: { unknownAuthor: '不明', accept: '変更を採用', reject: '変更を却下', insert: '挿入：', delete: '削除：', format: '書式：', bold: '太字', italic: '斜体', underline: '下線', strikeout: '取り消し線', doubleStrikeout: '二重取り消し線', hidden: '隠し文字', superscript: '上付き', subscript: '下付き', color: 'フォントの色', size: 'フォントサイズ', font: 'フォント', highlight: '蛍光ペン', characterScale: '文字の拡大縮小', letterSpacing: '文字間隔', textDecoration: '文字飾りのスタイル', rowFlex: '配置', lineHeight: '行間', lineHeightRule: '行間の規則', rowMargin: '行の間隔', paragraphIndentLeft: '左インデント', paragraphIndentRight: '右インデント', paragraphFirstLineIndent: '先頭行インデント', indentHanging: 'ぶら下げインデント', paragraphSpacingBefore: '段落前の間隔', paragraphSpacingAfter: '段落後の間隔', alignLeft: '左揃え', alignCenter: '中央揃え', alignRight: '右揃え', alignJustify: '両端揃え', alignDistribute: '均等割り付け', undo: 'キャンセル', default: '既定', property: '{label}：{value}', formatDescription: '書式を設定：{details}', setFormat: '書式を設定', separator: '、', descriptionSeparator: '；' }\r\n  }\r\n}\r\n","export default {\r\n  chart: {\r\n    dialog: { title: '차트 삽입', settings: '설정', data: '데이터', selectType: '차트 종류 선택', preview: '차트 미리보기', config: '차트 설정', clear: '지우기', cancel: '취소', confirm: '확인' },\r\n    category: { bar: '세로 막대형', line: '꺾은선형', pie: '원형', scatter: '분산형', radar: '방사형', mixed: '혼합형' },\r\n    preview: { 'bar-basic': '기본 세로 막대형', 'bar-stacked': '누적 세로 막대형', 'bar-horizontal': '가로 막대형', 'line-basic': '기본 꺾은선형', 'line-smooth': '부드러운 꺾은선형', 'line-stacked': '누적 꺾은선형', 'line-area': '누적 영역형', 'line-step': '계단형 꺾은선', 'line-dashed': '점선 꺾은선', 'pie-basic': '기본 원형', 'pie-doughnut': '도넛형', 'scatter-basic': '기본 분산형', 'radar-basic': '기본 방사형', 'radar-filled': '채워진 방사형', 'mixed-line-bar': '꺾은선 및 막대 혼합형' },\r\n    config: { showTitle: '제목 표시', title: '제목', titlePlaceholder: '차트 제목 입력', titlePosition: '제목 위치', showLegend: '범례 표시', legendPosition: '범례 위치', xAxisLabel: 'X축 제목', xAxisPlaceholder: 'X축 제목 입력', yAxisLabel: 'Y축 제목', yAxisPlaceholder: 'Y축 제목 입력', showGrid: '눈금선 표시', showDataLabel: '데이터 레이블 표시', colorScheme: '색 구성표' },\r\n    position: { left: '왼쪽', center: '가운데', right: '오른쪽', top: '위', bottom: '아래' },\r\n    colorScheme: { default: '기본값', warm: '따뜻한 색', cool: '차가운 색', nature: '자연색' },\r\n    sample: { series: '계열{index}', category: '범주{index}' },\r\n    noData: '데이터 없음', data: '데이터'\r\n  },\r\n  view: {\r\n    control: { search: '옵션 검색', noResults: '일치하는 옵션 없음', clear: '지우기' },\r\n    common: { cancel: '취소', confirm: '확인', none: '없음', leftAlign: '왼쪽 맞춤', rightAlign: '오른쪽 맞춤', center: '가운데 맞춤', justify: '양쪽 맞춤', distribute: '균등 분할', preview: '미리보기', color: '색상', spacing: '간격', points: 'pt' },\r\n    paragraph: { format: '단락 서식', body: '본문', heading1: '제목 1', heading2: '제목 2', heading3: '제목 3', heading4: '제목 4', heading5: '제목 5', heading6: '제목 6', cut: '잘라내기', copy: '복사', paste: '붙여넣기', fontSettings: '글꼴...', advancedSettings: '단락 고급 설정', link: '하이퍼링크', comment: '메모 삽입' },\r\n    hyperlink: {\r\n      text: '표시 텍스트', address: '링크 주소', addressPlaceholder: '전체 주소를 입력하세요(예: https://example.com)',\r\n      textRequired: '표시 텍스트를 입력하세요', addressRequired: '링크 주소를 입력하세요',\r\n      addressInvalid: '링크 주소는 http, https, mailto, tel 또는 ftp 프로토콜을 사용해야 합니다',\r\n      unsupported: '링크가 삽입되지 않았으며 구체적인 원인을 확인할 수 없습니다. 텍스트를 다시 선택하고 시도하세요. 문서는 변경되지 않았습니다.',\r\n      bookmarkSelection: '선택 영역에 책갈피 경계가 포함되어 있습니다. 현재 편집기는 책갈피 경계를 가로지르는 링크 삽입을 지원하지 않습니다. 경계를 피하도록 선택 영역을 조정하세요. 텍스트와 책갈피는 변경되지 않았습니다.',\r\n      fieldSelection: '선택 영역에 목차나 페이지 번호 같은 Word 필드가 포함되어 있습니다. 필드 밖의 일반 텍스트를 선택하세요. 문서는 변경되지 않았습니다.',\r\n      existingLink: '선택 영역에 기존 링크가 포함되어 있습니다. 중첩 링크와 링크 교체는 아직 지원되지 않습니다. 링크가 없는 텍스트를 선택하세요. 문서는 변경되지 않았습니다.',\r\n      crossContainer: '선택 영역이 여러 단락이나 셀 등 서로 다른 텍스트 영역에 걸쳐 있습니다. 같은 단락 안에서 텍스트를 선택하세요. 문서는 변경되지 않았습니다.',\r\n      crossParagraph: '선택 영역에 줄 바꿈이나 단락 끝이 포함되어 있습니다. 같은 단락 안에서 줄 바꿈이 없는 텍스트를 선택하세요. 문서는 변경되지 않았습니다.',\r\n      revisions: '선택 영역에 처리되지 않은 변경 내용이 있습니다. 검토 후 적용하거나 취소하거나, 변경 내용이 없는 텍스트를 선택하세요. 문서는 변경되지 않았습니다.',\r\n      tracking: '변경 내용 추적이 켜져 있습니다. 이 모드에서는 링크 삽입이 아직 지원되지 않습니다. 추적을 끄고 다시 시도하세요. 문서는 변경되지 않았습니다.',\r\n      readOnly: '문서가 읽기 전용입니다. 편집 가능한 모드로 전환하세요. 문서는 변경되지 않았습니다.',\r\n      disabled: '편집 기능이 비활성화되어 있습니다. 편집을 활성화하고 다시 시도하세요. 문서는 변경되지 않았습니다.',\r\n      noSelection: '커서 위치나 선택 영역을 찾을 수 없습니다. 대화 상자를 닫고 본문에 커서를 놓거나 텍스트를 선택하세요. 문서는 변경되지 않았습니다.',\r\n      invalidSelection: '텍스트 선택 영역이 더 이상 유효하지 않습니다. 대화 상자를 닫고 텍스트를 다시 선택하세요. 문서는 변경되지 않았습니다.',\r\n      nonText: '선택 영역에 이미지나 표 등 일반 텍스트가 아닌 내용이 있습니다. 일반 텍스트만 선택하세요. 문서는 변경되지 않았습니다.',\r\n      invalidText: '표시 텍스트는 비어 있지 않은 일반 텍스트여야 하며 줄 바꿈이나 숨겨진 제어 표식을 포함할 수 없습니다. 표시 텍스트를 수정하세요. 문서는 변경되지 않았습니다.'\r\n    },\r\n    table: { insert: '삽입', insertLeft: '왼쪽에 삽입', insertRight: '오른쪽에 삽입', insertAbove: '위에 삽입', insertBelow: '아래에 삽입', columnUnit: '열', rowUnit: '행', insertCell: '셀(E)...', splitCell: '셀 분할', mergeCell: '셀 병합', delete: '삭제', deleteRow: '행 삭제', deleteColumn: '열 삭제', deleteTable: '표 전체 삭제', selectAll: '표 전체 선택', horizontalAlign: '가로 맞춤', centerAlign: '가운데 맞춤', verticalAlign: '세로 맞춤', alignTop: '위쪽 맞춤', alignMiddle: '세로 가운데 맞춤', alignBottom: '아래쪽 맞춤', background: '음영 색상', repeatHeader: '머리글 행 반복', properties: '표 속성', select: '표 선택', addColumn: '열 추가', addRow: '행 추가' },\r\n    font: { title: '글꼴', characterSpacing: '문자 간격', cjkFont: '중국어 글꼴', style: '글꼴 스타일', regular: '보통', italic: '기울임꼴', bold: '굵게', boldItalic: '굵은 기울임꼴', size: '글자 크기', effects: '효과', strikethrough: '취소선', underline: '밑줄', superscript: '위 첨자', subscript: '아래 첨자', doubleStrikethrough: '이중 취소선', hidden: '숨김', previewText: '글꼴 미리보기 ABCabc 123', scale: '확대/축소', standard: '표준', expanded: '넓게', condensed: '좁게', position: '위치', raised: '위로', lowered: '아래로', spacingPreview: '문자 간격 미리보기 ABCabc 123', unsupported: '간격 및 위치 기능은 향후 버전에서 지원됩니다' },\r\n    paragraphDialog: { title: '단락', indentSpacing: '들여쓰기 및 간격', linePageBreak: '줄 및 페이지 나누기', cjkLayout: '중국어 조판', general: '일반', alignment: '맞춤', outline: '개요 수준', bodyText: '본문', level1: '수준 1', level2: '수준 2', level3: '수준 3', level4: '수준 4', level5: '수준 5', level6: '수준 6', indent: '들여쓰기', beforeText: '텍스트 앞', afterText: '텍스트 뒤', special: '특수', firstLine: '첫 줄', hanging: '내어쓰기', measure: '기준', cm: 'cm', adjustRightIndent: '문서 눈금이 정의된 경우 오른쪽 들여쓰기 자동 조정', before: '단락 앞', after: '단락 뒤', lineSpacing: '줄 간격', single: '1줄', oneHalf: '1.5줄', double: '2줄', atLeast: '최소', exact: '고정', multiple: '배수', setting: '설정값', times: '배', alignGrid: '문서 눈금이 정의된 경우 눈금에 맞춤', previewText: '단락 미리보기 텍스트', pagination: '페이지 나누기', widow: '문단 보호', keepNext: '다음 단락과 함께', breakBefore: '단락 앞에서 페이지 나누기', lineBreak: '줄 바꿈', noLineNumber: '줄 번호 표시 안 함', noHyphen: '하이픈 넣지 않음', unsupported: '이 기능은 향후 버전에서 지원됩니다', cjkWrap: '중국어 줄 바꿈 규칙 사용', punctuationOverflow: '문장 부호의 여백 넘침 허용', wordBreak: '서양어 단어 중간에서 줄 바꿈 허용', compressPunctuation: '줄 시작 문장 부호 압축 허용', cjkWesternSpacing: '중국어와 서양어 사이 간격 자동 조정', cjkNumberSpacing: '중국어와 숫자 사이 간격 자동 조정', textAlignment: '문자 맞춤', align: '맞춤', auto: '자동', baseline: '기준선에 맞춤' },\r\n    tableDialog: { categories: '속성 범주', table: '표', cell: '셀', presetHint: '미리 설정을 적용하면 표 전체의 테두리 구성이 바뀌며 선택하지 않은 테두리는 지워집니다.', border: '테두리', preset: '미리 설정', unchanged: '변경 안 함', allBorders: '모든 테두리', outsideBorders: '바깥쪽 테두리', noBorders: '테두리 없음', insideBorders: '안쪽 테두리', insideHorizontal: '안쪽 가로선', insideVertical: '안쪽 세로선', topBorder: '위쪽 테두리', bottomBorder: '아래쪽 테두리', leftBorder: '왼쪽 테두리', rightBorder: '오른쪽 테두리', borderPresets: '테두리 미리 설정', all: '모두', outside: '바깥쪽', inside: '안쪽', colorFormatTitle: '#RRGGBB 형식의 색상을 입력하세요', colorFormatClearTitle: '#RRGGBB 형식의 색상을 입력하세요. 비워 두면 지워집니다', borderColor: '테두리 색상', cellColor: '셀 배경색', chooseColor: '{label} 선택(현재: {state})', innerWidth: '안쪽 테두리 두께', outerWidth: '바깥쪽 테두리 두께', innerWidthAria: '안쪽 테두리 두께(픽셀)', outerWidthAria: '바깥쪽 테두리 두께(픽셀)', colorHelp: '색상 형식: #RRGGBB. 비워 두면 변경되지 않습니다.', borderPreview: '테두리 미리보기', presetPreview: '테두리 구성 미리보기. 점선은 표 범위만 나타냅니다. 입력하지 않은 색상과 두께는 변경되지 않습니다.', unchangedPreview: '선택한 미리 설정이 없어 테두리 구성이 유지됩니다. 미리보기는 혼합된 스타일을 나타내지 않습니다.', cellHint: '아래 설정은 현재 셀(마우스 오른쪽 버튼으로 클릭한 셀)에만 적용됩니다.', fill: '채우기', noFill: '채우기 없음', invalidColor: '색상 형식이 올바르지 않습니다', clearFill: '채우기 지우기', fillHelp: '색상 형식: #RRGGBB. 비워 두면 채우지 않습니다.', verticalAlign: '세로 맞춤', alignCenter: '가운데 맞춤' },\r\n    pageNumber: { header: '머리글', footer: '바닥글', insert: '페이지 번호 삽입', style: '스타일:', position: '위치:', left: '왼쪽', center: '가운데', right: '오른쪽', stylePage: '1페이지', styleTotal: '전체 x페이지 중 1페이지', styleFirst: '첫 페이지', styleFirstTotal: '전체 X페이지 중 첫 페이지' },\r\n    fontFamily: { SimSun: 'SimSun(쑹체)', SimHei: 'SimHei(헤이체)', KaiTi: 'KaiTi(카이체)', FangSong: 'FangSong(팡쑹)', MicrosoftYaHei: 'Microsoft YaHei', DengXian: 'DengXian', STSong: 'STSong', STHeiti: 'STHeiti', STKaiti: 'STKaiti', STFangsong: 'STFangsong', STZhongsong: 'STZhongsong', STXihei: 'STXihei', STXingkai: 'STXingkai', STLiti: 'STLiti', STXinwei: 'STXinwei', STCaiyun: 'STCaiyun' },\r\n    fontSize: { chuhao: '초호(42pt)', xiaochu: '소초(36pt)', yihao: '1호(26pt)', xiaoyi: '소1호(24pt)', erhao: '2호(22pt)', xiaoer: '소2호(18pt)', sanhao: '3호(16pt)', xiaosan: '소3호(15pt)', sihao: '4호(14pt)', xiaosi: '소4호(12pt)', wuhao: '5호(10.5pt)', xiaowu: '소5호(9pt)', liuhao: '6호(7.5pt)', xiaoliu: '소6호(6.5pt)', qihao: '7호(5.5pt)', bahao: '8호(5pt)' }\r\n  },\r\n  comment: {\r\n    balloon: { edit: '메모 편집', delete: '메모 삭제', resolve: '메모 해결', reopen: '메모 다시 열기', placeholder: '메모 내용을 입력하세요...', save: '저장', cancel: '취소', source: '출처:', addReply: '답글 추가', replyPlaceholder: '답글 입력...', reply: '답글' },\r\n    revision: { unknownAuthor: '알 수 없음', accept: '변경 내용 수락', reject: '변경 내용 거부', insert: '삽입:', delete: '삭제:', format: '서식:', bold: '굵게', italic: '기울임꼴', underline: '밑줄', strikeout: '취소선', doubleStrikeout: '이중 취소선', hidden: '숨김', superscript: '위 첨자', subscript: '아래 첨자', color: '글꼴 색상', size: '글자 크기', font: '글꼴', highlight: '강조', characterScale: '문자 확대/축소', letterSpacing: '문자 간격', textDecoration: '문자 장식 스타일', rowFlex: '맞춤', lineHeight: '줄 간격', lineHeightRule: '줄 간격 규칙', rowMargin: '행 간격', paragraphIndentLeft: '왼쪽 들여쓰기', paragraphIndentRight: '오른쪽 들여쓰기', paragraphFirstLineIndent: '첫 줄 들여쓰기', indentHanging: '내어쓰기', paragraphSpacingBefore: '단락 앞 간격', paragraphSpacingAfter: '단락 뒤 간격', alignLeft: '왼쪽 맞춤', alignCenter: '가운데 맞춤', alignRight: '오른쪽 맞춤', alignJustify: '양쪽 맞춤', alignDistribute: '균등 분할', undo: '취소', default: '기본값', property: '{label}: {value}', formatDescription: '서식 설정: {details}', setFormat: '서식 설정', separator: ', ', descriptionSeparator: '; ' }\r\n  }\r\n}\r\n","/**\r\n * VerveDocs Schema —— 常量\r\n */\r\n\r\nimport type { IEditorOption } from './types'\r\n\r\n/** 当前 Schema 版本号 */\r\nexport const SCHEMA_VERSION = '4.0.0-tree'\r\n\r\n/** 默认编辑器选项 */\r\nexport const DEFAULT_EDITOR_OPTION: Required<Pick<IEditorOption,\r\n  'defaultFont' | 'defaultSize' | 'defaultLineHeight' | 'defaultRowMargin' |\r\n  'pageMode' | 'pageWidth' | 'pageHeight' | 'pageMargins' | 'scale' | 'devicePixelRatio' |\r\n  'historyMaxRecordCount'\r\n>> = {\r\n  defaultFont: 'Microsoft YaHei',\r\n  defaultSize: 16,\r\n  defaultLineHeight: 1.5,\r\n  defaultRowMargin: 5,\r\n  pageMode: 'paging',\r\n  pageWidth: 794,           // A4 @ 96dpi\r\n  pageHeight: 1123,\r\n  pageMargins: [100, 120, 100, 120],\r\n  scale: 1,\r\n  devicePixelRatio: typeof window !== 'undefined' ? (window.devicePixelRatio || 1) : 1,\r\n  historyMaxRecordCount: 100\r\n}\r\n\r\n/** 段落级属性字段名（用于从 run 上剥离/继承） */\r\nexport const PARAGRAPH_ATTR_KEYS = [\r\n  'rowFlex',\r\n  'paragraphStyleId',\r\n  'paragraphFirstLineIndent',\r\n  'paragraphIndentLeft',\r\n  'paragraphSpacingBefore',\r\n  'paragraphSpacingAfter',\r\n  'lineHeight',\r\n  'lineHeightRule',\r\n  'groupIds'\r\n] as const\r\n\r\n/** 段落容器类型 */\r\nexport const PARAGRAPH_CONTAINER_TYPES = new Set(['title', 'list'])\r\n\r\n/** 段落级块类型（占独立段） */\r\nexport const BLOCK_LEVEL_TYPES = new Set([\r\n  'title', 'list', 'table', 'image', 'pageBreak', 'separator', 'block'\r\n])\r\n\r\n/** 列表类型 */\r\nexport const LIST_TYPE = {\r\n  UL: 'ul',\r\n  OL: 'ol'\r\n} as const\r\n\r\n/** 列表样式（项目符号 16 种 + 编号格式 13 种，对齐 WPS 全量） */\r\nexport const LIST_STYLE = {\r\n  // 项目符号\r\n  DISC: 'disc',\r\n  CIRCLE: 'circle',\r\n  SQUARE: 'square',\r\n  EMPTY_SQUARE: 'emptySquare',\r\n  FILLED_DIAMOND: 'filledDiamond',\r\n  DIAMOND: 'diamond',\r\n  ARROW: 'arrow',\r\n  ARROW_FILLED: 'arrowFilled',\r\n  CHECK: 'check',\r\n  CROSS: 'cross',\r\n  BULLET: 'bullet',\r\n  TRIANGLE: 'triangle',\r\n  STAR: 'star',\r\n  HEART: 'heart',\r\n  DASH: 'dash',\r\n  HYPHEN: 'hyphen',\r\n  // 编号格式\r\n  DECIMAL: 'decimal',\r\n  DECIMAL_ZERO: 'decimalZero',\r\n  LOWER_LETTER: 'lowerLetter',\r\n  UPPER_LETTER: 'upperLetter',\r\n  LOWER_ROMAN: 'lowerRoman',\r\n  UPPER_ROMAN: 'upperRoman',\r\n  CHINESE_COUNTING: 'chineseCounting',\r\n  CHINESE_COUNTING_THOUSAND: 'chineseCountingThousand',\r\n  IDEOGRAPH_DIGITAL: 'ideographDigital',\r\n  JAPANESE_COUNTING: 'japaneseCounting',\r\n  KOREAN_COUNTING: 'koreanCounting',\r\n  TAIWANESE_COUNTING: 'taiwaneseCounting'\r\n} as const\r\n\r\n/** 段落对齐方式 */\r\nexport const ROW_FLEX = {\r\n  LEFT: 'left',\r\n  CENTER: 'center',\r\n  RIGHT: 'right',\r\n  JUSTIFY: 'justify',\r\n  ALIGNMENT: 'alignment',\r\n  DISTRIBUTE: 'distribute'\r\n} as const\r\n\r\n/** 标题级别 */\r\nexport const TITLE_LEVEL = {\r\n  FIRST: 'first',\r\n  SECOND: 'second',\r\n  THIRD: 'third',\r\n  FOURTH: 'fourth',\r\n  FIFTH: 'fifth',\r\n  SIXTH: 'sixth'\r\n} as const\r\n\r\n/** 字体族常量（对齐 WPS 常用字体，代码内引用用） */\r\nexport const FONT_FAMILY = {\r\n  SIM_SUN: 'SimSun',\r\n  SIM_HEI: 'SimHei',\r\n  KAI_TI: 'KaiTi',\r\n  FANG_SONG: 'FangSong',\r\n  MICROSOFT_YAHEI: 'Microsoft YaHei',\r\n  DENG_XIAN: 'DengXian',\r\n  ST_SONG: 'STSong',\r\n  ST_HEITI: 'STHeiti',\r\n  ST_KAITI: 'STKaiti',\r\n  ST_FANGSONG: 'STFangsong',\r\n  ST_ZHONGSONG: 'STZhongsong',\r\n  ST_XIHEI: 'STXihei',\r\n  ST_XINGKAI: 'STXingkai',\r\n  ST_LITI: 'STLiti',\r\n  ST_XINWEI: 'STXinwei',\r\n  ST_CAIYUN: 'STCaiyun',\r\n  TIMES_NEW_ROMAN: 'Times New Roman',\r\n  ARIAL: 'Arial',\r\n  CALIBRI: 'Calibri',\r\n  COURIER_NEW: 'Courier New',\r\n  VERDANA: 'Verdana'\r\n} as const\r\n\r\n/**\r\n * 字体映射条目（三层结构）\r\n * - label: 显示名（工具栏下拉显示）\r\n * - value: 存储名（文档里存的，WPS/Office 兼容）\r\n * - css:   CSS font-family 值（带跨平台 fallback，引用系统字体不侵权 + 开源字体兜底）\r\n * - aliases: 文档里可能存的其他名字（中文名、大小写变体等）\r\n */\r\nexport interface FontFamilyEntry {\r\n  label: string\r\n  value: string\r\n  css: string\r\n  aliases?: string[]\r\n}\r\n\r\n/**\r\n * WPS 常用字体完整映射表（16 中文字体 + 5 英文字体）\r\n * CSS fallback 策略：Windows 系统字体 → macOS 对应字体 → 开源字体兜底 → 通用字体族\r\n */\r\nexport const FONT_FAMILY_MAP: FontFamilyEntry[] = [\r\n  { label: '宋体', value: 'SimSun', css: '\"SimSun\", \"Songti SC\", \"Noto Serif CJK SC\", serif', aliases: ['宋体', 'simsun'] },\r\n  { label: '黑体', value: 'SimHei', css: '\"SimHei\", \"STHeiti\", \"PingFang SC\", \"Noto Sans CJK SC\", sans-serif', aliases: ['黑体', 'simhei'] },\r\n  { label: '楷体', value: 'KaiTi', css: '\"KaiTi\", \"Kaiti SC\", \"STKaiti\", \"LXGW WenKai\", serif', aliases: ['楷体', 'kaiti'] },\r\n  { label: '仿宋', value: 'FangSong', css: '\"FangSong\", \"STFangsong\", \"Noto Serif CJK SC\", serif', aliases: ['仿宋', 'fangsong'] },\r\n  { label: '微软雅黑', value: 'Microsoft YaHei', css: '\"Microsoft YaHei\", \"PingFang SC\", \"Noto Sans CJK SC\", sans-serif', aliases: ['微软雅黑', 'microsoft yahei'] },\r\n  { label: '等线', value: 'DengXian', css: '\"DengXian\", \"Noto Sans CJK SC\", sans-serif', aliases: ['等线', 'dengxian'] },\r\n  { label: '华文宋体', value: 'STSong', css: '\"STSong\", \"SimSun\", \"Songti SC\", \"Noto Serif CJK SC\", serif', aliases: ['华文宋体'] },\r\n  { label: '华文黑体', value: 'STHeiti', css: '\"STHeiti\", \"SimHei\", \"PingFang SC\", \"Noto Sans CJK SC\", sans-serif', aliases: ['华文黑体'] },\r\n  { label: '华文楷体', value: 'STKaiti', css: '\"STKaiti\", \"KaiTi\", \"Kaiti SC\", \"LXGW WenKai\", serif', aliases: ['华文楷体'] },\r\n  { label: '华文仿宋', value: 'STFangsong', css: '\"STFangsong\", \"FangSong\", \"Noto Serif CJK SC\", serif', aliases: ['华文仿宋'] },\r\n  { label: '华文中宋', value: 'STZhongsong', css: '\"STZhongsong\", \"STSong\", \"SimSun\", \"Noto Serif CJK SC\", serif', aliases: ['华文中宋'] },\r\n  { label: '华文细黑', value: 'STXihei', css: '\"STXihei\", \"STHeiti\", \"SimHei\", \"Noto Sans CJK SC\", sans-serif', aliases: ['华文细黑'] },\r\n  { label: '华文行楷', value: 'STXingkai', css: '\"STXingkai\", \"STKaiti\", \"KaiTi\", \"LXGW WenKai\", serif', aliases: ['华文行楷'] },\r\n  { label: '华文隶书', value: 'STLiti', css: '\"STLiti\", \"STFangsong\", \"FangSong\", \"Noto Serif CJK SC\", serif', aliases: ['华文隶书'] },\r\n  { label: '华文新魏', value: 'STXinwei', css: '\"STXinwei\", \"STXihei\", \"SimHei\", \"Noto Sans CJK SC\", sans-serif', aliases: ['华文新魏'] },\r\n  { label: '华文彩云', value: 'STCaiyun', css: '\"STCaiyun\", \"STSong\", \"SimSun\", \"Noto Serif CJK SC\", serif', aliases: ['华文彩云'] },\r\n  { label: 'Times New Roman', value: 'Times New Roman', css: '\"Times New Roman\", \"Liberation Serif\", serif' },\r\n  { label: 'Arial', value: 'Arial', css: 'Arial, \"Liberation Sans\", sans-serif' },\r\n  { label: 'Calibri', value: 'Calibri', css: 'Calibri, \"Liberation Sans\", sans-serif' },\r\n  { label: 'Courier New', value: 'Courier New', css: '\"Courier New\", \"Liberation Mono\", monospace' },\r\n  { label: 'Verdana', value: 'Verdana', css: 'Verdana, \"DejaVu Sans\", sans-serif' }\r\n]\r\n\r\n/** 字体下拉选项（显示名列表，有序） */\r\nexport const FONT_FAMILY_LIST: string[] = FONT_FAMILY_MAP.map(e => e.label)\r\n\r\n/** 显示名 → 存储名（工具栏选中后存文档用） */\r\nexport const FONT_FAMILY_VALUE: Record<string, string> = Object.fromEntries(\r\n  FONT_FAMILY_MAP.map(e => [e.label, e.value])\r\n)\r\n\r\n/** 存储名/别名 → 显示名（用于回显，认中文名和英文名） */\r\nexport const FONT_FAMILY_LABEL: Record<string, string> = Object.fromEntries(\r\n  FONT_FAMILY_MAP.flatMap(e => [\r\n    [e.value, e.label],\r\n    ...(e.aliases ?? []).map(a => [a, e.label] as [string, string])\r\n  ])\r\n)\r\n\r\n/** 存储名/别名 → CSS font-family 值（用于渲染，带跨平台 fallback） */\r\nexport const FONT_FAMILY_CSS: Record<string, string> = Object.fromEntries(\r\n  FONT_FAMILY_MAP.flatMap(e => [\r\n    [e.value, e.css],\r\n    ...(e.aliases ?? []).map(a => [a, e.css] as [string, string])\r\n  ])\r\n)\r\n\r\n/**\r\n * WPS 字号表（中文字号名 → pt 值）\r\n * 完整覆盖 WPS 全部预设字号：初号~八号 + 小初~小六\r\n */\r\nexport const FONT_SIZE: Record<string, number> = {\r\n  '初号': 42,\r\n  '小初': 36,\r\n  '一号': 26,\r\n  '小一': 24,\r\n  '二号': 22,\r\n  '小二': 18,\r\n  '三号': 16,\r\n  '小三': 15,\r\n  '四号': 14,\r\n  '小四': 12,\r\n  '五号': 10.5,\r\n  '小五': 9,\r\n  '六号': 7.5,\r\n  '小六': 6.5,\r\n  '七号': 5.5,\r\n  '八号': 5\r\n}\r\n\r\n/**\r\n * 字号下拉选项（有序，中文字号 + 常用数字字号）\r\n * WPS 风格：先列中文字号，再列常用数字字号\r\n */\r\nexport const FONT_SIZE_LIST = [\r\n  '初号', '小初', '一号', '小一', '二号', '小二', '三号', '小三', '四号', '小四',\r\n  '五号', '小五', '六号', '小六', '七号', '八号',\r\n  '5', '5.5', '6.5', '7.5', '8', '9', '10', '10.5', '11', '12', '14', '15', '16',\r\n  '18', '20', '22', '24', '26', '28', '30', '36', '42', '48', '54', '60', '72'\r\n] as const\r\n\r\n/* ========== 纸张方向 / 表格边框 ========== */\r\n\r\n/** 纸张方向 */\r\nexport const PaperDirection = {\r\n  VERTICAL: 'vertical',\r\n  HORIZONTAL: 'horizontal'\r\n} as const\r\n\r\n/** 表格边框类型 */\r\nexport const TableBorder = {\r\n  NONE: 'none',\r\n  OUTSIDE: 'outside',\r\n  ALL: 'all',\r\n  INSIDE: 'inside',\r\n  INSIDE_HORIZONTAL: 'inside-horizontal',\r\n  INSIDE_VERTICAL: 'inside-vertical',\r\n  TOP: 'top',\r\n  BOTTOM: 'bottom',\r\n  LEFT: 'left',\r\n  RIGHT: 'right'\r\n} as const\r\n\r\nexport type TableBorderPreset = typeof TableBorder[keyof typeof TableBorder]\r\n\r\n/* ========== 单位换算（96 DPI） ========== */\r\n\r\n/** 屏幕 DPI 常量 */\r\nexport const DPI = 96\r\n\r\n/**\r\n * 磅（pt）转像素（px）\r\n * @param pt 磅值\r\n * @returns 像素值（保留两位小数）\r\n */\r\nexport function ptToPx(pt: number): number {\r\n  return Math.round(pt * (DPI / 72) * 100) / 100\r\n}\r\n\r\n/**\r\n * 像素（px）转磅（pt）\r\n * @param px 像素值\r\n * @returns 磅值（保留一位小数，0.5 步进）\r\n */\r\nexport function pxToPt(px: number): number {\r\n  return Math.round(px * (72 / DPI) * 2) / 2\r\n}\r\n\r\n/* ========== 纸张大小（对齐 WPS/Office，96 DPI） ========== */\r\n\r\nexport interface PaperSize {\r\n  /** 纸张标识（唯一 key） */\r\n  key: string\r\n  /** 显示名称 */\r\n  label: string\r\n  /** 纸张宽度（px @ 96dpi） */\r\n  width: number\r\n  /** 纸张高度（px @ 96dpi） */\r\n  height: number\r\n  /** 分类 */\r\n  category: 'a-series' | 'b-series' | 'us' | 'cn' | 'envelope' | 'other'\r\n}\r\n\r\n/**\r\n * WPS/Office 纸张预设列表（覆盖 80%+ 常用纸张）\r\n * 像素值按 96 DPI 换算：px = mm * 96 / 25.4\r\n */\r\nexport const PAPER_SIZE_LIST: PaperSize[] = [\r\n  // A 系列（ISO 216）\r\n  { key: 'a0', label: 'A0 (84.1×118.9cm)', width: 3179, height: 4494, category: 'a-series' },\r\n  { key: 'a1', label: 'A1 (59.4×84.1cm)', width: 2245, height: 3179, category: 'a-series' },\r\n  { key: 'a2', label: 'A2 (42×59.4cm)', width: 1587, height: 2245, category: 'a-series' },\r\n  { key: 'a3', label: 'A3 (29.7×42cm)', width: 1123, height: 1587, category: 'a-series' },\r\n  { key: 'a4', label: 'A4 (21×29.7cm)', width: 794, height: 1123, category: 'a-series' },\r\n  { key: 'a5', label: 'A5 (14.8×21cm)', width: 559, height: 794, category: 'a-series' },\r\n  { key: 'a6', label: 'A6 (10.5×14.8cm)', width: 397, height: 559, category: 'a-series' },\r\n  // B 系列（JIS）\r\n  { key: 'b4', label: 'B4 (25.7×36.4cm)', width: 971, height: 1376, category: 'b-series' },\r\n  { key: 'b5', label: 'B5 (18.2×25.7cm)', width: 688, height: 971, category: 'b-series' },\r\n  { key: 'b6', label: 'B6 (12.8×18.2cm)', width: 484, height: 688, category: 'b-series' },\r\n  // 美式\r\n  { key: 'letter', label: 'Letter (21.6×27.9cm)', width: 816, height: 1056, category: 'us' },\r\n  { key: 'legal', label: 'Legal (21.6×35.6cm)', width: 816, height: 1344, category: 'us' },\r\n  { key: 'tabloid', label: 'Tabloid (27.9×43.2cm)', width: 1056, height: 1633, category: 'us' },\r\n  { key: 'executive', label: 'Executive (18.4×26.7cm)', width: 696, height: 1009, category: 'us' },\r\n  { key: 'statement', label: 'Statement (14×21.6cm)', width: 529, height: 816, category: 'us' },\r\n  { key: 'folio', label: 'Folio (21.6×33cm)', width: 816, height: 1247, category: 'us' },\r\n  // 中式\r\n  { key: '16k', label: '16K (19.5×27cm)', width: 737, height: 1020, category: 'cn' },\r\n  { key: '32k', label: '32K (13×19cm)', width: 491, height: 718, category: 'cn' },\r\n  { key: '32k-large', label: '大32K (14×20.3cm)', width: 529, height: 767, category: 'cn' },\r\n  // 信封\r\n  { key: 'env-10', label: '信封 #10 (10.5×24.1cm)', width: 397, height: 910, category: 'envelope' },\r\n  { key: 'env-dl', label: '信封 DL (11×22cm)', width: 416, height: 831, category: 'envelope' },\r\n  { key: 'env-c5', label: '信封 C5 (16.2×22.9cm)', width: 612, height: 865, category: 'envelope' },\r\n  { key: 'env-c6', label: '信封 C6 (11.4×16.2cm)', width: 430, height: 612, category: 'envelope' },\r\n  { key: 'env-monarch', label: '信封 Monarch (9.8×19cm)', width: 370, height: 718, category: 'envelope' },\r\n  // 其他\r\n  { key: 'photo-4x6', label: '照片 4×6 (10.2×15.2cm)', width: 386, height: 574, category: 'other' },\r\n  { key: 'postcard', label: '明信片 (10×14.8cm)', width: 378, height: 559, category: 'other' }\r\n]\r\n\r\n/** 默认纸张大小（A4） */\r\nexport const DEFAULT_PAPER_SIZE: PaperSize = PAPER_SIZE_LIST[4]\r\n\r\n/* ========== 项目符号 / 编号样式 ========== */\r\n\r\n/** 项目符号样式 */\r\nexport const BULLET_STYLES = [\r\n  { style: 'disc', icon: '●', label: '实心圆点' },\r\n  { style: 'circle', icon: '○', label: '空心圆点' },\r\n  { style: 'square', icon: '■', label: '实心方块' },\r\n  { style: 'hollow-square', icon: '□', label: '空心方块' },\r\n  { style: 'diamond', icon: '◆', label: '实心菱形' },\r\n  { style: 'hollow-diamond', icon: '◇', label: '空心菱形' },\r\n  { style: 'arrow', icon: '▶', label: '箭头' },\r\n  { style: 'check', icon: '✓', label: '对勾' }\r\n]\r\n\r\n/** 编号样式 */\r\nexport const NUMBER_STYLES = [\r\n  { style: 'decimal', numFmt: 'decimal', lvlText: '%1.', samples: ['1.', '2.', '3.'], label: '阿拉伯数字' },\r\n  { style: 'decimal-bracket', numFmt: 'decimal', lvlText: '%1)', samples: ['1)', '2)', '3)'], label: '数字右括号' },\r\n  { style: 'decimal-paren', numFmt: 'decimal', lvlText: '(%1)', samples: ['(1)', '(2)', '(3)'], label: '数字括号' },\r\n  { style: 'upper-alpha', numFmt: 'upperLetter', lvlText: '%1.', samples: ['A.', 'B.', 'C.'], label: '大写字母' },\r\n  { style: 'lower-alpha-dot', numFmt: 'lowerLetter', lvlText: '%1.', samples: ['a.', 'b.', 'c.'], label: '小写字母' },\r\n  { style: 'chinese', numFmt: 'chineseCounting', lvlText: '%1、', samples: ['一、', '二、', '三、'], label: '中文数字' },\r\n  { style: 'chinese-bracket', numFmt: 'chineseCounting', lvlText: '（%1）', samples: ['（一）', '（二）', '（三）'], label: '中文括号' },\r\n  { style: 'decimal-circle', numFmt: 'decimalEnclosedCircle', lvlText: '%1', samples: ['①', '②', '③'], label: '圈码' }\r\n]\r\n\r\n/* ========== 行距 / 页边距 / 缩放 ========== */\r\n\r\n/** 行距选项 */\r\nexport const LINE_HEIGHT_OPTIONS = [\r\n  { value: 1, label: '单倍行距' },\r\n  { value: 1.15, label: '1.15 倍行距' },\r\n  { value: 1.5, label: '1.5 倍行距' },\r\n  { value: 2, label: '双倍行距' },\r\n  { value: 2.5, label: '2.5 倍行距' },\r\n  { value: 3, label: '三倍行距' }\r\n]\r\n\r\n/** 页边距预设 */\r\nexport const MARGIN_PRESETS = [\r\n  { name: '普通', margins: [96, 120, 96, 120], style: { margin: '14px 18px' } },\r\n  { name: '窄', margins: [48, 48, 48, 48], style: { margin: '7px 7px' } },\r\n  { name: '适中', margins: [96, 72, 96, 72], style: { margin: '14px 11px' } },\r\n  { name: '宽', margins: [96, 192, 96, 192], style: { margin: '14px 28px' } }\r\n]\r\n\r\n/** 缩放级别 */\r\nexport const ZOOM_LEVELS = [50, 75, 100, 125, 150, 200]\r\n\r\n/* ========== 分割线样式 ========== */\r\n\r\n/** 分割线样式 */\r\nexport const SEPARATOR_STYLES = [\r\n  { name: '极细实线', type: 'solid', width: 0.5, dashArray: [0, 0] },\r\n  { name: '细实线', type: 'solid', width: 1, dashArray: [0, 0] },\r\n  { name: '中实线', type: 'solid', width: 2, dashArray: [0, 0] },\r\n  { name: '粗实线', type: 'solid', width: 3, dashArray: [0, 0] },\r\n  { name: '特粗实线', type: 'solid', width: 4, dashArray: [0, 0] },\r\n  { name: '细点线', type: 'dotted', width: 0.5, dashArray: [1, 1] },\r\n  { name: '点线', type: 'dotted', width: 1, dashArray: [1, 1] },\r\n  { name: '粗点线', type: 'dotted', width: 2, dashArray: [1, 1] },\r\n  { name: '大点线', type: 'dotted', width: 3, dashArray: [2, 2] },\r\n  { name: '细短虚线', type: 'dashed', width: 0.5, dashArray: [3, 2] },\r\n  { name: '短虚线', type: 'dashed', width: 1, dashArray: [3, 2] },\r\n  { name: '粗短虚线', type: 'dashed', width: 2, dashArray: [3, 2] },\r\n  { name: '细长虚线', type: 'dashed', width: 0.5, dashArray: [6, 3] },\r\n  { name: '长虚线', type: 'dashed', width: 1, dashArray: [6, 3] },\r\n  { name: '粗长虚线', type: 'dashed', width: 2, dashArray: [6, 3] },\r\n  { name: '特长虚线', type: 'dashed', width: 1, dashArray: [10, 5] },\r\n  { name: '点划线', type: 'dashed', width: 1, dashArray: [6, 2, 1, 2] },\r\n  { name: '粗点划线', type: 'dashed', width: 2, dashArray: [6, 2, 1, 2] },\r\n  { name: '双点划线', type: 'dashed', width: 1, dashArray: [6, 2, 1, 2, 1, 2] },\r\n  { name: '粗双点划线', type: 'dashed', width: 2, dashArray: [6, 2, 1, 2, 1, 2] },\r\n  { name: '细双线', type: 'double', width: 2, dashArray: [0, 0] },\r\n  { name: '双线', type: 'double', width: 3, dashArray: [0, 0] },\r\n  { name: '粗双线', type: 'double', width: 4, dashArray: [0, 0] },\r\n  { name: '特粗双线', type: 'double', width: 5, dashArray: [0, 0] },\r\n  { name: '三线', type: 'triple', width: 4, dashArray: [0, 0] },\r\n  { name: '细波浪线', type: 'wavy', width: 0.5, dashArray: [0, 0] },\r\n  { name: '波浪线', type: 'wavy', width: 1, dashArray: [0, 0] },\r\n  { name: '粗波浪线', type: 'wavy', width: 2, dashArray: [0, 0] },\r\n  { name: '渐变线', type: 'gradient', width: 2, dashArray: [0, 0] },\r\n  { name: '阴影线', type: 'shadow', width: 2, dashArray: [0, 0] },\r\n  { name: '浮雕线', type: 'emboss', width: 3, dashArray: [0, 0] }\r\n]\r\n\r\n/* ========== 标题级别映射 ========== */\r\n\r\n/** 标题级别映射 */\r\nexport const TITLE_LEVEL_MAP: Record<string, string> = {\r\n  first: '标题1',\r\n  second: '标题2',\r\n  third: '标题3',\r\n  fourth: '标题4',\r\n  fifth: '标题5',\r\n  sixth: '标题6'\r\n}\r\n","const AUTHOR_COLORS = [\r\n  '#409EFF', '#67C23A', '#E6A23C', '#F56C6C',\r\n  '#909399', '#00BCD4', '#9C27B0', '#3F51B5',\r\n  '#FF9800', '#4CAF50', '#009688', '#795548',\r\n  '#FF5722', '#C2185B', '#FFC107', '#607D8B'\r\n]\r\n\r\n/** Stable author colors shared by review text, balloons and connectors. */\r\nexport function getAuthorColor(name: string): string {\r\n  let hash = 0\r\n  for (let i = 0; i < name.length; i++) {\r\n    hash = name.charCodeAt(i) + ((hash << 5) - hash)\r\n  }\r\n  return AUTHOR_COLORS[Math.abs(hash) % AUTHOR_COLORS.length]\r\n}\r\n","import type { IElement, ITextElement } from './types'\r\n\r\nexport interface RevisionMeta {\r\n  revisionId: string\r\n  revisionType: 'insert' | 'delete' | 'format'\r\n  revisionAuthor: string\r\n  revisionDate: string\r\n}\r\n\r\ntype FormatValue = string | number | boolean | null\r\nexport type RevisionFormat = Record<string, FormatValue>\r\n\r\nconst FORMAT_KEYS = [\r\n  'font', 'size', 'bold', 'italic', 'underline', 'strikeout', 'doubleStrikeout',\r\n  'hidden', 'superscript', 'subscript', 'color', 'highlight', 'characterScale',\r\n  'letterSpacing', 'textDecoration', 'characterStyleId', 'paragraphStyleId',\r\n  'paragraphColor', 'rowFlex', 'lineHeight', 'lineHeightRule', 'rowMargin',\r\n  'paragraphIndentLeft', 'paragraphIndentRight', 'paragraphFirstLineIndent',\r\n  'indentHanging', 'paragraphSpacingBefore', 'paragraphSpacingAfter'\r\n] as const\r\n\r\nconst BOOLEAN_TAGS = {\r\n  bold: 'b', italic: 'i', strikeout: 'strike', doubleStrikeout: 'dstrike', hidden: 'vanish'\r\n} as const\r\n\r\nexport function snapshotRevisionFormat(element: IElement): RevisionFormat {\r\n  const source = element as unknown as Record<string, unknown>\r\n  return Object.fromEntries(FORMAT_KEYS.map(key => [key, source[key] ?? null])) as RevisionFormat\r\n}\r\n\r\nexport function clearRevision(element: IElement): void {\r\n  const run = element as ITextElement\r\n  delete run.revisionId\r\n  delete run.revisionType\r\n  delete run.revisionAuthor\r\n  delete run.revisionDate\r\n  delete run.revisionOldRPr\r\n  if (run.extension) {\r\n    // Do not mutate extension objects that may be shared by split runs.\r\n    const extension = { ...run.extension }\r\n    delete extension.revisionOldProps\r\n    delete extension.revisionPrevious\r\n    if (Object.keys(extension).length) run.extension = extension\r\n    else delete run.extension\r\n  }\r\n}\r\n\r\nfunction decodeXml(value: string): string {\r\n  return value.replace(/&quot;/g, '\"').replace(/&apos;/g, \"'\")\r\n    .replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&')\r\n}\r\n\r\nfunction escapeXml(value: FormatValue): string {\r\n  return String(value).replace(/&/g, '&amp;').replace(/\"/g, '&quot;')\r\n    .replace(/</g, '&lt;').replace(/>/g, '&gt;')\r\n}\r\n\r\nfunction readRunProperties(xml: string): RevisionFormat {\r\n  const result: RevisionFormat = {}\r\n  const tag = (name: string) => xml.match(new RegExp(`<(?:\\\\w+:)?${name}(?=[\\\\s/>])([^>]*)>`))?.[1]\r\n  const attr = (source: string | undefined, name = 'val') =>\r\n    source?.match(new RegExp(`(?:^|\\\\s)(?:\\\\w+:)?${name}\\\\s*=\\\\s*[\"']([^\"']*)[\"']`))?.[1]\r\n  for (const [key, name] of Object.entries(BOOLEAN_TAGS)) {\r\n    const source = tag(name)\r\n    result[key] = source === undefined ? null : !/^(0|false|off)$/.test(attr(source) ?? '')\r\n  }\r\n  const underline = tag('u')\r\n  result.underline = underline === undefined ? null : attr(underline) !== 'none'\r\n  result.textDecoration = underline === undefined ? null : ({\r\n    single: 'solid', double: 'double', dash: 'dashed', dotted: 'dotted', wave: 'wavy'\r\n  } as Record<string, string>)[attr(underline) ?? 'single'] ?? 'solid'\r\n  const fonts = tag('rFonts')\r\n  const font = attr(fonts, 'eastAsia') ?? attr(fonts, 'ascii') ?? attr(fonts, 'hAnsi')\r\n  result.font = font === undefined ? null : decodeXml(font)\r\n  for (const [key, name, scale] of [\r\n    ['size', 'sz', 0.5], ['characterScale', 'w', 1], ['letterSpacing', 'spacing', 1 / 15]\r\n  ] as const) {\r\n    const value = attr(tag(name))\r\n    result[key] = value !== undefined && Number.isFinite(Number(value)) ? Number(value) * scale : null\r\n  }\r\n  const color = attr(tag('color'))\r\n  result.color = color && color !== 'auto' ? `#${color}` : null\r\n  result.highlight = attr(tag('highlight')) ?? null\r\n  result.characterStyleId = attr(tag('rStyle')) ?? null\r\n  const vertical = attr(tag('vertAlign'))\r\n  result.superscript = vertical === 'superscript' ? true : null\r\n  result.subscript = vertical === 'subscript' ? true : null\r\n  return result\r\n}\r\n\r\nexport function getRevisionOldProps(element: IElement): RevisionFormat {\r\n  const stored = element.extension?.revisionOldProps\r\n  if (stored && typeof stored === 'object' && !Array.isArray(stored)) {\r\n    const source = stored as Record<string, unknown>\r\n    const result: RevisionFormat = {}\r\n    for (const key of FORMAT_KEYS) {\r\n      if (!Object.prototype.hasOwnProperty.call(source, key)) continue\r\n      const value = source[key]\r\n      if (value == null || ['string', 'number', 'boolean'].includes(typeof value)) {\r\n        result[key] = (value ?? null) as FormatValue\r\n      }\r\n    }\r\n    return result\r\n  }\r\n  const xml = (element as ITextElement).revisionOldRPr\r\n  return xml === undefined ? {} : readRunProperties(xml)\r\n}\r\n\r\nfunction serializeRunProperties(format: RevisionFormat): string {\r\n  const parts: string[] = []\r\n  const add = (tag: string, value: FormatValue) => {\r\n    if (value !== null && value !== undefined) parts.push(`<w:${tag} w:val=\"${escapeXml(value)}\"/>`)\r\n  }\r\n  for (const [key, tag] of Object.entries(BOOLEAN_TAGS)) {\r\n    if (format[key] != null) add(tag, format[key] ? 1 : 0)\r\n  }\r\n  if (format.font != null) {\r\n    const font = escapeXml(format.font)\r\n    parts.push(`<w:rFonts w:ascii=\"${font}\" w:hAnsi=\"${font}\" w:eastAsia=\"${font}\"/>`)\r\n  }\r\n  if (typeof format.size === 'number') add('sz', format.size * 2)\r\n  if (typeof format.letterSpacing === 'number') add('spacing', Math.round(format.letterSpacing * 15))\r\n  add('w', format.characterScale)\r\n  add('rStyle', format.characterStyleId)\r\n  add('color', typeof format.color === 'string' ? format.color.replace(/^#/, '') : null)\r\n  add('highlight', format.highlight)\r\n  if (format.underline != null) {\r\n    const style = ({ solid: 'single', double: 'double', dashed: 'dash', dotted: 'dotted', wavy: 'wave' } as Record<string, string>)[String(format.textDecoration)] ?? 'single'\r\n    add('u', format.underline ? style : 'none')\r\n  }\r\n  if (format.superscript || format.subscript) add('vertAlign', format.superscript ? 'superscript' : 'subscript')\r\n  return parts.join('')\r\n}\r\n\r\nexport function recordFormatRevision(element: IElement, before: RevisionFormat, meta: RevisionMeta): void {\r\n  const run = element as ITextElement\r\n  // A run has one revision slot: formatting must not replace insertion/deletion identity.\r\n  if (run.revisionType === 'insert' || run.revisionType === 'delete') return\r\n  const after = snapshotRevisionFormat(element)\r\n  const changed = FORMAT_KEYS.filter(key => before[key] !== after[key])\r\n  if (!changed.length) return\r\n  const existing = run.revisionType === 'format'\r\n  const oldProps = existing ? getRevisionOldProps(element) : {}\r\n  for (const key of changed) {\r\n    if (!(key in oldProps)) oldProps[key] = before[key] ?? null\r\n  }\r\n  if (Object.entries(oldProps).every(([key, value]) => after[key] === value)) {\r\n    clearRevision(element)\r\n    return\r\n  }\r\n  if (!existing) {\r\n    Object.assign(run, meta)\r\n    run.revisionOldRPr = serializeRunProperties(before)\r\n  }\r\n  run.extension = { ...run.extension, revisionOldProps: oldProps }\r\n}\r\n\r\nexport function restoreRevisionFormat(element: IElement): void {\r\n  const target = element as unknown as Record<string, unknown>\r\n  for (const [key, value] of Object.entries(getRevisionOldProps(element))) {\r\n    if (value === null) delete target[key]\r\n    else target[key] = value\r\n  }\r\n}\r\n","'use strict'\nmodule.exports = rfdc\n\nfunction copyBuffer (cur) {\n  if (cur instanceof Buffer) {\n    return Buffer.from(cur)\n  }\n\n  return new cur.constructor(cur.buffer.slice(), cur.byteOffset, cur.length)\n}\n\nfunction rfdc (opts) {\n  opts = opts || {}\n  if (opts.circles) return rfdcCircles(opts)\n\n  const constructorHandlers = new Map()\n  constructorHandlers.set(Date, (o) => new Date(o))\n  constructorHandlers.set(Map, (o, fn) => new Map(cloneArray(Array.from(o), fn)))\n  constructorHandlers.set(Set, (o, fn) => new Set(cloneArray(Array.from(o), fn)))\n  if (opts.constructorHandlers) {\n    for (const handler of opts.constructorHandlers) {\n      constructorHandlers.set(handler[0], handler[1])\n    }\n  }\n\n  let handler = null\n\n  return opts.proto ? cloneProto : clone\n\n  function cloneArray (a, fn) {\n    const keys = Object.keys(a)\n    const a2 = new Array(keys.length)\n    for (let i = 0; i < keys.length; i++) {\n      const k = keys[i]\n      const cur = a[k]\n      if (typeof cur !== 'object' || cur === null) {\n        a2[k] = cur\n      } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n        a2[k] = handler(cur, fn)\n      } else if (ArrayBuffer.isView(cur)) {\n        a2[k] = copyBuffer(cur)\n      } else {\n        a2[k] = fn(cur)\n      }\n    }\n    return a2\n  }\n\n  function clone (o) {\n    if (typeof o !== 'object' || o === null) return o\n    if (Array.isArray(o)) return cloneArray(o, clone)\n    if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor))) {\n      return handler(o, clone)\n    }\n    const o2 = {}\n    for (const k in o) {\n      if (Object.hasOwnProperty.call(o, k) === false) continue\n      const cur = o[k]\n      if (typeof cur !== 'object' || cur === null) {\n        o2[k] = cur\n      } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n        o2[k] = handler(cur, clone)\n      } else if (ArrayBuffer.isView(cur)) {\n        o2[k] = copyBuffer(cur)\n      } else {\n        o2[k] = clone(cur)\n      }\n    }\n    return o2\n  }\n\n  function cloneProto (o) {\n    if (typeof o !== 'object' || o === null) return o\n    if (Array.isArray(o)) return cloneArray(o, cloneProto)\n    if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor))) {\n      return handler(o, cloneProto)\n    }\n    const o2 = {}\n    for (const k in o) {\n      const cur = o[k]\n      if (typeof cur !== 'object' || cur === null) {\n        o2[k] = cur\n      } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n        o2[k] = handler(cur, cloneProto)\n      } else if (ArrayBuffer.isView(cur)) {\n        o2[k] = copyBuffer(cur)\n      } else {\n        o2[k] = cloneProto(cur)\n      }\n    }\n    return o2\n  }\n}\n\nfunction rfdcCircles (opts) {\n  const refs = []\n  const refsNew = []\n\n  const constructorHandlers = new Map()\n  constructorHandlers.set(Date, (o) => new Date(o))\n  constructorHandlers.set(Map, (o, fn) => new Map(cloneArray(Array.from(o), fn)))\n  constructorHandlers.set(Set, (o, fn) => new Set(cloneArray(Array.from(o), fn)))\n  if (opts.constructorHandlers) {\n    for (const handler of opts.constructorHandlers) {\n      constructorHandlers.set(handler[0], handler[1])\n    }\n  }\n\n  let handler = null\n  return opts.proto ? cloneProto : clone\n\n  function cloneArray (a, fn) {\n    const keys = Object.keys(a)\n    const a2 = new Array(keys.length)\n    for (let i = 0; i < keys.length; i++) {\n      const k = keys[i]\n      const cur = a[k]\n      if (typeof cur !== 'object' || cur === null) {\n        a2[k] = cur\n      } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n        a2[k] = handler(cur, fn)\n      } else if (ArrayBuffer.isView(cur)) {\n        a2[k] = copyBuffer(cur)\n      } else {\n        const index = refs.indexOf(cur)\n        if (index !== -1) {\n          a2[k] = refsNew[index]\n        } else {\n          a2[k] = fn(cur)\n        }\n      }\n    }\n    return a2\n  }\n\n  function clone (o) {\n    if (typeof o !== 'object' || o === null) return o\n    if (Array.isArray(o)) return cloneArray(o, clone)\n    if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor))) {\n      return handler(o, clone)\n    }\n    const o2 = {}\n    refs.push(o)\n    refsNew.push(o2)\n    for (const k in o) {\n      if (Object.hasOwnProperty.call(o, k) === false) continue\n      const cur = o[k]\n      if (typeof cur !== 'object' || cur === null) {\n        o2[k] = cur\n      } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n        o2[k] = handler(cur, clone)\n      } else if (ArrayBuffer.isView(cur)) {\n        o2[k] = copyBuffer(cur)\n      } else {\n        const i = refs.indexOf(cur)\n        if (i !== -1) {\n          o2[k] = refsNew[i]\n        } else {\n          o2[k] = clone(cur)\n        }\n      }\n    }\n    refs.pop()\n    refsNew.pop()\n    return o2\n  }\n\n  function cloneProto (o) {\n    if (typeof o !== 'object' || o === null) return o\n    if (Array.isArray(o)) return cloneArray(o, cloneProto)\n    if (o.constructor !== Object && (handler = constructorHandlers.get(o.constructor))) {\n      return handler(o, cloneProto)\n    }\n    const o2 = {}\n    refs.push(o)\n    refsNew.push(o2)\n    for (const k in o) {\n      const cur = o[k]\n      if (typeof cur !== 'object' || cur === null) {\n        o2[k] = cur\n      } else if (cur.constructor !== Object && (handler = constructorHandlers.get(cur.constructor))) {\n        o2[k] = handler(cur, cloneProto)\n      } else if (ArrayBuffer.isView(cur)) {\n        o2[k] = copyBuffer(cur)\n      } else {\n        const i = refs.indexOf(cur)\n        if (i !== -1) {\n          o2[k] = refsNew[i]\n        } else {\n          o2[k] = cloneProto(cur)\n        }\n      }\n    }\n    refs.pop()\n    refsNew.pop()\n    return o2\n  }\n}\n","\r\n/**\r\n * VerveDocs Schema —— 树遍历与路径寻址\r\n *\r\n * 所有遍历严格保持树形语义，不做扁平化。\r\n */\r\n\r\nimport rfdc from 'rfdc'\r\nimport type { IElement, Path, PathSegment, IPosition, ITableElement, ITd, ITr, IControlElement, ControlDataValue } from './types'\r\n\r\n/* -------------------- 深拷贝 -------------------- */\r\n\r\n/** rfdc 深拷贝实例（关闭原型拷贝与循环引用检测以提升性能） */\r\nconst _clone = rfdc({ proto: false, circles: false })\r\n\r\n/**\r\n * 深拷贝树节点。\r\n * @param node 待拷贝的节点\r\n * @returns 拷贝后的新节点（基本类型直接返回）\r\n */\r\nexport function cloneTree<T>(node: T): T {\r\n  if (node === null || typeof node !== 'object') return node\r\n  return _clone(node)\r\n}\r\n\r\n/* -------------------- 类型守卫 -------------------- */\r\n\r\n/**\r\n * 判断元素是否为段落容器（title/list 且拥有 valueList 数组）。\r\n * @param el 待判断元素\r\n * @returns 是段落容器则返回 true，并收窄类型\r\n */\r\nexport function isParagraphContainer(el: IElement): el is IElement & { valueList: IElement[] } {\r\n  return (el?.type === 'title' || el?.type === 'list') && Array.isArray((el as { valueList?: unknown }).valueList)\r\n}\r\n\r\n/**\r\n * 判断元素是否为表格（type='table' 且拥有 trList 数组）。\r\n * @param el 待判断元素\r\n * @returns 是表格则返回 true，并收窄类型\r\n */\r\nexport function isTable(el: IElement): el is ITableElement {\r\n  return el?.type === 'table' && Array.isArray((el as ITableElement).trList)\r\n}\r\n\r\n/**\r\n * 判断元素是否为内置内容控件（type='control' 且 control 配置存在）。\r\n * @param el 待判断元素\r\n * @returns 是控件则返回 true，并收窄类型\r\n */\r\nexport function isControl(el: IElement): el is IControlElement {\r\n  return el?.type === 'control' && typeof (el as IControlElement).control === 'object' && (el as IControlElement).control !== null\r\n}\r\n\r\n/* -------------------- 访问器 -------------------- */\r\n\r\n/** 遍历上下文：携带父节点、路径与索引信息 */\r\nexport interface VisitContext {\r\n  /** 父节点（数组或单个元素，根数组时为 null） */\r\n  parent: IElement[] | IElement | null\r\n  /** 当前节点路径 */\r\n  path: Path\r\n  /** 在父容器中的索引 */\r\n  index: number\r\n}\r\n\r\n/** 访问者函数类型：返回 false 可跳过当前节点的子树 */\r\nexport type Visitor = (node: IElement, ctx: VisitContext) => void | boolean\r\n\r\n/**\r\n * 深度优先遍历（返回 false 可跳过子树）。\r\n * 遍历顺序：elements[i] → 若为段落容器则 valueList[i]；若为 table 则 trList[j].tdList[k].value[m]。\r\n */\r\nexport function walkTree(elements: IElement[], visitor: Visitor, parentPath: Path = []): void {\r\n  for (let i = 0; i < elements.length; i++) {\r\n    const node = elements[i]\r\n    const path: Path = [...parentPath, i]\r\n    const shouldDescend = visitor(node, { parent: elements, path, index: i })\r\n    if (shouldDescend === false) continue\r\n\r\n    if (isParagraphContainer(node)) {\r\n      walkTree(node.valueList, visitor, [...path, 'valueList'])\r\n    } else if ((isControl(node) || node.type === 'hyperlink') && Array.isArray(node.valueList)) {\r\n      walkTree(node.valueList, visitor, [...path, 'valueList'])\r\n    } else if (isTable(node)) {\r\n      for (let tr = 0; tr < node.trList.length; tr++) {\r\n        const row = node.trList[tr]\r\n        for (let td = 0; td < row.tdList.length; td++) {\r\n          const cell = row.tdList[td]\r\n          walkTree(cell.value, visitor, [...path, 'trList', tr, 'tdList', td, 'value'])\r\n        }\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\n/* -------------------- 控件归一化 -------------------- */\r\n\r\n/**\r\n * 将旧的 checkbox/radio/date 类型元素归一化为统一的 control 类型。\r\n * 在文档加载边界调用，确保历史数据平滑迁移到新模型。\r\n * 保留未知字段，不丢弃原始数据。\r\n */\r\nexport function normalizeControlElement(el: IElement): IElement {\r\n  if (el.type === 'checkbox') {\r\n    const old = el as IElement & { value?: string }\r\n    const checked = old.value === 'true' || old.value === '1' || old.value === 'checked'\r\n    return {\r\n      ...el,\r\n      type: 'control' as const,\r\n      control: { kind: 'checkbox' as const },\r\n      dataValue: checked as ControlDataValue,\r\n      value: old.value ?? '',\r\n    } as IControlElement\r\n  }\r\n  if (el.type === 'radio') {\r\n    const old = el as IElement & { value?: string }\r\n    return {\r\n      ...el,\r\n      type: 'control' as const,\r\n      control: { kind: 'radioGroup' as const },\r\n      dataValue: (old.value ?? null) as ControlDataValue,\r\n      value: old.value ?? '',\r\n    } as IControlElement\r\n  }\r\n  if (el.type === 'date') {\r\n    const old = el as IElement & { value?: string; valueList?: { value: string }[]; dateFormat?: string }\r\n    const dateValue = old.valueList?.[0]?.value ?? null\r\n    return {\r\n      ...el,\r\n      type: 'control' as const,\r\n      control: { kind: 'date' as const, format: old.dateFormat },\r\n      dataValue: dateValue as ControlDataValue,\r\n      value: dateValue ?? old.value ?? '',\r\n    } as IControlElement\r\n  }\r\n  return el\r\n}\r\n\r\n/**\r\n * 对整棵文档树执行控件归一化（原地替换节点）。\r\n * 遍历段落容器、控件 valueList、表格单元格，将旧类型元素转换为统一 control 类型。\r\n */\r\nexport function normalizeControlTree(elements: IElement[]): IElement[] {\r\n  for (let i = 0; i < elements.length; i++) {\r\n    elements[i] = normalizeControlElement(elements[i])\r\n    const node = elements[i]\r\n    if (isParagraphContainer(node)) {\r\n      normalizeControlTree(node.valueList)\r\n    } else if (isControl(node) && Array.isArray(node.valueList)) {\r\n      normalizeControlTree(node.valueList)\r\n    } else if (isTable(node)) {\r\n      for (const tr of node.trList) {\r\n        for (const td of tr.tdList) {\r\n          normalizeControlTree(td.value)\r\n        }\r\n      }\r\n    }\r\n  }\r\n  return elements\r\n}\r\n\r\n/* -------------------- 路径寻址 -------------------- */\r\n\r\n/**\r\n * 根据路径获取节点。\r\n * 路径示例：\r\n *   [3]                                → elements[3]\r\n *   [3, 'valueList', 1]                → elements[3].valueList[1]\r\n *   [5, 'trList', 0, 'tdList', 2, 'value', 1] → table 第 0 行第 2 单元格第 1 子元素\r\n */\r\nexport function getByPath(root: IElement[], path: Path): IElement | null {\r\n  if (path.length === 0) return null\r\n  let current: unknown = root\r\n  for (const seg of path) {\r\n    if (current == null) return null\r\n    if (typeof seg === 'number') {\r\n      if (!Array.isArray(current)) return null\r\n      current = current[seg]\r\n    } else {\r\n      current = (current as Record<string, unknown>)[seg]\r\n    }\r\n  }\r\n  return (current as IElement) ?? null\r\n}\r\n\r\n/**\r\n * 获取路径末段对应的父容器数组。\r\n * @param root 根元素数组\r\n * @param path 目标路径\r\n * @returns 父容器数组；若路径非法或末段不是数组索引则返回 null\r\n */\r\nexport function getParentContainer(root: IElement[], path: Path): IElement[] | null {\r\n  if (path.length === 0) return null\r\n  const parentPath = path.slice(0, -1)\r\n  const lastSeg = path[path.length - 1]\r\n  if (typeof lastSeg !== 'number') return null // 末段必须是数组索引\r\n  if (parentPath.length === 0) return root\r\n  let current: unknown = root\r\n  for (const seg of parentPath) {\r\n    if (typeof seg === 'number') {\r\n      if (!Array.isArray(current)) return null\r\n      current = current[seg]\r\n    } else {\r\n      current = (current as Record<string, unknown>)[seg]\r\n    }\r\n  }\r\n  return Array.isArray(current) ? (current as IElement[]) : null\r\n}\r\n\r\n/**\r\n * 在路径指定位置替换节点。\r\n * @param root 根元素数组\r\n * @param path 目标路径\r\n * @param node 新节点\r\n * @returns 替换成功返回 true，路径非法返回 false\r\n */\r\nexport function replaceAtPath(root: IElement[], path: Path, node: IElement): boolean {\r\n  const parent = getParentContainer(root, path)\r\n  if (!parent) return false\r\n  const idx = path[path.length - 1] as number\r\n  parent[idx] = node\r\n  return true\r\n}\r\n\r\n/**\r\n * 在路径指定位置插入节点（插入到该索引前）。\r\n * @param root 根元素数组\r\n * @param path 目标路径\r\n * @param node 待插入节点\r\n * @returns 插入成功返回 true，路径非法返回 false\r\n */\r\nexport function insertAtPath(root: IElement[], path: Path, node: IElement): boolean {\r\n  const parent = getParentContainer(root, path)\r\n  if (!parent) return false\r\n  const idx = path[path.length - 1] as number\r\n  parent.splice(idx, 0, node)\r\n  return true\r\n}\r\n\r\n/**\r\n * 移除路径指定位置的节点。\r\n * @param root 根元素数组\r\n * @param path 目标路径\r\n * @returns 被移除的节点；路径非法返回 null\r\n */\r\nexport function removeAtPath(root: IElement[], path: Path): IElement | null {\r\n  const parent = getParentContainer(root, path)\r\n  if (!parent) return null\r\n  const idx = path[path.length - 1] as number\r\n  const [removed] = parent.splice(idx, 1)\r\n  return removed ?? null\r\n}\r\n\r\n/* -------------------- 位置工具 -------------------- */\r\n\r\n/**\r\n * 判断两条路径是否完全相同。\r\n * @param a 路径 a\r\n * @param b 路径 b\r\n * @returns 相同返回 true\r\n */\r\nexport function isSamePath(a: Path, b: Path): boolean {\r\n  if (a.length !== b.length) return false\r\n  for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false\r\n  return true\r\n}\r\n\r\n/**\r\n * 比较两条路径的字典序（数字段按数值比较，字符串段按字符串比较）。\r\n * @param a 路径 a\r\n * @param b 路径 b\r\n * @returns a<b 返回负数，a=b 返回 0，a>b 返回正数\r\n */\r\nexport function comparePath(a: Path, b: Path): number {\r\n  const n = Math.min(a.length, b.length)\r\n  for (let i = 0; i < n; i++) {\r\n    const av = a[i]; const bv = b[i]\r\n    if (av === bv) continue\r\n    if (typeof av === 'number' && typeof bv === 'number') return av - bv\r\n    return String(av) < String(bv) ? -1 : 1\r\n  }\r\n  return a.length - b.length\r\n}\r\n\r\n/**\r\n * 比较两个文档位置：先比较路径，路径相同再比较 offset。\r\n * @param a 位置 a\r\n * @param b 位置 b\r\n * @returns a<b 返回负数，a=b 返回 0，a>b 返回正数\r\n */\r\nexport function comparePosition(a: IPosition, b: IPosition): number {\r\n  const c = comparePath(a.path, b.path)\r\n  if (c !== 0) return c\r\n  return a.offset - b.offset\r\n}\r\n\r\n/* -------------------- 表格辅助 -------------------- */\r\n\r\n/**\r\n * 遍历表格所有单元格，对每个单元格调用回调。\r\n * @param table 表格元素\r\n * @param fn 回调函数，接收单元格、行、行索引、列索引\r\n */\r\nexport function forEachCell(\r\n  table: ITableElement,\r\n  fn: (cell: ITd, tr: ITr, trIndex: number, tdIndex: number) => void\r\n) {\r\n  for (let i = 0; i < table.trList.length; i++) {\r\n    const row = table.trList[i]\r\n    for (let j = 0; j < row.tdList.length; j++) {\r\n      fn(row.tdList[j], row, i, j)\r\n    }\r\n  }\r\n}\r\n\r\n/** 计算表格列数（不考虑合并） */\r\nexport function getTableColCount(table: ITableElement): number {\r\n  if (Array.isArray(table.colgroup)) return table.colgroup.length\r\n  return table.trList[0]?.tdList.reduce((sum, td) => sum + (td.colspan || 1), 0) ?? 0\r\n}\r\n\r\n/** 计算某段路径所在的段落容器（title/list/纯段落用父数组表示） */\r\nexport function _pathSegAsKey(seg: PathSegment): string {\r\n  return typeof seg === 'number' ? String(seg) : seg\r\n}\r\n","/**\r\n * VerveDocs Schema —— 内置内容控件工具函数\r\n *\r\n * 提供控件显示文本计算、实例 ID 生成、值校验与元素工厂，\r\n * 供命令层、布局层和序列化层共享调用。\r\n */\r\n\r\nimport type { IControlConfig, IControlElement, ControlDataValue, ControlKind } from './types'\r\n\r\n/* -------------------- 显示文本计算 -------------------- */\r\n\r\n/**\r\n * 根据控件配置和实际业务值计算显示文本。\r\n * 空值返回空字符串（占位提示由布局层作为视图装饰渲染，不存入 value）。\r\n */\r\nexport function computeControlDisplayValue(control: IControlConfig, dataValue: ControlDataValue): string {\r\n  const { kind } = control\r\n  if (dataValue === null || dataValue === undefined) {\r\n    return ''\r\n  }\r\n  switch (kind) {\r\n    case 'text':\r\n      return String(dataValue)\r\n    case 'number':\r\n      return formatNumberDisplay(dataValue, control)\r\n    case 'date':\r\n      return String(dataValue)\r\n    case 'select': {\r\n      if (dataValue === '') return ''\r\n      const opt = control.options?.find(o => o.value === dataValue)\r\n      return opt?.label ?? String(dataValue)\r\n    }\r\n    case 'multiSelect': {\r\n      const values = Array.isArray(dataValue) ? dataValue : []\r\n      if (values.length === 0) return ''\r\n      const delimiter = control.delimiter ?? ','\r\n      const options = control.options ?? []\r\n      const selected = new Set(values)\r\n      const ordered = options.filter(option => selected.has(option.value)).map(option => option.value)\r\n      return [...new Set([...ordered, ...values])]\r\n        .map(v => control.options?.find(o => o.value === v)?.label ?? v)\r\n        .join(delimiter)\r\n    }\r\n    case 'checkbox':\r\n      return control.checkboxLabel ?? ''\r\n    case 'radioGroup': {\r\n      if (dataValue === '') return ''\r\n      const opt = control.options?.find(o => o.value === dataValue)\r\n      return opt?.label ?? String(dataValue)\r\n    }\r\n    default:\r\n      return String(dataValue)\r\n  }\r\n}\r\n\r\n/** 数字显示格式化：分离显示格式与实际值 */\r\nfunction formatNumberDisplay(dataValue: ControlDataValue, control: IControlConfig): string {\r\n  if (typeof dataValue !== 'number') return String(dataValue)\r\n  if (control.format) {\r\n    try {\r\n      return control.format.replace(/\\{0\\}/g, String(dataValue))\r\n    } catch {\r\n      return String(dataValue)\r\n    }\r\n  }\r\n  return String(dataValue)\r\n}\r\n\r\n/* -------------------- 实例 ID 生成 -------------------- */\r\n\r\nlet controlIdCounter = 0\r\n\r\n/**\r\n * 生成控件实例唯一 ID。\r\n * 格式：ctrl-<时间戳36进制>-<递增计数36进制>，保证文档内唯一。\r\n */\r\nexport function generateControlId(): string {\r\n  const ts = Date.now().toString(36)\r\n  const counter = (controlIdCounter++).toString(36)\r\n  return `ctrl-${ts}-${counter}`\r\n}\r\n\r\n/* -------------------- 值校验 -------------------- */\r\n\r\n/** 控件校验结果 */\r\nexport interface ControlValidationResult {\r\n  valid: boolean\r\n  /** 校验失败原因（国际化键名或空） */\r\n  reason?: string\r\n}\r\n\r\n/**\r\n * 校验控件值是否满足配置约束。\r\n * 不修改传入值，仅返回校验结果。\r\n */\r\nexport function validateControlValue(control: IControlConfig, dataValue: ControlDataValue): ControlValidationResult {\r\n  const { kind, required } = control\r\n\r\n  if (required) {\r\n    if (isEmptyValue(kind, dataValue)) {\r\n      return { valid: false, reason: 'control.required' }\r\n    }\r\n  }\r\n\r\n  switch (kind) {\r\n    case 'number':\r\n      return validateNumber(control, dataValue)\r\n    case 'text':\r\n      if (control.maxLength != null && typeof dataValue === 'string' && dataValue.length > control.maxLength) {\r\n        return { valid: false, reason: 'control.maxLength' }\r\n      }\r\n      return { valid: true }\r\n    case 'select':\r\n    case 'radioGroup': {\r\n      if (dataValue === null || dataValue === '' ) return { valid: true }\r\n      const options = control.options ?? []\r\n      if (!options.some(o => o.value === dataValue)) {\r\n        return { valid: false, reason: 'control.invalidOption' }\r\n      }\r\n      return { valid: true }\r\n    }\r\n    case 'multiSelect': {\r\n      const values = Array.isArray(dataValue) ? dataValue : []\r\n      const options = control.options ?? []\r\n      for (const v of values) {\r\n        if (!options.some(o => o.value === v)) {\r\n          return { valid: false, reason: 'control.invalidOption' }\r\n        }\r\n      }\r\n      return { valid: true }\r\n    }\r\n    default:\r\n      return { valid: true }\r\n  }\r\n}\r\n\r\n/** 判断控件值是否为空（区分空值、零、false） */\r\nexport function isEmptyValue(kind: ControlKind, dataValue: ControlDataValue): boolean {\r\n  if (dataValue === null || dataValue === undefined) return true\r\n  if (kind === 'multiSelect') {\r\n    return Array.isArray(dataValue) && dataValue.length === 0\r\n  }\r\n  if (kind === 'checkbox') {\r\n    return false\r\n  }\r\n  if (typeof dataValue === 'string') return dataValue === ''\r\n  return false\r\n}\r\n\r\n/** 数字校验：最小值、最大值、精度 */\r\nfunction validateNumber(control: IControlConfig, dataValue: ControlDataValue): ControlValidationResult {\r\n  if (dataValue === null || dataValue === '' || dataValue === undefined) {\r\n    return { valid: true }\r\n  }\r\n  const num = typeof dataValue === 'number' ? dataValue : Number(dataValue)\r\n  if (!Number.isFinite(num)) {\r\n    return { valid: false, reason: 'control.notNumber' }\r\n  }\r\n  if (control.min != null && num < control.min) {\r\n    return { valid: false, reason: 'control.belowMin' }\r\n  }\r\n  if (control.max != null && num > control.max) {\r\n    return { valid: false, reason: 'control.aboveMax' }\r\n  }\r\n  return { valid: true }\r\n}\r\n\r\n/* -------------------- 元素工厂 -------------------- */\r\n\r\n/**\r\n * 创建控件元素。\r\n * 自动生成 ID、计算初始显示文本。\r\n */\r\nexport function createControlElement(\r\n  config: IControlConfig,\r\n  dataValue: ControlDataValue = null,\r\n  id?: string\r\n): IControlElement {\r\n  const controlId = id ?? generateControlId()\r\n  const displayValue = computeControlDisplayValue(config, dataValue)\r\n  return {\r\n    type: 'control',\r\n    id: controlId,\r\n    control: config,\r\n    dataValue,\r\n    value: displayValue,\r\n  }\r\n}\r\n\r\n/**\r\n * 更新控件元素的值，同步刷新显示文本。\r\n * 返回新对象，不修改原元素。\r\n */\r\nexport function updateControlElementValue(\r\n  element: IControlElement,\r\n  newDataValue: ControlDataValue\r\n): IControlElement {\r\n  const displayValue = computeControlDisplayValue(element.control, newDataValue)\r\n  return {\r\n    ...element,\r\n    dataValue: newDataValue,\r\n    value: displayValue,\r\n  }\r\n}\r\n\r\n/**\r\n * 校验控件配置本身是否合法（options 的 value 唯一、min <= max 等）。\r\n */\r\nexport function validateControlConfig(config: IControlConfig): ControlValidationResult {\r\n  if (config.kind === 'number') {\r\n    if (config.min != null && config.max != null && config.min > config.max) {\r\n      return { valid: false, reason: 'control.minGreaterThanMax' }\r\n    }\r\n  }\r\n  if (config.options) {\r\n    const seen = new Set<string>()\r\n    for (const opt of config.options) {\r\n      if (seen.has(opt.value)) {\r\n        return { valid: false, reason: 'control.duplicateOptionValue' }\r\n      }\r\n      seen.add(opt.value)\r\n    }\r\n  }\r\n  return { valid: true }\r\n}\r\n","/**\r\n * VerveDocs Schema —— formatElementTree\r\n *\r\n * 唯一的树归一入口：只做默认值补全、字段规范化，绝不扁平化。\r\n * 输入即输出（原地修改），返回同一引用。\r\n */\r\n\r\nimport type {\r\n  IElement,\r\n  IImageElement,\r\n  IImageGeometry,\r\n  IDocxDocumentMeta,\r\n  IEditorOption,\r\n  IListNumbering,\r\n  IParagraphStyle,\r\n  IBookmark,\r\n  ITitleElement,\r\n  IListElement,\r\n  ITableElement,\r\n  ITd,\r\n  ITr,\r\n  IControlElement,\r\n  Path,\r\n  PathSegment\r\n} from './types'\r\nimport { DEFAULT_EDITOR_OPTION } from './constants'\r\nimport { isParagraphContainer, isTable, walkTree } from './walk'\r\nimport { computeControlDisplayValue } from './control'\r\n\r\n/** 按节引用选择页眉页脚；未定义的引用按 OOXML 继承前节同类引用。 */\r\nexport function resolveHeaderFooterPart(doc: IDocxDocumentMeta, zone: 'header' | 'footer', sectionIndex: number, pageIndex: number, firstPage: boolean): string | undefined {\r\n  const section = doc.sections?.[sectionIndex]\r\n  const kind = firstPage && section?.titlePage ? 'first' : doc.evenAndOddHeaders && (pageIndex + 1) % 2 === 0 ? 'even' : 'default'\r\n  for (let index = sectionIndex; index >= 0; index--) {\r\n    const refs = zone === 'header' ? doc.sections?.[index]?.headers : doc.sections?.[index]?.footers\r\n    if (refs?.[kind] !== undefined) return refs[kind]\r\n  }\r\n  return undefined\r\n}\r\n\r\n/** 格式化树上下文：携带编辑器选项、样式表、编号定义等归一化所需依赖 */\r\nexport interface FormatTreeContext {\r\n  /** 编辑器选项 */\r\n  editorOptions: IEditorOption\r\n  /** 段落样式表 */\r\n  styles?: Record<string, IParagraphStyle>\r\n  /** 列表编号定义表 */\r\n  numbering?: Record<string, IListNumbering>\r\n  /** 供 LaTeX / 公式等扩展使用的转换钩子 */\r\n  laTexToSVG?: (latex: string) => string\r\n  /** 书签标记收集器（遍历时填充，调用方配对 start/end 构建 bookmarks） */\r\n  bookmarkMarkers?: { name: string; position: string; path: Path }[]\r\n  /** 内部路径栈（递归时 push/pop，不暴露给外部） */\r\n  _pathStack?: PathSegment[]\r\n}\r\n\r\n/**\r\n * 归一化编辑器选项，填充默认值。\r\n */\r\nexport function mergeOption(options?: IEditorOption): IEditorOption {\r\n  return { ...DEFAULT_EDITOR_OPTION, ...(options || {}) }\r\n}\r\n\r\n/**\r\n * 递归归一化元素树。\r\n * - 保证段落容器有 valueList\r\n * - 保证 table 有 colgroup / trList / tdList\r\n * - 保证 td 有 padding / borderStyle / verticalAlign\r\n * - 保证 image 有 width/height\r\n * - 补齐 text 的默认字体/字号\r\n */\r\nexport function formatElementTree(\r\n  elements: IElement[],\r\n  ctx: FormatTreeContext\r\n): IElement[] {\r\n  if (!Array.isArray(elements)) return elements\r\n  // 空文档兜底：若 elements 为空数组，插入一个携带默认字体/字号的空 text run，\r\n  // 以保证 layout 能产出一个段落 block（空段兜底会为其生成零宽 caret 承载 inline），\r\n  // 光标可以定位、用户可以直接输入。新字符会拼入该 run 并继承其属性（默认无 bold/highlight）。\r\n  if (elements.length === 0) {\r\n    elements.push({\r\n      type: 'text',\r\n      value: '',\r\n      font: ctx.editorOptions.defaultFont,\r\n      size: ctx.editorOptions.defaultSize\r\n    } as unknown as IElement)\r\n  }\r\n  const stack = ctx._pathStack ??= []\r\n  for (let i = 0; i < elements.length; i++) {\r\n    stack.push(i)\r\n    const ext = (elements[i] as unknown as { extension?: { bookmarkMarker?: { name: string; position: string } } }).extension\r\n    if (ext?.bookmarkMarker && ctx.bookmarkMarkers) {\r\n      ctx.bookmarkMarkers.push({\r\n        name: ext.bookmarkMarker.name,\r\n        position: ext.bookmarkMarker.position,\r\n        path: [...stack]\r\n      })\r\n    }\r\n    normalizeNode(elements[i], ctx)\r\n    stack.pop()\r\n  }\r\n  return elements\r\n}\r\n\r\n/**\r\n * 调整浮动图片坐标：为非 inline/block 的浮动图片叠加页边距和行内 ascent 偏移。\r\n * 仅在导入时调用一次，不随 formatElementTree 自动触发（避免 undo/redo 二次偏移）。\r\n * @param elements 顶层元素数组（原地修改）\r\n * @param editorOptions 编辑器选项（提供 margins/paperDirection/defaultSize）\r\n */\r\nexport function adjustFloatImagePositions(\r\n  elements: IElement[],\r\n  editorOptions: IEditorOption\r\n): void {\r\n  // 坐标由 Java imageLayout 提供；保留旧 API，但禁止二次估算偏移。\r\n  void elements\r\n  void editorOptions\r\n}\r\n\r\n/**\r\n * 单节点归一化分发：按节点类型调用对应的归一化函数。\r\n * @param node 当前节点\r\n * @param ctx 格式化上下文\r\n */\r\nfunction normalizeNode(node: IElement, ctx: FormatTreeContext): void {\r\n  if (!node || typeof node !== 'object') return\r\n\r\n  switch (node.type) {\r\n    case 'text':\r\n      normalizeText(node as IElement, ctx)\r\n      break\r\n    case 'title':\r\n      normalizeTitle(node as ITitleElement, ctx)\r\n      break\r\n    case 'list':\r\n      normalizeList(node as IListElement, ctx)\r\n      break\r\n    case 'table':\r\n      normalizeTable(node as ITableElement, ctx)\r\n      break\r\n    case 'image':\r\n      normalizeImage(node as IElement, ctx)\r\n      break\r\n    case 'pageBreak':\r\n      normalizePageBreak(node as IElement, ctx)\r\n      break\r\n    case 'control':\r\n      normalizeControl(node as IControlElement, ctx)\r\n      break\r\n    default:\r\n      // 兜底：拥有 valueList/tdList/value 数组的容器一律递归\r\n      const anyNode = node as unknown as Record<string, unknown>\r\n      if (Array.isArray(anyNode.valueList)) {\r\n        ctx._pathStack?.push('valueList')\r\n        formatElementTree(anyNode.valueList as IElement[], ctx)\r\n        ctx._pathStack?.pop()\r\n      }\r\n      break\r\n  }\r\n}\r\n\r\n/**\r\n * 归一化 text 节点：补全 value、font、size 默认值并应用段落样式。\r\n * @param node text 节点\r\n * @param ctx 格式化上下文\r\n */\r\nfunction normalizeText(node: IElement, ctx: FormatTreeContext): void {\r\n  const anyNode = node as unknown as Record<string, unknown>\r\n  if (typeof anyNode.value !== 'string') anyNode.value = String(anyNode.value ?? '')\r\n  if (anyNode.font == null) anyNode.font = ctx.editorOptions.defaultFont\r\n  if (anyNode.size == null) anyNode.size = ctx.editorOptions.defaultSize\r\n  applyParagraphStyleId(node, ctx)\r\n}\r\n\r\n/**\r\n * 归一化 title 节点：补全 valueList、level 默认值，递归归一化子节点并下沉段落属性。\r\n * @param node title 节点\r\n * @param ctx 格式化上下文\r\n */\r\nfunction normalizeTitle(node: ITitleElement, ctx: FormatTreeContext): void {\r\n  if (!Array.isArray(node.valueList)) node.valueList = []\r\n  if (!node.level) node.level = 'first'\r\n  applyParagraphStyleId(node, ctx)\r\n  ctx._pathStack?.push('valueList')\r\n  formatElementTree(node.valueList, ctx)\r\n  ctx._pathStack?.pop()\r\n  // 段落级属性下沉到 valueList 内每个 run 上（若 run 未指定则继承）\r\n  inheritParagraphAttrsToChildren(node)\r\n}\r\n\r\n/**\r\n * 归一化 list 节点：补全 valueList、listType、listStyle、listLevel 等默认值，\r\n * 关联 numbering 定义，递归归一化子节点并下沉段落属性。\r\n * @param node list 节点\r\n * @param ctx 格式化上下文\r\n */\r\nfunction normalizeList(node: IListElement, ctx: FormatTreeContext): void {\r\n  if (!Array.isArray(node.valueList)) node.valueList = []\r\n  if (!node.listType) node.listType = 'ul'\r\n  if (!node.listStyle) node.listStyle = node.listType === 'ol' ? 'decimal' : 'disc'\r\n  if (typeof node.listLevel !== 'number') node.listLevel = 0\r\n  // 若有 numbering 定义引用，补齐\r\n  if (!node.listNumbering && ctx.numbering) {\r\n    const numId = (node as unknown as { numId?: string }).numId\r\n    if (numId && ctx.numbering[numId]) node.listNumbering = ctx.numbering[numId]\r\n  }\r\n  applyParagraphStyleId(node, ctx)\r\n  ctx._pathStack?.push('valueList')\r\n  formatElementTree(node.valueList, ctx)\r\n  ctx._pathStack?.pop()\r\n  inheritParagraphAttrsToChildren(node)\r\n}\r\n\r\n/**\r\n * 归一化 table 节点：补全 colgroup、trList，递归归一化各行；\r\n * 若 colgroup 为空则用第一行宽度推导。\r\n * @param node table 节点\r\n * @param ctx 格式化上下文\r\n */\r\nfunction normalizeTable(node: ITableElement, ctx: FormatTreeContext): void {\r\n  if (!Array.isArray(node.colgroup)) node.colgroup = []\r\n  if (!Array.isArray(node.trList)) node.trList = []\r\n\r\n  for (let ri = 0; ri < node.trList.length; ri++) {\r\n    ctx._pathStack?.push('trList', ri)\r\n    normalizeTr(node.trList[ri], ctx)\r\n    ctx._pathStack?.splice(-2, 2)\r\n  }\r\n\r\n  // 若 colgroup 为空则用第一行宽度推导\r\n  if (node.colgroup.length === 0 && node.trList[0]) {\r\n    node.colgroup = node.trList[0].tdList.map(td => ({ width: td.width || 100 }))\r\n  }\r\n}\r\n\r\n/**\r\n * 归一化表格行：补全 height、tdList 默认值，递归归一化各单元格。\r\n * @param tr 表格行\r\n * @param ctx 格式化上下文\r\n */\r\nfunction normalizeTr(tr: ITr, ctx: FormatTreeContext): void {\r\n  if (typeof tr.height !== 'number' || tr.height <= 0) tr.height = 32\r\n  if (!Array.isArray(tr.tdList)) tr.tdList = []\r\n  for (let ci = 0; ci < tr.tdList.length; ci++) {\r\n    ctx._pathStack?.push('tdList', ci)\r\n    normalizeTd(tr.tdList[ci], ctx)\r\n    ctx._pathStack?.splice(-2, 2)\r\n  }\r\n}\r\n\r\n/**\r\n * 归一化单元格：补全 width、colspan、rowspan、verticalAlign、padding、borderStyle 默认值，\r\n * 递归归一化单元格内容。\r\n * @param td 表格单元格\r\n * @param ctx 格式化上下文\r\n */\r\nfunction normalizeTd(td: ITd, ctx: FormatTreeContext): void {\r\n  if (typeof td.width !== 'number' || td.width <= 0) td.width = 100\r\n  if (typeof td.colspan !== 'number' || td.colspan <= 0) td.colspan = 1\r\n  if (typeof td.rowspan !== 'number' || td.rowspan <= 0) td.rowspan = 1\r\n  if (!td.verticalAlign) td.verticalAlign = 'middle'\r\n  if (!Array.isArray(td.padding) || td.padding.length !== 4) {\r\n    td.padding = [2, 2, 2, 2]\r\n  }\r\n  if (!Array.isArray(td.value)) td.value = []\r\n  ctx._pathStack?.push('value')\r\n  formatElementTree(td.value, ctx)\r\n  ctx._pathStack?.pop()\r\n}\r\n\r\n/**\r\n * 归一化 image 节点：补全 width、height、rotate 默认值并应用段落样式。\r\n * @param node image 节点\r\n * @param ctx 格式化上下文\r\n */\r\nfunction normalizeImage(node: IElement, ctx: FormatTreeContext): void {\r\n  applyImageLayout(node as IImageElement)\r\n  applyParagraphStyleId(node, ctx)\r\n}\r\n\r\n/** OOXML 的长度单位为 EMU，旋转单位为 1/60000 度。 */\r\nexport function applyImageLayout(image: IImageElement): void {\r\n  const layout = image.imageLayout\r\n  if (!layout) return\r\n  const ext = layout.transform?.children.find(child => child.name === 'ext')\r\n  if (ext?.attributes.cx !== undefined) image.width = Number(ext.attributes.cx) / 9525\r\n  if (ext?.attributes.cy !== undefined) image.height = Number(ext.attributes.cy) / 9525\r\n  image.rotate = Number(layout.transform?.attributes.rot ?? 0) / 60000\r\n  if (layout.anchored === false) image.imgDisplay = 'inline'\r\n  else if (layout.anchored === true) {\r\n    const wrap = layout.positioning?.find(node => node.name.startsWith('wrap'))\r\n    image.imgDisplay = wrap?.name === 'wrapNone'\r\n      ? (layout.anchorAttributes?.behindDoc === '1' || layout.anchorAttributes?.behindDoc === 'true' ? 'float-bottom' : 'float-top')\r\n      : 'surround'\r\n  }\r\n}\r\n\r\n/** 用户调整图片时同时更新 Java 写回使用的几何结构。 */\r\nexport function updateImageLayout(image: IImageElement, changes: {\r\n  width?: number; height?: number; rotate?: number; wrap?: IImageElement['imgDisplay']\r\n}): void {\r\n  const layout = image.imageLayout\r\n  if (!layout) return\r\n  const geometry = (name: string, namespace: string): IImageGeometry => ({ name, namespace, attributes: {}, children: [] })\r\n  const drawing = 'http://schemas.openxmlformats.org/drawingml/2006/main'\r\n  if (changes.width !== undefined || changes.height !== undefined || changes.rotate !== undefined) {\r\n    const transform = layout.transform ??= geometry('xfrm', drawing)\r\n    if (changes.rotate !== undefined) transform.attributes.rot = String(Math.round(changes.rotate * 60000))\r\n    if (changes.width !== undefined || changes.height !== undefined) {\r\n      let ext = transform.children.find(child => child.name === 'ext')\r\n      if (!ext) { ext = geometry('ext', drawing); transform.children.push(ext) }\r\n      if (changes.width !== undefined) ext.attributes.cx = String(Math.round(changes.width * 9525))\r\n      if (changes.height !== undefined) ext.attributes.cy = String(Math.round(changes.height * 9525))\r\n    }\r\n  }\r\n  if (changes.wrap !== undefined) {\r\n    layout.anchored = changes.wrap !== 'inline' && changes.wrap !== 'block'\r\n    layout.anchorAttributes ??= {}\r\n    layout.anchorAttributes.behindDoc = changes.wrap === 'float-bottom' ? '1' : '0'\r\n    layout.positioning = (layout.positioning ?? []).filter(node => !node.name.startsWith('wrap'))\r\n    if (layout.anchored) {\r\n      const wrap = geometry(changes.wrap === 'surround' ? 'wrapSquare' : 'wrapNone', 'http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing')\r\n      if (changes.wrap === 'surround') wrap.attributes.wrapText = 'bothSides'\r\n      layout.positioning.push(wrap)\r\n    }\r\n  }\r\n  applyImageLayout(image)\r\n}\r\n\r\n/**\r\n * 归一化 pageBreak 节点：补全 value 默认值为 'manual' 并应用段落样式。\r\n * @param node pageBreak 节点\r\n * @param ctx 格式化上下文\r\n */\r\nfunction normalizePageBreak(node: IElement, ctx: FormatTreeContext): void {\r\n  const anyNode = node as unknown as Record<string, unknown>\r\n  if (anyNode.value == null) throw new TypeError('pageBreak.value 缺失，必须由解析来源提供')\r\n  applyParagraphStyleId(node, ctx)\r\n}\r\n\r\n/**\r\n * 归一化 control 节点：确保 control 配置存在，同步显示文本，递归 valueList。\r\n * @param node control 节点\r\n * @param ctx 格式化上下文\r\n */\r\nfunction normalizeControl(node: IControlElement, ctx: FormatTreeContext): void {\r\n  if (!node.control || typeof node.control !== 'object') return\r\n  node.value = computeControlDisplayValue(node.control, node.dataValue)\r\n  applyParagraphStyleId(node, ctx)\r\n  if (Array.isArray(node.valueList)) {\r\n    ctx._pathStack?.push('valueList')\r\n    formatElementTree(node.valueList, ctx)\r\n    ctx._pathStack?.pop()\r\n  }\r\n}\r\n\r\n/**\r\n * 应用段落样式表：当节点引用了 paragraphStyleId 时，将样式字段填入节点未显式设置的字段。\r\n * @param node 当前节点\r\n * @param ctx 格式化上下文\r\n */\r\nfunction applyParagraphStyleId(node: IElement, ctx: FormatTreeContext): void {\r\n  if (!ctx.styles) return\r\n  const styleId = (node as unknown as { paragraphStyleId?: string }).paragraphStyleId\r\n  if (!styleId) return\r\n  const style = ctx.styles[styleId]\r\n  if (!style) return\r\n  const anyNode = node as unknown as Record<string, unknown>\r\n  const indentationBaseline = anyNode.paragraphIndentationBaseline as Record<string, number | null> | undefined\r\n  // 只在字段未显式设置时应用\r\n  for (const key of Object.keys(style)) {\r\n    if (key === 'id' || key === 'name' || key === 'basedOn') continue\r\n    const axis = key === 'paragraphIndentLeft' ? 'left'\r\n      : key === 'paragraphIndentRight' ? 'right'\r\n      : key === 'paragraphFirstLineIndent' ? 'firstLine' : undefined\r\n    // 后端基线已解析过样式继承；null 也是结果，不能再从原始样式回填。\r\n    if (axis && indentationBaseline && Object.prototype.hasOwnProperty.call(indentationBaseline, axis)) continue\r\n    if (anyNode[key] == null) anyNode[key] = (style as unknown as Record<string, unknown>)[key]\r\n  }\r\n}\r\n\r\n/**\r\n * 将容器上定义的段落级属性下沉到子 runs（子未显式指定时）。\r\n * 只处理段落级字段，不动 font/size/bold 等 run 级属性。\r\n */\r\nfunction inheritParagraphAttrsToChildren(container: ITitleElement | IListElement): void {\r\n  const PARA_KEYS = [\r\n    'rowFlex',\r\n    'paragraphFrame',\r\n    'paragraphStyleId',\r\n    'paragraphFirstLineIndent',\r\n    'paragraphIndentLeft',\r\n    'paragraphSpacingBefore',\r\n    'paragraphSpacingAfter',\r\n    'lineHeight',\r\n    'lineHeightRule'\r\n  ] as const\r\n  const containerAny = container as unknown as Record<string, unknown>\r\n  for (const child of container.valueList) {\r\n    const childAny = child as unknown as Record<string, unknown>\r\n    for (const key of PARA_KEYS) {\r\n      if (containerAny[key] != null && childAny[key] == null) {\r\n        childAny[key] = containerAny[key]\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\n/**\r\n * 将收集到的 bookmarkMarker 列表配对为 IBookmark[]。\r\n * 同名 start/end 配对，范围落在实际内容上，不把零宽标记作为选区文字。\r\n */\r\nexport function pairBookmarkMarkers(\r\n  markers: { name: string; position: string; path: Path }[],\r\n  elements: IElement[]\r\n): IBookmark[] {\r\n  const leaves: { node: IElement; path: Path }[] = []\r\n  const indices = new Map<string, number>()\r\n  walkTree(elements, (node, { path }) => {\r\n    if (isParagraphContainer(node) || isTable(node)) return\r\n    indices.set(JSON.stringify(path), leaves.length)\r\n    leaves.push({ node, path })\r\n  })\r\n  const isContent = (node: IElement): boolean =>\r\n    !node.extension?.bookmarkMarker && !node.extension?.fieldMarker &&\r\n    (node.type !== 'text' || (!!node.value && !/^[\\u200B\\uFEFF]+$/.test(node.value)))\r\n  const startMap = new Map<string, Path>()\r\n  const bookmarks: IBookmark[] = []\r\n  for (const m of markers) {\r\n    if (m.position === 'start') {\r\n      startMap.set(m.name, m.path)\r\n    } else if (m.position === 'end') {\r\n      const startPath = startMap.get(m.name)\r\n      if (startPath) {\r\n        const start = indices.get(JSON.stringify(startPath))\r\n        const end = indices.get(JSON.stringify(m.path))\r\n        let first: typeof leaves[number] | undefined\r\n        let last: typeof leaves[number] | undefined\r\n        if (start !== undefined && end !== undefined) {\r\n          for (let index = start + 1; index < end; index++) {\r\n            if (!isContent(leaves[index].node)) continue\r\n            first ??= leaves[index]\r\n            last = leaves[index]\r\n          }\r\n        }\r\n        const anchor = { path: first?.path ?? startPath, offset: 0 }\r\n        bookmarks.push({\r\n          name: m.name,\r\n          range: {\r\n            anchor,\r\n            focus: last\r\n              ? { path: last.path, offset: last.node.type === 'text' ? last.node.value.length : 1 }\r\n              : { ...anchor }\r\n          },\r\n          collapsed: !first,\r\n          hidden: m.name.startsWith('_')\r\n        })\r\n        startMap.delete(m.name)\r\n      }\r\n    }\r\n  }\r\n  return bookmarks\r\n}\r\n","/**\r\n * VerveDocs Schema —— 段落解析（辅助 view 层）\r\n *\r\n * 段落切分：将同层的 elements 按\"段落分隔\"划分成段落数组。\r\n * 规则：\r\n *  - title/list/table/image/pageBreak 各自独立成段。\r\n *  - 连续 text 归到同一段，遇到\"段落终止符\"或块级节点即断段。\r\n *  - 段落容器（title/list）自身即为一段，其内 valueList 作为 runs。\r\n *\r\n * 段落终止符：docx-parser 在每个段落末尾插入一个仅由零宽字符\r\n * (`\\u200B` / `\\uFEFF`) 组成的 text run 作为段落结束标记。\r\n *  - 遇到该标记就切段（不并入下一段）。\r\n *  - 空段落载体（`{ type:'text', value:'', ...段落属性 }`）保留为一段的 run，\r\n *    以维持视觉空行与其行高等属性。\r\n *  - 若某段仅由终止符组成（无任何载体），才作为块间分隔符跳过。\r\n */\r\n\r\nimport type { IElement } from './types'\r\nimport { BLOCK_LEVEL_TYPES } from './constants'\r\n\r\nexport interface IParagraphGroup {\r\n  /** 段落类型：normal / title / list / table / image / pageBreak / separator / block */\r\n  kind: 'normal' | 'title' | 'list' | 'table' | 'image' | 'pageBreak' | 'separator' | 'block'\r\n  /** 段落对应的父节点（当 kind !== 'normal' 时即为该节点自身；kind='normal' 时为 null） */\r\n  block: IElement | null\r\n  /** 段落包含的顶层节点在父数组中的索引区间 [start, end)（含 start 不含 end） */\r\n  start: number\r\n  end: number\r\n  /** 段落使用的 runs（对 normal 是原数组切片，对 title/list 是 valueList 切片） */\r\n  runs: IElement[]\r\n  /** runs 在原数组中的起始索引（对 title/list valueList 切片，用于 path 计算；normal 默认 0） */\r\n  runStartIndex?: number\r\n}\r\n\r\n/** 判断某个 text run 是否为\"段落终止符\"（仅由零宽字符构成的 text） */\r\nfunction isParagraphTerminator(el: IElement): boolean {\r\n  if (el.type !== 'text' || el.extension?.bookmarkMarker) return false\r\n  const v = (el as unknown as { value?: string }).value ?? ''\r\n  if (!v) return false\r\n  return /^[\\u200B\\uFEFF]+$/.test(v)\r\n}\r\n\r\n/** Some imports omit the separator after a bookmark marker at the end of a paragraph. */\r\nfunction endsBookmarkParagraph(previous: IElement, next: IElement): boolean {\r\n  return !!previous.extension?.bookmarkMarker &&\r\n    !!previous.sourceParagraphId && !!next.sourceParagraphId &&\r\n    previous.sourceParagraphId !== next.sourceParagraphId\r\n}\r\n\r\n/**\r\n * 将同层 elements 切分为段落数组。\r\n * - 块级节点（title/list/table/image/pageBreak/separator）各自独立成段\r\n * - 普通连续 text 归到同一段，遇到段落终止符或块级节点即断段\r\n * - title/list 内部按零宽分隔符切段以支持段内换行\r\n * @param elements 顶层元素数组\r\n * @returns 段落分组数组\r\n */\r\nexport function splitParagraphs(elements: IElement[]): IParagraphGroup[] {\r\n  const out: IParagraphGroup[] = []\r\n  let i = 0\r\n  while (i < elements.length) {\r\n    const node = elements[i]\r\n    if (node.type === 'columnBreak') {\r\n      out.push({ kind: 'pageBreak', block: node, start: i, end: i + 1, runs: [] })\r\n      i++\r\n      continue\r\n    }\r\n    if (BLOCK_LEVEL_TYPES.has(node.type)) {\r\n      const kind = node.type as IParagraphGroup['kind']\r\n      const valueList = (node as unknown as { valueList?: IElement[] }).valueList ?? []\r\n      // title/list 内部也按零宽分隔符切段（与普通段落一致），支持段内换行\r\n      if (kind === 'title' || kind === 'list') {\r\n        const segs = splitValueList(valueList)\r\n        for (const { runs, startIndex } of segs) {\r\n          out.push({ kind, block: node, start: i, end: i + 1, runs, runStartIndex: startIndex })\r\n        }\r\n      } else {\r\n        out.push({ kind, block: node, start: i, end: i + 1, runs: valueList })\r\n      }\r\n      i++\r\n      continue\r\n    }\r\n    // 普通段落：收集非块级节点，遇到段落终止符即切段\r\n    const start = i\r\n    while (i < elements.length && !BLOCK_LEVEL_TYPES.has(elements[i].type) && elements[i].type !== 'columnBreak') {\r\n      if (i > start && endsBookmarkParagraph(elements[i - 1], elements[i])) break\r\n      if (isParagraphTerminator(elements[i])) {\r\n        i++ // 消费终止符\r\n        break\r\n      }\r\n      i++\r\n    }\r\n    // 段内 runs 保留原切片（含终止符），以保证 ri 与原 elements 索引对齐；\r\n    // 终止符在排版时跳过（不产出 inline），但占位以保持索引一致。\r\n    const runs = elements.slice(start, i)\r\n    // 若段落仅有终止符（无任何载体/内容），视为块间分隔符，跳过\r\n    if (runs.every(isParagraphTerminator)) continue\r\n    out.push({ kind: 'normal', block: null, start, end: i, runs })\r\n  }\r\n  return out\r\n}\r\n\r\n/** 将 valueList 按零宽分隔符切成多段（与顶层 elements 切段逻辑一致） */\r\nfunction splitValueList(valueList: IElement[]): { runs: IElement[]; startIndex: number }[] {\r\n  const result: { runs: IElement[]; startIndex: number }[] = []\r\n  let vi = 0\r\n  while (vi < valueList.length) {\r\n    const vStart = vi\r\n    while (vi < valueList.length) {\r\n      if (vi > vStart && endsBookmarkParagraph(valueList[vi - 1], valueList[vi])) break\r\n      if (isParagraphTerminator(valueList[vi])) {\r\n        vi++\r\n        break\r\n      }\r\n      vi++\r\n    }\r\n    const runs = valueList.slice(vStart, vi)\r\n    if (runs.every(isParagraphTerminator)) continue\r\n    result.push({ runs, startIndex: vStart })\r\n  }\r\n  if (result.length === 0) {\r\n    result.push({ runs: [], startIndex: 0 })\r\n  }\r\n  return result\r\n}\r\n","import type { IDocxDocumentMeta, IElement, IPosition } from './types'\r\nimport { splitParagraphs } from './paragraph'\r\nimport { cloneTree, comparePosition, getByPath, isParagraphContainer, isTable, walkTree } from './walk'\r\n\r\ninterface BookmarkBoundary {\r\n  offset: number\r\n  name: string\r\n  position: 'start' | 'end'\r\n}\r\n\r\n/** Convert editor-only state to the document protocol accepted by DOCX writers. */\r\nexport function toDocxExportDocument(document: IDocxDocumentMeta): IDocxDocumentMeta {\r\n  const result = cloneTree(document)\r\n  const { bookmarks, contentZones } = result\r\n  delete result.bookmarks\r\n  delete result.contentZones\r\n  delete result.meta\r\n  result.header ??= contentZones?.header\r\n  result.footer ??= contentZones?.footer\r\n\r\n  // 只转换导出副本：Java 元素协议不接受顶层 indentHanging，\n  // 悬挂缩进以负的首行缩进传递；listNumbering 内同名字段仍是合法协议。\n  const normalizeIndentation = (elements: IElement[]) => {\n    walkTree(elements, node => {\n      const run = node as IElement & { indentHanging?: number }\n      const hanging = run.indentHanging\n      if (typeof hanging === 'number' && Number.isFinite(hanging) && hanging >= 0) {\n        if (hanging > 0 || run.paragraphFirstLineIndent == null) {\n          run.paragraphFirstLineIndent = -hanging\n        }\n      }\n      delete run.indentHanging\n    })\n  }\n\n  // 将渲染层的链接默认样式写入导出副本，目录链接仍沿用自己的样式。\r\n  const normalizeHyperlinks = (elements: IElement[]) => {\r\n    walkTree(elements, node => {\r\n      if (node.type !== 'hyperlink' ||\r\n        (node.extension?.toc as { role?: string } | undefined)?.role === 'entry') return\r\n      node.color ??= '#0000FF'\r\n      node.underline ??= true\r\n      const children = (node as IElement & { valueList?: IElement[] }).valueList\r\n      for (const run of children ?? []) {\r\n        if (run.type !== 'text') continue\r\n        run.color ??= node.color\r\n        run.underline ??= node.underline\r\n      }\r\n    })\r\n  }\r\n  for (const elements of [result.elements, result.header, result.footer,\r\n    ...Object.values(result.headerFooterParts ?? {})]) {\r\n    if (elements) {\n      normalizeIndentation(elements)\n      normalizeHyperlinks(elements)\n    }\n  }\r\n\r\n  const normalizeParagraphRuns = (elements: IElement[]) => {\r\n    for (const group of splitParagraphs(elements)) {\r\n      if (group.kind === 'normal') {\r\n        let first = true\r\n        for (const run of group.runs) {\r\n          if (run.extension?.bookmarkMarker || (run.type === 'text' && /^[\\u200B\\uFEFF]+$/.test(run.value))) continue\r\n          if (first) {\r\n            first = false\r\n            continue\r\n          }\r\n          delete run.paragraphStyleId\r\n          delete run.paragraphMarkSize\r\n          delete run.paragraphMarkUnderline\r\n          delete run.rowFlex\r\n          delete run.paragraphFrame\r\n          delete run.paragraphFirstLineIndent\r\n          delete run.paragraphIndentLeft\r\n          delete run.paragraphIndentRight\r\n          delete run.paragraphSpacingBefore\r\n          delete run.paragraphSpacingAfter\r\n          delete run.lineHeight\r\n          delete run.lineHeightRule\r\n          delete run.snapToGrid\r\n          delete (run as IElement & { paragraphColor?: string }).paragraphColor\r\n        }\r\n      }\r\n    }\r\n    for (const node of elements) {\r\n      if (isParagraphContainer(node)) normalizeParagraphRuns(node.valueList)\r\n      else if (isTable(node)) {\r\n        for (const row of node.trList) {\r\n          for (const cell of row.tdList) normalizeParagraphRuns(cell.value)\r\n        }\r\n      } else if (Array.isArray((node as { valueList?: unknown }).valueList)) {\r\n        normalizeParagraphRuns((node as { valueList: IElement[] }).valueList)\r\n      }\r\n    }\r\n  }\r\n  normalizeParagraphRuns(result.elements)\r\n  if (result.header) normalizeParagraphRuns(result.header)\r\n  if (result.footer) normalizeParagraphRuns(result.footer)\r\n  for (const elements of Object.values(result.headerFooterParts ?? {})) normalizeParagraphRuns(elements)\r\n\r\n  if (!bookmarks) return result\r\n\r\n  // Resolve all paths before splitting runs so overlapping ranges keep their positions.\r\n  const boundaries = new Map<IElement, BookmarkBoundary[]>()\r\n  const resolvePoint = (point: IPosition) => {\r\n    const node = getByPath(result.elements, point.path)\r\n    const length = node?.extension?.bookmarkMarker ? 0 : node?.type === 'text' ? node.value.length : 1\r\n    return node && Number.isInteger(point.offset) && point.offset >= 0 && point.offset <= length ? node : null\r\n  }\r\n  const addBoundary = (name: string, position: BookmarkBoundary['position'], point: IPosition) => {\r\n    const node = resolvePoint(point)\r\n    if (!node) {\r\n      throw new Error(`Invalid bookmark position: ${name}`)\r\n    }\r\n    const entries = boundaries.get(node) ?? []\r\n    entries.push({ name, position, offset: point.offset })\r\n    boundaries.set(node, entries)\r\n  }\r\n  for (const bookmark of bookmarks) {\r\n    let { anchor, focus } = bookmark.range\r\n    if (!resolvePoint(anchor) || !resolvePoint(focus)) {\r\n      const starts: IPosition[] = []\r\n      const ends: IPosition[] = []\r\n      walkTree(result.elements, (node, { path }) => {\r\n        const marker = node.extension?.bookmarkMarker as { name?: string; position?: string } | undefined\r\n        if (marker?.name !== bookmark.name) return\r\n        if (marker.position === 'start') starts.push({ path, offset: 0 })\r\n        if (marker.position === 'end') ends.push({ path, offset: 0 })\r\n      })\r\n      if (starts.length !== 1 || ends.length !== 1 || comparePosition(starts[0], ends[0]) >= 0) {\r\n        throw new Error(`Invalid bookmark position: ${bookmark.name}`)\r\n      }\r\n      // Recover both endpoints together; never mix a stale range with imported markers.\r\n      anchor = starts[0]\r\n      focus = ends[0]\r\n    }\r\n    const [start, end] = comparePosition(anchor, focus) <= 0 ? [anchor, focus] : [focus, anchor]\r\n    addBoundary(bookmark.name, 'start', start)\r\n    addBoundary(bookmark.name, 'end', end)\r\n  }\r\n\r\n  const marker = (boundary: BookmarkBoundary): IElement => ({\r\n    type: 'text',\r\n    value: '',\r\n    extension: { bookmarkMarker: { name: boundary.name, position: boundary.position } }\r\n  })\r\n  const convert = (elements: IElement[]): IElement[] => elements.flatMap(node => {\r\n    if (isParagraphContainer(node)) {\r\n      node.valueList = convert(node.valueList)\r\n    } else if (isTable(node)) {\r\n      for (const row of node.trList) {\r\n        for (const cell of row.tdList) cell.value = convert(cell.value)\r\n      }\r\n    }\r\n    const entries = boundaries.get(node)?.sort((a, b) => a.offset - b.offset) ?? []\r\n    // Runtime ranges are authoritative; replace imported markers instead of duplicating them.\r\n    if (node.extension?.bookmarkMarker) return entries.map(marker)\r\n    if (!entries.length) return [node]\r\n    if (node.type !== 'text') {\r\n      return [\r\n        ...entries.filter(entry => entry.offset === 0).map(marker),\r\n        node,\r\n        ...entries.filter(entry => entry.offset !== 0).map(marker)\r\n      ]\r\n    }\r\n    const parts: IElement[] = []\r\n    let offset = 0\r\n    for (const entry of entries) {\r\n      if (entry.offset > offset) parts.push({ ...node, value: node.value.slice(offset, entry.offset) })\r\n      parts.push(marker(entry))\r\n      offset = entry.offset\r\n    }\r\n    if (offset < node.value.length || !node.value.length) {\r\n      parts.push({ ...node, value: node.value.slice(offset) })\r\n    }\r\n    return parts\r\n  })\r\n  result.elements = convert(result.elements)\r\n  return result\r\n}\r\n","import type { IElement, ITextElement } from './types'\nimport { walkTree } from './walk'\nimport { splitParagraphs } from './paragraph'\n\nlet pageNumberSequence = 0\n\n/** Word 页码域的数字格式，与编辑器样式保持一致。 */\nexport const PAGE_NUMBER_FORMATS: Record<string, string> = {\n  ARABIC: '1, 2, 3 ...',\n  ROMAN: 'I, II, III ...',\n  roman: 'i, ii, iii ...',\n  ALPHABETIC: 'A, B, C ...',\n  alphabetic: 'a, b, c ...',\n  CHINESENUM1: '一, 二, 三 ...',\n  CHINESENUM2: '壹, 贰, 叁 ...',\n  DBNUM1: '一, 二, 三 ...',\n  DBNUM2: '壹, 贰, 叁 ...',\n  CIRCLE: '①, ②, ③ ...',\n  ZODIAC1: '甲, 乙, 丙 ...',\n  ZODIAC2: '子, 丑, 寅 ...',\n  ORDINAL: '1st, 2nd, 3rd ...',\n  CardText: 'One, Two, Three ...',\n  OrdText: 'First, Second, Third ...'\n}\n\nexport interface PageField {\n  type: 'PAGE' | 'NUMPAGES' | 'SECTIONPAGES'\n  instruction: string\n  parent: IElement[]\n  start: number\n  end: number\n  separator: IElement\n  results: IElement[]\n}\n\n/** 配对复杂域与简单域的统一标记，不把 PAGEREF 或普通数字误认成页码。 */\nexport function collectPageFields(elements: IElement[]): PageField[] {\n  const parents = new Set<IElement[]>([elements])\n  walkTree(elements, (_, ctx) => {\n    if (Array.isArray(ctx.parent)) parents.add(ctx.parent)\n  })\n  const fields: PageField[] = []\n  for (const parent of parents) {\n    const stack: { start: number; instruction: string; separator?: IElement; results: IElement[] }[] = []\n    parent.forEach((node, index) => {\n      const marker = node.extension?.fieldMarker as { kind?: string; value?: string } | undefined\n      if (marker?.kind === 'boundary' && marker.value === 'begin') {\n        stack.push({ start: index, instruction: '', results: [] })\n        return\n      }\n      const current = stack[stack.length - 1]\n      if (!current) return\n      if (marker?.kind === 'instruction') {\n        current.instruction += marker.value ?? ''\n      } else if (marker?.kind === 'boundary' && marker.value === 'separate') {\n        current.separator = node\n      } else if (marker?.kind === 'boundary' && marker.value === 'end') {\n        stack.pop()\n        const type = /^\\s*(PAGE|NUMPAGES|SECTIONPAGES)\\b/i.exec(current.instruction)?.[1].toUpperCase()\n        // 嵌套在 IF 等域中的页码不能脱离外层结果独立求值。\n        if (type && current.separator && stack.length === 0) {\n          fields.push({ ...current, type: type as PageField['type'], parent, end: index + 1, separator: current.separator })\n        }\n      } else if (!marker && current.separator && node.type === 'text' && !node.extension?.bookmarkMarker) {\n        current.results.push(node)\n      }\n    })\n  }\n  return fields\n}\n\n/** 从域开关读取数字样式；大小写区分罗马数字和英文字母格式。 */\nexport function getPageFieldStyle(field: PageField): string {\n  const explicit = field.results.find(run => typeof run.extension?.pageNumberStyle === 'string')\n  if (explicit) return String(explicit.extension!.pageNumberStyle)\n  for (const match of field.instruction.matchAll(/\\\\\\*\\s+([A-Za-z0-9]+)/g)) {\n    const style = PAGE_NUMBER_FORMATS[match[1]] ?? PAGE_NUMBER_FORMATS[match[1].toUpperCase()]\n    if (style) return style\n  }\n  return '1, 2, 3 ...'\n}\n\n/** 生成可导出的真实域，页码不再仅存在于 Canvas 覆盖层。 */\nfunction createPageNumberElements(style: string, template: IElement, position: 'left' | 'center' | 'right'): IElement[] {\n  const base = { ...template, type: 'text', rowFlex: position } as ITextElement\n  // 把前后缀和总页数视为同一个可更新对象，混排时再次修改也不会叠加。\n  const group = `page-number-${Date.now()}-${++pageNumberSequence}`\n  base.extension = { pageNumberGroup: group }\n  if (base.paragraphFrame) base.paragraphFrame = { ...base.paragraphFrame, xAlign: position }\n  base.paragraphFirstLineIndent = 0\n  base.paragraphIndentLeft = 0\n  base.paragraphIndentRight = 0\n  // Java 协议用 paragraphFirstLineIndent 表达悬挂缩进，不发送布局层字段。\n  delete (base as ITextElement & { indentHanging?: number }).indentHanging\n  const text = (value: string): IElement => ({ ...base, value })\n  const field = (type: 'PAGE' | 'NUMPAGES', numberStyle: string): IElement[] => {\n    const format = Object.entries(PAGE_NUMBER_FORMATS).find(([, value]) => value === numberStyle)?.[0] ?? 'ARABIC'\n    const marker = (kind: string, value: string): IElement => ({\n      ...base, value: '', extension: { ...base.extension, fieldMarker: { kind, value } }\n    })\n    return [\n      marker('boundary', 'begin'),\n      marker('instruction', ` ${type} \\\\* ${format} `),\n      marker('boundary', 'separate'),\n      { ...base, value: '1', extension: { ...base.extension, pageNumberStyle: numberStyle } },\n      marker('boundary', 'end')\n    ]\n  }\n  const chinese = style === '第一页' || style === '第一页共X页'\n  const numberStyle = chinese ? '一, 二, 三 ...' : '1, 2, 3 ...'\n  if (['第1页', '第1页共x页', '第一页', '第一页共X页'].includes(style)) {\n    return [\n      text('第'), ...field('PAGE', numberStyle), text('页'),\n      ...(['第1页共x页', '第一页共X页'].includes(style)\n        ? [text('共'), ...field('NUMPAGES', numberStyle), text('页')] : [])\n    ]\n  }\n  if (style === '1/x') return [...field('PAGE', numberStyle), text('/'), ...field('NUMPAGES', numberStyle)]\n  if (style === '-1-, -2-, -3- ...' || style === '—1—, —2—, —3— ...') {\n    const dash = style.startsWith('-') ? '-' : '—'\n    return [text(dash), ...field('PAGE', numberStyle), text(dash)]\n  }\n  return field('PAGE', style)\n}\n\n/** 原位更新当前区域的页码段落；混排段落只替换域，保留业务文字与书签。 */\nexport function updatePageFields(elements: IElement[], style: string | undefined, position: 'left' | 'center' | 'right'): void {\n  const fields = collectPageFields(elements)\n  const parents = new Set(fields.filter(field => field.type === 'PAGE').map(field => field.parent))\n  for (const parent of parents) {\n    for (const group of splitParagraphs(parent).reverse()) {\n      if (group.kind !== 'normal') continue\n      const pageFields = fields.filter(field => field.parent === parent && field.start >= group.start && field.end <= group.end)\n      if (!pageFields.some(field => field.type === 'PAGE')) continue\n      for (const run of group.runs) {\n        run.rowFlex = position\n        if (run.paragraphFrame) run.paragraphFrame = { ...run.paragraphFrame, xAlign: position }\n      }\n      // 仅改变位置时保留原有前后缀、总页数域和数字格式。\n      if (style === undefined) continue\n      const insideField = (index: number) => pageFields.some(field => index >= field.start && index < field.end)\n      const standalone = group.runs.every((run, index) => !run.extension?.bookmarkMarker && (insideField(group.start + index) ||\n        run.type === 'text' && !run.extension?.bookmarkMarker && !run.extension?.fieldMarker &&\n        /^(?:[\\s\\u200B\\uFEFF第页共/()（）\\-—]|Page|of)*$/i.test(String(run.value ?? ''))))\n      const first = pageFields.find(field => field.type === 'PAGE')!\n      const template = first.results[0] ?? first.separator\n      if (standalone) {\n        const last = group.runs[group.runs.length - 1]\n        const terminator = last?.type === 'text' && /^[\\u200B\\uFEFF]+$/.test(last.value) ? [last] : []\n        parent.splice(group.start, group.end - group.start, ...createPageNumberElements(style, template, position), ...terminator)\n      } else {\n        for (const field of pageFields.filter(field => field.type === 'PAGE').sort((a, b) => b.start - a.start)) {\n          let start = field.start\n          let end = field.end\n          const groupId = parent[start].extension?.pageNumberGroup\n          if (groupId) {\n            while (start > group.start && parent[start - 1].extension?.pageNumberGroup === groupId) start--\n            while (end < parent.length && parent[end].extension?.pageNumberGroup === groupId) end++\n          }\n          const bookmarks = parent.slice(start, end).filter(run => run.extension?.bookmarkMarker)\n          const isStart = (run: IElement) => (run.extension?.bookmarkMarker as { position?: string })?.position === 'start'\n          parent.splice(start, end - start,\n            ...bookmarks.filter(isStart),\n            ...createPageNumberElements(style, field.results[0] ?? field.separator, position),\n            ...bookmarks.filter(run => !isStart(run)))\n        }\n      }\n    }\n  }\n  if (parents.size === 0) {\n    if (elements.length === 1 && elements[0].type === 'text' && !elements[0].value &&\n      !elements[0].extension && !elements[0].paragraphBorder) elements.splice(0, 1)\n    const last = elements[elements.length - 1]\n    if (elements.length && !(last?.type === 'text' && /^[\\u200B\\uFEFF]+$/.test(last.value))) {\n      elements.push({ type: 'text', value: '\\u200B' })\n    }\n    elements.push(...createPageNumberElements(style ?? '1, 2, 3 ...', { type: 'text', value: '', size: 12 }, position))\n  }\n}\n","/**\r\n * VerveDocs Schema —— 快捷键类型与工具\r\n *\r\n * 定义键盘按键映射常量、快捷键注册接口及平台判断工具函数。\r\n */\r\n\r\n/** 键盘按键映射常量（使用 KeyboardEvent.key 值） */\r\nexport const KeyMap = {\r\n  A: 'a',\r\n  B: 'b',\r\n  C: 'c',\r\n  D: 'd',\r\n  E: 'e',\r\n  F: 'f',\r\n  G: 'g',\r\n  H: 'h',\r\n  I: 'i',\r\n  J: 'j',\r\n  K: 'k',\r\n  L: 'l',\r\n  M: 'm',\r\n  N: 'n',\r\n  O: 'o',\r\n  P: 'p',\r\n  Q: 'q',\r\n  R: 'r',\r\n  S: 's',\r\n  T: 't',\r\n  U: 'u',\r\n  V: 'v',\r\n  W: 'w',\r\n  X: 'x',\r\n  Y: 'y',\r\n  Z: 'z',\r\n  ZERO: '0',\r\n  ONE: '1',\r\n  TWO: '2',\r\n  THREE: '3',\r\n  FOUR: '4',\r\n  FIVE: '5',\r\n  SIX: '6',\r\n  SEVEN: '7',\r\n  EIGHT: '8',\r\n  NINE: '9',\r\n  MINUS: '-',\r\n  EQUAL: '=',\r\n  LEFT_BRACKET: '[',\r\n  RIGHT_BRACKET: ']',\r\n  BACKSLASH: '\\\\',\r\n  SEMICOLON: ';',\r\n  QUOTE: \"'\",\r\n  COMMA: ',',\r\n  PERIOD: '.',\r\n  SLASH: '/',\r\n  LEFT_ANGLE_BRACKET: '<',\r\n  RIGHT_ANGLE_BRACKET: '>',\r\n  ENTER: 'Enter',\r\n  SPACE: ' ',\r\n  TAB: 'Tab',\r\n  BACKSPACE: 'Backspace',\r\n  DELETE: 'Delete',\r\n  ESCAPE: 'Escape',\r\n  ARROW_LEFT: 'ArrowLeft',\r\n  ARROW_RIGHT: 'ArrowRight',\r\n  ARROW_UP: 'ArrowUp',\r\n  ARROW_DOWN: 'ArrowDown'\r\n} as const\r\n\r\n/** 快捷键注册配置接口 */\r\nexport interface IRegisterShortcut {\r\n  /** 按键值（对应 KeyboardEvent.key） */\r\n  key: string\r\n  /** Ctrl/Cmd 组合键（跨平台修饰键） */\r\n  mod?: boolean\r\n  /** Ctrl 键 */\r\n  ctrl?: boolean\r\n  /** Meta（Cmd）键 */\r\n  meta?: boolean\r\n  /** Shift 键 */\r\n  shift?: boolean\r\n  /** Alt 键 */\r\n  alt?: boolean\r\n  /** 是否为全局快捷键（在 document 上监听） */\r\n  isGlobal?: boolean\r\n  /** 是否禁用 */\r\n  disable?: boolean\r\n  /** 命中时执行的回调 */\r\n  callback?: (command: any) => void\r\n}\r\n\r\n/** 判断当前运行环境是否为 Apple 平台（macOS / iOS） */\r\nexport const isApple =\r\n  typeof navigator !== 'undefined' &&\r\n  /Mac|iPod|iPhone|iPad/.test(navigator.platform || navigator.userAgent || '')\r\n\r\n/**\r\n * 判断键盘事件是否按下了跨平台修饰键（macOS 为 Cmd，其他为 Ctrl）\r\n * @param evt 键盘事件\r\n * @returns 是否按下了修饰键\r\n */\r\nexport function isMod(evt: KeyboardEvent): boolean {\r\n  return isApple ? evt.metaKey : evt.ctrlKey\r\n}","'use strict';\n\nvar has = Object.prototype.hasOwnProperty\n  , prefix = '~';\n\n/**\n * Constructor to create a storage for our `EE` objects.\n * An `Events` instance is a plain object whose properties are event names.\n *\n * @constructor\n * @private\n */\nfunction Events() {}\n\n//\n// We try to not inherit from `Object.prototype`. In some engines creating an\n// instance in this way is faster than calling `Object.create(null)` directly.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// character to make sure that the built-in object properties are not\n// overridden or used as an attack vector.\n//\nif (Object.create) {\n  Events.prototype = Object.create(null);\n\n  //\n  // This hack is needed because the `__proto__` property is still inherited in\n  // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.\n  //\n  if (!new Events().__proto__) prefix = false;\n}\n\n/**\n * Representation of a single event listener.\n *\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} [once=false] Specify if the listener is a one-time listener.\n * @constructor\n * @private\n */\nfunction EE(fn, context, once) {\n  this.fn = fn;\n  this.context = context;\n  this.once = once || false;\n}\n\n/**\n * Add a listener for a given event.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} once Specify if the listener is a one-time listener.\n * @returns {EventEmitter}\n * @private\n */\nfunction addListener(emitter, event, fn, context, once) {\n  if (typeof fn !== 'function') {\n    throw new TypeError('The listener must be a function');\n  }\n\n  var listener = new EE(fn, context || emitter, once)\n    , evt = prefix ? prefix + event : event;\n\n  if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;\n  else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);\n  else emitter._events[evt] = [emitter._events[evt], listener];\n\n  return emitter;\n}\n\n/**\n * Clear event by name.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} evt The Event name.\n * @private\n */\nfunction clearEvent(emitter, evt) {\n  if (--emitter._eventsCount === 0) emitter._events = new Events();\n  else delete emitter._events[evt];\n}\n\n/**\n * Minimal `EventEmitter` interface that is molded against the Node.js\n * `EventEmitter` interface.\n *\n * @constructor\n * @public\n */\nfunction EventEmitter() {\n  this._events = new Events();\n  this._eventsCount = 0;\n}\n\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @public\n */\nEventEmitter.prototype.eventNames = function eventNames() {\n  var names = []\n    , events\n    , name;\n\n  if (this._eventsCount === 0) return names;\n\n  for (name in (events = this._events)) {\n    if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n  }\n\n  if (Object.getOwnPropertySymbols) {\n    return names.concat(Object.getOwnPropertySymbols(events));\n  }\n\n  return names;\n};\n\n/**\n * Return the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Array} The registered listeners.\n * @public\n */\nEventEmitter.prototype.listeners = function listeners(event) {\n  var evt = prefix ? prefix + event : event\n    , handlers = this._events[evt];\n\n  if (!handlers) return [];\n  if (handlers.fn) return [handlers.fn];\n\n  for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {\n    ee[i] = handlers[i].fn;\n  }\n\n  return ee;\n};\n\n/**\n * Return the number of listeners listening to a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Number} The number of listeners.\n * @public\n */\nEventEmitter.prototype.listenerCount = function listenerCount(event) {\n  var evt = prefix ? prefix + event : event\n    , listeners = this._events[evt];\n\n  if (!listeners) return 0;\n  if (listeners.fn) return 1;\n  return listeners.length;\n};\n\n/**\n * Calls each of the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Boolean} `true` if the event had listeners, else `false`.\n * @public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n  var evt = prefix ? prefix + event : event;\n\n  if (!this._events[evt]) return false;\n\n  var listeners = this._events[evt]\n    , len = arguments.length\n    , args\n    , i;\n\n  if (listeners.fn) {\n    if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n    switch (len) {\n      case 1: return listeners.fn.call(listeners.context), true;\n      case 2: return listeners.fn.call(listeners.context, a1), true;\n      case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n      case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n      case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n      case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n    }\n\n    for (i = 1, args = new Array(len -1); i < len; i++) {\n      args[i - 1] = arguments[i];\n    }\n\n    listeners.fn.apply(listeners.context, args);\n  } else {\n    var length = listeners.length\n      , j;\n\n    for (i = 0; i < length; i++) {\n      if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n      switch (len) {\n        case 1: listeners[i].fn.call(listeners[i].context); break;\n        case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n        case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n        case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;\n        default:\n          if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n            args[j - 1] = arguments[j];\n          }\n\n          listeners[i].fn.apply(listeners[i].context, args);\n      }\n    }\n  }\n\n  return true;\n};\n\n/**\n * Add a listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n  return addListener(this, event, fn, context, false);\n};\n\n/**\n * Add a one-time listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n  return addListener(this, event, fn, context, true);\n};\n\n/**\n * Remove the listeners of a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn Only remove the listeners that match this function.\n * @param {*} context Only remove the listeners that have this context.\n * @param {Boolean} once Only remove one-time listeners.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n  var evt = prefix ? prefix + event : event;\n\n  if (!this._events[evt]) return this;\n  if (!fn) {\n    clearEvent(this, evt);\n    return this;\n  }\n\n  var listeners = this._events[evt];\n\n  if (listeners.fn) {\n    if (\n      listeners.fn === fn &&\n      (!once || listeners.once) &&\n      (!context || listeners.context === context)\n    ) {\n      clearEvent(this, evt);\n    }\n  } else {\n    for (var i = 0, events = [], length = listeners.length; i < length; i++) {\n      if (\n        listeners[i].fn !== fn ||\n        (once && !listeners[i].once) ||\n        (context && listeners[i].context !== context)\n      ) {\n        events.push(listeners[i]);\n      }\n    }\n\n    //\n    // Reset the array, or remove it completely if we have no more listeners.\n    //\n    if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;\n    else clearEvent(this, evt);\n  }\n\n  return this;\n};\n\n/**\n * Remove all listeners, or those of the specified event.\n *\n * @param {(String|Symbol)} [event] The event name.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n  var evt;\n\n  if (event) {\n    evt = prefix ? prefix + event : event;\n    if (this._events[evt]) clearEvent(this, evt);\n  } else {\n    this._events = new Events();\n    this._eventsCount = 0;\n  }\n\n  return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Allow `EventEmitter` to be imported as module namespace.\n//\nEventEmitter.EventEmitter = EventEmitter;\n\n//\n// Expose the module.\n//\nif ('undefined' !== typeof module) {\n  module.exports = EventEmitter;\n}\n","/**\r\n * VerveDocs State —— EventBus\r\n *\r\n * 轻量事件总线，支持带类型的事件订阅。\r\n * 基于 eventemitter3 实现，保持 on/off/emit/clear API 不变。\r\n */\r\n\r\nimport { EventEmitter } from 'eventemitter3'\r\nimport type { EventHandler, EventBusMap } from '@vervedoc/docx-editor-schema'\r\n\r\n// 重新导出迁移至 schema 的跨包共享类型，保持 state 包 API 兼容\r\nexport type { EventHandler, EventBusMap } from '@vervedoc/docx-editor-schema'\r\n\r\n/**\r\n * 轻量事件总线\r\n *\r\n * 支持带类型的事件订阅与派发，泛型 M 描述事件名到 payload 类型的映射。\r\n * 默认泛型为 EventBusMap（用户交互事件），与 Listener（状态变更事件）职责区分。\r\n * 基于 eventemitter3 实现，保持 on/off/emit/clear API 不变。\r\n */\r\nexport class EventBus<M = EventBusMap> {\r\n  /** 底层事件分发器实例 */\r\n  private emitter = new EventEmitter()\r\n\r\n  /**\r\n   * 订阅指定事件\r\n   * @param event 事件名\r\n   * @param handler 事件处理器\r\n   * @returns 取消订阅函数，调用后移除该处理器\r\n   */\r\n  on<K extends keyof M>(event: K, handler: EventHandler<M[K]>): () => void {\r\n    const fn = handler as (...args: any[]) => void\r\n    const e = event as string\r\n    this.emitter.on(e, fn)\r\n    return () => this.emitter.off(e, fn)\r\n  }\r\n\r\n  /**\r\n   * 取消订阅指定事件\r\n   * @param event 事件名\r\n   * @param handler 需要移除的事件处理器\r\n   */\r\n  off<K extends keyof M>(event: K, handler: EventHandler<M[K]>): void {\r\n    this.emitter.off(event as string, handler as (...args: any[]) => void)\r\n  }\r\n\r\n  /**\r\n   * 派发指定事件\r\n   * @param event 事件名\r\n   * @param payload 事件载荷（void 类型事件可省略）\r\n   */\r\n  emit<K extends keyof M>(event: K, ...args: M[K] extends void ? [] : [payload: M[K]]): void {\r\n    this.emitter.emit(event as string, ...(args as any[]))\r\n  }\r\n\r\n  /**\r\n   * 移除所有事件的所有监听器\r\n   */\r\n  clear(): void {\r\n    this.emitter.removeAllListeners()\r\n  }\r\n}\r\n","/**\r\n * VerveDocs State —— Listener\r\n *\r\n * 编辑器生命周期/交互事件的回调注册中心。\r\n * 基于 eventemitter3 实现，保持 on/off/emit API 不变。\r\n *\r\n * 事件名统一使用 camelCase（如 'rangeChange'、'contentChange'）。\r\n * core 层在状态变更时主动 emit 事件，调用方通过 listener.on() 订阅。\r\n * 命名空间方法不带 on 前缀、不带 Change 后缀，以 Listener 结尾。\r\n */\r\n\r\nimport { EventEmitter } from 'eventemitter3'\r\nimport type {\r\n  IPosition,\r\n  IRange,\r\n  IRangeStyle,\r\n  IEditorAbility,\r\n  ListenerMap\r\n} from '@vervedoc/docx-editor-schema'\r\n\r\n// 重新导出迁移至 schema 的跨包共享类型，保持 state 包 API 兼容\r\nexport type { IRangeStyle, IEditorAbility, ListenerMap } from '@vervedoc/docx-editor-schema'\r\n\r\n/** 选区事件命名空间 */\r\nexport interface IRangeListener {\r\n  /** 选区变更（光标移动/选区改变） */\r\n  rangeListener(handler: (range: IRange | null) => void): () => void\r\n  /** 格式变更（bold/italic 等回显状态） */\r\n  formatListener(handler: (style: IRangeStyle) => void): () => void\r\n  /** 光标位置变更 */\r\n  positionListener(handler: (pos: IPosition | null) => void): () => void\r\n}\r\n\r\n/** 内容事件命名空间 */\r\nexport interface IContentListener {\r\n  /** 内容变更（文本增删/格式修改等） */\r\n  contentListener(handler: () => void): () => void\r\n  /** 文档保存完成 */\r\n  savedListener(handler: () => void): () => void\r\n}\r\n\r\n/** 能力事件命名空间 */\r\nexport interface IAbilityListener {\r\n  /** 编辑器能力变更（readonly/disabled/canUndo/canRedo） */\r\n  abilityListener(handler: (ability: IEditorAbility) => void): () => void\r\n}\r\n\r\n/** 页面事件命名空间 */\r\nexport interface IPageListener {\r\n  /** 缩放比例变更 */\r\n  pageScaleListener(handler: (scale: number) => void): () => void\r\n  /** 页面尺寸变更（宽高） */\r\n  pageSizeListener(handler: (size: { width: number; height: number }) => void): () => void\r\n  /** 总页数变更 */\r\n  pageCountListener(handler: (count: number) => void): () => void\r\n  /** 当前页码变更 */\r\n  currentPageNoListener(handler: (pageNo: number) => void): () => void\r\n}\r\n\r\n/** 目录事件命名空间 */\r\nexport interface ITocListener {\r\n  /** 目录变更 */\r\n  tocListener(handler: (toc: { id: string; level: number; name: string; number?: string }[]) => void): () => void\r\n}\r\n\r\n/** 区域事件命名空间 */\r\nexport interface IZoneListener {\r\n  /** 编辑区域切换（正文/页眉/页脚） */\r\n  zoneListener(handler: (zone: 'main' | 'header' | 'footer') => void): () => void\r\n}\r\n\r\n/** 生命周期事件命名空间 */\r\nexport interface ILifecycleListener {\r\n  /** 编辑器获得焦点 */\r\n  focusListener(handler: () => void): () => void\r\n  /** 编辑器失去焦点 */\r\n  blurListener(handler: () => void): () => void\r\n  /** 渲染完成后触发（各组件订阅此事件执行渲染联动） */\r\n  afterRenderListener(handler: () => void): () => void\r\n}\r\n\r\n/** 请求事件命名空间（右键菜单等触发的插入请求） */\r\nexport interface IRequestListener {\r\n  /** 请求插入图片 */\r\n  requestInsertImageListener(handler: () => void): () => void\r\n  /** 请求插入超链接 */\r\n  requestInsertHyperlinkListener(handler: () => void): () => void\r\n  /** 请求插入公式 */\r\n  requestInsertFormulaListener(handler: () => void): () => void\r\n\r\n}\r\n\r\n/** 缩略图事件命名空间 */\r\nexport interface IThumbnailListener {\r\n  /** 缩略图变更 */\r\n  thumbnailListener(handler: (images: string[]) => void): () => void\r\n}\r\n\r\n/**\r\n * 编辑器事件监听器\r\n *\r\n * 统一管理编辑器各类事件的订阅、取消订阅与触发。\r\n * 通过命名空间 getter（range/content/ability/page 等）提供分类订阅入口。\r\n */\r\nexport class Listener {\r\n  /** 底层事件分发器实例 */\r\n  private emitter = new EventEmitter()\r\n\r\n  /** 订阅事件，返回取消订阅函数 */\r\n  on<K extends keyof ListenerMap>(event: K, handler: ListenerMap[K]): () => void {\r\n    const fn = handler as (...args: any[]) => void\r\n    this.emitter.on(event, fn)\r\n    return () => this.emitter.off(event, fn)\r\n  }\r\n\r\n  /** 取消订阅事件 */\r\n  off<K extends keyof ListenerMap>(event: K, handler: ListenerMap[K]): void {\r\n    this.emitter.off(event, handler as (...args: any[]) => void)\r\n  }\r\n\r\n  hasListeners(event: keyof ListenerMap): boolean {\r\n    return this.emitter.listenerCount(event) > 0\r\n  }\r\n\r\n  /** 触发事件（core 内部调用） */\r\n  emit<K extends keyof ListenerMap>(event: K, ...args: Parameters<ListenerMap[K]>): void {\r\n    this.emitter.emit(event, ...args)\r\n  }\r\n\r\n  /** 选区事件 */\r\n  get range(): IRangeListener {\r\n    return {\r\n      rangeListener: (handler) => this.on('rangeChange', handler),\r\n      formatListener: (handler) => this.on('formatChange', handler),\r\n      positionListener: (handler) => this.on('positionChange', handler)\r\n    }\r\n  }\r\n\r\n  /** 内容事件 */\r\n  get content(): IContentListener {\r\n    return {\r\n      contentListener: (handler) => this.on('contentChange', handler),\r\n      savedListener: (handler) => this.on('saved', handler)\r\n    }\r\n  }\r\n\r\n  /** 能力事件 */\r\n  get ability(): IAbilityListener {\r\n    return {\r\n      abilityListener: (handler) => this.on('abilityChange', handler)\r\n    }\r\n  }\r\n\r\n  /** 页面事件 */\r\n  get page(): IPageListener {\r\n    return {\r\n      pageScaleListener: (handler) => this.on('pageScaleChange', handler),\r\n      pageSizeListener: (handler) => this.on('pageSizeChange', handler),\r\n      pageCountListener: (handler) => this.on('pageCountChange', handler),\r\n      currentPageNoListener: (handler) => this.on('currentPageNoChange', handler)\r\n    }\r\n  }\r\n\r\n  /** 目录事件 */\r\n  get toc(): ITocListener {\r\n    return {\r\n      tocListener: (handler) => this.on('tocChange', handler)\r\n    }\r\n  }\r\n\r\n  /** 缩略图事件 */\r\n  get thumbnail(): IThumbnailListener {\r\n    return {\r\n      thumbnailListener: (handler) => this.on('thumbnailChange', handler)\r\n    }\r\n  }\r\n\r\n  /** 区域事件 */\r\n  get zone(): IZoneListener {\r\n    return {\r\n      zoneListener: (handler) => this.on('zoneChange', handler)\r\n    }\r\n  }\r\n\r\n  /** 生命周期事件 */\r\n  get lifecycle(): ILifecycleListener {\r\n    return {\r\n      focusListener: (handler) => this.on('focus', handler),\r\n      blurListener: (handler) => this.on('blur', handler),\r\n      afterRenderListener: (handler) => this.on('afterRender', handler)\r\n    }\r\n  }\r\n\r\n  /** 请求事件 */\r\n  get request(): IRequestListener {\r\n    return {\r\n      requestInsertImageListener: (handler) => this.on('requestInsertImage', handler),\r\n      requestInsertHyperlinkListener: (handler) => this.on('requestInsertHyperlink', handler),\r\n      requestInsertFormulaListener: (handler) => this.on('requestInsertFormula', handler)\r\n    }\r\n  }\r\n}\r\n","/**\r\n * VerveDocs State —— RangeManager\r\n *\r\n * 基于树路径的选区/光标模型。\r\n * anchor / focus 均为 IPosition = { path, offset }。\r\n */\r\n\r\nimport type { IPosition, IRange, Path } from '@vervedoc/docx-editor-schema'\r\nimport { comparePosition, isSamePath } from '@vervedoc/docx-editor-schema'\r\nimport type { Listener } from './listener'\r\n\r\n/**\r\n * 选区/光标管理器\r\n *\r\n * 维护编辑器当前选区（anchor/focus 双点模型），\r\n * 并在选区变更时通过 Listener 派发 rangeChange 与 positionChange 事件。\r\n */\r\nexport class RangeManager {\r\n  /** 当前选区，未选中时为 null */\r\n  private _range: IRange | null = null\r\n\r\n  /**\r\n   * 构造选区管理器\r\n   * @param listener 可选的事件监听器，用于在选区变更时派发事件\r\n   */\r\n  constructor(private listener?: Listener) {}\r\n\r\n  /**\r\n   * 获取当前选区\r\n   * @returns 当前选区对象，未选中时返回 null\r\n   */\r\n  getRange(): IRange | null { return this._range }\r\n\r\n  /**\r\n   * 获取选区起点（anchor）\r\n   * @returns anchor 位置，未选中时返回 null\r\n   */\r\n  getAnchor(): IPosition | null { return this._range?.anchor ?? null }\r\n\r\n  /**\r\n   * 获取选区终点（focus，即光标位置）\r\n   * @returns focus 位置，未选中时返回 null\r\n   */\r\n  getFocus(): IPosition | null { return this._range?.focus ?? null }\r\n\r\n  /** 获取按文档顺序排序后的 [start, end] */\r\n  getOrdered(): { start: IPosition; end: IPosition } | null {\r\n    if (!this._range) return null\r\n    const { anchor, focus } = this._range\r\n    return comparePosition(anchor, focus) <= 0\r\n      ? { start: anchor, end: focus }\r\n      : { start: focus, end: anchor }\r\n  }\r\n\r\n  /**\r\n   * 判断选区是否折叠（anchor 与 focus 重合）\r\n   * @returns 折叠（光标状态）返回 true，无选区或存在范围选区时返回 true/false\r\n   */\r\n  isCollapsed(): boolean {\r\n    if (!this._range) return true\r\n    const { anchor, focus } = this._range\r\n    return isSamePath(anchor.path, focus.path) && anchor.offset === focus.offset\r\n  }\r\n\r\n  /**\r\n   * 设置光标位置（折叠选区，anchor = focus）\r\n   * @param pos 光标位置，传 null 清除选区\r\n   */\r\n  setCaret(pos: IPosition | null): void {\r\n    this._range = pos ? { anchor: { ...pos }, focus: { ...pos } } : null\r\n    this.emitChange()\r\n  }\r\n\r\n  /**\r\n   * 设置选区范围\r\n   * @param range 选区对象，传 null 清除选区\r\n   */\r\n  setRange(range: IRange | null): void {\r\n    this._range = range ? { anchor: { ...range.anchor }, focus: { ...range.focus } } : null\r\n    this.emitChange()\r\n  }\r\n\r\n  /**\r\n   * 将选区折叠到起点\r\n   */\r\n  collapseToStart(): void {\r\n    const ordered = this.getOrdered()\r\n    if (!ordered) return\r\n    this.setCaret(ordered.start)\r\n  }\r\n\r\n  /**\r\n   * 将选区折叠到终点\r\n   */\r\n  collapseToEnd(): void {\r\n    const ordered = this.getOrdered()\r\n    if (!ordered) return\r\n    this.setCaret(ordered.end)\r\n  }\r\n\r\n  /**\r\n   * 清除当前选区\r\n   */\r\n  clear(): void {\r\n    this._range = null\r\n    this.emitChange()\r\n  }\r\n\r\n  /**\r\n   * 派发选区变更事件\r\n   * 同时触发 rangeChange 与 positionChange 事件\r\n   */\r\n  private emitChange(): void {\r\n    this.listener?.emit('rangeChange', this._range)\r\n    this.listener?.emit('positionChange', this._range?.focus ?? null)\r\n  }\r\n\r\n  /** 用同一 path 移动 offset */\r\n  moveOffset(delta: number): void {\r\n    if (!this._range) return\r\n    const focus = this._range.focus\r\n    const newOffset = Math.max(0, focus.offset + delta)\r\n    this.setCaret({ path: focus.path.slice() as Path, offset: newOffset })\r\n  }\r\n}\r\n","/**\r\n * VerveDocs View —— TextMeasure\r\n *\r\n * 字形宽度 LRU 缓存 + 段落级 memoization。\r\n * 采用一个隐藏 canvas 的 ctx 做 measureText，主线程即可用。\r\n */\r\n\r\nimport { FONT_FAMILY_CSS, type ITextElement } from '@vervedoc/docx-editor-schema'\n\n/**\n * 按字符范围选择 DOCX 字体。与导出端一样，用户改过 font 后停用原始映射。\n * 字体选择与占宽分开：东亚兼容规则可能调整空格占宽，不能直接用西文字体宽度代替。\n */\nexport function resolveTextFont(\n  run: Pick<ITextElement, 'font' | 'fontFamilies' | 'sourceFont'>,\n  ch: string,\n  defaultFont: string\n): string {\n  const base = run.font ?? defaultFont\n  const fallback = FONT_FAMILY_CSS[base] ?? base\n  const families = run.sourceFont === run.font ? run.fontFamilies : undefined\n  if (!families || !ch) return fallback\n  const code = ch.codePointAt(0)!\n  const eastAsia = (code >= 0x1100 && code <= 0x11ff) ||\n    (code >= 0x2e80 && code <= 0xa4cf) ||\n    (code >= 0xac00 && code <= 0xd7af) ||\n    (code >= 0xf900 && code <= 0xfaff) ||\n    (code >= 0xfe10 && code <= 0xfe6f) ||\n    (code >= 0xff00 && code <= 0xffef) ||\n    (code >= 0x20000 && code <= 0x323af)\n  const complex = (code >= 0x0590 && code <= 0x08ff) ||\n    (code >= 0xfb1d && code <= 0xfdff) || (code >= 0xfe70 && code <= 0xfeff)\n  const family = code <= 0x7f ? families.ascii :\n    eastAsia ? families.eastAsia : complex ? families.cs : families.hAnsi\n  // 原始字体（如仿宋_GB2312）未安装时，继续使用已归一化字体的回退栈。\n  return family ? (FONT_FAMILY_CSS[family] ?? `${JSON.stringify(family)}, ${fallback}`) : fallback\n}\n\n/**\r\n * LRU 双向链表节点。\r\n */\r\ninterface LruNode<K, V> {\r\n  /** 节点键 */\r\n  key: K\r\n  /** 节点值 */\r\n  value: V\r\n  /** 前驱节点 */\r\n  prev: LruNode<K, V> | null\r\n  /** 后继节点 */\r\n  next: LruNode<K, V> | null\r\n}\r\n\r\n/**\r\n * LRU 缓存：基于双向链表 + Map 实现，最近访问的节点置于链表头部。\r\n */\r\nclass LRU<K, V> {\r\n  /** 节点查找表 */\r\n  private map = new Map<K, LruNode<K, V>>()\r\n  /** 链表头（最近访问） */\r\n  private head: LruNode<K, V> | null = null\r\n  /** 链表尾（最久未访问，淘汰端） */\r\n  private tail: LruNode<K, V> | null = null\r\n  /**\r\n   * 创建容量为 limit 的 LRU 缓存。\r\n   * @param limit 缓存容量上限\r\n   */\r\n  constructor(private limit: number) {}\r\n\r\n  /**\r\n   * 读取键对应的值，并将其置为最近访问。\r\n   * @param key 键\r\n   * @returns 命中返回值，未命中返回 undefined\r\n   */\r\n  get(key: K): V | undefined {\r\n    const node = this.map.get(key)\r\n    if (!node) return undefined\r\n    this.touch(node)\r\n    return node.value\r\n  }\r\n\r\n  /**\r\n   * 写入键值对，已存在则更新值并置为最近访问；超出容量时淘汰尾部。\r\n   * @param key 键\r\n   * @param value 值\r\n   */\r\n  set(key: K, value: V): void {\r\n    let node = this.map.get(key)\r\n    if (node) { node.value = value; this.touch(node); return }\r\n    node = { key, value, prev: null, next: this.head }\r\n    if (this.head) this.head.prev = node\r\n    this.head = node\r\n    if (!this.tail) this.tail = node\r\n    this.map.set(key, node)\r\n    if (this.map.size > this.limit) this.evict()\r\n  }\r\n\r\n  /**\r\n   * 将节点移动到链表头部，标记为最近访问。\r\n   * @param node 待移动节点\r\n   */\r\n  private touch(node: LruNode<K, V>): void {\r\n    if (node === this.head) return\r\n    if (node.prev) node.prev.next = node.next\r\n    if (node.next) node.next.prev = node.prev\r\n    if (node === this.tail) this.tail = node.prev\r\n    node.prev = null\r\n    node.next = this.head\r\n    if (this.head) this.head.prev = node\r\n    this.head = node\r\n  }\r\n\r\n  /**\r\n   * 淘汰链表尾部节点（最久未访问）。\r\n   */\r\n  private evict(): void {\r\n    if (!this.tail) return\r\n    this.map.delete(this.tail.key)\r\n    this.tail = this.tail.prev\r\n    if (this.tail) this.tail.next = null\r\n    else this.head = null\r\n  }\r\n}\r\n\r\n/**\r\n * 字形度量器：基于隐藏 canvas 的 measureText 计算字符宽度，带 LRU 缓存。\r\n */\r\nexport class TextMeasure {\r\n  /** canvas 2d 上下文，用于 measureText */\r\n  private ctx: CanvasRenderingContext2D\r\n  /** 字形宽度 LRU 缓存 */\r\n  private glyphCache = new LRU<string, number>(10000)\r\n  private inkCache = new LRU<string, { left: number; right: number }>(2000)\n\r\n  /**\r\n   * 创建度量器，初始化隐藏 canvas 及其 2d 上下文。\r\n   */\r\n  constructor() {\r\n    const c = typeof document !== 'undefined'\r\n      ? document.createElement('canvas')\r\n      : ({ getContext: () => null } as unknown as HTMLCanvasElement)\r\n    const ctx = c.getContext('2d')\r\n    if (!ctx) throw new Error('[TextMeasure] canvas 2d context unavailable')\r\n    this.ctx = ctx\r\n  }\r\n\r\n  /** 生成 canvas font 字符串 */\r\n  static font(family: string, size: number, bold?: boolean, italic?: boolean): string {\r\n    const w = bold ? '700' : '400'\r\n    const s = italic ? 'italic ' : ''\r\n    return `${s}${w} ${size}px ${family}`\r\n  }\r\n\r\n  /** 单字符宽度 */\r\n  charWidth(ch: string, family: string, size: number, bold?: boolean, italic?: boolean): number {\r\n    const key = `${ch}|${family}|${size}|${bold ? 1 : 0}|${italic ? 1 : 0}`\r\n    const hit = this.glyphCache.get(key)\r\n    if (hit != null) return hit\r\n    this.ctx.font = TextMeasure.font(family, size, bold, italic)\r\n    const w = this.ctx.measureText(ch).width\r\n    this.glyphCache.set(key, w)\r\n    return w\r\n  }\r\n\r\n  /** 整串宽度 */\r\n  textWidth(text: string, family: string, size: number, bold?: boolean, italic?: boolean): number {\r\n    let w = 0\r\n    for (const ch of text) w += this.charWidth(ch, family, size, bold, italic)\r\n    return w\r\n  }\r\n\n  /** 字形左右墨迹边界，用于压缩留白而不压缩或重叠字形。 */\n  inkBounds(ch: string, family: string, size: number, bold?: boolean, italic?: boolean): { left: number; right: number } {\n    const key = `${ch}|${family}|${size}|${bold ? 1 : 0}|${italic ? 1 : 0}`\n    const hit = this.inkCache.get(key)\n    if (hit) return hit\n    this.ctx.font = TextMeasure.font(family, size, bold, italic)\n    const metrics = this.ctx.measureText(ch)\n    const bounds = {\n      left: Number.isFinite(metrics.actualBoundingBoxLeft) ? -metrics.actualBoundingBoxLeft : 0,\n      right: Number.isFinite(metrics.actualBoundingBoxRight) ? metrics.actualBoundingBoxRight : metrics.width\n    }\n    this.inkCache.set(key, bounds)\n    return bounds\n  }\n}\r\n\r\n/** 全局共享度量器（浏览器环境） */\r\nlet _sharedMeasure: TextMeasure | null = null\r\n/**\r\n * 获取全局共享的 TextMeasure 实例，首次调用时惰性创建。\r\n * @returns 共享度量器实例\r\n */\r\nexport function getSharedMeasure(): TextMeasure {\r\n  if (!_sharedMeasure) _sharedMeasure = new TextMeasure()\r\n  return _sharedMeasure\r\n}\r\n","import { computeControlDisplayValue, type IControlElement } from '@vervedoc/docx-editor-schema'\n\nexport interface ControlPresentation {\n  text: string\n  placeholder?: boolean\n  mark?: { kind: 'checkbox' | 'radio'; checked: boolean }\n  optionValue?: string\n  /** 自动展示括号的字符偏移，不包含用户输入的真实括号。 */\n  bracketOffsets?: number[]\n}\n\n// 用于测量矢量勾选标记的占位字符，不写入文档数据值。\nexport const CONTROL_MARK = '\\uFFFC'\n\n/**\n * 生成用于布局和绘制的控件展示片段，不修改控件定义或文档数据。\n * @param element 内容控件及其当前数据值\n * @param printing 是否生成打印展示，省略自动括号与空值占位提示\n * @returns 包含展示文本及可选勾选标记、选项值的片段数组\n */\nexport function getControlPresentation(element: IControlElement, printing = false): ControlPresentation[] {\n  const { control, dataValue } = element\n  // 仅编辑态为带 binding 的控件自动添加展示括号。\n  const bracketed = !printing && !!element.extension?.binding\n  if (control.kind === 'checkbox') {\n    const text = CONTROL_MARK + (control.checkboxLabel ? ` ${control.checkboxLabel}` : '')\n    return [{\n      text: bracketed ? `[${text}]` : text,\n      bracketOffsets: bracketed ? [0, text.length + 1] : undefined,\n      mark: { kind: 'checkbox', checked: dataValue === true }\n    }]\n  }\n  if (control.kind === 'radioGroup' && control.options?.length) {\n    return control.options.map((option, index) => {\n      const first = index === 0\n      const last = index === control.options!.length - 1\n      const text = `${first && bracketed ? '[' : ''}${CONTROL_MARK} ${option.label}${last && bracketed ? ']' : ''}${last ? '' : '  '}`\n      return {\n        text,\n        bracketOffsets: bracketed ? [\n          ...(first ? [0] : []),\n          ...(last ? [text.length - 1] : [])\n        ] : undefined,\n        mark: { kind: 'radio' as const, checked: dataValue === option.value },\n        optionValue: option.value\n      }\n    })\n  }\n  // 由控件数据值计算的实际展示文本，不包含空值占位提示或编辑态自动括号。\n  const text = computeControlDisplayValue(control, dataValue)\n  if (printing) return [{ text }]\n  const displayText = text || control.placeholder || ''\n  return [{\n    text: bracketed ? `[${displayText}]` : displayText || '\\u200B',\n    bracketOffsets: bracketed ? [0, displayText.length + 1] : undefined,\n    placeholder: !text\n  }]\n}\n","import type { IDocxTypography, ITextElement } from '@vervedoc/docx-editor-schema'\nimport { resolveTextFont, type TextMeasure } from './text-measure'\n\n/** 全角标点的空白可压缩；不改变拉丁标点、普通汉字和数字的字形。 */\nconst PUNCTUATION = /^[、。，．！？：；【】（）《》〈〉「」『』〔〕［］｛｝“”‘’]$/\n\nexport interface CompressionMetrics {\n  minWidth: number\n  leadingRatio: number\n}\n\n/** 原文指定等宽东亚排位时，半角空格采用全角空格的一半占宽。 */\nexport function balancedSpaceWidth(\n  run: ITextElement, typography: IDocxTypography | undefined,\n  measure: TextMeasure, defaultFont: string, size: number\n): number | undefined {\n  if (!typography?.balanceSingleByteDoubleByteWidth || run.fontHint !== 'eastAsia' ||\n    run.sourceFont !== run.font || !run.fontFamilies?.eastAsia) return undefined\n  const font = resolveTextFont(run, '一', defaultFont)\n  const narrow = measure.charWidth('i', font, size, run.bold, run.italic)\n  const wide = measure.charWidth('W', font, size, run.bold, run.italic)\n  const full = measure.charWidth('\\u3000', font, size, run.bold, run.italic)\n  // 兼容开关只针对等宽字体，不能把比例字体中的空格也强制放大。\n  return Math.abs(narrow - wide) < 0.01 && Math.abs(wide * 2 - full) < 0.05 ? full / 2 : undefined\n}\n\n/** 测量允许收缩的标点留白，字形本身和至少半个字身宽度始终保留。 */\nexport function punctuationCompression(\n  ch: string, font: string, size: number, bold: boolean, italic: boolean,\n  typography: IDocxTypography | undefined, measure: TextMeasure\n): CompressionMetrics | undefined {\n  const rule = typography?.characterSpacingControl\n  if (!rule || rule === 'doNotCompress' || !PUNCTUATION.test(ch)) return undefined\n  const width = measure.charWidth(ch, font, size, bold, italic)\n  if (width < size * 0.9) return undefined\n  const ink = measure.inkBounds(ch, font, size, bold, italic)\n  const left = Math.max(0, ink.left)\n  const right = Math.max(0, width - ink.right)\n  const whitespace = left + right\n  const minWidth = Math.max(size / 2, width - whitespace)\n  if (minWidth >= width - 0.001) return undefined\n  return { minWidth, leadingRatio: left / whitespace }\n}\n","/**\r\n * VerveDocs View —— List Bullet & Numbering\r\n *\r\n * 无序符号：直接使用 Wingdings/Symbol 私有区字符，通过字体栈渲染。\r\n *   Windows 自带 Wingdings 字体 → 原生正确显示。\r\n *   其它系统 → 通过字体栈回退到 Segoe UI Symbol / Symbola / Noto 等，\r\n *   或者进一步映射到普通 Unicode（U+27A2 ➢ 等）。\r\n *\r\n * 有序编号：按 numFmt 转换数字，替换 lvlText 里的 %1..%9 占位。\r\n */\r\n\r\nimport type { IListElement, IListNumbering } from '@vervedoc/docx-editor-schema'\r\n\r\n/* ==================== 数字格式转换 ==================== */\r\n\r\n/**\r\n * 将阿拉伯数字转换为罗马数字。\r\n * @param num - 待转换的正整数（仅支持 1..3999，超出范围直接返回原数字字符串）\r\n * @param upper - 是否输出大写罗马数字\r\n * @returns 罗马数字字符串\r\n */\r\nfunction toRoman(num: number, upper: boolean): string {\r\n  if (num <= 0 || num >= 4000) return String(num)\r\n  const map: [number, string][] = [\r\n    [1000, 'M'], [900, 'CM'], [500, 'D'], [400, 'CD'],\r\n    [100, 'C'], [90, 'XC'], [50, 'L'], [40, 'XL'],\r\n    [10, 'X'], [9, 'IX'], [5, 'V'], [4, 'IV'], [1, 'I']\r\n  ]\r\n  let n = num, out = ''\r\n  for (const [v, s] of map) { while (n >= v) { out += s; n -= v } }\r\n  return upper ? out : out.toLowerCase()\r\n}\r\n\r\n/**\r\n * 将正整数转换为字母序号（1→A, 26→Z, 27→AA）。\r\n * @param num - 待转换的正整数（<=0 时直接返回原数字字符串）\r\n * @param upper - 是否输出大写字母\r\n * @returns 字母序号字符串\r\n */\r\nfunction toLetter(num: number, upper: boolean): string {\r\n  if (num <= 0) return String(num)\r\n  let n = num, out = ''\r\n  while (n > 0) {\r\n    const rem = (n - 1) % 26\r\n    out = String.fromCharCode(65 + rem) + out\r\n    n = Math.floor((n - 1) / 26)\r\n  }\r\n  return upper ? out : out.toLowerCase()\r\n}\r\n\r\n/** 中文小写数字字符表（0..9 对应 零..九） */\r\nconst CN_DIGITS = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']\r\n/** 中文数位单位（个、十、百、千） */\r\nconst CN_UNITS = ['', '十', '百', '千']\r\n/** 中文大分段单位（个、万、亿、兆） */\r\nconst CN_BIG_UNITS = ['', '万', '亿', '兆']\r\n/** 中文大写数字字符表（0..9 对应 零..玖，财务用大写） */\r\nconst CN_UPPER   = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']\r\n\r\n/**\r\n * 将正整数转换为中文小写计数（如 12 → 十二，23 → 二十三）。\r\n * @param num - 待转换的正整数（<=0 时直接返回原数字字符串）\r\n * @returns 中文小写计数字符串\r\n */\r\nfunction toChineseCounting(num: number): string {\r\n  if (num <= 0) return String(num)\r\n  if (num < 10) return CN_DIGITS[num]\r\n  if (num < 20) return num === 10 ? '十' : '十' + CN_DIGITS[num - 10]\r\n  if (num < 100) {\r\n    const t = Math.floor(num / 10), o = num % 10\r\n    return CN_DIGITS[t] + '十' + (o ? CN_DIGITS[o] : '')\r\n  }\r\n  return toChineseCountingLarge(num)\r\n}\r\n\r\n/**\r\n * 将任意大正整数转换为中文计数（支持万、亿、兆等大单位）。\r\n * @param num - 待转换的非负整数\r\n * @returns 中文计数字符串\r\n */\r\nfunction toChineseCountingLarge(num: number): string {\r\n  if (num === 0) return '零'\r\n  let out = ''\r\n  const segs: number[] = []\r\n  let n = num\r\n  while (n > 0) { segs.push(n % 10000); n = Math.floor(n / 10000) }\r\n  for (let s = segs.length - 1; s >= 0; s--) {\r\n    const seg = segs[s]\r\n    if (seg === 0) { if (out && !out.endsWith('零')) out += '零'; continue }\r\n    let segStr = ''\r\n    for (let u = 3; u >= 0; u--) {\r\n      const digit = Math.floor(seg / Math.pow(10, u)) % 10\r\n      if (digit === 0) { if (segStr && !segStr.endsWith('零')) segStr += '零' }\r\n      else segStr += CN_DIGITS[digit] + CN_UNITS[u]\r\n    }\r\n    if (segStr.endsWith('零')) segStr = segStr.slice(0, -1)\r\n    out += segStr + CN_BIG_UNITS[s]\r\n  }\r\n  return out\r\n}\r\n\r\n/**\r\n * 将正整数转换为中文大写计数（财务用，如 12 → 壹拾贰）。\r\n * @param num - 待转换的正整数\r\n * @returns 中文大写计数字符串\r\n */\r\nfunction toChineseUpper(num: number): string {\r\n  return toChineseCounting(num).split('').map(ch => {\r\n    const i = CN_DIGITS.indexOf(ch)\r\n    return i >= 0 ? CN_UPPER[i] : ch\r\n  }).join('')\r\n}\r\n\r\n/**\r\n * 将正整数转换为逐位中文数字（如 123 → 一二三，不进位）。\r\n * @param num - 待转换的正整数\r\n * @returns 逐位中文数字字符串\r\n */\r\nfunction toIdeographDigital(num: number): string {\r\n  return String(num).split('').map(d => CN_DIGITS[Number(d)] ?? d).join('')\r\n}\r\n\r\n/**\r\n * 将正整数格式化为两位前导零十进制（如 1 → 01，10 → 10）。\r\n * @param num - 待格式化的正整数\r\n * @returns 两位十进制字符串\r\n */\r\nfunction toDecimalZero(num: number): string {\r\n  return num < 10 ? '0' + num : String(num)\r\n}\r\n\r\n/**\r\n * 按 OOXML numFmt 编号格式将计数值转换为展示字符串。\r\n * @param num - 当前层级的计数值\r\n * @param numFmt - 编号格式名称（decimal / lowerLetter / upperRoman / chineseCounting 等）\r\n * @returns 格式化后的编号字符串\r\n */\r\nexport function formatCounter(num: number, numFmt: string): string {\r\n  switch (numFmt) {\r\n    case 'decimal':                    return String(num)\r\n    case 'decimalZero':                return toDecimalZero(num)\r\n    case 'decimalEnclosedCircle':\r\n      if (num >= 1 && num <= 20) return String.fromCodePoint(0x2460 + num - 1)\r\n      if (num >= 21 && num <= 35) return String.fromCodePoint(0x3251 + num - 21)\r\n      if (num >= 36 && num <= 50) return String.fromCodePoint(0x32B1 + num - 36)\r\n      return String(num)\r\n    case 'lowerLetter':                return toLetter(num, false)\r\n    case 'upperLetter':                return toLetter(num, true)\r\n    case 'lowerRoman':                 return toRoman(num, false)\r\n    case 'upperRoman':                 return toRoman(num, true)\r\n    case 'chineseCounting':            return toChineseCounting(num)\r\n    case 'chineseCountingThousand':    return toChineseUpper(num)\r\n    case 'ideographDigital':           return toIdeographDigital(num)\r\n    case 'japaneseCounting':\r\n    case 'koreanCounting':\r\n    case 'taiwaneseCounting':          return toChineseCounting(num)\r\n    case 'bullet':                     return ''\r\n    default:                            return String(num)\r\n  }\r\n}\r\n\r\n/* ==================== Wingdings PUA → Unicode 回退表 ==================== */\r\n\r\n/**\r\n * 当系统没有 Wingdings 字体时，把 Wingdings 私有区字符换成能被通用符号字体\r\n * （Segoe UI Symbol / Apple Color Emoji / Symbola）覆盖的 Unicode 字符。\r\n */\r\nconst WINGDINGS_FALLBACK: Record<string, string> = {\r\n  '\\uF020': ' ',\r\n  '\\uF021': '✏',   // 铅笔\r\n  '\\uF022': '✂',   // 剪刀\r\n  '\\uF025': '📞',\r\n  '\\uF029': '📁',\r\n  '\\uF04A': '☺',\r\n  '\\uF04B': '😐',\r\n  '\\uF04C': '☹',\r\n  '\\uF06C': '●',\r\n  '\\uF06D': '❍',\r\n  '\\uF06E': '■',\r\n  '\\uF06F': '□',\r\n  '\\uF070': '◘',\r\n  '\\uF071': '❑',\r\n  '\\uF072': '❒',\r\n  '\\uF073': '⬧',\r\n  '\\uF074': '⬨',\r\n  '\\uF075': '◆',\r\n  '\\uF076': '❖',\r\n  '\\uF077': '⬥',\r\n  '\\uF078': '⧫',\r\n  '\\uF07C': '•',\r\n  '\\uF0A7': '▪',\r\n  '\\uF0A8': '◆',\r\n  '\\uF0A2': '○',\r\n  '\\uF0B7': '•',\r\n  '\\uF0D2': '❑',\r\n  '\\uF0D8': '➢',   // ★★ 常用的中空右箭头（Word \"TAB页\" 项目符号）\r\n  '\\uF0E0': '➔',\r\n  '\\uF0E8': '➢',\r\n  '\\uF0F0': '⇒',\r\n  '\\uF0FC': '✓',\r\n  '\\uF0FB': '✗',\r\n  '\\uF0FE': '❑'\r\n}\r\n\r\n/** 常用符号字体栈：Wingdings 优先，其次系统符号字体，最后 sans-serif */\r\nexport const BULLET_FONT_STACK =\r\n  'Wingdings, \"Segoe UI Symbol\", \"Apple Symbols\", \"Apple Color Emoji\", \"Noto Sans Symbols\", \"Noto Sans Symbols 2\", Symbola, \"DejaVu Sans\", \"Arial Unicode MS\", sans-serif'\r\n\r\n/** 无 Wingdings 字体时的字符栈（跳过 Wingdings） */\r\nexport const BULLET_FONT_STACK_FALLBACK =\r\n  '\"Segoe UI Symbol\", \"Apple Symbols\", \"Apple Color Emoji\", \"Noto Sans Symbols\", \"Noto Sans Symbols 2\", Symbola, \"DejaVu Sans\", \"Arial Unicode MS\", sans-serif'\r\n\r\n/**\r\n * 环境检测：当前浏览器是否安装了 Wingdings 字体。\r\n * 通过测量特定字符宽度对比 sans-serif 判断。缓存结果。\r\n */\r\n/** Wingdings 字体检测结果缓存（null 表示尚未检测） */\r\nlet _hasWingdings: boolean | null = null\r\nexport function detectWingdings(): boolean {\r\n  if (_hasWingdings != null) return _hasWingdings\r\n  if (typeof document === 'undefined') { _hasWingdings = false; return false }\r\n  try {\r\n    const c = document.createElement('canvas')\r\n    const ctx = c.getContext('2d')!\r\n    ctx.font = '20px sans-serif'\r\n    const w1 = ctx.measureText('\\uF0D8').width\r\n    ctx.font = '20px Wingdings, sans-serif'\r\n    const w2 = ctx.measureText('\\uF0D8').width\r\n    _hasWingdings = Math.abs(w1 - w2) > 0.5\r\n  } catch { _hasWingdings = false }\r\n  return _hasWingdings\r\n}\r\n\r\n/** 从 lvlText / listStyle 解析无序符号字符（原始 PUA 或回退 Unicode） */\r\nexport function resolveUnorderedChar(list: IListElement): string {\r\n  const num = list.listNumbering\r\n  const style = (list.listStyle || '').toString()\r\n  const bulletFont = (num as unknown as { font?: string } | undefined)?.font ?? ''\r\n  const isWingdings = /wingdings/i.test(bulletFont)\r\n\r\n  // 1. lvlText 首字符（Word 里就是原始 Wingdings PUA 字符）\r\n  if (num?.lvlText) {\r\n    const trimmed = num.lvlText.trim()\r\n    if (trimmed && !/%[1-9]/.test(trimmed)) {\r\n      const ch = trimmed.charAt(0)\r\n      // 若 numbering 声明了 Wingdings 字体但 lvlText 是 ASCII，则把它当 Wingdings 私有区处理\r\n      if (isWingdings && ch.charCodeAt(0) < 0x80) {\r\n        return String.fromCharCode(0xF000 + ch.charCodeAt(0))\r\n      }\r\n      return ch\r\n    }\r\n  }\r\n\r\n  // 2. numbering 字体为 Wingdings 但 lvlText 为空 → Word 默认使用箭头 U+F0D8（➢）\r\n  if (isWingdings) return '\\uF0D8'\r\n\r\n  // 3. listStyle 命名 → Wingdings PUA 或 Unicode 默认\r\n  const styleMap: Record<string, string> = {\r\n    disc:        '\\uF0B7',\r\n    circle:      '\\uF0A2',\r\n    square:      '\\uF0A7',\r\n    emptySquare: '\\uF0D2',\r\n    filledDiamond: '\\uF0A8',\r\n    diamond:     '\\uF076',\r\n    arrow:       '\\uF0D8',\r\n    arrowFilled: '\\uF0E0',\r\n    check:       '\\uF0FC',\r\n    cross:       '\\uF0FB',\r\n    bullet:      '\\uF0B7',\r\n    triangle:    '▶',\r\n    star:        '★',\r\n    heart:       '♥',\r\n    dash:        '–',\r\n    hyphen:      '-'\r\n  }\r\n  if (styleMap[style]) return styleMap[style]\r\n\r\n  // 4. 层级默认循环\r\n  const level = Math.max(0, list.listLevel ?? 0)\r\n  const fallback = ['\\uF0B7', '\\uF0A2', '\\uF0A7']\r\n  return fallback[level % fallback.length]\r\n}\r\n\r\n/** 若无 Wingdings，就把 PUA 转为通用 Unicode 字符 */\r\nexport function normalizeBulletChar(ch: string, hasWingdings: boolean): string {\r\n  if (hasWingdings) return ch\r\n  return WINGDINGS_FALLBACK[ch] ?? ch\r\n}\r\n\r\n/* ==================== 顶层入口 ==================== */\r\n\r\n/**\r\n * 项目符号解析结果。\r\n * 描述一个列表项最终要绘制的符号/编号文本及其渲染方式。\r\n */\r\nexport interface BulletResult {\r\n  /** 无序符号 or 有序编号，最终要绘制的字符串 */\r\n  text: string\r\n  /** 是否是无序符号（用符号字体栈） */\r\n  isSymbol: boolean\r\n  /** 编号在其\"编号列\"内的对齐方式（来自 numbering.lvlJc） */\r\n  lvlJc?: 'left' | 'center' | 'right'\r\n}\r\n\r\n/**\r\n * 解析列表项的项目符号或编号文本（顶层入口）。\r\n * 无序列表返回符号字符；有序列表根据计数器计算当前编号并替换 lvlText 占位符。\r\n * @param list - 列表元素数据\r\n * @param counters - 跨列表项的编号计数器（按 \"groupId:level\" 索引），可选\r\n * @returns 项目符号解析结果\r\n */\r\nexport function resolveBullet(\r\n  list: IListElement,\r\n  counters?: Map<string, number>\r\n): BulletResult {\r\n  const num: IListNumbering | undefined = list.listNumbering\r\n  const listType = list.listType\r\n  const level = Math.max(0, list.listLevel ?? 0)\r\n\r\n  const isUnordered =\r\n    listType === 'ul' ||\r\n    num?.numFmt === 'bullet' ||\r\n    (num == null && !isOrderedStyle(list.listStyle))\r\n\r\n  if (isUnordered) {\r\n    const raw = resolveUnorderedChar(list)\r\n    const hasWD = detectWingdings()\r\n    const ch = normalizeBulletChar(raw, hasWD)\r\n    return { text: ch, isSymbol: true, lvlJc: num?.lvlJc }\r\n  }\r\n\r\n  const fmt = num?.numFmt ?? list.listStyle ?? 'decimal'\r\n  const start = num?.start ?? 1\r\n  const tpl = num?.lvlText ?? '%1.'\r\n  // 计数隔离键：优先使用 listId（独立列表实例），回退 numId，再回退 listStyle\r\n  const groupId = list.listId ?? num?.numId ?? list.listStyle ?? 'default'\r\n  const numId = groupId\r\n  const key = `${numId}:${level}`\r\n\r\n  let current = start\r\n  if (counters) {\r\n    const prev = counters.get(key)\r\n    current = (prev == null ? start - 1 : prev) + 1\r\n    counters.set(key, current)\r\n    for (const k of counters.keys()) {\r\n      if (!k.startsWith(`${numId}:`)) continue\r\n      const l = Number(k.split(':')[1])\r\n      if (l > level) counters.delete(k)\r\n    }\r\n  }\r\n\r\n  const text = tpl.replace(/%([1-9])/g, (_, d: string) => {\r\n    const lvl = Number(d) - 1\r\n    if (lvl === level) return formatCounter(current, fmt)\r\n    const val = counters?.get(`${numId}:${lvl}`) ?? start\r\n    return formatCounter(val, fmt)\r\n  })\r\n\r\n  return { text, isSymbol: false, lvlJc: num?.lvlJc }\r\n}\r\n\r\n/**\r\n * 判断给定的 listStyle 是否属于有序编号样式。\r\n * @param s - listStyle 字符串\r\n * @returns 若为有序编号样式返回 true，否则 false\r\n */\r\nfunction isOrderedStyle(s?: string): boolean {\r\n  if (!s) return false\r\n  return [\r\n    'decimal', 'decimalZero',\r\n    'lowerLetter', 'upperLetter',\r\n    'lowerRoman', 'upperRoman',\r\n    'chineseCounting', 'chineseCountingThousand',\r\n    'ideographDigital', 'japaneseCounting', 'koreanCounting', 'taiwaneseCounting'\r\n  ].includes(s)\r\n}\r\n","/**\r\n * BlockPainter —— 段落位图绘制纯函数\r\n *\r\n * 从 CanvasRenderer 抽出，无 this 依赖，用于把 paragraph block 绘制到目标 ctx。\r\n */\r\n\r\nimport type { ParagraphBlock, InlineBox } from './layout-types'\r\nimport type { IGroupColor } from '@vervedoc/docx-editor-schema'\r\nimport { getAuthorColor } from '@vervedoc/docx-editor-schema'\r\nimport { CONTROL_MARK } from './control-presentation'\r\n\r\n/** 单条文本绘制命令（分桶合并绘制以减少 ctx.font 切换开销） */\r\nexport interface DrawCommand {\r\n  font: string\r\n  color: string\r\n  x: number\r\n  y: number\r\n  text: string\r\n  letterSpacing?: number\r\n  glyphAdvance?: number\n  glyphScale?: number\n}\r\n\r\n/** 段落绘制选项 */\r\nexport interface PaintOptions {\r\n  groupColors?: Record<string, IGroupColor>\r\n  activeGroupId?: string | null\r\n  activeRevision?: { id: string; color: string } | null\r\n  /** 打印时跳过绑定控件自动括号的编辑态着色。 */\r\n  printing?: boolean\r\n}\r\n\r\n/** 绘制上下文类型（HTMLCanvasElement 或 OffscreenCanvas） */\r\nexport type PaintCtx = CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D\r\n\r\n/** 由 inline 生成 CSS font 简写 */\r\nexport function fontOf(inl: InlineBox): string {\r\n  const w = inl.bold ? '700' : '400'\r\n  const s = inl.italic ? 'italic ' : ''\r\n  return `${s}${w} ${inl.size}px ${inl.font}`\r\n}\r\n\r\n/** 将绘制命令按 key 推入分桶 */\r\nexport function addBucket(buckets: Map<string, DrawCommand[]>, key: string, cmd: DrawCommand): void {\r\n  let list = buckets.get(key)\r\n  if (!list) { list = []; buckets.set(key, list) }\r\n  list.push(cmd)\r\n}\r\n\r\n/** 将 hex 颜色转为半透明高亮色（批注/修订文本背景） */\r\nexport function groupHighlightColor(color: string, active = false): string {\r\n  const m = color.match(/^#([0-9a-f]{6})$/i)\r\n  if (m) {\r\n    const r = parseInt(m[1].slice(0, 2), 16)\r\n    const g = parseInt(m[1].slice(2, 4), 16)\r\n    const b = parseInt(m[1].slice(4, 6), 16)\r\n    return `rgba(${r},${g},${b},${active ? 0.14 : 0.18})`\r\n  }\r\n  return color\r\n}\r\n\r\n/**\r\n * 将段落块绘制到目标 ctx：项目符号/编号 + 分桶文本 + 背景色 + 下划线/删除线。\r\n * @param ctx 目标 2d 上下文\r\n * @param b 段落块\r\n * @param opts 绘制选项（groupColors / activeGroupId）\r\n */\r\nexport function paintParagraph(ctx: PaintCtx, b: ParagraphBlock, opts: PaintOptions): void {\r\n  // 项目符号 / 编号\r\n  if (b.bulletText) {\r\n    const firstLine = b.lines[0]\r\n    if (firstLine) {\r\n      const size = b.bulletSize ?? 16\r\n      const family = b.bulletFont ?? 'sans-serif'\r\n      const bold = b.bulletBold ? '700' : '400'\r\n      ctx.font = `${bold} ${size}px ${family}`\r\n      ctx.fillStyle = b.bulletColor ?? '#000000'\r\n      ctx.textBaseline = 'alphabetic'\r\n      const bx = firstLine.x + (b.bulletX ?? -(b.bulletWidth ?? 0))\r\n      const by = firstLine.y + firstLine.baseline\r\n      ctx.fillText(b.bulletText, bx, by)\r\n    }\r\n  }\r\n  // 分桶\r\n  const buckets = new Map<string, DrawCommand[]>()\r\n  const bgRects: { x: number; y: number; w: number; h: number; color: string }[] = []\r\n  const strokes: { x1: number; y1: number; x2: number; y2: number; color: string; width: number }[] = []\r\n  const groupColors = opts.groupColors\r\n  const activeColor = opts.activeGroupId ? groupColors?.[opts.activeGroupId]?.color : undefined\r\n  for (const line of b.lines) {\r\n    for (const inl of line.inlines) {\r\n      const hasGroupHighlight = !!(groupColors && inl.groupIds?.some(gid => groupColors[gid]))\r\n      if (opts.activeRevision && inl.run && 'revisionId' in inl.run && inl.run.revisionId === opts.activeRevision.id) {\r\n        bgRects.push({ x: inl.x, y: inl.y, w: inl.width, h: line.height, color: groupHighlightColor(opts.activeRevision.color, true) })\r\n      } else if (activeColor && opts.activeGroupId && inl.groupIds?.includes(opts.activeGroupId)) {\r\n        bgRects.push({ x: inl.x, y: inl.y, w: inl.width, h: line.height, color: groupHighlightColor(activeColor, true) })\r\n      } else if (hasGroupHighlight) {\r\n        for (const gid of inl.groupIds!) {\r\n          const gc = groupColors![gid]\r\n          if (gc) {\r\n            bgRects.push({ x: inl.x, y: inl.y, w: inl.width, h: line.height, color: groupHighlightColor(gc.color, gid === opts.activeGroupId) })\r\n          }\r\n        }\r\n      } else if (inl.bgColor) {\r\n        bgRects.push({ x: inl.x, y: inl.y, w: inl.width, h: line.height, color: inl.bgColor })\r\n      }\r\n      const run = inl.run\r\n      const revisionType = run && 'revisionId' in run && run.revisionId && 'revisionType' in run\r\n        ? run.revisionType : undefined\r\n      const inserted = revisionType === 'insert'\r\n      const deleted = revisionType === 'delete'\r\n      const revisionColor = inserted || deleted\r\n        ? getAuthorColor(run && 'revisionAuthor' in run ? String(run.revisionAuthor ?? '') : '')\r\n        : undefined\r\n      const textColor = revisionColor ?? inl.color\r\n      if (inl.text === '\\t' && (run?.extension?.toc as { role?: string } | undefined)?.role === 'entry') {\r\n        ctx.save()\r\n        ctx.strokeStyle = textColor\r\n        ctx.lineWidth = 1\r\n        ctx.setLineDash([1, 3])\r\n        ctx.beginPath()\r\n        ctx.moveTo(inl.x + 3, inl.baseline)\r\n        ctx.lineTo(inl.x + Math.max(3, inl.width - 3), inl.baseline)\r\n        ctx.stroke()\r\n        ctx.restore()\r\n        continue\r\n      }\r\n      const font = fontOf(inl)\r\n      const text = inl.text\r\n      if (inl.controlMark || (!opts.printing && inl.controlBracketOffsets?.length)) {\r\n        ctx.font = font\r\n        const spacing = inl.letterSpacing ?? 0\r\n        let x = inl.x\r\n        const markOffset = inl.controlMark ? text.indexOf(CONTROL_MARK) : -1\r\n        for (let i = 0; i < text.length; i++) {\r\n          const ch = text[i]\r\n          if (i === markOffset) {\r\n            x += inl.size + spacing\r\n            continue\r\n          }\r\n          const color = !opts.printing && inl.controlBracketOffsets?.includes(i) ? '#1677ff' : textColor\r\n          addBucket(buckets, `${font}||${color}`, { font, color, x: x + (inl.glyphOffset ?? 0), y: inl.baseline, text: ch })\n          x += (inl.glyphAdvance ?? ctx.measureText(ch).width) + spacing\n        }\r\n      } else {\r\n        const key = `${font}||${textColor}`\r\n        addBucket(buckets, key, {\n          font, color: textColor, x: inl.x + (inl.glyphOffset ?? 0), y: inl.baseline, text,\n          letterSpacing: inl.letterSpacing, glyphAdvance: inl.glyphAdvance, glyphScale: inl.glyphScale\n        })\n      }\r\n      // Review marks are visual overlays, never persisted as ordinary formatting.\r\n      if (inserted || inl.underline) {\r\n        strokes.push({\r\n          x1: inl.x, y1: inl.baseline + 2, x2: inl.x + inl.width, y2: inl.baseline + 2,\r\n          color: inserted ? revisionColor! : textColor, width: 1\r\n        })\r\n      }\r\n      if (deleted || inl.strikeout) {\r\n        const my = inl.baseline - inl.size * 0.3\r\n        strokes.push({\r\n          x1: inl.x, y1: my, x2: inl.x + inl.width, y2: my,\r\n          color: deleted ? revisionColor! : textColor, width: 1\r\n        })\r\n      }\r\n    }\r\n  }\r\n  for (const r of bgRects) {\r\n    ctx.fillStyle = r.color\r\n    ctx.fillRect(Math.round(r.x), Math.round(r.y), Math.round(r.w), Math.round(r.h))\r\n  }\r\n  ctx.textBaseline = 'alphabetic'\r\n  for (const [key, list] of buckets) {\r\n    const [font, color] = key.split('||')\r\n    ctx.font = font\r\n    ctx.fillStyle = color\r\n    for (const c of list) {\r\n      if (!c.letterSpacing && c.glyphAdvance == null && c.glyphScale == null) {\n        ctx.fillText(c.text, c.x, c.y)\r\n      } else {\r\n        let cx = c.x\r\n        for (let i = 0; i < c.text.length; i++) {\r\n          const ch = c.text[i]\r\n          if (c.glyphScale != null) {\n            ctx.save()\n            ctx.translate(cx, c.y)\n            ctx.scale(c.glyphScale, 1)\n            ctx.fillText(ch, 0, 0)\n            ctx.restore()\n          } else {\n            ctx.fillText(ch, cx, c.y)\n          }\n          cx += (c.glyphAdvance ?? ctx.measureText(ch).width) + (c.letterSpacing ?? 0)\n        }\r\n      }\r\n    }\r\n  }\r\n  for (const s of strokes) {\r\n    ctx.strokeStyle = s.color\r\n    ctx.lineWidth = s.width\r\n    ctx.beginPath()\r\n    ctx.moveTo(s.x1 + 0.5, s.y1 + 0.5)\r\n    ctx.lineTo(s.x2 + 0.5, s.y2 + 0.5)\r\n    ctx.stroke()\r\n  }\r\n  for (const line of b.lines) {\r\n    for (const inl of line.inlines) {\r\n      if (!inl.controlMark) continue\r\n      const { kind, checked } = inl.controlMark\r\n      const size = inl.size * 0.8\r\n      // 标记可能位于自动左括号之后，也可能被换行分到下一片段。\r\n      ctx.font = fontOf(inl)\r\n      const markOffset = inl.text.indexOf(CONTROL_MARK)\r\n      let x = inl.x + inl.size * 0.1\r\n      for (let i = 0; i < markOffset; i++) {\r\n        x += (inl.glyphAdvance ?? ctx.measureText(inl.text[i]).width) + (inl.letterSpacing ?? 0)\n      }\r\n      const y = inl.baseline - size\r\n      ctx.save()\r\n      ctx.strokeStyle = inl.color\r\n      ctx.fillStyle = inl.color\r\n      ctx.lineWidth = Math.max(1, inl.size / 14)\r\n      ctx.beginPath()\r\n      if (kind === 'radio') {\r\n        ctx.arc(x + size / 2, y + size / 2, size / 2, 0, Math.PI * 2)\r\n      } else {\r\n        ctx.rect(x, y, size, size)\r\n      }\r\n      ctx.stroke()\r\n      if (checked) {\r\n        ctx.beginPath()\r\n        if (kind === 'radio') {\r\n          ctx.arc(x + size / 2, y + size / 2, size / 4, 0, Math.PI * 2)\r\n          ctx.fill()\r\n        } else {\r\n          ctx.moveTo(x + size * 0.2, y + size * 0.5)\r\n          ctx.lineTo(x + size * 0.43, y + size * 0.75)\r\n          ctx.lineTo(x + size * 0.83, y + size * 0.22)\r\n          ctx.stroke()\r\n        }\r\n      }\r\n      ctx.restore()\r\n    }\r\n  }\r\n  paintParagraphBorders(ctx, b)\r\n}\r\n\r\n/** 绘制段落四边框；坐标沿用段落块本地坐标。 */\r\nfunction paintParagraphBorders(ctx: PaintCtx, block: ParagraphBlock): void {\r\n  const borders = block.paragraphBorder\r\n  if (!borders) return\r\n  const width = block.rect.width\r\n  const height = block.rect.height\r\n  ctx.save()\r\n  for (const [side, edge] of Object.entries(borders)) {\r\n    if (!edge || edge.style === 'none' || !Number.isFinite(edge.width) || edge.width <= 0) continue\r\n    const lineWidth = edge.width\r\n    const vertical = side === 'left' || side === 'right'\r\n    const x = side === 'left' ? lineWidth / 2 : width - lineWidth / 2\r\n    const y = side === 'top' ? lineWidth / 2 : height - lineWidth / 2\r\n    const x1 = vertical ? x : 0\r\n    const y1 = vertical ? 0 : y\r\n    const x2 = vertical ? x : width\r\n    const y2 = vertical ? height : y\r\n\r\n    ctx.strokeStyle = edge.color\r\n    ctx.lineCap = edge.style === 'dotted' ? 'round' : 'butt'\r\n    ctx.lineWidth = edge.style === 'double' ? Math.max(0.5, lineWidth / 3) : lineWidth\r\n    ctx.setLineDash(edge.style === 'dashed' ? [lineWidth * 3, lineWidth * 2] :\r\n      edge.style === 'dotted' ? [Math.max(0.5, lineWidth), Math.max(1.5, lineWidth * 1.5)] : [])\r\n    const stroke = (offset = 0) => {\r\n      ctx.beginPath()\r\n      ctx.moveTo(vertical ? x1 + offset : x1, vertical ? y1 : y1 + offset)\r\n      ctx.lineTo(vertical ? x2 + offset : x2, vertical ? y2 : y2 + offset)\r\n      ctx.stroke()\r\n    }\r\n    if (edge.style === 'double') {\r\n      const offset = Math.max(0.75, lineWidth / 3)\r\n      stroke(-offset)\r\n      stroke(offset)\r\n    } else {\r\n      stroke()\r\n    }\r\n  }\r\n  ctx.restore()\r\n}\r\n","/**\r\n * 块签名（用于跨帧复用 bitmap）\r\n */\r\n\r\nimport type { BlockNode, DocumentLayout, ParagraphBlock } from './layout-types'\r\n\r\nexport function chartTableSignature(b: BlockNode, layout: DocumentLayout): string {\r\n  if (b.kind !== 'chart') return ''\r\n  const source = (b.block as unknown as {\r\n    block?: { chartBlock?: { dataSource?: { type?: string; tableId?: string } } }\r\n  }).block?.chartBlock?.dataSource\r\n  if (source?.type !== 'table') return ''\r\n  for (const page of layout.pages) {\r\n    for (const block of page.blocks) {\r\n      if (block.kind === 'table' && block.block.id === source.tableId) return JSON.stringify(block.block)\r\n    }\r\n  }\r\n  return ''\r\n}\r\n\r\n/**\r\n * 计算块的签名（用于跨帧复用 bitmap）：按块类型拼接关键字段为字符串。\r\n * @param b 块\r\n * @param layout 文档布局（用于 chart-table 签名查找）\r\n * @returns 块签名字符串\r\n */\r\nexport function signBlock(b: BlockNode, layout?: DocumentLayout): string {\r\n  // Include all paint inputs, but not the block's placement on the page.\r\n  // Source objects are mutable, so callers must retain the string, not the object.\r\n  if (b.kind === 'table') {\r\n    const { trList: _rows, ...attrs } = b.block as unknown as Record<string, unknown>\r\n    return JSON.stringify([attrs, b.rect.width, b.rect.height, b.colWidths,\r\n      b.rows.map(row => [row.rect, row.cells.map(cell => {\r\n        const { value: _content, ...cellAttrs } = cell.cell\r\n        return [cellAttrs, cell.rect, cell.contentPaddingTop, cell.contentPaddingLeft,\r\n          cell.verticalOffset, cell.content.map(child => [child.rect, signBlock(child, layout)])]\r\n      })])])\r\n  }\r\n  if (b.kind === 'paragraph') return signParagraph(b)\r\n  if (b.kind === 'image') {\r\n    const img = b.block as unknown as {\n      value?: string\n      rotate?: number\n      imgDisplay?: string\n      wordArt?: { text?: string; fontFamily?: string; fontSize?: number; fillColor?: string }\n    }\n    const wordArtKey = img.wordArt\n      ? JSON.stringify([img.wordArt.text, img.wordArt.fontFamily, img.wordArt.fontSize, img.wordArt.fillColor])\n      : ''\n    return `img|${img.value ?? ''}|${b.rect.width}x${b.rect.height}|r${img.rotate ?? 0}|d${img.imgDisplay ?? 'block'}|wa${wordArtKey}`\n  }\r\n  if (b.kind === 'pageBreak') return `pb|${b.parentPath.join('.')}|${b.indexInParent}`\r\n  if (b.kind === 'separator') return JSON.stringify([b.kind, b.block, b.rect.width, b.rect.height])\r\n  if (b.kind === 'block') {\r\n    const el = b.block as unknown as { id?: string }\r\n    return `blk|${el.id ?? ''}|${b.parentPath.join('.')}|${b.indexInParent}|${b.rect.width}x${b.rect.height}`\r\n  }\r\n  if (b.kind === 'chart') {\r\n    const el = b.block as unknown as { id?: string; block?: { chartBlock?: Record<string, unknown> } }\r\n    return `chart|${el.id ?? ''}|${b.rect.width}x${b.rect.height}|${JSON.stringify(el.block?.chartBlock ?? '')}|${layout ? chartTableSignature(b, layout) : ''}`\r\n  }\r\n  return `unk`\r\n}\r\n\r\n/**\r\n * 计算段落块签名：拼接段落属性 + 各 inline 文本/字体/样式 + 项目符号 + 环绕图片关键字段。\r\n * @param b 段落块\r\n * @returns 段落签名字符串\r\n */\r\nexport function signParagraph(b: ParagraphBlock): string {\r\n  const attrs = b.block ?? (b.lines[0]?.inlines[0]?.run) ?? null\r\n  const a = attrs as unknown as Record<string, unknown> | null\r\n  const paraKey = a\r\n    ? `${a.rowFlex ?? ''}|${a.paragraphStyleId ?? ''}|${a.lineHeight ?? ''}|${a.lineHeightRule ?? ''}|${a.snapToGrid ?? ''}|${a.paragraphFirstLineIndent ?? ''}|${a.paragraphIndentLeft ?? ''}|${a.paragraphIndentRight ?? ''}|${a.indentHanging ?? ''}|${a.paragraphSpacingBefore ?? ''}|${a.paragraphSpacingAfter ?? ''}|${a.paragraphMarkSize ?? ''}|${JSON.stringify(a.paragraphBorder ?? null)}`\n    : ''\r\n  const runsKey: string[] = []\r\n  for (const line of b.lines) {\r\n    for (const inl of line.inlines) {\r\n      const { run, path: _path, ...paint } = inl\r\n      // Revision colors and decorations are painted from the run, not inline styles.\r\n      const revision = run && 'revisionId' in run && run.revisionId\r\n        ? [run.revisionId, run.revisionType, run.revisionAuthor]\r\n        : null\r\n      runsKey.push(JSON.stringify([line.x, line.y, line.height, line.baseline, paint, revision]))\r\n    }\r\n  }\r\n  const bulletKey = b.bulletText\r\n    ? `~b:${b.bulletKind ?? ''}|${b.bulletText ?? ''}|${b.bulletFont ?? ''}|${b.bulletSize ?? ''}|${b.bulletColor ?? ''}|${b.bulletBold ? 1 : 0}|bx=${b.bulletX ?? ''}|bw=${b.bulletWidth ?? ''}`\r\n    : ''\r\n  const si = b.surroundImage\r\n  const surroundKey = si\r\n    ? `~si:${JSON.stringify(si.rect)}|${signBlock(si)}`\r\n    : ''\r\n  return `p|${b.paragraphKind}|${b.rect.width}x${b.rect.height}|${paraKey}|${runsKey.join('~')}${bulletKey}${surroundKey}`\r\n}\r\n","/**\r\n * VerveDocs View —— CanvasRenderer\r\n *\r\n * 背景 DOM 层 + content/overlay 两层 canvas。\r\n *\r\n * 增量重绘：\r\n *  - 每个 Block 拥有独立 canvas 位图，key = block.id。\r\n *  - 首次或 dirty 时重建该 block bitmap；否则复用。\r\n *  - 主 content canvas 每帧执行：clear + drawImage(bitmap) 到屏幕对应位置。\r\n *  - 因此\"内容变化局部更新\" = 只对 dirty block 重建 bitmap。\r\n *\r\n * 坐标：block/line/inline 均使用块本地坐标；绘制到 bitmap 时以 (0,0) 为起点。\r\n * 主 canvas 落位时 = pageOriginY + block.rect.y - scrollY。\r\n */\r\n\r\nimport type {\r\n  BlockNode, DocumentLayout, PageLayout,\r\n  ParagraphBlock, ImageBlock, TableBlock, SeparatorBlock, ChartBlock\r\n} from './layout-types'\r\nimport type { IGroupColor, IImageElement } from '@vervedoc/docx-editor-schema'\r\nimport type { IChartRenderer } from '@vervedoc/docx-editor-schema'\r\nimport { paintParagraph, type PaintCtx } from './block-painter'\r\nimport { chartTableSignature } from './block-signature'\r\n\r\n\r\n/** CanvasRenderer 渲染器配置选项 */\r\nexport interface RendererOptions {\r\n  /** 设备像素比，用于高 DPI 屏幕清晰渲染 */\r\n  dpr: number\r\n  /** 渲染缩放倍数 */\r\n  scale: number\r\n  /** 页面背景色 */\r\n  pageBg: string\r\n  /** 页面阴影颜色 */\r\n  pageShadow: string\r\n  /** 页面居中时相对 canvas 左侧的水平偏移（外部计算并传入） */\r\n  pageOffsetX: number\r\n  /** 页面 margin（top,right,bottom,left），用于绘制标尺角标 */\r\n  pageMargins: [number, number, number, number]\r\n  /** 是否显示 WPS 风格的四角边距标记 */\r\n  showMarginRuler: boolean\r\n  /** 标尺颜色 */\r\n  rulerColor: string\r\n  /** 批注/修订组颜色映射，用于高亮文档中带 groupIds 的文本 */\r\n  groupColors?: Record<string, IGroupColor>\r\n  /** 当前高亮的 group ID（鼠标悬浮批注气泡时设置） */\r\n  activeGroupId?: string | null\r\n  /** 页码配置（设置后在页眉/页脚中渲染页码） */\r\n  pageNumber?: { style: string; position: 'left' | 'center' | 'right'; zone: 'header' | 'footer' } | null\r\n\r\n}\r\n\r\n\r\n/** 块位图缓存条目：保存已渲染好的位图及其尺寸元信息 */\r\ninterface BlockCache {\r\n  /** 块 id（与 BlockNode.id 对应） */\r\n  id: number\r\n  /** 已渲染好的位图（OffscreenCanvas 时为 ImageBitmap，降级时为 HTMLCanvasElement） */\r\n  bitmap: HTMLCanvasElement | ImageBitmap | null\r\n  /** 位图 CSS 宽度 */\r\n  width: number\r\n  /** 位图 CSS 高度 */\r\n  height: number\r\n  /** 创建该位图时的 dpr（dpr 变化时需重建） */\r\n  dpr: number\r\n}\r\n\r\n/**\r\n * Canvas 渲染器：维护背景 DOM 层 + content/overlay 两层 canvas，\r\n * 负责 block 位图缓存、增量重绘、光标/选区/页眉页脚分隔线绘制。\r\n */\r\nexport class CanvasRenderer {\r\n  /** 当前编辑区域；编辑页眉/页脚时淡化正文内容。 */\n  private activeZone: 'main' | 'header' | 'footer' = 'main'\n\n  /** 背景层 DOM 容器（每页背景 div，z-index:0） */\r\n  private bgLayer: HTMLDivElement\r\n  /** 内容层 canvas（绘制 block 位图） */\r\n  private contentCanvas: HTMLCanvasElement\r\n  /** 覆盖层 canvas（绘制光标、选区高亮、zone 分隔线） */\r\n  private overlayCanvas: HTMLCanvasElement\r\n  /** 内容层 2d 上下文 */\r\n  private contentCtx: CanvasRenderingContext2D\r\n  /** 覆盖层 2d 上下文 */\r\n  private overlayCtx: CanvasRenderingContext2D\r\n  /** 选区层 DOM 容器（选区高亮 div，z-index:3） */\r\n  private selectionLayer: HTMLDivElement\r\n  /** 每页背景 div（页号 → div），带 data-index 供协同光标定位 */\r\n  private pageBgEls = new Map<number, HTMLDivElement>()\r\n  /** 选区高亮 div 池（复用，避免频繁创建） */\r\n  private selectionEls: HTMLDivElement[] = []\r\n\r\n  /** canvas CSS 宽度（视口宽度） */\r\n  private cssWidth = 0\r\n  /** canvas CSS 高度（视口高度） */\r\n  private cssHeight = 0\r\n  /** 渲染器选项 */\r\n  private opts: RendererOptions\r\n  private chartRenderer: IChartRenderer | null = null\r\n\r\n  setChartRenderer(renderer: IChartRenderer | null): void {\r\n    this.chartRenderer = renderer\r\n    for (const key of this.imageCache.keys()) {\r\n      if (key.startsWith('chart|')) this.imageCache.delete(key)\r\n    }\r\n    this.invalidateAll()\r\n  }\r\n\r\n  /** 图片元素缓存（url -> HTMLImageElement） */\r\n  private imageCache = new Map<string, HTMLImageElement>()\r\n  /** block 位图缓存（blockId -> BlockCache） */\r\n  private blockCache = new Map<number, BlockCache>()\r\n  /** 待重建位图的 block id 集合 */\r\n  private dirtyBlocks = new Set<number>()\r\n  /** Built during layout, so hover does not scan the document. */\r\n  private groupBlockIds = new Map<string, Set<number>>()\r\n  private revisionBlockIds = new Map<string, Set<number>>()\r\n  private activeRevision: { id: string; color: string } | null = null\r\n\r\n  /** 当前帧的文档布局（供 drawChartInto 查找表格数据源） */\r\n  private currentLayout: DocumentLayout | null = null\r\n  /** 当前是否处于独立打印渲染，控制打印样式与资源加载回调。 */\r\n  private printing = false\r\n  /** 预加载阶段收集的打印图片与图表资源，供正式绘制前等待解码。 */\r\n  private printResources: Set<HTMLImageElement> | null = null\r\n\r\n\r\n  /** 水印 widget（可选，设置后在每页渲染完成后绘制水印） */\r\n  private watermarkWidget: { drawWatermark(ctx: CanvasRenderingContext2D, page: import('./layout-types').PageLayout, scrollY: number): void; drawWatermarkForThumbnail(ctx: CanvasRenderingContext2D, page: import('./layout-types').PageLayout): void } | null = null\r\n\r\n  /**\r\n   * 创建渲染器并挂载三层 canvas 到容器。\r\n   * @param container 宿主 DOM 容器，三层 canvas 绝对定位覆盖其内\r\n   * @param options 渲染选项（缺省字段使用默认值）\r\n   */\r\n  constructor(private container: HTMLElement, options: Partial<RendererOptions> = {}) {\r\n    this.opts = {\r\n      dpr: options.dpr ?? (typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1),\r\n      scale: options.scale ?? 1,\r\n      pageBg: options.pageBg ?? '#ffffff',\r\n      pageShadow: options.pageShadow ?? 'rgba(0,0,0,0.08)',\r\n      pageOffsetX: options.pageOffsetX ?? 0,\r\n      pageMargins: options.pageMargins ?? [100, 120, 100, 120],\r\n      showMarginRuler: options.showMarginRuler ?? true,\r\n      rulerColor: options.rulerColor ?? '#999999'\r\n    }\r\n\r\n    this.bgLayer = this.createDomLayer('bg', 0)\r\n    this.contentCanvas = this.createLayer('content', 1)\r\n    this.overlayCanvas = this.createLayer('overlay', 2)\r\n    this.selectionLayer = this.createDomLayer('selection', 3)\r\n    this.contentCtx = this.contentCanvas.getContext('2d')!\r\n    this.overlayCtx = this.overlayCanvas.getContext('2d')!\r\n\r\n  }\r\n\r\n  /**\r\n   * 创建一个 canvas 图层并挂载到容器。\r\n   * @param name 图层名（写入 dataset.layer，便于调试与查找）\r\n   * @param z 图层 z-index（越大越上层）\r\n   * @returns 创建好的 canvas 元素\r\n   */\r\n  private createLayer(name: string, z: number): HTMLCanvasElement {\r\n    const c = document.createElement('canvas')\r\n    c.dataset.layer = name\r\n    c.style.position = 'absolute'\r\n    c.style.top = '0'\r\n    c.style.left = '0'\r\n    c.style.zIndex = String(z)\r\n    c.style.pointerEvents = 'none'\r\n    this.container.appendChild(c)\r\n    return c\r\n  }\r\n\r\n  /** 创建一个 DOM 叠加层并挂载到容器 */\r\n  private createDomLayer(name: string, z: number): HTMLDivElement {\r\n    const el = document.createElement('div')\r\n    el.dataset.layer = name\r\n    el.style.position = 'absolute'\r\n    el.style.top = '0'\r\n    el.style.left = '0'\r\n    el.style.zIndex = String(z)\r\n    el.style.pointerEvents = 'none'\r\n    this.container.appendChild(el)\r\n    return el\r\n  }\r\n\r\n  /**\r\n   * 设置 canvas 视口尺寸（CSS 像素），同时按 dpr 调整物理像素与变换矩阵。\r\n   * @param cssWidth CSS 宽度\r\n   * @param cssHeight CSS 高度\r\n   */\r\n  setSize(cssWidth: number, cssHeight: number): void {\r\n    this.cssWidth = cssWidth\r\n    this.cssHeight = cssHeight\r\n    const dpr = this.opts.dpr\r\n    for (const c of [this.contentCanvas, this.overlayCanvas]) {\r\n      c.width = Math.round(cssWidth * dpr)\r\n      c.height = Math.round(cssHeight * dpr)\r\n      c.style.width = `${cssWidth}px`\r\n      c.style.height = `${cssHeight}px`\r\n    }\r\n    for (const ctx of [this.contentCtx, this.overlayCtx]) {\r\n      ctx.setTransform(dpr, 0, 0, dpr, 0, 0)\r\n    }\r\n  }\r\n\r\n  /** 更新可视化选项（页偏移 / margin / 是否显示标尺） */\r\n  updateVisualOptions(patch: Partial<Pick<RendererOptions,\r\n    'pageOffsetX' | 'pageMargins' | 'showMarginRuler' | 'rulerColor' | 'pageBg' | 'pageShadow' | 'scale' | 'groupColors' | 'activeGroupId'\r\n  >>): void {\r\n    Object.assign(this.opts, patch)\r\n  }\r\n\r\n  /** Change only the screen background, preserving layout and all canvas caches. */\r\n  setEyeCare(enabled: boolean): void {\r\n    if (enabled) this.bgLayer.style.setProperty('--vd-eye-care-bg', '#C7EDCC')\r\n    else this.bgLayer.style.removeProperty('--vd-eye-care-bg')\r\n  }\r\n\r\n  /**\r\n   * 渲染单页缩略图到离屏 canvas 并返回 data URL。\r\n   * 创建临时 canvas（页面尺寸 × dpr），绘制白底背景 + 页面内容，输出 PNG data URL。\r\n   * @param page 页面布局信息\r\n   * @param quality PNG 压缩质量（0-1）\r\n   * @returns 缩略图 data URL；页面尺寸为 0 时返回空字符串\r\n   */\r\n  renderPageThumbnail(page: PageLayout, quality = 0.7, pageCount = 1, onForeground?: (image: string) => void): string {\r\n    if (page.rect.width === 0 || page.rect.height === 0) return ''\r\n    const dpr = this.opts.dpr\r\n    const canvas = document.createElement('canvas')\r\n    canvas.width = Math.round(page.rect.width * dpr)\r\n    canvas.height = Math.round(page.rect.height * dpr)\r\n    const ctx = canvas.getContext('2d')!\r\n    ctx.setTransform(dpr, 0, 0, dpr, 0, 0)\r\n\r\n    // 内容区原点（相对于页面左上角）\r\n    const contentOriginX = page.contentRect.x - page.rect.x\r\n    const contentOriginY = page.contentRect.y - page.rect.y\r\n    const aliveIds = new Set<number>()\r\n    for (const b of page.blocks) {\r\n      this.renderBlockOnMain(ctx, b, contentOriginX, contentOriginY, aliveIds)\r\n    }\r\n\r\n    // 页眉\r\n    if (page.headerBlocks && page.headerRect) {\r\n      const hx = page.headerRect.x - page.rect.x\r\n      const hy = page.headerRect.y - page.rect.y\r\n      for (const b of page.headerBlocks) {\r\n        this.renderBlockOnMain(ctx, b, hx, hy, aliveIds)\r\n      }\r\n    }\r\n\r\n    // 页脚\r\n    if (page.footerBlocks && page.footerRect) {\r\n      const fx = page.footerRect.x - page.rect.x\r\n      const fy = page.footerRect.y - page.rect.y\r\n      for (const b of page.footerBlocks) {\r\n        this.renderBlockOnMain(ctx, b, fx, fy, aliveIds)\r\n      }\r\n    }\r\n\r\n    this.drawPageNumberForThumbnail(ctx, page, pageCount)\r\n    this.watermarkWidget?.drawWatermarkForThumbnail(ctx, page)\r\n\r\n    // Keep a transparent content snapshot for background-only Worker composition.\r\n    onForeground?.(canvas.toDataURL('image/png', quality))\r\n    ctx.globalCompositeOperation = 'destination-over'\r\n    ctx.fillStyle = this.opts.pageBg\r\n    ctx.fillRect(0, 0, page.rect.width, page.rect.height)\r\n    const image = canvas.toDataURL('image/png', quality)\r\n    this.trimCache()\r\n    return image\r\n  }\r\n\r\n  /**\r\n   * 独立打印位图与布局；共享已加载资源，但不改动编辑缓存或屏幕图层。\r\n   * @param layout 按打印展示规则独立重排的完整文档布局\r\n   * @returns 按页序排列的打印图片 data URL 数组\r\n   */\r\n  async renderPrintPages(layout: DocumentLayout): Promise<string[]> {\r\n    // 复制图片缓存映射，复用已加载资源并隔离打印新增资源。\r\n    const images = new Map(this.imageCache)\r\n    // 保存本次打印使用的渲染选项快照。\r\n    const options = { ...this.opts }\r\n    // 收集本次打印依赖的图片与图表，统一等待解码完成。\r\n    const resources = new Set<HTMLImageElement>()\r\n    /** 临时切换打印状态执行同步回调并恢复现场；preload 为真时仅收集资源。 */\r\n    const withPrintState = <T>(render: () => T, preload = false): T => {\r\n      // 保存切换前的渲染状态，确保异常时也能恢复。\r\n      const previous = {\r\n        blockCache: this.blockCache, dirtyBlocks: this.dirtyBlocks,\r\n        currentLayout: this.currentLayout, imageCache: this.imageCache,\r\n        printing: this.printing, opts: this.opts, printResources: this.printResources\r\n      }\r\n      // 本次同步打印操作专用的块位图缓存，结束时释放位图。\r\n      const cache = new Map<number, BlockCache>()\r\n      this.blockCache = cache\r\n      this.dirtyBlocks = new Set()\r\n      this.currentLayout = layout\r\n      this.imageCache = images\r\n      this.printing = true\r\n      this.printResources = preload ? resources : null\r\n      this.opts = options\r\n      try {\r\n        return render()\r\n      } finally {\r\n        Object.assign(this, previous)\r\n        for (const entry of cache.values()) {\r\n          if (entry.bitmap instanceof ImageBitmap) entry.bitmap.close()\r\n        }\r\n      }\r\n    }\r\n    withPrintState(() => {\r\n      // 临时绘图上下文用于触发资源预加载，不挂载到屏幕。\r\n      const ctx = document.createElement('canvas').getContext('2d')!\r\n      /** 递归遍历表格和环绕图片，收集各块依赖的图片与图表资源。 */\r\n      const visit = (blocks: BlockNode[]) => {\r\n        for (const block of blocks) {\r\n          if (block.kind === 'table') {\r\n            for (const row of block.rows) for (const cell of row.cells) visit(cell.content)\r\n          } else if (block.kind === 'paragraph' && block.surroundImage) {\r\n            visit([block.surroundImage])\r\n          } else if (block.kind === 'image') {\r\n            this.drawImageInto(ctx, block, 0, 0)\r\n          } else if (block.kind === 'chart') {\r\n            this.drawChartInto(ctx, block, 0, 0)\r\n          }\r\n        }\r\n      }\r\n      for (const page of layout.pages) {\r\n        visit(page.blocks)\r\n        visit(page.headerBlocks ?? [])\r\n        visit(page.footerBlocks ?? [])\r\n      }\r\n    }, true)\r\n    // 等待异步操作前必须恢复打印前的状态，期间可能触发屏幕渲染。\r\n    await Promise.all([...resources].filter(image => !image.complete || image.naturalWidth === 0).map(image => image.decode()))\r\n    return withPrintState(() => layout.pages.map(page => this.renderPageThumbnail(page, 0.7, layout.pages.length)))\r\n  }\r\n\r\n  /** 标脏（下一帧只重建这些 block 的 bitmap） */\r\n  markDirty(blockIds: number[] | Set<number>): void {\r\n    for (const id of blockIds) this.dirtyBlocks.add(id)\r\n  }\r\n\r\n  /** Retain offscreen document blocks; remove only deleted occurrences. */\r\n  setLayout(layout: DocumentLayout, ids: Set<number>): void {\r\n    this.currentLayout = layout\r\n    this.groupBlockIds.clear()\r\n    this.revisionBlockIds.clear()\r\n    const collect = (blocks: BlockNode[]) => {\r\n      for (const block of blocks) {\r\n        if (block.kind === 'table') {\r\n          for (const row of block.rows) {\r\n            for (const cell of row.cells) collect(cell.content)\r\n          }\r\n        } else if (block.kind === 'paragraph') {\r\n          for (const line of block.lines) {\r\n            for (const inline of line.inlines) {\r\n              const revisionId = inline.run && 'revisionId' in inline.run ? inline.run.revisionId : undefined\r\n              if (typeof revisionId === 'string' && revisionId) {\r\n                let blockIds = this.revisionBlockIds.get(revisionId)\r\n                if (!blockIds) this.revisionBlockIds.set(revisionId, blockIds = new Set())\r\n                blockIds.add(block.id)\r\n              }\r\n              for (const groupId of inline.groupIds ?? []) {\r\n                let blockIds = this.groupBlockIds.get(groupId)\r\n                if (!blockIds) this.groupBlockIds.set(groupId, blockIds = new Set())\r\n                blockIds.add(block.id)\r\n              }\r\n            }\r\n          }\r\n        }\r\n      }\r\n    }\r\n    for (const page of layout.pages) {\r\n      collect(page.blocks)\r\n      collect(page.headerBlocks ?? [])\r\n      collect(page.footerBlocks ?? [])\r\n    }\r\n    for (const [id, cached] of this.blockCache) {\r\n      if (ids.has(id)) continue\r\n      if (cached.bitmap instanceof ImageBitmap) cached.bitmap.close()\r\n      this.blockCache.delete(id)\r\n    }\r\n    for (const id of this.dirtyBlocks) {\r\n      if (!ids.has(id)) this.dirtyBlocks.delete(id)\r\n    }\r\n  }\r\n\r\n  /** Only the old and new groups need new text bitmaps. */\r\n  setActiveGroup(groupId: string | null): boolean {\r\n    const previous = this.opts.activeGroupId ?? null\r\n    if (previous === groupId) return false\r\n    this.opts.activeGroupId = groupId\r\n    for (const id of [previous, groupId]) {\r\n      if (id === null) continue\r\n      const blocks = this.groupBlockIds.get(id)\r\n      if (blocks) this.markDirty(blocks)\r\n    }\r\n    return true\r\n  }\r\n\r\n  /** Invalidate only the old and new revision's paragraph bitmaps. */\r\n  setActiveRevision(id: string | null, color = '#e60000'): boolean {\r\n    const previous = this.activeRevision\r\n    if ((previous?.id ?? null) === id && (!id || previous?.color === color)) return false\r\n    this.activeRevision = id === null ? null : { id, color }\r\n    for (const revisionId of [previous?.id, id]) {\r\n      if (!revisionId) continue\r\n      const blocks = this.revisionBlockIds.get(revisionId)\r\n      if (blocks) this.markDirty(blocks)\r\n    }\r\n    return true\r\n  }\r\n\r\n  /** Bound retained bitmap memory with least-recently-used eviction. */\r\n  private trimCache(): void {\r\n    let bytes = 0\r\n    const size = (entry: BlockCache) => Math.ceil(entry.width) * Math.ceil(entry.height) * entry.dpr ** 2 * 4\r\n    for (const entry of this.blockCache.values()) bytes += size(entry)\r\n    for (const [id, entry] of this.blockCache) {\r\n      if (bytes <= 64 * 1024 * 1024) break\r\n      bytes -= size(entry)\r\n      if (entry.bitmap instanceof ImageBitmap) entry.bitmap.close()\r\n      this.blockCache.delete(id)\r\n    }\r\n  }\r\n\r\n  /** 全部标脏（用于选项/主题变更） */\r\n  invalidateAll(): void {\r\n    for (const c of this.blockCache.values()) {\r\n      if (c.bitmap instanceof ImageBitmap) c.bitmap.close()\r\n    }\r\n    this.blockCache.clear()\r\n    this.dirtyBlocks.clear()\r\n  }\r\n\r\n  /** 销毁渲染器 */\r\n  destroy(): void {\r\n    for (const c of this.blockCache.values()) {\r\n      if (c.bitmap instanceof ImageBitmap) c.bitmap.close()\r\n    }\r\n    this.pageBgEls.clear()\r\n    this.groupBlockIds.clear()\r\n    this.revisionBlockIds.clear()\r\n    this.blockCache.clear()\r\n    this.dirtyBlocks.clear()\r\n    for (const image of this.imageCache.values()) image.onload = null\r\n    this.imageCache.clear()\r\n    this.selectionEls = []\r\n    this.bgLayer.remove()\r\n    this.selectionLayer.remove()\r\n    this.contentCanvas.remove()\r\n    this.overlayCanvas.remove()\r\n  }\r\n\r\n  /** 更新页码配置 */\r\n  updatePageNumber(cfg: { style: string; position: 'left' | 'center' | 'right'; zone: 'header' | 'footer' } | null): void {\r\n    this.opts.pageNumber = cfg\r\n  }\r\n\r\n  /** 更新编辑区域，页眉/页脚编辑时降低正文块的不透明度。 */\n  updateActiveZone(zone: 'main' | 'header' | 'footer'): void {\n    this.activeZone = zone\n  }\n\n  /** 设置水印 widget */\r\n  setWatermarkWidget(widget: { drawWatermark(ctx: CanvasRenderingContext2D, page: import('./layout-types').PageLayout, scrollY: number): void; drawWatermarkForThumbnail(ctx: CanvasRenderingContext2D, page: import('./layout-types').PageLayout): void } | null): void {\r\n    this.watermarkWidget = widget\r\n  }\r\n\r\n\r\n  /** 将数字转为罗马数字字符串 */\r\n  private static toRoman(num: number): string {\n    const map: [number, string][] = [[1000, 'M'], [900, 'CM'], [500, 'D'], [400, 'CD'], [100, 'C'], [90, 'XC'], [50, 'L'], [40, 'XL'], [10, 'X'], [9, 'IX'], [5, 'V'], [4, 'IV'], [1, 'I']]\r\n    let result = ''\r\n    for (const [v, s] of map) {\r\n      while (num >= v) { result += s; num -= v }\r\n    }\r\n    return result\r\n  }\r\n\r\n  /** 按字母表生成从 1 开始的连续编号（A...Z, AA...）。 */\n  private static toAlphabetic(num: number, alphabet: string[]): string {\n    if (num <= 0) return String(num)\n    let result = ''\n    while (num > 0) {\n      num--\n      result = alphabet[num % alphabet.length] + result\n      num = Math.floor(num / alphabet.length)\n    }\n    return result\n  }\n\n  /** 将罗马数字转换为全角罗马数字字符。 */\n  private static toUnicodeRoman(num: number): string {\n    const map: [number, string][] = [\n      [1000, 'Ⅿ'], [900, 'ⅭⅯ'], [500, 'Ⅾ'], [400, 'ⅭⅮ'],\n      [100, 'Ⅽ'], [90, 'ⅩⅭ'], [50, 'Ⅼ'], [40, 'ⅩⅬ'],\n      [10, 'Ⅹ'], [9, 'Ⅸ'], [5, 'Ⅴ'], [4, 'Ⅳ'], [1, 'Ⅰ']\n    ]\n    let result = ''\n    for (const [value, symbol] of map) {\n      while (num >= value) { result += symbol; num -= value }\n    }\n    return result\n  }\n\n  /** 转换为英文基数词，支持到万亿级页码。 */\n  private static toEnglishNumber(num: number): string {\n    const small = ['', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Eleven', 'Twelve', 'Thirteen', 'Fourteen', 'Fifteen', 'Sixteen', 'Seventeen', 'Eighteen', 'Nineteen']\n    const tens = ['', '', 'Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety']\n    const scales = ['', 'Thousand', 'Million', 'Billion', 'Trillion']\n    if (!Number.isSafeInteger(num) || num < 0) return String(num)\n    if (num === 0) return 'Zero'\n    if (num >= 1_000_000_000_000_000) return String(num)\n\n    const underThousand = (value: number): string => {\n      if (value < 20) return small[value]\n      if (value < 100) return `${tens[Math.floor(value / 10)]}${value % 10 ? `-${small[value % 10]}` : ''}`\n      return `${small[Math.floor(value / 100)]} Hundred${value % 100 ? ` ${underThousand(value % 100)}` : ''}`\n    }\n\n    const groups: string[] = []\n    let scale = 0\n    while (num > 0) {\n      const group = num % 1000\n      if (group) groups.unshift(`${underThousand(group)}${scales[scale] ? ` ${scales[scale]}` : ''}`)\n      num = Math.floor(num / 1000)\n      scale++\n    }\n    return groups.join(' ')\n  }\n\n  /** 将英文基数词最后一个单词变为序数词。 */\n  private static toEnglishOrdinal(num: number): string {\n    const words = this.toEnglishNumber(num)\n    const irregular: Record<string, string> = {\n      one: 'first', two: 'second', three: 'third', five: 'fifth',\n      eight: 'eighth', nine: 'ninth', twelve: 'twelfth'\n    }\n    return words.replace(/[A-Za-z]+$/, word => {\n      const lower = word.toLowerCase()\n      const ordinal = irregular[lower] ?? (lower.endsWith('y')\n        ? `${lower.slice(0, -1)}ieth`\n        : `${lower}th`)\n      return ordinal[0].toUpperCase() + ordinal.slice(1)\n    })\n  }\n\n  /** 转换为英文数字序数形式，并处理 11th、12th、13th 等例外。 */\n  private static toEnglishNumericOrdinal(num: number): string {\n    const remainder100 = num % 100\n    const suffix = remainder100 >= 11 && remainder100 <= 13\n      ? 'th'\n      : num % 10 === 1 ? 'st' : num % 10 === 2 ? 'nd' : num % 10 === 3 ? 'rd' : 'th'\n    return `${num}${suffix}`\n  }\n\n  /** 将中文数字转换为日文常用大字形式。 */\n  private static toJapaneseFinancialNumber(num: number): string {\n    const replacements: Record<string, string> = {\n      一: '壱', 二: '弐', 三: '参', 四: '肆', 五: '伍',\n      六: '陸', 七: '漆', 八: '捌', 九: '玖', 十: '拾',\n      百: '佰', 千: '仟', 万: '萬', 亿: '億'\n    }\n    return this.toChineseNumber(num).replace(/[一二三四五六七八九十百千万亿]/g, char => replacements[char])\n  }\n\n  /** 将数字转为中文数字字符串（支持大写） */\r\n  private static toChineseNumber(num: number, uppercase = false): string {\n    const digits = uppercase\r\n      ? ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']\r\n      : ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']\r\n    const units = uppercase\r\n      ? ['', '拾', '佰', '仟', '萬', '億']\r\n      : ['', '十', '百', '千', '万', '亿']\r\n    if (num === 0) return digits[0]\r\n    if (num < 10) return digits[num]\r\n    if (num < 20) return (num === 10 ? units[1] : units[1] + digits[num - 10])\r\n    if (num < 100) {\r\n      const tens = Math.floor(num / 10)\r\n      const ones = num % 10\r\n      return digits[tens] + units[1] + (ones > 0 ? digits[ones] : '')\r\n    }\r\n    if (num < 1000) {\r\n      const hundreds = Math.floor(num / 100)\r\n      const rest = num % 100\r\n      let result = digits[hundreds] + units[2]\r\n      if (rest >= 10) {\r\n        result += this.toChineseNumber(rest, uppercase)\r\n      } else if (rest > 0) {\r\n        result += digits[0] + digits[rest]\r\n      }\r\n      return result\r\n    }\r\n    if (num < 10000) {\r\n      const thousands = Math.floor(num / 1000)\r\n      const rest = num % 1000\r\n      let result = digits[thousands] + units[3]\r\n      if (rest >= 100) {\r\n        result += this.toChineseNumber(rest, uppercase)\r\n      } else if (rest > 0) {\r\n        result += digits[0] + this.toChineseNumber(rest, uppercase)\r\n      }\r\n      return result\r\n    }\r\n    return String(num)\r\n  }\r\n\r\n  /**\r\n   * 在页眉/页脚区域绘制页码文本。\r\n   * @param ct 内容 canvas 上下文\r\n   * @param page 页面布局\r\n   * @param scrollY 滚动偏移\r\n   * @param totalPages 总页数\r\n   */\r\n  private drawPageNumber(\r\n    ct: CanvasRenderingContext2D,\r\n    page: { index: number; rect: { x: number; y: number; width: number; height: number }; headerRect?: { x: number; y: number; width: number; height: number } | null; footerRect?: { x: number; y: number; width: number; height: number } | null },\r\n    scrollY: number,\r\n    totalPages: number\r\n  ): void {\r\n    const cfg = this.opts.pageNumber\r\n    if (!cfg) return\r\n    const rect = cfg.zone === 'header' ? page.headerRect : page.footerRect\r\n    if (!rect) return\r\n    const text = CanvasRenderer.formatPageNumber(page.index, totalPages, cfg.style)\n    ct.save()\r\n    ct.fillStyle = '#333333'\r\n    ct.font = '12px \"Microsoft YaHei\", \"PingFang SC\", sans-serif'\r\n    const metrics = ct.measureText(text)\r\n    const textW = metrics.width\r\n    const textH = 16\r\n    const cx = page.rect.x + this.opts.pageOffsetX\r\n    let x: number\r\n    if (cfg.position === 'left') {\r\n      x = cx + rect.x - page.rect.x + 4\r\n    } else if (cfg.position === 'right') {\r\n      x = cx + rect.x - page.rect.x + rect.width - textW - 4\r\n    } else {\r\n      x = cx + rect.x - page.rect.x + (rect.width - textW) / 2\r\n    }\r\n    const baselineY = cfg.zone === 'header'\r\n      ? rect.y + rect.height - textH - 4 - scrollY\r\n      : rect.y + 4 - scrollY\r\n    ct.fillText(text, x, baselineY + textH)\r\n    ct.restore()\r\n  }\r\n\r\n  /**\r\n   * 为缩略图绘制页码（原点在页面左上角 0,0，无 scrollY/pageOffsetX）。\r\n   */\r\n  private drawPageNumberForThumbnail(\r\n    ct: CanvasRenderingContext2D,\r\n    page: { index: number; rect: { x: number; y: number; width: number; height: number }; headerRect?: { x: number; y: number; width: number; height: number } | null; footerRect?: { x: number; y: number; width: number; height: number } | null },\r\n    totalPages: number\r\n  ): void {\r\n    const cfg = this.opts.pageNumber\r\n    if (!cfg) return\r\n    const rect = cfg.zone === 'header' ? page.headerRect : page.footerRect\r\n    if (!rect) return\r\n    const text = CanvasRenderer.formatPageNumber(page.index, totalPages, cfg.style)\n    ct.save()\r\n    ct.fillStyle = '#333333'\r\n    ct.font = '12px \"Microsoft YaHei\", \"PingFang SC\", sans-serif'\r\n    const metrics = ct.measureText(text)\r\n    const textW = metrics.width\r\n    const textH = 16\r\n    const relX = rect.x - page.rect.x\r\n    const relY = rect.y - page.rect.y\r\n    let x: number\r\n    if (cfg.position === 'left') {\r\n      x = relX + 4\r\n    } else if (cfg.position === 'right') {\r\n      x = relX + rect.width - textW - 4\r\n    } else {\r\n      x = relX + (rect.width - textW) / 2\r\n    }\r\n    const baselineY = cfg.zone === 'header'\r\n      ? relY + rect.height - textH - 4\r\n      : relY + 4\r\n    ct.fillText(text, x, baselineY + textH)\r\n    ct.restore()\r\n  }\r\n\r\n  /**\r\n   * 将页码索引格式化为字符串（Word 标准格式 + 原有格式）。\r\n   * @param index 页码索引（从 0 开始）\r\n   * @param totalPages 总页数\r\n   * @param style 页码样式\r\n   * @returns 格式化后的页码字符串\r\n   */\r\n  static formatPageNumber(index: number, totalPages: number, style: string): string {\n    const n = index + 1\r\n    const greekLower = ['α', 'β', 'γ', 'δ', 'ε', 'ζ', 'η', 'θ', 'ι', 'κ', 'λ', 'μ', 'ν', 'ξ', 'ο', 'π', 'ρ', 'σ', 'τ', 'υ', 'φ', 'χ', 'ψ', 'ω']\n    switch (style) {\r\n      case '第1页': return `第${n}页`\r\n      case '第1页共x页': return `第${n}页共${totalPages}页`\r\n      case '1/x': return `${n}/${totalPages}`\r\n      case '第一页': return `第${this.toChineseNumber(n)}页`\r\n      case '第一页共X页': return `第${this.toChineseNumber(n)}页共${this.toChineseNumber(totalPages)}页`\r\n      case '1, 2, 3 ...': return String(n)\r\n      case '-1-, -2-, -3- ...': return `-${n}-`\n      case '—1—, —2—, —3— ...': return `—${n}—`\n      case '①, ②, ③ ...':\n        if (n <= 20) return String.fromCodePoint(0x245f + n)\n        if (n <= 35) return String.fromCodePoint(0x3250 + n - 20)\n        if (n <= 50) return String.fromCodePoint(0x32b0 + n - 35)\n        return String(n)\n      case 'I, II, III ...': return this.toRoman(n).toUpperCase()\r\n      case 'i, ii, iii ...': return this.toRoman(n).toLowerCase()\r\n      case 'Ⅰ, Ⅱ, Ⅲ ...': return this.toUnicodeRoman(n)\n      case 'A, B, C ...': return this.toAlphabetic(n, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''))\n      case 'a, b, c ...': return this.toAlphabetic(n, 'abcdefghijklmnopqrstuvwxyz'.split(''))\n      case '一, 二, 三 ...': return this.toChineseNumber(n)\r\n      case '壹, 贰, 叁 ...': return this.toChineseNumber(n, true)\r\n      case '甲, 乙, 丙 ...': return '甲乙丙丁戊己庚辛壬癸'[(n - 1) % 10]\n      case '子, 丑, 寅 ...': return '子丑寅卯辰巳午未申酉戌亥'[(n - 1) % 12]\n      case '壱, 弐, 参 ...': return this.toJapaneseFinancialNumber(n)\n      case 'α, β, γ ...': return this.toAlphabetic(n, greekLower)\n      case '1st, 2nd, 3rd ...': return this.toEnglishNumericOrdinal(n)\n      case 'One, Two, Three ...': return this.toEnglishNumber(n)\n      case 'First, Second, Third ...': return this.toEnglishOrdinal(n)\n      default: return String(n)\r\n    }\r\n  }\r\n\r\n\r\n  /* -------------------- 光标 / 选区（Overlay） -------------------- */\r\n\r\n  /**\r\n\r\n   * 绘制选区高亮（DOM div 池）。传入文档坐标矩形列表，内部应用 scrollY 与 pageOffsetX。\r\n   */\r\n  drawSelection(rects: { x: number; y: number; width: number; height: number }[], scrollY: number): void {\r\n    for (let i = 0; i < rects.length; i++) {\r\n      const r = rects[i]\r\n      let el = this.selectionEls[i]\r\n      if (!el) {\r\n        el = document.createElement('div')\r\n        el.className = 'vd-selection'\r\n        el.style.position = 'absolute'\r\n        el.style.background = 'rgba(77, 146, 255, 0.3)'\r\n        el.style.pointerEvents = 'none'\r\n        this.selectionLayer.appendChild(el)\r\n        this.selectionEls[i] = el\r\n      }\r\n      el.style.display = 'block'\r\n      el.style.left = `${Math.round(r.x + this.opts.pageOffsetX)}px`\r\n      el.style.top = `${Math.round(r.y - scrollY)}px`\r\n      el.style.width = `${Math.round(r.width)}px`\r\n      el.style.height = `${Math.round(r.height)}px`\r\n    }\r\n    for (let i = rects.length; i < this.selectionEls.length; i++) {\r\n      this.selectionEls[i].style.display = 'none'\r\n    }\r\n  }\r\n\r\n  /** 清除 overlay canvas 上的光标/zone，并隐藏选区 div */\r\n  clearOverlay(): void {\r\n    this.overlayCtx.clearRect(0, 0, this.cssWidth, this.cssHeight)\r\n    for (const el of this.selectionEls) el.style.display = 'none'\r\n  }\r\n\r\n  /** 绘制页眉/页脚编辑区域的虚线边框（参照 Word：紧贴可输入内容区域的矩形边框） */\r\n  drawZoneBorder(\r\n    layout: DocumentLayout,\r\n    scrollY: number,\r\n    zone: 'header' | 'footer',\r\n    pageOffsetX: number\r\n  ): void {\r\n    const ov = this.overlayCtx\r\n    ov.save()\r\n    ov.strokeStyle = this.opts.rulerColor\r\n    ov.lineWidth = 1\r\n    ov.setLineDash([4, 3])\r\n    for (const page of layout.pages) {\r\n      const rect = zone === 'header' ? page.headerRect : page.footerRect\r\n      if (!rect) continue\r\n      const pageBottom = page.rect.y + page.rect.height\r\n      if (pageBottom < scrollY || page.rect.y > scrollY + this.cssHeight) continue\r\n\r\n      const blocks = zone === 'header' ? page.headerBlocks : page.footerBlocks\r\n      // 虚线矩形紧贴可输入内容区域，并留出 4px 视觉间距：\r\n      // - 页眉：顶部在内容上方 4px，底部对齐边距区域下沿（正文顶部）\r\n      // - 页脚：顶部对齐边距区域上沿（正文底部），底部在内容下方 4px\r\n      const PADDING = 20\r\n      const pageTop = page.rect.y\r\n      const clampY = (value: number, min: number, max: number) => Math.max(min, Math.min(max, value))\r\n      let top: number\r\n      let bottom: number\r\n      if (zone === 'header') {\r\n        bottom = clampY(rect.y + rect.height, pageTop, pageBottom)\r\n        if (blocks && blocks.length > 0) {\r\n          const contentTop = Math.min(...blocks.map(b => b.rect.y))\r\n          top = clampY(rect.y + contentTop - PADDING, pageTop, bottom)\r\n        } else {\r\n          top = clampY(rect.y, pageTop, bottom)\r\n        }\r\n      } else {\r\n        top = clampY(rect.y, pageTop, pageBottom)\r\n        if (blocks && blocks.length > 0) {\r\n          const contentBottom = Math.max(...blocks.map(b => b.rect.y + b.rect.height))\r\n          bottom = clampY(rect.y + contentBottom + PADDING, top, pageBottom)\r\n        } else {\r\n          bottom = clampY(rect.y + rect.height, top, pageBottom)\r\n        }\r\n      }\r\n\r\n      const pageLeft = page.rect.x\r\n      const pageRight = page.rect.x + page.rect.width\r\n      const left = Math.max(pageLeft, Math.min(pageRight, rect.x))\r\n      const right = Math.max(left, Math.min(pageRight, rect.x + rect.width))\r\n      const x = Math.round(left + pageOffsetX) + 0.5\r\n      const y = Math.round(top - scrollY) + 0.5\r\n      const w = Math.max(0, Math.round(right - left) - 1)\r\n      const h = Math.max(0, Math.round(bottom - top) - 1)\r\n\r\n      // 只绘制三边虚线（靠近正文的一侧由贯穿整页的分隔虚线代替，避免重叠）：\r\n      // - 页眉：上 + 左 + 右（不画底部）\r\n      // - 页脚：下 + 左 + 右（不画顶部）\r\n      ov.beginPath()\r\n      if (zone === 'header') {\r\n        // 上边\r\n        ov.moveTo(x, y)\r\n        ov.lineTo(x + w, y)\r\n        // 左边\r\n        ov.moveTo(x, y)\r\n        ov.lineTo(x, y + h)\r\n        // 右边\r\n        ov.moveTo(x + w, y)\r\n        ov.lineTo(x + w, y + h)\r\n      } else {\r\n        // 下边\r\n        ov.moveTo(x, y + h)\r\n        ov.lineTo(x + w, y + h)\r\n        // 左边\r\n        ov.moveTo(x, y)\r\n        ov.lineTo(x, y + h)\r\n        // 右边\r\n        ov.moveTo(x + w, y)\r\n        ov.lineTo(x + w, y + h)\r\n      }\r\n      ov.stroke()\r\n\r\n      // 贯穿整页宽度的分隔虚线（页眉：正文顶部；页脚：正文底部）\r\n      const fullLineStartX = Math.round(page.rect.x + pageOffsetX) + 0.5\r\n      const fullLineEndX = fullLineStartX + Math.round(page.rect.width) - 1\r\n      const dividerY = zone === 'header'\r\n        ? Math.round(bottom - scrollY) + 0.5\r\n        : Math.round(top - scrollY) + 0.5\r\n      ov.beginPath()\r\n      ov.moveTo(fullLineStartX, dividerY)\r\n      ov.lineTo(fullLineEndX, dividerY)\r\n      ov.stroke()\r\n    }\r\n    ov.restore()\r\n  }\r\n\r\n\r\n  /**\r\n   * 渲染一帧。\r\n   *   - 视口过滤：只处理与视口相交的页\r\n   *   - block bitmap：按需构建（首次 / dirty）\r\n   *   - 主 canvas：clear + drawImage\r\n   */\r\n  render(layout: DocumentLayout, scrollY: number, viewportHeight: number, dirtyRect?: { x: number; y: number; width: number; height: number } | null): void {\r\n    this.currentLayout = layout\r\n    const ct = this.contentCtx\r\n    const w = this.cssWidth\r\n    const h = this.cssHeight\r\n    const pageCount = layout.pages.length\r\n    const aliveIds = new Set<number>()\r\n\r\n    // 脏区域合成：无重排局部变更时只清 + 重画脏区域，不重画 bg，跳过 GC\r\n    if (dirtyRect) {\r\n      if (dirtyRect.width <= 0 || dirtyRect.height <= 0) return\r\n\r\n      // Expand to physical pixel boundaries; rounding just the origin can leave\r\n      // partially cleared rows when a fractional-height header intersects a table.\r\n      const dpr = this.opts.dpr\r\n      const dx = Math.floor((dirtyRect.x + this.opts.pageOffsetX) * dpr) / dpr\r\n      const dy = Math.floor((dirtyRect.y - scrollY) * dpr) / dpr\r\n      const dw = Math.ceil((dirtyRect.x + dirtyRect.width + this.opts.pageOffsetX) * dpr) / dpr - dx\r\n      const dh = Math.ceil((dirtyRect.y + dirtyRect.height - scrollY) * dpr) / dpr - dy\r\n      const dTop = dirtyRect.y\r\n      const dBottom = dirtyRect.y + dirtyRect.height\r\n\r\n      ct.clearRect(dx, dy, dw, dh)\r\n      ct.save()\r\n      ct.beginPath()\r\n      ct.rect(dx, dy, dw, dh)\r\n      ct.clip()\r\n      for (const page of layout.pages) {\r\n        const pageBottom = page.rect.y + page.rect.height\r\n        if (pageBottom < dTop || page.rect.y > dBottom ||\r\n            pageBottom < scrollY || page.rect.y > scrollY + viewportHeight) continue\r\n        this.renderPageContent(ct, page, scrollY, pageCount, aliveIds)\r\n      }\r\n      ct.restore()\r\n      this.trimCache()\r\n      return\r\n    }\r\n\r\n    // 全量\r\n\r\n    ct.clearRect(0, 0, w, h)\r\n    const viewTop = scrollY\r\n    const viewBottom = scrollY + viewportHeight\r\n\r\n    this.renderBgDom(layout, scrollY, viewportHeight)\r\n\r\n    for (const page of layout.pages) {\r\n      const pageBottom = page.rect.y + page.rect.height\r\n      if (pageBottom < viewTop || page.rect.y > viewBottom) continue\r\n      this.renderPageContent(ct, page, scrollY, pageCount, aliveIds)\r\n    }\r\n\r\n    this.trimCache()\r\n  }\r\n\r\n  /** 渲染每页背景 DOM div（带 data-index 供协同光标定位） */\r\n  private renderBgDom(layout: DocumentLayout, scrollY: number, viewportHeight: number): void {\r\n    const viewTop = scrollY\r\n    const viewBottom = scrollY + viewportHeight\r\n    const alive = new Set<number>()\r\n    for (const page of layout.pages) {\r\n      const pageBottom = page.rect.y + page.rect.height\r\n      if (pageBottom < viewTop || page.rect.y > viewBottom) continue\r\n      alive.add(page.index)\r\n      let el = this.pageBgEls.get(page.index)\r\n      if (!el) {\r\n        el = document.createElement('div')\r\n        el.className = 'vd-page-bg'\r\n        el.dataset.index = String(page.index)\r\n        el.style.position = 'absolute'\r\n        el.style.boxShadow = `0 4px 12px ${this.opts.pageShadow}`\r\n        el.style.pointerEvents = 'none'\r\n        this.bgLayer.appendChild(el)\r\n        this.pageBgEls.set(page.index, el)\r\n      }\r\n      el.style.background = `var(--vd-eye-care-bg, ${this.opts.pageBg})`\r\n      el.style.left = `${Math.round(page.rect.x + this.opts.pageOffsetX)}px`\r\n      el.style.top = `${Math.round(page.rect.y - scrollY)}px`\r\n      el.style.width = `${page.rect.width}px`\r\n      el.style.height = `${page.rect.height}px`\r\n      if (this.opts.showMarginRuler) {\r\n        this.renderMarginRuler(el, page)\r\n      }\r\n    }\r\n    for (const [idx, el] of this.pageBgEls) {\r\n      if (!alive.has(idx)) { el.remove(); this.pageBgEls.delete(idx) }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 绘制 WPS 风格四角边距标尺（SVG，DOM）。内容区四角的角标朝外伸入页边距。\r\n   * 用签名缓存避免每帧重建 SVG。\r\n   */\r\n  private renderMarginRuler(el: HTMLDivElement, page: PageLayout): void {\r\n    const { width: pw, height: ph } = page.rect\r\n    const ml = page.contentRect.x - page.rect.x\r\n    const mt = page.contentRect.y - page.rect.y\r\n    const mr = pw - ml - page.contentRect.width\r\n    const mb = ph - mt - page.contentRect.height\r\n    const color = this.opts.rulerColor\r\n    const L = 20\r\n    const sig = `${pw}|${ph}|${ml}|${mr}|${mt}|${mb}|${color}`\r\n    if (el.dataset.rulerSig === sig) return\r\n    el.dataset.rulerSig = sig\r\n    const corners = [\r\n      `${ml - L},${mt} ${ml},${mt} ${ml},${mt - L}`,\r\n      `${pw - mr + L},${mt} ${pw - mr},${mt} ${pw - mr},${mt - L}`,\r\n      `${ml - L},${ph - mb} ${ml},${ph - mb} ${ml},${ph - mb + L}`,\r\n      `${pw - mr + L},${ph - mb} ${pw - mr},${ph - mb} ${pw - mr},${ph - mb + L}`\r\n    ]\r\n    el.innerHTML = `<svg xmlns=\"http://www.w3.org/2000/svg\" style=\"position:absolute;inset:0;width:100%;height:100%;pointer-events:none\" fill=\"none\" stroke=\"${color}\" stroke-width=\"1\">${corners.map(p => `<polyline points=\"${p}\"/>`).join('')}</svg>`\r\n  }\r\n\r\n  /** 渲染单页内容：blocks + 页眉 + 页脚 + 页码 + 水印 */\r\n  private renderPageContent(ct: CanvasRenderingContext2D, page: PageLayout, scrollY: number, pageCount: number, aliveIds: Set<number>): void {\r\n    const contentOriginX = page.contentRect.x + this.opts.pageOffsetX\r\n    const contentOriginY = page.contentRect.y - scrollY\r\n    const layer = (block: BlockNode): number => block.kind === 'image'\r\n      ? ((block.block as IImageElement).imgDisplay === 'float-bottom' ? -1 : (block.block as IImageElement).imageLayout?.anchored ? 1 : 0) : 0\r\n    ct.save()\n    if (this.activeZone !== 'main') ct.globalAlpha *= 0.42\n    for (const b of [...page.blocks].sort((a, b) => layer(a) - layer(b))) {\r\n      this.renderBlockOnMain(ct, b, contentOriginX, contentOriginY, aliveIds)\r\n    }\r\n    ct.restore()\n    if (page.headerBlocks && page.headerRect) {\r\n      const hx = page.headerRect.x + this.opts.pageOffsetX\r\n      const hy = page.headerRect.y - scrollY\r\n      for (const b of page.headerBlocks) {\r\n        this.renderBlockOnMain(ct, b, hx, hy, aliveIds)\r\n      }\r\n    }\r\n    if (page.footerBlocks && page.footerRect) {\r\n      const fx = page.footerRect.x + this.opts.pageOffsetX\r\n      const fy = page.footerRect.y - scrollY\r\n      for (const b of page.footerBlocks) {\r\n        this.renderBlockOnMain(ct, b, fx, fy, aliveIds)\r\n      }\r\n    }\r\n    this.drawPageNumber(ct, page, scrollY, pageCount)\r\n    this.watermarkWidget?.drawWatermark(ct, page, scrollY)\r\n  }\r\n\r\n  /**\r\n   * 渲染单个 block 到主 content canvas：按需构建/复用位图，再 drawImage 落位。\r\n   * @param ctx 主 canvas 2d 上下文\r\n   * @param b 待渲染块\r\n   * @param originX 块所属内容区在 canvas 上的 x 原点\r\n   * @param originY 块所属内容区在 canvas 上的 y 原点（已应用 scrollY）\r\n   * @param aliveIds 收集本帧使用中的 block id，用于 GC 旧位图\r\n   */\r\n  private renderBlockOnMain(\r\n    ctx: CanvasRenderingContext2D,\r\n    b: BlockNode,\r\n    originX: number,\r\n    originY: number,\r\n    aliveIds: Set<number>\r\n  ): void {\r\n    aliveIds.add(b.id)\r\n    if (b.kind === 'pageBreak') return\r\n    if (b.kind === 'block') return\r\n    const bx = originX + b.rect.x\r\n    const by = originY + b.rect.y\r\n\r\n    // 分割线：直接在主 canvas 上按样式画线（简单图形，不走 bitmap 缓存）\r\n    if (b.kind === 'separator') {\r\n      this.drawSeparator(ctx, b, bx, by)\r\n      return\r\n    }\r\n\r\n    // table 不做整表 bitmap（cell 内容可能常变），直接递归绘制到主 canvas\r\n    if (b.kind === 'table') {\r\n      this.drawTable(ctx, b, bx, by, aliveIds)\r\n      return\r\n    }\r\n\r\n    // 其它块使用 block bitmap 缓存\r\n    const cache = this.blockCache.get(b.id)\r\n    const needRebuild = !cache || this.dirtyBlocks.has(b.id) ||\r\n      Math.round(cache.width) !== Math.round(b.rect.width) ||\r\n      Math.round(cache.height) !== Math.round(b.rect.height) ||\r\n      cache.dpr !== this.opts.dpr\r\n\r\n    let bitmap: HTMLCanvasElement | ImageBitmap | null\r\n    if (needRebuild) {\r\n      if (cache?.bitmap instanceof ImageBitmap) cache.bitmap.close()\r\n      bitmap = this.buildBlockBitmap(b)\r\n      this.blockCache.set(b.id, {\r\n        id: b.id,\r\n        bitmap,\r\n        width: b.rect.width,\r\n        height: b.rect.height,\r\n        dpr: this.opts.dpr\r\n      })\r\n      this.dirtyBlocks.delete(b.id)\r\n    } else {\r\n      bitmap = cache!.bitmap\r\n      this.blockCache.delete(b.id)\r\n      this.blockCache.set(b.id, cache!)\r\n    }\r\n    if (bitmap) {\r\n      ctx.drawImage(bitmap, Math.round(bx), Math.round(by), b.rect.width, b.rect.height)\r\n    }\r\n  }\r\n\r\n\r\n  /** 绘制分割线，按元素上的 lineType/lineWidth/dashArray/color 渲染 */\r\n  private drawSeparator(ctx: CanvasRenderingContext2D, b: SeparatorBlock, bx: number, by: number): void {\r\n    const anyBlock = b.block as unknown as Record<string, unknown>\r\n    const lineType = (anyBlock.lineType as string) || 'solid'\r\n    const lineWidth = Number(anyBlock.lineWidth ?? 1)\r\n    const dashArray = Array.isArray(anyBlock.dashArray) ? (anyBlock.dashArray as number[]) : [0, 0]\r\n    const color = (anyBlock.color as string) || '#9e9e9e'\r\n    const x0 = Math.round(bx)\r\n    const x1 = Math.round(bx + b.rect.width)\r\n    const cy = by + Math.round(b.rect.height / 2)\r\n\r\n    ctx.save()\r\n    ctx.strokeStyle = color\r\n    ctx.lineWidth = lineWidth\r\n    ctx.lineCap = 'butt'\r\n\r\n    if (lineType === 'wavy') {\r\n      // 波浪线：用正弦近似，振幅随线宽\r\n      const amp = Math.max(1.5, lineWidth * 1.5)\r\n      const wave = 6\r\n      ctx.beginPath()\r\n      for (let x = x0; x <= x1; x += 1) {\r\n        const y = cy + amp * Math.sin(((x - x0) / wave) * Math.PI)\r\n        if (x === x0) { ctx.moveTo(x, y) } else { ctx.lineTo(x, y) }\r\n      }\r\n      ctx.stroke()\r\n    } else if (lineType === 'double' || lineType === 'triple') {\r\n      const gap = Math.max(2, lineWidth + 1.5)\r\n      const lines = lineType === 'triple' ? [-gap, 0, gap] : [-gap / 2, gap / 2]\r\n      ctx.setLineDash(dashArray)\r\n      for (const off of lines) {\r\n        ctx.beginPath()\r\n        ctx.moveTo(x0, Math.round(cy + off) + 0.5)\r\n        ctx.lineTo(x1, Math.round(cy + off) + 0.5)\r\n        ctx.stroke()\r\n      }\r\n    } else if (lineType === 'shadow') {\r\n      // 阴影线：主线下方画一条浅色偏移线\r\n      ctx.beginPath()\r\n      ctx.moveTo(x0, Math.round(cy) + 0.5)\r\n      ctx.lineTo(x1, Math.round(cy) + 0.5)\r\n      ctx.stroke()\r\n      ctx.strokeStyle = 'rgba(0,0,0,0.25)'\r\n      ctx.beginPath()\r\n      ctx.moveTo(x0, Math.round(cy + 1.5) + 0.5)\r\n      ctx.lineTo(x1, Math.round(cy + 1.5) + 0.5)\r\n      ctx.stroke()\r\n    } else if (lineType === 'emboss') {\r\n      // 浮雕线：上亮下暗\r\n      ctx.strokeStyle = 'rgba(255,255,255,0.8)'\r\n      ctx.beginPath()\r\n      ctx.moveTo(x0, Math.round(cy - 0.75) + 0.5)\r\n      ctx.lineTo(x1, Math.round(cy - 0.75) + 0.5)\r\n      ctx.stroke()\r\n      ctx.strokeStyle = 'rgba(0,0,0,0.5)'\r\n      ctx.beginPath()\r\n      ctx.moveTo(x0, Math.round(cy + 0.75) + 0.5)\r\n      ctx.lineTo(x1, Math.round(cy + 0.75) + 0.5)\r\n      ctx.stroke()\r\n    } else if (lineType === 'gradient') {\r\n      // 渐变线：左透明右实色\r\n      const grad = ctx.createLinearGradient(x0, 0, x1, 0)\r\n      grad.addColorStop(0, 'rgba(158,158,158,0)')\r\n      grad.addColorStop(1, color)\r\n      ctx.strokeStyle = grad\r\n      ctx.beginPath()\r\n      ctx.moveTo(x0, Math.round(cy) + 0.5)\r\n      ctx.lineTo(x1, Math.round(cy) + 0.5)\r\n      ctx.stroke()\r\n    } else {\r\n      // solid / dotted / dashed\r\n      ctx.setLineDash(dashArray)\r\n      ctx.beginPath()\r\n      ctx.moveTo(x0, Math.round(cy) + 0.5)\r\n      ctx.lineTo(x1, Math.round(cy) + 0.5)\r\n      ctx.stroke()\r\n    }\r\n    ctx.restore()\r\n  }\r\n\r\n  /**\r\n   * 为单个 block 构建独立位图（paragraph/image）。\r\n   * 优先使用 OffscreenCanvas + transferToImageBitmap（零拷贝），不支持时降级 HTMLCanvasElement。\r\n   * @param b 待构建块（仅处理 paragraph/image，其它类型返回空位图）\r\n   * @returns 渲染好块内容的 ImageBitmap 或 canvas 元素\r\n   */\r\n  private buildBlockBitmap(b: BlockNode): HTMLCanvasElement | ImageBitmap {\r\n    const dpr = this.opts.dpr\r\n    const w = Math.max(1, Math.ceil(b.rect.width))\r\n    const h = Math.max(1, Math.ceil(b.rect.height))\r\n    const pw = Math.max(1, Math.round(w * dpr))\r\n    const ph = Math.max(1, Math.round(h * dpr))\r\n\r\n    let ctx: PaintCtx\r\n    let off: OffscreenCanvas | null = null\r\n    let c: HTMLCanvasElement | null = null\r\n    if (typeof OffscreenCanvas !== 'undefined') {\r\n      off = new OffscreenCanvas(pw, ph)\r\n      ctx = off.getContext('2d')!\r\n    } else {\r\n      c = document.createElement('canvas')\r\n      c.width = pw\r\n      c.height = ph\r\n      ctx = c.getContext('2d')!\r\n    }\r\n    ctx.setTransform(dpr, 0, 0, dpr, 0, 0)\r\n\r\n    if (b.kind === 'paragraph') {\r\n      if (b.surroundImage) {\r\n        const si = b.surroundImage\r\n        const sx = si.rect.x\r\n        const sy = 0\r\n        const mode = String((si.block as unknown as { imgDisplay?: string }).imgDisplay ?? 'surround')\r\n        if (mode === 'float-bottom') {\r\n          this.drawImageInto(ctx, si, sx, sy)\r\n          this.drawParagraphInto(ctx, b)\r\n        } else {\r\n          this.drawParagraphInto(ctx, b)\r\n          if (mode === 'surround') {\r\n            ctx.clearRect(sx, sy, si.rect.width, si.rect.height)\r\n          }\r\n          this.drawImageInto(ctx, si, sx, sy)\r\n        }\r\n      } else {\r\n        this.drawParagraphInto(ctx, b)\r\n      }\r\n    }\r\n    else if (b.kind === 'image') this.drawImageInto(ctx, b, 0, 0)\r\n    else if (b.kind === 'chart') this.drawChartInto(ctx, b, 0, 0)\r\n\r\n    if (off) return off.transferToImageBitmap()\r\n    return c!\r\n  }\r\n\r\n  /**\r\n   * 将段落块绘制到目标 ctx：委托共享纯函数 paintParagraph。\r\n   * @param ctx 目标 2d 上下文\r\n   * @param b 段落块\r\n   */\r\n  private drawParagraphInto(ctx: PaintCtx, b: ParagraphBlock): void {\r\n    paintParagraph(ctx, b, { groupColors: this.opts.groupColors, activeGroupId: this.opts.activeGroupId, activeRevision: this.activeRevision, printing: this.printing })\r\n  }\r\n\r\n\r\n  /**\r\n   * 绘制图片块；WordArt 直接使用 Canvas 文本接口，其余图片异步加载。\n   * @param ctx 目标 2d 上下文\r\n   * @param b 图片块\r\n   * @param x 绘制左上角 x\r\n   * @param y 绘制左上角 y\r\n   */\r\n  private drawImageInto(ctx: PaintCtx, b: ImageBlock, x: number, y: number): void {\r\n    const image = b.block as IImageElement\n    if (image.wordArt) {\n      this.drawWordArtInto(ctx, b, x, y, image.wordArt)\n      return\n    }\n\n    const url = String(image.value ?? '')\n    if (!url) return\r\n    let img = this.imageCache.get(url)\r\n    if (!img) {\r\n      img = new Image()\r\n      img.crossOrigin = 'anonymous'\r\n      if (!this.printing) img.onload = () => {\r\n        // 图片加载完成 → 使该 block 失效 + 触发全局重绘\r\n        this.invalidateAll()\r\n        this.container.dispatchEvent(new CustomEvent('vervedocs:image-loaded', { detail: { url } }))\r\n      }\r\n      img.src = url\r\n      this.imageCache.set(url, img)\r\n    }\r\n    if (this.printResources) {\r\n      this.printResources.add(img)\r\n      return\r\n    }\r\n    const transform = image.imageLayout?.transform?.attributes\r\n    const rotate = Number(transform?.rot ?? (image.rotate ?? 0) * 60000) / 60000\r\n    if (img.complete && img.naturalWidth > 0) {\r\n      const crop = image.imageLayout?.crop?.attributes\r\n      const l = Number(crop?.l ?? 0) / 100000\r\n      const t = Number(crop?.t ?? 0) / 100000\r\n      const r = Number(crop?.r ?? 0) / 100000\r\n      const bottom = Number(crop?.b ?? 0) / 100000\r\n      const dw = image.width\r\n      const dh = image.height\r\n      ctx.save()\r\n      try {\r\n        ctx.translate(x + b.rect.width / 2, y + b.rect.height / 2)\r\n        ctx.rotate((rotate * Math.PI) / 180)\r\n        ctx.scale(transform?.flipH === '1' || transform?.flipH === 'true' ? -1 : 1,\r\n          transform?.flipV === '1' || transform?.flipV === 'true' ? -1 : 1)\r\n        ctx.beginPath()\r\n        ctx.rect(-dw / 2, -dh / 2, dw, dh)\r\n        ctx.clip()\r\n        const scaledWidth = dw / (1 - l - r)\r\n        const scaledHeight = dh / (1 - t - bottom)\r\n        ctx.drawImage(img, -dw / 2 - l * scaledWidth, -dh / 2 - t * scaledHeight, scaledWidth, scaledHeight)\r\n      } finally {\r\n        ctx.restore()\r\n      }\r\n    } else {\r\n      ctx.strokeStyle = '#cccccc'\r\n      ctx.strokeRect(x + 0.5, y + 0.5, b.rect.width - 1, b.rect.height - 1)\r\n      ctx.fillStyle = '#f5f5f5'\r\n      ctx.fillRect(x, y, b.rect.width, b.rect.height)\r\n    }\r\n  }\r\n\r\n  /** 直接绘制 VML WordArt 文本，不经过 SVG 或图片解码。 */\n  private drawWordArtInto(\n    ctx: PaintCtx,\n    b: ImageBlock,\n    x: number,\n    y: number,\n    wordArt: NonNullable<IImageElement['wordArt']>,\n  ): void {\n    const lines = wordArt.text.split(/\\r\\n|\\r|\\n/)\n    const fontSize = wordArt.fontSize || b.rect.width\n    const height = (b.block as IImageElement).height || b.rect.height\n    const top = Math.max(0, (height - lines.length * fontSize) / 2)\n    const fontFamily = wordArt.fontFamily.replace(/[\"\\\\]/g, '\\\\$&')\n\n    ctx.save()\n    try {\n      ctx.font = `${fontSize}px \"${fontFamily}\", serif`\n      ctx.fillStyle = wordArt.fillColor || '#000000'\n      ctx.textAlign = 'center'\n      ctx.textBaseline = 'alphabetic'\n      lines.forEach((line, index) => {\n        if (line) ctx.fillText(line, x + b.rect.width / 2, y + top + (index + 1) * fontSize)\n      })\n    } finally {\n      ctx.restore()\n    }\n  }\n\n  /**\r\n   * 将图表块绘制到目标 ctx：从 chartBlock 数据生成 dataUrl，加载为 Image 后 drawImage。\r\n   * 数据源变更时由 signBlock 触发 bitmap 重建。\r\n   */\r\n  private drawChartInto(ctx: PaintCtx, b: ChartBlock, x: number, y: number): void {\r\n    const el = b.block as unknown as {\r\n      id?: string\r\n      block?: { chartBlock?: Record<string, unknown> }\r\n    }\r\n    const chartBlock = el.block?.chartBlock\r\n    if (!chartBlock) return\r\n\r\n    const renderer = this.chartRenderer\r\n    if (!renderer) {\r\n      ctx.strokeStyle = '#cccccc'\r\n      ctx.strokeRect(x + 0.5, y + 0.5, b.rect.width - 1, b.rect.height - 1)\r\n      ctx.fillStyle = '#f5f5f5'\r\n      ctx.fillRect(x, y, b.rect.width, b.rect.height)\r\n      ctx.fillStyle = '#999'\r\n      ctx.font = '14px sans-serif'\r\n      ctx.textAlign = 'center'\r\n      ctx.textBaseline = 'middle'\r\n      ctx.fillText('图表插件未加载', x + b.rect.width / 2, y + b.rect.height / 2)\r\n      return\r\n    }\r\n\r\n    const dependency = this.currentLayout ? chartTableSignature(b, this.currentLayout) : ''\r\n    const cacheKey = `chart|${el.id ?? ''}|${b.rect.width}x${b.rect.height}|${JSON.stringify(chartBlock)}|${dependency}`\r\n    let img = this.imageCache.get(cacheKey)\r\n    if (!img) {\r\n      const option = this.getChartOption(chartBlock, renderer)\r\n      const width = Math.max(10, Math.round(b.rect.width))\r\n      const height = Math.max(10, Math.round(b.rect.height))\r\n      const dataUrl = renderer.renderToDataUrl(option, width, height, 2)\r\n      img = new Image()\r\n      if (!this.printing) img.onload = () => {\r\n        this.invalidateAll()\r\n        this.container.dispatchEvent(new CustomEvent('vervedocs:chart-loaded', { detail: { id: el.id } }))\r\n      }\r\n      img.src = dataUrl\r\n      this.imageCache.set(cacheKey, img)\r\n    }\r\n    if (this.printResources) {\r\n      this.printResources.add(img)\r\n      return\r\n    }\r\n\r\n    if (img.complete && img.naturalWidth > 0) {\r\n      try {\r\n        ctx.drawImage(img, x, y, b.rect.width, b.rect.height)\r\n      } catch { /* ignore */ }\r\n    } else {\r\n      ctx.strokeStyle = '#cccccc'\r\n      ctx.strokeRect(x + 0.5, y + 0.5, b.rect.width - 1, b.rect.height - 1)\r\n      ctx.fillStyle = '#f5f5f5'\r\n      ctx.fillRect(x, y, b.rect.width, b.rect.height)\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 根据图表数据源生成图表配置选项。\r\n   * manual 数据直接使用；table 数据从布局中查找对应表格元素提取。\r\n   */\r\n  private getChartOption(chartBlock: Record<string, unknown>, renderer: IChartRenderer): any {\r\n    const { dataSource, chartType, config, subtype } = chartBlock as {\r\n      dataSource: { type: string; manualData?: any; tableId?: string; range?: any }\r\n      chartType: string\r\n      config?: any\r\n      subtype?: string\r\n    }\r\n\r\n    if (dataSource?.type === 'manual' && dataSource.manualData) {\r\n      return renderer!.generateOption(chartType, dataSource.manualData, config, subtype)\r\n    }\r\n\r\n    if (dataSource?.type === 'table' && dataSource.tableId && this.currentLayout) {\r\n      for (const page of this.currentLayout.pages) {\r\n        for (const blk of page.blocks) {\r\n          if (blk.kind === 'table') {\r\n            const tableEl = blk.block as unknown as { type?: string; id?: string }\r\n            if (tableEl.type === 'table' && tableEl.id === dataSource.tableId) {\r\n              const tableData = renderer!.extractTableData(tableEl, dataSource.range)\r\n              return renderer!.generateOption(chartType, tableData, config, subtype)\r\n            }\r\n          }\r\n        }\r\n      }\r\n    }\r\n\r\n    return {\r\n      type: 'bar',\r\n      data: { labels: [], datasets: [] },\r\n      options: { plugins: { title: { display: true, text: '暂无数据' } } }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 绘制表格块到主 canvas：依次绘制单元格背景色、单元格内容、统一边框（共享边去重）与斜线。\r\n   * @param ctx 主 canvas 2d 上下文\r\n   * @param b 表格块\r\n   * @param bx 表格左上角在 canvas 上的 x\r\n   * @param by 表格左上角在 canvas 上的 y\r\n   * @param aliveIds 收集本帧使用中的 block id，用于 GC\r\n   */\r\n  private drawTable(\r\n    ctx: CanvasRenderingContext2D,\r\n    b: TableBlock,\r\n    bx: number,\r\n    by: number,\r\n    aliveIds: Set<number>\r\n  ): void {\r\n    // 1) 先绘制所有单元格背景色（如有）\r\n    for (const row of b.rows) {\r\n      for (const cell of row.cells) {\r\n        const bg = (cell.cell as unknown as { backgroundColor?: string }).backgroundColor\r\n        if (bg) {\r\n          const cx = Math.round(bx + cell.rect.x)\r\n          const cy = Math.round(by + cell.rect.y)\r\n          const cw = Math.round(cell.rect.width)\r\n          const ch = Math.round(cell.rect.height)\r\n          ctx.fillStyle = bg\r\n          ctx.fillRect(cx, cy, cw, ch)\r\n        }\r\n      }\r\n    }\r\n    // 2) 绘制单元格内容（不含边框）\r\n    for (const row of b.rows) {\r\n      for (const cell of row.cells) {\r\n        const cx = bx + cell.rect.x\r\n        const cy = by + cell.rect.y\r\n        const contentX = cx + cell.contentPaddingLeft\r\n        const contentY = cy + cell.contentPaddingTop + cell.verticalOffset\r\n        for (const cb of cell.content) {\r\n          this.renderBlockOnMain(ctx, cb, contentX, contentY, aliveIds)\r\n        }\r\n      }\r\n    }\r\n    // 3) 统一绘制边框（每条网格边只画一次，避免共享边被重复描绘制造成\"边框加深/重影\"）\r\n    // 用\"边端点 + 方向\"做去重：相邻两个 cell 的共享边、跨行格下探边都会折叠为一条。\r\n    // 像素对齐沿用 strokeSide（奇数宽 +0.5）。\r\n    type BorderSide = { width: number; color: string; style: string; officeType?: string; source?: string; sizeEighthPoints?: number }\r\n    type Edge = { x1: number; y1: number; x2: number; y2: number; side: BorderSide }\r\n    const edges: Edge[] = []\r\n    const edgeKey = (x1: number, y1: number, x2: number, y2: number): string => {\r\n      // 归一化端点（保证横边/竖边方向唯一），保留 0.5px 精度避免浮点抖动\r\n      const a1 = Math.round(x1 * 2) / 2, b1 = Math.round(y1 * 2) / 2\r\n      const a2 = Math.round(x2 * 2) / 2, b2 = Math.round(y2 * 2) / 2\r\n      if (a1 === a2 && b1 === b2) return ''\r\n      // 竖边：x 相同，按 y 排序；横边：y 相同，按 x 排序\r\n      if (a1 === a2) return `V${a1}:${Math.min(b1, b2)}-${Math.max(b1, b2)}`\r\n      return `H${b1}:${Math.min(a1, a2)}-${Math.max(a1, a2)}`\r\n    }\r\n    const drawOnce = (\r\n      x1: number, y1: number, x2: number, y2: number,\r\n      side?: BorderSide\r\n    ) => {\r\n      // 该侧无边框定义 → 不画且不占用去重 key（否则会挡住邻格共享边的绘制）\r\n      if (!side || side.style === 'none' || side.width <= 0) return\r\n      if (edgeKey(x1, y1, x2, y2)) edges.push({ x1, y1, x2, y2, side })\r\n    }\r\n    // 每个 cell 四条边都尝试绘制（数据中共享边可能只由某一侧的格子定义，\r\n    // 例如附表5：水平分隔线只定义在上格的 bottom，下格无 top），\r\n    // 共享边由先遍历到的格子画出，后到的经 drawnEdges 去重跳过。\r\n    for (const row of b.rows) {\r\n      for (const cell of row.cells) {\r\n        const cx = bx + cell.rect.x\r\n        const cy = by + cell.rect.y\r\n        const cw = cell.rect.width\r\n        const ch = cell.rect.height\r\n        const bs = cell.cell.borderStyle ?? {}\r\n        // borderTypes: [top,right,bottom,left]，值为 0 表示隐藏该侧（三线表等场景）\r\n        const bt = (cell.cell as unknown as { borderTypes?: number[] }).borderTypes\r\n        const showTop    = !bt || bt[0] !== 0\r\n        const showRight  = !bt || bt[1] !== 0\r\n        const showBottom = !bt || bt[2] !== 0\r\n        const showLeft   = !bt || bt[3] !== 0\r\n        if (showTop)    drawOnce(cx, cy, cx + cw, cy, bs.top)              // 顶边\r\n        if (showBottom) drawOnce(cx, cy + ch, cx + cw, cy + ch, bs.bottom) // 底边\r\n        if (showLeft)   drawOnce(cx, cy, cx, cy + ch, bs.left)             // 左边\r\n        if (showRight)  drawOnce(cx + cw, cy, cx + cw, cy + ch, bs.right)  // 右边\r\n        // slashTypes: 单元格斜线（斜表头）\r\n        const slashes = (cell.cell as unknown as { slashTypes?: string[] }).slashTypes\r\n        if (slashes && slashes.length > 0) {\r\n          const side = bs.top ?? bs.bottom ?? bs.left ?? bs.right\r\n          const color = side?.color ?? '#000000'\r\n          const width = side?.width ?? 1\r\n          ctx.save()\r\n          ctx.strokeStyle = color\r\n          ctx.lineWidth = width\r\n          for (const s of slashes) {\r\n            ctx.beginPath()\r\n            if (s === 'forward') {\r\n              // '/'：左下 -> 右上\r\n              ctx.moveTo(cx + 0.5, cy + ch + 0.5)\r\n              ctx.lineTo(cx + cw + 0.5, cy + 0.5)\r\n            } else if (s === 'backward') {\r\n              // '\\'：左上 -> 右下\r\n              ctx.moveTo(cx + 0.5, cy + 0.5)\r\n              ctx.lineTo(cx + cw + 0.5, cy + ch + 0.5)\r\n            } else if (s === 'cross') {\r\n              // '×'：两条对角线\r\n              ctx.moveTo(cx + 0.5, cy + 0.5)\r\n              ctx.lineTo(cx + cw + 0.5, cy + ch + 0.5)\r\n              ctx.moveTo(cx + 0.5, cy + ch + 0.5)\r\n              ctx.lineTo(cx + cw + 0.5, cy + 0.5)\r\n            }\r\n            ctx.stroke()\r\n          }\r\n          ctx.restore()\r\n        }\r\n      }\r\n    }\r\n    const groups = new Map<string, Edge[]>()\r\n    for (const edge of edges) {\r\n      const vertical = edge.x1 === edge.x2\r\n      const key = `${vertical ? 'V' : 'H'}:${Math.round((vertical ? edge.x1 : edge.y1) * 2) / 2}`\r\n      const group = groups.get(key) ?? []\r\n      group.push(edge)\r\n      groups.set(key, group)\r\n    }\r\n    const rank: Record<string, number> = { solid: 1, single: 1, thick: 2, double: 3, dotted: 4, dashed: 5, dotDash: 6, dotDotDash: 7, triple: 8, thinThickSmallGap: 9, thickThinSmallGap: 10, thinThickThinSmallGap: 11, thinThickMediumGap: 12, thickThinMediumGap: 13, thinThickThinMediumGap: 14, thinThickLargeGap: 15, thickThinLargeGap: 16, thinThickThinLargeGap: 17, wave: 18, doubleWave: 19, dashSmallGap: 20, dashDotStroked: 21, threeDEmboss: 22, threeDEngrave: 23, outset: 24, inset: 25 }\r\n    const borderRank = (side: BorderSide) => rank[side.officeType ?? side.style] ?? 1\r\n    const borderWeight = (side: BorderSide) => (side.sizeEighthPoints ?? side.width * 6) * borderRank(side)\r\n    const brightness = (color: string): number => {\r\n      const rgb = Number.parseInt(color.replace('#', ''), 16)\r\n      return (rgb >> 16 & 255) + 2 * (rgb >> 8 & 255) + (rgb & 255)\r\n    }\r\n    const secondaryBrightness = (color: string): number => {\r\n      const rgb = Number.parseInt(color.slice(1), 16)\r\n      return (rgb >> 16 & 255) + 2 * (rgb >> 8 & 255)\r\n    }\r\n    for (const group of groups.values()) {\r\n      const vertical = group[0].x1 === group[0].x2\r\n      const start = (edge: Edge) => vertical ? Math.min(edge.y1, edge.y2) : Math.min(edge.x1, edge.x2)\r\n      const end = (edge: Edge) => vertical ? Math.max(edge.y1, edge.y2) : Math.max(edge.x1, edge.x2)\r\n      const points = [...new Set(group.flatMap(edge => [start(edge), end(edge)]))].sort((a, b) => a - b)\r\n      for (let index = 1; index < points.length; index++) {\r\n        const a = points[index - 1], b = points[index]\r\n        const candidates = group.filter(edge => start(edge) <= a && end(edge) >= b)\r\n        candidates.sort((a, b) => Number(b.side.source === 'cell') - Number(a.side.source === 'cell')\r\n          || borderWeight(b.side) - borderWeight(a.side)\r\n          || borderRank(b.side) - borderRank(a.side) || brightness(a.side.color) - brightness(b.side.color)\r\n          || secondaryBrightness(a.side.color) - secondaryBrightness(b.side.color)\r\n          || (Number.parseInt(a.side.color.slice(1), 16) >> 8 & 255) - (Number.parseInt(b.side.color.slice(1), 16) >> 8 & 255))\r\n        const winner = candidates[0]\r\n        if (!winner) continue\r\n        if (vertical) strokeSide(ctx, winner.x1, a, winner.x1, b, winner.side)\r\n        else strokeSide(ctx, a, winner.y1, b, winner.y1, winner.side)\r\n      }\r\n    }\r\n  }\r\n\r\n  /* -------------------- 边距标尺（WPS 风格） -------------------- */\r\n\r\n\r\n}\r\n\r\n/* -------------------- 工具 -------------------- */\r\n\r\n/**\r\n\r\n * 绘制一条带样式的边：支持 solid/dashed/dotted/double，并对奇数宽度做 0.5px 像素对齐。\r\n * @param ctx 目标 2d 上下文\r\n * @param x1 起点 x\r\n * @param y1 起点 y\r\n * @param x2 终点 x\r\n * @param y2 终点 y\r\n * @param side 边样式（宽/色/风格）\r\n */\r\nfunction strokeSide(\r\n  ctx: CanvasRenderingContext2D,\r\n  x1: number, y1: number, x2: number, y2: number,\r\n  side: { width: number; color: string; style: string }\r\n): void {\r\n  if (!side || side.style === 'none' || side.width <= 0) return\r\n  const w = side.width\r\n  // 像素对齐：奇数宽度用 +0.5，偶数宽度用 +0\r\n  const halfOffset = (w % 2 === 1) ? 0.5 : 0\r\n  ctx.save()\r\n  ctx.strokeStyle = side.color\r\n  ctx.lineWidth = w\r\n  // dashed / dotted 样式\r\n  switch (side.style) {\r\n    case 'dashed': ctx.setLineDash([Math.max(2, w * 3), Math.max(2, w * 2)]); break\r\n    case 'dotted': ctx.setLineDash([w, Math.max(2, w * 2)]); break\r\n    case 'double': {\r\n      // 双线：绘制两条平行线（简单实现）\r\n      const gap = Math.max(1, w)\r\n      ctx.lineWidth = 1\r\n      const off = halfOffset\r\n      ctx.beginPath()\r\n      if (y1 === y2) {\r\n        ctx.moveTo(Math.round(x1), Math.round(y1) + off - gap / 2)\r\n        ctx.lineTo(Math.round(x2), Math.round(y2) + off - gap / 2)\r\n        ctx.moveTo(Math.round(x1), Math.round(y1) + off + gap / 2)\r\n        ctx.lineTo(Math.round(x2), Math.round(y2) + off + gap / 2)\r\n      } else {\r\n        ctx.moveTo(Math.round(x1) + off - gap / 2, Math.round(y1))\r\n        ctx.lineTo(Math.round(x2) + off - gap / 2, Math.round(y2))\r\n        ctx.moveTo(Math.round(x1) + off + gap / 2, Math.round(y1))\r\n        ctx.lineTo(Math.round(x2) + off + gap / 2, Math.round(y2))\r\n      }\r\n      ctx.stroke()\r\n      ctx.restore()\r\n      return\r\n    }\r\n    default: ctx.setLineDash([])\r\n  }\r\n  ctx.beginPath()\r\n  ctx.moveTo(Math.round(x1) + halfOffset, Math.round(y1) + halfOffset)\r\n  ctx.lineTo(Math.round(x2) + halfOffset, Math.round(y2) + halfOffset)\r\n  ctx.stroke()\r\n  ctx.restore()\r\n}\r\n","/**\r\n * VerveDocs View —— LayoutEngine\r\n *\r\n * 坐标系约定：\r\n *  - block.rect.x/y = 相对父容器（页面内容原点 或 单元格内容原点）\r\n *  - line.x/y      = 相对块本地（0 起始）\r\n *  - inline.x/y/baseline = 相对块本地\r\n *  - TableRow/Cell rect = 相对 table 本地\r\n *\r\n * 绘制时递归传入偏移量（origin），把局部坐标累加为屏幕坐标。\r\n */\r\n\r\nimport type {\r\n  IElement,\r\n  IImageElement,\r\n  IDocxDocumentMeta,\r\n  IListElement,\r\n  ITableElement,\r\n  ITextElement,\n  IDocxTypography,\n  Path\r\n} from '@vervedoc/docx-editor-schema'\r\nimport { splitParagraphs, FONT_FAMILY_CSS, resolveHeaderFooterPart, isControl, collectPageFields, getPageFieldStyle } from '@vervedoc/docx-editor-schema'\r\nimport { CONTROL_MARK, getControlPresentation, type ControlPresentation } from './control-presentation'\r\nimport type {\r\n  DocumentLayout, PageLayout, BlockNode, ParagraphBlock,\r\n  ImageBlock, PageBreakBlock, SeparatorBlock, TableBlock, TableRowLayout, TableCellLayout,\r\n  EmbedBlock, ChartBlock, LineBox, InlineBox, Rect\r\n} from './layout-types'\r\nimport { TextMeasure, getSharedMeasure, resolveTextFont } from './text-measure'\nimport { balancedSpaceWidth, punctuationCompression, type CompressionMetrics } from './east-asian-layout'\nimport { resolveBullet, BULLET_FONT_STACK, BULLET_FONT_STACK_FALLBACK, detectWingdings } from './list-bullet'\r\nimport { CanvasRenderer } from './canvas-renderer'\r\n\r\n/** 排版引擎配置选项 */\r\nexport interface LayoutOptions {\r\n  /** 页面宽度（CSS 像素） */\r\n  pageWidth: number\r\n  /** 页面高度（CSS 像素） */\r\n  pageHeight: number\r\n  /** 页边距 [top, right, bottom, left] */\r\n  pageMargins: [number, number, number, number]   // top, right, bottom, left\r\n  /** 默认字体族名 */\r\n  defaultFont: string\r\n  /** 默认字号 */\r\n  defaultSize: number\r\n  /** 默认行高倍数 */\r\n  defaultLineHeight: number\r\n  /** 渲染缩放倍数 */\r\n  scale: number\r\n  /** 页首/尾垂直空白（渲染视觉上把纸张与边界隔开） */\r\n  pageGap: number\r\n  /** 仅用于独立打印布局，不影响编辑器配置。 */\r\n  printing?: boolean\r\n}\r\n\r\n/** 块 id 自增序列（跨 layout 调用持续递增，保证全局唯一） */\r\nlet _blockSeq = 0\r\n/** 取下一个全局唯一的 block id。 */\r\nfunction nextBlockId(): number { return ++_blockSeq }\r\n\r\ninterface ParagraphInput {\r\n  paragraphKind: ParagraphBlock['paragraphKind']\r\n  block: IElement | null\r\n  runs: IElement[]\r\n  runsParentPath: Path\r\n  startIndex: number\r\n  endIndex: number\r\n  parentPath: Path\r\n  availableWidth: number\r\n  docGridLinePitch?: number\r\n  typography?: IDocxTypography\n  runStartIndex?: number\r\n  ignoreParagraphIndents?: boolean\r\n  exclusions?: { rect: Rect; side: string; topBottom: boolean }[]\r\n  /** 跨栏后从源文字位置继续排版，保持光标路径不变。 */\n  resume?: { path: Path; offset: number }\n  /** 竖排单元格按字格高度布局，不沿用横排段落行距。 */\n  verticalText?: boolean\n}\r\n\r\ninterface ParagraphCache {\r\n  signature: string\r\n  input: ParagraphInput\r\n  layout: ParagraphBlock\r\n}\r\n\r\n/**\r\n * 文档排版引擎：把 IElement[] 排版成分页 DocumentLayout，\r\n * 处理段落折行、列表编号、表格跨行/跨页、图片环绕等。\r\n */\r\nexport class LayoutEngine {\r\n  /** 文本度量器（计算字符/文本宽度） */\r\n  private measure: TextMeasure\r\n  /** 排版选项 */\r\n  private opts: LayoutOptions\r\n  /** 跨列表的多级编号计数器（每次 layout() 重置） */\r\n  private counters = new Map<string, number>()\r\n  private paragraphCache = new Map<string, ParagraphCache>()\r\n  private nextParagraphCache = new Map<string, ParagraphCache>()\r\n  private layoutZone = 'main'\r\n  private typography?: IDocxTypography\n  /** 每页独立求值，绝不把动态结果写回共享的页眉页脚模板。 */\r\n  private pageFieldValues = new WeakMap<IElement, string>()\r\n  private diagnostics: NonNullable<DocumentLayout['diagnostics']> = []\r\n  private paragraphInputs = new WeakMap<ParagraphBlock, ParagraphInput>()\r\n\r\n  /**\r\n   * 创建排版引擎。\r\n   * @param options 排版选项\r\n   * @param measure 文本度量器，缺省时使用共享实例\r\n   */\r\n  constructor(options: LayoutOptions, measure?: TextMeasure) {\r\n    this.opts = options\r\n    this.measure = measure ?? getSharedMeasure()\r\n  }\r\n\r\n  /**\r\n   * 更新排版选项（不立即触发重排，由调用方决定何时 layout()）。\r\n   * @param options 新的排版选项\r\n   */\r\n  updateOptions(options: LayoutOptions): void {\r\n    this.opts = options\r\n    this.paragraphCache.clear()\r\n  }\r\n\r\n  /**\r\n   * 顶层入口：把 elements 排版成分页 layout。\r\n   * headerElements / footerElements 为页眉/页脚内容，每页都会渲染一份。\r\n   */\r\n  layout(elements: IElement[], headerElements?: IElement[], footerElements?: IElement[], document?: IDocxDocumentMeta): DocumentLayout {\r\n    this.counters.clear()\r\n    this.diagnostics = []\r\n    this.nextParagraphCache = new Map()\r\n    this.layoutZone = 'main'\r\n    this.typography = document?.typography\n    this.pageFieldValues = new WeakMap()\r\n    const { pageGap } = this.opts\r\n    // 缺失区域仅生成布局占位，不写入文档；进入编辑后沿用相同位置。\r\n    const emptyZoneElements: IElement[] = [{ type: 'text', value: '' }]\r\n    const zoneElements = (elements?: IElement[]) => elements?.length ? elements : emptyZoneElements\r\n    const isDefaultEmptyZone = (elements: IElement[]) => elements.length === 1 &&\r\n      elements[0].type === 'text' && elements[0].value === '' &&\r\n      Object.keys(elements[0]).every(key => ['type', 'value', 'font', 'size'].includes(key))\r\n    let sectionIndex = 0\r\n    let sectionFirstPage = 0\r\n    let pageWidth = this.opts.pageWidth\r\n    let pageHeight = this.opts.pageHeight\r\n    let [mt, mr, mb, ml] = this.opts.pageMargins\r\n    let footerAreaHeight = mb\r\n    let contentWidth = pageWidth - ml - mr\r\n    let contentHeight = pageHeight - mt - mb\r\n    const setSection = (index: number) => {\r\n      const section = document?.sections?.[index]\r\n      if (section) {\r\n        if (section.pageWidth === undefined || section.pageHeight === undefined || !section.margins) {\r\n          throw new TypeError(`Java sections[${index}] 缺少页面尺寸或页边距`)\r\n        }\r\n        pageWidth = section.pageWidth\r\n        pageHeight = section.pageHeight\r\n        ;[mt, mr, mb, ml] = section.margins\r\n      } else if (document && !document.sections) {\r\n        pageWidth = document.pageWidth ?? this.opts.pageWidth\r\n        pageHeight = document.pageHeight ?? this.opts.pageHeight\r\n        ;[mt, mr, mb, ml] = document.margins ?? this.opts.pageMargins\r\n      }\r\n      contentWidth = pageWidth - ml - mr\r\n      // 页脚距底部可能大于下页边距，需在分页前预留内容高度，避免负偏移侵入正文。\r\n      const footerPartIds = document?.sections\r\n        ? new Set([\r\n          resolveHeaderFooterPart(document, 'footer', index, 0, true),\r\n          resolveHeaderFooterPart(document, 'footer', index, 0, false),\r\n          resolveHeaderFooterPart(document, 'footer', index, 1, false)\r\n        ])\r\n        : new Set([undefined])\r\n      footerAreaHeight = mb\r\n      const previousZone = this.layoutZone\r\n      const previousCounters = new Map(this.counters)\r\n      try {\r\n        for (const partId of footerPartIds) {\r\n          const pageFooterElements = zoneElements(document?.sections\r\n            ? partId ? document.headerFooterParts?.[partId] : undefined\r\n            : footerElements)\r\n          this.layoutZone = `footer:${partId ?? ''}`\r\n          const blocks = this.layoutBlocks(pageFooterElements, [], contentWidth)\r\n          const height = blocks.reduce((max, block) => Math.max(max, block.rect.y + block.rect.height), 0)\r\n          const distance = isDefaultEmptyZone(pageFooterElements) ? 0 : section?.footerDistance ?? 0\r\n          footerAreaHeight = Math.max(footerAreaHeight, distance + height)\r\n        }\r\n      } finally {\r\n        this.layoutZone = previousZone\r\n        this.counters = previousCounters\r\n      }\r\n      contentHeight = pageHeight - mt - footerAreaHeight\r\n    }\r\n    setSection(0)\r\n    const sectionBreaks = new Set(['continuous', 'nextPage', 'evenPage', 'oddPage'])\r\n    const sectionColumns = (index: number) => {\r\n      const section = document?.sections?.[index]\r\n      const count = Math.max(1, section?.columnCount ?? document?.columnCount ?? 1)\n      const gap = section?.columnGap ?? document?.columnGap ?? 20\r\n      const width = section?.pageWidth !== undefined && section.margins\r\n        ? section.pageWidth - section.margins[1] - section.margins[3] : contentWidth\r\n      const widths = section?.columnWidths?.length && section.columnWidths.every(value => Number.isFinite(value) && value > 0)\n        ? section.columnWidths : Array(count).fill((width - gap * (count - 1)) / count) as number[]\n      return { widths, gap, gaps: section?.columnGaps }\n    }\r\n    const sectionWidths = (document?.sections ?? [undefined]).map((_, index) => sectionColumns(index).widths[0])\r\n    const columnGroups = new Map<string, { widths: number[]; gap: number }>()\r\n    let columnSection = 0\r\n    for (const element of elements) {\r\n      const data = element as IElement & { columnId?: string; columnCount?: number; columnWidths?: number[]; columnGap?: number }\r\n      if (data.columnId && data.columnCount) {\r\n        const gap = data.columnGap ?? 0\r\n        const width = sectionWidths?.[columnSection] ?? contentWidth\r\n        columnGroups.set(data.columnId, { gap, widths: data.columnWidths ?? Array(data.columnCount).fill((width - gap * (data.columnCount - 1)) / data.columnCount) })\r\n      }\r\n      if (element.type === 'pageBreak' && sectionBreaks.has(element.value)) columnSection++\r\n    }\r\n    const rawBlocks = this.layoutBlocks(elements, [], contentWidth, sectionWidths)\r\n    let gridSectionIndex = 0\r\n    for (let index = 0; index < rawBlocks.length; index++) {\r\n      const block = rawBlocks[index]\r\n      if (block.kind === 'pageBreak') {\r\n        if (sectionBreaks.has(String(block.block.value))) gridSectionIndex++\r\n        continue\r\n      }\r\n      if (block.kind !== 'paragraph') continue\r\n      const input = this.paragraphInputs.get(block)!\r\n      const columnId = input.runs.find(run => (run as Record<string, unknown>).columnId)?.columnId as string | undefined\r\n      const columns = columnId ? columnGroups.get(columnId) : undefined\r\n      const section = document?.sections?.[gridSectionIndex]\r\n      const gridType = section?.docGridType\r\n      const gridLinePitch = gridType === 'lines' || gridType === 'linesAndChars'\r\n        ? section?.docGridLinePitch\r\n        : undefined\r\n      if (columns || (gridLinePitch != null && gridLinePitch > 0)) {\r\n        rawBlocks[index] = this.layoutParagraph({\r\n          ...input,\r\n          availableWidth: columns?.widths[0] ?? input.availableWidth,\r\n          docGridLinePitch: gridLinePitch\r\n        })\r\n      }\r\n    }\r\n    const anchorParagraphs = new Map<string, ParagraphBlock>()\r\n    for (const block of rawBlocks) {\r\n      if (block.kind !== 'paragraph') continue\r\n      for (const run of this.paragraphInputs.get(block)?.runs ?? []) {\r\n        if (run.sourceParagraphId && !anchorParagraphs.has(run.sourceParagraphId)) anchorParagraphs.set(run.sourceParagraphId, block)\r\n      }\r\n    }\r\n    // Schedule floating drawings with their Java-identified paragraph, never an adjacent run.\r\n    const attachedImages = new Map<ParagraphBlock, ImageBlock[]>()\r\n    for (let index = rawBlocks.length - 1; index >= 0; index--) {\r\n      const block = rawBlocks[index]\r\n      if (block.kind !== 'image') continue\r\n      const id = (block.block as IImageElement).imageLayout?.anchorParagraphId\r\n      const anchor = id ? anchorParagraphs.get(id) : undefined\r\n      if (!anchor) continue\r\n      attachedImages.set(anchor, [block, ...(attachedImages.get(anchor) ?? [])])\r\n      rawBlocks.splice(index, 1)\r\n    }\r\n    for (let index = rawBlocks.length - 1; index >= 0; index--) {\r\n      const block = rawBlocks[index]\r\n      if (block.kind === 'paragraph') rawBlocks.splice(index + 1, 0, ...(attachedImages.get(block) ?? []))\r\n    }\r\n    const placedAnchors = new Map<string, { paragraph: ParagraphBlock; column: Rect }>()\r\n\r\n    // 页眉/页脚 block 预布局（rect.y 相对各自区域原点）\r\n    this.layoutZone = 'header'\r\n    const headerBlocks = this.layoutBlocks(zoneElements(headerElements), [], contentWidth)\r\n    this.layoutZone = 'footer'\r\n    const footerBlocks = this.layoutBlocks(zoneElements(footerElements), [], contentWidth)\r\n\r\n    // 分页\r\n    this.layoutZone = 'main'\n    const pages: PageLayout[] = []\r\n    let pageIndex = 0\r\n    let cursorY = 0\r\n    let currentBlocks: BlockNode[] = []\r\n    const hasVisiblePageContent = (blocks: BlockNode[]) => blocks.some(block => block.kind !== 'paragraph' ||\r\n      !!block.surroundImage || !!block.bulletText ||\r\n      block.lines.some(line => line.inlines.some(inline =>\r\n        !!inline.controlMark || !!inline.controlPlaceholder || inline.text.replace(/[\\s\\u200B\\uFEFF]/g, '').length > 0)))\r\n    let activeColumns: { widths: number[]; gap: number; gaps?: number[] } | undefined\n    let activeColumnId: string | undefined = undefined\r\n    let columnIndex = 0\r\n    let columnTop = 0\r\n    let columnBottom = 0\r\n    const columnX = () => activeColumns ? activeColumns.widths.slice(0, columnIndex)\n      .reduce((sum, width, index) => sum + width + (activeColumns!.gaps?.[index] ?? activeColumns!.gap), 0) : 0\n    const advanceColumn = () => {\r\n      columnBottom = Math.max(columnBottom, cursorY)\r\n      if (activeColumns && columnIndex + 1 < activeColumns.widths.length) { columnIndex++; cursorY = columnTop }\r\n      else { pushPage(); columnIndex = 0; columnTop = 0; columnBottom = 0 }\r\n    }\r\n\r\n    // 页面承载上限判定的浮点容差：\r\n    // 行高经多次浮点累加（cursorY += rowHeight）后，可能出现微小正偏离\r\n    // （如 903 累加为 903.0000000000001）。若用严格 \">\" 比较，会让\"恰好\r\n    // 填满页面\"的内容被误判为超出，从而提前触发分页。这里引入亚像素级\r\n    // 容差（0.5px，小于半像素，视觉上不可感知），仅当真实超出容差才分页。\r\n    const PAGE_FIT_EPSILON = 0.5\r\n\r\n    const pushPage = () => {\r\n      const previous = pages[pages.length - 1]\r\n      const pageOriginY = previous ? previous.rect.y + previous.rect.height + pageGap : pageGap\r\n      const section = document?.sections?.[sectionIndex]\r\n      const headerPartId = document?.sections ? resolveHeaderFooterPart(document, 'header', sectionIndex, pageIndex, pageIndex === sectionFirstPage) : undefined\r\n      const footerPartId = document?.sections ? resolveHeaderFooterPart(document, 'footer', sectionIndex, pageIndex, pageIndex === sectionFirstPage) : undefined\r\n      const pageHeaderElements = zoneElements(document?.sections\r\n        ? headerPartId ? document.headerFooterParts?.[headerPartId] : undefined\r\n        : headerElements)\r\n      const pageFooterElements = zoneElements(document?.sections\r\n        ? footerPartId ? document.headerFooterParts?.[footerPartId] : undefined\r\n        : footerElements)\r\n      this.layoutZone = `header:${headerPartId ?? ''}`\r\n      const pageHeaders = document?.sections ? this.layoutBlocks(pageHeaderElements, [], contentWidth) : headerBlocks\r\n      this.layoutZone = `footer:${footerPartId ?? ''}`\r\n      const pageFooters = document?.sections ? this.layoutBlocks(pageFooterElements, [], contentWidth) : footerBlocks\r\n      this.layoutZone = 'main'\r\n      const headerHeight = pageHeaders.reduce((height, block) => Math.max(height, block.rect.y + block.rect.height), 0)\r\n      const footerHeight = pageFooters.reduce((height, block) => Math.max(height, block.rect.y + block.rect.height), 0)\r\n      // 只有默认空段落忽略导入距离；含边框、域或段落格式的空内容仍保留原始布局。\r\n      const headerOffsetY = !isDefaultEmptyZone(pageHeaderElements) && section?.headerDistance !== undefined\r\n        ? section.headerDistance : Math.max(0, mt - headerHeight)\r\n      const footerOffsetY = !isDefaultEmptyZone(pageFooterElements) && section?.footerDistance !== undefined\r\n        ? footerAreaHeight - section.footerDistance - footerHeight : 0\r\n      const pageRect: Rect = { x: 0, y: pageOriginY, width: pageWidth, height: pageHeight }\r\n      const contentRect: Rect = {\r\n        x: ml,\r\n        y: pageOriginY + mt,\r\n        width: contentWidth,\r\n        height: contentHeight\r\n      }\r\n      const headerRect: Rect = { x: ml, y: pageOriginY, width: contentWidth, height: mt }\r\n      const footerRect: Rect = { x: ml, y: pageOriginY + mt + contentHeight, width: contentWidth, height: footerAreaHeight }\r\n      pages.push({\r\n        index: pageIndex, sectionIndex, headerPartId, footerPartId, rect: pageRect, contentRect, blocks: currentBlocks,\r\n        headerRect,\r\n        headerBlocks: pageHeaders.length\r\n          ? pageHeaders.map(b => ({ ...b, rect: { ...b.rect, y: b.rect.y + headerOffsetY } }))\r\n          : undefined,\r\n        footerRect,\r\n        footerBlocks: pageFooters.length\r\n          ? pageFooters.map(b => ({ ...b, rect: { ...b.rect, y: b.rect.y + footerOffsetY } }))\r\n          : undefined\r\n      })\r\n      pageIndex++\r\n      currentBlocks = []\r\n      cursorY = 0\r\n      columnIndex = 0\r\n      columnTop = 0\r\n      columnBottom = 0\r\n    }\r\n\r\n    for (let i = 0; i < rawBlocks.length; i++) {\r\n      let b = rawBlocks[i]\r\n      const source = b.kind === 'paragraph' ? this.paragraphInputs.get(b)?.runs.find(run => run.value !== '\\u200B') : b.block\r\n      const legacyColumnId = (source as { columnId?: string } | undefined)?.columnId\r\n      const sourceColumnId = legacyColumnId ?? `section:${sectionIndex}`\r\n      if (sourceColumnId !== activeColumnId) {\r\n        cursorY = Math.max(cursorY, columnBottom)\r\n        activeColumnId = sourceColumnId\r\n        activeColumns = legacyColumnId ? columnGroups.get(legacyColumnId) : sectionColumns(sectionIndex)\r\n        columnIndex = 0; columnTop = cursorY; columnBottom = cursorY\r\n      }\r\n      // 连续分节结束时需平衡本节各栏，不能等到整页填满才流入右栏。\n      if (!legacyColumnId && activeColumns && activeColumns.widths.length > 1 && columnIndex === 0 && cursorY === columnTop) {\n        let end = i\n        while (end < rawBlocks.length && rawBlocks[end].kind !== 'pageBreak') end++\n        const boundary = rawBlocks[end]\n        if (!boundary || (boundary.kind === 'pageBreak' && boundary.block.value === 'continuous')) {\n          const candidates = rawBlocks.slice(i, end)\n          if (candidates.every(block => block.kind === 'paragraph' && !block.surroundImage && !attachedImages.has(block))) {\n            const balanced = this.balanceColumns(candidates as ParagraphBlock[], activeColumns, contentHeight - columnTop)\n            if (balanced) {\n              for (const block of balanced.blocks) {\n                block.rect.y += columnTop\n                currentBlocks.push(block)\n              }\n              cursorY = columnTop + balanced.height\n              columnBottom = cursorY\n              i = end - 1\n              continue\n            }\n          }\n        }\n      }\n      if (b.kind === 'paragraph' && activeColumns) {\r\n        const input = this.paragraphInputs.get(b)!\r\n        b = this.layoutParagraph({ ...input, availableWidth: activeColumns.widths[columnIndex] })\r\n      }\r\n      if (b.kind === 'paragraph' && b.paragraphKind !== 'list') {\r\n        const exclusions: NonNullable<ParagraphInput['exclusions']> = []\r\n        for (const placed of currentBlocks) {\r\n          if (placed.kind !== 'image') continue\r\n          const geometry = (placed.block as IImageElement).imageLayout\r\n          if (!geometry?.anchored) continue\r\n          const wrap = geometry.positioning?.find(node => node.name === 'wrapSquare' || node.name === 'wrapTopAndBottom')\r\n          if (!wrap) continue\r\n          const attrs = geometry.anchorAttributes\r\n          const distance = (name: string) => {\r\n            if (attrs?.[name] === undefined) throw new TypeError(`Java anchored image 缺少 ${name}`)\r\n            return Number(attrs[name]) / 9525\r\n          }\r\n          exclusions.push({ rect: { x: placed.rect.x - columnX() - distance('distL'), y: placed.rect.y - cursorY - distance('distT'),\r\n            width: placed.rect.width + distance('distL') + distance('distR'), height: placed.rect.height + distance('distT') + distance('distB') },\r\n            side: wrap.name === 'wrapTopAndBottom' ? '' : wrap.attributes.wrapText, topBottom: wrap.name === 'wrapTopAndBottom' })\r\n        }\r\n        const input = this.paragraphInputs.get(b)\r\n        if (input && exclusions.length) b = this.computeParagraph({ ...input, exclusions })\r\n      }\r\n      if (b.kind === 'pageBreak') {\r\n        if (b.block.type === 'columnBreak') { advanceColumn(); continue }\r\n        const breakType = String(b.block.value)\r\n        const nextSection = sectionBreaks.has(breakType) ? document?.sections?.[sectionIndex + 1] : undefined\r\n        const geometryChanged = nextSection && (nextSection.pageWidth !== pageWidth || nextSection.pageHeight !== pageHeight ||\r\n          nextSection.margins?.some((margin, index) => margin !== [mt, mr, mb, ml][index]))\r\n        // 当前页已空时直接复用，避免 nextPage 再生成一张空白页。\r\n        const suppressEmptyNextPage = breakType === 'nextPage' && !hasVisiblePageContent(currentBlocks)\r\n        if ((breakType !== 'continuous' || geometryChanged) && !suppressEmptyNextPage) pushPage()\r\n        else if (suppressEmptyNextPage) {\r\n          currentBlocks = []\r\n          cursorY = 0\r\n          columnIndex = 0\r\n          columnTop = 0\r\n          columnBottom = 0\r\n        }\r\n        if (sectionBreaks.has(breakType) && document?.sections) {\r\n          sectionIndex++\r\n          if (!document.sections[sectionIndex]) throw new TypeError('Java sections 与正文分节符数量不一致')\r\n          setSection(sectionIndex)\r\n          sectionFirstPage = pageIndex\r\n        }\r\n        if (breakType === 'evenPage' && (pageIndex + 1) % 2 !== 0) pushPage()\r\n        if (breakType === 'oddPage' && (pageIndex + 1) % 2 !== 1) pushPage()\r\n        if (breakType === 'evenPage' || breakType === 'oddPage') sectionFirstPage = pageIndex\r\n        continue\r\n      }\r\n      // 多栏段落按行流入下一栏/页，而非把整个长段落移出页面。\r\n      if (b.kind === 'paragraph' && activeColumns && activeColumns.widths.length > 1 && !b.surroundImage && !attachedImages.has(rawBlocks[i] as ParagraphBlock)) {\r\n        const input = this.paragraphInputs.get(rawBlocks[i] as ParagraphBlock)!\n        let resume: ParagraphInput['resume']\n        for (;;) {\n          const fragment = this.layoutParagraph({ ...input, availableWidth: activeColumns.widths[columnIndex], resume })\n          let end = 0\n          while (end < fragment.lines.length &&\n            cursorY + fragment.lines[end].y + fragment.lines[end].height <= contentHeight + PAGE_FIT_EPSILON) end++\n          if (end === 0) {\n            if (cursorY > columnTop) { advanceColumn(); continue }\n            end = 1\n          }\r\n          const lines = fragment.lines.slice(0, end)\n          const height = end === fragment.lines.length ? fragment.rect.height : lines.at(-1)!.y + lines.at(-1)!.height\n          currentBlocks.push({ ...fragment, id: nextBlockId(), bulletText: resume ? undefined : b.bulletText,\n            rect: { ...fragment.rect, x: fragment.rect.x + columnX(), y: cursorY, height }, lines })\n          cursorY += height\r\n          if (end === fragment.lines.length) break\n          const next = fragment.lines[end].startPosition\n          if (!next) break\n          resume = next\n          advanceColumn()\n        }\r\n        continue\r\n      }\r\n      // Word 的普通长段落可以跨页；保留首尾的段间距，并尽量避免单行孤行。\r\n      if (b.kind === 'paragraph' && b.lines.length > 1 && !b.surroundImage && !attachedImages.has(rawBlocks[i] as ParagraphBlock) &&\r\n        cursorY + b.rect.height > contentHeight + PAGE_FIT_EPSILON) {\r\n        let start = 0\r\n        while (start < b.lines.length) {\r\n          const origin = start === 0 ? 0 : b.lines[start].y\r\n          let end = start\r\n          while (end < b.lines.length && cursorY + b.lines[end].y + b.lines[end].height - origin <= contentHeight + PAGE_FIT_EPSILON) end++\r\n          if (end === start && currentBlocks.length > 0) {\r\n            advanceColumn()\r\n            continue\r\n          }\r\n          if (end === start) end = start + 1\r\n          const remainingLines = b.lines.length - end\r\n          if (currentBlocks.length > 0 && end < b.lines.length && end - start === 1 && b.lines.length >= 4) {\r\n            advanceColumn()\r\n            continue\r\n          }\r\n          if (remainingLines === 1 && end - start > 2) end--\r\n          const lines = b.lines.slice(start, end).map(line => ({\r\n            ...line,\r\n            y: line.y - origin,\r\n            baseline: line.baseline - origin,\r\n            inlines: line.inlines.map(inline => ({ ...inline, y: inline.y - origin, baseline: inline.baseline - origin }))\r\n          }))\r\n          const height = end === b.lines.length ? b.rect.height - origin : b.lines[end - 1].y + b.lines[end - 1].height - origin\r\n          currentBlocks.push({\r\n            ...b, id: nextBlockId(), bulletText: start === 0 ? b.bulletText : undefined,\r\n            rect: { ...b.rect, y: cursorY, height }, lines\r\n          })\r\n          cursorY += height\r\n          start = end\r\n          if (start < b.lines.length) advanceColumn()\r\n        }\r\n        continue\r\n      }\r\n      let bh = b.rect.height\r\n      const overflow = cursorY + bh - contentHeight\r\n      // 仅当内容真实超出页面承载上限（超出浮点容差）才分页；\r\n      // 恰好填满（|cum - contentHeight| <= epsilon）时留在本页。\r\n      if (overflow > PAGE_FIT_EPSILON && !(b.kind === 'image' && (b.block as IImageElement).imageLayout?.anchored)) {\r\n        // 表格特判：先在当前页放能容纳的行，放不下的行推到下一页，\r\n        // 后续每页重新用整页高度计算能放几行。\r\n        // 跨行（rowspan）格被切割时自动裁剪（见 buildFragment），因此任意行边界都可切割。\r\n        if (b.kind === 'table') {\r\n          const remaining = contentHeight - cursorY\r\n          let frags = this.tryPaginateTableFlow(b, remaining, contentHeight)\r\n          if (!frags && currentBlocks.length > 0) {\r\n            // 当前页剩余空间连首行都放不下：整表推到新页，按整页高度拆分\r\n            pushPage()\r\n            cursorY = 0\r\n            frags = this.tryPaginateTableFlow(b, contentHeight, contentHeight)\r\n          }\r\n          if (frags) {\r\n            for (let fi = 0; fi < frags.length; fi++) {\r\n              const frag = frags[fi]\r\n              if (fi === 0) {\r\n                // 第 1 片：留在当前页（即使当前页尚为空页）\r\n                frag.rect.y = cursorY\r\n                currentBlocks.push(frag)\r\n                cursorY += frag.rect.height\r\n              } else {\r\n                // 第 2 片及以后：结束当前页，开启新页放置\r\n                pushPage()\r\n                frag.rect.y = 0\r\n                currentBlocks.push(frag)\r\n                cursorY = frag.rect.height\r\n              }\r\n            }\r\n            continue\r\n          }\r\n          // 表无法拆分（如单行高于整页）：回退为整表处理。\r\n        }\r\n        if (currentBlocks.length > 0) {\r\n          advanceColumn()\r\n          if (b.kind === 'paragraph' && activeColumns) b = this.layoutParagraph({ ...this.paragraphInputs.get(rawBlocks[i] as ParagraphBlock)!, availableWidth: activeColumns.widths[columnIndex] })\r\n          if (b.kind === 'paragraph' && !activeColumns && b !== rawBlocks[i]) {\r\n            b = rawBlocks[i]\r\n            bh = b.rect.height\r\n          }\r\n        }\r\n      }\r\n      b.rect.y = cursorY\r\n      if (activeColumns) b.rect.x += columnX()\r\n      bh = b.rect.height\r\n      if (b.kind === 'paragraph') {\r\n        for (const [id, anchor] of anchorParagraphs) {\r\n          if (anchor === rawBlocks[i]) placedAnchors.set(id, { paragraph: b, column: { x: columnX(), y: columnTop, width: activeColumns?.widths[columnIndex] ?? contentWidth, height: contentHeight - columnTop } })\r\n        }\r\n      }\r\n      const floating = b.kind === 'image' && (b.block as IImageElement).imageLayout?.anchored\r\n      const image = b.kind === 'image' ? b : b.kind === 'paragraph' ? b.surroundImage : undefined\r\n      if (image && (image.block as IImageElement).imageLayout?.anchored) {\r\n        const geometry = (image.block as IImageElement).imageLayout!\r\n        const horizontal = geometry.positioning?.find(node => node.name === 'positionH')\r\n        const vertical = geometry.positioning?.find(node => node.name === 'positionV')\r\n        const resolve = (node: typeof horizontal, axis: 'x' | 'y'): number => {\r\n          if (!node) throw new TypeError('Java anchored image 缺少定位节点')\r\n          const ref = node.attributes.relativeFrom\r\n          const isX = axis === 'x'\r\n          let origin: number, length: number\r\n          if (ref === 'page') { origin = isX ? -ml : -mt; length = isX ? pageWidth : pageHeight }\r\n          else if (ref === 'margin') { origin = 0; length = isX ? contentWidth : contentHeight }\r\n          else if ((isX && ref === 'column') || (!isX && ref === 'paragraph')) {\r\n            const anchor = geometry.anchorParagraphId ? placedAnchors.get(geometry.anchorParagraphId) : undefined\r\n            if (!anchor) throw new TypeError('Java anchored image 缺少已排版的 anchorParagraphId')\r\n            origin = isX ? anchor.column.x : anchor.paragraph.rect.y + (anchor.paragraph.lines[0]?.y ?? 0)\r\n            length = isX ? anchor.column.width : anchor.paragraph.lines.reduce((height, line) => Math.max(height, line.y + line.height - (anchor.paragraph.lines[0]?.y ?? 0)), 0)\r\n          }\r\n          else if (ref === 'paragraph' || ref === 'line' || ref === 'character' || ref === 'column') {\r\n            throw new TypeError(`尚未支持 OOXML 图片 ${ref} 参考系：需要真实锚点上下文与布局边界`)\r\n          }\r\n          else if (ref === 'leftMargin' || ref === 'topMargin') { origin = isX ? -ml : -mt; length = isX ? ml : mt }\r\n          else if (ref === 'rightMargin' || ref === 'bottomMargin') { origin = isX ? contentWidth : contentHeight; length = isX ? mr : mb }\r\n          else if (ref === 'insideMargin' || ref === 'outsideMargin') {\r\n            const leading = (ref === 'insideMargin') === ((pageIndex + 1) % 2 === 1)\r\n            origin = leading ? (isX ? -ml : -mt) : (isX ? contentWidth : contentHeight)\r\n            length = leading ? (isX ? ml : mt) : (isX ? mr : mb)\r\n          } else throw new TypeError(`不支持的 OOXML 图片定位参考系: ${ref}`)\r\n          const offset = node.children.find(child => child.name === 'posOffset')\r\n          if (offset) return origin + Number(offset.text) / 9525\r\n          const align = node.children.find(child => child.name === 'align')?.text\r\n          const size = isX ? image.rect.width : image.rect.height\r\n          if (align === 'center') return origin + (length - size) / 2\r\n          if (align === 'right' || align === 'bottom') return origin + length - size\r\n          if (align === 'inside' || align === 'outside') return origin + (((align === 'inside') === ((pageIndex + 1) % 2 === 1)) ? 0 : length - size)\r\n          if (align === 'left' || align === 'top') return origin\r\n          throw new TypeError('Java anchored image 缺少 align/posOffset')\r\n        }\r\n        image.rect.x = resolve(horizontal, 'x')\r\n        image.rect.y = resolve(vertical, 'y') - (b.kind === 'paragraph' ? b.rect.y : 0)\r\n        const wrap = geometry.positioning?.find(node => node.name.startsWith('wrap'))\r\n        if (wrap && wrap.name !== 'wrapNone' && b.kind === 'image') {\r\n          const distance = (name: string) => Number(geometry.anchorAttributes?.[name] ?? 0) / 9525\r\n          const top = image.rect.y - distance('distT'), bottom = image.rect.y + image.rect.height + distance('distB')\r\n          const left = image.rect.x - distance('distL'), right = image.rect.x + image.rect.width + distance('distR')\r\n          const intersects = currentBlocks.some(block => block.kind === 'paragraph' && block.lines.some(line =>\r\n            block.rect.y + line.y < bottom && block.rect.y + line.y + line.height > top &&\r\n            (wrap.name === 'wrapTopAndBottom' || (block.rect.x + line.x < right && block.rect.x + line.x + line.width > left))))\r\n          if (intersects) {\r\n            this.diagnostics.push({ code: 'unsupported-floating-image', severity: 'warning', feature: 'anchor-reflow',\r\n              message: '尚未支持浮动图片对已排版段落的回流；此浮动图片暂不显示，原始数据保留用于导出。',\r\n              zone: 'main', path: [...image.parentPath, image.indexInParent], action: 'image-omitted' })\r\n            continue\r\n          }\r\n        }\r\n      }\r\n      currentBlocks.push(b)\r\n      if (!floating) cursorY += bh\r\n    }\r\n    if (currentBlocks.length > 0) pushPage()\r\n    else if (pages.length === 0 || rawBlocks.at(-1)?.block?.type === 'pageBreak' && rawBlocks.at(-1)?.block?.value === 'manual') pushPage()\r\n\r\n    // 正文分页完成后再计算 PAGE / NUMPAGES，按真实文字宽度重新排版，\r\n    // 同时覆盖编辑画布、打印和缩略图，避免共享位图把所有页都画成第一页。\r\n    const fieldCache = new Map<IElement[], ReturnType<typeof collectPageFields>>()\r\n    const sectionPageCounts = new Map<number | undefined, number>()\r\n    for (const page of pages) {\r\n      sectionPageCounts.set(page.sectionIndex, (sectionPageCounts.get(page.sectionIndex) ?? 0) + 1)\r\n    }\r\n    for (const page of pages) {\r\n      for (const zone of ['header', 'footer'] as const) {\r\n        const partId = zone === 'header' ? page.headerPartId : page.footerPartId\r\n        const source = document?.sections\r\n          ? partId ? document.headerFooterParts?.[partId] : undefined\r\n          : zone === 'header' ? headerElements : footerElements\r\n        if (!source) continue\r\n        let fields = fieldCache.get(source)\r\n        if (!fields) {\r\n          fields = collectPageFields(source)\r\n          fieldCache.set(source, fields)\r\n        }\r\n        if (!fields.length) continue\r\n        this.pageFieldValues = new WeakMap()\r\n        for (const field of fields) {\r\n          const number = field.type === 'PAGE' ? page.index + 1\r\n            : field.type === 'SECTIONPAGES' ? sectionPageCounts.get(page.sectionIndex)! : pages.length\r\n          const results = field.results.length ? field.results : [field.separator]\r\n          results.forEach((run, index) => this.pageFieldValues.set(run, index === 0\r\n            ? CanvasRenderer.formatPageNumber(number - 1, pages.length, getPageFieldStyle(field)) : ''))\r\n        }\r\n        this.layoutZone = `${zone}:${partId ?? ''}:${page.index}:${pages.length}`\r\n        const rect = zone === 'header' ? page.headerRect : page.footerRect\r\n        if (!rect) continue\r\n        const blocks = this.layoutBlocks(source, [], rect.width)\r\n        const height = blocks.reduce((max, block) => Math.max(max, block.rect.y + block.rect.height), 0)\r\n        const section = document?.sections?.[page.sectionIndex ?? 0]\r\n        const offset = zone === 'header'\r\n          ? section?.headerDistance ?? Math.max(0, rect.height - height)\r\n          : section?.footerDistance !== undefined ? rect.height - section.footerDistance - height : 0\r\n        const positioned = blocks.map(block => ({ ...block, rect: { ...block.rect, y: block.rect.y + offset } }))\r\n        if (zone === 'header') page.headerBlocks = positioned\r\n        else page.footerBlocks = positioned\r\n      }\r\n    }\r\n    this.pageFieldValues = new WeakMap()\r\n    this.layoutZone = 'main'\r\n    this.paragraphCache = this.nextParagraphCache\r\n    const lastPage = pages[pages.length - 1]\r\n    const totalHeight = lastPage.rect.y + lastPage.rect.height + pageGap\r\n    return { pages, totalHeight, pageWidth: Math.max(...pages.map(page => page.rect.width)), diagnostics: this.diagnostics }\r\n  }\r\n\r\n  /**\r\n   * 将 elements 数组转换为 BlockNode 列表（y 起始为 0，返回后由上层重新分配 y）。\r\n   */\r\n  private layoutBlocks(\r\n    elements: IElement[],\r\n    parentPath: Path,\r\n    availableWidth: number,\r\n    sectionWidths?: number[],\r\n    ignoreParagraphIndents = false,\n    verticalText = false\n  ): BlockNode[] {\r\n    let section = 0\r\n    const paragraphs = splitParagraphs(elements)\r\n\r\n    const blocks: BlockNode[] = []\r\n    for (let gi = 0; gi < paragraphs.length; gi++) {\r\n      const g = paragraphs[gi]\r\n      if (g.kind === 'table') {\r\n        blocks.push(this.layoutTable(g.block as ITableElement, parentPath, g.start, availableWidth))\r\n      } else if (g.kind === 'image') {\r\n        const imgEl = g.block as IElement\r\n        const geometry = (imgEl as IImageElement).imageLayout\r\n        if (geometry?.anchored) {\r\n          const issues: { feature: string; reason: string }[] = []\r\n          const issue = (feature: string, reason: string) => issues.push({ feature, reason })\r\n          if (this.layoutZone !== 'main' || parentPath.length) issue('anchor-context', '页眉页脚或表格内浮动图片定位与绕排')\r\n          for (const axis of ['positionH', 'positionV']) {\r\n            const node = geometry.positioning?.find(node => node.name === axis)\r\n            const reference = node?.attributes.relativeFrom\r\n            const hasAnchor = geometry.anchorParagraphId && paragraphs.some(paragraph => paragraph.runs.some(run => run.sourceParagraphId === geometry.anchorParagraphId))\r\n            const supported = axis === 'positionH'\r\n              ? ['page', 'margin', 'leftMargin', 'rightMargin', 'insideMargin', 'outsideMargin', ...(hasAnchor ? ['column'] : [])]\r\n              : ['page', 'margin', 'topMargin', 'bottomMargin', 'insideMargin', 'outsideMargin', ...(hasAnchor ? ['paragraph'] : [])]\r\n            if (!reference || !supported.includes(reference)) issue(`${axis}.${reference ?? 'missing'}`, `${axis} 的 ${reference ?? '缺失'} 参考系（需要真实锚点上下文）`)\r\n            const offset = node?.children.find(child => child.name === 'posOffset')\r\n            const align = node?.children.find(child => child.name === 'align')?.text\r\n            if (offset ? !Number.isFinite(Number(offset.text)) : !['center', 'right', 'bottom', 'inside', 'outside', 'left', 'top'].includes(align ?? '')) {\r\n              issue(`${axis}.position`, `${axis} 缺少有效 align/posOffset`)\r\n            }\r\n          }\r\n          const wrap = geometry.positioning?.find(node => node.name.startsWith('wrap'))\r\n          if (!wrap || !['wrapNone', 'wrapSquare', 'wrapTopAndBottom'].includes(wrap.name)) {\r\n            issue(wrap?.name ?? 'wrap.missing', `${wrap?.name ?? '缺失绕排节点'} 多边形轮廓绕排`)\r\n          }\r\n          if (wrap?.name === 'wrapSquare' && !['left', 'right', 'largest'].includes(wrap.attributes.wrapText)) {\r\n            issue(`wrapSquare.${wrap.attributes.wrapText}`, `${wrap.attributes.wrapText ?? '缺失 wrapText'} 同行排文`)\r\n          }\r\n          if (wrap?.name !== 'wrapNone') {\r\n            const bound = geometry.anchorParagraphId && paragraphs.some(paragraph => paragraph.runs.some(run => run.sourceParagraphId === geometry.anchorParagraphId))\r\n            if (!bound && blocks.some(block => block.kind === 'paragraph')) issue('anchor-reflow', '后置浮动锚点触发前文回流')\r\n            if (paragraphs.some(paragraph => paragraph.kind === 'list')) issue('list-wrap', '浮动图片与列表绕排')\r\n            for (const name of ['distT', 'distB', 'distL', 'distR']) {\r\n              if (geometry.anchorAttributes?.[name] === undefined || !Number.isFinite(Number(geometry.anchorAttributes[name]))) issue(name, `缺少有效 ${name} 绕排距离`)\r\n            }\r\n          }\r\n          if (issues.length) {\r\n            const path: Path = [...parentPath, g.start]\r\n            for (const { feature, reason } of issues) {\r\n              if (!this.diagnostics.some(item => item.zone === this.layoutZone && item.feature === feature && JSON.stringify(item.path) === JSON.stringify(path))) {\r\n                this.diagnostics.push({ code: 'unsupported-floating-image', severity: 'warning', feature,\r\n                  message: `尚未支持 OOXML ${reason}；此浮动图片暂不显示，原始数据保留用于导出，周围内容布局可能与 Office 不一致。`,\r\n                  zone: this.layoutZone, path, action: 'image-omitted' })\r\n              }\r\n            }\r\n            continue\r\n          }\r\n        }\r\n        const imgDisplay = String((imgEl as unknown as Record<string, unknown>).imgDisplay ?? 'block')\r\n        if (imgDisplay === 'surround' || imgDisplay === 'float-top' || imgDisplay === 'float-bottom') {\r\n          const imgBlock = this.layoutImage(imgEl, parentPath, g.start, availableWidth)\r\n          const next = paragraphs[gi + 1]\r\n          if (!(imgEl as IImageElement).imageLayout?.anchored && next && (next.kind === 'normal' || next.kind === 'title' || next.kind === 'list')) {\r\n            const kind: ParagraphBlock['paragraphKind'] = next.kind === 'normal' ? 'normal' : next.kind\r\n            const runsParentPath: Path = (kind === 'normal')\r\n              ? parentPath\r\n              : [...parentPath, next.start, 'valueList']\r\n            const pb = this.layoutParagraph({\r\n              paragraphKind: kind,\r\n              block: next.block,\r\n              runs: next.runs,\r\n              runsParentPath,\r\n              startIndex: next.start,\r\n              endIndex: next.end,\r\n              parentPath,\r\n              availableWidth,\r\n              runStartIndex: next.runStartIndex ?? 0,\r\n              ignoreParagraphIndents,\n              verticalText\n            })\r\n            pb.surroundImage = imgBlock\r\n            if (imgBlock.rect.height > pb.rect.height) {\r\n              pb.rect.height = imgBlock.rect.height\r\n            }\r\n            blocks.push(pb)\r\n            gi++\r\n            continue\r\n          }\r\n          blocks.push(imgBlock)\r\n        } else {\r\n          blocks.push(this.layoutImage(imgEl, parentPath, g.start, availableWidth))\r\n        }\r\n      } else if (g.kind === 'pageBreak') {\r\n        blocks.push({\r\n          kind: 'pageBreak',\r\n          id: nextBlockId(),\r\n          block: g.block as IElement,\r\n          parentPath,\r\n          indexInParent: g.start,\r\n          rect: { x: 0, y: 0, width: availableWidth, height: 0 }\r\n        } as PageBreakBlock)\r\n        if (sectionWidths && ['continuous', 'nextPage', 'evenPage', 'oddPage'].includes(String(g.block?.value))) {\r\n          section++\r\n          if (sectionWidths[section] === undefined) throw new TypeError('Java sections 与正文分节符数量不一致')\r\n          availableWidth = sectionWidths[section]\r\n        }\r\n      } else if (g.kind === 'separator') {\r\n        // 分割线：独立块，高度含上下间距（各 6px）+ 线宽 1px\r\n        const sepHeight = 13\r\n        blocks.push({\r\n          kind: 'separator',\r\n          id: nextBlockId(),\r\n          block: g.block as IElement,\r\n          parentPath,\r\n          indexInParent: g.start,\r\n          rect: { x: 0, y: 0, width: availableWidth, height: sepHeight }\r\n        } as SeparatorBlock)\r\n      } else if (g.kind === 'block') {\r\n        const blockEl = g.block as IElement\r\n        const anyEl = blockEl as unknown as Record<string, unknown>\r\n        const metrics = anyEl.metrics as { width?: number; height?: number } | undefined\r\n        const w = Math.max(1, Number(metrics?.width ?? 420))\r\n        const h = Math.max(1, Number(metrics?.height ?? 320))\r\n        const innerBlock = anyEl.block as { type?: string } | undefined\r\n        if (innerBlock?.type === 'chart') {\r\n          blocks.push({\r\n            kind: 'chart',\r\n            id: nextBlockId(),\r\n            block: blockEl,\r\n            parentPath,\r\n            indexInParent: g.start,\r\n            rect: { x: 0, y: 0, width: w, height: h }\r\n          } as ChartBlock)\r\n        } else {\r\n          blocks.push({\r\n            kind: 'block',\r\n            id: nextBlockId(),\r\n            block: blockEl,\r\n            parentPath,\r\n            indexInParent: g.start,\r\n            rect: { x: 0, y: 0, width: w, height: h }\r\n          } as EmbedBlock)\r\n        }\r\n      } else {\r\n        const kind: ParagraphBlock['paragraphKind'] = g.kind === 'normal' ? 'normal' : g.kind\r\n        const runsParentPath: Path = (kind === 'normal')\r\n          ? parentPath\r\n          : [...parentPath, g.start, 'valueList']\r\n        blocks.push(this.layoutParagraph({\r\n          paragraphKind: kind,\r\n          block: g.block,\r\n          runs: g.runs,\r\n          runsParentPath,\r\n          startIndex: g.start,\r\n          endIndex: g.end,\r\n          parentPath,\r\n          availableWidth,\r\n          runStartIndex: g.runStartIndex ?? 0,\r\n          ignoreParagraphIndents,\n          verticalText\n        }))\r\n      }\r\n    }\r\n    return blocks\r\n  }\r\n\r\n  /**\r\n   * 将单个段落（normal/title/list）排版为 ParagraphBlock：解析段落属性、计算项目符号、\r\n   * 折行、行高、行内定位、rowFlex 对齐，并产出 inline 列表。\r\n   * @param input 段落排版输入（类型/容器/runs/路径/可用宽度等）\r\n   * @returns 段落块（含 lines/inlines 与 rect）\r\n   */\r\n  private layoutParagraph(input: ParagraphInput): ParagraphBlock {\r\n    input = { ...input, typography: this.typography }\n    // Numbered lists depend on preceding counters and must still be evaluated.\r\n    if (input.paragraphKind === 'list') {\r\n      const result = this.computeParagraph(input)\r\n      this.paragraphInputs.set(result, input)\r\n      return result\r\n    }\r\n    const key = JSON.stringify([this.layoutZone, input.runsParentPath, input.startIndex, input.runStartIndex])\r\n    const signature = JSON.stringify([input, input.runs.map(run => this.pageFieldValues.get(run))])\r\n    const cached = this.paragraphCache.get(key)\r\n    // Undo/document replacement may have identical text but different source refs.\r\n    const sameSources = cached?.input.block === input.block &&\r\n      cached.input.runs.length === input.runs.length &&\r\n      input.runs.every((run, index) => run === cached.input.runs[index])\r\n    const layout = cached && sameSources && cached.signature === signature\r\n      ? cached.layout\r\n      : this.computeParagraph(input)\r\n    this.nextParagraphCache.set(key, { signature, input, layout })\r\n    // Pagination, table placement and surrounding images mutate the outer block.\r\n    const result = { ...layout, rect: { ...layout.rect } }\r\n    this.paragraphInputs.set(result, input)\r\n    return result\r\n  }\r\n\r\n  /**\n   * 为连续分节寻找能容纳正文的最小栏高。每次换栏按目标栏宽重排剩余文字，\n   * 尾部空段落不参与平衡判定，但仍保留为可编辑内容。\n   */\n  private balanceColumns(\n    paragraphs: ParagraphBlock[],\n    columns: { widths: number[]; gap: number; gaps?: number[] },\n    availableHeight: number\n  ): { blocks: ParagraphBlock[]; height: number } | null {\n    if (!paragraphs.length || availableHeight <= 0) return null\n    let contentEnd = paragraphs.length\n    while (contentEnd > 0 && !paragraphs[contentEnd - 1].bulletText &&\n      paragraphs[contentEnd - 1].lines.every(line => line.inlines.every(inline =>\n        !inline.text.replace(/[\\s\\u200B\\uFEFF]/g, '')))) contentEnd--\n    if (contentEnd === 0) return null\n    const layouts = new Map<string, ParagraphBlock>()\n    const reflow = (index: number, column: number, resume?: ParagraphInput['resume']) => {\n      const key = JSON.stringify([index, column, resume])\n      let block = layouts.get(key)\n      if (!block) {\n        const original = paragraphs[index]\n        const counters = new Map(this.counters)\n        try {\n          block = this.layoutParagraph({\n            ...this.paragraphInputs.get(original)!,\n            availableWidth: columns.widths[column], resume\n          })\n          for (const property of ['bulletKind', 'bulletText', 'bulletWidth', 'bulletFont',\n            'bulletSize', 'bulletColor', 'bulletBold', 'bulletX'] as const) {\n            Object.assign(block, { [property]: original[property] })\n          }\n          if (resume) block.bulletText = undefined\n          layouts.set(key, block)\n        } finally {\n          this.counters = counters\n        }\n      }\n      return block\n    }\n    const flow = (limit: number) => {\n      const blocks: ParagraphBlock[] = []\n      let column = 0, y = 0, height = 0, x = 0\n      const nextColumn = () => {\n        if (column + 1 >= columns.widths.length) return false\n        x += columns.widths[column] + (columns.gaps?.[column] ?? columns.gap)\n        column++\n        y = 0\n        return true\n      }\n      for (let index = 0; index < contentEnd; index++) {\n        let resume: ParagraphInput['resume']\n        for (;;) {\n          const block = reflow(index, column, resume)\n          let end = 0\n          while (end < block.lines.length &&\n            y + (end + 1 === block.lines.length ? block.rect.height :\n              block.lines[end].y + block.lines[end].height) <= limit + 0.001) end++\n          if (end === 0) {\n            if (!nextColumn()) return null\n            continue\n          }\n          const whole = end === block.lines.length\n          const fragmentHeight = whole ? block.rect.height : block.lines[end - 1].y + block.lines[end - 1].height\n          blocks.push({\n            ...block, id: nextBlockId(), rect: { ...block.rect, x: block.rect.x + x, y, height: fragmentHeight },\n            lines: block.lines.slice(0, end)\n          })\n          y += fragmentHeight\n          height = Math.max(height, y)\n          if (whole) break\n          const next = block.lines[end].startPosition\n          if (!next || !nextColumn()) return null\n          resume = next\n        }\n      }\n      return { blocks, height }\n    }\n    if (!flow(availableHeight)) return null\n    let low = 0, high = availableHeight\n    for (let iteration = 0; iteration < 18 && high - low > 0.01; iteration++) {\n      const middle = (low + high) / 2\n      if (flow(middle)) high = middle\n      else low = middle\n    }\n    const balanced = flow(high)\n    if (!balanced) return null\n    const lastBlock = balanced.blocks[balanced.blocks.length - 1]\n    for (const paragraph of paragraphs.slice(contentEnd)) {\n      balanced.blocks.push({\n        ...paragraph,\n        id: nextBlockId(),\n        rect: { ...paragraph.rect, x: lastBlock?.rect.x ?? 0, y: balanced.height, height: 0 },\n        lines: paragraph.lines.map(line => ({\n          ...line, y: 0, height: 0, baseline: 0, inlines: []\n        }))\n      })\n    }\n    return balanced\n  }\n\n  private computeParagraph(input: ParagraphInput): ParagraphBlock {\r\n    const {\r\n      paragraphKind, block, runs, runsParentPath,\r\n      startIndex, endIndex, parentPath,\r\n      runStartIndex = 0\r\n    } = input\r\n    let availableWidth = input.availableWidth\r\n\r\n    // 段落属性优先级：block（title/list 容器） > 段内任一 run（docx-parser 会把 pPr 附在 run 上，未必是第 1 个）\r\n    // 段落级属性字段集合\r\n    const PARA_KEYS = [\r\n      'rowFlex',\r\n      'paragraphFrame',\r\n      'paragraphStyleId',\r\n      'paragraphFirstLineIndent',\r\n      'paragraphIndentation',\n      'paragraphIndentationBaseline',\n      'paragraphIndentLeft',\r\n      'paragraphIndentRight',\r\n      'indentHanging',\r\n      'paragraphSpacingBefore',\r\n      'paragraphSpacingAfter',\r\n      'paragraphMarkSize',\r\n      'snapToGrid',\r\n      'paragraphBorder',\r\n      'lineHeight',\r\n      'lineHeightRule'\r\n    ] as const\r\n    const containerAttrs = (block ?? {}) as unknown as Record<string, unknown>\r\n    // 扫描所有 runs，收集段落级属性（第一个非空值胜出）\r\n    const collectedRunAttrs: Record<string, unknown> = {}\r\n    for (const r of runs) {\r\n      const ra = r as unknown as Record<string, unknown>\r\n      for (const k of PARA_KEYS) {\r\n        if (collectedRunAttrs[k] == null && ra[k] != null) {\r\n          collectedRunAttrs[k] = ra[k]\r\n        }\r\n      }\r\n    }\r\n    const attr = (key: string): unknown =>\r\n      containerAttrs[key] != null ? containerAttrs[key] : collectedRunAttrs[key]\r\n\r\n    // 页眉页脚的页码框按页边距区域定位，框内文字仍使用自己的段落对齐属性。\r\n    const frame = attr('paragraphFrame') as IElement['paragraphFrame']\r\n    const positionedFrame = frame?.hAnchor === 'margin' &&\r\n      ['left', 'center', 'right'].includes(frame.xAlign) &&\r\n      /^(header|footer)(:|$)/.test(this.layoutZone)\r\n    const frameWidth = positionedFrame ? Number(frame?.w) / 15 : 0\r\n    if (frameWidth > 0) availableWidth = Math.min(availableWidth, frameWidth)\r\n    const rowFlex = (attr('rowFlex') as LineBox['rowFlex']) || 'left'\r\n    let firstIndent = input.ignoreParagraphIndents ? 0 : Number(attr('paragraphFirstLineIndent') ?? 0)\n    // 段落左右缩进：docx 可能出现负值（\"悬入左边距\"）。若不夹到 0，会使\r\n    // usableWidth > availableWidth，行宽越过 block 边界，超出的字符会被\r\n    // block bitmap 裁掉，表现为文字丢失。此处按可视排版约束夹到 [0, +inf)。\r\n    let indentLeft = input.ignoreParagraphIndents ? 0 : Math.max(0, Number(attr('paragraphIndentLeft') ?? 0))\r\n    const indentRight = input.ignoreParagraphIndents ? 0 : Math.max(0, Number(attr('paragraphIndentRight') ?? 0))\r\n    // 悬挂缩进：正值表示首行相对后续行左移 hangIndent\r\n    const indentHanging = input.ignoreParagraphIndents ? 0 : Number(attr('indentHanging') ?? 0)\r\n    const spacingBefore = input.resume ? 0 : Number(attr('paragraphSpacingBefore') ?? 0)\n    const spacingAfter = Number(attr('paragraphSpacingAfter') ?? 0)\r\n    const paragraphMarkSize = Number(attr('paragraphMarkSize') ?? 0)\r\n    const snapToGrid = attr('snapToGrid') !== false\r\n    const docGridLinePitch = Number(input.docGridLinePitch ?? 0)\r\n    const rawLineHeight = Number(attr('lineHeight') ?? (docGridLinePitch > 0 ? 1 : this.opts.defaultLineHeight))\r\n    const lineHeightRule = (attr('lineHeightRule') as string) || 'auto'\r\n\r\n    // 项目符号（跟随首个 run 的字体/字号/颜色/粗细）\r\n    let bulletKind: 'symbol' | 'text' | undefined\r\n    let bulletText: string | undefined\r\n    let bulletWidth = 0\r\n    let bulletFont: string | undefined\r\n    let bulletSize: number | undefined\r\n    let bulletColor: string | undefined\r\n    let bulletBold: boolean | undefined\r\n    let bulletX: number | undefined\r\n    // 是否使用 Word 悬挂缩进模型（有 indentHanging 时为 true）\r\n    let useWordHanging = false\r\n    // 悬挂缩进量（编号在文字左侧的偏移）\r\n    let bulletHanging = 0\r\n    // 项目符号/编号：list 段落必定处理；title 段落若带 listNumbering（Word heading 关联多级列表）也一并处理\r\n    const hasNumbering = !!(block as unknown as { listNumbering?: unknown } | undefined)?.listNumbering\r\n    if (block && (paragraphKind === 'list' || (paragraphKind === 'title' && hasNumbering))) {\r\n      const listEl = block as IListElement\r\n      const res = resolveBullet(listEl, this.counters)\r\n      // 层级缩进\r\n      const level = Math.max(0, listEl.listLevel ?? 0)\r\n      const listHanging = Number(listEl.listHanging ?? 24)\r\n      const listBaseIndent = Number(listEl.listIndent ?? listEl.listNumbering?.indentLeft ?? 0)\r\n      // 编号悬挂：仅当 listNumbering 明确定义 indentHanging 时才用 Word 悬挂模型\r\n      bulletHanging = Number(listEl.listNumbering?.indentHanging ?? 0)\r\n      useWordHanging = bulletHanging > 0\r\n      // title 段落（Word heading 关联多级列表）：段落本身已带自己的缩进/对齐，\r\n      // numbering.indentLeft 只作为\"编号列宽提示\"，不应再叠加到段落 indentLeft，\r\n      // 否则整段被推到右侧（源数据里 indentLeft 常带异常大值，如 368px）。\r\n      if (paragraphKind !== 'title') {\r\n        const proposed = listBaseIndent + level * listHanging\r\n        // 保护性上限：新缩进不得占用 > 60% 可用宽度，防止数据异常导致整段跑飞\r\n        const cap = availableWidth * 0.6\r\n        indentLeft = Math.max(indentLeft, Math.min(proposed, cap))\r\n      }\r\n      // 字体/字号/颜色 取自首个 text run\r\n      const firstText = runs.find(r => r.type === 'text') as IElement | undefined\r\n      const fa = firstText as unknown as Record<string, unknown> | undefined\r\n      bulletSize = Number(fa?.size ?? this.opts.defaultSize)\r\n      bulletColor = String(fa?.color ?? '#000000')\r\n      bulletBold = !!fa?.bold\r\n\r\n      if (res.isSymbol) {\r\n        // 无序符号：使用符号字体栈（含 Wingdings）\r\n        bulletKind = 'symbol'\r\n        bulletFont = detectWingdings() ? BULLET_FONT_STACK : BULLET_FONT_STACK_FALLBACK\r\n        bulletText = res.text\r\n      } else {\r\n        // 有序编号：使用文本字体\r\n        bulletKind = 'text'\r\n        const rawBulletFont = String(fa?.font ?? this.opts.defaultFont)\r\n        bulletFont = FONT_FAMILY_CSS[rawBulletFont] ?? rawBulletFont\r\n        bulletText = res.text\r\n      }\r\n      // 度量宽度：符号后加固定间距（half em）\r\n      const symbolGap = bulletSize * 0.4\r\n      const glyphW = this.measure.textWidth(bulletText, bulletFont, bulletSize, bulletBold)\r\n      bulletWidth = glyphW + symbolGap\r\n      // 编号列内对齐（lvlJc）：\r\n      //   useWordHanging（有 indentHanging）：indentLeft = 文字位置，编号在 indentLeft - bulletHanging\r\n      //   否则（无 indentHanging）：indentLeft = 编号位置，文字在 indentLeft + bulletWidth（原行为）\r\n      //   编号绘制 x = firstLine.x + bulletX（bulletX 为负）\r\n      const jc = res.lvlJc\r\n      const hangingOffset = useWordHanging ? bulletHanging : bulletWidth\r\n      if (jc === 'center') {\r\n        const inner = Math.max(0, hangingOffset - symbolGap - glyphW)\r\n        bulletX = -hangingOffset + inner / 2\r\n      } else {\r\n        bulletX = -hangingOffset\r\n      }\r\n    }\r\n\r\n    // 每行可用宽度：Word 悬挂模型下编号在悬挂区不占行宽；否则编号占 bulletWidth\r\n    const bulletWidthForLine = useWordHanging ? 0 : bulletWidth\r\n    const lines: LineBox[] = []\r\n    let currentInlines: InlineBox[] = []\r\n    let currentLineStart: LineBox['startPosition']\n    let currentLineWidth = 0\r\n    let compressionCandidates: { inline: InlineBox; originalWidth: number; metrics: CompressionMetrics }[] = []\n    let currentMaxSize = 0\r\n    let isFirstLine = !input.resume\n\r\n    // 首行偏移相对于文本前缩进，负值表示悬挂。\r\n    let firstLineOffset = attr('indentHanging') != null ? -indentHanging : firstIndent\n    let flowY = spacingBefore\r\n    const lineRegion = (): { x: number; width: number } => {\r\n      let left = indentLeft + bulletWidthForLine + (isFirstLine ? firstLineOffset : 0)\r\n      let right = availableWidth - indentRight\r\n      for (const exclusion of input.exclusions ?? []) {\r\n        const r = exclusion.rect\r\n        if (flowY >= r.y + r.height || flowY + computeLineHeight(currentMaxSize || this.opts.defaultSize) <= r.y) continue\r\n        if (exclusion.topBottom || (r.x <= left && r.x + r.width >= right)) {\r\n          flowY = r.y + r.height\r\n          return lineRegion()\r\n        }\r\n        const leftWidth = Math.max(0, r.x - left), rightWidth = Math.max(0, right - r.x - r.width)\r\n        const useLeft = exclusion.side === 'left' || (exclusion.side !== 'right' && leftWidth >= rightWidth)\r\n        if (useLeft) right = Math.min(right, r.x)\r\n        else left = Math.max(left, r.x + r.width)\r\n        if (right - left < (currentMaxSize || this.opts.defaultSize)) {\r\n          flowY = r.y + r.height\r\n          return lineRegion()\r\n        }\r\n      }\r\n      return { x: left, width: Math.max(1, right - left) }\r\n    }\r\n    const currentLineMaxWidth = (): number => lineRegion().width\r\n\n    // 只有整段所需空间都能从标点留白中取得时才收缩，避免失败后留下半压缩状态。\n    const compressLine = (needed: number): boolean => {\n      const capacity = compressionCandidates.reduce((sum, item) => sum + item.inline.width - item.metrics.minWidth, 0)\n      if (needed <= 0) return true\n      if (capacity + 0.001 < needed || capacity <= 0) return false\n      const ratio = Math.min(1, needed / capacity)\n      for (const item of compressionCandidates) {\n        const shrink = (item.inline.width - item.metrics.minWidth) * ratio\n        item.inline.width -= shrink\n        item.inline.glyphAdvance = item.inline.width\n        item.inline.glyphOffset = -(item.originalWidth - item.inline.width) * item.metrics.leadingRatio\n      }\n      currentLineWidth = 0\n      for (const inline of currentInlines) {\n        inline.x = currentLineWidth\n        currentLineWidth += inline.width\n      }\n      return true\n    }\n\r\n    // Word 行距 4 种模式：\r\n    //   'auto'    → lineHeight 是倍数（1.0 单倍；1.5 一倍半；2.0 双倍；数值任意）\r\n    //   'exact'   → lineHeight 是像素固定值（不小于字号）\r\n    //   'atLeast' → lineHeight 是像素最小值，字号 > lineHeight 时会自动扩展\r\n    //   'multiple'→ 与 auto 同义（Word 里\"多倍行距\"）\r\n    const computeLineHeight = (size: number): number => {\r\n      if (input.verticalText) return Math.max(1, size)\n      const lh = rawLineHeight\r\n      switch (lineHeightRule) {\r\n        case 'exact':    return Math.max(1, lh) // 固定值\r\n        case 'atLeast':  return Math.max(size * 1.15, lh) // 最小值\r\n        case 'multiple':\r\n        case 'auto':\r\n        default: {\r\n          // auto：若给的是\"合理的倍数\"（0.5..5）按倍数处理；否则按 px 处理（部分导出用 px 值 + auto）\r\n          if (lh > 0 && lh <= 5) return size * lh * 1.15\r\n          return Math.max(size, lh)\r\n        }\r\n      }\r\n    }\r\n\r\n    const finalizeLine = (isLastLine: boolean) => {\r\n      const size = currentMaxSize || paragraphMarkSize || this.opts.defaultSize\r\n      const naturalLineHeight = computeLineHeight(size)\r\n      // 网格定义行距下限；固定行距由段落自己决定，不受文档网格抬高。\r\n      const lh = snapToGrid && docGridLinePitch > 0 && lineHeightRule !== 'exact'\r\n        ? Math.max(naturalLineHeight, docGridLinePitch)\r\n        : naturalLineHeight\r\n      const region = lineRegion()\r\n      const lineXBase = region.x\r\n      // 把 inline.x 从\"相对 line 起点\"平移到\"相对块起点\"\r\n      for (const inl of currentInlines) inl.x += lineXBase\r\n      const line: LineBox = {\r\n        x: lineXBase,\r\n        y: flowY,\r\n        width: region.width,\r\n        height: lh,\r\n        baseline: lh * 0.82,\r\n        inlines: currentInlines,\r\n        startPosition: currentLineStart,\n        rowFlex,\r\n        isLastLine\r\n      }\r\n      lines.push(line)\r\n      flowY += lh\r\n      currentInlines = []\r\n      currentLineStart = undefined\n      currentLineWidth = 0\r\n      compressionCandidates = []\n      currentMaxSize = 0\r\n      isFirstLine = false\r\n    }\r\n\r\n    const expandedRuns = runs.flatMap((rawRun, sourceIndex): {\r\n      rawRun: IElement; sourceIndex: number; path: Path; hyperlink?: IElement & Record<string, unknown>; presentation?: ControlPresentation\r\n    }[] => {\r\n      const path: Path = [...runsParentPath, (paragraphKind === 'normal' ? startIndex : runStartIndex) + sourceIndex]\r\n      if (rawRun.type === 'hyperlink') {\r\n        const children = (rawRun as IElement & { valueList?: IElement[] }).valueList ?? []\r\n        return children.map((child, index) => ({\r\n          rawRun: child, sourceIndex, path: [...path, 'valueList', index], hyperlink: rawRun\r\n        }))\r\n      }\r\n      return isControl(rawRun)\r\n        ? getControlPresentation(rawRun, this.opts.printing).map(presentation => ({ rawRun, sourceIndex, path, presentation }))\r\n        : [{ rawRun, sourceIndex, path }]\r\n    })\r\n    const layoutRuns = expandedRuns.map(({ rawRun, hyperlink, presentation }) => {\r\n      if (hyperlink && (rawRun.type === 'text' || rawRun.type === 'tab')) {\r\n        const tocEntry = (hyperlink.extension?.toc as { role?: string } | undefined)?.role === 'entry'\r\n        return {\r\n          ...rawRun,\r\n          type: rawRun.type === 'tab' ? 'text' : rawRun.type,\r\n          value: rawRun.type === 'tab' ? '\\t' : rawRun.value,\r\n          color: rawRun.color ?? hyperlink.color ?? (tocEntry ? undefined : '#0000FF'),\r\n          underline: rawRun.underline ?? hyperlink.underline ?? (tocEntry ? undefined : true),\r\n          extension: { ...hyperlink.extension, ...rawRun.extension }\r\n        } as IElement\r\n      }\r\n      if (isControl(rawRun) && presentation) {\r\n        return {\r\n          ...rawRun, type: 'text', value: presentation.text,\r\n          color: presentation.placeholder ? '#999999' : rawRun.color\r\n        } as IElement\r\n      }\r\n      return rawRun\r\n    })\r\n    // 同一 w:fitText 标识可跨多个 Run；先度量整组，再统一缩放，不能每个 Run 各占一份总宽度。\n    const fitScales = new Map<number, number>()\n    for (let start = 0; start < layoutRuns.length;) {\n      const first = layoutRuns[start]\n      if (first.type !== 'text') { start++; continue }\n      const firstTextRun = first as ITextElement\n      const fitTextWidth = Number(firstTextRun.fitTextWidth)\n      if (!(fitTextWidth > 0)) { start++; continue }\n      let end = start + 1\n      while (firstTextRun.fitTextId != null && end < layoutRuns.length) {\n        const next = layoutRuns[end]\n        if (next.type !== 'text' || next.fitTextId !== firstTextRun.fitTextId ||\n          next.fitTextWidth !== firstTextRun.fitTextWidth) break\n        end++\n      }\n      let naturalWidth = 0\n      let count = 0\n      for (let index = start; index < end; index++) {\n        const run = layoutRuns[index] as ITextElement\n        const size = run.size ?? this.opts.defaultSize\n        for (const ch of run.value) {\n          if (/[\\n\\u200B\\uFEFF]/.test(ch)) continue\n          naturalWidth += this.measure.charWidth(ch, resolveTextFont(run, ch, this.opts.defaultFont),\n            size, !!run.bold, !!run.italic) + (run.letterSpacing ?? 0)\n          count++\n        }\n      }\n      if (naturalWidth > 0) {\n        for (let index = start; index < end; index++) fitScales.set(index, fitTextWidth / naturalWidth)\n        // 字符单位缩进以定宽后的字符宽度为基准，而非未经缩放的字号。\n        const indentation = attr('paragraphIndentation') as Record<string, string> | undefined\n        const baseline = attr('paragraphIndentationBaseline') as Record<string, number> | undefined\n        if (start === 0 && count > 0 && !input.ignoreParagraphIndents && indentation?.firstLineChars != null &&\n          baseline?.firstLine === firstIndent) {\n          firstIndent = Number(indentation.firstLineChars) / 100 * fitTextWidth / count\n          if (attr('indentHanging') == null) firstLineOffset = firstIndent\n        }\n      }\n      start = end\n    }\n    // Imported PAGEREF results may follow the tab in separate runs, with hidden fields in between.\r\n    const tocPageWidth = (runIndex: number, offset: number): number => {\r\n      let width = 0\r\n      for (let i = runIndex; i < layoutRuns.length; i++) {\r\n        const run = layoutRuns[i]\r\n        if (run.type !== 'text' || run.extension?.fieldMarker || run.extension?.bookmarkMarker) continue\r\n        const text = String(run.value ?? '').slice(i === runIndex ? offset : 0)\r\n        const size = Number(run.size ?? this.opts.defaultSize)\r\n        for (const ch of text) {\r\n          if (ch === '\\n' || ch === '\\t') return width\r\n          if (ch === '\\u200B' || ch === '\\uFEFF') continue\r\n          const font = resolveTextFont(run as ITextElement, ch, this.opts.defaultFont)\n          width += this.measure.charWidth(ch, font, size, !!run.bold, !!run.italic)\r\n        }\r\n      }\r\n      return width\r\n    }\r\n\r\n    const resumeIndex = input.resume\n      ? expandedRuns.findIndex(item => JSON.stringify(item.path) === JSON.stringify(input.resume!.path)) : 0\n    for (let ri = Math.max(0, resumeIndex); ri < expandedRuns.length; ri++) {\n      const { rawRun, sourceIndex, path: runPath, hyperlink, presentation } = expandedRuns[ri]\r\n      const run = layoutRuns[ri]\r\n      if (run.type !== 'text') continue\r\n      const hyperlinkUrl = hyperlink ? String(hyperlink.url ?? hyperlink.value ?? '') : undefined\r\n      const controlId = isControl(rawRun) ? String(rawRun.id ?? '') : undefined\r\n      const controlPlaceholder = presentation?.placeholder\r\n      const anyRun = run as unknown as Record<string, unknown>\r\n      const fontForChar = (ch: string): string =>\n        resolveTextFont(run as ITextElement, ch, this.opts.defaultFont)\n      const font = fontForChar('')\n      const size = Number(anyRun.size ?? this.opts.defaultSize)\r\n      const fitScale = fitScales.get(ri)\n      const runSpacing = Number(anyRun.letterSpacing ?? 0)\n      const customAdvance = fitScale != null || runSpacing !== 0\n      const bold = !!anyRun.bold\r\n      const italic = !!anyRun.italic\r\n      const color = String(anyRun.color ?? '#000000')\r\n      const bgColor = anyRun.highlight ? String(anyRun.highlight) : undefined\r\n      const strikeout = !!anyRun.strikeout\r\n      const underline = !!anyRun.underline\r\n      const groupIds = Array.isArray(anyRun.groupIds) ? anyRun.groupIds as string[] : undefined\r\n      const value = this.pageFieldValues.get(rawRun) ?? String(anyRun.value ?? '')\r\n\r\n      if (!value) {\r\n        if (rawRun.type === 'text' && !rawRun.extension?.fieldMarker && !rawRun.extension?.bookmarkMarker) {\r\n          const emptySize = Number(anyRun.size ?? (paragraphMarkSize || this.opts.defaultSize))\r\n          currentInlines.push({\r\n            run,\r\n            path: runPath,\r\n            startOffset: 0, endOffset: 0, text: '', x: currentLineWidth, y: 0,\r\n            width: 0, height: emptySize, font, size: emptySize, bold, italic, color, baseline: 0,\r\n            bgColor, strikeout, underline, groupIds, hyperlink: hyperlinkUrl\r\n          })\r\n          currentMaxSize = Math.max(currentMaxSize, emptySize)\r\n        }\r\n        continue\r\n      }\r\n      // 跳过段落终止符（零宽字符），不产出 inline，但 ri 仍递进以保持索引对齐\r\n      if (!controlId && /^[\\u200B\\uFEFF]+$/.test(value)) continue\r\n\r\n      let cursorInRun = input.resume && ri === resumeIndex ? input.resume.offset : 0\n      const spaceWidth = balancedSpaceWidth(run as ITextElement, input.typography, this.measure, this.opts.defaultFont, size)\n      const compressions = value.split('').map(ch => controlId || customAdvance ? undefined :\n        punctuationCompression(ch, fontForChar(ch), size, bold, italic, input.typography, this.measure))\n      const charWidth = (ch: string): number => input.verticalText ? size :\n        presentation?.mark && ch === CONTROL_MARK ? size :\r\n        controlId && value === '\\u200B' ? 20 :\r\n        ((ch === ' ' && spaceWidth != null ? spaceWidth :\n        this.measure.charWidth(ch, fontForChar(ch), size, bold, italic)) + runSpacing) * (fitScale ?? 1)\n\r\n      while (cursorInRun < value.length) {\r\n        if (!currentLineStart) currentLineStart = { path: runPath, offset: cursorInRun }\n        const font = fontForChar(value[cursorInRun])\n        const maxLineWidth = currentLineMaxWidth()\r\n        let remaining = maxLineWidth - currentLineWidth\n        // 段末普通空格可挂在行末，不能单独挤出一个空白行；不改动源文本。\n        const trailingSpace = /^ +$/.test(value.slice(cursorInRun)) &&\n          layoutRuns.slice(ri + 1).every(next => next.type === 'text' && /^[ \\u200B\\uFEFF]*$/.test(next.value))\n        const advance = trailingSpace ? Math.max(0, Math.min(charWidth(' '), remaining / (value.length - cursorInRun))) :\n          customAdvance ? charWidth(value[cursorInRun]) :\n          value[cursorInRun] === ' ' ? spaceWidth : undefined\n        // 数字和拉丁词优先整体放置；超过整行宽度的长串仍允许紧急折行。\n        const word = /^[A-Za-z0-9]+/.exec(value.slice(cursorInRun))?.[0]\n        if (word && currentLineWidth > 0) {\n          const wordWidth = [...word].reduce((sum, ch) => sum + charWidth(ch), 0)\n          if (wordWidth > remaining + 0.001 && wordWidth <= maxLineWidth) {\n            if (!compressLine(wordWidth - remaining)) {\n              finalizeLine(false)\n              continue\n            }\n            remaining = maxLineWidth - currentLineWidth\n          }\n        }\n        const tocEntry = (run.extension?.toc as { role?: string } | undefined)?.role === 'entry'\r\n        if (tocEntry && value[cursorInRun] === '\\t') {\r\n          const pageWidth = tocPageWidth(ri, cursorInRun + 1)\r\n          if (currentLineWidth > 0 && remaining < pageWidth + size) {\r\n            finalizeLine(false)\r\n            continue\r\n          }\r\n          const width = Math.max(0, remaining - pageWidth)\r\n          currentInlines.push({\r\n            run, path: runPath, startOffset: cursorInRun, endOffset: cursorInRun + 1,\r\n            text: '\\t', x: currentLineWidth, y: 0, width, height: size,\r\n            font, size, bold, italic, color, baseline: 0,\r\n            hyperlink: hyperlinkUrl\r\n          })\r\n          currentLineWidth += width\r\n          currentMaxSize = Math.max(currentMaxSize, size)\r\n          cursorInRun++\r\n          continue\r\n        }\r\n        // 若当前行已有内容且首个字符放不下 → 先换行再试，避免溢出被裁\r\n        if (currentLineWidth > 0 && value[cursorInRun] !== '\\n') {\r\n          const firstW = advance ?? charWidth(value[cursorInRun])\n          if (firstW > remaining + 0.001) {\r\n            if (!compressLine(firstW - remaining)) {\n              finalizeLine(false)\n              continue\n            }\n            remaining = maxLineWidth - currentLineWidth\n          }\r\n        }\r\n        let take = 0\r\n        let takenWidth = 0\r\n        for (let i = cursorInRun; i < value.length; i++) {\r\n          const ch = value[i]\r\n          if (tocEntry && ch === '\\t') break\r\n          if (take > 0 && customAdvance) break\n          // 仅拆分布局片段，不拆分文档 Run，确保绘制、光标和导出沿用同一字符偏移。\n          if (take > 0 && fontForChar(ch) !== font) break\n          if (take > 0 && (compressions[cursorInRun] || compressions[i])) break\n          if (take > 0 && (ch === ' ') !== (value[cursorInRun] === ' ')) break\n          if (take > 0 && /[A-Za-z0-9]/.test(ch) && !/[A-Za-z0-9]/.test(value[i - 1])) break\n          const w = advance ?? charWidth(ch)\n          if (ch === '\\n') { take = i - cursorInRun; break }\r\n          if (takenWidth + w > remaining + 0.001 && take > 0) break\r\n          takenWidth += w\r\n          take++\r\n        }\r\n        if (take === 0 && cursorInRun < value.length && value[cursorInRun] === '\\n') {\r\n          // 显式换行\r\n          finalizeLine(false)\r\n          cursorInRun++\r\n          continue\r\n        }\r\n        if (take === 0) {\r\n          // 剩余空间放不下一个字符 → 换行重试\r\n          finalizeLine(false)\r\n          continue\r\n        }\r\n        const segEnd = cursorInRun + take\r\n        const text = value.slice(cursorInRun, segEnd)\r\n        const segWidth = takenWidth\r\n        const inline: InlineBox = {\r\n          run: isControl(rawRun) ? rawRun : run,\r\n          path: runPath,\r\n          startOffset: controlId ? 0 : cursorInRun,\r\n          endOffset: controlId ? 1 : segEnd,\r\n          text,\r\n          x: currentLineWidth, // 暂存为\"相对 line 起点\"，finalizeLine 会平移\r\n          y: 0,\r\n          width: segWidth,\r\n          glyphAdvance: advance,\n          glyphScale: fitScale,\n          height: size,\r\n          font,\r\n          size,\r\n          bold,\r\n          italic,\r\n          color,\r\n          bgColor,\r\n          strikeout,\r\n          underline,\r\n          baseline: 0,\r\n          groupIds,\r\n          hyperlink: hyperlinkUrl,\r\n          controlId,\r\n          controlPlaceholder,\r\n          controlTextOffset: controlId ? cursorInRun : undefined,\r\n          controlStart: controlId ? cursorInRun === 0 && expandedRuns[ri - 1]?.sourceIndex !== sourceIndex : undefined,\r\n          controlEnd: controlId ? segEnd === value.length && expandedRuns[ri + 1]?.sourceIndex !== sourceIndex : undefined,\r\n          controlMark: text.includes(CONTROL_MARK) ? presentation?.mark : undefined,\r\n          controlBracketOffsets: presentation?.bracketOffsets\r\n            ?.filter(offset => offset >= cursorInRun && offset < segEnd)\r\n            .map(offset => offset - cursorInRun),\r\n          controlOptionValue: presentation?.optionValue\r\n        }\r\n        currentInlines.push(inline)\r\n        const compression = compressions[cursorInRun]\n        if (compression) compressionCandidates.push({ inline, originalWidth: segWidth, metrics: compression })\n        currentLineWidth += segWidth\r\n        if (size > currentMaxSize) currentMaxSize = size\r\n        cursorInRun = segEnd\r\n        if (cursorInRun < value.length && value[cursorInRun] === '\\n') {\r\n          finalizeLine(false)\r\n          cursorInRun++ // 消费换行符\r\n        }\r\n      }\r\n    }\r\n    // 空段兜底：若整个段落未产出任何 inline（所有 text run 为空字符串或零宽占位），\r\n    // 为首个空 text run 生成零宽 caret 承载 inline，确保光标可定位、行高不塌陷。\r\n    if (currentInlines.length === 0 && lines.length === 0) {\r\n      let placeholderRun: IElement | null = null\r\n      let placeholderRi = -1\r\n      // 优先选空字符串 run（光标通常落在 rest run），跳过零宽分隔符 run\r\n      for (let ri = 0; ri < runs.length; ri++) {\r\n        if (runs[ri].type !== 'text') continue\r\n        const v = String((runs[ri] as unknown as Record<string, unknown>).value ?? '')\r\n        if (v === '') { placeholderRun = runs[ri]; placeholderRi = ri; break }\r\n      }\r\n      // 退而求其次：用首个 text run（可能是零宽分隔符）\r\n      if (!placeholderRun) {\r\n        for (let ri = 0; ri < runs.length; ri++) {\r\n          if (runs[ri].type === 'text') { placeholderRun = runs[ri]; placeholderRi = ri; break }\r\n        }\r\n      }\r\n      if (placeholderRun) {\r\n        const pr = placeholderRun as unknown as Record<string, unknown>\r\n        const rawFont = String(pr.font ?? this.opts.defaultFont)\r\n        const font = FONT_FAMILY_CSS[rawFont] ?? rawFont\r\n        const size = Number(pr.size ?? (paragraphMarkSize || this.opts.defaultSize))\r\n        const runPath: Path = paragraphKind === 'normal'\r\n          ? [...runsParentPath, startIndex + placeholderRi]\r\n          : [...runsParentPath, runStartIndex + placeholderRi]\r\n        currentInlines.push({\r\n          run: placeholderRun,\r\n          path: runPath,\r\n          startOffset: 0,\r\n          endOffset: 0,\r\n          text: '',\r\n          x: 0,\r\n          y: 0,\r\n          width: 0,\r\n          height: size,\r\n          font,\r\n          size,\r\n          bold: !!pr.bold,\r\n          italic: !!pr.italic,\r\n          color: String(pr.color ?? '#000000'),\r\n          bgColor: undefined,\r\n          strikeout: false,\r\n          underline: false,\r\n          baseline: 0,\r\n          groupIds: undefined\r\n        })\r\n        currentMaxSize = size\r\n      }\r\n    }\r\n    if (currentInlines.length > 0 || lines.length === 0) {\r\n      currentMaxSize = Math.max(currentMaxSize, paragraphMarkSize)\r\n      finalizeLine(true)\r\n    }\r\n\r\n    // 未指定宽度的框架随内容收缩，再整体居左/居中/居右，避免与框内 rowFlex 混淆。\r\n    if (positionedFrame && !(frameWidth > 0)) {\r\n      availableWidth = Math.min(availableWidth, Math.max(1, ...lines.map(line =>\r\n        Math.max(line.x, ...line.inlines.map(inline => inline.x + inline.width)) + indentRight)))\r\n    }\r\n    if (positionedFrame) {\r\n      for (const line of lines) line.width = Math.max(1, availableWidth - indentRight - line.x)\r\n    }\r\n\r\n    // 分配行 y 与 inline y/baseline（相对块本地坐标）\r\n    let yy = spacingBefore\r\n    // 跟踪块内内容实际右边缘（含 rowFlex 平移后的最大 x），用于兜底 bitmap 宽度\r\n    let contentRight = 0\r\n    for (const line of lines) {\r\n      yy = Math.max(yy, line.y)\r\n      line.y = yy\r\n      line.baseline = 0.8 * line.height\r\n      for (const inl of line.inlines) {\r\n        inl.y = yy\r\n        inl.baseline = yy + line.baseline\r\n      }\r\n      applyRowFlex(line, line.width)\r\n      for (const inl of line.inlines) {\r\n        const r = inl.x + inl.width\r\n        if (r > contentRight) contentRight = r\r\n      }\r\n      yy += line.height\r\n    }\r\n    yy += spacingAfter\r\n\r\n    // rect.width 必须能覆盖实际内容最大右边缘，避免行末字符被 bitmap 裁掉\r\n    // （浮点误差 / rowFlex 分散对齐 / 负缩进兜底后仍可能微超 availableWidth）\r\n    const rectWidth = Math.max(availableWidth, Math.ceil(contentRight))\r\n    const frameX = !positionedFrame || frame?.xAlign === 'left' ? 0\r\n      : (input.availableWidth - availableWidth) / (frame?.xAlign === 'center' ? 2 : 1)\r\n    const rect: Rect = { x: frameX, y: 0, width: rectWidth, height: yy }\r\n    return {\r\n      kind: 'paragraph',\r\n      id: nextBlockId(),\r\n      paragraphKind,\r\n      verticalText: input.verticalText,\n      block,\r\n      paragraphBorder: attr('paragraphBorder') as ParagraphBlock['paragraphBorder'],\r\n      startIndex,\r\n      endIndex,\r\n      parentPath,\r\n\r\n      rect,\r\n      lines,\r\n      bulletKind,\r\n      bulletText,\r\n      bulletWidth,\r\n      bulletFont,\r\n      bulletSize,\r\n      bulletColor,\r\n      bulletBold,\r\n      bulletX\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 将图片元素排版为 ImageBlock：根据 width/height/rotate 计算占位尺寸与水平对齐位置。\r\n   * @param el 图片元素\r\n   * @param parentPath 父容器路径\r\n   * @param index 在父容器中的索引\r\n   * @param availableWidth 可用宽度（用于对齐计算）\r\n   * @returns 图片块\r\n   */\r\n  private layoutImage(el: IElement, parentPath: Path, index: number, availableWidth: number): ImageBlock {\r\n    const anyEl = el as unknown as Record<string, unknown>\r\n    const w = Number(anyEl.width)\r\n    const h = Number(anyEl.height)\r\n    const rotate = Number(anyEl.rotate ?? 0) * Math.PI / 180\r\n    const occupiedW = Math.abs(w * Math.cos(rotate)) + Math.abs(h * Math.sin(rotate))\r\n    const occupiedH = Math.abs(w * Math.sin(rotate)) + Math.abs(h * Math.cos(rotate))\r\n    // 水平对齐：rowFlex 决定 x 位置\r\n    const rowFlex = String(anyEl.rowFlex ?? 'left')\r\n    let x = 0\r\n    if (occupiedW < availableWidth) {\r\n      if (rowFlex === 'center') x = (availableWidth - occupiedW) / 2\r\n      else if (rowFlex === 'right') x = availableWidth - occupiedW\r\n    }\r\n    return {\r\n      kind: 'image',\r\n      id: nextBlockId(),\r\n      block: el,\r\n      parentPath,\r\n      indexInParent: index,\r\n      rect: { x, y: 0, width: occupiedW, height: occupiedH }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 将表格元素排版为 TableBlock：计算列宽、rowspan 占用矩阵、各行高、单元格内容排版、\r\n   * 跨行 cell 撑高与垂直对齐。\r\n   * @param table 表格元素\r\n   * @param parentPath 父容器路径\r\n   * @param index 在父容器中的索引\r\n   * @param availableWidth 可用宽度\r\n   * @returns 表格块\r\n   */\r\n  private layoutTable(\r\n    table: ITableElement,\r\n    parentPath: Path,\r\n    index: number,\r\n    availableWidth: number\r\n  ): TableBlock {\r\n    // ---------- 列宽计算 ----------\r\n    // 1) 优先使用 colgroup 定义\r\n    let colWidths = table.colgroup.map(c => c.width || 0)\r\n\r\n    // 2) colgroup 缺失或列数不足 → 用首行 tdList 补齐（每个 td 按 colspan 展开）\r\n    if (colWidths.length === 0 || colWidths.every(v => v <= 0)) {\r\n      const firstTr = table.trList[0]\r\n      if (firstTr) {\r\n        const inferred: number[] = []\r\n        for (const td of firstTr.tdList) {\r\n          const span = td.colspan || 1\r\n          const per = (td.width || 0) / span\r\n          for (let k = 0; k < span; k++) inferred.push(per)\r\n        }\r\n        colWidths = inferred\r\n      }\r\n    }\r\n\r\n    const totalDefined = colWidths.reduce((s, v) => s + v, 0)\r\n    // 3) 若 totalDefined 超过 availableWidth 太多，才等比缩放（避免小数误差反复缩放导致数据被改）\r\n    if (totalDefined > availableWidth * 1.02) {\r\n      const k = availableWidth / totalDefined\r\n      colWidths = colWidths.map(v => v * k)\r\n    } else if (totalDefined <= 0) {\r\n      // 兜底：均分\r\n      const n = Math.max(1, colWidths.length || (table.trList[0]?.tdList.length ?? 1))\r\n      colWidths = Array.from({ length: n }, () => availableWidth / n)\r\n    }\r\n    // 表格实际宽度 = 列宽之和（保留自然宽度，不撑满 availableWidth）\r\n    const tableWidth = colWidths.reduce((s, v) => s + v, 0)\r\n\r\n    // ---------- rowspan 网格占用矩阵 ----------\r\n    // occupied[ri][ci] = true 表示该格已被上方 rowspan 覆盖\r\n    const occupied: boolean[][] = table.trList.map(() => new Array(colWidths.length).fill(false))\r\n\r\n    // ---------- 逐行排版 ----------\r\n    const rows: TableRowLayout[] = []\r\n    // 先假设每行最小 = max(tr.height, tr.minHeight)，之后可能被合并单元格撑高\r\n    const rowHeights: number[] = table.trList.map(tr => Math.max(tr.height || 0, tr.minHeight || 0))\r\n    // 收集所有 cellLayouts，后面统一定位\r\n    const rowCells: TableCellLayout[][] = table.trList.map(() => [])\r\n    // 收集跨行单元格：{ startRow, endRow, cellLayout, requiredHeight }\r\n    interface RowspanPending {\r\n      startRow: number\r\n      endRow: number\r\n      layout: TableCellLayout\r\n      contentHeight: number\r\n      padTop: number\r\n      padBottom: number\r\n    }\r\n    const rowspanPending: RowspanPending[] = []\r\n\r\n    for (let ri = 0; ri < table.trList.length; ri++) {\r\n      const tr = table.trList[ri]\r\n      const legacyVerticalPeers = tr.tdList.filter(cell => {\r\n        const runs = cell.value.filter(run => run.type === 'text') as Array<IElement & {\r\n          size?: number\r\n          paragraphIndentLeft?: number\r\n        }>\r\n        const width = Number(cell.width ?? 0)\r\n        const size = runs.reduce((max, run) => Math.max(max, Number(run.size) || this.opts.defaultSize), 0) ||\r\n          this.opts.defaultSize\r\n        const indent = Number(runs.find(run => run.paragraphIndentLeft != null)?.paragraphIndentLeft ?? 0)\r\n        return width > 0 && width <= 60 && indent >= Math.max(width * 1.2, size * 3.5)\r\n      }).length\r\n      let colCursor = 0\r\n      for (let ci = 0; ci < tr.tdList.length; ci++) {\r\n        // 跳过已被上方 rowspan 覆盖的位置\r\n        while (colCursor < colWidths.length && occupied[ri][colCursor]) colCursor++\r\n        if (colCursor >= colWidths.length) break\r\n\r\n        const td = tr.tdList[ci]\r\n        const colspan = Math.max(1, td.colspan || 1)\r\n        const rowspan = Math.max(1, td.rowspan || 1)\r\n\r\n        // 标记被此 td 覆盖的格子\r\n        for (let rr = ri; rr < Math.min(ri + rowspan, table.trList.length); rr++) {\r\n          for (let cc = colCursor; cc < Math.min(colCursor + colspan, colWidths.length); cc++) {\r\n            if (rr !== ri || cc !== colCursor) occupied[rr][cc] = true\r\n          }\r\n        }\r\n\r\n        const cellWidth = colWidths.slice(colCursor, colCursor + colspan).reduce((s, v) => s + v, 0)\r\n        const cellX = sumUp(colWidths, colCursor)\r\n        const [pt, pr, pb, pl] = td.padding\r\n        const contentWidth = Math.max(10, cellWidth - pl - pr)\r\n        const textRuns = td.value.filter(run => run.type === 'text') as Array<IElement & {\r\n          size?: number\r\n          lineHeight?: number\r\n          paragraphIndentLeft?: number\r\n          value?: string\r\n        }>\r\n        const maxTextSize = textRuns.reduce((max, run) => Math.max(max, Number(run.size) || this.opts.defaultSize), 0) ||\r\n          this.opts.defaultSize\r\n        const firstIndent = Number(textRuns.find(run => run.paragraphIndentLeft != null)?.paragraphIndentLeft ?? 0)\r\n        const longestLineHeight = textRuns.reduce((max, run) => Math.max(max, Number(run.lineHeight) || 0), 0)\r\n        const textLength = textRuns.reduce((length, run) => length + (run.value?.replace(/[\\s\\u200B\\uFEFF]/g, '').length ?? 0), 0)\r\n        const direction = String(td.textDirection ?? '').toLowerCase()\r\n        const hasVerticalIndent = cellWidth <= 60 &&\r\n          firstIndent >= Math.max(cellWidth * 0.9, maxTextSize * 2)\r\n        const hasVerticalLineMetrics = legacyVerticalPeers >= 4 &&\r\n          cellWidth <= 30 &&\r\n          longestLineHeight >= maxTextSize &&\r\n          textLength >= 12\r\n        const isVerticalText = direction.startsWith('tb') || direction.startsWith('bt') || direction.endsWith('v') ||\n          (!td.textDirection && cellWidth <= 60 &&\r\n            (firstIndent >= Math.max(cellWidth * 1.2, maxTextSize * 3.5) ||\r\n              hasVerticalIndent ||\r\n              hasVerticalLineMetrics))\r\n        const verticalTextWidth = isVerticalText ? Math.min(contentWidth, maxTextSize) : contentWidth\r\n        const cellPath: Path = [...parentPath, index, 'trList', ri, 'tdList', ci]\r\n        const contentPath: Path = [...cellPath, 'value']\r\n        const content = this.layoutBlocks(\r\n          td.value,\r\n          contentPath,\r\n          verticalTextWidth,\r\n          undefined,\r\n          isVerticalText,\n          isVerticalText\n        )\r\n\r\n        // 内容 y 累加\r\n        let innerY = 0\r\n        for (const cb of content) {\r\n          cb.rect.y = innerY\r\n          innerY += cb.rect.height\r\n        }\r\n        const contentHeight = innerY\r\n\r\n        const layout: TableCellLayout = {\r\n          cell: td,\r\n          cellPath,\r\n          contentPath,\r\n          rect: { x: cellX, y: 0, width: cellWidth, height: 0 },\r\n          content,\r\n          contentPaddingTop: pt,\r\n          contentPaddingLeft: pl + (isVerticalText ? Math.max(0, contentWidth - verticalTextWidth) / 2 : 0),\r\n          verticalOffset: 0\r\n        }\r\n        rowCells[ri].push(layout)\r\n\r\n        if (rowspan === 1) {\r\n          // 单行 cell：直接撑高当前行\r\n          const required = contentHeight + pt + pb\r\n          if (required > rowHeights[ri]) rowHeights[ri] = required\r\n        } else {\r\n          // 跨行 cell：先记录，最后再检查是否需要撑高 endRow\r\n          rowspanPending.push({\r\n            startRow: ri,\r\n            endRow: Math.min(ri + rowspan - 1, table.trList.length - 1),\r\n            layout,\r\n            contentHeight,\r\n            padTop: pt,\r\n            padBottom: pb\r\n          })\r\n        }\r\n        colCursor += colspan\r\n      }\r\n    }\r\n\r\n    // ---------- 处理跨行 cell 的高度需求：若跨行区间累加高度 < 需求，则把差额加到最后一行 ----------\r\n    for (const rp of rowspanPending) {\r\n      let acc = 0\r\n      for (let r = rp.startRow; r <= rp.endRow; r++) acc += rowHeights[r]\r\n      const required = rp.contentHeight + rp.padTop + rp.padBottom\r\n      if (required > acc) {\r\n        rowHeights[rp.endRow] += (required - acc)\r\n      }\r\n    }\r\n\r\n    // ---------- 定位每行 y、每 cell 的最终 rect + 垂直对齐 ----------\r\n    let cursorY = 0\r\n    for (let ri = 0; ri < table.trList.length; ri++) {\r\n      const rowHeight = rowHeights[ri]\r\n      const cellLayouts = rowCells[ri]\r\n      for (const cl of cellLayouts) {\r\n        cl.rect.y = cursorY\r\n        // 高度：单行 = 当前行高；跨行 = 从起始行到结束行的高度累加\r\n        const rowspan = Math.max(1, cl.cell.rowspan || 1)\r\n        let cellH = rowHeight\r\n        if (rowspan > 1) {\r\n          cellH = 0\r\n          for (let r = ri; r < Math.min(ri + rowspan, table.trList.length); r++) cellH += rowHeights[r]\r\n        }\r\n        cl.rect.height = cellH\r\n        // 垂直对齐\r\n        const [pt, , pb] = cl.cell.padding\r\n        const contentHeight = cl.content.reduce((s, b) => s + b.rect.height, 0)\r\n        const inner = Math.max(0, cellH - pt - pb - contentHeight)\r\n        if (cl.cell.verticalAlign === 'middle') cl.verticalOffset = inner / 2\r\n        else if (cl.cell.verticalAlign === 'bottom') cl.verticalOffset = inner\r\n        else cl.verticalOffset = 0\r\n      }\r\n      rows.push({\r\n        rect: { x: 0, y: cursorY, width: tableWidth, height: rowHeight },\r\n        cells: cellLayouts\r\n      })\r\n      cursorY += rowHeight\r\n    }\r\n\r\n    return {\r\n      kind: 'table',\r\n      id: nextBlockId(),\r\n      block: table,\r\n      parentPath,\r\n      indexInParent: index,\r\n      rect: { x: 0, y: 0, width: tableWidth, height: cursorY },\r\n      rows,\r\n      colWidths\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 跨页表格拆分。被 `layout()` 分页循环调用。\r\n   *\r\n   * 逻辑：\r\n   *  - 任意行边界都可切割；跨行（rowspan）格被切割时由 buildFragment 裁剪，\r\n   *    上片保留上半（含内容），下片生成空内容的续接格，边框/背景保持连续。\r\n   *  - 第 1 片最多占用当前页剩余空间 (firstFit)；剩余行逐页推进，\r\n   *    每页用整页高度 (fullHeight) 计算能放几行。\r\n   *\r\n   * 返回的每个片段都是独立 TableBlock，带自己的 rows / colWidths，\r\n   * 其 rect 重建为\"从 0 开始的片段高度\"（y 由上层分页循环重新分配）。\r\n   * 不重复表头，因此不复制表头行。\r\n   *\r\n   * @returns 片段数组（至少 2 片）；null 表示不可拆分（首片连一行都放不下，\r\n   *          或整表本就能容纳）。调用方负责把片段落页。\r\n   */\r\n  private tryPaginateTableFlow(\r\n    b: TableBlock,\r\n    firstFit: number,\r\n    fullHeight: number\r\n  ): TableBlock[] | null {\r\n    const totalRows = b.rows.length\r\n    if (totalRows <= 1) return null\r\n\r\n    // 收集\"表头行\"（从第 0 行起连续被标记为 pagingRepeat 的行）：\r\n    // Word 语义只有从表首开始连续的行才可作为跨页重复表头\r\n    const repeatRows: number[] = []\r\n    for (let i = 0; i < b.rows.length; i++) {\r\n      const tr = (b.block as ITableElement).trList[i]\r\n      if (tr && tr.pagingRepeat) repeatRows.push(i)\r\n      else break\r\n    }\r\n    // 表头行占用的高度（不能小于表头本身，避免第 1 片就装不下）\r\n    const repeatHeight = repeatRows.reduce((s, ri) => s + b.rows[ri].rect.height, 0)\r\n\r\n    // 第 1 片：用当前页剩余空间\r\n    const firstEnd = this.findSliceEnd(b, 0, firstFit)\r\n    if (firstEnd < 0) return null\r\n    // 若第 1 片就已覆盖整张表（能整表容纳），说明本不该走进拆分分支，直接回退。\r\n    if (firstEnd >= totalRows - 1) return null\r\n\r\n    // 先组装全部片段，任一步失败则整体返回 null（事务性，避免半放置）\r\n    const frags: TableBlock[] = [this.buildFragment(b, 0, firstEnd)]\r\n    let startRow = firstEnd + 1\r\n    while (startRow < totalRows) {\r\n      // 后续片段预留表头高度\r\n      const budget = repeatRows.length > 0 ? Math.max(0, fullHeight - repeatHeight) : fullHeight\r\n      const endRow = this.findSliceEnd(b, startRow, budget)\r\n      if (endRow < 0) return null\r\n      frags.push(this.buildFragment(b, startRow, endRow, repeatRows))\r\n      startRow = endRow + 1\r\n    }\r\n    return frags\r\n  }\r\n\r\n  /** 在 [startRow, totalRows) 内，累计行高不超过 fit，找到最大可容纳的行下标；找不到返回 -1。 */\r\n  private findSliceEnd(b: TableBlock, startRow: number, fit: number): number {\r\n    let endRow = -1\r\n    let subAcc = 0\r\n    for (let ri = startRow; ri < b.rows.length; ri++) {\r\n      subAcc += b.rows[ri].rect.height\r\n      if (subAcc > fit) break\r\n      endRow = ri\r\n    }\r\n    return endRow\r\n  }\r\n\r\n  /** 从 TableBlock b 中切出行区间 [s, e]（含两端），重建一个独立 TableBlock 片段。\r\n   *  跨切割点的 rowspan 格做裁剪处理：\r\n   *  - 本片内起始、但延伸出本片的格：高度裁剪到本片底部，并重算垂直偏移；\r\n   *  - 起始于本片之前、延伸进本片的格：在首行补一个空内容的续接格，\r\n   *    使边框 / 背景在续页保持连续（内容只在上半显示一次）。\r\n    *  注意：不修改原表 b 的任何行 / 格对象（后续片段还要复用）。\r\n    *  @param b 表格块\r\n    *  @param s 起始行下标\r\n    *  @param e 结束行下标\r\n    *  @param repeatRowsBefore 需要在片段最前面复制一份的\"表头行\"下标列表（w:tblHeader），仅在非第一片时使用。 */\r\n  private buildFragment(b: TableBlock, s: number, e: number, repeatRowsBefore?: number[]): TableBlock {\r\n    // 先深拷贝主体行\r\n    const bodyRows = b.rows.slice(s, e + 1).map(r => ({\r\n      ...r,\r\n      rect: { ...r.rect },\r\n      cells: r.cells.map(c => ({ ...c, rect: { ...c.rect } }))\r\n    }))\r\n    // 表头重复行（跨页时）：仅当 s>0（非首片）且 repeatRowsBefore 中的行不在当前区间内时才复制\r\n    const headerRows = (s > 0 && repeatRowsBefore && repeatRowsBefore.length > 0)\r\n      ? repeatRowsBefore\r\n          .filter(ri => ri < s) // 首片已经含表头则不重复\r\n          .map(ri => ({\r\n            ...b.rows[ri],\r\n            rect: { ...b.rows[ri].rect },\r\n            cells: b.rows[ri].cells.map(c => ({ ...c, rect: { ...c.rect } }))\r\n          }))\r\n      : []\r\n    const rows = [...headerRows, ...bodyRows]\r\n    // 重建行 rect.y 为片段本地坐标（从 0 重新累加）\r\n    let y = 0\r\n    for (const r of rows) {\r\n      r.rect.y = y\r\n      r.rect.x = b.rect.x\r\n      y += r.rect.height\r\n    }\r\n    const spanHeight = (from: number, to: number): number => {\r\n      let h = 0\r\n      for (let rr = from; rr <= to; rr++) h += b.rows[rr].rect.height\r\n      return h\r\n    }\r\n    const headerOffset = headerRows.length\r\n    // 本片内起始的格：定位到行 y；延伸出本片的裁剪高度\r\n    for (let ri = s; ri <= e; ri++) {\r\n      const r = rows[headerOffset + (ri - s)]\r\n      for (const c of r.cells) {\r\n        c.rect.y = r.rect.y\r\n        const rs = Math.max(1, c.cell.rowspan || 1)\r\n        const end = ri + rs - 1\r\n        if (end > e) {\r\n          c.rect.height = spanHeight(ri, e)\r\n          c.verticalOffset = this.fitVerticalOffset(c, c.rect.height)\r\n        }\r\n      }\r\n    }\r\n    // 重复表头行：定位其内 cell 的 rect.y 到片段本地\r\n    for (let hi = 0; hi < headerOffset; hi++) {\r\n      const r = rows[hi]\r\n      for (const c of r.cells) {\r\n        c.rect.y = r.rect.y\r\n        // 表头行不参与 rowspan 裁剪（表头通常独立），保持原 height\r\n      }\r\n    }\r\n    // 起始于本片之前的 rowspan 格：body 首行补续接格（空内容）\r\n    if (s > 0) {\r\n      const cont: TableCellLayout[] = []\r\n      for (let ri = 0; ri < s; ri++) {\r\n        for (const c of b.rows[ri].cells) {\r\n          const rs = Math.max(1, c.cell.rowspan || 1)\r\n          const end = ri + rs - 1\r\n          if (rs > 1 && end >= s) {\r\n            cont.push({\r\n              ...c,\r\n              rect: { x: c.rect.x, y: 0, width: c.rect.width, height: spanHeight(s, Math.min(e, end)) },\r\n              content: [],\r\n              verticalOffset: 0\r\n            })\r\n          }\r\n        }\r\n      }\r\n      if (cont.length > 0) {\r\n        const bodyFirst = rows[headerOffset]\r\n        bodyFirst.cells = [...cont, ...bodyFirst.cells].sort((a, a2) => a.rect.x - a2.rect.x)\r\n      }\r\n    }\r\n    // 分页处\"封口\"：数据中共享边常只由邻格单侧定义，切开后邻格落在另一页，\r\n    // 因此片段首行缺 top / 末行缺 bottom 时补齐，保证合并格续接处边框连续。\r\n    if (s > 0) {\r\n      // 若有重复表头，封口对象是表头首行；否则是 body 首行\r\n      for (const c of rows[0].cells) this.ensureFragmentEdge(c, 'top')\r\n    }\r\n    if (e < b.rows.length - 1) {\r\n      for (const c of rows[rows.length - 1].cells) this.ensureFragmentEdge(c, 'bottom')\r\n    }\r\n    return {\r\n      kind: 'table',\r\n      id: nextBlockId(),\r\n      block: b.block,\r\n      parentPath: b.parentPath,\r\n      indexInParent: b.indexInParent,\r\n      rect: { x: b.rect.x, y: 0, width: b.rect.width, height: y },\r\n      rows,\r\n      colWidths: b.colWidths\r\n    }\r\n  }\r\n\r\n  /** 片段边界封口：该侧无边框时从本格其他边复制样式补齐（仅改片段副本，不动原数据）。 */\r\n  private ensureFragmentEdge(c: TableCellLayout, side: 'top' | 'bottom'): void {\r\n    // 分页片段不能补造源文档未提供或显式关闭的边框。\r\n    void c\r\n    void side\r\n  }\r\n\r\n  /** 按裁剪后的格高重算垂直偏移（规则同 layoutTable）。 */\r\n  private fitVerticalOffset(c: TableCellLayout, cellH: number): number {\r\n    const [pt, , pb] = c.cell.padding\r\n    const contentHeight = c.content.reduce((acc, blk) => acc + blk.rect.height, 0)\r\n    const inner = Math.max(0, cellH - pt - pb - contentHeight)\r\n    if (c.cell.verticalAlign === 'middle') return inner / 2\r\n    if (c.cell.verticalAlign === 'bottom') return inner\r\n    return 0\r\n  }\r\n\r\n}\r\n\r\n/* -------------------- 工具 -------------------- */\r\n\r\n/**\r\n * 数组前 upto 项求和。\r\n * @param arr 数值数组\r\n * @param upto 求和上界（不含）\r\n * @returns 前 upto 项之和\r\n */\r\nfunction sumUp(arr: number[], upto: number): number {\r\n  let s = 0\r\n  for (let i = 0; i < upto; i++) s += arr[i]\r\n  return s\r\n}\r\n\r\n/**\r\n * 对单行 inline 列表应用水平对齐：left/center/right 直接平移；\r\n * justify/alignment 将剩余空白均分到字符间隙（仅非末行）。\r\n * @param line 行盒\r\n * @param containerWidth 容器可用宽度\r\n */\r\nfunction applyRowFlex(line: LineBox, containerWidth: number): void {\r\n  const used = line.inlines.reduce((s, inl) => s + inl.width, 0)\r\n  const free = containerWidth - used\r\n  if (free <= 0) return\r\n  if (line.rowFlex === 'left') return\r\n  if (line.rowFlex === 'center') {\r\n    const dx = free / 2\r\n    for (const inl of line.inlines) inl.x += dx\r\n    return\r\n  }\r\n  if (line.rowFlex === 'right') {\r\n    for (const inl of line.inlines) inl.x += free\r\n    return\r\n  }\r\n  const isJustify = line.rowFlex === 'justify' || line.rowFlex === 'alignment'\r\n  const isDistribute = line.rowFlex === 'distribute'\r\n  if ((isJustify || isDistribute) && line.inlines.length > 0) {\r\n    if (isJustify && line.isLastLine) return\r\n    // 按\"字符间隙\"分配额外空白（接近 Word 的两端对齐视觉效果）：\r\n    // 全行字符数 N，可拉伸缝隙数 = N - 1，均分 free 到每个字符后。\r\n    // 每个 inline 的宽度按 letterSpacing * charCount 扩展，后续 inline\r\n    // 依次右移；inline 之间不再额外插入间隙，避免出现大块空白。\r\n    // distribute 与 justify 唯一区别：末行也分散对齐。\r\n    let totalChars = 0\r\n    for (const inl of line.inlines) totalChars += inl.text.length\r\n    const gaps = totalChars - 1\r\n    if (gaps <= 0) return\r\n    const extra = free / gaps\r\n    let dx = 0\r\n    let lastTextIndex = line.inlines.length - 1\r\n    while (lastTextIndex >= 0 && !line.inlines[lastTextIndex].text.length) lastTextIndex--\r\n    for (let i = 0; i < line.inlines.length; i++) {\r\n      const inl = line.inlines[i]\r\n      inl.x += dx\r\n      const n = inl.text.length\r\n      if (n > 0) {\r\n        inl.letterSpacing = extra\r\n        // 若该 inline 是行尾，其最后一个字符后不再有缝隙需要承担\r\n        const isLast = i === lastTextIndex\r\n        const add = isLast ? extra * (n - 1) : extra * n\r\n        inl.width += add\r\n        dx += add\r\n      }\r\n    }\r\n  }\r\n}\r\n","/**\r\n * VerveDocs View —— HitTest\r\n *\r\n * 屏幕坐标 -> IPosition。\r\n * 新坐标系：block/table/cell 均使用相对父容器坐标；命中时递归传入原点。\r\n */\r\n\r\nimport type { IPosition, Path } from '@vervedoc/docx-editor-schema'\r\nimport type { BlockNode, DocumentLayout, LineBox, ParagraphBlock, TableBlock } from './layout-types'\r\nimport type { Zone } from './widgets/header-footer-widget'\r\nimport { getSharedMeasure } from './text-measure'\r\n\r\n/**\r\n * 命中测试主入口：根据文档坐标（未减 scrollY）返回对应位置。\r\n * @param layout 文档布局\r\n * @param docX 文档 X 坐标\r\n * @param docY 文档 Y 坐标\r\n * @param zone 当前编辑区域，默认 'main'；'header'/'footer' 时仅命中对应区域块\r\n * @returns 命中位置；未命中返回 null\r\n */\r\nexport function hitTest(layout: DocumentLayout, docX: number, docY: number, zone: Zone = 'main'): IPosition | null {\r\n  for (const page of layout.pages) {\r\n    if (docY < page.rect.y || docY > page.rect.y + page.rect.height) continue\r\n    let blocks: BlockNode[]\r\n    let originX: number\r\n    let originY: number\r\n    if (zone === 'header' && page.headerBlocks && page.headerRect) {\r\n      if (docY < page.headerRect.y || docY > page.headerRect.y + page.headerRect.height) return null\r\n      blocks = page.headerBlocks\r\n      originX = page.headerRect.x\r\n      originY = page.headerRect.y\r\n    } else if (zone === 'footer' && page.footerBlocks && page.footerRect) {\r\n      if (docY < page.footerRect.y || docY > page.footerRect.y + page.footerRect.height) return null\r\n      blocks = page.footerBlocks\r\n      originX = page.footerRect.x\r\n      originY = page.footerRect.y\r\n    } else {\r\n      blocks = page.blocks\r\n      originX = page.contentRect.x\r\n      originY = page.contentRect.y\r\n    }\r\n    const p = hitBlocks(blocks, docX, docY, originX, originY)\r\n    if (p) return p\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 在指定原点偏移下遍历块列表进行命中测试。\r\n * @param blocks 块节点列表\r\n * @param x 文档 X 坐标\r\n * @param y 文档 Y 坐标\r\n * @param ox 父容器原点 X\r\n * @param oy 父容器原点 Y\r\n * @returns 命中位置；未命中返回 null\r\n */\r\nfunction hitBlocks(blocks: BlockNode[], x: number, y: number, ox: number, oy: number): IPosition | null {\r\n  // 分栏中多个段落可占用相同纵坐标，优先命中鼠标所在的栏，而非文档顺序中的左栏。\n  const distanceX = (block: BlockNode) => Math.max(ox + block.rect.x - x, x - ox - block.rect.x - block.rect.width, 0)\n  const candidates = blocks.filter(block => y >= oy + block.rect.y && y <= oy + block.rect.y + block.rect.height)\n    .sort((left, right) => distanceX(left) - distanceX(right))\n  for (const b of candidates) {\n    const bx = ox + b.rect.x\r\n    const by = oy + b.rect.y\r\n    if (y < by || y > by + b.rect.height) continue\r\n    if (b.kind === 'paragraph') {\r\n      if (b.surroundImage) {\r\n        const si = b.surroundImage\r\n        const six = bx + si.rect.x\r\n        if (x >= six && x <= six + si.rect.width && y >= by && y <= by + si.rect.height) {\r\n          const p: Path = [...si.parentPath, si.indexInParent]\r\n          return { path: p, offset: 0 }\r\n        }\r\n      }\r\n      const r = hitParagraph(b, x - bx, y - by, b)\r\n      if (r) return r\r\n    } else if (b.kind === 'table') {\r\n      const r = hitTable(b, x, y, bx, by)\r\n      if (r) return r\r\n    } else if (b.kind === 'image') {\r\n      const p: Path = [...b.parentPath, b.indexInParent]\r\n      return { path: p, offset: 0 }\r\n    } else if (b.kind === 'block') {\r\n      const p: Path = [...b.parentPath, b.indexInParent]\r\n      return { path: p, offset: 0 }\r\n    } else if (b.kind === 'chart') {\r\n      const p: Path = [...b.parentPath, b.indexInParent]\r\n      return { path: p, offset: 0 }\r\n    }\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 在段落内进行命中测试，返回所在行的命中位置。\r\n * @param b 段落块\r\n * @param lx 相对块本地 X 坐标\r\n * @param ly 相对块本地 Y 坐标\r\n * @param _pb 段落块（保留参数，当前未使用）\r\n * @returns 命中位置；未命中返回 null\r\n */\r\nfunction hitParagraph(b: ParagraphBlock, lx: number, ly: number, _pb: ParagraphBlock): IPosition | null {\r\n  for (const line of b.lines) {\r\n    if (ly < line.y || ly > line.y + line.height) continue\r\n    return hitLine(line, lx, ly - line.y, b.verticalText)\n  }\r\n  const last = b.lines[b.lines.length - 1]\r\n  if (last) return hitLine(last, lx, ly - last.y, b.verticalText)\n  return null\r\n}\r\n\r\n/**\r\n * 在单行内进行命中测试，按字符宽度逐字定位光标偏移。\r\n * @param line 行盒\r\n * @param lx 相对块本地 X 坐标\r\n * @returns 命中位置；空行返回 null\r\n */\r\nfunction hitLine(line: LineBox, lx: number, ly: number, verticalText = false): IPosition | null {\n  if (line.inlines.length === 0) return null\r\n  if (verticalText) {\n    const inl = line.inlines[0]\n    const after = ly >= line.height / 2\n    if (inl.controlId) return { path: inl.path, offset: after ? 1 : 0 }\n    return { path: inl.path, offset: after ? inl.endOffset : inl.startOffset }\n  }\n  const measure = getSharedMeasure()\r\n  for (const inl of line.inlines) {\r\n    if (lx >= inl.x && lx <= inl.x + inl.width) {\r\n      if (inl.controlId) {\r\n        return { path: inl.path, offset: lx < inl.x + inl.width / 2 ? 0 : 1 }\r\n      }\r\n      if (inl.text === '\\t' && (inl.run.extension?.toc as { role?: string } | undefined)?.role === 'entry') {\r\n        return { path: inl.path, offset: lx < inl.x + inl.width / 2 ? inl.startOffset : inl.endOffset }\r\n      }\r\n      let cursor = inl.x\r\n      const ls = inl.letterSpacing ?? 0\r\n      for (let i = 0; i < inl.text.length; i++) {\r\n        const ch = inl.text[i]\r\n        const cw = (inl.glyphAdvance ?? measure.charWidth(ch, inl.font, inl.size, inl.bold, inl.italic)) + ls\n        if (lx < cursor + cw / 2) return { path: inl.path, offset: inl.startOffset + i }\r\n        cursor += cw\r\n      }\r\n      return { path: inl.path, offset: inl.endOffset }\r\n    }\r\n  }\r\n  const first = line.inlines[0]\r\n  const last = line.inlines[line.inlines.length - 1]\r\n  if (lx < first.x) return { path: first.path, offset: first.startOffset }\r\n  return { path: last.path, offset: last.endOffset }\r\n}\r\n\r\n/**\r\n * 在表格内进行命中测试，递归进入命中的单元格内容。\r\n * @param b 表格块\r\n * @param x 文档 X 坐标\r\n * @param y 文档 Y 坐标\r\n * @param tbx 表格原点 X\r\n * @param tby 表格原点 Y\r\n * @returns 命中位置；未命中返回 null\r\n */\r\nfunction hitTable(b: TableBlock, x: number, y: number, tbx: number, tby: number): IPosition | null {\r\n  for (const row of b.rows) {\r\n    for (const cell of row.cells) {\r\n      const cx = tbx + cell.rect.x\r\n      const cy = tby + cell.rect.y\n      // 合并格只登记在起始行，命中范围应覆盖它自己的完整 rowspan 矩形。\n      if (x < cx || x > cx + cell.rect.width ||\n        y < cy || y > cy + cell.rect.height) continue\n      const contentOX = cx + cell.contentPaddingLeft\r\n      const contentOY = cy + cell.contentPaddingTop + cell.verticalOffset\n      const r = hitBlocks(cell.content, x, y, contentOX, contentOY)\r\n      if (r) return r\r\n      return { path: cell.contentPath.concat(0), offset: 0 }\r\n    }\r\n  }\r\n  return null\r\n}\r\n\r\n","/**\r\n * VerveDocs View —— CaretRect\r\n *\r\n * 由 IPosition -> 屏幕坐标的光标矩形（文档坐标系，未减 scrollY）。\r\n * 用于绘制光标闪烁与选区。\r\n */\r\n\r\nimport type { IPosition, Path } from '@vervedoc/docx-editor-schema'\r\nimport { isSamePath, comparePosition } from '@vervedoc/docx-editor-schema'\r\nimport type {\r\n  BlockNode, DocumentLayout, ParagraphBlock, TableBlock, InlineBox\r\n} from './layout-types'\r\nimport type { Zone } from './widgets/header-footer-widget'\r\nimport { getSharedMeasure } from './text-measure'\r\n\r\n/**\r\n * 光标矩形（文档坐标系，未减 scrollY），用于绘制光标闪烁。\r\n */\r\nexport interface CaretRect {\r\n  /** 文档坐标（未减 scrollY） */\r\n  x: number\r\n  y: number\r\n  /** 光标高度取行高与文字高度的较大值 */\r\n  height: number\r\n  /** 竖排文字使用横向光标线；宽度为当前字格宽度。 */\n  orientation?: 'horizontal' | 'vertical'\n  width?: number\n}\r\n\r\n/**\r\n * 选区矩形（文档坐标系，未减 scrollY），用于绘制选区高亮。\r\n */\r\nexport interface SelectionRect {\r\n  /** 文档坐标 X（未减 scrollY） */\r\n  x: number\r\n  /** 文档坐标 Y（未减 scrollY） */\r\n  y: number\r\n  /** 矩形宽度 */\r\n  width: number\r\n  /** 矩形高度 = line.height */\r\n  height: number\r\n}\r\n\r\n/**\r\n * 定位光标矩形：根据位置返回光标在文档坐标系中的矩形。\r\n * @param layout 文档布局\r\n * @param pos 光标位置\r\n * @param zone 当前编辑区域，默认 'main'；'header'/'footer' 时在对应区域块中定位\r\n * @param pageIndex 页眉/页脚的活动页索引，避免相同路径命中其他页面\r\n * @returns 光标矩形；未找到返回 null\r\n */\r\nexport function locateCaret(layout: DocumentLayout, pos: IPosition, zone: Zone = 'main', pageIndex?: number | null): CaretRect | null {\r\n  for (const page of layout.pages) {\r\n    if (zone !== 'main' && pageIndex != null && page.index !== pageIndex) continue\r\n    let blocks: BlockNode[]\r\n    let originX: number\r\n    let originY: number\r\n    if (zone === 'header') {\r\n      if (!page.headerBlocks || !page.headerRect) continue\r\n      blocks = page.headerBlocks\r\n      originX = page.headerRect.x\r\n      originY = page.headerRect.y\r\n    } else if (zone === 'footer') {\r\n      if (!page.footerBlocks || !page.footerRect) continue\r\n      blocks = page.footerBlocks\r\n      originX = page.footerRect.x\r\n      originY = page.footerRect.y\r\n    } else {\r\n      blocks = page.blocks\r\n      originX = page.contentRect.x\r\n      originY = page.contentRect.y\r\n    }\r\n    const r = locateInBlocks(blocks, pos, originX, originY)\r\n    if (r) return r\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 在指定原点偏移下遍历块列表定位光标矩形。\r\n * @param blocks 块节点列表\r\n * @param pos 光标位置\r\n * @param ox 父容器原点 X\r\n * @param oy 父容器原点 Y\r\n * @returns 光标矩形；未找到返回 null\r\n */\r\nfunction locateInBlocks(blocks: BlockNode[], pos: IPosition, ox: number, oy: number): CaretRect | null {\r\n  for (const b of blocks) {\r\n    const bx = ox + b.rect.x\r\n    const by = oy + b.rect.y\r\n    if (b.kind === 'paragraph') {\r\n      const r = locateInParagraph(b, pos, bx, by)\r\n      if (r) return r\r\n    } else if (b.kind === 'table') {\r\n      const r = locateInTable(b, pos, bx, by)\r\n      if (r) return r\r\n    }\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 在段落内定位光标矩形，按行和 inline 匹配位置。\r\n * @param b 段落块\r\n * @param pos 光标位置\r\n * @param bx 段落原点 X\r\n * @param by 段落原点 Y\r\n * @returns 光标矩形；未找到返回 null\r\n */\r\nfunction locateInParagraph(b: ParagraphBlock, pos: IPosition, bx: number, by: number): CaretRect | null {\r\n  for (const line of b.lines) {\r\n    for (const inl of line.inlines) {\r\n      if (!isSamePath(inl.path, pos.path)) continue\r\n      if (inl.controlId && !(pos.offset === 0 ? inl.controlStart : inl.controlEnd)) continue\r\n      if (pos.offset < inl.startOffset || pos.offset > inl.endOffset) continue\r\n      if (b.verticalText) {\n        const charCount = Math.max(1, inl.endOffset - inl.startOffset)\n        const charHeight = line.height / charCount\n        return {\n          x: bx + inl.x,\n          y: by + line.y + charHeight * (pos.offset - inl.startOffset),\n          height: line.height,\n          orientation: 'horizontal',\n          width: Math.max(1, inl.width)\n        }\n      }\n      const localX = charOffsetToX(inl, pos.offset - inl.startOffset)\r\n      // 极小行距的空段落仍需可见光标；向行顶上方扩展，避免页脚光标超出纸张。\r\n      const height = Math.max(line.height, inl.height)\r\n      return {\r\n        x: bx + localX,\r\n        y: by + line.y + line.height - height,\r\n        height\r\n      }\r\n    }\r\n  }\r\n  return null\r\n}\r\n\r\n\r\n/**\r\n * 在表格内定位光标矩形，递归进入匹配的单元格内容。\r\n * @param b 表格块\r\n * @param pos 光标位置\r\n * @param tbx 表格原点 X\r\n * @param tby 表格原点 Y\r\n * @returns 光标矩形；未找到返回 null\r\n */\r\nfunction locateInTable(b: TableBlock, pos: IPosition, tbx: number, tby: number): CaretRect | null {\r\n  for (const row of b.rows) {\r\n    for (const cell of row.cells) {\r\n      // 光标 path 必须以 cell.contentPath 为前缀\r\n      if (!pathStartsWith(pos.path, cell.contentPath)) continue\r\n      const cx = tbx + cell.rect.x\r\n      const cy = tby + row.rect.y\r\n      const contentOX = cx + cell.contentPaddingLeft\r\n      const contentOY = cy + cell.contentPaddingTop + cell.verticalOffset\r\n      const r = locateInBlocks(cell.content, pos, contentOX, contentOY)\r\n      if (r) return r\r\n    }\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 判断路径 path 是否以 prefix 为前缀。\r\n * @param path 待判断路径\r\n * @param prefix 前缀路径\r\n * @returns 是前缀返回 true，否则返回 false\r\n */\r\nfunction pathStartsWith(path: Path, prefix: Path): boolean {\r\n  if (path.length < prefix.length) return false\r\n  for (let i = 0; i < prefix.length; i++) {\r\n    if (path[i] !== prefix[i]) return false\r\n  }\r\n  return true\r\n}\r\n\r\n/**\r\n * 在 inline 内部按 offset 求 x（相对块本地）。\r\n * 使用真实 measureText 度量（与 layout 阶段一致），避免估算错位。\r\n */\r\nfunction charOffsetToX(inl: InlineBox, offsetInInline: number): number {\r\n  if (inl.controlId) return inl.x + (offsetInInline > 0 ? inl.width : 0)\r\n  if (offsetInInline <= 0) return inl.x\r\n  if (offsetInInline >= inl.text.length) return inl.x + inl.width\r\n  const measure = getSharedMeasure()\r\n  let x = inl.x\r\n  const ls = inl.letterSpacing ?? 0\r\n  for (let i = 0; i < offsetInInline; i++) {\r\n    x += (inl.glyphAdvance ?? measure.charWidth(inl.text[i], inl.font, inl.size, inl.bold, inl.italic)) + ls\n  }\r\n  return x\r\n}\r\n\r\n/* -------------------- 选区矩形 -------------------- */\r\n\r\n/**\r\n * 计算从 start 到 end（文档顺序）的选区矩形列表（文档坐标，未减 scrollY）。\r\n * 遍历所有 inline，收集与 [start, end] 相交的部分，同行 inline 合并为一个矩形。\r\n * @param layout 文档布局\r\n * @param start 选区起点\r\n * @param end 选区终点\r\n * @param zone 当前编辑区域，默认 'main'；'header'/'footer' 时在对应区域块中收集\r\n * @param pageIndex 页眉/页脚的活动页索引，选区仅绘制在当前编辑页\r\n * @returns 选区矩形列表\r\n */\r\nexport function computeSelectionRects(layout: DocumentLayout, start: IPosition, end: IPosition, zone: Zone = 'main', pageIndex?: number | null): SelectionRect[] {\r\n  const rects: SelectionRect[] = []\r\n  for (const page of layout.pages) {\r\n    if (zone !== 'main' && pageIndex != null && page.index !== pageIndex) continue\r\n    let blocks: BlockNode[]\r\n    let originX: number\r\n    let originY: number\r\n    if (zone === 'header') {\r\n      if (!page.headerBlocks || !page.headerRect) continue\r\n      blocks = page.headerBlocks\r\n      originX = page.headerRect.x\r\n      originY = page.headerRect.y\r\n    } else if (zone === 'footer') {\r\n      if (!page.footerBlocks || !page.footerRect) continue\r\n      blocks = page.footerBlocks\r\n      originX = page.footerRect.x\r\n      originY = page.footerRect.y\r\n    } else {\r\n      blocks = page.blocks\r\n      originX = page.contentRect.x\r\n      originY = page.contentRect.y\r\n    }\r\n    collectSelectionInBlocks(blocks, originX, originY, start, end, rects)\r\n  }\r\n  return rects\r\n}\r\n\r\n/**\r\n * 在指定原点偏移下遍历块列表收集选区矩形。\r\n * @param blocks 块节点列表\r\n * @param ox 父容器原点 X\r\n * @param oy 父容器原点 Y\r\n * @param start 选区起点\r\n * @param end 选区终点\r\n * @param rects 收集结果数组\r\n */\r\nfunction collectSelectionInBlocks(\r\n  blocks: BlockNode[], ox: number, oy: number,\r\n  start: IPosition, end: IPosition, rects: SelectionRect[]\r\n): void {\r\n  for (const b of blocks) {\r\n    const bx = ox + b.rect.x\r\n    const by = oy + b.rect.y\r\n    if (b.kind === 'paragraph') {\r\n      collectSelectionInParagraph(b, bx, by, start, end, rects)\r\n    } else if (b.kind === 'table') {\r\n      for (const row of b.rows) {\r\n        for (const cell of row.cells) {\r\n          const cx = bx + cell.rect.x + cell.contentPaddingLeft\r\n          const cy = by + cell.rect.y + cell.contentPaddingTop + cell.verticalOffset\r\n          collectSelectionInBlocks(cell.content, cx, cy, start, end, rects)\r\n        }\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\n/**\r\n * 在段落内收集选区矩形，同行 inline 合并为一个矩形。\r\n * @param b 段落块\r\n * @param bx 段落原点 X\r\n * @param by 段落原点 Y\r\n * @param start 选区起点\r\n * @param end 选区终点\r\n * @param rects 收集结果数组\r\n */\r\nfunction collectSelectionInParagraph(\r\n  b: ParagraphBlock, bx: number, by: number,\r\n  start: IPosition, end: IPosition, rects: SelectionRect[]\r\n): void {\r\n  for (const line of b.lines) {\r\n    // 同行选中片段合并：记录当前合并段的 [leftX, rightX]\r\n    let segLeft: number | null = null\r\n    let segRight = 0\r\n    const flush = () => {\r\n      if (segLeft != null) {\r\n        rects.push({ x: segLeft, y: by + line.y, width: segRight - segLeft, height: line.height })\r\n        segLeft = null\r\n      }\r\n    }\r\n    for (const inl of line.inlines) {\r\n      const inlStart: IPosition = { path: inl.path, offset: inl.startOffset }\r\n      const inlEnd: IPosition = { path: inl.path, offset: inl.endOffset }\r\n      // 不相交\r\n      if (comparePosition(inlEnd, start) <= 0) continue\r\n      if (comparePosition(inlStart, end) >= 0) { flush(); continue }\r\n      // 裁剪起点\r\n      let clipStartOff: number\r\n      if (comparePosition(inlStart, start) >= 0) {\r\n        clipStartOff = inl.startOffset\r\n      } else {\r\n        clipStartOff = isSamePath(inl.path, start.path) ? start.offset : inl.startOffset\r\n      }\r\n      // 裁剪终点\r\n      let clipEndOff: number\r\n      if (comparePosition(inlEnd, end) <= 0) {\r\n        clipEndOff = inl.endOffset\r\n      } else {\r\n        clipEndOff = isSamePath(inl.path, end.path) ? end.offset : inl.endOffset\r\n      }\r\n      const x1 = bx + charOffsetToX(inl, clipStartOff - inl.startOffset)\r\n      const x2 = bx + charOffsetToX(inl, clipEndOff - inl.startOffset)\r\n      if (segLeft == null) {\r\n        segLeft = x1\r\n        segRight = x2\r\n      } else {\r\n        // 同行连续 inline 合并（若有间隙也合并，视觉为整块高亮）\r\n        if (x1 <= segRight) segRight = Math.max(segRight, x2)\r\n        else { flush(); segLeft = x1; segRight = x2 }\r\n      }\r\n    }\r\n    flush()\r\n  }\r\n}\r\n","export type ViewTranslate = (key: string, params?: Record<string, string | number>) => string\r\n\r\n// Defaults are local to the view layer; option values and command values are never translated.\r\nexport const viewText: Record<string, string> = {\r\n  'view.control.search': '搜索选项',\r\n  'view.control.noResults': '无匹配结果',\r\n  'view.control.clear': '清空',\r\n  'view.common.cancel': '取消',\r\n  'view.common.confirm': '确定',\r\n  'view.common.none': '无',\r\n  'view.common.leftAlign': '左对齐',\r\n  'view.common.rightAlign': '右对齐',\r\n  'view.common.center': '居中',\r\n  'view.common.justify': '两端对齐',\r\n  'view.common.distribute': '分散对齐',\r\n  'view.common.preview': '预览',\r\n  'view.common.color': '颜色',\r\n  'view.common.spacing': '间距',\r\n  'view.common.points': '磅',\r\n  'view.paragraph.format': '段落格式',\r\n  'view.paragraph.body': '正文',\r\n  'view.paragraph.heading1': '一级标题',\r\n  'view.paragraph.heading2': '二级标题',\r\n  'view.paragraph.heading3': '三级标题',\r\n  'view.paragraph.heading4': '四级标题',\r\n  'view.paragraph.heading5': '五级标题',\r\n  'view.paragraph.heading6': '六级标题',\r\n  'view.paragraph.cut': '剪切',\r\n  'view.paragraph.copy': '复制',\r\n  'view.paragraph.paste': '粘贴',\r\n  'view.paragraph.fontSettings': '字体...',\r\n  'view.paragraph.advancedSettings': '段落高级设置',\r\n  'view.paragraph.link': '超链接',\r\n  'view.hyperlink.text': '显示文字',\r\n  'view.hyperlink.address': '链接地址',\r\n  'view.hyperlink.addressPlaceholder': '请输入完整地址（如 https://example.com）',\r\n  'view.hyperlink.textRequired': '请输入显示文字',\r\n  'view.hyperlink.addressRequired': '请输入链接地址',\r\n  'view.hyperlink.addressInvalid': '链接地址必须使用 http、https、mailto、tel 或 ftp 协议',\r\n  'view.hyperlink.unsupported': '超链接未插入，未能获取具体原因。请重新选择文字后重试，文档未修改。',\r\n  'view.hyperlink.bookmarkSelection': '选区包含书签标记，当前编辑器暂不支持跨书签插入超链接。请调整选区避开书签边界；原文和书签均未修改。',\r\n  'view.hyperlink.fieldSelection': '选区包含 Word 域标记（如目录或页码），暂不支持插入超链接。请选择域以外的普通文字，文档未修改。',\r\n  'view.hyperlink.existingLink': '选区包含已有超链接，当前暂不支持嵌套或替换链接。请选择尚未添加链接的文字，文档未修改。',\r\n  'view.hyperlink.crossContainer': '选区跨越不同文本容器（如段落或单元格）。请在同一段落内选择文字后重试，文档未修改。',\r\n  'view.hyperlink.crossParagraph': '选区包含换行或段落结束标记。请选择同一段落内不含换行的文字，文档未修改。',\r\n  'view.hyperlink.revisions': '选区包含尚未处理的修订。请先审阅并接受或拒绝相关修订，或选择不含修订的文字，文档未修改。',\r\n  'view.hyperlink.tracking': '当前已开启修订模式，暂不支持插入超链接。请关闭修订模式后重试，文档未修改。',\r\n  'view.hyperlink.readOnly': '文档处于只读模式，无法插入超链接。请切换到可编辑模式后重试，文档未修改。',\r\n  'view.hyperlink.disabled': '编辑功能已被禁用，无法插入超链接。请启用编辑后重试，文档未修改。',\r\n  'view.hyperlink.noSelection': '未找到光标位置或文字选区。请关闭弹窗，在正文中放置光标或选择文字后重试，文档未修改。',\r\n  'view.hyperlink.invalidSelection': '文字选区已失效。请关闭弹窗并重新选择文字后重试，文档未修改。',\r\n  'view.hyperlink.nonText': '选区包含图片、表格等非普通文本内容。请只选择普通文字，文档未修改。',\r\n  'view.hyperlink.invalidText': '显示文字必须为非空的普通文本，且不能包含换行或隐藏控制标记。请修改显示文字后重试，文档未修改。',\r\n  'view.paragraph.comment': '插入批注',\r\n  'view.table.insert': '插入',\r\n  'view.table.insertLeft': '在左侧插入',\r\n  'view.table.insertRight': '在右侧插入',\r\n  'view.table.insertAbove': '在上方插入',\r\n  'view.table.insertBelow': '在下方插入',\r\n  'view.table.columnUnit': '列',\r\n  'view.table.rowUnit': '行',\r\n  'view.table.insertCell': '单元格(E)...',\r\n  'view.table.cellOperations': '单元格操作',\n  'view.table.splitCell': '拆分单元格',\r\n  'view.table.mergeCell': '合并单元格',\r\n  'view.table.borderStyle': '边框样式',\n  'view.table.borderAll': '全部边框',\n  'view.table.borderOutside': '外侧边框',\n  'view.table.borderNone': '无边框',\n  'view.table.borderInside': '内部边框',\n  'view.table.borderInsideHorizontal': '内部横线',\n  'view.table.borderInsideVertical': '内部竖线',\n  'view.table.delete': '删除',\r\n  'view.table.deleteRow': '删除行',\r\n  'view.table.deleteColumn': '删除列',\r\n  'view.table.deleteTable': '删除整个表格',\r\n  'view.table.selectAll': '全选表格',\r\n  'view.table.horizontalAlign': '水平对齐方式',\r\n  'view.table.centerAlign': '居中对齐',\r\n  'view.table.verticalAlign': '垂直对齐方式',\r\n  'view.table.alignTop': '顶端对齐',\r\n  'view.table.alignMiddle': '垂直居中',\r\n  'view.table.alignBottom': '底端对齐',\r\n  'view.table.background': '底纹颜色',\r\n  'view.table.repeatHeader': '重复表头行',\r\n  'view.table.textDirection': '文字方向',\n  'view.table.directionHorizontal': '横排',\n  'view.table.directionVertical': '竖排',\n  'view.table.properties': '表格属性',\r\n  'view.table.propertiesDialog': '表格属性...',\n  'view.table.select': '选择表格',\r\n  'view.table.addColumn': '添加列',\r\n  'view.table.addRow': '添加行',\r\n  'view.font.title': '字体',\r\n  'view.font.characterSpacing': '字符间距',\r\n  'view.font.cjkFont': '中文字体',\r\n  'view.font.style': '字形',\r\n  'view.font.regular': '常规',\r\n  'view.font.italic': '倾斜',\r\n  'view.font.bold': '加粗',\r\n  'view.font.boldItalic': '加粗倾斜',\r\n  'view.font.size': '字号',\r\n  'view.font.effects': '效果',\r\n  'view.font.strikethrough': '删除线',\r\n  'view.font.underline': '下划线',\r\n  'view.font.superscript': '上标',\r\n  'view.font.subscript': '下标',\r\n  'view.font.doubleStrikethrough': '双删除线',\r\n  'view.font.hidden': '隐藏',\r\n  'view.font.previewText': '字体预览文本 ABCabc 123',\r\n  'view.font.scale': '缩放',\r\n  'view.font.standard': '标准',\r\n  'view.font.expanded': '加宽',\r\n  'view.font.condensed': '紧缩',\r\n  'view.font.position': '位置',\r\n  'view.font.raised': '提升',\r\n  'view.font.lowered': '降低',\r\n  'view.font.spacingPreview': '字符间距预览 ABCabc 123',\r\n  'view.font.unsupported': '间距与位置功能将在后续版本支持',\r\n  'view.paragraphDialog.title': '段落',\r\n  'view.paragraphDialog.indentSpacing': '缩进和间距',\r\n  'view.paragraphDialog.linePageBreak': '换行和分页',\r\n  'view.paragraphDialog.cjkLayout': '中文版式',\r\n  'view.paragraphDialog.general': '常规',\r\n  'view.paragraphDialog.alignment': '对齐方式',\r\n  'view.paragraphDialog.outline': '大纲级别',\r\n  'view.paragraphDialog.bodyText': '正文文本',\r\n  'view.paragraphDialog.level1': '1 级',\r\n  'view.paragraphDialog.level2': '2 级',\r\n  'view.paragraphDialog.level3': '3 级',\r\n  'view.paragraphDialog.level4': '4 级',\r\n  'view.paragraphDialog.level5': '5 级',\r\n  'view.paragraphDialog.level6': '6 级',\r\n  'view.paragraphDialog.indent': '缩进',\r\n  'view.paragraphDialog.beforeText': '文本之前',\r\n  'view.paragraphDialog.afterText': '文本之后',\r\n  'view.paragraphDialog.special': '特殊格式',\r\n  'view.paragraphDialog.firstLine': '首行缩进',\r\n  'view.paragraphDialog.hanging': '悬挂缩进',\r\n  'view.paragraphDialog.measure': '度量值',\r\n  'view.paragraphDialog.cm': '厘米',\r\n  'view.paragraphDialog.adjustRightIndent': '如果定义了文档网格，则自动调整右缩进',\r\n  'view.paragraphDialog.before': '段前',\r\n  'view.paragraphDialog.after': '段后',\r\n  'view.paragraphDialog.lineSpacing': '行距',\r\n  'view.paragraphDialog.single': '单倍行距',\r\n  'view.paragraphDialog.oneHalf': '1.5 倍行距',\r\n  'view.paragraphDialog.double': '双倍行距',\r\n  'view.paragraphDialog.atLeast': '最小值',\r\n  'view.paragraphDialog.exact': '固定值',\r\n  'view.paragraphDialog.multiple': '多倍行距',\r\n  'view.paragraphDialog.setting': '设置值',\r\n  'view.paragraphDialog.times': '倍',\r\n  'view.paragraphDialog.alignGrid': '如果定义了文档网格，则与网格对齐',\r\n  'view.paragraphDialog.previewText': '段落预览文本',\r\n  'view.paragraphDialog.pagination': '分页',\r\n  'view.paragraphDialog.widow': '孤行控制',\r\n  'view.paragraphDialog.keepNext': '与下段同页',\r\n  'view.paragraphDialog.breakBefore': '段前分页',\r\n  'view.paragraphDialog.lineBreak': '换行',\r\n  'view.paragraphDialog.noLineNumber': '取消行号',\r\n  'view.paragraphDialog.noHyphen': '取消断字',\r\n  'view.paragraphDialog.unsupported': '该功能将在后续版本支持',\r\n  'view.paragraphDialog.cjkWrap': '按中文习惯换行',\r\n  'view.paragraphDialog.punctuationOverflow': '允许标点溢出边界',\r\n  'view.paragraphDialog.wordBreak': '允许西文在单词中间换行',\r\n  'view.paragraphDialog.compressPunctuation': '允许行首标点压缩',\r\n  'view.paragraphDialog.cjkWesternSpacing': '自动调整中文与西文的间距',\r\n  'view.paragraphDialog.cjkNumberSpacing': '自动调整中文与数字的间距',\r\n  'view.paragraphDialog.textAlignment': '文字对齐方式',\r\n  'view.paragraphDialog.align': '对齐',\r\n  'view.paragraphDialog.auto': '自动',\r\n  'view.paragraphDialog.baseline': '基线对齐',\r\n  'view.tableDialog.categories': '属性类别',\r\n  'view.tableDialog.table': '表格',\r\n  'view.tableDialog.columnWidth': '列宽',\n  'view.tableDialog.currentColumnWidth': '当前列宽',\n  'view.tableDialog.mergedColumnWidthHint': '跨列合并单元格的列宽请通过表格边框拖拽调整。',\n  'view.tableDialog.row': '行',\n  'view.tableDialog.cell': '单元格',\r\n  'view.tableDialog.rowHint': '行高和重复表头设置应用于右键位置所在行。',\n  'view.tableDialog.rowHeight': '行高',\n  'view.tableDialog.height': '高度',\n  'view.tableDialog.repeatHeader': '重复表头',\n  'view.tableDialog.repeatThisRow': '在跨页时重复此行',\n  'view.tableDialog.presetHint': '预设替换整个表格的边框组合，未选中的边将清除。',\r\n  'view.tableDialog.border': '边框',\r\n  'view.tableDialog.preset': '预设',\r\n  'view.tableDialog.unchanged': '保持原样',\r\n  'view.tableDialog.allBorders': '全部边框',\r\n  'view.tableDialog.outsideBorders': '外侧边框',\r\n  'view.tableDialog.noBorders': '无边框',\r\n  'view.tableDialog.insideBorders': '内部边框',\r\n  'view.tableDialog.insideHorizontal': '内部横线',\r\n  'view.tableDialog.insideVertical': '内部竖线',\r\n  'view.tableDialog.topBorder': '上边框',\r\n  'view.tableDialog.bottomBorder': '下边框',\r\n  'view.tableDialog.leftBorder': '左边框',\r\n  'view.tableDialog.rightBorder': '右边框',\r\n  'view.tableDialog.borderPresets': '边框预设',\r\n  'view.tableDialog.all': '全部',\r\n  'view.tableDialog.outside': '外侧',\r\n  'view.tableDialog.inside': '内部',\r\n  'view.tableDialog.colorFormatTitle': '请输入 #RRGGBB 格式的颜色',\r\n  'view.tableDialog.colorFormatClearTitle': '请输入 #RRGGBB 格式的颜色，留空清除',\r\n  'view.tableDialog.borderColor': '边框颜色',\r\n  'view.tableDialog.cellColor': '单元格底色',\r\n  'view.tableDialog.chooseColor': '选择{label}（当前{state}）',\r\n  'view.tableDialog.innerWidth': '内框宽度',\r\n  'view.tableDialog.outerWidth': '外框宽度',\r\n  'view.tableDialog.innerWidthAria': '内框宽度（像素）',\r\n  'view.tableDialog.outerWidthAria': '外框宽度（像素）',\r\n  'view.tableDialog.colorHelp': '颜色格式：#RRGGBB；留空保持原样。',\r\n  'view.tableDialog.borderPreview': '边框示意',\r\n  'view.tableDialog.presetPreview': '边框组合示意；虚线仅标示表格范围。未填写的颜色、宽度保持原样。',\r\n  'view.tableDialog.unchangedPreview': '未选择预设，边框组合保持原样；示意不代表混合样式。',\r\n  'view.tableDialog.cellHint': '文字方向、底色、边距和垂直对齐应用于当前单元格；文字对齐应用于当前段落。',\n  'view.tableDialog.textDirection': '文字方向',\n  'view.tableDialog.direction': '方向',\n  'view.tableDialog.horizontal': '横排',\n  'view.tableDialog.vertical': '竖排',\n  'view.tableDialog.cellPadding': '单元格边距',\n  'view.tableDialog.paddingTop': '上',\n  'view.tableDialog.paddingRight': '右',\n  'view.tableDialog.paddingBottom': '下',\n  'view.tableDialog.paddingLeft': '左',\n  'view.tableDialog.textAlignment': '文字对齐',\n  'view.tableDialog.fill': '底色',\r\n  'view.tableDialog.noFill': '无底色',\r\n  'view.tableDialog.invalidColor': '颜色格式无效',\r\n  'view.tableDialog.clearFill': '清除底色',\r\n  'view.tableDialog.fillHelp': '颜色格式：#RRGGBB；留空表示无底色。',\r\n  'view.tableDialog.verticalAlign': '垂直对齐',\r\n  'view.tableDialog.alignCenter': '居中对齐',\r\n  'view.pageNumber.header': '页眉',\r\n  'view.pageNumber.footer': '页脚',\r\n  'view.pageNumber.insert': '插入页码',\r\n  'view.pageNumber.style': '样式:',\r\n  'view.pageNumber.position': '位置:',\r\n  'view.pageNumber.left': '左侧',\r\n  'view.pageNumber.center': '居中',\r\n  'view.pageNumber.right': '右侧',\r\n  'view.pageNumber.stylePage': '第1页',\r\n  'view.pageNumber.styleTotal': '第1页共x页',\r\n  'view.pageNumber.styleFirst': '第一页',\r\n  'view.pageNumber.styleFirstTotal': '第一页共X页',\r\n  'view.fontFamily.SimSun': '宋体',\r\n  'view.fontFamily.SimHei': '黑体',\r\n  'view.fontFamily.KaiTi': '楷体',\r\n  'view.fontFamily.FangSong': '仿宋',\r\n  'view.fontFamily.MicrosoftYaHei': '微软雅黑',\r\n  'view.fontFamily.DengXian': '等线',\r\n  'view.fontFamily.STSong': '华文宋体',\r\n  'view.fontFamily.STHeiti': '华文黑体',\r\n  'view.fontFamily.STKaiti': '华文楷体',\r\n  'view.fontFamily.STFangsong': '华文仿宋',\r\n  'view.fontFamily.STZhongsong': '华文中宋',\r\n  'view.fontFamily.STXihei': '华文细黑',\r\n  'view.fontFamily.STXingkai': '华文行楷',\r\n  'view.fontFamily.STLiti': '华文隶书',\r\n  'view.fontFamily.STXinwei': '华文新魏',\r\n  'view.fontFamily.STCaiyun': '华文彩云',\r\n  'view.fontSize.chuhao': '初号',\r\n  'view.fontSize.xiaochu': '小初',\r\n  'view.fontSize.yihao': '一号',\r\n  'view.fontSize.xiaoyi': '小一',\r\n  'view.fontSize.erhao': '二号',\r\n  'view.fontSize.xiaoer': '小二',\r\n  'view.fontSize.sanhao': '三号',\r\n  'view.fontSize.xiaosan': '小三',\r\n  'view.fontSize.sihao': '四号',\r\n  'view.fontSize.xiaosi': '小四',\r\n  'view.fontSize.wuhao': '五号',\r\n  'view.fontSize.xiaowu': '小五',\r\n  'view.fontSize.liuhao': '六号',\r\n  'view.fontSize.xiaoliu': '小六',\r\n  'view.fontSize.qihao': '七号',\r\n  'view.fontSize.bahao': '八号'\r\n}\r\n\r\nexport function viewTranslate(translate: ViewTranslate | undefined, key: string, params?: Record<string, string | number>): string {\r\n  const fallback = viewText[key] ?? key\r\n  const result = translate?.(key, params)\r\n  const text = !result || result === key ? fallback : result\r\n  return text.replace(/\\{(\\w+)}/g, (_, name: string) => String(params?.[name] ?? `{${name}}`))\r\n}\r\n\r\n// Translate template text nodes and display-only attributes, leaving form values intact.\r\nconst textKeys = new WeakMap<Text, string>()\r\n\r\nexport function translatePanel(root: HTMLElement, translate: ViewTranslate | undefined, prefix: string): void {\r\n  const entries = Object.entries(viewText)\r\n  const preferred = entries.filter(([key]) => key.startsWith(prefix) || key.startsWith('view.common.'))\r\n  const byText = new Map([...entries, ...preferred].map(([key, value]) => [value, key]))\r\n  const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT)\r\n  while (walker.nextNode()) {\r\n    const node = walker.currentNode as Text\r\n    const raw = node.textContent ?? ''\r\n    const text = raw.trim()\r\n    const key = textKeys.get(node) ?? byText.get(text)\r\n    if (key) {\r\n      textKeys.set(node, key)\r\n      node.textContent = raw.replace(text, () => viewTranslate(translate, key))\r\n    }\r\n  }\r\n  for (const el of [root, ...Array.from(root.querySelectorAll<HTMLElement>('*'))]) {\r\n    const keyedText = el.dataset.i18nKey\r\n    if (keyedText) el.textContent = viewTranslate(translate, keyedText)\r\n    for (const attr of ['title', 'aria-label', 'placeholder']) {\r\n      const marker = `i18n${attr === 'aria-label' ? 'AriaLabel' : attr[0].toUpperCase() + attr.slice(1)}`\r\n      const raw = el.getAttribute(attr)\r\n      const key = el.dataset[marker] ?? (raw && byText.get(raw))\r\n      if (key) {\r\n        el.dataset[marker] = key\r\n        el.setAttribute(attr, viewTranslate(translate, key))\r\n      }\r\n    }\r\n  }\r\n}\r\n","/**\r\n * VerveDocs View —— 表格右键菜单\r\n *\r\n * 纯 DOM 实现，无框架依赖。支持子菜单、图标、快捷键、分隔线。\r\n */\r\n\r\nimport './assets/css/context-menu.css'\r\nimport { viewTranslate, type ViewTranslate } from './view-i18n'\r\n\r\n/** CSS 类名前缀，所有菜单相关样式均以此为前缀 */\r\nconst PREFIX = 'ce-table-context-menu'\r\n\r\n/**\r\n * 菜单项内嵌数字输入框配置。\r\n * 用于在菜单项右侧展示一个带单位的数字输入控件（如行高、列宽）。\r\n */\r\nexport interface MenuItemInput {\r\n  /** 输入框初始值 */\r\n  defaultValue: number\r\n  /** 单位文本（如 \"px\"、\"%\"） */\r\n  unit: string\r\n  /** 允许的最小值，默认 1 */\r\n  min?: number\r\n  /** 允许的最大值，默认 99 */\r\n  max?: number\r\n}\r\n\r\n/**\r\n * 菜单项内嵌颜色选择器配置。\r\n * 用于在菜单项右侧展示一个原生 color input 及可选的\"无\"清除按钮。\r\n */\r\nexport interface MenuItemColorPicker {\r\n  /** 初始颜色值（如 \"#ffffff\"），默认白色 */\r\n  defaultColor?: string\r\n  /** 是否展示\"无\"清除按钮，点击后以空字符串触发 onClick */\r\n  allowClear?: boolean\r\n}\r\n\r\n/**\r\n * 右键菜单项描述。\r\n * 支持图标、快捷键、子菜单、内嵌输入框、内嵌颜色选择器、危险态、禁用态等。\r\n */\r\nexport interface MenuItem {\r\n  /** 显示文本；值为 \"---\" 时渲染为分隔线 */\r\n  label: string\r\n  /** material-symbols-outlined 图标名，可选 */\r\n  icon?: string\r\n  /** 快捷键提示文本（仅展示，不绑定按键），可选 */\r\n  shortcut?: string\r\n  /** 是否为危险操作（红色高亮），可选 */\r\n  danger?: boolean\r\n  /** 是否禁用该项，可选 */\r\n  disabled?: boolean\r\n  /** 子菜单项数组，存在时显示右箭头并悬停展开 */\r\n  submenu?: MenuItem[]\r\n  /** 内嵌数字输入框配置，可选 */\r\n  input?: MenuItemInput\r\n  /** 内嵌颜色选择器配置，可选 */\r\n  colorPicker?: MenuItemColorPicker\r\n  /** 点击回调；参数为输入框/颜色选择器的当前值（无控件时为 undefined） */\r\n  onClick?: (value?: number | string) => void\r\n}\r\n\r\n/** material-symbols-outlined 图标名映射表，供外部通过 getIcons() 引用 */\r\nconst SVG = {\r\n  insertRowAbove: 'table_rows',\r\n  insertRowBelow: 'table_rows',\r\n  insertColLeft: 'view_column',\r\n  insertColRight: 'view_column',\r\n  deleteRow: 'delete',\r\n  deleteCol: 'delete',\r\n  splitCell: 'splitscreen',\r\n  selectAll: 'select_all',\r\n  alignLeft: 'format_align_left',\r\n  alignCenter: 'format_align_center',\r\n  alignRight: 'format_align_right',\r\n  link: 'link',\r\n  tableProp: 'settings',\r\n  mergeCell: 'merge',\r\n  valignTop: 'vertical_align_top',\r\n  valignMiddle: 'vertical_align_center',\r\n  valignBottom: 'vertical_align_bottom',\r\n  cellBackground: 'format_color_fill',\r\n  repeatHeader: 'repeat',\r\n  textDirection: 'text_rotation_none',\n  horizontalText: 'format_textdirection_l_to_r',\n  verticalText: 'text_rotate_vertical',\n  check: 'check',\n  deleteTable: 'delete',\r\n  cellOperations: 'grid_view',\n  borderStyle: 'border_all',\n  arrow: 'chevron_right'\r\n}\r\n\r\n/**\r\n * 表格右键菜单控制器。\r\n * 纯 DOM 实现，负责菜单/子菜单的构建、定位、显隐与外部点击关闭。\r\n */\r\nexport class ContextMenu {\r\n  /** 主菜单根元素 */\r\n  private menuEl: HTMLDivElement | null = null\r\n  /** 子菜单根元素 */\r\n  private submenuEl: HTMLDivElement | null = null\r\n  /** 子菜单延迟隐藏定时器句柄 */\r\n  private hideTimer: number | null = null\r\n\r\n  constructor(private translate?: ViewTranslate) {}\r\n\r\n  /**\r\n   * 在指定坐标显示主菜单。\r\n   * @param x - 菜单左上角横坐标（px）\r\n   * @param y - 菜单左上角纵坐标（px）\r\n   * @param items - 菜单项描述数组\r\n   * @returns 无返回值\r\n   */\r\n  show(x: number, y: number, items: MenuItem[]): void {\r\n    this.showContent(x, y, this.buildMenu(items, false))\r\n  }\r\n\r\n  /** Display custom menu content with the same positioning and dismissal lifecycle. */\r\n  showContent(x: number, y: number, content: HTMLDivElement): void {\r\n    this.hide()\r\n    this.menuEl = content\r\n    this.menuEl.style.left = `${x}px`\r\n    this.menuEl.style.top = `${y}px`\r\n    document.body.appendChild(this.menuEl)\r\n    this.adjustPosition(this.menuEl, x, y)\r\n    document.addEventListener('mousedown', this.onOutsideDown, { capture: true })\r\n    document.addEventListener('scroll', this.onScroll, { capture: true })\r\n  }\r\n\r\n  /**\r\n   * 关闭并销毁主菜单与子菜单，移除所有全局事件监听。\r\n   * @returns 无返回值\r\n   */\r\n  hide(): void {\r\n    if (this.menuEl) { this.menuEl.remove(); this.menuEl = null }\r\n    if (this.submenuEl) { this.submenuEl.remove(); this.submenuEl = null }\r\n    document.removeEventListener('mousedown', this.onOutsideDown, { capture: true })\r\n    document.removeEventListener('scroll', this.onScroll, { capture: true })\r\n  }\r\n\r\n  /**\r\n   * 根据菜单项描述构建菜单根 div。\r\n   * @param items - 菜单项描述数组\r\n   * @param isSub - 是否为子菜单（影响是否追加子菜单修饰类）\r\n   * @returns 构建完成的菜单根 HTMLDivElement\r\n   */\r\n  private buildMenu(items: MenuItem[], isSub: boolean): HTMLDivElement {\r\n    const el = document.createElement('div')\r\n    el.className = PREFIX + (isSub ? ` ${PREFIX}--sub` : '')\r\n    for (const item of items) {\r\n      if (item.label === '---') {\r\n        const div = document.createElement('div')\r\n        div.className = `${PREFIX}__divider`\r\n        el.appendChild(div)\r\n        continue\r\n      }\r\n      el.appendChild(this.buildItem(item))\r\n    }\r\n    return el\r\n  }\r\n\r\n  /**\r\n   * 构建单个菜单项元素，包含图标、文本、快捷键、子菜单箭头、输入框、颜色选择器等。\r\n   * @param item - 菜单项描述\r\n   * @returns 构建完成的菜单项 HTMLDivElement\r\n   */\r\n  private buildItem(item: MenuItem): HTMLDivElement {\r\n    const el = document.createElement('div')\r\n    el.className = `${PREFIX}__item${item.danger ? ' danger' : ''}${item.disabled ? ' disabled' : ''}${item.input ? ` ${PREFIX}__item--with-input` : ''}`\r\n\r\n    const main = document.createElement('span')\r\n    main.className = `${PREFIX}__main`\r\n\r\n    if (item.icon) {\r\n      const icon = document.createElement('span')\r\n      icon.className = `material-symbols-outlined ${PREFIX}__icon`\r\n      icon.textContent = item.icon\r\n      main.appendChild(icon)\r\n    }\r\n\r\n    const label = document.createElement('span')\r\n    label.className = `${PREFIX}__label`\r\n    label.textContent = item.label\r\n    main.appendChild(label)\r\n    el.appendChild(main)\r\n\r\n    const meta = document.createElement('span')\r\n    meta.className = `${PREFIX}__meta`\r\n\r\n    if (item.shortcut) {\r\n      const sc = document.createElement('span')\r\n      sc.className = `${PREFIX}__shortcut`\r\n      sc.textContent = item.shortcut\r\n      meta.appendChild(sc)\r\n    }\r\n\r\n    if (item.submenu) {\r\n      const arrow = document.createElement('span')\r\n      arrow.className = `material-symbols-outlined ${PREFIX}__arrow`\r\n      arrow.textContent = SVG.arrow\r\n      meta.appendChild(arrow)\r\n    }\r\n\r\n    el.appendChild(meta)\r\n\r\n    let inputValue: number | undefined\r\n\r\n    if (item.input) {\r\n      const wrap = document.createElement('span')\r\n      wrap.className = `${PREFIX}__input-wrap`\r\n\r\n      const input = document.createElement('input')\r\n      input.type = 'number'\r\n      input.setAttribute('aria-label', item.label)\r\n      input.className = `${PREFIX}__input`\r\n      input.value = String(item.input.defaultValue)\r\n      const min = item.input.min ?? 1\r\n      const max = item.input.max ?? 99\r\n      input.min = String(min)\r\n      input.max = String(max)\r\n      inputValue = item.input.defaultValue\r\n\r\n      input.addEventListener('mousedown', (e) => {\r\n        e.stopPropagation()\r\n      })\r\n      input.addEventListener('click', (e) => {\r\n        e.stopPropagation()\r\n      })\r\n      input.addEventListener('input', () => {\r\n        const v = parseInt(input.value, 10)\r\n        inputValue = isNaN(v) ? item.input!.defaultValue : Math.max(min, Math.min(max, v))\r\n      })\r\n      input.addEventListener('keydown', (e) => {\r\n        e.stopPropagation()\r\n        if (e.key === 'Enter') {\r\n          if (!item.disabled && item.onClick) {\r\n            item.onClick(inputValue)\r\n            this.hide()\r\n          }\r\n        }\r\n      })\r\n\r\n      wrap.appendChild(input)\r\n\r\n      const unit = document.createElement('span')\r\n      unit.className = `${PREFIX}__input-unit`\r\n      unit.textContent = item.input.unit\r\n      wrap.appendChild(unit)\r\n\r\n      meta.appendChild(wrap)\r\n    }\r\n\r\n    let colorValue: string | undefined\r\n\r\n    if (item.colorPicker) {\r\n      const wrap = document.createElement('span')\r\n      wrap.className = `${PREFIX}__color-wrap`\r\n\r\n      const colorInput = document.createElement('input')\r\n      colorInput.type = 'color'\r\n      colorInput.setAttribute('aria-label', item.label)\r\n      colorInput.className = `${PREFIX}__color-input`\r\n      colorInput.value = item.colorPicker.defaultColor ?? '#ffffff'\r\n      colorValue = colorInput.value\r\n\r\n      colorInput.addEventListener('mousedown', (e) => { e.stopPropagation() })\r\n      colorInput.addEventListener('click', (e) => { e.stopPropagation() })\r\n      colorInput.addEventListener('input', () => { colorValue = colorInput.value })\r\n      colorInput.addEventListener('change', () => {\r\n        if (!item.disabled && item.onClick) {\r\n          item.onClick(colorValue)\r\n          this.hide()\r\n        }\r\n      })\r\n      wrap.appendChild(colorInput)\r\n\r\n      if (item.colorPicker.allowClear) {\r\n        const clear = document.createElement('span')\r\n        clear.className = `${PREFIX}__color-clear`\r\n        clear.textContent = viewTranslate(this.translate, 'view.common.none')\r\n        clear.addEventListener('mousedown', (e) => { e.stopPropagation() })\r\n        clear.addEventListener('click', (e) => {\r\n          e.stopPropagation()\r\n          if (!item.disabled && item.onClick) {\r\n            item.onClick('')\r\n            this.hide()\r\n          }\r\n        })\r\n        wrap.appendChild(clear)\r\n      }\r\n\r\n      meta.appendChild(wrap)\r\n    }\r\n\r\n    if (!item.disabled && item.onClick && !item.colorPicker) {\r\n      el.addEventListener('click', () => {\r\n        item.onClick!(inputValue ?? colorValue)\r\n        this.hide()\r\n      })\r\n    }\r\n\r\n    if (!item.disabled && item.submenu) {\r\n      el.addEventListener('mouseenter', () => {\r\n        if (this.hideTimer) { clearTimeout(this.hideTimer); this.hideTimer = null }\r\n        this.showSubmenu(el, item.submenu!)\r\n      })\r\n      el.addEventListener('mouseleave', () => {\r\n        this.hideTimer = window.setTimeout(() => {\r\n          if (this.submenuEl) { this.submenuEl.remove(); this.submenuEl = null }\r\n        }, 200)\r\n      })\r\n    }\r\n\r\n    return el\r\n  }\r\n\r\n  /**\r\n   * 在指定父菜单项右侧展开其子菜单，并绑定悬停保持/离开延迟隐藏。\r\n   * @param parentEl - 触发展开的父菜单项元素\r\n   * @param items - 子菜单项描述数组\r\n   * @returns 无返回值\r\n   */\r\n  private showSubmenu(parentEl: HTMLDivElement, items: MenuItem[]): void {\r\n    if (this.submenuEl) { this.submenuEl.remove(); this.submenuEl = null }\r\n    this.submenuEl = this.buildMenu(items, true)\r\n    this.submenuEl.addEventListener('mouseenter', () => {\r\n      if (this.hideTimer) { clearTimeout(this.hideTimer); this.hideTimer = null }\r\n    })\r\n    this.submenuEl.addEventListener('mouseleave', () => {\r\n      this.hideTimer = window.setTimeout(() => {\r\n        if (this.submenuEl) { this.submenuEl.remove(); this.submenuEl = null }\r\n      }, 200)\r\n    })\r\n    const rect = parentEl.getBoundingClientRect()\r\n    const x = rect.right\r\n    const y = rect.top\r\n    this.submenuEl.style.left = `${x}px`\r\n    this.submenuEl.style.top = `${y}px`\r\n    document.body.appendChild(this.submenuEl)\r\n    this.adjustPosition(this.submenuEl, x, y)\r\n  }\r\n\r\n  /**\r\n   * 校正菜单位置，避免其超出视口右边界或下边界。\r\n   * @param el - 待校正的菜单元素\r\n   * @param x - 期望的横坐标（px）\r\n   * @param y - 期望的纵坐标（px）\r\n   * @returns 无返回值\r\n   */\r\n  private adjustPosition(el: HTMLDivElement, x: number, y: number): void {\r\n    const rect = el.getBoundingClientRect()\r\n    const vw = window.innerWidth\r\n    const vh = window.innerHeight\r\n    if (x + rect.width > vw || x < 4) {\r\n      el.style.left = `${Math.max(4, Math.min(vw - rect.width - 4, x < 4 ? 4 : vw - rect.width - 4))}px`\r\n    }\r\n    if (y + rect.height > vh || y < 4) {\r\n      el.style.top = `${Math.max(4, Math.min(vh - rect.height - 4, y < 4 ? 4 : vh - rect.height - 4))}px`\r\n    }\r\n  }\r\n\r\n  /** 全局 mousedown 监听器：点击发生在菜单外部时关闭菜单 */\r\n  private onOutsideDown = (e: MouseEvent): void => {\r\n    const target = e.target as Node\r\n    if (this.menuEl?.contains(target)) return\r\n    if (this.submenuEl?.contains(target)) return\r\n    this.hide()\r\n  }\r\n\r\n  /** 全局 scroll 监听器：页面滚动时关闭菜单，避免错位 */\r\n  private onScroll = (): void => {\r\n    this.hide()\r\n  }\r\n\r\n  /**\r\n   * 获取内置 material-symbols-outlined 图标名映射表。\r\n   * @returns 图标名映射对象\r\n   */\r\n  static getIcons() { return SVG }\r\n}\r\n","/** Body-mounted handles must stay inside both the editor and the browser viewport. */\r\nexport function positionHandle(\r\n  handle: HTMLElement,\r\n  x: number,\r\n  y: number,\r\n  size: number,\r\n  viewport: DOMRect\r\n): boolean {\r\n  const left = Math.round(x)\r\n  const top = Math.round(y)\r\n  const visible = left >= Math.max(0, viewport.left) &&\r\n    top >= Math.max(0, viewport.top) &&\r\n    left + size <= Math.min(window.innerWidth, viewport.right) &&\r\n    top + size <= Math.min(window.innerHeight, viewport.bottom)\r\n\r\n  handle.style.boxSizing = 'border-box'\r\n  handle.style.left = `${left}px`\r\n  handle.style.top = `${top}px`\r\n  handle.style.display = visible ? 'flex' : 'none'\r\n  return visible\r\n}\r\n","export default \"<div class=\\\"pw-panel-mask tp-mask\\\">\\r\\n  <form class=\\\"pw-panel tp-panel\\\" role=\\\"dialog\\\" aria-modal=\\\"true\\\" aria-labelledby=\\\"tp-title\\\" tabindex=\\\"-1\\\" novalidate>\\n    <div class=\\\"pw-panel-title\\\" id=\\\"tp-title\\\">表格属性</div>\\r\\n    <div class=\\\"tp-tabs\\\" role=\\\"tablist\\\" aria-label=\\\"属性类别\\\">\\r\\n      <button type=\\\"button\\\" id=\\\"tp-table-tab\\\" role=\\\"tab\\\" aria-selected=\\\"true\\\" aria-controls=\\\"tp-table-pane\\\" data-tab=\\\"table\\\">表格</button>\\n      <button type=\\\"button\\\" id=\\\"tp-row-tab\\\" role=\\\"tab\\\" aria-selected=\\\"false\\\" aria-controls=\\\"tp-row-pane\\\" data-tab=\\\"row\\\" tabindex=\\\"-1\\\">行</button>\\n      <button type=\\\"button\\\" id=\\\"tp-cell-tab\\\" role=\\\"tab\\\" aria-selected=\\\"false\\\" aria-controls=\\\"tp-cell-pane\\\" data-tab=\\\"cell\\\" tabindex=\\\"-1\\\">单元格</button>\\r\\n    </div>\\r\\n    <div class=\\\"tp-body\\\">\\r\\n      <section id=\\\"tp-table-pane\\\" role=\\\"tabpanel\\\" aria-labelledby=\\\"tp-table-tab\\\" data-pane=\\\"table\\\">\\r\\n        <p class=\\\"tp-hint\\\">预设替换整个表格的边框组合，未选中的边将清除。</p>\\r\\n        <fieldset class=\\\"tp-group\\\">\\r\\n          <legend>边框</legend>\\r\\n          <div class=\\\"tp-border-layout\\\">\\r\\n            <div class=\\\"tp-settings\\\">\\r\\n              <label class=\\\"tp-label\\\" for=\\\"tp-type\\\">预设</label>\\r\\n              <select id=\\\"tp-type\\\" name=\\\"type\\\" class=\\\"pw-ctrl\\\"><option value=\\\"\\\">保持原样</option><option value=\\\"all\\\">全部边框</option><option value=\\\"outside\\\">外侧边框</option><option value=\\\"none\\\">无边框</option><option value=\\\"inside\\\">内部边框</option><option value=\\\"inside-horizontal\\\">内部横线</option><option value=\\\"inside-vertical\\\">内部竖线</option><option value=\\\"top\\\">上边框</option><option value=\\\"bottom\\\">下边框</option><option value=\\\"left\\\">左边框</option><option value=\\\"right\\\">右边框</option></select>\\r\\n              <div class=\\\"tp-presets\\\" role=\\\"group\\\" aria-label=\\\"边框预设\\\">\\r\\n                <button type=\\\"button\\\" data-preset=\\\"all\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"all\\\" aria-hidden=\\\"true\\\"></span>全部</button>\\r\\n                <button type=\\\"button\\\" data-preset=\\\"outside\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"outside\\\" aria-hidden=\\\"true\\\"></span>外侧</button>\\r\\n                <button type=\\\"button\\\" data-preset=\\\"none\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"none\\\" aria-hidden=\\\"true\\\"></span>无边框</button>\\r\\n                <button type=\\\"button\\\" data-preset=\\\"inside\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"inside\\\" aria-hidden=\\\"true\\\"></span>内部</button>\\r\\n                <button type=\\\"button\\\" data-preset=\\\"inside-horizontal\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"inside-horizontal\\\" aria-hidden=\\\"true\\\"></span>内部横线</button>\\r\\n                <button type=\\\"button\\\" data-preset=\\\"inside-vertical\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"inside-vertical\\\" aria-hidden=\\\"true\\\"></span>内部竖线</button>\\r\\n                <button type=\\\"button\\\" data-preset=\\\"top\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"top\\\" aria-hidden=\\\"true\\\"></span>上边框</button>\\r\\n                <button type=\\\"button\\\" data-preset=\\\"bottom\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"bottom\\\" aria-hidden=\\\"true\\\"></span>下边框</button>\\r\\n                <button type=\\\"button\\\" data-preset=\\\"left\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"left\\\" aria-hidden=\\\"true\\\"></span>左边框</button>\\r\\n                <button type=\\\"button\\\" data-preset=\\\"right\\\" aria-pressed=\\\"false\\\"><span class=\\\"tp-border-icon\\\" data-border=\\\"right\\\" aria-hidden=\\\"true\\\"></span>右边框</button>\\r\\n              </div>\\r\\n              <label class=\\\"tp-label\\\" for=\\\"tp-color\\\">颜色</label>\\r\\n              <div class=\\\"tp-color-field\\\" data-empty=\\\"true\\\">\\r\\n                <input id=\\\"tp-color\\\" type=\\\"text\\\" name=\\\"color\\\" class=\\\"pw-ctrl\\\" placeholder=\\\"保持原样\\\" pattern=\\\"#[0-9a-fA-F]{6}\\\" title=\\\"请输入 #RRGGBB 格式的颜色\\\" aria-describedby=\\\"tp-color-help\\\">\\r\\n                <input type=\\\"color\\\" value=\\\"#000000\\\" data-color-picker=\\\"color\\\" aria-label=\\\"选择边框颜色（当前保持原样）\\\" aria-describedby=\\\"tp-color-help\\\">\\r\\n              </div>\\r\\n              <label class=\\\"tp-label\\\" for=\\\"tp-width\\\">内框宽度</label>\\r\\n              <div class=\\\"tp-with-unit\\\"><input id=\\\"tp-width\\\" name=\\\"width\\\" class=\\\"pw-ctrl\\\" type=\\\"number\\\" min=\\\"0\\\" step=\\\"any\\\" placeholder=\\\"保持原样\\\" aria-label=\\\"内框宽度（像素）\\\"><span>px</span></div>\\r\\n              <label class=\\\"tp-label\\\" for=\\\"tp-external-width\\\">外框宽度</label>\\r\\n              <div class=\\\"tp-with-unit\\\"><input id=\\\"tp-external-width\\\" name=\\\"externalWidth\\\" class=\\\"pw-ctrl\\\" type=\\\"number\\\" min=\\\"0\\\" step=\\\"any\\\" placeholder=\\\"保持原样\\\" aria-label=\\\"外框宽度（像素）\\\"><span>px</span></div>\\r\\n              <p id=\\\"tp-color-help\\\" class=\\\"tp-field-help\\\">颜色格式：#RRGGBB；留空保持原样。</p>\\r\\n            </div>\\r\\n            <div class=\\\"tp-preview-box\\\">\\r\\n              <span class=\\\"tp-label\\\">预览</span>\\r\\n              <div class=\\\"tp-preview-stage\\\" aria-hidden=\\\"true\\\"><div class=\\\"tp-border-icon tp-border-preview\\\" data-preview data-border=\\\"all\\\"><span></span><span></span><span></span><span></span></div></div>\\r\\n              <p class=\\\"tp-hint\\\" data-preview-caption aria-live=\\\"polite\\\">边框示意</p>\\r\\n            </div>\\r\\n          </div>\\r\\n        </fieldset>\\r\\n        <fieldset class=\\\"tp-group\\\">\\n          <legend>列宽</legend>\\n          <div class=\\\"tp-settings\\\">\\n            <label class=\\\"tp-label\\\" for=\\\"tp-column-width\\\">当前列宽</label>\\n            <div class=\\\"tp-with-unit\\\"><input id=\\\"tp-column-width\\\" name=\\\"columnWidth\\\" class=\\\"pw-ctrl\\\" type=\\\"number\\\" min=\\\"20\\\" step=\\\"1\\\" placeholder=\\\"保持原样\\\"><span>px</span></div>\\n          </div>\\n          <p class=\\\"tp-field-help\\\">跨列合并单元格的列宽请通过表格边框拖拽调整。</p>\\n        </fieldset>\\n      </section>\\r\\n      <section id=\\\"tp-row-pane\\\" role=\\\"tabpanel\\\" aria-labelledby=\\\"tp-row-tab\\\" data-pane=\\\"row\\\" hidden>\\n        <p class=\\\"tp-hint\\\">行高和重复表头设置应用于右键位置所在行。</p>\\n        <fieldset class=\\\"tp-group\\\">\\n          <legend>行高</legend>\\n          <div class=\\\"tp-settings\\\">\\n            <label class=\\\"tp-label\\\" for=\\\"tp-row-height\\\">高度</label>\\n            <div class=\\\"tp-with-unit\\\"><input id=\\\"tp-row-height\\\" name=\\\"rowHeight\\\" class=\\\"pw-ctrl\\\" type=\\\"number\\\" min=\\\"20\\\" step=\\\"1\\\" placeholder=\\\"保持原样\\\"><span>px</span></div>\\n          </div>\\n        </fieldset>\\n        <fieldset class=\\\"tp-group\\\">\\n          <legend>重复标题</legend>\\n          <label class=\\\"tp-checkbox\\\"><input type=\\\"checkbox\\\" name=\\\"pagingRepeat\\\"><span>在跨页时重复此行</span></label>\\n        </fieldset>\\n      </section>\\n      <section id=\\\"tp-cell-pane\\\" role=\\\"tabpanel\\\" aria-labelledby=\\\"tp-cell-tab\\\" data-pane=\\\"cell\\\" hidden>\\r\\n        <p class=\\\"tp-hint\\\">文字方向、底色、边距和垂直对齐应用于当前单元格；文字对齐应用于当前段落。</p>\\n        <fieldset class=\\\"tp-group\\\">\\n          <legend>文字方向</legend>\\n          <div class=\\\"tp-cell-align\\\">\\n            <label class=\\\"tp-label\\\" for=\\\"tp-text-direction\\\">方向</label>\\n            <select id=\\\"tp-text-direction\\\" name=\\\"textDirection\\\" class=\\\"pw-ctrl\\\">\\n              <option value=\\\"\\\">保持原样</option>\\n              <option value=\\\"lrTb\\\">横排</option>\\n              <option value=\\\"tbRlV\\\">竖排</option>\\n            </select>\\n          </div>\\n        </fieldset>\\n        <fieldset class=\\\"tp-group\\\">\\n          <legend>文字对齐</legend>\\n          <div class=\\\"tp-cell-align\\\">\\n            <label class=\\\"tp-label\\\" for=\\\"tp-horizontal-align\\\">对齐方式</label>\\n            <select id=\\\"tp-horizontal-align\\\" name=\\\"horizontalAlign\\\" class=\\\"pw-ctrl\\\">\\n              <option value=\\\"\\\">保持原样</option>\\n              <option value=\\\"left\\\">左对齐</option>\\n              <option value=\\\"center\\\">居中</option>\\n              <option value=\\\"right\\\">右对齐</option>\\n            </select>\\n          </div>\\n        </fieldset>\\n        <fieldset class=\\\"tp-group\\\">\\r\\n          <legend>底色</legend>\\r\\n          <div class=\\\"tp-cell-fill\\\">\\r\\n            <label class=\\\"tp-label\\\" for=\\\"tp-background\\\">颜色</label>\\r\\n            <div class=\\\"tp-color-field\\\" data-empty=\\\"true\\\">\\r\\n              <input id=\\\"tp-background\\\" type=\\\"text\\\" name=\\\"backgroundColor\\\" class=\\\"pw-ctrl\\\" placeholder=\\\"无底色\\\" pattern=\\\"#[0-9a-fA-F]{6}\\\" title=\\\"请输入 #RRGGBB 格式的颜色，留空清除\\\" aria-describedby=\\\"tp-background-help\\\">\\r\\n              <input type=\\\"color\\\" value=\\\"#000000\\\" data-color-picker=\\\"backgroundColor\\\" aria-label=\\\"选择单元格底色（当前无底色）\\\" aria-describedby=\\\"tp-background-help\\\">\\r\\n            </div>\\r\\n            <button type=\\\"button\\\" data-clear-background>清除底色</button>\\r\\n          </div>\\r\\n          <p id=\\\"tp-background-help\\\" class=\\\"tp-hint\\\">颜色格式：#RRGGBB；留空表示无底色。</p>\\r\\n        </fieldset>\\r\\n        <fieldset class=\\\"tp-group\\\">\\r\\n          <legend>单元格边距</legend>\\n          <div class=\\\"tp-cell-padding\\\">\\n            <label class=\\\"tp-padding-field\\\" for=\\\"tp-padding-top\\\"><span>上</span><input id=\\\"tp-padding-top\\\" name=\\\"paddingTop\\\" class=\\\"pw-ctrl\\\" type=\\\"number\\\" min=\\\"0\\\" step=\\\"1\\\"></label>\\n            <label class=\\\"tp-padding-field\\\" for=\\\"tp-padding-right\\\"><span>右</span><input id=\\\"tp-padding-right\\\" name=\\\"paddingRight\\\" class=\\\"pw-ctrl\\\" type=\\\"number\\\" min=\\\"0\\\" step=\\\"1\\\"></label>\\n            <label class=\\\"tp-padding-field\\\" for=\\\"tp-padding-bottom\\\"><span>下</span><input id=\\\"tp-padding-bottom\\\" name=\\\"paddingBottom\\\" class=\\\"pw-ctrl\\\" type=\\\"number\\\" min=\\\"0\\\" step=\\\"1\\\"></label>\\n            <label class=\\\"tp-padding-field\\\" for=\\\"tp-padding-left\\\"><span>左</span><input id=\\\"tp-padding-left\\\" name=\\\"paddingLeft\\\" class=\\\"pw-ctrl\\\" type=\\\"number\\\" min=\\\"0\\\" step=\\\"1\\\"></label>\\n          </div>\\n        </fieldset>\\n        <fieldset class=\\\"tp-group\\\">\\n          <legend>垂直对齐</legend>\\r\\n          <div class=\\\"tp-cell-align\\\">\\r\\n            <label class=\\\"tp-label\\\" for=\\\"tp-vertical-align\\\">对齐方式</label>\\r\\n            <select id=\\\"tp-vertical-align\\\" name=\\\"verticalAlign\\\" class=\\\"pw-ctrl\\\"><option value=\\\"top\\\">顶端对齐</option><option value=\\\"middle\\\">居中对齐</option><option value=\\\"bottom\\\">底端对齐</option></select>\\r\\n          </div>\\r\\n        </fieldset>\\r\\n      </section>\\r\\n    </div>\\r\\n    <div class=\\\"tp-actions\\\">\\r\\n      <button type=\\\"submit\\\" class=\\\"tp-primary\\\">确定</button>\\r\\n      <button type=\\\"button\\\" data-cancel>取消</button>\\r\\n    </div>\\r\\n  </form>\\r\\n</div>\\r\\n\"","import '../../assets/css/paragraph-layout-widget.css'\r\nimport panelHtml from '../../assets/components/table-properties-widget.html?raw'\r\nimport type { IPosition } from '@vervedoc/docx-editor-schema'\r\nimport { translatePanel, viewTranslate, type ViewTranslate } from '../../view-i18n'\r\n\r\ninterface Deps {\r\n  onCommand: (cmd: string, ...args: any[]) => any\r\n  focusInput: () => void\r\n  translate?: ViewTranslate\r\n}\r\n\r\nexport class TablePropertiesWidget {\r\n  private root: HTMLElement | null = null\r\n  private initial: Record<string, string> = {}\r\n  private target: IPosition | null = null\r\n  private columnIndex: number | null = null\n\r\n  constructor(private deps: Deps) {}\r\n\r\n  show(target: IPosition): void {\r\n    this.hide()\r\n    this.target = { path: [...target.path], offset: target.offset }\r\n    const cmd = this.deps.onCommand\r\n    const selection = cmd('getRange')\r\n    let borders: Record<string, unknown> | null = null\n    let cell: Record<string, unknown> | null = null\n    let row: Record<string, unknown> | null = null\n    let column: { index: number; width: number; colspan: number } | null = null\n    try {\n      cmd('executeReplaceRange', { anchor: this.target, focus: this.target })\n      borders = cmd('getTableBorders')\n      cell = cmd('getCellProperties')\n      row = cmd('getTableRowProperties')\n      column = cmd('getTableColumnProperties')\n    } finally {\n      cmd('executeReplaceRange', selection)\n    }\n    const container = document.createElement('div')\r\n    container.innerHTML = panelHtml\r\n    this.root = container.firstElementChild as HTMLElement\r\n    translatePanel(this.root, this.deps.translate, 'view.tableDialog.')\r\n    document.body.appendChild(this.root)\r\n    this.initial = {}\r\n    this.columnIndex = Number.isFinite(column?.index) ? column!.index : null\n    const values = {\n      ...(borders ?? {}),\n      ...(cell ?? {\n        verticalAlign: 'top',\n        backgroundColor: '',\n        textDirection: '',\n        paddingTop: 5,\n        paddingRight: 5,\n        paddingBottom: 5,\n        paddingLeft: 5\n      }),\n      columnWidth: column?.width,\n      ...(row ?? { pagingRepeat: false })\n    }\n    for (const [name, value] of Object.entries(values)) {\n      const input = this.root.querySelector<HTMLInputElement | HTMLSelectElement>(`[name=\"${name}\"]`)\n      if (!input) continue\n      if (name === 'columnWidth' && column && column.colspan > 1) input.disabled = true\n      if (input instanceof HTMLInputElement && input.type === 'checkbox') {\n        input.checked = Boolean(value)\n        this.initial[name] = String(input.checked)\n        continue\n      }\n      input.value = value === undefined ? '' : String(value)\n      if (name === 'color' || name === 'backgroundColor') {\r\n        input.value = input.value.replace(/^#([\\da-f])([\\da-f])([\\da-f])$/i, '#$1$1$2$2$3$3')\r\n      }\r\n      this.initial[name] = input.value\r\n    }\r\n    this.root.querySelectorAll<HTMLButtonElement>('[data-tab]').forEach(tab => {\r\n      tab.addEventListener('click', () => this.selectTab(tab.dataset.tab!))\r\n      tab.addEventListener('keydown', event => {\r\n        const tabs = Array.from(this.root!.querySelectorAll<HTMLButtonElement>('[data-tab]'))\r\n        const index = tabs.indexOf(tab)\r\n        let next: number\r\n        if (event.key === 'ArrowRight') next = (index + 1) % tabs.length\r\n        else if (event.key === 'ArrowLeft') next = (index + tabs.length - 1) % tabs.length\r\n        else if (event.key === 'Home') next = 0\r\n        else if (event.key === 'End') next = tabs.length - 1\r\n        else return\r\n        event.preventDefault()\r\n        this.selectTab(tabs[next].dataset.tab!)\r\n        tabs[next].focus()\r\n      })\r\n    })\r\n    this.root.querySelectorAll<HTMLButtonElement>('[data-preset]').forEach(button => {\r\n      button.addEventListener('click', () => {\r\n        this.root!.querySelector<HTMLSelectElement>('[name=\"type\"]')!.value = button.dataset.preset!\r\n        this.updatePreview()\r\n      })\r\n    })\r\n    this.root.querySelectorAll<HTMLInputElement>('[data-color-picker]').forEach(picker => {\r\n      const input = this.root!.querySelector<HTMLInputElement>(`[name=\"${picker.dataset.colorPicker}\"]`)!\r\n      const selectColor = () => {\r\n        input.value = picker.value\r\n        this.updatePreview()\r\n      }\r\n      picker.addEventListener('input', selectColor)\r\n      picker.addEventListener('change', selectColor)\r\n    })\r\n    this.root.querySelector('[data-clear-background]')!.addEventListener('click', () => {\r\n      const input = this.root!.querySelector<HTMLInputElement>('[name=\"backgroundColor\"]')!\r\n      input.value = ''\r\n      this.updatePreview()\r\n      input.focus()\r\n    })\r\n    this.root.addEventListener('input', () => this.updatePreview())\r\n    this.root.addEventListener('change', () => this.updatePreview())\r\n    this.updatePreview()\r\n    this.root.querySelector('[data-cancel]')!.addEventListener('click', () => this.close())\r\n    this.root.addEventListener('keydown', event => {\r\n      if (event.key === 'Escape') { event.preventDefault(); this.close() }\r\n      if (event.key === 'Tab' && this.root) {\r\n        const controls = Array.from(this.root.querySelectorAll<HTMLElement>('input, select, button'))\r\n          .filter(control => control.tabIndex >= 0 && !control.closest('[hidden]'))\r\n        const first = controls[0]\r\n        const last = controls[controls.length - 1]\r\n        if (event.shiftKey && document.activeElement === first) { event.preventDefault(); last.focus() }\r\n        else if (!event.shiftKey && document.activeElement === last) { event.preventDefault(); first.focus() }\r\n      }\r\n      event.stopPropagation()\r\n    })\r\n    this.root.querySelector('form')!.addEventListener('submit', event => {\r\n      event.preventDefault()\r\n      const invalid = Array.from(this.root!.querySelectorAll<HTMLInputElement>('input'))\r\n        .find(input => !input.disabled && input.name in this.initial &&\n          input.value !== this.initial[input.name] && !input.validity.valid)\n      if (invalid) {\r\n        this.selectTab(invalid.closest<HTMLElement>('[data-pane]')!.dataset.pane!)\r\n        invalid.focus()\r\n        invalid.reportValidity()\r\n        return\r\n      }\r\n      this.apply()\r\n      this.close()\r\n    })\r\n    this.root.focus({ preventScroll: true })\n  }\r\n\r\n  refreshTranslations(): void {\r\n    if (!this.root) return\r\n    translatePanel(this.root, this.deps.translate, 'view.tableDialog.')\r\n    this.updatePreview()\r\n  }\r\n\r\n  private selectTab(name: string): void {\r\n    this.root!.querySelectorAll<HTMLElement>('[data-tab]').forEach(tab => {\r\n      const selected = tab.dataset.tab === name\r\n      tab.setAttribute('aria-selected', String(selected))\r\n      tab.tabIndex = selected ? 0 : -1\r\n    })\r\n    this.root!.querySelectorAll<HTMLElement>('[data-pane]').forEach(pane => {\r\n      pane.hidden = pane.dataset.pane !== name\r\n    })\r\n  }\r\n\r\n  private updatePreview(): void {\r\n    const value = (name: string) => this.root!.querySelector<HTMLInputElement | HTMLSelectElement>(`[name=\"${name}\"]`)!.value\r\n    this.root!.querySelectorAll<HTMLInputElement>('[data-color-picker]').forEach(picker => {\r\n      const color = value(picker.dataset.colorPicker!)\r\n      const valid = /^#[\\da-f]{6}$/i.test(color)\r\n      picker.value = valid ? color : '#000000'\r\n      picker.parentElement!.dataset.empty = String(color === '')\r\n      const t = (key: string) => viewTranslate(this.deps.translate, `view.tableDialog.${key}`)\r\n      const label = picker.dataset.colorPicker === 'color' ? t('borderColor') : t('cellColor')\r\n      const state = color === '' ? (picker.dataset.colorPicker === 'color' ? t('unchanged') : t('noFill')) : (valid ? color : t('invalidColor'))\r\n      picker.setAttribute('aria-label', viewTranslate(this.deps.translate, 'view.tableDialog.chooseColor', { label, state }))\r\n    })\r\n    const type = value('type')\r\n    this.root!.querySelectorAll<HTMLElement>('[data-preset]').forEach(button => {\r\n      button.setAttribute('aria-pressed', String(button.dataset.preset === type))\r\n    })\r\n    const preview = this.root!.querySelector<HTMLElement>('[data-preview]')!\r\n    preview.dataset.border = type || 'all'\r\n    preview.style.setProperty('--tp-line-color', /^#[\\da-f]{6}$/i.test(value('color')) ? value('color') : 'var(--tp-muted)')\r\n    for (const [name, property] of [['width', '--tp-inner-width'], ['externalWidth', '--tp-outer-width']]) {\r\n      const width = value(name)\r\n      preview.style.setProperty(property, `${width === '' ? 1 : Math.min(8, Math.max(0, Number(width)))}px`)\r\n    }\r\n    this.root!.querySelector<HTMLElement>('[data-preview-caption]')!.textContent = viewTranslate(this.deps.translate,\r\n      type ? 'view.tableDialog.presetPreview' : 'view.tableDialog.unchangedPreview')\r\n  }\r\n\r\n  private apply(): void {\r\n    if (!this.root || !this.target) return\r\n    const cmd = this.deps.onCommand\r\n    cmd('executeReplaceRange', { anchor: this.target, focus: this.target })\r\n    const patch: Record<string, string | number> = {}\r\n    for (const name of ['type', 'color', 'width', 'externalWidth']) {\r\n      const value = this.root.querySelector<HTMLInputElement>(`[name=\"${name}\"]`)!.value\r\n      if (value !== '' && value !== this.initial[name]) {\r\n        patch[name] = name === 'width' || name === 'externalWidth' ? Number(value) : value\r\n      }\r\n    }\r\n    if (Object.keys(patch).length) cmd('executeSetTableBorders', patch)\r\n    const columnWidth = this.root.querySelector<HTMLInputElement>('[name=\"columnWidth\"]')!.value\n    if (columnWidth !== '' && this.columnIndex !== null &&\n      Number(columnWidth) !== Number(this.initial.columnWidth)) {\n      cmd('executeSetTableColWidth', Number(this.target.path[0]), this.columnIndex, Number(columnWidth))\n    }\n    for (const [name, command] of [['verticalAlign', 'executeSetCellVerticalAlign'], ['backgroundColor', 'executeSetCellBackground']]) {\r\n      const value = this.root.querySelector<HTMLInputElement>(`[name=\"${name}\"]`)!.value\r\n      if (value !== this.initial[name]) cmd(command, value)\r\n    }\r\n    const horizontalAlign = this.root.querySelector<HTMLSelectElement>('[name=\"horizontalAlign\"]')!.value\n    if (horizontalAlign) cmd('executeSetRowFlex', horizontalAlign)\n    const textDirection = this.root.querySelector<HTMLSelectElement>('[name=\"textDirection\"]')!.value\n    if (textDirection && textDirection !== this.initial.textDirection) {\n      cmd('executeSetCellTextDirection', textDirection, this.target)\n    }\n    const paddingNames = ['paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft']\n    const paddingValues = paddingNames.map(name =>\n      Number(this.root!.querySelector<HTMLInputElement>(`[name=\"${name}\"]`)!.value)\n    ) as [number, number, number, number]\n    if (paddingNames.some((name, index) => String(paddingValues[index]) !== this.initial[name])) {\n      cmd('executeSetCellPadding', paddingValues, this.target)\n    }\n    const rowHeight = this.root.querySelector<HTMLInputElement>('[name=\"rowHeight\"]')!.value\n    if (rowHeight !== '' && Number(rowHeight) !== Number(this.initial.rowHeight)) {\n      cmd('executeSetTableRowHeight', Number(this.target.path[0]), Number(this.target.path[2]), Number(rowHeight))\n    }\n    const repeatHeader = this.root.querySelector<HTMLInputElement>('[name=\"pagingRepeat\"]')!.checked\n    if (String(repeatHeader) !== this.initial.pagingRepeat) {\n      cmd('executeToggleRepeatHeader', this.target)\n    }\n  }\r\n\r\n  private close(): void {\r\n    this.hide()\r\n    this.deps.focusInput()\r\n  }\r\n\r\n  hide(): void {\r\n    this.root?.remove()\r\n    this.root = null\r\n    this.target = null\r\n    this.columnIndex = null\n  }\r\n}\r\n","/**\r\n * TableWidget —— 表格交互 widget\r\n *\r\n * 从 Draw 分离的表格 UI 交互逻辑：\r\n *  - 表格选择手柄（左上角全选按钮）\r\n *  - 表格添加列按钮（右侧中间 + 号）\r\n *  - 表格右键上下文菜单\r\n *\r\n * 生命周期：create() → update() / showContextMenu() → destroy()\r\n */\r\n\r\nimport type { BlockNode, DocumentLayout, TableBlock } from '../layout-types'\r\nimport type { RangeManager } from '@vervedoc/docx-editor-state'\r\nimport type { IPosition } from '@vervedoc/docx-editor-schema'\r\nimport { ContextMenu, type MenuItem } from '../context-menu'\r\nimport { positionHandle } from './handle-position'\r\nimport { TablePropertiesWidget } from './layout/table-properties-widget'\r\nimport { viewText, viewTranslate, type ViewTranslate } from '../view-i18n'\r\n\r\n/** 边框热区半宽（像素），鼠标距离边框小于该值时视为命中边框可拖拽 */\r\nconst BORDER_HOT = 4\r\n\r\n/**\r\n * 表格边框拖拽状态\r\n *\r\n * 记录当前正在拖拽的列/行信息，用于拖拽过程中计算新尺寸。\r\n */\r\ninterface DragState {\r\n  /** 拖拽类型：列或行 */\r\n  type: 'col' | 'row'\r\n  /** 表格在父节点中的索引 */\r\n  tableIndex: number\r\n  /** 被拖拽边框对应的列/行索引 */\r\n  index: number\r\n  /** 拖拽起始时的客户端坐标（clientX 或 clientY） */\r\n  startClient: number\r\n  /** 拖拽起始时该列/行的原始尺寸（像素） */\r\n  origSize: number\r\n}\r\n\r\n/**\r\n * TableWidget 的依赖注入接口\r\n *\r\n * 由外部宿主提供，用于获取编辑器布局、选区、容器信息以及触发命令等。\r\n */\r\nexport interface TableWidgetDeps {\r\n  translate?: ViewTranslate\r\n  /** Whether editing interactions are currently allowed. */\r\n  canEdit: () => boolean\r\n  /** 获取当前文档布局，可能为 null */\r\n  getLayout: () => DocumentLayout | null\r\n  /** 获取当前选区管理器，可能为 null */\r\n  getRange: () => RangeManager | null\r\n  /** 获取编辑器容器在视口中的矩形位置 */\r\n  getContainerRect: () => DOMRect\r\n  /** 获取当前垂直滚动偏移量（像素） */\r\n  getScrollY: () => number\r\n  /** 获取页面水平偏移量（像素） */\r\n  getPageOffsetX: () => number\r\n  /** 触发编辑器命令；getter 命令会同步返回属性值 */\n  onCommand: (cmd: string, ...args: any[]) => any\n  /** 根据客户端坐标命中测试，返回位置信息或 null */\r\n  hit: (clientX: number, clientY: number) => IPosition | null\r\n  /** 让编辑器输入区获取焦点 */\r\n  focusInput: () => void\r\n  /** 设置鼠标光标样式 */\r\n  setCursor: (cursor: string) => void\r\n}\r\n\r\n/**\r\n * 表格交互 widget\r\n *\r\n * 提供表格选择手柄、添加列/行按钮、右键上下文菜单以及边框拖拽调整列宽行高功能。\r\n */\r\nexport class TableWidget {\r\n  /** 表格左上角的全选手柄 DOM 元素 */\r\n  private handle: HTMLDivElement | null = null\r\n  /** 表格右侧中间的添加列手柄 DOM 元素 */\r\n  private addColHandle: HTMLDivElement | null = null\r\n  /** 表格底部中间的添加行手柄 DOM 元素 */\r\n  private addRowHandle: HTMLDivElement | null = null\r\n  /** 右键上下文菜单实例 */\r\n  private contextMenu: ContextMenu\r\n  /** 当前边框拖拽状态，未拖拽时为 null */\r\n  private dragState: DragState | null = null\r\n  /** 标记光标样式是否已被修改，用于在离开边框时恢复 */\r\n  private cursorChanged = false\r\n\r\n  /**\r\n   * 构造 TableWidget 实例\r\n   *\r\n   * @param deps 依赖注入对象\r\n   */\r\n  private panel: TablePropertiesWidget\r\n\r\n  constructor(private deps: TableWidgetDeps) {\r\n    this.contextMenu = new ContextMenu(deps.translate)\r\n    this.panel = new TablePropertiesWidget({\r\n      onCommand: (cmd, ...args) => {\r\n        if (!this.deps.canEdit()) return undefined\n        return this.deps.onCommand(cmd, ...args)\n      },\r\n      focusInput: () => this.deps.focusInput(),\r\n      translate: deps.translate\r\n    })\r\n  }\r\n\r\n  refreshTranslations(): void {\r\n    this.contextMenu.hide()\r\n    for (const [el, key] of [[this.handle, 'select'], [this.addColHandle, 'addColumn'], [this.addRowHandle, 'addRow']] as const) {\r\n      if (!el) continue\r\n      el.title = viewTranslate(this.deps.translate, `view.table.${key}`)\r\n      el.setAttribute('aria-label', el.title)\r\n    }\r\n    this.panel.refreshTranslations()\r\n  }\r\n\r\n  /* -------------------- 创建 -------------------- */\r\n\r\n  /**\r\n   * 创建表格交互所需的全部手柄 DOM 并挂载到 document.body\r\n   */\r\n  create(): void {\r\n    this.handle = this.createHandle()\r\n    this.addColHandle = this.createAddColHandle()\r\n    this.addRowHandle = this.createAddRowHandle()\r\n  }\r\n\r\n  /**\r\n   * 创建表格左上角全选手柄\r\n   *\r\n   * @returns 创建并挂载好的手柄 DOM 元素\r\n   */\r\n  private createHandle(): HTMLDivElement {\r\n    const el = document.createElement('div')\r\n    el.className = 'vervedocs-table-handle'\r\n    el.title = viewTranslate(this.deps.translate, 'view.table.select')\r\n    el.setAttribute('aria-label', el.title)\r\n    const icon = document.createElement('span')\r\n    icon.className = 'material-symbols-outlined'\r\n    icon.textContent = 'drag_indicator'\r\n    icon.style.cssText = 'font-size:16px;color:#606266;'\r\n    el.appendChild(icon)\r\n    Object.assign(el.style, {\r\n      position: 'fixed',\r\n      width: '24px',\r\n      height: '24px',\r\n      background: '#fff',\r\n      border: '1px solid #dcdfe6',\r\n      borderRadius: '3px',\r\n      display: 'none',\r\n      zIndex: '100',\r\n      cursor: 'pointer',\r\n      alignItems: 'center',\r\n      justifyContent: 'center',\r\n      color: '#606266',\r\n      boxShadow: '0 1px 4px rgba(0,0,0,.15)'\r\n    } as CSSStyleDeclaration)\r\n    el.addEventListener('mousedown', (e) => {\r\n      e.preventDefault()\r\n      e.stopPropagation()\r\n      if (!this.deps.canEdit()) return\r\n      this.deps.onCommand('executeSelectTable')\r\n    })\r\n    document.body.appendChild(el)\r\n    return el\r\n  }\r\n\r\n  /**\r\n   * 创建表格右侧中间的添加列手柄\r\n   *\r\n   * @returns 创建并挂载好的手柄 DOM 元素\r\n   */\r\n  private createAddColHandle(): HTMLDivElement {\r\n    const el = document.createElement('div')\r\n    el.className = 'vervedocs-table-add-col'\r\n    el.title = viewTranslate(this.deps.translate, 'view.table.addColumn')\r\n    el.setAttribute('aria-label', el.title)\r\n    const icon = document.createElement('span')\r\n    icon.className = 'material-symbols-outlined'\r\n    icon.textContent = 'add'\r\n    icon.style.cssText = 'font-size:16px;color:#606266;'\r\n    el.appendChild(icon)\r\n    Object.assign(el.style, {\r\n      position: 'fixed',\r\n      width: '24px',\r\n      height: '24px',\r\n      background: '#fff',\r\n      border: '1px solid #dcdfe6',\r\n      borderRadius: '3px',\r\n      display: 'none',\r\n      zIndex: '100',\r\n      cursor: 'pointer',\r\n      alignItems: 'center',\r\n      justifyContent: 'center',\r\n      color: '#606266',\r\n      boxShadow: '0 1px 4px rgba(0,0,0,.15)'\r\n    } as CSSStyleDeclaration)\r\n    el.addEventListener('mouseenter', () => {\r\n      el.style.background = '#409eff'\r\n      el.style.color = '#fff'\r\n      el.style.borderColor = '#409eff'\r\n    })\r\n    el.addEventListener('mouseleave', () => {\r\n      el.style.background = '#fff'\r\n      el.style.color = '#606266'\r\n      el.style.borderColor = '#dcdfe6'\r\n    })\r\n    el.addEventListener('mousedown', (e) => {\r\n      e.preventDefault()\r\n      e.stopPropagation()\r\n      if (!this.deps.canEdit()) return\r\n      this.deps.onCommand('executeInsertTableCol', 'right')\r\n    })\r\n    document.body.appendChild(el)\r\n    return el\r\n  }\r\n\r\n  /**\r\n   * 创建表格底部中间的添加行手柄\r\n   *\r\n   * @returns 创建并挂载好的手柄 DOM 元素\r\n   */\r\n  private createAddRowHandle(): HTMLDivElement {\r\n    const el = document.createElement('div')\r\n    el.className = 'vervedocs-table-add-row'\r\n    el.title = viewTranslate(this.deps.translate, 'view.table.addRow')\r\n    el.setAttribute('aria-label', el.title)\r\n    const icon = document.createElement('span')\r\n    icon.className = 'material-symbols-outlined'\r\n    icon.textContent = 'add'\r\n    icon.style.cssText = 'font-size:16px;color:#606266;'\r\n    el.appendChild(icon)\r\n    Object.assign(el.style, {\r\n      position: 'fixed',\r\n      width: '24px',\r\n      height: '24px',\r\n      background: '#fff',\r\n      border: '1px solid #dcdfe6',\r\n      borderRadius: '3px',\r\n      display: 'none',\r\n      zIndex: '100',\r\n      cursor: 'pointer',\r\n      alignItems: 'center',\r\n      justifyContent: 'center',\r\n      color: '#606266',\r\n      boxShadow: '0 1px 4px rgba(0,0,0,.15)'\r\n    } as CSSStyleDeclaration)\r\n    el.addEventListener('mouseenter', () => {\r\n      el.style.background = '#409eff'\r\n      el.style.color = '#fff'\r\n      el.style.borderColor = '#409eff'\r\n    })\r\n    el.addEventListener('mouseleave', () => {\r\n      el.style.background = '#fff'\r\n      el.style.color = '#606266'\r\n      el.style.borderColor = '#dcdfe6'\r\n    })\r\n    el.addEventListener('mousedown', (e) => {\r\n      e.preventDefault()\r\n      e.stopPropagation()\r\n      if (!this.deps.canEdit()) return\r\n      this.deps.onCommand('executeInsertTableRow', 'below')\r\n    })\r\n    document.body.appendChild(el)\r\n    return el\r\n  }\r\n\r\n  /* -------------------- 更新手柄位置 -------------------- */\r\n\r\n  /**\r\n   * 根据当前选区更新手柄位置\r\n   *\r\n   * 当光标位于表格内时，显示全选、添加列、添加行手柄；否则隐藏全部手柄。\r\n   */\r\n  update(): void {\r\n    if (!this.deps.canEdit()) { this.resetInteraction(); return }\r\n    if (!this.handle) return\r\n    for (const [el, key] of [[this.handle, 'select'], [this.addColHandle, 'addColumn'], [this.addRowHandle, 'addRow']] as const) {\r\n      if (!el) continue\r\n      el.title = viewTranslate(this.deps.translate, `view.table.${key}`)\r\n      el.setAttribute('aria-label', el.title)\r\n    }\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) { this.hideHandles(); return }\r\n\r\n    const pos = range.getFocus()\r\n    const isTable = pos && pos.path.length >= 5 && pos.path[1] === 'trList'\r\n    if (!isTable) {\r\n      this.hideHandles()\r\n      return\r\n    }\r\n\r\n    const tableIndex = pos!.path[0] as number\r\n    // Match the focused cell so a paginated table uses the correct fragment.\r\n    const matchesTable = (b: BlockNode) =>\r\n      b.kind === 'table' && b.indexInParent === tableIndex &&\r\n      b.rows.some(row => row.cells.some(cell =>\r\n        cell.cellPath.every((part, index) => part === pos!.path[index])))\r\n    const page = layout.pages.find(p =>\r\n      p.blocks.some(matchesTable)\r\n    )\r\n    if (!page) { this.hideHandles(); return }\r\n\r\n    const block = page.blocks.find(matchesTable)\r\n    if (!block || block.kind !== 'table') { this.hideHandles(); return }\r\n\r\n    const rect = this.deps.getContainerRect()\r\n    const pageOffsetX = this.deps.getPageOffsetX()\r\n    const scrollY = this.deps.getScrollY()\r\n    const tableX = rect.left + pageOffsetX + page.contentRect.x + block.rect.x\r\n    const tableY = rect.top - scrollY + page.contentRect.y + block.rect.y\r\n    if (tableX + block.rect.width <= rect.left || tableX >= rect.right ||\r\n        tableY + block.rect.height <= rect.top || tableY >= rect.bottom) {\r\n      this.hideHandles()\r\n      return\r\n    }\r\n    positionHandle(this.handle, tableX - 31, tableY - 25, 24, rect)\r\n\r\n    if (this.addColHandle) {\r\n      const colX = tableX + block.rect.width + 4\r\n      const colY = tableY + block.rect.height / 2 - 12\r\n      positionHandle(this.addColHandle, colX, colY, 24, rect)\r\n    }\r\n\r\n    if (this.addRowHandle) {\r\n      const rowX = tableX + block.rect.width / 2 - 12\r\n      const rowY = tableY + block.rect.height + 4\r\n      positionHandle(this.addRowHandle, rowX, rowY, 24, rect)\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 隐藏全部手柄\r\n   */\r\n  private hideHandles(): void {\r\n    if (this.handle) this.handle.style.display = 'none'\r\n    if (this.addColHandle) this.addColHandle.style.display = 'none'\r\n    if (this.addRowHandle) this.addRowHandle.style.display = 'none'\r\n  }\r\n\r\n  private resetInteraction(): void {\r\n    this.hideHandles()\r\n    this.hideContextMenu()\r\n    this.panel.hide()\r\n    if (this.dragState || this.cursorChanged) this.deps.setCursor('default')\r\n    this.dragState = null\r\n    this.cursorChanged = false\r\n  }\r\n\r\n  /* -------------------- 右键菜单 -------------------- */\r\n\r\n  /**\r\n   * 在指定客户端坐标处显示表格右键上下文菜单\r\n   *\r\n   * 菜单保留结构性操作；格式设置集中在表格属性弹框内。\n   *\r\n   * @param clientX 客户端横坐标\r\n   * @param clientY 客户端纵坐标\r\n   * @returns 命中表格并显示菜单返回 true，否则返回 false\r\n   */\r\n  showContextMenu(clientX: number, clientY: number): boolean {\r\n    if (!this.deps.canEdit()) return false\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) return false\r\n\r\n    const pos = this.deps.hit(clientX, clientY)\r\n    if (!pos) return false\r\n\r\n    const isTable = pos.path.length >= 5 && pos.path[1] === 'trList'\r\n    if (!isTable) return false\r\n\r\n    const selected = range.getRange()\r\n    const inSameTable = selected && [selected.anchor, selected.focus].every(p =>\r\n      p.path[0] === pos.path[0] && p.path[1] === 'trList'\r\n    )\r\n    const insideSelection = inSameTable &&\r\n      Number(pos.path[2]) >= Math.min(Number(selected.anchor.path[2]), Number(selected.focus.path[2])) &&\r\n      Number(pos.path[2]) <= Math.max(Number(selected.anchor.path[2]), Number(selected.focus.path[2])) &&\r\n      Number(pos.path[4]) >= Math.min(Number(selected.anchor.path[4]), Number(selected.focus.path[4])) &&\r\n      Number(pos.path[4]) <= Math.max(Number(selected.anchor.path[4]), Number(selected.focus.path[4]))\r\n    if (!insideSelection) range.setCaret(pos)\r\n    this.deps.focusInput()\r\n\r\n    const icons = ContextMenu.getIcons()\r\n    const fire = (cmd: string, ...args: any[]) => {\r\n      if (this.deps.canEdit()) this.deps.onCommand(cmd, ...args)\r\n    }\r\n    const textDirection = String(this.deps.onCommand('getCellProperties', pos)?.textDirection ?? '').toLowerCase()\n    const hasExplicitDirection = Boolean(textDirection)\n    const isVerticalText = textDirection.startsWith('tb') || textDirection.startsWith('bt') || textDirection.endsWith('v')\n\r\n    const items: MenuItem[] = [\r\n      {\r\n        label: '插入',\r\n        icon: icons.insertRowAbove,\r\n        submenu: [\r\n          { label: '在左侧插入', icon: icons.insertColLeft, input: { defaultValue: 1, unit: '列', min: 1, max: 50 }, onClick: (v) => fire('executeInsertTableCol', 'left', v ?? 1) },\r\n          { label: '在右侧插入', icon: icons.insertColRight, input: { defaultValue: 1, unit: '列', min: 1, max: 50 }, onClick: (v) => fire('executeInsertTableCol', 'right', v ?? 1) },\r\n          { label: '在上方插入', icon: icons.insertRowAbove, input: { defaultValue: 1, unit: '行', min: 1, max: 50 }, onClick: (v) => fire('executeInsertTableRow', 'above', v ?? 1) },\r\n          { label: '在下方插入', icon: icons.insertRowBelow, input: { defaultValue: 1, unit: '行', min: 1, max: 50 }, onClick: (v) => fire('executeInsertTableRow', 'below', v ?? 1) },\r\n          { label: '---' },\r\n          { label: '单元格(E)...', onClick: () => fire('executeInsertTableCell') },\r\n        ]\r\n      },\r\n      {\r\n        label: '删除',\r\n        icon: icons.deleteRow,\r\n        danger: true,\r\n        submenu: [\r\n          { label: '删除行', icon: icons.deleteRow, danger: true, onClick: () => fire('executeDeleteTableRow') },\r\n          { label: '删除列', icon: icons.deleteCol, danger: true, onClick: () => fire('executeDeleteTableCol') },\r\n          { label: '---' },\r\n          { label: '删除整个表格', icon: icons.deleteTable, danger: true, onClick: () => fire('executeDeleteTable') },\r\n        ]\r\n      },\r\n      { label: '合并单元格', icon: icons.mergeCell, onClick: () => fire('executeMergeTableCells') },\n      { label: '全选表格', icon: icons.selectAll, onClick: () => fire('executeSelectTable') },\n      { label: '拆分单元格', icon: icons.splitCell, onClick: () => fire('executeSplitTableCell') },\n      {\n        label: '边框样式',\n        icon: icons.borderStyle,\n        submenu: [\n          { label: '全部边框', icon: icons.borderStyle, onClick: () => fire('executeSetTableBorders', { type: 'all' }) },\n          { label: '外侧边框', icon: icons.borderStyle, onClick: () => fire('executeSetTableBorders', { type: 'outside' }) },\n          { label: '无边框', icon: icons.borderStyle, onClick: () => fire('executeSetTableBorders', { type: 'none' }) },\n          { label: '内部边框', icon: icons.borderStyle, onClick: () => fire('executeSetTableBorders', { type: 'inside' }) },\n          { label: '内部横线', icon: icons.borderStyle, onClick: () => fire('executeSetTableBorders', { type: 'inside-horizontal' }) },\n          { label: '内部竖线', icon: icons.borderStyle, onClick: () => fire('executeSetTableBorders', { type: 'inside-vertical' }) },\n        ]\n      },\n      { label: '---' },\n      {\n        label: '文字方向',\n        icon: icons.textDirection,\n        submenu: [\n          {\n            label: '横排',\n            icon: hasExplicitDirection && !isVerticalText ? icons.check : icons.horizontalText,\n            onClick: () => fire('executeSetCellTextDirection', 'lrTb', pos)\n          },\n          {\n            label: '竖排',\n            icon: hasExplicitDirection && isVerticalText ? icons.check : icons.verticalText,\n            onClick: () => fire('executeSetCellTextDirection', 'tbRlV', pos)\n          },\n        ]\n      },\n      { label: '---' },\r\n      { label: '表格属性...', icon: icons.tableProp, onClick: () => { if (this.deps.canEdit()) this.panel.show(pos) } },\n    ]\r\n\r\n    const labels = new Map(Object.entries(viewText)\r\n      .filter(([key]) => key.startsWith('view.table.') || key.startsWith('view.common.'))\n      .map(([key, text]) => [text, key]))\r\n    const localize = (menu: MenuItem[]) => menu.forEach(item => {\r\n      const key = labels.get(item.label)\r\n      if (key) item.label = viewTranslate(this.deps.translate, key)\r\n      if (item.input) {\r\n        const unitKey = labels.get(item.input.unit)\r\n        if (unitKey) item.input.unit = viewTranslate(this.deps.translate, unitKey)\r\n      }\r\n      if (item.submenu) localize(item.submenu)\r\n    })\r\n    localize(items)\r\n    this.contextMenu.show(clientX, clientY, items)\r\n    return true\r\n  }\r\n\r\n  /**\r\n   * 隐藏右键上下文菜单\r\n   */\r\n  hideContextMenu(): void {\r\n    this.contextMenu.hide()\r\n  }\r\n\r\n  /* -------------------- 边框拖拽 -------------------- */\r\n\r\n  /**\r\n   * 根据屏幕坐标查找命中的表格块\r\n   *\r\n   * @param clientX 客户端横坐标\r\n   * @param clientY 客户端纵坐标\r\n   * @returns 命中的表格块及其屏幕起点坐标，未命中返回 null\r\n   */\r\n  private findTableAtScreen(clientX: number, clientY: number): { block: TableBlock; screenX: number; screenY: number } | null {\r\n    const layout = this.deps.getLayout()\r\n    if (!layout) return null\r\n    const rect = this.deps.getContainerRect()\r\n    const scrollY = this.deps.getScrollY()\r\n    const pageOffsetX = this.deps.getPageOffsetX()\r\n\r\n    for (const page of layout.pages) {\r\n      for (const b of page.blocks) {\r\n        if (b.kind !== 'table') continue\r\n        const sx = rect.left + pageOffsetX + page.contentRect.x + b.rect.x\r\n        const sy = rect.top - scrollY + page.contentRect.y + b.rect.y\r\n        if (clientX >= sx && clientX <= sx + b.rect.width && clientY >= sy && clientY <= sy + b.rect.height) {\r\n          return { block: b, screenX: sx, screenY: sy }\r\n        }\r\n      }\r\n    }\r\n    return null\r\n  }\r\n\r\n  /**\r\n   * 检测指定坐标是否命中表格边框（列边框或行边框）\r\n   *\r\n   * @param clientX 客户端横坐标\r\n   * @param clientY 客户端纵坐标\r\n   * @returns 命中边框时返回类型、索引、原始尺寸和表格索引，否则返回 null\r\n   */\r\n  private detectBorder(clientX: number, clientY: number): { type: 'col' | 'row'; index: number; origSize: number; tableIndex: number } | null {\r\n    const info = this.findTableAtScreen(clientX, clientY)\r\n    if (!info) return null\r\n    const { block, screenX, screenY } = info\r\n\r\n    for (let i = 0; i < block.colWidths.length; i++) {\r\n      const borderX = screenX + block.colWidths.slice(0, i + 1).reduce((a, b) => a + b, 0)\r\n      if (Math.abs(clientX - borderX) <= BORDER_HOT) {\r\n        return { type: 'col', index: i, origSize: block.colWidths[i], tableIndex: block.indexInParent }\r\n      }\r\n    }\r\n\r\n    for (let i = 0; i < block.rows.length; i++) {\r\n      const row = block.rows[i]\r\n      const borderY = screenY + row.rect.y + row.rect.height\r\n      if (Math.abs(clientY - borderY) <= BORDER_HOT) {\r\n        return { type: 'row', index: i, origSize: row.rect.height, tableIndex: block.indexInParent }\r\n      }\r\n    }\r\n\r\n    return null\r\n  }\r\n\r\n  /**\r\n   * 处理鼠标按下事件，若命中表格边框则进入拖拽状态\r\n   *\r\n   * @param e 鼠标事件\r\n   * @returns 命中边框并进入拖拽返回 true，否则返回 false\r\n   */\r\n  handleMouseDown(e: MouseEvent): boolean {\r\n    if (!this.deps.canEdit()) { this.resetInteraction(); return false }\r\n    if (this.dragState) return true\r\n    const border = this.detectBorder(e.clientX, e.clientY)\r\n    if (!border) return false\r\n    e.preventDefault()\r\n    e.stopPropagation()\r\n    this.dragState = {\r\n      type: border.type,\r\n      tableIndex: border.tableIndex,\r\n      index: border.index,\r\n      startClient: border.type === 'col' ? e.clientX : e.clientY,\r\n      origSize: border.origSize\r\n    }\r\n    this.deps.setCursor(border.type === 'col' ? 'col-resize' : 'row-resize')\r\n    return true\r\n  }\r\n\r\n  /**\r\n   * 处理鼠标移动事件\r\n   *\r\n   * 拖拽中：根据偏移量计算并应用新的列宽/行高；\r\n   * 非拖拽：检测是否悬停在边框上以更新光标样式。\r\n   *\r\n   * @param e 鼠标事件\r\n   */\r\n  handleMouseMove(e: MouseEvent): boolean {\r\n    if (!this.deps.canEdit()) { this.resetInteraction(); return false }\r\n    if (this.dragState) {\r\n      e.preventDefault()\r\n      const delta = this.dragState.type === 'col' ? e.clientX - this.dragState.startClient : e.clientY - this.dragState.startClient\r\n      const newSize = Math.max(20, this.dragState.origSize + delta)\r\n      if (this.dragState.type === 'col') {\r\n        this.deps.onCommand('executeSetTableColWidth', this.dragState.tableIndex, this.dragState.index, newSize)\r\n      } else {\r\n        this.deps.onCommand('executeSetTableRowHeight', this.dragState.tableIndex, this.dragState.index, newSize)\r\n      }\r\n      return true\r\n    }\r\n\r\n    const border = this.detectBorder(e.clientX, e.clientY)\r\n    if (border) {\r\n      this.deps.setCursor(border.type === 'col' ? 'col-resize' : 'row-resize')\r\n      this.cursorChanged = true\r\n      return true\r\n    } else if (this.cursorChanged) {\r\n      this.deps.setCursor('default')\r\n      this.cursorChanged = false\r\n    }\r\n    return false\r\n  }\r\n\r\n  /**\r\n   * 处理鼠标释放事件，结束边框拖拽并恢复光标\r\n   *\r\n   * @param _e 鼠标事件（未使用）\r\n   */\r\n  handleMouseUp(_e: MouseEvent): void {\r\n    if (!this.dragState) return\r\n    this.dragState = null\r\n    this.deps.setCursor('default')\r\n    this.cursorChanged = false\r\n  }\r\n\r\n  /* -------------------- 销毁 -------------------- */\r\n\r\n  /**\r\n   * 销毁 widget，隐藏手柄和菜单并移除所有手柄 DOM\r\n   */\r\n  destroy(): void {\r\n    this.panel.hide()\r\n    this.hideHandles()\r\n    this.hideContextMenu()\r\n    if (this.handle) { this.handle.remove(); this.handle = null }\r\n    if (this.addColHandle) { this.addColHandle.remove(); this.addColHandle = null }\r\n    if (this.addRowHandle) { this.addRowHandle.remove(); this.addRowHandle = null }\r\n  }\r\n}\r\n","import type { Rect } from '../layout-types'\r\n\r\n/** Keep selection chrome clipped to the same viewport as the document canvas. */\r\nexport function createSelectionLayer(container: HTMLElement, name: string): HTMLDivElement {\r\n  const layer = document.createElement('div')\r\n  layer.className = `vervedocs-${name}-selection-layer`\r\n  layer.style.cssText = 'position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:100;display:none;'\r\n  container.appendChild(layer)\r\n  return layer\r\n}\r\n\r\nexport function updateSelectionLayer(\r\n  layer: HTMLElement,\r\n  bounds: Rect,\r\n  viewport: Pick<Rect, 'width' | 'height'>\r\n): boolean {\r\n  const visible = bounds.x < viewport.width && bounds.y < viewport.height &&\r\n    bounds.x + bounds.width > 0 && bounds.y + bounds.height > 0\r\n  layer.style.display = visible ? 'block' : 'none'\r\n  return visible\r\n}\r\n\r\n/** Place the toolbar beside the object only when it fits inside the editor. */\r\nexport function positionSelectionToolbar(toolbar: HTMLElement, bounds: Rect, layer: HTMLElement): void {\r\n  const padding = 4\r\n  const gap = 6\r\n  toolbar.style.display = 'flex'\r\n  toolbar.style.maxWidth = `${Math.max(0, layer.clientWidth - padding * 2)}px`\r\n  const width = toolbar.offsetWidth\r\n  const height = toolbar.offsetHeight\r\n  const x = Math.max(padding, Math.min(\r\n    bounds.x + bounds.width / 2 - width / 2,\r\n    layer.clientWidth - width - padding\r\n  ))\r\n  let y = bounds.y - height - gap\r\n  if (y < padding) y = bounds.y + bounds.height + gap\r\n  if (y < padding || y + height > layer.clientHeight - padding) {\r\n    toolbar.style.display = 'none'\r\n    return\r\n  }\r\n  toolbar.style.left = `${Math.round(x)}px`\r\n  toolbar.style.top = `${Math.round(y)}px`\r\n}\r\n","/**\r\n * ImageWidget —— 图片交互 widget\r\n *\r\n * 从 Draw 分离的图片 UI 交互逻辑：\r\n *  - 点击图片选中（高亮边框 + 八方向缩放手柄）\r\n *  - 拖拽手柄缩放图片\r\n *  - 悬浮工具栏（删除、重置大小、对齐方式、替换图片）\r\n *\r\n * 生命周期：create() → handleMouseDown() / update() → destroy()\r\n */\r\n\r\nimport type { DocumentLayout, ImageBlock } from '../layout-types'\r\nimport type { IImageElement, Path } from '@vervedoc/docx-editor-schema'\nimport { createSelectionLayer, positionSelectionToolbar, updateSelectionLayer } from './selection-layer'\r\n\r\n\r\n/**\r\n * ImageWidget 的依赖注入接口\r\n *\r\n * 由外部宿主提供，用于获取编辑器布局、容器信息以及触发命令等。\r\n */\r\nexport interface ImageWidgetDeps {\r\n  /** 选框裁剪层的挂载容器 */\r\n  getContainer: () => HTMLElement\r\n  /** 获取当前文档布局，可能为 null */\r\n  getLayout: () => DocumentLayout | null\r\n  /** 获取编辑器容器在视口中的矩形位置 */\r\n  getContainerRect: () => DOMRect\r\n  /** 获取当前垂直滚动偏移量（像素） */\r\n  getScrollY: () => number\r\n  /** 获取页面水平偏移量（像素） */\r\n  getPageOffsetX: () => number\r\n  /** 触发编辑器命令的回调 */\r\n  onCommand: (cmd: string, ...args: any[]) => void\r\n  /** 拖拽过程中实时更新图片尺寸的回调（不写入文档，仅刷新显示） */\r\n  onUpdateImageSizeLive: (path: Path, width: number, height: number) => void\r\n}\r\n\r\n/**\r\n * 当前选中的图片信息\r\n *\r\n * 记录选中图片的路径、块数据以及所在页面的屏幕起点坐标，用于定位选中框和手柄。\r\n */\r\ninterface ImageSelection {\r\n  /** 图片在文档中的路径 */\r\n  path: Path\r\n  /** 图片块数据 */\r\n  block: ImageBlock\r\n  /** 图片所在页面的屏幕起点横坐标（像素） */\r\n  pageOriginX: number\r\n  /** 图片所在页面的屏幕起点纵坐标（像素） */\r\n  pageOriginY: number\r\n}\r\n\r\n/** 缩放手柄边长（像素） */\r\nconst HANDLE_SIZE = 8\r\n/** 缩放手柄中心偏移量（像素），用于将手柄中心对齐到图片边缘 */\r\nconst HANDLE_OFFSET = HANDLE_SIZE / 2\r\n/** 八方向缩放手柄的位置定义，x/y 为 0~1 的比例坐标 */\r\nconst HANDLES = [\r\n  { dir: 'nw', x: 0, y: 0 },\r\n  { dir: 'n', x: 0.5, y: 0 },\r\n  { dir: 'ne', x: 1, y: 0 },\r\n  { dir: 'e', x: 1, y: 0.5 },\r\n  { dir: 'se', x: 1, y: 1 },\r\n  { dir: 's', x: 0.5, y: 1 },\r\n  { dir: 'sw', x: 0, y: 1 },\r\n  { dir: 'w', x: 0, y: 0.5 },\r\n] as const\r\n\r\n/**\r\n * 图片交互 widget\r\n *\r\n * 提供图片选中高亮、八方向缩放手柄、悬浮工具栏（重置大小、旋转、对齐、\r\n * 环绕方式、替换、保存、删除等）以及拖拽缩放功能。\r\n */\r\nexport class ImageWidget {\r\n  private selectionLayer: HTMLDivElement | null = null\r\n  /** 选中高亮边框 DOM 元素 */\r\n  private selectionBox: HTMLDivElement | null = null\r\n  /** 八方向缩放手柄 DOM 元素数组 */\r\n  private handleEls: HTMLDivElement[] = []\r\n  /** 悬浮工具栏 DOM 元素 */\r\n  private toolbar: HTMLDivElement | null = null\r\n  /** 当前选中的图片信息，未选中时为 null */\r\n  private selection: ImageSelection | null = null\r\n\r\n  /** 拖拽缩放状态，未拖拽时为 null */\r\n  private dragging: { dir: string; startX: number; startY: number; origW: number; origH: number; lastW: number; lastH: number } | null = null\r\n\r\n  /**\r\n   * 构造 ImageWidget 实例\r\n   *\r\n   * @param deps 依赖注入对象\r\n   */\r\n  constructor(private deps: ImageWidgetDeps) {}\r\n\r\n  /**\r\n   * 创建选中框、八方向缩放手柄和悬浮工具栏，统一挂载到编辑区裁剪层\r\n   */\r\n  create(): void {\r\n    this.selectionLayer = createSelectionLayer(this.deps.getContainer(), 'image')\r\n    this.selectionBox = document.createElement('div')\r\n    this.selectionBox.style.cssText = 'position:absolute;border:1.5px solid #409eff;pointer-events:none;z-index:100;box-sizing:border-box;'\r\n    this.selectionLayer.appendChild(this.selectionBox)\r\n\r\n    for (const h of HANDLES) {\r\n      const el = document.createElement('div')\r\n      el.dataset.dir = h.dir\r\n      el.style.cssText = `position:absolute;pointer-events:auto;width:${HANDLE_SIZE}px;height:${HANDLE_SIZE}px;background:#fff;border:1.5px solid #409eff;border-radius:50%;z-index:101;cursor:${this.cursorFor(h.dir)};box-sizing:border-box;`\r\n      el.addEventListener('mousedown', (e) => this.onHandleMouseDown(e, h.dir))\r\n      this.selectionLayer.appendChild(el)\r\n      this.handleEls.push(el)\r\n    }\r\n\r\n    this.toolbar = this.createToolbar()\r\n    this.selectionLayer.appendChild(this.toolbar)\r\n  }\r\n\r\n  /**\r\n   * 根据手柄方向返回对应的鼠标光标样式\r\n   *\r\n   * @param dir 手柄方向（nw/n/ne/e/se/s/sw/w）\r\n   * @returns 对应的 CSS 光标样式\r\n   */\r\n  private cursorFor(dir: string): string {\r\n    const map: Record<string, string> = {\r\n      nw: 'nwse-resize', n: 'ns-resize', ne: 'nesw-resize', e: 'ew-resize',\r\n      se: 'nwse-resize', s: 'ns-resize', sw: 'nesw-resize', w: 'ew-resize',\r\n    }\r\n    return map[dir] || 'default'\r\n  }\r\n\r\n  /**\r\n   * 创建图片悬浮工具栏\r\n   *\r\n   * 工具栏包含重置大小、旋转、预览、对齐方式、环绕方式、替换、保存、删除等按钮。\r\n   *\r\n   * @returns 创建好的工具栏 DOM 元素\r\n   */\r\n  private createToolbar(): HTMLDivElement {\r\n    const bar = document.createElement('div')\r\n    bar.style.cssText = 'position:absolute;pointer-events:auto;box-sizing:border-box;overflow-x:auto;display:none;z-index:102;background:#f5f5f5;border-radius:6px;box-shadow:0 2px 8px rgba(0,0,0,0.15);padding:4px 6px;align-items:center;gap:2px;font-family:sans-serif;'\r\n\r\n    const mkBtn = (icon: string, title: string, action: string, onClick: () => void): HTMLButtonElement => {\n      const btn = document.createElement('button')\r\n      btn.title = title\r\n      btn.dataset.imageAction = action\n      btn.style.cssText = 'border:none;background:transparent;cursor:pointer;padding:5px;border-radius:4px;display:flex;align-items:center;justify-content:center;transition:background .15s;'\r\n      const sp = document.createElement('span')\r\n      sp.className = 'material-symbols-outlined'\r\n      sp.textContent = icon\r\n      sp.style.cssText = 'font-size:18px;color:#333;'\r\n      btn.appendChild(sp)\r\n      btn.addEventListener('mouseenter', () => { btn.style.background = '#e0e0e0' })\r\n      btn.addEventListener('mouseleave', () => { btn.style.background = 'transparent' })\r\n      btn.addEventListener('mousedown', (e) => { e.preventDefault(); e.stopPropagation() })\r\n      btn.addEventListener('click', (e) => { e.preventDefault(); e.stopPropagation(); onClick() })\r\n      return btn\r\n    }\r\n    const mkSep = (): HTMLDivElement => {\n      const sep = document.createElement('div')\r\n      sep.dataset.imageAction = 'separator'\n      sep.style.cssText = 'width:1px;height:20px;background:#ccc;margin:0 3px;'\r\n      return sep\r\n    }\r\n\r\n    bar.appendChild(mkBtn('restore', '重置大小', 'resize', () => this.fire('executeResetImageSize')))\n    bar.appendChild(mkBtn('rotate_right', '旋转 90°', 'rotate', () => this.fire('executeRotateImage')))\n    bar.appendChild(mkBtn('zoom_in', '预览', 'preview', () => this.showPreview()))\n    bar.appendChild(mkSep())\r\n    bar.appendChild(mkBtn('format_align_left', '左对齐', 'align', () => this.fire('executeImageAlign', 'left')))\n    bar.appendChild(mkBtn('format_align_center', '居中对齐', 'align', () => this.fire('executeImageAlign', 'center')))\n    bar.appendChild(mkBtn('format_align_right', '右对齐', 'align', () => this.fire('executeImageAlign', 'right')))\n    bar.appendChild(mkSep())\r\n    bar.appendChild(mkBtn('wrap_text', '文字环绕', 'wrap', () => this.fire('executeImageWrap', 'surround')))\n    bar.appendChild(mkBtn('flip_to_front', '浮于文字上方', 'wrap', () => this.fire('executeImageWrap', 'float-top')))\n    bar.appendChild(mkBtn('flip_to_back', '浮于文字下方', 'wrap', () => this.fire('executeImageWrap', 'float-bottom')))\n    bar.appendChild(mkSep())\r\n    bar.appendChild(mkBtn('image', '替换图片', 'replace', () => this.fire('executeReplaceImage')))\n    bar.appendChild(mkBtn('download', '保存图片', 'save', () => this.fire('executeSaveImage')))\n    const delBtn = mkBtn('delete', '删除图片', 'delete', () => this.fire('executeDeleteImage'))\n    const delIcon = delBtn.querySelector('.material-symbols-outlined') as HTMLElement\r\n    delBtn.addEventListener('mouseenter', () => { delIcon.style.color = '#e53935' })\r\n    delBtn.addEventListener('mouseleave', () => { delIcon.style.color = '#333' })\r\n    bar.appendChild(delBtn)\r\n\r\n    return bar\r\n  }\r\n\r\n  /**\r\n   * 触发针对当前选中图片的编辑器命令\r\n   *\r\n   * @param cmd 命令名称\r\n   * @param args 命令参数\r\n   */\r\n  private fire(cmd: string, ...args: any[]): void {\r\n    if (!this.selection) return\r\n    this.deps.onCommand(cmd, this.selection.path, ...args)\r\n  }\r\n\r\n  /**\r\n   * 显示图片预览遮罩层\r\n   *\r\n   * 创建全屏黑色遮罩并居中展示当前选中图片的原始大小，支持点击遮罩或按 Esc 关闭。\r\n   */\r\n  private showPreview(): void {\r\n    if (!this.selection) return\r\n    const src = String((this.selection.block.block as unknown as { value?: string }).value ?? '')\r\n    if (!src) return\r\n    const rotate = Number((this.selection.block.block as unknown as { rotate?: number }).rotate ?? 0) % 360\r\n\r\n    const overlay = document.createElement('div')\r\n    Object.assign(overlay.style, {\r\n      position: 'fixed', inset: '0', zIndex: '10000',\r\n      background: 'rgba(0,0,0,.75)',\r\n      display: 'flex', alignItems: 'center', justifyContent: 'center',\r\n      cursor: 'zoom-out'\r\n    } as CSSStyleDeclaration)\r\n\r\n    const img = document.createElement('img')\r\n    img.src = src\r\n    Object.assign(img.style, {\r\n      maxWidth: '90vw', maxHeight: '90vh',\r\n      objectFit: 'contain',\r\n      boxShadow: '0 8px 32px rgba(0,0,0,.5)',\r\n      borderRadius: '4px',\r\n      transform: `rotate(${rotate}deg)`\r\n    } as CSSStyleDeclaration)\r\n    overlay.appendChild(img)\r\n\r\n    const close = () => overlay.remove()\r\n    overlay.addEventListener('mousedown', (e) => { if (e.target === overlay) close() })\r\n    const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') { close(); document.removeEventListener('keydown', onKey) } }\r\n    document.addEventListener('keydown', onKey)\r\n    document.body.appendChild(overlay)\r\n  }\r\n\r\n\r\n  /**\r\n   * 处理 mousedown，返回 true 表示点击了图片（已拦截），false 表示未处理\r\n   *\r\n   * @param e 鼠标事件\r\n   * @returns 点击命中图片返回 true，否则返回 false\r\n   */\r\n  handleMouseDown(e: MouseEvent): boolean {\r\n    this.clearSelection()\r\n    const hit = this.findImageAt(e.clientX, e.clientY)\r\n    if (!hit) return false\r\n\r\n    e.preventDefault()\r\n    e.stopPropagation()\r\n    this.selectImage(hit)\r\n    return true\r\n  }\r\n\r\n  /** 艺术字仅响应删除键，其他图片继续沿用原有键盘行为。 */\n  handleKeyDown(e: KeyboardEvent): boolean {\n    if (!this.selection || !(this.selection.block.block as IImageElement).imgToolDisabled) return false\n    if (e.key !== 'Backspace' && e.key !== 'Delete') return false\n    e.preventDefault()\n    e.stopPropagation()\n    this.fire('executeDeleteImage')\n    return true\n  }\n\n  /**\r\n   * 根据屏幕坐标查找命中的图片\r\n   *\r\n   * 同时支持独立图片块和段落环绕图片。\r\n   *\r\n   * @param clientX 客户端横坐标\r\n   * @param clientY 客户端纵坐标\r\n   * @returns 命中的图片选中信息，未命中返回 null\r\n   */\r\n  private findImageAt(clientX: number, clientY: number): ImageSelection | null {\r\n    const layout = this.deps.getLayout()\r\n    if (!layout) return null\r\n    const rect = this.deps.getContainerRect()\r\n    const scrollY = this.deps.getScrollY()\r\n    const pageOffsetX = this.deps.getPageOffsetX()\r\n\r\n    for (const page of layout.pages) {\r\n      const pageOriginX = rect.left + pageOffsetX + page.contentRect.x\r\n      const pageOriginY = rect.top - scrollY + page.contentRect.y\r\n      for (const b of page.blocks) {\r\n        if (b.kind === 'image') {\r\n          const bx = pageOriginX + b.rect.x\r\n          const by = pageOriginY + b.rect.y\r\n          if (clientX >= bx && clientX <= bx + b.rect.width && clientY >= by && clientY <= by + b.rect.height) {\r\n            const path = [...b.parentPath, b.indexInParent] as Path\r\n            return { path, block: b, pageOriginX, pageOriginY }\r\n          }\r\n        } else if (b.kind === 'paragraph' && b.surroundImage) {\r\n          const si = b.surroundImage\r\n          const bx = pageOriginX + b.rect.x + si.rect.x\r\n          const by = pageOriginY + b.rect.y\r\n          if (clientX >= bx && clientX <= bx + si.rect.width && clientY >= by && clientY <= by + si.rect.height) {\r\n            const path = [...si.parentPath, si.indexInParent] as Path\r\n            return { path, block: si, pageOriginX: pageOriginX + b.rect.x, pageOriginY: pageOriginY + b.rect.y }\r\n          }\r\n        }\r\n      }\r\n    }\r\n    return null\r\n  }\r\n\r\n  /**\r\n   * 选中指定图片并刷新选中 UI\r\n   *\r\n   * @param sel 图片选中信息\r\n   */\r\n  private selectImage(sel: ImageSelection): void {\r\n    this.selection = sel\r\n    this.updateSelectionUI()\r\n  }\r\n\r\n  /**\r\n   * 清除当前选中状态，隐藏选中框、手柄和工具栏\r\n   */\r\n  private clearSelection(): void {\r\n    this.selection = null\r\n    if (this.selectionLayer) this.selectionLayer.style.display = 'none'\r\n  }\r\n\r\n  /**\r\n   * 刷新选中状态\r\n   *\r\n   * 根据当前选中图片路径重新查找布局中的图片块，若已不存在则清除选中。\r\n   */\r\n  update(): void {\r\n    if (!this.selection) return\r\n    const hit = this.findImageByPath(this.selection.path)\r\n    if (!hit) { this.clearSelection(); return }\r\n    this.selection = hit\r\n    this.updateSelectionUI()\r\n  }\r\n\r\n  /**\r\n   * 根据路径查找图片块\r\n   *\r\n   * @param path 图片路径\r\n   * @returns 命中的图片选中信息，未找到返回 null\r\n   */\r\n  private findImageByPath(path: Path): ImageSelection | null {\r\n    const layout = this.deps.getLayout()\r\n    if (!layout) return null\r\n    const rect = this.deps.getContainerRect()\r\n    const scrollY = this.deps.getScrollY()\r\n    const pageOffsetX = this.deps.getPageOffsetX()\r\n\r\n    for (const page of layout.pages) {\r\n      const pageOriginX = rect.left + pageOffsetX + page.contentRect.x\r\n      const pageOriginY = rect.top - scrollY + page.contentRect.y\r\n      for (const b of page.blocks) {\r\n        if (b.kind === 'image') {\r\n          const bp = [...b.parentPath, b.indexInParent] as Path\r\n          if (bp.length === path.length && bp.every((seg, i) => seg === path[i])) {\r\n            return { path, block: b, pageOriginX, pageOriginY }\r\n          }\r\n        } else if (b.kind === 'paragraph' && b.surroundImage) {\r\n          const si = b.surroundImage\r\n          const bp = [...si.parentPath, si.indexInParent] as Path\r\n          if (bp.length === path.length && bp.every((seg, i) => seg === path[i])) {\r\n            return { path, block: si, pageOriginX: pageOriginX + b.rect.x, pageOriginY: pageOriginY + b.rect.y }\r\n          }\r\n        }\r\n      }\r\n    }\r\n    return null\r\n  }\r\n\r\n  /**\r\n   * 更新选中框、八方向手柄和悬浮工具栏的位置与显示状态\r\n   */\r\n  private updateSelectionUI(): void {\r\n    if (!this.selection || !this.selectionBox || !this.selectionLayer) return\r\n    const { block, pageOriginX, pageOriginY } = this.selection\r\n    const deleteOnly = Boolean((block.block as IImageElement).imgToolDisabled)\n    const viewport = this.deps.getContainerRect()\r\n    const x = pageOriginX + block.rect.x - viewport.left\r\n    const y = pageOriginY + block.rect.y - viewport.top\r\n    const w = block.rect.width\r\n    const h = block.rect.height\r\n    const bounds = { x, y, width: w, height: h }\r\n    if (!updateSelectionLayer(this.selectionLayer, bounds, viewport)) return\r\n    this.selectionBox.style.left = `${Math.round(x)}px`\r\n    this.selectionBox.style.top = `${Math.round(y)}px`\r\n    this.selectionBox.style.width = `${Math.round(w)}px`\r\n    this.selectionBox.style.height = `${Math.round(h)}px`\r\n\r\n    for (let i = 0; i < this.handleEls.length; i++) {\r\n      const el = this.handleEls[i]\r\n      const hd = HANDLES[i]\r\n      if (deleteOnly) el.style.display = 'none'\n      else el.style.removeProperty('display')\n      el.style.left = `${Math.round(x + w * hd.x - HANDLE_OFFSET)}px`\r\n      el.style.top = `${Math.round(y + h * hd.y - HANDLE_OFFSET)}px`\r\n    }\r\n\r\n    // 悬浮工具栏：定位在图片上方居中，空间不足时放下方\r\n    if (this.toolbar) {\r\n      for (const child of Array.from(this.toolbar.children) as HTMLElement[]) {\n        const action = child.dataset.imageAction\n        if (deleteOnly && action !== 'delete') child.style.display = 'none'\n        else if (action === 'separator') child.style.removeProperty('display')\n        else child.style.display = 'flex'\n      }\n      positionSelectionToolbar(this.toolbar, bounds, this.selectionLayer)\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 处理缩放手柄的 mousedown 事件，进入拖拽缩放状态\r\n   *\r\n   * @param e 鼠标事件\r\n   * @param dir 手柄方向\r\n   */\r\n  private onHandleMouseDown(e: MouseEvent, dir: string): void {\r\n    if (!this.selection) return\r\n    if ((this.selection.block.block as IImageElement).imgToolDisabled) return\n    e.preventDefault()\r\n    e.stopPropagation()\r\n    const { block } = this.selection\r\n    this.dragging = { dir, startX: e.clientX, startY: e.clientY, origW: block.rect.width, origH: block.rect.height, lastW: block.rect.width, lastH: block.rect.height }\r\n    window.addEventListener('mousemove', this.onDragMove)\r\n    window.addEventListener('mouseup', this.onDragEnd)\r\n  }\r\n\r\n  /**\r\n   * 拖拽缩放过程中的 mousemove 处理（箭头函数绑定）\r\n   *\r\n   * 根据手柄方向和鼠标偏移量按图片原始宽高比计算新的宽高，并实时刷新显示。\r\n   *\r\n   * @param e 鼠标事件\r\n   */\r\n  private onDragMove = (e: MouseEvent): void => {\r\n    if (!this.dragging || !this.selection) return\r\n    const dx = e.clientX - this.dragging.startX\r\n    const dy = e.clientY - this.dragging.startY\r\n    const { dir, origW, origH } = this.dragging\r\n    let w = origW\r\n    let h = origH\r\n    const ratio = origW / origH\r\n    if (dir.includes('e')) w = Math.max(20, origW + dx)\r\n    if (dir.includes('w')) w = Math.max(20, origW - dx)\r\n    if (dir.includes('s')) h = Math.max(20, origH + dy)\r\n    if (dir.includes('n')) h = Math.max(20, origH - dy)\r\n    if (dir === 'n' || dir === 's') w = h * ratio\r\n    if (dir === 'e' || dir === 'w') h = w / ratio\r\n    this.dragging.lastW = w\r\n    this.dragging.lastH = h\r\n    this.deps.onUpdateImageSizeLive(this.selection.path, w, h)\r\n  }\r\n\r\n  /**\r\n   * 拖拽缩放结束的 mouseup 处理（箭头函数绑定）\r\n   *\r\n   * 将最终尺寸写入文档并清理拖拽状态和事件监听。\r\n   */\r\n  private onDragEnd = (): void => {\r\n    if (this.dragging && this.selection) {\r\n      this.deps.onCommand('executeUpdateImageSize', this.selection.path, this.dragging.lastW, this.dragging.lastH)\r\n    }\r\n    this.dragging = null\r\n    window.removeEventListener('mousemove', this.onDragMove)\r\n    window.removeEventListener('mouseup', this.onDragEnd)\r\n  }\r\n\r\n  /**\r\n   * 销毁 widget，清除选中、移除事件监听并清理所有 DOM\r\n   */\r\n  destroy(): void {\r\n    this.clearSelection()\r\n    window.removeEventListener('mousemove', this.onDragMove)\r\n    window.removeEventListener('mouseup', this.onDragEnd)\r\n    if (this.selectionLayer) { this.selectionLayer.remove(); this.selectionLayer = null }\r\n    this.selectionBox = null\r\n    this.handleEls = []\r\n    this.toolbar = null\r\n    this.dragging = null\r\n  }\r\n}\r\n","/**\r\n * ChartWidget —— 图表交互 widget\r\n *\r\n * 图表以 canvas drawImage 方式渲染（同图片），交互层独立：\r\n *  - 点击图表选中（高亮边框 + 八方向缩放手柄）\r\n *  - 拖拽手柄缩放图表\r\n *  - 悬浮工具栏（编辑图表、删除）\r\n *  - 点击或\"编辑\"按钮 → emit chartClick 事件 → 弹出编辑面板\r\n */\r\n\r\nimport type { DocumentLayout, ChartBlock } from '../layout-types'\r\nimport type { EventBus } from '@vervedoc/docx-editor-state'\r\nimport type { Path } from '@vervedoc/docx-editor-schema'\r\nimport { createSelectionLayer, positionSelectionToolbar, updateSelectionLayer } from './selection-layer'\r\n\r\n\r\n/** ChartWidget 的依赖注入接口 */\r\nexport interface ChartWidgetDeps {\r\n  /** 选框裁剪层的挂载容器 */\r\n  getContainer: () => HTMLElement\r\n  /** 获取当前文档布局 */\r\n  getLayout: () => DocumentLayout | null\r\n  /** 获取编辑器容器在视口中的矩形位置 */\r\n  getContainerRect: () => DOMRect\r\n  /** 获取当前垂直滚动偏移量 */\r\n  getScrollY: () => number\r\n  /** 获取页面水平偏移量 */\r\n  getPageOffsetX: () => number\r\n  /** 触发编辑器命令的回调 */\r\n  onCommand: (cmd: string, ...args: any[]) => void\r\n  /** 拖拽过程中实时更新图表尺寸（不写入文档，仅刷新显示） */\r\n  onUpdateChartSizeLive: (path: Path, width: number, height: number) => void\r\n  /** 获取事件总线（用于发射 chartClick 事件） */\r\n  getEventBus: () => EventBus | undefined\r\n}\r\n\r\n/** 当前选中的图表信息 */\r\ninterface ChartSelection {\r\n  /** 图表在文档中的路径 */\r\n  path: Path\r\n  /** 图表块数据 */\r\n  block: ChartBlock\r\n  /** 图表所在页面的屏幕起点横坐标 */\r\n  pageOriginX: number\r\n  /** 图表所在页面的屏幕起点纵坐标 */\r\n  pageOriginY: number\r\n}\r\n\r\n/** 缩放手柄边长 */\r\nconst HANDLE_SIZE = 8\r\n/** 缩放手柄中心偏移量 */\r\nconst HANDLE_OFFSET = HANDLE_SIZE / 2\r\n/** 八方向缩放手柄定义 */\r\nconst HANDLES = [\r\n  { dir: 'nw', x: 0, y: 0 },\r\n  { dir: 'n', x: 0.5, y: 0 },\r\n  { dir: 'ne', x: 1, y: 0 },\r\n  { dir: 'e', x: 1, y: 0.5 },\r\n  { dir: 'se', x: 1, y: 1 },\r\n  { dir: 's', x: 0.5, y: 1 },\r\n  { dir: 'sw', x: 0, y: 1 },\r\n  { dir: 'w', x: 0, y: 0.5 },\r\n] as const\r\n\r\n/**\r\n * 图表交互 widget\r\n *\r\n * 提供图表选中高亮、八方向缩放手柄、悬浮工具栏（编辑、删除）以及拖拽缩放功能。\r\n */\r\nexport class ChartWidget {\r\n  private selectionLayer: HTMLDivElement | null = null\r\n  /** 选中高亮边框 DOM */\r\n  private selectionBox: HTMLDivElement | null = null\r\n  /** 缩放手柄 DOM 数组 */\r\n  private handleEls: HTMLDivElement[] = []\r\n  /** 悬浮工具栏 DOM */\r\n  private toolbar: HTMLDivElement | null = null\r\n  /** 当前选中的图表信息 */\r\n  private selection: ChartSelection | null = null\r\n  /** 拖拽缩放状态 */\r\n  private dragging: { dir: string; startX: number; startY: number; origW: number; origH: number; lastW: number; lastH: number } | null = null\r\n\r\n  /**\r\n   * 创建 ChartWidget 实例\r\n   * @param deps 依赖注入对象\r\n   */\r\n  constructor(private deps: ChartWidgetDeps) {}\r\n\r\n  /**\r\n   * 创建选中框、缩放手柄和工具栏，统一挂载到编辑区裁剪层\r\n   */\r\n  create(): void {\r\n    this.selectionLayer = createSelectionLayer(this.deps.getContainer(), 'chart')\r\n    this.selectionBox = document.createElement('div')\r\n    this.selectionBox.style.cssText = 'position:absolute;border:1.5px solid #409eff;pointer-events:none;z-index:100;box-sizing:border-box;'\r\n    this.selectionLayer.appendChild(this.selectionBox)\r\n\r\n    for (const h of HANDLES) {\r\n      const el = document.createElement('div')\r\n      el.dataset.dir = h.dir\r\n      el.style.cssText = `position:absolute;pointer-events:auto;width:${HANDLE_SIZE}px;height:${HANDLE_SIZE}px;background:#fff;border:1.5px solid #409eff;border-radius:50%;z-index:101;cursor:${this.cursorFor(h.dir)};box-sizing:border-box;`\r\n      el.addEventListener('mousedown', (e) => this.onHandleMouseDown(e, h.dir))\r\n      this.selectionLayer.appendChild(el)\r\n      this.handleEls.push(el)\r\n    }\r\n\r\n    this.toolbar = this.createToolbar()\r\n    this.selectionLayer.appendChild(this.toolbar)\r\n  }\r\n\r\n  /**\r\n   * 根据手柄方向返回对应的鼠标光标样式\r\n   */\r\n  private cursorFor(dir: string): string {\r\n    const map: Record<string, string> = {\r\n      nw: 'nwse-resize', n: 'ns-resize', ne: 'nesw-resize', e: 'ew-resize',\r\n      se: 'nwse-resize', s: 'ns-resize', sw: 'nesw-resize', w: 'ew-resize',\r\n    }\r\n    return map[dir] || 'default'\r\n  }\r\n\r\n  /**\r\n   * 创建图表悬浮工具栏（编辑图表、删除）\r\n   */\r\n  private createToolbar(): HTMLDivElement {\r\n    const bar = document.createElement('div')\r\n    bar.style.cssText = 'position:absolute;pointer-events:auto;box-sizing:border-box;overflow-x:auto;display:none;z-index:102;background:#f5f5f5;border-radius:6px;box-shadow:0 2px 8px rgba(0,0,0,0.15);padding:4px 6px;align-items:center;gap:2px;font-family:sans-serif;'\r\n\r\n    const mkBtn = (icon: string, title: string, onClick: () => void): HTMLButtonElement => {\r\n      const btn = document.createElement('button')\r\n      btn.title = title\r\n      btn.style.cssText = 'border:none;background:transparent;cursor:pointer;padding:5px;border-radius:4px;display:flex;align-items:center;justify-content:center;transition:background .15s;'\r\n      const sp = document.createElement('span')\r\n      sp.className = 'material-symbols-outlined'\r\n      sp.textContent = icon\r\n      sp.style.cssText = 'font-size:18px;color:#333;'\r\n      btn.appendChild(sp)\r\n      btn.addEventListener('mouseenter', () => { btn.style.background = '#e0e0e0' })\r\n      btn.addEventListener('mouseleave', () => { btn.style.background = 'transparent' })\r\n      btn.addEventListener('mousedown', (e) => { e.preventDefault(); e.stopPropagation() })\r\n      btn.addEventListener('click', (e) => { e.preventDefault(); e.stopPropagation(); onClick() })\r\n      return btn\r\n    }\r\n    const mkSep = (): HTMLDivElement => {\r\n      const sep = document.createElement('div')\r\n      sep.style.cssText = 'width:1px;height:20px;background:#ccc;margin:0 3px;'\r\n      return sep\r\n    }\r\n\r\n    bar.appendChild(mkBtn('edit', '编辑图表', () => this.editChart()))\r\n    bar.appendChild(mkSep())\r\n    const delBtn = mkBtn('delete', '删除图表', () => this.deleteChart())\r\n    const delIcon = delBtn.querySelector('.material-symbols-outlined') as HTMLElement\r\n    delBtn.addEventListener('mouseenter', () => { delIcon.style.color = '#e53935' })\r\n    delBtn.addEventListener('mouseleave', () => { delIcon.style.color = '#333' })\r\n    bar.appendChild(delBtn)\r\n\r\n    return bar\r\n  }\r\n\r\n  /**\r\n   * 编辑当前选中的图表：emit chartClick 事件\r\n   */\r\n  private editChart(): void {\r\n    if (!this.selection) return\r\n    const el = this.selection.block.block as unknown as {\r\n      id?: string\r\n      block?: { chartBlock?: Record<string, unknown> }\r\n    }\r\n    const chartBlock = el.block?.chartBlock\r\n    this.deps.getEventBus()?.emit('chartClick', {\r\n      chartId: el.id ?? '',\r\n      chartType: String(chartBlock?.chartType ?? ''),\r\n      dataSource: chartBlock?.dataSource,\r\n      config: chartBlock?.config,\r\n      subtype: String(chartBlock?.subtype ?? '')\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 删除当前选中的图表\r\n   */\r\n  private deleteChart(): void {\r\n    if (!this.selection) return\r\n    this.deps.onCommand('executeDeleteBlock', this.selection.path)\r\n    this.clearSelection()\r\n  }\r\n\r\n  /**\r\n   * 处理 mousedown，返回 true 表示点击了图表（已拦截）\r\n   */\r\n  handleMouseDown(e: MouseEvent): boolean {\r\n    this.clearSelection()\r\n    const hit = this.findChartAt(e.clientX, e.clientY)\r\n    if (!hit) return false\r\n\r\n    e.preventDefault()\r\n    e.stopPropagation()\r\n    this.selectChart(hit)\r\n    return true\r\n  }\r\n\r\n  /**\r\n   * 根据屏幕坐标查找命中的图表\r\n   */\r\n  private findChartAt(clientX: number, clientY: number): ChartSelection | null {\r\n    const layout = this.deps.getLayout()\r\n    if (!layout) return null\r\n    const rect = this.deps.getContainerRect()\r\n    const scrollY = this.deps.getScrollY()\r\n    const pageOffsetX = this.deps.getPageOffsetX()\r\n\r\n    for (const page of layout.pages) {\r\n      const pageOriginX = rect.left + pageOffsetX + page.contentRect.x\r\n      const pageOriginY = rect.top - scrollY + page.contentRect.y\r\n      for (const b of page.blocks) {\r\n        if (b.kind === 'chart') {\r\n          const bx = pageOriginX + b.rect.x\r\n          const by = pageOriginY + b.rect.y\r\n          if (clientX >= bx && clientX <= bx + b.rect.width && clientY >= by && clientY <= by + b.rect.height) {\r\n            const path = [...b.parentPath, b.indexInParent] as Path\r\n            return { path, block: b, pageOriginX, pageOriginY }\r\n          }\r\n        }\r\n      }\r\n    }\r\n    return null\r\n  }\r\n\r\n  /**\r\n   * 选中指定图表并刷新选中 UI\r\n   */\r\n  private selectChart(sel: ChartSelection): void {\r\n    this.selection = sel\r\n    this.updateSelectionUI()\r\n  }\r\n\r\n  /**\r\n   * 清除当前选中状态\r\n   */\r\n  private clearSelection(): void {\r\n    this.selection = null\r\n    if (this.selectionLayer) this.selectionLayer.style.display = 'none'\r\n  }\r\n\r\n  /**\r\n   * 刷新选中状态：按当前 path 重新查找图表块\r\n   */\r\n  update(): void {\r\n    if (!this.selection) return\r\n    const hit = this.findChartByPath(this.selection.path)\r\n    if (!hit) { this.clearSelection(); return }\r\n    this.selection = hit\r\n    this.updateSelectionUI()\r\n  }\r\n\r\n  /**\r\n   * 根据路径查找图表块\r\n   */\r\n  private findChartByPath(path: Path): ChartSelection | null {\r\n    const layout = this.deps.getLayout()\r\n    if (!layout) return null\r\n    const rect = this.deps.getContainerRect()\r\n    const scrollY = this.deps.getScrollY()\r\n    const pageOffsetX = this.deps.getPageOffsetX()\r\n\r\n    for (const page of layout.pages) {\r\n      const pageOriginX = rect.left + pageOffsetX + page.contentRect.x\r\n      const pageOriginY = rect.top - scrollY + page.contentRect.y\r\n      for (const b of page.blocks) {\r\n        if (b.kind === 'chart') {\r\n          const bp = [...b.parentPath, b.indexInParent] as Path\r\n          if (bp.length === path.length && bp.every((seg, i) => seg === path[i])) {\r\n            return { path, block: b, pageOriginX, pageOriginY }\r\n          }\r\n        }\r\n      }\r\n    }\r\n    return null\r\n  }\r\n\r\n  /**\r\n   * 更新选中框、手柄和工具栏的位置\r\n   */\r\n  private updateSelectionUI(): void {\r\n    if (!this.selection || !this.selectionBox || !this.selectionLayer) return\r\n    const { block, pageOriginX, pageOriginY } = this.selection\r\n    const viewport = this.deps.getContainerRect()\r\n    const x = pageOriginX + block.rect.x - viewport.left\r\n    const y = pageOriginY + block.rect.y - viewport.top\r\n    const w = block.rect.width\r\n    const h = block.rect.height\r\n    const bounds = { x, y, width: w, height: h }\r\n    if (!updateSelectionLayer(this.selectionLayer, bounds, viewport)) return\r\n    this.selectionBox.style.left = `${Math.round(x)}px`\r\n    this.selectionBox.style.top = `${Math.round(y)}px`\r\n    this.selectionBox.style.width = `${Math.round(w)}px`\r\n    this.selectionBox.style.height = `${Math.round(h)}px`\r\n\r\n    for (let i = 0; i < this.handleEls.length; i++) {\r\n      const el = this.handleEls[i]\r\n      const hd = HANDLES[i]\r\n      el.style.left = `${Math.round(x + w * hd.x - HANDLE_OFFSET)}px`\r\n      el.style.top = `${Math.round(y + h * hd.y - HANDLE_OFFSET)}px`\r\n    }\r\n\r\n    if (this.toolbar) {\r\n      positionSelectionToolbar(this.toolbar, bounds, this.selectionLayer)\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 处理缩放手柄的 mousedown 事件\r\n   */\r\n  private onHandleMouseDown(e: MouseEvent, dir: string): void {\r\n    if (!this.selection) return\r\n    e.preventDefault()\r\n    e.stopPropagation()\r\n    const { block } = this.selection\r\n    this.dragging = { dir, startX: e.clientX, startY: e.clientY, origW: block.rect.width, origH: block.rect.height, lastW: block.rect.width, lastH: block.rect.height }\r\n    window.addEventListener('mousemove', this.onDragMove)\r\n    window.addEventListener('mouseup', this.onDragEnd)\r\n  }\r\n\r\n  /**\r\n   * 拖拽缩放过程中的 mousemove 处理\r\n   */\r\n  private onDragMove = (e: MouseEvent): void => {\r\n    if (!this.dragging || !this.selection) return\r\n    const dx = e.clientX - this.dragging.startX\r\n    const dy = e.clientY - this.dragging.startY\r\n    const { dir, origW, origH } = this.dragging\r\n    let w = origW\r\n    let h = origH\r\n    const ratio = origW / origH\r\n    if (dir.includes('e')) w = Math.max(20, origW + dx)\r\n    if (dir.includes('w')) w = Math.max(20, origW - dx)\r\n    if (dir.includes('s')) h = Math.max(20, origH + dy)\r\n    if (dir.includes('n')) h = Math.max(20, origH - dy)\r\n    if (dir === 'n' || dir === 's') w = h * ratio\r\n    if (dir === 'e' || dir === 'w') h = w / ratio\r\n    this.dragging.lastW = w\r\n    this.dragging.lastH = h\r\n    this.deps.onUpdateChartSizeLive(this.selection.path, w, h)\r\n  }\r\n\r\n  /**\r\n   * 拖拽缩放结束的 mouseup 处理\r\n   */\r\n  private onDragEnd = (): void => {\r\n    if (this.dragging && this.selection) {\r\n      this.deps.onCommand('executeUpdateChartSize', this.selection.path, this.dragging.lastW, this.dragging.lastH)\r\n    }\r\n    this.dragging = null\r\n    window.removeEventListener('mousemove', this.onDragMove)\r\n    window.removeEventListener('mouseup', this.onDragEnd)\r\n  }\r\n\r\n  /**\r\n   * 销毁 widget，清除选中、移除事件监听并清理所有 DOM\r\n   */\r\n  destroy(): void {\r\n    this.clearSelection()\r\n    window.removeEventListener('mousemove', this.onDragMove)\r\n    window.removeEventListener('mouseup', this.onDragEnd)\r\n    if (this.selectionLayer) { this.selectionLayer.remove(); this.selectionLayer = null }\r\n    this.selectionBox = null\r\n    this.handleEls = []\r\n    this.toolbar = null\r\n    this.dragging = null\r\n  }\r\n}\r\n","export default \"<div class=\\\"pw-panel-mask\\\">\\r\\n  <div class=\\\"pw-panel pw-paragraph-panel\\\">\\r\\n    <div class=\\\"pw-panel-title\\\">段落</div>\\r\\n\\r\\n    <div class=\\\"pw-tabs\\\">\\r\\n      <div class=\\\"pw-tab pw-tab-active\\\" data-tab=\\\"indent\\\">缩进和间距</div>\\r\\n      <div class=\\\"pw-tab\\\" data-tab=\\\"break\\\">换行和分页</div>\\r\\n      <div class=\\\"pw-tab\\\" data-tab=\\\"cjk\\\">中文版式</div>\\r\\n    </div>\\r\\n\\r\\n    <div class=\\\"pw-panel-body\\\">\\r\\n      <!-- ===== Tab 1：缩进和间距 ===== -->\\r\\n      <div class=\\\"pw-pane pw-pane-active\\\" data-pane=\\\"indent\\\">\\r\\n\\r\\n        <fieldset class=\\\"pw-group\\\">\\r\\n          <legend>常规</legend>\\r\\n          <div class=\\\"pw-grid\\\">\\r\\n            <div class=\\\"pw-field\\\">\\r\\n              <label class=\\\"pw-field-label\\\" for=\\\"pw-align\\\">对齐方式</label>\\r\\n              <select id=\\\"pw-align\\\" class=\\\"pw-ctrl\\\">\\r\\n                <option value=\\\"left\\\">左对齐</option>\\r\\n                <option value=\\\"center\\\">居中对齐</option>\\r\\n                <option value=\\\"right\\\">右对齐</option>\\r\\n                <option value=\\\"justify\\\">两端对齐</option>\\r\\n                <option value=\\\"distribute\\\">分散对齐</option>\\r\\n              </select>\\r\\n            </div>\\r\\n            <div class=\\\"pw-field\\\">\\r\\n              <label class=\\\"pw-field-label\\\" for=\\\"pw-outline\\\">大纲级别</label>\\r\\n              <select id=\\\"pw-outline\\\" class=\\\"pw-ctrl\\\">\\r\\n                <option value=\\\"\\\">正文文本</option>\\r\\n                <option value=\\\"first\\\">1 级</option>\\r\\n                <option value=\\\"second\\\">2 级</option>\\r\\n                <option value=\\\"third\\\">3 级</option>\\r\\n                <option value=\\\"fourth\\\">4 级</option>\\r\\n                <option value=\\\"fifth\\\">5 级</option>\\r\\n                <option value=\\\"sixth\\\">6 级</option>\\r\\n              </select>\\r\\n            </div>\\r\\n          </div>\\r\\n        </fieldset>\\r\\n\\r\\n        <fieldset class=\\\"pw-group\\\">\\r\\n          <legend>缩进</legend>\\r\\n          <div class=\\\"pw-grid\\\">\\r\\n            <div class=\\\"pw-field\\\">\\r\\n              <label class=\\\"pw-field-label\\\" for=\\\"pw-indent-left\\\">文本之前</label>\\r\\n              <input type=\\\"number\\\" id=\\\"pw-indent-left\\\" class=\\\"pw-ctrl\\\" value=\\\"0.00\\\" min=\\\"0\\\" step=\\\"0.01\\\">\\r\\n              <span class=\\\"pw-unit\\\">厘米</span>\\r\\n            </div>\\r\\n            <div class=\\\"pw-field\\\">\\r\\n              <label class=\\\"pw-field-label\\\" for=\\\"pw-special\\\">特殊格式</label>\\r\\n              <select id=\\\"pw-special\\\" class=\\\"pw-ctrl\\\">\\r\\n                <option value=\\\"none\\\">无</option>\\r\\n                <option value=\\\"firstLine\\\">首行缩进</option>\\r\\n                <option value=\\\"hanging\\\">悬挂缩进</option>\\r\\n              </select>\\r\\n            </div>\\r\\n            <div class=\\\"pw-field\\\">\\r\\n              <label class=\\\"pw-field-label\\\" for=\\\"pw-indent-right\\\">文本之后</label>\\r\\n              <input type=\\\"number\\\" id=\\\"pw-indent-right\\\" class=\\\"pw-ctrl\\\" value=\\\"0.00\\\" min=\\\"0\\\" step=\\\"0.01\\\">\\r\\n              <span class=\\\"pw-unit\\\">厘米</span>\\r\\n            </div>\\r\\n            <div class=\\\"pw-field\\\">\\r\\n              <label class=\\\"pw-field-label\\\" for=\\\"pw-special-value\\\">度量值</label>\\r\\n              <input type=\\\"number\\\" id=\\\"pw-special-value\\\" class=\\\"pw-ctrl\\\" value=\\\"0.00\\\" min=\\\"0\\\" step=\\\"0.01\\\" disabled>\\r\\n              <span class=\\\"pw-unit\\\">厘米</span>\\r\\n            </div>\\r\\n          </div>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" disabled> 如果定义了文档网格，则自动调整右缩进</label>\\r\\n        </fieldset>\\r\\n\\r\\n        <fieldset class=\\\"pw-group\\\">\\r\\n          <legend>间距</legend>\\r\\n          <div class=\\\"pw-grid\\\">\\r\\n            <div class=\\\"pw-field\\\">\\r\\n              <label class=\\\"pw-field-label\\\" for=\\\"pw-spacing-before\\\">段前</label>\\r\\n              <input type=\\\"number\\\" id=\\\"pw-spacing-before\\\" class=\\\"pw-ctrl\\\" value=\\\"0.00\\\" min=\\\"0\\\" step=\\\"0.5\\\">\\r\\n              <span class=\\\"pw-unit\\\">磅</span>\\r\\n            </div>\\r\\n            <div class=\\\"pw-field\\\">\\r\\n              <label class=\\\"pw-field-label\\\" for=\\\"pw-lh-type\\\">行距</label>\\r\\n              <select id=\\\"pw-lh-type\\\" class=\\\"pw-ctrl\\\">\\r\\n                <option value=\\\"single\\\">单倍行距</option>\\r\\n                <option value=\\\"1.5\\\">1.5 倍行距</option>\\r\\n                <option value=\\\"double\\\">双倍行距</option>\\r\\n                <option value=\\\"atLeast\\\">最小值</option>\\r\\n                <option value=\\\"exact\\\">固定值</option>\\r\\n                <option value=\\\"multiple\\\">多倍行距</option>\\r\\n              </select>\\r\\n            </div>\\r\\n            <div class=\\\"pw-field\\\">\\r\\n              <label class=\\\"pw-field-label\\\" for=\\\"pw-spacing-after\\\">段后</label>\\r\\n              <input type=\\\"number\\\" id=\\\"pw-spacing-after\\\" class=\\\"pw-ctrl\\\" value=\\\"0.00\\\" min=\\\"0\\\" step=\\\"0.5\\\">\\r\\n              <span class=\\\"pw-unit\\\">磅</span>\\r\\n            </div>\\r\\n            <div class=\\\"pw-field\\\">\\r\\n              <label class=\\\"pw-field-label\\\" for=\\\"pw-lh-value\\\">设置值</label>\\r\\n              <input type=\\\"number\\\" id=\\\"pw-lh-value\\\" class=\\\"pw-ctrl\\\" value=\\\"1.00\\\" min=\\\"0\\\" step=\\\"0.05\\\" disabled>\\r\\n              <span class=\\\"pw-unit\\\" id=\\\"pw-lh-unit\\\">磅</span>\\r\\n            </div>\\r\\n          </div>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" disabled> 如果定义了文档网格，则与网格对齐</label>\\r\\n        </fieldset>\\r\\n\\r\\n        <div class=\\\"pw-preview-box\\\">\\r\\n          <div class=\\\"pw-preview-label\\\">预览</div>\\r\\n          <div class=\\\"pw-preview\\\" id=\\\"pw-preview\\\">段落预览文本</div>\\r\\n        </div>\\r\\n      </div>\\r\\n\\r\\n      <!-- ===== Tab 2：换行和分页 ===== -->\\r\\n      <div class=\\\"pw-pane\\\" data-pane=\\\"break\\\">\\r\\n        <fieldset class=\\\"pw-group\\\">\\r\\n          <legend>分页</legend>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-widow\\\" disabled> 孤行控制</label>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-keep-next\\\" disabled> 与下段同页</label>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-page-break-before\\\" disabled> 段前分页</label>\\r\\n        </fieldset>\\r\\n        <fieldset class=\\\"pw-group\\\">\\r\\n          <legend>换行</legend>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-suppress-line-num\\\" disabled> 取消行号</label>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-suppress-auto-hyphen\\\" disabled> 取消断字</label>\\r\\n        </fieldset>\\r\\n        <div class=\\\"pw-placeholder\\\">该功能将在后续版本支持</div>\\r\\n      </div>\\r\\n\\r\\n      <!-- ===== Tab 3：中文版式 ===== -->\\r\\n      <div class=\\\"pw-pane\\\" data-pane=\\\"cjk\\\">\\r\\n        <fieldset class=\\\"pw-group\\\">\\r\\n          <legend>换行</legend>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-word-wrap\\\" disabled> 按中文习惯换行</label>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-overflow-punct\\\" disabled> 允许标点溢出边界</label>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-allow-break-word\\\" disabled> 允许西文在单词中间换行</label>\\r\\n        </fieldset>\\r\\n        <fieldset class=\\\"pw-group\\\">\\r\\n          <legend>字符间距</legend>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-compress-punct\\\" disabled> 允许行首标点压缩</label>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-auto-space-cjk-west\\\" disabled> 自动调整中文与西文的间距</label>\\r\\n          <label class=\\\"pw-check\\\"><input type=\\\"checkbox\\\" id=\\\"pw-auto-space-cjk-num\\\" disabled> 自动调整中文与数字的间距</label>\\r\\n        </fieldset>\\r\\n        <fieldset class=\\\"pw-group\\\">\\r\\n          <legend>文字对齐方式</legend>\\r\\n          <div class=\\\"pw-field\\\">\\r\\n            <label class=\\\"pw-field-label\\\" for=\\\"pw-text-align\\\">对齐</label>\\r\\n            <select id=\\\"pw-text-align\\\" class=\\\"pw-ctrl\\\" disabled>\\r\\n              <option value=\\\"auto\\\">自动</option>\\r\\n              <option value=\\\"top\\\">顶端对齐</option>\\r\\n              <option value=\\\"center\\\">居中</option>\\r\\n              <option value=\\\"baseline\\\">基线对齐</option>\\r\\n              <option value=\\\"bottom\\\">底端对齐</option>\\r\\n            </select>\\r\\n          </div>\\r\\n        </fieldset>\\r\\n        <div class=\\\"pw-placeholder\\\">该功能将在后续版本支持</div>\\r\\n      </div>\\r\\n    </div>\\r\\n\\r\\n    <div class=\\\"pw-panel-actions\\\">\\r\\n      <button type=\\\"button\\\" id=\\\"pw-cancel\\\">取消</button>\\r\\n      <button type=\\\"button\\\" id=\\\"pw-ok\\\">确定</button>\\r\\n    </div>\\r\\n  </div>\\r\\n</div>\\r\\n\"","/**\r\n * ParagraphLayoutWidget —— 段落设置弹出面板（对齐 Word 标准）\r\n *\r\n * 结构在 paragraph-layout-widget.html，样式在 paragraph-layout-widget.css，\r\n * 本模块负责注入资源、填充当前值、绑定事件、应用命令。\r\n * CSS 由 cssInjectedByJsPlugin 自动注入，HTML 通过 ?raw 导入字符串。\r\n */\r\nimport '../../assets/css/paragraph-layout-widget.css'\r\nimport panelHtml from '../../assets/components/paragraph-layout-widget.html?raw'\r\nimport { translatePanel, viewTranslate } from '../../view-i18n'\r\nimport type { ViewTranslate } from '../../view-i18n'\r\n\r\n/** 每厘米对应的像素数（96 DPI） */\r\nconst PX_PER_CM = 96 / 2.54\r\n\r\n/** 命令调用签名：可返回值（用于 getter） */\r\ntype CommandFn = (cmd: string, ...args: any[]) => any\r\n\r\n/** 段落设置弹出面板依赖 */\r\nexport interface ParagraphLayoutWidgetDeps {\r\n  /** 触发编辑器命令 / 读取状态 */\r\n  onCommand: CommandFn\r\n  translate?: ViewTranslate\r\n}\r\n\r\n/**\r\n * 段落设置弹出面板。\r\n *\r\n * show() 显示面板并填充当前段落值，hide() 关闭。\r\n * 确定按钮应用缩进、行距、对齐、大纲级别等命令。\r\n */\r\nexport class ParagraphLayoutWidget {\r\n  /** 面板根元素（.pw-panel-mask） */\r\n  private root: HTMLElement | null = null\r\n  /** 命令回调 */\r\n  private onCommand: CommandFn | null = null\r\n  private translate?: ViewTranslate\r\n\r\n  /** 注入依赖 */\r\n  setDeps(deps: ParagraphLayoutWidgetDeps): void {\r\n    this.onCommand = deps.onCommand\r\n    this.translate = deps.translate\r\n  }\r\n\r\n  /**\r\n   * 显示段落设置面板。\r\n   */\r\n  show(): void {\r\n    this.hide()\r\n\r\n    const container = document.createElement('div')\r\n    container.innerHTML = panelHtml\r\n    this.root = container.firstElementChild as HTMLElement\r\n    translatePanel(this.root, this.translate, 'view.paragraphDialog.')\r\n    document.body.appendChild(this.root)\r\n\r\n    this.bindTabs()\r\n    this.bindIndentSpacing()\r\n    this.root.querySelectorAll<HTMLInputElement>('input[type=\"number\"]').forEach(input => {\r\n      input.addEventListener('blur', () => {\r\n        if (input.value !== '' && Number.isFinite(input.valueAsNumber)) {\r\n          input.value = input.valueAsNumber.toFixed(2)\r\n        }\r\n      })\r\n    })\r\n    this.fillValues()\r\n    this.root.querySelector('#pw-cancel')!.addEventListener('click', () => this.hide())\r\n    this.root.querySelector('#pw-ok')!.addEventListener('click', () => {\r\n      this.apply()\r\n      this.hide()\r\n    })\r\n  }\r\n\r\n  refreshTranslations(): void {\r\n    if (!this.root) return\r\n    translatePanel(this.root, this.translate, 'view.paragraphDialog.')\r\n    this.syncLhDisabled()\r\n    this.updatePreview()\r\n  }\r\n\r\n  /**\r\n   * 关闭面板。\r\n   */\r\n  hide(): void {\r\n    if (this.root) { this.root.remove(); this.root = null }\r\n  }\r\n\r\n  /** 绑定 Tab 切换 */\r\n  private bindTabs(): void {\r\n    const tabs = this.root!.querySelectorAll<HTMLElement>('.pw-tab')\r\n    const panes = this.root!.querySelectorAll<HTMLElement>('.pw-pane')\r\n    tabs.forEach(tab => {\r\n      tab.addEventListener('click', () => {\r\n        const key = tab.dataset.tab\r\n        tabs.forEach(t => t.classList.toggle('pw-tab-active', t === tab))\r\n        panes.forEach(p => p.classList.toggle('pw-pane-active', p.dataset.pane === key))\r\n      })\r\n    })\r\n  }\r\n\r\n  /** 绑定缩进和间距 Tab 的联动交互 */\r\n  private bindIndentSpacing(): void {\r\n    const lhType = this.root!.querySelector<HTMLSelectElement>('#pw-lh-type')!\r\n    const lhValue = this.root!.querySelector<HTMLInputElement>('#pw-lh-value')!\r\n    const lhUnit = this.root!.querySelector<HTMLElement>('#pw-lh-unit')!\r\n    const special = this.root!.querySelector<HTMLSelectElement>('#pw-special')!\r\n    const specialValue = this.root!.querySelector<HTMLInputElement>('#pw-special-value')!\r\n\r\n    const updateLh = () => {\r\n      const t = lhType.value\r\n      lhValue.disabled = t === 'single' || t === '1.5' || t === 'double'\r\n      if (t === 'single') { lhValue.value = '1.00' }\r\n      else if (t === '1.5') { lhValue.value = '1.50' }\r\n      else if (t === 'double') { lhValue.value = '2.00' }\r\n      lhUnit.textContent = (t === 'atLeast' || t === 'exact') ? viewTranslate(this.translate, 'view.common.points') : viewTranslate(this.translate, 'view.paragraphDialog.times')\r\n      this.updatePreview()\r\n    }\r\n\r\n    const updateSpecial = () => {\r\n      const s = special.value\r\n      specialValue.disabled = s === 'none'\r\n      if (s === 'none') { specialValue.value = '0.00' }\r\n      this.updatePreview()\r\n    }\r\n\r\n    lhType.addEventListener('change', updateLh)\r\n    special.addEventListener('change', updateSpecial)\r\n    lhValue.addEventListener('input', () => this.updatePreview())\r\n    specialValue.addEventListener('input', () => this.updatePreview())\r\n\r\n    const align = this.root!.querySelector<HTMLSelectElement>('#pw-align')!\r\n    align.addEventListener('change', () => this.updatePreview())\r\n  }\r\n\r\n  /** 从编辑器读取当前段落状态并填充表单 */\r\n  private fillValues(): void {\r\n    if (!this.onCommand) return\r\n    const cmd = this.onCommand\r\n    const displayNumber = (value: number) => value.toFixed(2)\r\n\r\n    let style: any = null\r\n    try { style = cmd('getRangeStyle') } catch { /* noop */ }\r\n    if (!style) {\r\n      this.root!.querySelectorAll<HTMLInputElement>('input[type=\"number\"]').forEach(input => {\r\n        input.value = Number(input.value).toFixed(2)\r\n      })\r\n      return\r\n    }\r\n\r\n    const align = this.root!.querySelector<HTMLSelectElement>('#pw-align')!\r\n    align.value = style.rowFlex === 'alignment' ? 'justify' : (style.rowFlex || 'left')\r\n\r\n    const outline = this.root!.querySelector<HTMLSelectElement>('#pw-outline')!\r\n    outline.value = style.level || ''\r\n\r\n    const lhType = this.root!.querySelector<HTMLSelectElement>('#pw-lh-type')!\r\n    const lhValue = this.root!.querySelector<HTMLInputElement>('#pw-lh-value')!\r\n    const lh = Number(style.lineHeight ?? 1.5)\r\n    const rule: string = style.lineHeightRule || 'auto'\r\n    if (rule === 'exact') { lhType.value = 'exact'; lhValue.value = displayNumber(lh * 72 / 96) }\r\n    else if (rule === 'atLeast') { lhType.value = 'atLeast'; lhValue.value = displayNumber(lh * 72 / 96) }\r\n    else if (lh === 1) { lhType.value = 'single'; lhValue.value = displayNumber(1) }\r\n    else if (lh === 1.5) { lhType.value = '1.5'; lhValue.value = displayNumber(1.5) }\r\n    else if (lh === 2) { lhType.value = 'double'; lhValue.value = displayNumber(2) }\r\n    else { lhType.value = 'multiple'; lhValue.value = displayNumber(lh) }\r\n    this.syncLhDisabled()\r\n\r\n    const spacingAfter = this.root!.querySelector<HTMLInputElement>('#pw-spacing-after')!\r\n    let spAfter: number\r\n    try { spAfter = Number(cmd('getParagraphSpacingAfter')) || 0 } catch { spAfter = Number(style.rowMargin ?? 0) }\r\n    spacingAfter.value = displayNumber(spAfter)\r\n\r\n    const spacingBefore = this.root!.querySelector<HTMLInputElement>('#pw-spacing-before')!\r\n    try { spacingBefore.value = displayNumber(Number(cmd('getParagraphSpacingBefore')) || 0) } catch { /* noop */ }\r\n\r\n    const indentLeft = this.root!.querySelector<HTMLInputElement>('#pw-indent-left')!\r\n    const indentRight = this.root!.querySelector<HTMLInputElement>('#pw-indent-right')!\r\n    try { indentLeft.value = displayNumber((Number(cmd('getParagraphIndentLeft')) || 0) / PX_PER_CM) } catch { /* noop */ }\r\n    try { indentRight.value = displayNumber((Number(cmd('getParagraphIndentRight')) || 0) / PX_PER_CM) } catch { /* noop */ }\r\n\r\n    let indentPx = 0\r\n    try { indentPx = Number(cmd('getFirstLineIndent')) || 0 } catch { /* noop */ }\r\n    const special = this.root!.querySelector<HTMLSelectElement>('#pw-special')!\r\n    const specialValue = this.root!.querySelector<HTMLInputElement>('#pw-special-value')!\r\n    if (indentPx === 0) {\r\n      special.value = 'none'; specialValue.value = displayNumber(0)\r\n    } else if (indentPx > 0) {\r\n      special.value = 'firstLine'; specialValue.value = displayNumber(indentPx / PX_PER_CM)\r\n    } else {\r\n      special.value = 'hanging'; specialValue.value = displayNumber(Math.abs(indentPx) / PX_PER_CM)\r\n    }\r\n    this.syncSpecialDisabled()\r\n    this.root!.querySelectorAll<HTMLInputElement>('input[type=\"number\"]').forEach(input => {\r\n      input.value = Number(input.value).toFixed(2)\r\n    })\r\n\r\n    this.updatePreview()\r\n  }\r\n\r\n  /** 同步行距设置值禁用态 */\r\n  private syncLhDisabled(): void {\r\n    const lhType = this.root!.querySelector<HTMLSelectElement>('#pw-lh-type')!\r\n    const lhValue = this.root!.querySelector<HTMLInputElement>('#pw-lh-value')!\r\n    const lhUnit = this.root!.querySelector<HTMLElement>('#pw-lh-unit')!\r\n    const t = lhType.value\r\n    lhValue.disabled = t === 'single' || t === '1.5' || t === 'double'\r\n    lhUnit.textContent = (t === 'atLeast' || t === 'exact') ? viewTranslate(this.translate, 'view.common.points') : viewTranslate(this.translate, 'view.paragraphDialog.times')\r\n  }\r\n\r\n  /** 同步特殊格式度量值禁用态 */\r\n  private syncSpecialDisabled(): void {\r\n    const special = this.root!.querySelector<HTMLSelectElement>('#pw-special')!\r\n    const specialValue = this.root!.querySelector<HTMLInputElement>('#pw-special-value')!\r\n    specialValue.disabled = special.value === 'none'\r\n  }\r\n\r\n  /** 实时更新预览区 */\r\n  private updatePreview(): void {\r\n    const preview = this.root!.querySelector<HTMLElement>('#pw-preview')!\r\n    if (!preview) return\r\n\r\n    const align = this.root!.querySelector<HTMLSelectElement>('#pw-align')!.value\r\n    const lhType = this.root!.querySelector<HTMLSelectElement>('#pw-lh-type')!.value\r\n    const lhValue = this.root!.querySelector<HTMLInputElement>('#pw-lh-value')!.value\r\n    const special = this.root!.querySelector<HTMLSelectElement>('#pw-special')!.value\r\n    const specialValue = this.root!.querySelector<HTMLInputElement>('#pw-special-value')!.value\r\n\r\n    const alignMap: Record<string, string> = {\r\n      left: 'left', center: 'center', right: 'right',\r\n      justify: 'justify', distribute: 'justify'\r\n    }\r\n    preview.style.textAlign = alignMap[align] || 'left'\r\n\r\n    let lh: number\r\n    if (lhType === 'single') lh = 1\r\n    else if (lhType === '1.5') lh = 1.5\r\n    else if (lhType === 'double') lh = 2\r\n    else lh = Number(lhValue) || 1.5\r\n    if (lhType === 'atLeast' || lhType === 'exact') {\r\n      preview.style.lineHeight = `${lh * 96 / 72}px`\r\n    } else {\r\n      preview.style.lineHeight = String(lh)\r\n    }\r\n\r\n    let indent = 0\r\n    if (special === 'firstLine') indent = Number(specialValue) || 0\r\n    else if (special === 'hanging') indent = -(Number(specialValue) || 0)\r\n    preview.style.textIndent = `${indent * PX_PER_CM}px`\r\n\r\n    preview.textContent = viewTranslate(this.translate, 'view.paragraphDialog.previewText')\r\n  }\r\n\r\n  /** 确定按钮：应用所有设置到编辑器 */\r\n  private apply(): void {\r\n    if (!this.onCommand) return\r\n    const cmd = this.onCommand\r\n\r\n    const align = this.root!.querySelector<HTMLSelectElement>('#pw-align')!.value\r\n    cmd('executeSetRowFlex', align)\r\n\r\n    const outline = this.root!.querySelector<HTMLSelectElement>('#pw-outline')!.value\r\n    cmd('executeSetTitle', outline || null)\r\n\r\n    const lhType = this.root!.querySelector<HTMLSelectElement>('#pw-lh-type')!.value\r\n    const lhValue = this.root!.querySelector<HTMLInputElement>('#pw-lh-value')!.value\r\n    let lh: number\r\n    let rule: 'auto' | 'exact' | 'atLeast'\r\n    if (lhType === 'single') { lh = 1; rule = 'auto' }\r\n    else if (lhType === '1.5') { lh = 1.5; rule = 'auto' }\r\n    else if (lhType === 'double') { lh = 2; rule = 'auto' }\r\n    else if (lhType === 'atLeast') { lh = (Number(lhValue) || 1) * 96 / 72; rule = 'atLeast' }\r\n    else if (lhType === 'exact') { lh = (Number(lhValue) || 1) * 96 / 72; rule = 'exact' }\r\n    else { lh = Number(lhValue) || 1; rule = 'auto' }\r\n    cmd('executeSetLineHeight', lh, rule)\r\n\r\n    const spacingBefore = this.root!.querySelector<HTMLInputElement>('#pw-spacing-before')!.value\r\n    cmd('executeSetParagraphSpacingBefore', Number(spacingBefore) || 0)\r\n\r\n    const spacingAfter = this.root!.querySelector<HTMLInputElement>('#pw-spacing-after')!.value\r\n    cmd('executeSetParagraphSpacingAfter', Number(spacingAfter) || 0)\r\n\r\n    const indentLeft = this.root!.querySelector<HTMLInputElement>('#pw-indent-left')!.value\r\n    const indentRight = this.root!.querySelector<HTMLInputElement>('#pw-indent-right')!.value\r\n    cmd('executeSetParagraphIndentLeft', (Number(indentLeft) || 0) * PX_PER_CM)\r\n    cmd('executeSetParagraphIndentRight', (Number(indentRight) || 0) * PX_PER_CM)\r\n\r\n    const special = this.root!.querySelector<HTMLSelectElement>('#pw-special')!.value\r\n    const specialValue = this.root!.querySelector<HTMLInputElement>('#pw-special-value')!.value\r\n    let indentPx = 0\r\n    if (special === 'firstLine') indentPx = (Number(specialValue) || 0) * PX_PER_CM\r\n    else if (special === 'hanging') indentPx = -(Number(specialValue) || 0) * PX_PER_CM\r\n    cmd('executeSetFirstLineIndent', indentPx)\r\n  }\r\n}\r\n","export default \"<div class=\\\"fw-panel-mask\\\">\\r\\n  <div class=\\\"fw-panel\\\">\\r\\n    <div class=\\\"fw-panel-title\\\">字体</div>\\r\\n\\r\\n    <div class=\\\"fw-tabs\\\">\\r\\n      <div class=\\\"fw-tab fw-tab-active\\\" data-tab=\\\"font\\\">字体</div>\\r\\n      <div class=\\\"fw-tab\\\" data-tab=\\\"spacing\\\">字符间距</div>\\r\\n    </div>\\r\\n\\r\\n    <div class=\\\"fw-panel-body\\\">\\r\\n      <!-- ===== Tab 1：字体 ===== -->\\r\\n      <div class=\\\"fw-pane fw-pane-active\\\" data-pane=\\\"font\\\">\\r\\n        <fieldset class=\\\"fw-group\\\">\\r\\n          <legend>字体</legend>\\r\\n          <div class=\\\"fw-row\\\">\\r\\n            <span class=\\\"fw-label\\\">中文字体</span>\\r\\n            <select id=\\\"fw-font-cjk\\\" class=\\\"fw-input\\\"></select>\\r\\n          </div>\\r\\n          <div class=\\\"fw-row\\\">\\r\\n\\r\\n            <span class=\\\"fw-label\\\">字形</span>\\r\\n            <select id=\\\"fw-style\\\" class=\\\"fw-input\\\">\\r\\n              <option value=\\\"regular\\\">常规</option>\\r\\n              <option value=\\\"italic\\\">倾斜</option>\\r\\n              <option value=\\\"bold\\\">加粗</option>\\r\\n              <option value=\\\"bold-italic\\\">加粗倾斜</option>\\r\\n            </select>\\r\\n          </div>\\r\\n          <div class=\\\"fw-row\\\">\\r\\n            <span class=\\\"fw-label\\\">字号</span>\\r\\n            <select id=\\\"fw-size\\\" class=\\\"fw-input\\\"></select>\\r\\n          </div>\\r\\n          <div class=\\\"fw-row\\\">\\r\\n            <span class=\\\"fw-label\\\">颜色</span>\\r\\n            <input type=\\\"color\\\" id=\\\"fw-color\\\" class=\\\"fw-color\\\" value=\\\"#000000\\\">\\r\\n          </div>\\r\\n        </fieldset>\\r\\n\\r\\n        <fieldset class=\\\"fw-group\\\">\\r\\n          <legend>效果</legend>\\r\\n          <div class=\\\"fw-check-grid\\\">\\r\\n            <label class=\\\"fw-check\\\"><input type=\\\"checkbox\\\" id=\\\"fw-strikeout\\\"> 删除线</label>\\r\\n            <label class=\\\"fw-check\\\"><input type=\\\"checkbox\\\" id=\\\"fw-underline\\\"> 下划线</label>\\r\\n            <label class=\\\"fw-check\\\"><input type=\\\"checkbox\\\" id=\\\"fw-superscript\\\"> 上标</label>\\r\\n            <label class=\\\"fw-check\\\"><input type=\\\"checkbox\\\" id=\\\"fw-subscript\\\"> 下标</label>\\r\\n            <label class=\\\"fw-check\\\"><input type=\\\"checkbox\\\" id=\\\"fw-double-strikeout\\\"> 双删除线</label>\\r\\n            <label class=\\\"fw-check\\\"><input type=\\\"checkbox\\\" id=\\\"fw-hidden\\\"> 隐藏</label>\\r\\n          </div>\\r\\n        </fieldset>\\r\\n\\r\\n        <div class=\\\"fw-preview-box\\\">\\r\\n          <div class=\\\"fw-preview-label\\\">预览</div>\\r\\n          <div class=\\\"fw-preview\\\" id=\\\"fw-preview\\\">字体预览文本 ABCabc 123</div>\\r\\n        </div>\\r\\n      </div>\\r\\n\\r\\n      <!-- ===== Tab 2：字符间距 ===== -->\\r\\n      <div class=\\\"fw-pane\\\" data-pane=\\\"spacing\\\">\\r\\n        <fieldset class=\\\"fw-group\\\">\\r\\n          <legend>间距</legend>\\r\\n          <div class=\\\"fw-row\\\">\\r\\n            <span class=\\\"fw-label\\\">缩放</span>\\r\\n            <select id=\\\"fw-scale\\\" class=\\\"fw-input\\\">\\r\\n              <option value=\\\"100\\\">100%</option>\\r\\n              <option value=\\\"90\\\">90%</option>\\r\\n              <option value=\\\"80\\\">80%</option>\\r\\n              <option value=\\\"66\\\">66%</option>\\r\\n              <option value=\\\"50\\\">50%</option>\\r\\n              <option value=\\\"200\\\">200%</option>\\r\\n              <option value=\\\"150\\\">150%</option>\\r\\n            </select>\\r\\n          </div>\\r\\n          <div class=\\\"fw-row\\\">\\r\\n            <span class=\\\"fw-label\\\">间距</span>\\r\\n            <select id=\\\"fw-spacing-type\\\" class=\\\"fw-input\\\">\\r\\n              <option value=\\\"normal\\\">标准</option>\\r\\n              <option value=\\\"expanded\\\">加宽</option>\\r\\n              <option value=\\\"condensed\\\">紧缩</option>\\r\\n            </select>\\r\\n            <input type=\\\"number\\\" id=\\\"fw-spacing-value\\\" class=\\\"fw-input fw-sm\\\" value=\\\"0\\\" min=\\\"0\\\" step=\\\"0.1\\\">\\r\\n            <span class=\\\"fw-unit\\\">磅</span>\\r\\n          </div>\\r\\n          <div class=\\\"fw-row\\\">\\r\\n            <span class=\\\"fw-label\\\">位置</span>\\r\\n            <select id=\\\"fw-position-type\\\" class=\\\"fw-input\\\">\\r\\n              <option value=\\\"normal\\\">标准</option>\\r\\n              <option value=\\\"raised\\\">提升</option>\\r\\n              <option value=\\\"lowered\\\">降低</option>\\r\\n            </select>\\r\\n            <input type=\\\"number\\\" id=\\\"fw-position-value\\\" class=\\\"fw-input fw-sm\\\" value=\\\"0\\\" min=\\\"0\\\" step=\\\"0.1\\\">\\r\\n            <span class=\\\"fw-unit\\\">磅</span>\\r\\n          </div>\\r\\n        </fieldset>\\r\\n\\r\\n        <div class=\\\"fw-preview-box\\\">\\r\\n          <div class=\\\"fw-preview-label\\\">预览</div>\\r\\n          <div class=\\\"fw-preview\\\" id=\\\"fw-preview-spacing\\\">字符间距预览 ABCabc 123</div>\\r\\n        </div>\\r\\n\\r\\n        <div class=\\\"fw-placeholder\\\">间距与位置功能将在后续版本支持</div>\\r\\n      </div>\\r\\n    </div>\\r\\n\\r\\n    <div class=\\\"fw-panel-actions\\\">\\r\\n      <button type=\\\"button\\\" id=\\\"fw-cancel\\\">取消</button>\\r\\n      <button type=\\\"button\\\" id=\\\"fw-ok\\\">确定</button>\\r\\n    </div>\\r\\n  </div>\\r\\n</div>\\r\\n\"","/**\r\n * FontLayoutWidget —— 字体设置弹出面板（对齐 Word 标准）\r\n *\r\n * 结构在 font-layout-widget.html，样式在 font-layout-widget.css，\r\n * 本模块负责注入资源、填充当前值、绑定事件、应用命令。\r\n */\r\nimport '../../assets/css/font-layout-widget.css'\r\nimport panelHtml from '../../assets/components/font-layout-widget.html?raw'\r\nimport { translatePanel, viewText, viewTranslate, type ViewTranslate } from '../../view-i18n'\r\nimport {\r\n  FONT_FAMILY_MAP,\r\n  FONT_FAMILY_LABEL,\r\n  FONT_SIZE,\r\n  FONT_SIZE_LIST\r\n} from '@vervedoc/docx-editor-schema'\r\n\r\n/** 命令调用签名：可返回值（用于 getter） */\r\ntype CommandFn = (cmd: string, ...args: any[]) => any\r\n\r\n/** 字体设置弹出面板依赖 */\r\nexport interface FontLayoutWidgetDeps {\r\n  /** 触发编辑器命令 / 读取状态 */\r\n  onCommand: CommandFn\r\n  translate?: ViewTranslate\r\n}\r\n\r\n/**\r\n * 字体设置弹出面板。\r\n *\r\n * show() 显示面板并填充当前字体值，hide() 关闭。\r\n * 确定按钮应用字体、字号、字形、颜色、效果等命令。\r\n */\r\nexport class FontLayoutWidget {\r\n  /** 面板根元素 */\r\n  private root: HTMLElement | null = null\r\n  /** 命令回调 */\r\n  private onCommand: CommandFn | null = null\r\n  private translate?: ViewTranslate\r\n\r\n  /** 注入依赖 */\r\n  setDeps(deps: FontLayoutWidgetDeps): void {\r\n    this.onCommand = deps.onCommand\r\n    this.translate = deps.translate\r\n  }\r\n\r\n  /** 显示字体设置面板 */\r\n  show(): void {\r\n    this.hide()\r\n\r\n    const container = document.createElement('div')\r\n    container.innerHTML = panelHtml\r\n    this.root = container.firstElementChild as HTMLElement\r\n    translatePanel(this.root, this.translate, 'view.font.')\r\n    document.body.appendChild(this.root)\r\n\r\n    this.fillFontOptions()\r\n    this.fillSizeOptions()\r\n    this.bindTabs()\r\n    this.bindPreview()\r\n    this.fillValues()\r\n    this.root.querySelector('#fw-cancel')!.addEventListener('click', () => this.hide())\r\n    this.root.querySelector('#fw-ok')!.addEventListener('click', () => {\r\n      this.apply()\r\n      this.hide()\r\n    })\r\n  }\r\n\r\n  refreshTranslations(): void {\r\n    if (this.root) translatePanel(this.root, this.translate, 'view.font.')\r\n  }\r\n\r\n  /** 关闭面板 */\r\n  hide(): void {\r\n    if (this.root) { this.root.remove(); this.root = null }\r\n  }\r\n\r\n  /** 填充中文字体下拉选项 */\r\n  private fillFontOptions(): void {\r\n    const cjk = this.root!.querySelector<HTMLSelectElement>('#fw-font-cjk')!\r\n    const opts = FONT_FAMILY_MAP.map(e => {\r\n      const o = document.createElement('option')\r\n      o.value = e.value\r\n      const key = `view.fontFamily.${e.value.replace(/\\s/g, '')}`\r\n      o.textContent = key in viewText ? viewTranslate(this.translate, key) : e.label\r\n      return o\r\n    })\r\n    cjk.append(...opts)\r\n  }\r\n\r\n  /** 填充字号下拉选项 */\r\n  private fillSizeOptions(): void {\r\n    const size = this.root!.querySelector<HTMLSelectElement>('#fw-size')!\r\n    for (const item of FONT_SIZE_LIST) {\r\n      const o = document.createElement('option')\r\n      o.value = String(item)\r\n      const sizeKeys = ['chuhao', 'xiaochu', 'yihao', 'xiaoyi', 'erhao', 'xiaoer', 'sanhao', 'xiaosan', 'sihao', 'xiaosi', 'wuhao', 'xiaowu', 'liuhao', 'xiaoliu', 'qihao', 'bahao']\r\n      const index = FONT_SIZE_LIST.indexOf(item)\r\n      o.textContent = index < sizeKeys.length ? viewTranslate(this.translate, `view.fontSize.${sizeKeys[index]}`) : String(item)\r\n      size.appendChild(o)\r\n    }\r\n  }\r\n\r\n  /** 绑定 Tab 切换 */\r\n  private bindTabs(): void {\r\n    const tabs = this.root!.querySelectorAll<HTMLElement>('.fw-tab')\r\n    const panes = this.root!.querySelectorAll<HTMLElement>('.fw-pane')\r\n    tabs.forEach(tab => {\r\n      tab.addEventListener('click', () => {\r\n        const key = tab.dataset.tab\r\n        tabs.forEach(t => t.classList.toggle('fw-tab-active', t === tab))\r\n        panes.forEach(p => p.classList.toggle('fw-pane-active', p.dataset.pane === key))\r\n      })\r\n    })\r\n  }\r\n\r\n  /** 绑定实时预览 */\r\n  private bindPreview(): void {\r\n    const ids = [\r\n      '#fw-font-cjk', '#fw-style', '#fw-size', '#fw-color',\r\n      '#fw-strikeout', '#fw-underline'\r\n    ]\r\n    for (const id of ids) {\r\n      const el = this.root!.querySelector<HTMLElement>(id)!\r\n      el.addEventListener('input', () => this.updatePreview())\r\n      el.addEventListener('change', () => this.updatePreview())\r\n    }\r\n    const scale = this.root!.querySelector<HTMLElement>('#fw-scale')!\r\n    scale.addEventListener('change', () => this.updatePreviewSpacing())\r\n  }\r\n\r\n  /** 从编辑器读取当前字体状态并填充表单 */\r\n  private fillValues(): void {\r\n    if (!this.onCommand) return\r\n    let style: any = null\r\n    try { style = this.onCommand('getRangeStyle') } catch { /* noop */ }\r\n    if (!style) return\r\n\r\n    const fontValue = style.font || 'SimSun'\r\n    const fontLabel = FONT_FAMILY_LABEL[fontValue] || fontValue\r\n    const fontEntry = FONT_FAMILY_MAP.find(e => e.label === fontLabel)\r\n\r\n    const cjk = this.root!.querySelector<HTMLSelectElement>('#fw-font-cjk')!\r\n    if (fontEntry) {\r\n      cjk.value = fontEntry.value\r\n    }\r\n\r\n    const styleSel = this.root!.querySelector<HTMLSelectElement>('#fw-style')!\r\n    const bold = !!style.bold\r\n    const italic = !!style.italic\r\n    styleSel.value = bold && italic ? 'bold-italic' : bold ? 'bold' : italic ? 'italic' : 'regular'\r\n\r\n    const sizeSel = this.root!.querySelector<HTMLSelectElement>('#fw-size')!\r\n    const pt = Number(style.size) || 10.5\r\n    const cnName = Object.keys(FONT_SIZE).find(k => FONT_SIZE[k] === pt)\r\n    sizeSel.value = cnName ? cnName : String(pt)\r\n    if (!sizeSel.value) sizeSel.value = '五号'\r\n\r\n    const color = this.root!.querySelector<HTMLInputElement>('#fw-color')!\r\n    color.value = style.color || '#000000'\r\n\r\n    const strikeout = this.root!.querySelector<HTMLInputElement>('#fw-strikeout')!\r\n    strikeout.checked = !!style.strikeout\r\n    const underline = this.root!.querySelector<HTMLInputElement>('#fw-underline')!\r\n    underline.checked = !!style.underline\r\n\r\n    const doubleStrikeout = this.root!.querySelector<HTMLInputElement>('#fw-double-strikeout')!\r\n    doubleStrikeout.checked = !!style.doubleStrikeout\r\n    const hidden = this.root!.querySelector<HTMLInputElement>('#fw-hidden')!\r\n    hidden.checked = !!style.hidden\r\n    const superscript = this.root!.querySelector<HTMLInputElement>('#fw-superscript')!\r\n    superscript.checked = !!style.superscript\r\n    const subscript = this.root!.querySelector<HTMLInputElement>('#fw-subscript')!\r\n    subscript.checked = !!style.subscript\r\n\r\n    const scale = this.root!.querySelector<HTMLSelectElement>('#fw-scale')!\r\n    scale.value = String(style.characterScale || 100)\r\n\r\n    this.updatePreview()\r\n    this.updatePreviewSpacing()\r\n  }\r\n\r\n  /** 实时更新字体预览 */\r\n  private updatePreview(): void {\r\n    const preview = this.root!.querySelector<HTMLElement>('#fw-preview')!\r\n    const cjk = this.root!.querySelector<HTMLSelectElement>('#fw-font-cjk')!.value\r\n    const styleVal = this.root!.querySelector<HTMLSelectElement>('#fw-style')!.value\r\n    const sizeVal = this.root!.querySelector<HTMLSelectElement>('#fw-size')!.value\r\n    const color = this.root!.querySelector<HTMLInputElement>('#fw-color')!.value\r\n    const strikeout = this.root!.querySelector<HTMLInputElement>('#fw-strikeout')!.checked\r\n    const underline = this.root!.querySelector<HTMLInputElement>('#fw-underline')!.checked\r\n\r\n    const entry = FONT_FAMILY_MAP.find(e => e.value === cjk)\r\n    preview.style.fontFamily = entry ? entry.css : cjk\r\n    const pt = FONT_SIZE[sizeVal] ?? Number(sizeVal) ?? 14\r\n    preview.style.fontSize = `${pt * 1.5}px`\r\n    preview.style.color = color\r\n    preview.style.fontWeight = (styleVal === 'bold' || styleVal === 'bold-italic') ? 'bold' : 'normal'\r\n    preview.style.fontStyle = (styleVal === 'italic' || styleVal === 'bold-italic') ? 'italic' : 'normal'\r\n    preview.style.textDecoration = [\r\n      underline ? 'underline' : '',\r\n      strikeout ? 'line-through' : ''\r\n    ].filter(Boolean).join(' ') || 'none'\r\n  }\r\n\r\n  /** 实时更新字符间距预览 */\r\n  private updatePreviewSpacing(): void {\r\n    const preview = this.root!.querySelector<HTMLElement>('#fw-preview-spacing')!\r\n    const scale = this.root!.querySelector<HTMLSelectElement>('#fw-scale')!.value\r\n    preview.style.transform = `scaleX(${Number(scale) / 100})`\r\n    preview.style.transformOrigin = 'center'\r\n  }\r\n\r\n  /** 确定按钮：应用所有设置到编辑器 */\r\n  private apply(): void {\r\n    if (!this.onCommand) return\r\n    const cmd = this.onCommand\r\n\r\n    const cjk = this.root!.querySelector<HTMLSelectElement>('#fw-font-cjk')!.value\r\n    cmd('executeSetFont', cjk)\r\n\r\n    const styleVal = this.root!.querySelector<HTMLSelectElement>('#fw-style')!.value\r\n    const bold = styleVal === 'bold' || styleVal === 'bold-italic'\r\n    const italic = styleVal === 'italic' || styleVal === 'bold-italic'\r\n    cmd('executeSetBold', bold)\r\n    cmd('executeSetItalic', italic)\r\n\r\n    const sizeVal = this.root!.querySelector<HTMLSelectElement>('#fw-size')!.value\r\n    const pt = FONT_SIZE[sizeVal] ?? Number(sizeVal)\r\n    if (pt) cmd('executeSetSize', pt)\r\n\r\n    const color = this.root!.querySelector<HTMLInputElement>('#fw-color')!.value\r\n    if (color) cmd('executeSetColor', color)\r\n\r\n    const strikeout = this.root!.querySelector<HTMLInputElement>('#fw-strikeout')!.checked\r\n    cmd('executeSetStrikeout', strikeout)\r\n\r\n    const doubleStrikeout = this.root!.querySelector<HTMLInputElement>('#fw-double-strikeout')!.checked\r\n    cmd('executeSetDoubleStrikeout', doubleStrikeout)\r\n\r\n    const hidden = this.root!.querySelector<HTMLInputElement>('#fw-hidden')!.checked\r\n    cmd('executeSetHidden', hidden)\r\n\r\n    const underline = this.root!.querySelector<HTMLInputElement>('#fw-underline')!.checked\r\n    cmd('executeSetUnderline', underline)\r\n\r\n    const superscript = this.root!.querySelector<HTMLInputElement>('#fw-superscript')!.checked\r\n    if (superscript) cmd('executeSetSuperscript')\r\n\r\n    const subscript = this.root!.querySelector<HTMLInputElement>('#fw-subscript')!.checked\r\n    if (subscript) cmd('executeSetSubscript')\r\n\r\n    const scale = this.root!.querySelector<HTMLSelectElement>('#fw-scale')!.value\r\n    cmd('executeSetCharacterScale', Number(scale))\r\n  }\r\n}\r\n","export default \"<div class=\\\"pw-panel-mask hw-mask\\\">\\r\\n  <div class=\\\"pw-panel hw-panel\\\" role=\\\"dialog\\\" aria-modal=\\\"true\\\" aria-labelledby=\\\"hw-title\\\">\\r\\n    <div class=\\\"pw-panel-title\\\" id=\\\"hw-title\\\" data-i18n-key=\\\"view.paragraph.link\\\">超链接</div>\\r\\n    <div class=\\\"hw-body\\\">\\r\\n      <label for=\\\"hw-text\\\" data-i18n-key=\\\"view.hyperlink.text\\\">显示文字</label>\\r\\n      <input id=\\\"hw-text\\\" type=\\\"text\\\" />\\r\\n      <label for=\\\"hw-url\\\" data-i18n-key=\\\"view.hyperlink.address\\\">链接地址</label>\\r\\n      <input id=\\\"hw-url\\\" type=\\\"url\\\" placeholder=\\\"https://\\\" data-i18n-placeholder=\\\"view.hyperlink.addressPlaceholder\\\" />\\r\\n      <div class=\\\"hw-error\\\" id=\\\"hw-error\\\" role=\\\"alert\\\" aria-live=\\\"polite\\\"></div>\\r\\n    </div>\\r\\n    <div class=\\\"pw-panel-actions\\\">\\r\\n      <button type=\\\"button\\\" id=\\\"hw-cancel\\\" data-i18n-key=\\\"view.common.cancel\\\">取消</button>\\r\\n      <button type=\\\"button\\\" id=\\\"hw-ok\\\" data-i18n-key=\\\"view.common.confirm\\\">确定</button>\\r\\n    </div>\\r\\n  </div>\\r\\n</div>\\r\\n\"","import '../../assets/css/hyperlink-widget.css'\r\nimport panelHtml from '../../assets/components/hyperlink-widget.html?raw'\r\nimport { translatePanel, viewTranslate } from '../../view-i18n'\r\nimport type { ViewTranslate } from '../../view-i18n'\r\nimport type { HyperlinkInsertionError } from '@vervedoc/docx-editor-transform'\r\n\r\nexport class HyperlinkWidget {\r\n  private root: HTMLElement | null = null\r\n  private translate?: ViewTranslate\r\n  setTranslate(translate?: ViewTranslate): void {\r\n    this.translate = translate\r\n  }\r\n\r\n  private t(key: string): string {\r\n    return viewTranslate(this.translate, key)\r\n  }\r\n\r\n  show(text: string, onConfirm: (text: string, url: string) => boolean | HyperlinkInsertionError, onSuccess?: () => void): void {\r\n    this.hide()\r\n    const container = document.createElement('div')\r\n    container.innerHTML = panelHtml\r\n    this.root = container.firstElementChild as HTMLElement\r\n    translatePanel(this.root, this.translate, 'view.')\r\n    document.body.appendChild(this.root)\r\n\r\n    const root = this.root\r\n    const textInput = root.querySelector<HTMLInputElement>('#hw-text')!\r\n    const urlInput = root.querySelector<HTMLInputElement>('#hw-url')!\r\n    const error = root.querySelector<HTMLElement>('#hw-error')!\r\n    const controls: HTMLElement[] = [textInput, urlInput, root.querySelector<HTMLButtonElement>('#hw-cancel')!, root.querySelector<HTMLButtonElement>('#hw-ok')!]\r\n    const setError = (key: string, control: HTMLElement): void => {\r\n      error.dataset.i18nKey = key\r\n      error.textContent = this.t(key)\r\n      control.focus()\r\n    }\r\n    textInput.value = text\r\n    textInput.focus()\r\n    root.querySelector('#hw-cancel')!.addEventListener('click', () => this.hide())\r\n    root.querySelector('#hw-ok')!.addEventListener('click', () => {\r\n      const value = textInput.value\r\n      const url = urlInput.value.trim()\r\n      if (!value.trim()) return setError('view.hyperlink.textRequired', textInput)\r\n      if (!url) return setError('view.hyperlink.addressRequired', urlInput)\r\n      try {\r\n        if (/[\\u0000-\\u0020\\u007F]/.test(url)) return setError('view.hyperlink.addressInvalid', urlInput)\r\n        const protocol = new URL(url).protocol\r\n        if (!['http:', 'https:', 'mailto:', 'tel:', 'ftp:'].includes(protocol)) return setError('view.hyperlink.addressInvalid', urlInput)\r\n      } catch {\r\n        return setError('view.hyperlink.addressInvalid', urlInput)\r\n      }\r\n      const result = onConfirm(value, url)\r\n      if (result === true) {\r\n        this.hide()\r\n        onSuccess?.()\r\n      } else setError(`view.hyperlink.${typeof result === 'string' ? result : 'unsupported'}`, urlInput)\r\n    })\r\n    root.addEventListener('keyup', event => event.stopPropagation())\r\n    root.addEventListener('keypress', event => event.stopPropagation())\r\n    root.addEventListener('keydown', event => {\r\n      event.stopPropagation()\r\n      if (event.key === 'Escape') {\r\n        event.preventDefault()\r\n        this.hide()\r\n      } else if (event.key === 'Enter' && !event.isComposing) {\r\n        event.preventDefault()\r\n        root.querySelector<HTMLButtonElement>('#hw-ok')?.click()\r\n      } else if (event.key === 'Tab') {\r\n        event.preventDefault()\r\n        const index = controls.indexOf(document.activeElement as HTMLElement)\r\n        controls[(index + (event.shiftKey ? controls.length - 1 : 1)) % controls.length].focus()\r\n      }\r\n    })\r\n  }\r\n\r\n  refreshTranslations(): void {\r\n    if (this.root) translatePanel(this.root, this.translate, 'view.')\r\n  }\r\n\r\n  hide(): void {\r\n    this.root?.remove()\r\n    this.root = null\r\n  }\r\n}\r\n","/**\r\n * ParagraphWidget —— 段落格式悬浮 widget\r\n *\r\n * 光标在段落中或鼠标悬浮在段落上时，在首行左侧显示小图标，\r\n * 点击弹出菜单可修改标题类型、对齐方式。\r\n */\r\n\r\nimport type { DocumentLayout, ParagraphBlock, BlockNode } from '../layout-types'\r\nimport type { RangeManager } from '@vervedoc/docx-editor-state'\r\nimport type { Command } from '@vervedoc/docx-editor-transform'\r\nimport type { IPosition, IRangeStyle } from '@vervedoc/docx-editor-schema'\r\nimport { TITLE_LEVEL, ROW_FLEX, comparePosition } from '@vervedoc/docx-editor-schema'\r\nimport { ContextMenu, type MenuItem } from '../context-menu'\r\nimport { ParagraphLayoutWidget } from './layout/paragraph-layout-widget'\r\nimport { FontLayoutWidget } from './layout/font-layout-widget'\r\nimport { HyperlinkWidget } from './layout/hyperlink-widget'\r\nimport { positionHandle } from './handle-position'\r\nimport { viewTranslate, type ViewTranslate } from '../view-i18n'\r\nimport '../assets/css/paragraph-handle-menu.css'\r\n\r\n\r\n/**\r\n * ParagraphWidget 的依赖注入接口\r\n *\r\n * 由外部宿主提供，用于获取编辑器布局、选区、容器信息以及触发命令等。\r\n */\r\nexport interface ParagraphWidgetDeps {\r\n  translate?: ViewTranslate\r\n  /** Whether editing interactions are currently allowed. */\r\n  canEdit: () => boolean\r\n  /** 获取当前文档布局，可能为 null */\r\n  getLayout: () => DocumentLayout | null\r\n  /** 获取当前选区管理器，可能为 null */\r\n  getRange: () => RangeManager | null\r\n  /** 获取编辑器容器在视口中的矩形位置 */\r\n  getContainerRect: () => DOMRect\r\n  /** 获取当前垂直滚动偏移量（像素） */\r\n  getScrollY: () => number\r\n  /** 获取页面水平偏移量（像素） */\r\n  getPageOffsetX: () => number\r\n  /** 触发编辑器命令的回调 */\r\n  onCommand: (cmd: string, ...args: any[]) => any\r\n  /** 根据客户端坐标命中测试，返回位置信息或 null */\r\n  hit: (clientX: number, clientY: number) => IPosition | null\r\n  /** 临时抑制工具栏显示 */\r\n  suppressToolbar: () => void\r\n  /** 让隐藏输入区获焦，以接收后续键盘事件 */\r\n  focusInput: () => void\r\n}\r\n\r\n/**\r\n * 段落格式悬浮 widget\r\n *\r\n * 在段落首行左侧显示拖拽手柄，点击后弹出两行格式菜单，可修改标题级别和对齐方式。\r\n */\r\nexport class ParagraphWidget {\r\n  /** 段落左侧的拖拽手柄 DOM 元素 */\r\n  private handle: HTMLDivElement | null = null\r\n  /** 当前关联的段落块 */\r\n  private currentBlock: ParagraphBlock | null = null\r\n  /** 段落右键菜单控制器 */\r\n  private contextMenu = new ContextMenu()\r\n  /** 段落设置弹出面板 */\r\n  private panel = new ParagraphLayoutWidget()\r\n  /** 字体设置弹出面板 */\r\n  private fontPanel = new FontLayoutWidget()\r\n  private hyperlinkPanel = new HyperlinkWidget()\r\n\r\n  /**\r\n   * 构造 ParagraphWidget 实例\r\n   *\r\n   * @param deps 依赖注入对象\r\n   */\r\n  constructor(private deps: ParagraphWidgetDeps) {\r\n    const onCommand = (cmd: string, ...args: any[]) => {\r\n      if (this.deps.canEdit()) return this.deps.onCommand(cmd, ...args)\r\n    }\r\n    this.panel.setDeps({ onCommand, translate: deps.translate })\r\n    this.fontPanel.setDeps({ onCommand, translate: deps.translate })\r\n    this.hyperlinkPanel.setTranslate(deps.translate)\r\n  }\r\n\r\n  refreshTranslations(): void {\r\n    this.hideMenu()\r\n    if (this.handle) {\r\n      this.handle.title = this.t('view.paragraph.format')\r\n      this.handle.setAttribute('aria-label', this.handle.title)\r\n    }\r\n    this.panel.refreshTranslations()\r\n    this.fontPanel.refreshTranslations()\r\n    this.hyperlinkPanel.refreshTranslations()\r\n  }\r\n\r\n  /**\r\n   * 创建手柄 DOM 并挂载到 document.body\r\n   *\r\n   * 手柄包含一个 drag_indicator 图标，并绑定鼠标悬停、点击等事件。\r\n   */\r\n  create(): void {\r\n    this.handle = document.createElement('div')\r\n    this.handle.className = 'vervedocs-paragraph-handle'\r\n    this.handle.setAttribute('role', 'button')\r\n    this.handle.setAttribute('aria-label', this.t('view.paragraph.format'))\r\n    this.handle.title = this.t('view.paragraph.format')\r\n    Object.assign(this.handle.style, {\r\n      position: 'fixed',\r\n      width: '22px',\r\n      height: '22px',\r\n      background: '#fff',\r\n      border: '1px solid #dcdfe6',\r\n      borderRadius: '4px',\r\n      display: 'none',\r\n      zIndex: '99',\r\n      cursor: 'pointer',\r\n      alignItems: 'center',\r\n      justifyContent: 'center',\r\n      boxShadow: '0 1px 3px rgba(0,0,0,.12)',\r\n      transition: 'background .15s'\r\n    } as CSSStyleDeclaration)\r\n    const icon = document.createElement('span')\r\n    icon.className = 'material-symbols-outlined'\r\n    icon.textContent = 'drag_indicator'\r\n    icon.style.cssText = 'font-size:14px;color:#606266;'\r\n    this.handle.appendChild(icon)\r\n    this.handle.addEventListener('mouseenter', () => { this.handle!.style.background = '#f0f0f0' })\r\n    this.handle.addEventListener('mouseleave', () => { this.handle!.style.background = '#fff' })\r\n    this.handle.addEventListener('mousedown', (e) => { e.preventDefault(); e.stopPropagation() })\r\n    this.handle.addEventListener('click', (e) => { e.preventDefault(); e.stopPropagation(); this.selectParagraph(); this.showMenu() })\r\n    this.handle.addEventListener('dblclick', (e) => { e.preventDefault(); e.stopPropagation() })\r\n    document.body.appendChild(this.handle)\r\n  }\r\n\r\n  /**\r\n   * 根据当前选区更新手柄位置\r\n   *\r\n   * 当光标位于段落中时，将手柄定位到段落首行左侧；否则隐藏手柄。\r\n   */\r\n  update(): void {\r\n    if (!this.deps.canEdit()) {\r\n      this.hide()\r\n      this.panel.hide()\r\n      this.fontPanel.hide()\r\n      this.currentBlock = null\r\n      return\r\n    }\r\n    if (!this.handle) return\r\n    this.handle.title = this.t('view.paragraph.format')\r\n    this.handle.setAttribute('aria-label', this.handle.title)\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) { this.hide(); return }\r\n\r\n    const pos = range.getFocus()\r\n    if (!pos) { this.hide(); return }\r\n\r\n    const block = this.findParagraphBlock(layout, pos)\r\n    if (!block) { this.hide(); return }\r\n\r\n    this.currentBlock = block\r\n    const rect = this.deps.getContainerRect()\r\n    const pageOffsetX = this.deps.getPageOffsetX()\r\n    const scrollY = this.deps.getScrollY()\r\n\r\n    const page = layout.pages.find(p => p.blocks.includes(block as BlockNode))\r\n    if (!page) { this.hide(); return }\r\n\r\n    const firstLine = block.lines[0]\r\n    if (!firstLine) { this.hide(); return }\r\n\r\n    const bx = rect.left + pageOffsetX + page.contentRect.x + block.rect.x\r\n    const by = rect.top - scrollY + page.contentRect.y + block.rect.y + firstLine.y\r\n    if (!positionHandle(this.handle, bx - 34, by + (firstLine.height - 22) / 2, 22, rect)) {\r\n      this.hide()\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 隐藏手柄和菜单\r\n   */\r\n  private hide(): void {\r\n    if (this.handle) this.handle.style.display = 'none'\r\n    this.hideMenu()\r\n  }\r\n\r\n  /**\r\n   * 选中当前段落的所有内容\r\n   *\r\n   * 根据段落首行第一个 inline 和末行最后一个 inline 设置选区范围。\r\n   */\r\n  private selectParagraph(): void {\r\n    if (!this.deps.canEdit()) return\r\n    const range = this.deps.getRange()\r\n    if (!range || !this.currentBlock) return\r\n    const lines = this.currentBlock.lines\r\n    if (!lines.length) return\r\n    const firstLine = lines[0]\r\n    const lastLine = lines[lines.length - 1]\r\n    const firstInline = firstLine.inlines[0]\r\n    const lastInline = lastLine.inlines[lastLine.inlines.length - 1]\r\n    if (!firstInline || !lastInline) return\r\n    this.deps.suppressToolbar()\r\n    range.setRange({\r\n      anchor: { path: firstInline.path, offset: firstInline.startOffset },\r\n      focus: { path: lastInline.path, offset: lastInline.endOffset }\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 在文档布局中查找包含指定位置的段落块\r\n   *\r\n   * @param layout 文档布局\r\n   * @param pos 位置信息\r\n   * @returns 命中的段落块，未找到返回 null\r\n   */\r\n  private findParagraphBlock(layout: DocumentLayout, pos: IPosition): ParagraphBlock | null {\r\n    for (const page of layout.pages) {\r\n      const r = this.findParagraphInBlocks(page.blocks, pos)\r\n      if (r) return r\r\n    }\r\n    return null\r\n  }\r\n\r\n  /**\r\n   * 在块列表中递归查找包含指定位置的段落块\r\n   *\r\n   * 支持在表格单元格内继续递归查找。\r\n   *\r\n   * @param blocks 块列表\r\n   * @param pos 位置信息\r\n   * @returns 命中的段落块，未找到返回 null\r\n   */\r\n  private findParagraphInBlocks(blocks: BlockNode[], pos: IPosition): ParagraphBlock | null {\r\n    for (const b of blocks) {\r\n      if (b.kind === 'paragraph') {\r\n        for (const line of b.lines) {\r\n          for (const inl of line.inlines) {\r\n            if (this.pathContains(inl.path, pos.path)) return b\r\n          }\r\n        }\r\n      } else if (b.kind === 'table') {\r\n        for (const row of b.rows) {\r\n          for (const cell of row.cells) {\r\n            const r = this.findParagraphInBlocks(cell.content, pos)\r\n            if (r) return r\r\n          }\r\n        }\r\n      }\r\n    }\r\n    return null\r\n  }\r\n\r\n  /**\r\n   * 判断 parent 路径是否为 child 路径的前缀\r\n   *\r\n   * @param parent 父路径\r\n   * @param child 子路径\r\n   * @returns 是前缀返回 true，否则返回 false\r\n   */\r\n  private pathContains(parent: IPosition['path'], child: IPosition['path']): boolean {\r\n    if (parent.length > child.length) return false\r\n    for (let i = 0; i < parent.length; i++) {\r\n      if (parent[i] !== child[i]) return false\r\n    }\r\n    return true\r\n  }\r\n\r\n  /**\r\n   * 在手柄下方弹出格式菜单\r\n   *\r\n   * 第一行为正文和 H1-H6，第二行为五种对齐方式。\r\n   * 同时绑定滚动隐藏和点击外部关闭逻辑。\r\n   */\r\n  private t(key: string): string { return viewTranslate(this.deps.translate, key) }\r\n\r\n  private showMenu(): void {\r\n    this.hideMenu()\r\n    if (!this.deps.canEdit()) return\r\n    if (!this.handle || !this.currentBlock) return\r\n\r\n    const style: Partial<IRangeStyle> = this.deps.onCommand('getRangeStyle') ?? {}\r\n    const alignment = style.rowFlex === ROW_FLEX.ALIGNMENT ? ROW_FLEX.JUSTIFY : (style.rowFlex || ROW_FLEX.LEFT)\r\n    const menu = document.createElement('div')\r\n    menu.className = 'ce-paragraph-handle-menu'\r\n    menu.setAttribute('role', 'toolbar')\r\n    menu.setAttribute('aria-label', this.t('view.paragraph.format'))\r\n    menu.addEventListener('mousedown', e => e.preventDefault())\r\n    menu.addEventListener('keydown', e => {\r\n      e.stopPropagation()\r\n      if (e.key === 'Escape') {\r\n        this.hideMenu()\r\n        this.deps.focusInput()\r\n      }\r\n    })\r\n\r\n    const addButton = (label: string, active: boolean, command: keyof Command, value: unknown) => {\r\n      const button = document.createElement('button')\r\n      button.type = 'button'\r\n      button.title = label\r\n      button.setAttribute('aria-label', label)\r\n      button.setAttribute('aria-pressed', String(active))\r\n      button.addEventListener('click', () => {\r\n        this.hideMenu()\r\n        if (!this.deps.canEdit()) return\r\n        this.deps.onCommand(command, value)\r\n        this.deps.focusInput()\r\n      })\r\n      menu.appendChild(button)\r\n      return button\r\n    }\r\n\r\n    const levels = [null, TITLE_LEVEL.FIRST, TITLE_LEVEL.SECOND, TITLE_LEVEL.THIRD, TITLE_LEVEL.FOURTH, TITLE_LEVEL.FIFTH, TITLE_LEVEL.SIXTH]\r\n    const labels = ['body', 'heading1', 'heading2', 'heading3', 'heading4', 'heading5', 'heading6'].map(key => this.t(`view.paragraph.${key}`))\r\n    levels.forEach((level, index) => {\r\n      const button = addButton(labels[index], (style.level ?? null) === level, 'executeSetTitle', level)\r\n      button.className = 'ce-paragraph-handle-menu__heading'\r\n      button.append(index === 0 ? 'T' : 'H')\r\n      if (index > 0) {\r\n        const sub = document.createElement('sub')\r\n        sub.textContent = String(index)\r\n        button.appendChild(sub)\r\n      }\r\n    })\r\n\r\n    const alignments = [\r\n      { label: this.t('view.common.leftAlign'), value: ROW_FLEX.LEFT, path: 'M4 5H19M4 12H12M4 19H19' },\r\n      { label: this.t('view.common.center'), value: ROW_FLEX.CENTER, path: 'M4 5H19M8 12H15M4 19H19' },\r\n      { label: this.t('view.common.rightAlign'), value: ROW_FLEX.RIGHT, path: 'M4 5H19M11 12H19M4 19H19' },\r\n      { label: this.t('view.common.justify'), value: ROW_FLEX.JUSTIFY, path: 'M4 5H19M4 12H19M4 19H19' },\r\n      { label: this.t('view.common.distribute'), value: ROW_FLEX.DISTRIBUTE, path: 'M3 4V20M21 4V20M7 13H17M7 19H17' }\r\n    ]\r\n    for (const item of alignments) {\r\n      const button = addButton(item.label, alignment === item.value, 'executeSetRowFlex', item.value)\r\n      const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\r\n      svg.setAttribute('viewBox', '0 0 24 24')\r\n      svg.setAttribute('aria-hidden', 'true')\r\n      const path = document.createElementNS(svg.namespaceURI, 'path')\r\n      path.setAttribute('d', item.path)\r\n      svg.appendChild(path)\r\n      if (item.value === ROW_FLEX.DISTRIBUTE) {\r\n        const arrows = document.createElementNS(svg.namespaceURI, 'path')\r\n        arrows.setAttribute('d', 'M9 4L7 6L9 8M15 4L17 6L15 8')\r\n        arrows.setAttribute('stroke', '#527bb5')\r\n        svg.appendChild(arrows)\r\n      }\r\n      button.appendChild(svg)\r\n    }\r\n\r\n    const hx = parseFloat(this.handle.style.left)\r\n    const hy = parseFloat(this.handle.style.top)\r\n    this.contextMenu.showContent(hx, hy + 22, menu)\r\n  }\r\n\r\n  /**\r\n   * 隐藏格式菜单及其所有子菜单\r\n   */\r\n  private hideMenu(): void {\r\n    this.contextMenu.hide()\r\n  }\r\n\r\n  /**\r\n   * 显示段落右键菜单。\r\n   *\r\n   * 参照 Word 段落右键菜单，覆盖剪切/复制/粘贴、样式、对齐、缩进、行距、\r\n   * 项目符号/编号、超链接、清除格式、段落对话框等常用功能。\r\n   * 复用 ContextMenu 类，样式与表格右键菜单一致（紧凑）。\r\n   *\r\n   * @param clientX 右键横坐标（视口）\r\n   * @param clientY 右键纵坐标（视口）\r\n   * @returns 命中段落并显示菜单返回 true，否则 false\r\n   */\r\n  showContextMenu(clientX: number, clientY: number): boolean {\r\n    if (!this.deps.canEdit()) return false\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) return false\r\n\r\n    const pos = this.deps.hit(clientX, clientY)\r\n    if (!pos) return false\r\n\r\n    // 表格内选区由 tableWidget 处理，此处跳过\r\n    if (pos.path.length >= 5 && pos.path[1] === 'trList') return false\r\n\r\n    const block = this.findParagraphBlock(layout, pos)\r\n    if (!block) return false\r\n\r\n    const ordered = range.getOrdered()\r\n    if (!ordered || range.isCollapsed() ||\r\n        comparePosition(pos, ordered.start) < 0 || comparePosition(pos, ordered.end) > 0) {\r\n      range.setCaret(pos)\r\n    }\r\n    this.deps.focusInput()\r\n\r\n    const icons = ContextMenu.getIcons()\r\n    const fire = (cmd: keyof Command | 'requestInsertComment', ...args: any[]) => {\r\n      if (this.deps.canEdit()) this.deps.onCommand(cmd, ...args)\r\n    }\r\n\r\n    const items: MenuItem[] = [\r\n      { label: this.t('view.paragraph.cut'), icon: 'content_cut', shortcut: 'Ctrl+X', onClick: () => fire('executeCut') },\r\n      { label: this.t('view.paragraph.copy'), icon: 'content_copy', shortcut: 'Ctrl+C', onClick: () => fire('executeCopy') },\r\n      { label: this.t('view.paragraph.paste'), icon: 'content_paste', shortcut: 'Ctrl+V', onClick: () => fire('executePaste') },\r\n      { label: '---' },\r\n      { label: this.t('view.paragraph.fontSettings'), icon: 'format_size', onClick: () => { if (this.deps.canEdit()) this.fontPanel.show() } },\r\n      { label: this.t('view.paragraph.advancedSettings'), icon: 'subject', onClick: () => { if (this.deps.canEdit()) this.panel.show() } },\r\n      { label: '---' },\r\n      { label: this.t('view.paragraph.link'), icon: icons.link, shortcut: 'Ctrl+K', onClick: () => {\r\n        if (!this.deps.canEdit()) return\r\n        const range = this.deps.getRange()\r\n        const savedRange = range?.getRange()\r\n        if (!range || !savedRange) {\r\n          this.hyperlinkPanel.show('', () => 'noSelection')\r\n          return\r\n        }\r\n        const snapshot = {\r\n          anchor: { path: savedRange.anchor.path.slice(), offset: savedRange.anchor.offset },\r\n          focus: { path: savedRange.focus.path.slice(), offset: savedRange.focus.offset }\r\n        }\r\n        const text = this.deps.onCommand('executeExtractSelectionText') as string || ''\r\n        this.hyperlinkPanel.show(text, (value, url) => {\r\n          range.setRange({\r\n            anchor: { ...snapshot.anchor, path: snapshot.anchor.path.slice() },\r\n            focus: { ...snapshot.focus, path: snapshot.focus.path.slice() }\r\n          })\r\n          const inserted = this.deps.onCommand('executeHyperlink', { url, valueList: [{ type: 'text', value }] })\r\n          return inserted === true ? true : this.deps.onCommand('getHyperlinkInsertionError') ?? false\r\n        }, () => this.deps.focusInput())\r\n      } },\r\n      { label: this.t('view.paragraph.comment'), icon: 'comment', onClick: () => fire('requestInsertComment') },\r\n\r\n    ]\r\n\r\n    this.contextMenu.show(clientX, clientY, items)\r\n    return true\r\n  }\r\n\r\n  /**\r\n   * 隐藏段落右键菜单。\r\n   */\r\n  hideContextMenu(): void {\r\n    this.contextMenu.hide()\r\n  }\r\n\r\n  /**\r\n   * 销毁 widget，移除菜单和手柄 DOM 及相关事件监听\r\n   */\r\n  destroy(): void {\r\n    this.hideMenu()\r\n    this.hideContextMenu()\r\n    this.panel.hide()\r\n    this.fontPanel.hide()\r\n    this.hyperlinkPanel.hide()\r\n    if (this.handle) { this.handle.remove(); this.handle = null }\r\n  }\r\n}\r\n","/**\r\n * HeaderFooterWidget —— 页眉页脚交互 widget\r\n *\r\n * 从 Draw 分离的页眉页脚 UI 交互逻辑：\r\n *  - 双击页眉/页脚区域进入编辑\r\n *  - 双击正文区域退出编辑\r\n *  - 编辑时绘制虚线边框 + 标签栏（左侧 \"页眉 - 第 1 节\" + 居中 \"插入页码\"）\r\n *  - \"插入页码\" 弹出面板：样式 + 位置（左侧 / 居中 / 右侧）+ 确定\r\n *\r\n * 生命周期：create() → renderBorder() → destroy()\r\n */\r\n\r\nimport type { DocumentLayout } from '../layout-types'\r\nimport { viewTranslate, type ViewTranslate } from '../view-i18n'\r\n\r\n/** 文档区域类型：正文 / 页眉 / 页脚 */\r\nexport type Zone = 'main' | 'header' | 'footer'\r\n\r\n/** 页码位置：左侧 / 居中 / 右侧 */\r\nexport type PageNumberPosition = 'left' | 'center' | 'right'\r\n/** 页码样式（对齐 Word 标准） */\r\nexport type PageNumberStyle =\r\n  | '第1页'\r\n  | '第1页共x页'\r\n  | '1/x'\r\n  | '第一页'\r\n  | '第一页共X页'\r\n  | '1, 2, 3 ...'\r\n  | '-1-, -2-, -3- ...'\n  | '—1—, —2—, —3— ...'\n  | '①, ②, ③ ...'\n  | 'I, II, III ...'\r\n  | 'i, ii, iii ...'\r\n  | 'A, B, C ...'\r\n  | 'a, b, c ...'\r\n  | '一, 二, 三 ...'\r\n  | '壹, 贰, 叁 ...'\r\n  | '甲, 乙, 丙 ...'\n  | '子, 丑, 寅 ...'\n  | '壱, 弐, 参 ...'\n  | 'α, β, γ ...'\n  | 'Ⅰ, Ⅱ, Ⅲ ...'\n  | '1st, 2nd, 3rd ...'\n  | 'One, Two, Three ...'\n  | 'First, Second, Third ...'\n\r\n/** 插入页码的配置选项 */\r\nexport interface PageNumberOptions {\r\n  /** 页码样式 */\r\n  style: PageNumberStyle\r\n  /** 页码位置 */\r\n  position: PageNumberPosition\r\n}\r\n\r\n/** HeaderFooterWidget 的依赖注入接口 */\r\nexport interface HeaderFooterWidgetDeps {\r\n  translate?: ViewTranslate\r\n  /** 获取当前文档布局 */\r\n  getLayout: () => DocumentLayout | null\r\n  /** 获取浮层挂载容器，与画布使用相同坐标原点 */\n  getContainer: () => HTMLElement\n  /** 获取容器元素的矩形位置 */\r\n  getContainerRect: () => DOMRect\r\n  /** 获取当前垂直滚动偏移 */\r\n  getScrollY: () => number\r\n  /** 获取编辑区可视宽度 */\r\n  getWrapperWidth: () => number\r\n  /** 获取编辑区可视高度 */\n  getWrapperHeight: () => number\n  /** 获取页面在容器中的水平偏移 */\r\n  getPageOffsetX: () => number\r\n  /** 获取当前所处区域 */\r\n  getZone: () => Zone\r\n  /** 获取当前页眉/页脚编辑所在页 */\n  getActivePageIndex: () => number | null\n  /** 设置当前所处区域 */\r\n  setZone: (zone: Zone) => void\r\n  /** 切换区域并设置初始光标到对应区域起始位置 */\r\n  setZoneWithCaret: (zone: Zone, pageIndex?: number) => void\n  /** 让编辑区获取焦点 */\r\n  focusInput: () => void\r\n  /** 绘制页眉/页脚区域虚线边框 */\r\n  drawZoneBorder: (layout: DocumentLayout, scrollY: number, zone: 'header' | 'footer', pageOffsetX: number) => void\r\n  /** 插入页码回调（可选） */\r\n  onInsertPageNumber?: (options: PageNumberOptions) => void\r\n}\r\n\r\n/** 页眉页脚交互 widget，负责双击进入/退出编辑、虚线边框、标签栏及插入页码面板 */\r\nexport class HeaderFooterWidget {\r\n  /** 编辑区内的裁剪层，避免滚动时控件覆盖外部工具栏 */\n  private layerEl: HTMLDivElement | null = null\n  /** 页眉标签栏容器 */\r\n  private headerLabelEl: HTMLDivElement | null = null\r\n  /** 页脚标签栏容器 */\r\n  private footerLabelEl: HTMLDivElement | null = null\r\n\r\n  /** 居中的\"插入页码\"按钮 */\r\n  private insertBtnEl: HTMLButtonElement | null = null\r\n\r\n  /** 插入页码弹出面板 */\r\n  private popupEl: HTMLDivElement | null = null\r\n  /** 弹出面板是否可见 */\r\n  private popupVisible = false\r\n\r\n  /** 面板内当前选中的页码位置 */\r\n  private selectedPosition: PageNumberPosition = 'center'\r\n  /** 面板内当前选中的页码样式 */\r\n  private selectedStyle: PageNumberStyle = '1, 2, 3 ...'\n  private t(key: string): string { return viewTranslate(this.deps.translate, key) }\r\n\r\n  /** 点击面板外部时隐藏 popup 的全局 mousedown 监听 */\r\n  private onDocumentMouseDown = (e: MouseEvent) => {\r\n    if (!this.popupVisible) return\r\n    const target = e.target as Node\r\n    if (this.popupEl && this.popupEl.contains(target)) return\r\n    if (this.insertBtnEl && this.insertBtnEl.contains(target)) return\r\n    this.hidePopup()\r\n  }\r\n\r\n  /**\r\n   * 创建 HeaderFooterWidget 实例\r\n   * @param deps 依赖注入对象\r\n   */\r\n  constructor(private deps: HeaderFooterWidgetDeps) {}\r\n\r\n  /* -------------------- 生命周期 -------------------- */\r\n\r\n  /** 创建所有 DOM 元素并绑定全局监听 */\r\n  create(): void {\r\n    this.layerEl = document.createElement('div')\n    this.layerEl.className = 'vervedocs-header-footer-layer'\n    this.layerEl.style.cssText = 'position:absolute;left:0;top:0;overflow:hidden;pointer-events:none;z-index:5;display:none;'\n    this.deps.getContainer().appendChild(this.layerEl)\n    this.createLabel()\r\n    this.createInsertButton()\r\n    this.createPopup()\r\n    document.addEventListener('mousedown', this.onDocumentMouseDown, true)\r\n  }\r\n\r\n  refreshTranslations(): void {\r\n    for (const [el, zone] of [[this.headerLabelEl, 'header'], [this.footerLabelEl, 'footer']] as const) {\r\n      const label = el?.querySelector('span')\r\n      if (label) label.textContent = this.t(`view.pageNumber.${zone}`)\r\n    }\r\n    if (this.insertBtnEl) {\r\n      const label = this.t('view.pageNumber.insert')\r\n      this.insertBtnEl.children[1].textContent = label\r\n      this.insertBtnEl.title = label\r\n      this.insertBtnEl.setAttribute('aria-label', label)\r\n    }\r\n    this.popupEl?.querySelectorAll<HTMLElement>('[data-i18n-key]').forEach(el => {\r\n      el.textContent = this.t(el.dataset.i18nKey!)\r\n    })\r\n    this.popupEl?.querySelector('select')?.setAttribute('aria-label', this.t('view.pageNumber.style'))\r\n    if (this.popupVisible) this.positionPopup()\r\n  }\r\n\r\n  /** 销毁 widget：移除全局监听与所有 DOM 元素并清理引用 */\r\n  destroy(): void {\r\n    document.removeEventListener('mousedown', this.onDocumentMouseDown, true)\r\n    this.headerLabelEl?.remove()\r\n    this.footerLabelEl?.remove()\r\n    this.insertBtnEl?.remove()\r\n    this.popupEl?.remove()\r\n    this.layerEl?.remove()\n    this.layerEl = null\n    this.headerLabelEl = null\r\n    this.footerLabelEl = null\r\n    this.insertBtnEl = null\r\n    this.popupEl = null\r\n  }\r\n\r\n  /* -------------------- DOM 构建 -------------------- */\r\n\r\n  /** 创建左侧标签栏 DOM（页眉/页脚 - 第 N 节） */\r\n  private createLabel(): void {\r\n    const make = (text: string): { el: HTMLDivElement; textEl: HTMLSpanElement } => {\r\n      const el = document.createElement('div')\r\n      el.className = 'vervedocs-zone-label'\r\n      Object.assign(el.style, {\r\n        position: 'absolute',\n        display: 'none',\r\n        zIndex: '100',\r\n        alignItems: 'center',\r\n        gap: '6px',\r\n        padding: '2px 10px',\r\n        background: '#e8e8e8',\r\n        border: '1px solid #bfbfbf',\r\n        borderRadius: '0',\r\n        fontSize: '12px',\r\n        color: '#595959',\r\n        userSelect: 'none',\r\n        pointerEvents: 'auto',\r\n        fontFamily: '\"Microsoft YaHei\", \"PingFang SC\", sans-serif',\r\n        boxShadow: 'none',\r\n      } as CSSStyleDeclaration)\r\n      const textEl = document.createElement('span')\r\n      textEl.textContent = text\r\n      el.appendChild(textEl)\r\n      this.layerEl!.appendChild(el)\n      return { el, textEl }\r\n    }\r\n\r\n    const h = make(this.t('view.pageNumber.header'))\r\n    this.headerLabelEl = h.el\r\n    const f = make(this.t('view.pageNumber.footer'))\r\n    this.footerLabelEl = f.el\r\n  }\r\n\r\n  /** 创建居中\"插入页码\"按钮 DOM（含图标、文字、下拉箭头及悬停态） */\r\n  private createInsertButton(): void {\r\n    const btn = document.createElement('button')\r\n    btn.className = 'vervedocs-zone-insert-pagenumber'\r\n    btn.title = this.t('view.pageNumber.insert')\r\n    btn.setAttribute('aria-label', btn.title)\r\n    Object.assign(btn.style, {\r\n      position: 'absolute',\n      display: 'none',\r\n      zIndex: '100',\r\n      alignItems: 'center',\r\n      gap: '4px',\r\n      height: '22px',\r\n      padding: '0 10px',\r\n      background: '#e8e8e8',\r\n      border: '1px solid #bfbfbf',\r\n      borderRadius: '0',\r\n      fontSize: '12px',\r\n      color: '#333333',\r\n      cursor: 'pointer',\r\n      userSelect: 'none',\r\n      pointerEvents: 'auto',\r\n      fontFamily: '\"Microsoft YaHei\", \"PingFang SC\", sans-serif',\r\n      boxShadow: 'none',\r\n    } as CSSStyleDeclaration)\r\n\r\n    // 左侧图标（灰色页码 icon，统一色调）\r\n    const icon = document.createElement('span')\r\n    icon.innerHTML =\r\n      '<svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">' +\r\n      '<rect x=\"2\" y=\"1.5\" width=\"10\" height=\"11\" rx=\"1\" stroke=\"#333333\" stroke-width=\"1\"/>' +\r\n      '<text x=\"7\" y=\"9.5\" text-anchor=\"middle\" font-size=\"6.5\" fill=\"#333333\" font-family=\"Arial\" font-weight=\"600\">1</text>' +\r\n      '</svg>'\r\n    icon.style.display = 'inline-flex'\r\n    icon.style.alignItems = 'center'\r\n    btn.appendChild(icon)\r\n\r\n    const label = document.createElement('span')\r\n    label.textContent = this.t('view.pageNumber.insert')\r\n    label.style.color = '#333333'\r\n    btn.appendChild(label)\r\n\r\n    const caret = document.createElement('span')\r\n    caret.textContent = '▾'\r\n    caret.style.fontSize = '10px'\r\n    caret.style.color = '#595959'\r\n    caret.style.marginLeft = '2px'\r\n    btn.appendChild(caret)\r\n\r\n    btn.addEventListener('mouseenter', () => { btn.style.background = '#dcdcdc'; btn.style.borderColor = '#a6a6a6' })\r\n    btn.addEventListener('mouseleave', () => { btn.style.background = '#e8e8e8'; btn.style.borderColor = '#bfbfbf' })\r\n    btn.addEventListener('click', (e) => {\r\n      e.stopPropagation()\r\n      this.togglePopup()\r\n    })\r\n\r\n    this.insertBtnEl = btn\r\n    this.layerEl!.appendChild(btn)\n  }\r\n\r\n  /** 创建插入页码弹出面板 DOM（样式选择 + 位置预览 + 确定按钮） */\r\n  private createPopup(): void {\r\n    const popup = document.createElement('div')\r\n    popup.className = 'ce-zone-pagenumber-menu'\r\n    Object.assign(popup.style, {\r\n      position: 'absolute',\n      display: 'none',\r\n      zIndex: '1000',\r\n      width: '244px',\r\n      padding: '10px 14px 12px',\r\n      background: '#ffffff',\r\n      border: '1px solid #d9d9d9',\r\n      borderRadius: '5px',\r\n      boxShadow: '0 4px 14px rgba(0, 0, 0, 0.12)',\r\n      fontFamily: '\"Microsoft YaHei\", \"PingFang SC\", sans-serif',\r\n      userSelect: 'none',\r\n      pointerEvents: 'auto',\n    } as CSSStyleDeclaration)\r\n\r\n    // -------- 样式 --------\r\n    const styleRow = document.createElement('div')\r\n    Object.assign(styleRow.style, {\r\n      display: 'flex',\r\n      alignItems: 'center',\r\n      marginBottom: '10px',\r\n    } as CSSStyleDeclaration)\r\n\r\n    const styleLabel = document.createElement('span')\r\n    styleLabel.dataset.i18nKey = 'view.pageNumber.style'\r\n    styleLabel.textContent = this.t('view.pageNumber.style')\r\n    Object.assign(styleLabel.style, {\r\n      width: '40px',\r\n      fontSize: '12px',\r\n      color: '#1f1f1f',\r\n      flexShrink: '0',\r\n    } as CSSStyleDeclaration)\r\n    styleRow.appendChild(styleLabel)\r\n\r\n    const styleSelect = document.createElement('select')\r\n    styleSelect.setAttribute('aria-label', this.t('view.pageNumber.style'))\r\n    Object.assign(styleSelect.style, {\r\n      flex: '1',\r\n      height: '26px',\r\n      padding: '0 8px',\r\n      fontSize: '12px',\r\n      color: '#1f1f1f',\r\n      background: '#ffffff',\r\n      border: '1px solid #cfcfcf',\r\n      borderRadius: '3px',\r\n      outline: 'none',\r\n      cursor: 'pointer',\r\n    } as CSSStyleDeclaration)\r\n    const styleOptions: PageNumberStyle[] = [\r\n      '1, 2, 3 ...',\r\n      '-1-, -2-, -3- ...',\n      '—1—, —2—, —3— ...',\n      'I, II, III ...',\r\n      '第1页',\n      '第1页共x页',\n      '1/x',\n      '第一页',\n      '第一页共X页',\n      '①, ②, ③ ...',\n      '一, 二, 三 ...',\n      '壹, 贰, 叁 ...',\n      'i, ii, iii ...',\r\n      'A, B, C ...',\r\n      'a, b, c ...',\r\n      '甲, 乙, 丙 ...',\n      '子, 丑, 寅 ...',\n      '壱, 弐, 参 ...',\n      'α, β, γ ...',\n      'Ⅰ, Ⅱ, Ⅲ ...',\n      '1st, 2nd, 3rd ...',\n      'One, Two, Three ...',\n      'First, Second, Third ...',\n    ]\r\n    styleOptions.forEach((s) => {\r\n      const opt = document.createElement('option')\r\n      opt.value = s\r\n      const styleKeys: Partial<Record<PageNumberStyle, string>> = {\r\n        '第1页': 'stylePage', '第1页共x页': 'styleTotal',\r\n        '第一页': 'styleFirst', '第一页共X页': 'styleFirstTotal'\r\n      }\r\n      if (styleKeys[s]) opt.dataset.i18nKey = `view.pageNumber.${styleKeys[s]}`\r\n      opt.textContent = styleKeys[s] ? this.t(`view.pageNumber.${styleKeys[s]}`) : s\r\n      styleSelect.appendChild(opt)\r\n    })\r\n    styleSelect.value = this.selectedStyle\r\n    styleSelect.addEventListener('change', () => {\r\n      this.selectedStyle = styleSelect.value as PageNumberStyle\r\n    })\r\n    styleRow.appendChild(styleSelect)\r\n    popup.appendChild(styleRow)\r\n\r\n    // -------- 位置 --------\r\n    const posTitle = document.createElement('div')\r\n    posTitle.dataset.i18nKey = 'view.pageNumber.position'\r\n    posTitle.textContent = this.t('view.pageNumber.position')\r\n    Object.assign(posTitle.style, {\r\n      fontSize: '12px',\r\n      color: '#1f1f1f',\r\n      marginBottom: '6px',\r\n    } as CSSStyleDeclaration)\r\n    popup.appendChild(posTitle)\r\n\r\n    const posRow = document.createElement('div')\r\n    Object.assign(posRow.style, {\r\n      display: 'flex',\r\n      gap: '12px',\r\n      justifyContent: 'center',\n      marginBottom: '12px',\r\n    } as CSSStyleDeclaration)\r\n\r\n    const positions: Array<{ value: PageNumberPosition; text: string }> = [\r\n      { value: 'left', text: this.t('view.pageNumber.left') },\r\n      { value: 'center', text: this.t('view.pageNumber.center') },\r\n      { value: 'right', text: this.t('view.pageNumber.right') },\r\n    ]\r\n\r\n    const posItems: Array<{ value: PageNumberPosition; el: HTMLDivElement; preview: HTMLDivElement }> = []\r\n\r\n    positions.forEach(({ value, text }) => {\r\n      const item = document.createElement('div')\r\n      Object.assign(item.style, {\r\n        display: 'inline-flex',\r\n        flexDirection: 'column',\r\n        alignItems: 'center',\r\n        gap: '4px',\r\n        cursor: 'pointer',\r\n      } as CSSStyleDeclaration)\r\n\r\n      const preview = document.createElement('div')\r\n      Object.assign(preview.style, {\r\n        position: 'relative',\r\n        display: 'flex',\r\n        flexDirection: 'column',\r\n        width: '40px',\r\n        height: '54px',\r\n        padding: '7px 5px',\r\n        background: '#ffffff',\r\n        border: '1px solid #dddddd',\r\n        borderRadius: '3px',\r\n        boxSizing: 'border-box',\r\n      } as CSSStyleDeclaration)\r\n\r\n      // 顶部数字\r\n      const num = document.createElement('span')\r\n      num.textContent = '1'\r\n      Object.assign(num.style, {\r\n        position: 'absolute',\r\n        top: '3px',\r\n        fontSize: '8px',\r\n        lineHeight: '1',\r\n        color: '#666666',\r\n      } as CSSStyleDeclaration)\r\n      if (value === 'left') { num.style.left = '5px' }\r\n      else if (value === 'right') { num.style.right = '5px' }\r\n      else { num.style.left = '50%'; num.style.transform = 'translateX(-50%)' }\r\n      preview.appendChild(num)\r\n\r\n      // 页内假的文本行\r\n      for (let i = 0; i < 5; i++) {\r\n        const line = document.createElement('div')\r\n        Object.assign(line.style, {\r\n          height: '2px',\r\n          marginTop: i === 0 ? '14px' : '3px',\r\n          background: '#dadada',\r\n          borderRadius: '999px',\r\n          width: i === 4 ? '70%' : '100%',\r\n        } as CSSStyleDeclaration)\r\n        preview.appendChild(line)\r\n      }\r\n\r\n      const textEl = document.createElement('span')\r\n      textEl.dataset.i18nKey = `view.pageNumber.${value}`\r\n      textEl.textContent = text\r\n      Object.assign(textEl.style, {\r\n        fontSize: '11px',\r\n        color: '#1f1f1f',\r\n      } as CSSStyleDeclaration)\r\n\r\n      item.appendChild(preview)\r\n      item.appendChild(textEl)\r\n      item.addEventListener('click', () => {\r\n        this.selectedPosition = value\r\n\r\n        // 更新所有项高亮\r\n        posItems.forEach((it) => {\r\n          const isActive = it.value === value\r\n          it.preview.style.background = isActive ? '#ececec' : '#ffffff'\r\n          it.preview.style.borderColor = isActive ? '#d6d6d6' : '#dddddd'\r\n          const t = it.el.querySelector('span:last-child') as HTMLSpanElement | null\r\n          if (t) t.style.color = isActive ? '#1677ff' : '#1f1f1f'\r\n        })\r\n      })\r\n\r\n      posRow.appendChild(item)\r\n      posItems.push({ value, el: item, preview })\r\n    })\r\n    popup.appendChild(posRow)\r\n\r\n    // 初始化默认选中\r\n    posItems.forEach((it) => {\r\n      const isActive = it.value === this.selectedPosition\r\n      it.preview.style.background = isActive ? '#ececec' : '#ffffff'\r\n      it.preview.style.borderColor = isActive ? '#d6d6d6' : '#dddddd'\r\n      const t = it.el.querySelector('span:last-child') as HTMLSpanElement | null\r\n      if (t) t.style.color = isActive ? '#1677ff' : '#1f1f1f'\r\n    })\r\n\r\n    // -------- 确定 --------\r\n    const footer = document.createElement('div')\r\n    Object.assign(footer.style, {\r\n      display: 'flex',\r\n      justifyContent: 'flex-end',\r\n      marginTop: '4px',\r\n    } as CSSStyleDeclaration)\r\n\r\n    const confirmBtn = document.createElement('button')\r\n    confirmBtn.dataset.i18nKey = 'view.common.confirm'\r\n    confirmBtn.textContent = this.t('view.common.confirm')\r\n    Object.assign(confirmBtn.style, {\r\n      minWidth: '58px',\r\n      height: '26px',\r\n      padding: '0 14px',\r\n      fontSize: '12px',\r\n      color: '#ffffff',\r\n      background: '#1677ff',\r\n      border: '1px solid #1677ff',\r\n      borderRadius: '3px',\r\n      cursor: 'pointer',\r\n    } as CSSStyleDeclaration)\r\n    confirmBtn.addEventListener('mouseenter', () => {\r\n      confirmBtn.style.background = '#4096ff'\r\n      confirmBtn.style.borderColor = '#4096ff'\r\n    })\r\n    confirmBtn.addEventListener('mouseleave', () => {\r\n      confirmBtn.style.background = '#1677ff'\r\n      confirmBtn.style.borderColor = '#1677ff'\r\n    })\r\n    confirmBtn.addEventListener('click', (e) => {\r\n      e.stopPropagation()\r\n      this.deps.onInsertPageNumber?.({\r\n        style: this.selectedStyle,\r\n        position: this.selectedPosition,\r\n      })\r\n      this.hidePopup()\r\n    })\r\n    footer.appendChild(confirmBtn)\r\n    popup.appendChild(footer)\r\n\r\n    this.popupEl = popup\r\n    this.layerEl!.appendChild(popup)\n  }\r\n\r\n\r\n  /* -------------------- 交互 -------------------- */\r\n\r\n  /**\r\n   * 处理 mousedown 事件中的页眉/页脚交互逻辑（参照 Word 标准）。\r\n   * - 双击页眉/页脚区域：进入对应区域编辑并设置初始光标\r\n   * - 双击正文区域：若当前处于页眉/页脚编辑，切回正文\r\n   * - 单击页眉/页脚区域：若当前处于页眉/页脚编辑，切换到对应区域并命中\r\n   * - 单击正文区域：若当前处于页眉/页脚编辑，拦截事件（正文不可编辑不可选中）\r\n   * 返回 true 表示已处理（Draw 应跳过后续 hit/选词逻辑）。\r\n   * @param e 鼠标事件\r\n   * @returns 是否已处理该事件\r\n   */\r\n  handleMouseDown(e: MouseEvent): boolean {\r\n    const layout = this.deps.getLayout()\r\n    if (!layout) return false\r\n    const rect = this.deps.getContainerRect()\r\n    const docY = e.clientY - rect.top + this.deps.getScrollY()\r\n    const page = this.pageAtY(docY)\n    const hitZone = this.hitZone(docY)\r\n    const currentZone = this.deps.getZone()\r\n    // 双击页眉/页脚：进入对应区域编辑\r\n    if (e.detail === 2 && (hitZone === 'header' || hitZone === 'footer')) {\r\n      this.deps.setZoneWithCaret(hitZone, page?.index)\n      return true\r\n    }\r\n    // 双击正文 + 当前在页眉/页脚：切回正文\r\n    if (e.detail === 2 && hitZone === 'main' && currentZone !== 'main') {\r\n      this.hidePopup()\r\n      this.deps.setZone('main')\r\n      this.deps.focusInput()\r\n      return true\r\n    }\r\n    // 当前处于页眉/页脚编辑模式\r\n    if (currentZone !== 'main') {\r\n      // 单击页眉/页脚区域：切换到对应区域，让后续 hit 在对应 zone 中命中\r\n      if (hitZone === 'header' || hitZone === 'footer') {\r\n        // 双击的第一次单击也必须同步重置选区，不能只提前改掉活动页码。\n        if (hitZone !== currentZone || page?.index !== this.deps.getActivePageIndex()) {\n          this.deps.setZoneWithCaret(hitZone, page?.index)\n        }\r\n        return false\r\n      }\r\n      // 单击正文区域：拦截事件，正文不可编辑不可选中\r\n      return true\r\n    }\r\n    return false\r\n  }\r\n\r\n\r\n  /**\r\n   * 判断文档坐标 docY 落在哪个区域\r\n   * @param docY 文档纵向坐标\r\n   * @returns 命中的区域类型\r\n   */\r\n  hitZone(docY: number): Zone {\r\n    const layout = this.deps.getLayout()\r\n    if (!layout) return 'main'\r\n    const page = this.pageAtY(docY)\n    if (!page) return 'main'\n    if (page.headerRect && docY >= page.headerRect.y && docY <= page.headerRect.y + page.headerRect.height) return 'header'\n    if (page.footerRect && docY >= page.footerRect.y && docY <= page.footerRect.y + page.footerRect.height) return 'footer'\n    return 'main'\n  }\n\n  /** 根据文档纵坐标查找命中的页面 */\n  private pageAtY(docY: number) {\n    return this.deps.getLayout()?.pages.find(page =>\n      docY >= page.rect.y && docY <= page.rect.y + page.rect.height\n    )\n  }\r\n\r\n  /**\r\n   * 渲染 zone 边框 + 更新标签栏（在 overlay clearOverlay 之后调用）\r\n   * 页眉/页脚编辑模式下同时绘制两个区域的虚线边框（Word 标准行为）\r\n   */\r\n  renderBorder(): void {\r\n    const layout = this.deps.getLayout()\r\n    const zone = this.deps.getZone()\r\n    if (!this.layerEl) return\n\r\n    if (!layout || zone === 'main') {\n      this.layerEl.style.display = 'none'\n      this.hideLabel()\r\n      this.hideInsertButton()\r\n      this.hidePopup()\r\n      return\r\n    }\r\n\r\n    this.layerEl.style.width = `${this.deps.getWrapperWidth()}px`\n    this.layerEl.style.height = `${this.deps.getWrapperHeight()}px`\n    this.layerEl.style.display = 'block'\n\n    // 同时绘制页眉和页脚的虚线边框\r\n    this.deps.drawZoneBorder(layout, this.deps.getScrollY(), 'header', this.deps.getPageOffsetX())\r\n    this.deps.drawZoneBorder(layout, this.deps.getScrollY(), 'footer', this.deps.getPageOffsetX())\r\n\r\n    // 同时更新页眉和页脚标签\r\n    this.updateLabelForZone(layout, 'header')\r\n    this.updateLabelForZone(layout, 'footer')\r\n    // 居中\"插入页码\"按钮跟随当前激活区域\r\n    this.updateInsertButton(layout, zone)\r\n    // 若 popup 显示中，同步跟随按钮位置\r\n    if (this.popupVisible) this.positionPopup()\r\n  }\r\n\r\n  /**\r\n   * 更新指定区域标签栏的位置与文本\r\n   * @param layout 文档布局\r\n   * @param zone 区域（header / footer）\r\n   */\r\n  private updateLabelForZone(layout: DocumentLayout, zone: 'header' | 'footer'): void {\r\n    const el = zone === 'header' ? this.headerLabelEl : this.footerLabelEl\r\n    if (!el) return\r\n    el.querySelector('span')!.textContent = this.t(`view.pageNumber.${zone}`)\r\n    const page = this.getActivePage(layout)\n    const rect = zone === 'header' ? page?.headerRect : page?.footerRect\n    if (!page || !rect) { el.style.display = 'none'; return }\n\r\n    const pageOffsetX = this.deps.getPageOffsetX()\r\n    const scrollY = this.deps.getScrollY()\r\n\r\n    // 分隔虚线的 y（页眉：headerRect 下沿；页脚：footerRect 上沿）\r\n    const dividerDocY = zone === 'header' ? rect.y + rect.height : rect.y\r\n    const dividerY = dividerDocY - scrollY\n\r\n    // 标签贴在页面左边缘（页边距之外）并向右微移，与虚线对齐\r\n    const x = page.rect.x + pageOffsetX + 24\n    // 先显示再测量，避免首次显示页脚标签时高度为零。\n    el.style.display = 'flex'\n    const labelY = zone === 'header'\r\n      ? dividerY + 1\n      : dividerY - el.offsetHeight - 1\n\r\n    el.style.left = `${x}px`\n    el.style.top = `${labelY}px`\r\n    if (!this.isInsideViewport(el)) el.style.display = 'none'\n  }\r\n\r\n  /**\r\n   * 更新居中\"插入页码\"按钮的位置（横向居中于页面，纵向贴齐虚线）\r\n   * @param layout 文档布局\r\n   * @param zone 当前区域（header / footer）\r\n   */\r\n  private updateInsertButton(layout: DocumentLayout, zone: 'header' | 'footer'): void {\r\n    if (!this.insertBtnEl) return\r\n    const label = this.t('view.pageNumber.insert')\r\n    this.insertBtnEl.children[1].textContent = label\r\n    this.insertBtnEl.title = label\r\n    this.insertBtnEl.setAttribute('aria-label', label)\r\n    const page = this.getActivePage(layout)\n    const rect = zone === 'header' ? page?.headerRect : page?.footerRect\n    if (!rect) {\n      this.hideInsertButton()\n      this.hidePopup()\n      return\n    }\n\r\n    const pageOffsetX = this.deps.getPageOffsetX()\r\n    const scrollY = this.deps.getScrollY()\r\n\r\n    // 先显示以便可以拿到宽度\r\n    this.insertBtnEl.style.display = 'inline-flex'\r\n\r\n    // 居中于页面（沿页面横向中点）\r\n    const pageCenterX = rect.x + pageOffsetX + rect.width / 2\n    const btnWidth = this.insertBtnEl.offsetWidth\r\n    const left = pageCenterX - btnWidth / 2\r\n\r\n    // 与虚线对齐：按钮紧贴虚线（页眉时在下方，页脚时在上方）\r\n    const dividerDocY = zone === 'header' ? rect.y + rect.height : rect.y\r\n    const dividerY = dividerDocY - scrollY\n    const btnHeight = this.insertBtnEl.offsetHeight\r\n    const top = zone === 'header'\r\n      ? dividerY + 1\n      : dividerY - btnHeight - 1\n\r\n    this.insertBtnEl.style.left = `${left}px`\r\n    this.insertBtnEl.style.top = `${top}px`\r\n    if (!this.isInsideViewport(this.insertBtnEl)) {\n      this.hideInsertButton()\n      this.hidePopup()\n    }\n  }\n\n  /** 控件必须完整处于编辑视口内，滚出后不保留可点击的残片。 */\n  private isInsideViewport(el: HTMLElement): boolean {\n    return el.offsetLeft >= 0 && el.offsetTop >= 0 &&\n      el.offsetLeft + el.offsetWidth <= this.deps.getWrapperWidth() &&\n      el.offsetTop + el.offsetHeight <= this.deps.getWrapperHeight()\n  }\r\n\n  /** 获取当前激活页，未设置时回退到第一页 */\n  private getActivePage(layout: DocumentLayout) {\n    const pageIndex = this.deps.getActivePageIndex()\n    return pageIndex == null\n      ? layout.pages[0]\n      : layout.pages.find(page => page.index === pageIndex) ?? layout.pages[0]\n  }\n\r\n  /** 隐藏所有标签栏 */\r\n  private hideLabel(): void {\r\n    if (this.headerLabelEl) this.headerLabelEl.style.display = 'none'\r\n    if (this.footerLabelEl) this.footerLabelEl.style.display = 'none'\r\n  }\r\n\r\n  /** 隐藏\"插入页码\"按钮 */\r\n  private hideInsertButton(): void {\r\n    if (this.insertBtnEl) this.insertBtnEl.style.display = 'none'\r\n  }\r\n\r\n  /* -------------------- 弹出面板 -------------------- */\r\n\r\n  /** 切换弹出面板的显示/隐藏状态 */\r\n  private togglePopup(): void {\r\n    if (this.popupVisible) this.hidePopup()\r\n    else this.showPopup()\r\n  }\r\n\r\n  /** 显示弹出面板并定位 */\r\n  private showPopup(): void {\r\n    if (!this.popupEl || !this.insertBtnEl || this.insertBtnEl.style.display === 'none') return\n    for (const node of Array.from(this.popupEl.querySelectorAll<HTMLElement>('[data-i18n-key]'))) {\r\n      node.textContent = this.t(node.dataset.i18nKey!)\r\n    }\r\n    this.popupEl.querySelector('select')!.setAttribute('aria-label', this.t('view.pageNumber.style'))\r\n    this.popupEl.style.display = 'block'\r\n    this.popupVisible = true\r\n    this.positionPopup()\r\n  }\r\n\r\n  /** 隐藏弹出面板 */\r\n  private hidePopup(): void {\r\n    if (!this.popupEl) return\r\n    this.popupEl.style.display = 'none'\r\n    this.popupVisible = false\r\n  }\r\n\r\n  /** 根据按钮位置计算弹出面板坐标，含越界翻转处理 */\r\n  private positionPopup(): void {\r\n    if (!this.popupEl || !this.insertBtnEl) return\r\n    if (this.insertBtnEl.style.display === 'none' || !this.isInsideViewport(this.insertBtnEl)) {\n      this.hidePopup()\n      return\n    }\n    const btn = this.insertBtnEl\n    const popupWidth = this.popupEl.offsetWidth\r\n    const popupHeight = this.popupEl.offsetHeight\r\n\r\n    let left = btn.offsetLeft + btn.offsetWidth / 2 - popupWidth / 2\n    let top = btn.offsetTop + btn.offsetHeight + 6\n\r\n    // 以编辑区而非浏览器窗口为边界，空间不足时关闭面板。\n    const vw = this.deps.getWrapperWidth()\n    const vh = this.deps.getWrapperHeight()\n    if (popupWidth > vw - 8) { this.hidePopup(); return }\n    left = Math.max(4, Math.min(left, vw - popupWidth - 4))\n    if (top + popupHeight > vh - 4) {\r\n      // 若下方空间不足，则显示在按钮上方\r\n      top = btn.offsetTop - popupHeight - 6\n    }\r\n    if (top < 4) { this.hidePopup(); return }\n\r\n    this.popupEl.style.left = `${left}px`\r\n    this.popupEl.style.top = `${top}px`\r\n  }\r\n}\r\n","import type { DocumentLayout } from '../layout-types'\r\n\r\nconst PX_PER_CM = 96 / 2.54\r\nconst RULER_SIZE = 27\r\nconst BAND_START = 3\r\nconst BAND_SIZE = 17\r\nconst BACKGROUND = '#e2e2e2'\r\nconst MARGIN_BACKGROUND = '#d6d6d6'\r\nconst BORDER = '#bcbcbc'\r\n\r\n/** Positions relative to the paragraph's available content area, in document pixels. */\r\nexport interface RulerIndent {\r\n  first: number\r\n  left: number\r\n  right: number\r\n}\r\n\r\nexport interface RulerWidgetDeps {\r\n  container: HTMLDivElement\r\n  getLayout: () => DocumentLayout | null\r\n  getScrollY: () => number\r\n  getWrapperWidth: () => number\r\n  getWrapperHeight: () => number\r\n  getPageOffsetX: () => number\r\n  getScale: () => number\r\n  getPageMargins: () => [number, number, number, number]\r\n  getParagraphIndent: () => RulerIndent | null\r\n  onCommand: (cmd: string, ...args: any[]) => void\r\n}\r\n\r\ntype MarginSide = 'left' | 'right' | 'top' | 'bottom'\r\ntype IndentSide = 'first' | 'hanging' | 'indent' | 'end'\r\ntype Handle = MarginSide | IndentSide\r\nconst MARGINS: MarginSide[] = ['left', 'right', 'top', 'bottom']\r\nconst INDENTS: IndentSide[] = ['first', 'hanging', 'indent', 'end']\r\n\r\n/** Compact Word-style rulers. All screen positions use the rendered page geometry. */\r\nexport class RulerWidget {\r\n  private hRuler: HTMLDivElement | null = null\r\n  private vRuler: HTMLDivElement | null = null\r\n  private hCanvas: HTMLCanvasElement | null = null\r\n  private vCanvas: HTMLCanvasElement | null = null\r\n  private corner: HTMLDivElement | null = null\r\n  private markers = new Map<Handle, HTMLDivElement>()\r\n  private drag: { side: Handle; start: number; indent: RulerIndent | null; pageIndex: number } | null = null\r\n  private visible = false\r\n\r\n  constructor(private deps: RulerWidgetDeps) {}\r\n\r\n  create(): void {\r\n    const createRuler = (horizontal: boolean): [HTMLDivElement, HTMLCanvasElement] => {\r\n      const ruler = document.createElement('div')\r\n      ruler.className = `vervedocs-ruler-${horizontal ? 'horizontal' : 'vertical'}`\r\n      Object.assign(ruler.style, {\r\n        position: 'absolute', top: '0', left: '0', zIndex: horizontal ? '6' : '5',\r\n        background: BACKGROUND, pointerEvents: 'none', overflow: 'hidden',\r\n        ...(horizontal ? { right: '0', height: `${RULER_SIZE}px` } : { bottom: '0', width: `${RULER_SIZE}px` })\r\n      })\r\n      const canvas = document.createElement('canvas')\r\n      canvas.style.cssText = 'width:100%;height:100%;display:block;'\r\n      ruler.appendChild(canvas)\r\n      this.deps.container.appendChild(ruler)\r\n      return [ruler, canvas]\r\n    }\r\n    ;[this.hRuler, this.hCanvas] = createRuler(true)\r\n    ;[this.vRuler, this.vCanvas] = createRuler(false)\r\n    this.corner = document.createElement('div')\r\n    this.corner.style.cssText = `position:absolute;top:0;left:0;width:${RULER_SIZE}px;height:${RULER_SIZE}px;background:${BACKGROUND};z-index:8;pointer-events:none;`\r\n    this.deps.container.appendChild(this.corner)\r\n\r\n    for (const side of [...MARGINS, ...INDENTS]) {\r\n      const marker = this.createMarker(side)\r\n      this.markers.set(side, marker)\r\n      this.deps.container.appendChild(marker)\r\n    }\r\n    this.applyVisible()\r\n  }\r\n\r\n  private createMarker(side: Handle): HTMLDivElement {\r\n    const marker = document.createElement('div')\r\n    const vertical = side === 'top' || side === 'bottom'\r\n    const isMargin = MARGINS.includes(side as MarginSide)\r\n    marker.dataset.rulerHandle = side\r\n    const titles: Record<Handle, string> = {\r\n      left: '左页边距', right: '右页边距', top: '上页边距', bottom: '下页边距',\r\n      first: '首行缩进', hanging: '悬挂缩进', indent: '左缩进', end: '右缩进'\r\n    }\r\n    marker.title = titles[side]\r\n    Object.assign(marker.style, {\r\n      position: 'absolute', zIndex: isMargin ? '6' : '7', pointerEvents: 'auto',\r\n      cursor: vertical ? 'ns-resize' : 'ew-resize', touchAction: 'none',\r\n      // Keep a grab area outside the indent handles when they share the margin.\r\n      width: vertical ? `${BAND_SIZE}px` : isMargin ? '20px' : '12px',\r\n      height: vertical ? '6px' : isMargin ? `${BAND_SIZE}px` : side === 'indent' ? '6px' : '12px',\r\n      ...(vertical ? { left: `${BAND_START}px` } : {\r\n        top: `${isMargin ? BAND_START : side === 'first' ? 0 : side === 'indent' ? 20 : 9}px`\r\n      })\r\n    })\r\n    if (!isMargin) {\r\n      const canvas = document.createElement('canvas')\r\n      const height = side === 'indent' ? 6 : 12\r\n      const dpr = window.devicePixelRatio || 1\r\n      canvas.width = Math.round(12 * dpr)\r\n      canvas.height = Math.round(height * dpr)\r\n      canvas.style.cssText = `display:block;width:12px;height:${height}px;pointer-events:none;`\r\n      const ctx = canvas.getContext('2d')!\r\n      ctx.scale(dpr, dpr)\r\n      ctx.fillStyle = '#fff'\r\n      ctx.strokeStyle = '#666'\r\n      ctx.lineWidth = 1\r\n      ctx.beginPath()\r\n      if (side === 'indent') {\r\n        ctx.rect(0.5, 0.5, 11, 5)\r\n      } else if (side === 'first') {\r\n        ctx.moveTo(0.5, 0.5)\r\n        ctx.lineTo(11.5, 0.5)\r\n        ctx.lineTo(11.5, 4.5)\r\n        ctx.lineTo(6, 11.5)\r\n        ctx.lineTo(0.5, 4.5)\r\n        ctx.closePath()\r\n      } else {\r\n        ctx.moveTo(6, 0.5)\r\n        ctx.lineTo(11.5, 6.5)\r\n        ctx.lineTo(11.5, 10.5)\r\n        ctx.lineTo(0.5, 10.5)\r\n        ctx.lineTo(0.5, 6.5)\r\n        ctx.closePath()\r\n      }\r\n      ctx.fill()\r\n      ctx.stroke()\r\n      marker.appendChild(canvas)\r\n    }\r\n    marker.addEventListener('mousedown', (event) => {\r\n      if (event.button !== 0) return\r\n      event.preventDefault()\r\n      event.stopPropagation()\r\n      this.drag = {\r\n        side, start: event.clientX, indent: this.deps.getParagraphIndent(),\r\n        pageIndex: this.getVerticalPage()?.index ?? 0\r\n      }\r\n      window.addEventListener('mousemove', this.onDragMove)\r\n      window.addEventListener('mouseup', this.onDragEnd)\r\n      window.addEventListener('blur', this.onDragEnd)\r\n    })\r\n    return marker\r\n  }\r\n\r\n  private getVerticalPage() {\r\n    const page = this.deps.getLayout()?.pages[0]\r\n    const scrollY = this.deps.getScrollY()\r\n    return page && page.rect.y + page.rect.height > scrollY + RULER_SIZE &&\r\n      page.rect.y - scrollY < this.deps.getWrapperHeight() ? page : undefined\r\n  }\r\n\r\n  private onDragMove = (event: MouseEvent): void => {\r\n    const drag = this.drag\r\n    const layout = this.deps.getLayout()\r\n    if (!drag || !layout) return\r\n    event.preventDefault()\r\n    const scale = this.deps.getScale()\r\n    const rect = this.deps.container.getBoundingClientRect()\r\n    const pageX = this.deps.getPageOffsetX()\r\n    const [mt, mr, mb, ml] = this.deps.getPageMargins()\r\n    const width = (layout.pages[0]?.rect.width ?? layout.pageWidth) / scale\r\n    const clamp = (value: number, min: number, max: number) => Math.max(min, Math.min(Math.max(min, max), value))\r\n    if (INDENTS.includes(drag.side as IndentSide)) {\r\n      if (!drag.indent) return\r\n      const next = { ...drag.indent }\r\n      const contentWidth = width - ml - mr\r\n      const movement = (event.clientX - drag.start) / scale\r\n      const limit = contentWidth - next.right - 20\r\n      if (drag.side === 'first') next.first = clamp(next.first + movement, 0, limit)\r\n      if (drag.side === 'hanging') next.left = clamp(next.left + movement, 0, limit)\r\n      if (drag.side === 'end') next.right = clamp(next.right - movement, 0, contentWidth - Math.max(next.first, next.left) - 20)\r\n      if (drag.side === 'indent') {\r\n        const delta = clamp(movement,\r\n          -Math.min(next.first, next.left), limit - Math.max(next.first, next.left))\r\n        next.first += delta\r\n        next.left += delta\r\n      }\r\n      this.deps.onCommand('executeSetRulerIndent', next.first, next.left, next.right)\r\n      return\r\n    }\r\n    const page = layout.pages[drag.pageIndex]\r\n    if (!page) return\r\n    const height = page.rect.height / scale\r\n    const y = (event.clientY - rect.top + this.deps.getScrollY() - page.rect.y) / scale\r\n    const x = (event.clientX - rect.left - pageX) / scale\r\n    const margins: [number, number, number, number] = [mt, mr, mb, ml]\r\n    if (drag.side === 'left') margins[3] = clamp(x, 0, width - mr - 50)\r\n    if (drag.side === 'right') margins[1] = clamp(width - x, 0, width - ml - 50)\r\n    if (drag.side === 'top') margins[0] = clamp(y, 0, height - mb - 50)\r\n    if (drag.side === 'bottom') margins[2] = clamp(height - y, 0, height - mt - 50)\r\n    this.deps.onCommand('executeSetPaperMargin', margins)\r\n  }\r\n\r\n  private onDragEnd = (): void => {\r\n    this.drag = null\r\n    window.removeEventListener('mousemove', this.onDragMove)\r\n    window.removeEventListener('mouseup', this.onDragEnd)\r\n    window.removeEventListener('blur', this.onDragEnd)\r\n  }\r\n\r\n  setVisible(visible: boolean): void {\r\n    this.visible = visible\r\n    if (!visible) this.onDragEnd()\r\n    this.applyVisible()\r\n    if (visible) this.update()\r\n  }\r\n\r\n  private applyVisible(): void {\r\n    for (const element of [this.hRuler, this.vRuler, this.corner, ...this.markers.values()]) {\r\n      if (element) element.style.display = this.visible ? 'block' : 'none'\r\n    }\r\n  }\r\n\r\n  update(): void {\r\n    if (!this.visible || !this.hCanvas || !this.vCanvas) return\r\n    this.drawHorizontal()\r\n    this.drawVertical()\r\n    this.updateMarkers()\r\n  }\r\n\r\n  private updateMarkers(): void {\r\n    const layout = this.deps.getLayout()\r\n    const page = this.getVerticalPage()\r\n    const scale = this.deps.getScale()\r\n    const [mt, mr, mb, ml] = this.deps.getPageMargins()\r\n    const start = this.deps.getPageOffsetX() + ml * scale\r\n    const end = this.deps.getPageOffsetX() + (layout?.pages[0]?.rect.width ?? layout?.pageWidth ?? 0) - mr * scale\r\n    const indent = this.deps.getParagraphIndent()\r\n    const positions: Record<Handle, number> = {\r\n      left: start, right: end,\r\n      top: (page?.rect.y ?? 0) - this.deps.getScrollY() + mt * scale,\r\n      bottom: (page?.rect.y ?? 0) + (page?.rect.height ?? 0) - this.deps.getScrollY() - mb * scale,\r\n      first: start + (indent?.first ?? 0) * scale,\r\n      hanging: start + (indent?.left ?? 0) * scale,\r\n      indent: start + (indent?.left ?? 0) * scale,\r\n      end: end - (indent?.right ?? 0) * scale\r\n    }\r\n    for (const [side, marker] of this.markers) {\r\n      const vertical = side === 'top' || side === 'bottom'\r\n      const isMargin = MARGINS.includes(side as MarginSide)\r\n      const position = Math.round(positions[side])\r\n      const max = vertical ? this.deps.getWrapperHeight() : this.deps.getWrapperWidth()\r\n      marker.style.display = layout && (!vertical || page) && (isMargin || indent) &&\r\n        position >= RULER_SIZE + 6 && position <= max - 6 ? 'block' : 'none'\r\n      marker.style[vertical ? 'top' : 'left'] = `${position - (isMargin ? vertical ? 3 : 10 : 6)}px`\r\n    }\r\n  }\r\n\r\n  private prepareCanvas(canvas: HTMLCanvasElement, width: number, height: number): CanvasRenderingContext2D {\r\n    const dpr = window.devicePixelRatio || 1\r\n    canvas.width = Math.max(1, Math.round(width * dpr))\r\n    canvas.height = Math.max(1, Math.round(height * dpr))\r\n    const ctx = canvas.getContext('2d')!\r\n    ctx.setTransform(dpr, 0, 0, dpr, 0, 0)\r\n    ctx.clearRect(0, 0, width, height)\r\n    return ctx\r\n  }\r\n\r\n  /** The same 17px band is used horizontally and vertically (via a canvas transform). */\r\n  private drawBand(ctx: CanvasRenderingContext2D, start: number, end: number, origin: number, contentEnd: number, viewport: number): void {\r\n    const step = PX_PER_CM * this.deps.getScale()\r\n    const center = BAND_START + BAND_SIZE / 2\r\n    ctx.fillStyle = MARGIN_BACKGROUND\r\n    ctx.fillRect(start, BAND_START, end - start, BAND_SIZE)\r\n    ctx.fillStyle = '#fff'\r\n    ctx.fillRect(origin, BAND_START, Math.max(0, contentEnd - origin), BAND_SIZE)\r\n    ctx.strokeStyle = BORDER\r\n    ctx.lineWidth = 1\r\n    ctx.strokeRect(Math.round(start) + 0.5, BAND_START + 0.5, Math.round(end) - Math.round(start) - 1, BAND_SIZE - 1)\r\n    ctx.save()\r\n    ctx.beginPath()\r\n    ctx.rect(start + 1, BAND_START + 1, Math.max(0, end - start - 2), BAND_SIZE - 2)\r\n    ctx.clip()\r\n    ctx.strokeStyle = '#363636'\r\n    ctx.fillStyle = '#161616'\r\n    ctx.font = '11px Arial, sans-serif'\r\n    ctx.textAlign = 'center'\r\n    ctx.textBaseline = 'middle'\r\n    const firstTick = Math.ceil((Math.max(start, 0) - origin) / step * 4)\r\n    const lastTick = Math.floor((Math.min(end, viewport) - origin) / step * 4)\r\n    for (let tick = firstTick; tick <= lastTick; tick++) {\r\n      const x = Math.round(origin + tick * step / 4) + 0.5\r\n      if (tick % 4 === 0) {\r\n        if (tick !== 0) ctx.fillText(String(Math.abs(tick / 4)), x, center)\r\n      } else {\r\n        const height = tick % 2 === 0 ? 5 : 3\r\n        ctx.beginPath()\r\n        ctx.moveTo(x, Math.round(center - height / 2))\r\n        ctx.lineTo(x, Math.round(center + height / 2))\r\n        ctx.stroke()\r\n      }\r\n    }\r\n    ctx.restore()\r\n  }\r\n\r\n  private drawHorizontal(): void {\r\n    const width = this.deps.getWrapperWidth()\r\n    const ctx = this.prepareCanvas(this.hCanvas!, width, RULER_SIZE)\r\n    const layout = this.deps.getLayout()\r\n    if (!layout) return\r\n    const scale = this.deps.getScale()\r\n    const start = this.deps.getPageOffsetX()\r\n    const end = start + (layout.pages[0]?.rect.width ?? layout.pageWidth)\r\n    const [, mr, , ml] = this.deps.getPageMargins()\r\n    const origin = start + ml * scale\r\n    const contentEnd = end - mr * scale\r\n    this.drawBand(ctx, start, end, origin, contentEnd, width)\r\n    // Default tab stops sit below the band, starting at the text origin.\r\n    const tabStep = PX_PER_CM * 1.25 * scale\r\n    ctx.strokeStyle = '#777'\r\n    ctx.beginPath()\r\n    for (let x = origin + tabStep; x < Math.min(contentEnd, width); x += tabStep) {\r\n      if (x < 0) continue\r\n      const aligned = Math.round(x) + 0.5\r\n      ctx.moveTo(aligned, 22)\r\n      ctx.lineTo(aligned, 25)\r\n    }\r\n    ctx.stroke()\r\n  }\r\n\r\n  private drawVertical(): void {\r\n    const page = this.getVerticalPage()\r\n    if (!page) {\r\n      this.vRuler!.style.display = 'none'\r\n      return\r\n    }\r\n    const start = page.rect.y - this.deps.getScrollY()\r\n    const end = start + page.rect.height\r\n    // Limit both the canvas and its background to the first page.\r\n    const height = Math.min(this.deps.getWrapperHeight(), Math.ceil(end))\r\n    this.vRuler!.style.display = 'block'\r\n    this.vRuler!.style.bottom = 'auto'\r\n    this.vRuler!.style.height = `${height}px`\r\n    const ctx = this.prepareCanvas(this.vCanvas!, RULER_SIZE, height)\r\n    const scale = this.deps.getScale()\r\n    const [mt, , mb] = this.deps.getPageMargins()\r\n    // Rotate, rather than reflect, so vertical labels remain readable.\r\n    ctx.transform(0, 1, -1, 0, BAND_START * 2 + BAND_SIZE, 0)\r\n    this.drawBand(ctx, start, end, start + mt * scale, end - mb * scale, height)\r\n  }\r\n\r\n  destroy(): void {\r\n    this.onDragEnd()\r\n    for (const element of [this.hRuler, this.vRuler, this.corner, ...this.markers.values()]) element?.remove()\r\n    this.markers.clear()\r\n    this.hRuler = this.vRuler = this.corner = null\r\n    this.hCanvas = this.vCanvas = null\r\n  }\r\n}\r\n","/**\r\n * WatermarkWidget —— 水印渲染 widget\r\n *\r\n * 负责在每页内容区绘制水印文本：\r\n *  - repeat=true：平铺水印（按 gapX/gapY 间隔，斜向 45° 排列）\r\n *  - repeat=false：单条居中水印（斜向 45° 居中于页面内容区）\r\n *  - 支持 color / opacity / size / font 自定义\r\n *\r\n * 生命周期：create() → drawWatermark() 每页调用 → destroy()\r\n */\r\n\r\nimport type { PageLayout } from '../layout-types'\r\n\r\n/** 水印配置 */\r\nexport interface WatermarkConfig {\r\n  /** 水印文本内容 */\r\n  data: string\r\n  /** 字体（如 'Microsoft YaHei'） */\r\n  font?: string\r\n  /** 字号（如 120） */\r\n  size?: number\r\n  /** 颜色（如 '#AEB5C0'） */\r\n  color?: string\r\n  /** 透明度（0-1） */\r\n  opacity?: number\r\n  /** 是否平铺重复 */\r\n  repeat?: boolean\r\n  /** 水平间隔（px，平铺模式生效） */\r\n  gapX?: number\r\n  /** 垂直间隔（px，平铺模式生效） */\r\n  gapY?: number\r\n}\r\n\r\n/** WatermarkWidget 的依赖注入接口 */\r\nexport interface WatermarkWidgetDeps {\r\n  /** 获取页面在容器中的水平偏移 */\r\n  getPageOffsetX: () => number\r\n}\r\n\r\n/** 水印渲染 widget，负责在每页 canvas 上绘制水印文本 */\r\nexport class WatermarkWidget {\r\n  /** 当前水印配置 */\r\n  private config: WatermarkConfig | null = null\r\n\r\n  /**\r\n   * 创建 WatermarkWidget 实例\r\n   * @param deps 依赖注入对象\r\n   */\r\n  constructor(private deps: WatermarkWidgetDeps) {}\r\n\r\n  /* -------------------- 生命周期 -------------------- */\r\n\r\n  /** 初始化（当前无需额外操作，保留接口一致性） */\r\n  create(): void {}\r\n\r\n  /** 销毁 widget：清理配置引用 */\r\n  destroy(): void {\r\n    this.config = null\r\n  }\r\n\r\n  /* -------------------- 配置 -------------------- */\r\n\r\n  /** 设置水印配置 */\r\n  setConfig(cfg: WatermarkConfig | null): void {\r\n    this.config = cfg\r\n  }\r\n\r\n  /** 获取当前水印配置 */\r\n  getConfig(): WatermarkConfig | null {\r\n    return this.config\r\n  }\r\n\r\n  /* -------------------- 渲染 -------------------- */\r\n\r\n  /**\r\n   * 在指定页面上绘制水印。\r\n   * @param ctx 内容 canvas 2d 上下文\r\n   * @param page 页面布局信息\r\n   * @param scrollY 当前垂直滚动偏移\r\n   */\r\n  drawWatermark(\r\n    ctx: CanvasRenderingContext2D,\r\n    page: PageLayout,\r\n    scrollY: number\r\n  ): void {\r\n    const pageOffsetX = this.deps.getPageOffsetX()\r\n    const px = page.rect.x + pageOffsetX\r\n    const py = page.rect.y - scrollY\r\n    this.renderAt(ctx, px, py, page.rect.width, page.rect.height)\r\n  }\r\n\r\n  /**\r\n   * 为缩略图绘制水印（原点在页面左上角 0,0）。\r\n   * @param ctx 离屏 canvas 2d 上下文\r\n   * @param page 页面布局信息\r\n   */\r\n  drawWatermarkForThumbnail(\r\n    ctx: CanvasRenderingContext2D,\r\n    page: PageLayout\r\n  ): void {\r\n    this.renderAt(ctx, 0, 0, page.rect.width, page.rect.height)\r\n  }\r\n\r\n  /** 水印渲染核心：在指定位置和尺寸内绘制水印 */\r\n  private renderAt(\r\n    ctx: CanvasRenderingContext2D,\r\n    px: number, py: number,\r\n    pw: number, ph: number\r\n  ): void {\r\n    const cfg = this.config\r\n    if (!cfg || !cfg.data) return\r\n\r\n    const font = cfg.font || 'Microsoft YaHei'\r\n    const fontSize = cfg.size || 120\r\n    const color = cfg.color || '#AEB5C0'\r\n    const opacity = cfg.opacity ?? 0.3\r\n    const repeat = cfg.repeat ?? false\r\n\r\n    ctx.save()\r\n    ctx.rect(px, py, pw, ph)\r\n    ctx.clip()\r\n    ctx.globalAlpha = opacity\r\n    ctx.fillStyle = color\r\n    ctx.font = `${fontSize}px \"${font}\", \"PingFang SC\", sans-serif`\r\n\r\n    if (repeat) {\r\n      this.drawTiled(ctx, cfg.data, px, py, pw, ph, fontSize, cfg.gapX ?? 10, cfg.gapY ?? 10)\r\n    } else {\r\n      this.drawCentered(ctx, cfg.data, px, py, pw, ph)\r\n    }\r\n\r\n    ctx.restore()\r\n  }\r\n\r\n  /**\r\n   * 绘制单条居中水印（斜向 45° 居中于页面）。\r\n   */\r\n  private drawCentered(\r\n    ctx: CanvasRenderingContext2D,\r\n    text: string,\r\n    px: number, py: number,\r\n    pw: number, ph: number\r\n  ): void {\r\n    const cx = px + pw / 2\r\n    const cy = py + ph / 2\r\n    ctx.translate(cx, cy)\r\n    ctx.rotate(-Math.PI / 4)\r\n    ctx.textAlign = 'center'\r\n    ctx.textBaseline = 'middle'\r\n    ctx.fillText(text, 0, 0)\r\n  }\r\n\r\n  /**\r\n   * 绘制平铺水印（按间隔斜向 45° 排列，覆盖整页）。\r\n   */\r\n  private drawTiled(\r\n    ctx: CanvasRenderingContext2D,\r\n    text: string,\r\n    px: number, py: number,\r\n    pw: number, ph: number,\r\n    fontSize: number,\r\n    gapX: number, gapY: number\r\n  ): void {\r\n    const metrics = ctx.measureText(text)\r\n    const textW = metrics.width\r\n    const stepX = textW + gapX\r\n    const stepY = fontSize + gapY\r\n\r\n    ctx.textAlign = 'center'\r\n    ctx.textBaseline = 'middle'\r\n\r\n    const diag = Math.sqrt(pw * pw + ph * ph)\r\n    const cols = Math.ceil(diag / stepX) + 1\r\n    const rows = Math.ceil(diag / stepY) + 1\r\n\r\n    const cx = px + pw / 2\r\n    const cy = py + ph / 2\r\n\r\n    ctx.translate(cx, cy)\r\n    ctx.rotate(-Math.PI / 4)\r\n\r\n    const startX = -(cols * stepX) / 2\r\n    const startY = -(rows * stepY) / 2\r\n\r\n    for (let r = 0; r < rows; r++) {\r\n      const y = startY + r * stepY\r\n      const offsetX = (r % 2 === 0) ? 0 : stepX / 2\r\n      for (let c = 0; c < cols; c++) {\r\n        const x = startX + c * stepX + offsetX\r\n        ctx.fillText(text, x, y)\r\n      }\r\n    }\r\n  }\r\n}","/**\r\n * SystemWatermarkWidget —— 系统级水印 widget\r\n *\r\n * 与普通水印（canvas 内绘制）不同，系统级水印是覆盖整个编辑器视口的 DOM 层：\r\n *  - 创建一个 position:absolute; inset:0 的 div，叠加在 canvas 之上\r\n *  - pointer-events:none，不拦截鼠标交互\r\n *  - repeat=true：用 SVG 背景平铺水印文本\r\n *  - repeat=false：单条居中水印（CSS transform 旋转 -45°）\r\n *\r\n * 生命周期：create() → setConfig() → destroy()\r\n */\r\n\r\n/** 系统级水印配置 */\r\nexport interface SystemWatermarkConfig {\r\n  /** 水印文本内容 */\r\n  data: string\r\n  /** 字体（如 'Microsoft YaHei'） */\r\n  font?: string\r\n  /** 字号（如 120） */\r\n  size?: number\r\n  /** 颜色（如 '#AEB5C0'） */\r\n  color?: string\r\n  /** 透明度（0-1） */\r\n  opacity?: number\r\n  /** 是否平铺重复 */\r\n  repeat?: boolean\r\n  /** 水平间隔（px，平铺模式生效） */\r\n  gapX?: number\r\n  /** 垂直间隔（px，平铺模式生效） */\r\n  gapY?: number\r\n}\r\n\r\n/** SystemWatermarkWidget 的依赖注入接口 */\r\nexport interface SystemWatermarkWidgetDeps {\r\n  /** 获取编辑器容器 DOM（水印覆盖层挂载于此） */\r\n  getContainer: () => HTMLDivElement\r\n}\r\n\r\n/** 系统级水印 widget，在编辑器容器上叠加 DOM 水印层 */\r\nexport class SystemWatermarkWidget {\r\n  /** 水印覆盖层 div */\r\n  private overlayEl: HTMLDivElement | null = null\r\n  /** 当前水印配置 */\r\n  private config: SystemWatermarkConfig | null = null\r\n\r\n  /**\r\n   * 创建 SystemWatermarkWidget 实例\r\n   * @param deps 依赖注入对象\r\n   */\r\n  constructor(private deps: SystemWatermarkWidgetDeps) {}\r\n\r\n  /* -------------------- 生命周期 -------------------- */\r\n\r\n  /** 创建覆盖层 DOM 并挂载到容器 */\r\n  create(): void {\r\n    const el = document.createElement('div')\r\n    el.className = 'vervedocs-system-watermark'\r\n    Object.assign(el.style, {\r\n      position: 'absolute',\r\n      inset: '0',\r\n      pointerEvents: 'none',\r\n      zIndex: '50',\r\n      display: 'none',\r\n      overflow: 'hidden',\r\n    } as CSSStyleDeclaration)\r\n    this.deps.getContainer().appendChild(el)\r\n    this.overlayEl = el\r\n  }\r\n\r\n  /** 销毁 widget：移除 DOM 并清理引用 */\r\n  destroy(): void {\r\n    this.overlayEl?.remove()\r\n    this.overlayEl = null\r\n    this.config = null\r\n  }\r\n\r\n  /* -------------------- 配置 -------------------- */\r\n\r\n  /** 设置系统水印配置，null 表示移除水印 */\r\n  setConfig(config: SystemWatermarkConfig | null): void {\r\n    this.config = config\r\n    this.render()\r\n  }\r\n\r\n  /** 获取当前配置 */\r\n  getConfig(): SystemWatermarkConfig | null {\r\n    return this.config\r\n  }\r\n\r\n  /* -------------------- 渲染 -------------------- */\r\n\r\n  /** 根据配置渲染水印 */\r\n  private render(): void {\r\n    const el = this.overlayEl\r\n    if (!el) return\r\n    const cfg = this.config\r\n    if (!cfg || !cfg.data) {\r\n      el.style.display = 'none'\r\n      el.innerHTML = ''\r\n      el.style.backgroundImage = ''\r\n      return\r\n    }\r\n\r\n    const font = cfg.font || 'Microsoft YaHei'\r\n    const fontSize = cfg.size || 120\r\n    const color = cfg.color || '#AEB5C0'\r\n    const opacity = cfg.opacity ?? 0.3\r\n    const repeat = cfg.repeat ?? false\r\n\r\n    el.style.display = 'block'\r\n    el.innerHTML = ''\r\n    el.style.backgroundImage = ''\r\n\r\n    if (repeat) {\r\n      this.renderTiled(el, cfg.data, font, fontSize, color, opacity, cfg.gapX ?? 10, cfg.gapY ?? 10)\r\n    } else {\r\n      this.renderCentered(el, cfg.data, font, fontSize, color, opacity)\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 平铺水印：用 SVG data URL 作为 background-image，background-repeat: repeat\r\n   */\r\n  private renderTiled(\r\n    el: HTMLDivElement,\r\n    text: string, font: string, fontSize: number,\r\n    color: string, opacity: number,\r\n    gapX: number, gapY: number\r\n  ): void {\r\n    const tileW = fontSize * 2 + gapX\r\n    const tileH = fontSize + gapY\r\n    const cx = tileW / 2\r\n    const cy = tileH / 2\r\n    const escText = text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')\r\n    const svg =\r\n      `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${tileW}\" height=\"${tileH}\">` +\r\n      `<text x=\"${cx}\" y=\"${cy}\" text-anchor=\"middle\" dominant-baseline=\"middle\" ` +\r\n      `transform=\"rotate(-45 ${cx} ${cy})\" ` +\r\n      `font-family=\"${font}\" font-size=\"${fontSize}\" fill=\"${color}\" opacity=\"${opacity}\">${escText}</text>` +\r\n      `</svg>`\r\n    const encoded = encodeURIComponent(svg).replace(/'/g, '%27').replace(/\"/g, '%22')\r\n    el.style.backgroundImage = `url(\"data:image/svg+xml,${encoded}\")`\r\n    el.style.backgroundRepeat = 'repeat'\r\n  }\r\n\r\n  /**\r\n   * 居中水印：单个文本元素，CSS transform 旋转 -45° 居中\r\n   */\r\n  private renderCentered(\r\n    el: HTMLDivElement,\r\n    text: string, font: string, fontSize: number,\r\n    color: string, opacity: number\r\n  ): void {\r\n    const span = document.createElement('span')\r\n    span.textContent = text\r\n    Object.assign(span.style, {\r\n      position: 'absolute',\r\n      top: '50%',\r\n      left: '50%',\r\n      transform: 'translate(-50%, -50%) rotate(-45deg)',\r\n      fontSize: `${fontSize}px`,\r\n      fontFamily: `\"${font}\", \"PingFang SC\", sans-serif`,\r\n      color: color,\r\n      opacity: String(opacity),\r\n      whiteSpace: 'nowrap',\r\n      userSelect: 'none',\r\n      pointerEvents: 'none',\r\n    } as CSSStyleDeclaration)\r\n    el.appendChild(span)\r\n  }\r\n}","/**\r\n * SelectionToolbarWidget —— 悬浮选区工具栏 widget\r\n *\r\n * 选区非折叠时在选区起点上方显示悬浮工具栏，提供字体/字号/B/I/U/S/颜色/高亮/对齐/清除格式等操作。\r\n */\r\n\r\nimport type { DocumentLayout } from '../layout-types'\r\nimport type { RangeManager } from '@vervedoc/docx-editor-state'\r\nimport type { Command } from '@vervedoc/docx-editor-transform'\r\nimport type { IDocxDocumentMeta } from '@vervedoc/docx-editor-schema'\r\nimport { getByPath, FONT_FAMILY_LIST, FONT_FAMILY_VALUE, FONT_FAMILY_LABEL, FONT_SIZE, FONT_SIZE_LIST } from '@vervedoc/docx-editor-schema'\r\nimport { locateCaret } from '../caret-rect'\r\nimport type { Zone } from './header-footer-widget'\r\n\r\n/**\r\n * SelectionToolbarWidget 的依赖注入接口\r\n *\r\n * 由外部宿主提供，用于获取编辑器布局、选区、容器信息以及触发命令等。\r\n */\r\nexport interface SelectionToolbarWidgetDeps {\r\n  /** Whether editing interactions are currently allowed. */\r\n  canEdit: () => boolean\r\n  /** 获取当前文档布局，可能为 null */\r\n  getLayout: () => DocumentLayout | null\r\n  /** 获取当前选区管理器，可能为 null */\r\n  getRange: () => RangeManager | null\r\n  /** 获取当前文档元数据 */\r\n  getDocument: () => IDocxDocumentMeta\r\n  /** 获取当前编辑区域 */\r\n  getZone: () => Zone\r\n  /** 获取当前页眉/页脚编辑所在页 */\n  getActivePageIndex: () => number | null\n  /** 获取当前垂直滚动偏移量（像素） */\r\n  getScrollY: () => number\r\n  /** 获取页面水平偏移量（像素） */\r\n  getPageOffsetX: () => number\r\n  /** 获取视口宽度（像素） */\r\n  getViewportWidth: () => number\r\n  /** 获取外层容器 DOM */\r\n  getContainer: () => HTMLDivElement\r\n  /** 触发编辑器命令的回调 */\r\n  onCommand: (cmd: keyof Command, ...args: any[]) => void\r\n  /** 查询是否抑制下一次工具栏显示 */\r\n  isSuppressToolbar: () => boolean\r\n  /** 消费（重置）抑制标志 */\r\n  consumeSuppressToolbar: () => void\r\n}\r\n\r\n/**\r\n * 悬浮选区工具栏 widget\r\n *\r\n * 在选区起点上方显示工具栏，回显光标所在 run 的格式状态，\r\n * 点击按钮触发对应命令。\r\n */\r\nexport class SelectionToolbarWidget {\r\n  /** 工具栏 DOM 元素 */\r\n  private toolbar: HTMLDivElement | null = null\r\n\r\n  /**\r\n   * 构造 SelectionToolbarWidget 实例\r\n   *\r\n   * @param deps 依赖注入对象\r\n   */\r\n  constructor(private deps: SelectionToolbarWidgetDeps) {}\r\n\r\n  /** 创建工具栏 DOM 并挂载到容器 */\r\n  create(): void {\r\n    const tb = document.createElement('div')\r\n    tb.className = 'vervedocs-selection-toolbar'\r\n    Object.assign(tb.style, {\r\n      position: 'absolute',\r\n      display: 'none',\r\n      zIndex: '100',\r\n      background: '#fff',\r\n      borderRadius: '0',\r\n      boxShadow: '0 4px 16px rgba(0,0,0,0.15)',\r\n      padding: '8px 10px',\r\n      gap: '6px',\r\n      alignItems: 'center',\r\n      fontSize: '14px',\r\n      userSelect: 'none',\r\n      whiteSpace: 'nowrap',\r\n      fontFamily: '\"Microsoft YaHei\", \"PingFang SC\", \"Noto Sans CJK SC\", sans-serif',\r\n    } as CSSStyleDeclaration)\r\n\r\n    const fire = (cmd: keyof Command, ...args: any[]) => {\r\n      if (this.deps.canEdit()) this.deps.onCommand?.(cmd, ...args)\r\n    }\r\n\r\n\r\n    const mkBtn = (icon: string, cmd: keyof Command, args: any[] = [], title = ''): HTMLButtonElement => {\r\n      const el = document.createElement('button')\r\n      el.title = title\r\n      el.dataset.cmd = cmd\r\n      el.dataset.args = JSON.stringify(args)\r\n      Object.assign(el.style, {\r\n        border: 'none', background: 'transparent', borderRadius: '4px',\r\n        padding: '4px', cursor: 'pointer', display: 'flex',\r\n        alignItems: 'center', justifyContent: 'center', lineHeight: '0',\r\n      } as CSSStyleDeclaration)\r\n      const sp = document.createElement('span')\r\n      sp.className = 'material-symbols-outlined'\r\n      sp.textContent = icon\r\n      sp.style.cssText = 'font-size:18px;color:#3D4757;'\r\n      el.appendChild(sp)\r\n      el.addEventListener('mousedown', (e) => { e.preventDefault(); e.stopPropagation() })\r\n      el.addEventListener('click', (e) => { e.preventDefault(); e.stopPropagation(); fire(cmd, ...args) })\r\n      return el\r\n    }\r\n\r\n    const mkSep = (): HTMLSpanElement => {\r\n      const sep = document.createElement('span')\r\n      Object.assign(sep.style, {\r\n        display: 'inline-block', width: '1px', height: '24px',\r\n        background: '#e0e0e0', margin: '0 3px',\r\n      } as CSSStyleDeclaration)\r\n      return sep\r\n    }\r\n\r\n    // 字体下拉\r\n    const fontSel = document.createElement('select')\r\n    Object.assign(fontSel.style, {\r\n      border: '1px solid #ddd', borderRadius: '4px', padding: '4px 6px',\r\n      fontSize: '13px', background: '#fff', cursor: 'pointer', maxWidth: '110px',\r\n    } as CSSStyleDeclaration)\r\n    for (const f of FONT_FAMILY_LIST) {\r\n      const opt = document.createElement('option')\r\n      opt.value = FONT_FAMILY_VALUE[f] ?? f; opt.textContent = f\r\n      fontSel.appendChild(opt)\r\n    }\r\n    fontSel.addEventListener('mousedown', (e) => e.stopPropagation())\r\n    fontSel.addEventListener('change', () => fire('executeSetFont', fontSel.value))\r\n    tb.appendChild(fontSel)\r\n\r\n    // 字号下拉\r\n    const sizeSel = document.createElement('select')\r\n    Object.assign(sizeSel.style, {\r\n      border: '1px solid #ddd', borderRadius: '4px', padding: '4px 6px',\r\n      fontSize: '13px', background: '#fff', cursor: 'pointer', width: '68px',\r\n    } as CSSStyleDeclaration)\r\n    for (const s of FONT_SIZE_LIST) {\r\n      const opt = document.createElement('option')\r\n      const pt = FONT_SIZE[s] ?? Number(s)\r\n      opt.value = String(pt); opt.textContent = s\r\n      sizeSel.appendChild(opt)\r\n    }\r\n    sizeSel.value = '14'\r\n    sizeSel.addEventListener('mousedown', (e) => e.stopPropagation())\r\n    // The selector uses points; the core stores font sizes in pixels.\r\n    sizeSel.addEventListener('change', () => fire('executeSetSize', Number(sizeSel.value) * 96 / 72))\r\n    tb.appendChild(sizeSel)\r\n\r\n    tb.appendChild(mkSep())\r\n\r\n    // B I U S\r\n    tb.appendChild(mkBtn('format_bold', 'executeSetBold', [], '加粗'))\r\n    tb.appendChild(mkBtn('format_italic', 'executeSetItalic', [], '斜体'))\r\n    tb.appendChild(mkBtn('format_underlined', 'executeSetUnderline', [], '下划线'))\r\n    tb.appendChild(mkBtn('format_strikethrough', 'executeSetStrikeout', [], '删除线'))\r\n\r\n    tb.appendChild(mkSep())\r\n\r\n    // 颜色\r\n    const colorBtn = document.createElement('input')\r\n    colorBtn.type = 'color'\r\n    colorBtn.value = '#000000'\r\n    colorBtn.dataset.cmd = 'executeSetColor'\r\n    Object.assign(colorBtn.style, {\r\n      width: '32px', height: '28px', border: '1px solid #ddd',\r\n      borderRadius: '4px', cursor: 'pointer', padding: '0', background: 'transparent',\r\n    } as CSSStyleDeclaration)\r\n    colorBtn.title = '字体颜色'\r\n    colorBtn.addEventListener('mousedown', (e) => e.stopPropagation())\r\n    colorBtn.addEventListener('input', () => fire('executeSetColor', colorBtn.value))\r\n    tb.appendChild(colorBtn)\r\n\r\n    // 高亮\r\n    const hlBtn = document.createElement('input')\r\n    hlBtn.type = 'color'\r\n    hlBtn.value = '#ffff00'\r\n    hlBtn.dataset.cmd = 'executeSetHighlight'\r\n    Object.assign(hlBtn.style, {\r\n      width: '32px', height: '28px', border: '1px solid #ddd',\r\n      borderRadius: '4px', cursor: 'pointer', padding: '0', background: 'transparent',\r\n    } as CSSStyleDeclaration)\r\n    hlBtn.title = '高亮颜色'\r\n    hlBtn.addEventListener('mousedown', (e) => e.stopPropagation())\r\n    hlBtn.addEventListener('input', () => fire('executeSetHighlight', hlBtn.value))\r\n    tb.appendChild(hlBtn)\r\n\r\n    tb.appendChild(mkSep())\r\n\r\n    // 对齐\r\n    tb.appendChild(mkBtn('format_align_left', 'executeSetRowFlex', ['left'], '左对齐'))\r\n    tb.appendChild(mkBtn('format_align_center', 'executeSetRowFlex', ['center'], '居中'))\r\n    tb.appendChild(mkBtn('format_align_right', 'executeSetRowFlex', ['right'], '右对齐'))\r\n    tb.appendChild(mkBtn('format_align_justify', 'executeSetRowFlex', ['justify'], '两端对齐'))\r\n\r\n    tb.appendChild(mkSep())\r\n\r\n    // 清除格式\r\n    tb.appendChild(mkBtn('format_clear', 'executeClearFormat', [], '清除格式'))\r\n\r\n    this.deps.getContainer().appendChild(tb)\r\n    this.toolbar = tb\r\n  }\r\n\r\n  /** 更新工具栏：折叠选区/表格内选区时隐藏，否则定位到选区起点上方并回显格式状态。 */\r\n  update(): void {\r\n    if (!this.toolbar) return\r\n    const tb = this.toolbar\r\n    if (!this.deps.canEdit()) { tb.style.display = 'none'; return }\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) { tb.style.display = 'none'; return }\r\n    if (this.deps.isSuppressToolbar()) { tb.style.display = 'none'; this.deps.consumeSuppressToolbar(); return }\r\n    if (range.isCollapsed()) {\r\n      tb.style.display = 'none'\r\n      return\r\n    }\r\n    const ordered = range.getOrdered()\r\n    if (!ordered) { tb.style.display = 'none'; return }\r\n    // 表格内选区不显示段落悬浮工具栏\r\n    if (ordered.start.path.length >= 2 && ordered.start.path[1] === 'trList') {\r\n      tb.style.display = 'none'\r\n      return\r\n    }\r\n    const rect = locateCaret(layout, ordered.start, this.deps.getZone(), this.deps.getActivePageIndex())\n    if (!rect) { tb.style.display = 'none'; return }\r\n    const pageOffsetX = this.deps.getPageOffsetX()\r\n    const x = Math.round(rect.x + pageOffsetX)\r\n    const gap = Math.max(16, Math.round(rect.height * 0.5))\r\n    tb.style.display = 'flex'\r\n    const y = Math.round(rect.y - this.deps.getScrollY()) - tb.offsetHeight - gap\r\n    tb.style.left = `${Math.max(4, Math.min(x, this.deps.getViewportWidth() - tb.offsetWidth - 4))}px`\r\n    tb.style.top = `${Math.max(4, y)}px`\r\n\r\n    this.syncToolbarState(tb)\r\n  }\r\n\r\n  /** 读取光标所在 run 的格式状态，回显到工具栏控件 */\r\n  private syncToolbarState(tb: HTMLDivElement): void {\r\n    const range = this.deps.getRange()\r\n    if (!range) return\r\n    const pos = range.getFocus()\r\n    if (!pos) return\r\n    const node = getByPath(this.deps.getDocument().elements, pos.path)\r\n    if (!node || node.type !== 'text') return\r\n    const run = node as unknown as Record<string, unknown>\r\n\r\n    const fontSel = tb.querySelector('select:nth-of-type(1)') as HTMLSelectElement | null\r\n    const sizeSel = tb.querySelector('select:nth-of-type(2)') as HTMLSelectElement | null\r\n\r\n    // 回显字体\r\n    if (fontSel) {\r\n      const font = String(run.font ?? '')\r\n      const label = FONT_FAMILY_LABEL[font] ?? font\r\n      for (let i = 0; i < fontSel.options.length; i++) {\r\n        const opt = fontSel.options[i]\r\n        opt.selected = opt.value === font || opt.textContent === label\r\n      }\r\n    }\r\n\r\n    // 回显字号（run.size 是 px，选项值是 pt，需要转换）\r\n    if (sizeSel) {\r\n      const sizePt = Math.round(Number(run.size ?? 0) * (72 / 96) * 2) / 2\r\n      const size = String(sizePt)\r\n      for (let i = 0; i < sizeSel.options.length; i++) {\r\n        if (sizeSel.options[i].value === size) { sizeSel.options[i].selected = true; break }\r\n      }\r\n    }\r\n\r\n    // 回显 B/I/U/S 高亮\r\n    const btns = tb.querySelectorAll<HTMLButtonElement>('button[data-cmd]')\r\n    for (let i = 0; i < btns.length; i++) {\r\n      const btn = btns[i]\r\n      const cmd = btn.dataset.cmd\r\n      let active = false\r\n      if (cmd === 'executeSetBold') active = !!run.bold\r\n      else if (cmd === 'executeSetItalic') active = !!run.italic\r\n      else if (cmd === 'executeSetUnderline') active = !!run.underline\r\n      else if (cmd === 'executeSetStrikeout') active = !!run.strikeout\r\n      else if (cmd === 'executeSetRowFlex') {\r\n        const args = JSON.parse(btn.dataset.args || '[]')\r\n        active = String(run.rowFlex ?? 'left') === args[0]\r\n      }\r\n      btn.style.background = active ? '#e8eaf6' : 'transparent'\r\n    }\r\n\r\n    // 回显字体颜色和高亮颜色\r\n    const colorInputs = tb.querySelectorAll<HTMLInputElement>('input[type=color][data-cmd]')\r\n    for (let i = 0; i < colorInputs.length; i++) {\r\n      const input = colorInputs[i]\r\n      if (input.dataset.cmd === 'executeSetColor') {\r\n        input.value = String(run.color ?? '#000000')\r\n      } else if (input.dataset.cmd === 'executeSetHighlight') {\r\n        input.value = String(run.highlight ?? '#ffff00')\r\n      }\r\n    }\r\n  }\r\n\r\n  /** 销毁工具栏：从容器移除 DOM */\r\n  destroy(): void {\r\n    if (this.toolbar && this.toolbar.parentElement) {\r\n      this.toolbar.parentElement.removeChild(this.toolbar)\r\n    }\r\n    this.toolbar = null\r\n  }\r\n}\r\n","/**\r\n * CaretWidget —— DOM 光标 widget\r\n *\r\n * 用一个 position:absolute 的 div 绘制横排或竖排文本光标，替代 canvas overlay 绘制。\n *  - 挂载于 canvasHost（覆盖 container 视口，pointer-events:none）\r\n *  - 增量更新 style.left/top/height + display，不每帧重建 DOM\r\n *  - 显隐由外部 visible 开关驱动（沿用原 setInterval 闪烁机制）\r\n *\r\n * 生命周期：create() → update() / hide() → destroy()\r\n */\r\n\r\nimport type { CaretRect } from '../caret-rect'\r\n\r\n/** CaretWidget 的依赖注入接口 */\r\nexport interface CaretWidgetDeps {\r\n  /** 获取 canvasHost DOM（光标 div 挂载于此） */\r\n  getCanvasHost: () => HTMLDivElement\r\n}\r\n\r\n/** DOM 光标 widget，在 canvasHost 上叠加 1px 竖线 div */\r\nexport class CaretWidget {\r\n  /** 光标 div 元素 */\r\n  private el: HTMLDivElement | null = null\r\n\r\n  /**\r\n   * 创建 CaretWidget 实例\r\n   * @param deps 依赖注入对象\r\n   */\r\n  constructor(private deps: CaretWidgetDeps) {}\r\n\r\n  /* -------------------- 生命周期 -------------------- */\r\n\r\n  /** 创建光标 div 并挂载到 canvasHost */\r\n  create(): void {\r\n    const el = document.createElement('div')\r\n    el.className = 'vervedocs-caret'\r\n    Object.assign(el.style, {\r\n      position: 'absolute',\r\n      left: '0px',\r\n      top: '0px',\r\n      width: '1px',\r\n      height: '0px',\r\n      background: '#111',\r\n      display: 'none',\r\n      pointerEvents: 'none',\r\n      zIndex: '3'\r\n    } as CSSStyleDeclaration)\r\n    this.deps.getCanvasHost().appendChild(el)\r\n    this.el = el\r\n\r\n  }\r\n\r\n  /** 销毁 widget：移除 DOM 并清理引用 */\r\n  destroy(): void {\r\n    this.el?.remove()\r\n    this.el = null\r\n  }\r\n\r\n  /* -------------------- 渲染 -------------------- */\r\n\r\n  /**\r\n   * 更新光标位置与可见性。\r\n   * rect 为文档坐标系（未减 scrollY），内部应用 scrollY 与 pageOffsetX 转为视口坐标。\r\n   * @param rect 光标矩形（文档坐标）\r\n   * @param scrollY 当前垂直滚动偏移\r\n   * @param pageOffsetX 页面水平居中偏移\r\n   * @param visible 是否可见（闪烁开关）\r\n   */\r\n  update(rect: CaretRect, scrollY: number, pageOffsetX: number, visible: boolean): void {\r\n    const el = this.el\r\n    if (!el) return\r\n    if (!visible) {\r\n      el.style.display = 'none'\r\n      return\r\n    }\r\n    const x = Math.round(rect.x + pageOffsetX)\r\n    const y = Math.round(rect.y - scrollY)\r\n    el.style.left = `${x}px`\r\n    el.style.top = `${y}px`\r\n    if (rect.orientation === 'horizontal') {\n      el.style.width = `${rect.width ?? 1}px`\n      el.style.height = '1px'\n    } else {\n      el.style.width = '1px'\n      el.style.height = `${rect.height}px`\n    }\n    el.style.display = 'block'\r\n  }\r\n\r\n  /** 隐藏光标（无 focus 或定位失败时调用） */\r\n  hide(): void {\r\n    if (this.el) this.el.style.display = 'none'\r\n  }\r\n}\n","import type { BlockNode, DocumentLayout, InlineBox } from '../layout-types'\nimport type { IControlElement, ControlDataValue, IPosition } from '@vervedoc/docx-editor-schema'\nimport { isControl } from '@vervedoc/docx-editor-schema'\nimport { viewTranslate, type ViewTranslate } from '../view-i18n'\n\nexport interface ControlWidgetDeps {\n  getContainer: () => HTMLElement\n  getLayout: () => DocumentLayout | null\n  getContainerRect: () => DOMRect\n  getScrollY: () => number\n  getPageOffsetX: () => number\n  getZone?: () => 'main' | 'header' | 'footer'\n  onCommand: (cmd: string, ...args: any[]) => void\n  isReadonly: () => boolean\n  translate?: ViewTranslate\n  onActivate?: (position: IPosition) => void\n  focusEditor?: () => void\n}\n\ninterface ControlActivation {\n  element: IControlElement\n  inline: InlineBox\n  x: number\n  y: number\n  width: number\n  height: number\n}\n\nexport class ControlWidget {\n  private overlay: HTMLDivElement | null = null\n  private floatEl: HTMLElement | null = null\n  private activation: ControlActivation | null = null\n  private dropdown = false\n  private refreshLabels: (() => void) | null = null\n\n  constructor(private deps: ControlWidgetDeps) {}\n\n  create(): void {\n    this.overlay = document.createElement('div')\n    this.overlay.className = 'vervedocs-control-overlay'\n    this.overlay.style.cssText = 'position:absolute;inset:0;pointer-events:none;z-index:200;'\n    for (const event of ['mousedown', 'click', 'dblclick', 'keydown', 'keyup', 'wheel']) {\n      this.overlay.addEventListener(event, e => e.stopPropagation())\n    }\n    this.deps.getContainer().appendChild(this.overlay)\n  }\n\n  private readonly onOutsideMouseDown = (e: MouseEvent): void => {\n    if (this.floatEl?.contains(e.target as Node)) return\n    if (this.floatEl instanceof HTMLInputElement) this.commitInput()\n    else this.deactivate()\n  }\n\n  handleMouseDown(e: MouseEvent): boolean {\n    if (e.button !== 0 || this.deps.isReadonly() || e.shiftKey) return false\n    const rect = this.deps.getContainerRect()\n    const { scaleX, scaleY } = this.getScale()\n    const x = (e.clientX - rect.left) / scaleX\n    const y = (e.clientY - rect.top) / scaleY\n    for (const hit of this.getActivations()) {\n      if (x < hit.x || x > hit.x + hit.width || y < hit.y || y > hit.y + hit.height) continue\n      e.preventDefault()\n      e.stopPropagation()\n      this.deactivate()\n      this.deps.onActivate?.({ path: hit.inline.path, offset: 1 })\n      if (hit.element.control.readOnly) return true\n      this.activation = hit\n      const kind = hit.element.control.kind\n      if (kind === 'checkbox') {\n        this.submit(hit.element.dataValue !== true)\n      } else if (kind === 'radioGroup' && hit.inline.controlOptionValue !== undefined) {\n        this.submit(hit.inline.controlOptionValue)\n      } else if (kind === 'select' || kind === 'multiSelect') {\n        this.activateDropdown(hit, kind === 'multiSelect')\n      } else if (kind !== 'radioGroup') {\n        this.activateInput(hit)\n      }\n      if (this.floatEl) document.addEventListener('mousedown', this.onOutsideMouseDown, true)\n      return true\n    }\n    this.deactivate()\n    return false\n  }\n\n  private getScale(): { scaleX: number; scaleY: number } {\n    const container = this.deps.getContainer()\n    const rect = this.deps.getContainerRect()\n    return {\n      scaleX: container.offsetWidth ? rect.width / container.offsetWidth : 1,\n      scaleY: container.offsetHeight ? rect.height / container.offsetHeight : 1\n    }\n  }\n\n  // Coordinates remain local to the canvas host, including nested table content.\n  private *getActivations(): Generator<ControlActivation> {\n    const layout = this.deps.getLayout()\n    if (!layout) return\n    const zone = this.deps.getZone?.() ?? 'main'\n    for (const page of layout.pages) {\n      const rect = zone === 'header' ? page.headerRect : zone === 'footer' ? page.footerRect : page.contentRect\n      const blocks = zone === 'header' ? page.headerBlocks : zone === 'footer' ? page.footerBlocks : page.blocks\n      if (rect && blocks) {\n        yield* this.getBlockActivations(blocks, this.deps.getPageOffsetX() + rect.x, rect.y - this.deps.getScrollY())\n      }\n    }\n  }\n\n  private *getBlockActivations(blocks: BlockNode[], ox: number, oy: number): Generator<ControlActivation> {\n    for (const block of blocks) {\n      const x = ox + block.rect.x\n      const y = oy + block.rect.y\n      if (block.kind === 'paragraph') {\n        for (const line of block.lines) {\n          for (const inline of line.inlines) {\n            if (!inline.controlId || !isControl(inline.run)) continue\n            yield { element: inline.run, inline, x: x + inline.x, y: y + inline.y, width: inline.width, height: line.height }\n          }\n        }\n      } else if (block.kind === 'table') {\n        for (const row of block.rows) {\n          for (const cell of row.cells) {\n            yield* this.getBlockActivations(cell.content,\n              x + cell.rect.x + cell.contentPaddingLeft,\n              y + row.rect.y + cell.contentPaddingTop + cell.verticalOffset)\n          }\n        }\n      }\n    }\n  }\n\n  private activateInput(info: ControlActivation): void {\n    if (!this.overlay) return\n    const { control, dataValue } = info.element\n    const input = document.createElement('input')\n    input.type = control.kind === 'date'\n      ? (control.dateMode === 'dateTime' ? 'datetime-local' : 'date')\n      : control.kind === 'number' ? 'number' : 'text'\n    input.value = dataValue == null ? '' : String(dataValue)\n    input.setAttribute('aria-label', control.title || control.placeholder || control.kind)\n    if (control.maxLength != null) input.maxLength = control.maxLength\n    if (control.min != null) input.min = String(control.min)\n    if (control.max != null) input.max = String(control.max)\n    if (control.kind === 'number') input.step = control.precision == null ? 'any' : String(10 ** -control.precision)\n    input.style.cssText = [\n      'position:absolute', `width:${Math.max(info.width, 100)}px`, `height:${info.height}px`,\n      `font:${this.fontOf(info.inline)}`, `color:${info.inline.color}`,\n      'border:1px solid #409eff;border-radius:2px;background:#fff;outline:none',\n      'padding:0 2px;margin:0;box-sizing:border-box;pointer-events:auto'\n    ].join(';')\n    this.floatEl = input\n    this.overlay.appendChild(input)\n    this.positionFloat()\n    input.focus()\n    if (input.type === 'text') input.select()\n    input.addEventListener('blur', () => this.commitInput())\n    input.addEventListener('keydown', e => {\n      if (e.isComposing) return\n      if (e.key === 'Enter') { e.preventDefault(); this.commitInput() }\n      if (e.key === 'Escape') { e.preventDefault(); this.deactivate(); this.deps.focusEditor?.() }\n    })\n  }\n\n  private fontOf(inline: InlineBox): string {\n    return `${inline.italic ? 'italic ' : ''}${inline.bold ? '700' : '400'} ${inline.size}px ${inline.font}`\n  }\n\n  private activateDropdown(info: ControlActivation, multi: boolean): void {\n    if (!this.overlay) return\n    this.dropdown = true\n    const panel = document.createElement('div')\n    panel.setAttribute('role', 'dialog')\n    panel.setAttribute('aria-label', info.element.control.title || info.element.control.placeholder || info.element.control.kind)\n    panel.style.cssText = [\n      'position:absolute', `width:${Math.min(320, Math.max(info.width, 220))}px`,\n      'font:normal 400 14px/1.5 system-ui, sans-serif', 'color:#333',\n      'border:1px solid #d9d9d9;border-radius:4px;background:#fff',\n      'box-shadow:0 2px 8px rgba(0,0,0,.15);pointer-events:auto;box-sizing:border-box',\n      'padding:8px;display:flex;flex-direction:column;gap:6px;min-width:0;overflow-y:auto;overflow-x:hidden'\n    ].join(';')\n    const search = document.createElement('input')\n    search.type = 'search'\n    search.style.cssText = 'width:100%;box-sizing:border-box;padding:4px 6px;font:inherit;border:1px solid #ddd;'\n    const list = document.createElement('div')\n    list.style.cssText = 'max-height:200px;min-width:0;width:100%;box-sizing:border-box;overflow-y:auto;overflow-x:hidden;flex-shrink:0;'\n    const footer = document.createElement('div')\n    footer.style.cssText = 'display:flex;gap:8px;justify-content:flex-end;'\n    panel.append(search, list, footer)\n    const value = info.element.dataValue\n    const selected = new Set(Array.isArray(value) ? value : typeof value === 'string' && value !== '' ? [value] : [])\n    const options = info.element.control.options ?? []\n    const renderList = (): void => {\n      list.replaceChildren()\n      const query = search.value.toLocaleLowerCase()\n      for (const option of options) {\n        if (!option.label.toLocaleLowerCase().includes(query) && !option.value.toLocaleLowerCase().includes(query)) continue\n        const row = document.createElement('label')\n        row.style.cssText = 'display:flex;align-items:center;gap:8px;padding:5px 4px;width:100%;box-sizing:border-box;min-width:0;cursor:pointer;overflow-wrap:anywhere;'\n        const input = document.createElement('input')\n        input.type = multi ? 'checkbox' : 'radio'\n        input.checked = selected.has(option.value)\n        input.style.cssText = 'flex:0 0 16px;width:16px;height:16px;margin:0;accent-color:#409eff;'\n        const label = document.createElement('span')\n        label.style.cssText = 'flex:1;min-width:0;white-space:normal;overflow-wrap:anywhere;text-align:left;'\n        label.textContent = option.label\n        row.append(input, label)\n        input.addEventListener('change', () => {\n          if (!multi) { this.submit(option.value); return }\n          if (input.checked) selected.add(option.value)\n          else selected.delete(option.value)\n        })\n        list.appendChild(row)\n      }\n      if (!list.childElementCount) {\n        const empty = document.createElement('div')\n        empty.textContent = this.t('view.control.noResults')\n        empty.style.cssText = 'padding:8px;color:#999;'\n        list.appendChild(empty)\n      }\n      this.positionFloat()\n    }\n    const button = (key: string, action: () => void): HTMLButtonElement => {\n      const el = document.createElement('button')\n      el.type = 'button'\n      el.dataset.i18nKey = key\n      el.style.cssText = 'font:inherit;cursor:pointer;border:1px solid #ddd;border-radius:3px;background:#fff;padding:3px 8px;'\n      el.addEventListener('click', action)\n      footer.appendChild(el)\n      return el\n    }\n    button('view.control.clear', () => {\n      if (!multi) { this.submit(null); return }\n      selected.clear()\n      renderList()\n    })\n    if (multi) {\n      button('view.common.cancel', () => { this.deactivate(); this.deps.focusEditor?.() })\n      button('view.common.confirm', () => {\n        const ordered = options.filter(option => selected.has(option.value)).map(option => option.value)\n        // Preserve unknown imported values so a filtered list cannot silently erase them.\n        this.submit([...new Set([...ordered, ...selected])])\n      })\n    }\n    this.refreshLabels = () => {\n      search.placeholder = this.t('view.control.search')\n      search.setAttribute('aria-label', search.placeholder)\n      for (const el of Array.from(footer.querySelectorAll<HTMLElement>('[data-i18n-key]'))) {\n        el.textContent = this.t(el.dataset.i18nKey!)\n      }\n      renderList()\n    }\n    this.floatEl = panel\n    this.overlay.appendChild(panel)\n    this.refreshLabels()\n    search.addEventListener('input', renderList)\n    panel.addEventListener('keydown', e => {\n      if (e.key === 'Escape') { e.preventDefault(); this.deactivate(); this.deps.focusEditor?.() }\n    })\n    search.focus()\n  }\n\n  private t(key: string): string {\n    return viewTranslate(this.deps.translate, key)\n  }\n\n  refreshLocale(): void {\n    this.refreshLabels?.()\n  }\n\n  private positionFloat(): void {\n    if (!this.floatEl || !this.activation || !this.overlay) return\n    const info = this.activation\n    const rect = this.deps.getContainerRect()\n    const { scaleX, scaleY } = this.getScale()\n    const left = Math.max(0, -rect.left / scaleX) + 4\n    const top = Math.max(0, -rect.top / scaleY) + 4\n    const right = Math.min(this.overlay.clientWidth, (window.innerWidth - rect.left) / scaleX) - 4\n    const bottom = Math.min(this.overlay.clientHeight, (window.innerHeight - rect.top) / scaleY) - 4\n    this.floatEl.style.maxWidth = `${Math.max(0, right - left)}px`\n    this.floatEl.style.maxHeight = `${Math.max(0, bottom - top)}px`\n    const width = this.floatEl.offsetWidth\n    const height = this.floatEl.offsetHeight\n    let y = this.dropdown ? info.y + info.height + 2 : info.y\n    if (this.dropdown && y + height > bottom) y = info.y - height - 2\n    this.floatEl.style.left = `${Math.max(left, Math.min(info.x, right - width))}px`\n    this.floatEl.style.top = `${Math.max(top, Math.min(y, bottom - height))}px`\n  }\n\n  private submit(value: ControlDataValue, restoreFocus = true): void {\n    const id = this.activation?.element.id\n    const readOnly = this.deps.isReadonly() || this.activation?.element.control.readOnly\n    this.deactivate()\n    if (id && !readOnly) this.deps.onCommand('executeUpdateControlValue', id, value)\n    if (restoreFocus) this.deps.focusEditor?.()\n  }\n\n  private commitInput(restoreFocus = true): void {\n    if (!this.activation || !(this.floatEl instanceof HTMLInputElement)) return\n    // 数字输入不合法时浏览器也会返回空字符串，不能将其当作主动清空。\n    if (this.floatEl.validity.badInput) return\n    const raw = this.floatEl.value\n    const kind = this.activation.element.control.kind\n    const value = kind === 'number' ? (raw === '' ? null : Number(raw)) : raw || null\n    if (typeof value === 'number' && !Number.isFinite(value)) return\n    this.submit(value, restoreFocus)\n  }\n\n  deactivate(): void {\n    document.removeEventListener('mousedown', this.onOutsideMouseDown, true)\n    const el = this.floatEl\n    this.floatEl = null\n    this.activation = null\n    this.refreshLabels = null\n    this.dropdown = false\n    el?.remove()\n  }\n\n  update(): void {\n    if (!this.activation) return\n    if (this.deps.isReadonly()) { this.deactivate(); return }\n    const current = this.activation\n    let fallback: ControlActivation | undefined\n    for (const info of this.getActivations()) {\n      if (info.element.id !== current.element.id) continue\n      fallback ??= info\n      if (info.inline.controlTextOffset === current.inline.controlTextOffset &&\n          info.inline.controlOptionValue === current.inline.controlOptionValue) {\n        fallback = info\n        break\n      }\n    }\n    if (!fallback || fallback.element.control.readOnly ||\n        fallback.element.control.kind !== current.element.control.kind) {\n      this.deactivate()\n      return\n    }\n    if (this.overlay?.clientHeight && (fallback.y + fallback.height <= 0 || fallback.y >= this.overlay.clientHeight)) {\n      if (this.floatEl instanceof HTMLInputElement) {\n        this.commitInput(false)\n        if (this.activation) this.deactivate()\n      } else {\n        this.deactivate()\n      }\n      return\n    }\n    this.activation = fallback\n    this.positionFloat()\n  }\n\n  destroy(): void {\n    this.deactivate()\n    this.overlay?.remove()\n    this.overlay = null\n  }\n}\n","import type { BlockNode, DocumentLayout, Rect } from './layout-types'\r\nimport { signBlock } from './block-signature'\r\n\r\ninterface BlockState {\r\n  id: number\r\n  signature: string\r\n  rect: Rect\r\n}\r\n\r\nexport interface RenderState {\r\n  blocks: Map<string, BlockState>\r\n  pageBlocks: Map<number, BlockState>\r\n  pageSignatures: Map<number, string>\r\n  geometry: string\r\n}\r\n\r\nlet nextRenderId = 0\r\n\r\n/** Separate a block's stable identity from its mutable paint signature. */\r\nexport function prepareRenderState(layout: DocumentLayout, previous?: RenderState): {\r\n  state: RenderState\r\n  dirty: number[]\r\n} {\r\n  const state: RenderState = {\r\n    blocks: new Map(),\r\n    pageBlocks: new Map(),\r\n    pageSignatures: new Map(),\r\n    geometry: JSON.stringify(layout.pages.map(p => [p.rect, p.contentRect, p.headerRect, p.footerRect]))\r\n  }\r\n  const dirty: number[] = []\r\n  const visit = (source: BlockNode, key: string, x: number, y: number, topLevel: boolean): BlockNode => {\r\n    // Header/footer and repeated table fragments can share source layout objects.\r\n    // Never assign occurrence IDs into those shared objects or cached geometry.\r\n    const b = { ...source, rect: { ...source.rect } }\r\n    if (b.kind === 'table') {\r\n      b.rows = b.rows.map((row, ri) => ({\r\n        ...row,\r\n        cells: row.cells.map((cell, ci) => ({\r\n          ...cell,\r\n          content: cell.content.map((child, bi) =>\r\n            visit(child, `${key}/${ri}/${ci}/${bi}`, 0, 0, false))\r\n        }))\r\n      }))\r\n    }\r\n    const old = previous?.blocks.get(key)\r\n    b.id = old?.id ?? ++nextRenderId\r\n    const signature = signBlock(b, layout)\r\n    const entry = {\r\n      id: b.id, signature,\r\n      rect: { ...b.rect, x: x + b.rect.x, y: y + b.rect.y }\r\n    }\r\n    state.blocks.set(key, entry)\r\n    if (topLevel) state.pageBlocks.set(b.id, entry)\r\n    if (!old || old.signature !== signature) dirty.push(b.id)\r\n    return b\r\n  }\r\n  for (const page of layout.pages) {\r\n    const parts: unknown[] = [page.rect, page.contentRect, page.headerRect, page.footerRect]\r\n    const zone = (blocks: BlockNode[], name: string, origin: Rect) => blocks.map((block, index) => {\r\n      const b = visit(block, `${page.index}/${name}/${index}`, origin.x, origin.y, true)\r\n      parts.push([b.rect, state.pageBlocks.get(b.id)!.signature])\r\n      return b\r\n    })\r\n    page.blocks = zone(page.blocks, 'main', page.contentRect)\r\n    if (page.headerBlocks && page.headerRect) page.headerBlocks = zone(page.headerBlocks, 'header', page.headerRect)\r\n    if (page.footerBlocks && page.footerRect) page.footerBlocks = zone(page.footerBlocks, 'footer', page.footerRect)\r\n    state.pageSignatures.set(page.index, JSON.stringify(parts))\r\n  }\r\n  return { state, dirty }\r\n}\r\n\r\n/** Diff against the last painted frame, not the last edit queued in that frame. */\r\nexport function computeDirtyRect(\r\n  painted: RenderState | undefined,\r\n  next: RenderState,\r\n  viewport: Rect\r\n): Rect | null {\r\n  if (!painted || painted.geometry !== next.geometry) return null\r\n  let left = Infinity, top = Infinity, right = -Infinity, bottom = -Infinity\r\n  const include = (rect: Rect) => {\r\n    left = Math.min(left, rect.x - 2)\r\n    top = Math.min(top, rect.y - 2)\r\n    right = Math.max(right, rect.x + rect.width + 2)\r\n    bottom = Math.max(bottom, rect.y + rect.height + 2)\r\n  }\r\n  const ids = new Set([...painted.pageBlocks.keys(), ...next.pageBlocks.keys()])\r\n  for (const id of ids) {\r\n    const old = painted.pageBlocks.get(id)\r\n    const current = next.pageBlocks.get(id)\r\n    if (old && current && old.signature === current.signature &&\r\n        JSON.stringify(old.rect) === JSON.stringify(current.rect)) continue\r\n    if (old) include(old.rect)\r\n    if (current) include(current.rect)\r\n  }\r\n  left = Math.max(left, viewport.x)\r\n  top = Math.max(top, viewport.y)\r\n  right = Math.min(right, viewport.x + viewport.width)\r\n  bottom = Math.min(bottom, viewport.y + viewport.height)\r\n  if (right <= left || bottom <= top) return { x: 0, y: 0, width: 0, height: 0 }\r\n  return { x: left, y: top, width: right - left, height: bottom - top }\r\n}\r\n","/**\r\n * LayoutQuery —— 布局查询纯函数\r\n *\r\n * 提供按 position 定位 inline / paragraph / line / hyperlink 等布局节点的工具函数。\r\n * 所有函数均不持有状态，调用方传入 DocumentLayout / blocks 即可。\r\n */\r\n\r\nimport type { DocumentLayout, BlockNode, InlineBox, LineBox, ParagraphBlock } from './layout-types'\r\nimport type { IPosition } from '@vervedoc/docx-editor-schema'\r\nimport { isSamePath } from '@vervedoc/docx-editor-schema'\r\n\r\n/**\r\n * 按 position 在 layout 中查找所属 inline。\r\n * @param layout 文档布局\r\n * @param pos 待定位位置\r\n * @returns 命中的 InlineBox；未命中返回 null\r\n */\r\nexport function findInlineByPos(layout: DocumentLayout | null, pos: IPosition): InlineBox | null {\r\n  if (!layout) return null\r\n  for (const page of layout.pages) {\r\n    const r = findInlineInBlocks(page.blocks, pos)\r\n    if (r) return r\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 在 block 列表中递归查找所属 inline（含表格单元格递归）。\r\n * @param blocks 块列表\r\n * @param pos 待定位位置\r\n * @returns 命中的 InlineBox；未命中返回 null\r\n */\r\nexport function findInlineInBlocks(blocks: BlockNode[], pos: IPosition): InlineBox | null {\r\n  for (const b of blocks) {\r\n    if (b.kind === 'paragraph') {\r\n      for (const line of b.lines) {\r\n        for (const inl of line.inlines) {\r\n          if (inl.controlId && !(pos.offset === 0 ? inl.controlStart : inl.controlEnd)) continue\r\n          if (isSamePath(inl.path, pos.path) && pos.offset >= inl.startOffset && pos.offset <= inl.endOffset) {\r\n            return inl\r\n          }\r\n        }\r\n      }\r\n    } else if (b.kind === 'table') {\r\n      for (const row of b.rows) {\r\n        for (const cell of row.cells) {\r\n          const r = findInlineInBlocks(cell.content, pos)\r\n          if (r) return r\r\n        }\r\n      }\r\n    }\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 按 position 在 layout 中查找所属段落块。\r\n * @param layout 文档布局\r\n * @param pos 待定位位置\r\n * @returns 命中的 ParagraphBlock；未命中返回 null\r\n */\r\nexport function findParagraphByPos(layout: DocumentLayout | null, pos: IPosition): ParagraphBlock | null {\r\n  if (!layout) return null\r\n  for (const page of layout.pages) {\r\n    const r = findParagraphInBlocks(page.blocks, pos)\r\n    if (r) return r\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 在 block 列表中递归查找所属段落块（含表格单元格递归）。\r\n * @param blocks 块列表\r\n * @param pos 待定位位置\r\n * @returns 命中的 ParagraphBlock；未命中返回 null\r\n */\r\nexport function findParagraphInBlocks(blocks: BlockNode[], pos: IPosition): ParagraphBlock | null {\r\n  for (const b of blocks) {\r\n    if (b.kind === 'paragraph') {\r\n      for (const line of b.lines) {\r\n        for (const inl of line.inlines) {\r\n          if (inl.controlId && !(pos.offset === 0 ? inl.controlStart : inl.controlEnd)) continue\r\n          if (isSamePath(inl.path, pos.path)) return b\r\n        }\r\n      }\r\n    } else if (b.kind === 'table') {\r\n      for (const row of b.rows) {\r\n        for (const cell of row.cells) {\r\n          const r = findParagraphInBlocks(cell.content, pos)\r\n          if (r) return r\r\n        }\r\n      }\r\n    }\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 按 position 在 layout 中查找所属行盒。\r\n * @param layout 文档布局\r\n * @param pos 待定位位置\r\n * @returns 命中的 LineBox；未命中返回 null\r\n */\r\nexport function findLineByPos(layout: DocumentLayout | null, pos: IPosition): LineBox | null {\r\n  if (!layout) return null\r\n  for (const page of layout.pages) {\r\n    const r = findLineInBlocks(page.blocks, pos)\r\n    if (r) return r\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 在 block 列表中递归查找所属行盒（含表格单元格递归）。\r\n * @param blocks 块列表\r\n * @param pos 待定位位置\r\n * @returns 命中的 LineBox；未命中返回 null\r\n */\r\nexport function findLineInBlocks(blocks: BlockNode[], pos: IPosition): LineBox | null {\r\n  for (const b of blocks) {\r\n    if (b.kind === 'paragraph') {\r\n      for (const line of b.lines) {\r\n        for (const inl of line.inlines) {\r\n          if (inl.controlId && !(pos.offset === 0 ? inl.controlStart : inl.controlEnd)) continue\r\n          if (isSamePath(inl.path, pos.path) && pos.offset >= inl.startOffset && pos.offset <= inl.endOffset) {\r\n            return line\r\n          }\r\n        }\r\n      }\r\n    } else if (b.kind === 'table') {\r\n      for (const row of b.rows) {\r\n        for (const cell of row.cells) {\r\n          const r = findLineInBlocks(cell.content, pos)\r\n          if (r) return r\r\n        }\r\n      }\r\n    }\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 查找文档首个 inline（用于光标兜底定位到文档首）。\r\n * @param layout 文档布局\r\n * @returns 首个 InlineBox；空文档返回 null\r\n */\r\nexport function findFirstInline(layout: DocumentLayout | null): InlineBox | null {\r\n  if (!layout) return null\r\n  for (const page of layout.pages) {\r\n    const r = findFirstInlineInBlocks(page.blocks)\r\n    if (r) return r\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 在 block 列表中递归查找首个 inline（含表格单元格递归）。\r\n * @param blocks 块列表\r\n * @returns 首个 InlineBox；未命中返回 null\r\n */\r\nexport function findFirstInlineInBlocks(blocks: BlockNode[]): InlineBox | null {\r\n  for (const b of blocks) {\r\n    if (b.kind === 'paragraph') {\r\n      for (const line of b.lines) {\r\n        if (line.inlines[0]) return line.inlines[0]\r\n      }\r\n    } else if (b.kind === 'table') {\r\n      for (const row of b.rows) {\r\n        for (const cell of row.cells) {\r\n          const r = findFirstInlineInBlocks(cell.content)\r\n          if (r) return r\r\n        }\r\n      }\r\n    }\r\n  }\r\n  return null\r\n}\r\n\r\n/**\r\n * 查找文档末个 inline（用于光标定位到文档尾/全选终点）。\r\n * @param layout 文档布局\r\n * @returns 末个 InlineBox；空文档返回 null\r\n */\r\nexport function findLastInline(layout: DocumentLayout | null): InlineBox | null {\r\n  if (!layout) return null\r\n  let last: InlineBox | null = null\r\n  for (const page of layout.pages) {\r\n    findLastInlineInBlocks(page.blocks, (inl) => { last = inl })\r\n  }\r\n  return last\r\n}\r\n\r\n/**\r\n * 在 block 列表中递归遍历所有 inline，对每个 inline 调用回调（含表格单元格递归）。\r\n * @param blocks 块列表\r\n * @param onInline 每个 inline 的回调\r\n */\r\nexport function findLastInlineInBlocks(blocks: BlockNode[], onInline: (inl: InlineBox) => void): void {\r\n  for (const b of blocks) {\r\n    if (b.kind === 'paragraph') {\r\n      for (const line of b.lines) {\r\n        for (const inl of line.inlines) onInline(inl)\r\n      }\r\n    } else if (b.kind === 'table') {\r\n      for (const row of b.rows) {\r\n        for (const cell of row.cells) {\r\n          findLastInlineInBlocks(cell.content, onInline)\r\n        }\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\n/** 按 position 定位 inline，若属于超链接则返回其 URL（供 Ctrl+点击跳转） */\r\nexport function findHyperlinkByPos(layout: DocumentLayout | null, pos: IPosition): string | null {\r\n  return findInlineByPos(layout, pos)?.hyperlink ?? null\r\n}\r\n\r\n/** 按 position 定位 inline，若属于内置控件则返回其 controlId（供点击激活交互浮层） */\r\nexport function findControlByPos(layout: DocumentLayout | null, pos: IPosition): InlineBox | null {\r\n  const inline = findInlineByPos(layout, pos)\r\n  if (inline?.controlId) return inline\r\n  return null\r\n}\r\n","/**\r\n * AnchorCollector —— 锚点收集纯函数\r\n *\r\n * 遍历 layout 收集批注组/修订锚点坐标，供批注/修订 overlay 绘制竖线。\r\n */\r\n\r\nimport type { BlockNode } from './layout-types'\r\n\r\n/** 锚点坐标信息 */\r\nexport interface AnchorInfo {\r\n  startX: number\r\n  startY: number\r\n  endX: number\r\n  endY: number\r\n  lineHeight: number\r\n  endLineHeight?: number\r\n  glyphHeight: number\r\n  startGlyphTop: number\r\n  endGlyphTop: number\r\n}\r\n\r\n/**\r\n * 遍历 block 列表，收集每个 groupId 所对应的锚点坐标（文档绝对坐标）。\r\n * @param blocks 块列表\r\n * @param originX 块列表原点 x\r\n * @param originY 块列表原点 y\r\n * @param result 收集结果的 Map\r\n */\r\nexport function collectGroupAnchors(\r\n  blocks: BlockNode[],\r\n  originX: number,\r\n  originY: number,\r\n  result: Map<string, AnchorInfo>\r\n): void {\r\n  for (const b of blocks) {\r\n    if (b.kind === 'table') {\r\n      for (const row of b.rows) {\r\n        for (const cell of row.cells) {\r\n          const cx = originX + b.rect.x + cell.rect.x + cell.contentPaddingLeft\r\n          const cy = originY + b.rect.y + cell.rect.y + cell.contentPaddingTop + cell.verticalOffset\r\n          collectGroupAnchors(cell.content, cx, cy, result)\r\n        }\r\n      }\r\n      continue\r\n    }\r\n    if (b.kind !== 'paragraph') continue\r\n    const bx = originX + b.rect.x\r\n    const by = originY + b.rect.y\r\n    for (const line of b.lines) {\r\n      for (const inl of line.inlines) {\r\n        if (!inl.groupIds?.length) continue\r\n        const absX = bx + inl.x\r\n        const absY = by + line.y\r\n        const absEndX = absX + inl.width\r\n        const absEndY = absY + line.height\r\n        const glyphHeight = inl.size * 1.15\r\n        const absGlyphTop = absY + line.baseline - inl.size * 0.875\r\n        for (const gid of inl.groupIds) {\r\n          const existing = result.get(gid)\r\n          if (!existing) {\r\n            result.set(gid, { startX: absX, startY: absY, endX: absEndX, endY: absEndY, lineHeight: line.height, endLineHeight: line.height, glyphHeight, startGlyphTop: absGlyphTop, endGlyphTop: absGlyphTop })\r\n          } else {\r\n            if (absY < existing.startY || (absY === existing.startY && absX < existing.startX)) {\r\n              existing.startX = absX\r\n              existing.startY = absY\r\n              existing.lineHeight = line.height\r\n              existing.startGlyphTop = absGlyphTop\r\n            }\r\n            if (absEndY > existing.endY || (absEndY === existing.endY && absEndX > existing.endX)) {\r\n              existing.endX = absEndX\r\n              existing.endY = absEndY\r\n              existing.endLineHeight = line.height\r\n              existing.endGlyphTop = absGlyphTop\r\n            }\r\n          }\r\n        }\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\n/**\r\n * 遍历 block 列表，收集每个 revisionId 所对应的锚点坐标（文档绝对坐标）。\r\n * @param blocks 块列表\r\n * @param originX 块列表原点 x\r\n * @param originY 块列表原点 y\r\n * @param result 收集结果的 Map\r\n */\r\nexport function collectRevisionAnchors(\r\n  blocks: BlockNode[],\r\n  originX: number,\r\n  originY: number,\r\n  result: Map<string, AnchorInfo>\r\n): void {\r\n  for (const b of blocks) {\r\n    if (b.kind === 'table') {\r\n      for (const row of b.rows) {\r\n        for (const cell of row.cells) {\r\n          const cx = originX + b.rect.x + cell.rect.x + cell.contentPaddingLeft\r\n          const cy = originY + b.rect.y + cell.rect.y + cell.contentPaddingTop + cell.verticalOffset\r\n          collectRevisionAnchors(cell.content, cx, cy, result)\r\n        }\r\n      }\r\n      continue\r\n    }\r\n    if (b.kind !== 'paragraph') continue\r\n    const bx = originX + b.rect.x\r\n    const by = originY + b.rect.y\r\n    for (const line of b.lines) {\r\n      for (const inl of line.inlines) {\r\n        const revisionId = (inl.run as any)?.revisionId\r\n        if (!revisionId) continue\r\n        const absX = bx + inl.x\r\n        const absY = by + line.y\r\n        const absEndX = absX + inl.width\r\n        const absEndY = absY + line.height\r\n        const glyphHeight = inl.size * 1.15\r\n        const absGlyphTop = absY + line.baseline - inl.size * 0.875\r\n        const existing = result.get(revisionId)\r\n        if (!existing) {\r\n          result.set(revisionId, {\r\n            startX: absX,\r\n            startY: absY,\r\n            endX: absEndX,\r\n            endY: absEndY,\r\n            lineHeight: line.height,\r\n            endLineHeight: line.height,\r\n            glyphHeight,\r\n            startGlyphTop: absGlyphTop,\r\n            endGlyphTop: absGlyphTop\r\n          })\r\n        } else {\r\n          if (absY < existing.startY || (absY === existing.startY && absX < existing.startX)) {\r\n            existing.startX = absX\r\n            existing.startY = absY\r\n            existing.lineHeight = line.height\r\n            existing.startGlyphTop = absGlyphTop\r\n          }\r\n          if (absEndY > existing.endY || (absEndY === existing.endY && absEndX > existing.endX)) {\r\n            existing.endX = absEndX\r\n            existing.endY = absEndY\r\n            existing.endLineHeight = line.height\r\n            existing.endGlyphTop = absGlyphTop\r\n          }\r\n        }\r\n      }\r\n    }\r\n  }\r\n}\r\n","/**\r\n * CaretNavigation —— 光标导航 Controller\r\n *\r\n * 提供双击选词、三击选段、方向键移动、Home/End、词移动、文档首尾、全选等光标导航功能。\r\n */\r\n\r\nimport type { DocumentLayout, InlineBox, LineBox, ParagraphBlock } from './layout-types'\r\nimport type { RangeManager } from '@vervedoc/docx-editor-state'\r\nimport { isSamePath, type IPosition } from '@vervedoc/docx-editor-schema'\nimport { locateCaret } from './caret-rect'\r\nimport { hitTest } from './hit-test'\r\nimport type { Zone } from './widgets/header-footer-widget'\r\n\r\n/**\r\n * CaretNavigation 的依赖注入接口\r\n *\r\n * 由外部宿主提供，用于获取布局、选区、区域信息以及布局查询方法等。\r\n */\r\nexport interface CaretNavigationDeps {\r\n  /** 获取当前文档布局，可能为 null */\r\n  getLayout: () => DocumentLayout | null\r\n  /** 获取当前选区管理器，可能为 null */\r\n  getRange: () => RangeManager | null\r\n  /** 获取当前编辑区域 */\r\n  getZone: () => Zone\r\n  /** 获取当前页眉/页脚编辑所在页 */\n  getActivePageIndex: () => number | null\n  /** 按 position 查找所属 inline */\r\n  findInlineByPos: (pos: IPosition) => InlineBox | null\r\n  /** 按 position 查找所属段落块 */\r\n  findParagraphByPos: (pos: IPosition) => ParagraphBlock | null\r\n  /** 按 position 查找所属行盒 */\r\n  findLineByPos: (pos: IPosition) => LineBox | null\r\n  /** 查找文档首个 inline */\r\n  findFirstInline: () => InlineBox | null\r\n  /** 查找文档末个 inline */\r\n  findLastInline: () => InlineBox | null\r\n  /** 设置光标可见性 */\r\n  setCaretVisible: (visible: boolean) => void\r\n  /** 重绘光标 overlay */\r\n  renderCaretIfAny: () => void\r\n}\r\n\r\n/**\r\n * 光标导航 Controller\r\n *\r\n * 封装光标移动、选词、选段、全选等导航操作。\r\n */\r\nexport class CaretNavigation {\r\n  /**\r\n   * 构造 CaretNavigation 实例\r\n   *\r\n   * @param deps 依赖注入对象\r\n   */\r\n  constructor(private deps: CaretNavigationDeps) {}\r\n\r\n  /**\r\n   * 双击选词：在命中 inline 内按 word char 边界扩展选区；非 word char 选当前单字。\r\n   * @param pos 命中位置\r\n   */\r\n  selectWordAt(pos: IPosition): void {\r\n    const range = this.deps.getRange()\r\n    const layout = this.deps.getLayout()\r\n    if (!range || !layout) return\r\n    const inl = this.deps.findInlineByPos(pos)\r\n    if (!inl) { range.setCaret(pos); return }\r\n    const text = inl.controlId ? '\\uFFFC' : inl.text\r\n    const localOff = pos.offset - inl.startOffset\r\n    const isWord = (ch: string) => /[A-Za-z0-9_]/.test(ch)\r\n    let left = localOff\r\n    let right = localOff\r\n    while (left > 0 && isWord(text[left - 1])) left--\r\n    while (right < text.length && isWord(text[right])) right++\r\n    // 非 word char（CJK / 标点 / 空格）：选当前单字\r\n    if (left === right) {\r\n      if (localOff < text.length) right = localOff + 1\r\n      else left = Math.max(0, localOff - 1)\r\n    }\r\n    range.setRange({\r\n      anchor: { path: inl.path, offset: inl.startOffset + left },\r\n      focus: { path: inl.path, offset: inl.startOffset + right }\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 三击选段：把选区扩展到命中段落的首 inline 起点到末 inline 终点。\r\n   * @param pos 命中位置\r\n   */\r\n  selectParagraphAt(pos: IPosition): void {\r\n    const range = this.deps.getRange()\r\n    const layout = this.deps.getLayout()\r\n    if (!range || !layout) return\r\n    const para = this.deps.findParagraphByPos(pos)\r\n    if (!para) { range.setCaret(pos); return }\r\n    let first: InlineBox | undefined\r\n    let last: InlineBox | undefined\r\n    for (const line of para.lines) {\r\n      for (const inl of line.inlines) {\r\n        if (!first) first = inl\r\n        last = inl\r\n      }\r\n    }\r\n    if (!first || !last) { range.setCaret(pos); return }\r\n    range.setRange({\r\n      anchor: { path: first.path, offset: first.startOffset },\r\n      focus: { path: last.path, offset: last.endOffset }\r\n    })\r\n  }\r\n\r\n  /** 光标上移：基于当前光标矩形，用 hitTest 命中上一行同 x 最近字符 */\r\n  moveCaretUp(): void {\r\n    this.moveCaretVertical(-1)\r\n  }\r\n\r\n  /** 光标下移 */\r\n  moveCaretDown(): void {\r\n    this.moveCaretVertical(1)\r\n  }\r\n\r\n  /**\r\n   * 光标垂直移动：基于当前光标矩形，用 hitTest 命中上一/下一行同 x 最近字符。\r\n   * @param dir 移动方向，1=下移，-1=上移\r\n   */\r\n  private moveCaretVertical(dir: 1 | -1): void {\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) return\r\n    const pos = range.getFocus()\r\n    if (!pos) return\r\n    const paragraph = this.deps.findParagraphByPos(pos)\n    if (paragraph?.verticalText) {\n      this.moveCaretInVerticalText(paragraph, pos, dir)\n      return\n    }\n    const rect = locateCaret(layout, pos, this.deps.getZone(), this.deps.getActivePageIndex())\n    if (!rect) return\r\n    // 目标 y = 当前光标 y ± 行高（估算上一/下一行中部）\r\n    const targetY = rect.y + dir * rect.height\r\n    const newPos = hitTest(layout, rect.x, targetY, this.deps.getZone())\r\n    if (newPos) {\r\n      range.setCaret(newPos)\r\n      this.deps.setCaretVisible(true)\r\n      this.deps.renderCaretIfAny()\r\n    }\r\n  }\r\n\r\n  /** 竖排时，上下方向键沿字符流移动，而不是按横排行盒做几何跳转。 */\n  private moveCaretInVerticalText(paragraph: ParagraphBlock, pos: IPosition, dir: 1 | -1): void {\n    const range = this.deps.getRange()\n    if (!range) return\n    const inlines = paragraph.lines.flatMap(line => line.inlines)\n    const index = inlines.findIndex(inline =>\n      isSamePath(inline.path, pos.path) &&\n      pos.offset >= inline.startOffset &&\n      pos.offset <= inline.endOffset)\n    if (index < 0) return\n\n    const current = inlines[index]\n    let target: IPosition | undefined\n    if (dir > 0) {\n      target = pos.offset < current.endOffset\n        ? { path: current.path, offset: pos.offset + 1 }\n        : inlines[index + 1] && {\n          path: inlines[index + 1].path,\n          offset: Math.min(inlines[index + 1].startOffset + 1, inlines[index + 1].endOffset)\n        }\n    } else {\n      target = pos.offset > current.startOffset\n        ? { path: current.path, offset: pos.offset - 1 }\n        : inlines[index - 1] && {\n          path: inlines[index - 1].path,\n          offset: Math.max(inlines[index - 1].endOffset - 1, inlines[index - 1].startOffset)\n        }\n    }\n    if (!target) return\n    range.setCaret(target)\n    this.deps.setCaretVisible(true)\n    this.deps.renderCaretIfAny()\n  }\n\n  /** 当前行首 */\r\n  moveCaretToLineStart(): void {\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) return\r\n    const pos = range.getFocus()\r\n    if (!pos) return\r\n    const paragraph = this.deps.findParagraphByPos(pos)\n    if (paragraph?.verticalText) {\n      const first = paragraph.lines.flatMap(line => line.inlines)[0]\n      if (!first) return\n      range.setCaret({ path: first.path, offset: first.startOffset })\n      this.deps.setCaretVisible(true)\n      this.deps.renderCaretIfAny()\n      return\n    }\n    const line = this.deps.findLineByPos(pos)\r\n    if (!line) return\r\n    const first = line.inlines[0]\r\n    if (first) {\r\n      range.setCaret({ path: first.path, offset: first.startOffset })\r\n      this.deps.setCaretVisible(true)\r\n      this.deps.renderCaretIfAny()\r\n    }\r\n  }\r\n\r\n  /** 当前行尾 */\r\n  moveCaretToLineEnd(): void {\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) return\r\n    const pos = range.getFocus()\r\n    if (!pos) return\r\n    const paragraph = this.deps.findParagraphByPos(pos)\n    if (paragraph?.verticalText) {\n      const inlines = paragraph.lines.flatMap(line => line.inlines)\n      const last = inlines[inlines.length - 1]\n      if (!last) return\n      range.setCaret({ path: last.path, offset: last.endOffset })\n      this.deps.setCaretVisible(true)\n      this.deps.renderCaretIfAny()\n      return\n    }\n    const line = this.deps.findLineByPos(pos)\r\n    if (!line) return\r\n    const last = line.inlines[line.inlines.length - 1]\r\n    if (last) {\r\n      range.setCaret({ path: last.path, offset: last.endOffset })\r\n      this.deps.setCaretVisible(true)\r\n      this.deps.renderCaretIfAny()\r\n    }\r\n  }\r\n\r\n  /** 按词左移 */\r\n  moveCaretWordLeft(): void {\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) return\r\n    const pos = range.getFocus()\r\n    if (!pos) return\r\n    const inl = this.deps.findInlineByPos(pos)\r\n    if (!inl) return\r\n    const text = inl.controlId ? '\\uFFFC' : inl.text\r\n    const localOff = pos.offset - inl.startOffset\r\n    const isWord = (ch: string) => /[A-Za-z0-9_]/.test(ch)\r\n    let off = localOff\r\n    // 先跳过非 word char（空格/标点），再跳过 word char\r\n    while (off > 0 && !isWord(text[off - 1])) off--\r\n    while (off > 0 && isWord(text[off - 1])) off--\r\n    if (off === localOff && off > 0) off = localOff - 1\r\n    range.setCaret({ path: inl.path, offset: inl.startOffset + off })\r\n    this.deps.setCaretVisible(true)\r\n    this.deps.renderCaretIfAny()\r\n  }\r\n\r\n  /** 按词右移 */\r\n  moveCaretWordRight(): void {\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) return\r\n    const pos = range.getFocus()\r\n    if (!pos) return\r\n    const inl = this.deps.findInlineByPos(pos)\r\n    if (!inl) return\r\n    const text = inl.text\r\n    const localOff = pos.offset - inl.startOffset\r\n    const isWord = (ch: string) => /[A-Za-z0-9_]/.test(ch)\r\n    let off = localOff\r\n    while (off < text.length && !isWord(text[off])) off++\r\n    while (off < text.length && isWord(text[off])) off++\r\n    if (off === localOff && off < text.length) off = localOff + 1\r\n    range.setCaret({ path: inl.path, offset: inl.startOffset + off })\r\n    this.deps.setCaretVisible(true)\r\n    this.deps.renderCaretIfAny()\r\n  }\r\n\r\n  /** 文档首 */\r\n  moveCaretToDocStart(): void {\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) return\r\n    const first = this.deps.findFirstInline()\r\n    if (first) {\r\n      range.setCaret({ path: first.path, offset: first.startOffset })\r\n      this.deps.setCaretVisible(true)\r\n      this.deps.renderCaretIfAny()\r\n    }\r\n  }\r\n\r\n  /** 文档尾 */\r\n  moveCaretToDocEnd(): void {\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) return\r\n    const last = this.deps.findLastInline()\r\n    if (last) {\r\n      range.setCaret({ path: last.path, offset: last.endOffset })\r\n      this.deps.setCaretVisible(true)\r\n      this.deps.renderCaretIfAny()\r\n    }\r\n  }\r\n\r\n  /** 全选：从文档首到文档尾 */\r\n  selectAll(): void {\r\n    const layout = this.deps.getLayout()\r\n    const range = this.deps.getRange()\r\n    if (!layout || !range) return\r\n    const first = this.deps.findFirstInline()\r\n    const last = this.deps.findLastInline()\r\n    if (!first || !last) return\r\n    range.setRange({\r\n      anchor: { path: first.path, offset: first.startOffset },\r\n      focus: { path: last.path, offset: last.endOffset }\r\n    })\r\n    this.deps.setCaretVisible(false)\r\n    this.deps.renderCaretIfAny()\r\n  }\r\n}\r\n","/**\r\n * ZoneManager —— 编辑区域 Manager\r\n *\r\n * 管理正文/页眉/页脚编辑区域切换、活动文档获取与写回。\r\n */\r\n\r\nimport type { IDocxDocumentMeta, IElement, IPosition } from '@vervedoc/docx-editor-schema'\r\nimport type { RangeManager } from '@vervedoc/docx-editor-state'\r\nimport type { DocumentLayout } from './layout-types'\nimport type { Zone } from './widgets/header-footer-widget'\r\n\r\n/**\r\n * ZoneManager 的依赖注入接口\r\n *\r\n * 由外部宿主提供，用于获取/设置区域、文档、选区以及触发渲染等。\r\n */\r\nexport interface ZoneManagerDeps {\r\n  /** 获取当前编辑区域 */\r\n  getZone: () => Zone\r\n  /** 直接设置区域状态（不触发副作用） */\r\n  setZoneState: (zone: Zone) => void\r\n  /** 获取当前文档元数据 */\r\n  getDocument: () => IDocxDocumentMeta\r\n  /** 获取布局，用于判断当前页是否为本节首页 */\n  getLayout: () => DocumentLayout | null\n  getPage: () => import('@vervedoc/docx-editor-schema').PageLayout | undefined\r\n  /** 获取当前选区管理器，可能为 null */\r\n  getRange: () => RangeManager | null\r\n  /** 聚焦隐藏输入框 */\r\n  focusInput: () => void\r\n  /** zone 变化回调 */\r\n  onZoneChange: (zone: Zone) => void\r\n  /** 调度一帧渲染 */\r\n  scheduleRender: () => void\r\n  /** 重排版+重渲染 */\r\n  reformatAndRender: () => void\r\n}\r\n\r\n/**\r\n * 编辑区域 Manager\r\n *\r\n * 封装区域切换、活动文档获取/写回、区域首文本位置查找等逻辑。\r\n */\r\nexport class ZoneManager {\r\n  /**\r\n   * 构造 ZoneManager 实例\r\n   *\r\n   * @param deps 依赖注入对象\r\n   */\r\n  constructor(private deps: ZoneManagerDeps) {}\r\n\r\n  /** 切换编辑区域（main/header/footer） */\r\n  setZone(zone: Zone): void {\r\n    const initialized = zone !== 'main' && this.ensureZoneContent(zone)\n    const changed = this.deps.getZone() !== zone\n    this.deps.setZoneState(zone)\r\n    if (initialized) this.deps.reformatAndRender()\n    if (changed) this.deps.onZoneChange(zone)\n    this.deps.scheduleRender()\r\n  }\r\n\r\n  /**\n   * 用户显式进入空区域时补齐可编辑段落及分节引用，不在读取文档时隐式创建。\n   * 已有引用（包括继承引用）直接复用，首页及奇偶页引用分别保留。\n   */\n  private ensureZoneContent(zone: 'header' | 'footer'): boolean {\n    const doc = this.deps.getDocument()\n    let elements: IElement[]\n    let initialized = false\n    if (doc.sections) {\n      const page = this.deps.getPage()\n      const sectionIndex = page?.sectionIndex\n      const section = sectionIndex == null ? undefined : doc.sections[sectionIndex]\n      if (!page || !section) throw new TypeError('当前页缺少分节信息，无法编辑页眉页脚')\n      const parts = doc.headerFooterParts ??= {}\n      let partId = zone === 'header' ? page.headerPartId : page.footerPartId\n      if (!partId) {\n        const firstPage = this.deps.getLayout()?.pages.find(p => p.sectionIndex === sectionIndex)\n        const kind = section.titlePage && firstPage?.index === page.index\n          ? 'first'\n          : doc.evenAndOddHeaders && (page.index + 1) % 2 === 0 ? 'even' : 'default'\n        const baseId = `editor-${zone}-${sectionIndex}-${kind}`\n        partId = baseId\n        for (let suffix = 1; parts[partId] !== undefined; suffix++) partId = `${baseId}-${suffix}`\n        const refs = zone === 'header' ? (section.headers ??= {}) : (section.footers ??= {})\n        refs[kind] = partId\n        initialized = true\n      }\n      elements = parts[partId] ??= []\n    } else {\n      elements = doc[zone] ?? doc.contentZones?.[zone] ?? (doc[zone] = [])\n    }\n    if (elements.length === 0) {\n      elements.push({ type: 'text', value: '' })\n      initialized = true\n    }\n    return initialized\n  }\n\n  /**\r\n   * 切换编辑区域并设置初始光标。\r\n   * 切换到页眉/页脚时，将光标定位到对应区域的起始文本位置；\r\n   * 切回正文时清空选区。\r\n   * @param zone 目标区域\r\n   */\r\n  setZoneWithCaret(zone: Zone, resetCaret = false): void {\n    const changed = this.deps.getZone() !== zone\r\n    this.setZone(zone)\r\n    if (!changed && !resetCaret) return\n    const range = this.deps.getRange()\r\n    if (!range) return\r\n    if (zone === 'header' || zone === 'footer') {\r\n      const pos = this.findZoneFirstPosition()\r\n      range.setCaret(pos)\r\n      this.deps.focusInput()\r\n    } else {\r\n      range.clear()\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 查找当前活动区域（页眉/页脚）的第一个文本位置，用于切换区域时设置初始光标。\r\n   * 若区域为空则返回指向元素数组末尾的虚拟位置，便于后续插入。\r\n   * @returns 起始文本位置\r\n   */\r\n  private findZoneFirstPosition(): IPosition {\r\n    const doc = this.getActiveDocument()\r\n    const pos = this.findFirstTextPositionInElements(doc.elements)\r\n    if (pos) return pos\r\n    return { path: [doc.elements.length], offset: 0 }\r\n  }\r\n\r\n  /**\r\n   * 递归查找元素列表中的第一个文本元素位置。\r\n   * @param elements 元素列表\r\n   * @returns 第一个文本位置；未找到返回 null\r\n   */\r\n  private findFirstTextPositionInElements(elements: IElement[]): IPosition | null {\r\n    for (let i = 0; i < elements.length; i++) {\r\n      const el = elements[i] as any\r\n      if (el.type === 'text') {\r\n        return { path: [i], offset: 0 }\r\n      }\r\n      if (el.type === 'title' || el.type === 'list') {\r\n        const sub = el.valueList ?? el.elements ?? []\r\n        const pos = this.findFirstTextPositionInElements(sub)\r\n        if (pos) return { path: [i, 'valueList', ...pos.path], offset: pos.offset }\r\n      }\r\n      if (el.type === 'table') {\r\n        const trList = el.trList ?? []\r\n        for (let r = 0; r < trList.length; r++) {\r\n          const tdList = trList[r].tdList ?? []\r\n          for (let c = 0; c < tdList.length; c++) {\r\n            const pos = this.findFirstTextPositionInElements(tdList[c].value ?? [])\r\n            if (pos) return { path: [i, 'trList', r, 'tdList', c, 'value', ...pos.path], offset: pos.offset }\r\n          }\r\n        }\r\n      }\r\n    }\r\n    return null\r\n  }\r\n\r\n  /** 获取当前活动区域的文档（zone=header/footer 时 elements 指向对应区域） */\r\n  getActiveDocument(): IDocxDocumentMeta {\r\n    const doc = this.deps.getDocument()\r\n    const zone = this.deps.getZone()\r\n    if (zone === 'header' || zone === 'footer') {\r\n      if (doc.sections) {\r\n        const page = this.deps.getPage()\r\n        const partId = zone === 'header' ? page?.headerPartId : page?.footerPartId\r\n        if (!partId || !doc.headerFooterParts?.[partId]) throw new TypeError('当前页没有 Java 页眉页脚 part 引用，不能隐式创建')\r\n        return { ...doc, elements: doc.headerFooterParts[partId] }\r\n      }\r\n      return { ...doc, elements: doc[zone] ?? doc.contentZones?.[zone] ?? (doc[zone] = []) }\r\n    }\r\n    return doc\r\n  }\r\n\r\n  /** 将修改后的活动文档写回对应区域并触发重渲染 */\r\n  applyActiveDocument(doc: IDocxDocumentMeta): void {\r\n    const current = this.deps.getDocument()\r\n    const zone = this.deps.getZone()\r\n    if (zone === 'header' || zone === 'footer') {\r\n      if (current.sections) {\r\n        const page = this.deps.getPage()\r\n        const partId = zone === 'header' ? page?.headerPartId : page?.footerPartId\r\n        if (!partId || !current.headerFooterParts?.[partId]) throw new TypeError('当前页没有 Java 页眉页脚 part 引用，不能隐式创建')\r\n        current.headerFooterParts[partId] = doc.elements\r\n      } else if (current[zone] !== undefined || !current.contentZones?.[zone]) {\r\n        current[zone] = doc.elements\r\n      } else {\r\n        current.contentZones[zone] = doc.elements\r\n      }\r\n    } else {\r\n      current.elements = doc.elements\r\n    }\r\n    this.deps.reformatAndRender()\r\n  }\r\n}\n","/**\r\n * VerveDocs View —— Draw\r\n *\r\n * 编辑器视图门面。\r\n *\r\n * 增量策略：\r\n *  - Reuse unchanged paragraph layout and block bitmaps.\r\n *  - Diff paint snapshots against the last rendered frame.\r\n *  - Regenerate thumbnails only for changed pages.\r\n */\r\n\r\nimport { createEditorI18n, type EditorI18n, type Translate } from '@vervedoc/i18n'\r\nimport type { IDocxDocumentMeta, IEditorOption, IPosition, Path } from '@vervedoc/docx-editor-schema'\r\nimport { formatElementTree, pairBookmarkMarkers, getByPath } from '@vervedoc/docx-editor-schema'\r\n\r\nimport type { Listener, RangeManager, EventBus } from '@vervedoc/docx-editor-state'\r\nimport { LayoutEngine, type LayoutOptions } from './layout-engine'\r\nimport type { DocumentLayout, ParagraphBlock, InlineBox, LineBox } from './layout-types'\r\nimport { CanvasRenderer } from './canvas-renderer'\r\nimport { hitTest } from './hit-test'\r\nimport { locateCaret, computeSelectionRects } from './caret-rect'\r\nimport { TableWidget } from './widgets/table-widget'\r\nimport { ImageWidget } from './widgets/image-widget'\r\nimport { ChartWidget } from './widgets/chart-widget'\r\nimport { ParagraphWidget } from './widgets/paragraph-widget'\r\nimport { HeaderFooterWidget, type Zone } from './widgets/header-footer-widget'\r\nimport { RulerWidget } from './widgets/ruler-widget'\r\nimport { WatermarkWidget, type WatermarkConfig } from './widgets/watermark-widget'\r\nimport { SystemWatermarkWidget, type SystemWatermarkConfig } from './widgets/watermark-system-widget'\r\nimport { SelectionToolbarWidget } from './widgets/selection-toolbar-widget'\r\nimport { CaretWidget } from './widgets/caret-widget'\r\nimport { ControlWidget } from './widgets/control-widget'\r\nimport { computeDirtyRect, prepareRenderState, type RenderState } from './render-state'\r\nimport {\r\n  findInlineByPos,\r\n  findParagraphByPos,\r\n  findLineByPos,\r\n  findFirstInline,\r\n  findLastInline,\r\n  findHyperlinkByPos\r\n} from './layout-query'\r\nimport { collectGroupAnchors, collectRevisionAnchors, type AnchorInfo } from './anchor-collector'\r\nimport { CaretNavigation } from './caret-navigation'\r\nimport { ZoneManager } from './zone-manager'\r\n\r\n// 固定黑色 I-beam，避免系统文本指针在白色页面上不可见。\r\nconst TEXT_CURSOR = `url(\"data:image/svg+xml,${encodeURIComponent('<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\"><path d=\"M8 3h8M12 3v18M8 21h8\" fill=\"none\" stroke=\"black\" stroke-width=\"2\"/></svg>')}\") 9 9, text`\r\n\r\n/** Draw 门面依赖：装配文档、状态管理器与各类回调 */\r\nexport interface DrawDeps {\r\n  /** 文档元数据 */\r\n  document: IDocxDocumentMeta\r\n  /** 事件监听器（用于发射 page-count-change 等事件） */\r\n  listener?: Listener\r\n  /** 事件总线（用于发射用户交互事件，如 editor-mousedown/chart-click 等） */\r\n  eventBus?: EventBus\r\n\r\n  /** 选区管理器 */\r\n  rangeManager?: RangeManager\r\n  /** 键盘/输入时触发的回调（由 core 装配） */\r\n  onInput?: (text: string) => void\r\n  /** 键盘事件回调（由 core 装配） */\r\n  onKeyDown?: (e: KeyboardEvent) => void\r\n  /** 每次 RAF 渲染完成后调用（用于驱动批注/修订 overlay 更新） */\r\n  afterRender?: () => void\r\n  /** 悬浮工具栏命令回调（由 core 装配，转发到 Command） */\r\n  onCommand?: (command: string, ...args: any[]) => any\r\n  /** zone 变化回调（由 core 装配，用于驱动 UI 标签显示） */\r\n  onZoneChange?: (zone: Zone) => void\r\n  i18n?: EditorI18n\r\n}\r\n\r\n/**\r\n * 编辑器视图门面类：装配 LayoutEngine + CanvasRenderer + 各交互 widget，\r\n * 对外提供文档/光标/选区/工具栏 API，对内调度排版、渲染、事件绑定。\r\n */\r\nexport class Draw {\r\n  /** 外层容器 DOM */\r\n  private container: HTMLDivElement\r\n  /** 滚动包装层（绝对定位、自身溢出滚动） */\r\n  private wrapper: HTMLDivElement\r\n  /** 撑起文档总高度的占位元素（驱动 wrapper 滚动） */\r\n  private scroller: HTMLDivElement\r\n  /** canvas 三层宿主（pointer-events:none，覆盖 container 视口） */\r\n  private canvasHost: HTMLDivElement\r\n  /** canvas 渲染器 */\r\n  private renderer: CanvasRenderer\r\n\r\n  setChartRenderer(renderer: import('@vervedoc/docx-editor-schema').IChartRenderer | null): void {\r\n    this.renderer.setChartRenderer(renderer)\r\n    this.thumbnailCache.clear()\r\n    this.forceFullRender = true\r\n    this.scheduleRender()\r\n  }\r\n  /** 排版引擎 */\r\n  private engine: LayoutEngine\r\n  /** 最近一次排版结果 */\r\n  private layout: DocumentLayout | null = null\r\n  private diagnosticNotice?: HTMLDivElement\r\n  private diagnosticSignature = ''\r\n\r\n  /** 文档元数据 */\r\n  private document: IDocxDocumentMeta\r\n  /** 编辑器选项 */\r\n  private options: IEditorOption\r\n  /** 选区管理器 */\r\n  private range?: RangeManager\r\n  /** 事件监听器 */\r\n  private listener?: Listener\r\n  /** 事件总线（用户交互事件） */\r\n  private eventBus?: EventBus\r\n  private translate: Translate\r\n  private unsubscribeI18n: () => void\r\n\r\n  /** 当前滚动 y（wrapper.scrollTop） */\r\n  private scrollY = 0\r\n  /** 视口高度 */\r\n  private viewportHeight = 0\r\n  /** 视口宽度 */\r\n  private viewportWidth = 0\r\n  /** RAF 帧句柄 */\r\n  private rafId: number | null = null\r\n  /** 当前 RAF 是否跳过 afterRender（滚动渲染时为 true，避免每帧生成缩略图） */\r\n  private _pendingSkipAfterRender = false\r\n\r\n  /** 容器尺寸观察器 */\r\n  private ro?: ResizeObserver\r\n\r\n  private renderState?: RenderState\r\n  private paintedState?: RenderState\r\n  private forceFullRender = true\r\n  private thumbnailCache = new Map<number, { signature: string; image: string; foreground?: string }>()\r\n\r\n  /** 隐藏 textarea：作为输入焦点与 IME 组合的宿主 */\r\n  private inputEl!: HTMLTextAreaElement\r\n  /** IME 组合输入中标志 */\r\n  private isComposing = false\r\n\r\n  /** 光标闪烁可见性 */\r\n  private caretVisible = true\r\n  /** 光标闪烁定时器句柄 */\r\n  private caretTimer: number | null = null\r\n\r\n  /** 鼠标拖拽选区状态 */\r\n  private isDragging = false\r\n  /** 拖拽锚点（按下位置） */\r\n  private dragAnchor: IPosition | null = null\r\n  /** 拖拽过程中最近一次命中位置（RAF 节流） */\r\n  private dragPendingPos: IPosition | null = null\r\n  /** 拖拽 RAF 句柄 */\r\n  private dragRafId: number | null = null\r\n\r\n  /** 文本输入回调 */\r\n  private onInput?: (text: string) => void\r\n  /** 键盘事件回调 */\r\n  private onKeyDown?: (e: KeyboardEvent) => void\r\n  /** 渲染完成后回调 */\r\n  private afterRender?: () => void\r\n  /** 命令回调（转发到 Command） */\r\n  private onCommand?: (command: string, ...args: any[]) => any\r\n\r\n  /** 悬浮选区工具栏 widget */\r\n  private selectionToolbarWidget: SelectionToolbarWidget | null = null\r\n  /** 抑制下一次悬浮工具栏显示（段落手柄选中时用） */\r\n  private _suppressToolbar = false\r\n\r\n\r\n  /** 当前编辑区域：正文 / 页眉 / 页脚 */\r\n  private zone: Zone = 'main'\r\n  /** 当前页眉/页脚编辑对应的页面索引 */\r\n  private activeZonePageIndex: number | null = null\r\n  /** zone 变化回调（由 core 装配，用于驱动 UI 标签显示） */\r\n  private onZoneChange?: (zone: Zone) => void\r\n\r\n  /** 表格交互 widget（手柄 + 右键菜单） */\r\n  private tableWidget: TableWidget | null = null\r\n  /** 图片交互 widget（选中 + 缩放手柄 + 右键菜单） */\r\n  private imageWidget: ImageWidget | null = null\r\n  /** 图表交互 widget（选中 + 缩放手柄 + 编辑/删除工具栏） */\r\n  private chartWidget: ChartWidget | null = null\r\n  /** 段落格式悬浮 widget */\r\n  private paragraphWidget: ParagraphWidget | null = null\r\n  /** 页眉页脚交互 widget */\r\n  private headerFooterWidget: HeaderFooterWidget | null = null\r\n  /** 标尺 widget */\r\n  private rulerWidget: RulerWidget | null = null\r\n  /** 水印渲染 widget */\r\n  private watermarkWidget: WatermarkWidget | null = null\r\n  /** 系统级水印 widget（DOM 覆盖层） */\r\n  private systemWatermarkWidget: SystemWatermarkWidget | null = null\r\n  /** DOM 光标 widget（替代 canvas overlay 绘制光标） */\r\n  private caretWidget: CaretWidget | null = null\r\n  /** 内置控件交互 widget（点击激活 + 输入浮层） */\r\n  private controlWidget: ControlWidget | null = null\r\n  /** 光标导航 Controller */\r\n  private caretNavigation: CaretNavigation | null = null\r\n  /** 编辑区域 Manager */\r\n  private zoneManager: ZoneManager | null = null\r\n\r\n  /**\r\n   * 创建 Draw 视图门面：构建 DOM 骨架、装配渲染器/排版引擎/各 widget、绑定事件并首次渲染。\r\n   * @param container 外层容器 DOM\r\n   * @param options 编辑器选项\r\n   * @param deps 依赖装配（文档、状态、回调）\r\n   */\r\n  constructor(container: HTMLDivElement, options: IEditorOption, deps: DrawDeps) {\r\n    this.container = container\r\n    this.options = options\r\n    this.document = deps.document\r\n    this.range = deps.rangeManager\r\n    this.onInput = deps.onInput\r\n    this.onKeyDown = deps.onKeyDown\r\n    this.afterRender = deps.afterRender\r\n    this.onCommand = deps.onCommand\r\n    this.onZoneChange = deps.onZoneChange\r\n    this.listener = deps.listener\r\n    this.eventBus = deps.eventBus\r\n    const i18n = deps.i18n ?? createEditorI18n(options.locale)\r\n    this.translate = i18n.t\r\n    this.unsubscribeI18n = i18n.subscribe(() => {\r\n      this.options.locale = i18n.locale\r\n      this.refreshTranslations()\r\n    })\r\n\r\n    container.classList.add('vervedocs-container')\r\n    // container 需要作为绝对定位的参照\r\n    if (getComputedStyle(container).position === 'static') {\r\n      container.style.position = 'relative'\r\n    }\r\n    container.style.overflow = 'hidden'\r\n    container.style.background = '#E2E2E2'\r\n\r\n    // scroller 是可滚动容器（自身溢出出现滚动条）\r\n    this.wrapper = document.createElement('div')\r\n    this.wrapper.className = 'vervedocs-wrapper'\r\n    this.wrapper.style.position = 'absolute'\r\n    this.wrapper.style.inset = '0'\r\n    this.wrapper.style.overflow = 'auto'\r\n    this.wrapper.style.background = 'transparent'\r\n    this.wrapper.style.cursor = TEXT_CURSOR\r\n    this.wrapper.style.zIndex = '5'\r\n\r\n    // 撑起文档总高度的占位元素\r\n    this.scroller = document.createElement('div')\r\n    this.scroller.className = 'vervedocs-scroller'\r\n    this.scroller.style.position = 'relative'\r\n\r\n    this.wrapper.appendChild(this.scroller)\r\n    container.appendChild(this.wrapper)\r\n\r\n    // canvas 层放在 container 内、wrapper 之上；绝对定位覆盖 container 视口，不参与滚动\r\n    this.canvasHost = document.createElement('div')\r\n    this.canvasHost.className = 'vervedocs-canvas-host'\r\n    this.canvasHost.style.position = 'absolute'\r\n    this.canvasHost.style.inset = '0'\r\n    this.canvasHost.style.pointerEvents = 'none'\r\n    container.appendChild(this.canvasHost)\r\n\r\n    this.renderer = new CanvasRenderer(this.canvasHost, {\r\n      dpr: Number(options.devicePixelRatio ?? window.devicePixelRatio ?? 1),\r\n      scale: Number(options.scale ?? 1),\r\n      pageMargins: (options.pageMargins as [number, number, number, number]) ?? [100, 120, 100, 120],\r\n      showMarginRuler: (options as unknown as { showMarginRuler?: boolean }).showMarginRuler ?? true,\r\n      groupColors: (options as unknown as { group?: { groupColors?: Record<string, import('@vervedoc/docx-editor-schema').IGroupColor> } }).group?.groupColors\r\n    })\r\n\r\n    this.renderer.setEyeCare(!!options.eyeCare)\r\n    this.engine = new LayoutEngine(this.toLayoutOptions())\r\n\r\n    this.wrapper.addEventListener('scroll', this.onScroll, { passive: true })\r\n    if (typeof ResizeObserver !== 'undefined') {\r\n      this.ro = new ResizeObserver(() => this.resize())\r\n      this.ro.observe(container)\r\n    }\r\n    const assetLoaded = () => {\r\n      this.thumbnailCache.clear()\r\n      this.forceFullRender = true\r\n      this.scheduleRender()\r\n    }\r\n    this.canvasHost.addEventListener('vervedocs:image-loaded', assetLoaded)\r\n    this.canvasHost.addEventListener('vervedocs:chart-loaded', assetLoaded)\r\n\r\n    // Range 变化时触发光标重绘 + 悬浮工具栏 + 工具栏样式同步\r\n    if (deps.listener && this.range) {\r\n      deps.listener.on('rangeChange', () => {\r\n        this.caretVisible = true\r\n        this.renderCaretIfAny()\r\n        // 拖拽过程中不更新悬浮工具栏，等 mouseup 再触发，避免工具栏跟随拖拽闪烁\r\n        if (!this.isDragging) {\r\n          // 同步选区样式到工具栏（formatChange）\r\n          const style = this.onCommand?.('getRangeStyle')\r\n          if (style) this.listener?.emit('formatChange', style)\r\n          this.selectionToolbarWidget?.update()\r\n          this.tableWidget?.update()\r\n          this.imageWidget?.update()\r\n          this.chartWidget?.update()\r\n          this.controlWidget?.update()\r\n          this.paragraphWidget?.update()\r\n          this.rulerWidget?.update()\r\n        }\r\n      })\r\n    }\r\n\r\n    // 隐藏输入框（textarea）：捕获所有键盘 & IME 输入\r\n    this.inputEl = document.createElement('textarea')\r\n    this.inputEl.className = 'vervedocs-hidden-input'\r\n    this.inputEl.readOnly = !!options.readonly\r\n    this.inputEl.disabled = !!options.disabled\r\n    Object.assign(this.inputEl.style, {\r\n      position: 'absolute',\r\n      left: '0px',\r\n      top: '0px',\r\n      width: '1px',\r\n      height: '1px',\r\n      opacity: '0',\r\n      border: 'none',\r\n      outline: 'none',\r\n      resize: 'none',\r\n      padding: '0',\r\n      margin: '0',\r\n      overflow: 'hidden',\r\n      zIndex: '10',\r\n      background: 'transparent',\r\n      color: 'transparent',\r\n      cursor: TEXT_CURSOR,\r\n      caretColor: 'transparent'\r\n    } as CSSStyleDeclaration)\r\n    this.inputEl.setAttribute('autocorrect', 'off')\r\n    this.inputEl.setAttribute('autocapitalize', 'off')\r\n    this.inputEl.setAttribute('spellcheck', 'false')\r\n    container.appendChild(this.inputEl)\r\n\r\n    this.bindEditingEvents()\r\n\r\n    this.resize()\r\n    this.reformatAndRender()\r\n    this.startCaretBlink()\r\n    this.selectionToolbarWidget = new SelectionToolbarWidget({\r\n      canEdit: () => !this.options.readonly && !this.options.disabled,\r\n      getLayout: () => this.layout,\r\n      getRange: () => this.range ?? null,\r\n      getDocument: () => this.document,\r\n      getZone: () => this.zone,\r\n      getActivePageIndex: () => this.activeZonePageIndex,\n      getScrollY: () => this.scrollY,\r\n      getPageOffsetX: () => this.getPageOffsetX(),\r\n      getViewportWidth: () => this.viewportWidth,\r\n      getContainer: () => this.container,\r\n      onCommand: (cmd: string, ...args: any[]) => this.onCommand?.(cmd, ...args),\r\n      isSuppressToolbar: () => this._suppressToolbar,\r\n      consumeSuppressToolbar: () => { this._suppressToolbar = false }\r\n    })\r\n    this.selectionToolbarWidget.create()\r\n    this.tableWidget = new TableWidget({\r\n      translate: this.translate,\r\n      canEdit: () => !this.options.readonly && !this.options.disabled,\r\n      getLayout: () => this.layout,\r\n      getRange: () => this.range ?? null,\r\n      getContainerRect: () => this.canvasHost.getBoundingClientRect(),\r\n      getScrollY: () => this.scrollY,\r\n      getPageOffsetX: () => this.getPageOffsetX(),\r\n      onCommand: (cmd: string, ...args: any[]) => this.onCommand?.(cmd, ...args),\r\n      hit: (clientX: number, clientY: number) => this.hit(clientX, clientY),\r\n      focusInput: () => this.focusInput(),\r\n      setCursor: (cursor: string) => {\r\n        this.wrapper.style.cursor = cursor === 'text' || cursor === 'default' ? TEXT_CURSOR : cursor\r\n      }\r\n    })\r\n    this.tableWidget.create()\r\n    this.headerFooterWidget = new HeaderFooterWidget({\r\n      translate: this.translate,\r\n      getLayout: () => this.layout,\r\n      getContainer: () => this.canvasHost,\n      getContainerRect: () => this.canvasHost.getBoundingClientRect(),\r\n      getScrollY: () => this.scrollY,\r\n      getWrapperWidth: () => this.wrapper.clientWidth,\r\n      getWrapperHeight: () => this.wrapper.clientHeight,\n      getPageOffsetX: () => this.getPageOffsetX(),\r\n      getZone: () => this.zone,\r\n      getActivePageIndex: () => this.activeZonePageIndex,\r\n      setZone: (zone: Zone) => this.setZone(zone),\r\n      setZoneWithCaret: (zone: Zone, pageIndex?: number) => this.setZoneWithCaret(zone, pageIndex),\r\n      focusInput: () => this.focusInput(),\r\n      drawZoneBorder: (layout, scrollY, zone, pageOffsetX) => this.renderer.drawZoneBorder(layout, scrollY, zone, pageOffsetX),\r\n      onInsertPageNumber: (options) => {\r\n        const zone: 'header' | 'footer' = this.zone === 'header' ? 'header' : 'footer'\r\n        this.onCommand?.('executeSetPageNumber', { ...options, zone })\r\n      }\r\n    })\r\n    this.headerFooterWidget.create()\r\n    this.imageWidget = new ImageWidget({\r\n      getContainer: () => this.canvasHost,\r\n      getLayout: () => this.layout,\r\n      getContainerRect: () => this.canvasHost.getBoundingClientRect(),\r\n      getScrollY: () => this.scrollY,\r\n      getPageOffsetX: () => this.getPageOffsetX(),\r\n      onCommand: (cmd: string, ...args: any[]) => this.onCommand?.(cmd, ...args),\r\n      onUpdateImageSizeLive: (path: Path, width: number, height: number) => this.updateImageSizeLive(path, width, height)\r\n    })\r\n    this.imageWidget.create()\r\n    this.chartWidget = new ChartWidget({\r\n      getContainer: () => this.canvasHost,\r\n      getLayout: () => this.layout,\r\n      getContainerRect: () => this.canvasHost.getBoundingClientRect(),\r\n      getScrollY: () => this.scrollY,\r\n      getPageOffsetX: () => this.getPageOffsetX(),\r\n      onCommand: (cmd: string, ...args: any[]) => this.onCommand?.(cmd, ...args),\r\n      onUpdateChartSizeLive: (path: Path, width: number, height: number) => this.updateChartSizeLive(path, width, height),\r\n      getEventBus: () => this.eventBus\r\n    })\r\n    this.chartWidget.create()\r\n    this.controlWidget = new ControlWidget({\r\n      onActivate: position => {\r\n        this.range?.setCaret(position)\r\n        this.focusInput()\r\n      },\r\n      focusEditor: () => this.focusInput(),\r\n      translate: this.translate,\r\n      getZone: () => this.zone,\r\n      getContainer: () => this.canvasHost,\r\n      getLayout: () => this.layout,\r\n      getContainerRect: () => this.canvasHost.getBoundingClientRect(),\r\n      getScrollY: () => this.scrollY,\r\n      getPageOffsetX: () => this.getPageOffsetX(),\r\n      onCommand: (cmd: string, ...args: any[]) => this.onCommand?.(cmd, ...args),\r\n      isReadonly: () => !!this.options.readonly || !!this.options.disabled\r\n    })\r\n    this.controlWidget.create()\r\n    this.paragraphWidget = new ParagraphWidget({\r\n      translate: this.translate,\r\n      canEdit: () => !this.options.readonly && !this.options.disabled,\r\n      getLayout: () => this.layout,\r\n      getRange: () => this.range ?? null,\r\n      getContainerRect: () => this.canvasHost.getBoundingClientRect(),\r\n      getScrollY: () => this.scrollY,\r\n      getPageOffsetX: () => this.getPageOffsetX(),\r\n      onCommand: (cmd: string, ...args: any[]) => this.onCommand?.(cmd, ...args),\r\n      hit: (clientX: number, clientY: number) => this.hit(clientX, clientY),\r\n      suppressToolbar: () => { this._suppressToolbar = true },\r\n      focusInput: () => this.focusInput()\r\n    })\r\n    this.paragraphWidget.create()\r\n    this.rulerWidget = new RulerWidget({\r\n      container: container,\r\n      getLayout: () => this.layout,\r\n      getScrollY: () => this.scrollY,\r\n      getWrapperWidth: () => this.wrapper.clientWidth,\r\n      getWrapperHeight: () => this.wrapper.clientHeight,\r\n      getPageOffsetX: () => this.getPageOffsetX(),\r\n      // 布局与渲染均直接使用未缩放的 CSS 像素，页面尺寸差异不代表缩放。\r\n      getScale: () => 1,\r\n      getPageMargins: () => {\r\n        const page = this.layout?.pages[0]\r\n        if (!page) return (this.options.pageMargins as [number, number, number, number]) ?? [100, 120, 100, 120]\r\n        const { rect, contentRect } = page\r\n        const top = contentRect.y - rect.y\r\n        const left = contentRect.x - rect.x\r\n        return [top, rect.width - left - contentRect.width, rect.height - top - contentRect.height, left]\r\n      },\r\n      getParagraphIndent: () => {\r\n        const pos = this.range?.getFocus()\r\n        const paragraph = pos ? findParagraphByPos(this.layout, pos) : null\r\n        if (!paragraph) return null\r\n        const run = paragraph.lines[0]?.inlines[0]?.run\r\n        const attr = (key: string) => Number(\r\n          (paragraph.block as unknown as Record<string, unknown> | null)?.[key] ??\r\n          (run as unknown as Record<string, unknown> | undefined)?.[key] ?? 0\r\n        )\r\n        const left = Math.max(0, attr('paragraphIndentLeft'))\r\n        const hanging = Math.max(0, attr('indentHanging'))\r\n        return {\r\n          first: left + (hanging ? 0 : Math.max(0, attr('paragraphFirstLineIndent'))),\r\n          left: left + hanging,\r\n          right: Math.max(0, attr('paragraphIndentRight'))\r\n        }\r\n      },\r\n      onCommand: (cmd: string, ...args: any[]) => this.onCommand?.(cmd, ...args)\r\n    })\r\n    this.rulerWidget.create()\r\n    if ((options as unknown as { showRuler?: boolean }).showRuler) {\r\n      this.rulerWidget.setVisible(true)\r\n    }\r\n\r\n    this.watermarkWidget = new WatermarkWidget({\r\n      getPageOffsetX: () => this.getPageOffsetX()\r\n    })\r\n    this.watermarkWidget.create()\r\n    this.renderer.setWatermarkWidget(this.watermarkWidget)\r\n\r\n    this.systemWatermarkWidget = new SystemWatermarkWidget({\r\n      getContainer: () => this.container\r\n    })\r\n    this.systemWatermarkWidget.create()\r\n\r\n    this.caretWidget = new CaretWidget({\r\n      getCanvasHost: () => this.canvasHost\r\n    })\r\n    this.caretWidget.create()\r\n\r\n    this.caretNavigation = new CaretNavigation({\r\n      getLayout: () => this.layout,\r\n      getRange: () => this.range ?? null,\r\n      getZone: () => this.zone,\r\n      getActivePageIndex: () => this.activeZonePageIndex,\n      findInlineByPos: (pos) => this.findInlineByPos(pos),\r\n      findParagraphByPos: (pos) => this.findParagraphByPos(pos),\r\n      findLineByPos: (pos) => this.findLineByPos(pos),\r\n      findFirstInline: () => this.findFirstInline(),\r\n      findLastInline: () => this.findLastInline(),\r\n      setCaretVisible: (visible: boolean) => { this.caretVisible = visible },\r\n      renderCaretIfAny: () => this.renderCaretIfAny()\r\n    })\r\n\r\n    this.zoneManager = new ZoneManager({\r\n      getLayout: () => this.layout,\n      getPage: () => {\r\n        const pages = this.layout?.pages\r\n        if (this.activeZonePageIndex != null) {\n          const activePage = pages?.find(page => page.index === this.activeZonePageIndex)\r\n          if (activePage) return activePage\r\n        }\r\n        return pages?.find(page => this.scrollY < page.rect.y + page.rect.height)\r\n      },\r\n      getZone: () => this.zone,\r\n      setZoneState: (zone: Zone) => {\n        this.zone = zone\n        this.renderer.updateActiveZone(zone)\n        this.forceFullRender = true\n      },\n      getDocument: () => this.document,\r\n      getRange: () => this.range ?? null,\r\n      focusInput: () => this.focusInput(),\r\n      onZoneChange: (zone: Zone) => { this.onZoneChange?.(zone) },\r\n      scheduleRender: () => this.scheduleRender(),\r\n      reformatAndRender: () => this.reformatAndRender()\r\n    })\r\n  }\r\n\r\n  /* -------------------- 输入 / 键盘事件 -------------------- */\r\n\r\n  /** 绑定编辑相关事件：鼠标点选/拖拽、右键菜单、键盘、IME 组合输入。 */\r\n  private bindEditingEvents(): void {\r\n    // 让 wrapper 可接收指针事件（canvasHost 为 pointer-events:none）\r\n    this.wrapper.addEventListener('mousedown', this.onMouseDown)\r\n    this.wrapper.addEventListener('contextmenu', this.onContextMenu)\r\n    // 拖拽选区：mousemove/mouseup 绑定在 window，以捕获拖出 wrapper 的情况\r\n    window.addEventListener('mousemove', this.onMouseMove)\r\n    window.addEventListener('mouseup', this.onMouseUp)\r\n\r\n    // 键盘事件在 inputEl 上\r\n    this.inputEl.addEventListener('keydown', (e) => {\r\n      if (this.imageWidget?.handleKeyDown(e)) return\n      // 光标可见性重置（阻止闪烁在打字时消失）\r\n      this.caretVisible = true\r\n      this.renderCaretIfAny()\r\n      if (this.onKeyDown) this.onKeyDown(e)\r\n    })\r\n\r\n    // 组合输入（中文/emoji）\r\n    this.inputEl.addEventListener('compositionstart', () => { this.isComposing = true })\r\n    this.inputEl.addEventListener('compositionend', (e) => {\r\n      this.isComposing = false\r\n      const text = (e as CompositionEvent).data ?? ''\r\n      if (text && !this.options.readonly && !this.options.disabled) this.onInput?.(text)\r\n      this.inputEl.value = ''\r\n    })\r\n\r\n    // 普通输入（非 IME）\r\n    this.inputEl.addEventListener('input', (e) => {\r\n      if (this.isComposing) return\r\n      const ie = e as InputEvent\r\n      const data = ie.data ?? this.inputEl.value\r\n      if (data && !this.options.readonly && !this.options.disabled) this.onInput?.(data)\r\n      this.inputEl.value = ''\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 鼠标按下处理：表格/图片/页眉页脚手柄优先；否则命中文档位置后处理\r\n   * Ctrl+点击跳转、双击选词、三击选段、Shift+扩展选区、普通点击+开始拖拽。\r\n   * @param e 鼠标事件\r\n   */\r\n  /** 获取事件总线（供 commands 插件等发射交互事件） */\r\n  getEventBus(): EventBus | undefined {\r\n    return this.eventBus\r\n  }\r\n\r\n  private isAnnotationEvent(e: MouseEvent): boolean {\r\n    return e.target instanceof Element\r\n      && !!e.target.closest('.ce-comment-overlay, .ce-revision-overlay')\r\n  }\r\n\r\n  private onMouseDown = (e: MouseEvent): void => {\r\n    // Annotation controls own their native focus and text selection.\r\n    if (this.isAnnotationEvent(e)) return\r\n    if (this.options.disabled) return\r\n    this.eventBus?.emit('editorMousedown', e)\r\n    if (!this.range || e.button !== 0) return\r\n    // 阻止 mousedown 默认行为抢走隐藏输入框的焦点\r\n    e.preventDefault()\r\n\r\n    // 表格边框拖拽\r\n    if (!this.options.readonly && this.tableWidget?.handleMouseDown(e)) return\r\n\r\n    // 图片选中/缩放\r\n    if (!this.options.readonly && this.imageWidget?.handleMouseDown(e)) {\r\n      this.eventBus?.emit('imageMousedown', e)\r\n      return\r\n    }\r\n\r\n    // 图表选中/缩放\r\n    if (!this.options.readonly && this.chartWidget?.handleMouseDown(e)) {\r\n      return\r\n    }\r\n\r\n    // 双击页眉/页脚区域：切换编辑区域\r\n    if (!this.options.readonly && this.headerFooterWidget?.handleMouseDown(e)) return\r\n\r\n    // 内置控件点击激活\r\n    if (!this.options.readonly && this.controlWidget?.handleMouseDown(e)) return\r\n\r\n    const pos = this.hit(e.clientX, e.clientY)\r\n    if (!pos) { this.inputEl.focus(); return }\r\n    // Ctrl/Cmd + 单击：命中超链接则打开浏览器跳转（WPS 行为）\r\n    if ((e.ctrlKey || e.metaKey) && !e.shiftKey && e.detail === 1) {\r\n      const url = this.findHyperlinkByPos(pos)\r\n      if (url) { window.open(url, '_blank', 'noopener'); return }\r\n    }\r\n    // 三击：选段\r\n    if (e.detail >= 3) { this.selectParagraphAt(pos); this.finishMouseSelect(); return }\r\n    // 双击：选词\r\n    if (e.detail === 2) { this.selectWordAt(pos); this.finishMouseSelect(); return }\r\n    // Shift+Click：扩展选区（anchor 不动，focus 移到点击点）\r\n    if (e.shiftKey) {\r\n      const anchor = this.range.getAnchor()\r\n      if (anchor) { this.range.setRange({ anchor, focus: pos }); this.finishMouseSelect(); return }\r\n    }\r\n    // 普通点击：折叠光标并开始拖拽\r\n    this.range.setCaret(pos)\r\n    this.dragAnchor = pos\r\n    this.isDragging = true\r\n    this.wrapper.style.cursor = TEXT_CURSOR\r\n    this.finishMouseSelect()\r\n  }\r\n\r\n  /**\r\n   * 鼠标移动处理：非拖拽时按 hover 超链接切换光标；拖拽时 RAF 节流更新选区 focus。\r\n   * @param e 鼠标事件\r\n   */\r\n  private onMouseMove = (e: MouseEvent): void => {\r\n    if (!this.isDragging && this.isAnnotationEvent(e)) return\r\n    // 文本选区拖拽保持文本指针；表格边框悬浮和拖拽优先于链接指针。\r\n    if (!this.isDragging && this.tableWidget?.handleMouseMove(e)) return\r\n    // 非拖拽时：hover 超链接显示手型，提示可 Ctrl+点击跳转\r\n    if (!this.isDragging) {\r\n      const pos = this.hit(e.clientX, e.clientY)\r\n      const url = pos ? this.findHyperlinkByPos(pos) : null\r\n      this.wrapper.style.cursor = url ? 'pointer' : TEXT_CURSOR\r\n      // 正文模式下，悬浮页眉/页脚区域显示提示\r\n      this.updateZoneHoverTooltip(e)\r\n      return\r\n    }\r\n    if (!this.range || !this.dragAnchor || !this.layout) return\r\n    const pos = this.hit(e.clientX, e.clientY)\r\n    if (!pos) return\r\n    this.dragPendingPos = pos\r\n    if (this.dragRafId == null) {\r\n      this.dragRafId = requestAnimationFrame(() => {\r\n        this.dragRafId = null\r\n        if (!this.dragPendingPos || !this.range || !this.dragAnchor) return\r\n        this.range.setRange({ anchor: this.dragAnchor, focus: this.dragPendingPos })\r\n        this.caretVisible = true\r\n        this.renderCaretIfAny()\r\n      })\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 正文模式下，鼠标悬浮在页眉/页脚区域时设置 title 提示。\r\n   * @param e 鼠标事件\r\n   */\r\n  private updateZoneHoverTooltip(e: MouseEvent): void {\r\n    if (!this.layout || this.zone !== 'main') {\r\n      this.wrapper.title = ''\r\n      return\r\n    }\r\n    const rect = this.canvasHost.getBoundingClientRect()\r\n    const docY = e.clientY - rect.top + this.scrollY\r\n    for (const page of this.layout.pages) {\r\n      if (docY < page.rect.y || docY > page.rect.y + page.rect.height) continue\r\n      if (page.headerRect && docY >= page.headerRect.y && docY <= page.headerRect.y + page.headerRect.height) {\r\n        this.wrapper.title = '双击编辑页眉'\r\n        return\r\n      }\r\n      if (page.footerRect && docY >= page.footerRect.y && docY <= page.footerRect.y + page.footerRect.height) {\r\n        this.wrapper.title = '双击编辑页脚'\r\n        return\r\n      }\r\n      break\r\n    }\r\n    this.wrapper.title = ''\r\n  }\r\n\r\n  /**\r\n   * 鼠标松开处理：结束拖拽、清理 RAF、更新悬浮工具栏与各 widget。\r\n   * @param e 鼠标事件\r\n   */\r\n  private onMouseUp = (e: MouseEvent): void => {\r\n    this.eventBus?.emit('editorMouseup', e)\r\n    this.tableWidget?.handleMouseUp(e)\r\n    const wasDragging = this.isDragging\r\n    if (wasDragging && this.dragRafId != null && this.dragPendingPos && this.dragAnchor && this.range) {\r\n      this.range.setRange({ anchor: this.dragAnchor, focus: this.dragPendingPos })\r\n    }\r\n    this.isDragging = false\r\n    this.dragAnchor = null\r\n    this.dragPendingPos = null\r\n    if (this.dragRafId != null) { cancelAnimationFrame(this.dragRafId); this.dragRafId = null }\r\n    if (wasDragging) {\r\n      const style = this.onCommand?.('getRangeStyle')\r\n      if (style) this.listener?.emit('formatChange', style)\r\n    }\r\n    // 松开鼠标后才显示悬浮工具栏\r\n    this.selectionToolbarWidget?.update()\r\n\r\n  }\r\n\r\n  /** 鼠标选区结束收尾：聚焦隐藏输入框、重置光标可见性并重绘。 */\r\n  private finishMouseSelect(): void {\r\n    this.focusInput()\r\n    this.caretVisible = true\r\n    this.renderCaretIfAny()\r\n  }\r\n\r\n  /* -------------------- 右键菜单 -------------------- */\r\n\r\n  /**\r\n   * 右键菜单处理：优先交给图片/表格 widget 显示上下文菜单。\r\n   * @param e 鼠标事件\r\n   */\r\n  private onContextMenu = (e: MouseEvent): void => {\r\n    if (this.isAnnotationEvent(e)) return\r\n    e.preventDefault()\r\n    if (this.options.readonly || this.options.disabled) return\r\n\r\n    // 命中超链接时通知 UI 显示超链接右键菜单\r\n    const pos = this.hit(e.clientX, e.clientY)\r\n    const target = pos\n      ? getByPath(this.getActiveDocument().elements, pos.path) as unknown as { imgToolDisabled?: boolean } | undefined\n      : undefined\n    if (target?.imgToolDisabled) return\n    if (pos && this.findHyperlinkByPos(pos)) {\r\n      this.eventBus?.emit('hyperlinkMenuClick')\r\n      return\r\n    }\r\n\r\n    // 优先表格，未命中再尝试段落\r\n    if (this.tableWidget?.showContextMenu(e.clientX, e.clientY)) return\r\n    this.paragraphWidget?.showContextMenu(e.clientX, e.clientY)\r\n  }\r\n\r\n\r\n  /* -------------------- 双击选词 / 三击选段 -------------------- */\r\n\r\n  /**\r\n   * 双击选词：在命中 inline 内按 word char 边界扩展选区；非 word char 选当前单字。\r\n   * @param pos 命中位置\r\n   */\r\n  private selectWordAt(pos: IPosition): void {\r\n    this.caretNavigation?.selectWordAt(pos)\r\n  }\r\n\r\n  /**\r\n   * 三击选段：把选区扩展到命中段落的首 inline 起点到末 inline 终点。\r\n   * @param pos 命中位置\r\n   */\r\n  private selectParagraphAt(pos: IPosition): void {\r\n    this.caretNavigation?.selectParagraphAt(pos)\r\n  }\r\n\r\n  /**\r\n   * 按 position 在当前 layout 中查找所属 inline。\r\n   * @param pos 待定位位置\r\n   * @returns 命中的 InlineBox；未命中返回 null\r\n   */\r\n  private findInlineByPos(pos: IPosition): InlineBox | null {\r\n    return findInlineByPos(this.layout, pos)\r\n  }\r\n\r\n  /**\r\n   * 按 position 在当前 layout 中查找所属段落块。\r\n   * @param pos 待定位位置\r\n   * @returns 命中的 ParagraphBlock；未命中返回 null\r\n   */\r\n  private findParagraphByPos(pos: IPosition): ParagraphBlock | null {\r\n    return findParagraphByPos(this.layout, pos)\r\n  }\r\n\r\n  /* -------------------- 光标移动（方向键 / Home / End / 词移动） -------------------- */\r\n\r\n  /** 光标上移：基于当前光标矩形，用 hitTest 命中上一行同 x 最近字符 */\r\n  moveCaretUp(): void {\r\n    this.caretNavigation?.moveCaretUp()\r\n  }\r\n\r\n  /** 光标下移 */\r\n  moveCaretDown(): void {\r\n    this.caretNavigation?.moveCaretDown()\r\n  }\r\n\r\n  /** 当前行首 */\r\n  moveCaretToLineStart(): void {\r\n    this.caretNavigation?.moveCaretToLineStart()\r\n  }\r\n\r\n  /** 当前行尾 */\r\n  moveCaretToLineEnd(): void {\r\n    this.caretNavigation?.moveCaretToLineEnd()\r\n  }\r\n\r\n  /** 按词左移 */\r\n  moveCaretWordLeft(): void {\r\n    this.caretNavigation?.moveCaretWordLeft()\r\n  }\r\n\r\n  /** 按词右移 */\r\n  moveCaretWordRight(): void {\r\n    this.caretNavigation?.moveCaretWordRight()\r\n  }\r\n\r\n  /** 文档首 */\r\n  moveCaretToDocStart(): void {\r\n    this.caretNavigation?.moveCaretToDocStart()\r\n  }\r\n\r\n  /** 文档尾 */\r\n  moveCaretToDocEnd(): void {\r\n    this.caretNavigation?.moveCaretToDocEnd()\r\n  }\r\n\r\n  /** 全选：从文档首到文档尾 */\r\n  selectAll(): void {\r\n    this.caretNavigation?.selectAll()\r\n  }\r\n\r\n  /**\r\n   * 按 position 在当前 layout 中查找所属行盒。\r\n   * @param pos 待定位位置\r\n   * @returns 命中的 LineBox；未命中返回 null\r\n   */\r\n  private findLineByPos(pos: IPosition): LineBox | null {\r\n    return findLineByPos(this.layout, pos)\r\n  }\r\n\r\n  /**\r\n   * 查找文档首个 inline（用于光标兜底定位到文档首）。\r\n   * @returns 首个 InlineBox；空文档返回 null\r\n   */\r\n  private findFirstInline(): InlineBox | null {\r\n    return findFirstInline(this.layout)\r\n  }\r\n\r\n  /** 按 position 定位 inline，若属于超链接则返回其 URL（供 Ctrl+点击跳转） */\r\n  private findHyperlinkByPos(pos: IPosition): string | null {\r\n    return findHyperlinkByPos(this.layout, pos)\r\n  }\r\n\r\n  /**\r\n   * 查找文档末个 inline（用于光标定位到文档尾/全选终点）。\r\n   * @returns 末个 InlineBox；空文档返回 null\r\n   */\r\n  private findLastInline(): InlineBox | null {\r\n    return findLastInline(this.layout)\r\n  }\r\n\r\n  /** 把隐藏输入框放到当前光标位置，以便 IME 弹窗位置正确 */\r\n  focusInput(): void {\r\n    if (!this.range) return\r\n    const pos = this.range.getFocus()\r\n    if (!pos || !this.layout) { this.inputEl.focus(); return }\r\n    const rect = locateCaret(this.layout, pos, this.zone, this.activeZonePageIndex)\n    if (rect) {\r\n      const pageOffsetX = this.getPageOffsetX()\r\n      this.inputEl.style.left = `${Math.round(rect.x + pageOffsetX)}px`\r\n      this.inputEl.style.top = `${Math.round(rect.y - this.scrollY)}px`\r\n    }\r\n    this.inputEl.focus()\r\n  }\r\n\r\n  /* -------------------- 光标闪烁 -------------------- */\r\n\r\n  /** 启动光标闪烁定时器（530ms 切换可见性）。 */\r\n  private startCaretBlink(): void {\r\n    if (this.caretTimer != null) return\r\n    this.caretTimer = window.setInterval(() => {\r\n      this.caretVisible = !this.caretVisible\r\n      this.renderCaretIfAny()\r\n    }, 530) as unknown as number\r\n  }\r\n\r\n  /** 重绘 overlay：zone 边框 + 选区高亮 + 光标（按 caretVisible 闪烁）。 */\r\n  private renderCaretIfAny(): void {\r\n    if (!this.layout || !this.range) return\r\n    this.renderer.clearOverlay()\r\n    // zone 边框（页眉/页脚编辑时）\r\n    this.headerFooterWidget?.renderBorder()\r\n    // 选区高亮（非折叠时）\r\n    const ordered = this.range.getOrdered()\r\n    if (ordered && !this.range.isCollapsed()) {\r\n      const tableRects = this.computeTableSelectionRects(ordered)\r\n      if (tableRects) {\r\n        this.renderer.drawSelection(tableRects, this.scrollY)\r\n      } else {\r\n        const selRects = computeSelectionRects(this.layout, ordered.start, ordered.end, this.zone, this.activeZonePageIndex)\n        this.renderer.drawSelection(selRects, this.scrollY)\r\n      }\r\n    }\r\n    // 光标（DOM 绘制）\r\n    const pos = this.range.getFocus()\r\n    if (!pos || this.options.readonly || this.options.disabled) {\r\n      this.caretWidget?.hide()\r\n      return\r\n    }\r\n    const rect = locateCaret(this.layout, pos, this.zone, this.activeZonePageIndex)\n    if (rect) {\r\n      this.caretWidget?.update(rect, this.scrollY, this.getPageOffsetX(), this.caretVisible)\r\n    } else {\r\n      this.caretWidget?.hide()\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 计算表格整表选区高亮矩形：当选区恰好覆盖整张表（首格到末格）时返回所有 cell 矩形，\r\n   * 否则返回 null（交由普通文本选区处理）。\r\n   * @param ordered 有序选区\r\n   * @returns 单元格矩形数组；非整表选区返回 null\r\n   */\r\n  private computeTableSelectionRects(ordered: { start: IPosition; end: IPosition }): { x: number; y: number; width: number; height: number }[] | null {\r\n    // 页眉页脚的表格路径与正文相互独立，交由当前区域的选区计算处理。\n    if (!this.layout || this.zone !== 'main') return null\n    const { start, end } = ordered\r\n    if (start.path.length < 5 || end.path.length < 5) return null\r\n    if (start.path[1] !== 'trList' || end.path[1] !== 'trList') return null\r\n    if (start.path[0] !== end.path[0]) return null\r\n    const tableIndex = start.path[0] as number\r\n    for (const page of this.layout.pages) {\r\n      const block = page.blocks.find(b => b.kind === 'table' && b.indexInParent === tableIndex)\r\n      if (!block || block.kind !== 'table') continue\r\n      const rowCount = block.rows.length\r\n      const lastRow = block.rows[rowCount - 1]\r\n      if (!lastRow) return null\r\n      const lastColIdx = lastRow.cells.length - 1\r\n      const startRow = start.path[2] as number\r\n      const startCol = start.path[4] as number\r\n      const endRow = end.path[2] as number\r\n      const endCol = end.path[4] as number\r\n      if (startRow !== 0 || startCol !== 0 || endRow !== rowCount - 1 || endCol !== lastColIdx) return null\r\n      const rects: { x: number; y: number; width: number; height: number }[] = []\r\n      for (const row of block.rows) {\r\n        for (const cell of row.cells) {\r\n          rects.push({\r\n            x: page.contentRect.x + block.rect.x + cell.rect.x,\r\n            y: page.contentRect.y + block.rect.y + cell.rect.y,\r\n            width: cell.rect.width,\r\n            height: cell.rect.height\r\n          })\r\n        }\r\n      }\r\n      return rects\r\n    }\r\n    return null\r\n  }\r\n\r\n\r\n\r\n  /* -------------------- 对外 API -------------------- */\r\n\r\n  /**\r\n   * 设置新文档并触发重排版+重渲染。\r\n   * @param doc 新文档元数据\r\n   */\r\n  setDocument(doc: IDocxDocumentMeta): void {\r\n    this.controlWidget?.deactivate()\r\n    if (!doc || !Array.isArray(doc.elements)) {\r\n      doc = { ...(doc ?? {}), elements: (doc as { elements?: unknown[] })?.elements ?? [] } as IDocxDocumentMeta\r\n    }\r\n    this.document = doc\r\n    this.reformatAndRender()\r\n  }\r\n\r\n  /**\r\n   * 获取当前文档元数据。\r\n   * @returns 文档元数据\r\n   */\r\n  getDocument(): IDocxDocumentMeta { return this.document }\r\n\r\n  /**\r\n   * 设置渲染缩放倍数并重排+重渲染。\r\n   * @param scale 缩放倍数\r\n   */\r\n  setScale(scale: number): void {\r\n    this.options.scale = scale\r\n    this.reformatWithInvalidation()\r\n  }\r\n\r\n  /**\r\n   * 设置标尺可见性。\r\n   * @param visible 是否可见\r\n   */\r\n  setRulerVisible(visible: boolean): void {\r\n    this.rulerWidget?.setVisible(visible)\r\n  }\r\n\r\n  /**\r\n   * 实时更新图片尺寸（拖拽缩放时调用）并重排+重渲染。\r\n   * @param path 图片元素路径\r\n   * @param width 新宽度\r\n   * @param height 新高度\r\n   */\r\n  updateImageSizeLive(path: Path, width: number, height: number): void {\r\n    const el = getByPath(this.document.elements, path)\r\n    if (!el || el.type !== 'image') return\r\n    ;(el as unknown as { width: number; height: number }).width = Math.max(1, Math.round(width))\r\n    ;(el as unknown as { width: number; height: number }).height = Math.max(1, Math.round(height))\r\n    this.reformatAndRender()\r\n  }\r\n\r\n  /**\r\n   * 拖拽缩放图表过程中实时更新尺寸（不写文档历史，仅刷新显示）。\r\n   * @param path 图表路径\r\n   * @param width 新宽度\r\n   * @param height 新高度\r\n   */\r\n  updateChartSizeLive(path: Path, width: number, height: number): void {\r\n    const el = getByPath(this.document.elements, path)\r\n    if (!el || el.type !== 'block') return\r\n    const metrics = (el as unknown as { metrics?: { width: number; height: number } }).metrics\r\n    if (!metrics) return\r\n    metrics.width = Math.max(1, Math.round(width))\r\n    metrics.height = Math.max(1, Math.round(height))\r\n    this.reformatAndRender()\r\n  }\r\n\r\n  /**\r\n   * 设置页边距并重排+重渲染。\r\n   * @param margins 页边距 [top, right, bottom, left]\r\n   */\r\n  setPaperMargins(margins: [number, number, number, number]): void {\r\n    this.options.pageMargins = [...margins]\r\n    this.document.margins = [...margins]\r\n    for (const section of this.document.sections ?? []) {\r\n      section.margins = [...margins]\r\n    }\r\n    this.reformatWithInvalidation()\r\n  }\r\n\r\n  /**\r\n   * 设置页面尺寸（宽/高）并重排+重渲染。\r\n   * @param width 页面宽度\r\n   * @param height 页面高度\r\n   */\r\n  setPageSize(width: number, height: number): void {\r\n    this.options.pageWidth = width\r\n    this.options.pageHeight = height\r\n    // Imported document geometry takes precedence over layout option defaults.\r\n    const paperDirection = width > height ? 'horizontal' : 'vertical'\r\n    this.document.pageWidth = width\r\n    this.document.pageHeight = height\r\n    this.document.paperDirection = paperDirection\r\n    for (const section of this.document.sections ?? []) {\r\n      section.pageWidth = width\r\n      section.pageHeight = height\r\n      section.paperDirection = paperDirection\r\n    }\r\n    this.reformatWithInvalidation()\r\n  }\r\n\r\n  /**\r\n   * 获取当前编辑器选项。\r\n   * @returns 编辑器选项\r\n   */\r\n  getOptions(): IEditorOption { return this.options }\r\n\r\n  /** Refresh display translations without rebuilding open panels or changing editor state. */\r\n  refreshTranslations(): void {\r\n    this.controlWidget?.refreshLocale()\r\n    this.paragraphWidget?.refreshTranslations()\r\n    this.tableWidget?.refreshTranslations()\r\n    this.headerFooterWidget?.refreshTranslations()\r\n  }\r\n\r\n  /**\r\n   * 批量更新编辑器选项并重排+重渲染。\r\n   * @param patch 选项补丁\r\n   */\r\n  updateOptions(patch: Partial<IEditorOption>): void {\r\n    Object.assign(this.options, patch)\r\n    if ('readonly' in patch || 'disabled' in patch) {\r\n      this.inputEl.readOnly = !!this.options.readonly\r\n      this.inputEl.disabled = !!this.options.disabled\r\n      this.inputEl.value = ''\r\n      this.isComposing = false\r\n      this._suppressToolbar = false\r\n      this.selectionToolbarWidget?.update()\r\n      this.paragraphWidget?.update()\r\n      this.tableWidget?.update()\r\n      this.renderCaretIfAny()\r\n    }\r\n    if (Object.prototype.hasOwnProperty.call(patch, 'eyeCare')) {\r\n      this.renderer.setEyeCare(!!this.options.eyeCare)\r\n      this.listener?.emit('thumbnailAppearanceChange')\r\n    }\r\n    // View-only toggles must not enter the document layout/render lifecycle.\r\n    if (Object.keys(patch).every(key => ['eyeCare', 'readonly', 'disabled'].includes(key))) return\r\n    this.reformatWithInvalidation()\r\n  }\r\n\r\n  /** 按控件打印展示规则独立重排并打印完整分页，不依赖当前视口的 Canvas 图层。 */\r\n  async print(): Promise<void> {\r\n    if (!this.layout?.pages.length) return\r\n    const frame = document.createElement('iframe')\r\n    frame.title = '文档打印'\r\n    frame.setAttribute('aria-hidden', 'true')\r\n    frame.tabIndex = -1\r\n    frame.style.cssText = 'position:fixed;width:0;height:0;border:0;left:-10000px;top:0;'\r\n    try {\r\n      // 打印专用布局独立重排，不覆盖当前编辑态布局。\r\n      const printLayout = new LayoutEngine({ ...this.toLayoutOptions(), printing: true }).layout(\r\n        this.document.elements,\r\n        this.document.header ?? this.document.contentZones?.header,\r\n        this.document.footer ?? this.document.contentZones?.footer,\r\n        this.document\r\n      )\r\n      this.syncPageNumberToRenderer()\r\n      this.syncWatermarkToRenderer()\r\n      // 按打印重排后的页序生成完整页面图片，并等待资源解码。\r\n      const images = await this.renderer.renderPrintPages(printLayout)\r\n      // 每页使用对应纸张尺寸，保留文档中的页面尺寸差异。\r\n      const pageStyles = printLayout.pages.map((page, index) =>\r\n        `@page docx-page-${index}{size:${page.rect.width}px ${page.rect.height}px;margin:0}`\r\n      ).join('')\r\n      // 将重排后的页面图片与逐页纸张设置按相同页序组合为打印内容。\r\n      const pages = printLayout.pages.map((page, index) =>\r\n        `<div class=\"page\" style=\"page:docx-page-${index};width:${page.rect.width}px;height:${page.rect.height}px\"><img src=\"${images[index]}\" alt=\"\"/></div>`\r\n      ).join('')\r\n      // 页面图片加载完成后再打开系统打印对话框。\r\n      frame.onload = () => {\r\n        const w = frame.contentWindow\r\n        if (!w) {\r\n          frame.remove()\r\n          return\r\n        }\r\n        frame.onload = null\r\n        w.addEventListener('afterprint', () => {\r\n          setTimeout(() => frame.remove(), 0)\r\n        }, { once: true })\r\n        w.focus()\r\n        w.print()\r\n      }\r\n      frame.srcdoc = `<!doctype html><html lang=\"zh-CN\"><head><meta charset=\"UTF-8\"><title>打印文档</title><style>\r\n        @page{margin:0}${pageStyles};\r\n        body{margin:0}\r\n        .page{break-after:page;page-break-after:always}\r\n        .page:last-child{break-after:auto;page-break-after:auto}\r\n        .page img{display:block;width:100%;height:100%}\r\n      </style></head><body>${pages}</body></html>`\r\n      document.body.appendChild(frame)\r\n    } catch (error) {\r\n      frame.remove()\r\n      throw error\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 获取所有页面的缩略图图片（data URL）。\r\n   * Reuse cached PNGs; only changed page content or visual options require painting.\r\n   * @returns 缩略图 data URL 数组，每个元素对应一页\r\n   */\r\n  getPageThumbnails(): string[] {\r\n    if (!this.layout) return []\r\n    this.syncPageNumberToRenderer()\r\n    this.syncWatermarkToRenderer()\r\n    const visualSignature = JSON.stringify([\r\n      { ...this.options, eyeCare: undefined }, this.layout.pages.length\r\n    ])\r\n    const images: string[] = []\r\n    for (const page of this.layout.pages) {\r\n      const signature = `${visualSignature}|${this.renderState?.pageSignatures.get(page.index)}`\r\n      let cached = this.thumbnailCache.get(page.index)\r\n      if (cached?.signature !== signature) {\r\n        let foreground: string | undefined\r\n        const image = this.renderer.renderPageThumbnail(page, 0.7, this.layout.pages.length, value => { foreground = value })\r\n        cached = { signature, image, foreground }\r\n        this.thumbnailCache.set(page.index, cached)\r\n      }\r\n      if (cached.image) images.push(cached.image)\r\n    }\r\n    for (const index of this.thumbnailCache.keys()) {\r\n      if (index >= this.layout.pages.length) this.thumbnailCache.delete(index)\r\n    }\r\n    return images\r\n  }\r\n\r\n  /** Cached transparent content only: this never renders pages on an appearance toggle. */\r\n  getThumbnailForegrounds(): string[] {\r\n    return Array.from(this.thumbnailCache.values(), cached => cached.foreground ?? '')\r\n  }\r\n\r\n  /**\r\n   * 获取最近一次排版结果。\r\n   * @returns 排版结果；未排版返回 null\r\n   */\r\n  getLayout(): DocumentLayout | null { return this.layout }\r\n\r\n  /**\r\n   * 获取滚动占位元素（驱动 wrapper 滚动，批注/修订组件据此判断新架构）。\r\n   * @returns scroller DOM\r\n   */\r\n  getScroller(): HTMLDivElement {\r\n    // 打标记，让批注/修订组件的 _applyContainerWidth 跳过宽度覆盖\r\n    ;(this.scroller as any).__vervedocsNewLayout = true\r\n    return this.scroller\r\n  }\r\n\r\n  /** 供 commands 组件（BlockParticle 等）挂载 DOM 的容器（随文档滚动） */\r\n  getContainer(): HTMLDivElement {\r\n    return this.scroller\r\n  }\r\n\r\n  /**\r\n   * 滚动到指定文档位置使其可见。\r\n   * @param pos 文档位置\r\n   */\r\n  scrollPositionIntoView(pos: IPosition): void {\r\n    if (!this.layout) return\r\n    const rect = locateCaret(this.layout, pos, this.zone, this.activeZonePageIndex)\n    if (!rect) return\r\n    const anchor = document.createElement('div')\r\n    anchor.style.position = 'absolute'\r\n    anchor.style.left = `${rect.x}px`\r\n    anchor.style.top = `${rect.y}px`\r\n    anchor.style.width = rect.orientation === 'horizontal' ? `${rect.width ?? 1}px` : '1px'\n    anchor.style.height = rect.orientation === 'horizontal' ? '1px' : `${rect.height}px`\n    this.scroller.append(anchor)\r\n    anchor.scrollIntoView({ block: 'center' })\r\n    anchor.remove()\r\n\r\n  }\r\n\r\n  /** 供 commands 组件获取当前活动区域元素列表 */\r\n  getElementList(): import('@vervedoc/docx-editor-schema').IElement[] {\r\n    return this.getActiveDocument().elements\r\n  }\r\n\r\n\r\n  /** 供 commands 组件访问 RangeManager（路径接口） */\r\n  getRange(): RangeManager | null {\r\n    return this.range ?? null\r\n  }\r\n\r\n\r\n  /** 获取当前编辑区域 */\r\n  getZone(): Zone { return this.zone }\r\n\r\n  /** 切换编辑区域（main/header/footer） */\r\n  setZone(zone: Zone): void {\r\n    if (zone === 'main') {\r\n      this.activeZonePageIndex = null\r\n    } else {\r\n      this.activeZonePageIndex ??= this.getViewportPageIndex()\r\n    }\r\n    this.zoneManager?.setZone(zone)\r\n  }\r\n\r\n  /**\r\n   * 切换编辑区域并设置初始光标。\r\n   * 切换到页眉/页脚时，将光标定位到对应区域的起始文本位置；\r\n   * 切回正文时清空选区。\r\n   * @param zone 目标区域\r\n   */\r\n  setZoneWithCaret(zone: Zone, pageIndex?: number): void {\r\n    const previousPageIndex = this.activeZonePageIndex\r\n    if (zone === 'main') {\r\n      this.activeZonePageIndex = null\r\n    } else if (pageIndex != null) {\r\n      this.activeZonePageIndex = pageIndex\r\n    } else {\r\n      this.activeZonePageIndex ??= this.getViewportPageIndex()\r\n    }\r\n    const pageChanged = pageIndex != null && previousPageIndex !== pageIndex\r\n    this.zoneManager?.setZoneWithCaret(zone, pageChanged)\r\n    this.caretVisible = true\n    this.renderCaretIfAny()\n  }\r\n\r\n  /** 获取当前视口顶部所在的页面索引 */\r\n  private getViewportPageIndex(): number {\r\n    return this.layout?.pages.find(page => this.scrollY < page.rect.y + page.rect.height)?.index ?? 0\r\n  }\r\n\r\n  /** 获取当前活动区域的文档（zone=header/footer 时 elements 指向对应区域） */\r\n  getActiveDocument(): IDocxDocumentMeta {\r\n    return this.zoneManager?.getActiveDocument() ?? this.document\r\n  }\r\n\r\n  /** 将修改后的活动文档写回对应区域并触发重渲染 */\r\n  applyActiveDocument(doc: IDocxDocumentMeta): void {\r\n    this.zoneManager?.applyActiveDocument(doc)\r\n  }\r\n\r\n  /** 设置当前高亮的批注/修订组 ID（鼠标悬浮气泡时调用） */\r\n  setActiveGroup(groupId: string | null): void {\r\n    if (!this.renderer.setActiveGroup(groupId) || !this.layout) return\r\n    // Hover is transient: paint now, without rebuilding cards, widgets or thumbnails.\r\n    // Keep any pending document RAF intact; it still owns its normal lifecycle hooks.\r\n    this.renderer.render(this.layout, this.scrollY, this.viewportHeight)\r\n  }\r\n\r\n  setActiveRevision(revisionId: string | null, color?: string): void {\r\n    if (!this.renderer.setActiveRevision(revisionId, color) || !this.layout) return\r\n    this.renderer.render(this.layout, this.scrollY, this.viewportHeight)\r\n  }\r\n\r\n  /**\r\n   * 遍历当前 layout，收集每个 groupId 所对应的锚点坐标（文档绝对坐标）。\r\n   * 返回 Map<groupId, { startX, startY, endX, endY, lineHeight, glyphHeight, startGlyphTop, endGlyphTop }>\r\n   * glyphHeight / startGlyphTop / endGlyphTop 用于按字形实际高度绘制竖线（而非行高）\r\n   */\r\n  getGroupAnchorMap(): Map<string, AnchorInfo> {\r\n    const result = new Map<string, AnchorInfo>()\r\n    if (!this.layout) return result\r\n    for (const page of this.layout.pages) {\r\n      collectGroupAnchors(page.blocks, page.contentRect.x, page.contentRect.y, result)\r\n    }\r\n    return result\r\n  }\r\n\r\n  /**\r\n   * 遍历当前 layout，收集每个 revisionId 所对应的锚点坐标（文档绝对坐标）。\r\n   * 返回 Map<revisionId, { startX, startY, endX, endY, lineHeight, glyphHeight, startGlyphTop, endGlyphTop }>\r\n   */\r\n  getRevisionAnchorMap(): Map<string, AnchorInfo> {\r\n    const result = new Map<string, AnchorInfo>()\r\n    if (!this.layout) return result\r\n    for (const page of this.layout.pages) {\r\n      collectRevisionAnchors(page.blocks, page.contentRect.x, page.contentRect.y, result)\r\n    }\r\n    return result\r\n  }\r\n\r\n  /**\r\n   * 命中测试：把客户端坐标转为文档坐标并调用 hitTest。\r\n   * @param clientX 客户端 x\r\n   * @param clientY 客户端 y\r\n   * @returns 命中位置；未命中返回 null\r\n   */\r\n  hit(clientX: number, clientY: number): IPosition | null {\r\n    if (!this.layout) return null\r\n    const rect = this.canvasHost.getBoundingClientRect()\r\n    // canvasHost 覆盖 container 视口；页面在 canvas 上的 x = page.rect.x + pageOffsetX\r\n    // 反推：文档坐标 x = (clientX - rect.left) - pageOffsetX\r\n    const pageOffsetX = this.getPageOffsetX()\r\n    const x = clientX - rect.left - pageOffsetX\r\n    const y = clientY - rect.top + this.scrollY\r\n    return hitTest(this.layout, x, y, this.zone)\r\n  }\r\n\r\n  /** 销毁视图：解绑事件、断开 ResizeObserver、取消 RAF/定时器、销毁各 widget、移除 DOM。 */\r\n  destroy(): void {\r\n    this.unsubscribeI18n()\r\n    this.diagnosticNotice?.remove()\r\n    this.wrapper.removeEventListener('scroll', this.onScroll)\r\n    this.wrapper.removeEventListener('mousedown', this.onMouseDown)\r\n    this.wrapper.removeEventListener('contextmenu', this.onContextMenu)\r\n    window.removeEventListener('mousemove', this.onMouseMove)\r\n    window.removeEventListener('mouseup', this.onMouseUp)\r\n    this.ro?.disconnect()\r\n    if (this.rafId != null) cancelAnimationFrame(this.rafId)\r\n    if (this.caretTimer != null) { clearInterval(this.caretTimer); this.caretTimer = null }\r\n    this.tableWidget?.destroy()\r\n    this.imageWidget?.destroy()\r\n    this.chartWidget?.destroy()\r\n    this.controlWidget?.destroy()\r\n    this.paragraphWidget?.destroy()\r\n    this.headerFooterWidget?.destroy()\r\n    this.rulerWidget?.destroy()\r\n    this.watermarkWidget?.destroy()\r\n    this.systemWatermarkWidget?.destroy()\r\n    this.selectionToolbarWidget?.destroy()\r\n    this.caretWidget?.destroy()\r\n    this.renderer.destroy()\r\n    this.thumbnailCache.clear()\r\n\r\n    if (this.inputEl && this.inputEl.parentElement === this.container) {\r\n      this.container.removeChild(this.inputEl)\r\n    }\r\n    this.container.removeChild(this.wrapper)\r\n  }\r\n\r\n  /* -------------------- 内部 -------------------- */\r\n\r\n  /**\r\n   * 把编辑器选项映射为排版引擎选项。\r\n   * @returns 排版选项\r\n   */\r\n  private toLayoutOptions(): LayoutOptions {\r\n    return {\r\n      pageWidth: Number(this.options.pageWidth ?? 794),\r\n      pageHeight: Number(this.options.pageHeight ?? 1123),\r\n      pageMargins: (this.options.pageMargins as [number, number, number, number]) ?? [100, 120, 100, 120],\r\n      defaultFont: String(this.options.defaultFont ?? 'Microsoft YaHei'),\r\n      defaultSize: Number(this.options.defaultSize ?? 16),\r\n      defaultLineHeight: Number(this.options.defaultLineHeight ?? 1.5),\r\n      scale: Number(this.options.scale ?? 1),\r\n      pageGap: Number((this.options as unknown as { pageGap?: number }).pageGap ?? 24)\r\n    }\r\n  }\r\n\r\n  /** 重排版+重渲染：格式化元素树 → 排版 → 复用 block id → 标脏 → 同步视觉 → 调度渲染。 */\r\n  private reformatAndRender(): void {\r\n    if (!this.document || !Array.isArray(this.document.elements)) {\r\n      this.document = { ...this.document, elements: this.document?.elements ?? [] }\r\n    }\r\n    const bookmarkMarkers: { name: string; position: string; path: Path }[] = []\r\n    formatElementTree(this.document.elements, { editorOptions: this.options, bookmarkMarkers })\r\n    // Imported markers initialize the runtime index; repainting must not undo edits.\r\n    if (this.document.bookmarks === undefined && bookmarkMarkers.length > 0) {\r\n      this.document.bookmarks = pairBookmarkMarkers(bookmarkMarkers, this.document.elements)\r\n    }\r\n    const headerElements = this.document.header ?? this.document.contentZones?.header\r\n    const footerElements = this.document.footer ?? this.document.contentZones?.footer\r\n    for (const elements of [headerElements, footerElements, ...Object.values(this.document.headerFooterParts ?? {})]) {\r\n      if (elements?.length) formatElementTree(elements, { editorOptions: this.options })\r\n    }\r\n    const layout = this.engine.layout(this.document.elements, headerElements, footerElements, this.document)\r\n\r\n    const { state, dirty } = prepareRenderState(layout, this.renderState)\r\n    this.renderState = state\r\n    this.layout = layout\r\n    const diagnostics = layout.diagnostics ?? []\r\n    const signature = JSON.stringify(diagnostics)\r\n    if (signature !== this.diagnosticSignature) {\r\n      this.diagnosticSignature = signature\r\n      this.diagnosticNotice?.remove()\r\n      this.diagnosticNotice = undefined\r\n      if (diagnostics.length) {\r\n        const notice = document.createElement('div')\r\n        notice.className = 'vervedocs-layout-diagnostics'\r\n        notice.setAttribute('role', 'status')\r\n        notice.style.cssText = 'position:absolute;top:0;left:0;right:0;z-index:100;max-height:120px;overflow:auto;white-space:pre-wrap;padding:8px 12px;background:#fff4ce;color:#663c00;font-size:13px;'\r\n        notice.textContent = diagnostics.map(item => `[${item.zone} / ${item.path.join('.')} / ${item.feature}] ${item.message}`).join('\\n')\r\n        this.container.appendChild(notice)\r\n        this.diagnosticNotice = notice\r\n      }\r\n      this.listener?.emit('layoutDiagnosticsChange', diagnostics)\r\n    }\r\n    this.listener?.emit('pageCountChange', layout.pages.length)\r\n\r\n    // scroller 撑起文档总高（页面居中通过 CSS margin:0 auto）\r\n    this.scroller.style.height = `${layout.totalHeight}px`\r\n    this.scroller.style.width = `${layout.pageWidth}px`\r\n    this.scroller.style.margin = '0 auto'\r\n\r\n    if (dirty.length > 0) this.renderer.markDirty(dirty)\r\n    this.renderer.setLayout(layout, new Set([...state.blocks.values()].map(block => block.id)))\r\n    this.updateVisualLayout()\r\n    // 光标兜底：若 range 尚未定位（首次渲染 / 之前是空文档），把光标置到文档首位，\r\n    // 避免\"看不到光标 / 无法输入\"。findFirstInline 在空文档兜底 run 上也能命中零宽 inline。\r\n    if (this.range && !this.range.getFocus()) {\r\n      const first = this.findFirstInline()\r\n      if (first) {\r\n        this.range.setCaret({ path: first.path, offset: first.startOffset })\r\n        this.caretVisible = true\r\n      }\r\n    }\r\n    this.scheduleRender()\r\n  }\r\n\r\n  /** 计算页面水平居中偏移：(wrapperWidth - pageWidth)/2 - scrollLeft */\r\n  private getPageOffsetX(): number {\r\n    const wrapperWidth = this.wrapper.clientWidth\r\n    const scrollLeft = this.wrapper.scrollLeft\r\n    return Math.max(0, (wrapperWidth - (this.layout?.pageWidth ?? 0)) / 2) - scrollLeft\r\n  }\r\n\r\n\r\n  /** 选项变更后重排版并重渲染：更新引擎选项、失效位图缓存、重排版 */\r\n  private reformatWithInvalidation(): void {\r\n    this.engine.updateOptions(this.toLayoutOptions())\r\n    this.renderer.invalidateAll()\r\n    this.thumbnailCache.clear()\r\n    this.forceFullRender = true\r\n    this.reformatAndRender()\r\n  }\r\n\r\n  /** 计算居中偏移并同步给 renderer */\r\n  private updateVisualLayout(): void {\r\n    if (!this.layout) return\r\n    const pageOffsetX = this.getPageOffsetX()\r\n    const bg = (this.options as unknown as { background?: { color?: string } }).background\r\n    this.renderer.updateVisualOptions({\r\n      pageOffsetX,\r\n      pageMargins: (this.options.pageMargins as [number, number, number, number]) ?? [100, 120, 100, 120],\r\n      pageBg: bg?.color || '#ffffff',\r\n      groupColors: (this.options as unknown as { group?: { groupColors?: Record<string, import('@vervedoc/docx-editor-schema').IGroupColor> } }).group?.groupColors\r\n    })\r\n    this.rulerWidget?.update()\r\n  }\r\n\r\n  /** 容器 resize 处理：更新视口尺寸、同步 renderer、刷新视觉布局并调度重渲染。 */\r\n  private resize = (): void => {\r\n    const rect = this.container.getBoundingClientRect()\r\n    if (rect.width === this.viewportWidth && rect.height === this.viewportHeight) return\r\n    this.forceFullRender = true\r\n    this.viewportWidth = rect.width\r\n    this.viewportHeight = rect.height\r\n    this.renderer.setSize(this.viewportWidth, this.viewportHeight)\r\n    this.updateVisualLayout()\r\n    this.scheduleRender()\r\n\r\n  }\r\n\r\n  /** 滚动处理：更新 scrollY、刷新视觉布局与各 widget、发射当前页码变化事件。 */\r\n  private onScroll = (): void => {\r\n    this.forceFullRender = true\r\n    this.scrollY = this.wrapper.scrollTop\r\n    this.updateVisualLayout()\r\n    // 滚动渲染跳过 afterRender（避免每帧生成缩略图等重操作），widget 更新在 RAF 内完成\r\n    this.scheduleRender(true)\r\n\r\n    // 发射当前页码变化\r\n    if (this.layout && this.listener) {\r\n      const midY = this.scrollY + this.wrapper.clientHeight / 2\r\n      for (const page of this.layout.pages) {\r\n        if (midY >= page.rect.y && midY < page.rect.y + page.rect.height) {\r\n          this.listener.emit('currentPageNoChange', page.index)\r\n          break\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 调度一帧渲染：RAF 内执行 renderer.render + 光标/工具栏重绘 + afterRender 回调。\r\n   * @param skipAfterRender 是否跳过 afterRender 回调（滚动时传 true，避免每帧生成缩略图等重操作）\r\n   */\r\n  private scheduleRender(skipAfterRender = false): void {\r\n    if (this.rafId != null) {\r\n      this._pendingSkipAfterRender = this._pendingSkipAfterRender && skipAfterRender\r\n      return\r\n    }\r\n    this._pendingSkipAfterRender = skipAfterRender\r\n    this.rafId = requestAnimationFrame(() => {\r\n      this.rafId = null\r\n      if (!this.layout) return\r\n      this.syncPageNumberToRenderer()\r\n      this.syncWatermarkToRenderer()\r\n      const dirtyRect = this.forceFullRender || !this.renderState ? null :\r\n        computeDirtyRect(this.paintedState, this.renderState, {\r\n          x: -this.getPageOffsetX(), y: this.scrollY,\r\n          width: this.viewportWidth, height: this.viewportHeight\r\n        })\r\n      this.forceFullRender = false\r\n\r\n      this.renderer.render(this.layout, this.scrollY, this.viewportHeight, dirtyRect)\r\n      this.paintedState = this.renderState\r\n      this.renderCaretIfAny()\r\n      this.selectionToolbarWidget?.update()\r\n      this.tableWidget?.update()\r\n      this.paragraphWidget?.update()\r\n      this.imageWidget?.update()\r\n      this.chartWidget?.update()\r\n      this.controlWidget?.update()\r\n      if (!this._pendingSkipAfterRender) {\r\n        this.afterRender?.()\r\n      }\r\n      this._pendingSkipAfterRender = false\r\n    })\r\n  }\r\n\r\n  /** 将 options.pageNumber 配置同步到渲染器 */\r\n  private syncPageNumberToRenderer(): void {\r\n    const pn = (this.options as any).pageNumber ?? null\r\n    this.renderer.updatePageNumber(pn)\r\n  }\r\n\r\n  /** 将 options.watermark 配置同步到水印 widget */\r\n  private syncWatermarkToRenderer(): void {\r\n    const wm = (this.options as any).watermark ?? null\r\n    this.watermarkWidget?.setConfig(wm as WatermarkConfig | null)\r\n  }\r\n\r\n  /** 设置系统级水印（DOM 覆盖层） */\r\n  setSystemWatermark(config: SystemWatermarkConfig | null): void {\r\n    this.systemWatermarkWidget?.setConfig(config)\r\n  }\r\n}\r\n","/**\r\n * 命令分发责任链（Chain of Responsibility）\r\n *\r\n * 将命令分发从 if-else 硬编码改为可插拔的 handler 链。\r\n * 每个 handler 决定是否处理命令，或调 next() 传递给下一个 handler。\r\n * 支持运行时插入中间件（日志/权限/撤销重做等）而不侵入核心逻辑。\r\n */\r\n\r\n/** 传递给下一个 handler 的函数，调 next() 表示\"我不处理，交给下一个\" */\r\nexport type CommandNext = () => any\r\n\r\n/** 命令处理器：(command, args, next) → result | next() */\r\nexport type CommandHandler = (command: string, args: any[], next: CommandNext) => any\r\n\r\n/**\r\n * 命令责任链。\r\n *\r\n * 用法：\r\n * ```ts\r\n * const chain = new CommandChain()\r\n *   .use((cmd, args, next) => {\r\n *     if (cmd === 'foo') return handleFoo(...args)\r\n *     return next() // 不归我管，交给下一个\r\n *   })\r\n *   .use((cmd, args, next) => {\r\n *     // 兜底 handler\r\n *     return defaultHandler(cmd, ...args)\r\n *   })\r\n * chain.dispatch('foo', 1, 2) // → handleFoo(1, 2)\r\n * ```\r\n */\r\nexport class CommandChain {\r\n  /** 有序 handler 列表 */\r\n  private readonly handlers: CommandHandler[] = []\r\n\r\n  /** 注册 handler，返回 this 支持链式调用 */\r\n  use(handler: CommandHandler): this {\r\n    this.handlers.push(handler)\r\n    return this\r\n  }\r\n\r\n  /**\r\n   * 沿链分发命令。\r\n   * 从第一个 handler 开始，依次调用；handler 返回 next() 时传递给下一个。\r\n   * 所有 handler 都不处理时返回 undefined。\r\n   */\r\n  dispatch(command: string, ...args: any[]): any {\r\n    let index = 0\r\n    const next: CommandNext = () => {\r\n      if (index >= this.handlers.length) return undefined\r\n      const handler = this.handlers[index++]\r\n      return handler(command, args, next)\r\n    }\r\n    return next()\r\n  }\r\n}","/**\r\n * VerveDocs Transform —— CommandAdapt\r\n *\r\n * 基于路径的树编辑命令。所有命令直接操作 IDocxDocumentMeta.elements 树。\r\n * 通过 draw.setDocument 通知视图重排（避免直接依赖 view）。\r\n */\r\n\r\nimport type {\r\n  IDocxDocumentMeta, IElement, IImageElement, Path, ITextElement,\r\n  ITitleElement, ITableElement, IListElement, ListTypeName, IPosition, IRange, ITd, VerticalAlign, CellTextDirection,\n  IAutoTocItem, IAutoTocResult, DocumentLayout, IBookmark, IEditorOption, BlockNode,\r\n  HistorySnapshot, IHistoryManager, TableBorderPreset, RevisionMeta,\r\n  IControlElement, IControlConfig, ControlDataValue\r\n} from '@vervedoc/docx-editor-schema'\r\nimport {\r\n  getByPath, getParentContainer, cloneTree, walkTree, isSamePath, splitParagraphs, comparePath, formatElementTree,\r\n  DEFAULT_EDITOR_OPTION, applyImageLayout, updateImageLayout, TableBorder, BULLET_STYLES, NUMBER_STYLES,\r\n  clearRevision, snapshotRevisionFormat, recordFormatRevision,\r\n  collectPageFields, updatePageFields,\n  isControl, createControlElement, updateControlElementValue, validateControlValue, validateControlConfig, comparePosition, isEmptyValue\r\n} from '@vervedoc/docx-editor-schema'\r\nimport type { RangeManager, IRangeStyle, IEditorAbility, Listener } from '@vervedoc/docx-editor-state'\r\n\r\nconst CONTROL_FORMAT_KEYS = ['font', 'size', 'bold', 'italic', 'color', 'highlight', 'strikeout', 'underline'] as const\r\n\r\n/** Heading sizes in layout pixels, matching the units used by text runs. */\r\nconst HEADING_SIZES: Record<ITitleElement['level'], number> = {\r\n  first: 26,\r\n  second: 24,\r\n  third: 22,\r\n  fourth: 20,\r\n  fifth: 18,\r\n  sixth: 16\r\n}\r\n\r\n// 重新导出迁移至 schema 的跨包共享类型，保持 transform 包 API 兼容\r\nexport type { HistorySnapshot, IHistoryManager } from '@vervedoc/docx-editor-schema'\r\n\r\n/** 文档编辑区域类型：主体、页眉、页脚 */\r\nexport type Zone = 'main' | 'header' | 'footer'\r\n\r\nexport type HyperlinkInsertionError =\r\n  | 'readOnly' | 'disabled' | 'tracking' | 'revisions' | 'bookmarkSelection'\r\n  | 'fieldSelection' | 'existingLink' | 'crossContainer' | 'crossParagraph'\r\n  | 'noSelection' | 'invalidSelection' | 'nonText' | 'invalidText' | 'addressInvalid'\r\n\r\n/**\r\n * DrawLike 接口：描述 CommandAdapt 所依赖的视图/绘制层抽象。\r\n * 通过该接口隔离命令适配器与具体视图实现，便于测试与解耦。\r\n */\r\nexport interface DrawLike {\r\n  /** 获取当前文档元数据 */\r\n  getDocument(): IDocxDocumentMeta\r\n  /** 设置文档元数据并触发重排 */\r\n  setDocument(doc: IDocxDocumentMeta): void\r\n  /** 获取当前活动文档（根据 zone 切换的文档） */\r\n  getActiveDocument(): IDocxDocumentMeta\r\n  /** 应用活动文档变更 */\r\n  applyActiveDocument(doc: IDocxDocumentMeta): void\r\n  /** 获取文档布局信息，未布局时返回 null */\r\n  getLayout(): DocumentLayout | null\r\n  /** 获取滚动容器元素 */\r\n  getScroller(): HTMLDivElement\r\n  /** 设置页面缩放比例 */\r\n  setScale(scale: number): void\r\n  /** 设置页面尺寸（宽高） */\r\n  setPageSize(width: number, height: number): void\r\n  /** 设置标尺可见性 */\r\n  setRulerVisible(visible: boolean): void\r\n  /** 设置页边距（上、右、下、左） */\r\n  setPaperMargins(margins: [number, number, number, number]): void\r\n  /** 获取编辑器选项 */\r\n  getOptions(): { pageWidth?: number; pageHeight?: number; scale?: number; [key: string]: unknown }\r\n  /** 以补丁方式更新编辑器选项 */\r\n  updateOptions(patch: Partial<IEditorOption>): void\r\n  /** 获取当前编辑区域 */\r\n  getZone(): Zone\r\n  /** 设置当前编辑区域 */\r\n  setZone(zone: Zone): void\r\n  /** 切换编辑区域并设置初始光标到对应区域起始位置 */\r\n  setZoneWithCaret(zone: Zone): void\r\n  /** 打印文档 */\r\n  print(): Promise<void>\r\n  /** 获取所有页面缩略图（data URL 数组） */\r\n  getPageThumbnails(): string[]\r\n  /** 滚动到指定文档位置使其可见 */\r\n  scrollPositionIntoView?(pos: IPosition): void\r\n  /** 设置系统级水印（DOM 覆盖层），null 表示移除 */\r\n  setSystemWatermark?(config: { data: string; color?: string; opacity?: number; size?: number; font?: string; repeat?: boolean; gapX?: number; gapY?: number } | null): void\r\n}\r\n\r\n/**\r\n * CommandAdapt 类：基于路径的树编辑命令适配器。\r\n * 所有命令直接操作 IDocxDocumentMeta.elements 树，通过 draw.setDocument 通知视图重排，\r\n * 避免直接依赖 view。是 Command 门面背后真正执行编辑逻辑的核心实现。\r\n */\r\nexport class CommandAdapt {\r\n  /** 格式刷暂存的文本格式片段，null 表示未启用格式刷 */\r\n  private _paintFmt: Partial<Pick<ITextElement, 'bold' | 'italic' | 'underline' | 'strikeout' | 'color' | 'highlight' | 'font' | 'size'>> | null = null\r\n  /** 当前搜索命中结果列表，每项记录命中的路径与起止偏移 */\r\n  private _searchHits: { path: Path; start: number; end: number }[] = []\r\n  /** 当前搜索命中索引（高亮位置） */\r\n  private _searchIdx = 0\r\n  private _searchDocument: IDocxDocumentMeta | null = null\r\n  private _searchZone: Zone = 'main'\r\n  private _searchContent = ''\r\n  private _revisionSequence = 0\r\n  private _hyperlinkInsertionError: HyperlinkInsertionError | null = null\r\n\r\n  /** 生成指定类型的修订元数据，包含递增数字 ID、当前作者和时间。 */\r\n  private newRevision(type: 'insert' | 'delete' | 'format'): RevisionMeta {\r\n    // Numeric IDs are also accepted by Word's w:id attribute.\r\n    this._revisionSequence = Math.max(Date.now(), this._revisionSequence + 1)\r\n    return {\r\n      revisionId: String(this._revisionSequence),\r\n      revisionType: type,\r\n      revisionAuthor: String(this.draw.getOptions().revisionAuthor || '当前用户'),\r\n      revisionDate: new Date().toISOString()\r\n    }\r\n  }\r\n\r\n  /** 跳过删除修订元素并应用格式变更，开启修订时记录变更前的格式。 */\r\n  private formatElements(elements: IElement[], mutate: (element: IElement) => void): void {\r\n    const tracking = !!this.draw.getOptions().trackChanges\r\n    const meta = tracking ? this.newRevision('format') : null\r\n    for (const element of elements) {\r\n      if ((element as ITextElement).revisionType === 'delete') continue\r\n      const before = meta ? snapshotRevisionFormat(element) : null\r\n      mutate(element)\r\n      if (meta && before) recordFormatRevision(element, before, meta)\r\n    }\r\n  }\r\n\r\n  /** 统一目标文本附近同作者连续删除修订的 ID 和时间，保留各 run 的恢复数据。 */\r\n  private mergeAdjacentDeletions(doc: IDocxDocumentMeta, runs: ITextElement[], meta: RevisionMeta): void {\r\n    const targets = new Set<IElement>(runs)\r\n    const parents = new Set<IElement[]>()\r\n    walkTree(doc.elements, (node, ctx) => {\r\n      if (targets.has(node) && Array.isArray(ctx.parent)) parents.add(ctx.parent)\r\n    })\r\n    for (const parent of parents) {\r\n      let index = 0\r\n      while (index < parent.length) {\r\n        const group: ITextElement[] = []\r\n        while (index < parent.length) {\r\n          const node = parent[index]\r\n          if (node.type !== 'text' || node.revisionType !== 'delete' ||\r\n            node.revisionAuthor !== meta.revisionAuthor || node.extension?.bookmarkMarker ||\r\n            /^[\\u200B\\uFEFF]+$/.test(node.value)) break\r\n          group.push(node as ITextElement)\r\n          index++\r\n        }\r\n        if (group.length > 1 && group.some(node => targets.has(node))) {\r\n          // Reuse the existing ID in either direction; keep each run's restore data intact.\r\n          const existing = group.find(node => node.revisionId !== meta.revisionId) ?? group[0]\r\n          for (const node of group) {\r\n            node.revisionId = existing.revisionId\r\n            node.revisionDate = existing.revisionDate\r\n          }\r\n        }\r\n        index++\r\n      }\r\n    }\r\n  }\r\n\r\n  /** 将范围内文本标记为删除修订（本人新增文本直接清空），收拢光标并按 commit 决定是否提交；无目标 run 时返回 false。 */\r\n  private deleteTrackedRange(doc: IDocxDocumentMeta, start: IPosition, end: IPosition, commit: boolean): boolean {\r\n    const adjusted = this.splitBoundaryRuns(doc, start, end)\r\n    const runs = this.collectRunsInRange(doc.elements, adjusted.start, adjusted.end)\r\n    if (!runs.length) return false\r\n    const meta = this.newRevision('delete')\r\n    for (const run of runs) {\r\n      if (run.revisionType === 'delete') continue\r\n      if (run.revisionType === 'insert' && run.revisionAuthor === meta.revisionAuthor) {\r\n        run.value = ''\r\n        clearRevision(run)\r\n      } else {\r\n        const previous = run.revisionId ? {\r\n          revisionId: run.revisionId, revisionType: run.revisionType,\r\n          revisionAuthor: run.revisionAuthor, revisionDate: run.revisionDate,\r\n          revisionOldRPr: run.revisionOldRPr,\r\n          oldProps: run.extension?.revisionOldProps\r\n        } : null\r\n        clearRevision(run)\r\n        Object.assign(run, meta)\r\n        if (previous) run.extension = { ...run.extension, revisionPrevious: previous }\r\n      }\r\n    }\r\n    this.mergeAdjacentDeletions(doc, runs, meta)\r\n    this.range.setCaret(adjusted.start)\r\n    this.clearEmptyHyperlinks(doc)\r\n    if (commit) this._commit(doc, 'text')\r\n    return true\r\n  }\r\n\r\n  /** 按修订方式删除光标相邻的一个 Unicode 字符；backward 为 true 时向前查找，跳过已删除文本和书签标记。 */\r\n  private deleteTrackedCharacter(backward: boolean): void {\r\n    const pos = this.range.getFocus()\r\n    if (!pos) return\r\n    const doc = this.draw.getActiveDocument()\r\n    const parent = getParentContainer(doc.elements, pos.path)\r\n    if (!parent) return\r\n    const current = Number(pos.path[pos.path.length - 1])\r\n    for (let index = current; index >= 0 && index < parent.length; index += backward ? -1 : 1) {\r\n      const run = parent[index]\r\n      if (run.type !== 'text') {\r\n        if (isControl(run) && run.control.removable !== false) {\r\n          parent.splice(index, 1)\r\n          if (backward) {\r\n            const prevIdx = index - 1\r\n            if (prevIdx >= 0 && parent[prevIdx]) {\r\n              const newPath = [...pos.path.slice(0, -1), prevIdx] as Path\r\n              const prevEl = parent[prevIdx]\r\n              const newOffset = prevEl.type === 'text' ? (prevEl as ITextElement).value.length : 0\r\n              this.range.setCaret({ path: newPath, offset: newOffset })\r\n            } else {\r\n              const newPath = [...pos.path.slice(0, -1), 0] as Path\r\n              this.range.setCaret({ path: newPath, offset: 0 })\r\n            }\r\n          } else if (index === current) {\r\n            const newPath = [...pos.path.slice(0, -1), index] as Path\r\n            this.range.setCaret({ path: newPath, offset: 0 })\r\n          }\r\n          this._commit(doc, 'text')\r\n          return\r\n        }\r\n        return\r\n      }\r\n      if (run.revisionType === 'delete' || !run.value.length || run.extension?.bookmarkMarker) continue\r\n      const offset = index === current ? pos.offset : backward ? run.value.length : 0\r\n      if ((backward && offset <= 0) || (!backward && offset >= run.value.length)) continue\r\n      const text = backward ? Array.from(run.value.slice(0, offset)).at(-1)! : Array.from(run.value.slice(offset))[0]\r\n      const path: Path = [...pos.path.slice(0, -1), index]\r\n      this.deleteTrackedRange(doc,\r\n        { path, offset: backward ? offset - text.length : offset },\r\n        { path, offset: backward ? offset : offset + text.length }, true)\r\n      return\r\n    }\r\n  }\r\n\r\n  /** 文档、编辑区域或内容与搜索快照不一致时，清空失效的搜索结果。 */\r\n  private validateSearch(): void {\r\n    if (this._searchDocument !== this.draw.getDocument() ||\r\n      this._searchZone !== this.draw.getZone() ||\r\n      this._searchContent !== JSON.stringify(this.draw.getActiveDocument().elements)) {\r\n      this._searchHits = []\r\n      this._searchIdx = 0\r\n    }\r\n  }\r\n\r\n  /** 保存当前文档引用、编辑区域和内容快照，供搜索结果有效性校验使用。 */\r\n  private captureSearch(): void {\r\n    this._searchDocument = this.draw.getDocument()\r\n    this._searchZone = this.draw.getZone()\r\n    this._searchContent = JSON.stringify(this.draw.getActiveDocument().elements)\r\n  }\r\n  /** 历史管理器实例，未设置时为 null */\r\n  private _historyManager: IHistoryManager | null = null\r\n\r\n\r\n  /**\r\n   * 创建 CommandAdapt 实例。\r\n   * @param draw 绘制层抽象，用于读写文档与触发视图更新\r\n   * @param range 选区管理器，用于维护光标与选区\r\n   * @param listener 事件监听器，可选，用于对外发射状态变更事件\r\n   */\r\n  constructor(\r\n    private draw: DrawLike,\r\n    private range: RangeManager,\r\n    private listener?: Listener\r\n  ) {}\r\n\r\n  /**\r\n   * 设置历史管理器。\r\n   * @param hm 历史管理器实例\r\n   */\r\n  setHistoryManager(hm: IHistoryManager): void {\r\n    this._historyManager = hm\r\n  }\r\n\r\n\r\n  /** 计算当前页面内容区宽度（pageWidth - 左右边距） */\r\n  private getContentWidth(): number {\r\n    const opts = this.draw.getOptions()\r\n    const pageWidth = Number(opts.pageWidth ?? 794)\r\n    const margins = (opts.pageMargins as [number, number, number, number] | undefined) ?? [96, 120, 96, 120]\r\n    return Math.max(100, pageWidth - margins[0] - margins[2])\r\n  }\r\n\r\n  /** 初始化历史首快照（编辑器就绪后调用一次） */\r\n  pushInitialHistory(): void {\r\n    if (!this._historyManager) return\r\n    this._historyManager.pushInitial({\r\n      doc: cloneTree(this.draw.getDocument()),\r\n      range: this.range.getRange(),\r\n      zone: this.draw.getZone()\r\n    })\r\n  }\r\n\r\n  /** 克隆并规范化文档各内容区，切回正文并清空选区，按 resetHistory 初始化或追加历史后通知状态变更。 */\r\n  replaceDocument(document: IDocxDocumentMeta, resetHistory = false): void {\r\n    const doc = cloneTree(document)\r\n    const options = { editorOptions: this.draw.getOptions() as IEditorOption, styles: doc.styles, numbering: doc.numbering }\r\n    formatElementTree(doc.elements, options)\r\n    for (const elements of [doc.header, doc.footer, ...Object.values(doc.contentZones ?? {}), ...Object.values(doc.headerFooterParts ?? {})]) {\r\n      if (Array.isArray(elements)) formatElementTree(elements, options)\r\n    }\r\n    this.draw.setZone('main')\r\n    this.range.clear()\r\n    this.draw.setDocument(doc)\r\n    if (resetHistory) this.pushInitialHistory()\r\n    else this._historyManager?.push({ doc: cloneTree(doc), range: null, zone: this.draw.getZone() })\r\n    this.listener?.emit('documentSet', doc)\r\n    this.listener?.emit('contentChange')\r\n    this.listener?.emit('formatChange', this.getRangeStyle())\r\n    this.listener?.emit('abilityChange', this.getAbility())\r\n  }\r\n\r\n  /** 在可编辑时对文档副本执行插件事务，清空选区并提交历史与状态通知；回调返回 false 时取消提交。 */\r\n  commitPluginTransaction(action: (doc: IDocxDocumentMeta) => boolean | void): void {\r\n    if (!this.getIsCanInput()) return\r\n    const doc = cloneTree(this.draw.getDocument())\r\n    if (action(doc) === false) return\r\n    this.range.clear()\r\n    this.draw.setDocument(doc)\r\n    this._historyManager?.push({ doc: cloneTree(doc), range: null, zone: this.draw.getZone() })\r\n    this.listener?.emit('contentChange')\r\n    this.listener?.emit('formatChange', this.getRangeStyle())\r\n    this.listener?.emit('abilityChange', this.getAbility())\r\n  }\r\n\r\n  /** 提交变更并推送历史快照，同时通知调用方状态变更 */\r\n  private _commit(doc: IDocxDocumentMeta, coalesceKey?: string): void {\r\n    this.draw.applyActiveDocument(doc)\r\n    if (this._historyManager) {\r\n      this._historyManager.push(\r\n        { doc: cloneTree(this.draw.getDocument()), range: this.range.getRange(), zone: this.draw.getZone() },\r\n        coalesceKey\r\n      )\r\n    }\r\n    // 通知调用方：内容变更 + 选区样式变更 + 能力变更（含撤销/重做状态）\r\n    this.listener?.emit('contentChange')\r\n    this.listener?.emit('formatChange', this.getRangeStyle())\r\n    this.listener?.emit('abilityChange', this.getAbility())\r\n  }\r\n\r\n  /**\r\n   * 模板方法：获取活动文档 → 执行修改动作 → 提交（重渲染 + 历史 + 事件）。\r\n   *\r\n   * 命令方法只需提供修改逻辑（action），无需手动调 `_commit`。\r\n   * action 返回 `false` 时跳过提交（用于校验失败提前退出）。\r\n   *\r\n   * @param action 修改动作，接收 doc 引用直接 mutate，返回 false 跳过提交\r\n   * @param coalesceKey 历史合并键（如 'text' 用于连续输入合并为一条撤销记录）\r\n   *\r\n   * @example\r\n   * ```ts\r\n   * setBold(): void {\r\n   *   this.execute(doc => {\r\n   *     const pos = this.range.getFocus()\r\n   *     if (!pos) return false\r\n   *     // ... mutate doc\r\n   *   })\r\n   * }\r\n   * ```\r\n   */\r\n  protected execute(\r\n    action: (doc: IDocxDocumentMeta) => boolean | void,\r\n    coalesceKey?: string\r\n  ): void {\r\n    if (!this.getIsCanInput()) return\r\n    const doc = this.draw.getActiveDocument()\r\n    if (action(doc) !== false) {\r\n      this._commit(doc, coalesceKey)\r\n    }\r\n  }\r\n\r\n  /* -------------------- 文本编辑 -------------------- */\r\n\r\n  private controlText(node: IControlElement): ITextElement {\r\n    return {\r\n      type: 'text', value: '', font: node.font, size: node.size,\r\n      bold: node.bold, italic: node.italic, color: node.color,\r\n      underline: node.underline, strikeout: node.strikeout,\r\n      rowFlex: node.rowFlex, sourceParagraphId: node.sourceParagraphId\r\n    }\r\n  }\r\n\r\n  /** 导入的书签与域标记只记录位置，不是可编辑字符。 */\r\n  private isInvisibleText(node?: IElement | null): node is ITextElement {\r\n    return node?.type === 'text' && !!(node.extension?.bookmarkMarker || node.extension?.fieldMarker)\r\n  }\r\n\r\n  /** Controls have two caret positions (0 before, 1 after), never editable display-text offsets. */\r\n  private ensureTextCaret(doc: IDocxDocumentMeta): void {\r\n    const pos = this.range.getFocus()\r\n    if (!pos) return\r\n    const node = getByPath(doc.elements, pos.path)\r\n    if (!node || (!isControl(node) && !this.isInvisibleText(node))) return\r\n    const parent = getParentContainer(doc.elements, pos.path)!\r\n    const index = Number(pos.path.at(-1)) + (pos.offset > 0 ? 1 : 0)\r\n    const carrier: ITextElement = isControl(node)\r\n      ? this.controlText(node)\r\n      : { type: 'text', value: '', font: node.font, size: node.size }\r\n    parent.splice(index, 0, carrier)\r\n    if (this.isInvisibleText(node)) {\r\n      const parentPath = pos.path.slice(0, -1)\r\n      this.mapBookmarkPositions(doc, point => {\r\n        if (!isSamePath(point.path.slice(0, parentPath.length), parentPath) ||\r\n          typeof point.path[parentPath.length] !== 'number' ||\r\n          Number(point.path[parentPath.length]) < index) return point\r\n        const path = [...point.path] as Path\r\n        path[parentPath.length] = Number(path[parentPath.length]) + 1\r\n        return { path, offset: point.offset }\r\n      })\r\n    }\r\n    this.range.setCaret({ path: [...pos.path.slice(0, -1), index], offset: 0 })\r\n  }\r\n\r\n  /** Handle an atom or the text immediately beside it before ordinary character deletion. */\r\n  private deleteControlBoundary(backward: boolean): boolean {\r\n    const pos = this.range.getFocus()\r\n    if (!pos) return false\r\n    const doc = this.draw.getActiveDocument()\r\n    const node = getByPath(doc.elements, pos.path)\r\n    const parent = getParentContainer(doc.elements, pos.path)\r\n    if (!node || !parent) return false\r\n    const atom = isControl(node)\r\n    if (!atom && (node.type !== 'text' || (backward ? pos.offset > 0 : pos.offset < node.value.length))) return false\r\n    const current = Number(pos.path.at(-1))\r\n    const onAtom = atom && (backward ? pos.offset > 0 : pos.offset === 0)\r\n    let index = onAtom ? current : current + (backward ? -1 : 1)\r\n    while (index >= 0 && index < parent.length &&\r\n      (this.isInvisibleText(parent[index]) || (parent[index].type === 'text' && parent[index].value === ''))) {\r\n      index += backward ? -1 : 1\r\n    }\r\n    const target = parent[index]\r\n    if (target && isControl(target)) {\r\n      if (target.control.removable === false) return true\r\n      // Keep an empty text carrier so deleting the only control still leaves a valid caret.\r\n      parent[index] = this.controlText(target)\r\n      this.range.setCaret({ path: [...pos.path.slice(0, -1), index], offset: 0 })\r\n      this._commit(doc)\r\n      return true\r\n    }\r\n    if (target && this.deleteAtomicAtCaret(doc, { path: [...pos.path.slice(0, -1), index], offset: 0 })) return true\r\n    // Delete 在文本末尾继续删除下一文本片段，跳过控件删除后留下的空载体。\r\n    if (atom || (node.type === 'text' && target?.type === 'text' && (!backward || node.value === ''))) {\r\n      if (target?.type === 'text') {\r\n        this.range.setCaret({\r\n          path: [...pos.path.slice(0, -1), index],\r\n          offset: backward ? target.value.length : 0\r\n        })\r\n        if (backward) this.deleteBackward()\r\n        else this.deleteForward()\r\n      }\r\n      return true\r\n    }\r\n    return false\r\n  }\r\n\r\n  /** 光标意外落在导入标记上时，转到相邻可见元素再执行删除。 */\r\n  private deleteAtInvisibleCaret(backward: boolean): boolean {\r\n    const pos = this.range.getFocus()\r\n    if (!pos) return false\r\n    const doc = this.draw.getActiveDocument()\r\n    if (!this.isInvisibleText(getByPath(doc.elements, pos.path))) return false\r\n    const adjacent = this.adjacentInline(doc, pos.path, backward)\r\n    if (adjacent) {\r\n      if (adjacent.node.type === 'text' || isControl(adjacent.node)) {\r\n        this.range.setCaret({\r\n          path: adjacent.path,\r\n          offset: backward ? (isControl(adjacent.node) ? 1 : adjacent.node.value.length) : 0\r\n        })\r\n        if (backward) this.deleteBackward()\r\n        else this.deleteForward()\r\n      } else {\r\n        this.deleteAtomicAtCaret(doc, { path: adjacent.path, offset: 0 })\r\n      }\r\n    }\r\n    return true\r\n  }\r\n\r\n  /** 图片等独立节点可直接通过键盘删除，删除后保留可输入的光标位置。 */\r\n  private deleteAtomicAtCaret(doc: IDocxDocumentMeta, pos: IPosition, commit = true): boolean {\r\n    const node = getByPath(doc.elements, pos.path)\r\n    if (!node || !['image', 'pageBreak', 'columnBreak', 'block', 'table', 'separator'].includes(node.type)) return false\r\n    const parent = getParentContainer(doc.elements, pos.path)\r\n    const index = pos.path.at(-1)\r\n    if (!parent || typeof index !== 'number') return false\r\n    this.updateBookmarksAfterDeletion(doc, { path: pos.path, offset: 0 }, { path: pos.path, offset: 1 })\r\n    if (parent === doc.elements) {\r\n      this.removeSectionBoundaries(doc, index, index)\r\n      this.spliceBodyWithBookmarks(doc, index, 1)\r\n    } else {\r\n      parent.splice(index, 1)\r\n      if (!parent.length) parent.push({ type: 'text', value: '' })\r\n      this.mapBookmarkPositions(doc, point => {\r\n        const depth = pos.path.length - 1\r\n        if (!isSamePath(point.path.slice(0, depth), pos.path.slice(0, depth)) ||\r\n          typeof point.path[depth] !== 'number' || Number(point.path[depth]) <= index) return point\r\n        const path = [...point.path] as Path\r\n        path[depth] = Number(path[depth]) - 1\r\n        return { path, offset: point.offset }\r\n      })\r\n    }\r\n    let caretIndex = Math.min(index, parent.length - 1)\r\n    if (parent[caretIndex]?.type !== 'text' || this.isInvisibleText(parent[caretIndex])) {\r\n      if (caretIndex > 0 && parent[caretIndex - 1]?.type === 'text' && !this.isInvisibleText(parent[caretIndex - 1])) {\r\n        caretIndex--\r\n      } else {\r\n        parent.splice(caretIndex, 0, { type: 'text', value: '' })\r\n        const parentPath = pos.path.slice(0, -1)\r\n        this.mapBookmarkPositions(doc, point => {\r\n          if (!isSamePath(point.path.slice(0, parentPath.length), parentPath) ||\r\n            typeof point.path[parentPath.length] !== 'number' ||\r\n            Number(point.path[parentPath.length]) < caretIndex) return point\r\n          const path = [...point.path] as Path\r\n          path[parentPath.length] = Number(path[parentPath.length]) + 1\r\n          return { path, offset: point.offset }\r\n        })\r\n      }\r\n    }\r\n    this.range.setCaret({\r\n      path: [...pos.path.slice(0, -1), caretIndex],\r\n      offset: caretIndex < index && parent[caretIndex].type === 'text' ? parent[caretIndex].value.length : 0\r\n    })\r\n    if (commit) this._commit(doc, 'text')\r\n    return true\r\n  }\r\n\r\n  private deleteRangeWithControls(doc: IDocxDocumentMeta, start: IPosition, end: IPosition, commit: boolean): boolean | null {\r\n    const entries: { node: ITextElement | IControlElement; path: Path; parent: IElement[]; index: number }[] = []\r\n    let hasControl = false\r\n    walkTree(doc.elements, (node, ctx) => {\r\n      if (node.type !== 'text' && !isControl(node)) return\r\n      if (comparePath(ctx.path, start.path) >= 0 && comparePath(ctx.path, end.path) <= 0) {\r\n        entries.push({ node: node as ITextElement | IControlElement, path: ctx.path, parent: ctx.parent as IElement[], index: ctx.index })\r\n        if (isControl(node)) hasControl = true\r\n      }\r\n      if (isControl(node)) return false\r\n      return\r\n    })\r\n    if (!hasControl) return null\r\n    const selected = entries.filter(({ node, path }) => {\r\n      const length = isControl(node) ? 1 : node.value.length\r\n      return comparePosition({ path, offset: length }, start) > 0 && comparePosition({ path, offset: 0 }, end) < 0\r\n    })\r\n    if (selected.some(({ node }) => isControl(node) && node.control.removable === false)) return false\r\n    let caret = start\r\n    let changed = false\r\n    for (const { node, path, parent, index } of selected.reverse()) {\r\n      if (isControl(node)) {\r\n        parent[index] = this.controlText(node)\r\n        if (isSamePath(path, start.path)) caret = { path, offset: 0 }\r\n        changed = true\r\n      } else {\r\n        const from = isSamePath(path, start.path) ? start.offset : 0\r\n        const to = isSamePath(path, end.path) ? end.offset : node.value.length\r\n        if (from === to) continue\r\n        if (this.draw.getOptions().trackChanges) {\r\n          this.deleteTrackedRange(doc, { path, offset: from }, { path, offset: to }, false)\r\n          if (isSamePath(path, start.path)) caret = this.range.getFocus()!\r\n        } else {\r\n          node.value = node.value.slice(0, from) + node.value.slice(to)\r\n        }\r\n        changed = true\r\n      }\r\n    }\r\n    this.range.setCaret(caret)\r\n    if (changed && !this.draw.getOptions().trackChanges) this.updateBookmarksAfterDeletion(doc, start, end)\r\n    this.clearEmptyHyperlinks(doc)\r\n    if (changed && commit) this._commit(doc)\r\n    return changed\r\n  }\r\n\r\n  /**\r\n   * 在当前光标位置插入文本。若存在选区则先删除选区再插入。\r\n   * @param text 待插入的文本内容\r\n   */\r\n  insertText(text: string): void {\r\n    if (!this.getIsCanInput()) return\r\n    if (!text) return\r\n    if (this.deleteSelection(false)) {\r\n      // 选区已删除，光标在原选区 start，继续插入 text\r\n    }\r\n    if (!this.range.isCollapsed()) return\r\n    this.ensureTextCaret(this.draw.getActiveDocument())\r\n    const pos = this.range.getFocus()\r\n    if (!pos) return\r\n    const doc = this.draw.getActiveDocument()\r\n    const node = getByPath(doc.elements, pos.path)\r\n    if (!node) return\r\n    if (node.type === 'text') {\r\n      const t = node as ITextElement\r\n      const before = t.value.slice(0, pos.offset)\r\n      const after = t.value.slice(pos.offset)\r\n      const tracking = !!this.draw.getOptions().trackChanges\r\n      const author = String(this.draw.getOptions().revisionAuthor || '当前用户')\r\n      if ((tracking && !(t.revisionType === 'insert' && t.revisionAuthor === author)) ||\r\n        (!tracking && t.revisionId)) {\r\n        const parent = getParentContainer(doc.elements, pos.path)\r\n        if (!parent) return\r\n        const index = Number(pos.path[pos.path.length - 1])\r\n        const inserted = cloneTree(t)\r\n        clearRevision(inserted)\r\n        inserted.value = text\r\n        if (tracking) Object.assign(inserted, this.newRevision('insert'))\r\n        const parts: ITextElement[] = []\r\n        if (before) parts.push({ ...cloneTree(t), value: before })\r\n        const insertIndex = index + parts.length\r\n        parts.push(inserted)\r\n        if (after) parts.push({ ...cloneTree(t), value: after })\r\n        parent.splice(index, 1, ...parts)\r\n        this.range.setCaret({ path: [...pos.path.slice(0, -1), insertIndex], offset: text.length })\r\n        this._commit(doc, 'text')\r\n        return\r\n      }\r\n      t.value = before + text + after\r\n      this.range.setCaret({ path: pos.path.slice() as Path, offset: pos.offset + text.length })\r\n      // 不可迁移：前置 deleteSelection() 可能已 commit\r\n      this._commit(doc, 'text')\r\n    }\r\n  }\r\n\r\n  private isHyperlinkRun(doc: IDocxDocumentMeta, path: Path): boolean {\r\n    return path.length > 2 && getByPath(doc.elements, path.slice(0, -2))?.type === 'hyperlink'\r\n  }\r\n\r\n  /** Traverse inline runs without crossing a paragraph/list/table container. */\r\n  private adjacentInline(doc: IDocxDocumentMeta, path: Path, backward: boolean): { node: IElement; path: Path } | null {\r\n    const containerPath = this.isHyperlinkRun(doc, path) ? path.slice(0, -3) : path.slice(0, -1)\r\n    const parent = getParentContainer(doc.elements, [...containerPath, 0])\r\n    if (!parent) return null\r\n    const entries: { node: IElement; path: Path }[] = []\r\n    parent.forEach((node, index) => {\r\n      const nodePath: Path = [...containerPath, index]\r\n      if (node.type === 'hyperlink') {\r\n        const children = node.valueList as IElement[] | undefined\r\n        children?.forEach((child, childIndex) => entries.push({ node: child, path: [...nodePath, 'valueList', childIndex] }))\r\n      } else entries.push({ node, path: nodePath })\r\n    })\r\n    const current = entries.findIndex(entry => isSamePath(entry.path, path))\r\n    if (current < 0) return null\r\n    for (let index = current + (backward ? -1 : 1); index >= 0 && index < entries.length; index += backward ? -1 : 1) {\r\n      const entry = entries[index]\r\n      if (entry.node.type === 'text' && (entry.node.value === '' || entry.node.extension?.bookmarkMarker || entry.node.extension?.fieldMarker)) continue\r\n      return entry\r\n    }\r\n    return null\r\n  }\r\n\r\n  /** Keep an editable caret carrier, but never an empty clickable hyperlink. */\r\n  private clearEmptyHyperlinks(doc: IDocxDocumentMeta): void {\r\n    const focus = this.range.getFocus()\r\n    let caret = focus\r\n    walkTree(doc.elements, (node, ctx) => {\r\n      if (node.type !== 'hyperlink') return\r\n      const children = (node.valueList ?? []) as IElement[]\r\n      if (children.some(child => child.type !== 'text' || child.value !== '')) return\r\n      const text: ITextElement = { type: 'text', value: '', sourceParagraphId: node.sourceParagraphId }\r\n      ;(ctx.parent as IElement[])[ctx.index] = text\r\n      if (caret && isSamePath(caret.path.slice(0, ctx.path.length), ctx.path)) {\r\n        caret = { path: ctx.path.slice() as Path, offset: 0 }\r\n      }\r\n      return false\r\n    })\r\n    if (caret !== focus) this.range.setCaret(caret)\r\n  }\r\n\r\n  private deleteHyperlinkCharacter(backward: boolean): boolean {\r\n    const pos = this.range.getFocus()\r\n    if (!pos) return false\r\n    const doc = this.draw.getActiveDocument()\r\n    const node = getByPath(doc.elements, pos.path)\r\n    if (!node || node.type !== 'text') return false\r\n    const inside = this.isHyperlinkRun(doc, pos.path)\r\n    const atBoundary = backward ? pos.offset === 0 : pos.offset === node.value.length\r\n    const target = atBoundary ? this.adjacentInline(doc, pos.path, backward) : { node, path: pos.path }\r\n    if (!target || target.node.type !== 'text' || (!inside && !this.isHyperlinkRun(doc, target.path))) return false\r\n    const offset = atBoundary ? (backward ? target.node.value.length : 0) : pos.offset\r\n    const character = backward ? Array.from(target.node.value.slice(0, offset)).at(-1) : Array.from(target.node.value.slice(offset))[0]\r\n    if (!character) return false\r\n    const from = backward ? offset - character.length : offset\r\n    if (this.draw.getOptions().trackChanges) {\r\n      this.deleteTrackedRange(doc, { path: target.path, offset: from }, { path: target.path, offset: from + character.length }, false)\r\n    } else {\r\n      target.node.value = target.node.value.slice(0, from) + target.node.value.slice(from + character.length)\r\n      this.updateBookmarksAfterDeletion(doc,\r\n        { path: target.path, offset: from }, { path: target.path, offset: from + character.length })\r\n      this.range.setCaret(backward ? { path: target.path, offset: from } : pos)\r\n    }\r\n    this.clearEmptyHyperlinks(doc)\r\n    this._commit(doc, 'text')\r\n    return true\r\n  }\r\n\r\n  /** 删除当前选区内容（若已 collapsed 则不操作）。光标收缩到选区 start。返回是否实际删除。 */\r\n  deleteSelection(commit = true): boolean {\r\n    if (!this.getIsCanInput()) return false\r\n    if (this.range.isCollapsed()) return false\r\n    const ordered = this.range.getOrdered()\r\n    if (!ordered) return false\r\n    const { start, end } = ordered\r\n    const doc = this.draw.getActiveDocument()\r\n    if (isSamePath(start.path, end.path) && start.offset === 0 && end.offset === 1 &&\r\n      this.deleteAtomicAtCaret(doc, start, commit)) return true\r\n    const controlResult = this.deleteRangeWithControls(doc, start, end, commit)\r\n    if (controlResult !== null) return controlResult\r\n    if (this.draw.getOptions().trackChanges) {\r\n      return this.deleteTrackedRange(doc, start, end, commit)\r\n    }\r\n\r\n    const runs: { path: Path; parent: IElement[]; idx: number }[] = []\r\n    walkTree(doc.elements, (node, ctx) => {\r\n      if ((node.type === 'text' || (isControl(node) && node.control.removable !== false)) && Array.isArray(ctx.parent)) {\r\n        runs.push({ path: ctx.path.slice() as Path, parent: ctx.parent as IElement[], idx: ctx.index })\r\n      }\r\n    })\r\n\r\n    let startRunIdx = -1, endRunIdx = -1\r\n    for (let i = 0; i < runs.length; i++) {\r\n      if (isSamePath(runs[i].path, start.path)) startRunIdx = i\r\n      if (isSamePath(runs[i].path, end.path)) endRunIdx = i\r\n    }\r\n    if (startRunIdx === -1 || endRunIdx === -1 || startRunIdx > endRunIdx) return false\r\n\r\n    const selected = runs.slice(startRunIdx, endRunIdx + 1)\r\n    if (selected.some(run => this.isHyperlinkRun(doc, run.path))) {\r\n      // Trim each run independently: surviving suffixes keep their formatting and link ownership.\r\n      for (const run of selected) {\r\n        const node = run.parent[run.idx]\r\n        if (node.type !== 'text') continue\r\n        const from = isSamePath(run.path, start.path) ? start.offset : 0\r\n        const to = isSamePath(run.path, end.path) ? end.offset : node.value.length\r\n        node.value = node.value.slice(0, from) + node.value.slice(to)\r\n      }\r\n      this.range.setCaret({ path: start.path.slice() as Path, offset: start.offset })\r\n      this.updateBookmarksAfterDeletion(doc, start, end)\r\n      this.clearEmptyHyperlinks(doc)\r\n      if (commit) this._commit(doc, 'text')\r\n      return true\r\n    }\r\n\r\n    if (startRunIdx === endRunIdx) {\r\n      const node = getByPath(doc.elements, start.path)\r\n      if (node && node.type === 'text') {\r\n        const t = node as ITextElement\r\n        t.value = t.value.slice(0, start.offset) + t.value.slice(end.offset)\r\n        this.range.setCaret({ path: start.path.slice() as Path, offset: start.offset })\r\n        this.updateBookmarksAfterDeletion(doc, start, end)\r\n        if (commit) this._commit(doc, 'text')\r\n        return true\r\n      }\r\n      return false\r\n    }\r\n\r\n    const startRun = runs[startRunIdx]\r\n    const endRun = runs[endRunIdx]\r\n    const startNode = startRun.parent[startRun.idx] as ITextElement\r\n    const endNode = endRun.parent[endRun.idx] as ITextElement\r\n    if (startNode.type !== 'text' || endNode.type !== 'text') return false\r\n\r\n    const before = startNode.value.slice(0, start.offset)\r\n    const after = endNode.value.slice(end.offset)\r\n    startNode.value = before + after\r\n    this.updateBookmarksAfterDeletion(doc, start, end, true)\r\n\r\n    if (start.path.length === 1 && end.path.length === 1) {\r\n      const first = Number(start.path[0]), last = Number(end.path[0])\r\n      this.removeSectionBoundaries(doc, first + 1, last)\r\n      doc.elements.splice(first + 1, last - first)\r\n      this.range.setCaret({ path: [first], offset: start.offset })\r\n      if (commit) this._commit(doc, 'text')\r\n      return true\r\n    }\r\n\r\n    const toDelete = runs.slice(startRunIdx + 1, endRunIdx + 1)\r\n    const groups = new Map<IElement[], number[]>()\r\n    for (const r of toDelete) {\r\n      let arr = groups.get(r.parent)\r\n      if (!arr) { arr = []; groups.set(r.parent, arr) }\r\n      arr.push(r.idx)\r\n    }\r\n    for (const [parent, idxs] of groups) {\r\n      idxs.sort((a, b) => b - a)\r\n      for (const idx of idxs) parent.splice(idx, 1)\r\n    }\r\n\r\n    this.range.setCaret({ path: start.path.slice() as Path, offset: start.offset })\r\n    if (commit) this._commit(doc, 'text')\r\n    return true\r\n  }\r\n\r\n  /** 获取文档全文纯文本（所有 text run 的 value 拼接）。 */\r\n  getFullText(): string {\r\n    const doc = this.draw.getDocument()\r\n    return (doc.elements || []).map(el => (el as any).value || '').join('')\r\n  }\r\n\r\n  /** 跳转到指定页码（通过设置滚动位置）。 */\r\n  jumpToPage(pageNo: number): void {\r\n    const opts = this.draw.getOptions()\r\n    const pageHeight = Number(opts.pageHeight ?? 1123)\r\n    const pageGap = Number(opts.pageGap ?? 24) * Number(opts.scale ?? 1)\r\n    const scroller = this.draw.getScroller()\r\n    const wrapper = scroller?.parentElement as HTMLElement | null\r\n    if (wrapper) {\r\n      wrapper.scrollTop = pageNo * (pageHeight + pageGap)\r\n    }\r\n  }\r\n\r\n  /** 定位到指定修订 ID 的首个元素位置，返回是否找到。 */\r\n  locateRevision(id: string): boolean {\r\n    if (!id) return false\r\n    const doc = this.draw.getDocument()\r\n    let position: IPosition | null = null\r\n    walkTree(doc.elements, (node, ctx) => {\r\n      if (!position && (node as ITextElement).revisionId === id) position = { path: ctx.path, offset: 0 }\r\n    })\r\n    if (!position) return false\r\n    this.range.setCaret(position)\r\n    this.draw.scrollPositionIntoView?.(position)\r\n    return true\r\n  }\r\n\r\n  /** 提取当前选区纯文本（用于复制/剪切）。 */\r\n  extractSelectionText(): string {\r\n    if (this.range.isCollapsed()) return ''\r\n    const ordered = this.range.getOrdered()\r\n    if (!ordered) return ''\r\n    const { start, end } = ordered\r\n    const doc = this.draw.getActiveDocument()\r\n\r\n    const runs: { path: Path; text: string; atomic?: boolean }[] = []\r\n    walkTree(doc.elements, (node, ctx) => {\r\n      if (node.type === 'text' || isControl(node)) {\r\n        runs.push({\r\n          path: ctx.path.slice() as Path,\r\n          text: node.extension?.bookmarkMarker ? '' : node.value,\r\n          atomic: isControl(node)\r\n        })\r\n      }\r\n      if (isControl(node)) return false\r\n      return\r\n    })\r\n\r\n    let startRunIdx = -1, endRunIdx = -1\r\n    for (let i = 0; i < runs.length; i++) {\r\n      if (isSamePath(runs[i].path, start.path)) startRunIdx = i\r\n      if (isSamePath(runs[i].path, end.path)) endRunIdx = i\r\n    }\r\n    if (startRunIdx === -1 || endRunIdx === -1 || startRunIdx > endRunIdx) return ''\r\n\r\n    if (startRunIdx === endRunIdx) {\r\n      const run = runs[startRunIdx]\r\n      return run.text.slice(run.atomic && start.offset > 0 ? run.text.length : start.offset,\r\n        run.atomic && end.offset > 0 ? run.text.length : end.offset)\r\n    }\r\n\r\n    const first = runs[startRunIdx]\r\n    let result = first.text.slice(first.atomic && start.offset > 0 ? first.text.length : start.offset)\r\n    for (let i = startRunIdx + 1; i < endRunIdx; i++) {\r\n      const t = runs[i].text\r\n      result += t === '\\u200B' ? '\\n' : t\r\n    }\r\n    const last = runs[endRunIdx]\r\n    result += last.text.slice(0, last.atomic && end.offset > 0 ? last.text.length : end.offset)\r\n    return result\r\n  }\r\n\r\n  /**\r\n   * 向后删除一个字符（Backspace 行为）。若有选区则删除选区；否则删除光标前一个字符，\r\n   * 列表起点先取消编号，其他 run 起点尝试与前一个 text run 合并。\r\n   */\r\n  deleteBackward(): void {\r\n    if (!this.getIsCanInput()) return\r\n    if (this.deleteSelection()) return\r\n    if (this.deleteAtInvisibleCaret(true)) return\r\n    if (!this.range.isCollapsed() || this.deleteControlBoundary(true)) return\r\n    if (this.deleteHyperlinkCharacter(true)) return\r\n    if (this.draw.getOptions().trackChanges) {\r\n      this.deleteTrackedCharacter(true)\r\n      return\r\n    }\r\n    const pos = this.range.getFocus()\r\n    if (!pos) return\r\n    const doc = this.draw.getActiveDocument()\r\n    const node = getByPath(doc.elements, pos.path)\r\n    if (!node) return\r\n    if (this.deleteAtomicAtCaret(doc, pos)) return\r\n    if (pos.offset === 0) {\r\n      const listPath = this.getListPath(doc.elements, pos.path)\r\n      if (listPath) {\r\n        const list = getByPath(doc.elements, listPath) as IListElement\r\n        const childIndex = Number(pos.path[listPath.length + 1])\r\n        const atStart = isSamePath(pos.path, listPath) || (\r\n          pos.path.length === listPath.length + 2 &&\r\n          pos.path[listPath.length] === 'valueList' &&\r\n          list.valueList.slice(0, childIndex).every(child =>\r\n            child.extension?.bookmarkMarker || (child.type === 'text' && child.value === '')\r\n          )\r\n        )\r\n        if (atStart) {\r\n          this.setList(null, null)\r\n          return\r\n        }\r\n      }\r\n    }\r\n    if (node.type === 'text') {\r\n      const t = node as ITextElement\r\n      if (pos.offset > 0) {\r\n        t.value = t.value.slice(0, pos.offset - 1) + t.value.slice(pos.offset)\r\n        this.updateBookmarksAfterDeletion(doc,\r\n          { path: pos.path, offset: pos.offset - 1 }, pos)\r\n        this.range.setCaret({ path: pos.path.slice() as Path, offset: pos.offset - 1 })\r\n        // 不可迁移：多个 _commit 在不同分支\r\n        this._commit(doc, 'text')\r\n      } else {\r\n        // 与前一个 text run 合并\r\n        const parent = getParentContainer(doc.elements, pos.path)\r\n        const idx = pos.path[pos.path.length - 1] as number\r\n        if (parent && idx > 0) {\r\n          let previousIndex = idx - 1\r\n          while (previousIndex >= 0 && this.isInvisibleText(parent[previousIndex])) previousIndex--\r\n          if (previousIndex !== idx - 1) {\r\n            const previous = parent[previousIndex]\r\n            if (previous?.type === 'text' && previous.value.length > 0) {\r\n              const path = [...pos.path.slice(0, -1), previousIndex] as Path\r\n              const offset = previous.value.length - 1\r\n              previous.value = previous.value.slice(0, offset)\r\n              this.updateBookmarksAfterDeletion(doc, { path, offset }, { path, offset: offset + 1 })\r\n              this.range.setCaret({ path, offset })\r\n              this._commit(doc, 'text')\r\n            }\r\n            return\r\n          }\r\n          const prev = parent[idx - 1]\r\n          if (parent === doc.elements && prev && this.isSectionBoundary(prev)) {\r\n            this.removeSectionBoundaries(doc, idx - 1, idx - 1)\r\n            parent.splice(idx - 1, 1)\r\n            this.range.setCaret({ path: [idx - 1], offset: 0 })\r\n            this._commit(doc)\r\n            return\r\n          }\r\n          if (prev && prev.type === 'text') {\r\n            const p = prev as ITextElement\r\n            const newOffset = p.value.length > 0 ? p.value.length - 1 : 0\r\n            if (p.value.length > 0) {\r\n              this.updateBookmarksAfterDeletion(doc,\r\n                { path: [...pos.path.slice(0, -1), idx - 1], offset: p.value.length - 1 },\r\n                { path: [...pos.path.slice(0, -1), idx - 1], offset: p.value.length })\r\n              p.value = p.value.slice(0, -1)\r\n            }\r\n            // 合并 current 到 prev\r\n            const previousPath = [...pos.path.slice(0, -1), idx - 1] as Path\r\n            const prefixLength = p.value.length\r\n            this.mapBookmarkPositions(doc, point => {\r\n              if (isSamePath(point.path, pos.path)) {\r\n                return { path: previousPath, offset: prefixLength + point.offset }\r\n              }\r\n              const depth = pos.path.length - 1\r\n              if (isSamePath(point.path.slice(0, depth), pos.path.slice(0, depth)) &&\r\n                typeof point.path[depth] === 'number' && Number(point.path[depth]) > idx) {\r\n                const path = [...point.path] as Path\r\n                path[depth] = Number(path[depth]) - 1\r\n                return { path, offset: point.offset }\r\n              }\r\n              return point\r\n            })\r\n            p.value += t.value\r\n            parent.splice(idx, 1)\r\n            const newPath = pos.path.slice() as Path\r\n            newPath[newPath.length - 1] = idx - 1\r\n            this.range.setCaret({ path: newPath, offset: newOffset })\r\n            // 不可迁移：多个 _commit 在不同分支\r\n            this._commit(doc, 'text')\r\n          }\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 向前删除一个字符（Delete 行为）。若有选区则删除选区；否则删除光标后一个字符。\r\n   */\r\n  deleteForward(): void {\r\n    if (!this.getIsCanInput()) return\r\n    if (this.deleteSelection()) return\r\n    if (this.deleteAtInvisibleCaret(false)) return\r\n    if (!this.range.isCollapsed() || this.deleteControlBoundary(false)) return\r\n    if (this.deleteHyperlinkCharacter(false)) return\r\n    if (this.draw.getOptions().trackChanges) {\r\n      this.deleteTrackedCharacter(false)\r\n      return\r\n    }\r\n    const pos = this.range.getFocus()\r\n    if (pos && this.deleteAtomicAtCaret(this.draw.getActiveDocument(), pos)) return\r\n    this.execute(doc => {\r\n      const pos = this.range.getFocus()\r\n      if (!pos) return false\r\n      const node = getByPath(doc.elements, pos.path)\r\n      if (!node || node.type !== 'text') return false\r\n      const t = node as ITextElement\r\n      if (pos.offset >= t.value.length) {\r\n        const next = Number(pos.path[0]) + 1\r\n        if (pos.path.length !== 1 || !doc.elements[next] || !this.isSectionBoundary(doc.elements[next])) return false\r\n        this.removeSectionBoundaries(doc, next, next)\r\n        doc.elements.splice(next, 1)\r\n        return\r\n      }\r\n      t.value = t.value.slice(0, pos.offset) + t.value.slice(pos.offset + 1)\r\n      this.updateBookmarksAfterDeletion(doc, pos, { path: pos.path, offset: pos.offset + 1 })\r\n      return\r\n    }, 'text')\r\n  }\r\n\r\n  /** Enter 换段：在当前 text run 内切成两半，第二半为新 run；对普通段落即插入零宽段分隔 */\r\n  splitParagraph(): void {\r\n    if (this.deleteSelection()) return\r\n    this.execute(doc => {\r\n      if (!this.range.isCollapsed()) return false\r\n      this.ensureTextCaret(doc)\r\n      const pos = this.range.getFocus()\r\n      if (!pos) return false\r\n      const node = getByPath(doc.elements, pos.path)\r\n      const parent = getParentContainer(doc.elements, pos.path)\r\n      if (!node || !parent) return false\r\n      if (node.type !== 'text') return false\r\n      const t = node as ITextElement\r\n      const idx = pos.path[pos.path.length - 1] as number\r\n\r\n      const before = t.value.slice(0, pos.offset)\r\n      const after = t.value.slice(pos.offset)\r\n      t.value = before\r\n      // 插入段落分隔标记 + 后半 text\r\n      const sep: ITextElement = { type: 'text', value: '\\u200B' } as ITextElement\r\n      // Splitting must preserve pending revisions and their independent format snapshots.\r\n      const rest: ITextElement = { ...cloneTree(t), value: after }\r\n      parent.splice(idx + 1, 0, sep, rest)\r\n      const newPath = pos.path.slice() as Path\r\n      newPath[newPath.length - 1] = idx + 2\r\n      this.range.setCaret({ path: newPath, offset: 0 })\r\n      return\r\n    }, 'text')\r\n  }\r\n\r\n  /* -------------------- 光标移动 -------------------- */\r\n\r\n  /**\r\n   * 将光标向左移动一位。若已处于 run 起点，则跨 run 向前移动到上一个 text run 末尾。\r\n   */\r\n  moveCaretLeft(): void {\r\n    const pos = this.range.getFocus()\r\n    if (!pos) return\r\n    const doc = this.draw.getActiveDocument()\r\n    if (this.isInvisibleText(getByPath(doc.elements, pos.path))) {\r\n      const previous = this.adjacentInline(doc, pos.path, true)\r\n      if (previous?.node.type === 'text' || (previous && isControl(previous.node))) {\r\n        this.range.setCaret({ path: previous.path, offset: isControl(previous.node) ? 1 : previous.node.value.length })\r\n      }\r\n      return\r\n    }\r\n    if (pos.offset > 0) {\r\n      this.range.setCaret({ path: pos.path.slice() as Path, offset: pos.offset - 1 })\r\n      return\r\n    }\r\n    // 跨 run 向前\r\n    const adjacent = this.adjacentInline(doc, pos.path, true)\r\n    if (adjacent && (this.isHyperlinkRun(doc, pos.path) || this.isHyperlinkRun(doc, adjacent.path)) &&\r\n      (adjacent.node.type === 'text' || isControl(adjacent.node))) {\r\n      this.range.setCaret({ path: adjacent.path, offset: isControl(adjacent.node) ? 1 : adjacent.node.value.length })\r\n      return\r\n    }\r\n    const parent = getParentContainer(doc.elements, pos.path)\r\n    const idx = pos.path[pos.path.length - 1] as number\r\n    if (parent && idx > 0) {\r\n      for (let i = idx - 1; i >= 0; i--) {\r\n        const p = parent[i]\r\n        if (p && !this.isInvisibleText(p) && (p.type === 'text' || isControl(p))) {\r\n          const newPath = pos.path.slice() as Path\r\n          newPath[newPath.length - 1] = i\r\n          const t = p as ITextElement\r\n          this.range.setCaret({ path: newPath, offset: isControl(p) ? 1 : t.value.length })\r\n          return\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 将光标向右移动一位。若已处于 run 末尾，则跨 run 向后移动到下一个 text run 起点。\r\n   */\r\n  moveCaretRight(): void {\r\n    const pos = this.range.getFocus()\r\n    if (!pos) return\r\n    const doc = this.draw.getActiveDocument()\r\n    const node = getByPath(doc.elements, pos.path)\r\n    if (this.isInvisibleText(node)) {\r\n      const next = this.adjacentInline(doc, pos.path, false)\r\n      if (next?.node.type === 'text' || (next && isControl(next.node))) {\r\n        this.range.setCaret({ path: next.path, offset: 0 })\r\n      }\r\n      return\r\n    }\r\n    if (node && isControl(node) && pos.offset === 0) {\r\n      this.range.setCaret({ path: pos.path.slice() as Path, offset: 1 })\r\n      return\r\n    }\r\n    if (node && node.type === 'text') {\r\n      const t = node as ITextElement\r\n      if (pos.offset < t.value.length) {\r\n        this.range.setCaret({ path: pos.path.slice() as Path, offset: pos.offset + 1 })\r\n        return\r\n      }\r\n    }\r\n    // 跨 run 向后\r\n    const adjacent = this.adjacentInline(doc, pos.path, false)\r\n    if (adjacent && (this.isHyperlinkRun(doc, pos.path) || this.isHyperlinkRun(doc, adjacent.path)) &&\r\n      (adjacent.node.type === 'text' || isControl(adjacent.node))) {\r\n      this.range.setCaret({ path: adjacent.path, offset: 0 })\r\n      return\r\n    }\r\n    const parent = getParentContainer(doc.elements, pos.path)\r\n    const idx = pos.path[pos.path.length - 1] as number\r\n    if (parent && idx < parent.length - 1) {\r\n      for (let i = idx + 1; i < parent.length; i++) {\r\n        const p = parent[i]\r\n        if (p && !this.isInvisibleText(p) && (p.type === 'text' || isControl(p))) {\r\n          const newPath = pos.path.slice() as Path\r\n          newPath[newPath.length - 1] = i\r\n          this.range.setCaret({ path: newPath, offset: 0 })\r\n          return\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  /* -------------------- 段落属性 -------------------- */\r\n\r\n  /**\r\n   * 设置当前段落的行弹性对齐方式。\r\n   * @param flex 对齐方式：'left' | 'center' | 'right' | 'justify' | 'alignment' | 'distribute'\r\n   */\r\n  setRowFlex(flex: 'left' | 'center' | 'right' | 'justify' | 'alignment' | 'distribute'): void {\r\n    this.execute(doc => {\r\n      const ordered = this.range.getOrdered()\r\n      const pos = ordered?.start ?? this.range.getFocus()\r\n      if (!pos) return false\r\n      const parent = getParentContainer(doc.elements, pos.path)\r\n      if (!parent) return false\r\n      const cursorIdx = pos.path[pos.path.length - 1] as number\r\n      const groups = splitParagraphs(parent)\r\n      for (const g of groups) {\r\n        if (cursorIdx < g.start || cursorIdx >= g.end) continue\r\n        this.formatElements(g.block ? [g.block, ...g.runs] : g.runs, r => { r.rowFlex = flex })\r\n        return\r\n      }\r\n      return false\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 设置当前段落的行高及行高规则。\r\n   * @param lh 行高数值\r\n   * @param rule 行高规则，默认 'auto'\r\n   */\r\n  setLineHeight(lh: number, rule: 'auto' | 'exact' | 'atLeast' = 'auto'): void {\r\n    this.execute(doc => {\r\n      const pos = this.range.getFocus()\r\n      if (!pos) return false\r\n      const parent = getParentContainer(doc.elements, pos.path)\r\n      if (!parent) return false\r\n      const cursorIdx = pos.path[pos.path.length - 1] as number\r\n      const groups = splitParagraphs(parent)\r\n      for (const g of groups) {\r\n        if (cursorIdx < g.start || cursorIdx >= g.end) continue\r\n        const targets = g.block ? [g.block, ...g.runs] : g.runs\r\n        this.formatElements(targets, r => {\r\n          const any = r as unknown as Record<string, unknown>\r\n          any.lineHeight = lh\r\n          any.lineHeightRule = rule\r\n        })\r\n        return\r\n      }\r\n      return false\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 段间距（前后各 margin）。\r\n   * @param margin 段前段后间距数值\r\n   */\r\n  setRowMargin(margin: number): void {\r\n    this.execute(doc => {\r\n      const pos = this.range.getFocus()\r\n      if (!pos) return false\r\n      const parent = getParentContainer(doc.elements, pos.path)\r\n      if (!parent) return false\r\n      const cursorIdx = pos.path[pos.path.length - 1] as number\r\n      const groups = splitParagraphs(parent)\r\n      for (const g of groups) {\r\n        if (cursorIdx < g.start || cursorIdx >= g.end) continue\r\n        const targets = g.block ? [g.block, ...g.runs] : g.runs\r\n        this.formatElements(targets, r => {\r\n          const any = r as unknown as Record<string, unknown>\r\n          any.paragraphSpacingBefore = margin\r\n          any.paragraphSpacingAfter = margin\r\n        })\r\n        return\r\n      }\r\n      return false\r\n    })\r\n  }\r\n\r\n  /* -------------------- run 样式 -------------------- */\r\n\r\n  /**\r\n   * 设置选区内 run 的加粗样式。\r\n   * @param bold 是否加粗，省略时为切换语义\r\n   */\r\n  setBold(bold?: boolean): void {\r\n    this.mutateRuns(run => { run.bold = bold }, 'bold')\r\n  }\r\n  /**\r\n   * 设置选区内 run 的斜体样式。\r\n   * @param italic 是否斜体，省略时为切换语义\r\n   */\r\n  setItalic(italic?: boolean): void {\r\n    this.mutateRuns(run => { run.italic = italic }, 'italic')\r\n  }\r\n  /**\r\n   * 设置选区内 run 的文字颜色。\r\n   * @param color 颜色值字符串\r\n   */\r\n  setColor(color: string): void {\r\n    this.mutateRuns(run => { (run as unknown as Record<string, unknown>).color = color })\r\n  }\r\n  /**\r\n   * 设置选区内 run 的字体。\r\n   * @param font 字体名称\r\n   */\r\n  setFont(font: string): void {\r\n    this.mutateRuns(run => { (run as unknown as Record<string, unknown>).font = font })\r\n  }\r\n  /**\r\n   * 设置选区内 run 的字号。\r\n   * @param size 字号数值\r\n   */\r\n  setSize(size: number): void {\r\n    this.mutateRuns(run => { (run as unknown as Record<string, unknown>).size = size })\r\n  }\r\n  /** 增大选区内 run 的字号（步进 2，上限 72）。 */\r\n  setSizeAdd(): void {\r\n    this.mutateRuns(run => { run.size = Math.min(72, (run.size ?? 14) + 2) })\r\n  }\r\n  /** 减小选区内 run 的字号（步进 2，下限 8）。 */\r\n  setSizeMinus(): void {\r\n    this.mutateRuns(run => { run.size = Math.max(8, (run.size ?? 14) - 2) })\r\n  }\r\n  /**\r\n   * 设置选区内 run 的高亮颜色。\r\n   * @param color 高亮颜色值\r\n   */\r\n  setHighlight(color: string): void {\r\n    this.mutateRuns(run => { (run as unknown as Record<string, unknown>).highlight = color })\r\n  }\r\n  /**\r\n   * 设置选区内 run 的删除线。\r\n   * @param v 是否显示删除线，省略时为切换语义\r\n   */\r\n  setStrikeout(v?: boolean): void {\r\n    this.mutateRuns(run => { (run as unknown as Record<string, unknown>).strikeout = v }, 'strikeout')\r\n  }\r\n  /** 设置选区内 run 的双删除线 */\r\n  setDoubleStrikeout(v?: boolean): void {\r\n    this.mutateRuns(run => { (run as unknown as Record<string, unknown>).doubleStrikeout = v })\r\n  }\r\n  /** 设置选区内 run 的隐藏属性 */\r\n  setHidden(v?: boolean): void {\r\n    this.mutateRuns(run => { (run as unknown as Record<string, unknown>).hidden = v })\r\n  }\r\n  /**\r\n   * 设置选区内 run 的下划线。\r\n   * @param v 是否显示下划线，省略时为切换语义\r\n   */\r\n  setUnderline(v?: boolean): void {\r\n    this.mutateRuns(run => { (run as unknown as Record<string, unknown>).underline = v }, 'underline')\r\n  }\r\n\r\n  /** 清除当前选区所有 run 的字符格式 */\r\n  clearFormat(): void {\r\n    this.mutateRuns(run => {\r\n      run.bold = undefined\r\n      run.italic = undefined\r\n      run.underline = undefined\r\n      run.strikeout = undefined\r\n      run.color = undefined\r\n      run.highlight = undefined\r\n      run.font = undefined\r\n      run.size = undefined\r\n    })\r\n  }\r\n\r\n  /** 格式刷：首次调用复制当前 run 格式，二次调用应用到当前 run */\r\n  paintFormat(): void {\r\n    if (!this.getIsCanInput()) return\r\n    if (this._paintFmt) {\r\n      this.mutateRun(run => {\r\n        Object.assign(run, this._paintFmt)\r\n      })\r\n      this._paintFmt = null\r\n    } else {\r\n      const pos = this.range.getFocus()\r\n      if (!pos) return\r\n      const doc = this.draw.getActiveDocument()\r\n      const node = getByPath(doc.elements, pos.path)\r\n      if (!node || node.type !== 'text') return\r\n      const t = node as ITextElement\r\n      this._paintFmt = {\r\n        bold: t.bold, italic: t.italic, underline: t.underline,\r\n        strikeout: t.strikeout, color: t.color, highlight: t.highlight,\r\n        font: t.font, size: t.size\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 对当前光标所在的 text run 执行变更并提交。\r\n   * @param fn 对目标 run 的变更函数\r\n   */\r\n  private mutateRun(fn: (run: ITextElement) => void): void {\r\n    this.mutateRuns(fn)\r\n  }\r\n\r\n  /**\r\n   * 选区感知的 run 变更：折叠时改当前 run，展开时改选区内所有 run。\r\n   * toggleKey 传入时：若 value 为 undefined 则按\"选区内任一 run 未设置 → 全设 true，全已设 → 全取消\"toggle。\r\n   */\r\n  private mutateRuns(fn: (run: ITextElement) => void, toggleKey?: keyof ITextElement): void {\r\n    if (!this.getIsCanInput()) return\r\n    const doc = this.draw.getActiveDocument()\r\n    const ordered = this.range.getOrdered()\r\n    if (!ordered) return\r\n    const { start, end } = ordered\r\n    const collapsed = this.range.isCollapsed()\r\n    const adjusted = collapsed ? { start, end } : this.splitBoundaryRuns(doc, start, end)\r\n    this.range.setRange({ anchor: adjusted.start, focus: adjusted.end })\r\n    const node = collapsed ? getByPath(doc.elements, start.path) : null\r\n    const selectedRuns: IElement[] = []\r\n    if (collapsed) {\r\n      if (node && (node.type === 'text' || isControl(node))) selectedRuns.push(node)\r\n    } else {\r\n      walkTree(doc.elements, (element, { path }) => {\r\n        if (element.type !== 'text' && !isControl(element)) return\r\n        const length = isControl(element) ? 1 : element.value.length\r\n        if (comparePosition({ path, offset: length }, adjusted.start) > 0 &&\r\n          comparePosition({ path, offset: 0 }, adjusted.end) < 0 && !element.extension?.bookmarkMarker) {\r\n          selectedRuns.push(element)\r\n        }\r\n        if (isControl(element)) return false\r\n        return undefined\r\n      })\r\n    }\r\n    const runs = selectedRuns.filter(run => (run as ITextElement).revisionType !== 'delete')\r\n    if (!runs.length) return\r\n    const allSet = toggleKey ? runs.every(r => Boolean((r as ITextElement)[toggleKey])) : false\r\n    const format = {} as ITextElement\r\n    fn(format)\r\n    const changedKeys = CONTROL_FORMAT_KEYS.filter(key => Object.prototype.hasOwnProperty.call(format, key))\r\n    this.formatElements(runs, element => {\r\n      const run = element as ITextElement\r\n      fn(run)\r\n      if (toggleKey && run[toggleKey] === undefined) {\r\n        ;(run as unknown as Record<string, unknown>)[toggleKey] = !allSet\r\n      }\r\n      if (isControl(element) && element.valueList) {\r\n        const children: IElement[] = []\r\n        walkTree(element.valueList, child => {\r\n          if (child.type === 'text' || isControl(child)) children.push(child)\r\n        })\r\n        // 子内容也用于导出；只同步本次命令涉及的样式，保留其他格式。\r\n        this.formatElements(children, child => {\r\n          for (const key of changedKeys) {\r\n            ;(child as unknown as Record<string, unknown>)[key] = run[key]\r\n          }\r\n        })\r\n      }\r\n    })\r\n    // 不可迁移：多个分支各自 commit\r\n    this._commit(doc)\r\n  }\r\n\r\n  /** 删除范围书签的全部文字后移除它，并同步调整保留书签的端点。 */\r\n  private updateBookmarksAfterDeletion(doc: IDocxDocumentMeta, start: IPosition, end: IPosition, mergeRuns = false): void {\r\n    if (doc.elements !== this.draw.getDocument().elements || !doc.bookmarks?.length) return\r\n    const sameRun = isSamePath(start.path, end.path)\r\n    const removedLength = end.offset - start.offset\r\n    const sameParent = mergeRuns && start.path.length === end.path.length &&\r\n      isSamePath(start.path.slice(0, -1), end.path.slice(0, -1))\r\n    doc.bookmarks = doc.bookmarks.filter(bookmark => {\r\n      const { anchor, focus } = bookmark.range\r\n      const [first, last] = comparePosition(anchor, focus) <= 0 ? [anchor, focus] : [focus, anchor]\r\n      const isRange = !bookmark.collapsed && comparePosition(first, last) < 0\r\n      if (isRange && comparePosition(start, first) <= 0 && comparePosition(last, end) <= 0) {\r\n        return false\r\n      }\r\n      const map = (point: IPosition): IPosition => {\r\n        if (sameRun) {\r\n          if (!isSamePath(point.path, start.path) || point.offset <= start.offset) return point\r\n          return { path: point.path, offset: point.offset < end.offset ? start.offset : point.offset - removedLength }\r\n        }\r\n        if (!sameParent) {\r\n          if (isSamePath(point.path, start.path) && point.offset > start.offset) {\r\n            return { path: point.path, offset: start.offset }\r\n          }\r\n          if (isSamePath(point.path, end.path)) {\r\n            return { path: point.path, offset: Math.max(0, point.offset - end.offset) }\r\n          }\r\n          return point\r\n        }\r\n        if (comparePosition(point, start) <= 0) return point\r\n        if (comparePosition(point, end) <= 0) return { path: [...start.path], offset: start.offset }\r\n        if (isSamePath(point.path, end.path)) {\r\n          return { path: [...start.path], offset: start.offset + point.offset - end.offset }\r\n        }\r\n        const depth = start.path.length - 1\r\n        if (isSamePath(point.path.slice(0, depth), start.path.slice(0, depth)) &&\r\n          typeof point.path[depth] === 'number' && Number(point.path[depth]) > Number(end.path[depth])) {\r\n          const path = [...point.path] as Path\r\n          path[depth] = Number(path[depth]) - Number(end.path[depth]) + Number(start.path[depth])\r\n          return { path, offset: point.offset }\r\n        }\r\n        return point\r\n      }\r\n      bookmark.range = { anchor: map(anchor), focus: map(focus) }\r\n      // 原范围被部分删到零长度时，同样不能留下位置书签。\r\n      if (isRange && comparePosition(bookmark.range.anchor, bookmark.range.focus) === 0) return false\r\n      return true\r\n    })\r\n  }\r\n\r\n  /** Map body bookmark endpoints before notifying layout or recording history. */\r\n  private mapBookmarkPositions(doc: IDocxDocumentMeta, map: (point: IPosition, forward: boolean) => IPosition): void {\r\n    // Header/footer paths belong to a different tree than body bookmarks.\r\n    if (doc.elements !== this.draw.getDocument().elements) return\r\n    for (const bookmark of doc.bookmarks ?? []) {\r\n      const { anchor, focus } = bookmark.range\r\n      const order = comparePath(anchor.path, focus.path) || anchor.offset - focus.offset\r\n      bookmark.range = {\r\n        anchor: map(anchor, order <= 0),\r\n        focus: map(focus, order >= 0)\r\n      }\r\n      bookmark.collapsed = isSamePath(bookmark.range.anchor.path, bookmark.range.focus.path) &&\r\n        bookmark.range.anchor.offset === bookmark.range.focus.offset\r\n    }\r\n  }\r\n\r\n  /** Keep offsets and descendant paths aligned when a text run is split. */\r\n  private mapBookmarksAfterSplit(doc: IDocxDocumentMeta, path: Path, offset: number): void {\r\n    const parentPath = path.slice(0, -1)\r\n    const depth = parentPath.length\r\n    const index = path[depth] as number\r\n    this.mapBookmarkPositions(doc, (point, forward) => {\r\n      if (isSamePath(point.path, path)) {\r\n        if (point.offset > offset || (point.offset === offset && forward)) {\r\n          return { path: [...parentPath, index + 1], offset: point.offset - offset }\r\n        }\r\n      } else if (point.path.length > depth &&\r\n        isSamePath(point.path.slice(0, depth), parentPath) &&\r\n        typeof point.path[depth] === 'number' && point.path[depth] > index) {\r\n        const shifted = point.path.slice() as Path\r\n        shifted[depth] = Number(shifted[depth]) + 1\r\n        return { path: shifted, offset: point.offset }\r\n      }\r\n      return point\r\n    })\r\n  }\r\n\r\n  /** Splice body blocks and move bookmarks with them; removed content collapses to the edit boundary. */\r\n  private spliceBodyWithBookmarks(doc: IDocxDocumentMeta, start: number, count: number, elements: IElement[] = []): void {\r\n    doc.elements.splice(start, count, ...elements)\r\n    if (!doc.elements.length) doc.elements.push({ type: 'text', value: '' })\r\n    let boundary: IPosition | undefined\r\n    const removedPosition = (): IPosition => {\r\n      if (!boundary) {\r\n        const index = Math.min(start, doc.elements.length - 1)\r\n        const leaves: { node: IElement; path: Path }[] = []\r\n        walkTree([doc.elements[index]], (node, { path }) => {\r\n          if (node.type !== 'table' && node.type !== 'title' && node.type !== 'list') {\r\n            leaves.push({ node, path: [index, ...path.slice(1)] })\r\n          }\r\n        })\r\n        const leaf = start < doc.elements.length ? leaves[0] : leaves[leaves.length - 1]\r\n        boundary = {\r\n          path: leaf?.path ?? [index],\r\n          offset: start >= doc.elements.length && leaf?.node.type === 'text' && !leaf.node.extension?.bookmarkMarker\r\n            ? leaf.node.value.length : 0\r\n        }\r\n      }\r\n      return { path: [...boundary.path], offset: boundary.offset }\r\n    }\r\n    this.mapBookmarkPositions(doc, point => {\r\n      const index = point.path[0]\r\n      if (typeof index !== 'number' || index < start) return point\r\n      if (index < start + count) return removedPosition()\r\n      return { path: [index + elements.length - count, ...point.path.slice(1)], offset: point.offset }\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 在选区边界拆分 text run，使选区恰好对齐 whole runs。\r\n   * 例：run=\"中国神华本部\"，选 offset 2~6 → 拆成 \"中国\"|\"神华本部\"|\"月度...\"，\r\n   * 返回调整后的 start/end（start 指向 \"神华本部\" offset 0，end 指向它 offset 4）。\r\n   */\r\n  private splitBoundaryRuns(doc: IDocxDocumentMeta, start: IPosition, end: IPosition): { start: IPosition; end: IPosition } {\r\n    let startPath = start.path.slice() as Path\r\n    let startOffset = start.offset\r\n    let endPath = end.path.slice() as Path\r\n    let endOffset = end.offset\r\n    const sameRun = isSamePath(start.path, end.path)\r\n\r\n    // 拆分 start run（start.offset > 0 且 < run.length）\r\n    if (startOffset > 0) {\r\n      const node = getByPath(doc.elements, startPath)\r\n      if (node && node.type === 'text') {\r\n        const t = node as ITextElement\r\n        if (startOffset < t.value.length) {\r\n          const parent = getParentContainer(doc.elements, startPath)\r\n          if (parent) {\r\n            const idx = startPath[startPath.length - 1] as number\r\n            const after = t.value.slice(startOffset)\r\n            t.value = t.value.slice(0, startOffset)\r\n            const second = { ...cloneTree(t), value: after } as ITextElement\r\n            parent.splice(idx + 1, 0, second as IElement)\r\n            this.mapBookmarksAfterSplit(doc, startPath, startOffset)\r\n            startPath = startPath.slice() as Path\r\n            startPath[startPath.length - 1] = idx + 1\r\n            startOffset = 0\r\n            if (sameRun) {\r\n              endPath = startPath.slice() as Path\r\n              endOffset = end.offset - start.offset\r\n            } else {\r\n              const startParent = start.path.slice(0, -1)\r\n              const depth = startParent.length\r\n              if (isSamePath(startParent, endPath.slice(0, depth)) && Number(endPath[depth]) > idx) {\r\n                endPath[depth] = Number(endPath[depth]) + 1\r\n              }\r\n            }\r\n          }\r\n        }\r\n      }\r\n    }\r\n\r\n    // 拆分 end run（end.offset > 0 且 < run.length）\r\n    if (endOffset > 0) {\r\n      const node = getByPath(doc.elements, endPath)\r\n      if (node && node.type === 'text') {\r\n        const t = node as ITextElement\r\n        if (endOffset < t.value.length) {\r\n          const parent = getParentContainer(doc.elements, endPath)\r\n          if (parent) {\r\n            const idx = endPath[endPath.length - 1] as number\r\n            const after = t.value.slice(endOffset)\r\n            t.value = t.value.slice(0, endOffset)\r\n            const second = { ...cloneTree(t), value: after } as ITextElement\r\n            parent.splice(idx + 1, 0, second as IElement)\r\n            this.mapBookmarksAfterSplit(doc, endPath, endOffset)\r\n          }\r\n        }\r\n      }\r\n    }\r\n\r\n    return { start: { path: startPath, offset: startOffset }, end: { path: endPath, offset: endOffset } }\r\n  }\r\n\r\n  /**\r\n   * 收集选区范围内的所有 text run。\r\n   * @param elements 文档元素树\r\n   * @param start 选区起点\r\n   * @param end 选区终点\r\n   * @returns 范围内的 text run 数组\r\n   */\r\n  private collectRunsInRange(elements: IElement[], start: IPosition, end: IPosition): ITextElement[] {\r\n    const runs: { path: Path; node: ITextElement }[] = []\r\n    walkTree(elements, (node, ctx) => {\r\n      if (node.type === 'text') runs.push({ path: ctx.path.slice() as Path, node: node as ITextElement })\r\n    })\r\n    let startIdx = -1, endIdx = -1\r\n    for (let i = 0; i < runs.length; i++) {\r\n      if (startIdx === -1 && isSamePath(runs[i].path, start.path)) startIdx = i\r\n      if (isSamePath(runs[i].path, end.path)) endIdx = i\r\n    }\r\n    if (startIdx === -1 || endIdx === -1) return []\r\n    if (startIdx > endIdx) { const t = startIdx; startIdx = endIdx; endIdx = t }\r\n    return runs.slice(startIdx, endIdx + 1)\r\n      .filter(r => (!isSamePath(r.path, start.path) || start.offset < r.node.value.length) &&\r\n        (!isSamePath(r.path, end.path) || end.offset > 0) && !r.node.extension?.bookmarkMarker)\r\n      .map(r => r.node)\r\n  }\r\n\r\n  /* -------------------- 标题 / 列表 -------------------- */\r\n\r\n  /**\r\n   * 设置选区涉及段落的标题级别，null 表示正文。保留 runs、段落边界和选区。\r\n   * @param level 标题级别，null 表示取消标题\r\n   */\r\n  setTitle(level: ITitleElement['level'] | null): void {\r\n    if (!this.getIsCanInput()) return\r\n    const selection = this.range.getRange()\r\n    const ordered = this.range.getOrdered()\r\n    if (!selection || !ordered) return\r\n    const doc = this.draw.getActiveDocument()\r\n    const targets = new Map<IElement, { parent: IElement[]; start: number; end: number; path: Path }>()\r\n    const collect = (path: Path) => {\r\n      const titlePath = this.getTitlePath(doc.elements, path)\r\n      const targetPath = titlePath ?? path\r\n      const parent = getParentContainer(doc.elements, targetPath)\r\n      if (!parent) return\r\n      const index = targetPath[targetPath.length - 1] as number\r\n      const group = splitParagraphs(parent).find(g => index >= g.start && index < g.end)\r\n      if (!group || (group.kind !== 'normal' && group.kind !== 'title')) return\r\n      targets.set(parent[group.start], {\r\n        parent, start: group.start, end: group.end,\r\n        path: [...targetPath.slice(0, -1), group.start]\r\n      })\r\n    }\r\n    if (this.range.isCollapsed()) {\r\n      collect(selection.focus.path)\r\n    } else {\r\n      walkTree(doc.elements, (node, ctx) => {\r\n        if (node.type !== 'text' && node.type !== 'title') return\r\n        if (node.type === 'title' && (node as ITitleElement).valueList.length\r\n          && !isSamePath(ctx.path, ordered.start.path) && !isSamePath(ctx.path, ordered.end.path)) return\r\n        const fromStart = comparePath(ctx.path, ordered.start.path)\r\n        const fromEnd = comparePath(ctx.path, ordered.end.path)\r\n        if (fromStart >= 0 && (fromEnd < 0 || (fromEnd === 0 && ordered.end.offset > 0))) {\r\n          collect(ctx.path)\r\n        }\r\n      })\r\n    }\r\n    const anchorNode = getByPath(doc.elements, selection.anchor.path)\r\n    const focusNode = getByPath(doc.elements, selection.focus.path)\r\n    const replacements = new Map<IElement, IElement>()\r\n    const isTerminator = (node?: IElement) =>\r\n      node?.type === 'text' && /^[\\u200B\\uFEFF]+$/.test(node.value)\r\n    const options = this.draw.getOptions()\r\n    const textFormat = {\r\n      font: String(options.defaultFont ?? DEFAULT_EDITOR_OPTION.defaultFont),\r\n      size: level === null ? Number(options.defaultSize ?? DEFAULT_EDITOR_OPTION.defaultSize) : HEADING_SIZES[level],\r\n      bold: level !== null\r\n    }\r\n    const formatRuns = (elements: IElement[]) => {\r\n      const runs: IElement[] = []\r\n      walkTree(elements, element => {\r\n        if (element.type === 'text') runs.push(element)\r\n      })\r\n      this.formatElements(runs, element => {\r\n        Object.assign(element, textFormat)\r\n        delete element.paragraphStyleId\r\n      })\r\n    }\r\n    let changed = false\r\n    // Reverse document order keeps pending sibling indices valid after splicing.\r\n    for (const [node, target] of [...targets].sort((a, b) => comparePath(b[1].path, a[1].path))) {\r\n      const { parent, start, end } = target\r\n      if (node.type === 'title') {\r\n        const title = node as ITitleElement\r\n        if (level !== null) {\r\n          title.level = level\r\n          delete title.paragraphStyleId\r\n          formatRuns(title.valueList)\r\n        } else {\r\n          const runs = title.valueList.length ? [...title.valueList] : [{ type: 'text', value: '' } as IElement]\r\n          formatRuns(runs)\r\n          replacements.set(title, runs[0])\r\n          const paragraphKeys = [\r\n            'rowFlex', 'paragraphFirstLineIndent', 'paragraphIndentLeft', 'paragraphIndentRight',\r\n            'paragraphSpacingBefore', 'paragraphSpacingAfter', 'lineHeight', 'lineHeightRule'\r\n          ] as const\r\n          for (const run of runs) {\r\n            for (const key of paragraphKeys) {\r\n              if (title[key] !== undefined) Object.assign(run, { [key]: title[key] })\r\n            }\r\n            delete run.paragraphStyleId\r\n          }\r\n          // A title is a block boundary; unwrapping must not merge adjacent paragraphs.\r\n          if (!isTerminator(runs[runs.length - 1])) runs.push({ type: 'text', value: '\\u200B' })\r\n          const previous = splitParagraphs(parent).find(g => g.end === start)\r\n          if (previous?.kind === 'normal' && !isTerminator(parent[start - 1])) {\r\n            runs.unshift({ type: 'text', value: '\\u200B' })\r\n          }\r\n          parent.splice(start, 1, ...runs)\r\n        }\r\n      } else {\r\n        if (level === null) continue\r\n        const runs = parent.slice(start, end)\r\n        formatRuns(runs)\r\n        parent.splice(start, end - start, {\r\n          type: 'title', value: '', level, valueList: runs\r\n        })\r\n      }\r\n      changed = true\r\n    }\r\n    if (!changed) return\r\n    const restored = { anchor: selection.anchor, focus: selection.focus }\r\n    walkTree(doc.elements, (node, ctx) => {\r\n      if (node === (anchorNode && (replacements.get(anchorNode) ?? anchorNode))) {\r\n        restored.anchor = { path: ctx.path, offset: selection.anchor.offset }\r\n      }\r\n      if (node === (focusNode && (replacements.get(focusNode) ?? focusNode))) {\r\n        restored.focus = { path: ctx.path, offset: selection.focus.offset }\r\n      }\r\n    })\r\n    this.range.setRange(restored)\r\n    this._commit(doc)\r\n  }\r\n\r\n  /** Resolve the heading container even when the caret is on one of its text runs. */\r\n  private getTitlePath(elements: IElement[], path: Path): Path | null {\r\n    for (let length = path.length; length > 0; length--) {\r\n      if (typeof path[length - 1] !== 'number') continue\r\n      const candidate = path.slice(0, length) as Path\r\n      if (getByPath(elements, candidate)?.type === 'title') return candidate\r\n    }\r\n    return null\r\n  }\r\n\r\n  /** 从指定路径逐级向上查找最近的列表容器路径，未找到时返回 null。 */\r\n  private getListPath(elements: IElement[], path: Path): Path | null {\r\n    for (let length = path.length; length > 0; length--) {\r\n      if (typeof path[length - 1] !== 'number') continue\r\n      const candidate = path.slice(0, length) as Path\r\n      if (getByPath(elements, candidate)?.type === 'list') return candidate\r\n    }\r\n    return null\r\n  }\r\n\r\n  /**\r\n   * 设置或取消列表。\r\n   * @param type 列表类型名\r\n   * @param style 列表样式\r\n   */\r\n  setList(type: ListTypeName | null, style: string | null): void {\r\n    this.execute(doc => {\r\n      const pos = this.range.getFocus()\r\n      if (!pos) return false\r\n      const path = this.getListPath(doc.elements, pos.path) ?? pos.path\r\n      const parent = getParentContainer(doc.elements, path)\r\n      if (!parent) return false\r\n      const idx = path[path.length - 1] as number\r\n      const cur = parent[idx]\r\n      if (!cur) return false\r\n      if (cur.type === 'list' && (!type || !style || (cur.listType === type && cur.listStyle === style))) {\r\n        const valueList = (cur as IListElement).valueList\r\n        const children = valueList.length ? [...valueList] : [{ type: 'text', value: '' } as IElement]\r\n        const groups = splitParagraphs(parent)\r\n        const isTerminator = (element?: IElement) =>\r\n          element?.type === 'text' && /^[\\u200B\\uFEFF]+$/.test(element.value) && !element.extension?.bookmarkMarker\r\n        let leadingSeparator = 0\r\n        // Removing the list container must retain its paragraph boundaries.\r\n        if (groups.some(group => group.kind === 'normal' && group.end === idx) && !isTerminator(parent[idx - 1])) {\r\n          children.unshift({ type: 'text', value: '\\u200B' })\r\n          leadingSeparator = 1\r\n        }\r\n        if (groups.some(group => group.kind === 'normal' && group.start === idx + 1) && !isTerminator(children[children.length - 1])) {\r\n          children.push({ type: 'text', value: '\\u200B' })\r\n        }\r\n        parent.splice(idx, 1, ...children)\r\n        const childIndex = pos.path[path.length] === 'valueList' ? Number(pos.path[path.length + 1]) : 0\r\n        this.range.setCaret({ path: [...path.slice(0, -1), idx + leadingSeparator + childIndex, ...pos.path.slice(path.length + 2)] as Path, offset: pos.offset })\r\n        return\r\n      }\r\n      if (!type || !style) return false\r\n      let list: IListElement\r\n      if (cur.type === 'list') {\r\n        list = cur as IListElement\r\n        list.listType = type\r\n        list.listStyle = style\r\n      } else if (cur.type === 'text') {\r\n        list = { type: 'list', value: '', listType: type, listStyle: style, listLevel: 0, valueList: [cloneTree(cur)] }\r\n        parent[idx] = list\r\n        this.range.setCaret({ path: [...path, 'valueList', 0], offset: pos.offset })\r\n      } else return false\r\n      const bullet = type === 'ul' ? BULLET_STYLES.find(item => item.style === style) : undefined\r\n      const number = type === 'ol' ? NUMBER_STYLES.find(item => item.style === style) : undefined\r\n      const previous = list.listNumbering\r\n      delete list.listNumbering\r\n      if (bullet || number) {\r\n        list.listNumbering = {\r\n          numId: previous?.numId ?? list.listId ?? style,\r\n          abstractNumId: previous?.abstractNumId ?? style,\r\n          level: list.listLevel,\r\n          numFmt: number?.numFmt ?? 'bullet',\r\n          lvlText: number ? number.lvlText.replace('%1', `%${list.listLevel + 1}`) : bullet!.icon,\r\n          start: previous?.start ?? 1,\r\n          indentLeft: previous?.indentLeft ?? list.listIndent ?? 0,\r\n          indentHanging: previous?.indentHanging ?? list.listHanging ?? 0,\r\n          lvlJc: previous?.lvlJc ?? 'left'\r\n        }\r\n      }\r\n      return\r\n    })\r\n  }\r\n\r\n  /* -------------------- 表格 -------------------- */\r\n\r\n  /**\r\n   * 在当前光标处插入表格。\r\n   * @param rows 行数\r\n   * @param cols 列数\r\n   * @param availableWidth 可用宽度，省略时取内容区宽度\r\n   */\r\n  insertTable(rows: number, cols: number, availableWidth?: number): void {\r\n    if (!Number.isInteger(rows) || !Number.isInteger(cols) || rows < 1 || cols < 1) return\r\n    this.deleteSelection(false)\r\n    this.execute(doc => {\r\n      const contentWidth = availableWidth ?? this.getContentWidth()\r\n      const colWidth = contentWidth / cols\r\n      const table: ITableElement = {\r\n        type: 'table',\r\n        value: '',\r\n        colgroup: Array.from({ length: cols }, () => ({ width: colWidth })),\r\n        trList: Array.from({ length: rows }, () => ({\r\n          height: 32,\r\n          tdList: Array.from({ length: cols }, () => ({\r\n            width: colWidth,\r\n            colspan: 1,\r\n            rowspan: 1,\r\n            value: [{ type: 'text', value: '' } as IElement],\r\n            verticalAlign: 'top' as const,\r\n            borderStyle: {\r\n              top: { width: 1, color: '#000', style: 'solid' as const },\r\n              right: { width: 1, color: '#000', style: 'solid' as const },\r\n              bottom: { width: 1, color: '#000', style: 'solid' as const },\r\n              left: { width: 1, color: '#000', style: 'solid' as const }\r\n            },\r\n            padding: [5, 5, 5, 5] as [number, number, number, number]\r\n          }))\r\n        }))\r\n      }\r\n      const path = this.insertBlockAtCaret(doc, table)\r\n      if (!path) return false\r\n      this.range.setCaret({ path: [...path, 'trList', 0, 'tdList', 0, 'value', 0], offset: 0 })\r\n      return\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 获取当前光标所在的表格上下文信息。\r\n   * @returns 包含 doc/table/tableIndex/trIndex/tdIndex 的对象；光标不在表格内时返回 null\r\n   */\r\n  private getTableContext(position?: IPosition): { doc: IDocxDocumentMeta; table: ITableElement; tableIndex: number; trIndex: number; tdIndex: number } | null {\n    const pos = position ?? this.range.getFocus()\n    if (!pos) return null\r\n    const p = pos.path\r\n    if (p.length < 5 || p[1] !== 'trList' || p[3] !== 'tdList') return null\r\n    const doc = this.draw.getActiveDocument()\r\n    const tableIndex = p[0] as number\r\n    const trIndex = p[2] as number\r\n    const tdIndex = p[4] as number\r\n    const table = doc.elements[tableIndex]\r\n    if (!table || table.type !== 'table') return null\r\n    return { doc, table: table as ITableElement, tableIndex, trIndex, tdIndex }\r\n  }\r\n\n  /** 按表格网格占用关系计算单元格起始列，兼容跨行、跨列合并。 */\n  private getLogicalColumnIndex(table: ITableElement, targetRow: number, targetCell: number): number | null {\n    const columnCount = table.colgroup.length\n    if (!columnCount) return null\n    const occupied = table.trList.map(() => new Array(columnCount).fill(false))\n    for (let ri = 0; ri <= targetRow; ri++) {\n      const row = table.trList[ri]\n      if (!row) return null\n      let column = 0\n      for (let ci = 0; ci < row.tdList.length; ci++) {\n        while (column < columnCount && occupied[ri][column]) column++\n        if (column >= columnCount) break\n        const cell = row.tdList[ci]\n        if (ri === targetRow && ci === targetCell) return column\n        const colspan = Math.max(1, Number(cell.colspan) || 1)\n        const rowspan = Math.max(1, Number(cell.rowspan) || 1)\n        for (let rr = ri; rr < Math.min(ri + rowspan, table.trList.length); rr++) {\n          for (let cc = column; cc < Math.min(column + colspan, columnCount); cc++) {\n            if (rr !== ri || cc !== column) occupied[rr][cc] = true\n          }\n        }\n        column += colspan\n      }\n    }\n    return null\n  }\n\r\n  /**\r\n   * 创建一个空的表格单元格。\r\n   * @param width 单元格宽度\r\n   * @returns 空单元格对象\r\n   */\r\n  private makeEmptyTd(width: number): ITd {\r\n    return {\r\n      width,\r\n      colspan: 1,\r\n      rowspan: 1,\r\n      value: [{ type: 'text', value: '' } as IElement],\r\n      verticalAlign: 'top' as const,\r\n      borderStyle: {\r\n        top: { width: 1, color: '#000', style: 'solid' as const },\r\n        right: { width: 1, color: '#000', style: 'solid' as const },\r\n        bottom: { width: 1, color: '#000', style: 'solid' as const },\r\n        left: { width: 1, color: '#000', style: 'solid' as const }\r\n      },\r\n      padding: [5, 5, 5, 5] as [number, number, number, number]\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 在当前行上方或下方插入指定数量的表格行。\r\n   * @param position 插入位置：'above' | 'below'\r\n   * @param count 插入行数，默认 1\r\n   */\r\n  insertTableRow(position: 'above' | 'below', count = 1): void {\r\n    this.execute(_doc => {\r\n      const ctx = this.getTableContext()\r\n      if (!ctx) return false\r\n      const { table, trIndex } = ctx\r\n      const insertAt = position === 'above' ? trIndex : trIndex + 1\r\n      for (let i = 0; i < count; i++) {\r\n        const newRow = cloneTree(table.trList[trIndex])\r\n        for (const td of newRow.tdList) {\r\n          td.value = [{ type: 'text', value: '' } as IElement]\r\n        }\r\n        table.trList.splice(insertAt + i, 0, newRow)\r\n      }\r\n      return\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 在当前列左侧或右侧插入指定数量的表格列，并重新均分列宽。\r\n   * @param position 插入位置：'left' | 'right'\r\n   * @param count 插入列数，默认 1\r\n   */\r\n  insertTableCol(position: 'left' | 'right', count = 1): void {\r\n    this.execute(_doc => {\r\n      const ctx = this.getTableContext()\r\n      if (!ctx) return false\r\n      const { table, tdIndex } = ctx\r\n      const totalWidth = table.colgroup.reduce((s, c) => s + c.width, 0)\r\n      const newColCount = table.colgroup.length + count\r\n      const colWidth = totalWidth / newColCount\r\n      const insertAt = position === 'left' ? tdIndex : tdIndex + 1\r\n      for (let i = 0; i < count; i++) {\r\n        for (const tr of table.trList) {\r\n          const newTd = this.makeEmptyTd(colWidth)\r\n          tr.tdList.splice(insertAt + i, 0, newTd)\r\n        }\r\n        table.colgroup.splice(insertAt + i, 0, { width: colWidth })\r\n      }\r\n      for (const tr of table.trList) {\r\n        for (const td of tr.tdList) td.width = colWidth\r\n      }\r\n      for (const c of table.colgroup) c.width = colWidth\r\n      return\r\n    })\r\n  }\r\n\r\n  /** 删除当前表格行（至少保留一行）。 */\r\n  deleteTableRow(): void {\r\n    this.execute(_doc => {\r\n      const ctx = this.getTableContext()\r\n      if (!ctx) return false\r\n      const { table, trIndex } = ctx\r\n      if (table.trList.length <= 1) return false\r\n      table.trList.splice(trIndex, 1)\r\n      return\r\n    })\r\n  }\r\n\r\n  /** 删除当前表格列（至少保留一列）。 */\r\n  deleteTableCol(): void {\r\n    this.execute(_doc => {\r\n      const ctx = this.getTableContext()\r\n      if (!ctx) return false\r\n      const { table, tdIndex } = ctx\r\n      if (table.trList[0].tdList.length <= 1) return false\r\n      for (const tr of table.trList) {\r\n        tr.tdList.splice(tdIndex, 1)\r\n      }\r\n      table.colgroup.splice(tdIndex, 1)\r\n      return\r\n    })\r\n  }\r\n\r\n  /** 将当前单元格拆分为两个单元格，并均分原列宽。 */\r\n  splitTableCell(): void {\r\n    this.execute(_doc => {\r\n      const ctx = this.getTableContext()\r\n      if (!ctx) return false\r\n      const { table, trIndex, tdIndex } = ctx\r\n      const td = table.trList[trIndex].tdList[tdIndex]\r\n      const newTd = this.makeEmptyTd(td.width)\r\n      table.trList[trIndex].tdList.splice(tdIndex + 1, 0, newTd)\r\n      const colWidth = td.width / 2\r\n      td.width = colWidth\r\n      newTd.width = colWidth\r\n      if (table.colgroup[tdIndex]) {\r\n        const totalWidth = table.colgroup[tdIndex].width\r\n        table.colgroup.splice(tdIndex, 1, { width: colWidth }, { width: totalWidth - colWidth })\r\n      }\r\n      return\r\n    })\r\n  }\r\n\r\n  /** 选中当前表格的全部内容。 */\r\n  selectTable(): void {\r\n    const ctx = this.getTableContext()\r\n    if (!ctx) return\r\n    const { table, tableIndex } = ctx\r\n    const firstTr = table.trList[0]\r\n    const lastTr = table.trList[table.trList.length - 1]\r\n    if (!firstTr || !lastTr) return\r\n    const anchor: IPosition = { path: [tableIndex, 'trList', 0, 'tdList', 0, 'value', 0], offset: 0 }\r\n    const lastTdIdx = lastTr.tdList.length - 1\r\n    const lastValue = lastTr.tdList[lastTdIdx].value\r\n    const lastIdx = lastValue.length - 1\r\n    const lastEl = lastValue[lastIdx]\r\n    const focus: IPosition = {\r\n      path: [tableIndex, 'trList', table.trList.length - 1, 'tdList', lastTdIdx, 'value', lastIdx],\r\n      offset: lastEl && typeof (lastEl as { value?: unknown }).value === 'string' ? String((lastEl as { value: string }).value).length : 1\r\n    }\r\n    this.range.setRange({ anchor, focus })\r\n  }\r\n\r\n  /** 合并选区内单元格 */\r\n  mergeTableCells(): void {\r\n    this.execute(_doc => {\r\n      const ctx = this.getTableContext()\r\n      if (!ctx) return false\r\n      const { table } = ctx\r\n\r\n      const ordered = this.range.getOrdered()\r\n      if (!ordered) return false\r\n      const { start, end } = ordered\r\n      if (start.path.length < 5 || end.path.length < 5) return false\r\n      if (start.path[0] !== end.path[0]) return false\r\n\r\n      const minRow = Math.min(start.path[2] as number, end.path[2] as number)\r\n      const maxRow = Math.max(start.path[2] as number, end.path[2] as number)\r\n      const minCol = Math.min(start.path[4] as number, end.path[4] as number)\r\n      const maxCol = Math.max(start.path[4] as number, end.path[4] as number)\r\n\r\n      if (minRow === maxRow && minCol === maxCol) return false\r\n\r\n      const firstTd = table.trList[minRow]?.tdList[minCol]\r\n      if (!firstTd) return false\r\n\r\n      const allContent: IElement[] = []\r\n      for (let r = minRow; r <= maxRow; r++) {\r\n        for (let c = minCol; c <= maxCol; c++) {\r\n          const td = table.trList[r]?.tdList[c]\r\n          if (td && !td.merged) {\r\n            for (const el of td.value) allContent.push(el)\r\n          }\r\n        }\r\n      }\r\n\r\n      firstTd.colspan = maxCol - minCol + 1\r\n      firstTd.rowspan = maxRow - minRow + 1\r\n      firstTd.value = allContent.length > 0 ? allContent : [{ type: 'text', value: '' } as IElement]\r\n      firstTd.width = table.colgroup.slice(minCol, maxCol + 1).reduce((s, c) => s + c.width, 0)\r\n\r\n      for (let r = minRow; r <= maxRow; r++) {\r\n        for (let c = minCol; c <= maxCol; c++) {\r\n          if (r === minRow && c === minCol) continue\r\n          const td = table.trList[r]?.tdList[c]\r\n          if (td) {\r\n            td.merged = true\r\n            td.value = []\r\n          }\r\n        }\r\n      }\r\n      return\r\n    })\r\n  }\r\n\r\n  /** 删除整个表格 */\r\n  deleteTable(): void {\r\n    this.execute(doc => {\r\n      const ctx = this.getTableContext()\r\n      if (!ctx) return false\r\n      const { tableIndex } = ctx\r\n      doc.elements.splice(tableIndex, 1)\r\n      return\r\n    })\r\n  }\r\n\r\n  /** 获取当前单元格的垂直对齐与底纹颜色（默认顶部对齐、空颜色），无单元格时返回 null。 */\r\n  getCellProperties(position?: IPosition) {\n    const ctx = this.getTableContext(position)\n    const cell = ctx?.table.trList[ctx.trIndex]?.tdList[ctx.tdIndex]\r\n    return cell ? {\n      verticalAlign: cell.verticalAlign ?? 'top',\n      backgroundColor: cell.backgroundColor ?? '',\n      textDirection: cell.textDirection,\n      paddingTop: cell.padding?.[0] ?? 5,\n      paddingRight: cell.padding?.[1] ?? 5,\n      paddingBottom: cell.padding?.[2] ?? 5,\n      paddingLeft: cell.padding?.[3] ?? 5\n    } : null\n  }\r\n\r\n  /** 获取目标行高和重复表头状态。 */\n  getTableRowProperties(position?: IPosition) {\n    const ctx = this.getTableContext(position)\n    const row = ctx?.table.trList[ctx.trIndex]\n    return row ? { height: row.height, pagingRepeat: Boolean(row.pagingRepeat) } : null\n  }\n\n  /** 获取目标单元格起始列的宽度及跨列信息。 */\n  getTableColumnProperties(position?: IPosition) {\n    const ctx = this.getTableContext(position)\n    if (!ctx) return null\n    const cell = ctx.table.trList[ctx.trIndex]?.tdList[ctx.tdIndex]\n    const index = this.getLogicalColumnIndex(ctx.table, ctx.trIndex, ctx.tdIndex)\n    if (!cell || index == null) return null\n    return {\n      index,\n      width: ctx.table.colgroup[index]?.width ?? cell.width,\n      colspan: Math.max(1, Number(cell.colspan) || 1)\n    }\n  }\n\n  /** 设置当前单元格垂直对齐 */\r\n  setCellVerticalAlign(align: VerticalAlign): void {\r\n    this.execute(_doc => {\r\n      const ctx = this.getTableContext()\r\n      if (!ctx) return false\r\n      const { table, trIndex, tdIndex } = ctx\r\n      const td = table.trList[trIndex]?.tdList[tdIndex]\r\n      if (!td) return false\r\n      td.verticalAlign = align\r\n      return\r\n    })\r\n  }\r\n\r\n  /** 设置指定单元格的文字方向；默认修改当前光标所在单元格。 */\n  setCellTextDirection(direction: CellTextDirection, position?: IPosition): void {\n    this.execute(_doc => {\n      const ctx = this.getTableContext(position)\n      if (!ctx) return false\n      const td = ctx.table.trList[ctx.trIndex]?.tdList[ctx.tdIndex]\n      if (!td || td.textDirection === direction) return false\n      td.textDirection = direction\n      return\n    })\n  }\n\n  /** 设置指定单元格的四边内边距；默认修改当前光标所在单元格。 */\n  setCellPadding(padding: ITd['padding'], position?: IPosition): void {\n    this.execute(_doc => {\n      const ctx = this.getTableContext(position)\n      if (!ctx) return false\n      const td = ctx.table.trList[ctx.trIndex]?.tdList[ctx.tdIndex]\n      if (!td) return false\n      const next = padding.map(value => Math.max(0, Math.round(Number(value) || 0))) as ITd['padding']\n      if (td.padding?.every((value, index) => value === next[index])) return false\n      td.padding = next\n      return\n    })\n  }\n\n  /** 设置当前单元格底纹颜色 */\r\n  setCellBackground(color: string): void {\r\n    this.execute(_doc => {\r\n      const ctx = this.getTableContext()\r\n      if (!ctx) return false\r\n      const { table, trIndex, tdIndex } = ctx\r\n      const td = table.trList[trIndex]?.tdList[tdIndex]\r\n      if (!td) return false\r\n      td.backgroundColor = color\r\n      return\r\n    })\r\n  }\r\n\r\n  /** 切换当前行重复表头 */\r\n  toggleRepeatHeader(position?: IPosition): void {\n    this.execute(_doc => {\r\n      const ctx = this.getTableContext(position)\n      if (!ctx) return false\r\n      const { table, trIndex } = ctx\r\n      const tr = table.trList[trIndex]\r\n      if (!tr) return false\r\n      tr.pagingRepeat = !tr.pagingRepeat\r\n      return\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 设置指定表格列的宽度。\r\n   * @param tableIndex 表格索引\r\n   * @param colIndex 列索引\r\n   * @param width 列宽\r\n   */\r\n  setTableColWidth(tableIndex: number, colIndex: number, width: number): void {\r\n    this.execute(doc => {\n      const table = doc.elements[tableIndex]\n      if (!table || table.type !== 'table') return false\n      const t = table as ITableElement\n      if (!Number.isFinite(width) || colIndex < 0 || colIndex >= t.colgroup.length) return false\n      const widthValue = Math.max(20, Math.round(width))\n      if (t.colgroup[colIndex].width === widthValue) return false\n      t.colgroup[colIndex].width = widthValue\n      for (let ri = 0; ri < t.trList.length; ri++) {\n        const row = t.trList[ri]\n        for (let ci = 0; ci < row.tdList.length; ci++) {\n          const td = row.tdList[ci]\n          const startColumn = this.getLogicalColumnIndex(t, ri, ci)\n          if (startColumn == null || td.merged) continue\n          const span = Math.max(1, Number(td.colspan) || 1)\n          if (colIndex < startColumn || colIndex >= startColumn + span) continue\n          td.width = t.colgroup.slice(startColumn, startColumn + span)\n            .reduce((sum, column) => sum + column.width, 0)\n        }\n      }\n      return\n    })\n  }\r\n\r\n  /**\r\n   * 设置指定表格行的高度。\r\n   * @param tableIndex 表格索引\r\n   * @param rowIndex 行索引\r\n   * @param height 行高\r\n   */\r\n  setTableRowHeight(tableIndex: number, rowIndex: number, height: number): void {\r\n    this.execute(doc => {\n      const table = doc.elements[tableIndex]\n      if (!table || table.type !== 'table' || !Number.isFinite(height)) return false\n      const targetRow = (table as ITableElement).trList[rowIndex]\n      if (!targetRow) return false\n      const nextHeight = Math.max(20, Math.round(height))\n      if (targetRow.height === nextHeight) return false\n      targetRow.height = nextHeight\n      return\n    })\n  }\r\n\r\n  /* -------------------- 图片 / 分页 -------------------- */\r\n\r\n  /**\r\n   * 在当前光标处插入图片。\r\n   * @param src 图片源，可以是 URL 字符串或包含 value/width/height 的对象\r\n   * @param width 宽度，当 src 为字符串时生效，默认 200\r\n   * @param height 高度，当 src 为字符串时生效，默认 150\r\n   */\r\n  insertImage(src: string | { value: string; width?: number; height?: number }, width?: number, height?: number): void {\r\n    this.deleteSelection(false)\r\n    this.execute(doc => {\r\n      const imgSrc = typeof src === 'string' ? src : src.value\r\n      const w = (typeof src === 'string' ? width : src.width) ?? 200\r\n      const h = (typeof src === 'string' ? height : src.height) ?? 150\r\n      const imgW = Number.isFinite(w) && w > 0 ? w : 200\r\n      const imgH = Number.isFinite(h) && h > 0 ? h : 150\r\n      const bounds = this.getImageInsertionBounds(doc)\r\n      const ratio = Math.min(1, bounds.width / imgW, bounds.height / imgH)\r\n      const img: IElement = { type: 'image', value: imgSrc, width: imgW * ratio, height: imgH * ratio } as unknown as IElement\r\n      const path = this.insertBlockAtCaret(doc, img)\r\n      if (!path) return false\r\n      const parent = getParentContainer(doc.elements, path)!\r\n      const idx = (path[path.length - 1] as number) + 1\r\n      if (parent[idx]?.type !== 'text') parent.splice(idx, 0, { type: 'text', value: '' } as IElement)\r\n      this.range.setCaret({ path: [...path.slice(0, -1), idx], offset: 0 })\r\n      return\r\n    })\r\n  }\r\n\r\n  /** 使用文档坐标限制新图片；单元格高度可增长，但不应超过一页内容区。 */\r\n  private getImageInsertionBounds(doc: IDocxDocumentMeta): { width: number; height: number } {\r\n    const opts = this.draw.getOptions()\r\n    const [mt, mr, mb, ml] = (opts.pageMargins as [number, number, number, number] | undefined)\r\n      ?? DEFAULT_EDITOR_OPTION.pageMargins\r\n    const zone = this.draw.getZone()\r\n    let width = Number(opts.pageWidth ?? DEFAULT_EDITOR_OPTION.pageWidth) - ml - mr\r\n    let height = zone === 'header' ? mt : zone === 'footer' ? mb\r\n      : Number(opts.pageHeight ?? DEFAULT_EDITOR_OPTION.pageHeight) - mt - mb\r\n    const path = this.range.getFocus()?.path ?? []\r\n    const cells = new Map<string, number>()\r\n    const collect = (blocks: BlockNode[]) => {\r\n      for (const block of blocks) {\r\n        if (block.kind !== 'table') continue\r\n        for (const row of block.rows) {\r\n          for (const cell of row.cells) {\r\n            cells.set(JSON.stringify(cell.cellPath), cell.rect.width)\r\n            collect(cell.content)\r\n          }\r\n        }\r\n      }\r\n    }\r\n    for (const page of this.draw.getLayout()?.pages ?? []) {\r\n      collect(zone === 'header' ? page.headerBlocks ?? [] : zone === 'footer' ? page.footerBlocks ?? [] : page.blocks)\r\n    }\r\n    for (let i = 0; i < path.length; i++) {\r\n      if (path[i] !== 'trList' || path[i + 2] !== 'tdList' || path[i + 4] !== 'value') continue\r\n      const table = getByPath(doc.elements, path.slice(0, i) as Path) as ITableElement\r\n      const ri = path[i + 1] as number\r\n      const ci = path[i + 3] as number\r\n      const td = table.trList[ri].tdList[ci]\r\n      let cellWidth = cells.get(JSON.stringify(path.slice(0, i + 4)))\r\n      if (cellWidth === undefined) {\r\n        // 尚未排版时使用与 layoutTable 一致的列宽、合并格占位规则。\r\n        let cols = table.colgroup.map(c => c.width || 0)\r\n        if (!cols.length || cols.every(v => v <= 0)) {\r\n          cols = (table.trList[0]?.tdList ?? []).flatMap(cell =>\r\n            Array.from({ length: cell.colspan || 1 }, () => (cell.width || 0) / (cell.colspan || 1)))\r\n        }\r\n        const total = cols.reduce((sum, v) => sum + v, 0)\r\n        if (total > width * 1.02) cols = cols.map(v => v * width / total)\r\n        else if (total <= 0) {\r\n          const count = Math.max(1, cols.length || (table.trList[0]?.tdList.length ?? 1))\r\n          cols = Array.from({ length: count }, () => width / count)\r\n        }\r\n        const occupied: boolean[][] = table.trList.map(() => [])\r\n        for (let r = 0; r <= ri; r++) {\r\n          let col = 0\r\n          for (let c = 0; c < table.trList[r].tdList.length; c++) {\r\n            while (col < cols.length && occupied[r][col]) col++\r\n            const cell = table.trList[r].tdList[c]\r\n            const span = Math.max(1, cell.colspan || 1)\r\n            if (r === ri && c === ci) cellWidth = cols.slice(col, col + span).reduce((sum, v) => sum + v, 0)\r\n            for (let rr = r + 1; rr < Math.min(r + Math.max(1, cell.rowspan || 1), table.trList.length); rr++) {\r\n              for (let cc = col; cc < Math.min(col + span, cols.length); cc++) occupied[rr][cc] = true\r\n            }\r\n            col += span\r\n          }\r\n        }\r\n      }\r\n      const [pt, pr, pb, pl] = td.padding\r\n      width = Math.min(width, Math.max(10, (cellWidth ?? width) - pl - pr))\r\n      height -= pt + pb\r\n    }\r\n    return { width: Math.max(1, width), height: Math.max(1, height) }\r\n  }\r\n\r\n  /** 在文本偏移处分段，并将块节点放入正文或单元格的块容器。 */\r\n  private insertBlockAtCaret(doc: IDocxDocumentMeta, block: IElement): Path | null {\r\n    const pos = this.range.getFocus() ?? { path: [doc.elements.length], offset: 0 }\r\n    let path = pos.path.slice() as Path\r\n    let parent = getParentContainer(doc.elements, path)\r\n    if (!parent) return null\r\n    let idx = Math.min(path[path.length - 1] as number, parent.length)\r\n    const node = parent[idx]\r\n    if (node?.type === 'text') {\r\n      const offset = Math.max(0, Math.min(pos.offset, node.value.length))\r\n      if (offset > 0) {\r\n        if (offset < node.value.length) {\r\n          parent.splice(idx + 1, 0, { ...node, value: node.value.slice(offset) } as IElement)\r\n          node.value = node.value.slice(0, offset)\r\n        }\r\n        idx++\r\n      }\r\n    } else if (node) {\r\n      idx++\r\n    }\r\n    // valueList 是标题、列表和超链接的行内容器，不可直接容纳独立块。\r\n    while (path[path.length - 2] === 'valueList') {\r\n      const containerPath = path.slice(0, -2) as Path\r\n      const container = getByPath(doc.elements, containerPath)!\r\n      const outer = getParentContainer(doc.elements, containerPath)!\r\n      const containerIndex = containerPath[containerPath.length - 1] as number\r\n      const tail = parent.splice(idx)\r\n      const replacements: IElement[] = []\r\n      if (parent.length) replacements.push(container)\r\n      const insertionIndex = containerIndex + replacements.length\r\n      if (tail.length) replacements.push({ ...container, valueList: tail } as IElement)\r\n      outer.splice(containerIndex, 1, ...replacements)\r\n      parent = outer\r\n      path = containerPath\r\n      idx = insertionIndex\r\n    }\r\n    parent.splice(idx, 0, block)\r\n    return [...path.slice(0, -1), idx] as Path\r\n  }\r\n\r\n  /** 插入电子签名图片，固定 100×100 */\r\n  signature(dataUrl: string): void {\r\n    this.insertImage({ value: dataUrl, width: 100, height: 100 })\r\n  }\r\n\r\n  /**\r\n   * 在当前光标处插入 LaTeX 公式元素。\r\n   * @param payload LaTeX 参数，包含 latex/svg/width/height\r\n   */\r\n  insertLatex(payload: { latex: string; svg: string; width: number; height: number }): void {\r\n    this.execute(doc => {\r\n      const pos = this.range.getFocus() ?? { path: [doc.elements.length], offset: 0 }\r\n      const el: IElement = { type: 'latex', value: payload.latex, laTexSVG: payload.svg, width: payload.width, height: payload.height } as unknown as IElement\r\n      const parent = pos.path.length === 1 ? doc.elements : getParentContainer(doc.elements, pos.path)\r\n      if (!parent) return false\r\n      const idx = (pos.path[pos.path.length - 1] as number) + 1\r\n      parent.splice(idx, 0, el)\r\n      return\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 更新指定图片的尺寸。\r\n   * @param path 图片路径\r\n   * @param width 新宽度\r\n   * @param height 新高度\r\n   */\r\n  updateImageSize(path: Path, width: number, height: number): void {\r\n    this.execute(doc => {\r\n      const el = getByPath(doc.elements, path)\r\n      if (!el || el.type !== 'image') return false\r\n      ;(el as unknown as { width: number; height: number }).width = Math.max(1, Math.round(width))\r\n      ;(el as unknown as { width: number; height: number }).height = Math.max(1, Math.round(height))\r\n      updateImageLayout(el as IImageElement, { width: (el as IImageElement).width, height: (el as IImageElement).height })\r\n      return\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 删除指定路径的图片元素。\r\n   * @param path 图片路径\r\n   */\r\n  deleteImage(path: Path): void {\r\n    this.execute(doc => {\r\n      const parent = getParentContainer(doc.elements, path)\r\n      if (!parent) return false\r\n      const idx = path[path.length - 1]\r\n      if (typeof idx !== 'number' || idx < 0 || idx >= parent.length) return false\r\n      if (parent[idx].type !== 'image') return false\r\n      parent.splice(idx, 1)\r\n      return\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 重置指定图片为原始尺寸（通过加载图片获取 naturalWidth/Height）。\r\n   * @param path 图片路径\r\n   */\r\n  resetImageSize(path: Path): void {\r\n    if (!this.getIsCanInput()) return\r\n    const doc = this.draw.getActiveDocument()\r\n    const el = getByPath(doc.elements, path) as unknown as { type: string; value?: string; width: number; height: number } | null\r\n    if (!el || el.type !== 'image' || !el.value) return\r\n    const img = new Image()\r\n    img.onload = () => {\r\n      if (!this.getIsCanInput()) return\r\n      el.width = img.naturalWidth\r\n      el.height = img.naturalHeight\r\n      updateImageLayout(el as IImageElement, { width: el.width, height: el.height })\r\n      // 不可迁移：_commit 在异步 onload 回调内\r\n      this._commit(doc)\r\n    }\r\n    img.src = el.value\r\n  }\r\n\r\n  /**\r\n   * 设置图片对齐方式。\r\n   * @param path 图片路径\r\n   * @param align 对齐方式：'left' | 'center' | 'right'\r\n   */\r\n  imageAlign(path: Path, align: 'left' | 'center' | 'right'): void {\r\n    this.execute(doc => {\r\n      const el = getByPath(doc.elements, path)\r\n      if (!el || el.type !== 'image') return false\r\n      ;(el as unknown as { rowFlex: string }).rowFlex = align\r\n      return\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 替换指定图片：弹出文件选择框，读取本地图片并以 data URL 替换原图片，同时更新尺寸。\r\n   * @param path 图片路径\r\n   */\r\n  replaceImage(path: Path): void {\r\n    if (!this.getIsCanInput()) return\r\n    const input = document.createElement('input')\r\n    input.type = 'file'\r\n    input.accept = 'image/*'\r\n    input.onchange = () => {\r\n      const file = input.files?.[0]\r\n      if (!file) return\r\n      const reader = new FileReader()\r\n      reader.onload = () => {\r\n        const value = reader.result\r\n        if (typeof value !== 'string') return\r\n        const doc = this.draw.getActiveDocument()\r\n        const el = getByPath(doc.elements, path) as unknown as { type: string; value: string; width: number; height: number } | null\r\n        if (!el || el.type !== 'image') return\r\n        const img = new Image()\r\n        img.onload = () => {\r\n          if (!this.getIsCanInput()) return\r\n          el.value = value\r\n          el.width = img.naturalWidth\r\n          el.height = img.naturalHeight\r\n          updateImageLayout(el as IImageElement, { width: el.width, height: el.height })\r\n          // 不可迁移：_commit 在异步嵌套回调内\r\n          this._commit(doc)\r\n        }\r\n        img.src = value\r\n      }\r\n      reader.readAsDataURL(file)\r\n    }\r\n    input.click()\r\n  }\r\n\r\n  /**\r\n   * 将指定图片顺时针旋转 90 度。\r\n   * @param path 图片路径\r\n   */\r\n  rotateImage(path: Path): void {\r\n    this.execute(doc => {\r\n      const el = getByPath(doc.elements, path) as unknown as { type: string; rotate?: number; width: number; height: number } | null\r\n      if (!el || el.type !== 'image') return false\r\n      applyImageLayout(el as IImageElement)\r\n      const cur = el.rotate ?? 0\r\n      el.rotate = (cur + 90) % 360\r\n      updateImageLayout(el as IImageElement, { rotate: el.rotate })\r\n      return\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 保存指定图片到本地（触发浏览器下载）。\r\n   * @param path 图片路径\r\n   */\r\n  async saveImage(path: Path): Promise<void> {\r\n    const doc = this.draw.getActiveDocument()\r\n    const el = getByPath(doc.elements, path) as unknown as { type: string; value: string } | null\r\n    if (!el || el.type !== 'image') return\r\n    try {\r\n      const url = new URL(el.value, document.baseURI)\r\n      if (!['https:', 'http:', 'data:', 'blob:'].includes(url.protocol)) return\r\n      const imageType = /^image\\/(png|jpeg|gif|webp|avif|bmp|x-icon|vnd\\.microsoft\\.icon)$/i\r\n      if (url.protocol === 'data:' && !imageType.test(url.pathname.split(/[;,]/, 1)[0])) return\r\n      const response = await fetch(url.href)\r\n      if (!response.ok) return\r\n      const blob = await response.blob()\r\n      if (!imageType.test(blob.type)) return\r\n      const href = URL.createObjectURL(blob)\r\n      const a = document.createElement('a')\r\n      a.href = href\r\n      a.download = `image-${Date.now()}`\r\n      document.body.appendChild(a)\r\n      a.click()\r\n      a.remove()\r\n      setTimeout(() => URL.revokeObjectURL(href), 1000)\r\n    } catch {\r\n      // 网络、CORS 或已释放的 blob URL 无法下载。\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 设置图片环绕方式。\r\n   * @param path 图片路径\r\n   * @param mode 环绕模式：'block' | 'surround' | 'floatTop' | 'floatBottom'\r\n   */\r\n  imageWrap(path: Path, mode: 'block' | 'surround' | 'float-top' | 'float-bottom'): void {\r\n    this.execute(doc => {\r\n      const el = getByPath(doc.elements, path) as unknown as { type: string; imgDisplay?: string; rowFlex?: string } | null\r\n      if (!el || el.type !== 'image') return false\r\n      el.imgDisplay = mode\r\n      updateImageLayout(el as IImageElement, { wrap: mode })\r\n      return\r\n    })\r\n  }\r\n\r\n  /** 在光标处切开正文，后文移至下一页。 */\r\n  insertPageBreak(): void {\r\n    if (!this.getIsCanInput() || this.draw.getZone() !== 'main') return\r\n    const pos = this.range.getOrdered()?.start ?? this.range.getFocus()\r\n    if (pos?.path.includes('trList')) throw new Error('暂不支持在表格单元格内插入分页符：表格分页及 DOCX 导出无法保真')\r\n    this.deleteSelection(false)\r\n    this.execute(doc => {\r\n      const path = this.insertBlockAtCaret(doc, { type: 'pageBreak', value: 'manual' })\r\n      if (!path) return false\r\n      const index = Number(path[path.length - 1])\r\n      const parent = getParentContainer(doc.elements, path)!\r\n      const next = parent[index + 1]\r\n      if (next?.type === 'text') this.range.setCaret({ path: [...path.slice(0, -1), index + 1], offset: 0 })\r\n      else if (next?.type === 'title' || next?.type === 'list') this.range.setCaret({ path: [...path.slice(0, -1), index + 1, 'valueList', 0], offset: 0 })\r\n      else this.range.setCaret(path.length === 1 ? { path: [index], offset: 0 } : { path, offset: 0 })\r\n      return true\r\n    })\r\n  }\r\n\r\n  /** 在光标处插入可编辑的空白页。 */\r\n  insertBlankPage(): void {\r\n    if (!this.getIsCanInput() || this.draw.getZone() !== 'main') return\r\n    const pos = this.range.getOrdered()?.start ?? this.range.getFocus()\r\n    if (pos?.path.includes('trList')) throw new Error('暂不支持在表格单元格内插入空白页：表格分页及 DOCX 导出无法保真')\r\n    this.deleteSelection(false)\r\n    this.execute(doc => {\r\n      const path = this.insertBlockAtCaret(doc, { type: 'text', value: '' })\r\n      if (!path) return false\r\n      const parent = getParentContainer(doc.elements, path)!\r\n      let index = Number(path[path.length - 1])\r\n      const previous = parent[index - 1]\r\n      const next = parent[index + 1]\r\n      if (previous && !(previous.type === 'pageBreak' && previous.value !== 'continuous')) {\r\n        parent.splice(index++, 0, { type: 'pageBreak', value: 'manual' })\r\n      }\r\n      if (next && !(next.type === 'pageBreak' && next.value !== 'continuous')) {\r\n        parent.splice(index + 1, 0, { type: 'pageBreak', value: 'manual' })\r\n      }\r\n      this.range.setCaret({ path: [...path.slice(0, -1), index], offset: 0 })\r\n      return true\r\n    })\r\n  }\r\n\r\n  /** 最近一次插入超链接失败的原因；成功后清空，供 UI 翻译显示。 */\r\n  getHyperlinkInsertionError(): HyperlinkInsertionError | null {\r\n    return this._hyperlinkInsertionError\r\n  }\r\n\r\n  /**\r\n   * 插入超链接。\r\n   * @param payload 超链接参数，包含 url 与 valueList\r\n   */\r\n  insertHyperlink(payload: { url: string; valueList: IElement[] }): boolean {\r\n    this._hyperlinkInsertionError = null\r\n    const fail = (reason: HyperlinkInsertionError): false => {\r\n      this._hyperlinkInsertionError = reason\r\n      return false\r\n    }\r\n    if (this.getIsReadonly()) return fail('readOnly')\r\n    if (this.getIsDisabled()) return fail('disabled')\r\n    if (!payload || typeof payload.url !== 'string') return fail('addressInvalid')\r\n    if (!Array.isArray(payload.valueList) || !payload.valueList.length) return fail('invalidText')\r\n    const url = payload.url.trim()\r\n    if (!url || /[\\u0000-\\u0020\\u007F]/.test(url)) return fail('addressInvalid')\r\n    try {\r\n      if (!['http:', 'https:', 'mailto:', 'tel:', 'ftp:'].includes(new URL(url).protocol)) return fail('addressInvalid')\r\n    } catch {\r\n      return fail('addressInvalid')\r\n    }\r\n    const hasRevision = (element: IElement): boolean => {\r\n      const run = element as ITextElement\r\n      return !!(run.revisionId || run.revisionType || run.revisionOldRPr ||\r\n        run.extension?.revisionOldProps || run.extension?.revisionPrevious)\r\n    }\r\n    if (payload.valueList.some(run => !run || run.type !== 'text' || typeof run.value !== 'string' ||\r\n      hasRevision(run) || run.extension?.bookmarkMarker || run.extension?.fieldMarker)) return fail('invalidText')\r\n    const text = payload.valueList.map(run => run.value).join('')\r\n    // 链接子 run 尚不参与修订遍历，不能把待审修订藏入 valueList 或绕过修订模式。\r\n    if (this.draw.getOptions().trackChanges) return fail('tracking')\r\n    let success = false\r\n    this.execute(doc => {\r\n      const ordered = this.range.getOrdered()\r\n      if (!ordered) return fail('noSelection')\r\n      const { start, end } = ordered\r\n      const parentPath = start.path.slice(0, -1)\r\n      if (!isSamePath(parentPath, end.path.slice(0, -1))) return fail('crossContainer')\r\n      const startNode = getByPath(doc.elements, start.path)\r\n      const endNode = getByPath(doc.elements, end.path)\r\n      if (!startNode || !endNode) return fail('invalidSelection')\r\n      if (startNode.type === 'hyperlink' || endNode.type === 'hyperlink') return fail('existingLink')\r\n      if (startNode.type !== 'text' || endNode.type !== 'text') return fail('nonText')\r\n      if (!Number.isInteger(start.offset) || !Number.isInteger(end.offset) ||\r\n        start.offset < 0 || start.offset > startNode.value.length ||\r\n        end.offset < 0 || end.offset > endNode.value.length) return fail('invalidSelection')\r\n      if (parentPath[parentPath.length - 1] === 'valueList') {\r\n        const container = getByPath(doc.elements, parentPath.slice(0, -1))\r\n        if (container?.type === 'hyperlink') return fail('existingLink')\r\n        if (container?.type !== 'title' && container?.type !== 'list') return fail('nonText')\r\n      }\r\n      const parent = getParentContainer(doc.elements, start.path)\r\n      if (!parent) return fail('invalidSelection')\r\n      const first = Number(start.path[start.path.length - 1])\r\n      const last = Number(end.path[end.path.length - 1])\r\n      const runs = parent.slice(first, last + 1)\r\n      if (runs.some(run => run.extension?.bookmarkMarker)) return fail('bookmarkSelection')\r\n      if (runs.some(run => run.extension?.fieldMarker)) return fail('fieldSelection')\r\n      if (runs.some(run => run.type === 'hyperlink')) return fail('existingLink')\r\n      if (runs.some(run => run.type !== 'text')) return fail('nonText')\r\n      if (runs.some(hasRevision)) return fail('revisions')\r\n      const selected = runs.map((run, i) => ({\r\n        ...cloneTree(run),\r\n        value: run.value.slice(i === 0 ? start.offset : 0, i === runs.length - 1 ? end.offset : run.value.length)\r\n      })).filter(run => run.value.length)\r\n      const selectedText = selected.map(run => run.value).join('')\r\n      // 不跨段落或吞掉段落终止符；不支持的选区必须在任何修改之前退出。\r\n      if (/[\\r\\n\\u200B\\uFEFF]/.test(selectedText)) return fail('crossParagraph')\r\n      // 先检查原选区，避免书签零宽标记被误报为显示文字错误。\r\n      if (!text.trim() || /[\\r\\n\\u200B\\uFEFF]/.test(text)) return fail('invalidText')\r\n      const base = selected[0] ?? startNode\r\n      // 对原选中文字加链接时沿用原 run 边界；更改显示文字时继承起点格式。\r\n      const valueList = selectedText === text ? selected : payload.valueList\r\n        .filter(run => run.value.length)\r\n        .map(run => ({ ...cloneTree(base), ...cloneTree(run) }))\r\n      const link = { ...cloneTree(base), type: 'hyperlink', value: url, valueList } as IElement\r\n      const parts: IElement[] = []\r\n      if (start.offset > 0) parts.push({ ...cloneTree(startNode), value: startNode.value.slice(0, start.offset) })\r\n      const linkIndex = first + parts.length\r\n      parts.push(link)\r\n      if (end.offset < endNode.value.length) parts.push({ ...cloneTree(endNode), value: endNode.value.slice(end.offset) })\r\n      parent.splice(first, last - first + 1, ...parts)\r\n      // layout-engine 将 valueList 展平到链接外层路径，offset 是所有子 run 的总长度。\r\n      this.range.setCaret({ path: [...parentPath, linkIndex], offset: text.length })\r\n      success = true\r\n      return true\r\n    })\r\n    return success\r\n  }\r\n\r\n  /**\r\n   * 插入分隔线。\r\n   * @param opts 分隔线选项，可以是对象或数组形式\r\n   */\r\n  insertSeparator(opts?: { lineType?: string; lineWidth?: number; dashArray?: number[]; color?: string } | any[]): void {\r\n    let normalized: { lineType?: string; lineWidth?: number; dashArray?: number[]; color?: string }\r\n    if (Array.isArray(opts)) {\r\n      const base: { lineType: string; lineWidth: number; dashArray: number[] } = { lineType: 'solid', lineWidth: 1, dashArray: [0, 0] }\r\n      if (opts.length === 3) {\r\n        base.lineType = opts[0]; base.lineWidth = opts[1]; base.dashArray = opts[2]\r\n      } else {\r\n        base.dashArray = opts\r\n      }\r\n      normalized = base\r\n    } else if (opts && typeof opts === 'object') {\r\n      normalized = {\r\n        lineType: (opts as any).type || (opts as any).lineType || 'solid',\r\n        lineWidth: (opts as any).width || (opts as any).lineWidth || 1,\r\n        dashArray: (opts as any).dashArray || [0, 0],\r\n        color: (opts as any).color\r\n      }\r\n    } else {\r\n      normalized = { lineType: 'solid', lineWidth: 1, dashArray: [0, 0] }\r\n    }\r\n    this.execute(doc => {\r\n      const pos = this.range.getFocus() ?? { path: [doc.elements.length], offset: 0 }\r\n      const parent = pos.path.length === 1 ? doc.elements : getParentContainer(doc.elements, pos.path)\r\n      if (!parent) return false\r\n      const idx = (pos.path[pos.path.length - 1] as number) + 1\r\n      const sep: IElement = { type: 'separator', value: '' } as unknown as IElement\r\n      const sepAny = sep as unknown as Record<string, unknown>\r\n      if (normalized.lineType != null) sepAny.lineType = normalized.lineType\r\n      if (normalized.lineWidth != null) sepAny.lineWidth = normalized.lineWidth\r\n      if (normalized.dashArray != null) sepAny.dashArray = normalized.dashArray\r\n      if (normalized.color != null) sepAny.color = normalized.color\r\n      parent.splice(idx, 0, sep)\r\n      return\r\n    })\r\n  }\r\n\r\n  /** 插入换行符 */\r\n  lineBreak(): void {\r\n    this.insertElementList([{ type: 'text', value: '\\n' } as IElement])\r\n  }\r\n\r\n  /** 插入分栏符 */\r\n  columnBreak(): void {\r\n    this.insertElementList([{ type: 'text', value: '\\n' } as IElement])\r\n  }\r\n\r\n  /** 通过分节命令在正文光标处插入连续分节符。 */\r\n  sectionBreakContinuous(): void { this.sectionBreak('continuous') }\r\n\r\n  /** 分节标记描述下一节的开始方式，sections 保存各节自己的设置。 */\r\n  sectionBreak(breakType: 'nextPage' | 'continuous' | 'evenPage' | 'oddPage'): void {\r\n    if (!this.getIsCanInput()) return\r\n    if (this.draw.getZone() !== 'main') throw new Error('分节符只能插入正文')\r\n    const ordered = this.range.getOrdered()\r\n    const positions = ordered ? [ordered.start, ordered.end] : [this.range.getFocus()]\r\n    if (positions.some(pos => pos?.path.includes('trList'))) throw new Error('暂不支持在表格单元格内插入分节符，请将光标移到表格前后的正文段落')\r\n    this.deleteSelection(false)\r\n    this.execute(doc => {\r\n      const path = this.insertBlockAtCaret(doc, { type: 'pageBreak', value: breakType })\r\n      if (!path) return false\r\n      const index = Number(path[0])\r\n      if (!doc.sections) {\r\n        const options = this.draw.getOptions()\r\n        doc.sections = [{ pageWidth: doc.pageWidth ?? Number(options.pageWidth), pageHeight: doc.pageHeight ?? Number(options.pageHeight),\r\n          margins: [...(doc.margins ?? options.pageMargins as [number, number, number, number])],\r\n          paperDirection: doc.paperDirection, columnCount: doc.columnCount ?? 1, columnGap: doc.columnGap ?? 20, breakType: 'nextPage' }]\r\n        const parts = doc.headerFooterParts ??= {}\r\n        for (const zone of ['header', 'footer'] as const) {\r\n          const elements = doc[zone] ?? doc.contentZones?.[zone]\r\n          if (elements?.length) {\r\n            const id = `section-${zone}-${Date.now()}`\r\n            parts[id] = cloneTree(elements)\r\n            doc.sections[0][zone === 'header' ? 'headers' : 'footers'] = { default: id }\r\n          }\r\n        }\r\n      }\r\n      const sectionIndex = doc.elements.slice(0, index).filter(el => el.type === 'pageBreak' && ['continuous', 'nextPage', 'evenPage', 'oddPage'].includes(el.value)).length\r\n      const next = cloneTree(doc.sections[sectionIndex])\r\n      next.breakType = breakType\r\n      doc.sections.splice(sectionIndex + 1, 0, next)\r\n      if (!doc.elements[index + 1] || doc.elements[index + 1].type === 'pageBreak') doc.elements.splice(index + 1, 0, { type: 'text', value: '' })\r\n      const following = doc.elements[index + 1]\r\n      this.range.setCaret({ path: following.type === 'title' || following.type === 'list' ? [index + 1, 'valueList', 0] : [index + 1], offset: 0 })\r\n      return true\r\n    })\r\n  }\r\n\r\n  /* -------------------- 内容读写 / 目录 -------------------- */\r\n\r\n  /**\r\n   * 获取当前活动文档的全部元素。\r\n   * @returns 文档元素数组\r\n   */\r\n  getValue(): IDocxDocumentMeta {\r\n    return cloneTree(this.draw.getDocument())\r\n  }\r\n\r\n  /**\r\n   * 完整替换文档内容，并重置编辑区域到 main。\r\n   * @param payload 文档内容，包含 main 及可选的 header/footer/comments\r\n   */\r\n  setValue(payload: Omit<Partial<IDocxDocumentMeta>, 'comments'> & { main?: IElement[]; comments?: unknown[] }): void {\r\n    const { main, ...document } = payload\r\n    const elements = main ?? document.elements\r\n    if (!Array.isArray(elements)) throw new TypeError('文档 elements/main 必须为数组')\r\n    if (document.sections !== undefined && !Array.isArray(document.sections)) {\r\n      throw new TypeError('旧 sections 内容区必须显式迁移到 contentZones')\r\n    }\r\n    this.replaceDocument({\r\n      ...document,\r\n      success: true,\r\n      elements,\r\n      comments: payload.comments as IDocxDocumentMeta['comments']\r\n    })\r\n\r\n  }\r\n\r\n  /**\r\n   * 统计文档字数（所有 text run 的字符数之和）。\r\n   * @returns 字数数值\r\n   */\r\n  getWordCount(): number {\r\n    const doc = this.draw.getActiveDocument()\r\n    let count = 0\r\n    walkTree(doc.elements, (node) => {\r\n      if (node.type === 'text') count += (node as ITextElement).value.length\r\n    })\r\n    return count\r\n  }\r\n\r\n  /**\r\n   * 获取文档目录（基于标题元素）。\r\n   * @returns 目录项数组，每项包含 id/level/name\r\n   */\r\n  getToc(): { id: string; level: number; name: string }[] {\r\n    const doc = this.draw.getActiveDocument()\r\n    const catalog: { id: string; level: number; name: string }[] = []\r\n    const levelMap: Record<string, number> = { first: 1, second: 2, third: 3, fourth: 4, fifth: 5, sixth: 6 }\r\n    walkTree(doc.elements, (node, ctx) => {\r\n      if (node.type === 'title') {\r\n        const t = node as ITitleElement\r\n        const name = (t.valueList ?? []).map(v => v.type === 'text' ? (v as ITextElement).value : '').join('')\r\n        catalog.push({ id: JSON.stringify(ctx.path), level: levelMap[t.level] ?? 1, name })\r\n      }\r\n    })\r\n    return catalog\r\n  }\r\n\r\n  /**\r\n   * 定位到指定目录项：滚动到对应标题位置并设置光标。\r\n   * @param id 目录项 ID（序列化的路径字符串）\r\n   */\r\n  locationToc(id: string): void {\r\n    try {\r\n      const path = JSON.parse(id) as Path\r\n      const layout = this.draw.getLayout()\r\n      if (layout) {\r\n        for (const page of layout.pages) {\r\n          for (const b of page.blocks) {\r\n            if (b.kind !== 'paragraph') continue\r\n            const blockPath = b.parentPath.concat(b.startIndex)\r\n            if (blockPath.length === path.length && blockPath.every((v, i) => v === path[i])) {\r\n              const scroller = this.draw.getScroller()\r\n              const scrollContainer = scroller.parentElement as HTMLDivElement\r\n              const absY = page.contentRect.y + b.rect.y\r\n              scrollContainer.scrollTop = Math.max(0, absY - scrollContainer.clientHeight / 2)\r\n              this.range.setCaret({ path, offset: 0 })\r\n              return\r\n            }\r\n          }\r\n        }\r\n      }\r\n      this.range.setCaret({ path, offset: 0 })\r\n    } catch {\r\n      // ignore invalid catalog id\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 设置光标位置。\r\n   * @param path 光标路径\r\n   * @param offset 偏移量\r\n   */\r\n  setCaret(path: Path, offset: number): void {\r\n    this.range.setCaret({ path: path.slice() as Path, offset })\r\n  }\r\n\r\n  /**\r\n   * 基于布局分页生成自动目录结果（按层级过滤的三组目录）。\r\n   * @returns 包含 toc1/toc2/toc3 的自动目录结果\r\n   */\r\n  getAutoToc(): IAutoTocResult {\r\n    const layout = this.draw.getLayout()\r\n    const empty: IAutoTocResult = { toc1: [], toc2: [], toc3: [] }\r\n    if (!layout) return empty\r\n\r\n    const levelMap: Record<string, number> = { first: 1, second: 2, third: 3, fourth: 4, fifth: 5, sixth: 6 }\r\n    const all: IAutoTocItem[] = []\r\n    const seen = new Set<string>()\r\n\r\n    for (const page of layout.pages) {\r\n      const pageNo = page.index + 1\r\n      for (const b of page.blocks) {\r\n        if (b.kind !== 'paragraph' || b.paragraphKind !== 'title' || !b.block) continue\r\n        const titleEl = b.block as unknown as ITitleElement\r\n        const level = levelMap[titleEl.level] ?? 1\r\n        const name = (titleEl.valueList ?? []).map(v => v.type === 'text' ? (v as ITextElement).value : '').join('')\r\n        const id = JSON.stringify(b.parentPath.concat(b.startIndex))\r\n        if (seen.has(id) || titleEl.extension?.toc) continue\r\n        seen.add(id)\r\n        // 从排版块中直接取编号文本（由排版引擎通过 listNumbering 计算得到）\r\n        const bulletText = (b as unknown as { bulletText?: string }).bulletText\r\n        const number = bulletText?.trim() || undefined\r\n\r\n        all.push({ id, level, name, pageNo, number })\r\n      }\r\n    }\r\n\r\n    return {\r\n      toc1: all.filter(i => i.level <= 1),\r\n      toc2: all.filter(i => i.level <= 2),\r\n      toc3: all.filter(i => i.level <= 3)\r\n    }\r\n  }\r\n\r\n  /** 在正文光标处插入 Office 自动目录模板（均收录三级标题）。 */\r\n  insertAutoToc(template: 1 | 2): void {\r\n    this.insertToc({ type: template })\r\n  }\r\n\r\n  /* -------------------- 页面 / 打印 -------------------- */\r\n\r\n  /**\r\n   * 设置纸张尺寸并发出页面尺寸变更事件。\r\n   * @param width 宽度\r\n   * @param height 高度\r\n   */\r\n  setPaperSize(width: number, height: number): void {\r\n    // Paper settings remain available in readonly mode.\r\n    if (this.getIsDisabled()) return\r\n    this.draw.setPageSize(width, height)\r\n    this.listener?.emit('pageSizeChange', { width, height })\r\n    this.listener?.emit('contentChange')\r\n  }\r\n\r\n  /**\r\n   * 设置纸张方向（纵向/横向），自动调整宽高。\r\n   * @param direction 方向：'vertical' | 'horizontal'\r\n   */\r\n  setPaperDirection(direction: 'vertical' | 'horizontal'): void {\r\n    const opts = this.draw.getOptions()\r\n    const doc = this.draw.getDocument()\r\n    const section = doc.sections?.[0]\r\n    const w = Number(section?.pageWidth ?? doc.pageWidth ?? opts.pageWidth ?? 794)\r\n    const h = Number(section?.pageHeight ?? doc.pageHeight ?? opts.pageHeight ?? 1123)\r\n    if (direction === 'horizontal') {\r\n      this.setPaperSize(Math.max(w, h), Math.min(w, h))\r\n    } else {\r\n      this.setPaperSize(Math.min(w, h), Math.max(w, h))\r\n    }\r\n  }\r\n\r\n  /** 放大页面缩放（步进 0.1，上限 3）。 */\r\n  pageScaleAdd(): void {\r\n    const opts = this.draw.getOptions()\r\n    const scale = Math.min(3, Number(opts.scale ?? 1) + 0.1)\r\n    this.draw.setScale(scale)\r\n    this.listener?.emit('pageScaleChange', scale)\r\n  }\r\n\r\n  /** 缩小页面缩放（步进 0.1，下限 0.5）。 */\r\n  pageScaleMinus(): void {\r\n    const opts = this.draw.getOptions()\r\n    const scale = Math.max(0.5, Number(opts.scale ?? 1) - 0.1)\r\n    this.draw.setScale(scale)\r\n    this.listener?.emit('pageScaleChange', scale)\r\n  }\r\n\r\n  /**\r\n   * 获取纸张高度（含缩放）。\r\n   * @returns 纸张高度数值\r\n   */\r\n  getPaperHeight(): number {\r\n    const opts = this.draw.getOptions()\r\n    return Number(opts.pageHeight ?? 1123) * Number(opts.scale ?? 1)\r\n  }\r\n\r\n  /**\r\n   * 获取编辑器选项。\r\n   * @returns 当前编辑器配置选项\r\n   */\r\n  getOptions(): IEditorOption {\r\n    return this.draw.getOptions() as IEditorOption\r\n  }\r\n\r\n  /**\r\n   * 设置页面模式。\r\n   * @param mode 页面模式字符串\r\n   */\r\n  setPageMode(mode: string): void {\r\n    this.draw.updateOptions({ pageMode: mode as 'paging' | 'continuity' })\r\n  }\r\n\r\n  /**\r\n   * 设置页面缩放比例。\r\n   * @param scale 缩放比例\r\n   */\r\n  setPageScale(scale: number): void {\r\n    this.draw.setScale(scale)\r\n    this.listener?.emit('pageScaleChange', scale)\r\n  }\r\n\r\n  /** 恢复默认缩放比例 */\r\n  setPageScaleRecovery(): void {\r\n    this.draw.setScale(1)\r\n    this.listener?.emit('pageScaleChange', 1)\r\n  }\r\n\r\n  /**\r\n   * 设置分栏数。\r\n   * @param value 分栏数量\r\n   */\r\n  setColumns(value: number): void {\r\n    if (!this.getIsCanInput()) return\r\n    if (![1, 2, 3].includes(value)) throw new RangeError('仅支持一栏、二栏或三栏')\r\n    if (this.draw.getZone() !== 'main') throw new Error('分栏只能应用于正文')\r\n    const focus = this.range.getFocus()\r\n    if (focus?.path.includes('trList')) throw new Error('暂不支持在表格单元格内设置分栏，请将光标移到正文段落')\r\n    this.execute(doc => {\r\n      const index = Number(focus?.path[0] ?? 0)\r\n      const sectionIndex = doc.elements.slice(0, index).filter(el => el.type === 'pageBreak' && ['continuous', 'nextPage', 'evenPage', 'oddPage'].includes(el.value)).length\r\n      const section = doc.sections?.[sectionIndex]\r\n      if (section) {\r\n        section.columnCount = value\r\n        section.columnGap ??= doc.columnGap ?? 20\r\n        // 工具栏选择的是等宽栏，清除导入文档的自定义栏宽。\n        delete section.columnWidths\n        delete section.columnGaps\n      } else {\r\n        doc.columnCount = value\r\n        doc.columnGap ??= 20\r\n      }\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 批量更新编辑器选项。\r\n   * @param patch 选项补丁对象\r\n   */\r\n  updateOptions(patch: Partial<IEditorOption>): void {\r\n    this.draw.updateOptions(patch)\r\n    if ('readonly' in patch || 'disabled' in patch) {\r\n      if (!this.getIsCanInput()) this._paintFmt = null\r\n      this.listener?.emit('formatChange', this.getRangeStyle())\r\n      this.listener?.emit('abilityChange', this.getAbility())\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 设置标尺可见性。\r\n   * @param visible 是否可见\r\n   */\r\n  setRulerVisible(visible: boolean): void {\r\n    this.draw.setRulerVisible(visible)\r\n  }\r\n\r\n  /**\r\n   * 设置页边距（四边数值取整并保证非负）。\r\n   * @param margins 边距数组，顺序为上、右、下、左\r\n   */\r\n  setPaperMargin(margins: number[]): void {\r\n    if (!this.getIsCanInput()) return\r\n    const m = [\r\n      Math.max(0, Math.round(margins[0] ?? 0)),\r\n      Math.max(0, Math.round(margins[1] ?? 0)),\r\n      Math.max(0, Math.round(margins[2] ?? 0)),\r\n      Math.max(0, Math.round(margins[3] ?? 0))\r\n    ] as [number, number, number, number]\r\n    this.draw.setPaperMargins(m)\r\n  }\r\n\r\n  /** 打印文档。 */\r\n  print(): Promise<void> {\r\n    return this.draw.print()\r\n  }\r\n\r\n  /**\r\n   * 获取所有页面缩略图。\r\n   * @returns 缩略图 data URL 数组\r\n   */\r\n  getPageThumbnails(): string[] {\r\n    return this.draw.getPageThumbnails()\r\n  }\r\n\r\n  /* -------------------- 水印 -------------------- */\r\n\r\n  /**\r\n   * 添加水印。\r\n   * @param payload 水印参数，可包含 data/content/color/opacity/size/font/repeat\r\n   */\r\n  addWatermark(payload: { data?: string; content?: string; color?: string; opacity?: number; size?: number; font?: string; repeat?: boolean; gapX?: number; gapY?: number } | any): void {\r\n    if (!this.getIsCanInput()) return\r\n    const p = payload || {}\r\n    this.draw.updateOptions({ watermark: {\r\n      data: p.data || p.content || '',\r\n      color: p.color,\r\n      opacity: p.opacity,\r\n      size: p.size,\r\n      font: p.font,\r\n      repeat: p.repeat,\r\n      gapX: p.gapX,\r\n      gapY: p.gapY\r\n    } } as Partial<IEditorOption>)\r\n  }\r\n\r\n  /** 删除水印 */\r\n  deleteWatermark(): void {\r\n    if (!this.getIsCanInput()) return\r\n    this.draw.updateOptions({ watermark: null } as Partial<IEditorOption>)\r\n  }\r\n\r\n  /**\r\n   * 设置系统级水印（全页面 DOM 覆盖层）。\r\n   * @param config 水印配置，null 表示移除\r\n   */\r\n  setSystemWatermark(config: { data: string; color?: string; opacity?: number; size?: number; font?: string; repeat?: boolean; gapX?: number; gapY?: number } | null): void {\r\n    this.draw.setSystemWatermark?.(config)\r\n  }\r\n\r\n  /** 删除系统级水印 */\r\n  deleteSystemWatermark(): void {\r\n    this.draw.setSystemWatermark?.(null)\r\n  }\r\n\r\n  /* -------------------- 查找替换 -------------------- */\r\n\r\n  /**\r\n   * 查找关键词，返回命中数，并选中第一个命中。\r\n   * @param keyword 搜索关键字\r\n   * @returns 包含命中数量 count 的结果对象\r\n   */\r\n  search(keyword: string): { count: number } {\r\n    this._searchHits = []\r\n    this._searchIdx = 0\r\n    if (!keyword) return { count: 0 }\r\n    const doc = this.draw.getActiveDocument()\r\n    walkTree(doc.elements, (node, ctx) => {\r\n      if (node.type !== 'text') return\r\n      const text = (node as ITextElement).value\r\n      let from = 0\r\n      while (true) {\r\n        const i = text.indexOf(keyword, from)\r\n        if (i === -1) break\r\n        this._searchHits.push({ path: ctx.path.slice() as Path, start: i, end: i + keyword.length })\r\n        from = i + keyword.length\r\n      }\r\n    })\r\n    this.captureSearch()\r\n    if (this._searchHits.length > 0) this._selectHit(0)\r\n    return { count: this._searchHits.length }\r\n  }\r\n\r\n  /**\r\n   * 替换当前命中为 text，跳到下一个命中。返回是否还有命中。opts.index 可指定替换第几个命中。\r\n   * @param text 替换文本\r\n   * @param opts 替换选项，可指定 index\r\n   * @returns 是否还存在后续命中\r\n   */\r\n  replace(text: string, opts?: { index?: number }): boolean {\r\n    if (!this.getIsCanInput()) return false\r\n    this.validateSearch()\r\n    if (opts?.index != null) {\r\n      if (!Number.isInteger(opts.index) || opts.index < 0 || opts.index >= this._searchHits.length) return false\r\n      this._searchIdx = opts.index\r\n    }\r\n    if (this._searchIdx >= this._searchHits.length) return false\r\n    const hit = this._searchHits[this._searchIdx]\r\n    const doc = this.draw.getActiveDocument()\r\n    const node = getByPath(doc.elements, hit.path)\r\n    if (node && node.type === 'text') {\r\n      const t = node as ITextElement\r\n      t.value = t.value.slice(0, hit.start) + text + t.value.slice(hit.end)\r\n      const delta = text.length - (hit.end - hit.start)\r\n      for (let i = this._searchIdx + 1; i < this._searchHits.length; i++) {\r\n        const h = this._searchHits[i]\r\n        if (isSamePath(h.path, hit.path)) { h.start += delta; h.end += delta }\r\n      }\r\n      this.captureSearch()\r\n      this._commit(doc)\r\n    }\r\n    this.captureSearch()\r\n    this._searchIdx++\r\n    if (this._searchIdx < this._searchHits.length) {\r\n      this._selectHit(this._searchIdx)\r\n      return true\r\n    }\r\n    return false\r\n  }\r\n\r\n  /**\r\n   * 定位到指定搜索结果索引。\r\n   * @param idx 搜索结果索引\r\n   */\r\n  locateSearchResult(idx: number): void {\r\n    this.validateSearch()\r\n    if (idx < 0 || idx >= this._searchHits.length) return\r\n    this._searchIdx = idx\r\n    this._selectHit(idx)\r\n  }\r\n\r\n  /**\r\n   * 获取当前搜索命中列表，每项包含匹配文本及前后上下文片段。\r\n   * @returns 匹配项数组，index 为命中序号，before/match/after 为上下文与匹配文本\r\n   */\r\n  getSearchMatches(): { index: number; before: string; match: string; after: string }[] {\r\n    this.validateSearch()\r\n    const doc = this.draw.getActiveDocument()\r\n    const PAD = 50\r\n    const result: { index: number; before: string; match: string; after: string }[] = []\r\n\r\n    // 预计算文本元素扁平列表，用于跨元素收集上下文\r\n    const textNodes: { path: Path; value: string }[] = []\r\n    walkTree(doc.elements, (node, ctx) => {\r\n      if (node.type === 'text') {\r\n        textNodes.push({ path: ctx.path.slice() as Path, value: (node as ITextElement).value })\r\n      }\r\n    })\r\n\r\n    for (let i = 0; i < this._searchHits.length; i++) {\r\n      const hit = this._searchHits[i]\r\n      const nodeIdx = textNodes.findIndex(t => isSamePath(t.path, hit.path))\r\n      if (nodeIdx === -1) continue\r\n      const value = textNodes[nodeIdx].value\r\n      const match = value.slice(hit.start, hit.end)\r\n\r\n      // 向前收集上下文（跨元素），不在开头加 …\r\n      let before = value.slice(Math.max(0, hit.start - PAD), hit.start)\r\n      let needBefore = PAD - before.length\r\n      let niBefore = nodeIdx - 1\r\n      while (needBefore > 0 && niBefore >= 0) {\r\n        const prevValue = textNodes[niBefore].value\r\n        const take = Math.min(needBefore, prevValue.length)\r\n        before = prevValue.slice(prevValue.length - take) + before\r\n        needBefore -= take\r\n        niBefore--\r\n      }\r\n\r\n      // 向后收集上下文（跨元素）\r\n      let after = value.slice(hit.end, Math.min(value.length, hit.end + PAD))\r\n      let needAfter = PAD - after.length\r\n      let niAfter = nodeIdx + 1\r\n      while (needAfter > 0 && niAfter < textNodes.length) {\r\n        const nextValue = textNodes[niAfter].value\r\n        const take = Math.min(needAfter, nextValue.length)\r\n        after += nextValue.slice(0, take)\r\n        needAfter -= take\r\n        niAfter++\r\n      }\r\n      if (niAfter < textNodes.length || hit.end + PAD < value.length) after += '…'\r\n\r\n      result.push({ index: i, before, match, after })\r\n    }\r\n    return result\r\n  }\r\n\r\n  /**\r\n   * 全部替换：先搜索 keyword，逐个替换为 replacement，返回替换计数。\r\n   * @param keyword 搜索关键字\r\n   * @param replacement 替换文本\r\n   * @returns 包含替换数量 count 的结果对象\r\n   */\r\n  replaceAll(keyword: string, replacement: string): { count: number } {\r\n    if (!this.getIsCanInput()) return { count: 0 }\r\n    this.search(keyword)\r\n    let count = 0\r\n    while (this._searchIdx < this._searchHits.length) {\r\n      this.replace(replacement)\r\n      count++\r\n    }\r\n    return { count }\r\n  }\r\n\r\n  /**\r\n   * 替换一处搜索结果并继续搜索，返回新的搜索结果。\r\n   * @param result 搜索结果定位信息\r\n   * @param replacement 替换文本\r\n   * @returns 包含新的命中数量 count 的结果对象\r\n   */\r\n  replaceOne(result: { resultIndex: number; keyword: string }, replacement: string): { count: number } {\r\n    if (!this.getIsCanInput()) return { count: 0 }\r\n    if (!result || !replacement) return { count: 0 }\r\n    this.replace(replacement, { index: result.resultIndex })\r\n    return this.search(result.keyword)\r\n  }\r\n\r\n  /**\r\n   * 选中指定索引的搜索命中区域。\r\n   * @param idx 搜索命中索引\r\n   */\r\n  private _selectHit(idx: number): void {\r\n    const hit = this._searchHits[idx]\r\n\r\n    if (!hit) return\r\n    this.range.setRange({\r\n      anchor: { path: hit.path, offset: hit.start },\r\n      focus: { path: hit.path, offset: hit.end }\r\n    })\r\n    this.draw.scrollPositionIntoView?.({ path: hit.path, offset: hit.start })\r\n  }\r\n\r\n  /* -------------------- 书签 -------------------- */\r\n\r\n  /**\r\n   * 获取所有书签。\r\n   * @returns 书签数组\r\n   */\r\n  getBookmarks(): IBookmark[] {\r\n    return this.draw.getDocument().bookmarks ?? []\r\n  }\r\n\r\n  /**\r\n   * 在当前选区添加书签。\r\n   * @param payload 书签参数，包含 name\r\n   */\r\n  addBookmark(payload: { name: string }): void {\r\n    if (!this.getIsCanInput()) return\r\n    const range = this.range.getRange()\r\n    if (!range) return\r\n    const doc = this.draw.getDocument()\r\n    const bookmarks = doc.bookmarks ?? []\r\n    if (bookmarks.some(b => b.name === payload.name)) return\r\n    const collapsed = isSamePath(range.anchor.path, range.focus.path) && range.anchor.offset === range.focus.offset\r\n    bookmarks.push({ name: payload.name, range: cloneTree(range), collapsed })\r\n    doc.bookmarks = bookmarks\r\n    // 不可迁移：doc 来自 this.draw.getDocument() 而非 getActiveDocument()\r\n    this._commit(doc)\r\n  }\r\n\r\n  /**\r\n   * 删除指定书签。\r\n   * @param payload 书签参数，包含 name\r\n   */\r\n  deleteBookmark(payload: { name: string }): void {\r\n    if (!this.getIsCanInput()) return\r\n    const doc = this.draw.getDocument()\r\n    if (!doc.bookmarks) return\r\n    doc.bookmarks = doc.bookmarks.filter(b => b.name !== payload.name)\r\n    // 不可迁移：doc 来自 this.draw.getDocument() 而非 getActiveDocument()\r\n    this._commit(doc)\r\n  }\r\n\r\n  /**\r\n   * 跳转到指定书签。\r\n   * @param payload 书签参数，包含 name\r\n   */\r\n  gotoBookmark(payload: { name: string }): void {\r\n    const doc = this.draw.getDocument()\r\n    const bookmark = doc.bookmarks?.find(b => b.name === payload.name)\r\n    if (!bookmark) return\r\n    const anchor = this.findVisiblePosNearby(doc.elements, bookmark.range.anchor) ?? bookmark.range.anchor\r\n    const focus = bookmark.collapsed\r\n      ? anchor\r\n      : this.findVisiblePosNearby(doc.elements, bookmark.range.focus) ?? bookmark.range.focus\r\n    this.range.setRange({ anchor, focus })\r\n    this.draw.scrollPositionIntoView?.(focus)\r\n  }\r\n\r\n  /**\r\n   * bookmarkMarker 是零宽 run，layout 中无 inline，locateCaret 找不到。\r\n   * 从 marker path 出发，在同一兄弟数组中找相邻的非零宽元素，返回其位置。\r\n   */\r\n  private findVisiblePosNearby(elements: IElement[], pos: IPosition): IPosition | null {\r\n    if (!getByPath(elements, pos.path)?.extension?.bookmarkMarker) return pos\r\n    const path = pos.path\r\n    if (path.length < 1) return null\r\n    const lastSeg = path[path.length - 1]\r\n    if (typeof lastSeg !== 'number') return null\r\n    const parentPath = path.slice(0, -1)\r\n    const parent = parentPath.length === 0 ? elements : getByPath(elements, parentPath as Path)\r\n    if (!Array.isArray(parent)) return null\r\n    const isVisible = (el: unknown): boolean => {\r\n      if ((el as IElement)?.extension?.bookmarkMarker) return false\r\n      const v = String((el as { value?: string })?.value ?? '')\r\n      return !!v && !/^[\\u200B\\uFEFF]+$/.test(v)\r\n    }\r\n    for (let i = lastSeg + 1; i < parent.length; i++) {\r\n      if (isVisible(parent[i])) return { path: [...parentPath, i] as Path, offset: 0 }\r\n    }\r\n    for (let i = lastSeg - 1; i >= 0; i--) {\r\n      if (isVisible(parent[i])) {\r\n        const node = parent[i] as IElement\r\n        return { path: [...parentPath, i] as Path, offset: node.type === 'text' ? node.value.length : 1 }\r\n      }\r\n    }\r\n    return null\r\n  }\r\n\r\n  /* -------------------- 目录 -------------------- */\r\n\r\n  /** 读取元素扩展中的目录域元数据，未标记目录域时返回 undefined。 */\r\n  private tocMetadata(element?: IElement): { id: string; template: 1 | 2; maxLevel: number; role: 'heading' | 'entry' | 'placeholder'; level?: number } | undefined {\r\n    return element?.extension?.toc as ReturnType<CommandAdapt['tocMetadata']>\r\n  }\r\n\r\n  /** 查找光标所在目录组，否则取首个目录组，返回起止索引（结束不含）及元数据；无目录时返回 null。 */\r\n  private tocGroup(elements: IElement[]) {\r\n    const focus = this.range.getFocus()\r\n    const index = focus?.path.length === 1 ? Number(focus.path[0]) : -1\r\n    const selected = this.tocMetadata(elements[index])\r\n    const start = selected\r\n      ? elements.findIndex(el => this.tocMetadata(el)?.id === selected.id)\r\n      : elements.findIndex(el => !!this.tocMetadata(el))\r\n    if (start < 0) return null\r\n    const metadata = this.tocMetadata(elements[start])!\r\n    let end = start + 1\r\n    while (end < elements.length && this.tocMetadata(elements[end])?.id === metadata.id) end++\r\n    return { start, end, metadata }\r\n  }\r\n\r\n  /** 根据布局目录和最大标题级别生成带目录域标记的标题、条目及段落分隔，无条目时生成提示文本。 */\r\n  private buildToc(id: string, template: 1 | 2, maxLevel: number): IElement[] {\r\n    const elements: IElement[] = []\r\n    const append = (value: string, role: 'heading' | 'entry' | 'placeholder', level?: number) => {\r\n      const run: ITextElement = {\r\n        type: 'text', value, size: role === 'heading' ? 21 : 14,\r\n        bold: role === 'heading', rowFlex: role === 'heading' ? 'center' : 'left',\r\n        paragraphIndentLeft: role === 'entry' ? ((level ?? 1) - 1) * 21 : 0,\r\n        paragraphSpacingAfter: role === 'heading' ? 8 : 0,\r\n        extension: { toc: { id, template, maxLevel, role, ...(level ? { level } : {}) } }\r\n      }\r\n      elements.push(run, { ...cloneTree(run), value: '\\u200B' })\r\n    }\r\n    append('目录', 'heading')\r\n    const items = this.getAutoToc().toc3.filter(item => item.level <= maxLevel)\r\n    for (const item of items) {\r\n      const name = item.name.replace(/[\\u200B\\uFEFF\\t\\r\\n]/g, '').trim()\r\n      append(`${item.number ? item.number + ' ' : ''}${name}\\t${item.pageNo}`, 'entry', item.level)\r\n    }\r\n    if (!items.length) append('未找到目录项。请先为正文应用标题样式，再更新目录。', 'placeholder')\r\n    return elements\r\n  }\r\n\r\n  /** 在最终布局上刷新页码，所有重排结果合并为同一条历史记录。 */\r\n  private refreshToc(doc: IDocxDocumentMeta, start: number, count: number, id: string, template: 1 | 2, maxLevel: number): void {\r\n    for (let pass = 0; pass < 8; pass++) {\r\n      this.draw.applyActiveDocument(doc)\r\n      const next = this.buildToc(id, template, maxLevel)\r\n      const previous = doc.elements.slice(start, start + count)\r\n      if (next.length === previous.length && next.every((el, i) => el.value === previous[i].value)) break\r\n      this.spliceBodyWithBookmarks(doc, start, count, next)\r\n      count = next.length\r\n    }\r\n    this.range.setCaret({ path: [start], offset: 0 })\r\n  }\r\n\r\n  /** 插入普通文本目录，extension.toc 为前后端共享的目录域协议。 */\r\n  insertToc(payload: { type?: 1 | 2; mode?: string; [key: string]: unknown }): void {\r\n    if (payload.mode === 'update') { this.updateToc(); return }\r\n    if (this.draw.getZone() !== 'main') return\r\n    this.execute(doc => {\r\n      // 在选区起点插入，保留选中的正文；标题/列表内部提升到整个正文块之前。\r\n      const pos = this.range.getOrdered()?.start ?? this.range.getFocus()\r\n      if (pos?.path.includes('trList')) throw new Error('暂不支持在表格单元格内插入目录，请将光标移到表格前后的正文段落')\r\n      let index = pos ? Number(pos.path[0]) : doc.elements.length\r\n      const node = doc.elements[index]\r\n      if (this.tocMetadata(node)) return false\r\n      if (pos && pos.path.length > 1 && node?.type !== 'title' && node?.type !== 'list') return false\r\n      if (node?.type === 'text' && pos) {\r\n        const offset = Math.max(0, Math.min(pos.offset, node.value.length))\r\n        if (offset > 0 && !/^[\\u200B\\uFEFF]*$/.test(node.value.slice(0, offset))) {\r\n          if (offset < node.value.length) {\r\n            doc.elements.splice(index + 1, 0, { ...cloneTree(node), value: node.value.slice(offset) })\r\n            node.value = node.value.slice(0, offset)\r\n            this.mapBookmarksAfterSplit(doc, [index], offset)\r\n          }\r\n          index++\r\n        }\r\n      } else if (node?.type === 'pageBreak') index++\r\n      const template = payload.type === 2 ? 2 : 1\r\n      const maxLevel = payload.maxLevel === 1 || payload.maxLevel === 2 || payload.maxLevel === 3 ? payload.maxLevel : 3\r\n      const id = `toc-${Date.now()}-${++this._revisionSequence}`\r\n      const elements = this.buildToc(id, template, maxLevel)\r\n      const isPageStart = (element?: IElement) => element?.type === 'pageBreak' && element.value !== 'continuous'\r\n      // 页首可能有编辑器的空文本/段落标记，不为这些占位内容再产生一张空白页。\r\n      let boundary = index\r\n      while (boundary > 0 && doc.elements[boundary - 1].type === 'text' && /^[\\u200B\\uFEFF]*$/.test(doc.elements[boundary - 1].value) && !this.tocMetadata(doc.elements[boundary - 1])) boundary--\r\n      if (boundary === 0 || isPageStart(doc.elements[boundary - 1])) index = boundary\r\n      // 单独的扩展标记不属于 extension.toc 域，Java 仍按普通 manual 分页符导出。\r\n      const pageBreak = (): IElement => ({ type: 'pageBreak', value: 'manual', extension: { tocPageBreak: id } })\r\n      if (index > 0 && !isPageStart(doc.elements[index - 1])) this.spliceBodyWithBookmarks(doc, index++, 0, [pageBreak()])\r\n      this.spliceBodyWithBookmarks(doc, index, 0, elements)\r\n      const end = index + elements.length\r\n      if (!isPageStart(doc.elements[end])) this.spliceBodyWithBookmarks(doc, end, 0, [pageBreak()])\r\n      if (end + 1 === doc.elements.length) doc.elements.push({ type: 'text', value: '' })\r\n      this.refreshToc(doc, index, elements.length, id, template, maxLevel)\r\n      return true\r\n    })\r\n  }\r\n\r\n  /** 更新选中目录；光标在正文时更新第一个目录。 */\r\n  updateToc(): void {\r\n    if (this.draw.getZone() !== 'main') return\r\n    this.execute(doc => {\r\n      const group = this.tocGroup(doc.elements)\r\n      if (!group) return false\r\n      const { id, template, maxLevel } = group.metadata\r\n      const elements = this.buildToc(id, template, maxLevel)\r\n      this.spliceBodyWithBookmarks(doc, group.start, group.end - group.start, elements)\r\n      this.refreshToc(doc, group.start, elements.length, id, template, maxLevel)\r\n      return true\r\n    })\r\n  }\r\n\r\n  /** 删除选中目录组，保留正文及其他目录。 */\r\n  removeToc(): void {\r\n    if (this.draw.getZone() !== 'main') return\r\n    this.execute(doc => {\r\n      const group = this.tocGroup(doc.elements)\r\n      if (!group) return false\r\n      const ownedBreak = (element?: IElement) => element?.type === 'pageBreak' && element.value === 'manual' && element.extension?.tocPageBreak === group.metadata.id\r\n      const start = ownedBreak(doc.elements[group.start - 1]) ? group.start - 1 : group.start\r\n      const end = ownedBreak(doc.elements[group.end]) ? group.end + 1 : group.end\r\n      this.spliceBodyWithBookmarks(doc, start, end - start)\r\n      this.range.setCaret({ path: [Math.min(start, doc.elements.length - 1)], offset: 0 })\r\n      return true\r\n    })\r\n  }\r\n\r\n  /* -------------------- 撤销 / 重做 -------------------- */\r\n\r\n  /** 撤销上一步操作，恢复历史快照并通知选区样式与能力变更。 */\r\n  undo(): void {\r\n    if (!this.getIsCanInput()) return\r\n    if (!this._historyManager) return\r\n    const current: HistorySnapshot = {\r\n      doc: cloneTree(this.draw.getDocument()),\r\n      range: this.range.getRange(),\r\n      zone: this.draw.getZone()\r\n    }\r\n    const prev = this._historyManager.undo(current)\r\n    if (prev) {\r\n      this.range.clear()\r\n      this.draw.setZone(prev.zone ?? 'main')\r\n      this.draw.setDocument(cloneTree(prev.doc))\r\n      if (prev.range) this.range.setRange(cloneTree(prev.range))\r\n      else this.range.clear()\r\n      this.listener?.emit('documentSet', this.draw.getDocument())\r\n      this.listener?.emit('contentChange')\r\n    }\r\n    // 撤销后通知：选区样式变更 + 能力变更（canUndo/canRedo 可能变化）\r\n    this.listener?.emit('formatChange', this.getRangeStyle())\r\n    this.listener?.emit('abilityChange', this.getAbility())\r\n  }\r\n\r\n  /** 重做下一步操作，恢复历史快照并通知选区样式与能力变更。 */\r\n  redo(): void {\r\n    if (!this.getIsCanInput()) return\r\n    if (!this._historyManager) return\r\n    const current: HistorySnapshot = {\r\n      doc: cloneTree(this.draw.getDocument()),\r\n      range: this.range.getRange(),\r\n      zone: this.draw.getZone()\r\n    }\r\n    const next = this._historyManager.redo(current)\r\n    if (next) {\r\n      this.range.clear()\r\n      this.draw.setZone(next.zone ?? 'main')\r\n      this.draw.setDocument(cloneTree(next.doc))\r\n      if (next.range) this.range.setRange(cloneTree(next.range))\r\n      else this.range.clear()\r\n      this.listener?.emit('documentSet', this.draw.getDocument())\r\n      this.listener?.emit('contentChange')\r\n    }\r\n    // 重做后通知：选区样式变更 + 能力变更\r\n    this.listener?.emit('formatChange', this.getRangeStyle())\r\n    this.listener?.emit('abilityChange', this.getAbility())\r\n  }\r\n\r\n  /* -------------------- 区域切换 -------------------- */\r\n\r\n  /**\r\n   * 切换编辑区域。切换到页眉/页脚时，将光标定位到对应区域的起始文本位置；\r\n   * 切回正文时清空选区，由后续点击/键盘事件重新定位。\r\n   * @param zone 区域：'main' | 'header' | 'footer'\r\n   */\r\n  setZone(zone: Zone): void {\r\n    this.draw.setZoneWithCaret(zone)\r\n  }\r\n\r\n  /** 清除页眉内容并回到正文 */\r\n  clearHeader(): void {\r\n    if (!this.getIsCanInput()) return\r\n    this.setZone('header')\r\n    this.selectAll()\r\n    this.deleteBackward()\r\n    this.setZone('main')\r\n  }\r\n\r\n  /** 清除页脚内容并回到正文 */\r\n  clearFooter(): void {\r\n    if (!this.getIsCanInput()) return\r\n    this.setZone('footer')\r\n    this.selectAll()\r\n    this.deleteBackward()\r\n    this.setZone('main')\r\n  }\r\n\r\n  /**\r\n   * 原位更新当前页眉/页脚中的真实页码域，兼容仅传样式或位置的调用。\n   * @param payload 页码配置对象\r\n   */\r\n  setPageNumber(payload: Record<string, unknown>): void {\r\n    if (!this.getIsCanInput()) return\r\n    const previousZone = this.draw.getZone()\n    const previous = this.draw.getOptions().pageNumber as Record<string, unknown> | undefined\n    const zone = payload.zone ?? previous?.zone ?? (previousZone === 'header' ? 'header' : 'footer')\n    if (zone !== 'header' && zone !== 'footer') return\n    this.draw.setZone(zone)\n    const doc = this.draw.getActiveDocument()\n    const current = collectPageFields(doc.elements).find(field => field.type === 'PAGE')\n    const requestedStyle = payload.style ?? previous?.style\n    const style = requestedStyle == null ? undefined : String(requestedStyle)\n    const position = payload.position ?? previous?.position ?? current?.results[0]?.rowFlex ?? 'center'\n    if (position !== 'left' && position !== 'center' && position !== 'right') {\n      this.draw.setZone(previousZone)\n      return\n    }\n    // 旧配置属于独立绘制层；转为真实文档域后必须关闭，避免重复显示。\n    if (previous) this.draw.updateOptions({ pageNumber: null })\n    updatePageFields(doc.elements, style, position)\n    this.range.clear()\n    this._commit(doc)\n    if (previousZone !== zone) this.draw.setZone(previousZone)\n  }\r\n\r\n  /**\r\n\r\n   * 获取当前编辑区域。\r\n   * @returns 区域：'main' | 'header' | 'footer'\r\n   */\r\n  getZone(): Zone {\r\n    return this.draw.getZone()\r\n  }\r\n\r\n  /* -------------------- 选区 / 全选 -------------------- */\r\n\r\n  /** 选中当前活动文档的全部内容。 */\r\n  selectAll(): void {\r\n    const doc = this.draw.getActiveDocument()\r\n    const runs: { path: Path }[] = []\r\n    walkTree(doc.elements, (node, ctx) => {\r\n      if (node.type === 'text') {\r\n        runs.push({ path: ctx.path.slice() as Path })\r\n      }\r\n    })\r\n    if (runs.length === 0) return\r\n    const first = runs[0]\r\n    const last = runs[runs.length - 1]\r\n    const lastNode = getByPath(doc.elements, last.path) as ITextElement | null\r\n    const endOffset = lastNode ? lastNode.value.length : 0\r\n    this.range.setRange({\r\n      anchor: { path: first.path, offset: 0 },\r\n      focus: { path: last.path, offset: endOffset }\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 按起止 run 索引设置选区范围。\r\n   * @param startIndex 起始 run 索引\r\n   * @param endIndex 结束 run 索引\r\n   */\r\n  setRange(startIndex: number, endIndex: number): void {\r\n    const doc = this.draw.getActiveDocument()\r\n    const runs: { path: Path }[] = []\r\n    walkTree(doc.elements, (node, ctx) => {\r\n      if (node.type === 'text') {\r\n        runs.push({ path: ctx.path.slice() as Path })\r\n      }\r\n    })\r\n    if (runs.length === 0) return\r\n    const startIdx = Math.max(0, Math.min(startIndex, runs.length - 1))\r\n    const endIdx = Math.max(0, Math.min(endIndex, runs.length - 1))\r\n    const startPath = runs[startIdx].path\r\n    const endPath = runs[endIdx].path\r\n    const endNode = getByPath(doc.elements, endPath) as ITextElement | null\r\n    const endOffset = endNode ? endNode.value.length : 0\r\n    this.range.setRange({\r\n      anchor: { path: startPath, offset: 0 },\r\n      focus: { path: endPath, offset: endOffset }\r\n    })\r\n  }\r\n\r\n  /* -------------------- 插入元素列表 -------------------- */\r\n\r\n  /**\r\n   * 在当前光标处插入元素列表，若存在选区则先删除选区。\r\n   * @param elements 待插入的元素数组\r\n   */\r\n  insertElementList(elements: IElement[]): void {\r\n    if (!this.getIsCanInput()) return\r\n    if (!elements || elements.length === 0) return\r\n    if (elements.some(element => this.isSectionBoundary(element))) {\r\n      throw new TypeError('粘贴分节符必须通过 pasteFragment 同时传入 sections')\r\n    }\r\n    this.deleteSelection()\r\n    const doc = this.draw.getActiveDocument()\r\n    const pos = this.range.getFocus() ?? { path: [doc.elements.length], offset: 0 }\r\n    const inserted = cloneTree(elements)\r\n    this.remapParagraphIdentities(inserted, doc.elements)\r\n    for (const cloned of inserted) {\r\n      if (cloned.type === 'text') {\r\n        const textEl = cloned as ITextElement\r\n        const node = getByPath(doc.elements, pos.path)\r\n        if (node && node.type === 'text') {\r\n          const t = node as ITextElement\r\n          const before = t.value.slice(0, pos.offset)\r\n          const after = t.value.slice(pos.offset)\r\n          t.value = before + textEl.value + after\r\n          pos.offset += textEl.value.length\r\n        } else {\r\n          const parent = pos.path.length === 1 ? doc.elements : getParentContainer(doc.elements, pos.path)\r\n          if (parent) {\r\n            const idx = (pos.path[pos.path.length - 1] as number) + 1\r\n            parent.splice(idx, 0, cloned)\r\n            pos.path = [...pos.path.slice(0, -1), idx] as Path\r\n            pos.offset = 0\r\n          }\r\n        }\r\n      } else {\r\n        const parent = pos.path.length === 1 ? doc.elements : getParentContainer(doc.elements, pos.path)\r\n        if (parent) {\r\n          const idx = (pos.path[pos.path.length - 1] as number) + 1\r\n          parent.splice(idx, 0, cloned)\r\n          pos.path = [...pos.path.slice(0, -1), idx] as Path\r\n          pos.offset = 0\r\n        }\r\n      }\r\n    }\r\n    this.range.setCaret({ path: pos.path.slice() as Path, offset: pos.offset })\r\n    // 不可迁移：前置 deleteSelection() 可能已 commit\r\n    this._commit(doc, 'text')\r\n  }\r\n\r\n  /** 为复制元素重新分配不冲突的段落 ID，并同步图片锚点；未复制的锚定段落改为脱离引用。 */\r\n  private remapParagraphIdentities(elements: IElement[], existing: IElement[]): void {\r\n    const used = new Set<string>()\r\n    const ids = new Map<string, string>()\r\n    walkTree(existing, node => { if (node.sourceParagraphId) used.add(node.sourceParagraphId) })\r\n    walkTree(elements, node => {\r\n      const id = node.sourceParagraphId\r\n      if (!id || ids.has(id)) return\r\n      let next = `${id}-copy`, suffix = 1\r\n      while (used.has(next)) next = `${id}-copy${suffix++}`\r\n      used.add(next)\r\n      ids.set(id, next)\r\n    })\r\n    walkTree(elements, node => {\r\n      if (node.sourceParagraphId) node.sourceParagraphId = ids.get(node.sourceParagraphId)!\r\n      const geometry = (node as IImageElement).imageLayout\r\n      if (geometry?.anchorParagraphId) {\r\n        // A drawing copied without its paragraph must not bind to the original.\r\n        geometry.anchorParagraphId = ids.get(geometry.anchorParagraphId) ?? `${geometry.anchorParagraphId}-detached`\r\n      }\r\n    })\r\n  }\r\n\r\n  /** 判断元素是否为连续、下一页、偶数页或奇数页分节符，不包含普通分页符。 */\r\n  private isSectionBoundary(element: IElement): boolean {\r\n    return element.type === 'pageBreak' && ['continuous', 'nextPage', 'evenPage', 'oddPage'].includes(element.value)\r\n  }\r\n\r\n  /** 按正文闭区间内的分节符移除对应节配置，保留后续节格式并补齐继承的页眉页脚引用。 */\r\n  private removeSectionBoundaries(doc: IDocxDocumentMeta, start: number, end: number): void {\r\n    if (!doc.sections || this.draw.getZone() !== 'main') return\r\n    const index = doc.elements.slice(0, start).filter(element => this.isSectionBoundary(element)).length\r\n    const count = doc.elements.slice(start, end + 1).filter(element => this.isSectionBoundary(element)).length\r\n    // Removing a section break joins into the following section's formatting.\r\n    if (count) {\r\n      const survivor = doc.sections[index + count]\r\n      for (const key of ['headers', 'footers'] as const) {\r\n        survivor[key] = Object.assign({}, ...doc.sections.slice(0, index + count + 1).map(section => section[key]))\r\n      }\r\n      doc.sections.splice(index, count)\r\n    }\r\n  }\r\n\r\n  /** 克隆顶层文本选区及其涉及的节配置、页眉页脚部件，裁剪边界文本；不支持的选区返回 null。 */\r\n  copyFragment(): Partial<IDocxDocumentMeta> | null {\r\n    const ordered = this.range.getOrdered()\r\n    if (!ordered || this.range.isCollapsed() || ordered.start.path.length !== 1 || ordered.end.path.length !== 1) return null\r\n    const doc = this.draw.getActiveDocument()\r\n    const first = Number(ordered.start.path[0]), last = Number(ordered.end.path[0])\r\n    const elements = cloneTree(doc.elements.slice(first, last + 1))\r\n    if (elements[0]?.type !== 'text' || elements[elements.length - 1]?.type !== 'text') return null\r\n    if (first === last) elements[0].value = elements[0].value.slice(ordered.start.offset, ordered.end.offset)\r\n    else {\r\n      elements[0].value = elements[0].value.slice(ordered.start.offset)\r\n      elements[elements.length - 1].value = elements[elements.length - 1].value.slice(0, ordered.end.offset)\r\n    }\r\n    const index = doc.elements.slice(0, first).filter(element => this.isSectionBoundary(element)).length\r\n    const count = elements.filter(element => this.isSectionBoundary(element)).length\r\n    const sections = count ? cloneTree(doc.sections?.slice(index, index + count + 1)) : undefined\r\n    if (sections?.length) for (const key of ['headers', 'footers'] as const) {\r\n      sections[0][key] = Object.assign({}, ...doc.sections!.slice(0, index + 1).map(section => section[key]))\r\n    }\r\n    return { elements, sections, headerFooterParts: count ? cloneTree(doc.headerFooterParts) : undefined }\r\n  }\r\n\r\n  /** 在正文顶层粘贴文档片段并替换选区，重映射段落标识、合并节配置及页眉页脚部件后提交。 */\r\n  pasteFragment(fragment: Partial<IDocxDocumentMeta>): void {\r\n    if (!this.getIsCanInput()) return\r\n    if (!fragment.elements?.length || this.draw.getZone() !== 'main') return\r\n    const boundaries = fragment.elements.filter(element => this.isSectionBoundary(element)).length\r\n    if (boundaries && fragment.sections?.length !== boundaries + 1) throw new TypeError('剪贴板 sections 与分节符数量不一致')\r\n    const focus = this.range.getFocus()\r\n    if (focus && focus.path.length !== 1) return\r\n    this.deleteSelection(false)\r\n    const doc = this.draw.getActiveDocument()\r\n    const pos = this.range.getFocus() ?? { path: [doc.elements.length], offset: 0 }\r\n    const index = Number(pos.path[0])\r\n    const node = doc.elements[index]\r\n    const elements = cloneTree(fragment.elements)\r\n    this.remapParagraphIdentities(elements, doc.elements)\r\n    const sectionIndex = doc.elements.slice(0, index).filter(element => this.isSectionBoundary(element)).length\r\n    if (boundaries) {\r\n      if (!doc.sections?.[sectionIndex]) throw new TypeError('目标文档缺少 sections')\r\n      const sections = cloneTree(fragment.sections!)\r\n      const parts = cloneTree(fragment.headerFooterParts ?? {})\r\n      doc.headerFooterParts ??= {}\r\n      for (const [id, content] of Object.entries(parts)) {\r\n        let target = id\r\n        let suffix = 1\r\n        while (doc.headerFooterParts[target] && JSON.stringify(doc.headerFooterParts[target]) !== JSON.stringify(content)) {\r\n          target = id.replace(/\\.xml$/, '') + `-paste${suffix++}.xml`\r\n        }\r\n        doc.headerFooterParts[target] = content\r\n        for (const section of sections) for (const refs of [section.headers, section.footers]) {\r\n          if (refs) for (const key of Object.keys(refs) as (keyof typeof refs)[]) if (refs[key] === id) refs[key] = target\r\n        }\r\n      }\r\n      doc.sections.splice(sectionIndex, 0, ...sections.slice(0, boundaries))\r\n    }\r\n    const prefix = node?.type === 'text' ? [{ ...node, value: node.value.slice(0, pos.offset) }] : []\r\n    const suffix = node?.type === 'text' ? [{ ...node, value: node.value.slice(pos.offset) }] : []\r\n    doc.elements.splice(index, node?.type === 'text' ? 1 : 0, ...prefix, ...elements, ...suffix)\r\n    const caretIndex = index + prefix.length + elements.length - (suffix.length ? 0 : 1)\r\n    const caretNode = doc.elements[caretIndex]\r\n    this.range.setCaret({ path: [caretIndex], offset: suffix.length ? 0 : caretNode.type === 'text' ? caretNode.value.length : 0 })\r\n    this._commit(doc)\r\n  }\r\n\r\n  /* -------------------- 剪贴板 -------------------- */\r\n\r\n  /**\r\n   * 复制当前选区文本。\r\n   * @returns 选区纯文本\r\n   */\r\n  copy(): string {\r\n    return this.extractSelectionText()\r\n  }\r\n\r\n  /**\r\n   * 剪切当前选区文本并删除选区。\r\n   * @returns 选区纯文本\r\n   */\r\n  cut(): string {\r\n    const text = this.extractSelectionText()\r\n    this.deleteSelection()\r\n    return text\r\n  }\r\n\r\n  /**\r\n   * 粘贴文本（等同于插入文本）。\r\n   * @param text 待粘贴文本\r\n   */\r\n  paste(text: string): void {\r\n    this.insertText(text)\r\n  }\r\n\r\n  /**\r\n   * 粘贴纯文本（等同于插入文本）。\r\n   * @param text 待粘贴文本\r\n   */\r\n  pastePlain(text: string): void {\r\n    this.insertText(text)\r\n  }\r\n\r\n  /* -------------------- run 扩展样式 -------------------- */\r\n\r\n  /** 切换选区内 run 的上标样式（与下标互斥）。 */\r\n  setSuperscript(): void {\r\n    this.mutateRuns(run => {\r\n      const r = run as unknown as Record<string, unknown>\r\n      r.superscript = !r.superscript\r\n      if (r.superscript) r.subscript = false\r\n    }, 'superscript' as keyof ITextElement)\r\n  }\r\n\r\n  /** 切换选区内 run 的下标样式（与上标互斥）。 */\r\n  setSubscript(): void {\r\n    this.mutateRuns(run => {\r\n      const r = run as unknown as Record<string, unknown>\r\n      r.subscript = !r.subscript\r\n      if (r.subscript) r.superscript = false\r\n    }, 'subscript' as keyof ITextElement)\r\n  }\r\n\r\n  /**\r\n   * 设置选区内 run 的字符缩放比例。\r\n   * @param value 缩放比例\r\n   */\r\n  setCharacterScale(value: number): void {\r\n    this.mutateRuns(run => {\r\n      (run as unknown as Record<string, unknown>).characterScale = value\r\n    })\r\n  }\r\n\r\n  /** Normalize ruler positions to the layout engine's first-line/hanging model. */\r\n  setRulerIndent(first: number, left: number, right: number): void {\r\n    if (![first, left, right].every(Number.isFinite)) return\r\n    first = Math.max(0, first)\r\n    left = Math.max(0, left)\r\n    right = Math.max(0, right)\r\n    this.execute(doc => {\r\n      const pos = this.range.getFocus()\r\n      if (!pos) return false\r\n      const parent = getParentContainer(doc.elements, pos.path)\r\n      if (!parent) return false\r\n      const cursorIdx = pos.path[pos.path.length - 1] as number\r\n      const group = splitParagraphs(parent).find(g => cursorIdx >= g.start && cursorIdx < g.end)\r\n      if (!group) return false\r\n      const targets = group.block ? [group.block, ...group.runs] : group.runs\r\n      this.formatElements(targets, target => {\r\n        Object.assign(target, {\r\n          paragraphIndentLeft: left,\r\n          paragraphIndentRight: right,\r\n          paragraphFirstLineIndent: first - left,\r\n          indentHanging: undefined\r\n        })\r\n      })\r\n      return\r\n    })\r\n  }\r\n\r\n  /* -------------------- 段落首行缩进 -------------------- */\r\n\r\n  /**\r\n   * 设置当前段落的首行缩进。\r\n   * @param indentPx 缩进像素值\r\n   */\r\n  setParagraphFirstLineIndent(indentPx: number): void {\r\n    this.execute(doc => {\r\n      const pos = this.range.getFocus()\r\n      if (!pos) return false\r\n      const parent = getParentContainer(doc.elements, pos.path)\r\n      if (!parent) return false\r\n      const cursorIdx = pos.path[pos.path.length - 1] as number\r\n      const groups = splitParagraphs(parent)\r\n      for (const g of groups) {\r\n        if (cursorIdx < g.start || cursorIdx >= g.end) continue\r\n        const targets = g.block ? [g.block, ...g.runs] : g.runs\r\n        this.formatElements(targets, r => {\r\n          (r as unknown as Record<string, unknown>).paragraphFirstLineIndent = indentPx\r\n          delete (r as unknown as Record<string, unknown>).indentHanging\r\n        })\r\n        return\r\n      }\r\n      return false\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 获取当前段落的首行缩进值。\r\n   * @returns 首行缩进像素值\r\n   */\r\n  getFirstLineIndent(): number {\r\n    const doc = this.draw.getActiveDocument()\r\n    const pos = this.range.getFocus()\r\n    if (!pos) return 0\r\n    const parent = getParentContainer(doc.elements, pos.path)\r\n    if (!parent) return 0\r\n    const cursorIdx = pos.path[pos.path.length - 1] as number\r\n    const groups = splitParagraphs(parent)\r\n    for (const g of groups) {\r\n      if (cursorIdx < g.start || cursorIdx >= g.end) continue\r\n      const target = g.block ?? g.runs[0]\r\n      if (!target) return 0\r\n      const attrs = target as unknown as Record<string, unknown>\r\n      return attrs.indentHanging != null ? -Number(attrs.indentHanging) : Number(attrs.paragraphFirstLineIndent ?? 0)\r\n    }\r\n    return 0\r\n  }\r\n\r\n  /**\r\n   * 按方向执行首行缩进步进（步长 20 像素，下限 0）。\r\n   * @param direction 方向：'add' | 'sub'\r\n   */\r\n  indentStep(direction: 'add' | 'sub'): void {\r\n    const step = 20\r\n    const current = this.getFirstLineIndent()\r\n    const next = direction === 'add' ? current + step : Math.max(0, current - step)\r\n    this.setParagraphFirstLineIndent(next)\r\n  }\r\n\r\n  /* -------------------- 段落属性通用读写 -------------------- */\r\n\r\n  /**\r\n   * 设置当前段落的指定属性值。\r\n   * @param key 属性名（如 paragraphIndentLeft）\r\n   * @param value 属性值\r\n   */\r\n  private setParagraphAttr(key: string, value: number): void {\r\n    this.execute(doc => {\r\n      const pos = this.range.getFocus()\r\n      if (!pos) return false\r\n      const parent = getParentContainer(doc.elements, pos.path)\r\n      if (!parent) return false\r\n      const cursorIdx = pos.path[pos.path.length - 1] as number\r\n      const groups = splitParagraphs(parent)\r\n      for (const g of groups) {\r\n        if (cursorIdx < g.start || cursorIdx >= g.end) continue\r\n        const targets = g.block ? [g.block, ...g.runs] : g.runs\r\n        this.formatElements(targets, r => {\r\n          (r as unknown as Record<string, unknown>)[key] = value\r\n        })\r\n        return\r\n      }\r\n      return false\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 获取当前段落的指定属性值。\r\n   * @param key 属性名\r\n   * @returns 属性数值\r\n   */\r\n  private getParagraphAttr(key: string): number {\r\n    const doc = this.draw.getActiveDocument()\r\n    const pos = this.range.getFocus()\r\n    if (!pos) return 0\r\n    const parent = getParentContainer(doc.elements, pos.path)\r\n    if (!parent) return 0\r\n    const cursorIdx = pos.path[pos.path.length - 1] as number\r\n    const groups = splitParagraphs(parent)\r\n    for (const g of groups) {\r\n      if (cursorIdx < g.start || cursorIdx >= g.end) continue\r\n      const target = g.block ?? g.runs[0]\r\n      if (!target) return 0\r\n      return Number((target as unknown as Record<string, unknown>)[key] ?? 0)\r\n    }\r\n    return 0\r\n  }\r\n\r\n  /* -------------------- 左/右缩进 -------------------- */\r\n\r\n  /** 设置左缩进（px） */\r\n  setParagraphIndentLeft(px: number): void { this.setParagraphAttr('paragraphIndentLeft', px) }\r\n  /** 获取左缩进（px） */\r\n  getParagraphIndentLeft(): number { return this.getParagraphAttr('paragraphIndentLeft') }\r\n\r\n  /** 设置右缩进（px） */\r\n  setParagraphIndentRight(px: number): void { this.setParagraphAttr('paragraphIndentRight', px) }\r\n  /** 获取右缩进（px） */\r\n  getParagraphIndentRight(): number { return this.getParagraphAttr('paragraphIndentRight') }\r\n\r\n  /* -------------------- 段前/段后间距 -------------------- */\r\n\r\n  /** 设置段前间距（px） */\r\n  setParagraphSpacingBefore(px: number): void { this.setParagraphAttr('paragraphSpacingBefore', px) }\r\n  /** 获取段前间距（px） */\r\n  getParagraphSpacingBefore(): number { return this.getParagraphAttr('paragraphSpacingBefore') }\r\n\r\n  /** 设置段后间距（px） */\r\n  setParagraphSpacingAfter(px: number): void { this.setParagraphAttr('paragraphSpacingAfter', px) }\r\n  /** 获取段后间距（px） */\r\n  getParagraphSpacingAfter(): number { return this.getParagraphAttr('paragraphSpacingAfter') }\r\n\r\n  /**\r\n   * 获取当前选区范围。\r\n   * @returns 选区范围对象，无选区时返回 null\r\n   */\r\n  getRange(): IRange | null {\r\n    return this.range.getRange()\r\n  }\r\n\r\n  /**\r\n   * 获取是否只读状态。\r\n   * @returns 是否只读\r\n   */\r\n  getIsReadonly(): boolean {\r\n    return !!this.draw.getOptions().readonly\r\n  }\r\n\r\n  /**\r\n   * 获取是否禁用状态。\r\n   * @returns 是否禁用\r\n   */\r\n  getIsDisabled(): boolean {\r\n    return !!this.draw.getOptions().disabled\r\n  }\r\n\r\n  /**\r\n   * 获取是否可输入状态（非只读且非禁用）。\r\n   * @returns 是否可输入\r\n   */\r\n  getIsCanInput(): boolean {\r\n    return !this.getIsReadonly() && !this.getIsDisabled()\r\n  }\r\n\r\n  /**\r\n   * 获取当前选区样式快照（bold/italic/underline 等回显状态）\r\n   * @returns 选区样式状态对象\r\n   */\r\n  getRangeStyle(): IRangeStyle {\r\n    const doc = this.draw.getActiveDocument()\r\n    const pos = this.range.getFocus()\r\n\r\n    /** 默认样式快照 */\r\n    const defaultStyle: IRangeStyle = {\r\n      hasSelection: !this.range.isCollapsed(),\r\n      type: null, bold: false, italic: false, underline: false, strikeout: false,\r\n      doubleStrikeout: false, hidden: false, superscript: false, subscript: false,\r\n      color: '', highlight: '', font: '', size: 0, level: null,\r\n      rowFlex: 'left', lineHeight: 1.5, lineHeightRule: 'auto', paragraphFirstLineIndent: 0,\r\n      characterScale: 100, painter: !!this._paintFmt,\r\n      undo: this.getIsCanInput() && (this._historyManager?.canUndo() ?? false),\r\n      redo: this.getIsCanInput() && (this._historyManager?.canRedo() ?? false)\r\n    }\r\n\r\n    if (!pos) return defaultStyle\r\n\r\n    const parent = getParentContainer(doc.elements, pos.path)\r\n    if (!parent) return defaultStyle\r\n\r\n    const cursorIdx = pos.path[pos.path.length - 1] as number\r\n    const el = parent[cursorIdx] as Record<string, unknown> | undefined\r\n    if (!el) return defaultStyle\r\n\r\n    // 段落级属性：从段落第一个有该属性的元素获取（光标所在元素可能缺少段落级属性）\r\n    const groups = splitParagraphs(parent)\r\n    let paraEl: Record<string, unknown> = el\r\n    for (const g of groups) {\r\n      if (cursorIdx < g.start || cursorIdx >= g.end) continue\r\n      for (const r of g.runs) {\r\n        const candidate = r as Record<string, unknown>\r\n        if (candidate.rowFlex !== undefined) {\r\n          paraEl = candidate\r\n          break\r\n        }\r\n      }\r\n      break\r\n    }\r\n\r\n    const titlePath = this.getTitlePath(doc.elements, pos.path)\r\n    const title = titlePath ? getByPath(doc.elements, titlePath) as ITitleElement : null\r\n    return {\r\n      hasSelection: !this.range.isCollapsed(),\r\n      type: (el.type as string) ?? null,\r\n      bold: !!el.bold,\r\n      italic: !!el.italic,\r\n      underline: !!el.underline,\r\n      strikeout: !!el.strikeout,\r\n      doubleStrikeout: !!el.doubleStrikeout,\r\n      hidden: !!el.hidden,\r\n      superscript: !!el.superscript,\r\n      subscript: !!el.subscript,\r\n      color: (el.color as string) ?? '',\r\n      highlight: (el.highlight as string) ?? '',\r\n      font: (el.font as string) ?? '',\r\n      size: Math.round(((el.size as number) ?? 0) * (72 / 96) * 2) / 2,\r\n      level: title?.level ?? null,\r\n      rowFlex: (paraEl.rowFlex as string) ?? 'left',\r\n      lineHeight: (paraEl.lineHeight as number) ?? 1.5,\r\n      lineHeightRule: (paraEl.lineHeightRule as string) ?? 'auto',\r\n      paragraphFirstLineIndent: (paraEl.paragraphFirstLineIndent as number) ?? 0,\r\n      characterScale: (el.characterScale as number) ?? 100,\r\n      painter: !!this._paintFmt,\r\n      undo: this.getIsCanInput() && (this._historyManager?.canUndo() ?? false),\r\n      redo: this.getIsCanInput() && (this._historyManager?.canRedo() ?? false)\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 获取光标所在行/列信息（基于布局可视行计数）\r\n   * @returns 行列信息，-1 表示无有效光标\r\n   */\r\n  getRangeContext(): { startRowNo: number; startColNo: number } {\r\n    const pos = this.range.getFocus()\r\n    const layout = this.draw.getLayout()\r\n    if (!pos || !layout) return { startRowNo: -1, startColNo: -1 }\r\n\r\n    let rowNo = 0\r\n    for (const page of layout.pages) {\r\n      const result = this.findRowColInBlocks(page.blocks, pos, rowNo)\r\n      if (result) return result\r\n    }\r\n    return { startRowNo: -1, startColNo: -1 }\r\n  }\r\n\r\n  /**\r\n   * 在布局块中查找光标所在行/列信息。\r\n   * @param blocks 布局块数组\r\n   * @param pos 光标位置\r\n   * @param startRow 起始行号\r\n   * @returns 行列信息对象；未找到时返回 null\r\n   */\r\n  private findRowColInBlocks(blocks: BlockNode[], pos: IPosition, startRow: number): { startRowNo: number; startColNo: number } | null {\r\n    let rowNo = startRow\r\n    for (const b of blocks) {\r\n      if (b.kind === 'paragraph') {\r\n        for (const line of b.lines) {\r\n          for (const inl of line.inlines) {\r\n            if (isSamePath(inl.path, pos.path) && pos.offset >= inl.startOffset && pos.offset <= inl.endOffset) {\r\n              let colNo = 0\r\n              for (const prev of line.inlines) {\r\n                if (prev === inl) {\r\n                  colNo += pos.offset - prev.startOffset\r\n                  break\r\n                }\r\n                colNo += prev.text.length\r\n              }\r\n              return { startRowNo: rowNo, startColNo: colNo }\r\n            }\r\n          }\r\n          rowNo++\r\n        }\r\n      } else if (b.kind === 'table') {\r\n        for (const row of b.rows) {\r\n          let maxLinesInRow = 1\r\n          for (const cell of row.cells) {\r\n            const cellLines = this.countLinesInBlocks(cell.content)\r\n            const result = this.findRowColInBlocks(cell.content, pos, rowNo)\r\n            if (result) return result\r\n            if (cellLines > maxLinesInRow) maxLinesInRow = cellLines\r\n          }\r\n          rowNo += maxLinesInRow\r\n        }\r\n      }\r\n    }\r\n    return null\r\n  }\r\n\r\n  /**\r\n   * 统计布局块中的行数（表格按各行最大行数累加）。\r\n   * @param blocks 布局块数组\r\n   * @returns 行数总计\r\n   */\r\n  private countLinesInBlocks(blocks: BlockNode[]): number {\r\n    let count = 0\r\n    for (const b of blocks) {\r\n      if (b.kind === 'paragraph') {\r\n        count += b.lines.length\r\n      } else if (b.kind === 'table') {\r\n        for (const row of b.rows) {\r\n          let maxLinesInRow = 1\r\n          for (const cell of row.cells) {\r\n            const cellLines = this.countLinesInBlocks(cell.content)\r\n            if (cellLines > maxLinesInRow) maxLinesInRow = cellLines\r\n          }\r\n          count += maxLinesInRow\r\n        }\r\n      }\r\n    }\r\n    return count\r\n  }\r\n\r\n  /**\r\n   * 获取编辑器能力状态快照（readonly/disabled/canUndo/canRedo）\r\n   * @returns 能力状态对象\r\n   */\r\n  getAbility(): IEditorAbility {\r\n    return {\r\n      readonly: this.getIsReadonly(),\r\n      disabled: this.getIsDisabled(),\r\n      canInput: this.getIsCanInput(),\r\n      canUndo: this.getIsCanInput() && (this._historyManager?.canUndo() ?? false),\r\n      canRedo: this.getIsCanInput() && (this._historyManager?.canRedo() ?? false)\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 设置编辑器模式（paging/continuity/readonly/edit），并通知能力变更。\r\n   * @param mode 模式字符串\r\n   */\r\n  setMode(mode: string): void {\r\n    if (mode === 'paging' || mode === 'continuity') {\r\n      this.draw.updateOptions({ pageMode: mode })\r\n    } else if (mode === 'readonly') {\r\n      this._paintFmt = null\r\n      this.draw.updateOptions({ readonly: true } as Partial<IEditorOption>)\r\n    } else if (mode === 'edit') {\r\n      this.draw.updateOptions({ readonly: false } as Partial<IEditorOption>)\r\n    }\r\n    // 模式切换后通知能力变更（readonly/disabled 状态可能变化）\r\n    this.listener?.emit('formatChange', this.getRangeStyle())\r\n    this.listener?.emit('abilityChange', this.getAbility())\r\n  }\r\n\r\n  /**\r\n   * 预览 HTML 内容（调用 options.previewCallback）。\r\n   * @param payload 预览参数\r\n   */\r\n  previewHtml(payload: any): void {\r\n    const cb = this.draw.getOptions().previewCallback as ((data: any, opts?: any) => void) | undefined\r\n    if (cb) {\r\n      cb(this.draw.getDocument(), payload)\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 替换当前选区范围。\r\n   * @param range 新的选区范围，可为 null\r\n   */\r\n  replaceRange(range: IRange | null): void {\r\n    this.range.setRange(range)\r\n  }\r\n\r\n  /** 将当前选区内的元素标记为同一群组，返回 groupId 或 null。 */\r\n  setGroup(update?: (doc: IDocxDocumentMeta, groupId: string) => void): string | null {\r\n    if (!this.getIsCanInput()) return null\r\n    const doc = this.draw.getActiveDocument()\r\n    const ordered = this.range.getOrdered()\r\n    if (!ordered || this.range.isCollapsed()) return null\r\n    const adjusted = this.splitBoundaryRuns(doc, ordered.start, ordered.end)\r\n    const startRun = getByPath(doc.elements, adjusted.start.path)\r\n    const endRun = getByPath(doc.elements, adjusted.end.path)\r\n    const runs = this.collectRunsInRange(doc.elements, adjusted.start, adjusted.end).filter(run =>\r\n      run.value.length > 0 &&\r\n      (run !== startRun || adjusted.start.offset < run.value.length) &&\r\n      (run !== endRun || adjusted.end.offset > 0)\r\n    )\r\n    if (!runs.length) return null\r\n\r\n    const groupId = `g_${Date.now()}`\r\n    for (const run of runs) {\r\n      run.groupIds = [...(run.groupIds ?? []), groupId]\r\n    }\r\n    this.range.setRange({ anchor: adjusted.start, focus: adjusted.end })\r\n    update?.(this.draw.getDocument(), groupId)\r\n    this._commit(doc)\r\n    return groupId\r\n  }\r\n\r\n  /**\r\n   * 定位到指定群组的第一个元素。\r\n   * @param id 群组 ID\r\n   */\r\n  locationGroup(id: string): void {\r\n    const doc = this.draw.getActiveDocument()\r\n    for (let i = 0; i < doc.elements.length; i++) {\r\n      const el = doc.elements[i]\r\n      if ((el as unknown as Record<string, unknown>).groupId === id) {\r\n        this.range.setCaret({ path: [i], offset: 0 })\r\n        return\r\n      }\r\n    }\r\n  }\r\n\r\n  /* -------------------- 表格边框 -------------------- */\r\n\r\n  /** 根据单元格跨行跨列关系枚举有效单元格的四条边，标记内外边框及边序号。 */\r\n  private tableBorderSides(table: ITableElement) {\r\n    const sides: { cell: ITd; side: 'top' | 'right' | 'bottom' | 'left'; external: boolean; index: number }[] = []\r\n    const occupied: number[] = []\r\n    table.trList.forEach((row, r) => {\r\n      let col = 0\r\n      row.tdList.forEach(cell => {\r\n        if (cell.merged) return\r\n        while ((occupied[col] ?? 0) > r) col++\r\n        const span = Math.max(1, cell.colspan || 1)\r\n        const rowSpan = Math.max(1, cell.rowspan || 1)\r\n        const external = [r === 0, col + span >= table.colgroup.length, r + rowSpan >= table.trList.length, col === 0]\r\n        ;(['top', 'right', 'bottom', 'left'] as const).forEach((side, index) => {\r\n          sides.push({ cell, side, external: external[index], index })\r\n        })\r\n        for (let c = col; c < col + span; c++) occupied[c] = r + rowSpan\r\n        col += span\r\n      })\r\n    })\r\n    return sides\r\n  }\r\n\r\n  /** 根据边的方向及内外位置，判断指定边框预设是否应显示该边。 */\r\n  private matchesBorderPreset(type: TableBorderPreset, side: 'top' | 'right' | 'bottom' | 'left', external: boolean): boolean {\r\n    if (type === 'all') return true\r\n    if (type === 'outside') return external\r\n    if (type === 'inside') return !external\r\n    if (type === 'inside-horizontal') return !external && (side === 'top' || side === 'bottom')\r\n    if (type === 'inside-vertical') return !external && (side === 'left' || side === 'right')\r\n    return external && type === side\r\n  }\r\n\r\n  /** 汇总光标所在表格的边框预设、统一颜色及内外线宽，混合属性为 undefined，无表格时返回 null。 */\r\n  getTableBorders(): { type?: TableBorderPreset; color?: string; width?: number; externalWidth?: number } | null {\r\n    const pos = this.range.getFocus()\r\n    const table = pos && this._findEnclosingTable(this.draw.getActiveDocument().elements, pos.path)\r\n    if (!table) return null\r\n    const sides = this.tableBorderSides(table)\r\n    const visible = (s: typeof sides[number]) => s.cell.borderTypes?.[s.index] !== 0 &&\r\n      !!s.cell.borderStyle?.[s.side] && s.cell.borderStyle[s.side].style !== 'none' && s.cell.borderStyle[s.side].width > 0\r\n    const uniform = <T>(values: T[]): T | undefined => values.length && values.every(v => v === values[0]) ? values[0] : undefined\r\n    const shown = sides.filter(visible)\r\n    return {\r\n      type: shown.length === 0 ? 'none' : shown.length === sides.length ? 'all'\r\n        : Object.values(TableBorder).find(type => sides.every(s => visible(s) === this.matchesBorderPreset(type, s.side, s.external))),\r\n      color: uniform(shown.map(s => s.cell.borderStyle[s.side].color.replace(/^#([\\da-f])([\\da-f])([\\da-f])$/i, '#$1$1$2$2$3$3'))),\r\n      width: uniform(shown.filter(s => !s.external).map(s => s.cell.borderStyle[s.side].width)),\r\n      externalWidth: uniform(shown.filter(s => s.external).map(s => s.cell.borderStyle[s.side].width))\r\n    }\r\n  }\r\n\r\n  /** 按补丁更新光标所在表格各边的可见性、颜色及内外线宽，并同步 Office 边框属性。 */\r\n  setTableBorders(patch: { type?: TableBorderPreset; color?: string; width?: number; externalWidth?: number }): void {\r\n    if (patch.type !== undefined && !Object.values(TableBorder).includes(patch.type)) return\r\n    if (!Object.values(patch).some(v => v !== undefined)) return\r\n    this.execute(doc => {\r\n      const pos = this.range.getFocus()\r\n      const table = pos && this._findEnclosingTable(doc.elements, pos.path)\r\n      if (!table) return false\r\n      for (const { cell, side, external, index } of this.tableBorderSides(table)) {\r\n        const previous = cell.borderStyle?.[side]\r\n        const border = { ...(previous ?? { width: 1, color: '#000000', style: 'solid' as const }) }\r\n        if (patch.type !== undefined) {\r\n          const show = this.matchesBorderPreset(patch.type, side, external)\r\n          border.style = show ? (border.style === 'none' ? 'solid' : border.style) : 'none'\r\n          if (show && border.width === 0) border.width = 1\r\n          if (cell.borderTypes) cell.borderTypes[index] = show ? 1 : 0\r\n          border.officeType = !show ? 'nil' : previous?.style !== 'none' && previous?.officeType && !['nil', 'none'].includes(previous.officeType)\r\n            ? previous.officeType : border.style === 'solid' ? 'single' : border.style\r\n          border.sizeEighthPoints = Math.round(border.width * 6)\r\n        }\r\n        if (patch.color !== undefined) border.color = patch.color\r\n        const width = external ? patch.externalWidth : patch.width\r\n        if (width !== undefined && Number.isFinite(width) && width >= 0) {\r\n          border.width = width\r\n          border.sizeEighthPoints = Math.round(width * 6)\r\n          if (width === 0) {\r\n            border.style = 'none'\r\n            border.officeType = 'nil'\r\n          }\r\n        }\r\n        border.source = 'cell'\r\n        cell.borderStyle = { ...cell.borderStyle, [side]: border }\r\n      }\r\n      return\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 设置当前光标所在表格的边框类型（none/outside/all 等）。\r\n   * @param type 边框类型字符串\r\n   */\r\n  setTableBorderType(type: string): void {\r\n    const t = String(type || '').trim().toLowerCase()\r\n    const resolved =\r\n      t === 'none' || t === 'empty' || t === 'no' ? 'none'\r\n      : t === 'outside' || t === 'external' || t === 'box' ? 'outside'\r\n      : t === 'all' || t === 'full' || t === '' ? 'all'\r\n      : t\r\n    const preset = Object.values(TableBorder).find(value => value === resolved)\r\n    if (preset) this.setTableBorders({ type: preset })\r\n  }\r\n\r\n  /**\r\n   * 设置当前光标所在表格的边框颜色。\r\n   * @param color 颜色值\r\n   */\r\n  setTableBorderColor(color: string): void {\r\n    this.setTableBorders({ color })\r\n  }\r\n\r\n  /**\r\n   * 设置当前光标所在表格的边框宽度。\r\n   * @param width 宽度数值\r\n   */\r\n  setTableBorderWidth(width: number): void {\r\n    this.setTableBorders({ width, externalWidth: width })\r\n  }\r\n\r\n  /**\r\n   * 设置当前光标所在表格的外部边框宽度。\r\n   * @param width 宽度数值\r\n   */\r\n  setTableBorderExternalWidth(width: number): void {\r\n    this.setTableBorders({ externalWidth: width })\r\n  }\r\n\r\n  /**\r\n   * 沿路径查找包含指定路径的最近表格元素。\r\n   * @param elements 文档元素树\r\n   * @param path 目标路径\r\n   * @returns 包裹该路径的表格元素；不存在时返回 null\r\n   */\r\n  private _findEnclosingTable(elements: IElement[], path: Path): ITableElement | null {\r\n    for (let i = 0; i < path.length; i++) {\r\n      const subPath = path.slice(0, i + 1) as Path\r\n      const node = getByPath(elements, subPath)\r\n      if (node && node.type === 'table') return node as ITableElement\r\n    }\r\n    return null\r\n  }\r\n\r\n\r\n  /* -------------------- 图表 -------------------- */\r\n\r\n  /**\r\n   * 在当前光标处插入图表元素（构造 IBlockElement 嵌套结构）。\r\n   * @param payload 图表参数：chartType/subtype/dataSource/config/width/height\r\n   */\r\n  insertChart(payload: { chartType: string; subtype?: string; dataSource: any; config?: any; width?: number; height?: number }): void {\r\n    this.execute(doc => {\r\n      const pos = this.range.getFocus() ?? { path: [doc.elements.length], offset: 0 }\r\n      const el: IElement = {\r\n        type: 'block',\r\n        value: '',\r\n        id: `chart_${Date.now()}`,\r\n        block: {\r\n          type: 'chart',\r\n          chartBlock: {\r\n            chartType: payload.chartType,\r\n            dataSource: payload.dataSource,\r\n            config: payload.config,\r\n            subtype: payload.subtype\r\n          }\r\n        },\r\n        metrics: {\r\n          width: payload.width ?? 420,\r\n          height: payload.height ?? 320\r\n        }\r\n      } as unknown as IElement\r\n      // chart 是块级元素，始终插入到顶层 doc.elements（光标可能在 title/list/table 等嵌套结构内，\r\n      // 取 path[0] 作为顶层索引，插入到该顶层元素之后）\r\n      const topLevelIndex = (pos.path[0] as number) ?? doc.elements.length\r\n      const idx = Math.min(topLevelIndex + 1, doc.elements.length)\r\n      doc.elements.splice(idx, 0, el)\r\n      return\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 更新指定图表的属性（写入 block.chartBlock）。\r\n   * @param id 图表元素 ID\r\n   * @param patch 属性补丁对象\r\n   */\r\n  updateChart(id: string, patch: Record<string, unknown>): void {\r\n    this.execute(doc => {\r\n      walkTree(doc.elements, (node) => {\r\n        const n = node as unknown as {\r\n          type: string; id?: string\r\n          block?: { type: string; chartBlock?: Record<string, unknown> }\r\n        }\r\n        if (n.type === 'block' && n.id === id && n.block?.type === 'chart' && n.block.chartBlock) {\r\n          Object.assign(n.block.chartBlock, patch)\r\n        }\r\n      })\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 更新指定路径图表块的尺寸（写入 metrics.width/height）。\r\n   * @param path 图表路径\r\n   * @param width 新宽度\r\n   * @param height 新高度\r\n   */\r\n  updateChartSize(path: Path, width: number, height: number): void {\r\n    this.execute(doc => {\r\n      const el = getByPath(doc.elements, path)\r\n      if (!el || el.type !== 'block') return false\r\n      const metrics = (el as unknown as { metrics?: { width: number; height: number } }).metrics\r\n      if (!metrics) return false\r\n      metrics.width = Math.max(1, Math.round(width))\r\n      metrics.height = Math.max(1, Math.round(height))\r\n      return\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 删除指定路径的块元素（图表等）。\r\n   * @param path 块路径\r\n   */\r\n  deleteBlock(path: Path): void {\r\n    this.execute(doc => {\r\n      const parent = getParentContainer(doc.elements, path)\r\n      if (!parent) return false\r\n      const idx = path[path.length - 1]\r\n      if (typeof idx !== 'number' || idx < 0 || idx >= parent.length) return false\r\n      if (parent[idx].type !== 'block') return false\r\n      parent.splice(idx, 1)\r\n      return\r\n    })\r\n  }\r\n\r\n  /* -------------------- 评论组删除 -------------------- */\r\n\r\n  /**\r\n   * 删除指定评论组。\r\n   * @param groupId 评论组 ID\r\n   */\r\n  deleteGroup(groupId: string): void {\r\n    this.execute(doc => {\r\n      walkTree(doc.elements, (node) => {\r\n        const any = node as unknown as Record<string, unknown>\r\n        const ids = any.groupIds as string[] | undefined\r\n        if (ids && ids.includes(groupId)) {\r\n          const next = ids.filter(id => id !== groupId)\r\n          if (next.length === 0) delete any.groupIds\r\n          else any.groupIds = next\r\n        }\r\n        if (any.groupId === groupId) delete any.groupId\r\n      })\r\n      const groups = (doc as unknown as { comments?: { groups?: { id: string }[] } }).comments?.groups\r\n      if (groups) {\r\n        const idx = groups.findIndex(g => g.id === groupId)\r\n        if (idx >= 0) {\r\n          groups.splice(idx, 1)\r\n        }\r\n      }\r\n    })\r\n  }\r\n\r\n  /* -------------------- 内置内容控件 -------------------- */\r\n\r\n  /**\r\n   * 在当前光标位置插入控件。若光标在文本中间则分割文本。\r\n   * @param config 控件配置\r\n   * @param dataValue 初始值（默认 null）\r\n   * @returns 控件实例 ID，失败返回 null\r\n   */\r\n  insertControl(config: IControlConfig, dataValue: ControlDataValue = null): string | null {\r\n    if (!this.getIsCanInput()) return null\r\n    const configValidation = validateControlConfig(config)\r\n    if (!configValidation.valid) return null\r\n\r\n    if (!this.range.isCollapsed() && !this.deleteSelection(false)) return null\r\n    const pos = this.range.getFocus()\r\n    if (!pos) return null\r\n\r\n    const doc = this.draw.getActiveDocument()\r\n    const parent = getParentContainer(doc.elements, pos.path)\r\n    if (!parent) return null\r\n\r\n    const index = Number(pos.path[pos.path.length - 1])\r\n    const controlElement = createControlElement(config, dataValue)\r\n    const currentNode = getByPath(doc.elements, pos.path)\r\n    let insertedIndex = index\r\n\r\n    if (currentNode && currentNode.type === 'text') {\r\n      const t = currentNode as ITextElement\r\n      for (const key of CONTROL_FORMAT_KEYS) {\r\n        if (t[key] !== undefined) {\r\n          ;(controlElement as unknown as Record<string, unknown>)[key] = t[key]\r\n        }\r\n      }\r\n      const before = t.value.slice(0, pos.offset)\r\n      const after = t.value.slice(pos.offset)\r\n      if (before && after) {\r\n        t.value = before\r\n        const afterElement = cloneTree(t)\r\n        afterElement.value = after\r\n        parent.splice(index + 1, 0, controlElement, afterElement)\r\n        insertedIndex = index + 1\r\n      } else if (before) {\r\n        parent.splice(index + 1, 0, controlElement)\r\n        insertedIndex = index + 1\r\n      } else if (after) {\r\n        parent.splice(index, 0, controlElement)\r\n      } else {\r\n        parent.splice(index, 1, controlElement)\r\n      }\r\n    } else {\r\n      insertedIndex = index + (currentNode && isControl(currentNode) && pos.offset === 0 ? 0 : 1)\r\n      parent.splice(insertedIndex, 0, controlElement)\r\n    }\r\n\r\n    this.range.setCaret({ path: [...pos.path.slice(0, -1), insertedIndex], offset: 1 })\r\n    this._commit(doc)\r\n    return controlElement.id ?? null\r\n  }\r\n\r\n  /**\r\n   * 更新控件值。先校验，校验失败不修改文档。\r\n   * @param controlId 控件实例 ID\r\n   * @param newDataValue 新业务值\r\n   * @returns 是否成功更新\r\n   */\r\n  updateControlValue(controlId: string, newDataValue: ControlDataValue): boolean {\r\n    let success = false\r\n    this.execute(doc => {\r\n      let found = false\r\n      walkTree(doc.elements, (node) => {\r\n        if (isControl(node) && node.id === controlId) {\r\n          if (node.control.readOnly) return false\r\n          // 编辑时允许清空必填控件，配置及独立验证的必填约束保持不变。\r\n          const config = isEmptyValue(node.control.kind, newDataValue)\r\n            ? { ...node.control, required: false } : node.control\r\n          const validation = validateControlValue(config, newDataValue)\r\n          if (!validation.valid) return false\r\n          const updated = updateControlElementValue(node, newDataValue)\r\n          Object.assign(node, updated)\r\n          found = true\r\n          return false\r\n        }\r\n        return\r\n      })\r\n      success = found\r\n      return found\r\n    })\r\n    return success\r\n  }\r\n\r\n  /**\r\n   * 移除控件。\r\n   * @param controlId 控件实例 ID\r\n   * @param keepContent true=保留子内容（仅移除控件外壳），false=删除控件及内容\r\n   */\r\n  removeControl(controlId: string, keepContent: boolean): void {\r\n    this.execute(doc => {\r\n      let found = false\r\n      walkTree(doc.elements, (node, ctx) => {\r\n        if (isControl(node) && node.id === controlId) {\r\n          if (node.control.removable === false) return false\r\n          if (Array.isArray(ctx.parent)) {\r\n            const parent = ctx.parent as IElement[]\r\n            const idx = ctx.index\r\n            if (keepContent && Array.isArray(node.valueList) && node.valueList.length > 0) {\r\n              parent.splice(idx, 1, ...node.valueList)\r\n            } else {\r\n              parent[idx] = { ...this.controlText(node), value: keepContent ? node.value : '' }\r\n            }\r\n            this.range.setCaret({ path: ctx.path, offset: 0 })\r\n            found = true\r\n            return false\r\n          }\r\n        }\r\n        return\r\n      })\r\n      return found\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 清空控件内容（保留控件本身，值置空）。\r\n   * @param controlId 控件实例 ID\r\n   */\r\n  clearControl(controlId: string): void {\r\n    this.execute(doc => {\r\n      let found = false\r\n      walkTree(doc.elements, (node) => {\r\n        if (isControl(node) && node.id === controlId) {\r\n          if (node.control.readOnly) return false\r\n          const cleared = updateControlElementValue(node, null)\r\n          Object.assign(node, cleared)\r\n          if (Array.isArray(node.valueList)) {\r\n            node.valueList = []\r\n          }\r\n          found = true\r\n          return false\r\n        }\r\n        return\r\n      })\r\n      return found\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 更新控件配置（属性编辑）。\r\n   * @param controlId 控件实例 ID\r\n   * @param newConfig 新配置\r\n   */\r\n  updateControlConfig(controlId: string, newConfig: IControlConfig): boolean {\r\n    let success = false\r\n    this.execute(doc => {\r\n      const configValidation = validateControlConfig(newConfig)\r\n      if (!configValidation.valid) return false\r\n      let found = false\r\n      walkTree(doc.elements, (node) => {\r\n        if (isControl(node) && node.id === controlId) {\r\n          node.control = newConfig\r\n          const updated = updateControlElementValue(node, node.dataValue)\r\n          Object.assign(node, updated)\r\n          found = true\r\n          return false\r\n        }\r\n        return\r\n      })\r\n      success = found\r\n      return found\r\n    })\r\n    return success\r\n  }\r\n\r\n  /**\r\n   * 根据 ID 查找控件元素。\r\n   * @param controlId 控件实例 ID\r\n   * @returns 控件元素或 null\r\n   */\r\n  getControlById(controlId: string): IControlElement | null {\r\n    const doc = this.draw.getActiveDocument()\r\n    let result: IControlElement | null = null\r\n    walkTree(doc.elements, (node) => {\r\n      if (isControl(node) && node.id === controlId) {\r\n        result = node\r\n        return false\r\n      }\r\n      return\r\n    })\r\n    return result\r\n  }\r\n}\r\n","/**\r\n * VerveDocs Transform —— Command 门面\r\n */\r\n\r\nimport type { CommandAdapt } from './command-adapt'\r\nimport type { IElement, Path, IAutoTocResult, IBookmark, IEditorOption, IRange, IDocxDocumentMeta, IControlConfig, ControlDataValue, IControlElement, IPosition, CellTextDirection } from '@vervedoc/docx-editor-schema'\nimport type { IRangeStyle, IEditorAbility } from '@vervedoc/docx-editor-state'\r\n\r\n/**\r\n * Command 命令门面类。\r\n * 作为对外暴露的统一命令入口，将各类编辑操作委托给内部的 CommandAdapt 适配器执行。\r\n */\r\nexport class Command {\r\n  /**\r\n   * 创建 Command 实例。\r\n   * @param adapt 命令适配器实例，负责实际执行各项编辑操作\r\n   */\r\n  constructor(public adapt: CommandAdapt) {}\r\n\r\n  /**\r\n   * 在当前光标位置插入文本。\r\n   * @param text 待插入的文本内容\r\n   */\r\n  executeInsertText(text: string): void { this.adapt.insertText(text) }\r\n  /**\r\n   * 向后删除一个字符（Backspace 键行为）。\r\n   */\r\n  executeDeleteBackward(): void { this.adapt.deleteBackward() }\r\n  /**\r\n   * 向后删除一个字符（Backspace 键行为的别名）。\r\n   */\r\n  executeBackspace(): void { this.adapt.deleteBackward() }\r\n  /**\r\n   * 向前删除一个字符（Delete 键行为）。\r\n   */\r\n  executeDeleteForward(): void { this.adapt.deleteForward() }\r\n  /**\r\n   * 在当前光标处拆分段落。\r\n   */\r\n  executeSplitParagraph(): void { this.adapt.splitParagraph() }\r\n  /**\r\n   * 删除当前选区内容。\r\n   * @returns 是否成功删除\r\n   */\r\n  executeDeleteSelection(): boolean { return this.adapt.deleteSelection() }\r\n  /**\r\n   * 提取当前选区的纯文本内容。\r\n   * @returns 选区文本字符串\r\n   */\r\n  executeExtractSelectionText(): string { return this.adapt.extractSelectionText() }\r\n  /**\r\n   * 将光标向左移动一位。\r\n   */\r\n  executeMoveCaretLeft(): void { this.adapt.moveCaretLeft() }\r\n  /**\r\n   * 将光标向右移动一位。\r\n   */\r\n  executeMoveCaretRight(): void { this.adapt.moveCaretRight() }\r\n  /**\r\n   * 设置行弹性布局。\r\n   * @param f 行弹性布局参数\r\n   */\r\n  executeSetRowFlex(f: Parameters<CommandAdapt['setRowFlex']>[0]): void { this.adapt.setRowFlex(f) }\r\n  /**\r\n   * 设置或切换加粗样式。\r\n   * @param b 是否加粗，省略时为切换语义\r\n   */\r\n  executeSetBold(b?: boolean): void { this.adapt.setBold(b) }\r\n  /**\r\n   * 设置或切换斜体样式。\r\n   * @param b 是否斜体，省略时为切换语义\r\n   */\r\n  executeSetItalic(b?: boolean): void { this.adapt.setItalic(b) }\r\n  /**\r\n   * 设置文字颜色。\r\n   * @param c 颜色值字符串\r\n   */\r\n  executeSetColor(c: string): void { this.adapt.setColor(c) }\r\n  /**\r\n   * 设置字体。\r\n   * @param f 字体名称\r\n   */\r\n  executeSetFont(f: string): void { this.adapt.setFont(f) }\r\n  /**\r\n   * 设置字号。\r\n   * @param s 字号数值\r\n   */\r\n  executeSetSize(s: number): void { this.adapt.setSize(s) }\r\n  /**\r\n   * 增大字号。\r\n   */\r\n  executeSizeAdd(): void { this.adapt.setSizeAdd() }\r\n  /**\r\n   * 减小字号。\r\n   */\r\n  executeSizeMinus(): void { this.adapt.setSizeMinus() }\r\n  /**\r\n   * 设置文字高亮颜色。\r\n   * @param c 高亮颜色值\r\n   */\r\n  executeSetHighlight(c: string): void { this.adapt.setHighlight(c) }\r\n  /**\r\n   * 设置或切换删除线。\r\n   * @param v 是否显示删除线\r\n   */\r\n  executeSetStrikeout(v?: boolean): void { this.adapt.setStrikeout(v) }\r\n  /** 设置双删除线 */\r\n  executeSetDoubleStrikeout(v?: boolean): void { this.adapt.setDoubleStrikeout(v) }\r\n  /** 设置隐藏 */\r\n  executeSetHidden(v?: boolean): void { this.adapt.setHidden(v) }\r\n  /**\r\n   * 设置或切换下划线。\r\n   * @param v 是否显示下划线\r\n   */\r\n  executeSetUnderline(v?: boolean): void { this.adapt.setUnderline(v) }\r\n  /**\r\n   * 清除当前选区的格式。\r\n   */\r\n  executeClearFormat(): void { this.adapt.clearFormat() }\r\n  /**\r\n   * 使用格式刷应用格式。\r\n   */\r\n  executePaintFormat(): void { this.adapt.paintFormat() }\r\n  /**\r\n   * 设置行高。\r\n   * @param lh 行高数值\r\n   * @param rule 行高规则：'auto' | 'exact' | 'atLeast'\r\n   */\r\n  executeSetLineHeight(lh: number, rule?: 'auto' | 'exact' | 'atLeast'): void { this.adapt.setLineHeight(lh, rule) }\r\n  /**\r\n   * 设置行间距。\r\n   * @param m 行间距数值\r\n   */\r\n  executeSetRowMargin(m: number): void { this.adapt.setRowMargin(m) }\r\n  /**\r\n   * 设置标题级别。\r\n   * @param l 标题级别，null 表示取消标题\r\n   */\r\n  executeSetTitle(l: 'first' | 'second' | 'third' | 'fourth' | 'fifth' | 'sixth' | null): void { this.adapt.setTitle(l) }\r\n  /**\r\n   * 设置列表。\r\n   * @param type 列表类型\r\n   * @param style 列表样式\r\n   */\r\n  executeSetList(type: Parameters<CommandAdapt['setList']>[0], style: Parameters<CommandAdapt['setList']>[1]): void { this.adapt.setList(type, style) }\r\n  /**\r\n   * 插入表格。\r\n   * @param rows 行数\r\n   * @param cols 列数\r\n   * @param availableWidth 可用宽度，可选\r\n   */\r\n  executeInsertTable(rows: number, cols: number, availableWidth?: number): void { this.adapt.insertTable(rows, cols, availableWidth) }\r\n  /**\r\n   * 插入表格行。\r\n   * @param position 插入位置：'above' | 'below'\r\n   * @param count 插入行数，可选\r\n   */\r\n  executeInsertTableRow(position: 'above' | 'below', count?: number): void { this.adapt.insertTableRow(position, count) }\r\n  /**\r\n   * 插入表格列。\r\n   * @param position 插入位置：'left' | 'right'\r\n   * @param count 插入列数，可选\r\n   */\r\n  executeInsertTableCol(position: 'left' | 'right', count?: number): void { this.adapt.insertTableCol(position, count) }\r\n  /**\r\n   * 删除当前表格行。\r\n   */\r\n  executeDeleteTableRow(): void { this.adapt.deleteTableRow() }\r\n  /**\r\n   * 删除当前表格列。\r\n   */\r\n  executeDeleteTableCol(): void { this.adapt.deleteTableCol() }\r\n  /**\r\n   * 拆分当前表格单元格。\r\n   */\r\n  executeSplitTableCell(): void { this.adapt.splitTableCell() }\r\n  /**\r\n   * 合并选中的表格单元格。\r\n   */\r\n  executeMergeTableCells(): void { this.adapt.mergeTableCells() }\r\n  /**\r\n   * 删除整个表格。\r\n   */\r\n  executeDeleteTable(): void { this.adapt.deleteTable() }\r\n  /**\r\n   * 设置单元格垂直对齐方式。\r\n   * @param align 对齐方式：'top' | 'middle' | 'bottom'\r\n   */\r\n  executeSetCellVerticalAlign(align: 'top' | 'middle' | 'bottom'): void { this.adapt.setCellVerticalAlign(align) }\r\n  /**\r\n   * 设置单元格背景色。\r\n   * @param color 背景颜色值\r\n   */\r\n  executeSetCellBackground(color: string): void { this.adapt.setCellBackground(color) }\r\n  /**\n   * 设置单元格文字方向。\n   * @param direction 横排 lrTb 或竖排 tbRlV\n   * @param target 可选的目标单元格位置；未提供时使用当前光标\n   */\n  executeSetCellTextDirection(direction: CellTextDirection, target?: IPosition): void {\n    this.adapt.setCellTextDirection(direction, target)\n  }\n  /**\r\n   * 切换表格重复表头状态。\r\n   */\r\n  executeToggleRepeatHeader(target?: IPosition): void { this.adapt.toggleRepeatHeader(target) }\n  /**\n   * 设置单元格四边内边距。\n   * @param padding [上, 右, 下, 左]，单位为像素\n   * @param target 可选的目标单元格位置\n   */\n  executeSetCellPadding(padding: [number, number, number, number], target?: IPosition): void {\n    this.adapt.setCellPadding(padding, target)\n  }\n  /**\r\n   * 设置表格列宽。\r\n   * @param tableIndex 表格索引\r\n   * @param colIndex 列索引\r\n   * @param width 列宽\r\n   */\r\n  executeSetTableColWidth(tableIndex: number, colIndex: number, width: number): void { this.adapt.setTableColWidth(tableIndex, colIndex, width) }\r\n  /**\r\n   * 设置表格行高。\r\n   * @param tableIndex 表格索引\r\n   * @param rowIndex 行索引\r\n   * @param height 行高\r\n   */\r\n  executeSetTableRowHeight(tableIndex: number, rowIndex: number, height: number): void { this.adapt.setTableRowHeight(tableIndex, rowIndex, height) }\r\n  /**\r\n   * 选中当前表格。\r\n   */\r\n  executeSelectTable(): void { this.adapt.selectTable() }\r\n  /**\r\n   * 插入图片。\r\n   * @param src 图片源，可以是 URL 字符串或包含 value/width/height 的对象\r\n   * @param w 宽度，可选\r\n   * @param h 高度，可选\r\n   */\r\n  executeInsertImage(src: string | { value: string; width?: number; height?: number }, w?: number, h?: number): void { this.adapt.insertImage(src, w, h) }\r\n  /**\r\n   * 插入签名图片。\r\n   * @param dataUrl 签名图片的 data URL\r\n   */\r\n  executeInsertSignature(dataUrl: string): void { this.adapt.signature(dataUrl) }\r\n  /**\r\n   * 插入条形码图片。\r\n   * @param payload 条形码参数，包含 value/width/height\r\n   */\r\n  executeInsertBarcode(payload: { value: string; width: number; height: number }): void { this.adapt.insertImage(payload) }\r\n  /**\r\n   * 插入二维码图片。\r\n   * @param payload 二维码参数，包含 value/width/height\r\n   */\r\n  executeInsertQrcode(payload: { value: string; width: number; height: number }): void { this.adapt.insertImage(payload) }\r\n  /**\r\n   * 更新图片尺寸。\r\n   * @param path 图片路径\r\n   * @param width 新宽度\r\n   * @param height 新高度\r\n   */\r\n  executeUpdateImageSize(path: Path, width: number, height: number): void { this.adapt.updateImageSize(path, width, height) }\r\n  /**\r\n   * 删除图片。\r\n   * @param path 图片路径\r\n   */\r\n  executeDeleteImage(path: Path): void { this.adapt.deleteImage(path) }\r\n  /**\r\n   * 重置图片为原始尺寸。\r\n   * @param path 图片路径\r\n   */\r\n  executeResetImageSize(path: Path): void { this.adapt.resetImageSize(path) }\r\n  /**\r\n   * 设置图片对齐方式。\r\n   * @param path 图片路径\r\n   * @param align 对齐方式：'left' | 'center' | 'right'\r\n   */\r\n  executeImageAlign(path: Path, align: 'left' | 'center' | 'right'): void { this.adapt.imageAlign(path, align) }\r\n  /**\r\n   * 替换图片。\r\n   * @param path 图片路径\r\n   */\r\n  executeReplaceImage(path: Path): void { this.adapt.replaceImage(path) }\r\n  /**\r\n   * 旋转图片。\r\n   * @param path 图片路径\r\n   */\r\n  executeRotateImage(path: Path): void { this.adapt.rotateImage(path) }\r\n  /**\r\n   * 保存图片。\r\n   * @param path 图片路径\r\n   */\r\n  executeSaveImage(path: Path): Promise<void> { return this.adapt.saveImage(path) }\r\n  /**\r\n   * 设置图片环绕方式。\r\n   * @param path 图片路径\r\n   * @param mode 环绕模式：'block' | 'surround' | 'floatTop' | 'floatBottom'\r\n   */\r\n  executeImageWrap(path: Path, mode: 'block' | 'surround' | 'float-top' | 'float-bottom'): void { this.adapt.imageWrap(path, mode) }\r\n  /**\r\n   * 插入分页符。\r\n   */\r\n  executePageBreak(): void { this.adapt.insertPageBreak() }\r\n  executeInsertBlankPage(): void { this.adapt.insertBlankPage() }\r\n  /**\r\n   * 插入超链接。\r\n   * @param payload 超链接参数，包含 url 和 valueList\r\n   */\r\n  executeHyperlink(payload: { url: string; valueList: IElement[] }): boolean { return this.adapt.insertHyperlink(payload) }\r\n  getHyperlinkInsertionError() { return this.adapt.getHyperlinkInsertionError() }\r\n  /**\r\n   * 插入 LaTeX 公式。\r\n   * @param payload LaTeX 参数，包含 latex/svg/width/height\r\n   */\r\n  executeInsertLatex(payload: { latex: string; svg: string; width: number; height: number }): void { this.adapt.insertLatex(payload) }\r\n  /**\r\n   * 插入分隔线。\r\n   * @param opts 分隔线选项，可选\r\n   */\r\n  executeSeparator(opts?: { lineType?: string; lineWidth?: number; dashArray?: number[]; color?: string } | any[]): void { this.adapt.insertSeparator(opts) }\r\n  /**\r\n   * 插入换行符。\r\n   */\r\n  executeLineBreak(): void { this.adapt.lineBreak() }\r\n  /**\r\n   * 插入分栏符。\r\n   */\r\n  executeColumnBreak(): void { this.adapt.columnBreak() }\r\n  /**\r\n   * 插入连续分节符。\r\n   */\r\n  executeSectionBreakContinuous(): void { this.adapt.sectionBreakContinuous() }\r\n  executeSectionBreakNextPage(): void { this.adapt.sectionBreak('nextPage') }\r\n  executeSectionBreakEvenPage(): void { this.adapt.sectionBreak('evenPage') }\r\n  executeSectionBreakOddPage(): void { this.adapt.sectionBreak('oddPage') }\r\n  /**\r\n   * 搜索关键字。\r\n   * @param keyword 搜索关键字\r\n   * @returns 包含匹配数量 count 的结果对象\r\n   */\r\n  executeSearch(keyword: string): { count: number } { return this.adapt.search(keyword) }\r\n  /**\r\n   * 替换匹配内容。\r\n   * @param text 替换文本\r\n   * @param opts 替换选项，可指定 index\r\n   * @returns 是否成功替换\r\n   */\r\n  executeReplace(text: string, opts?: { index?: number }): boolean { return this.adapt.replace(text, opts) }\r\n  /**\r\n   * 定位到指定索引的搜索结果。\r\n   * @param idx 搜索结果索引\r\n   */\r\n  executeLocateSearchResult(idx: number): void { this.adapt.locateSearchResult(idx) }\r\n  /**\r\n   * 获取当前搜索命中列表。\r\n   * @returns 匹配项数组，每项含 index、before、match、after\r\n   */\r\n  executeGetSearchMatches(): { index: number; before: string; match: string; after: string }[] { return this.adapt.getSearchMatches() }\r\n  /**\r\n   * 全部替换。\r\n   * @param keyword 搜索关键字\r\n   * @param replacement 替换文本\r\n   * @returns 包含替换数量 count 的结果对象\r\n   */\r\n  executeReplaceAll(keyword: string, replacement: string): { count: number } { return this.adapt.replaceAll(keyword, replacement) }\r\n  /**\r\n   * 替换单个搜索结果。\r\n   * @param result 搜索结果定位信息\r\n   * @param replacement 替换文本\r\n   * @returns 包含替换数量 count 的结果对象\r\n   */\r\n  executeReplaceOne(result: { resultIndex: number; keyword: string }, replacement: string): { count: number } { return this.adapt.replaceOne(result, replacement) }\r\n  /**\r\n   * 设置纸张尺寸。\r\n   * @param w 宽度\r\n   * @param h 高度\r\n   */\r\n  executeSetPaperSize(w: number, h: number): void { this.adapt.setPaperSize(w, h) }\r\n  /**\r\n   * 设置纸张方向。\r\n   * @param d 方向：'vertical' | 'horizontal'\r\n   */\r\n  executeSetPaperDirection(d: 'vertical' | 'horizontal'): void { this.adapt.setPaperDirection(d) }\r\n  /**\r\n   * 放大页面缩放。\r\n   */\r\n  executePageScaleAdd(): void { this.adapt.pageScaleAdd() }\r\n  /**\r\n   * 缩小页面缩放。\r\n   */\r\n  executePageScaleMinus(): void { this.adapt.pageScaleMinus() }\r\n  /**\r\n   * 设置标尺可见性。\r\n   * @param visible 是否可见\r\n   */\r\n  executeSetRulerVisible(visible: boolean): void { this.adapt.setRulerVisible(visible) }\r\n  /**\r\n   * 设置页边距。\r\n   * @param margins 边距数组\r\n   */\r\n  executeSetPaperMargin(margins: number[]): void { this.adapt.setPaperMargin(margins) }\r\n  /**\r\n   * 打印文档。\r\n   */\r\n  executePrint(): Promise<void> { return this.adapt.print() }\r\n  /**\r\n   * 获取所有页面缩略图。\r\n   * @returns 缩略图 data URL 数组\r\n   */\r\n  getPageThumbnails(): string[] { return this.adapt.getPageThumbnails() }\r\n  /**\r\n   * 获取纸张高度。\r\n   * @returns 纸张高度数值\r\n   */\r\n  getPaperHeight(): number { return this.adapt.getPaperHeight() }\r\n  /**\r\n   * 获取编辑器选项。\r\n   * @returns 当前编辑器配置选项\r\n   */\r\n  getOptions(): IEditorOption { return this.adapt.getOptions() }\r\n  /**\r\n   * 设置页面模式。\r\n   * @param mode 页面模式字符串\r\n   */\r\n  executeSetPageMode(mode: string): void { this.adapt.setPageMode(mode) }\r\n  /**\r\n   * 设置页面缩放比例。\r\n   * @param scale 缩放比例\r\n   */\r\n  executeSetPageScale(scale: number): void { this.adapt.setPageScale(scale) }\r\n  /**\r\n   * 恢复页面缩放至默认比例。\r\n   */\r\n  executePageScaleRecovery(): void { this.adapt.setPageScaleRecovery() }\r\n  /**\r\n   * 设置分栏数。\r\n   * @param value 分栏数量\r\n   */\r\n  executeSetColumns(value: number): void { this.adapt.setColumns(value) }\r\n  /**\r\n   * 更新编辑器选项。\r\n   * @param patch 选项补丁对象\r\n   */\r\n  executeUpdateOptions(patch: Partial<IEditorOption>): void { this.adapt.updateOptions(patch) }\r\n  /**\r\n   * 添加水印。\r\n   * @param payload 水印参数，可包含 data/content/color/opacity/size/font/repeat\r\n   */\r\n  executeAddWatermark(payload: { data?: string; content?: string; color?: string; opacity?: number; size?: number; font?: string; repeat?: boolean } | any): void { this.adapt.addWatermark(payload) }\r\n  /**\r\n   * 删除水印。\r\n   */\r\n  executeDeleteWatermark(): void { this.adapt.deleteWatermark() }\r\n  /**\r\n   * 设置系统级水印（全页面 DOM 覆盖层）。\r\n   * @param config 水印配置，null 表示移除\r\n   */\r\n  executeSetSystemWatermark(config: { data: string; color?: string; opacity?: number; size?: number; font?: string; repeat?: boolean; gapX?: number; gapY?: number } | null): void { this.adapt.setSystemWatermark(config) }\r\n  /** 删除系统级水印 */\r\n  executeDeleteSystemWatermark(): void { this.adapt.deleteSystemWatermark() }\r\n  /**\r\n   * 获取文档全部元素值。\r\n   * @returns 文档元素数组\r\n   */\r\n  getValue(): IDocxDocumentMeta { return this.adapt.getValue() }\r\n  /**\r\n   * 设置文档内容。\r\n   * @param payload 文档内容，包含 main 及可选的 header/footer/comments\r\n   */\r\n  executeSetValue(payload: Parameters<CommandAdapt['setValue']>[0]): void { this.adapt.setValue(payload) }\r\n  /**\r\n   * 获取字数统计。\r\n   * @returns 字数数值\r\n   */\r\n  getWordCount(): number { return this.adapt.getWordCount() }\r\n  /**\r\n   * 获取文档目录。\r\n   * @returns 目录项数组，每项包含 id/level/name\r\n   */\r\n  getToc(): { id: string; level: number; name: string }[] { return this.adapt.getToc() }\r\n  /**\r\n   * 定位到指定目录项。\r\n   * @param id 目录项 ID\r\n   */\r\n  executeLocationToc(id: string): void { this.adapt.locationToc(id) }\r\n  /**\r\n   * 设置光标位置。\r\n   * @param path 光标路径\r\n   * @param offset 偏移量\r\n   */\r\n  executeSetCaret(path: Path, offset: number): void { this.adapt.setCaret(path, offset) }\r\n  /**\r\n   * 获取自动生成的目录结果。\r\n   * @returns 自动目录结果\r\n   */\r\n  getAutoToc(): IAutoTocResult { return this.adapt.getAutoToc() }\r\n  /**\r\n   * 插入自动目录。\r\n   * @param type Office 自动目录模板：1 | 2（均收录三级标题）\r\n   */\r\n  executeInsertAutoToc(type: 1 | 2): void { this.adapt.insertAutoToc(type) }\r\n  /**\r\n   * 撤销操作。\r\n   */\r\n  executeUndo(): void { this.adapt.undo() }\r\n  /**\r\n   * 重做操作。\r\n   */\r\n  executeRedo(): void { this.adapt.redo() }\r\n  /**\r\n   * 获取所有书签。\r\n   * @returns 书签数组\r\n   */\r\n  getBookmarks(): IBookmark[] { return this.adapt.getBookmarks() }\r\n  /**\r\n   * 添加书签。\r\n   * @param payload 书签参数，包含 name\r\n   */\r\n  executeAddBookmark(payload: { name: string }): void { this.adapt.addBookmark(payload) }\r\n  /**\r\n   * 删除书签。\r\n   * @param payload 书签参数，包含 name\r\n   */\r\n  executeDeleteBookmark(payload: { name: string }): void { this.adapt.deleteBookmark(payload) }\r\n  /**\r\n   * 跳转到指定书签。\r\n   * @param payload 书签参数，包含 name\r\n   */\r\n  executeGotoBookmark(payload: { name: string }): void { this.adapt.gotoBookmark(payload) }\r\n  /**\r\n   * 插入目录（TOC）。\r\n   * @param payload 目录参数，可包含 type/mode 及其他自定义字段\r\n   */\r\n  executeInsertToc(payload: { type?: 1 | 2; mode?: string; [key: string]: unknown }): void { this.adapt.insertToc(payload) }\r\n  /** 更新整个目录，包括标题文本、层级与页码。 */\r\n  executeUpdateToc(): void { this.adapt.updateToc() }\r\n  /**\r\n   * 移除目录（TOC）。\r\n   */\r\n  executeRemoveToc(): void { this.adapt.removeToc() }\r\n  /**\r\n   * 设置当前编辑区域。\r\n   * @param zone 区域：'main' | 'header' | 'footer'\r\n   */\r\n  executeSetZone(zone: 'main' | 'header' | 'footer'): void { this.adapt.setZone(zone) }\r\n  /**\r\n   * 清空页眉内容。\r\n   */\r\n  executeClearHeader(): void { this.adapt.clearHeader() }\r\n  /**\r\n   * 清空页脚内容。\r\n   */\r\n  executeClearFooter(): void { this.adapt.clearFooter() }\r\n  /**\r\n   * 设置页码。\r\n   * @param payload 页码配置\r\n   */\r\n  executeSetPageNumber(payload: Record<string, unknown>): void { this.adapt.setPageNumber(payload) }\r\n\r\n\r\n  /**\r\n   * 获取当前编辑区域。\r\n   * @returns 区域：'main' | 'header' | 'footer'\r\n   */\r\n  getZone(): 'main' | 'header' | 'footer' { return this.adapt.getZone() }\r\n  /**\r\n   * 全选文档内容。\r\n   */\r\n  executeSelectAll(): void { this.adapt.selectAll() }\r\n  /**\r\n   * 设置选区范围。\r\n   * @param startIndex 起始索引\r\n   * @param endIndex 结束索引\r\n   */\r\n  executeSetRange(startIndex: number, endIndex: number): void { this.adapt.setRange(startIndex, endIndex) }\r\n  /**\r\n   * 插入元素列表。\r\n   * @param elements 元素数组\r\n   */\r\n  executeInsertElementList(elements: IElement[]): void { this.adapt.insertElementList(elements) }\r\n  /**\r\n   * 复制选区内容并返回可粘贴字符串。\r\n   * @returns 复制得到的数据字符串\r\n   */\r\n  executeCopy(): string { return this.adapt.copy() }\r\n  /**\r\n   * 剪切选区内容并返回可粘贴字符串。\r\n   * @returns 剪切得到的数据字符串\r\n   */\r\n  executeCut(): string { return this.adapt.cut() }\r\n  /**\r\n   * 粘贴内容。\r\n   * @param text 待粘贴的数据字符串\r\n   */\r\n  executePaste(text: string): void { this.adapt.paste(text) }\r\n  /**\r\n   * 粘贴纯文本。\r\n   * @param text 待粘贴的纯文本\r\n   */\r\n  executePastePlain(text: string): void { this.adapt.pastePlain(text) }\r\n  /**\r\n   * 粘贴时不保留格式（等同于粘贴纯文本）。\r\n   * @param text 待粘贴的文本\r\n   */\r\n  executePasteNoFormat(text: string): void { this.adapt.pastePlain(text) }\r\n  /**\r\n   * 设置上标。\r\n   */\r\n  executeSetSuperscript(): void { this.adapt.setSuperscript() }\r\n  /**\r\n   * 设置下标。\r\n   */\r\n  executeSetSubscript(): void { this.adapt.setSubscript() }\r\n  /**\r\n   * 设置字符缩放比例。\r\n   * @param value 缩放比例\r\n   */\r\n  executeSetCharacterScale(value: number): void { this.adapt.setCharacterScale(value) }\r\n  /**\r\n   * 设置段落首行缩进。\r\n   * @param indentPx 缩进像素值\r\n   */\r\n  executeSetFirstLineIndent(indentPx: number): void { this.adapt.setParagraphFirstLineIndent(indentPx) }\r\n  /** Apply ruler handle positions as one paragraph-format transaction. */\r\n  executeSetRulerIndent(first: number, left: number, right: number): void {\r\n    this.adapt.setRulerIndent(first, left, right)\r\n  }\r\n  /**\r\n   * 获取首行缩进值。\r\n   * @returns 首行缩进像素值\r\n   */\r\n  getFirstLineIndent(): number { return this.adapt.getFirstLineIndent() }\r\n  /**\r\n   * 按方向执行缩进步进。\r\n   * @param direction 方向：'add' | 'sub'\r\n   */\r\n  executeIndentStep(direction: 'add' | 'sub'): void { this.adapt.indentStep(direction) }\r\n  /** 设置左缩进（px） */\r\n  executeSetParagraphIndentLeft(px: number): void { this.adapt.setParagraphIndentLeft(px) }\r\n  /** 获取左缩进（px） */\r\n  getParagraphIndentLeft(): number { return this.adapt.getParagraphIndentLeft() }\r\n  /** 设置右缩进（px） */\r\n  executeSetParagraphIndentRight(px: number): void { this.adapt.setParagraphIndentRight(px) }\r\n  /** 获取右缩进（px） */\r\n  getParagraphIndentRight(): number { return this.adapt.getParagraphIndentRight() }\r\n  /** 设置段前间距（px） */\r\n  executeSetParagraphSpacingBefore(px: number): void { this.adapt.setParagraphSpacingBefore(px) }\r\n  /** 获取段前间距（px） */\r\n  getParagraphSpacingBefore(): number { return this.adapt.getParagraphSpacingBefore() }\r\n  /** 设置段后间距（px） */\r\n  executeSetParagraphSpacingAfter(px: number): void { this.adapt.setParagraphSpacingAfter(px) }\r\n  /** 获取段后间距（px） */\r\n  getParagraphSpacingAfter(): number { return this.adapt.getParagraphSpacingAfter() }\r\n  /**\r\n   * 获取当前选区范围。\r\n   * @returns 选区范围对象，无选区时返回 null\r\n   */\r\n  getRange(): IRange | null { return this.adapt.getRange() }\r\n  /**\r\n   * 获取是否只读状态。\r\n   * @returns 是否只读\r\n   */\r\n  getIsReadonly(): boolean { return this.adapt.getIsReadonly() }\r\n  /**\r\n   * 获取是否禁用状态。\r\n   * @returns 是否禁用\r\n   */\r\n  getIsDisabled(): boolean { return this.adapt.getIsDisabled() }\r\n  /**\r\n   * 获取是否可输入状态。\r\n   * @returns 是否可输入\r\n   */\r\n  getIsCanInput(): boolean { return this.adapt.getIsCanInput() }\r\n  /**\r\n   * 获取当前选区样式。\r\n   * @returns 选区样式对象\r\n   */\r\n  getRangeStyle(): IRangeStyle { return this.adapt.getRangeStyle() }\r\n  /**\r\n   * 获取选区上下文信息。\r\n   * @returns 包含起始行号和列号的对象\r\n   */\r\n  getRangeContext(): { startRowNo: number; startColNo: number } { return this.adapt.getRangeContext() }\r\n  /**\r\n   * 获取编辑器能力描述。\r\n   * @returns 编辑器能力对象\r\n   */\r\n  getAbility(): IEditorAbility { return this.adapt.getAbility() }\r\n  /**\r\n   * 设置编辑器模式。\r\n   * @param mode 模式字符串\r\n   */\r\n  executeSetMode(mode: string): void { this.adapt.setMode(mode) }\r\n  /**\r\n   * 预览 HTML 内容。\r\n   * @param payload 预览参数\r\n   */\r\n  executePreviewHtml(payload: any): void { this.adapt.previewHtml(payload) }\r\n  /**\r\n   * 替换指定范围的内容。\r\n   * @param range 范围对象\r\n   */\r\n  executeReplaceRange(range: any): void { this.adapt.replaceRange(range) }\r\n  /**\r\n   * 设置群组，返回 groupId 或 null。\r\n   */\r\n  executeSetGroup(update?: Parameters<CommandAdapt['setGroup']>[0]): string | null { return this.adapt.setGroup(update) }\r\n  /**\r\n   * 定位到指定群组。\r\n   * @param id 群组 ID\r\n   */\r\n  executeLocationGroup(id: string): void { this.adapt.locationGroup(id) }\r\n  /**\r\n   * 设置表格边框类型。\r\n   * @param type 边框类型字符串\r\n   */\r\n  executeSetTableBorderType(type: string): void { this.adapt.setTableBorderType(type) }\r\n  getCellProperties(target?: IPosition) { return this.adapt.getCellProperties(target) }\n  getTableRowProperties(target?: IPosition) { return this.adapt.getTableRowProperties(target) }\n  getTableColumnProperties(target?: IPosition) { return this.adapt.getTableColumnProperties(target) }\n  getTableBorders() { return this.adapt.getTableBorders() }\r\n  executeSetTableBorders(patch: Parameters<CommandAdapt['setTableBorders']>[0]): void { this.adapt.setTableBorders(patch) }\r\n  /**\r\n   * 设置表格边框颜色。\r\n   * @param color 颜色值\r\n   */\r\n  executeSetTableBorderColor(color: string): void { this.adapt.setTableBorderColor(color) }\r\n  /**\r\n   * 设置表格边框宽度。\r\n   * @param width 宽度数值\r\n   */\r\n  executeSetTableBorderWidth(width: number): void { this.adapt.setTableBorderWidth(width) }\r\n  /**\r\n   * 设置表格外部边框宽度。\r\n   * @param width 宽度数值\r\n   */\r\n  executeSetTableBorderExternalWidth(width: number): void { this.adapt.setTableBorderExternalWidth(width) }\r\n  /**\r\n\r\n   * 插入图表。\r\n   * @param payload 图表参数：chartType/subtype/dataSource/config/width/height\r\n   */\r\n  executeInsertChart(payload: { chartType: string; subtype?: string; dataSource: any; config?: any; width?: number; height?: number }): void { this.adapt.insertChart(payload) }\r\n  /**\r\n   * 更新图表属性。\r\n   * @param id 图表 ID\r\n   * @param patch 属性补丁对象\r\n   */\r\n  executeUpdateChart(id: string, patch: Record<string, unknown>): void { this.adapt.updateChart(id, patch) }\r\n  /**\r\n   * 更新图表尺寸。\r\n   * @param path 图表路径\r\n   * @param width 新宽度\r\n   * @param height 新高度\r\n   */\r\n  executeUpdateChartSize(path: Path, width: number, height: number): void { this.adapt.updateChartSize(path, width, height) }\r\n  /**\r\n   * 删除块元素（图表等）。\r\n   * @param path 块路径\r\n   */\r\n  executeDeleteBlock(path: Path): void { this.adapt.deleteBlock(path) }\r\n  /**\r\n   * 删除指定群组。\r\n   * @param groupId 群组 ID\r\n   */\r\n  executeDeleteGroup(groupId: string): void { this.adapt.deleteGroup(groupId) }\r\n  /**\r\n   * 获取文档全文纯文本（所有 text run 的 value 拼接）。\r\n   * @returns 文档全文字符串\r\n   */\r\n  executeGetFullText(): string { return this.adapt.getFullText() }\r\n  /**\r\n   * 跳转到指定页码（通过设置滚动位置）。\r\n   * @param pageNo 页码索引（从 0 开始）\r\n   */\r\n  executeJumpToPage(pageNo: number): void { this.adapt.jumpToPage(pageNo) }\r\n  /**\r\n   * 定位到指定修订 ID 的首个元素位置。\r\n   * @param id 修订唯一标识\r\n   * @returns 是否找到并定位成功\r\n   */\r\n  executeLocateRevision(id: string): boolean { return this.adapt.locateRevision(id) }\r\n\r\n  /* -------------------- 内置内容控件 -------------------- */\r\n\r\n  /**\r\n   * 在当前光标位置插入控件。\r\n   * @param config 控件配置\r\n   * @param dataValue 初始值（默认 null）\r\n   * @returns 控件实例 ID，失败返回 null\r\n   */\r\n  executeInsertControl(config: IControlConfig, dataValue?: ControlDataValue): string | null {\r\n    return this.adapt.insertControl(config, dataValue ?? null)\r\n  }\r\n  /**\r\n   * 更新控件值。\r\n   * @param controlId 控件实例 ID\r\n   * @param newDataValue 新业务值\r\n   * @returns 是否成功更新\r\n   */\r\n  executeUpdateControlValue(controlId: string, newDataValue: ControlDataValue): boolean {\r\n    return this.adapt.updateControlValue(controlId, newDataValue)\r\n  }\r\n  /**\r\n   * 移除控件。\r\n   * @param controlId 控件实例 ID\r\n   * @param keepContent true=保留子内容，false=删除控件及内容\r\n   */\r\n  executeRemoveControl(controlId: string, keepContent: boolean): void {\r\n    this.adapt.removeControl(controlId, keepContent)\r\n  }\r\n  /**\r\n   * 清空控件内容（保留控件本身）。\r\n   * @param controlId 控件实例 ID\r\n   */\r\n  executeClearControl(controlId: string): void {\r\n    this.adapt.clearControl(controlId)\r\n  }\r\n  /**\r\n   * 更新控件配置。\r\n   * @param controlId 控件实例 ID\r\n   * @param newConfig 新配置\r\n   * @returns 是否成功更新\r\n   */\r\n  executeUpdateControlConfig(controlId: string, newConfig: IControlConfig): boolean {\r\n    return this.adapt.updateControlConfig(controlId, newConfig)\r\n  }\r\n  /**\r\n   * 根据 ID 查找控件元素。\r\n   * @param controlId 控件实例 ID\r\n   * @returns 控件元素或 null\r\n   */\r\n  executeGetControlById(controlId: string): IControlElement | null {\r\n    return this.adapt.getControlById(controlId)\r\n  }\r\n}\r\n","/**\r\n * docx-editor-commands 内部共享常量\r\n *\r\n * verve schema 未导出这些符号，在此定义以保持 commands 模块自洽。\r\n */\r\n\r\nimport type { IElementBase } from '@vervedoc/docx-editor-schema'\r\n\r\n// 重新导出迁移至 schema 的跨包共享类型，保持 commands 包 API 兼容\r\nexport type { IElementPosition } from '@vervedoc/docx-editor-schema'\r\n\r\n/** CSS 类名前缀，与 verve view 的 container 前缀保持一致 */\r\nexport const EDITOR_PREFIX = 'vervedocs'\r\n\r\n/** 嵌入块类型 */\r\nexport enum BlockType {\r\n  IFRAME = 'iframe'\r\n}\r\n\r\n/** 文本类元素类型集合（用于 Search 匹配） */\r\nexport const TEXTLIKE_ELEMENT_TYPE = new Set(['text', 'hyperlink', 'date', 'control'])\r\n\r\n/** 零值常量 */\r\nexport const ZERO = 0\r\n\r\n/** 组件 data 属性名 */\r\nexport const EDITOR_COMPONENT = 'data-vervedoc-component'\r\n\r\n/** 组件类型枚举 */\r\nexport enum EditorComponent {\r\n  POPUP = 'popup',\r\n  CONTROL = 'control',\r\n  DATE = 'date'\r\n}\r\n\r\n/* ========== 嵌入块元素类型 ========== */\r\n\r\n/** iframe 块数据 */\r\nexport interface IIFrameBlockData {\r\n  src?: string\r\n  srcdoc?: string\r\n}\r\n\r\n/** 图表块数据 */\r\nexport interface IChartBlockData {\r\n  chartType: string\r\n  dataSource: any\r\n  config?: any\r\n  subtype?: string\r\n}\r\n\r\n/** 块内嵌结构 */\r\nexport interface IBlockContent {\r\n  type: BlockType\r\n  iframeBlock?: IIFrameBlockData\r\n  chartBlock?: IChartBlockData\r\n}\r\n\r\n/** 块元素度量 */\r\nexport interface IBlockMetrics {\r\n  width: number\r\n  height: number\r\n}\r\n\r\n/** block 类型元素（type === 'block'） */\r\nexport interface IBlockElement extends IElementBase {\r\n  type: 'block'\r\n  id?: string\r\n  block?: IBlockContent\r\n  metrics?: IBlockMetrics\r\n}\r\n\r\n/* ========== LaTeX 元素类型 ========== */\r\n\r\n/** latex 类型元素（type === 'latex'） */\r\nexport interface ILatexElement extends IElementBase {\r\n  type: 'latex'\r\n  laTexSVG: string\r\n  width: number\r\n  height: number\r\n}\r\n\r\n/* ========== 日期元素类型 ========== */\r\n\r\n/** 日期值项 */\r\nexport interface IDateValueItem {\r\n  value: string\r\n}\r\n\r\n/** date 类型元素（type === 'date'） */\r\nexport interface IDateElement extends IElementBase {\r\n  type: 'date'\r\n  dateId?: string\r\n  dateFormat?: string\r\n  valueList?: IDateValueItem[]\r\n}","import {\r\n  EDITOR_COMPONENT,\r\n  EDITOR_PREFIX,\r\n  EditorComponent,\r\n  type IElementPosition\r\n} from './constants'\r\nimport './assets/css/date-picker.css'\nimport type { Draw } from '@vervedoc/docx-editor-view'\r\n\r\n/** 日期选择器多语言文案接口 */\r\nexport interface IDatePickerLang {\r\n  /** \"现在\"按钮文案 */\r\n  now: string\r\n  /** \"确定\"按钮文案 */\r\n  confirm: string\r\n  /** \"返回\"按钮文案 */\r\n  return: string\r\n  /** \"选择时间\"按钮文案 */\r\n  timeSelect: string\r\n  /** 星期文案 */\r\n  weeks: {\r\n    /** 周日文案 */\r\n    sun: string\r\n    /** 周一文案 */\r\n    mon: string\r\n    /** 周二文案 */\r\n    tue: string\r\n    /** 周三文案 */\r\n    wed: string\r\n    /** 周四文案 */\r\n    thu: string\r\n    /** 周五文案 */\r\n    fri: string\r\n    /** 周六文案 */\r\n    sat: string\r\n  }\r\n  /** \"年\"文案 */\r\n  year: string\r\n  /** \"月\"文案 */\r\n  month: string\r\n  /** \"时\"文案 */\r\n  hour: string\r\n  /** \"分\"文案 */\r\n  minute: string\r\n  /** \"秒\"文案 */\r\n  second: string\r\n}\r\n\r\n/** 日期选择器选项接口 */\r\nexport interface IDatePickerOption {\r\n  /** 用户提交日期时的回调函数 */\r\n  onSubmit?: (date: string) => any\r\n}\r\n\r\n/** 日期选择器内部 DOM 结构引用 */\r\ninterface IDatePickerDom {\r\n  /** 最外层容器 */\r\n  container: HTMLDivElement\r\n  /** 日期面板包裹元素 */\r\n  dateWrap: HTMLDivElement\r\n  /** 星期标题行 */\r\n  datePickerWeek: HTMLDivElement\r\n  /** 时间面板包裹元素 */\r\n  timeWrap: HTMLUListElement\r\n  /** 标题栏（年月切换按钮） */\r\n  title: {\r\n    /** 上一年按钮 */\r\n    preYear: HTMLSpanElement\r\n    /** 上一月按钮 */\r\n    preMonth: HTMLSpanElement\r\n    /** 当前年月显示 */\r\n    now: HTMLSpanElement\r\n    /** 下一月按钮 */\r\n    nextMonth: HTMLSpanElement\r\n    /** 下一年按钮 */\r\n    nextYear: HTMLSpanElement\r\n  }\r\n  /** 日期网格容器 */\r\n  day: HTMLDivElement\r\n  /** 时分秒选择列表 */\r\n  time: {\r\n    /** 小时列表 */\r\n    hour: HTMLOListElement\r\n    /** 分钟列表 */\r\n    minute: HTMLOListElement\r\n    /** 秒列表 */\r\n    second: HTMLOListElement\r\n  }\r\n  /** 底部菜单按钮 */\r\n  menu: {\r\n    /** 切换时间选择按钮 */\r\n    time: HTMLButtonElement\r\n    /** \"现在\"按钮 */\r\n    now: HTMLButtonElement\r\n    /** \"确定\"按钮 */\r\n    submit: HTMLButtonElement\r\n  }\r\n}\r\n\r\n/** 渲染选项 */\r\ninterface IRenderOption {\r\n  /** 当前日期值 */\r\n  value: string\r\n  /** 元素位置信息 */\r\n  position: IElementPosition\r\n  /** 日期格式化模板 */\r\n  dateFormat?: string\r\n}\r\n\r\n/** 日期选择器组件，提供日期/时间选择能力并写回文档 */\r\nexport class DatePicker {\r\n  /** 编辑器绘制实例 */\r\n  private draw: Draw\r\n  /** 外部传入的选项 */\r\n  private options: IDatePickerOption\r\n  /** 当前浏览的日期（用于面板显示年月） */\r\n  private now: Date\r\n  /** DOM 引用 */\r\n  private dom: IDatePickerDom\r\n  /** 当前渲染选项 */\r\n  private renderOptions: IRenderOption | null\r\n  /** 是否处于日期选择模式（true=日期，false=时间） */\r\n  private isDatePicker: boolean\r\n  /** 用户已选定的日期 */\r\n  private pickDate: Date | null\r\n  /** 多语言文案 */\r\n  private lang: IDatePickerLang\r\n\r\n  /**\r\n   * 创建日期选择器实例\r\n   * @param draw 编辑器绘制实例\r\n   * @param options 选项\r\n   */\r\n  constructor(draw: Draw, options: IDatePickerOption = {}) {\r\n    this.draw = draw\r\n    this.options = options\r\n    this.lang = this._getLang()\r\n    this.now = new Date()\r\n    this.dom = this._createDom()\r\n    this.renderOptions = null\r\n    this.isDatePicker = true\r\n    this.pickDate = null\r\n    this._bindEvent()\r\n  }\r\n\r\n  /**\r\n   * 构建日期选择器 DOM 结构\r\n   * @returns DOM 引用对象\r\n   */\r\n  private _createDom(): IDatePickerDom {\r\n    const datePickerContainer = document.createElement('div')\r\n    datePickerContainer.classList.add(`${EDITOR_PREFIX}-date-container`)\r\n    datePickerContainer.setAttribute(EDITOR_COMPONENT, EditorComponent.POPUP)\r\n    // title-切换年月、年月显示\r\n    const dateWrap = document.createElement('div')\r\n    dateWrap.classList.add(`${EDITOR_PREFIX}-date-wrap`)\r\n    const datePickerTitle = document.createElement('div')\r\n    datePickerTitle.classList.add(`${EDITOR_PREFIX}-date-title`)\r\n    const preYearTitle = document.createElement('span')\r\n    preYearTitle.classList.add(`${EDITOR_PREFIX}-date-title__pre-year`)\r\n    preYearTitle.innerText = `<<`\r\n    const preMonthTitle = document.createElement('span')\r\n    preMonthTitle.classList.add(`${EDITOR_PREFIX}-date-title__pre-month`)\r\n    preMonthTitle.innerText = `<`\r\n    const nowTitle = document.createElement('span')\r\n    nowTitle.classList.add(`${EDITOR_PREFIX}-date-title__now`)\r\n    const nextMonthTitle = document.createElement('span')\r\n    nextMonthTitle.classList.add(`${EDITOR_PREFIX}-date-title__next-month`)\r\n    nextMonthTitle.innerText = `>`\r\n    const nextYearTitle = document.createElement('span')\r\n    nextYearTitle.classList.add(`${EDITOR_PREFIX}-date-title__next-year`)\r\n    nextYearTitle.innerText = `>>`\r\n    datePickerTitle.append(preYearTitle)\r\n    datePickerTitle.append(preMonthTitle)\r\n    datePickerTitle.append(nowTitle)\r\n    datePickerTitle.append(nextMonthTitle)\r\n    datePickerTitle.append(nextYearTitle)\r\n    // week-星期显示\r\n    const datePickerWeek = document.createElement('div')\r\n    datePickerWeek.classList.add(`${EDITOR_PREFIX}-date-week`)\r\n    const {\r\n      weeks: { sun, mon, tue, wed, thu, fri, sat }\r\n    } = this.lang\r\n    const weekList = [sun, mon, tue, wed, thu, fri, sat]\r\n    weekList.forEach(week => {\r\n      const weekDom = document.createElement('span')\r\n      weekDom.innerText = `${week}`\r\n      datePickerWeek.append(weekDom)\r\n    })\r\n    // day-天数显示\r\n    const datePickerDay = document.createElement('div')\r\n    datePickerDay.classList.add(`${EDITOR_PREFIX}-date-day`)\r\n    // 日期内容构建\r\n    dateWrap.append(datePickerTitle)\r\n    dateWrap.append(datePickerWeek)\r\n    dateWrap.append(datePickerDay)\r\n    // time-时间选择\r\n    const timeWrap = document.createElement('ul')\r\n    timeWrap.classList.add(`${EDITOR_PREFIX}-time-wrap`)\r\n    let hourTime: HTMLOListElement\r\n    let minuteTime: HTMLOListElement\r\n    let secondTime: HTMLOListElement\r\n    const timeList = [this.lang.hour, this.lang.minute, this.lang.second]\r\n    timeList.forEach((t, i) => {\r\n      const li = document.createElement('li')\r\n      const timeText = document.createElement('span')\r\n      timeText.innerText = t\r\n      li.append(timeText)\r\n      const ol = document.createElement('ol')\r\n      const isHour = i === 0\r\n      const isMinute = i === 1\r\n      const endIndex = isHour ? 24 : 60\r\n      for (let i = 0; i < endIndex; i++) {\r\n        const time = document.createElement('li')\r\n        time.innerText = `${String(i).padStart(2, '0')}`\r\n        time.setAttribute('data-id', `${i}`)\r\n        ol.append(time)\r\n      }\r\n      if (isHour) {\r\n        hourTime = ol\r\n      } else if (isMinute) {\r\n        minuteTime = ol\r\n      } else {\r\n        secondTime = ol\r\n      }\r\n      li.append(ol)\r\n      timeWrap.append(li)\r\n    })\r\n    // menu-选择时间、现在、确定\r\n    const datePickerMenu = document.createElement('div')\r\n    datePickerMenu.classList.add(`${EDITOR_PREFIX}-date-menu`)\r\n    const timeMenu = document.createElement('button')\r\n    timeMenu.classList.add(`${EDITOR_PREFIX}-date-menu__time`)\r\n    timeMenu.innerText = this.lang.timeSelect\r\n    const nowMenu = document.createElement('button')\r\n    nowMenu.classList.add(`${EDITOR_PREFIX}-date-menu__now`)\r\n    nowMenu.innerText = this.lang.now\r\n    const submitMenu = document.createElement('button')\r\n    submitMenu.classList.add(`${EDITOR_PREFIX}-date-menu__submit`)\r\n    submitMenu.innerText = this.lang.confirm\r\n    datePickerMenu.append(timeMenu)\r\n    datePickerMenu.append(nowMenu)\r\n    datePickerMenu.append(submitMenu)\r\n    // 构建\r\n    datePickerContainer.append(dateWrap)\r\n    datePickerContainer.append(timeWrap)\r\n    datePickerContainer.append(datePickerMenu)\r\n\r\n    return {\r\n      container: datePickerContainer,\r\n      dateWrap,\r\n      datePickerWeek,\r\n      timeWrap,\r\n      title: {\r\n        preYear: preYearTitle,\r\n        preMonth: preMonthTitle,\r\n        now: nowTitle,\r\n        nextMonth: nextMonthTitle,\r\n        nextYear: nextYearTitle\r\n      },\r\n      day: datePickerDay,\r\n      time: {\r\n        hour: hourTime!,\r\n        minute: minuteTime!,\r\n        second: secondTime!\r\n      },\r\n      menu: {\r\n        time: timeMenu,\r\n        now: nowMenu,\r\n        submit: submitMenu\r\n      }\r\n    }\r\n  }\r\n\r\n  /** 绑定 DOM 事件监听 */\r\n  private _bindEvent() {\r\n    this.dom.title.preYear.onclick = () => {\r\n      this._preYear()\r\n    }\r\n    this.dom.title.preMonth.onclick = () => {\r\n      this._preMonth()\r\n    }\r\n    this.dom.title.nextMonth.onclick = () => {\r\n      this._nextMonth()\r\n    }\r\n    this.dom.title.nextYear.onclick = () => {\r\n      this._nextYear()\r\n    }\r\n    this.dom.menu.time.onclick = () => {\r\n      this.isDatePicker = !this.isDatePicker\r\n      this._toggleDateTimePicker()\r\n    }\r\n    this.dom.menu.now.onclick = () => {\r\n      this._now()\r\n      this._submit()\r\n    }\r\n    this.dom.menu.submit.onclick = () => {\r\n      this.dispose()\r\n      this._submit()\r\n    }\r\n    this.dom.time.hour.onclick = evt => {\r\n      if (!this.pickDate) return\r\n      const li = <HTMLLIElement>evt.target\r\n      const id = li.dataset.id\r\n      if (!id) return\r\n      this.pickDate.setHours(Number(id))\r\n      this._setTimePick(false)\r\n    }\r\n    this.dom.time.minute.onclick = evt => {\r\n      if (!this.pickDate) return\r\n      const li = <HTMLLIElement>evt.target\r\n      const id = li.dataset.id\r\n      if (!id) return\r\n      this.pickDate.setMinutes(Number(id))\r\n      this._setTimePick(false)\r\n    }\r\n    this.dom.time.second.onclick = evt => {\r\n      if (!this.pickDate) return\r\n      const li = <HTMLLIElement>evt.target\r\n      const id = li.dataset.id\r\n      if (!id) return\r\n      this.pickDate.setSeconds(Number(id))\r\n      this._setTimePick(false)\r\n    }\r\n  }\r\n\r\n  /** 根据元素位置计算并设置选择器在容器中的坐标 */\r\n  private _setPosition() {\r\n    if (!this.renderOptions) return\r\n    const {\r\n      position: {\r\n        coordinate: {\r\n          leftTop: [left, top]\r\n        },\r\n        lineHeight,\r\n        pageNo\r\n      }\r\n    } = this.renderOptions\r\n    const layout = this.draw.getLayout()\r\n    const height = layout?.pages?.[0]?.rect?.height\r\n      ?? this.draw.getOptions().pageHeight\r\n      ?? 1123\r\n    const pageGap = (this.draw.getOptions() as { pageGap?: number }).pageGap ?? 24\r\n    const currentPageNo = pageNo ?? 0\r\n    const preY = currentPageNo * (height + pageGap)\r\n    // 位置\r\n    this.dom.container.style.left = `${left}px`\r\n    this.dom.container.style.top = `${top + preY + lineHeight}px`\r\n  }\r\n\r\n  /**\r\n   * 判断日期是否无效\r\n   * @param value 待校验日期\r\n   * @returns 是否为无效日期\r\n   */\r\n  public isInvalidDate(value: Date): boolean {\r\n    return value.toDateString() === 'Invalid Date'\r\n  }\r\n\r\n  /** 根据渲染选项初始化当前日期与已选日期 */\r\n  private _setValue() {\r\n    const value = this.renderOptions?.value\r\n    if (value) {\r\n      const setDate = new Date(value)\r\n      this.now = this.isInvalidDate(setDate) ? new Date() : setDate\r\n    } else {\r\n      this.now = new Date()\r\n    }\r\n    this.pickDate = new Date(this.now)\r\n  }\r\n\r\n  /** 获取多语言文案，支持从 i18n 实例取值或回退到默认中文 */\r\n  private _getLang() {\r\n    const i18n = (this.draw as any).getI18n?.()\r\n    const defaults: Record<string, string> = {\r\n      'datePicker.now': '现在',\r\n      'datePicker.confirm': '确定',\r\n      'datePicker.return': '返回',\r\n      'datePicker.timeSelect': '选择时间',\r\n      'datePicker.weeks.sun': '日',\r\n      'datePicker.weeks.mon': '一',\r\n      'datePicker.weeks.tue': '二',\r\n      'datePicker.weeks.wed': '三',\r\n      'datePicker.weeks.thu': '四',\r\n      'datePicker.weeks.fri': '五',\r\n      'datePicker.weeks.sat': '六',\r\n      'datePicker.year': '年',\r\n      'datePicker.month': '月',\r\n      'datePicker.hour': '时',\r\n      'datePicker.minute': '分',\r\n      'datePicker.second': '秒'\r\n    }\r\n    const t = i18n?.t ? i18n.t.bind(i18n) : (key: string) => defaults[key] ?? key\r\n    return {\r\n      now: t('datePicker.now'),\r\n      confirm: t('datePicker.confirm'),\r\n      return: t('datePicker.return'),\r\n      timeSelect: t('datePicker.timeSelect'),\r\n      weeks: {\r\n        sun: t('datePicker.weeks.sun'),\r\n        mon: t('datePicker.weeks.mon'),\r\n        tue: t('datePicker.weeks.tue'),\r\n        wed: t('datePicker.weeks.wed'),\r\n        thu: t('datePicker.weeks.thu'),\r\n        fri: t('datePicker.weeks.fri'),\r\n        sat: t('datePicker.weeks.sat')\r\n      },\r\n      year: t('datePicker.year'),\r\n      month: t('datePicker.month'),\r\n      hour: t('datePicker.hour'),\r\n      minute: t('datePicker.minute'),\r\n      second: t('datePicker.second')\r\n    }\r\n  }\r\n\r\n  /** 语言变更后刷新 DOM 文案 */\r\n  private _setLangChange() {\r\n    this.dom.menu.time.innerText = this.lang.timeSelect\r\n    this.dom.menu.now.innerText = this.lang.now\r\n    this.dom.menu.submit.innerText = this.lang.confirm\r\n    const {\r\n      weeks: { sun, mon, tue, wed, thu, fri, sat }\r\n    } = this.lang\r\n    const weekList = [sun, mon, tue, wed, thu, fri, sat]\r\n    this.dom.datePickerWeek.childNodes.forEach((child, i) => {\r\n      const childElement = <HTMLSpanElement>child\r\n      childElement.innerText = weekList[i]\r\n    })\r\n    const hourTitle = <HTMLSpanElement>this.dom.time.hour.previousElementSibling\r\n    hourTitle.innerText = this.lang.hour\r\n    const minuteTitle = <HTMLSpanElement>(\r\n      this.dom.time.minute.previousElementSibling\r\n    )\r\n    minuteTitle.innerText = this.lang.minute\r\n    const secondTitle = <HTMLSpanElement>(\r\n      this.dom.time.second.previousElementSibling\r\n    )\r\n    secondTitle.innerText = this.lang.second\r\n  }\r\n\r\n  /** 重新渲染日期网格（包含上下月填充与高亮状态） */\r\n  private _update() {\r\n    // 本地年月日\r\n    const localDate = new Date()\r\n    const localYear = localDate.getFullYear()\r\n    const localMonth = localDate.getMonth() + 1\r\n    const localDay = localDate.getDate()\r\n    // 选择年月日\r\n    let pickYear: number | null = null\r\n    let pickMonth: number | null = null\r\n    let pickDay: number | null = null\r\n    if (this.pickDate) {\r\n      pickYear = this.pickDate.getFullYear()\r\n      pickMonth = this.pickDate.getMonth() + 1\r\n      pickDay = this.pickDate.getDate()\r\n    }\r\n    // 当前年月日\r\n    const year = this.now.getFullYear()\r\n    const month = this.now.getMonth() + 1\r\n    this.dom.title.now.innerText = `${year}${this.lang.year} ${String(\r\n      month\r\n    ).padStart(2, '0')}${this.lang.month}`\r\n    // 日期补差\r\n    const curDate = new Date(year, month, 0) // 当月日期\r\n    const curDay = curDate.getDate() // 当月总天数\r\n    let curWeek = new Date(year, month - 1, 1).getDay() // 当月第一天星期几\r\n    if (curWeek === 0) {\r\n      curWeek = 7\r\n    }\r\n    const preDay = new Date(year, month - 1, 0).getDate() // 上个月天数\r\n    this.dom.day.replaceChildren()\r\n    // 渲染上个月日期\r\n    const preStartDay = preDay - curWeek + 1\r\n    for (let i = preStartDay; i <= preDay; i++) {\r\n      const dayDom = document.createElement('div')\r\n      dayDom.classList.add('disable')\r\n      dayDom.innerText = `${i}`\r\n      dayDom.onclick = () => {\r\n        const newMonth = month - 2\r\n        this.now = new Date(year, newMonth, i)\r\n        this._setDatePick(year, newMonth, i)\r\n      }\r\n      this.dom.day.append(dayDom)\r\n    }\r\n    // 渲染当月日期\r\n    for (let i = 1; i <= curDay; i++) {\r\n      const dayDom = document.createElement('div')\r\n      if (localYear === year && localMonth === month && localDay === i) {\r\n        dayDom.classList.add('active')\r\n      }\r\n      if (\r\n        this.pickDate &&\r\n        pickYear === year &&\r\n        pickMonth === month &&\r\n        pickDay === i\r\n      ) {\r\n        dayDom.classList.add('select')\r\n      }\r\n      dayDom.innerText = `${i}`\r\n      dayDom.onclick = evt => {\r\n        const newMonth = month - 1\r\n        this.now = new Date(year, newMonth, i)\r\n        this._setDatePick(year, newMonth, i)\r\n        evt.stopPropagation()\r\n      }\r\n      this.dom.day.append(dayDom)\r\n    }\r\n    // 渲染下月日期\r\n    const nextEndDay = 6 * 7 - curWeek - curDay\r\n    for (let i = 1; i <= nextEndDay; i++) {\r\n      const dayDom = document.createElement('div')\r\n      dayDom.classList.add('disable')\r\n      dayDom.innerText = `${i}`\r\n      dayDom.onclick = () => {\r\n        this.now = new Date(year, month, i)\r\n        this._setDatePick(year, month, i)\r\n      }\r\n      this.dom.day.append(dayDom)\r\n    }\r\n  }\r\n\r\n  /** 在日期面板与时间面板之间切换显示 */\r\n  private _toggleDateTimePicker() {\r\n    if (this.isDatePicker) {\r\n      this.dom.dateWrap.classList.add('active')\r\n      this.dom.timeWrap.classList.remove('active')\r\n      this.dom.menu.time.innerText = this.lang.timeSelect\r\n    } else {\r\n      this.dom.dateWrap.classList.remove('active')\r\n      this.dom.timeWrap.classList.add('active')\r\n      this.dom.menu.time.innerText = this.lang.return\r\n      // 设置时分秒选择\r\n      this._setTimePick()\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 设置用户选定的日期\r\n   * @param year 年\r\n   * @param month 月（0 基）\r\n   * @param day 日\r\n   */\r\n  private _setDatePick(year: number, month: number, day: number) {\r\n    this.now = new Date(year, month, day)\r\n    this.pickDate?.setFullYear(year)\r\n    this.pickDate?.setMonth(month)\r\n    this.pickDate?.setDate(day)\r\n    this._update()\r\n  }\r\n\r\n  /**\r\n   * 设置时分秒选择高亮\r\n   * @param isIntoView 是否同步滚动到选中项\r\n   */\r\n  private _setTimePick(isIntoView = true) {\r\n    const hour = this.pickDate?.getHours() || 0\r\n    const minute = this.pickDate?.getMinutes() || 0\r\n    const second = this.pickDate?.getSeconds() || 0\r\n    const {\r\n      hour: hourDom,\r\n      minute: minuteDom,\r\n      second: secondDom\r\n    } = this.dom.time\r\n    const timeDomList = [hourDom, minuteDom, secondDom]\r\n    // 清空\r\n    timeDomList.forEach(timeDom => {\r\n      timeDom\r\n        .querySelectorAll('li')\r\n        .forEach(li => li.classList.remove('active'))\r\n    })\r\n    const pickList: [HTMLOListElement, number][] = [\r\n      [hourDom, hour],\r\n      [minuteDom, minute],\r\n      [secondDom, second]\r\n    ]\r\n    pickList.forEach(([dom, time]) => {\r\n      const pickDom = dom.querySelector<HTMLLIElement>(`[data-id='${time}']`)!\r\n      pickDom.classList.add('active')\r\n      if (isIntoView) {\r\n        this._scrollIntoView(dom, pickDom)\r\n      }\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 将选中元素滚动到容器可视区域\r\n   * @param container 滚动容器\r\n   * @param selected 选中的元素\r\n   */\r\n  private _scrollIntoView(container: HTMLElement, selected: HTMLElement) {\r\n    if (!selected) {\r\n      container.scrollTop = 0\r\n      return\r\n    }\r\n    const offsetParents: HTMLElement[] = []\r\n    let pointer = <HTMLElement>selected.offsetParent\r\n    while (pointer && container !== pointer && container.contains(pointer)) {\r\n      offsetParents.push(pointer)\r\n      pointer = <HTMLElement>pointer.offsetParent\r\n    }\r\n    const top =\r\n      selected.offsetTop +\r\n      offsetParents.reduce((prev, curr) => prev + curr.offsetTop, 0)\r\n    const bottom = top + selected.offsetHeight\r\n    const viewRectTop = container.scrollTop\r\n    const viewRectBottom = viewRectTop + container.clientHeight\r\n    if (top < viewRectTop) {\r\n      container.scrollTop = top\r\n    } else if (bottom > viewRectBottom) {\r\n      container.scrollTop = bottom - container.clientHeight\r\n    }\r\n  }\r\n\r\n  /** 切换到上一个月 */\r\n  private _preMonth() {\r\n    this.now.setMonth(this.now.getMonth() - 1)\r\n    this._update()\r\n  }\r\n\r\n  /** 切换到下一个月 */\r\n  private _nextMonth() {\r\n    this.now.setMonth(this.now.getMonth() + 1)\r\n    this._update()\r\n  }\r\n\r\n  /** 切换到上一年 */\r\n  private _preYear() {\r\n    this.now.setFullYear(this.now.getFullYear() - 1)\r\n    this._update()\r\n  }\r\n\r\n  /** 切换到下一年 */\r\n  private _nextYear() {\r\n    this.now.setFullYear(this.now.getFullYear() + 1)\r\n    this._update()\r\n  }\r\n\r\n  /** 选中当前时刻并关闭面板 */\r\n  private _now() {\r\n    this.pickDate = new Date()\r\n    this.dispose()\r\n  }\r\n\r\n  /**\r\n   * 切换面板可见性\r\n   * @param isVisible 是否可见\r\n   */\r\n  private _toggleVisible(isVisible: boolean) {\r\n    if (isVisible) {\r\n      this.dom.container.classList.add('active')\r\n    } else {\r\n      this.dom.container.classList.remove('active')\r\n    }\r\n  }\r\n\r\n  /** 触发 onSubmit 回调，将选定日期格式化后传出 */\r\n  private _submit() {\r\n    if (this.options.onSubmit && this.pickDate) {\r\n      const format = this.renderOptions?.dateFormat\r\n      const pickDateString = this.formatDate(this.pickDate, format)\r\n      this.options.onSubmit(pickDateString)\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 按指定模板格式化日期\r\n   * @param date 待格式化日期\r\n   * @param format 格式模板，默认 yyyy-MM-dd hh:mm:ss\r\n   * @returns 格式化后的日期字符串\r\n   */\r\n  public formatDate(date: Date, format = 'yyyy-MM-dd hh:mm:ss'): string {\r\n    let dateString = format\r\n    const dateOption = {\r\n      'y+': date.getFullYear().toString(),\r\n      'M+': (date.getMonth() + 1).toString(),\r\n      'd+': date.getDate().toString(),\r\n      'h+': date.getHours().toString(),\r\n      'm+': date.getMinutes().toString(),\r\n      's+': date.getSeconds().toString()\r\n    }\r\n    for (const k in dateOption) {\r\n      const reg = new RegExp('(' + k + ')').exec(format)\r\n      const key = <keyof typeof dateOption>k\r\n      if (reg) {\r\n        dateString = dateString.replace(\r\n          reg[1],\r\n          reg[1].length === 1\r\n            ? dateOption[key]\r\n            : dateOption[key].padStart(reg[1].length, '0')\r\n        )\r\n      }\r\n    }\r\n    return dateString\r\n  }\r\n\r\n  /**\r\n   * 渲染日期选择器\r\n   * @param option 渲染选项\r\n   */\r\n  public render(option: IRenderOption) {\r\n    // 按需挂载到容器，避免初始化时就出现在页面上\r\n    if (!this.dom.container.parentElement) {\r\n      this.draw.getContainer().append(this.dom.container)\r\n    }\r\n    this.renderOptions = option\r\n    this.lang = this._getLang()\r\n    this._setLangChange()\r\n    this._setValue()\r\n    this._update()\r\n    this._setPosition()\r\n    this.isDatePicker = true\r\n    this._toggleDateTimePicker()\r\n    this._toggleVisible(true)\r\n  }\r\n\r\n  /** 隐藏并从 DOM 中移除面板 */\r\n  public dispose() {\r\n    this._toggleVisible(false)\r\n    this.dom.container.remove()\r\n  }\r\n\r\n  /** 销毁选择器，移除容器 */\r\n  public destroy() {\r\n    this.dom.container.remove()\r\n  }\r\n}\r\n","import type { IElement } from '@vervedoc/docx-editor-schema'\r\nimport { getByPath } from '@vervedoc/docx-editor-schema'\r\nimport type { RangeManager } from '@vervedoc/docx-editor-state'\r\nimport type { Draw } from '@vervedoc/docx-editor-view'\r\nimport type { IElementPosition } from './constants'\r\nimport { DatePicker } from './date-picker'\r\n\r\n/** 日期粒子管理器，负责 date 元素的日期选择器挂载与值写回 */\r\nexport class DateParticle {\r\n  /** 编辑器绘制实例 */\r\n  private draw: Draw\r\n  /** 选区管理器 */\r\n  private range: RangeManager | null\r\n  /** 日期选择器实例 */\r\n  private datePicker: DatePicker\r\n\r\n  /**\r\n   * 创建日期粒子管理器\r\n   * @param draw 编辑器绘制实例\r\n   */\r\n  constructor(draw: Draw) {\r\n    this.draw = draw\r\n    this.range = draw.getRange()\r\n    this.datePicker = new DatePicker(draw, {\r\n      onSubmit: this._setValue.bind(this)\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 获取当前光标所在的 date 元素（基于路径寻址）\r\n   * @returns date 元素或 null\r\n   */\r\n  private getDateElement(): IElement | null {\r\n    if (!this.range) return null\r\n    const focus = this.range.getFocus()\r\n    if (!focus) return null\r\n    const elementList = this.draw.getElementList()\r\n    return getByPath(elementList, focus.path)\r\n  }\r\n\r\n  /**\r\n   * 用户选择日期后写回：直接修改 date 元素的 valueList[0].value，再刷新文档\r\n   * @param date 用户选定的日期字符串\r\n   */\r\n  private _setValue(date: string) {\r\n    if (!date) return\r\n    const element = this.getDateElement()\r\n    if (!element || element.type !== 'date') return\r\n    const el = element as IElement & { valueList?: { value: string }[]; dateFormat?: string }\r\n    if (!el.valueList) {\r\n      el.valueList = [{ value: date }]\r\n    } else {\r\n      el.valueList[0] = { value: date }\r\n    }\r\n    // 刷新文档渲染\r\n    this.draw.setDocument(this.draw.getDocument())\r\n  }\r\n\r\n  /** 关闭日期选择器面板 */\r\n  public clearDatePicker() {\r\n    this.datePicker.dispose()\r\n  }\r\n\r\n  /**\r\n   * 渲染日期选择器面板\r\n   * @param element date 元素\r\n   * @param position 元素位置信息\r\n   */\r\n  public renderDatePicker(element: IElement, position: IElementPosition) {\r\n    const el = element as IElement & { valueList?: { value: string }[]; dateFormat?: string }\r\n    const value = el.valueList?.[0]?.value ?? ''\r\n    this.datePicker.render({\r\n      value,\r\n      position,\r\n      dateFormat: el.dateFormat\r\n    })\r\n  }\r\n}\r\n","/** Hershey 字形条目：包含包围盒与多段折线 */\r\ninterface HersheyEntry {\r\n  /** 字形宽度 */\r\n  w: number\r\n  /** X 方向最小值 */\r\n  xmin: number\r\n  /** X 方向最大值 */\r\n  xmax: number\r\n  /** Y 方向最小值 */\r\n  ymin: number\r\n  /** Y 方向最大值 */\r\n  ymax: number\r\n  /** 多段折线坐标 */\r\n  polylines: Array<Array<Array<number>>>\r\n}\r\n\r\n/** 'R' 字符的 ASCII 码，用于 Hershey 坐标解码基准 */\r\nconst ordR = 'R'.charCodeAt(0)\r\n\r\n/**\r\n * 获取指定索引的 Hershey 字形（懒编译并缓存）\r\n * @param i 字形索引\r\n * @returns 字形条目\r\n */\r\nexport function HERSHEY(i: number): HersheyEntry {\r\n  if (data[i] == null) {\r\n    compile(i)\r\n  }\r\n  return data[i]\r\n}\r\n\r\n/**\r\n * 编译原始 Hershey 字符串为字形条目并写入缓存\r\n * @param i 字形索引\r\n */\r\nfunction compile(i: number): void {\r\n  const entry: string = raw[i]\r\n  if (entry == null) {\r\n    return\r\n  }\r\n  const bound: string = entry.substring(3, 5)\r\n  const xmin: number = 1 * bound.charCodeAt(0) - ordR\r\n  const xmax: number = 1 * bound.charCodeAt(1) - ordR\r\n  const content: string = entry.substring(5)\r\n\r\n  const polylines: Array<Array<Array<number>>> = [[]]\r\n  let ymin = Infinity\r\n  let ymax = -Infinity\r\n  let zmin = Infinity\r\n  let zmax = -Infinity\r\n  let j = 0\r\n  while (j < content.length) {\r\n    const digit: string = content.substring(j, j + 2)\r\n    if (digit == ' R') {\r\n      polylines.push([])\r\n    } else {\r\n      const x: number = digit.charCodeAt(0) - ordR - xmin\r\n      const y: number = digit.charCodeAt(1) - ordR\r\n      ymin = Math.min(y, ymin)\r\n      ymax = Math.max(y, ymax)\r\n      zmin = Math.min(x, zmin)\r\n      zmax = Math.max(x, zmax)\r\n      polylines[polylines.length - 1].push([x, y])\r\n    }\r\n    j += 2\r\n  }\r\n  data[i] = {\r\n    w: xmax - xmin,\r\n    xmin: zmin,\r\n    xmax: zmax,\r\n    ymin: ymin,\r\n    ymax: ymax,\r\n    polylines: polylines\r\n  }\r\n}\r\n/** 已编译的字形缓存，按索引存取 */\r\nconst data: Record<number, HersheyEntry> = {}\r\n\r\n/** 原始 Hershey 字形字符串表 */\r\nconst raw: Record<number, string> = {\r\n  1: '  9MWRMNV RRMVV RPSTS',\r\n  2: ' 16MWOMOV ROMSMUNUPSQ ROQSQURUUSVOV',\r\n  3: ' 11MXVNTMRMPNOPOSPURVTVVU',\r\n  4: ' 12MWOMOV ROMRMTNUPUSTURVOV',\r\n  5: ' 12MWOMOV ROMUM ROQSQ ROVUV',\r\n  6: '  9MVOMOV ROMUM ROQSQ',\r\n  7: ' 15MXVNTMRMPNOPOSPURVTVVUVR RSRVR',\r\n  8: '  9MWOMOV RUMUV ROQUQ',\r\n  9: '  3PTRMRV',\r\n  10: '  7NUSMSTRVPVOTOS',\r\n  11: '  9MWOMOV RUMOS RQQUV',\r\n  12: '  6MVOMOV ROVUV',\r\n  13: ' 12LXNMNV RNMRV RVMRV RVMVV',\r\n  14: '  9MWOMOV ROMUV RUMUV',\r\n  15: ' 14MXRMPNOPOSPURVSVUUVSVPUNSMRM',\r\n  16: ' 10MWOMOV ROMSMUNUQSROR',\r\n  17: ' 17MXRMPNOPOSPURVSVUUVSVPUNSMRM RSTVW',\r\n  18: ' 13MWOMOV ROMSMUNUQSROR RRRUV',\r\n  19: ' 13MWUNSMQMONOOPPTRUSUUSVQVOU',\r\n  20: '  6MWRMRV RNMVM',\r\n  21: '  9MXOMOSPURVSVUUVSVM',\r\n  22: '  6MWNMRV RVMRV',\r\n  23: ' 12LXNMPV RRMPV RRMTV RVMTV',\r\n  24: '  6MWOMUV RUMOV',\r\n  25: '  7MWNMRQRV RVMRQ',\r\n  26: '  9MWUMOV ROMUM ROVUV',\r\n  27: '  9MWRMNV RRMVV RPSTS',\r\n  28: ' 16MWOMOV ROMSMUNUPSQ ROQSQURUUSVOV',\r\n  29: '  6MVOMOV ROMUM',\r\n  30: '  9MWRMNV RRMVV RNVVV',\r\n  31: ' 12MWOMOV ROMUM ROQSQ ROVUV',\r\n  32: '  9MWUMOV ROMUM ROVUV',\r\n  33: '  9MWOMOV RUMUV ROQUQ',\r\n  34: ' 20MXRMPNOPOSPURVSVUUVSVPUNSMRM RQQTR RTQQR',\r\n  35: '  3PTRMRV',\r\n  36: '  9MWOMOV RUMOS RQQUV',\r\n  37: '  6MWRMNV RRMVV',\r\n  38: ' 12LXNMNV RNMRV RVMRV RVMVV',\r\n  39: '  9MWOMOV ROMUV RUMUV',\r\n  40: ' 12MWOMUM RPQTR RTQPR ROVUV',\r\n  41: ' 14MXRMPNOPOSPURVSVUUVSVPUNSMRM',\r\n  42: '  9MWOMOV RUMUV ROMUM',\r\n  43: ' 10MWOMOV ROMSMUNUQSROR',\r\n  44: ' 10MWOMRQOV ROMUM ROVUV',\r\n  45: '  6MWRMRV RNMVM',\r\n  46: ' 15MWNONNOMPMQNRPRV RVOVNUMTMSNRP',\r\n  47: ' 13LXRMRV RPONPNSPTTTVSVPTOPO',\r\n  48: '  6MWOMUV RUMOV',\r\n  49: ' 12LXRMRV RNOOPOSQTSTUSUPVO',\r\n  50: ' 13MXOVQVOROPPNRMSMUNVPVRTVVV',\r\n  200: ' 12MWRMPNOPOSPURVTUUSUPTNRM',\r\n  201: '  4MWPORMRV',\r\n  202: '  9MWONQMSMUNUPTROVUV',\r\n  203: ' 15MWONQMSMUNUPSQ RRQSQURUUSVQVOU',\r\n  204: '  7MWSMSV RSMNSVS',\r\n  205: ' 14MWPMOQQPRPTQUSTURVQVOU RPMTM',\r\n  206: ' 14MWTMRMPNOPOSPURVTUUSTQRPPQOS',\r\n  207: '  6MWUMQV ROMUM',\r\n  208: ' 19MWQMONOPQQSQUPUNSMQM RQQOROUQVSVUUURSQ',\r\n  209: ' 14MWUPTRRSPROPPNRMTNUPUSTURVPV',\r\n  210: '  6PURURVSVSURU',\r\n  211: '  7PUSVRVRUSUSWRY',\r\n  212: ' 12PURPRQSQSPRP RRURVSVSURU',\r\n  213: ' 13PURPRQSQSPRP RSVRVRUSUSWRY',\r\n  214: ' 12PURMRR RSMSR RRURVSVSURU',\r\n  215: ' 17NWPNRMSMUNUPRQRRSRSQUP RRURVSVSURU',\r\n  216: '  3PTRMRQ',\r\n  217: '  6NVPMPQ RTMTQ',\r\n  218: ' 10NVQMPNPPQQSQTPTNSMQM',\r\n  219: ' 16MWUNSMQMONOPQQTRUSUUSVQVOU RRLRW',\r\n  220: '  3MWVLNW',\r\n  221: '  7OVTLRNQPQSRUTW',\r\n  222: '  7NUPLRNSPSSRUPW',\r\n  223: '  3PTRLRW',\r\n  224: '  3LXNRVR',\r\n  225: '  6LXRNRV RNRVR',\r\n  226: '  6LXNPVP RNTVT',\r\n  227: '  6MWOOUU RUOOU',\r\n  228: '  9MWRORU ROPUT RUPOT',\r\n  229: '  6PURQRRSRSQRQ',\r\n  230: '  7PUSMRORQSQSPRP',\r\n  231: '  7PUSNRNRMSMSORQ',\r\n  232: '  7LXSOVRSU RNRVR',\r\n  233: ' 12MXRLPW RULSW ROPVP ROSVS',\r\n  234: ' 21LXVRURTSSURVOVNUNSORRQSPSNRMPMONOPQSSUUVVV',\r\n  235: ' 20LXNNOQOSNV RVNUQUSVV RNNQOSOVN RNVQUSUVV',\r\n  501: '  9I[RFJ[ RRFZ[ RMTWT',\r\n  502: ' 24G\\\\KFK[ RKFTFWGXHYJYLXNWOTP RKPTPWQXRYTYWXYWZT[K[',\r\n  503: ' 19H]ZKYIWGUFQFOGMILKKNKSLVMXOZQ[U[WZYXZV',\r\n  504: ' 16G\\\\KFK[ RKFRFUGWIXKYNYSXVWXUZR[K[',\r\n  505: ' 12H[LFL[ RLFYF RLPTP RL[Y[',\r\n  506: '  9HZLFL[ RLFYF RLPTP',\r\n  507: ' 23H]ZKYIWGUFQFOGMILKKNKSLVMXOZQ[U[WZYXZVZS RUSZS',\r\n  508: '  9G]KFK[ RYFY[ RKPYP',\r\n  509: '  3NVRFR[',\r\n  510: ' 11JZVFVVUYTZR[P[NZMYLVLT',\r\n  511: '  9G\\\\KFK[ RYFKT RPOY[',\r\n  512: '  6HYLFL[ RL[X[',\r\n  513: ' 12F^JFJ[ RJFR[ RZFR[ RZFZ[',\r\n  514: '  9G]KFK[ RKFY[ RYFY[',\r\n  515: ' 22G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF',\r\n  516: ' 14G\\\\KFK[ RKFTFWGXHYJYMXOWPTQKQ',\r\n  517: ' 25G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF RSWY]',\r\n  518: ' 17G\\\\KFK[ RKFTFWGXHYJYLXNWOTPKP RRPY[',\r\n  519: ' 21H\\\\YIWGTFPFMGKIKKLMMNOOUQWRXSYUYXWZT[P[MZKX',\r\n  520: '  6JZRFR[ RKFYF',\r\n  521: ' 11G]KFKULXNZQ[S[VZXXYUYF',\r\n  522: '  6I[JFR[ RZFR[',\r\n  523: ' 12F^HFM[ RRFM[ RRFW[ R\\\\FW[',\r\n  524: '  6H\\\\KFY[ RYFK[',\r\n  525: '  7I[JFRPR[ RZFRP',\r\n  526: '  9H\\\\YFK[ RKFYF RK[Y[',\r\n  527: '  9I[RFJ[ RRFZ[ RMTWT',\r\n  528: ' 24G\\\\KFK[ RKFTFWGXHYJYLXNWOTP RKPTPWQXRYTYWXYWZT[K[',\r\n  529: '  6HYLFL[ RLFXF',\r\n  530: '  9I[RFJ[ RRFZ[ RJ[Z[',\r\n  531: ' 12H[LFL[ RLFYF RLPTP RL[Y[',\r\n  532: '  9H\\\\YFK[ RKFYF RK[Y[',\r\n  533: '  9G]KFK[ RYFY[ RKPYP',\r\n  534: ' 25G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF ROPUP',\r\n  535: '  3NVRFR[',\r\n  536: '  9G\\\\KFK[ RYFKT RPOY[',\r\n  537: '  6I[RFJ[ RRFZ[',\r\n  538: ' 12F^JFJ[ RJFR[ RZFR[ RZFZ[',\r\n  539: '  9G]KFK[ RKFY[ RYFY[',\r\n  540: '  9I[KFYF ROPUP RK[Y[',\r\n  541: ' 22G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF',\r\n  542: '  9G]KFK[ RYFY[ RKFYF',\r\n  543: ' 14G\\\\KFK[ RKFTFWGXHYJYMXOWPTQKQ',\r\n  544: ' 10I[KFRPK[ RKFYF RK[Y[',\r\n  545: '  6JZRFR[ RKFYF',\r\n  546: ' 19I[KKKILGMFOFPGQIRMR[ RYKYIXGWFUFTGSIRM',\r\n  547: ' 21H\\\\RFR[ RPKMLLMKOKRLTMUPVTVWUXTYRYOXMWLTKPK',\r\n  548: '  6H\\\\KFY[ RK[YF',\r\n  549: ' 18G]RFR[ RILJLKMLQMSNTQUSUVTWSXQYMZL[L',\r\n  550: ' 17H\\\\K[O[LTKPKLLINGQFSFVGXIYLYPXTU[Y[',\r\n  551: ' 20G[G[IZLWOSSLVFV[UXSUQSNQLQKRKTLVNXQZT[Y[',\r\n  552: ' 41F]SHTITLSPRSQUOXMZK[J[IZIWJRKOLMNJPHRGUFXFZG[I[KZMYNWOTP RSPTPWQXRYTYWXYWZU[R[PZOX',\r\n  553: ' 24H\\\\TLTMUNWNYMZKZIYGWFTFQGOIMLLNKRKVLYMZO[Q[TZVXWV',\r\n  554: ' 35G^TFRGQIPMOSNVMXKZI[G[FZFXGWIWKXMZP[S[VZXXZT[O[KZHYGWFTFRHRJSMUPWRZT\\\\U',\r\n  555: ' 28H\\\\VJVKWLYLZKZIYGVFRFOGNINLONPOSPPPMQLRKTKWLYMZP[S[VZXXYV',\r\n  556: ' 28H\\\\RLPLNKMINGQFTFXG[G]F RXGVNTTRXPZN[L[JZIXIVJULUNV RQPZP',\r\n  557: ' 29G^G[IZMVPQQNRJRGQFPFOGNINLONQOUOXNYMZKZQYVXXVZS[O[LZJXIVIT',\r\n  558: ' 38F^MMKLJJJIKGMFNFPGQIQKPONULYJ[H[GZGX RMRVOXN[L]J^H^G]F\\\\FZHXLVRUWUZV[W[YZZY\\\\V',\r\n  559: ' 25IZWVUTSQROQLQIRGSFUFVGWIWLVQTVSXQZO[M[KZJXJVKUMUOV',\r\n  560: ' 25JYT^R[PVOPOJPGRFTFUGVJVMURR[PaOdNfLgKfKdLaN^P\\\\SZWX',\r\n  561: ' 39F^MMKLJJJIKGMFNFPGQIQKPONULYJ[H[GZGX R^I^G]F\\\\FZGXIVLTNROPO RROSQSXTZU[V[XZYY[V',\r\n  562: ' 29I\\\\MRORSQVOXMYKYHXFVFUGTISNRSQVPXNZL[J[IZIXJWLWNXQZT[V[YZ[X',\r\n  563: ' 45@aEMCLBJBICGEFFFHGIIIKHPGTE[ RGTJLLHMGOFPFRGSISKRPQTO[ RQTTLVHWGYFZF\\\\G]I]K\\\\PZWZZ[[\\\\[^Z_YaV',\r\n  564: ' 32E]JMHLGJGIHGJFKFMGNINKMPLTJ[ RLTOLQHRGTFVFXGYIYKXPVWVZW[X[ZZ[Y]V',\r\n  565: ' 29H]TFQGOIMLLNKRKVLYMZO[Q[TZVXXUYSZOZKYHXGVFTFRHRKSNUQWSZU\\\\V',\r\n  566: ' 31F_SHTITLSPRSQUOXMZK[J[IZIWJRKOLMNJPHRGUFZF\\\\G]H^J^M]O\\\\PZQWQUPTO',\r\n  567: ' 32H^ULTNSOQPOPNNNLOIQGTFWFYGZIZMYPWSSWPYNZK[I[HZHXIWKWMXPZS[V[YZ[X',\r\n  568: ' 38F_SHTITLSPRSQUOXMZK[J[IZIWJRKOLMNJPHRGUFYF[G\\\\H]J]M\\\\O[PYQVQSPTQUSUXVZX[ZZ[Y]V',\r\n  569: ' 28H\\\\H[JZLXOTQQSMTJTGSFRFQGPIPKQMSOVQXSYUYWXYWZT[P[MZKXJVJT',\r\n  570: ' 25H[RLPLNKMINGQFTFXG[G]F RXGVNTTRXPZN[L[JZIXIVJULUNV',\r\n  571: ' 33E]JMHLGJGIHGJFKFMGNINKMOLRKVKXLZN[P[RZSYUUXMZF RXMWQVWVZW[X[ZZ[Y]V',\r\n  572: ' 32F]KMILHJHIIGKFLFNGOIOKNOMRLVLYM[O[QZTWVTXPYMZIZGYFXFWGVIVKWNYP[Q',\r\n  573: ' 25C_HMFLEJEIFGHFIFKGLILLK[ RUFK[ RUFS[ RaF_G\\\\JYNVTS[',\r\n  574: ' 36F^NLLLKKKILGNFPFRGSISLQUQXRZT[V[XZYXYVXUVU R]I]G\\\\FZFXGVITLPUNXLZJ[H[GZGX',\r\n  575: ' 38F]KMILHJHIIGKFLFNGOIOKNOMRLVLXMZN[P[RZTXVUWSYM R[FYMVWT]RbPfNgMfMdNaP^S[VY[V',\r\n  576: ' 40H]ULTNSOQPOPNNNLOIQGTFWFYGZIZMYPWTTWPZN[K[JZJXKWNWPXQYR[R^QaPcNfLgKfKdLaN^Q[TYZV',\r\n  583: '  9I[JFR[ RZFR[ RJFZF',\r\n  601: ' 18I\\\\XMX[ RXPVNTMQMONMPLSLUMXOZQ[T[VZXX',\r\n  602: ' 18H[LFL[ RLPNNPMSMUNWPXSXUWXUZS[P[NZLX',\r\n  603: ' 15I[XPVNTMQMONMPLSLUMXOZQ[T[VZXX',\r\n  604: ' 18I\\\\XFX[ RXPVNTMQMONMPLSLUMXOZQ[T[VZXX',\r\n  605: ' 18I[LSXSXQWOVNTMQMONMPLSLUMXOZQ[T[VZXX',\r\n  606: '  9MYWFUFSGRJR[ ROMVM',\r\n  607: ' 23I\\\\XMX]W`VaTbQbOa RXPVNTMQMONMPLSLUMXOZQ[T[VZXX',\r\n  608: ' 11I\\\\MFM[ RMQPNRMUMWNXQX[',\r\n  609: '  9NVQFRGSFREQF RRMR[',\r\n  610: ' 12MWRFSGTFSERF RSMS^RaPbNb',\r\n  611: '  9IZMFM[ RWMMW RQSX[',\r\n  612: '  3NVRFR[',\r\n  613: ' 19CaGMG[ RGQJNLMOMQNRQR[ RRQUNWMZM\\\\N]Q][',\r\n  614: ' 11I\\\\MMM[ RMQPNRMUMWNXQX[',\r\n  615: ' 18I\\\\QMONMPLSLUMXOZQ[T[VZXXYUYSXPVNTMQM',\r\n  616: ' 18H[LMLb RLPNNPMSMUNWPXSXUWXUZS[P[NZLX',\r\n  617: ' 18I\\\\XMXb RXPVNTMQMONMPLSLUMXOZQ[T[VZXX',\r\n  618: '  9KXOMO[ ROSPPRNTMWM',\r\n  619: ' 18J[XPWNTMQMNNMPNRPSUTWUXWXXWZT[Q[NZMX',\r\n  620: '  9MYRFRWSZU[W[ ROMVM',\r\n  621: ' 11I\\\\MMMWNZP[S[UZXW RXMX[',\r\n  622: '  6JZLMR[ RXMR[',\r\n  623: ' 12G]JMN[ RRMN[ RRMV[ RZMV[',\r\n  624: '  6J[MMX[ RXMM[',\r\n  625: ' 10JZLMR[ RXMR[P_NaLbKb',\r\n  626: '  9J[XMM[ RMMXM RM[X[',\r\n  627: ' 24H]QMONMPLRKUKXLZN[P[RZUWWTYPZM RQMSMTNUPWXXZY[Z[',\r\n  628: ' 31I\\\\UFSGQIOMNPMTLZKb RUFWFYHYKXMWNUORO RROTPVRWTWWVYUZS[Q[OZNYMV',\r\n  629: ' 17I\\\\JPLNNMOMQNROSRSVR[ RZMYPXRR[P_Ob',\r\n  630: ' 24I[TMQMONMPLSLVMYNZP[R[TZVXWUWRVOTMRKQIQGRFTFVGXI',\r\n  631: ' 19JZWOVNTMQMONOPPRSS RSSOTMVMXNZP[S[UZWX',\r\n  632: ' 23JYTFRGQHQIRJUKXK RXKTMQONRMUMWNYP[S]T_TaSbQbP`',\r\n  633: ' 19H\\\\IQJOLMNMONOPNTL[ RNTPPRNTMVMXOXRWWTb',\r\n  634: ' 27G\\\\HQIOKMMMNNNPMUMXNZO[Q[SZUWVUWRXMXJWGUFSFRHRJSMUPWRZT',\r\n  635: '  9LWRMPTOXOZP[R[TYUW',\r\n  636: ' 19I[OMK[ RYNXMWMUNQROSNS RNSPTQUSZT[U[VZ',\r\n  637: '  9JZKFMFOGPHX[ RRML[',\r\n  638: ' 21H]OMIb RNQMVMYO[Q[SZUXWT RYMWTVXVZW[Y[[Y\\\\W',\r\n  639: ' 14I[LMOMNSMXL[ RYMXPWRUURXOZL[',\r\n  640: ' 29JZTFRGQHQIRJUKXK RUKRLPMOOOQQSTTVT RTTPUNVMXMZO\\\\S^T_TaRbPb',\r\n  641: ' 18J[RMPNNPMSMVNYOZQ[S[UZWXXUXRWOVNTMRM',\r\n  642: ' 13G]PML[ RUMVSWXX[ RIPKNNM[M',\r\n  643: ' 19I[MSMVNYOZQ[S[UZWXXUXRWOVNTMRMPNNPMSIb',\r\n  644: ' 18I][MQMONMPLSLVMYNZP[R[TZVXWUWRVOUNSM',\r\n  645: '  8H\\\\SMP[ RJPLNOMZM',\r\n  646: ' 16H\\\\IQJOLMNMONOPMVMYO[Q[TZVXXTYPYM',\r\n  647: ' 21G]ONMOKQJTJWKYLZN[Q[TZWXYUZRZOXMVMTORSPXMb',\r\n  648: ' 14I[KMMMOOU`WbYb RZMYOWRM]K`Jb',\r\n  649: ' 20F]VFNb RGQHOJMLMMNMPLULXMZO[Q[TZVXXUZP[M',\r\n  650: ' 23F]NMLNJQITIWJZK[M[OZQW RRSQWRZS[U[WZYWZTZQYNXM',\r\n  651: ' 22L\\\\UUTSRRPRNSMTLVLXMZO[Q[SZTXVRUWUZV[W[YZZY\\\\V',\r\n  652: ' 23M[MVOSRNSLTITGSFQGPIOMNTNZO[P[RZTXUUURVVWWYW[V',\r\n  653: ' 14MXTTTSSRQROSNTMVMXNZP[S[VYXV',\r\n  654: ' 24L\\\\UUTSRRPRNSMTLVLXMZO[Q[SZTXZF RVRUWUZV[W[YZZY\\\\V',\r\n  655: ' 17NXOYQXRWSUSSRRQROSNUNXOZQ[S[UZVYXV',\r\n  656: ' 24OWOVSQUNVLWIWGVFTGSIQQNZKaJdJfKgMfNcOZP[R[TZUYWV',\r\n  657: ' 28L[UUTSRRPRNSMTLVLXMZO[Q[SZTY RVRTYPdOfMgLfLdMaP^S\\\\U[XY[V',\r\n  658: ' 29M\\\\MVOSRNSLTITGSFQGPIOMNSM[ RM[NXOVQSSRURVSVUUXUZV[W[YZZY\\\\V',\r\n  659: ' 16PWSMSNTNTMSM RPVRRPXPZQ[R[TZUYWV',\r\n  660: ' 20PWSMSNTNTMSM RPVRRLdKfIgHfHdIaL^O\\\\Q[TYWV',\r\n  661: ' 33M[MVOSRNSLTITGSFQGPIOMNSM[ RM[NXOVQSSRURVSVUTVQV RQVSWTZU[V[XZYY[V',\r\n  662: ' 18OWOVQSTNULVIVGUFSGRIQMPTPZQ[R[TZUYWV',\r\n  663: ' 33E^EVGSIRJSJTIXH[ RIXJVLSNRPRQSQTPXO[ RPXQVSSURWRXSXUWXWZX[Y[[Z\\\\Y^V',\r\n  664: ' 23J\\\\JVLSNROSOTNXM[ RNXOVQSSRURVSVUUXUZV[W[YZZY\\\\V',\r\n  665: ' 23LZRRPRNSMTLVLXMZO[Q[SZTYUWUUTSRRQSQURWTXWXYWZV',\r\n  666: ' 24KZKVMSNQMUGg RMUNSPRRRTSUUUWTYSZQ[ RMZO[R[UZWYZV',\r\n  667: ' 27L[UUTSRRPRNSMTLVLXMZO[Q[SZ RVRUUSZPaOdOfPgRfScS\\\\U[XY[V',\r\n  668: ' 15MZMVOSPQPSSSTTTVSYSZT[U[WZXYZV',\r\n  669: ' 16NYNVPSQQQSSVTXTZR[ RNZP[T[VZWYYV',\r\n  670: ' 16OXOVQSSO RVFPXPZQ[S[UZVYXV RPNWN',\r\n  671: ' 19L[LVNRLXLZM[O[QZSXUU RVRTXTZU[V[XZYY[V',\r\n  672: ' 17L[LVNRMWMZN[O[RZTXUUUR RURVVWWYW[V',\r\n  673: ' 25I^LRJTIWIYJ[L[NZPX RRRPXPZQ[S[UZWXXUXR RXRYVZW\\\\W^V',\r\n  674: ' 20JZJVLSNRPRQSQZR[U[XYZV RWSVRTRSSOZN[L[KZ',\r\n  675: ' 23L[LVNRLXLZM[O[QZSXUU RVRPdOfMgLfLdMaP^S\\\\U[XY[V',\r\n  676: ' 23LZLVNSPRRRTTTVSXQZN[P\\\\Q^QaPdOfMgLfLdMaP^S\\\\WYZV',\r\n  677: ' 22J\\\\K[NZQXSVUSWOXKXIWGUFSGRHQJPOPTQXRZT[V[XZYY',\r\n  683: ' 26I[WUWRVOUNSMQMONMPLSLVMYNZP[R[TZVXWUXPXKWHVGTFRFPGNI',\r\n  684: ' 16JZWNUMRMPNNPMSMVNYOZQ[T[VZ RMTUT',\r\n  685: ' 23J[TFRGPJOLNOMTMXNZO[Q[SZUWVUWRXMXIWGVFTF RNPWP',\r\n  686: ' 21H\\\\VFNb RQMNNLPKSKVLXNZQ[S[VZXXYUYRXPVNSMQM',\r\n  687: ' 16I[XOWNTMQMNNMOLQLSMUOWSZT\\\\T^S_Q_',\r\n  700: ' 18H\\\\QFNGLJKOKRLWNZQ[S[VZXWYRYOXJVGSFQF',\r\n  701: '  5H\\\\NJPISFS[',\r\n  702: ' 15H\\\\LKLJMHNGPFTFVGWHXJXLWNUQK[Y[',\r\n  703: ' 16H\\\\MFXFRNUNWOXPYSYUXXVZS[P[MZLYKW',\r\n  704: '  7H\\\\UFKTZT RUFU[',\r\n  705: ' 18H\\\\WFMFLOMNPMSMVNXPYSYUXXVZS[P[MZLYKW',\r\n  706: ' 24H\\\\XIWGTFRFOGMJLOLTMXOZR[S[VZXXYUYTXQVOSNRNOOMQLT',\r\n  707: '  6H\\\\YFO[ RKFYF',\r\n  708: ' 30H\\\\PFMGLILKMMONSOVPXRYTYWXYWZT[P[MZLYKWKTLRNPQOUNWMXKXIWGTFPF',\r\n  709: ' 24H\\\\XMWPURRSQSNRLPKMKLLINGQFRFUGWIXMXRWWUZR[P[MZLX',\r\n  710: '  6MWRYQZR[SZRY',\r\n  711: '  9MWSZR[QZRYSZS\\\\R^Q_',\r\n  712: ' 12MWRMQNROSNRM RRYQZR[SZRY',\r\n  713: ' 15MWRMQNROSNRM RSZR[QZRYSZS\\\\R^Q_',\r\n  714: '  9MWRFRT RRYQZR[SZRY',\r\n  715: ' 21I[LKLJMHNGPFTFVGWHXJXLWNVORQRT RRYQZR[SZRY',\r\n  716: '  3NVRFRM',\r\n  717: '  6JZNFNM RVFVM',\r\n  718: ' 14KYQFOGNINKOMQNSNUMVKVIUGSFQF',\r\n  719: ' 27H\\\\PBP_ RTBT_ RYIWGTFPFMGKIKKLMMNOOUQWRXSYUYXWZT[P[MZKX',\r\n  720: '  3G][BIb',\r\n  721: ' 11KYVBTDRGPKOPOTPYR]T`Vb',\r\n  722: ' 11KYNBPDRGTKUPUTTYR]P`Nb',\r\n  723: '  3NVRBRb',\r\n  724: '  3E_IR[R',\r\n  725: '  6E_RIR[ RIR[R',\r\n  726: '  6E_IO[O RIU[U',\r\n  727: '  6G]KKYY RYKKY',\r\n  728: '  9JZRLRX RMOWU RWOMU',\r\n  729: '  6MWRQQRRSSRRQ',\r\n  730: '  8MWSFRGQIQKRLSKRJ',\r\n  731: '  8MWRHQGRFSGSIRKQL',\r\n  732: '  9E_UMXP[RXTUW RIR[R',\r\n  733: ' 12H]SBLb RYBRb RLOZO RKUYU',\r\n  734: ' 35E_\\\\O\\\\N[MZMYNXPVUTXRZP[L[JZIYHWHUISJRQNRMSKSIRGPFNGMIMKNNPQUXWZY[[[\\\\Z\\\\Y',\r\n  735: ' 28G]IIJKKOKUJYI[ R[IZKYOYUZY[[ RIIKJOKUKYJ[I RI[KZOYUYYZ[[',\r\n  737: '  6KYOBO[ RUBU[',\r\n  738: '  6F^RBR[ RI[[[',\r\n  739: '  4F^[BI[[[',\r\n  740: ' 18E_RIQJRKSJRI RIYHZI[JZIY R[YZZ[[\\\\Z[Y',\r\n  741: ' 33F^RHNLKPJSJUKWMXOXQWRU RRHVLYPZSZUYWWXUXSWRU RRUQYP\\\\ RRUSYT\\\\ RP\\\\T\\\\',\r\n  742: ' 26F^RNQKPINHMHKIJKJOKRLTNWR\\\\ RRNSKTIVHWHYIZKZOYRXTVWR\\\\',\r\n  743: ' 20F^RGPJLOIR RRGTJXO[R RIRLUPZR] R[RXUTZR]',\r\n  744: ' 48F^RTTWVXXXZW[U[SZQXPVPSQ RSQUOVMVKUISHQHOINKNMOOQQ RQQNPLPJQISIUJWLXNXPWRT RRTQYP\\\\ RRTSYT\\\\ RP\\\\T\\\\',\r\n  745: ' 55F^RRR[Q\\\\ RRVQ\\\\ RRIQHOHNINKONRR RRISHUHVIVKUNRR RRRNOLNJNIOIQJR RRRVOXNZN[O[QZR RRRNULVJVIUISJR RRRVUXVZV[U[SZR',\r\n  746: ' 55F^ISJSLTMVMXLZ RISIRJQLQMRNTNWMYLZ RRGPIOLOOQUQXPZR\\\\ RRGTIULUOSUSXTZR\\\\ R[S[RZQXQWRVTVWWYXZ R[SZSXTWVWXXZ RKVYV',\r\n  750: ' 18PSSRRSQSPRPQQPRPSQSSRUQV RQQQRRRRQQQ',\r\n  751: ' 16PTQPPQPSQTSTTSTQSPQP RRQQRRSSRRQ',\r\n  752: '  9NVPOTU RTOPU RNRVR',\r\n  753: ' 28MWRKQMOPMR RRKSMUPWR RRMOQ RRMUQ RROPQ RROTQ RQQSQ RMRWR',\r\n  754: ' 26MWMRMQNOONQMSMUNVOWQWR RPNTN ROOUO RNPVP RNQVQ RMRWR',\r\n  755: ' 14LRLFLRRRLF RLIPQ RLLOR RLOMQ',\r\n  756: ' 10MWRKQMOPMR RRKSMUPWR',\r\n  757: ' 11MWWRWQVOUNSMQMONNOMQMR',\r\n  758: ' 13G]]R]P\\\\MZJWHTGPGMHJJHMGPGR',\r\n  759: ' 11MWMRMSNUOVQWSWUVVUWSWR',\r\n  760: '  7LXLPNRQSSSVRXP',\r\n  761: '  6RURUTTURTPRO',\r\n  762: '  7RVRRUPVNVLUKTK',\r\n  763: '  7NRRROPNNNLOKPK',\r\n  764: ' 21MWWHVGTFQFOGNHMJMLNNOOUSVTWVWXVZU[S\\\\P\\\\N[MZ',\r\n  765: ' 21G]IWHVGTGQHOINKMMMONPOTUUVWWYW[V\\\\U]S]P\\\\N[M',\r\n  766: ' 31G]RRTUUVWWYW[V\\\\U]S]Q\\\\O[NYMWMUNTOPUOVMWKWIVHUGSGQHOINKMMMONPORR',\r\n  767: ' 22H\\\\KFK[ RHF[FQP[Z RZV[Y\\\\[ RZVZY RWYZY RWYZZ\\\\[',\r\n  768: ' 30KYUARBPCNELHKLKRLUNWQXSXVWXUYR RKPLMNKQJSJVKXMYPYVXZV]T_R`Oa',\r\n  796: '  3>f>RfR',\r\n  797: '  3D`D``D',\r\n  798: '  3RRR>Rf',\r\n  799: '  3D`DD``',\r\n  800: '  3D`DR`R',\r\n  801: '  3F^FY^K',\r\n  802: '  3KYK^YF',\r\n  803: '  3RRRDR`',\r\n  804: '  3KYKFY^',\r\n  805: '  3F^FK^Y',\r\n  806: '  3KYKRYR',\r\n  807: '  3MWMWWM',\r\n  808: '  3RRRKRY',\r\n  809: '  3MWMMWW',\r\n  810: '  8GRRGPGMHJJHMGPGR',\r\n  811: '  8GRGRGTHWJZM\\\\P]R]',\r\n  812: '  8R]R]T]W\\\\ZZ\\\\W]T]R',\r\n  813: '  8R]]R]P\\\\MZJWHTGRG',\r\n  814: '  9D`DOGQKSPTTTYS]Q`O',\r\n  815: '  9PUUDSGQKPPPTQYS]U`',\r\n  816: '  9OTODQGSKTPTTSYQ]O`',\r\n  817: '  9D`DUGSKQPPTPYQ]S`U',\r\n  818: '  5KYRJYNKVRZ',\r\n  819: '  5JZJRNKVYZR',\r\n  820: '  5KYKVKNYVYN',\r\n  821: '  5JZLXJPZTXL',\r\n  822: ' 23JZJ]L]O\\\\Q[TXUVVSVOULTJSIQIPJOLNONSOVPXS[U\\\\X]Z]',\r\n  823: ' 23I]]Z]X\\\\U[SXPVOSNONLOJPIQISJTLUOVSVVUXT[Q\\\\O]L]J',\r\n  824: ' 23JZZGXGUHSIPLONNQNUOXPZQ[S[TZUXVUVQUNTLQIOHLGJG',\r\n  825: ' 23G[GJGLHOIQLTNUQVUVXUZT[S[QZPXOUNQNNOLPISHUGXGZ',\r\n  826: ' 21E[EPFRHTJUMVQVUUXSZP[NZLWLSMQNNPLSKVKYL\\\\M^',\r\n  827: ' 19EYETHVKWPWSVVTXQYNYLXKVKSLPNNQMTMYN\\\\P_',\r\n  828: ' 26OUQOOQOSQUSUUSUQSOQO RQPPQPSQTSTTSTQSPQP RRQQRRSSRRQ',\r\n  829: ' 11RWRMSMUNVOWQWSVUUVSWRW',\r\n  830: '  9D`DRJR RORUR RZR`R',\r\n  831: '  5D`DUDO`O`U',\r\n  832: '  6JZRDJR RRDZR',\r\n  833: '  9D`DR`R RJYZY RP`T`',\r\n  834: '  9D`DR`R RDRRb R`RRb',\r\n  840: ' 18KYQKNLLNKQKSLVNXQYSYVXXVYSYQXNVLSKQK',\r\n  841: '  6LXLLLXXXXLLL',\r\n  842: '  5KYRJKVYVRJ',\r\n  843: '  6LXRHLRR\\\\XRRH',\r\n  844: ' 12JZRIPOJOOSMYRUWYUSZOTORI',\r\n  845: '  6KYRKRY RKRYR',\r\n  846: '  6MWMMWW RWMMW',\r\n  847: '  9MWRLRX RMOWU RWOMU',\r\n  850: ' 35NVQNOONQNSOUQVSVUUVSVQUOSNQN ROQOS RPPPT RQOQU RRORU RSOSU RTPTT RUQUS',\r\n  851: ' 27NVNNNVVVVNNN ROOOU RPOPU RQOQU RRORU RSOSU RTOTU RUOUU',\r\n  852: ' 17MWRLMUWURL RROOT RROUT RRRQT RRRST',\r\n  853: ' 17LULRUWUMLR RORTU RORTO RRRTS RRRTQ',\r\n  854: ' 17MWRXWOMORX RRUUP RRUOP RRRSP RRRQP',\r\n  855: ' 17OXXROMOWXR RURPO RURPU RRRPQ RRRPS',\r\n  856: ' 22LXRLNWXPLPVWRL RRRRL RRRLP RRRNW RRRVW RRRXP',\r\n  857: ' 11RYRKRY RRKYNRQ RSMVNSO',\r\n  860: ' 13MWRLRX ROOUO RMUOWQXSXUWWU',\r\n  861: ' 11LXRLRX RLQMOWOXQ RPWTW',\r\n  862: ' 14KYMNWX RWNMX ROLLOKQ RULXOYQ',\r\n  863: ' 18I[NII[ RVI[[ RMM[[ RWMI[ RNIVI RMMWM',\r\n  864: ' 21I[RGRV RMJWP RWJMP RIVL\\\\ R[VX\\\\ RIV[V RL\\\\X\\\\',\r\n  865: ' 11G[MJSV RKPSL RG\\\\[\\\\[RG\\\\',\r\n  866: ' 14LXPLPPLPLTPTPXTXTTXTXPTPTLPL',\r\n  867: ' 32KYYPXNVLSKQKNLLNKQKSLVNXQYSYVXXVYT RYPWNUMSMQNPOOQOSPUQVSWUWWVYT',\r\n  868: ' 10KYRJKVYVRJ RRZYNKNRZ',\r\n  869: ' 34G]PIPGQFSFTGTI RGZHXJVKTLPLKMJOIUIWJXKXPYTZV\\\\X]Z RGZ]Z RQZP[Q\\\\S\\\\T[SZ',\r\n  870: ' 64JZRMRS RRSQ\\\\ RRSS\\\\ RQ\\\\S\\\\ RRMQJPHNG RQJNG RRMSJTHVG RSJVG RRMNKLKJM RPLLLJM RRMVKXKZM RTLXLZM RRMPNOOOR RRMPOOR RRMTNUOUR RRMTOUR',\r\n  871: ' 94JZRIRK RRNRP RRSRU RRYQ\\\\ RRYS\\\\ RQ\\\\S\\\\ RRGQIPJ RRGSITJ RPJRITJ RRKPNNOMN RRKTNVOWN RNOPORNTOVO RRPPSNTLTKRKSLT RRPTSVTXTYRYSXT RNTPTRSTTVT RRUPXOYMZLZKYJWJYLZ RRUTXUYWZXZYYZWZYXZ RMZOZRYUZWZ',\r\n  872: ' 40JZRYQ\\\\ RRYS\\\\ RQ\\\\S\\\\ RRYUZXZZXZUYTWTYRZOYMWLUMVJUHSGQGOHNJOMMLKMJOKRMTKTJUJXLZOZRY',\r\n  873: ' 32JZRYQ\\\\ RRYS\\\\ RQ\\\\S\\\\ RRYVXVVXUXRZQZLYIXHVHTGPGNHLHKIJLJQLRLUNVNXRY',\r\n  874: ' 15I[IPKR RLKNP RRGRO RXKVP R[PYR',\r\n  899: '  6QSRQQRRSSRRQ',\r\n  900: ' 10PTQPPQPSQTSTTSTQSPQP',\r\n  901: ' 14NVQNOONQNSOUQVSVUUVSVQUOSNQN',\r\n  902: ' 18MWQMONNOMQMSNUOVQWSWUVVUWSWQVOUNSMQM',\r\n  903: ' 18KYQKNLLNKQKSLVNXQYSYVXXVYSYQXNVLSKQK',\r\n  904: ' 22G]PGMHJJHMGPGTHWJZM\\\\P]T]W\\\\ZZ\\\\W]T]P\\\\MZJWHTGPG',\r\n  905: ' 34AcPALBJCGEEGCJBLAPATBXCZE]G_JaLbPcTcXbZa]__]aZbXcTcPbLaJ_G]EZCXBTAPA',\r\n  906: ' 34<hP<K=G?DAAD?G=K<P<T=Y?]A`DcGeKgPhThYg]e`cc`e]gYhThPgKeGcD`A]?Y=T<P<',\r\n  907: ' 50){O)I*E+@-;073370;-@+E*I)O)U*[+_-d0i3m7q;t@wEyIzO{U{[z_ydwitmqqmtiwdy_z[{U{OzIyEw@t;q7m3i0d-_+[*U)O)',\r\n  908: ' 34>fRAPCMDJDGCEA>H@JAMAZB]D_G`M`PaRc RRATCWDZD]C_AfHdJcMcZb]`_]`W`TaRc',\r\n  909: ' 33AcRAPCMDJDGCEABGAKAPBTDXG\\\\L`Rc RRATCWDZD]C_AbGcKcPbT`X]\\\\X`Rc RBHbH',\r\n  997: '  3MWMXWX',\r\n  998: '  3JZJZZZ',\r\n  999: '  3JZJ]Z]',\r\n  1001: ' 18KYRKMX RRNVX RRKWX ROTTT RKXPX RTXYX',\r\n  1002: ' 35JZNKNX ROKOX RLKSKVLWNVPSQ RSKULVNUPSQ ROQSQVRWTWUVWSXLX RSQURVTVUUWSX',\r\n  1003: ' 24KYVLWKWOVLTKQKOLNMMPMSNVOWQXTXVWWU RQKOMNPNSOVQX',\r\n  1004: ' 26JZNKNX ROKOX RLKSKVLWMXPXSWVVWSXLX RSKULVMWPWSVVUWSX',\r\n  1005: ' 22JYNKNX ROKOX RSOSS RLKVKVOUK ROQSQ RLXVXVTUX',\r\n  1006: ' 20JXNKNX ROKOX RSOSS RLKVKVOUK ROQSQ RLXQX',\r\n  1007: ' 36K[VLWKWOVLTKQKOLNMMPMSNVOWQXTXVW RQKOMNPNSOVQX RTXUWVU RVSVX RWSWX RTSYS',\r\n  1008: ' 27J[NKNX ROKOX RVKVX RWKWX RLKQK RTKYK ROQVQ RLXQX RTXYX',\r\n  1009: ' 12NWRKRX RSKSX RPKUK RPXUX',\r\n  1010: ' 19LXSKSURWQX RTKTUSWQXPXNWMUNTOUNV RQKVK',\r\n  1011: ' 27JZNKNX ROKOX RWKOS RQQVX RRQWX RLKQK RTKYK RLXQX RTXYX',\r\n  1012: ' 14KXOKOX RPKPX RMKRK RMXWXWTVX',\r\n  1013: ' 30I\\\\MKMX RNNRX RNKRU RWKRX RWKWX RXKXX RKKNK RWKZK RKXOX RUXZX',\r\n  1014: ' 21JZNKNX ROMVX ROKVV RVKVX RLKOK RTKXK RLXPX',\r\n  1015: ' 32KZQKOLNMMPMSNVOWQXTXVWWVXSXPWMVLTKQK RQKOMNPNSOVQX RTXVVWSWPVMTK',\r\n  1016: ' 25JYNKNX ROKOX RLKSKVLWNWOVQSROR RSKULVNVOUQSR RLXQX',\r\n  1017: ' 47KZQKOLNMMPMSNVOWQXTXVWWVXSXPWMVLTKQK RQKOMNPNSOVQX RTXVVWSWPVMTK RPWPUQTSTTUUZV[W[XZ RTUUXVZW[',\r\n  1018: ' 37JZNKNX ROKOX RLKSKVLWNWOVQSROR RSKULVNVOUQSR RLXQX RSRTSUWVXWXXW RSRUSVWWX',\r\n  1019: ' 32KZVMWKWOVMULSKQKOLNMNOOPQQTRVSWT RNNOOQPTQVRWSWVVWTXRXPWOVNTNXOV',\r\n  1020: ' 16KZRKRX RSKSX RNKMOMKXKXOWK RPXUX',\r\n  1021: ' 20J[NKNUOWQXTXVWWUWK ROKOUPWQX RLKQK RUKYK',\r\n  1022: ' 15KYMKRX RNKRU RWKRX RKKPK RTKYK',\r\n  1023: ' 24I[LKOX RMKOT RRKOX RRKUX RSKUT RXKUX RJKOK RVKZK',\r\n  1024: ' 21KZNKVX ROKWX RWKNX RLKQK RTKYK RLXQX RTXYX',\r\n  1025: ' 20LYNKRRRX ROKSR RWKSRSX RLKQK RTKYK RPXUX',\r\n  1026: ' 16LYVKNX RWKOX ROKNONKWK RNXWXWTVX',\r\n  1027: ' 18KYRKMX RRNVX RRKWX ROTTT RKXPX RTXYX',\r\n  1028: ' 35JZNKNX ROKOX RLKSKVLWNVPSQ RSKULVNUPSQ ROQSQVRWTWUVWSXLX RSQURVTVUUWSX',\r\n  1029: ' 14KXOKOX RPKPX RMKWKWOVK RMXRX',\r\n  1030: ' 15KYRKLX RRMWX RRKXX RMWVW RLXXX',\r\n  1031: ' 22JYNKNX ROKOX RSOSS RLKVKVOUK ROQSQ RLXVXVTUX',\r\n  1032: ' 16LYVKNX RWKOX ROKNONKWK RNXWXWTVX',\r\n  1033: ' 27J[NKNX ROKOX RVKVX RWKWX RLKQK RTKYK ROQVQ RLXQX RTXYX',\r\n  1034: ' 44KZQKOLNMMPMSNVOWQXTXVWWVXSXPWMVLTKQK RQKOMNPNSOVQX RTXVVWSWPVMTK RQOQT RTOTT RQQTQ RQRTR',\r\n  1035: ' 12NWRKRX RSKSX RPKUK RPXUX',\r\n  1036: ' 27JZNKNX ROKOX RWKOS RQQVX RRQWX RLKQK RTKYK RLXQX RTXYX',\r\n  1037: ' 15KYRKMX RRNVX RRKWX RKXPX RTXYX',\r\n  1038: ' 30I\\\\MKMX RNNRX RNKRU RWKRX RWKWX RXKXX RKKNK RWKZK RKXOX RUXZX',\r\n  1039: ' 21JZNKNX ROMVX ROKVV RVKVX RLKOK RTKXK RLXPX',\r\n  1040: ' 36JZMJLM RXJWM RPPOS RUPTS RMVLY RXVWY RMKWK RMLWL RPQTQ RPRTR RMWWW RMXWX',\r\n  1041: ' 32KZQKOLNMMPMSNVOWQXTXVWWVXSXPWMVLTKQK RQKOMNPNSOVQX RTXVVWSWPVMTK',\r\n  1042: ' 21J[NKNX ROKOX RVKVX RWKWX RLKYK RLXQX RTXYX',\r\n  1043: ' 25JYNKNX ROKOX RLKSKVLWNWOVQSROR RSKULVNVOUQSR RLXQX',\r\n  1044: ' 20K[MKRQ RNKSQMX RMKWKXOVK RNWWW RMXWXXTVX',\r\n  1045: ' 16KZRKRX RSKSX RNKMOMKXKXOWK RPXUX',\r\n  1046: ' 33KZMONLOKPKQLRORX RXOWLVKUKTLSOSX RMONMOLPLQMRO RXOWMVLULTMSO RPXUX',\r\n  1047: ' 40KZRKRX RSKSX RQNNOMQMRNTQUTUWTXRXQWOTNQN RQNOONQNROTQU RTUVTWRWQVOTN RPKUK RPXUX',\r\n  1048: ' 21KZNKVX ROKWX RWKNX RLKQK RTKYK RLXQX RTXYX',\r\n  1049: ' 33J[RKRX RSKSX RLPMONOOSQU RTUVSWOXOYP RMONROTQUTUVTWRXO RPKUK RPXUX',\r\n  1050: ' 35KZMVNXQXMRMONMOLQKTKVLWMXOXRTXWXXV ROUNRNOOMQK RTKVMWOWRVU RNWPW RUWWW',\r\n  1051: ' 18KYTKKX RSMTX RTKUX RNTTT RIXNX RRXWX',\r\n  1052: ' 34JYPKLX RQKMX RNKUKWLWNVPSQ RUKVLVNUPSQ ROQRQTRUSUUTWQXJX RRQTSTUSWQX',\r\n  1053: ' 25KXVLWLXKWNVLTKRKPLOMNOMRMUNWPXRXTWUU RRKPMOONRNVPX',\r\n  1054: ' 26JYPKLX RQKMX RNKTKVLWNWQVTUVTWQXJX RTKULVNVQUTTVSWQX',\r\n  1055: ' 22JYPKLX RQKMX RSORS RNKXKWNWK ROQRQ RJXTXUUSX',\r\n  1056: ' 20JXPKLX RQKMX RSORS RNKXKWNWK ROQRQ RJXOX',\r\n  1057: ' 33KYVLWLXKWNVLTKRKPLOMNOMRMUNWPXRXTWUVVS RRKPMOONRNVPX RRXTVUS RSSXS',\r\n  1058: ' 27J[PKLX RQKMX RXKTX RYKUX RNKSK RVK[K ROQVQ RJXOX RRXWX',\r\n  1059: ' 12NWTKPX RUKQX RRKWK RNXSX',\r\n  1060: ' 19LXUKRUQWPX RVKSURWPXOXMWLUMTNUMV RSKXK',\r\n  1061: ' 27JZPKLX RQKMX RYKOR RRPTX RSPUX RNKSK RVK[K RJXOX RRXWX',\r\n  1062: ' 14KXQKMX RRKNX ROKTK RKXUXVUTX',\r\n  1063: ' 30I\\\\OKKX ROMPX RPKQV RYKPX RYKUX RZKVX RMKPK RYK\\\\K RIXMX RSXXX',\r\n  1064: ' 21JZPKLX RPKTX RQKTU RXKTX RNKQK RVKZK RJXNX',\r\n  1065: ' 32KYRKPLOMNOMRMUNWPXRXTWUVVTWQWNVLTKRK RRKPMOONRNVPX RRXTVUTVQVMTK',\r\n  1066: ' 24JYPKLX RQKMX RNKUKWLXMXOWQTROR RUKWMWOVQTR RJXOX',\r\n  1067: ' 46KYRKPLOMNOMRMUNWPXRXTWUVVTWQWNVLTKRK RRKPMOONRNVPX RRXTVUTVQVMTK ROWOVPUQURVRZS[T[UZ RRVSZT[',\r\n  1068: ' 35JZPKLX RQKMX RNKUKWLXMXOWQTROR RUKWMWOVQTR RSRTWUXVXWW RSRTSUWVX RJXOX',\r\n  1069: ' 28KZWLXLYKXNWLUKRKPLOMOOPPUSVT RONPOURVSVVUWSXPXNWMULXMWNW',\r\n  1070: ' 16KZTKPX RUKQX RPKNNOKZKYNYK RNXSX',\r\n  1071: ' 20J[PKMUMWOXSXUWVUYK RQKNUNWOX RNKSK RWK[K',\r\n  1072: ' 15KYOKPX RPKQV RYKPX RMKRK RVK[K',\r\n  1073: ' 24I[NKMX ROKNV RTKMX RTKSX RUKTV RZKSX RLKQK RXK\\\\K',\r\n  1074: ' 21KZPKTX RQKUX RYKLX RNKSK RVK[K RJXOX RRXWX',\r\n  1075: ' 20LYPKRQPX RQKSQ RYKSQQX RNKSK RVK[K RNXSX',\r\n  1076: ' 16LYXKLX RYKMX RQKONPKYK RLXUXVUTX',\r\n  1101: ' 32LZQOPPPQOQOPQOTOVQVWWXXX RTOUQUWWX RURRSPTOUOWPXSXTWUU RRSPUPWQX',\r\n  1102: ' 29JYNKNX ROKOX RORPPROTOVPWRWUVWTXRXPWOU RTOUPVRVUUWTX RLKOK',\r\n  1103: ' 24LXVQUQURVRVQUPSOQOOPNRNUOWQXSXUWVV RQOPPOROUPWQX',\r\n  1104: ' 32L[VKVX RWKWX RVRUPSOQOOPNRNUOWQXSXUWVU RQOPPOROUPWQX RTKWK RVXYX',\r\n  1105: ' 26LXOSVSVRUPSOQOOPNRNUOWQXSXUWVV RUSUQSO RQOPPOROUPWQX',\r\n  1106: ' 20LWTKULUMVMVLTKRKPMPX RRKQMQX RNOSO RNXSX',\r\n  1107: ' 42LYQOOQOSQUSUUSUQSOQO RQOPQPSQU RSUTSTQSO RTPUOVO RPTOUOXPYTYVZ ROWPXTXVYV[T\\\\P\\\\N[NYPX',\r\n  1108: ' 28J[NKNX ROKOX RORPPROTOVPWRWX RTOUPVRVX RLKOK RLXQX RTXYX',\r\n  1109: ' 18NWRKRLSLSKRK RRORX RSOSX RPOSO RPXUX',\r\n  1110: ' 23NWSKSLTLTKSK RSOSZR\\\\ RTOTZR\\\\P\\\\O[OZPZP[O[ RQOTO',\r\n  1111: ' 27JZNKNX ROKOX RWOOU RRSVX RSSWX RLKOK RTOYO RLXQX RTXYX',\r\n  1112: ' 12NWRKRX RSKSX RPKSK RPXUX',\r\n  1113: ' 44F_JOJX RKOKX RKRLPNOPORPSRSX RPOQPRRRX RSRTPVOXOZP[R[X RXOYPZRZX RHOKO RHXMX RPXUX RXX]X',\r\n  1114: ' 28J[NONX ROOOX RORPPROTOVPWRWX RTOUPVRVX RLOOO RLXQX RTXYX',\r\n  1115: ' 28LYQOOPNRNUOWQXTXVWWUWRVPTOQO RQOPPOROUPWQX RTXUWVUVRUPTO',\r\n  1116: ' 32JYNON\\\\ ROOO\\\\ RORPPROTOVPWRWUVWTXRXPWOU RTOUPVRVUUWTX RLOOO RL\\\\Q\\\\',\r\n  1117: ' 29KYUOU\\\\ RVOV\\\\ RURTPROPONPMRMUNWPXRXTWUU RPOOPNRNUOWPX RS\\\\X\\\\',\r\n  1118: ' 22KXOOOX RPOPX RPRQPSOUOVPVQUQUPVP RMOPO RMXRX',\r\n  1119: ' 26LYTOUPUQVQVPTOQOOPORQSTTVU ROQQRTSVTVWTXQXOWOVPVPWQX',\r\n  1120: ' 14LWPKPVRXTXUWUV RQKQVRX RNOTO',\r\n  1121: ' 28J[NONUOWQXSXUWVU ROOOUPWQX RVOVX RWOWX RLOOO RTOWO RVXYX',\r\n  1122: ' 15KYNORX ROORV RVORX RLOQO RTOXO',\r\n  1123: ' 24I[LOOX RMOOU RROOX RROUX RSOUU RXOUX RJOOO RVOZO',\r\n  1124: ' 21KYNOUX ROOVX RVONX RLOQO RTOXO RLXPX RSXXX',\r\n  1125: ' 23KYNORX ROORV RVORXP[N\\\\M\\\\L[LZMZM[L[ RLOQO RTOXO',\r\n  1126: ' 16LXUONX RVOOX ROONQNOVO RNXVXVVUX',\r\n  1127: ' 32K[QOOPNQMSMUNWPXQXSWUUWRXO RQOOQNSNUOWPX RQOSOUPWWXX RSOTPVWXXYX',\r\n  1128: ' 40KXRKPMOOMUK\\\\ RQLPNNTL\\\\ RRKTKVLVNUPRQ RTKULUNTPRQ RRQTRUTUVTWRXQXOWNT RRQSRTTTVRX',\r\n  1129: ' 19KYLQNOPORPSSSXR\\\\ RLQNPPPRQSS RWOVRSXQ\\\\',\r\n  1130: ' 39KYSOQOOPNQMSMUNWPXRXTWUVVTVRUPRNQLQKRJTJUKVM RQOOQNSNVPX RRXTVUTUQSO RQLRKTKVM',\r\n  1131: ' 27LXVPTOQOOPOQPRRS RQOPPPQRS RRSOTNUNWPXSXUW RRSPTOUOWPX',\r\n  1132: ' 28LWRKQLQMSNVNVMSNPOOPNRNTOVPWRXSYS[R\\\\P\\\\O[ RSNQOPPOROTPVRX',\r\n  1133: ' 26IYJRKPLONOOPOQMX RMONPNQLX ROQPPROTOVPVRS\\\\ RTOUPURR\\\\',\r\n  1134: ' 35IYJSKQLPNPOQOVPX RMPNQNUOWPXQXSWTVUTVQVNULTKRKQLQNRPURWS RQXSVTTUQUNTK',\r\n  1135: ' 13NWROPVPWQXSXUWVU RSOQVQWRX',\r\n  1136: ' 26KYOOLX RPOMX RUOVPWPVOTORQOR RORPSRWTXVWWU RORQSSWTX',\r\n  1137: ' 15LXLKNKPLWX RNKOLVX RRPMX RRPNX',\r\n  1138: ' 26KZOOK\\\\ RPOL\\\\ RNUNWOXQXSWTV RVOTVTWUXWXXWYU RWOUVUWVX',\r\n  1139: ' 19JYNOMX ROONUMX RVRVOWOVRTUQWNXMX RLOOO',\r\n  1140: ' 36MXRKQLQMSNVN RTNQOPPPRRSUS RTNROQPQRRS RSSPTOUOWQXSYTZT[S\\\\Q\\\\ RSSQTPUPWQX',\r\n  1141: ' 28KXQOOPNQMSMUNWPXRXTWUVVTVRUPSOQO RQOOQNSNVPX RRXTVUTUQSO',\r\n  1142: ' 20IZPPMX RPPNX RTPSX RTPTX RKQMOXO RKQMPXP',\r\n  1143: ' 29JXSOQOOPNQMSJ\\\\ RQOOQNSK\\\\ RSOUPVRVTUVTWRXPXNWMU RSOUQUTTVRX',\r\n  1144: ' 28K[YOQOOPNQMSMUNWPXRXTWUVVTVRUPYP RQOOQNSNVPX RRXTVUTUQSO',\r\n  1145: ' 14KZSPQX RSPRX RMQOOXO RMQOPXP',\r\n  1146: ' 24JXKRLPMOOOPPPROUOWPX RNOOPORNUNWPXQXSWUUVRVOUOVP',\r\n  1147: ' 35KZOPNQMSMUNWPXRXUWWUXRXPWOUOTPSRRUO\\\\ RMUNVPWRWUVWTXR RXQWPUPSR RRUQXP\\\\',\r\n  1148: ' 17KXMONOPPS[T\\\\ RNOOPR[T\\\\U\\\\ RVOTRNYL\\\\',\r\n  1149: ' 28I[TKQ\\\\ RUKP\\\\ RJRKPLONOOPOVPWSWUVWT RMONPNTOWPXSXUWWTXRYO',\r\n  1150: ' 36JZNPPPPONPMQLSLUMWNXPXQWRUSR RLUNWPWRU RRRRWSXUXWVXTXRWPVOVPWP RRUSWUWWV',\r\n  1151: ' 32KZVOTVTWUXWXXWYU RWOUVUWVX RUSUQSOQOOPNQMSMUNWPXRXTV RQOOQNSNVPX',\r\n  1152: ' 32JXOKMR RPKNRNVPX RNROPQOSOUPVRVTUVTWRXPXNWMUMR RSOUQUTTVRX RMKPK',\r\n  1153: ' 22KXUPUQVQUPSOQOOPNQMSMUNWPXRXTWUV RQOOQNSNVPX',\r\n  1154: ' 35KZWKTVTWUXWXXWYU RXKUVUWVX RUSUQSOQOOPNQMSMUNWPXRXTV RQOOQNSNVPX RUKXK',\r\n  1155: ' 23KWNURTTSURUPSOQOOPNQMSMUNWPXRXTWUV RQOOQNSNVPX',\r\n  1156: ' 23MXWKXLXKVKTLSNPYO[N\\\\ RVKULTNQYP[N\\\\L\\\\L[M\\\\ RPOVO',\r\n  1157: ' 34KYVOTVSYR[ RWOUVTYR[P\\\\M\\\\L[M[N\\\\ RUSUQSOQOOPNQMSMUNWPXRXTV RQOOQNSNVPX',\r\n  1158: ' 29KZPKLX RQKMX ROQPPROTOVPVRUUUWVX RTOUPURTUTWUXWXXWYU RNKQK',\r\n  1159: ' 26MWSKSLTLTKSK RNROPPOROSPSRRURWSX RQORPRRQUQWRXTXUWVU',\r\n  1160: ' 26MWTKTLULUKTK RORPPQOSOTPTRRYQ[O\\\\M\\\\M[N\\\\ RROSPSRQYP[O\\\\',\r\n  1161: ' 32KXPKLX RQKMX RVPUQVQVPUOTORQPROR RORPSQWRXTXUWVU RORQSRWSX RNKQK',\r\n  1162: ' 16NVSKPVPWQXSXTWUU RTKQVQWRX RQKTK',\r\n  1163: ' 46F^GRHPIOKOLPLQJX RJOKPKQIX RLQMPOOQOSPSQQX RQORPRQPX RSQTPVOXOZPZRYUYWZX RXOYPYRXUXWYX[X\\\\W]U',\r\n  1164: ' 33J[KRLPMOOOPPPQNX RNOOPOQMX RPQQPSOUOWPWRVUVWWX RUOVPVRUUUWVXXXYWZU',\r\n  1165: ' 28KXQOOPNQMSMUNWPXRXTWUVVTVRUPSOQO RQOOQNSNVPX RRXTVUTUQSO',\r\n  1166: ' 35JYKRLPMOOOPPPQM\\\\ RNOOPOQL\\\\ RPQROTOVPWRWTVVUWSXQXOVOT RTOVQVTUVSX RJ\\\\O\\\\',\r\n  1167: ' 28KYVOR\\\\ RWOS\\\\ RUSUQSOQOOPNQMSMUNWPXRXTV RQOOQNSNVPX RP\\\\U\\\\',\r\n  1168: ' 22LXMRNPOOQORPRQPX RPOQPQQOX RRQSPUOVOWPWQVQWP',\r\n  1169: ' 24LYVPVQWQVPTOQOOPORQSTTVU ROQQRTSVTVWTXQXOWNVOVOW',\r\n  1170: ' 16NWSKPVPWQXSXTWUU RTKQVQWRX RPOUO',\r\n  1171: ' 33IZJRKPLONOOPORNUNWOX RMONPNRMUMWOXQXSWTV RVOTVTWUXWXXWYU RWOUVUWVX',\r\n  1172: ' 24JXKRLPMOOOPPPROUOWPX RNOOPORNUNWPXQXSWUUVRVOUOVP',\r\n  1173: ' 37H\\\\IRJPKOMONPNRMUMWNX RLOMPMRLULWNXOXQWRV RTORVRWTX RUOSVSWTXUXWWYUZRZOYOZP',\r\n  1174: ' 38JZMRNPPOROSPSR RQORPRRQUPWNXMXLWLVMVLW RXPWQXQXPWOVOTPSRRURWSX RQUQWRXTXVWWU',\r\n  1175: ' 35IYJRKPLONOOPORNUNWOX RMONPNRMUMWOXQXSWTV RVOTVSYR[ RWOUVTYR[P\\\\M\\\\L[M[N\\\\',\r\n  1176: ' 27KYWOWPVQNVMWMX RNQOOROUQ ROPRPUQVQ RNVOVRWUW ROVRXUXVV',\r\n  1177: ' 39H[RKSLSMTMTLRKOKMLLNLX ROKNLMNMX RXKYLYMZMZLXKVKTMTX RVKUMUX RJOWO RJXOX RRXWX',\r\n  1178: ' 29J[UKVLWLWKQKOLNNNX RQKPLONOX RVOVX RWOWX RLOWO RLXQX RTXYX',\r\n  1179: ' 27J[WKQKOLNNNX RQKPLONOX RUKVLVX RWKWX RLOVO RLXQX RTXYX',\r\n  1180: ' 48F_PKQLQMRMRLPKMKKLJNJX RMKLLKNKX RYKZL[L[KUKSLRNRX RUKTLSNSX RZOZX R[O[X RHO[O RHXMX RPXUX RXX]X',\r\n  1181: ' 46F_PKQLQMRMRLPKMKKLJNJX RMKLLKNKX R[KUKSLRNRX RUKTLSNSX RYKZLZX R[K[X RHOZO RHXMX RPXUX RXX]X',\r\n  1182: ' 12NWRORX RSOSX RPOSO RPXUX',\r\n  1184: ' 21LXVPTOROPPOQNSNUOWQXSXUW RROPQOSOVQX ROSSS',\r\n  1185: ' 35LYSKQLPMOONRNUOWPXRXTWUVVTWQWNVLUKSK RSKQMPOOSOVPX RRXTVUTVPVMUK ROQVQ',\r\n  1186: ' 34KZTKQ\\\\ RUKP\\\\ RQONPMRMUNWQXTXWWXUXRWPTOQO RQOOPNRNUOWQX RTXVWWUWRVPTO',\r\n  1187: ' 22LXUPVRVQUPSOQOOPNRNTOVRX RQOOQOTPVRXSYS[R\\\\P\\\\',\r\n  1191: ' 45I[VKWLXLVKSKQLPMOOLYK[J\\\\ RSKQMPOMYL[J\\\\H\\\\H[I\\\\ RZK[L[KYKWLVNSYR[Q\\\\ RYKXLWNTYS[Q\\\\O\\\\O[P\\\\ RLOYO',\r\n  1192: ' 38IZVKWLXLXKSKQLPMOOLYK[J\\\\ RSKQMPOMYL[J\\\\H\\\\H[I\\\\ RVOTVTWUXWXXWYU RWOUVUWVX RLOWO',\r\n  1193: ' 38IZVKWL RXKSKQLPMOOLYK[J\\\\ RSKQMPOMYL[J\\\\H\\\\H[I\\\\ RWKTVTWUXWXXWYU RXKUVUWVX RLOVO',\r\n  1194: ' 63F^SKTLTM RULSKPKNLMMLOIYH[G\\\\ RPKNMMOJYI[G\\\\E\\\\E[F\\\\ RZK[L\\\\L\\\\KWKUL RTMSOPYO[N\\\\ RWKUMTOQYP[N\\\\L\\\\L[M\\\\ RZOXVXWYX[X\\\\W]U R[OYVYWZX RIO[O',\r\n  1195: ' 63F^SKTLTM RULSKPKNLMMLOIYH[G\\\\ RPKNMMOJYI[G\\\\E\\\\E[F\\\\ RZK[L R\\\\KWKUL RTMSOPYO[N\\\\ RWKUMTOQYP[N\\\\L\\\\L[M\\\\ R[KXVXWYX[X\\\\W]U R\\\\KYVYWZX RIOZO',\r\n  1196: ' 20MWNROPPOROSPSRRURWSX RQORPRRQUQWRXTXUWVU',\r\n  1200: ' 28LYQKOLNONTOWQXTXVWWTWOVLTKQK RQKPLOOOTPWQX RTXUWVTVOULTK',\r\n  1201: ' 10LYPNSKSX RRLRX ROXVX',\r\n  1202: ' 35LYOMONNNNMOLQKTKVLWNVPTQQROSNUNX RTKULVNUPTQ RNWOVPVSWVWWV RPVSXVXWVWU',\r\n  1203: ' 39LYOMONNNNMOLQKTKVLWNVPTQ RTKULVNUPTQ RRQTQVRWTWUVWTXQXOWNVNUOUOV RTQURVTVUUWTX',\r\n  1204: ' 13LYSMSX RTKTX RTKMTXT RQXVX',\r\n  1205: ' 33LYOKNQ ROKVK ROLSLVK RNQOPQOTOVPWRWUVWTXQXOWNVNUOUOV RTOUPVRVUUWTX',\r\n  1206: ' 36LYVMVNWNWMVLTKRKPLOMNPNUOWQXTXVWWUWSVQTPQPNR RRKPMOPOUPWQX RTXUWVUVSUQTP',\r\n  1207: ' 22LYNKNO RVMRTPX RWKTQQX RNMPKRKUM RNMPLRLUMVM',\r\n  1208: ' 51LYQKOLNNOPQQTQVPWNVLTKQK RQKPLONPPQQ RTQUPVNULTK RQQORNTNUOWQXTXVWWUWTVRTQ RQQPROTOUPWQX RTXUWVUVTURTQ',\r\n  1209: ' 36LYOVOUNUNVOWQXSXUWVVWSWNVLTKQKOLNNNPORQSTSWQ RSXUVVSVNULTK RQKPLONOPPRQS',\r\n  1210: '  6NVRVQWRXSWRV',\r\n  1211: '  8NVSWRXQWRVSWSYQ[',\r\n  1212: ' 12NVROQPRQSPRO RRVQWRXSWRV',\r\n  1213: ' 14NVROQPRQSPRO RSWRXQWRVSWSYQ[',\r\n  1214: ' 15NVRKQLRSSLRK RRLRO RRVQWRXSWRV',\r\n  1215: ' 29LYNNONOONONNOLQKTKVLWNWOVQSRRSRTST RTKVMVPUQSR RRWRXSXSWRW',\r\n  1216: '  6OVRKRP RSKRP',\r\n  1217: ' 12LXOKOP RPKOP RUKUP RVKUP',\r\n  1218: ' 10MWQKPLPNQOSOTNTLSKQK',\r\n  1219: '  9MWRJRP ROKUO RUKOO',\r\n  1220: '  3KZXHM\\\\',\r\n  1221: ' 16MWUHSJQMPPPTQWSZU\\\\ RSJRLQPQTRXSZ',\r\n  1222: ' 16MWOHQJSMTPTTSWQZO\\\\ RQJRLSPSTRXQZ',\r\n  1223: ' 12MWPHP\\\\ RQHQ\\\\ RPHUH RP\\\\U\\\\',\r\n  1224: ' 12MWSHS\\\\ RTHT\\\\ ROHTH RO\\\\T\\\\',\r\n  1225: ' 38LWSHQIPJPLRNSP RQIPL RSNRQ RPJQLSNSPRQPRRSSTSVQXPZ RRSSV RPXQ[ RSTRVPXPZQ[S\\\\',\r\n  1226: ' 38MXQHSITJTLRNQP RSITL RQNRQ RTJSLQNQPRQTRRSQTQVSXTZ RRSQV RTXS[ RQTRVTXTZS[Q\\\\',\r\n  1227: '  4MWTHPRT\\\\',\r\n  1228: '  4MWPHTRP\\\\',\r\n  1229: '  3OURHR\\\\',\r\n  1230: '  6MWPHP\\\\ RTHT\\\\',\r\n  1231: '  3I[LRXR',\r\n  1232: '  6I[RLRX RLRXR',\r\n  1233: '  9JZRMRX RMRWR RMXWX',\r\n  1234: '  9JZRMRX RMMWM RMRWR',\r\n  1235: '  6JZMMWW RWMMW',\r\n  1236: '  6NVRQQRRSSRRQ',\r\n  1237: ' 15I[RLQMRNSMRL RLRXR RRVQWRXSWRV',\r\n  1238: '  6I[LPXP RLTXT',\r\n  1239: '  9I[WLMX RLPXP RLTXT',\r\n  1240: '  9I[LNXN RLRXR RLVXV',\r\n  1241: '  4JZWLMRWX',\r\n  1242: '  4JZMLWRMX',\r\n  1243: ' 10JZWKMOWS RMTWT RMXWX',\r\n  1244: ' 10JZMKWOMS RMTWT RMXWX',\r\n  1245: ' 21H[YUWUUTTSRPQOONNNLOKQKRLTNUOUQTRSTPUOWNYN',\r\n  1246: ' 16JZLTLRMPOPUSWSXR RLRMQOQUTWTXRXP',\r\n  1247: '  8JZMSRPWS RMSRQWS',\r\n  1248: '  7NVSKPO RSKTLPO',\r\n  1249: '  7NVQKTO RQKPLTO',\r\n  1250: ' 14LXNKOMQNSNUMVK RNKONQOSOUNVK',\r\n  1251: '  8NVSLRMQLRKSLSNQP',\r\n  1252: '  8NVSKQMQORPSORNQO',\r\n  1253: '  8NVQLRMSLRKQLQNSP',\r\n  1254: '  8NVQKSMSORPQORNSO',\r\n  1256: ' 11JZWMQMONNOMQMSNUOVQWWW',\r\n  1257: ' 11JZMMMSNUOVQWSWUVVUWSWM',\r\n  1258: ' 11JZMMSMUNVOWQWSVUUVSWMW',\r\n  1259: ' 11JZMWMQNOONQMSMUNVOWQWW',\r\n  1260: ' 14JZWMQMONNOMQMSNUOVQWWW RMRUR',\r\n  1261: ' 13I[TOUPXRUTTU RUPWRUT RLRWR',\r\n  1262: ' 13MWRMRX ROPPORLTOUP RPORMTO',\r\n  1263: ' 13I[POOPLROTPU ROPMROT RMRXR',\r\n  1264: ' 13MWRLRW ROTPURXTUUT RPURWTU',\r\n  1265: ' 37KYVSUPSOQOOPNQMSMUNWPXRXTWUVVTWQWNVLTKQKPLQLRK RQOOQNSNVPX RRXTVUTVQVNULTK',\r\n  1266: ' 15JZLKRX RMKRV RXKRX RLKXK RNLWL',\r\n  1267: ' 10G[IOLORW RKORX R[FRX',\r\n  1268: ' 26I[XIXJYJYIXHVHTJSLROQUPYO[ RUITKSORUQXPZN\\\\L\\\\K[KZLZL[',\r\n  1269: ' 40I[XIXJYJYIXHVHTJSLROQUPYO[ RUITKSORUQXPZN\\\\L\\\\K[KZLZL[ RQNOONQNSOUQVSVUUVSVQUOSNQN',\r\n  1270: ' 26H\\\\ZRYTWUVUTTSSQPPONNMNKOJQJRKTMUNUPTQSSPTOVNWNYOZQZR',\r\n  1271: ' 26JZXKLX ROKPLPNOOMOLNLLMKOKSLVLXK RUTTUTWUXWXXWXUWTUT',\r\n  1272: ' 41J[YPXPXQYQYPXOWOVPUTTVSWQXOXMWLVLTMSORRPSNSLRKPKOLONPQUWWXXXYW ROXMVMTOR RONPPVWWX',\r\n  1273: ' 29J[UPSOQOPQPRQTSTUS RUOUSVTXTYRYQXNVLSKRKOLMNLQLRMUOWRXSXVW',\r\n  1274: ' 34KZQHQ\\\\ RTHT\\\\ RWLVLVMWMWLUKPKNLNNOPVSWT RNNOOVRWTWVVWTXQXOWNVNUOUOVNV',\r\n  1275: ' 12KYRKN\\\\ RVKR\\\\ RNQWQ RMVVV',\r\n  1276: ' 40LXTLSLSMTMTLSKQKPLPNQPTRUS RPNQOTQUSUUSW RQPOROTPVSXTY ROTPUSWTYT[S\\\\Q\\\\P[PZQZQ[P[',\r\n  1277: ' 29LXRKQLRMSLRK RRMRQ RRQQSRVSSRQ RRVR\\\\ RPOONNOOPPOTOUNVOUPTO',\r\n  1278: ' 42LXRMSLRKQLRMRQQRSURV RRQSRQURVRZQ[R\\\\S[RZ RPOONNOOPPOTOUNVOUPTO RPXOWNXOYPXTXUWVXUYTX',\r\n  1279: ' 12LYVKVX RNKVK RQQVQ RNXVX',\r\n  1281: ' 24H\\\\QKNLLNKQKSLVNXQYSYVXXVYSYQXNVLSKQK RRQQRRSSRRQ',\r\n  1282: ' 33LYQKPLPMQN RTKULUMTN RRNPOOQORPTRUSUUTVRVQUOSNRN RRURY RSUSY ROWVW',\r\n  1283: ' 23LYRKPLONOOPQRRSRUQVOVNULSKRK RRRRX RSRSX ROUVU',\r\n  1284: ' 24H\\\\QKNLLNKQKSLVNXQYSYVXXVYSYQXNVLSKQK RRKRY RKRYR',\r\n  1285: ' 25JYRRPQOQMRLTLUMWOXPXRWSUSTRR RWMRR RRMWMWR RRMVNWR',\r\n  1286: ' 25JZLLMKOKQLRNRPQRPSNT ROKPLQNQQPS RVKUX RWKTX RNTXT',\r\n  1287: ' 27JYNKNU ROKNR RNROPQOSOUPVQVTTVTXUYVYWX RSOUQUTTV RLKOK',\r\n  1288: ' 27LYONRKRQ RVNSKSQ RRQPROTOUPWRXSXUWVUVTURSQ RRTRUSUSTRT',\r\n  1289: ' 27JZRKRY RMKMPNRPSTSVRWPWK RLMMKNM RQMRKSM RVMWKXM ROVUV',\r\n  1290: ' 27JYNKNX ROKOX RLKSKVLWNWOVQSROR RSKULVNVOUQSR RLXVXVUUX',\r\n  1291: ' 20LYWKTKQLONNQNSOVQXTYWY RWKTLRNQQQSRVTXWY',\r\n  1292: ' 23JZRRPQOQMRLTLUMWOXPXRWSUSTRR RSLQQ RWMRR RXQSS',\r\n  1293: ' 12KYPMTW RTMPW RMPWT RWPMT',\r\n  1294: ' 34J[OUMULVLXMYOYPXPVNTMRMONMOLQKTKVLWMXOXRWTUVUXVYXYYXYVXUVU RNMPLULWM',\r\n  1295: ' 34J[OOMOLNLLMKOKPLPNNPMRMUNWOXQYTYVXWWXUXRWPUNULVKXKYLYNXOVO RNWPXUXWW',\r\n  1401: ' 21F^KHK\\\\ RLHL\\\\ RXHX\\\\ RYHY\\\\ RHH\\\\H RH\\\\O\\\\ RU\\\\\\\\\\\\',\r\n  1402: ' 20H]KHRQJ\\\\ RJHQQ RJHYHZMXH RK[X[ RJ\\\\Y\\\\ZWX\\\\',\r\n  1403: ' 20KYVBTDRGPKOPOTPYR]T`Vb RTDRHQKPPPTQYR\\\\T`',\r\n  1404: ' 20KYNBPDRGTKUPUTTYR]P`Nb RPDRHSKTPTTSYR\\\\P`',\r\n  1405: ' 12KYOBOb RPBPb ROBVB RObVb',\r\n  1406: ' 12KYTBTb RUBUb RNBUB RNbUb',\r\n  1407: ' 40KYTBRCQDPFPHQJRKSMSOQQ RRCQEQGRISJTLTNSPORSTTVTXSZR[Q]Q_Ra RQSSUSWRYQZP\\\\P^Q`RaTb',\r\n  1408: ' 40KYPBRCSDTFTHSJRKQMQOSQ RRCSESGRIQJPLPNQPURQTPVPXQZR[S]S_Ra RSSQUQWRYSZT\\\\T^S`RaPb',\r\n  1409: ' 24KYU@RCPFOIOLPOSVTYT\\\\S_Ra RRCQEPHPKQNTUUXU[T^RaOd',\r\n  1410: ' 24KYO@RCTFUIULTOQVPYP\\\\Q_Ra RRCSETHTKSNPUOXO[P^RaUd',\r\n  1411: ' 13AXCRGRR` RGSRa RFSRb RX:Rb',\r\n  1412: ' 32F^[CZD[E\\\\D\\\\C[BYBWCUETGSJRNPZO^N` RVDUFTJRVQZP]O_MaKbIbHaH`I_J`Ia',\r\n  2001: ' 18H\\\\RFK[ RRFY[ RRIX[ RMUVU RI[O[ RU[[[',\r\n  2002: ' 45G]LFL[ RMFM[ RIFUFXGYHZJZLYNXOUP RUFWGXHYJYLXNWOUP RMPUPXQYRZTZWYYXZU[I[ RUPWQXRYTYWXYWZU[',\r\n  2003: ' 32G\\\\XIYLYFXIVGSFQFNGLIKKJNJSKVLXNZQ[S[VZXXYV RQFOGMILKKNKSLVMXOZQ[',\r\n  2004: ' 30G]LFL[ RMFM[ RIFSFVGXIYKZNZSYVXXVZS[I[ RSFUGWIXKYNYSXVWXUZS[',\r\n  2005: ' 22G\\\\LFL[ RMFM[ RSLST RIFYFYLXF RMPSP RI[Y[YUX[',\r\n  2006: ' 20G[LFL[ RMFM[ RSLST RIFYFYLXF RMPSP RI[P[',\r\n  2007: ' 40G^XIYLYFXIVGSFQFNGLIKKJNJSKVLXNZQ[S[VZXX RQFOGMILKKNKSLVMXOZQ[ RXSX[ RYSY[ RUS\\\\S',\r\n  2008: ' 27F^KFK[ RLFL[ RXFX[ RYFY[ RHFOF RUF\\\\F RLPXP RH[O[ RU[\\\\[',\r\n  2009: ' 12MXRFR[ RSFS[ ROFVF RO[V[',\r\n  2010: ' 20KZUFUWTZR[P[NZMXMVNUOVNW RTFTWSZR[ RQFXF',\r\n  2011: ' 27F\\\\KFK[ RLFL[ RYFLS RQOY[ RPOX[ RHFOF RUF[F RH[O[ RU[[[',\r\n  2012: ' 14I[NFN[ ROFO[ RKFRF RK[Z[ZUY[',\r\n  2013: ' 30F_KFK[ RLFRX RKFR[ RYFR[ RYFY[ RZFZ[ RHFLF RYF]F RH[N[ RV[][',\r\n  2014: ' 21G^LFL[ RMFYY RMHY[ RYFY[ RIFMF RVF\\\\F RI[O[',\r\n  2015: ' 44G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF RQFOGMILKKOKRLVMXOZQ[ RS[UZWXXVYRYOXKWIUGSF',\r\n  2016: ' 29G]LFL[ RMFM[ RIFUFXGYHZJZMYOXPUQMQ RUFWGXHYJYMXOWPUQ RI[P[',\r\n  2017: ' 64G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF RQFOGMILKKOKRLVMXOZQ[ RS[UZWXXVYRYOXKWIUGSF RNYNXOVQURUTVUXV_W`Y`Z^Z] RUXV\\\\W^X_Y_Z^',\r\n  2018: ' 45G]LFL[ RMFM[ RIFUFXGYHZJZLYNXOUPMP RUFWGXHYJYLXNWOUP RI[P[ RRPTQURXYYZZZ[Y RTQUSWZX[Z[[Y[X',\r\n  2019: ' 34H\\\\XIYFYLXIVGSFPFMGKIKKLMMNOOUQWRYT RKKMMONUPWQXRYTYXWZT[Q[NZLXKUK[LX',\r\n  2020: ' 16I\\\\RFR[ RSFS[ RLFKLKFZFZLYF RO[V[',\r\n  2021: ' 23F^KFKULXNZQ[S[VZXXYUYF RLFLUMXOZQ[ RHFOF RVF\\\\F',\r\n  2022: ' 15H\\\\KFR[ RLFRX RYFR[ RIFOF RUF[F',\r\n  2023: ' 24F^JFN[ RKFNV RRFN[ RRFV[ RSFVV RZFV[ RGFNF RWF]F',\r\n  2024: ' 21H\\\\KFX[ RLFY[ RYFK[ RIFOF RUF[F RI[O[ RU[[[',\r\n  2025: ' 20H]KFRQR[ RLFSQS[ RZFSQ RIFOF RVF\\\\F RO[V[',\r\n  2026: ' 16H\\\\XFK[ RYFL[ RLFKLKFYF RK[Y[YUX[',\r\n  2027: ' 18H\\\\RFK[ RRFY[ RRIX[ RMUVU RI[O[ RU[[[',\r\n  2028: ' 45G]LFL[ RMFM[ RIFUFXGYHZJZLYNXOUP RUFWGXHYJYLXNWOUP RMPUPXQYRZTZWYYXZU[I[ RUPWQXRYTYWXYWZU[',\r\n  2029: ' 14I[NFN[ ROFO[ RKFZFZLYF RK[R[',\r\n  2030: ' 15H\\\\RFJ[ RRFZ[ RRIY[ RKZYZ RJ[Z[',\r\n  2031: ' 22G\\\\LFL[ RMFM[ RSLST RIFYFYLXF RMPSP RI[Y[YUX[',\r\n  2032: ' 16H\\\\XFK[ RYFL[ RLFKLKFYF RK[Y[YUX[',\r\n  2033: ' 27F^KFK[ RLFL[ RXFX[ RYFY[ RHFOF RUF\\\\F RLPXP RH[O[ RU[\\\\[',\r\n  2034: ' 56G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF RQFOGMILKKOKRLVMXOZQ[ RS[UZWXXVYRYOXKWIUGSF ROMOT RUMUT ROPUP ROQUQ',\r\n  2035: ' 12MXRFR[ RSFS[ ROFVF RO[V[',\r\n  2036: ' 27F\\\\KFK[ RLFL[ RYFLS RQOY[ RPOX[ RHFOF RUF[F RH[O[ RU[[[',\r\n  2037: ' 15H\\\\RFK[ RRFY[ RRIX[ RI[O[ RU[[[',\r\n  2038: ' 30F_KFK[ RLFRX RKFR[ RYFR[ RYFY[ RZFZ[ RHFLF RYF]F RH[N[ RV[][',\r\n  2039: ' 21G^LFL[ RMFYY RMHY[ RYFY[ RIFMF RVF\\\\F RI[O[',\r\n  2040: ' 36G]KEJJ RZEYJ RONNS RVNUS RKWJ\\\\ RZWY\\\\ RKGYG RKHYH ROPUP ROQUQ RKYYY RKZYZ',\r\n  2041: ' 44G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF RQFOGMILKKOKRLVMXOZQ[ RS[UZWXXVYRYOXKWIUGSF',\r\n  2042: ' 21F^KFK[ RLFL[ RXFX[ RYFY[ RHF\\\\F RH[O[ RU[\\\\[',\r\n  2043: ' 29G]LFL[ RMFM[ RIFUFXGYHZJZMYOXPUQMQ RUFWGXHYJYMXOWPUQ RI[P[',\r\n  2044: ' 20H]KFRPJ[ RJFQP RJFYFZLXF RKZXZ RJ[Y[ZUX[',\r\n  2045: ' 16I\\\\RFR[ RSFS[ RLFKLKFZFZLYF RO[V[',\r\n  2046: ' 33I\\\\KKKILGMFOFPGQIRMR[ RKIMGOGQI RZKZIYGXFVFUGTISMS[ RZIXGVGTI RO[V[',\r\n  2047: ' 48H]RFR[ RSFS[ RPKMLLMKOKRLTMUPVUVXUYTZRZOYMXLUKPK RPKNLMMLOLRMTNUPV RUVWUXTYRYOXMWLUK ROFVF RO[V[',\r\n  2048: ' 21H\\\\KFX[ RLFY[ RYFK[ RIFOF RUF[F RI[O[ RU[[[',\r\n  2049: ' 41G^RFR[ RSFS[ RIMJLLMMQNSOTQU RJLKMLQMSNTQUTUWTXSYQZM[L RTUVTWSXQYM[L\\\\M ROFVF RO[V[',\r\n  2050: ' 43G]JXK[O[MWKSJPJLKIMGPFTFWGYIZLZPYSWWU[Y[ZX RMWLTKPKLLINGPF RTFVGXIYLYPXTWW RKZNZ RVZYZ',\r\n  2051: ' 18H\\\\UFH[ RUFV[ RTHU[ RLUUU RF[L[ RR[X[',\r\n  2052: ' 41F^OFI[ RPFJ[ RLFWFZG[I[KZNYOVP RWFYGZIZKYNXOVP RMPVPXQYSYUXXVZR[F[ RVPWQXSXUWXUZR[',\r\n  2053: ' 34H]ZH[H\\\\F[L[JZHYGWFTFQGOIMLLOKSKVLYMZP[S[UZWXXV RTFRGPINLMOLSLVMYNZP[',\r\n  2054: ' 30F]OFI[ RPFJ[ RLFUFXGYHZKZOYSWWUYSZO[F[ RUFWGXHYKYOXSVWTYRZO[',\r\n  2055: ' 22F]OFI[ RPFJ[ RTLRT RLF[FZLZF RMPSP RF[U[WVT[',\r\n  2056: ' 20F\\\\OFI[ RPFJ[ RTLRT RLF[FZLZF RMPSP RF[M[',\r\n  2057: ' 42H^ZH[H\\\\F[L[JZHYGWFTFQGOIMLLOKSKVLYMZP[R[UZWXYT RTFRGPINLMOLSLVMYNZP[ RR[TZVXXT RUT\\\\T',\r\n  2058: ' 27E_NFH[ ROFI[ R[FU[ R\\\\FV[ RKFRF RXF_F RLPXP RE[L[ RR[Y[',\r\n  2059: ' 12LYUFO[ RVFP[ RRFYF RL[S[',\r\n  2060: ' 21I[XFSWRYQZO[M[KZJXJVKULVKW RWFRWQYO[ RTF[F',\r\n  2061: ' 27F]OFI[ RPFJ[ R]FLS RSOW[ RROV[ RLFSF RYF_F RF[M[ RS[Y[',\r\n  2062: ' 14H\\\\QFK[ RRFL[ RNFUF RH[W[YUV[',\r\n  2063: ' 30E`NFH[ RNFO[ ROFPY R\\\\FO[ R\\\\FV[ R]FW[ RKFOF R\\\\F`F RE[K[ RS[Z[',\r\n  2064: ' 21F_OFI[ ROFVX ROIV[ R\\\\FV[ RLFOF RYF_F RF[L[',\r\n  2065: ' 42G]SFPGNILLKOJSJVKYLZN[Q[TZVXXUYRZNZKYHXGVFSF RSFQGOIMLLOKSKVLYN[ RQ[SZUXWUXRYNYKXHVF',\r\n  2066: ' 27F]OFI[ RPFJ[ RLFXF[G\\\\I\\\\K[NYPUQMQ RXFZG[I[KZNXPUQ RF[M[',\r\n  2067: ' 61G]SFPGNILLKOJSJVKYLZN[Q[TZVXXUYRZNZKYHXGVFSF RSFQGOIMLLOKSKVLYN[ RQ[SZUXWUXRYNYKXHVF RLYLXMVOUPURVSXS_T`V`W^W] RSXT^U_V_W^',\r\n  2068: ' 42F^OFI[ RPFJ[ RLFWFZG[I[KZNYOVPMP RWFYGZIZKYNXOVP RRPTQURVZW[Y[ZYZX RURWYXZYZZY RF[M[',\r\n  2069: ' 35G^ZH[H\\\\F[L[JZHYGVFRFOGMIMKNMONVRXT RMKOMVQWRXTXWWYVZS[O[LZKYJWJUI[JYKY',\r\n  2070: ' 16H]UFO[ RVFP[ ROFLLNF]F\\\\L\\\\F RL[S[',\r\n  2071: ' 25F_NFKQJUJXKZN[R[UZWXXU\\\\F ROFLQKUKXLZN[ RKFRF RYF_F',\r\n  2072: ' 15H\\\\NFO[ ROFPY R\\\\FO[ RLFRF RXF^F',\r\n  2073: ' 24E_MFK[ RNFLY RUFK[ RUFS[ RVFTY R]FS[ RJFQF RZF`F',\r\n  2074: ' 21G]NFU[ ROFV[ R\\\\FH[ RLFRF RXF^F RF[L[ RR[X[',\r\n  2075: ' 20H]NFRPO[ ROFSPP[ R]FSP RLFRF RYF_F RL[S[',\r\n  2076: ' 16G][FH[ R\\\\FI[ ROFLLNF\\\\F RH[V[XUU[',\r\n  2077: ' 46H\\\\KILKXWYYY[ RLLXX RKIKKLMXYY[ RPPLTKVKXLZK[ RKVMZ RLTLVMXMZK[ RSSXN RVIVLWNYNYLWKVI RVIWLYN',\r\n  2101: ' 39I]NONPMPMONNPMTMVNWOXQXXYZZ[ RWOWXXZZ[[[ RWQVRPSMTLVLXMZP[S[UZWX RPSNTMVMXNZP[',\r\n  2102: ' 33G\\\\LFL[ RMFM[ RMPONQMSMVNXPYSYUXXVZS[Q[OZMX RSMUNWPXSXUWXUZS[ RIFMF',\r\n  2103: ' 28H[WPVQWRXQXPVNTMQMNNLPKSKULXNZQ[S[VZXX RQMONMPLSLUMXOZQ[',\r\n  2104: ' 36H]WFW[ RXFX[ RWPUNSMQMNNLPKSKULXNZQ[S[UZWX RQMONMPLSLUMXOZQ[ RTFXF RW[[[',\r\n  2105: ' 31H[LSXSXQWOVNTMQMNNLPKSKULXNZQ[S[VZXX RWSWPVN RQMONMPLSLUMXOZQ[',\r\n  2106: ' 22KXUGTHUIVHVGUFSFQGPIP[ RSFRGQIQ[ RMMUM RM[T[',\r\n  2107: ' 60I\\\\QMONNOMQMSNUOVQWSWUVVUWSWQVOUNSMQM RONNPNTOV RUVVTVPUN RVOWNYMYNWN RNUMVLXLYM[P\\\\U\\\\X]Y^ RLYMZP[U[X\\\\Y^Y_XaUbObLaK_K^L\\\\O[',\r\n  2108: ' 28G]LFL[ RMFM[ RMPONRMTMWNXPX[ RTMVNWPW[ RIFMF RI[P[ RT[[[',\r\n  2109: ' 18MXRFQGRHSGRF RRMR[ RSMS[ ROMSM RO[V[',\r\n  2110: ' 25MXSFRGSHTGSF RTMT_SaQbObNaN`O_P`Oa RSMS_RaQb RPMTM',\r\n  2111: ' 27G\\\\LFL[ RMFM[ RWMMW RRSX[ RQSW[ RIFMF RTMZM RI[P[ RT[Z[',\r\n  2112: ' 12MXRFR[ RSFS[ ROFSF RO[V[',\r\n  2113: ' 44BcGMG[ RHMH[ RHPJNMMOMRNSPS[ ROMQNRPR[ RSPUNXMZM]N^P^[ RZM\\\\N]P][ RDMHM RD[K[ RO[V[ RZ[a[',\r\n  2114: ' 28G]LML[ RMMM[ RMPONRMTMWNXPX[ RTMVNWPW[ RIMMM RI[P[ RT[[[',\r\n  2115: ' 36H\\\\QMNNLPKSKULXNZQ[S[VZXXYUYSXPVNSMQM RQMONMPLSLUMXOZQ[ RS[UZWXXUXSWPUNSM',\r\n  2116: ' 36G\\\\LMLb RMMMb RMPONQMSMVNXPYSYUXXVZS[Q[OZMX RSMUNWPXSXUWXUZS[ RIMMM RIbPb',\r\n  2117: ' 33H\\\\WMWb RXMXb RWPUNSMQMNNLPKSKULXNZQ[S[UZWX RQMONMPLSLUMXOZQ[ RTb[b',\r\n  2118: ' 23IZNMN[ ROMO[ ROSPPRNTMWMXNXOWPVOWN RKMOM RK[R[',\r\n  2119: ' 32J[WOXMXQWOVNTMPMNNMOMQNRPSUUWVXW RMPNQPRUTWUXVXYWZU[Q[OZNYMWM[NY',\r\n  2120: ' 16KZPFPWQZS[U[WZXX RQFQWRZS[ RMMUM',\r\n  2121: ' 28G]LMLXMZP[R[UZWX RMMMXNZP[ RWMW[ RXMX[ RIMMM RTMXM RW[[[',\r\n  2122: ' 15I[LMR[ RMMRY RXMR[ RJMPM RTMZM',\r\n  2123: ' 24F^JMN[ RKMNX RRMN[ RRMV[ RSMVX RZMV[ RGMNM RWM]M',\r\n  2124: ' 21H\\\\LMW[ RMMX[ RXML[ RJMPM RTMZM RJ[P[ RT[Z[',\r\n  2125: ' 22H[LMR[ RMMRY RXMR[P_NaLbKbJaK`La RJMPM RTMZM',\r\n  2126: ' 16I[WML[ RXMM[ RMMLQLMXM RL[X[XWW[',\r\n  2127: ' 40G^QMNNLPKRJUJXKZN[P[RZUWWTYPZM RQMONMPLRKUKXLZN[ RQMSMUNVPXXYZZ[ RSMTNUPWXXZZ[[[',\r\n  2128: ' 57G\\\\TFQGOIMMLPKTJZIb RTFRGPINMMPLTKZJb RTFVFXGYHYKXMWNTOPO RVFXHXKWMVNTO RPOTPVRWTWWVYUZR[P[NZMYLV RPOSPURVTVWUYTZR[',\r\n  2129: ' 28H\\\\IPKNMMOMQNROSRSVRZOb RJOLNPNRO RZMYPXRSYP^Nb RYMXPWRSY',\r\n  2130: ' 44I\\\\VNTMRMONMQLTLWMYNZP[R[UZWWXTXQWOSJRHRFSEUEWFYH RRMPNNQMTMXNZ RR[TZVWWTWPVNTKSISGTFVFYH',\r\n  2131: ' 32I[XPVNTMPMNNNPPRSS RPMONOPQRSS RSSNTLVLXMZP[S[UZWX RSSOTMVMXNZP[',\r\n  2132: ' 31I[TFRGQHQIRJUKZKZJWKSMPOMRLULWMYP[S]T_TaSbQbPa RULQONRMUMWNYP[',\r\n  2133: ' 32G]HQIOKMNMONOPNTL[ RMMNNNPMTK[ RNTPPRNTMVMXNYOYRXWUb RVMXOXRWWTb',\r\n  2134: ' 44F]GQHOJMMMNNNPMUMXNZO[ RLMMNMPLULXMZO[Q[SZUXWUXRYMYIXGVFTFRHRJSMUPWRZT RSZUWVUWRXMXIWGVF',\r\n  2135: ' 15LXRMPTOXOZP[S[UYVW RSMQTPXPZQ[',\r\n  2136: ' 29H\\\\NMJ[ ROMK[ RXMYNZNYMWMUNQROSMS ROSQTSZT[ ROSPTRZS[U[WZYW',\r\n  2137: ' 23H\\\\KFMFOGPHQJWXXZY[ RMFOHPJVXWZY[Z[ RRMJ[ RRMK[',\r\n  2138: ' 28F]MMGb RNMHb RMPLVLYN[P[RZTXVU RXMUXUZV[Y[[Y\\\\W RYMVXVZW[',\r\n  2139: ' 24H\\\\NML[ ROMNSMXL[ RYMXQVU RZMYPXRVUTWQYOZL[ RKMOM',\r\n  2140: ' 45IZTFRGQHQIRJUKXK RUKQLOMNONQPSSTVT RUKRLPMOOOQQSST RSTOUMVLXLZN\\\\S^T_TaRbPb RSTPUNVMXMZO\\\\S^',\r\n  2141: ' 32I[RMONMQLTLWMYNZP[R[UZWWXTXQWOVNTMRM RRMPNNQMTMXNZ RR[TZVWWTWPVN',\r\n  2142: ' 22G]PNL[ RPNM[ RVNV[ RVNW[ RIPKNNM[M RIPKONN[N',\r\n  2143: ' 31H[LVMYNZP[R[UZWWXTXQWOVNTMRMONMQLTHb RR[TZVWWTWPVN RRMPNNQMTIb',\r\n  2144: ' 35H][MQMNNLQKTKWLYMZO[Q[TZVWWTWQVOUNSM RQMONMQLTLXMZ RQ[SZUWVTVPUN RUN[N',\r\n  2145: ' 16H\\\\SNP[ RSNQ[ RJPLNOMZM RJPLOONZN',\r\n  2146: ' 31H\\\\IQJOLMOMPNPPNVNYP[ RNMONOPMVMYNZP[Q[TZVXXUYRYOXMWNXOYR RXUYO',\r\n  2147: ' 37G]ONMOKQJTJWKYLZN[Q[TZWXYUZRZOXMVMTORSPXMb RJWLYNZQZTYWWYU RZOXNVNTPRSPYNb',\r\n  2148: ' 23I[KMMMONPPU_VaWb RMMNNOPT_UaWbYb RZMYOWRM]K`Jb',\r\n  2149: ' 34F]UFOb RVFNb RGQHOJMMMNNNPMUMXOZRZTYWVYS RLMMNMPLULXMZO[R[TZVXXUYS[M',\r\n  2150: ' 44F]JQLOONNMLNJQITIWJZK[M[OZQWRT RIWJYKZMZOYQW RQTQWRZS[U[WZYWZTZQYNXMWNYOZQ RQWRYSZUZWYYW',\r\n  2151: ' 39H]XMVTUXUZV[Y[[Y\\\\W RYMWTVXVZW[ RVTVQUNSMQMNNLQKTKWLYMZO[Q[SZUWVT RQMONMQLTLXMZ',\r\n  2152: ' 36H[PFLSLVMYNZ RQFMS RMSNPPNRMTMVNWOXQXTWWUZR[P[NZMWMS RVNWPWTVWTZR[ RMFQF',\r\n  2153: ' 25I[WPWQXQXPWNUMRMONMQLTLWMYNZP[R[UZWW RRMPNNQMTMXNZ',\r\n  2154: ' 42H]ZFVTUXUZV[Y[[Y\\\\W R[FWTVXVZW[ RVTVQUNSMQMNNLQKTKWLYMZO[Q[SZUWVT RQMONMQLTLXMZ RWF[F',\r\n  2155: ' 26I[MVQUTTWRXPWNUMRMONMQLTLWMYNZP[R[UZWX RRMPNNQMTMXNZ',\r\n  2156: ' 35KZZGYHZI[H[GZFXFVGUHTJSMP[O_Na RXFVHUJTNRWQ[P^O`NaLbJbIaI`J_K`Ja ROMYM',\r\n  2157: ' 43H\\\\YMU[T^RaObLbJaI`I_J^K_J` RXMT[S^QaOb RVTVQUNSMQMNNLQKTKWLYMZO[Q[SZUWVT RQMONMQLTLXMZ',\r\n  2158: ' 31H]PFJ[ RQFK[ RMTOPQNSMUMWNXOXQVWVZW[ RUMWOWQUWUZV[Y[[Y\\\\W RMFQF',\r\n  2159: ' 26LYUFTGUHVGUF RMQNOPMSMTNTQRWRZS[ RRMSNSQQWQZR[U[WYXW',\r\n  2160: ' 32LYVFUGVHWGVF RNQOOQMTMUNUQR[Q^P`OaMbKbJaJ`K_L`Ka RSMTNTQQ[P^O`Mb',\r\n  2161: ' 34H\\\\PFJ[ RQFK[ RXNWOXPYOYNXMWMUNQROSMS ROSQTSZT[ ROSPTRZS[U[WZYW RMFQF',\r\n  2162: ' 18MYUFQTPXPZQ[T[VYWW RVFRTQXQZR[ RRFVF',\r\n  2163: ' 52AbBQCOEMHMINIPHTF[ RGMHNHPGTE[ RHTJPLNNMPMRNSOSQP[ RPMRORQO[ RRTTPVNXMZM\\\\N]O]Q[W[Z\\\\[ RZM\\\\O\\\\QZWZZ[[^[`YaW',\r\n  2164: ' 37F]GQHOJMMMNNNPMTK[ RLMMNMPLTJ[ RMTOPQNSMUMWNXOXQVWVZW[ RUMWOWQUWUZV[Y[[Y\\\\W',\r\n  2165: ' 32I[RMONMQLTLWMYNZP[R[UZWWXTXQWOVNTMRM RRMPNNQMTMXNZ RR[TZVWWTWPVN',\r\n  2166: ' 42G\\\\HQIOKMNMONOPNTJb RMMNNNPMTIb RNTOQQNSMUMWNXOYQYTXWVZS[Q[OZNWNT RWNXPXTWWUZS[ RFbMb',\r\n  2167: ' 33H\\\\XMRb RYMSb RVTVQUNSMQMNNLQKTKWLYMZO[Q[SZUWVT RQMONMQLTLXMZ RObVb',\r\n  2168: ' 26IZJQKOMMPMQNQPPTN[ ROMPNPPOTM[ RPTRPTNVMXMYNYOXPWOXN',\r\n  2169: ' 28J[XOXPYPYOXNUMRMONNONQORVVWW RNPOQVUWVWYVZS[P[MZLYLXMXMY',\r\n  2170: ' 18KYTFPTOXOZP[S[UYVW RUFQTPXPZQ[ RNMWM',\r\n  2171: ' 37F]GQHOJMMMNNNQLWLYN[ RLMMNMQKWKYLZN[P[RZTXVT RXMVTUXUZV[Y[[Y\\\\W RYMWTVXVZW[',\r\n  2172: ' 26H\\\\IQJOLMOMPNPQNWNYP[ RNMONOQMWMYNZP[Q[TZVXXUYQYMXMYO',\r\n  2173: ' 41C`DQEOGMJMKNKQIWIYK[ RIMJNJQHWHYIZK[M[OZQXRV RTMRVRYSZU[W[YZ[X\\\\V]R]M\\\\M]O RUMSVSYU[',\r\n  2174: ' 42H\\\\KQMNOMRMSOSR RQMRORRQVPXNZL[K[JZJYKXLYKZ RQVQYR[U[WZYW RYNXOYPZOZNYMXMVNTPSRRVRYS[',\r\n  2175: ' 41G\\\\HQIOKMNMONOQMWMYO[ RMMNNNQLWLYMZO[Q[SZUXWT RZMV[U^SaPbMbKaJ`J_K^L_K` RYMU[T^RaPb',\r\n  2176: ' 31H\\\\YMXOVQNWLYK[ RLQMOOMRMVO RMOONRNVOXO RLYNYRZUZWY RNYR[U[WYXW',\r\n  2177: ' 43G^VGUHVIWHWGUFRFOGMILLL[ RRFPGNIMLM[ R\\\\G[H\\\\I]H]G\\\\FZFXGWIW[ RZFYGXIX[ RIM[M RI[P[ RT[[[',\r\n  2178: ' 33G]WGVHWIXHWGUFRFOGMILLL[ RRFPGNIMLM[ RWMW[ RXMX[ RIMXM RI[P[ RT[[[',\r\n  2179: ' 35G]VGUHVIWHWGUF RXFRFOGMILLL[ RRFPGNIMLM[ RWHW[ RXFX[ RIMWM RI[P[ RT[[[',\r\n  2180: ' 54BcRGQHRISHRGPFMFJGHIGLG[ RMFKGIIHLH[ R]G\\\\H]I^H]G[FXFUGSIRLR[ RXFVGTISLS[ R]M][ R^M^[ RDM^M RD[K[ RO[V[ RZ[a[',\r\n  2181: ' 56BcRGQHRISHRGPFMFJGHIGLG[ RMFKGIIHLH[ R\\\\G[H\\\\I]H]G[F R^FXFUGSIRLR[ RXFVGTISLS[ R]H][ R^F^[ RDM]M RD[K[ RO[V[ RZ[a[',\r\n  2182: ' 12MXRMR[ RSMS[ ROMSM RO[V[',\r\n  2184: ' 25IZWNUMRMONMPLSLVMYNZQ[T[VZ RRMPNNPMSMVNYOZQ[ RMTUT',\r\n  2185: ' 43I\\\\TFQGOJNLMOLTLXMZO[Q[TZVWWUXRYMYIXGVFTF RTFRGPJOLNOMTMXNZO[ RQ[SZUWVUWRXMXIWGVF RNPWP',\r\n  2186: ' 42G]UFOb RVFNb RQMMNKPJSJVKXMZP[S[WZYXZUZRYPWNTMQM RQMNNLPKSKVLXNZP[ RS[VZXXYUYRXPVNTM',\r\n  2187: ' 27I[TMVNXPXOWNTMQMNNMOLQLSMUOWSZ RQMONNOMQMSNUSZT\\\\T^S_Q_',\r\n  2190: ' 45G]LMKNJPJRKUOYP[ RJRKTOXP[P]O`MbLbKaJ_J\\\\KXMTOQRNTMVMYNZPZTYXWZU[T[SZSXTWUXTY RVMXNYPYTXXWZ',\r\n  2191: ' 69E_YGXHYIZHYGWFTFQGOINKMNLRJ[I_Ha RTFRGPIOKNNLWK[J^I`HaFbDbCaC`D_E`Da R_G^H_I`H`G_F]F[GZHYJXMU[T_Sa R]F[HZJYNWWV[U^T`SaQbObNaN`O_P`Oa RIM^M',\r\n  2192: ' 52F^[GZH[I\\\\H[GXFUFRGPIOKNNMRK[J_Ia RUFSGQIPKONMWL[K^J`IaGbEbDaD`E_F`Ea RYMWTVXVZW[Z[\\\\Y]W RZMXTWXWZX[ RJMZM',\r\n  2193: ' 54F^YGXHYIZHZGXF R\\\\FUFRGPIOKNNMRK[J_Ia RUFSGQIPKONMWL[K^J`IaGbEbDaD`E_F`Ea R[FWTVXVZW[Z[\\\\Y]W R\\\\FXTWXWZX[ RJMYM',\r\n  2194: ' 86@cTGSHTIUHTGRFOFLGJIIKHNGRE[D_Ca ROFMGKIJKINGWF[E^D`CaAb?b>a>`?_@`?a R`G_H`IaH`G]FZFWGUITKSNRRP[O_Na RZFXGVIUKTNRWQ[P^O`NaLbJbIaI`J_K`Ja R^M\\\\T[X[Z\\\\[_[aYbW R_M]T\\\\X\\\\Z][ RDM_M',\r\n  2195: ' 88@cTGSHTIUHTGRFOFLGJIIKHNGRE[D_Ca ROFMGKIJKINGWF[E^D`CaAb?b>a>`?_@`?a R^G]H^I_H_G]F RaFZFWGUITKSNRRP[O_Na RZFXGVIUKTNRWQ[P^O`NaLbJbIaI`J_K`Ja R`F\\\\T[X[Z\\\\[_[aYbW RaF]T\\\\X\\\\Z][ RDM^M',\r\n  2196: ' 20LYMQNOPMSMTNTQRWRZS[ RRMSNSQQWQZR[U[WYXW',\r\n  2200: ' 40H\\\\QFNGLJKOKRLWNZQ[S[VZXWYRYOXJVGSFQF RQFOGNHMJLOLRMWNYOZQ[ RS[UZVYWWXRXOWJVHUGSF',\r\n  2201: ' 11H\\\\NJPISFS[ RRGR[ RN[W[',\r\n  2202: ' 45H\\\\LJMKLLKKKJLHMGPFTFWGXHYJYLXNUPPRNSLUKXK[ RTFVGWHXJXLWNTPPR RKYLXNXSZVZXYYX RNXS[W[XZYXYV',\r\n  2203: ' 47H\\\\LJMKLLKKKJLHMGPFTFWGXIXLWNTOQO RTFVGWIWLVNTO RTOVPXRYTYWXYWZT[P[MZLYKWKVLUMVLW RWQXTXWWYVZT[',\r\n  2204: ' 13H\\\\THT[ RUFU[ RUFJUZU RQ[X[',\r\n  2205: ' 39H\\\\MFKP RKPMNPMSMVNXPYSYUXXVZS[P[MZLYKWKVLUMVLW RSMUNWPXSXUWXUZS[ RMFWF RMGRGWF',\r\n  2206: ' 48H\\\\WIVJWKXJXIWGUFRFOGMILKKOKULXNZQ[S[VZXXYUYTXQVOSNRNOOMQLT RRFPGNIMKLOLUMXOZQ[ RS[UZWXXUXTWQUOSN',\r\n  2207: ' 31H\\\\KFKL RKJLHNFPFUIWIXHYF RLHNGPGUI RYFYIXLTQSSRVR[ RXLSQRSQVQ[',\r\n  2208: ' 63H\\\\PFMGLILLMNPOTOWNXLXIWGTFPF RPFNGMIMLNNPO RTOVNWLWIVGTF RPOMPLQKSKWLYMZP[T[WZXYYWYSXQWPTO RPONPMQLSLWMYNZP[ RT[VZWYXWXSWQVPTO',\r\n  2209: ' 48H\\\\XMWPURRSQSNRLPKMKLLINGQFSFVGXIYLYRXVWXUZR[O[MZLXLWMVNWMX RQSORMPLMLLMIOGQF RSFUGWIXLXRWVVXTZR[',\r\n  2210: '  6MWRYQZR[SZRY',\r\n  2211: '  8MWR[QZRYSZS\\\\R^Q_',\r\n  2212: ' 12MWRMQNROSNRM RRYQZR[SZRY',\r\n  2213: ' 14MWRMQNROSNRM RR[QZRYSZS\\\\R^Q_',\r\n  2214: ' 15MWRFQHRTSHRF RRHRN RRYQZR[SZRY',\r\n  2215: ' 32I[MJNKMLLKLJMHNGPFSFVGWHXJXLWNVORQRT RSFUGVHWJWLVNTP RRYQZR[SZRY',\r\n  2216: '  6NVRFQM RSFQM',\r\n  2217: ' 12JZNFMM ROFMM RVFUM RWFUM',\r\n  2218: ' 14KYQFOGNINKOMQNSNUMVKVIUGSFQF',\r\n  2219: '  9JZRFRR RMIWO RWIMO',\r\n  2220: '  3G][BIb',\r\n  2221: ' 20KYVBTDRGPKOPOTPYR]T`Vb RTDRHQKPPPTQYR\\\\T`',\r\n  2222: ' 20KYNBPDRGTKUPUTTYR]P`Nb RPDRHSKTPTTSYR\\\\P`',\r\n  2223: ' 12KYOBOb RPBPb ROBVB RObVb',\r\n  2224: ' 12KYTBTb RUBUb RNBUB RNbUb',\r\n  2225: ' 40KYTBRCQDPFPHQJRKSMSOQQ RRCQEQGRISJTLTNSPORSTTVTXSZR[Q]Q_Ra RQSSUSWRYQZP\\\\P^Q`RaTb',\r\n  2226: ' 40KYPBRCSDTFTHSJRKQMQOSQ RRCSESGRIQJPLPNQPURQTPVPXQZR[S]S_Ra RSSQUQWRYSZT\\\\T^S`RaPb',\r\n  2227: '  4KYUBNRUb',\r\n  2228: '  4KYOBVROb',\r\n  2229: '  3NVRBRb',\r\n  2230: '  6KYOBOb RUBUb',\r\n  2231: '  3E_IR[R',\r\n  2232: '  6E_RIR[ RIR[R',\r\n  2233: '  9F^RJR[ RJRZR RJ[Z[',\r\n  2234: '  9F^RJR[ RJJZJ RJRZR',\r\n  2235: '  6G]KKYY RYKKY',\r\n  2236: '  6MWRQQRRSSRRQ',\r\n  2237: ' 15E_RIQJRKSJRI RIR[R RRYQZR[SZRY',\r\n  2238: '  6E_IO[O RIU[U',\r\n  2239: '  9E_YIK[ RIO[O RIU[U',\r\n  2240: '  9E_IM[M RIR[R RIW[W',\r\n  2241: '  4F^ZIJRZ[',\r\n  2242: '  4F^JIZRJ[',\r\n  2243: ' 10F^ZFJMZT RJVZV RJ[Z[',\r\n  2244: ' 10F^JFZMJT RJVZV RJ[Z[',\r\n  2245: ' 21F_[WYWWVUTRPQOONMNKOJQJSKUMVOVQURTUPWNYM[M',\r\n  2246: ' 24F^IUISJPLONOPPTSVTXTZS[Q RISJQLPNPPQTTVUXUZT[Q[O',\r\n  2247: '  8G]JTROZT RJTRPZT',\r\n  2248: '  7LXTFOL RTFUGOL',\r\n  2249: '  7LXPFUL RPFOGUL',\r\n  2250: ' 18H\\\\KFLHNJQKSKVJXHYF RKFLINKQLSLVKXIYF',\r\n  2251: '  8MWRHQGRFSGSIRKQL',\r\n  2252: '  8MWSFRGQIQKRLSKRJ',\r\n  2253: '  8MWRHSGRFQGQIRKSL',\r\n  2254: '  8MWQFRGSISKRLQKRJ',\r\n  2255: ' 10E[HMLMRY RKMR[ R[BR[',\r\n  2256: ' 13F^ZJSJOKMLKNJQJSKVMXOYSZZZ',\r\n  2257: ' 13F^JJJQKULWNYQZSZVYXWYUZQZJ',\r\n  2258: ' 13F^JJQJUKWLYNZQZSYVWXUYQZJZ',\r\n  2259: ' 13F^JZJSKOLMNKQJSJVKXMYOZSZZ',\r\n  2260: ' 16F^ZJSJOKMLKNJQJSKVMXOYSZZZ RJRVR',\r\n  2261: ' 11E_XP[RXT RUMZRUW RIRZR',\r\n  2262: ' 11JZPLRITL RMORJWO RRJR[',\r\n  2263: ' 11E_LPIRLT ROMJROW RJR[R',\r\n  2264: ' 11JZPXR[TX RMURZWU RRIRZ',\r\n  2265: ' 44I\\\\XRWOVNTMRMONMQLTLWMYNZP[R[UZWXXUYPYKXHWGUFRFPGOHOIPIPH RRMPNNQMTMXNZ RR[TZVXWUXPXKWHUF',\r\n  2266: ' 15H\\\\JFR[ RKFRY RZFR[ RJFZF RKGYG',\r\n  2267: ' 10AbDMIMRY RHNR[ Rb:R[',\r\n  2268: ' 32F^[CZD[E\\\\D\\\\C[BYBWCUETGSJRNPZO^N` RVDUFTJRVQZP]O_MaKbIbHaH`I_J`Ia',\r\n  2269: ' 50F^[CZD[E\\\\D\\\\C[BYBWCUETGSJRNPZO^N` RVDUFTJRVQZP]O_MaKbIbHaH`I_J`Ia RQKNLLNKQKSLVNXQYSYVXXVYSYQXNVLSKQK',\r\n  2270: ' 26F_\\\\S[UYVWVUUTTQPPONNLNJOIQISJULVNVPUQTTPUOWNYN[O\\\\Q\\\\S',\r\n  2271: ' 32F^[FI[ RNFPHPJOLMMKMIKIIJGLFNFPGSHVHYG[F RWTUUTWTYV[X[ZZ[X[VYTWT',\r\n  2272: ' 49F_[NZO[P\\\\O\\\\N[MZMYNXPVUTXRZP[M[JZIXIUJSPORMSKSIRGPFNGMIMKNNPQUXWZZ[[[\\\\Z\\\\Y RM[KZJXJUKSMQ RMKNMVXXZZ[',\r\n  2273: ' 56E`WNVLTKQKOLNMMPMSNUPVSVUUVS RQKOMNPNSOUPV RWKVSVUXVZV\\\\T]Q]O\\\\L[JYHWGTFQFNGLHJJILHOHRIUJWLYNZQ[T[WZYYZX RXKWSWUXV',\r\n  2274: ' 42H\\\\PBP_ RTBT_ RXIWJXKYJYIWGTFPFMGKIKKLMMNOOUQWRYT RKKMMONUPWQXRYTYXWZT[P[MZKXKWLVMWLX',\r\n  2275: ' 12H]SFLb RYFRb RLQZQ RKWYW',\r\n  2276: ' 46JZUITJUKVJVIUGSFQFOGNINKOMQOVR ROMTPVRWTWVVXTZ RPNNPMRMTNVPXU[ RNVSYU[V]V_UaSbQbOaN_N^O]P^O_',\r\n  2277: ' 30JZRFQHRJSHRF RRFRb RRQQTRbSTRQ RLMNNPMNLLM RLMXM RTMVNXMVLTM',\r\n  2278: ' 56JZRFQHRJSHRF RRFRT RRPQRSVRXQVSRRP RRTRb RR^Q`RbS`R^ RLMNNPMNLLM RLMXM RTMVNXMVLTM RL[N\\\\P[NZL[ RL[X[ RT[V\\\\X[VZT[',\r\n  2279: ' 12I\\\\XFX[ RKFXF RPPXP RK[X[',\r\n  2281: ' 38E`QFNGKIILHOHRIUKXNZQ[T[WZZX\\\\U]R]O\\\\LZIWGTFQF RROQPQQRRSRTQTPSORO RRPRQSQSPRP',\r\n  2282: ' 45J[PFNGOIQJ RPFOGOI RUFWGVITJ RUFVGVI RQJOKNLMNMQNSOTQUTUVTWSXQXNWLVKTJQJ RRUR[ RSUS[ RNXWX',\r\n  2283: ' 27I\\\\RFOGMILLLMMPORRSSSVRXPYMYLXIVGSFRF RRSR[ RSSS[ RNWWW',\r\n  2284: ' 28D`PFMGJIHLGOGSHVJYM[P\\\\T\\\\W[ZY\\\\V]S]O\\\\LZIWGTFPF RRFR\\\\ RGQ]Q',\r\n  2285: ' 31G`PMMNKPJSJTKWMYPZQZTYVWWTWSVPTNQMPM R]GWG[HUN R]G]M\\\\IVO R\\\\HVN',\r\n  2286: ' 28F\\\\IIJGLFOFQGRIRLQOPQNSKU ROFPGQIQMPPNS RVFT[ RWFS[ RKUYU',\r\n  2287: ' 30I\\\\MFMU RNFMQ RMQNOONQMTMWNXPXRWTUV RTMVNWPWRTXTZU[W[YY RKFNF',\r\n  2288: ' 44I\\\\RNOOMQLTLUMXOZR[S[VZXXYUYTXQVOSNRN RRHNJRFRN RSHWJSFSN RRSQTQURVSVTUTTSSRS RRTRUSUSTRT',\r\n  2289: ' 37G^QHRFR[ RTHSFS[ RJHKFKMLPNRQSRS RMHLFLNMQ R[HZFZMYPWRTSSS RXHYFYNXQ RNWWW',\r\n  2290: ' 31G]LFL[ RMFM[ RIFUFXGYHZJZMYOXPUQMQ RUFWGXHYJYMXOWPUQ RI[Y[YVX[',\r\n  2291: ' 24H[YGUGQHNJLMKPKSLVNYQ[U\\\\Y\\\\ RYGVHSJQMPPPSQVSYV[Y\\\\',\r\n  2292: ' 27F_OQMQKRJSIUIWJYKZM[O[QZRYSWSURSQROQ RSHPQ RZJRR R\\\\QST',\r\n  2293: ' 12H\\\\OKUY RUKOY RKOYU RYOKU',\r\n  2294: ' 48F^NVLUKUIVHXHYI[K\\\\L\\\\N[OYOXNVKRJOJMKJMHPGTGWHYJZMZOYRVVUXUYV[X\\\\Y\\\\[[\\\\Y\\\\X[VYUXUVV RJMKKMIPHTHWIYKZM',\r\n  2295: ' 48F^NMLNKNIMHKHJIHKGLGNHOJOKNMKQJTJVKYM[P\\\\T\\\\W[YYZVZTYQVMUKUJVHXGYG[H\\\\J\\\\K[MYNXNVM RJVKXMZP[T[WZYXZV',\r\n  2301: ' 40F_JMILIJJHLGNGPHQIRKSP RIJKHMHOIPJQLRPR[ R[M\\\\L\\\\J[HYGWGUHTISKRP R\\\\JZHXHVIUJTLSPS[',\r\n  2302: ' 51F^IGJKKMMOPPTPWOYMZK[G RIGJJKLMNPOTOWNYLZJ[G RPONPMQLSLVMXOZQ[S[UZWXXVXSWQVPTO RPPNQMSMVNY RVYWVWSVQTP',\r\n  2303: ' 30F^MJMV RNKNU RVKVU RWJWV RIGKIMJPKTKWJYI[G RIYKWMVPUTUWVYW[Y',\r\n  2304: ' 48F^[ILIJJILINJPLQNQPPQNQLPJ[J RIMJOKPMQ RQMPKOJMI RIXXXZW[U[SZQXPVPTQSSSUTWIW R[TZRYQWP RSTTVUWWX',\r\n  2305: ' 48F]OUMTLTJUIWIXJZL[M[OZPXPWOUJPINIKJILHOGSGWHYJZLZOYRVUUWUYV[X[YZZX RMSKPJNJKKILH RSGVHXJYLYOXRVU',\r\n  2306: ' 48G_HKKHMKMV RJILLLV RMKPHRKRU ROIQLQU RRKUHWKW[ RTIVLV[ RWKZH[J\\\\M\\\\P[SZUXWUYP[ RYIZJ[M[PZSYUWWTYP[',\r\n  2307: ' 41F^ISMSLRKOKMLJNHQGSGVHXJYMYOXRWS[S RITOTMRLOLMMJOHQG RSGUHWJXMXOWRUT[T RKXYX RKYYY',\r\n  2308: ' 30F_GLJIMLMX RIJLMLX RMLPISLSX ROJRMRX RSLVIYLYW[Y RUJXMXXZZ]W',\r\n  2309: ' 33G]ZIJY RZIWJQJ RXKUKQJ RZIYLYR RXKXNYR RQRJR RPSMSJR RQRQY RPSPVQY',\r\n  2310: ' 33F^HOJKOU RJMOWRPWPZO[M[KZIXHWHUITKTMUPVRWUWXUZ RWHVIUKUMWQXTXWWYUZ',\r\n  2311: ' 36F^IOLLPN RKMOORLUN RQMTOWLYN RVMXO[L RIULRPT RKSOURRUT RQSTUWRYT RVSXU[R',\r\n  2312: ' 48F^JHNJPLQOQRPUNWJY RJHMIOJQLRO RRRQUOWMXJY RZHWIUJSLRO RRRSUUWWXZY RZHVJTLSOSRTUVWZY RIP[P RIQ[Q',\r\n  2317: ' 12NVQQQSSSSQQQ RQQSS RSQQS',\r\n  2318: ' 18JZMPQRTTVVWYW[V]U^ RMQST RMRPSTUVWWY',\r\n  2319: ' 18JZWKVMTOPQMR RSPMS RUFVGWIWKVNTPQRMT',\r\n  2320: ' 36H\\\\SMONLPKRKTLVNWQWUVXTYRYPXNVMSM RXNSM RVMQNLP RONKR RLVQW RNWSVXT RUVYR',\r\n  2321: ' 36H\\\\SMONLPKRKTLVNWQWUVXTYRYPXNVMSM RXNSM RVMQNLP RONKR RLVQW RNWSVXT RUVYR',\r\n  2322: ' 34J[SMPNNPMRMTNVPWRWUVWTXRXPWNUMSM ROPUM RNRVN RMTWO RNUXP ROVWR RPWVT',\r\n  2323: ' 18JZOGO^ RUFU] RMNWL RMOWM RMWWU RMXWV',\r\n  2324: ' 18JZNFNX RVLV^ RNNVL RNOVM RNWVU RNXVV',\r\n  2325: ' 25JZNBNW RNNQLTLVMWOWQVSSUQVNW RNNQMTMVN RUMVOVQUSSU',\r\n  2326: ' 18E_HIHL R\\\\I\\\\L RHI\\\\I RHJ\\\\J RHK\\\\K RHL\\\\L',\r\n  2327: ' 18JZMNMQ RWNWQ RMNWN RMOWO RMPWP RMQWQ',\r\n  2328: ' 49JZMLWX RMLONQOTOVNWMWKUKUMTO RONTO RQOWM RVKVN RULWL RWXUVSUPUNVMWMYOYOWPU RUVPU RSUMW RNVNY RMXOX',\r\n  2329: ' 26JZPOOMOKMKMMNNPOSOUNWL RNKNN RMLOL RMMSO RPOUN RWLWY',\r\n  2330: ' 86A^GfHfIeIdHcGcFdFfGhIiKiNhPfQdR`RUQ;Q4R/S-U,V,X-Y/Y3X6W8U;P?JCHEFHEJDNDREVGYJ[N\\\\R\\\\V[XZZW[T[PZMYKWITHPHMIKKJNJRKUMW RGdGeHeHdGd RU;Q?LCIFGIFKENERFVGXJ[ RR\\\\U[WZYWZTZPYMXKVITH',\r\n  2331: '103EfNSOUQVSVUUVSVQUOSNQNOONPMSMVNYP[S\\\\V\\\\Y[[Y\\\\W]T]P\\\\MZJXIUHRHOIMJKLIOHSHXI]KaMcPeTfYf]e`cba RKLJNIRIXJ\\\\L`NbQdUeYe]d_cba RPOTO ROPUP RNQVQ RNRVR RNSVS ROTUT RPUTU RaLaNcNcLaL RbLbN RaMcM RaVaXcXcVaV RbVbX RaWcW',\r\n  2332: ' 30D`H@Hd RM@Md RW@Wd R\\\\@\\\\d RMMWK RMNWL RMOWM RMWWU RMXWV RMYWW',\r\n  2367: ' 12NVQQQSSSSQQQ RQQSS RSQQS',\r\n  2368: ' 18JZMPQRTTVVWYW[V]U^ RMQST RMRPSTUVWWY',\r\n  2369: ' 18JZWKVMTOPQMR RSPMS RUFVGWIWKVNTPQRMT',\r\n  2370: ' 32H\\\\PMMNLOKQKSLUMVPWTWWVXUYSYQXOWNTMPM RMNLPLSMUNVPW RWVXTXQWOVNTM',\r\n  2371: ' 36H\\\\SMONLPKRKTLVNWQWUVXTYRYPXNVMSM RXNSM RVMQNLP RONKR RLVQW RNWSVXT RUVYR',\r\n  2372: ' 34J[SMPNNPMRMTNVPWRWUVWTXRXPWNUMSM ROPUM RNRVN RMTWO RNUXP ROVWR RPWVT',\r\n  2373: ' 18JZOGO^ RUFU] RMNWL RMOWM RMWWU RMXWV',\r\n  2374: ' 18JZNFNX RVLV^ RNNVL RNOVM RNWVU RNXVV',\r\n  2375: ' 25JZNBNW RNNQLTLVMWOWQVSSUQVNW RNNQMTMVN RUMVOVQUSSU',\r\n  2376: ' 18E_HIHL R\\\\I\\\\L RHI\\\\I RHJ\\\\J RHK\\\\K RHL\\\\L',\r\n  2377: ' 18JZMNMQ RWNWQ RMNWN RMOWO RMPWP RMQWQ',\r\n  2378: ' 36JZQCVMRTRU RULQS RTITKPRRUUY RW\\\\UYSXQXOYN[N]O_Ra RW\\\\UZSYOYO]P_Ra RSXPZN]',\r\n  2379: ' 26JZPOOMOKMKMMNNPOSOUNWL RNKNN RMLOL RMMSO RPOUN RWLSY',\r\n  2380: ' 86A^GfHfIeIdHcGcFdFfGhIiKiNhPfQdR`RUQ;Q4R/S-U,V,X-Y/Y3X6W8U;P?JCHEFHEJDNDREVGYJ[N\\\\R\\\\V[XZZW[T[PZMYKWITHPHMIKKJNJRKUMW RGdGeHeHdGd RU;Q?LCIFGIFKENERFVGXJ[ RR\\\\U[WZYWZTZPYMXKVITH',\r\n  2381: ' 89IjNQOOQNSNUOVQVSUUSVQVOUNTMQMNNKPISHWH[I^K`NaRaW`[_]]`ZcVfQiMk RWHZI]K_N`R`W_[^]\\\\`YcTgQi RPOTO ROPUP RNQVQ RNRVR RNSVS ROTUT RPUTU ReLeNgNgLeL RfLfN ReMgM ReVeXgXgVeV RfVfX ReWgW',\r\n  2382: ' 85D`H>Hf RI>If RM>Mf RQBSBSDQDQAR?T>W>Y?[A\\\\D\\\\I[LYNWOUOSNRLQNOQNROSQVRXSVUUWUYV[X\\\\[\\\\`[cYeWfTfReQcQ`S`SbQb RRBRD RQCSC RY?ZA[D[IZLYN RRLRNPQNRPSRVRX RYVZX[[[`ZcYe RR`Rb RQaSa',\r\n  2401: ' 21AcHBHb RIBIb R[B[b R\\\\B\\\\b RDB`B RDbMb RWb`b',\r\n  2402: ' 23BaGBQPFb RFBPP REBPQ REB\\\\B^I[B RGa\\\\a RFb\\\\b^[[b',\r\n  2403: ' 28I[X+U1R8P=OANFMNMVN^OcPgRlUsXy RU1S6Q<P@OFNNNVO^PdQhSnUs',\r\n  2404: ' 28I[L+O1R8T=UAVFWNWVV^UcTgRlOsLy RO1Q6S<T@UFVNVVU^TdShQnOs',\r\n  2405: ' 14I[M+MRMy RN+NRNy RM+X+ RMyXy',\r\n  2406: ' 14I[V+VRVy RW+WRWy RL+W+ RLyWy',\r\n  2407: ' 48I[V+S-Q/P1O4O8P<TDUGUJTMRP RS-Q0P4P8Q;UCVGVJUMRPNRRTUWVZV]UaQiPlPpQtSw RRTTWUZU]T`PhOlOpPsQuSwVy',\r\n  2408: ' 48I[N+Q-S/T1U4U8T<PDOGOJPMRP RQ-S0T4T8S;OCNGNJOMRPVRRTOWNZN]OaSiTlTpStQw RRTPWOZO]P`ThUlUpTsSuQwNy',\r\n  2409: ' 32I[V.S1Q4O8N=NCOIPMSXT\\\\UbUgTlSoQs RS1Q5P8O=OBPHQLTWU[VaVgUlSpQsNv',\r\n  2410: ' 32I[N.Q1S4U8V=VCUITMQXP\\\\ObOgPlQoSs RQ1S5T8U=UBTHSLPWO[NaNgOlQpSsVv',\r\n  2411: ' 147Z:RARRo R@RQo R?RRr RZ\"VJRr',\r\n  2412: ' 57Ca].\\\\.[/[0\\\\1]1^0^.],[+Y+W,U.T0S3R:QJQjPsOv R\\\\/\\\\0]0]/\\\\/ RR:Rj RU.T1S:SZRjQqPtOvMxKyIyGxFvFtGsHsItIuHvGv RGtGuHuHtGt',\r\n  2501: ' 20H\\\\RFJ[ RRIK[J[ RRIY[Z[ RRFZ[ RMUWU RLVXV',\r\n  2502: ' 44H\\\\LFL[ RMGMZ RLFTFWGXHYJYMXOWPTQ RMGTGWHXJXMWOTP RMPTPWQXRYTYWXYWZT[L[ RMQTQWRXTXWWYTZMZ',\r\n  2503: ' 38H]ZKYIWGUFQFOGMILKKNKSLVMXOZQ[U[WZYXZV RZKYKXIWHUGQGOHMKLNLSMVOYQZUZWYXXYVZV',\r\n  2504: ' 32H]LFL[ RMGMZ RLFSFVGXIYKZNZSYVXXVZS[L[ RMGSGVHWIXKYNYSXVWXVYSZMZ',\r\n  2505: ' 27I\\\\MFM[ RNGNZ RMFYF RNGYGYF RNPTPTQ RNQTQ RNZYZY[ RM[Y[',\r\n  2506: ' 21I[MFM[ RNGN[M[ RMFYF RNGYGYF RNPTPTQ RNQTQ',\r\n  2507: ' 44H]ZKYIWGUFQFOGMILKKNKSLVMXOZQ[U[WZYXZVZRUR RZKYKXIWHUGQGOHNIMKLNLSMVNXOYQZUZWYXXYVYSUSUR',\r\n  2508: ' 22G]KFK[ RKFLFL[K[ RYFXFX[Y[ RYFY[ RLPXP RLQXQ',\r\n  2509: '  8NWRFR[S[ RRFSFS[',\r\n  2510: ' 20J[VFVVUYSZQZOYNVMV RVFWFWVVYUZS[Q[OZNYMV',\r\n  2511: ' 22H]LFL[M[ RLFMFM[ RZFYFMR RZFMS RPOY[Z[ RQOZ[',\r\n  2512: ' 14IZMFM[ RMFNFNZ RNZYZY[ RM[Y[',\r\n  2513: ' 26F^JFJ[ RKKK[J[ RKKR[ RJFRX RZFRX RYKR[ RYKY[Z[ RZFZ[',\r\n  2514: ' 20G]KFK[ RLIL[K[ RLIY[ RKFXX RXFXX RXFYFY[',\r\n  2515: ' 40G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF RQGNHLKKNKSLVNYQZSZVYXVYSYNXKVHSGQG',\r\n  2516: ' 27H\\\\LFL[ RMGM[L[ RLFUFWGXHYJYMXOWPUQMQ RMGUGWHXJXMWOUPMP',\r\n  2517: ' 48G]PFNGLIKKJNJSKVLXNZP[T[VZXXYVZSZNYKXIVGTFPF RQGNHLKKNKSLVNYQZSZVYXVYSYNXKVHSGQG RSXX]Y] RSXTXY]',\r\n  2518: ' 34H\\\\LFL[ RMGM[L[ RLFTFWGXHYJYMXOWPTQMQ RMGTGWHXJXMWOTPMP RRQX[Y[ RSQY[',\r\n  2519: ' 43H\\\\YIWGTFPFMGKIKKLMMNOOTQVRWSXUXXWYTZPZNYMXKX RYIWIVHTGPGMHLILKMMONTPVQXSYUYXWZT[P[MZKX',\r\n  2520: ' 15J[RGR[ RSGS[R[ RLFYFYG RLFLGYG',\r\n  2521: ' 24G]KFKULXNZQ[S[VZXXYUYF RKFLFLUMXNYQZSZVYWXXUXFYF',\r\n  2522: ' 14H\\\\JFR[ RJFKFRX RZFYFRX RZFR[',\r\n  2523: ' 26E_GFM[ RGFHFMX RRFMX RRIM[ RRIW[ RRFWX R]F\\\\FWX R]FW[',\r\n  2524: ' 16H\\\\KFX[Y[ RKFLFY[ RYFXFK[ RYFL[K[',\r\n  2525: ' 17I\\\\KFRPR[S[ RKFLFSP RZFYFRP RZFSPS[',\r\n  2526: ' 20H\\\\XFK[ RYFL[ RKFYF RKFKGXG RLZYZY[ RK[Y[',\r\n  2551: ' 38E\\\\XFVHTKQPOSLWIZG[E[DZDXEWFXEY RXFWJUTT[ RXFU[ RT[TYSVRTPRNQLQKRKTLWOZR[V[XZ',\r\n  2552: ' 70F^UGTHSJQOOUNWLZJ[ RTHSKQSPVOXMZJ[H[GZGXHWIXHY ROLNNMOKOJNJLKJMHOGRFXFZG[I[KZMXNTORO RXFYGZIZKYMXN RTOWPXQYSYVXYWZU[S[RZRXSU RTOVPWQXSXVWYU[',\r\n  2553: ' 41H]KHJJJLKNNOQOUNWMYKZIZGYFWFTGQJOMMQLULXMZP[R[UZWXXVXTWRURSSRU RWFUGRJPMNQMUMXNZP[',\r\n  2554: ' 43F]UGTHSJQOOUNWLZJ[ RTHSKQSPVOXMZJ[H[GZGXHWJWLXNZP[S[UZWXYTZOZLYIWGUFPFMGKIJKJMKNMNNMOK',\r\n  2555: ' 49I\\\\WIVJVLWMYMZKZIYGWFTFRGQHPJPLQNSO RTFRHQJQMSO RSOQONPLRKTKWLYMZO[R[UZWXXVXTWRURSSRU RQOOPMRLTLXMZ',\r\n  2556: ' 46G\\\\WHVJTORUQWOZM[ RQLPNNOLOKMKKLINGQF[FXGWHVKTSSVRXPZM[K[IZHYHXIWJXIY RSFWGXG ROSPRRQVQXPZMXT',\r\n  2557: ' 53G]JIIKIMJOLPOPROTNWKXHXGWFVFTGRIQKPNPQQSSTUTWSYQZO RWFUGSIRKQNQRST RZOYSWWUYSZO[L[JZIXIWJVKWJX RYSWVUXRZO[',\r\n  2558: ' 55F^LLKKKILGOFRFOQMWLYKZI[G[FZFXGWHXGY RRFOONRLWKYI[ RJTKSMRVOXN[L]J^H^G]F\\\\FZGXJWLURTVTYV[W[YZ[X R\\\\FZHXLVRUVUYV[',\r\n  2559: ' 33IYWHUKSPQUPWNZL[ RYLWNTOQOONNLNJOHQGUFYFWHVJTPRVQXOZL[J[IZIXJWKXJY',\r\n  2560: ' 34IZYFWHUKSPPYN] RYMWOTPQPOONMNKOIQGUFYFWIVKSTQXPZN]M^K_J^J\\\\KZMXOWRVVU',\r\n  2561: ' 59F^LLKKKIMGPFRFOQMWLYKZI[G[FZFXGWHXGY RRFOONRLWKYI[ RZGWKUMSNPO R]G\\\\H]I^H^G]F\\\\FZGWLVMTNPO RPOSPTRUYV[ RPORPSRTYV[W[YZ[X',\r\n  2562: ' 40I[MILKLMMOOPRPUOWNZK[H[GZFYFWGVHTKPUOWMZK[ RVHTLRSQVPXNZK[I[HZHXIWKWMXPZR[U[WZYX',\r\n  2563: ' 49D`RFNOKUIXGZE[C[BZBXCWDXCY RRFPMOQNVNZP[ RRFQJPOOVOZP[ R[FWORXP[ R[FYMXQWVWZY[Z[\\\\Z^X R[FZJYOXVXZY[',\r\n  2564: ' 38G^RFQJOPMULWJZH[F[EZEXFWGXFY RRFRKSVT[ RRFSKTVT[ R`G_H`IaHaG`F^F\\\\GZJYLWQUWT[',\r\n  2565: ' 34H]SFQGOIMLLNKRKVLYMZO[Q[TZVXXUYSZOZKYHXGWGUHSJQNPSPV RQGOJMNLRLVMYO[',\r\n  2566: ' 53F]UGTHSJQOOUNWLZJ[ RTHSKQSPVOXMZJ[H[GZGXHWIXHY ROLNNMOKOJNJLKJMHOGRFVFYGZH[J[MZOYPVQTQRP RVFXGYHZJZMYOXPVQ',\r\n  2567: ' 43H]UJULTNSOQPOPNNNLOIQGTFWFYGZIZMYPWSSWPYNZK[I[HZHXIWKWMXPZS[V[XZZX RWFXGYIYMXPVSSVOYK[',\r\n  2568: ' 65F^UGTHSJQOOUNWLZJ[ RTHSKQSPVOXMZJ[H[GZGXHWIXHY ROLNNMOKOJNJLKJMHOGRFWFZG[I[KZMYNVORO RWFYGZIZKYMXNVO RROUPVRWYX[ RROTPURVYX[Y[[Z]X',\r\n  2569: ' 36H\\\\NIMKMMNOPPSPVOXN[K\\\\H\\\\G[FZFXGWHVJUMSTRWPZN[ RVJUNTUSXQZN[K[IZHXHWIVJWIX',\r\n  2570: ' 38I[YHXJVOTUSWQZO[ RSLRNPONOMMMKNIPGSF\\\\FZGYHXKVSUVTXRZO[M[KZJYJXKWLXKY RUFYGZG',\r\n  2571: ' 39G]HJJGLFMFOHOKNNKVKYL[ RMFNHNKKSJVJYL[N[PZSWUTVR RZFVRUVUYW[X[ZZ\\\\X R[FWRVVVYW[',\r\n  2572: ' 36G\\\\HJJGLFMFOHOKNOLVLYM[ RMFNHNKLRKVKYM[N[QZTWVTXPYMZIZGYFXFWGVIVLWNYP[Q]Q',\r\n  2573: ' 41F]ILHLGKGIHGJFNFMHLLKUJ[ RLLLUK[ RVFTHRLOUMYK[ RVFUHTLSUR[ RTLTUS[ R`F^G\\\\IZLWUUYS[',\r\n  2574: ' 52H\\\\PKOLMLLKLIMGOFQFSGTITLSPQUOXMZJ[H[GZGXHWIXHY RQFRGSISLRPPUNXLZJ[ R]G\\\\H]I^H^G]F[FYGWIULSPRURXSZT[U[WZYX',\r\n  2575: ' 42G]JJLGNFOFQGQIOOORPT ROFPGPINONRPTRTUSWQYNZL R\\\\FZLWTUX R]F[LYQWUUXSZP[L[JZIXIWJVKWJX',\r\n  2576: ' 44G\\\\ZHYJWOVRUTSWQYOZL[ RSLRNPONOMMMKNIPGSF]F[GZHYKXOVUTXQZL[H[GZGXHWJWLXOZQ[T[WZYX RVFZG[G',\r\n  2601: ' 36H\\\\WMW[X[ RWMXMX[ RWPUNSMPMNNLPKSKULXNZP[S[UZWX RWPSNPNNOMPLSLUMXNYPZSZWX',\r\n  2602: ' 36H\\\\LFL[M[ RLFMFM[ RMPONQMTMVNXPYSYUXXVZT[Q[OZMX RMPQNTNVOWPXSXUWXVYTZQZMX',\r\n  2603: ' 32I[XPVNTMQMONMPLSLUMXOZQ[T[VZXX RXPWQVOTNQNOONPMSMUNXOYQZTZVYWWXX',\r\n  2604: ' 36H\\\\WFW[X[ RWFXFX[ RWPUNSMPMNNLPKSKULXNZP[S[UZWX RWPSNPNNOMPLSLUMXNYPZSZWX',\r\n  2605: ' 36I[MTXTXQWOVNTMQMONMPLSLUMXOZQ[T[VZXX RMSWSWQVOTNQNOONPMSMUNXOYQZTZVYWWXX',\r\n  2606: ' 24LZWFUFSGRJR[S[ RWFWGUGSH RTGSJS[ ROMVMVN ROMONVN',\r\n  2607: ' 48H\\\\XMWMW\\\\V_U`SaQaO`N_L_ RXMX\\\\W_UaSbPbNaL_ RWPUNSMPMNNLPKSKULXNZP[S[UZWX RWPSNPNNOMPLSLUMXNYPZSZWX',\r\n  2608: ' 25H\\\\LFL[M[ RLFMFM[ RMQPNRMUMWNXQX[ RMQPORNTNVOWQW[X[',\r\n  2609: ' 24NWRFQGQHRISITHTGSFRF RRGRHSHSGRG RRMR[S[ RRMSMS[',\r\n  2610: ' 24NWRFQGQHRISITHTGSFRF RRGRHSHSGRG RRMRbSb RRMSMSb',\r\n  2611: ' 22H[LFL[M[ RLFMFM[ RXMWMMW RXMMX RPTV[X[ RQSX[',\r\n  2612: '  8NWRFR[S[ RRFSFS[',\r\n  2613: ' 42CbGMG[H[ RGMHMH[ RHQKNMMPMRNSQS[ RHQKOMNONQORQR[S[ RSQVNXM[M]N^Q^[ RSQVOXNZN\\\\O]Q][^[',\r\n  2614: ' 25H\\\\LML[M[ RLMMMM[ RMQPNRMUMWNXQX[ RMQPORNTNVOWQW[X[',\r\n  2615: ' 36I\\\\QMONMPLSLUMXOZQ[T[VZXXYUYSXPVNTMQM RQNOONPMSMUNXOYQZTZVYWXXUXSWPVOTNQN',\r\n  2616: ' 36H\\\\LMLbMb RLMMMMb RMPONQMTMVNXPYSYUXXVZT[Q[OZMX RMPQNTNVOWPXSXUWXVYTZQZMX',\r\n  2617: ' 36H\\\\WMWbXb RWMXMXb RWPUNSMPMNNLPKSKULXNZP[S[UZWX RWPSNPNNOMPLSLUMXNYPZSZWX',\r\n  2618: ' 21KYOMO[P[ ROMPMP[ RPSQPSNUMXM RPSQQSOUNXNXM',\r\n  2619: ' 50J[XPWNTMQMNNMPNRPSUUWV RVUWWWXVZ RWYTZQZNY ROZNXMX RXPWPVN RWOTNQNNO RONNPOR RNQPRUTWUXWXXWZT[Q[NZMX',\r\n  2620: ' 16MXRFR[S[ RRFSFS[ ROMVMVN ROMONVN',\r\n  2621: ' 25H\\\\LMLWMZO[R[TZWW RLMMMMWNYPZRZTYWW RWMW[X[ RWMXMX[',\r\n  2622: ' 14JZLMR[ RLMMMRY RXMWMRY RXMR[',\r\n  2623: ' 26F^IMN[ RIMJMNX RRMNX RRPN[ RRPV[ RRMVX R[MZMVX R[MV[',\r\n  2624: ' 16I[LMW[X[ RLMMMX[ RXMWML[ RXMM[L[',\r\n  2625: ' 17JZLMR[ RLMMMRY RXMWMRYNb RXMR[ObNb',\r\n  2626: ' 20I[VNL[ RXMNZ RLMXM RLMLNVN RNZXZX[ RL[X[',\r\n  2651: ' 33K[UUTSRRPRNSMTLVLXMZO[Q[SZTX RPRNTMVMYO[ RVRTXTZV[XZYY[V RWRUXUZV[',\r\n  2652: ' 23LZLVNSPO RSFMXMZO[P[RZTXUUURVVWWXWZV RTFNXNZO[',\r\n  2653: ' 22LXTSSTTTTSSRQROSNTMVMXNZP[S[VYXV RQROTNVNYP[',\r\n  2654: ' 33K[UUTSRRPRNSMTLVLXMZO[Q[SZTX RPRNTMVMYO[ RZFTXTZV[XZYY[V R[FUXUZV[',\r\n  2655: ' 23LXOYQXRWSUSSRRQROSNTMVMXNZP[S[VYXV RQROTNVNYP[',\r\n  2656: ' 27OXRRUOWLXIXGWFUGTIKdKfLgNfOcPZQ[S[UZVYXV RTISNRRO[M`Kd',\r\n  2657: ' 38K[UUTSRRPRNSMTLVLXMZO[Q[SZTX RPRNTMVMYO[ RVRPd RWRT[R`PdOfMgLfLdMaO_R]V[YY[V',\r\n  2658: ' 30L[LVNSPO RSFL[ RTFM[ ROUQSSRTRVSVUUXUZV[ RTRUSUUTXTZV[XZYY[V',\r\n  2659: ' 19NVSLRMSNTMSL RQROXOZQ[SZTYVV RRRPXPZQ[',\r\n  2660: ' 24NVSLRMSNTMSL RQRKd RRRO[M`KdJfHgGfGdHaJ_M]Q[TYVV',\r\n  2661: ' 31LZLVNSPO RSFL[ RTFM[ RURUSVSURTRRTOU ROURVSZT[ ROUQVRZT[U[XYZV',\r\n  2662: ' 17NVNVPSRO RUFOXOZQ[SZTYVV RVFPXPZQ[',\r\n  2663: ' 45E^EVGSIRKSKUI[ RIRJSJUH[ RKUMSORPRRSRUP[ RPRQSQUO[ RRUTSVRWRYSYUXXXZY[ RWRXSXUWXWZY[[Z\\\\Y^V',\r\n  2664: ' 32I[IVKSMROSOUM[ RMRNSNUL[ ROUQSSRTRVSVUUXUZV[ RTRUSUUTXTZV[XZYY[V',\r\n  2665: ' 29KYRRPRNSMTLVLXMZO[Q[SZTYUWUUTSRRQSQURWTXVXXWYV RPRNTMVMYO[',\r\n  2666: ' 30L[LVNSPO RQLHg RRLIg ROUQSSRTRVSVUUXUZV[ RTRUSUUTXTZV[XZYY[V',\r\n  2667: ' 35K[UUTSRRPRNSMTLVLXMZO[Q[SZ RPRNTMVMYO[ RVRPdPfQgSfTcT[V[YY[V RWRT[R`Pd',\r\n  2668: ' 24LZLVNSPRRSRUP[ RPRQSQUO[ RRUTSVRWRVU RVRVUWWXWZV',\r\n  2669: ' 22NZNVPSQQQSTUUWUYTZR[ RQSSUTWTYR[ RNZP[U[XYZV',\r\n  2670: ' 20NVNVPSRO RUFOXOZQ[SZTYVV RVFPXPZQ[ RPNVN',\r\n  2671: ' 27K[NRLXLZN[O[QZSXUU RORMXMZN[ RVRTXTZV[XZYY[V RWRUXUZV[',\r\n  2672: ' 23KZNRMTLWLZN[O[RZTXUUUR RORNTMWMZN[ RURVVWWXWZV',\r\n  2673: ' 36H]LRJTIWIZK[L[NZPX RMRKTJWJZK[ RRRPXPZR[S[UZWXXUXR RSRQXQZR[ RXRYVZW[W]V',\r\n  2674: ' 42JZJVLSNRPRQSQUPXOZM[L[KZKYLYKZ RWSVTWTWSVRURSSRUQXQZR[U[XYZV RQSRU RSSQU RPXQZ RQXOZ',\r\n  2675: ' 32K[NRLXLZN[O[QZSXUU RORMXMZN[ RVRPd RWRT[R`PdOfMgLfLdMaO_R]V[YY[V',\r\n  2676: ' 38LYLVNSPRRRTSTVSXPZN[ RRRSSSVRXPZ RN[P\\\\Q^QaPdNfLgKfKdLaO^R\\\\VYYV RN[O\\\\P^PaOdNf',\r\n  2700: ' 42H\\\\QFNGLJKOKRLWNZQ[S[VZXWYRYOXJVGSFQF ROGMJLOLRMWOZ RNYQZSZVY RUZWWXRXOWJUG RVHSGQGNH',\r\n  2701: ' 12H\\\\NJPISFS[ RNJNKPJRHR[S[',\r\n  2702: ' 34H\\\\LKLJMHNGPFTFVGWHXJXLWNUQL[ RLKMKMJNHPGTGVHWJWLVNTQK[ RLZYZY[ RK[Y[',\r\n  2703: ' 48H\\\\MFXFQO RMFMGWG RWFPO RQNSNVOXQYTYUXXVZS[P[MZLYKWLW RPOSOVPXS RTOWQXTXUWXTZ RXVVYSZPZMYLW ROZLX',\r\n  2704: ' 18H\\\\UIU[V[ RVFV[ RVFKVZV RUILV RLUZUZV',\r\n  2705: ' 53H\\\\MFLO RNGMN RMFWFWG RNGWG RMNPMSMVNXPYSYUXXVZS[P[MZLYKWLW RLOMOONSNVOXR RTNWPXSXUWXTZ RXVVYSZPZMYLW ROZLX',\r\n  2706: ' 62H\\\\VGWIXIWGTFRFOGMJLOLTMXOZR[S[VZXXYUYTXQVOSNRNOOMQ RWHTGRGOH RPGNJMOMTNXQZ RMVOYRZSZVYXV RTZWXXUXTWQTO RXSVPSOROOPMS RQONQMT',\r\n  2707: ' 12H\\\\KFYFO[ RKFKGXG RXFN[O[',\r\n  2708: ' 68H\\\\PFMGLILKMMNNPOTPVQWRXTXWWYTZPZMYLWLTMRNQPPTOVNWMXKXIWGTFPF RNGMIMKNMPNTOVPXRYTYWXYWZT[P[MZLYKWKTLRNPPOTNVMWKWIVG RWHTGPGMH RLXOZ RUZXX',\r\n  2709: ' 62H\\\\WPURRSQSNRLPKMKLLINGQFRFUGWIXMXRWWUZR[P[MZLXMXNZ RWMVPSR RWNUQRRQRNQLN RPRMPLMLLMIPG RLKNHQGRGUHWK RSGVIWMWRVWTZ RUYRZPZMY',\r\n  2710: ' 16MXRXQYQZR[S[TZTYSXRX RRYRZSZSYRY',\r\n  2711: ' 24MXTZS[R[QZQYRXSXTYT\\\\S^Q_ RRYRZSZSYRY RS[T\\\\ RTZS^',\r\n  2712: ' 32MXRMQNQORPSPTOTNSMRM RRNROSOSNRN RRXQYQZR[S[TZTYSXRX RRYRZSZSYRY',\r\n  2713: ' 40MXRMQNQORPSPTOTNSMRM RRNROSOSNRN RTZS[R[QZQYRXSXTYT\\\\S^Q_ RRYRZSZSYRY RS[T\\\\ RTZS^',\r\n  2714: ' 24MXRFRTST RRFSFST RRXQYQZR[S[TZTYSXRX RRYRZSZSYRY',\r\n  2715: ' 58I\\\\LKLJMHNGQFTFWGXHYJYLXNWOUPRQ RLKMKMJNHQGTGWHXJXLWNUORP RMIPG RUGXI RXMTP RRPRTSTSP RRXQYQZR[S[TZTYSXRX RRYRZSZSYRY',\r\n  2716: ' 24MXTFRGQIQLRMSMTLTKSJRJQK RRKRLSLSKRK RRGQK RQIRJ',\r\n  2717: ' 24MXTHSIRIQHQGRFSFTGTJSLQM RRGRHSHSGRG RSITJ RTHSL',\r\n  2718: ' 71F_\\\\MZMXNWPUVTXSYQZMZKYJWJUKSLRQOSMTKTISGQFPFNGMIMKNNPQUWXZZ[\\\\[ R\\\\M\\\\NZNXO RYNXPVVUXSZQ[M[KZJYIWIUJSLQQNRMSKSIRG RSHQGPGNH ROGNINKONQQVWXYZZ\\\\Z\\\\[',\r\n  2719: ' 51I\\\\RBR_S_ RRBSBS_ RWIYIWGTFQFNGLILKMMNNVRWSXUXWWYTZQZOYNX RWIVHTGQGNHMIMKNMVQXSYUYWXYWZT[Q[NZLXNX RXXUZ',\r\n  2720: '  8G^[BIbJb R[B\\\\BJb',\r\n  2721: ' 24KYUBSDQGOKNPNTOYQ]S`UbVb RUBVBTDRGPKOPOTPYR]T`Vb',\r\n  2722: ' 24KYNBPDRGTKUPUTTYR]P`NbOb RNBOBQDSGUKVPVTUYS]Q`Ob',\r\n  2723: ' 39JZRFQGSQRR RRFRR RRFSGQQRR RMINIVOWO RMIWO RMIMJWNWO RWIVINOMO RWIMO RWIWJMNMO',\r\n  2724: '  8F_JQ[Q[R RJQJR[R',\r\n  2725: ' 16F_RIRZSZ RRISISZ RJQ[Q[R RJQJR[R',\r\n  2726: ' 16F_JM[M[N RJMJN[N RJU[U[V RJUJV[V',\r\n  2727: ' 11NWSFRGRM RSGRM RSFTGRM',\r\n  2728: ' 22I[NFMGMM RNGMM RNFOGMM RWFVGVM RWGVM RWFXGVM',\r\n  2729: ' 30KYQFOGNINKOMQNSNUMVKVIUGSFQF RQFNIOMSNVKUGQF RSFOGNKQNUMVISF',\r\n  2750: ' 42H]TFQGOIMLLOKSKVLYMZO[Q[TZVXXUYRZNZKYHXGVFTF RTFRGPINLMOLSLVMYO[ RQ[SZUXWUXRYNYKXHVF',\r\n  2751: ' 15H]TJO[ RVFP[ RVFSIPKNL RUIQKNL',\r\n  2752: ' 42H]OJPKOLNKNJOHPGSFVFYGZIZKYMWOTQPSMUKWI[ RVFXGYIYKXMVOPS RJYKXMXRZUZWYXW RMXR[U[WZXW',\r\n  2753: ' 50H]OJPKOLNKNJOHPGSFVFYGZIZKYMVOSP RVFXGYIYKXMVO RQPSPVQWRXTXWWYVZS[O[LZKYJWJVKULVKW RSPUQVRWTWWVYUZS[',\r\n  2754: ' 10H]XGR[ RYFS[ RYFJUZU',\r\n  2755: ' 39H]QFLP RQF[F RQGVG[F RLPMOPNSNVOWPXRXUWXUZR[O[LZKYJWJVKULVKW RSNUOVPWRWUVXTZR[',\r\n  2756: ' 46H]YIXJYKZJZIYGWFTFQGOIMLLOKSKWLYMZO[R[UZWXXVXSWQVPTOQOOPMRLT RTFRGPINLMOLSLXMZ RR[TZVXWVWRVP',\r\n  2757: ' 30H]NFLL R[FZIXLSRQUPWO[ RXLRRPUOWN[ RMIPFRFWI RNHPGRGWIYIZH[F',\r\n  2758: ' 63H]SFPGOHNJNMOOQPTPXOYNZLZIYGVFSF RSFQGPHOJOMPOQP RTPWOXNYLYIXGVF RQPMQKSJUJXKZN[R[VZWYXWXTWRVQTP RQPNQLSKUKXLZN[ RR[UZVYWWWSVQ',\r\n  2759: ' 46H]YMXOVQTRQROQNPMNMKNIPGSFVFXGYHZJZNYRXUVXTZQ[N[LZKXKWLVMWLX ROQNONKOIQGSF RXGYIYNXRWUUXSZQ[',\r\n  2760: '  6MXPYOZP[QZPY',\r\n  2761: '  8MXP[OZPYQZQ[P]N_',\r\n  2762: ' 11MXSMRNSOTNSM RPYOZP[QZ',\r\n  2763: ' 14MXSMRNSOTNSM RP[OZPYQZQ[P]N_',\r\n  2764: ' 17MXUFTGRS RUGRS RUFVGRS RPYOZP[QZPY',\r\n  2765: ' 34H]OJPKOLNKNJOHPGSFWFZG[I[KZMYNSPQQQSRTTT RWFYGZIZKYMXNVO RPYOZP[QZPY',\r\n  2766: '  8MXVFTHSJSKTLUKTJ',\r\n  2767: '  8MXUHTGUFVGVHUJSL',\r\n  2768: ' 55E_\\\\N[O\\\\P]O]N\\\\M[MYNWPRXPZN[K[HZGXGVHTISKRPPROTMUKUITGRFPGOIOLPRQUSXUZW[Y[ZYZX RK[IZHXHVITJSPP ROLPQQTSWUYWZYZZY',\r\n  2769: ' 41H]TBL_ RYBQ_ RZJYKZL[K[JZHYGVFRFOGMIMKNMONVRXT RMKOMVQWRXTXWWYVZS[O[LZKYJWJVKULVKW',\r\n  2770: '  3G]_BEb',\r\n  2771: ' 20KZZBVESHQKOONTNXO]P`Qb RVESIQMPPOUOZP_Qb',\r\n  2772: ' 20JYSBTDUGVLVPUUSYQ\\\\N_Jb RSBTEUJUOTTSWQ[N_',\r\n  2773: '  9J[TFTR ROIYO RYIOO',\r\n  2774: '  3E_IR[R',\r\n  2775: '  6E_RIR[ RIR[R',\r\n  2776: '  6E_IO[O RIU[U',\r\n  2777: '  6NWUFSM RVFSM',\r\n  2778: ' 12I[PFNM RQFNM RYFWM RZFWM',\r\n  2779: ' 14KZSFQGPIPKQMSNUNWMXKXIWGUFSF',\r\n  2801: ' 18H\\\\RFK[ RRFY[ RRIX[ RMUVU RI[O[ RU[[[',\r\n  2802: ' 31G]LFL[ RMFM[ RIFYFYLXF RMPUPXQYRZTZWYYXZU[I[ RUPWQXRYTYWXYWZU[',\r\n  2803: ' 45G]LFL[ RMFM[ RIFUFXGYHZJZLYNXOUP RUFWGXHYJYLXNWOUP RMPUPXQYRZTZWYYXZU[I[ RUPWQXRYTYWXYWZU[',\r\n  2804: ' 14I[NFN[ ROFO[ RKFZFZLYF RK[R[',\r\n  2805: ' 31F^NFNLMTLXKZJ[ RXFX[ RYFY[ RKF\\\\F RG[\\\\[ RG[Gb RH[Gb R[[\\\\b R\\\\[\\\\b',\r\n  2806: ' 22G\\\\LFL[ RMFM[ RSLST RIFYFYLXF RMPSP RI[Y[YUX[',\r\n  2807: ' 71CbRFR[ RSFS[ ROFVF RGGHHGIFHFGGFHFIGJIKMLONPWPYOZM[I\\\\G]F^F_G_H^I]H^G RNPLQKSJXIZH[ RNPMQLSKXJZI[G[FZEX RWPYQZS[X\\\\Z][ RWPXQYSZX[Z\\\\[^[_Z`X RO[V[',\r\n  2808: ' 45H\\\\LIKFKLLINGPFTFWGXIXLWNTOQO RTFVGWIWLVNTO RTOVPXRYTYWXYWZT[O[MZLYKWKVLUMVLW RWQXTXWWYVZT[',\r\n  2809: ' 27F^KFK[ RLFL[ RXFX[ RYFY[ RHFOF RUF\\\\F RXHLY RH[O[ RU[\\\\[',\r\n  2810: ' 37F^KFK[ RLFL[ RXFX[ RYFY[ RHFOF RUF\\\\F RXHLY RH[O[ RU[\\\\[ RN@N?M?M@NBPCTCVBW@',\r\n  2811: ' 43F^KFK[ RLFL[ RHFOF RLPSPUOVMWIXGYFZF[G[HZIYHZG RSPUQVSWXXZY[ RSPTQUSVXWZX[Z[[Z\\\\X RH[O[',\r\n  2812: ' 25E^MFMLLTKXJZI[H[GZGYHXIYHZ RXFX[ RYFY[ RJF\\\\F RU[\\\\[',\r\n  2813: ' 30F_KFK[ RLFRX RKFR[ RYFR[ RYFY[ RZFZ[ RHFLF RYF]F RH[N[ RV[][',\r\n  2814: ' 27F^KFK[ RLFL[ RXFX[ RYFY[ RHFOF RUF\\\\F RLPXP RH[O[ RU[\\\\[',\r\n  2815: ' 44G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF RQFOGMILKKOKRLVMXOZQ[ RS[UZWXXVYRYOXKWIUGSF',\r\n  2816: ' 21F^KFK[ RLFL[ RXFX[ RYFY[ RHF\\\\F RH[O[ RU[\\\\[',\r\n  2817: ' 29G]LFL[ RMFM[ RIFUFXGYHZJZMYOXPUQMQ RUFWGXHYJYMXOWPUQ RI[P[',\r\n  2818: ' 32G\\\\XIYLYFXIVGSFQFNGLIKKJNJSKVLXNZQ[S[VZXXYV RQFOGMILKKNKSLVMXOZQ[',\r\n  2819: ' 16I\\\\RFR[ RSFS[ RLFKLKFZFZLYF RO[V[',\r\n  2820: ' 24H]KFRV RLFSV RZFSVQYPZN[M[LZLYMXNYMZ RIFOF RVF\\\\F',\r\n  2821: ' 48F_RFR[ RSFS[ ROFVF RPILJJLIOIRJULWPXUXYW[U\\\\R\\\\O[LYJUIPI RPIMJKLJOJRKUMWPX RUXXWZU[R[OZLXJUI RO[V[',\r\n  2822: ' 21H\\\\KFX[ RLFY[ RYFK[ RIFOF RUF[F RI[O[ RU[[[',\r\n  2823: ' 27F^KFK[ RLFL[ RXFX[ RYFY[ RHFOF RUF\\\\F RH[\\\\[ R[[\\\\b R\\\\[\\\\b',\r\n  2824: ' 28F]KFKQLSOTRTUSWQ RLFLQMSOT RWFW[ RXFX[ RHFOF RTF[F RT[[[',\r\n  2825: ' 30BcGFG[ RHFH[ RRFR[ RSFS[ R]F][ R^F^[ RDFKF ROFVF RZFaF RD[a[',\r\n  2826: ' 36BcGFG[ RHFH[ RRFR[ RSFS[ R]F][ R^F^[ RDFKF ROFVF RZFaF RD[a[ R`[ab Ra[ab',\r\n  2827: ' 31F`PFP[ RQFQ[ RIFHLHFTF RQPXP[Q\\\\R]T]W\\\\Y[ZX[M[ RXPZQ[R\\\\T\\\\W[YZZX[',\r\n  2828: ' 41CaHFH[ RIFI[ REFLF RIPPPSQTRUTUWTYSZP[E[ RPPRQSRTTTWSYRZP[ R[F[[ R\\\\F\\\\[ RXF_F RX[_[',\r\n  2829: ' 29H]MFM[ RNFN[ RJFQF RNPUPXQYRZTZWYYXZU[J[ RUPWQXRYTYWXYWZU[',\r\n  2830: ' 39H]LIKFKLLINGQFSFVGXIYKZNZSYVXXVZS[P[MZLYKWKVLUMVLW RSFUGWIXKYNYSXVWXUZS[ RPPYP',\r\n  2831: ' 59CbHFH[ RIFI[ REFLF RE[L[ RVFSGQIPKOOORPVQXSZV[X[[Z]X^V_R_O^K]I[GXFVF RVFTGRIQKPOPRQVRXTZV[ RX[ZZ\\\\X]V^R^O]K\\\\IZGXF RIPOP',\r\n  2832: ' 45G]WFW[ RXFX[ R[FOFLGKHJJJLKNLOOPWP ROFMGLHKJKLLNMOOP RRPPQORLYKZJZIY RPQOSMZL[J[IYIX RT[[[',\r\n  2901: ' 39I]NONPMPMONNPMTMVNWOXQXXYZZ[ RWOWXXZZ[[[ RWQVRPSMTLVLXMZP[S[UZWX RPSNTMVMXNZP[',\r\n  2902: ' 48H\\\\XFWGQINKLNKQKULXNZQ[S[VZXXYUYSXPVNSMQMNNLPKS RXFWHUIQJNLLN RQMONMPLSLUMXOZQ[ RS[UZWXXUXSWPUNSM',\r\n  2903: ' 37H\\\\MMM[ RNMN[ RJMUMXNYPYQXSUT RUMWNXPXQWSUT RNTUTXUYWYXXZU[J[ RUTWUXWXXWZU[',\r\n  2904: ' 14HZMMM[ RNMN[ RJMXMXRWM RJ[Q[',\r\n  2905: ' 22F]NMNQMWLZK[ RWMW[ RXMX[ RKM[M RI[H`H[[[[`Z[',\r\n  2906: ' 31H[LSXSXQWOVNTMQMNNLPKSKULXNZQ[S[VZXX RWSWPVN RQMONMPLSLUMXOZQ[',\r\n  2907: ' 59E`RMR[ RSMS[ ROMVM RJNIOHNIMJMKNMRNSPTUTWSXRZN[M\\\\M]N\\\\O[N RPTNUMVKZJ[ RPTNVLZK[I[HZGX RUTWUXVZZ[[ RUTWVYZZ[\\\\[]Z^X RO[V[',\r\n  2908: ' 42I[MOLMLQMONNPMTMWNXPXQWSTT RTMVNWPWQVSTT RQTTTWUXWXXWZT[P[MZLXLWMVNWMX RTTVUWWWXVZT[',\r\n  2909: ' 27G]LML[ RMMM[ RWMW[ RXMX[ RIMPM RTM[M RI[P[ RT[[[ RWNMZ',\r\n  2910: ' 37G]LML[ RMMM[ RWMW[ RXMX[ RIMPM RTM[M RI[P[ RT[[[ RWNMZ ROGOFNFNGOIQJSJUIVG',\r\n  2911: ' 38H\\\\MMM[ RNMN[ RJMQM RNTPTSSTRVNWMXMYNXOWN RPTSUTVVZW[ RPTRUSVUZV[X[YZZX RJ[Q[',\r\n  2912: ' 22G]NMNQMWLZK[J[IZJYKZ RWMW[ RXMX[ RKM[M RT[[[',\r\n  2913: ' 30G^LML[ RLMR[ RMMRY RXMR[ RXMX[ RYMY[ RIMMM RXM\\\\M RI[O[ RU[\\\\[',\r\n  2914: ' 27G]LML[ RMMM[ RWMW[ RXMX[ RIMPM RTM[M RMTWT RI[P[ RT[[[',\r\n  2915: ' 36H\\\\QMNNLPKSKULXNZQ[S[VZXXYUYSXPVNSMQM RQMONMPLSLUMXOZQ[ RS[UZWXXUXSWPUNSM',\r\n  2916: ' 21G]LML[ RMMM[ RWMW[ RXMX[ RIM[M RI[P[ RT[[[',\r\n  2917: ' 36G\\\\LMLb RMMMb RMPONQMSMVNXPYSYUXXVZS[Q[OZMX RSMUNWPXSXUWXUZS[ RIMMM RIbPb',\r\n  2918: ' 28H[WPVQWRXQXPVNTMQMNNLPKSKULXNZQ[S[VZXX RQMONMPLSLUMXOZQ[',\r\n  2919: ' 16I\\\\RMR[ RSMS[ RMMLRLMYMYRXM RO[V[',\r\n  2920: ' 22I[LMR[ RMMRY RXMR[P_NaLbKbJaK`La RJMPM RTMZM',\r\n  2921: ' 52H]RFRb RSFSb ROFSF RRPQNPMNMLNKQKWLZN[P[QZRX RNMMNLQLWMZN[ RWMXNYQYWXZW[ RSPTNUMWMYNZQZWYZW[U[TZSX RObVb',\r\n  2922: ' 21H\\\\LMW[ RMMX[ RXML[ RJMPM RTMZM RJ[P[ RT[Z[',\r\n  2923: ' 23G]LML[ RMMM[ RWMW[ RXMX[ RIMPM RTM[M RI[[[[`Z[',\r\n  2924: ' 28G]LMLTMVPWRWUVWT RMMMTNVPW RWMW[ RXMX[ RIMPM RTM[M RT[[[',\r\n  2925: ' 30CbHMH[ RIMI[ RRMR[ RSMS[ R\\\\M\\\\[ R]M][ REMLM ROMVM RYM`M RE[`[',\r\n  2926: ' 32CbHMH[ RIMI[ RRMR[ RSMS[ R\\\\M\\\\[ R]M][ REMLM ROMVM RYM`M RE[`[``_[',\r\n  2927: ' 27H]QMQ[ RRMR[ RLMKRKMUM RRTVTYUZWZXYZV[N[ RVTXUYWYXXZV[',\r\n  2928: ' 37E_JMJ[ RKMK[ RGMNM RKTOTRUSWSXRZO[G[ ROTQURWRXQZO[ RYMY[ RZMZ[ RVM]M RV[][',\r\n  2929: ' 25J[OMO[ RPMP[ RLMSM RPTTTWUXWXXWZT[L[ RTTVUWWWXVZT[',\r\n  2930: ' 34I\\\\MOLMLQMONNPMSMVNXPYSYUXXVZS[P[NZLXLWMVNWMX RSMUNWPXSXUWXUZS[ RRTXT',\r\n  2931: ' 51DaIMI[ RJMJ[ RFMMM RF[M[ RVMSNQPPSPUQXSZV[X[[Z]X^U^S]P[NXMVM RVMTNRPQSQURXTZV[ RX[ZZ\\\\X]U]S\\\\PZNXM RJTPT',\r\n  2932: ' 40G\\\\VMV[ RWMW[ RZMOMLNKPKQLSOTVT ROMMNLPLQMSOT RTTQUPVNZM[ RTTRUQVOZN[L[KZJX RS[Z[',\r\n  3001: ' 36H\\\\RFKZ RQIW[ RRIX[ RRFY[ RMUVU RI[O[ RT[[[ RKZJ[ RKZM[ RWZU[ RWYV[ RXYZ[',\r\n  3002: ' 78G]LFL[ RMGMZ RNFN[ RIFUFXGYHZJZLYNXOUP RXHYJYLXN RUFWGXIXMWOUP RNPUPXQYRZTZWYYXZU[I[ RXRYTYWXY RUPWQXSXXWZU[ RJFLG RKFLH ROFNH RPFNG RLZJ[ RLYK[ RNYO[ RNZP[',\r\n  3003: ' 37G\\\\XIYFYLXIVGTFQFNGLIKKJNJSKVLXNZQ[T[VZXXYV RMILKKNKSLVMX RQFOGMJLNLSMWOZQ[',\r\n  3004: ' 62G]LFL[ RMGMZ RNFN[ RIFSFVGXIYKZNZSYVXXVZS[I[ RWIXKYNYSXVWX RSFUGWJXNXSWWUZS[ RJFLG RKFLH ROFNH RPFNG RLZJ[ RLYK[ RNYO[ RNZP[',\r\n  3005: ' 83G\\\\LFL[ RMGMZ RNFN[ RIFYFYL RNPTP RTLTT RI[Y[YU RJFLG RKFLH ROFNH RPFNG RTFYG RVFYH RWFYI RXFYL RTLSPTT RTNRPTR RTOPPTQ RLZJ[ RLYK[ RNYO[ RNZP[ RT[YZ RV[YY RW[YX RX[YU',\r\n  3006: ' 70G[LFL[ RMGMZ RNFN[ RIFYFYL RNPTP RTLTT RI[Q[ RJFLG RKFLH ROFNH RPFNG RTFYG RVFYH RWFYI RXFYL RTLSPTT RTNRPTR RTOPPTQ RLZJ[ RLYK[ RNYO[ RNZP[',\r\n  3007: ' 60G^XIYFYLXIVGTFQFNGLIKKJNJSKVLXNZQ[T[VZXZY[YS RMILKKNKSLVMX RQFOGMJLNLSMWOZQ[ RXTXY RWSWYVZ RTS\\\\S RUSWT RVSWU RZSYU R[SYT',\r\n  3008: ' 81F^KFK[ RLGLZ RMFM[ RWFW[ RXGXZ RYFY[ RHFPF RTF\\\\F RMPWP RH[P[ RT[\\\\[ RIFKG RJFKH RNFMH ROFMG RUFWG RVFWH RZFYH R[FYG RKZI[ RKYJ[ RMYN[ RMZO[ RWZU[ RWYV[ RYYZ[ RYZ[[',\r\n  3009: ' 39LXQFQ[ RRGRZ RSFS[ RNFVF RN[V[ ROFQG RPFQH RTFSH RUFSG RQZO[ RQYP[ RSYT[ RSZU[',\r\n  3010: ' 45JYSFSWRZQ[ RTGTWSZ RUFUWTZQ[O[MZLXLVMUNUOVOWNXMX RMVMWNWNVMV RPFXF RQFSG RRFSH RVFUH RWFUG',\r\n  3011: ' 69F\\\\KFK[ RLGLZ RMFM[ RXGMR RPPW[ RQPX[ RQNY[ RHFPF RUF[F RH[P[ RT[[[ RIFKG RJFKH RNFMH ROFMG RWFXG RZFXG RKZI[ RKYJ[ RMYN[ RMZO[ RWYU[ RWYZ[',\r\n  3012: ' 52I[NFN[ ROGOZ RPFP[ RKFSF RK[Z[ZU RLFNG RMFNH RQFPH RRFPG RNZL[ RNYM[ RPYQ[ RPZR[ RU[ZZ RW[ZY RX[ZX RY[ZU',\r\n  3013: ' 63E_JFJZ RJFQ[ RKFQX RLFRX RXFQ[ RXFX[ RYGYZ RZFZ[ RGFLF RXF]F RG[M[ RU[][ RHFJG R[FZH R\\\\FZG RJZH[ RJZL[ RXZV[ RXYW[ RZY[[ RZZ\\\\[',\r\n  3014: ' 39F^KFKZ RKFY[ RLFXX RMFYX RYGY[ RHFMF RVF\\\\F RH[N[ RIFKG RWFYG R[FYG RKZI[ RKZM[',\r\n  3015: ' 54G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF RMILKKNKSLVMX RWXXVYSYNXKWI RQFOGMJLNLSMWOZQ[ RS[UZWWXSXNWJUGSF',\r\n  3016: ' 59G]LFL[ RMGMZ RNFN[ RIFUFXGYHZJZMYOXPUQNQ RXHYJYMXO RUFWGXIXNWPUQ RI[Q[ RJFLG RKFLH ROFNH RPFNG RLZJ[ RLYK[ RNYO[ RNZP[',\r\n  3017: ' 77G]QFNGLIKKJOJRKVLXNZQ[S[VZXXYVZRZOYKXIVGSFQF RMILKKNKSLVMX RWXXVYSYNXKWI RQFOGMJLNLSMWOZQ[ RS[UZWWXSXNWJUGSF RNXOVQURUTVUXV^W`Y`Z^Z\\\\ RV\\\\W^X_Y_ RUXW]X^Y^Z]',\r\n  3018: ' 80G]LFL[ RMGMZ RNFN[ RIFUFXGYHZJZLYNXOUPNP RXHYJYLXN RUFWGXIXMWOUP RRPTQUSWYX[Z[[Y[W RWWXYYZZZ RTQURXXYYZY[X RI[Q[ RJFLG RKFLH ROFNH RPFNG RLZJ[ RLYK[ RNYO[ RNZP[',\r\n  3019: ' 44H\\\\XIYFYLXIVGSFPFMGKIKLLNOPURWSXUXXWZ RLLMNOOUQWRXT RMGLILKMMONUPXRYTYWXYWZT[Q[NZLXKUK[LX',\r\n  3020: ' 57H\\\\JFJL RQFQ[ RRGRZ RSFS[ RZFZL RJFZF RN[V[ RKFJL RLFJI RMFJH ROFJG RUFZG RWFZH RXFZI RYFZL RQZO[ RQYP[ RSYT[ RSZU[',\r\n  3021: ' 45F^KFKULXNZQ[S[VZXXYUYG RLGLVMX RMFMVNYOZQ[ RHFPF RVF\\\\F RIFKG RJFKH RNFMH ROFMG RWFYG R[FYG',\r\n  3022: ' 34H\\\\KFR[ RLFRXR[ RMFSX RYGR[ RIFPF RUF[F RJFLH RNFMH ROFMG RWFYG RZFYG',\r\n  3023: ' 55F^JFN[ RKFNVN[ RLFOV RRFOVN[ RRFV[ RSFVVV[ RTFWV RZGWVV[ RGFOF RRFTF RWF]F RHFKG RIFKH RMFLH RNFLG RXFZG R\\\\FZG',\r\n  3024: ' 54H\\\\KFW[ RLFX[ RMFY[ RXGLZ RIFPF RUF[F RI[O[ RT[[[ RJFMH RNFMH ROFMG RVFXG RZFXG RLZJ[ RLZN[ RWZU[ RWYV[ RWYZ[',\r\n  3025: ' 48G]JFQQQ[ RKFRQRZ RLFSQS[ RYGSQ RHFOF RVF\\\\F RN[V[ RIFKG RNFLG RWFYG R[FYG RQZO[ RQYP[ RSYT[ RSZU[',\r\n  3026: ' 41H\\\\YFKFKL RWFK[ RXFL[ RYFM[ RK[Y[YU RLFKL RMFKI RNFKH RPFKG RT[YZ RV[YY RW[YX RX[YU',\r\n  3051: ' 38H\\\\UFIZ RSJT[ RTHUZ RUFUHVYV[ RLUTU RF[L[ RQ[X[ RIZG[ RIZK[ RTZR[ RTYS[ RVYW[',\r\n  3052: ' 78F^OFI[ RPFJ[ RQFK[ RLFWFZG[I[KZNYOVP RYGZIZKYNXO RWFXGYIYKXNVP RNPVPXQYSYUXXVZR[F[ RWQXSXUWXUZ RVPWRWUVXTZR[ RMFPG RNFOH RRFPH RSFPG RJZG[ RJYH[ RKYL[ RJZM[',\r\n  3053: ' 41H]ZH[H\\\\F[L[JZHYGWFTFQGOIMLLOKSKVLYMZP[S[UZWXXV RQHOJNLMOLSLWMY RTFRGPJOLNOMSMXNZP[',\r\n  3054: ' 63F]OFI[ RPFJ[ RQFK[ RLFUFXGYHZKZOYSWWUYSZO[F[ RWGXHYKYOXSVWTY RUFWHXKXOWSUWRZO[ RMFPG RNFOH RRFPH RSFPG RJZG[ RJYH[ RKYL[ RJZM[',\r\n  3055: ' 80F]OFI[ RPFJ[ RQFK[ RULST RLF[FZL RNPTP RF[U[WV RMFPG RNFOH RRFPH RSFPG RWFZG RXFZH RYFZI RZFZL RULSPST RTNRPSR RTOQPSQ RJZG[ RJYH[ RKYL[ RJZM[ RP[UZ RR[UY RUYWV',\r\n  3056: ' 70F\\\\OFI[ RPFJ[ RQFK[ RULST RLF[FZL RNPTP RF[N[ RMFPG RNFOH RRFPH RSFPG RWFZG RXFZH RYFZI RZFZL RULSPST RTNRPSR RTOQPSQ RJZG[ RJYH[ RKYL[ RJZM[',\r\n  3057: ' 65H^ZH[H\\\\F[L[JZHYGWFTFQGOIMLLOKSKVLYMZP[R[UZWXYT RQHOJNLMOLSLWMY RVXWWXT RTFRGPJOLNOMSMXNZP[ RR[TZVWWT RTT\\\\T RUTWU RVTWW RZTXV R[TXU',\r\n  3058: ' 81E_NFH[ ROFI[ RPFJ[ RZFT[ R[FU[ R\\\\FV[ RKFSF RWF_F RLPXP RE[M[ RQ[Y[ RLFOG RMFNH RQFOH RRFOG RXF[G RYFZH R]F[H R^F[G RIZF[ RIYG[ RJYK[ RIZL[ RUZR[ RUYS[ RVYW[ RUZX[',\r\n  3059: ' 39KYTFN[ RUFO[ RVFP[ RQFYF RK[S[ RRFUG RSFTH RWFUH RXFUG ROZL[ ROYM[ RPYQ[ ROZR[',\r\n  3060: ' 47I\\\\WFRWQYO[ RXFTSSVRX RYFUSSXQZO[M[KZJXJVKULUMVMWLXKX RKVKWLWLVKV RTF\\\\F RUFXG RVFWH RZFXH R[FXG',\r\n  3061: ' 72F]OFI[ RPFJ[ RQFK[ R\\\\GMR RQOU[ RROV[ RSNWZ RLFTF RYF_F RF[N[ RR[Y[ RMFPG RNFOH RRFPH RSFPG RZF\\\\G R^F\\\\G RJZG[ RJYH[ RKYL[ RJZM[ RUZS[ RUYT[ RVYX[',\r\n  3062: ' 49H\\\\QFK[ RRFL[ RSFM[ RNFVF RH[W[YU ROFRG RPFQH RTFRH RUFRG RLZI[ RLYJ[ RMYN[ RLZO[ RR[WZ RT[XX RV[YU',\r\n  3063: ' 68D`MFGZ RMGNYN[ RNFOY ROFPX R[FPXN[ R[FU[ R\\\\FV[ R]FW[ RJFOF R[F`F RD[J[ RR[Z[ RKFMG RLFMH R^F\\\\H R_F\\\\G RGZE[ RGZI[ RVZS[ RVYT[ RWYX[ RVZY[',\r\n  3064: ' 43F_OFIZ ROFV[ RPFVX RQFWX R\\\\GWXV[ RLFQF RYF_F RF[L[ RMFPG RNFPH RZF\\\\G R^F\\\\G RIZG[ RIZK[',\r\n  3065: ' 56G]SFPGNILLKOJSJVKYLZN[Q[TZVXXUYRZNZKYHXGVFSF ROIMLLOKSKWLY RUXWUXRYNYJXH RSFQGOJNLMOLSLXMZN[ RQ[SZUWVUWRXNXIWGVF',\r\n  3066: ' 60F]OFI[ RPFJ[ RQFK[ RLFXF[G\\\\I\\\\K[NYPUQMQ RZG[I[KZNXP RXFYGZIZKYNWPUQ RF[N[ RMFPG RNFOH RRFPH RSFPG RJZG[ RJYH[ RKYL[ RJZM[',\r\n  3067: ' 78G]SFPGNILLKOJSJVKYLZN[Q[TZVXXUYRZNZKYHXGVFSF ROIMLLOKSKWLY RUXWUXRYNYJXH RSFQGOJNLMOLSLXMZN[ RQ[SZUWVUWRXNXIWGVF RLXMVOUPURVSXT]U^V^W] RT^U_V_ RSXS_T`V`W]W\\\\',\r\n  3068: ' 78F^OFI[ RPFJ[ RQFK[ RLFWFZG[I[KZNYOVPNP RYGZIZKYNXO RWFXGYIYKXNVP RRPTQURWXXYYYZX RWYXZYZ RURVZW[Y[ZXZW RF[N[ RMFPG RNFOH RRFPH RSFPG RJZG[ RJYH[ RKYL[ RJZM[',\r\n  3069: ' 44G^ZH[H\\\\F[L[JZHYGVFRFOGMIMLNNPPVSWUWXVZ RNLONVRWT ROGNINKOMUPWRXTXWWYVZS[O[LZKYJWJUI[JYKY',\r\n  3070: ' 54G]TFN[ RUFO[ RVFP[ RMFKL R]F\\\\L RMF]F RK[S[ RNFKL RPFLI RRFMG RYF\\\\G RZF\\\\H R[F\\\\I R\\\\F\\\\L ROZL[ ROYM[ RPYQ[ ROZR[',\r\n  3071: ' 48F_NFKQJUJXKZN[R[UZWXXU\\\\G ROFLQKUKYLZ RPFMQLULYN[ RKFSF RYF_F RLFOG RMFNH RQFOH RRFOG RZF\\\\G R^F\\\\G',\r\n  3072: ' 35H\\\\NFNHOYO[ ROGPX RPFQW R[GO[ RLFSF RXF^F RMFNH RQFPH RRFOG RYF[G R]F[G',\r\n  3073: ' 57E_MFMHKYK[ RNGLX ROFMW RUFMWK[ RUFUHSYS[ RVGTX RWFUW R]GUWS[ RJFRF RUFWF RZF`F RKFNG RLFMH RPFNI RQFNG R[F]G R_F]G',\r\n  3074: ' 54G]NFT[ ROFU[ RPFV[ R[GIZ RLFSF RXF^F RF[L[ RQ[X[ RMFOH RQFPH RRFPG RYF[G R]F[G RIZG[ RIZK[ RTZR[ RTYS[ RUYW[',\r\n  3075: ' 51G]MFQPN[ RNFRPO[ ROFSPP[ R\\\\GSP RKFRF RYF_F RK[S[ RLFNG RPFOH RQFNG RZF\\\\G R^F\\\\G ROZL[ ROYM[ RPYQ[ ROZR[',\r\n  3076: ' 35G]ZFH[ R[FI[ R\\\\FJ[ R\\\\FNFLL RH[V[XU ROFLL RPFMI RRFNG RR[VZ RT[WX RU[XU',\r\n  3101: ' 54I]NPNOOOOQMQMONNPMTMVNWOXQXXYZZ[ RVOWQWXXZ RTMUNVPVXWZZ[[[ RVRUSPTMULWLXMZP[S[UZVX RNUMWMXNZ RUSQTOUNWNXOZP[',\r\n  3102: ' 47G\\\\LFL[MZOZ RMGMY RIFNFNZ RNPONQMSMVNXPYSYUXXVZS[Q[OZNX RWPXRXVWX RSMUNVOWRWVVYUZS[ RJFLG RKFLH',\r\n  3103: ' 34H[WQWPVPVRXRXPVNTMQMNNLPKSKULXNZQ[S[VZXX RMPLRLVMX RQMONNOMRMVNYOZQ[',\r\n  3104: ' 52H]VFV[[[ RWGWZ RSFXFX[ RVPUNSMQMNNLPKSKULXNZQ[S[UZVX RMPLRLVMX RQMONNOMRMVNYOZQ[ RTFVG RUFVH RXYY[ RXZZ[',\r\n  3105: ' 41H[MSXSXQWOVNSMQMNNLPKSKULXNZQ[S[VZXX RWRWQVO RMPLRLVMX RVSVPUNSM RQMONNOMRMVNYOZQ[',\r\n  3106: ' 40KYWHWGVGVIXIXGWFTFRGQHPKP[ RRHQKQZ RTFSGRIR[ RMMVM RM[U[ RPZN[ RPYO[ RRYS[ RRZT[',\r\n  3107: ' 89I\\\\XNYOZNYMXMVNUO RQMONNOMQMSNUOVQWSWUVVUWSWQVOUNSMQM ROONQNSOU RUUVSVQUO RQMPNOPOTPVQW RSWTVUTUPTNSM RNUMVLXLYM[N\\\\Q]U]X^Y_ RN[Q\\\\U\\\\X] RLYMZP[U[X\\\\Y^Y_XaUbObLaK_K^L\\\\O[ RObMaL_L^M\\\\O[',\r\n  3108: ' 65G^LFL[ RMGMZ RIFNFN[ RNQOOPNRMUMWNXOYRY[ RWOXRXZ RUMVNWQW[ RI[Q[ RT[\\\\[ RJFLG RKFLH RLZJ[ RLYK[ RNYO[ RNZP[ RWZU[ RWYV[ RYYZ[ RYZ[[',\r\n  3109: ' 43LXQFQHSHSFQF RRFRH RQGSG RQMQ[ RRNRZ RNMSMS[ RN[V[ ROMQN RPMQO RQZO[ RQYP[ RSYT[ RSZU[',\r\n  3110: ' 41KXRFRHTHTFRF RSFSH RRGTG RRMR^QaPb RSNS]R` ROMTMT]S`RaPbMbLaL_N_NaMaM` RPMRN RQMRO',\r\n  3111: ' 61G]LFL[ RMGMZ RIFNFN[ RWNNW RRSY[ RRTX[ RQTW[ RTM[M RI[Q[ RT[[[ RJFLG RKFLH RUMWN RZMWN RLZJ[ RLYK[ RNYO[ RNZP[ RWYU[ RVYZ[',\r\n  3112: ' 31LXQFQ[ RRGRZ RNFSFS[ RN[V[ ROFQG RPFQH RQZO[ RQYP[ RSYT[ RSZU[',\r\n  3113: ' 99AcFMF[ RGNGZ RCMHMH[ RHQIOJNLMOMQNROSRS[ RQORRRZ ROMPNQQQ[ RSQTOUNWMZM\\\\N]O^R^[ R\\\\O]R]Z RZM[N\\\\Q\\\\[ RC[K[ RN[V[ RY[a[ RDMFN REMFO RFZD[ RFYE[ RHYI[ RHZJ[ RQZO[ RQYP[ RSYT[ RSZU[ R\\\\ZZ[ R\\\\Y[[ R^Y_[ R^Z`[',\r\n  3114: ' 65G^LML[ RMNMZ RIMNMN[ RNQOOPNRMUMWNXOYRY[ RWOXRXZ RUMVNWQW[ RI[Q[ RT[\\\\[ RJMLN RKMLO RLZJ[ RLYK[ RNYO[ RNZP[ RWZU[ RWYV[ RYYZ[ RYZ[[',\r\n  3115: ' 46H\\\\QMNNLPKSKULXNZQ[S[VZXXYUYSXPVNSMQM RMPLRLVMX RWXXVXRWP RQMONNOMRMVNYOZQ[ RS[UZVYWVWRVOUNSM',\r\n  3116: ' 60G\\\\LMLb RMNMa RIMNMNb RNPONQMSMVNXPYSYUXXVZS[Q[OZNX RWPXRXVWX RSMUNVOWRWVVYUZS[ RIbQb RJMLN RKMLO RLaJb RL`Kb RN`Ob RNaPb',\r\n  3117: ' 55H\\\\VNVb RWOWa RUNWNXMXb RVPUNSMQMNNLPKSKULXNZQ[S[UZVX RMPLRLVMX RQMONNOMRMVNYOZQ[ RSb[b RVaTb RV`Ub RX`Yb RXaZb',\r\n  3118: ' 43IZNMN[ RONOZ RKMPMP[ RWOWNVNVPXPXNWMUMSNQPPS RK[S[ RLMNN RMMNO RNZL[ RNYM[ RPYQ[ RPZR[',\r\n  3119: ' 43J[WOXMXQWOVNTMPMNNMOMQNSPTUUWVXY RNNMQ RNRPSUTWU RXVWZ RMONQPRUSWTXVXYWZU[Q[OZNYMWM[NY',\r\n  3120: ' 22KZPHPVQYRZT[V[XZYX RQHQWRY RPHRFRWSZT[ RMMVM',\r\n  3121: ' 43G^LMLVMYNZP[S[UZVYWW RMNMWNY RIMNMNWOZP[ RWMW[\\\\[ RXNXZ RTMYMY[ RJMLN RKMLO RYYZ[ RYZ[[',\r\n  3122: ' 31I[LMR[ RMMRY RNMSY RXNSYR[ RJMQM RTMZM RKMNO RPMNN RVMXN RYMXN',\r\n  3123: ' 45F^JMN[ RKMNX RLMOX RRMOXN[ RRMV[ RSMVX RRMTMWX RZNWXV[ RGMOM RWM]M RHMKN RNMLN RXMZN R\\\\MZN',\r\n  3124: ' 48H\\\\LMV[ RMMW[ RNMX[ RWNMZ RJMQM RTMZM RJ[P[ RS[Z[ RKMMN RPMNN RUMWN RYMWN RMZK[ RMZO[ RVZT[ RWZY[',\r\n  3125: ' 40H[LMR[ RMMRY RNMSY RXNSYP_NaLbJbIaI_K_KaJaJ` RJMQM RTMZM RKMNO RPMNN RVMXN RYMXN',\r\n  3126: ' 41I[VML[ RWMM[ RXMN[ RXMLMLQ RL[X[XW RMMLQ RNMLP ROMLO RQMLN RS[XZ RU[XY RV[XX RW[XW',\r\n  3151: ' 50G]WMUTUXVZW[Y[[Y\\\\W RXMVTVZ RWMYMWTVX RUTUQTNRMPMMNKQJTJVKYLZN[P[RZSYTWUT RNNLQKTKWLY RPMNOMQLTLWMZN[',\r\n  3152: ' 52I\\\\PFNMMSMWNYOZQ[S[VZXWYTYRXOWNUMSMQNPOOQNT RQFOMNQNWOZ RVYWWXTXQWO RMFRFPMNT RS[UYVWWTWQVNUM RNFQG ROFPH',\r\n  3153: ' 34I[WQWPVPVRXRXPWNUMRMONMQLTLVMYNZP[R[UZWW ROONQMTMWNY RRMPOOQNTNWOZP[',\r\n  3154: ' 58G]YFVQUUUXVZW[Y[[Y\\\\W RZFWQVUVZ RVF[FWTVX RUTUQTNRMPMMNKQJTJVKYLZN[P[RZSYTWUT RMOLQKTKWLY RPMNOMQLTLWMZN[ RWFZG RXFYH',\r\n  3155: ' 33I[MVQUTTWRXPWNUMRMONMQLTLVMYNZP[R[UZWX ROONQMTMWNY RRMPOOQNTNWOZP[',\r\n  3156: ' 45JZZHZGYGYI[I[GZFXFVGTISKRNQRO[N^M`Kb RTJSMRRP[O^ RXFVHUJTMSRQZP]O_MaKbIbHaH_J_JaIaI` RNMYM',\r\n  3157: ' 57H]XMT[S^QaOb RYMU[S_ RXMZMV[T_RaObLbJaI`I^K^K`J`J_ RVTVQUNSMQMNNLQKTKVLYMZO[Q[SZTYUWVT RNOMQLTLWMY RQMOONQMTMWNZO[',\r\n  3158: ' 41G]OFI[K[ RPFJ[ RLFQFK[ RMTOPQNSMUMWNXPXSVX RWNWRVVVZ RWPUUUXVZW[Y[[Y\\\\W RMFPG RNFOH',\r\n  3159: ' 35KXSFSHUHUFSF RTFTH RSGUG RLQMOOMQMRNSPSSQX RRNRRQVQZ RRPPUPXQZR[T[VYWW',\r\n  3160: ' 45KXUFUHWHWFUF RVFVH RUGWG RMQNOPMRMSNTPTSRZQ]P_NaLbJbIaI_K_KaJaJ` RSNSSQZP]O_ RSPRTP[O^N`Lb',\r\n  3161: ' 49G]OFI[K[ RPFJ[ RLFQFK[ RYOYNXNXPZPZNYMWMUNQROS RMSOSQTRUTYUZWZ RQUSYTZ ROSPTRZS[U[WZYW RMFPG RNFOH',\r\n  3162: ' 26LXTFQQPUPXQZR[T[VYWW RUFRQQUQZ RQFVFRTQX RRFUG RSFTH',\r\n  3163: ' 61@cAQBODMFMGNHPHSF[ RGNGSE[ RGPFTD[F[ RHSJPLNNMPMRNSPSSQ[ RRNRSP[ RRPQTO[Q[ RSSUPWNYM[M]N^P^S\\\\X R]N]R\\\\V\\\\Z R]P[U[X\\\\Z][_[aYbW',\r\n  3164: ' 42F^GQHOJMLMMNNPNSL[ RMNMSK[ RMPLTJ[L[ RNSPPRNTMVMXNYPYSWX RXNXRWVWZ RXPVUVXWZX[Z[\\\\Y]W',\r\n  3165: ' 46H\\\\QMNNLQKTKVLYMZP[S[VZXWYTYRXOWNTMQM RNOMQLTLWMY RVYWWXTXQWO RQMOONQMTMWNZP[ RS[UYVWWTWQVNTM',\r\n  3166: ' 66G]HQIOKMMMNNOPOSNWKb RNNNSMWJb RNPMTIb ROTPQQORNTMVMXNYOZRZTYWWZT[R[PZOWOT RXOYQYTXWWY RVMWNXQXTWWVYT[ RFbNb RJaGb RJ`Hb RK`Lb RJaMb',\r\n  3167: ' 57G\\\\WMQb RXMRb RWMYMSb RUTUQTNRMPMMNKQJTJVKYLZN[P[RZSYTWUT RMOLQKTKWLY RPMNOMQLTLWMZN[ RNbVb RRaOb RR`Pb RS`Tb RRaUb',\r\n  3168: ' 30I[JQKOMMOMPNQPQTO[ RPNPTN[ RPPOTM[O[ RYOYNXNXPZPZNYMWMUNSPQT',\r\n  3169: ' 47J[XPXOWOWQYQYOXNUMRMONNONQOSQTTUVVWX RONNQ RORQSTTVU RWVVZ RNOOQQRTSVTWVWXVZS[P[MZLYLWNWNYMYMX',\r\n  3170: ' 23KYTFQQPUPXQZR[T[VYWW RUFRQQUQZ RTFVFRTQX RNMXM',\r\n  3171: ' 42F^GQHOJMLMMNNPNSLX RMNMRLVLZ RMPKUKXLZN[P[RZTXVU RXMVUVXWZX[Z[\\\\Y]W RYMWUWZ RXMZMXTWX',\r\n  3172: ' 29H\\\\IQJOLMNMONPPPSNX RONORNVNZ ROPMUMXNZP[R[TZVXXUYQYMXMXNYP',\r\n  3173: ' 48CaDQEOGMIMJNKPKSIX RJNJRIVIZ RJPHUHXIZK[M[OZQXRU RTMRURXSZU[W[YZ[X]U^Q^M]M]N^P RUMSUSZ RTMVMTTSX',\r\n  3174: ' 51G]JQLNNMPMRNSPSR RPMQNQRPVOXMZK[I[HZHXJXJZIZIY RRORRQVQY RZOZNYNYP[P[NZMXMVNTPSRRVRZS[ RPVPXQZS[U[WZYW',\r\n  3175: ' 49G]HQIOKMMMNNOPOSMX RNNNRMVMZ RNPLULXMZO[Q[SZUXWT RYMU[T^RaPb RZMV[T_ RYM[MW[U_SaPbMbKaJ`J^L^L`K`K_',\r\n  3176: ' 39H\\\\YMXOVQNWLYK[ RXOOOMPLR RVORNONNO RVORMOMMOLR RLYUYWXXV RNYRZUZVY RNYR[U[WYXV',\r\n  3200: ' 50H\\\\QFNGLJKOKRLWNZQ[S[VZXWYRYOXJVGSFQF RNHMJLNLSMWNY RVYWWXSXNWJVH RQFOGNIMNMSNXOZQ[ RS[UZVXWSWNVIUGSF',\r\n  3201: ' 28H\\\\QHQ[ RRHRZ RSFS[ RSFPINJ RM[W[ RQZO[ RQYP[ RSYT[ RSZU[',\r\n  3202: ' 62H\\\\LJLKMKMJLJ RLIMINJNKMLLLKKKJLHMGPFTFWGXHYJYLXNUPPRNSLUKXK[ RWHXJXLWN RTFVGWJWLVNTPPR RKYLXNXSYWYYX RNXSZWZXY RNXS[W[XZYXYV',\r\n  3203: ' 76H\\\\LJLKMKMJLJ RLIMINJNKMLLLKKKJLHMGPFTFWGXIXLWNTO RVGWIWLVN RSFUGVIVLUNSO RQOTOVPXRYTYWXYWZT[P[MZLYKWKVLUMUNVNWMXLX RWRXTXWWY RSOUPVQWTWWVZT[ RLVLWMWMVLV',\r\n  3204: ' 28H\\\\SIS[ RTHTZ RUFU[ RUFJUZU RP[X[ RSZQ[ RSYR[ RUYV[ RUZW[',\r\n  3205: ' 55H\\\\MFKPMNPMSMVNXPYSYUXXVZS[P[MZLYKWKVLUMUNVNWMXLX RWPXRXVWX RSMUNVOWRWVVYUZS[ RLVLWMWMVLV RMFWF RMGUG RMHQHUGWF',\r\n  3206: ' 69H\\\\VIVJWJWIVI RWHVHUIUJVKWKXJXIWGUFRFOGMILKKOKULXNZQ[S[VZXXYUYTXQVOSNQNOONPMR RNIMKLOLUMXNY RWXXVXSWQ RRFPGOHNJMNMUNXOZQ[ RS[UZVYWVWSVPUOSN',\r\n  3207: ' 43H\\\\KFKL RYFYIXLTQSSRWR[ RSRRTQWQ[ RXLSQQTPWP[R[ RKJLHNFPFUIWIXHYF RMHNGPGRH RKJLINHPHUI',\r\n  3208: ' 79H\\\\PFMGLILLMNPOTOWNXLXIWGTFPF RNGMIMLNN RVNWLWIVG RPFOGNINLONPO RTOUNVLVIUGTF RPOMPLQKSKWLYMZP[T[WZXYYWYSXQWPTO RMQLSLWMY RWYXWXSWQ RPONPMSMWNZP[ RT[VZWWWSVPTO',\r\n  3209: ' 69H\\\\MWMXNXNWMW RWOVQURSSQSNRLPKMKLLINGQFSFVGXIYLYRXVWXUZR[O[MZLXLWMVNVOWOXNYMY RMPLNLKMI RVHWIXLXRWVVX RQSORNQMNMKNHOGQF RSFUGVIWLWSVWUYTZR[',\r\n  3210: ' 16MXRXQYQZR[S[TZTYSXRX RRYRZSZSYRY',\r\n  3211: ' 24MXTZS[R[QZQYRXSXTYT\\\\S^Q_ RRYRZSZSYRY RS[T\\\\ RTZS^',\r\n  3212: ' 32MXRMQNQORPSPTOTNSMRM RRNROSOSNRN RRXQYQZR[S[TZTYSXRX RRYRZSZSYRY',\r\n  3213: ' 40MXRMQNQORPSPTOTNSMRM RRNROSOSNRN RTZS[R[QZQYRXSXTYT\\\\S^Q_ RRYRZSZSYRY RS[T\\\\ RTZS^',\r\n  3214: ' 34MXRFQGQIRQ RRFRTST RRFSFST RSFTGTISQ RRXQYQZR[S[TZTYSXRX RRYRZSZSYRY',\r\n  3215: ' 52I\\\\MKMJNJNLLLLJMHNGPFTFWGXHYJYLXNWOSQ RWHXIXMWN RTFVGWIWMVOUP RRQRTSTSQRQ RRXQYQZR[S[TZTYSXRX RRYRZSZSYRY',\r\n  3216: ' 24MXTFRGQIQLRMSMTLTKSJRJQK RRKRLSLSKRK RRGQK RQIRJ',\r\n  3217: ' 24MXTHSIRIQHQGRFSFTGTJSLQM RRGRHSHSGRG RSITJ RTHSL',\r\n  3218: ' 74E_[O[NZNZP\\\\P\\\\N[MZMYNXPVUTXRZP[L[JZIXIUJSPORMSKSIRGPFNGMIMLNOPRTWWZY[[[\\\\Y\\\\X RKZJXJUKSLR RRMSI RSKRG RNGMK RNNPQTVWYYZ RN[LZKXKULSPO RMINMQQUVXYZZ[Z\\\\Y',\r\n  3219: ' 56H\\\\PBP_ RTBT_ RXKXJWJWLYLYJXHWGTFPFMGKIKLLNOPURWSXUXXWZ RLLMNOOUQWRXT RMGLILKMMONUPXRYTYWXYWZT[P[MZLYKWKUMUMWLWLV',\r\n  3220: '  8G^[BIbJb R[B\\\\BJb',\r\n  3221: ' 27KYUBSDQGOKNPNTOYQ]S`Ub RQHPKOOOUPYQ\\\\ RSDRFQIPOPUQ[R^S`',\r\n  3222: ' 27KYOBQDSGUKVPVTUYS]Q`Ob RSHTKUOUUTYS\\\\ RQDRFSITOTUS[R^Q`',\r\n  3223: ' 39JZRFQGSQRR RRFRR RRFSGQQRR RMINIVOWO RMIWO RMIMJWNWO RWIVINOMO RWIMO RWIWJMNMO',\r\n  3224: '  8F_JQ[Q[R RJQJR[R',\r\n  3225: ' 16F_RIRZSZ RRISISZ RJQ[Q[R RJQJR[R',\r\n  3226: ' 16F_JM[M[N RJMJN[N RJU[U[V RJUJV[V',\r\n  3227: ' 11NWSFRGRM RSGRM RSFTGRM',\r\n  3228: ' 22I[NFMGMM RNGMM RNFOGMM RWFVGVM RWGVM RWFXGVM',\r\n  3229: ' 30KYQFOGNINKOMQNSNUMVKVIUGSFQF RQFNIOMSNVKUGQF RSFOGNKQNUMVISF',\r\n  3250: ' 58H]TFQGOIMLLOKSKVLYMZO[Q[TZVXXUYRZNZKYHXGVFTF RQHOJNLMOLSLWMY RTYVWWUXRYNYJXH RTFRGPJOLNOMSMXNZO[ RQ[SZUWVUWRXNXIWGVF',\r\n  3251: ' 20H]TJO[Q[ RWFUJP[ RWFQ[ RWFTIQKOL RTJRKOL',\r\n  3252: ' 52H]OKOJPJPLNLNJOHPGSFVFYGZIZKYMWOMUKWI[ RXGYIYKXMVOSQ RVFWGXIXKWMUOMU RJYKXMXRYWYXX RMXRZWZ RMXR[U[WZXXXW',\r\n  3253: ' 64H]OKOJPJPLNLNJOHPGSFVFYGZIZKYMXNVOSP RXGYIYKXMWN RVFWGXIXKWMUOSP RQPSPVQWRXTXWWYUZR[O[LZKYJWJULULWKWKV RVRWTWWVY RSPUQVSVWUYTZR[',\r\n  3254: ' 15H]WJR[T[ RZFXJS[ RZFT[ RZFJUZU',\r\n  3255: ' 49H]QFLP RQF[F RQGYG RPHUHYG[F RLPMOPNSNVOWPXRXUWXUZQ[N[LZKYJWJULULWKWKV RVPWRWUVXTZ RSNUOVQVUUXSZQ[',\r\n  3256: ' 61H]YJYIXIXKZKZIYGWFTFQGOIMLLOKSKVLYMZO[R[UZWXXVXSWQVPTOQOOPNQMS RPINLMOLSLWMY RVXWVWSVQ RTFRGPJOLNOMSMXNZO[ RR[TZUYVVVRUPTO',\r\n  3257: ' 39H]NFLL R[FZIXLTQRTQWP[ RRSPWO[ RXLRRPUOWN[P[ RMIPFRFWI ROGRGWI RMIOHRHWIYIZH[F',\r\n  3258: '104H]SFPGOHNJNMOOQPTPWOYNZLZIYGWFSF RUFPG RPHOJONPO ROORP RSPWO RXNYLYIXG RYGUF RSFQHPJPNQP RTPVOWNXLXHWF RQPMQKSJUJXKZN[R[VZWYXWXTWRVQTP RRPMQ RNQLSKUKXLZ RKZP[VZ RVYWWWTVR RVQSP RQPOQMSLULXMZN[ RR[TZUYVWVSUQTP',\r\n  3259: ' 61H]XNWPVQTRQROQNPMNMKNIPGSFVFXGYHZKZNYRXUVXTZQ[N[LZKXKVMVMXLXLW ROPNNNKOI RXHYJYNXRWUUX RQRPQOOOKPHQGSF RVFWGXIXNWRVUUWSZQ[',\r\n  3260: ' 16MXPXOYOZP[Q[RZRYQXPX RPYPZQZQYPY',\r\n  3261: ' 22MXQ[P[OZOYPXQXRYR[Q]P^N_ RPYPZQZQYPY RQ[Q\\\\P^',\r\n  3262: ' 32MXSMRNROSPTPUOUNTMSM RSNSOTOTNSN RPXOYOZP[Q[RZRYQXPX RPYPZQZQYPY',\r\n  3263: ' 38MXSMRNROSPTPUOUNTMSM RSNSOTOTNSN RQ[P[OZOYPXQXRYR[Q]P^N_ RPYPZQZQYPY RQ[Q\\\\P^',\r\n  3264: ' 34MXVFUFTGRT RVGUGRT RVGVHRT RVFWGWHRT RPXOYOZP[Q[RZRYQXPX RPYPZQZQYPY',\r\n  3265: ' 59H]OKOJPJPLNLNJOHPGSFWFZG[I[KZMYNWOSPQQQSSTTT RUFZG RYGZIZKYMXNVO RWFXGYIYKXMWNSPRQRSST RPXOYOZP[Q[RZRYQXPX RPYPZQZQYPY',\r\n  3266: ' 22MXWFUGTHSJSLTMUMVLVKUJTJ RUGTITJ RTKTLULUKTK',\r\n  3267: ' 22MXVIUITHTGUFVFWGWIVKULSM RUGUHVHVGUG RVIVJUL',\r\n  3268: ' 72E_\\\\O\\\\N[N[P]P]N\\\\M[MYNWPRXPZN[K[HZGXGVHTISKRPPROTMUKUITGRFPGOIOLPRQURWTZV[X[YYYX RL[HZ RIZHXHVITJSLR RPPQSTYVZ RK[JZIXIVJTKSMRRO ROLPOQRSVUYWZXZYY',\r\n  3269: ' 52H]TBL_ RYBQ_ RZKZJYJYL[L[JZHYGVFRFOGMIMLNNPPVSWUWXVZ RNLONVRWT ROGNINKOMUPWRXTXWWYVZS[O[LZKYJWJULULWKWKV',\r\n  3270: '  8G^_BEbFb R_B`BFb',\r\n  3271: ' 32JZZBXCUERHPKNOMSMXN\\\\O_Qb RSHQKOONTN\\\\ RZBWDTGRJQLPOOSN\\\\ RNTO]P`Qb',\r\n  3272: ' 32JZSBUEVHWLWQVUTYR\\\\O_LaJb RVHVPUUSYQ\\\\ RSBTDUGVP RVHUQTUSXRZP]M`Jb',\r\n  3273: ' 39J[TFSGUQTR RTFTR RTFUGSQTR ROIPIXOYO ROIYO ROIOJYNYO RYIXIPOOO RYIOO RYIYJONOO',\r\n  3274: '  8F_JQ[Q[R RJQJR[R',\r\n  3275: ' 16F_RIRZSZ RRISISZ RJQ[Q[R RJQJR[R',\r\n  3276: ' 16F_JM[M[N RJMJN[N RJU[U[V RJUJV[V',\r\n  3277: ' 11MWUFTGRM RUGRM RUFVGRM',\r\n  3278: ' 22H\\\\PFOGMM RPGMM RPFQGMM RZFYGWM RZGWM RZF[GWM',\r\n  3279: ' 30KZSFQGPIPKQMSNUNWMXKXIWGUFSF RSFPIQMUNXKWGSF RUFQGPKSNWMXIUF',\r\n  3301: ' 62F^IHJIIJHIIGKFMFOGPHQKQOPRNTLUIV ROHPKPPOR RMFNGOJOPNSLU RLVOY RKVOZ RIVN[UV R\\\\G[H\\\\H\\\\G[FYFWGVHUJUYW[[W RWHVJVXXZ RYFXGWJWWYY',\r\n  3302: '101E_GQGRHSJSLRLOKMIJIHKF RKOIK RJSKRKPIMHKHIIGKFNFPGQHRJRRQUOW RPHQJQT RNFOGPJPUOW RRISGUFWFYGZH[J\\\\K RYHZJ RWFXGYJZK\\\\K R\\\\KRP RYM[O\\\\R\\\\U[XYZV[S[PZJWIWHX RXNYN[P RVNYO[Q\\\\S RTZRZLWKW RZYXZUZRYNWKVIVHXHZI[JZIY',\r\n  3303: ' 79F^RHPFNFLGJJINIRJVLYNZQ[T[WZYY[W RLHKJJMJRKVMYPZ RNFMGLIKMKQLUMWOYRZUZXY[W RUFRHQIPKPLQNTPURUT RQKQLUPUQ RQIQJRLUNVPVRUTSURUPTOR RUFVGXHZH RUGVHWH RTGVIXIZH[G',\r\n  3304: ' 79E_HLHKIIKGNFRFUGWHYJ[M\\\\Q\\\\U[XYZV[S[PZJWIWHX RKHMGRGUHWIYK[N RTZRZLWKW RHKJIMHRHUIWJYL[O\\\\R RZYXZUZRYNWKVIVHXHZI[JZIY RPHMKLMLONSNU RMNMONQNR RMKMMOQOSNUMVKVJUJT',\r\n  3305: ' 95F^RHPFNFLGJJINIRJVLYNZQ[T[WZYY[W RLHKJJMJRKVMYPZ RNFMGLIKMKQLUMWOYRZUZXY[W RUFRHQIPKPLQNTPURUT RQKQLUPUQ RQIQJRLUNVPVRUTSURUPTOR RUFVGXHZH RUGVHWH RTGVIXIZH[G RUNYK RYKZL\\\\L RXLYMZM RWMXNZN\\\\L',\r\n  3306: ' 94F^MNKMJKJIKGNFQFTGXI RKHMGRGUH RJKKIMHRHXIZI[H[GZFYF RSHRIQKQMROVSWVWYV\\\\U]S^ RTPWSXVXYW[ RQMSOVQXSYVYYX[V]S^O^L]K\\\\JZJWLTLRKQ RL\\\\K[KWLU RO^M]L[LWMTMRLQJQIRIS RUPYL RYLZM\\\\M RXMYNZN RWNXOZO\\\\M',\r\n  3307: ' 99E_UJTHSGQFNFKGIJHNHRIUJWLYNZQ[T[WZYY[W\\\\T\\\\Q[NYL RKHJJIMIRJUKW RZW[U[QZNYM RNFLGKIJMJRKVLXNZ RWZYXZUZQYOWM RUFRHPJOLOMPOSQTSTU RPLPMTQTR RPJPKQMTOUQUSTURVQVOUNS RTOYLZJ R\\\\FZJ RYG]I R\\\\F[GYGZHZJ[I]I\\\\H\\\\F',\r\n  3308: ' 92F_RFPGNIMKMMNOPQQSQU RNLNMQQQR RNINKOMQORQRSQUPVNWLWJVIUHSHQIPJQIR RRFTHVHXG RQGSH RPGQHSIUIXG RRPYK RYK[N\\\\Q\\\\T[WYYVZR[ RXLZN[Q[UZW RVMWMYOZRZVYXXYVZ RVZTZRYPYNZM\\\\N^P_R_T^ RSZQZ RR[PZNZ',\r\n  3309: ' 83F_PPNPLOKNJLJJKHLGOFQFTGWJYK RLHNGRGTHUI RJJKIMHQHTIVJYK[K\\\\J\\\\H[GYG RJXKYJZIYIWJVLVNWPYR\\\\T^ RNXOYQ\\\\R] RLVMWNYP\\\\Q]S^V^X]Y\\\\ZZZWYUWRVPVO RYXYWVRVQ RX]Y[YYXWVTURUPWNYNZOZP',\r\n  3310: ' 83F_PPNPLOKNJLJJKHLGOFQFTGWJYK RLHNGRGTHUI RJJKIMHQHTIVJYK[K\\\\J\\\\H[GYG RJXKYJZIYIWJVLVNWPYR\\\\T^ RNXOYQ\\\\R] RLVMWNYP\\\\Q]S^V^X]Y\\\\ZZZWYUWRVPVO RYXYWVRVQ RX]Y[YYXWVTURUPWNYNZOZP',\r\n  3311: ' 81E_[KZIXGUFRFOGMILKLNMQPWPYN[ RMNMOPUPV RNHMJMMNOPSQVQXPZN[L[JZ RHVJZ RGYKW RHVHXGYIYJZJXKWIWHV RNONMOKQJTJVKXMYM RUKWM RRJTKULVN RYMPQ RUOYXZY[Y RTPXXZZ RSPWYY[\\\\X',\r\n  3312: ' 73G^ZSYTVTUSUQVOXLYJYH RVQVPYLYK RWTVSVRWPYNZLZJYHXGUFPFMGLHKJKLLNNQOSOTNV RLKLLOQOR RLHLJMLOOPQPSOUMWJY RMWOWRYUZXZZY RNXOXSZTZ RJYLXMXQZT[V[YZZY[W',\r\n  3313: '128BbEQERFSHSJRJOIMGJGHIF RIOGK RHSIRIPGMFKFIGGIFKFMGOIPLPROUNWLYI[HZGZ RNIOLORNUMW RJZIYHY RKFMHNKNRMVLXKYJXIXF[ RNGPFRFTGVIWLWRVUUWSYQ[PZOZ RUIVLVRUV RRZQYPY RRFTHUKUSTWSYRXQXN[ RUHVGXFZF\\\\G]H^J_K R\\\\H]J RZF[G\\\\J]K_K R_K\\\\M[NZQZT[X][`X R\\\\N[P[T\\\\W^Z R_K]M\\\\O\\\\S]W_Y',\r\n  3314: ' 96D`GQGRHSJSLRLOKMIJIHKF RKOIK RJSKRKPIMHKHIIGKFNFPGRISLSRRUQWOYL[KZIZG[ RQIRKRRQUPWOX RMZKYIY RNFPHQKQRPVNYLXJXG[ RRHSGUFWFYGZH[J\\\\K RYHZJ RWFXGYJZK\\\\K R\\\\KYMXNWQWTXXZ[]X RYNXPXTYW[Z R\\\\KZMYOYSZW\\\\Y',\r\n  3315: ' 72D`PFNGLIKKKMMQMS RLLLMMOMP RLILKNONQMSLTJTISIR RPFQGWIZK[M\\\\P\\\\S[VZXXZU[R[OZIWHWGX RPGQHWJYKZL RPFPHQIWKYL[N\\\\P RSZQZKWJW RYYWZTZQYMWJVHVGXGZH[IZHY',\r\n  3316: '100E`HQHRISKSMRMOLMJJJHLF RLOJK RKSLRLPJMIKIIJGLFOFQGRHSJSU RSWS\\\\R^P_M_L^L\\\\M[N\\\\M] RQHRJR\\\\Q^ ROFPGQJQU RQWQ\\\\P^O_ RSJXF RXFZI[K\\\\O\\\\R[UYXV[ RWGZK[N[O RVHXJZM[P[SZVYX RWYUVSU RQUOVMX RWZUWSVPV RV[TXSW RQWOWMX',\r\n  3317: ' 88D`PFNGLIKKKMMQMS RLLLMMOMP RLILKNONQMSLTJTISIR RPFQGWIZK[M\\\\P\\\\S[VZX RXZU[R[OZIWHWGX RPGQHWJYKZL RPFPHQIWKYL[N\\\\P RSZQZKWJW RXZTZQYMWJVHVGXGZH[IZHY RTXVVXV\\\\Z]Z RWWXW[Z RUWVWZ[\\\\[^Y',\r\n  3318: ' 96D`GQGRHSJSLRLOKMIJIHKF RKOIK RJSKRKPIMHKHIIGKFNFPGQHRJRVQXOZM[K[IZ RPHQJQVPX RNFOGPJPVOYM[ RGVIZ RFYJW RGVGXFYHYIZIXJWHWGV RRISGUFWFYGZH[J\\\\K RYHZJ RWFXGYJZK\\\\K R\\\\KRP RTOXYZ[]X RUOYX[Z RVNZX[Y\\\\Y',\r\n  3319: ' 83E`\\\\H[G\\\\F]G]I\\\\KZKVISHOHKIIK RYJVHSGOGLH R]I\\\\JZJVGSFOFLGJIIKHNHRIUJWLYNZQ[U[XZZY\\\\W]T]Q\\\\OZNWNUOSRQSOS RLXNYQZUZYY RIUKWMXPYUYYX[W\\\\V]T RXOWOSSRS R]Q[OYOWPUSSTQTOSNQNOOMQL',\r\n  3320: ' 81F_LNJMIKIIJGMFRFUGYJ[J\\\\I RJHLGRGUHXJ RIKJILHRHUIYK[K\\\\I\\\\G[FZG[H RUIRLQNQPSTSV RRORPSRSS RRLRNTRTTSVRWPWOVOT RJYKZJ[IZIXJVLVOWSYVZYZ[Y RLWMWSZUZ RIXJWKWMXQZT[W[ZZ\\\\X',\r\n  3321: ' 45G]JHKHLILWJX RKGMHMXPZ RIILFNHNWPYRY RJXKXMYO[RYVV RTHUHVIVYX[[X RUGWHWYYZ RSIVFYHXIXXYYZY',\r\n  3322: '100D`GQGRHSJSLRLOKMIJIHKF RKOIK RJSKRKPIMHKHIIGKFNFPGQHRJRRQUOW RPHQJQT RNFOGPJPUOW RRISGUFWFYG[J\\\\K RYHZJ RWFXGYJZK\\\\K RZKXKWLWNXP[R\\\\T RXO[Q RWMXN[P\\\\R\\\\V[XYZW[S[PZJWIWHX RTZRZLWKW RZYXZUZRYNWKVIVHXHZI[JZIY',\r\n  3323: '143BcEQERFSHSJRJOIMGJGHIF RIOGK RHSIRIPGMFKFIGGIFLFNGOHPJPNOQMTKV RNHOJOONR RLFMGNJNOMSKV RNGPFSFUG RWFTGSISMTPVSWUWWVY RTMTNWSWT RWFUGTITLUNWQXTXVWXUZS[O[MZKXIWGWFX RNZKWJW RQ[OZLWJVGVFXFZG[HZGY RWFZF\\\\G^J_K R\\\\H]J RZF[G\\\\J]K_K R]K[KZLZN[P^R_T R[O^Q RZM[N^P_R_W^Y]Z[[X[UZ RYZXZVY R^Y\\\\ZZZXYWX',\r\n  3324: ' 86F^KHMHOIPJQMQO RQQQUPXM[KZI[ RNZLYKY ROYNYLXI[ RMGPHQIRLRUSWUYWZ RIINFPGRISLSO RSQSTTWUXWYYY RQURXTZV[[X RSLTIWFYG[F RVGXHYH RUHVHXI[F RKSMOQO RSOWOYM RMPWP RKSMQQQ RSQWQYM',\r\n  3325: ' 74E_HQHRISKSMRMOLMJJJHLF RLOJK RKSLRLPJMIKIIJGLFOFQGRHSJSORRQTQUSWTW RQHRJRPQSPUSX ROFPGQJQPPTOVRYUV RSJ[F RYGYZX] RZGZXY[ R[F[VZZY\\\\W^T_P_M^K\\\\JZKYLZK[',\r\n  3326: ' 74F^NIOGQFTFVGWHXJXMWOVPTQ RQQOPNN RVHWIWNVO RTFUGVIVNUPTQ RMUNSORQQTQWRYTZVZZY\\\\W^T_P_N^KZJY RXTYVYZX\\\\ RTQWSXUX[W]V^T_ RO^N]LZKY RR_P^O]MZLYIYHZH\\\\I]J]',\r\n  3401: ' 46J[TMQNOONPMSMVNYO[UX RNVOYPZ RQNOPNSNUOXQZ RRNSOUPUYW[ZX RSNVPVXXZ RTMUNWOXO RWPXO RWPWXXYYY',\r\n  3402: ' 50J[LHMINK RTFQGOINKNXMY RPIOKOXRZ RTFRGQHPKPXRYSZ RMYNYPZQ[TZ RPPVMWOXRXUWXVYTZ RUNVOWQ RTNVPWSWUVXTZ',\r\n  3403: ' 27KXRNTPVOTMRNOPNRNWOYQ[UY RSNUO RPPOROWPYQZ RQOPQPVQXSZ',\r\n  3404: ' 47J[QFNINKOLSNVPWRWUVXTZ ROJOKSMVOWP ROHOIPJUMWOXRXUWXTZQ[ RRNNPNXMY ROPOXRZ RPOPXRYSZ RMYNYPZQ[',\r\n  3405: ' 27KXPUVQSMOPNRNWOYQ[UY RUQRN RPPOROWPYQZ RTRROQOPQPVQXSZ',\r\n  3406: ' 49LYXFWGUGSFQFPHPMOONP RVHTHRGQG RXFWHVITIRHQHPI RPKQMRNTOVOVP RNPPP RRPVP RPPPTQ` RSOPOQNQ[ RRPRTQ`',\r\n  3407: ' 53J[TMQNOONPMSMVNYO[UX RNWOYPZ RQNOPNSNUOXQZ RRNSOUPUXV[V]U_ RSNVPVZ RTMUNWOXO RWPXO RWPW\\\\V^U_S`P`N_M^M]N]N^',\r\n  3408: ' 50J[LHMINK RTFQGOINKNXMY RPIOKOYPZ RTFRGQHPKPXQYRY RMYOZP[SX RPPVMWOXSXWWZV\\\\T^Q` RUNVOWR RTNVQWTWWV[T^',\r\n  3409: ' 39MWRFQGQHRISHSGRF RQGSH RQHSG ROOPOQPQYS[VX RPNRORXTZ RNPQMRNTO RSPTO RSPSXTYUY',\r\n  3410: ' 45MWRFQGQHRISHSGRF RQGSH RQHSG ROOPOQPQ[P^O_M` RPNROR[Q] RNPQMRNTO RSPTO RSPS[R]P_M` RS[T]U^',\r\n  3411: ' 63KYNHOIPK RUFSGQIPKPMOONP RPPPXOY RRIQKQM RQOPOQMQXSZ RUFSHRKRO RRPRXSYTY ROYQZR[UX RRLVIWJWLUNSO RUJVKVLUN RROWOWP RNPPP RRPWP',\r\n  3412: ' 29MWOHPIQK RWFTGRIQKQXPY RSIRKRYTZ RWFUGTHSKSXTYUY RPYRZS[VX',\r\n  3413: ' 74E_GOHOIPIXHYJ[ RHNJPJXIYJZKYJX RFPIMKOKXLYJ[ RNNPOQQQXPYR[ RPNQORQRXQYRZSYRX RKPNNPMRNSPSXTYR[ RVNWOYPYY[[^X RWNZPZX\\\\Z RSPVNXMYN[O\\\\O R[P\\\\O R[P[X\\\\Y]Y',\r\n  3414: ' 49I[KOLOMPMXLYN[ RLNNPNXMYNZOYNX RJPMMOOOXPYN[ RRNSOUPUYW[ZX RSNVPVXXZ ROPRNTMUNWOXO RWPXO RWPWXXYYY',\r\n  3415: ' 41J[NPNXMY ROPOXRZ RQOPPPXRYSZ RMYNYPZQ[TZ RNPQOVMWOXRXUWXVYTZ RUNVOWQ RTNVPWSWUVXTZ',\r\n  3416: ' 57J[OJMLMNNQNXLZ RNYO` RNMNNOQO[ RNKNLONPQPXQXSYTZ RPYO` RSZQY RTZR[PY RNYLZ RPPVMWOXRXUWXVYTZ RUNVOWQ RTNVPWSWUVXTZ',\r\n  3417: ' 43J[TMQNOONPMSMVNYO[UX RNWOYPZ RQNOPNSNUOXQZ RRNSOUPUXV` RSNVPV[ RTMUNWOXO RWPXO RWPWXV`',\r\n  3418: ' 32KYNOOOPPPXOY RONQPQYSZ RMPPMRORXSYTY ROYQZR[UX RTNUPWOVMRO RUNVO',\r\n  3419: ' 42LWXFWGUGSFQFPHPMOONP RVHTHRGQG RXFWHVITIRHQHPI RPKRP RPPPTQ` RQOPOQNQ[ RRPRTQ` RNPPP',\r\n  3420: ' 37LXSIRLQNPONP RSISOVOVP RNPQP RSPVP RQPQXPY RROQORMRXTZ RSPSXTYUY RPYRZS[VX',\r\n  3421: ' 47I[KOLOMPMXLY RLNNPNXPZ RJPMMOOOXQYRZ RLYMYOZP[RZUX RVMTOUPUYW[ZX RVPWOVNUOVPVXXZ RVMXOWPWXXYYY',\r\n  3422: ' 47J[OKMMMONRNXMY RNNNOOROXRZ RNLNMOOPRPXRYSZ RMYNYPZQ[TZ RPPVMWOXRXUWXVYTZ RUNVOWQ RTNVPWSWUVXTZ',\r\n  3423: ' 72F_KKIMIOJRJXIYK[ RJNJOKRKXJYKZLYKX RJLJMKOLRLXMYK[ RONQORQRXQY RQNROSQSXVZ RLPONQMSNTPTXVYWZ RQYRYTZU[XZ RTPZM[O\\\\R\\\\T[XZYXZ RYNZO[Q RXNZP[S[UZXXZ',\r\n  3424: ' 44KZOOPOQPQXPXNYM[M]N_P`S`V_V^U^U_ RPNRPRXUZ RNPQMSOSXUYVZ RXYT[SZQYOYM[ RUNVPXOWMSO RVNWO',\r\n  3425: ' 47J[OKMMMONRNXMY RNNNOOROYQZ RNLNMOOPRPXQYRY RMYOZP[SX RPPVMWOXSXWWZV\\\\T^Q` RUNVOWR RTNVQWTWWV[T^',\r\n  3426: ' 43KYNPSMUNVPVRUTQV RSNUO RRNTOUQURTTSU RSUUWVYV]U_S`Q`O_N]N[OYQXWV RRVTWUY RQVTXUZU]T_S`',\r\n  3427: ' 61JZRMPNMPMRNU RNPNROT RPNOOORPT RPNROTOVNWMWKVJTJ RQNSN RRMTNVN RNUVRWUWWVYR[ RUSVUVXUY RTSUUUXTZ RTZRYOYL[ RSZQZ RR[PZNZL[',\r\n  3428: ' 78J[VFUGSGQFOFNHNMMOLP RTHRHPGOG RVFUHTIRIPHOHNI RNKPP RNPNTO` ROONOONO[ RPPPTO` RLPNP RPPUMWNXPXRWTSV RUNWO RTNVOWQWRVTUU RUUWVXXX[W]U_R` RUVWW RSVTVVWWYW\\\\V^',\r\n  3429: ' 62J[PIOLNNMOKP RPIPXQYO[ ROONOONOXNYOZPYOX RKPNPNXMYO[ RPPUMWNXPXRWTSV RUNWO RTNVOWQWRVTUU RUUWVXXX[W]U_R` RUVWW RSVTVVWWYW\\\\V^',\r\n  3501: ' 60G]LINGPFRFSGZW[X]X RQGRHYXZZ[YYX RNGPGQHXXYZZ[[[]X RLMMLOKPKQL RPLPM RMLOLPN RG[IYKXNXPY RJYNYOZ RG[JZMZN[PY RRJLX RNSVS',\r\n  3502: '110F^HHJFMFOGQF RKGNG RHHJGLHOHQF RMKLLKNKOIOHPHRIQKQKW RLMLU RIPLP RMKMTLVKW RRIQJPLPU RQKQS RRIRRQTPU RRIXFZG[I[KYMUO RXGZIZK RVGXHYIYLWN RWNZP[R[X RYPZRZW RWNXOYQYX RJ[MYPXTXWY RLZOYTYVZ RJ[NZSZU[WYYX[X RUOUX RURYR RUUYU',\r\n  3503: ' 69E]NGLHJJILHOHSIVJXMZP[S[VZXYZW[U RJKINISKWNYQZTZWY RNGLIKKJNJRKUNXQYTYWXYW[U RPJPV RQJQT RRIRSQUPV RPJRIUFWGYGZF RTGVHXH RSHUIWIYHZF RWIWX',\r\n  3504: ' 72G^IFWFYGZIZX RKGWGYIYW RIFJGLHWHXIXX ROKNLMNMOKOJPJRKQMQMV RNMNT RKPNP ROKOSNUMV RI[LYOXSXVY RKZNYSYUZ RI[MZRZT[VYXXZX RRHRX RRMTNVNXM RRSTRVRXS',\r\n  3505: ' 94G]IHKFMFOGQF RLGNG RIHKGMHOHQF RNKMLLNLOJOIPIRJQLQLW RMMMU RJPMP RNKNTMVLW RQMRJSHTGVFXF[G RTHVGXGZH RRJSIUHWHYI[G RQURRSPTOVOXP RTPVPWQ RRRSQUQVRXP RK[NYRXWX[Y RMZPYWYZZ RK[OZVZY[[Y RQMQX',\r\n  3506: ' 91F]JHLFOFQGSF RMGPG RJHLGNHQHSF RPKOLNNNOLOKPKRLQNQNV ROMOT RLPOP RPKPSOUNV RSJSYRZQZMXKXIYG[ RTJTX RTPXP RPZOZMYJY RUIUOXO RXQUQUWTYP[N[LZJZG[ RSJUIXFZG\\\\G]F RWGYH[H RVHXIZI\\\\H]F RXIXW',\r\n  3507: ' 87E^NGLHJJILHOHRIUJWLYNZQ[U[XZZX[V[SZQYPWOUO RJKINISJV RNGLIKKJNJSKVLXNZ RYXZWZSYQ RU[WZXYYWYSXQWPUO RPJPW RQJQU RRIRTQVPW RPJRIUFWGYGZF RTGVHXH RSHUIWIYHZF RYHUOU[ RUSYS RUVYV',\r\n  3508: '112F^HHJFMFOGQF RKGNG RHHJGLHOHQF RMKLLKNKOIOHPHRIQKQKW RLMLU RIPLP RMKMTLVKW RJ[MYPXSXUY RLZOYRYTZ RJ[NZQZS[UY RRIQJPLPU RQKQS RRIRRQTPU RRITGVFXFZG RWGXGYH RTGVGXIZG RUOWNYLZM[P[TZXX[ RXMYNZPZUYX RWNXNYPYUX[ RUOUY RURYR RUUYU',\r\n  3509: ' 67I\\\\LHNFQFTGVF ROGSG RLHNGQHTHVF RSKRLQNQOOONPNROQQQQV RRMRT ROPRP RSKSSRUQV RYHWJVMVXUZSZOXMXKYI[ RWKWW RRZQZOYLY RYHXJXVWXUZS[P[NZKZI[',\r\n  3510: ' 65H\\\\LHNFQFTGVF ROGSG RLHNGQHTHVF RSKRLQNQOOONPNROQQQQV RRMRT ROPRP RSKSSRUQV RYHWJVMVXUZ RWKWW RYHXJXVWXUZR[O[LZJXJVKULUMVLWKW RJVMV',\r\n  3511: '115F^HHJFMFOGQF RKGNG RHHJGLHOHQF RMKLLKNKOIOHPHRIQKQKW RLMLU RIPLP RMKMTLVKW RJ[MYPXSXUY RLZNYRYTZ RJ[NZQZS[UY RRIQJPLPU RQKQS RRIRRQTPU RRITGVFXFZG RWGXGYH RTGVGXIZG RUOXLYM[N RWMYN[N R[NYQWSUU RWSYTZX[Z\\\\Z RYVZZ RWSXTYZZ[[[\\\\Z RUOUY',\r\n  3512: ' 85G]IHKFNFPGRF RLGOG RIHKGMHPHRF RNKMLLNLOJOIPIRJQLQLW RMMMU RJPMP RNKNTMVLW RK[NYRXWX[Y RMZPYWYZZ RK[OZVZY[[Y RSIRJQLQU RRKRS RSISRRTQU RSIUGWFYF[G RXGYGZH RUGWGYI[G RWGWX',\r\n  3513: '107D`LJKKJMJOHOGPGRHQJQJU RKLKS RHPKP RLJLRKTJU RE[GYIXKXMYNYOX RHYKYMZ RE[GZJZL[M[NZOX RLJPFTJTWUYVY RPGSJSXRYSZTYSX RPPSP RNHOHRKROOO ROQRQRXQYS[VYWX RTJXF\\\\J\\\\W]Y^Y RXG[J[X]Z RXP[P RVHWHZKZOWO RWQZQZY\\\\[^Y ROHOX RWHWX',\r\n  3514: ' 84E^GIIGKFMFOGQJVUXXYY RMGOIPKVWYZ RIGKGMHOKTVVYWZY[ RVHXIZI\\\\H]F RWGYH[H RVHXFZG\\\\G]F RKOIOHPHRIQKQ RIPKP RG[IYKXNXPY RJYMYOZ RG[JZMZN[PY RKGKX RYIY[ RRLSMUNWNYM RKTMSQSST',\r\n  3515: ' 79E_NFLGJIIKHNHRIUJWLYNZQ[S[VZXYZW[U\\\\R\\\\N[KZIXGVFUGRIOJ RJJIMISJV RNFLHKJJMJSKVLXNZ RZV[S[MYIXH RVZXXYVZSZMYKWHUG ROJOW RPJPU RQJQTPVOW RUGUZ RUMWNXNZM RUSWRXRZS',\r\n  3516: ' 70H^KFLGMIMOKOJPJRKQMQMYJ[MZMbO` RMHNJN` RKPNP RKFMGNHOJO` ROKRIVFZJZX RVGYJYX RTHUHXKXY RRXUXXY RSYUYWZ RRZTZV[XYZX RRIR_ RRMTNVNXM RRSTRVRXS',\r\n  3517: ' 99E_NFLGJIIKHNHRIUJWLYNZP[T[VZXYZW[U\\\\R\\\\N[KZIXGVFUGRIOJ RJJIMISJV RNFLHKJJMJSKVLXNZ RZV[S[MYIXH RVZXXYVZSZMYKWHUG ROJOW RPJPU RQJQTPVOW RUGUZ RUMWNXNZM RUSWRXRZS RP[QZRZT[X`Za[a RT\\\\V_XaYa RRZS[VaXbZb[a',\r\n  3518: '108F^HHJFMFOGQF RKGNG RHHJGLHOHQF RMKLLKNKOIOHPHRIQKQKW RLMLU RIPLP RMKMTLVKW RJ[MYPXRXUY RLZNYRYTZ RJ[NZQZS[UY RRIQJPLPU RQKQS RRIRRQTPU RRIUGWFYGZIZLYNXOTQRR RWGXGYIYMXN RUGWHXJXMWOTQ RTQVRWSZX[Y\\\\Y RWTYX[Z RTQVSXYZ[\\\\Y',\r\n  3519: ' 94G^UITHRGOF RVHTG RWGSFOFLGKHJJKLLMONWNYOZPZRYU RKKLLOMXMZN[O[QZS RKHKJLKOLYL[M\\\\O\\\\QYUU[ RIOJPLQUQVRVSUU RJQLRTRUS RIOIPJRLSSSUTUU RI[LYPXSXVY RKZNYRYUZ RI[MZRZU[ RWGUISL RRNPQ ROSMUKVJVJUKV',\r\n  3520: ' 71E]JJILHOHSIVKYMZP[S[VZXYZW[U RISJVLXNYQZTZWY RJJIMIQJTLWNXQYTYWXYW[U RHIIGKFOFUGYG[F RPGTHXH RHIIHKGNGTIWIYH[F RSIRJPKPV RQKQT RRJRSQUPV RWIWX',\r\n  3521: ' 89F^HHJFLFOGQF RKGNG RHHJGMHOHQF RKJJLIOISJVKXMZP[S[VZXYZ[\\\\Y RJSKVNYQZTZ RKJJNJQKTLVNXQYUYXX RUIQJPLPV RQKQT RRJRSQUPV RUIWHYFZG\\\\HZIZW[Y\\\\Y RYIZHYGXHYIYX[Z RWHXIXX RUIUY RUNXN RURXR',\r\n  3522: ' 72G^JFKGLILOJOIPIRJQLQLXJY RLHMJMX RJPMP RNYQYSZ RJFLGMHNJNXRXUY RJYMYPZR[UYXXZX RRJUIWHYFZG\\\\HZIZX RYIZHYGXHYIYW RWHXIXX RRJRX RRMTNVNXM RRSTRVRXS',\r\n  3523: ' 95E`HFIGJIJOHOGPGRHQJQJXHY RJHKJKX RHPKP RLYNYPZ RHFJGKHLJLXOXQY RHYKYNZO[QYTXVYW[YY\\\\X ROHRFTHTXWXYY RRGSHSX ROHQHRIRXQY RWYXZ RWHZF\\\\H\\\\X RZG[H[X RWHYHZIZXYY ROHOX RWHWX RONRN RORRR RWNZN RWRZR',\r\n  3524: ' 65G]HIJGLFNFOGWYXZZZ RMGNHVYWZ RJGLGMHUZV[X[ZZ\\\\X RWFYG[G\\\\F RWGXHZH RVHWIYI[H\\\\F RH[IYKXMXNY RJYLYMZ RH[IZKZM[ RWFSO RQRM[ RLPPP RSPXP',\r\n  3525: ' 86G^JFKGLILOJOIPIRJQLQLXJY RLHMJMX RJPMP RNYQYSZ RJFLGMHNJNXRXUY RJYMYPZR[UYXX RRJUIWHYFZG\\\\HZIZ^Y`WbUaQ`L` RYIZHYGXHYIYY RWHXIXXZ[ RXaV`S` RY`V_P_L` RRJRX RRMTNVNXM RRSTRVRXS',\r\n  3526: ' 57H\\\\XGWIROOSMWJ[ RVKNV RZFWJUNRRMXLZ RJHLFOGUGZF RKGOHSHWG RJHNIRIVHXG RLZNYRXVXZY RMZQYUYYZ RJ[OZUZX[ZY RMPQP RTPXP',\r\n  3601: ' 53J[PRNTMVMXNZP[RYUX RMVNXOYQZ RNTNVOXQYRY RNPPPSOUNVMXOWPWXXYYY RONNOQO RTOWOVNVYWZ RMOOMPNROUPUYW[YY RMORT',\r\n  3602: ' 44I[LHMJMXKY RNJMHNGNXQZ RLHOFOXQYRZ RKYMYOZP[RZUYWY ROPROTNUMVNXOYOWPWY RTNVOVX RROSOUPUY',\r\n  3603: ' 35JXNONXLYMYOZP[ ROOOYQZ RPOPXRYSYQZP[ RNORNTMUNWOXO RSNTOVO RPORNTPVPXO',\r\n  3604: ' 41IZRMPNMOMXKY RNONXQZ RRMOOOXQYRZ RKYMYOZP[RZUYWY RMHPFQIWOWY RPINHOGPIVOVX RMHUPUY',\r\n  3605: ' 32JXNONXLYMYOZP[ ROOOYQZ RPOPXRYSYQZP[ RNORNTMWQURPU RSNVQ RPORNUR',\r\n  3606: ' 41JWNHNXLYMYOZP[ ROHOYQZ RPHPXRYSYQZP[ RNHQGSFTGVHWH RRGSHUH RPHQGSIUIWH RKMNM RPMTM',\r\n  3607: ' 56I[MOMXKYLYNZO[PZRYUX RNPNYPZ ROOOXQYRY RMOOORNTMUNWOYOWPW\\\\V_TaRbQaO`M` RSNVPV\\\\ RSaQ`P` RRNSOUPUZV]V_ RTaS`Q_O_M`',\r\n  3608: ' 47I[LHMJMXKYLYNZO[ RNJMHNGNYPZ RLHOFOXQYO[ ROPROTNUMVNXOYOWPWYU[T] RTNVOVYU[ RROSOUPUYT]T`UbVbT`',\r\n  3609: ' 35MWRFPHRITHRF RRGQHSHRG RRMQNOOQPQYS[UY RRPSORNQORPRYSZ RRMSNUOSPSXTYUY',\r\n  3610: ' 39MWRFPHRITHRF RRGQHSHRG RRMQNOOQPQYS[T] RRPSORNQORPRYS[ RRMSNUOSPSYT]T`RbPbPaRb',\r\n  3611: ' 50IZLHMJMXKYLYNZO[ RNJMHNGNYPZ RLHOFOXQYO[ ROPRNTMVPSROU RSNUP RRNTQ RSRTSVXWYXY RSSTTUYVZ RRSSTTYV[XY',\r\n  3612: ' 22MWPHQJQXOYPYRZS[ RRJQHRGRYTZ RPHSFSXUYVYTZS[',\r\n  3613: ' 67E_GOHOIPIXGYHYJZK[ RINJOJYLZ RGOIMKOKXMYK[ RKPNOPNQMSOSXUYS[ RPNRORYTZ RNOOOQPQXPYRZS[ RSPVOXNYMZN\\\\O]O[P[X\\\\Y]Y RXNZOZY[Z RVOWOYPYY[[]Y',\r\n  3614: ' 45I[KOLOMPMXKYLYNZO[ RMNNONYPZ RKOMMOOOXQYO[ ROPROTNUMVNXOYOWPWXXYYY RTNVOVYWZ RROSOUPUYW[YY',\r\n  3615: ' 40I[MOMXKY RNPNXQZ ROOOXQYRZ RKYMYOZP[RZUYWY RMOOORNTMUNWOYOWPWY RSNVPVX RRNSOUPUY',\r\n  3616: ' 54I[LMMOMXKYMYMb RMNNONaO`N^ RNYOYQZ RLMNNOOOXQYRZ ROZP[RZUYWY ROZO^P`Mb ROPROTNUMVNXOYOWPWY RTNVOVX RROSOUPUY',\r\n  3617: ' 44I[MOMXKY RNPNYPZ ROOOXQYRY RKYLYNZO[PZRYUX RMOOORNTMUNWOYOWPWb RSNVPVaU`V^ RRNSOUPU^T`Wb',\r\n  3618: ' 38JXLOMONPNXLYMYOZP[ RMNOOOYQZ RLONMPOPXRYSYQZP[ RPOTMUNWOXO RSNTOVO RRNTPVPXO',\r\n  3619: ' 59JZMOMSOTUTWUWY RNONS RVUVY RPNOOOSQT RSTUUUYTZ RMOPNRMTNVNWM RQNSN RPNROTOVN RWYTZR[PZNZL[ RSZQZ RTZRYOYL[ RWMVOTROWL[',\r\n  3620: ' 28MWPHQJQXOYPYRZS[ RRJQHRGRYTZ RPHSFSXUYVYTZS[ RNMQM RSMVM',\r\n  3621: ' 47I[KOLOMPMXKY RLNNONYPZ RKOMMOOOXQYRY RKYLYNZO[PZRYUX RUMVNXOYOWPWXXYYY RTNVOVYWZ RUMSOUPUYW[YY',\r\n  3622: ' 36I[LMMOMXP[RYUXWX RMNNONXQZ RLMNNOOOWPXRY RUMVNXOYOWPWX RTNVOVW RUMSOUPUX',\r\n  3623: ' 57E_HMIOIXL[NYQX RINJOJXMZ RHMJNKOKWLXNY RQMOOQPQXT[VYYX[X RPNRORXUZ RQMRNTOSPSWTXVY RYMZN\\\\O]O[P[X RXNZOZW RYMWOYPYX',\r\n  3624: ' 59H[KOLONPOQSYTZV[XY RMNOOTYVZ RKOMMONPOTWUXWYXY RRSUMVNXNYM RUNVOWO RTOVPXOYM RQUN[MZKZJ[ RNZMYLY ROYMXKYJ[ RMTPT RSTVT',\r\n  3625: ' 60I[KOLOMPMXKY RLNNONYPZ RKOMMOOOXQYRY RKYLYNZO[PZRYUX RUMVNXOYOWPW\\\\V_TaRbQaO`M` RTNVOV\\\\ RSaQ`P` RUMSOUPUZV]V_ RTaS`Q_O_M`',\r\n  3626: ' 38I[XML[ RLONPQPTOXM RMNOOSO RLONMPNTNXM RL[PYSXVXXY RQYUYWZ RL[PZTZV[XY RNTVT',\r\n  3700: ' 42H\\\\LHLXJY RMIMXPZ RNHNXPYQZ RLHNHSGUF RSGTHVIVY RTGWIWX RUFVGXHZHXIXY RJYLYNZO[QZVYXY',\r\n  3701: ' 27H\\\\OHPIQKQXOY RQIPHQGRIRYTZ ROHRFSHSXUYVY ROYPYRZS[TZVY',\r\n  3702: ' 48H\\\\LHNHPGQFSGVHXH RPHRG RLHNIPIRHSG RVHVP RWIWO RXHXPQPNQLSKVK[ RK[OYSXVXZY RNZQYVYYZ RK[PZUZX[ZY',\r\n  3703: ' 57H\\\\LHMHOGPFRGVHXH ROHQG RLHNIPIRG RVHVO RWIWN RXHXOVOSPQQ RQPSQVRXRXY RWSWX RVRVY RKYMXOXQYRZ ROYQZ RKYMYOZP[RZVYXY',\r\n  3704: ' 41H\\\\UFKPKUTU RVUZU[V[TZU RLPLT RMNMU RTGTXRY RUJVHUGUYWZ RUFWHVJVXXYYY RRYSYUZV[WZYY',\r\n  3705: ' 53H\\\\LFLO RLFXF RMGVG RLHUHWGXF RVLUMSNOOLO RSNTNVOVY RUMWNWX RVLWMYNZNXOXY RKYMXOXQYRZ ROYQZ RKYMYOZP[RZVYXY',\r\n  3706: ' 59H\\\\LHLXJY RMIMXPZ RNHNXPYQZ RLHNHRGTFUGWHXH RSGUH RRGTIVIXH RNPOPSOUNVM RSOTOVPVY RUNWPWX RVMWNYOZOXPXY RJYLYNZO[QZVYXY',\r\n  3707: ' 38H\\\\KHMFPGUGZF RLGOHTHWG RKHOIRIVHZF RZFYHWKSOQRPUPXQ[ RRQQTQWRZ RUMSPRSRVSYQ[',\r\n  3708: ' 71H\\\\LILO RMJMN RNINO RLINISHUGVF RSHTHVIVO RUGWHWN RVFWGYHZHXIXO RLONOVRXR RXOVONRLR RLRLXJY RMSMXPZ RNRNXPYQZ RVRVY RWSWX RXRXY RJYLYNZO[QZVYXY',\r\n  3709: ' 60H\\\\LHLQJR RMIMROS RNHNQPRQR RLHNHSGUF RSGTHVIVY RTGWIWX RUFVGXHZHXIXY RJRKRMSNTOSQRUQVQ RKYMXOXQYRZ ROYQZ RKYMYOZP[RZVYXY',\r\n  3710: ' 11LXRXPZR[TZRX RRYQZSZRY',\r\n  3711: ' 14LXR^R\\\\PZRXSZS\\\\R^P_ RRYQZR[RY',\r\n  3712: ' 22LXRMPORPTORM RRNQOSORN RRXPZR[TZRX RRYQZSZRY',\r\n  3713: ' 25LXRMPORPTORM RRNQOSORN RR^R\\\\PZRXSZS\\\\R^P_ RRYQZR[RY',\r\n  3714: ' 30LXRFQGOHQIRT RRISHRGQHRIRT RRFSGUHSIRT RRXPZR[TZRX RRYQZSZRY',\r\n  3715: ' 51I[LJMHNGQFSFVGWHXJXLWNUPSQ RMJNH RVHWIWMVN RLJNKNIOGQF RSFUGVIVMUOSQ RRQRTSQQQRT RRXPZR[TZRX RRYQZSZRY',\r\n  3716: ' 14LXTFRGQIQKRMTKRIRG RRJRLSKRJ',\r\n  3717: ' 14LXRLRJPHRFSHSJRLPM RRGQHRIRG',\r\n  3718: ' 62E_YNZO[O\\\\N RXOYP[P RXPYQZQ[P\\\\N RYNST RRUL[HVNP ROOSKOFJLPRTXVZX[Z[[Z\\\\X RLZIV RRKOG RKLPQTWVYXZ[Z RMZIU RRLNG RKKQQUWVXXY[Y\\\\X',\r\n  3719: ' 60H\\\\PBP_ RTBT_ RTFVGWIWKYJXHWGTFPFMGKIKLLNOPURWSXUXXWZ RXJWH RLLMNOOUQWRXT RMYLW RMGLILKMMONUPXRYTYWXYWZT[P[MZLYKWMVMXNZP[',\r\n  3720: '  8G^[BIbJb R[B\\\\BJb',\r\n  3721: ' 27KYUBSDQGOKNPNTOYQ]S`Ub RQHPKOOOUPYQ\\\\ RSDRFQIPOPUQ[R^S`',\r\n  3722: ' 27KYOBQDSGUKVPVTUYS]Q`Ob RSHTKUOUUTYS\\\\ RQDRFSITOTUS[R^Q`',\r\n  3723: ' 39JZRFQGSQRR RRFRR RRFSGQQRR RMINIVOWO RMIWO RMIMJWNWO RWIVINOMO RWIMO RWIWJMNMO',\r\n  3724: '  8F_JQ[Q[R RJQJR[R',\r\n  3725: ' 16F_RIRZSZ RRISISZ RJQ[Q[R RJQJR[R',\r\n  3726: ' 16F_JM[M[N RJMJN[N RJU[U[V RJUJV[V',\r\n  3727: ' 11NWSFRGRM RSGRM RSFTGRM',\r\n  3728: ' 22I[NFMGMM RNGMM RNFOGMM RWFVGVM RWGVM RWFXGVM',\r\n  3729: ' 30KYQFOGNINKOMQNSNUMVKVIUGSFQF RQFNIOMSNVKUGQF RSFOGNKQNUMVISF',\r\n  3801: ' 52E_NHLIJKIMHPHSIUKV RJLIOISJU RNHLJKLJOJRKVKXJZH[ RVHXHXYVY RYHYY RZGZZ RHFKGQHVHZG\\\\F RJPXP RH[KZQYVYZZ\\\\[',\r\n  3802: ' 65E_LGLZ RMGMZ RPFNGNZP[ RHJJHLGPFUFXGZIZKYM RXHYIYKXM RUFWGXIXKWL RQUOTNRNPONPMSLVLYM[O\\\\Q\\\\T[WYYWZT[P[LZJYHW RZO[Q[UZW RVLYNZQZUYXWZ',\r\n  3803: ' 60E_\\\\F[HZJXHVGSFQFNGLHJJILHOHRIUJWLYNZQ[S[VZXYZW[Y\\\\[ R[HZMZT[Y RZKYJ RZNYKXIVG RJKINISJV RNGLIKKJNJSKVLXNZ RYWZV RVZXXYVZS',\r\n  3804: ' 46E_KGKZ RLGLZ RNFMGMZN[ RHKIIKGNFSFVGXHZJ[L\\\\O\\\\R[UZWXYVZS[N[KZIXHV RZK[N[SZV RVGXIYKZNZSYVXXVZ',\r\n  3805: ' 86E_\\\\F[HZJXHVGSFQFNGLHJJILHOHRIUJWLYNZQ[S[VZXYZW[Y\\\\[ R[HZMZT[Y RZKYJ RZMXIVG RJKINISJV RNGLIKKJNJSKVLXNZ RYWZV RVZXXYVZS RJPKONOUQXQZP RPPRQURWRYQ RMORRUSWSYRZP RZMYLXLWMXNYM',\r\n  3806: ' 69E_JHJZ RMGKHKY ROFMGLILYNY RHJJHLGOFSFVGXHYI\\\\F R\\\\F[HZLZO[S\\\\U RZIYK RVGXIYLZO RLPMOOOTPWPYO RQPTQVQXP RNOTRVRXQYOYLXKWKVLWMXL RH[JZNYSYYZ\\\\[',\r\n  3807: ' 90E_\\\\F[HZJXHVGSFQFNGLHJJILHOHRIUJWLYNZQ[T[VZXYYXZV[Y\\\\[ R[HZMZT[Y RZKYJ RZNYKXIVG RJKINISJV RNGLIKKJNJSKVLXNZ RXXYVYR RVZWYXVXQ RKSLRMSLTKTJS RJPKNMMOMRNUPWQ RKOMNONROTP RJPLOOOUQYQZP',\r\n  3808: ' 50E_JGJZH[ RKHKZ RNHLHLZ RHFJGNHSHYG\\\\F RLPMNOLRKVKYL[N\\\\Q\\\\T[UYV RZN[P[SZU RVKXLYMZOZSYVYXZZ\\\\[ RH[LZPZU[',\r\n  3809: ' 23E_QIQY RRJRX RSISY RHFLHPITIXH\\\\F RH[KZOYUYYZ\\\\[',\r\n  3810: ' 42E_TIVIVXUZS[ RWIWXVY RXHXY RHFLHPITIXH\\\\F RIOHQHUIXKZN[S[VZXYZW\\\\T RIUJXKY RHSJUKXLZN[',\r\n  3811: ' 70E_JGJZH[ RKHKZ RNHLHLZ RHFJGNHSHYG\\\\F RLPMNOLRKUKXLYMYOXPSRQSPTPUQVRUQT RWLXMXOWP RUKWMWOVPSR RSRVRYSZUZWYX RWSYUYW RSRVSXUYXZZ[[\\\\[ RH[LZPZU[',\r\n  3812: ' 45E_JGJZ RKHKY RNHLHLYNY R\\\\KZNYPXSXUYW[X RZOYRYUZW R\\\\K[MZQZT[X\\\\[ RHFJGNHSHYG\\\\F RH[JZNYSYYZ\\\\[',\r\n  3813: ' 68E_QIQY RRJRX RSISY RNYLWJVIUHRHMIJKHMGPFTFWGYH[J\\\\M\\\\R[UZVXWVY RJUIRIMJJ RLWKUJRJLKIMG RZJ[M[RZU RWGYIZLZRYUXW RHFLHPITIXH\\\\F RH[KZOYUYYZ\\\\[',\r\n  3814: ' 48E_JHJZH[ RLHKIKZ ROFMGLILZ RHJJHLGOFSFVGXHZJ[L\\\\O\\\\S[UYV RZK[N[RZU RVGXIYKZNZRYVYXZZ[[\\\\[ RH[LZPZU[',\r\n  3815: ' 54E_QFNGLHJJILHOHRIUJWLYNZQ[S[VZXYZW[U\\\\R\\\\O[LZJXHVGSFQF RJKINISJV RNGLIKKJNJSKVLXNZ RZV[S[NZK RVZXXYVZSZNYKXIVG',\r\n  3816: ' 51E_JIJZ RMHKJKY RQFOGMILKLYNY RHKJINGQFTFWGYH[J\\\\M\\\\O[RYTVURUOTMRLO RZJ[L[PZR RWGYIZLZPYSVU RH[JZNYSYYZ\\\\[',\r\n  3817: ' 74E_QFNGLHJJILHOHRIUJWLYNZQ[S[VZXYZW[U\\\\R\\\\O[LZJXHVGSFQF RJKINISJV RNGLIKKJNJSKVLXNZ RZV[S[NZK RVZXXYVZSZNYKXIVG RJSKUNVTW[W\\\\X\\\\Z[[[Z\\\\Y RPWRW RKUNWQXSXTW',\r\n  3818: ' 69E_JIJZH[ RKIKZ RLHLZ RHKJILHNGQFUFYG[I\\\\K\\\\N[PZQ RYHZI[K[NZP RUFWGYIZKZOYQ RXRUSRSPRPPROUOXPZR\\\\U\\\\W[XZX RXQYR[V[WZT RTOVPXRYTZX[Z\\\\[ RH[LZPZU[',\r\n  3819: ' 94E_TFZG\\\\F[H[JYHWGTFPFMGJJIMIOJRLTOURUTTUSVQVP R[GZH[J RJPKRLSOTRTTS RKIJKJNKPMRPSRSTRVPWOXO RLQMQNPPNRMUMWNYPZRZUYXWZ RPMRLULXMZO[R[UZW RIWJYIZ RNPNOOMPLRKUKXL[O\\\\R\\\\T[WYYWZT[P[MZKYIWIYH[JZP[',\r\n  3820: ' 66E_QHMHKIJJILHOHSIVJXKYMZP[S[VZXYZW[U\\\\R\\\\N[KYIWH RUHTITKULVKUJ RISJVLXNYQZTZWY RJJINIQJTLWNXQYTYWXYW[T\\\\R RHFKI RKHLG RIGJGKFMGQHWHZG\\\\F',\r\n  3821: ' 51E_LHJJILHOHRIUJWLYNZQ[U[XZZY RKJJLIOISJV RKILJLKKMJPJSKVLXNZ RVHXHXXWZU[ RYHYXXY RZGZY\\\\[ RHFKGQHVHZG\\\\F',\r\n  3822: ' 31E_HFR[ RIGJHQWRY RJGKHRWSX R\\\\FR[ RWNUS RYLUQTTTV RHFJGOHUHZG\\\\F',\r\n  3823: ' 67E_LHJJILHOHRIUJWLYNZQ[S[VZXYZW[U\\\\R\\\\O[LZJXH RJLIOIRJUKW RJJKKKLJOJRKVLXNZ RYWZU[R[OZL RVZXXYVZRZOYLYKZJ RQIQ[ RRJRZ RSIS[ RHFLHPITIXH\\\\F',\r\n  3824: ' 41E_HFXYYZ RIGKHZZ RLH\\\\[ R\\\\FSP RQRJZ RPSMULW RQRMTLUKWKY RHFLHPITIXH\\\\F RH[JZNYSYYZ\\\\[',\r\n  3825: ' 47E_XHXZ RYHYY RZGZY RKHIJHMHPISKUMVPWSWVVXU RLUOVUV RHPIRKTNUTUVV RHFLHPITIXH\\\\F RHWJYLZP[T[XZ\\\\X',\r\n  3826: ' 73E_HFIGKHNHSFVFYGZIZKYM RXGYIYKXM RVFWGXIXL RXNTOROPNPLRKTKXL RTKVLWMVNTO RYM[O\\\\R\\\\T[WYYWZT[P[MZKYIWHTHRIOJNLMNMPNPPOQNPOO RXMZO[Q[UZW RXNYOZQZUYXWZ',\r\n  3901: ' 42J[PQMTMXP[TY RNTNXPZ ROROWRZ RRSMNNMONNO RONSNUMWOWXXY RUNVOVXUYVZWYVX RSNUPUXTYV[XY',\r\n  3902: ' 31IZNHLFMJMXP[UYWX RNHNXPZ RNHPFOJOWRZ ROOTMWPWX RTNVPVX RRNUQUY',\r\n  3903: ' 23KWNPNYP[RY ROPOYPZ RPOPXQYRY RNPTMVOTPRN RSNUO',\r\n  3904: ' 32JZRMMPMXP[RZUYWY RNPNXPZ ROOOWRZ RPIPFQIWPWY RPIVPVX RPIMIPJUPUY',\r\n  3905: ' 25KXNPNYP[RY ROPOYPZ RPOPXQYRY RNPTMWQPU RSNVQ RRNUR',\r\n  3906: ' 32KWOIOXNYP[ RPIPXOYPZQYPX RQHQXRYP[ ROIUFWHUISG RTGVH RLMOM RQMUM',\r\n  3907: ' 41J[MPMXP[UY RNPNXPZ ROOOWRZ RMPOOTMWPW]V_U`SaQaO`MaObQa RTNVPV]U_ RPaNa RRNUQU^T`Sa',\r\n  3908: ' 42I[NHLFMJMXLYN[ RNHNXMYNZOYNX RNHPFOJOXPYN[ ROORNTMWPWYT]T`UbVbT` RTNVPVYU[ RRNUQUZT]',\r\n  3909: ' 37MWRFPHRJTHRF RRGQHRISHRG RRMPOQPQXPYR[ RRPSORNQORPRXQYRZSYRX RRMTOSPSXTYR[',\r\n  3910: ' 37MWRFPHRJTHRF RRGQHRISHRG RRMPOQPQYT] RRPSORNQORPRYS[ RRMTOSPSZT]T`RbPaPbRb',\r\n  3911: ' 51IZNHLFMJMXLYN[ RNHNXMYNZOYNX RNHPFOJOXPYN[ ROPRNTMVPSROU RSNUP RRNTQ RRSSTTYV[XY RSSTUUYVZ RSRTSVXWYXY',\r\n  3912: ' 21MWRHPFQJQXPYR[ RRHRXQYRZSYRX RRHTFSJSXTYR[',\r\n  3913: ' 66E_GOHOIPIXHYJ[ RINJOJXIYJZKYJX RGOIMKOKXLYJ[ RKONNPMSOSXTYR[ RPNRORXQYRZSYRX RNNQPQXPYR[ RSOVNXM[O[X\\\\YZ[ RXNZOZXYYZZ[YZX RVNYPYXXYZ[',\r\n  3914: ' 44I[KOLOMPMXLYN[ RMNNONXMYNZOYNX RKOMMOOOXPYN[ ROORNTMWOWXXYV[ RTNVOVXUYVZWYVX RRNUPUXTYV[',\r\n  3915: ' 28JZMPMXP[UYWX RNPNXPZ ROOOWRZ RMPOOTMWPWX RTNVPVX RRNUQUY',\r\n  3916: ' 47IZLMMOMXKYMYM_LbN` RNON` RLMNNOOOXQYRZ RNYOYQZ ROZP[UYWX ROZO_PbN` ROORNTMWPWX RTNVPVX RRNUQUY',\r\n  3917: ' 31J[MPMXP[UY RNPNXPZ ROOOWRZ RMPOOTMWPW_XbV` RTNVPV` RRNUQU_TbV`',\r\n  3918: ' 31KXMONOOPOXNYP[ RONPOPXOYPZQYPX RMOOMQOQXRYP[ RQOUMWOUPSN RTNVO',\r\n  3919: ' 41JZMPMSOUURWTWX RNPNSOT ROOOSPT RUSVTVX RTSUTUY RMPSMVNTOQN RRNUN RWXQ[MYOXSZ ROYQZ',\r\n  3920: ' 27MWRHPFQJQXPYR[ RRHRXQYRZSYRX RRHTFSJSXTYR[ RNMQM RSMVM',\r\n  3921: ' 40I[KOLOMPMYP[UY RMNNONYPZ RKOMMOOOXRZ RVMXOWPWXXYYY RVPWOVNUOVPVYWZ RVMTOUPUYW[YY',\r\n  3922: ' 36I[LMMOMXQ[SYWW RMNNONXQZ RLMNNOOOWRYSY RVMXOWPWW RVPWOVNUOVPVW RVMTOUPUX',\r\n  3923: ' 59E_HMIOIXM[OYQX RINJOJXMZ RHMJNKOKWNYOY RRMPOQPQXU[WY[W RRPSORNQORPRXUZ RRMTOSPSWVYWY RZM\\\\O[P[W RZP[OZNYOZPZW RZMXOYPYX',\r\n  3924: ' 39I[LONPUZV[XY RMNOOUYWZ RLONMONVXXY RXMVMVOXOXMVOSS RQUNYL[N[NYLYL[ RNTQT RSTVT',\r\n  3925: ' 49I[KOLOMPMYP[UY RMNNONYPZ RKOMMOOOXRZ RVMXOWPW]V_U`SaQaO`MaObQa RVPWOVNUOVPV^U_ RPaNa RVMTOUPU^T`Sa',\r\n  3926: ' 43L[RNOPOORNTMWOWSRU RTNVOVS RRNUPUSTT RRUWWW]V_U`SaQaO`MaObQa RVWV^U_ RPaNa RTVUWU^T`Sa'\r\n}\r\n","/*\r\nhttps://oeis.org/wiki/List_of_LaTeX_mathematical_symbols\r\nhttps://en.wikibooks.org/wiki/LaTeX/Mathematics\r\n*/\r\n\r\n/** LaTeX 符号描述接口 */\r\nexport interface Symb {\r\n  /** Hershey 字形索引 */\r\n  glyph: number\r\n  /** 参数元数 */\r\n  arity?: number\r\n  /** 符号标志位集合 */\r\n  flags: Record<string, boolean>\r\n}\r\n\r\n/** LaTeX 符号表，记录每个命令的字形、参数与标志 */\r\nconst SYMB: Record<string, Symb> = {\r\n  '\\\\frac': { glyph: 0, arity: 2, flags: {} },\r\n  '\\\\binom': { glyph: 0, arity: 2, flags: {} },\r\n  '\\\\sqrt': {\r\n    glyph: 2267,\r\n    arity: 1,\r\n    flags: { opt: true, xfl: true, yfl: true }\r\n  },\r\n  '^': { glyph: 0, arity: 1, flags: {} },\r\n  _: { glyph: 0, arity: 1, flags: {} },\r\n  '(': { glyph: 2221, arity: 0, flags: { yfl: true } },\r\n  ')': { glyph: 2222, arity: 0, flags: { yfl: true } },\r\n  '[': { glyph: 2223, arity: 0, flags: { yfl: true } },\r\n  ']': { glyph: 2224, arity: 0, flags: { yfl: true } },\r\n  '\\\\langle': { glyph: 2227, arity: 0, flags: { yfl: true } },\r\n  '\\\\rangle': { glyph: 2228, arity: 0, flags: { yfl: true } },\r\n  '|': { glyph: 2229, arity: 0, flags: { yfl: true } },\r\n\r\n  '\\\\|': { glyph: 2230, arity: 0, flags: { yfl: true } },\r\n  '\\\\{': { glyph: 2225, arity: 0, flags: { yfl: true } },\r\n  '\\\\}': { glyph: 2226, arity: 0, flags: { yfl: true } },\r\n\r\n  '\\\\#': { glyph: 2275, arity: 0, flags: {} },\r\n  '\\\\$': { glyph: 2274, arity: 0, flags: {} },\r\n  '\\\\&': { glyph: 2273, arity: 0, flags: {} },\r\n  '\\\\%': { glyph: 2271, arity: 0, flags: {} },\r\n\r\n  /*semantics*/\r\n  '\\\\begin': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\end': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\left': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\right': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\middle': { glyph: 0, arity: 1, flags: {} },\r\n\r\n  /*operators*/\r\n  '\\\\cdot': { glyph: 2236, arity: 0, flags: {} },\r\n  '\\\\pm': { glyph: 2233, arity: 0, flags: {} },\r\n  '\\\\mp': { glyph: 2234, arity: 0, flags: {} },\r\n  '\\\\times': { glyph: 2235, arity: 0, flags: {} },\r\n  '\\\\div': { glyph: 2237, arity: 0, flags: {} },\r\n  '\\\\leqq': { glyph: 2243, arity: 0, flags: {} },\r\n  '\\\\geqq': { glyph: 2244, arity: 0, flags: {} },\r\n  '\\\\leq': { glyph: 2243, arity: 0, flags: {} },\r\n  '\\\\geq': { glyph: 2244, arity: 0, flags: {} },\r\n  '\\\\propto': { glyph: 2245, arity: 0, flags: {} },\r\n  '\\\\sim': { glyph: 2246, arity: 0, flags: {} },\r\n  '\\\\equiv': { glyph: 2240, arity: 0, flags: {} },\r\n  '\\\\dagger': { glyph: 2277, arity: 0, flags: {} },\r\n  '\\\\ddagger': { glyph: 2278, arity: 0, flags: {} },\r\n  '\\\\ell': { glyph: 662, arity: 0, flags: {} },\r\n\r\n  /*accents*/\r\n  '\\\\vec': {\r\n    glyph: 2261,\r\n    arity: 1,\r\n    flags: { hat: true, xfl: true, yfl: true }\r\n  },\r\n  '\\\\overrightarrow': {\r\n    glyph: 2261,\r\n    arity: 1,\r\n    flags: { hat: true, xfl: true, yfl: true }\r\n  },\r\n  '\\\\overleftarrow': {\r\n    glyph: 2263,\r\n    arity: 1,\r\n    flags: { hat: true, xfl: true, yfl: true }\r\n  },\r\n  '\\\\bar': { glyph: 2231, arity: 1, flags: { hat: true, xfl: true } },\r\n  '\\\\overline': { glyph: 2231, arity: 1, flags: { hat: true, xfl: true } },\r\n  '\\\\widehat': {\r\n    glyph: 2247,\r\n    arity: 1,\r\n    flags: { hat: true, xfl: true, yfl: true }\r\n  },\r\n  '\\\\hat': { glyph: 2247, arity: 1, flags: { hat: true } },\r\n  '\\\\acute': { glyph: 2248, arity: 1, flags: { hat: true } },\r\n  '\\\\grave': { glyph: 2249, arity: 1, flags: { hat: true } },\r\n  '\\\\breve': { glyph: 2250, arity: 1, flags: { hat: true } },\r\n  '\\\\tilde': { glyph: 2246, arity: 1, flags: { hat: true } },\r\n  '\\\\underline': { glyph: 2231, arity: 1, flags: { mat: true, xfl: true } },\r\n\r\n  '\\\\not': { glyph: 2220, arity: 1, flags: {} },\r\n\r\n  '\\\\neq': { glyph: 2239, arity: 1, flags: {} },\r\n  '\\\\ne': { glyph: 2239, arity: 1, flags: {} },\r\n  '\\\\exists': { glyph: 2279, arity: 0, flags: {} },\r\n  '\\\\in': { glyph: 2260, arity: 0, flags: {} },\r\n  '\\\\subset': { glyph: 2256, arity: 0, flags: {} },\r\n  '\\\\supset': { glyph: 2258, arity: 0, flags: {} },\r\n  '\\\\cup': { glyph: 2257, arity: 0, flags: {} },\r\n  '\\\\cap': { glyph: 2259, arity: 0, flags: {} },\r\n  '\\\\infty': { glyph: 2270, arity: 0, flags: {} },\r\n  '\\\\partial': { glyph: 2265, arity: 0, flags: {} },\r\n  '\\\\nabla': { glyph: 2266, arity: 0, flags: {} },\r\n  '\\\\aleph': { glyph: 2077, arity: 0, flags: {} },\r\n  '\\\\wp': { glyph: 2190, arity: 0, flags: {} },\r\n  '\\\\therefore': { glyph: 740, arity: 0, flags: {} },\r\n  '\\\\mid': { glyph: 2229, arity: 0, flags: {} },\r\n\r\n  '\\\\sum': { glyph: 2402, arity: 0, flags: { big: true } },\r\n  '\\\\prod': { glyph: 2401, arity: 0, flags: { big: true } },\r\n  '\\\\bigoplus': { glyph: 2284, arity: 0, flags: { big: true } },\r\n  '\\\\bigodot': { glyph: 2281, arity: 0, flags: { big: true } },\r\n  '\\\\int': { glyph: 2412, arity: 0, flags: { yfl: true } },\r\n  '\\\\oint': { glyph: 2269, arity: 0, flags: { yfl: true } },\r\n  '\\\\oplus': { glyph: 1284, arity: 0, flags: {} },\r\n  '\\\\odot': { glyph: 1281, arity: 0, flags: {} },\r\n  '\\\\perp': { glyph: 738, arity: 0, flags: {} },\r\n  '\\\\angle': { glyph: 739, arity: 0, flags: {} },\r\n  '\\\\triangle': { glyph: 842, arity: 0, flags: {} },\r\n  '\\\\Box': { glyph: 841, arity: 0, flags: {} },\r\n\r\n  '\\\\rightarrow': { glyph: 2261, arity: 0, flags: {} },\r\n  '\\\\to': { glyph: 2261, arity: 0, flags: {} },\r\n  '\\\\leftarrow': { glyph: 2263, arity: 0, flags: {} },\r\n  '\\\\gets': { glyph: 2263, arity: 0, flags: {} },\r\n  '\\\\circ': { glyph: 902, arity: 0, flags: {} },\r\n  '\\\\bigcirc': { glyph: 904, arity: 0, flags: {} },\r\n  '\\\\bullet': { glyph: 828, arity: 0, flags: {} },\r\n  '\\\\star': { glyph: 856, arity: 0, flags: {} },\r\n  '\\\\diamond': { glyph: 743, arity: 0, flags: {} },\r\n  '\\\\ast': { glyph: 728, arity: 0, flags: {} },\r\n\r\n  /*verbatim symbols*/\r\n  '\\\\log': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\ln': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\exp': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\mod': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\lim': { glyph: 0, arity: 0, flags: { txt: true, big: true } },\r\n\r\n  '\\\\sin': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\cos': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\tan': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\csc': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\sec': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\cot': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\sinh': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\cosh': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\tanh': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\csch': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\sech': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\coth': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\arcsin': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\arccos': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\arctan': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\arccsc': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\arcsec': { glyph: 0, arity: 0, flags: { txt: true } },\r\n  '\\\\arccot': { glyph: 0, arity: 0, flags: { txt: true } },\r\n\r\n  /*font modes*/\r\n  '\\\\text': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\mathnormal': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\mathrm': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\mathit': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\mathbf': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\mathsf': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\mathtt': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\mathfrak': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\mathcal': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\mathbb': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\mathscr': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\rm': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\it': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\bf': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\sf': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\tt': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\frak': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\cal': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\bb': { glyph: 0, arity: 1, flags: {} },\r\n  '\\\\scr': { glyph: 0, arity: 1, flags: {} },\r\n\r\n  '\\\\quad': { glyph: 0, arity: 0, flags: {} },\r\n  '\\\\,': { glyph: 0, arity: 0, flags: {} },\r\n  '\\\\.': { glyph: 0, arity: 0, flags: {} },\r\n  '\\\\;': { glyph: 0, arity: 0, flags: {} },\r\n  '\\\\!': { glyph: 0, arity: 0, flags: {} },\r\n\r\n  /*greek letters*/\r\n  '\\\\alpha': { glyph: 2127, flags: {} },\r\n  '\\\\beta': { glyph: 2128, flags: {} },\r\n  '\\\\gamma': { glyph: 2129, flags: {} },\r\n  '\\\\delta': { glyph: 2130, flags: {} },\r\n  '\\\\varepsilon': { glyph: 2131, flags: {} },\r\n  '\\\\zeta': { glyph: 2132, flags: {} },\r\n  '\\\\eta': { glyph: 2133, flags: {} },\r\n  '\\\\vartheta': { glyph: 2134, flags: {} },\r\n  '\\\\iota': { glyph: 2135, flags: {} },\r\n  '\\\\kappa': { glyph: 2136, flags: {} },\r\n  '\\\\lambda': { glyph: 2137, flags: {} },\r\n  '\\\\mu': { glyph: 2138, flags: {} },\r\n  '\\\\nu': { glyph: 2139, flags: {} },\r\n  '\\\\xi': { glyph: 2140, flags: {} },\r\n  '\\\\omicron': { glyph: 2141, flags: {} },\r\n  '\\\\pi': { glyph: 2142, flags: {} },\r\n  '\\\\rho': { glyph: 2143, flags: {} },\r\n  '\\\\sigma': { glyph: 2144, flags: {} },\r\n  '\\\\tau': { glyph: 2145, flags: {} },\r\n  '\\\\upsilon': { glyph: 2146, flags: {} },\r\n  '\\\\varphi': { glyph: 2147, flags: {} },\r\n  '\\\\chi': { glyph: 2148, flags: {} },\r\n  '\\\\psi': { glyph: 2149, flags: {} },\r\n  '\\\\omega': { glyph: 2150, flags: {} },\r\n\r\n  '\\\\epsilon': { glyph: 2184, flags: {} },\r\n  '\\\\theta': { glyph: 2185, flags: {} },\r\n  '\\\\phi': { glyph: 2186, flags: {} },\r\n  '\\\\varsigma': { glyph: 2187, flags: {} },\r\n\r\n  '\\\\Alpha': { glyph: 2027, flags: {} },\r\n  '\\\\Beta': { glyph: 2028, flags: {} },\r\n  '\\\\Gamma': { glyph: 2029, flags: {} },\r\n  '\\\\Delta': { glyph: 2030, flags: {} },\r\n  '\\\\Epsilon': { glyph: 2031, flags: {} },\r\n  '\\\\Zeta': { glyph: 2032, flags: {} },\r\n  '\\\\Eta': { glyph: 2033, flags: {} },\r\n  '\\\\Theta': { glyph: 2034, flags: {} },\r\n  '\\\\Iota': { glyph: 2035, flags: {} },\r\n  '\\\\Kappa': { glyph: 2036, flags: {} },\r\n  '\\\\Lambda': { glyph: 2037, flags: {} },\r\n  '\\\\Mu': { glyph: 2038, flags: {} },\r\n  '\\\\Nu': { glyph: 2039, flags: {} },\r\n  '\\\\Xi': { glyph: 2040, flags: {} },\r\n  '\\\\Omicron': { glyph: 2041, flags: {} },\r\n  '\\\\Pi': { glyph: 2042, flags: {} },\r\n  '\\\\Rho': { glyph: 2043, flags: {} },\r\n  '\\\\Sigma': { glyph: 2044, flags: {} },\r\n  '\\\\Tau': { glyph: 2045, flags: {} },\r\n  '\\\\Upsilon': { glyph: 2046, flags: {} },\r\n  '\\\\Phi': { glyph: 2047, flags: {} },\r\n  '\\\\Chi': { glyph: 2048, flags: {} },\r\n  '\\\\Psi': { glyph: 2049, flags: {} },\r\n  '\\\\Omega': { glyph: 2050, flags: {} }\r\n}\r\n\r\nexport { SYMB }\r\n\r\n/**\r\n * 将 ASCII 字符按指定模式映射到 Hershey 字形索引\r\n * @param x 字符\r\n * @param mode 排版模式，默认 math\r\n * @returns Hershey 字形索引\r\n */\r\nexport function asciiMap(x: string, mode = 'math'): number {\r\n  const c = x.charCodeAt(0)\r\n  if (65 <= c && c <= 90) {\r\n    const d = c - 65\r\n    if (mode == 'text' || mode == 'rm') {\r\n      return d + 2001\r\n    } else if (mode == 'tt') {\r\n      return d + 501\r\n    } else if (mode == 'bf' || mode == 'bb') {\r\n      return d + 3001\r\n    } else if (mode == 'sf') {\r\n      return d + 2501\r\n    } else if (mode == 'frak') {\r\n      return d + 3301\r\n    } else if (mode == 'scr' || mode == 'cal') {\r\n      return d + 2551\r\n    } else {\r\n      return d + 2051\r\n    }\r\n  }\r\n  if (97 <= c && c <= 122) {\r\n    const d = c - 97\r\n    if (mode == 'text' || mode == 'rm') {\r\n      return d + 2101\r\n    } else if (mode == 'tt') {\r\n      return d + 601\r\n    } else if (mode == 'bf' || mode == 'bb') {\r\n      return d + 3101\r\n    } else if (mode == 'sf') {\r\n      return d + 2601\r\n    } else if (mode == 'frak') {\r\n      return d + 3401\r\n    } else if (mode == 'scr' || mode == 'cal') {\r\n      return d + 2651\r\n    } else {\r\n      return d + 2151\r\n    }\r\n  }\r\n  if (48 <= c && c <= 57) {\r\n    const d = c - 48\r\n    if (mode == 'it') {\r\n      return d + 2750\r\n    } else if (mode == 'bf') {\r\n      return d + 3200\r\n    } else if (mode == 'tt') {\r\n      return d + 700\r\n    } else {\r\n      return d + 2200\r\n    }\r\n  }\r\n\r\n  return <number>{\r\n    '.': 2210,\r\n    ',': 2211,\r\n    ':': 2212,\r\n    ';': 2213,\r\n    '!': 2214,\r\n    '?': 2215,\r\n    '\\'': 2216,\r\n    '\"': 2217,\r\n    '*': 2219,\r\n    '/': 2220,\r\n    '-': 2231,\r\n    '+': 2232,\r\n    '=': 2238,\r\n    '<': 2241,\r\n    '>': 2242,\r\n    '~': 2246,\r\n    '@': 2273,\r\n    '\\\\': 804\r\n  }[x]\r\n}\r\n","import { HERSHEY } from './latex-hershey'\r\nimport { SYMB, Symb, asciiMap } from './latex-symbols'\r\n\r\n/** LaTeX 排版配置常量 */\r\nconst CONFIG: Record<string, number> = {\r\n  /** 上下标缩放比例 */\r\n  SUB_SUP_SCALE: 0.5,\r\n  /** 根号额外项缩放比例 */\r\n  SQRT_MAG_SCALE: 0.5,\r\n  /** 分式缩放比例 */\r\n  FRAC_SCALE: 0.85,\r\n  /** 行间距 */\r\n  LINE_SPACING: 0.5,\r\n  /** 分式上下间距 */\r\n  FRAC_SPACING: 0.4\r\n}\r\n\r\n/**\r\n * 将 LaTeX 字符串切分为 token 数组\r\n * @param str LaTeX 字符串\r\n * @returns token 数组\r\n */\r\nfunction tokenize(str: string): string[] {\r\n  str = str.replace(/\\n/g, ' ')\r\n  let i = 0\r\n  const tokens: string[] = []\r\n  let curr = ''\r\n  while (i < str.length) {\r\n    if (str[i] == ' ') {\r\n      if (curr.length) {\r\n        tokens.push(curr)\r\n        curr = ''\r\n      }\r\n    } else if (str[i] == '\\\\') {\r\n      if (curr.length == 1 && curr[0] == '\\\\') {\r\n        curr += str[i]\r\n        tokens.push(curr)\r\n        curr = ''\r\n      } else {\r\n        if (curr.length) {\r\n          tokens.push(curr)\r\n        }\r\n        curr = str[i]\r\n      }\r\n    } else if (/[A-Za-z0-9\\.]/.test(str[i])) {\r\n      curr += str[i]\r\n    } else {\r\n      if (curr.length && curr != '\\\\') {\r\n        tokens.push(curr)\r\n        curr = ''\r\n      }\r\n      curr += str[i]\r\n      tokens.push(curr)\r\n      curr = ''\r\n    }\r\n    i++\r\n  }\r\n  if (curr.length) tokens.push(curr)\r\n  return tokens\r\n}\r\n\r\n/** 包围盒信息 */\r\ninterface Bbox {\r\n  /** 左上角 X 坐标 */\r\n  x: number\r\n  /** 左上角 Y 坐标 */\r\n  y: number\r\n  /** 宽度 */\r\n  w: number\r\n  /** 高度 */\r\n  h: number\r\n}\r\n\r\n/** LaTeX 表达式节点 */\r\ninterface Expr {\r\n  /** 节点类型 */\r\n  type: string\r\n  /** 节点文本 */\r\n  text: string\r\n  /** 排版模式 */\r\n  mode: string\r\n  /** 子节点 */\r\n  chld: Expr[]\r\n  /** 包围盒 */\r\n  bbox: Bbox\r\n}\r\n\r\n/**\r\n * 将单个 token 解析为原子表达式\r\n * @param x token 字符串\r\n * @returns 原子表达式\r\n */\r\nfunction parseAtom(x: string): Expr {\r\n  return {\r\n    type: SYMB[x] ? 'symb' : 'char',\r\n    mode: 'math',\r\n    text: x,\r\n    chld: [],\r\n    // @ts-ignore\r\n    bbox: null\r\n  }\r\n}\r\n\r\n/**\r\n * 将 token 数组解析为表达式树\r\n * @param tokens token 数组\r\n * @returns 表达式树\r\n */\r\nfunction parse(tokens: string[]): Expr {\r\n  let i = 0\r\n  let expr: Expr = {\r\n    type: 'node',\r\n    text: '',\r\n    mode: 'math',\r\n    chld: [],\r\n    // @ts-ignore\r\n    bbox: null\r\n  }\r\n\r\n  /** 取可选参数（方括号包裹部分） */\r\n  function takeOpt(): Expr | null {\r\n    if (tokens[i] != '[') {\r\n      return null\r\n    }\r\n    let lvl = 0\r\n    let j = i\r\n    while (j < tokens.length) {\r\n      if (tokens[j] == '[') {\r\n        lvl++\r\n      } else if (tokens[j] == ']') {\r\n        lvl--\r\n        if (!lvl) {\r\n          break\r\n        }\r\n      }\r\n      j++\r\n    }\r\n    const ret: Expr = parse(tokens.slice(i + 1, j))\r\n    i = j\r\n    return ret\r\n  }\r\n\r\n  /**\r\n   * 顺序取 n 个参数（花括号包裹或单个 token）\r\n   * @param n 参数个数\r\n   * @returns 参数表达式数组\r\n   */\r\n  function takeN(n: number): Expr[] {\r\n    let j: number = i\r\n    let j0: number = j\r\n    let lvl = 0\r\n    let cnt = 0\r\n    const ret: Expr[] = []\r\n    while (j < tokens.length) {\r\n      if (tokens[j] == '{') {\r\n        if (!lvl) {\r\n          j0 = j\r\n        }\r\n        lvl++\r\n      } else if (tokens[j] == '}') {\r\n        lvl--\r\n        if (!lvl) {\r\n          ret.push(parse(tokens.slice(j0 + 1, j)))\r\n          cnt++\r\n          if (cnt == n) {\r\n            break\r\n          }\r\n        }\r\n      } else {\r\n        if (lvl == 0) {\r\n          ret.push(parseAtom(tokens[j]))\r\n          cnt++\r\n          if (cnt == n) {\r\n            break\r\n          }\r\n        }\r\n      }\r\n      j++\r\n    }\r\n    i = j\r\n    return ret\r\n  }\r\n\r\n  for (i = 0; i < tokens.length; i++) {\r\n    const s: Symb = SYMB[tokens[i]]\r\n    const e: Expr = {\r\n      type: '',\r\n      text: tokens[i],\r\n      mode: 'math',\r\n      chld: [],\r\n      // @ts-ignore\r\n      bbox: null\r\n    }\r\n    if (s) {\r\n      if (s.arity) {\r\n        i++\r\n        e.type = 'func'\r\n        let opt: Expr | null = null\r\n        if (s.flags.opt) {\r\n          opt = takeOpt()\r\n          if (opt) i++\r\n        }\r\n        const chld: Expr[] = takeN(s.arity)\r\n        e.chld = chld\r\n        if (opt) {\r\n          e.chld.push(opt)\r\n        }\r\n      } else {\r\n        e.type = 'symb'\r\n      }\r\n    } else {\r\n      if (tokens[i] == '{') {\r\n        e.type = 'node'\r\n        e.text = ''\r\n        e.chld = takeN(1)\r\n      } else {\r\n        e.type = 'char'\r\n      }\r\n    }\r\n    expr.chld.push(e)\r\n  }\r\n  if (expr.chld.length == 1) {\r\n    expr = expr.chld[0]\r\n  }\r\n  return expr\r\n}\r\n\r\n/**\r\n * 处理 \\begin/\\end 环境结构，将环境内容收纳为子节点\r\n * @param exprs 表达式数组\r\n */\r\nfunction environments(exprs: Expr[]) {\r\n  let i = 0\r\n  while (i < exprs.length) {\r\n    if (exprs[i].text == '\\\\begin') {\r\n      let j: number\r\n      for (j = i; j < exprs.length; j++) {\r\n        if (exprs[j].text == '\\\\end') {\r\n          break\r\n        }\r\n      }\r\n      const es: Expr[] = exprs.splice(i + 1, j - (i + 1))\r\n      environments(es)\r\n      exprs[i].text = exprs[i].chld[0].text\r\n      exprs[i].chld = es\r\n      exprs.splice(i + 1, 1)\r\n    }\r\n    i++\r\n  }\r\n}\r\n\r\n/**\r\n * 对表达式及其子树进行缩放与平移变换\r\n * @param expr 表达式\r\n * @param sclx X 缩放\r\n * @param scly Y 缩放\r\n * @param x X 平移\r\n * @param y Y 平移\r\n * @param notFirst 是否非首层（首层不缩放坐标）\r\n */\r\nfunction transform(\r\n  expr: Expr,\r\n  sclx: number,\r\n  scly: number,\r\n  x: number,\r\n  y: number,\r\n  notFirst?: boolean\r\n) {\r\n  if (scly == null) {\r\n    scly = sclx\r\n  }\r\n  if (!expr.bbox) return\r\n  if (notFirst) {\r\n    expr.bbox.x *= sclx\r\n    expr.bbox.y *= scly\r\n  }\r\n  expr.bbox.w *= sclx\r\n  expr.bbox.h *= scly\r\n  for (let i = 0; i < expr.chld.length; i++) {\r\n    transform(expr.chld[i], sclx, scly, 0, 0, true)\r\n  }\r\n  expr.bbox.x += x\r\n  expr.bbox.y += y\r\n}\r\n\r\n/**\r\n * 计算表达式数组的合并包围盒\r\n * @param exprs 表达式数组\r\n * @returns 合并包围盒\r\n */\r\nfunction computeBbox(exprs: Expr[]): Bbox {\r\n  let xmin = Infinity\r\n  let xmax = -Infinity\r\n  let ymin = Infinity\r\n  let ymax = -Infinity\r\n  for (let i = 0; i < exprs.length; i++) {\r\n    if (!exprs[i].bbox) {\r\n      continue\r\n    }\r\n    xmin = Math.min(xmin, exprs[i].bbox.x)\r\n    ymin = Math.min(ymin, exprs[i].bbox.y)\r\n    xmax = Math.max(xmax, exprs[i].bbox.x + exprs[i].bbox.w)\r\n    ymax = Math.max(ymax, exprs[i].bbox.y + exprs[i].bbox.h)\r\n  }\r\n  return { x: xmin, y: ymin, w: xmax - xmin, h: ymax - ymin }\r\n}\r\n\r\n/**\r\n * 将表达式数组打包为单个节点，并归零子节点坐标\r\n * @param exprs 表达式数组\r\n * @returns 打包后的表达式\r\n */\r\nfunction group(exprs: Expr[]): Expr {\r\n  if (!exprs.length) {\r\n    // @ts-ignore\r\n    return null\r\n  }\r\n  const bbox: Bbox = computeBbox(exprs)\r\n  for (let i = 0; i < exprs.length; i++) {\r\n    if (!exprs[i].bbox) {\r\n      continue\r\n    }\r\n    exprs[i].bbox.x -= bbox.x\r\n    exprs[i].bbox.y -= bbox.y\r\n  }\r\n  const expr: Expr = {\r\n    type: 'node',\r\n    text: '',\r\n    mode: 'math',\r\n    chld: exprs,\r\n    bbox\r\n  }\r\n  return expr\r\n}\r\n\r\n/**\r\n * 对表达式数组进行上下标、左右定界符与矩阵/方程组对齐处理\r\n * @param exprs 表达式数组\r\n * @param alignment 对齐方式\r\n */\r\nfunction align(exprs: Expr[], alignment = 'center'): void {\r\n  for (let i = 0; i < exprs.length; i++) {\r\n    if (exprs[i].text == '^' || exprs[i].text == '\\'') {\r\n      let h = 0\r\n      let j = i\r\n      while (\r\n        j > 0 &&\r\n        (exprs[j].text == '^' || exprs[j].text == '_' || exprs[j].text == '\\'')\r\n      ) {\r\n        j--\r\n      }\r\n      h = exprs[j].bbox.y\r\n      if (exprs[i].text == '\\'') {\r\n        exprs[i].bbox.y = h\r\n      } else {\r\n        // @ts-ignore\r\n        transform(exprs[i], CONFIG.SUB_SUP_SCALE, null, 0, 0)\r\n        if (SYMB[exprs[j].text] && SYMB[exprs[j].text].flags.big) {\r\n          exprs[i].bbox.y = h - exprs[i].bbox.h\r\n        } else if (exprs[j].text == '\\\\int') {\r\n          exprs[i].bbox.y = h\r\n        } else {\r\n          exprs[i].bbox.y = h - exprs[i].bbox.h / 2\r\n        }\r\n      }\r\n    } else if (exprs[i].text == '_') {\r\n      let h = 1\r\n      let j = i\r\n      while (\r\n        j > 0 &&\r\n        (exprs[j].text == '^' || exprs[j].text == '_' || exprs[j].text == '\\'')\r\n      ) {\r\n        j--\r\n      }\r\n      h = exprs[j].bbox.y + exprs[j].bbox.h\r\n      // @ts-ignore\r\n      transform(exprs[i], CONFIG.SUB_SUP_SCALE, null, 0, 0)\r\n      if (SYMB[exprs[j].text] && SYMB[exprs[j].text].flags.big) {\r\n        exprs[i].bbox.y = h\r\n      } else if (exprs[j].text == '\\\\int') {\r\n        exprs[i].bbox.y = h - exprs[i].bbox.h\r\n      } else {\r\n        exprs[i].bbox.y = h - exprs[i].bbox.h / 2\r\n      }\r\n    }\r\n  }\r\n  /**\r\n   * 在指定方向上搜索定界符包围的纵向范围\r\n   * @param i 起始索引\r\n   * @param l 左定界符\r\n   * @param r 右定界符\r\n   * @param dir 搜索方向\r\n   * @param lvl0 初始层级\r\n   * @returns [ymin, ymax]\r\n   */\r\n  function searchHigh(\r\n    i: number,\r\n    l: string,\r\n    r: string,\r\n    dir: number,\r\n    lvl0: number\r\n  ): number[] {\r\n    let j = i\r\n    let lvl = lvl0\r\n    let ymin = Infinity\r\n    let ymax = -Infinity\r\n    while (dir > 0 ? j < exprs.length : j >= 0) {\r\n      if (exprs[j].text == l) {\r\n        lvl++\r\n      } else if (exprs[j].text == r) {\r\n        lvl--\r\n        if (lvl == 0) {\r\n          break\r\n        }\r\n      } else if (exprs[j].text == '^' || exprs[j].text == '_') {\r\n        //skip\r\n      } else if (exprs[j].bbox) {\r\n        ymin = Math.min(ymin, exprs[j].bbox.y)\r\n        ymax = Math.max(ymax, exprs[j].bbox.y + exprs[j].bbox.h)\r\n      }\r\n      j += dir\r\n    }\r\n    return [ymin, ymax]\r\n  }\r\n  for (let i = 0; i < exprs.length; i++) {\r\n    if (exprs[i].text == '\\\\left') {\r\n      const [ymin, ymax] = searchHigh(i, '\\\\left', '\\\\right', 1, 0)\r\n      if (ymin != Infinity && ymax != -Infinity) {\r\n        exprs[i].bbox.y = ymin\r\n        transform(exprs[i], 1, (ymax - ymin) / exprs[i].bbox.h, 0, 0)\r\n      }\r\n    } else if (exprs[i].text == '\\\\right') {\r\n      const [ymin, ymax] = searchHigh(i, '\\\\right', '\\\\left', -1, 0)\r\n      if (ymin != Infinity && ymax != -Infinity) {\r\n        exprs[i].bbox.y = ymin\r\n        transform(exprs[i], 1, (ymax - ymin) / exprs[i].bbox.h, 0, 0)\r\n      }\r\n    } else if (exprs[i].text == '\\\\middle') {\r\n      const [lmin, lmax] = searchHigh(i, '\\\\right', '\\\\left', -1, 1)\r\n      const [rmin, rmax] = searchHigh(i, '\\\\left', '\\\\right', 1, 1)\r\n      const ymin = Math.min(lmin, rmin)\r\n      const ymax = Math.max(lmax, rmax)\r\n      if (ymin != Infinity && ymax != -Infinity) {\r\n        exprs[i].bbox.y = ymin\r\n        transform(exprs[i], 1, (ymax - ymin) / exprs[i].bbox.h, 0, 0)\r\n      }\r\n    }\r\n  }\r\n\r\n  if (!exprs.some(x => x.text == '&' || x.text == '\\\\\\\\')) {\r\n    return\r\n  }\r\n\r\n  const rows: Expr[][][] = []\r\n  let row: Expr[][] = []\r\n  let cell: Expr[] = []\r\n\r\n  for (let i = 0; i < exprs.length; i++) {\r\n    if (exprs[i].text == '&') {\r\n      row.push(cell)\r\n      cell = []\r\n    } else if (exprs[i].text == '\\\\\\\\') {\r\n      if (cell.length) {\r\n        row.push(cell)\r\n        cell = []\r\n      }\r\n      rows.push(row)\r\n      row = []\r\n    } else {\r\n      cell.push(exprs[i])\r\n    }\r\n  }\r\n  if (cell.length) {\r\n    row.push(cell)\r\n  }\r\n  if (row.length) {\r\n    rows.push(row)\r\n  }\r\n  const colws: number[] = []\r\n  const erows: Expr[][] = []\r\n  for (let i = 0; i < rows.length; i++) {\r\n    const erow: Expr[] = []\r\n    for (let j = 0; j < rows[i].length; j++) {\r\n      const e: Expr = group(rows[i][j])\r\n      if (e) {\r\n        colws[j] = colws[j] || 0\r\n        colws[j] = Math.max(e.bbox.w + 1, colws[j])\r\n      }\r\n      erow[j] = e\r\n    }\r\n    erows.push(erow)\r\n  }\r\n\r\n  const ybds: number[][] = []\r\n  for (let i = 0; i < erows.length; i++) {\r\n    let ymin = Infinity\r\n    let ymax = -Infinity\r\n    for (let j = 0; j < erows[i].length; j++) {\r\n      if (!erows[i][j]) {\r\n        continue\r\n      }\r\n      ymin = Math.min(ymin, erows[i][j].bbox.y)\r\n      ymax = Math.max(ymax, erows[i][j].bbox.y + erows[i][j].bbox.h)\r\n    }\r\n    ybds.push([ymin, ymax])\r\n  }\r\n\r\n  for (let i = 0; i < ybds.length; i++) {\r\n    if (ybds[i][0] == Infinity || ybds[i][1] == Infinity) {\r\n      ybds[i][0] = i == 0 ? 0 : ybds[i - 1][1]\r\n      ybds[i][1] = ybds[i][0] + 2\r\n    }\r\n  }\r\n\r\n  for (let i = 1; i < erows.length; i++) {\r\n    const shft = ybds[i - 1][1] - ybds[i][0] + CONFIG.LINE_SPACING\r\n    for (let j = 0; j < erows[i].length; j++) {\r\n      if (erows[i][j]) {\r\n        erows[i][j].bbox.y += shft\r\n      }\r\n    }\r\n    ybds[i][0] += shft\r\n    ybds[i][1] += shft\r\n  }\r\n\r\n  exprs.splice(0, exprs.length)\r\n  for (let i = 0; i < erows.length; i++) {\r\n    let dx = 0\r\n    for (let j = 0; j < erows[i].length; j++) {\r\n      const e: Expr = erows[i][j]\r\n      if (!e) {\r\n        dx += colws[j]\r\n        continue\r\n      }\r\n      e.bbox.x += dx\r\n      dx += colws[j] - e.bbox.w\r\n      // e.bbox.w = colws[j];\r\n      if (alignment == 'center') {\r\n        e.bbox.x += (colws[j] - e.bbox.w) / 2\r\n      } else if (alignment == 'left') {\r\n        //ok\r\n      } else if (alignment == 'right') {\r\n        e.bbox.x += colws[j] - e.bbox.w\r\n      } else if (alignment == 'equation') {\r\n        if (j != erows[i].length - 1) {\r\n          e.bbox.x += colws[j] - e.bbox.w\r\n        }\r\n      }\r\n      exprs.push(e)\r\n    }\r\n  }\r\n}\r\n\r\n/**\r\n * 排版表达式：递归计算各节点包围盒\r\n * @param expr 表达式\r\n * @param mode 当前排版模式\r\n */\r\nfunction plan(expr: Expr, mode = 'math'): void {\r\n  const tmd: string =\r\n    {\r\n      '\\\\text': 'text',\r\n      '\\\\mathnormal': 'math',\r\n      '\\\\mathrm': 'rm',\r\n      '\\\\mathit': 'it',\r\n      '\\\\mathbf': 'bf',\r\n      '\\\\mathsf': 'sf',\r\n      '\\\\mathtt': 'tt',\r\n      '\\\\mathfrak': 'frak',\r\n      '\\\\mathcal': 'cal',\r\n      '\\\\mathbb': 'bb',\r\n      '\\\\mathscr': 'scr',\r\n      '\\\\rm': 'rm',\r\n      '\\\\it': 'it',\r\n      '\\\\bf': 'bf',\r\n      '\\\\sf': 'tt',\r\n      '\\\\tt': 'tt',\r\n      '\\\\frak': 'frak',\r\n      '\\\\cal': 'cal',\r\n      '\\\\bb': 'bb',\r\n      '\\\\scr': 'scr'\r\n    }[expr.text] ?? mode\r\n  if (!expr.chld.length) {\r\n    if (SYMB[expr.text]) {\r\n      if (SYMB[expr.text].flags.big) {\r\n        if (expr.text == '\\\\lim') {\r\n          expr.bbox = { x: 0, y: 0, w: 3.5, h: 2 }\r\n        } else {\r\n          expr.bbox = { x: 0, y: -0.5, w: 3, h: 3 }\r\n        }\r\n      } else if (SYMB[expr.text].flags.txt) {\r\n        let w = 0\r\n        for (let i = 1; i < expr.text.length; i++) {\r\n          w += HERSHEY(asciiMap(expr.text[i], 'text')).w\r\n        }\r\n        w /= 16\r\n        expr.bbox = { x: 0, y: 0, w: w, h: 2 }\r\n      } else if (SYMB[expr.text].glyph) {\r\n        let w = HERSHEY(SYMB[expr.text].glyph).w\r\n        w /= 16\r\n        if (expr.text == '\\\\int' || expr.text == '\\\\oint') {\r\n          expr.bbox = { x: 0, y: -1.5, w: w, h: 5 }\r\n        } else {\r\n          expr.bbox = { x: 0, y: 0, w: w, h: 2 }\r\n        }\r\n      } else {\r\n        expr.bbox = { x: 0, y: 0, w: 1, h: 2 }\r\n      }\r\n    } else {\r\n      let w = 0\r\n      for (let i = 0; i < expr.text.length; i++) {\r\n        if (!HERSHEY(asciiMap(expr.text[i], tmd))) {\r\n          continue\r\n        }\r\n        if (tmd == 'tt') {\r\n          w += 16\r\n        } else {\r\n          w += HERSHEY(asciiMap(expr.text[i], tmd)).w\r\n        }\r\n      }\r\n      w /= 16\r\n      expr.bbox = { x: 0, y: 0, w: w, h: 2 }\r\n    }\r\n    expr.mode = tmd\r\n    return\r\n  }\r\n  if (expr.text == '\\\\frac') {\r\n    const a: Expr = expr.chld[0]\r\n    const b: Expr = expr.chld[1]\r\n    const s: number = CONFIG.FRAC_SCALE\r\n    plan(a)\r\n    plan(b)\r\n    a.bbox.x = 0\r\n    a.bbox.y = 0\r\n    b.bbox.x = 0\r\n    b.bbox.y = 0\r\n    const mw: number = Math.max(a.bbox.w, b.bbox.w) * s\r\n    // @ts-ignore\r\n    transform(a, s, null, (mw - a.bbox.w * s) / 2, 0)\r\n    transform(\r\n      b,\r\n      s,\r\n      // @ts-ignore\r\n      null,\r\n      (mw - b.bbox.w * s) / 2,\r\n      a.bbox.h + CONFIG.FRAC_SPACING\r\n    )\r\n    expr.bbox = {\r\n      x: 0,\r\n      y: -a.bbox.h + 1 - CONFIG.FRAC_SPACING / 2,\r\n      w: mw,\r\n      h: a.bbox.h + b.bbox.h + CONFIG.FRAC_SPACING\r\n    }\r\n  } else if (expr.text == '\\\\binom') {\r\n    const a: Expr = expr.chld[0]\r\n    const b: Expr = expr.chld[1]\r\n    plan(a)\r\n    plan(b)\r\n    a.bbox.x = 0\r\n    a.bbox.y = 0\r\n    b.bbox.x = 0\r\n    b.bbox.y = 0\r\n    const mw: number = Math.max(a.bbox.w, b.bbox.w)\r\n    // @ts-ignore\r\n    transform(a, 1, null, (mw - a.bbox.w) / 2 + 1, 0)\r\n    // @ts-ignore\r\n    transform(b, 1, null, (mw - b.bbox.w) / 2 + 1, a.bbox.h)\r\n    expr.bbox = { x: 0, y: -a.bbox.h + 1, w: mw + 2, h: a.bbox.h + b.bbox.h }\r\n  } else if (expr.text == '\\\\sqrt') {\r\n    const e: Expr = expr.chld[0]\r\n    plan(e)\r\n    const f: Expr = expr.chld[1]\r\n    let pl = 0\r\n    if (f) {\r\n      plan(f)\r\n      pl = Math.max(f.bbox.w * CONFIG.SQRT_MAG_SCALE - 0.5, 0)\r\n      // @ts-ignore\r\n      transform(f, CONFIG.SQRT_MAG_SCALE, null, 0, 0.5)\r\n    }\r\n    // @ts-ignore\r\n    transform(e, 1, null, 1 + pl, 0.5)\r\n    expr.bbox = {\r\n      x: 0,\r\n      y: 2 - e.bbox.h - 0.5,\r\n      w: e.bbox.w + 1 + pl,\r\n      h: e.bbox.h + 0.5\r\n    }\r\n  } else if (SYMB[expr.text] && SYMB[expr.text].flags.hat) {\r\n    const e: Expr = expr.chld[0]\r\n    plan(e)\r\n    const y0 = e.bbox.y - 0.5\r\n    e.bbox.y = 0.5\r\n    expr.bbox = { x: 0, y: y0, w: e.bbox.w, h: e.bbox.h + 0.5 }\r\n  } else if (SYMB[expr.text] && SYMB[expr.text].flags.mat) {\r\n    const e: Expr = expr.chld[0]\r\n    plan(e)\r\n    expr.bbox = { x: 0, y: 0, w: e.bbox.w, h: e.bbox.h + 0.5 }\r\n  } else {\r\n    let dx = 0\r\n    let dy = 0\r\n    let mh = 1\r\n    for (let i = 0; i < expr.chld.length; i++) {\r\n      const c: Expr = expr.chld[i]\r\n      // @ts-ignore\r\n      const spac: number =\r\n        {\r\n          '\\\\quad': 2,\r\n          '\\\\,': (2 * 3) / 18,\r\n          '\\\\:': (2 * 4) / 18,\r\n          '\\\\;': (2 * 5) / 18,\r\n          '\\\\!': (2 * -3) / 18\r\n        }[c.text] ?? null\r\n\r\n      if (c.text == '\\\\\\\\') {\r\n        dy += mh\r\n        dx = 0\r\n        mh = 1\r\n        continue\r\n      } else if (c.text == '&') {\r\n        continue\r\n      } else if (spac != null) {\r\n        dx += spac\r\n        continue\r\n      } else {\r\n        plan(c, tmd)\r\n        // @ts-ignore\r\n        transform(c, 1, null, dx, dy)\r\n        if (c.text == '^' || c.text == '_' || c.text == '\\'') {\r\n          let j: number = i\r\n          while (\r\n            j > 0 &&\r\n            (expr.chld[j].text == '^' ||\r\n              expr.chld[j].text == '_' ||\r\n              expr.chld[j].text == '\\'')\r\n          ) {\r\n            j--\r\n          }\r\n          const wasBig =\r\n            SYMB[expr.chld[j].text] && SYMB[expr.chld[j].text].flags.big\r\n          if (c.text == '\\'') {\r\n            let k = j + 1\r\n            let nth = 0\r\n            while (k < i) {\r\n              if (expr.chld[k].text == '\\'') {\r\n                nth++\r\n              }\r\n              k++\r\n            }\r\n            c.bbox.x =\r\n              expr.chld[j].bbox.x + expr.chld[j].bbox.w + c.bbox.w * nth\r\n            dx = Math.max(dx, c.bbox.x + c.bbox.w)\r\n          } else {\r\n            if (wasBig) {\r\n              const ex =\r\n                expr.chld[j].bbox.x +\r\n                (expr.chld[j].bbox.w - c.bbox.w * CONFIG.SUB_SUP_SCALE) / 2\r\n              c.bbox.x = ex\r\n              dx = Math.max(\r\n                dx,\r\n                expr.chld[j].bbox.x +\r\n                  expr.chld[j].bbox.w +\r\n                  (c.bbox.w * CONFIG.SUB_SUP_SCALE - expr.chld[j].bbox.w) / 2\r\n              )\r\n            } else {\r\n              c.bbox.x = expr.chld[j].bbox.x + expr.chld[j].bbox.w\r\n              dx = Math.max(dx, c.bbox.x + c.bbox.w * CONFIG.SUB_SUP_SCALE)\r\n            }\r\n          }\r\n        } else {\r\n          dx += c.bbox.w\r\n        }\r\n        if (mode == 'text') {\r\n          dx += 1\r\n        }\r\n        mh = Math.max(c.bbox.y + c.bbox.h - dy, mh)\r\n      }\r\n    }\r\n    dy += mh\r\n    const m2s: Record<string, string[]> = {\r\n      bmatrix: ['[', ']'],\r\n      pmatrix: ['(', ')'],\r\n      Bmatrix: ['\\\\{', '\\\\}'],\r\n      cases: ['\\\\{']\r\n    }\r\n    const alt: string =\r\n      {\r\n        bmatrix: 'center',\r\n        pmatrix: 'center',\r\n        Bmatrix: 'center',\r\n        cases: 'left',\r\n        matrix: 'center',\r\n        aligned: 'equation'\r\n      }[expr.text] ?? 'left'\r\n\r\n    const hasLp = !!m2s[expr.text]\r\n    const hasRp = !!m2s[expr.text] && m2s[expr.text].length > 1\r\n\r\n    align(expr.chld, alt)\r\n    const bb = computeBbox(expr.chld)\r\n    if (expr.text == '\\\\text') {\r\n      bb.x -= 1\r\n      bb.w += 2\r\n    }\r\n\r\n    for (let i = 0; i < expr.chld.length; i++) {\r\n      // @ts-ignore\r\n      transform(expr.chld[i], 1, null, -bb.x + (hasLp ? 1.5 : 0), -bb.y)\r\n    }\r\n    expr.bbox = {\r\n      x: 0,\r\n      y: 0,\r\n      w: bb.w + 1.5 * Number(hasLp) + 1.5 * Number(hasRp),\r\n      h: bb.h\r\n    }\r\n\r\n    if (hasLp) {\r\n      expr.chld.unshift({\r\n        type: 'symb',\r\n        text: m2s[expr.text][0],\r\n        mode: expr.mode,\r\n        chld: [],\r\n        bbox: { x: 0, y: 0, w: 1, h: bb.h }\r\n      })\r\n    }\r\n    if (hasRp) {\r\n      expr.chld.push({\r\n        type: 'symb',\r\n        text: m2s[expr.text][1],\r\n        mode: expr.mode,\r\n        chld: [],\r\n        bbox: { x: bb.w + 2, y: 0, w: 1, h: bb.h }\r\n      })\r\n    }\r\n    if (hasLp || hasRp || expr.text == 'matrix') {\r\n      expr.type = 'node'\r\n      expr.text = ''\r\n      expr.bbox.y -= (expr.bbox.h - 2) / 2\r\n    }\r\n  }\r\n}\r\n\r\n/**\r\n * 将表达式树扁平化为符号列表，提取分数线、根号等装饰符号\r\n * @param expr 表达式\r\n */\r\nfunction flatten(expr: Expr) {\r\n  /**\r\n   * 递归扁平化子节点\r\n   * @param expr 当前表达式\r\n   * @param dx X 累计偏移\r\n   * @param dy Y 累计偏移\r\n   * @returns 扁平化后的符号表达式数组\r\n   */\r\n  function flat(expr: Expr, dx: number, dy: number): Expr[] {\r\n    const ff: Expr[] = []\r\n    if (expr.bbox) {\r\n      dx += expr.bbox.x\r\n      dy += expr.bbox.y\r\n      if (expr.text == '\\\\frac') {\r\n        const h: number =\r\n          expr.chld[1].bbox.y - (expr.chld[0].bbox.y + expr.chld[0].bbox.h)\r\n        const e: Expr = {\r\n          type: 'symb',\r\n          mode: expr.mode,\r\n          text: '\\\\bar',\r\n          bbox: {\r\n            x: dx,\r\n            y: dy + (expr.chld[1].bbox.y - h / 2) - h / 2,\r\n            w: expr.bbox.w,\r\n            h: h\r\n          },\r\n          chld: []\r\n        }\r\n        ff.push(e)\r\n      } else if (expr.text == '\\\\sqrt') {\r\n        const h: number = expr.chld[0].bbox.y\r\n        const xx: number = Math.max(\r\n          0,\r\n          expr.chld[0].bbox.x - expr.chld[0].bbox.h / 2\r\n        )\r\n        const e: Expr = {\r\n          type: 'symb',\r\n          mode: expr.mode,\r\n          text: '\\\\sqrt',\r\n          bbox: {\r\n            x: dx + xx,\r\n            y: dy + h / 2,\r\n            w: expr.chld[0].bbox.x - xx,\r\n            h: expr.bbox.h - h / 2\r\n          },\r\n          chld: []\r\n        }\r\n        ff.push(e)\r\n        ff.push({\r\n          type: 'symb',\r\n          text: '\\\\bar',\r\n          mode: expr.mode,\r\n          bbox: {\r\n            x: dx + expr.chld[0].bbox.x,\r\n            y: dy,\r\n            w: expr.bbox.w - expr.chld[0].bbox.x,\r\n            h: h\r\n          },\r\n          chld: []\r\n        })\r\n      } else if (expr.text == '\\\\binom') {\r\n        const w = Math.min(expr.chld[0].bbox.x, expr.chld[1].bbox.x)\r\n        const e: Expr = {\r\n          type: 'symb',\r\n          mode: expr.mode,\r\n          text: '(',\r\n          bbox: {\r\n            x: dx,\r\n            y: dy,\r\n            w: w,\r\n            h: expr.bbox.h\r\n          },\r\n          chld: []\r\n        }\r\n        ff.push(e)\r\n        ff.push({\r\n          type: 'symb',\r\n          text: ')',\r\n          mode: expr.mode,\r\n          bbox: {\r\n            x: dx + expr.bbox.w - w,\r\n            y: dy,\r\n            w: w,\r\n            h: expr.bbox.h\r\n          },\r\n          chld: []\r\n        })\r\n      } else if (SYMB[expr.text] && SYMB[expr.text].flags.hat) {\r\n        const h: number = expr.chld[0].bbox.y\r\n        const e: Expr = {\r\n          type: 'symb',\r\n          mode: expr.mode,\r\n          text: expr.text,\r\n          bbox: {\r\n            x: dx,\r\n            y: dy,\r\n            w: expr.bbox.w,\r\n            h: h\r\n          },\r\n          chld: []\r\n        }\r\n        ff.push(e)\r\n      } else if (SYMB[expr.text] && SYMB[expr.text].flags.mat) {\r\n        const h: number = expr.chld[0].bbox.h\r\n        const e: Expr = {\r\n          type: 'symb',\r\n          text: expr.text,\r\n          mode: expr.mode,\r\n          bbox: {\r\n            x: dx,\r\n            y: dy + h,\r\n            w: expr.bbox.w,\r\n            h: expr.bbox.h - h\r\n          },\r\n          chld: []\r\n        }\r\n        ff.push(e)\r\n      } else if (expr.type != 'node' && expr.text != '^' && expr.text != '_') {\r\n        const e: Expr = {\r\n          type: expr.type == 'func' ? 'symb' : expr.type,\r\n          text: expr.text,\r\n          mode: expr.mode,\r\n          bbox: {\r\n            x: dx,\r\n            y: dy,\r\n            w: expr.bbox.w,\r\n            h: expr.bbox.h\r\n          },\r\n          chld: []\r\n        }\r\n        ff.push(e)\r\n      }\r\n    }\r\n    for (let i = 0; i < expr.chld.length; i++) {\r\n      const f = flat(expr.chld[i], dx, dy)\r\n      ff.push(...f)\r\n    }\r\n    return ff\r\n  }\r\n  const f = flat(expr, -expr.bbox.x, -expr.bbox.y)\r\n  expr.type = 'node'\r\n  expr.text = ''\r\n  expr.chld = f\r\n}\r\n\r\n/**\r\n * 将扁平化后的表达式渲染为多段折线（用于 SVG/Canvas/PDF 输出）\r\n * @param expr 表达式\r\n * @returns 折线坐标数组\r\n */\r\nfunction render(expr: Expr): number[][][] {\r\n  const o: number[][][] = []\r\n  for (let i = 0; i < expr.chld.length; i++) {\r\n    const e: Expr = expr.chld[i]\r\n    let s = e.bbox.h / 2\r\n    let isSmallHat = false\r\n    if (\r\n      SYMB[e.text] &&\r\n      SYMB[e.text].flags.hat &&\r\n      !SYMB[e.text].flags.xfl &&\r\n      !SYMB[e.text].flags.yfl\r\n    ) {\r\n      s *= 4\r\n      isSmallHat = true\r\n    }\r\n    if (SYMB[e.text] && SYMB[e.text].glyph) {\r\n      const d = HERSHEY(SYMB[e.text].glyph)\r\n      for (let j = 0; j < d.polylines.length; j++) {\r\n        const l: number[][] = []\r\n\r\n        for (let k = 0; k < d.polylines[j].length; k++) {\r\n          let x = d.polylines[j][k][0]\r\n          let y = d.polylines[j][k][1]\r\n\r\n          if (SYMB[e.text].flags.xfl) {\r\n            x = ((x - d.xmin) / Math.max(d.xmax - d.xmin, 1)) * e.bbox.w\r\n            x += e.bbox.x\r\n          } else if ((d.w / 16) * s > e.bbox.w) {\r\n            x = (x / Math.max(d.w, 1)) * e.bbox.w\r\n            x += e.bbox.x\r\n          } else {\r\n            x = (x / 16) * s\r\n            const p = (e.bbox.w - (d.w / 16) * s) / 2\r\n            x += e.bbox.x + p\r\n          }\r\n          if (SYMB[e.text].flags.yfl) {\r\n            y = ((y - d.ymin) / Math.max(d.ymax - d.ymin, 1)) * e.bbox.h\r\n            y += e.bbox.y\r\n          } else {\r\n            y = (y / 16) * s\r\n            if (isSmallHat) {\r\n              const p = (d.ymax + d.ymin) / 2\r\n              y -= (p / 16) * s\r\n            }\r\n            y += e.bbox.y + e.bbox.h / 2\r\n          }\r\n          l.push([x, y])\r\n        }\r\n        o.push(l)\r\n      }\r\n    } else if ((SYMB[e.text] && SYMB[e.text].flags.txt) || e.type == 'char') {\r\n      let x0 = e.bbox.x\r\n      const isVerb = !!(SYMB[e.text] && SYMB[e.text].flags.txt)\r\n      for (let n = Number(isVerb); n < e.text.length; n++) {\r\n        const d = HERSHEY(asciiMap(e.text[n], isVerb ? 'text' : e.mode))\r\n        if (!d) {\r\n          console.warn('unmapped character: ' + e.text[n])\r\n          continue\r\n        }\r\n        for (let j = 0; j < d.polylines.length; j++) {\r\n          const l: number[][] = []\r\n          for (let k = 0; k < d.polylines[j].length; k++) {\r\n            let x = d.polylines[j][k][0]\r\n            let y = d.polylines[j][k][1]\r\n            x /= 16\r\n            y /= 16\r\n            x *= s\r\n            y *= s\r\n            if (e.mode == 'tt') {\r\n              if (d.w > 16) {\r\n                x *= 16 / d.w\r\n              } else {\r\n                x += (16 - d.w) / 2 / 16\r\n              }\r\n            }\r\n            x += x0\r\n            y += e.bbox.y + e.bbox.h / 2\r\n            l.push([x, y])\r\n          }\r\n          o.push(l)\r\n        }\r\n        if (e.mode == 'tt') {\r\n          x0 += s\r\n        } else {\r\n          x0 += (d.w / 16) * s\r\n        }\r\n      }\r\n    }\r\n  }\r\n  return o\r\n}\r\n\r\n/** LaTeX 导出选项 */\r\ninterface ExportOpt {\r\n  /** 最小字符高度 */\r\n  MIN_CHAR_H?: number\r\n  /** 最大宽度 */\r\n  MAX_W?: number\r\n  /** 最大高度 */\r\n  MAX_H?: number\r\n  /** X 方向边距 */\r\n  MARGIN_X?: number\r\n  /** Y 方向边距 */\r\n  MARGIN_Y?: number\r\n  /** X 缩放 */\r\n  SCALE_X?: number\r\n  /** Y 缩放 */\r\n  SCALE_Y?: number\r\n  /** 描边宽度 */\r\n  STROKE_W?: number\r\n  /** 前景颜色 */\r\n  FG_COLOR?: string\r\n  /** 背景颜色 */\r\n  BG_COLOR?: string\r\n}\r\n\r\n/**\r\n * 将数值保留两位小数\r\n * @param x 待处理数值\r\n * @returns 处理后的数值\r\n */\r\nfunction nf(x: number): number {\r\n  return Math.round(x * 100) / 100\r\n}\r\n\r\n/** LaTeX 转 SVG 结果 */\r\nexport interface LaTexSVG {\r\n  /** SVG data URL */\r\n  svg: string\r\n  /** 宽度 */\r\n  width: number\r\n  /** 高度 */\r\n  height: number\r\n}\r\n\r\n/** LaTeX 工具类，提供从 LaTeX 字符串到 SVG/PDF/折线的转换能力 */\r\nexport class LaTexUtils {\r\n  /** 原始 LaTeX 字符串 */\r\n  _latex: string\r\n  /** 解析后的表达式树 */\r\n  _tree: Expr\r\n  /** token 数组 */\r\n  _tokens: string[]\r\n  /** 渲染后的折线 */\r\n  _polylines: number[][][]\r\n\r\n  /**\r\n   * 创建 LaTeX 工具实例并完成解析与排版\r\n   * @param latex LaTeX 字符串\r\n   */\r\n  constructor(latex: string) {\r\n    this._latex = latex\r\n    this._tokens = tokenize(latex)\r\n    this._tree = parse(this._tokens)\r\n    environments(this._tree.chld)\r\n    plan(this._tree)\r\n    flatten(this._tree)\r\n    this._polylines = render(this._tree)\r\n  }\r\n\r\n  /**\r\n   * 根据导出选项解析缩放与边距\r\n   * @param opt 导出选项\r\n   * @returns [px, py, sclx, scly]\r\n   */\r\n  private resolveScale(opt?: ExportOpt): number[] {\r\n    if (opt == undefined) {\r\n      return [16, 16, 16, 16]\r\n    }\r\n    let sclx: number = opt.SCALE_X ?? 16\r\n    let scly: number = opt.SCALE_Y ?? 16\r\n\r\n    if (opt.MIN_CHAR_H != undefined) {\r\n      let mh = 0\r\n      for (let i = 0; i < this._tree.chld.length; i++) {\r\n        const c: Expr = this._tree.chld[i]\r\n        if (\r\n          c.type == 'char' ||\r\n          (SYMB[c.text] &&\r\n            (SYMB[c.text].flags.txt || !Object.keys(SYMB[c.text].flags).length))\r\n        ) {\r\n          mh = Math.min(c.bbox.h, mh)\r\n        }\r\n      }\r\n      const s: number = Math.max(1, opt.MIN_CHAR_H / mh)\r\n      sclx *= s\r\n      scly *= s\r\n    }\r\n    if (opt.MAX_W != undefined) {\r\n      const s0 = sclx\r\n      sclx = Math.min(sclx, opt.MAX_W / this._tree.bbox.w)\r\n      scly *= sclx / s0\r\n    }\r\n    if (opt.MAX_H != undefined) {\r\n      const s0 = scly\r\n      scly = Math.min(scly, opt.MAX_H / this._tree.bbox.h)\r\n      sclx *= scly / s0\r\n    }\r\n    const px: number = opt.MARGIN_X ?? sclx\r\n    const py: number = opt.MARGIN_Y ?? scly\r\n    return [px, py, sclx, scly]\r\n  }\r\n\r\n  /**\r\n   * 输出折线坐标，应用缩放与边距\r\n   * @param opt 导出选项\r\n   * @returns 折线坐标数组\r\n   */\r\n  polylines(opt?: ExportOpt): number[][][] {\r\n    if (!opt) opt = {}\r\n    const polylines: number[][][] = []\r\n    const [px, py, sclx, scly] = this.resolveScale(opt)\r\n    for (let i = 0; i < this._polylines.length; i++) {\r\n      polylines.push([])\r\n      for (let j = 0; j < this._polylines[i].length; j++) {\r\n        const [x, y] = this._polylines[i][j]\r\n        polylines[polylines.length - 1].push([px + x * sclx, py + y * scly])\r\n      }\r\n    }\r\n    return polylines\r\n  }\r\n\r\n  /**\r\n   * 输出 SVG path 的 d 属性字符串\r\n   * @param opt 导出选项\r\n   * @returns path d 字符串\r\n   */\r\n  pathd(opt?: ExportOpt): string {\r\n    if (!opt) opt = {}\r\n    let d = ''\r\n    const [px, py, sclx, scly] = this.resolveScale(opt)\r\n    for (let i = 0; i < this._polylines.length; i++) {\r\n      for (let j = 0; j < this._polylines[i].length; j++) {\r\n        const [x, y] = this._polylines[i][j]\r\n        d += !j ? 'M' : 'L'\r\n        d += `${nf(px + x * sclx)} ${nf(py + y * scly)}`\r\n      }\r\n    }\r\n    return d\r\n  }\r\n\r\n  /**\r\n   * 生成 SVG data URL\r\n   * @param opt 导出选项\r\n   * @returns SVG 结果\r\n   */\r\n  svg(opt: ExportOpt): LaTexSVG {\r\n    if (!opt) opt = {}\r\n    const [px, py, sclx, scly] = this.resolveScale(opt)\r\n    const w = nf(this._tree.bbox.w * sclx + px * 2)\r\n    const h = nf(this._tree.bbox.h * scly + py * 2)\r\n    let o = `<svg\r\n      xmlns=\"http://www.w3.org/2000/svg\"\r\n      width=\"${w}\" height=\"${h}\"\r\n      fill=\"none\" stroke=\"${opt.FG_COLOR ?? 'black'}\" stroke-width=\"${\r\n      opt.STROKE_W ?? 1\r\n    }\"\r\n      stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n    >`\r\n    if (opt.BG_COLOR) {\r\n      o += `<rect x=\"${0}\" y=\"${0}\" width=\"${w}\" height=\"${h}\" fill=\"${\r\n        opt.BG_COLOR\r\n      }\" stroke=\"none\"></rect>`\r\n    }\r\n    o += `<path d=\"`\r\n    for (let i = 0; i < this._polylines.length; i++) {\r\n      o += 'M'\r\n      for (let j = 0; j < this._polylines[i].length; j++) {\r\n        const [x, y] = this._polylines[i][j]\r\n        o += nf(px + x * sclx) + ' ' + nf(py + y * scly) + ' '\r\n      }\r\n    }\r\n    o += `\"/>`\r\n    o += `</svg>`\r\n    return {\r\n      svg: `data:image/svg+xml;base64,${window.btoa(o)}`,\r\n      width: Math.ceil(w),\r\n      height: Math.ceil(h)\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 生成 PDF 字符串\r\n   * @param opt 导出选项\r\n   * @returns PDF 字符串\r\n   */\r\n  pdf(opt: ExportOpt): string {\r\n    if (!opt) opt = {}\r\n    const [px, py, sclx, scly] = this.resolveScale(opt)\r\n\r\n    const width = nf(this._tree.bbox.w * sclx + px * 2)\r\n    const height = nf(this._tree.bbox.h * scly + py * 2)\r\n    let head = `%PDF-1.1\\n%%¥±ë\\n1 0 obj\\n<< /Type /Catalog\\n/Pages 2 0 R\\n>>endobj\r\n    2 0 obj\\n<< /Type /Pages\\n/Kids [3 0 R]\\n/Count 1\\n/MediaBox [0 0 ${width} ${height}]\\n>>\\nendobj\r\n    3 0 obj\\n<< /Type /Page\\n/Parent 2 0 R\\n/Resources\\n<< /Font\\n<< /F1\\n<< /Type /Font\r\n    /Subtype /Type1\\n/BaseFont /Times-Roman\\n>>\\n>>\\n>>\\n/Contents [`\r\n    let pdf = ''\r\n    let count = 4\r\n    for (let i = 0; i < this._polylines.length; i++) {\r\n      pdf += `${count} 0 obj \\n<< /Length 0 >>\\n stream\\n 1 j 1 J ${\r\n        opt.STROKE_W ?? 1\r\n      } w\\n`\r\n      for (let j = 0; j < this._polylines[i].length; j++) {\r\n        const [x, y] = this._polylines[i][j]\r\n        pdf += `${nf(px + x * sclx)} ${nf(height - (py + y * scly))} ${\r\n          j ? 'l' : 'm'\r\n        } `\r\n      }\r\n      pdf += '\\nS\\nendstream\\nendobj\\n'\r\n      head += `${count} 0 R `\r\n      count++\r\n    }\r\n    head += ']\\n>>\\nendobj\\n'\r\n    pdf += '\\ntrailer\\n<< /Root 1 0 R \\n /Size 0\\n >>startxref\\n\\n%%EOF\\n'\r\n    return head + pdf\r\n  }\r\n\r\n  /**\r\n   * 返回各子节点的包围盒\r\n   * @param opt 导出选项\r\n   * @returns 包围盒数组\r\n   */\r\n  boxes(opt: ExportOpt): Bbox[] {\r\n    if (!opt) opt = {}\r\n    const [px, py, sclx, scly] = this.resolveScale(opt)\r\n    const bs: Bbox[] = []\r\n    for (let i = 0; i < this._tree.chld.length; i++) {\r\n      const { x, y, w, h } = this._tree.chld[i].bbox\r\n      bs.push({ x: px + x * sclx, y: py + y * scly, w: w * sclx, h: h * scly })\r\n    }\r\n    return bs\r\n  }\r\n\r\n  /**\r\n   * 返回整体包围盒\r\n   * @param opt 导出选项\r\n   * @returns 包围盒\r\n   */\r\n  box(opt: ExportOpt): Bbox {\r\n    if (!opt) opt = {}\r\n    const [px, py, sclx, scly] = this.resolveScale(opt)\r\n    return {\r\n      x: px + this._tree.bbox.x * sclx,\r\n      y: py + this._tree.bbox.y * scly,\r\n      w: this._tree.bbox.w * sclx,\r\n      h: this._tree.bbox.h * scly\r\n    }\r\n  }\r\n}\r\n\r\n/** 内部实现集合，便于外部测试或调试 */\r\nconst _impl: Record<string, Function> = {\r\n  tokenize,\r\n  parse,\r\n  environments,\r\n  plan,\r\n  flatten,\r\n  render\r\n}\r\n\r\nexport { CONFIG, _impl }\r\n","import type { IElement } from '@vervedoc/docx-editor-schema'\r\nimport type { Draw } from '@vervedoc/docx-editor-view'\r\nimport type { ILatexElement } from './constants'\r\nimport { LaTexSVG, LaTexUtils } from './latex-utils'\r\n\r\n/** 默认缩放比例 */\r\nconst DEFAULT_SCALE = 1\r\n\r\n/** LaTeX 粒子渲染器，将 LaTeX 元素以 SVG 图片形式绘制到 canvas */\r\nexport class LaTexParticle {\r\n  /** 编辑器绘制实例 */\r\n  private draw: Draw\r\n  /** 已加载图片缓存，避免重复加载 */\r\n  private imageCache: Map<string, HTMLImageElement> = new Map()\r\n  /** 正在加载的图片 Promise 集合 */\r\n  private pendingImages: Set<Promise<unknown>> = new Set()\r\n\r\n  /**\r\n   * 创建 LaTeX 粒子渲染器\r\n   * @param draw 编辑器绘制实例\r\n   */\r\n  constructor(draw: Draw) {\r\n    this.draw = draw\r\n  }\r\n\r\n  /**\r\n   * 将 LaTeX 字符串转换为 SVG\r\n   * @param laTex LaTeX 字符串\r\n   * @returns SVG 结果\r\n   */\r\n  public static convertLaTextToSVG(laTex: string): LaTexSVG {\r\n    return new LaTexUtils(laTex).svg({\r\n      SCALE_X: 10,\r\n      SCALE_Y: 10,\r\n      MARGIN_X: 0,\r\n      MARGIN_Y: 0\r\n    })\r\n  }\r\n\r\n  /**\r\n   * 在 canvas 上渲染 LaTeX 元素\r\n   * @param ctx canvas 上下文\r\n   * @param element 元素\r\n   * @param x X 坐标\r\n   * @param y Y 坐标\r\n   */\r\n  public render(\r\n    ctx: CanvasRenderingContext2D,\r\n    element: IElement,\r\n    x: number,\r\n    y: number\r\n  ): void {\r\n    const { scale = DEFAULT_SCALE } = this.draw.getOptions() as { scale?: number }\r\n    const el = element as unknown as ILatexElement\r\n    const width = el.width * scale\r\n    const height = el.height * scale\r\n    if (this.imageCache.has(element.value)) {\r\n      const img = this.imageCache.get(element.value)!\r\n      ctx.drawImage(img, x, y, width, height)\r\n      return\r\n    }\r\n    const promise = new Promise<void>((resolve, reject) => {\r\n      const img = new Image()\r\n      img.src = el.laTexSVG\r\n      img.onload = () => {\r\n        ctx.drawImage(img, x, y, width, height)\r\n        this.imageCache.set(element.value, img)\r\n        resolve()\r\n      }\r\n      img.onerror = reject\r\n    })\r\n    this.pendingImages.add(promise)\r\n    promise.finally(() => this.pendingImages.delete(promise))\r\n  }\r\n\r\n  /**\r\n   * 等待所有正在加载的 LaTeX 图片完成\r\n   * @returns Promise\r\n   */\r\n  public awaitImages(): Promise<void> {\r\n    return Promise.all(this.pendingImages).then(() => undefined)\r\n  }\r\n\r\n  /** 销毁渲染器，清空缓存 */\r\n  public destroy(): void {\r\n    this.imageCache.clear()\r\n    this.pendingImages.clear()\r\n  }\r\n}\r\n","import type { IElement, IEditorOption, Path, ISearchResult, IReplaceOption, INavigateInfo } from '@vervedoc/docx-editor-schema'\r\nimport { walkTree, getByPath } from '@vervedoc/docx-editor-schema'\r\nimport type { RangeManager } from '@vervedoc/docx-editor-state'\r\nimport type { Draw } from '@vervedoc/docx-editor-view'\r\nimport { TEXTLIKE_ELEMENT_TYPE } from './constants'\r\n\r\n// 重新导出迁移至 schema 的跨包共享类型，保持 commands 包 API 兼容\r\nexport type { ISearchResult, IReplaceOption, INavigateInfo } from '@vervedoc/docx-editor-schema'\r\n\r\n/**\r\n * 生成简易唯一 ID\r\n * @returns 唯一 ID 字符串\r\n */\r\nfunction getUUID(): string {\r\n  return `s-${Math.random().toString(36).slice(2)}-${Date.now().toString(36)}`\r\n}\r\n\r\n/**\r\n * 判断值是否为数字\r\n * @param v 待判断值\r\n * @returns 是否为数字\r\n */\r\nfunction isNumber(v: unknown): v is number {\r\n  return typeof v === 'number'\r\n}\r\n\r\n/**\r\n * 文本类元素判定（可参与搜索）\r\n * @param el 元素\r\n * @returns 是否可搜索\r\n */\r\nfunction isSearchable(el: IElement): boolean {\r\n  return TEXTLIKE_ELEMENT_TYPE.has(el.type) && !!el.value\r\n}\r\n\r\n/** 搜索管理器，提供关键字搜索、高亮、导航与替换能力 */\r\nexport class Search {\r\n  /** 编辑器绘制实例 */\r\n  private draw: Draw\r\n  /** 编辑器选项 */\r\n  private options: IEditorOption\r\n  /** 选区管理器 */\r\n  private range: RangeManager | null\r\n  /** 当前搜索关键字 */\r\n  private searchKeyword: string | null\r\n  /** 当前导航索引 */\r\n  private searchNavigateIndex: number | null\r\n  /** 匹配结果列表 */\r\n  private searchMatchList: ISearchResult[]\r\n\r\n  /**\r\n   * 创建搜索管理器\r\n   * @param draw 编辑器绘制实例\r\n   */\r\n  constructor(draw: Draw) {\r\n    this.draw = draw\r\n    this.options = draw.getOptions()\r\n    this.range = draw.getRange()\r\n    this.searchNavigateIndex = null\r\n    this.searchKeyword = null\r\n    this.searchMatchList = []\r\n  }\r\n\r\n  /**\r\n   * 获取当前搜索关键字\r\n   * @returns 关键字或 null\r\n   */\r\n  public getSearchKeyword(): string | null {\r\n    return this.searchKeyword\r\n  }\r\n\r\n  /**\r\n   * 设置搜索关键字并重置导航索引\r\n   * @param payload 关键字\r\n   */\r\n  public setSearchKeyword(payload: string | null) {\r\n    this.searchKeyword = payload\r\n    this.searchNavigateIndex = null\r\n  }\r\n\r\n  /**\r\n   * 上一个匹配\r\n   * @returns 当前导航索引或 null\r\n   */\r\n  public searchNavigatePre(): number | null {\r\n    if (!this.searchMatchList.length || !this.searchKeyword) return null\r\n    if (this.searchNavigateIndex === null) {\r\n      this.searchNavigateIndex = 0\r\n    } else {\r\n      this.searchNavigateIndex = Math.max(0, this.searchNavigateIndex - 1)\r\n    }\r\n    this._applyNavigate()\r\n    return this.searchNavigateIndex\r\n  }\r\n\r\n  /**\r\n   * 下一个匹配\r\n   * @returns 当前导航索引或 null\r\n   */\r\n  public searchNavigateNext(): number | null {\r\n    if (!this.searchMatchList.length || !this.searchKeyword) return null\r\n    if (this.searchNavigateIndex === null) {\r\n      this.searchNavigateIndex = 0\r\n    } else {\r\n      this.searchNavigateIndex = Math.min(\r\n        this.searchMatchList.length - 1,\r\n        this.searchNavigateIndex + 1\r\n      )\r\n    }\r\n    this._applyNavigate()\r\n    return this.searchNavigateIndex\r\n  }\r\n\r\n  /**\r\n   * 将当前导航匹配定位到光标\r\n   */\r\n  private _applyNavigate(): void {\r\n    if (this.searchNavigateIndex === null) return\r\n    const match = this.searchMatchList[this.searchNavigateIndex]\r\n    if (!match || !this.range) return\r\n    this.range.setCaret({ path: match.path.slice() as Path, offset: match.offset })\r\n  }\r\n\r\n  /**\r\n   * 获取当前导航索引列表（用于高亮判定）\r\n   * @returns 导航索引数组\r\n   */\r\n  public getSearchNavigateIndexList(): number[] {\r\n    if (this.searchNavigateIndex === null || !this.searchKeyword) return []\r\n    return [this.searchNavigateIndex]\r\n  }\r\n\r\n  /**\r\n   * 获取搜索匹配结果列表\r\n   * @returns 匹配结果数组\r\n   */\r\n  public getSearchMatchList(): ISearchResult[] {\r\n    return this.searchMatchList\r\n  }\r\n\r\n  /**\r\n   * 获取搜索导航信息\r\n   * @returns 导航信息或 null\r\n   */\r\n  public getSearchNavigateInfo(): null | INavigateInfo {\r\n    if (!this.searchKeyword || !this.searchMatchList.length) return null\r\n    const index = this.searchNavigateIndex !== null ? this.searchNavigateIndex + 1 : 0\r\n    return {\r\n      index,\r\n      count: this.searchMatchList.length\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 在元素列表中搜索关键字，返回匹配列表。\r\n   * 基于 walkTree 遍历，在每个文本元素的 value 内进行匹配。\r\n   * @param payload 搜索关键字\r\n   * @param elementList 元素列表\r\n   * @returns 匹配结果数组\r\n   */\r\n  public getSearchMatchListByKeyword(\r\n    payload: string,\r\n    elementList: IElement[]\r\n  ): ISearchResult[] {\r\n    if (!payload) return []\r\n    const keyword = payload.toLocaleLowerCase()\r\n    const matchList: ISearchResult[] = []\r\n\r\n    walkTree(elementList, (node, ctx) => {\r\n      if (!isSearchable(node)) return\r\n      const text = node.value.toLocaleLowerCase()\r\n      let pos = text.indexOf(keyword)\r\n      while (pos !== -1) {\r\n        matchList.push({\r\n          path: ctx.path.slice() as Path,\r\n          offset: pos,\r\n          length: payload.length,\r\n          groupId: getUUID()\r\n        })\r\n        pos = text.indexOf(keyword, pos + keyword.length)\r\n      }\r\n    })\r\n\r\n    return matchList\r\n  }\r\n\r\n  /**\r\n   * 计算并缓存搜索匹配\r\n   * @param payload 搜索关键字\r\n   */\r\n  public computeSearchMatches(payload: string) {\r\n    this.searchMatchList = this.getSearchMatchListByKeyword(\r\n      payload,\r\n      this.draw.getElementList()\r\n    )\r\n  }\r\n\r\n  /**\r\n   * 绘制搜索高亮：从 verve layout 查找匹配元素的 inline 坐标。\r\n   * @param ctx canvas 上下文\r\n   * @param pageIndex 页码\r\n   */\r\n  public renderSearchHighlights(ctx: CanvasRenderingContext2D, pageIndex: number) {\r\n    if (!this.searchMatchList.length || !this.searchKeyword) return\r\n    const layout = (this.draw as any).getLayout?.()\r\n    if (!layout) return\r\n\r\n    const opts = this.options as any\r\n    const alpha = opts.searchMatchAlpha ?? 0.3\r\n    const matchColor = opts.searchMatchColor ?? '#ffe58f'\r\n    const navigateColor = opts.searchNavigateMatchColor ?? '#ff9c6e'\r\n    const navigateIndexList = this.getSearchNavigateIndexList()\r\n\r\n    ctx.save()\r\n    ctx.globalAlpha = alpha\r\n    for (let s = 0; s < this.searchMatchList.length; s++) {\r\n      const match = this.searchMatchList[s]\r\n      const rect = this._findMatchRect(layout, match)\r\n      if (!rect) continue\r\n      if (rect.pageNo !== pageIndex) continue\r\n      ctx.fillStyle = navigateIndexList.includes(s) ? navigateColor : matchColor\r\n      ctx.fillRect(rect.x, rect.y, rect.width, rect.height)\r\n    }\r\n    ctx.restore()\r\n  }\r\n\r\n  /**\r\n   * 在 layout 中查找匹配对应的矩形坐标\r\n   * @param layout 布局对象\r\n   * @param match 匹配结果\r\n   * @returns 矩形坐标或 null\r\n   */\r\n  private _findMatchRect(\r\n    layout: any,\r\n    match: ISearchResult\r\n  ): { x: number; y: number; width: number; height: number; pageNo: number } | null {\r\n    for (let p = 0; p < layout.pages.length; p++) {\r\n      const page = layout.pages[p]\r\n      const found = this._findInBlocks(page.blocks, page.contentRect.x, page.contentRect.y, p, match)\r\n      if (found) return found\r\n    }\r\n    return null\r\n  }\r\n\r\n  /**\r\n   * 在指定页块的子块中查找匹配矩形\r\n   * @param blocks 块列表\r\n   * @param originX 起始 X 偏移\r\n   * @param originY 起始 Y 偏移\r\n   * @param pageNo 页码\r\n   * @param match 匹配结果\r\n   * @returns 矩形坐标或 null\r\n   */\r\n  private _findInBlocks(\r\n    blocks: any[],\r\n    originX: number,\r\n    originY: number,\r\n    pageNo: number,\r\n    match: ISearchResult\r\n  ): { x: number; y: number; width: number; height: number; pageNo: number } | null {\r\n    for (const b of blocks) {\r\n      if (b.kind === 'table') {\r\n        for (const row of b.rows) {\r\n          for (const cell of row.cells) {\r\n            const cx = originX + b.rect.x + cell.rect.x + cell.contentPaddingLeft\r\n            const cy = originY + b.rect.y + cell.rect.y + cell.contentPaddingTop + cell.verticalOffset\r\n            const found = this._findInBlocks(cell.content, cx, cy, pageNo, match)\r\n            if (found) return found\r\n          }\r\n        }\r\n        continue\r\n      }\r\n      if (b.kind !== 'paragraph') continue\r\n      const bx = originX + b.rect.x\r\n      const by = originY + b.rect.y\r\n      for (const line of b.lines) {\r\n        for (const inl of line.inlines) {\r\n          // 通过 inline 的 path 匹配\r\n          if (this._pathMatchesInline(inl, match)) {\r\n            return {\r\n              x: bx + inl.x,\r\n              y: by + line.y,\r\n              width: inl.width,\r\n              height: line.height,\r\n              pageNo\r\n            }\r\n          }\r\n        }\r\n      }\r\n    }\r\n    return null\r\n  }\r\n\r\n  /**\r\n   * 判断 inline 是否属于匹配的元素\r\n   * @param inl inline 对象\r\n   * @param match 匹配结果\r\n   * @returns 是否匹配\r\n   */\r\n  private _pathMatchesInline(inl: any, match: ISearchResult): boolean {\r\n    if (!inl.path) return false\r\n    const p = inl.path as Path\r\n    if (p.length !== match.path.length) return false\r\n    for (let i = 0; i < p.length; i++) {\r\n      if (p[i] !== match.path[i]) return false\r\n    }\r\n    return true\r\n  }\r\n\r\n  /** 滚动到当前导航匹配的可视范围 */\r\n  public searchNavigateScrollIntoView() {\r\n    if (this.searchNavigateIndex === null) return\r\n    const match = this.searchMatchList[this.searchNavigateIndex]\r\n    if (!match) return\r\n    const layout = (this.draw as any).getLayout?.()\r\n    if (!layout) return\r\n    const rect = this._findMatchRect(layout, match)\r\n    if (!rect) return\r\n    const container = this.draw.getContainer()\r\n    const anchor = document.createElement('div')\r\n    anchor.style.position = 'absolute'\r\n    anchor.style.width = `${rect.width + 50}px`\r\n    anchor.style.height = `${rect.height + 50}px`\r\n    anchor.style.left = `${rect.x}px`\r\n    anchor.style.top = `${rect.y}px`\r\n    container.append(anchor)\r\n    anchor.scrollIntoView(false)\r\n    anchor.remove()\r\n  }\r\n\r\n  /**\r\n   * 替换匹配的关键词。\r\n   * 基于 verve 树模型：直接修改元素的 value，再 setDocument 刷新。\r\n   * @param payload 替换文本\r\n   * @param option 替换选项\r\n   */\r\n  public replaceSearchMatch(payload: string, option?: IReplaceOption) {\r\n    const isReadonly = (this.draw as any).isReadonly?.()\r\n    if (isReadonly) return\r\n    if (!payload) return\r\n\r\n    let matchList = this.getSearchMatchList()\r\n    const replaceIndex = option?.index\r\n    if (isNumber(replaceIndex)) {\r\n      matchList = [matchList[replaceIndex]].filter(Boolean)\r\n    }\r\n    if (!matchList.length) return\r\n\r\n    const elementList = this.draw.getElementList()\r\n    const keyword = this.searchKeyword!\r\n    let firstMatch: ISearchResult | null = null\r\n\r\n    for (const match of matchList) {\r\n      const element = getByPath(elementList, match.path)\r\n      if (!element || !element.value) continue\r\n      // 在 value 中替换关键词\r\n      const before = element.value\r\n      element.value = before.slice(0, match.offset) + payload + before.slice(match.offset + keyword.length)\r\n      if (!firstMatch) firstMatch = match\r\n    }\r\n\r\n    if (!firstMatch) return\r\n    // 定位到首个替换位置\r\n    if (this.range) {\r\n      this.range.setCaret({\r\n        path: firstMatch.path.slice() as Path,\r\n        offset: firstMatch.offset + payload.length\r\n      })\r\n    }\r\n    // 重新渲染\r\n    this.draw.setDocument(this.draw.getDocument())\r\n    // 重新计算匹配\r\n    this.computeSearchMatches(keyword)\r\n  }\r\n}\r\n","import type { IBlockElement } from './constants'\r\n\r\n/** 允许作为 iframe src 的协议白名单 */\r\nconst ALLOWED_SRC_PROTOCOLS = ['https:', 'http:']\r\n\r\n/**\r\n * 判断给定 URL 是否使用了允许的协议\r\n * @param url 待校验 URL\r\n * @returns 是否允许加载\r\n */\r\nfunction isAllowedSrc(url: string): boolean {\r\n  try {\r\n    const { protocol } = new URL(url, location.href)\r\n    return ALLOWED_SRC_PROTOCOLS.includes(protocol)\r\n  } catch {\r\n    return false\r\n  }\r\n}\r\n\r\n/** iframe 块组件，用于在文档中嵌入外部页面 */\r\nexport class IFrameBlock {\r\n  /** iframe sandbox 允许的能力，仅允许脚本执行 */\r\n  public static readonly sandbox = ['allow-scripts']\r\n  /** 关联的块元素 */\r\n  private element: IBlockElement\r\n\r\n  /**\r\n   * 创建 iframe 块实例\r\n   * @param element 块元素\r\n   */\r\n  constructor(element: IBlockElement) {\r\n    this.element = element\r\n  }\r\n\r\n  /**\r\n   * 在 iframe 的 window 上定义隔离属性，阻断 parent/top 访问\r\n   * @param iframeWindow iframe 的 contentWindow\r\n   */\r\n  private _defineIframeProperties(iframeWindow: Window) {\r\n    try {\r\n      Object.defineProperties(iframeWindow, {\r\n        parent: { get: () => null },\r\n        top: { get: () => null },\r\n        __POWERED_BY_CANVAS_EDITOR__: { get: () => true }\r\n      })\r\n    } catch {}\r\n  }\r\n\r\n  /**\r\n   * 渲染 iframe 到指定容器\r\n   * @param blockItemContainer 块项容器\r\n   */\r\n  public render(blockItemContainer: HTMLDivElement) {\r\n    const iframeBlock = this.element.block?.iframeBlock\r\n    const iframe = document.createElement('iframe')\r\n    iframe.setAttribute('data-id', this.element.id ?? '')\r\n    iframe.sandbox.add(...IFrameBlock.sandbox)\r\n    iframe.style.border = 'none'\r\n    iframe.style.width = '100%'\r\n    iframe.style.height = '100%'\r\n    if (iframeBlock?.src) {\r\n      if (!isAllowedSrc(iframeBlock.src)) return\r\n      iframe.src = iframeBlock.src\r\n    } else if (iframeBlock?.srcdoc) {\r\n      iframe.srcdoc = iframeBlock.srcdoc\r\n    }\r\n    iframe.addEventListener('load', () => {\r\n      const contentWindow = iframe.contentWindow\r\n      if (contentWindow) {\r\n        this._defineIframeProperties(contentWindow)\r\n      }\r\n    })\r\n    blockItemContainer.append(iframe)\r\n  }\r\n}\r\n","import { EDITOR_PREFIX, BlockType } from './constants'\r\nimport type { IBlockElement } from './constants'\r\nimport type { IElement } from '@vervedoc/docx-editor-schema'\r\nimport { BlockParticle } from './block-particle'\r\nimport { IFrameBlock } from './block-iframe'\r\n\r\n/** 嵌入块基类，根据块类型分发到具体实现（iframe） */\r\nexport class BaseBlock {\r\n  /** 关联的块元素 */\r\n  private element: IElement\r\n  /** 具体块实现实例 */\r\n  private block: IFrameBlock | null\r\n  /** 块容器 */\r\n  private blockContainer: HTMLDivElement\r\n  /** 当前块项 DOM */\r\n  private blockItem: HTMLDivElement\r\n\r\n  constructor(blockParticle: BlockParticle, element: IElement) {\r\n    this.blockContainer = blockParticle.getBlockContainer()\r\n    this.element = element\r\n    this.block = null\r\n    this.blockItem = this._createBlockItem()\r\n    this.blockContainer.append(this.blockItem)\r\n  }\r\n\r\n  public getBlockElement(): IElement {\r\n    return this.element\r\n  }\r\n\r\n  private _createBlockItem(): HTMLDivElement {\r\n    const blockItem = document.createElement('div')\r\n    blockItem.classList.add(`${EDITOR_PREFIX}-block-item`)\r\n    return blockItem\r\n  }\r\n\r\n  public render() {\r\n    const el = this.element as IBlockElement\r\n    const block = el.block\r\n    if (!block) return\r\n    if (block.type === BlockType.IFRAME) {\r\n      this.block = new IFrameBlock(el)\r\n      this.block.render(this.blockItem)\r\n    }\r\n  }\r\n\r\n  public setClientRects(_pageNo: number, x: number, y: number) {\r\n    const metrics = (this.element as IBlockElement).metrics\r\n    if (metrics) {\r\n      this.blockItem.style.width = `${metrics.width}px`\r\n      this.blockItem.style.height = `${metrics.height}px`\r\n    }\r\n    this.blockItem.style.position = 'absolute'\r\n    this.blockItem.style.left = `${x}px`\r\n    this.blockItem.style.top = `${y}px`\r\n  }\r\n\r\n  public remove() {\r\n\r\n    this.blockItem.remove()\r\n  }\r\n}\r\n","import { EDITOR_PREFIX } from './constants'\r\n\r\nimport { walkTree } from '@vervedoc/docx-editor-schema'\r\nimport type { IElement } from '@vervedoc/docx-editor-schema'\r\nimport type { Draw } from '@vervedoc/docx-editor-view'\r\nimport { BaseBlock } from './block-base'\r\nimport './assets/css/block.css'\r\n\r\n/** 块粒子管理器，负责嵌入块元素的创建、缓存与清理 */\r\nexport class BlockParticle {\r\n  /** 编辑器绘制实例 */\r\n  private draw: Draw\r\n  /** 编辑器容器 */\r\n  private container: HTMLDivElement\r\n  /** 块容器 */\r\n  private blockContainer: HTMLDivElement\r\n  /** 块实例缓存，按元素 id 索引 */\r\n  private blockMap: Map<string, BaseBlock>\r\n\r\n  /**\r\n   * 创建块粒子管理器\r\n   * @param draw 编辑器绘制实例\r\n   */\r\n  constructor(draw: Draw) {\r\n    this.draw = draw\r\n    this.container = draw.getContainer()\r\n    this.blockMap = new Map()\r\n    this.blockContainer = this._createBlockContainer()\r\n    this.container.append(this.blockContainer)\r\n  }\r\n\r\n  /** 创建块容器 DOM 并设置基础样式 */\r\n  private _createBlockContainer(): HTMLDivElement {\r\n    const blockContainer = document.createElement('div')\r\n    blockContainer.classList.add(`${EDITOR_PREFIX}-block-container`)\r\n    blockContainer.style.position = 'absolute'\r\n    blockContainer.style.inset = '0'\r\n    blockContainer.style.pointerEvents = 'auto'\r\n    return blockContainer\r\n  }\r\n\r\n  /**\r\n   * 获取编辑器绘制实例\r\n   * @returns 绘制实例\r\n   */\r\n  public getDraw(): Draw {\r\n    return this.draw\r\n  }\r\n\r\n  /**\r\n   * 获取块容器\r\n   * @returns 块容器 DOM\r\n   */\r\n  public getBlockContainer(): HTMLDivElement {\r\n    return this.blockContainer\r\n  }\r\n\r\n  /**\r\n   * 渲染指定页的块元素，复用已存在实例\r\n   * @param pageNo 页码\r\n   * @param element 元素\r\n   * @param x X 坐标\r\n   * @param y Y 坐标\r\n   */\r\n  public render(pageNo: number, element: IElement, x: number, y: number) {\r\n    const id = (element as any).id\r\n    if (!id) return\r\n    const cacheBlock = this.blockMap.get(id)\r\n    if (cacheBlock) {\r\n      cacheBlock.setClientRects(pageNo, x, y)\r\n    } else {\r\n      const newBlock = new BaseBlock(this, element)\r\n      newBlock.render()\r\n      newBlock.setClientRects(pageNo, x, y)\r\n      this.blockMap.set(id, newBlock)\r\n    }\r\n  }\r\n\r\n  /** 清理已从文档中删除的块实例 */\r\n  public clear() {\r\n    if (!this.blockMap.size) return\r\n    const elementList = this.draw.getElementList()\r\n    const blockElementIds: string[] = []\r\n    walkTree(elementList, (node) => {\r\n      if (node.type === 'block') {\r\n        const id = (node as any).id\r\n        if (id) blockElementIds.push(id)\r\n      }\r\n    })\r\n    this.blockMap.forEach(block => {\r\n      const id = (block.getBlockElement() as any).id\r\n      if (id && !blockElementIds.includes(id)) {\r\n        block.remove()\r\n        this.blockMap.delete(id)\r\n      }\r\n    })\r\n  }\r\n\r\n  /** 销毁所有块实例并移除块容器 */\r\n  public destroy() {\r\n    this.blockMap.forEach(block => block.remove())\r\n    this.blockMap.clear()\r\n    this.blockContainer.remove()\r\n  }\r\n}\r\n","import type { IElement } from '@vervedoc/docx-editor-schema'\r\nimport { walkTree } from '@vervedoc/docx-editor-schema'\r\nimport type { Draw } from '@vervedoc/docx-editor-view'\r\nimport { EDITOR_PREFIX } from './constants'\r\n\r\n/**\r\n * 控件组件（checkbox / radio / text / select / date / number）挂载骨架。\r\n *\r\n * verve view 未提供 Control 系列类，此处提供统一挂载框架：\r\n * - install 时获取容器\r\n * - clear 在每帧渲染后清理已从文档中删除的控件 DOM\r\n * - render 在控件元素需要渲染时创建对应 DOM（具体控件 UI 待实现）\r\n */\r\nexport class ControlComponent {\r\n  private draw: Draw | null = null\r\n  private container: HTMLDivElement | null = null\r\n  private controlMap: Map<string, HTMLElement> = new Map()\r\n\r\n  public install(draw: Draw): this {\r\n    this.draw = draw\r\n    this.container = draw.getContainer()\r\n    this._createControlContainer()\r\n    return this\r\n  }\r\n\r\n  private _createControlContainer(): HTMLDivElement {\r\n    const controlContainer = document.createElement('div')\r\n    controlContainer.classList.add(`${EDITOR_PREFIX}-control-container`)\r\n    controlContainer.style.position = 'absolute'\r\n    controlContainer.style.inset = '0'\r\n    controlContainer.style.pointerEvents = 'auto'\r\n    this.container?.append(controlContainer)\r\n    return controlContainer\r\n  }\r\n\r\n  /**\r\n   * 渲染单个控件元素（具体控件 UI 待实现）。\r\n   * 由外部渲染流程在遇到 control 类型元素时调用。\r\n   */\r\n  public render(element: IElement, x: number, y: number): void {\r\n    if (!this.draw) return\r\n    const id = (element as { id?: string }).id\r\n    if (!id) return\r\n    // TODO: 根据 element.type（checkbox/radio/text/select/date/number）创建对应控件 DOM\r\n    void x\r\n    void y\r\n  }\r\n\r\n  /** 每帧渲染后清理已从文档中删除的控件 DOM */\r\n  public clear(): void {\r\n    if (!this.controlMap.size || !this.draw) return\r\n    const elementList = this.draw.getElementList()\r\n    const controlIds: string[] = []\r\n    walkTree(elementList, (node) => {\r\n      if (node.type === 'control') {\r\n        const id = (node as { id?: string }).id\r\n        if (id) controlIds.push(id)\r\n      }\r\n    })\r\n    this.controlMap.forEach((el, id) => {\r\n      if (!controlIds.includes(id)) {\r\n        el.remove()\r\n        this.controlMap.delete(id)\r\n      }\r\n    })\r\n  }\r\n\r\n  public destroy(): void {\r\n    this.controlMap.forEach(el => el.remove())\r\n    this.controlMap.clear()\r\n    this.draw = null\r\n    this.container = null\r\n  }\r\n}\r\n","/**\r\n * VerveDocs History —— HistoryManager\r\n *\r\n * 基于整树快照的撤销/重做管理器。\r\n * 使用 rfdc（经 schema cloneTree）深拷贝文档树，配合 coalescing 合并连续同类编辑。\r\n */\r\n\r\nimport type { IDocxDocumentMeta, IRange, HistorySnapshot } from '@vervedoc/docx-editor-schema'\r\nimport { cloneTree } from '@vervedoc/docx-editor-schema'\r\n\r\n// 重新导出迁移至 schema 的跨包共享类型，保持 history 包 API 兼容\r\nexport type { HistorySnapshot } from '@vervedoc/docx-editor-schema'\r\n\r\n/** 默认最大历史记录数 */\r\nconst DEFAULT_MAX_RECORD_COUNT = 50\r\n/** 默认合并时间窗（毫秒） */\r\nconst DEFAULT_COALESCE_MS = 300\r\n\r\n/** 基于整树快照的撤销/重做管理器 */\r\nexport class HistoryManager {\r\n  /** 撤销栈 */\r\n  private _undoStack: HistorySnapshot[] = []\r\n  /** 重做栈 */\r\n  private _redoStack: HistorySnapshot[] = []\r\n  /** 最大记录数 */\r\n  private _maxRecordCount: number\r\n  /** 合并时间窗（毫秒） */\r\n  private _coalesceMs: number\r\n  /** 上次提交时间戳 */\r\n  private _lastPushTime = 0\r\n  /** 上次合并键 */\r\n  private _lastCoalesceKey: string | undefined = undefined\r\n  /** 是否正在执行撤销/重做 */\r\n  private _isExecuting = false\r\n\r\n  /**\r\n   * 构造历史管理器\r\n   * @param options 配置选项，包含最大记录数与合并时间窗\r\n   */\r\n  constructor(options?: { maxRecordCount?: number; coalesceMs?: number }) {\r\n    this._maxRecordCount = options?.maxRecordCount ?? DEFAULT_MAX_RECORD_COUNT\r\n    this._coalesceMs = options?.coalesceMs ?? DEFAULT_COALESCE_MS\r\n  }\r\n\r\n  /**\r\n   * 初始化首快照（编辑器就绪后调用一次）\r\n   * @param snapshot 初始快照\r\n   * @returns 无返回值\r\n   */\r\n  pushInitial(snapshot: HistorySnapshot): void {\r\n    this._undoStack = [snapshot]\r\n    this._redoStack = []\r\n    this._lastPushTime = Date.now()\r\n    this._lastCoalesceKey = undefined\r\n  }\r\n\r\n  /**\r\n   * 提交一次编辑后的快照。\r\n   * coalesceKey 传入时：若与上次相同且在时间窗内，则替换栈顶（合并连续同类编辑）。\r\n   * @param snapshot 编辑后的快照\r\n   * @param coalesceKey 合并键，用于合并连续同类编辑\r\n   * @returns 无返回值\r\n   */\r\n  push(snapshot: HistorySnapshot, coalesceKey?: string): void {\r\n    if (this._isExecuting) return\r\n    const now = Date.now()\r\n    if (\r\n      coalesceKey !== undefined &&\r\n      coalesceKey === this._lastCoalesceKey &&\r\n      now - this._lastPushTime < this._coalesceMs &&\r\n      this._undoStack.length > 0\r\n    ) {\r\n      this._undoStack[this._undoStack.length - 1] = snapshot\r\n      this._redoStack = []\r\n      this._lastPushTime = now\r\n      return\r\n    }\r\n    this._undoStack.push(snapshot)\r\n    this._redoStack = []\r\n    this._lastPushTime = now\r\n    this._lastCoalesceKey = coalesceKey\r\n    while (this._undoStack.length > this._maxRecordCount) {\r\n      this._undoStack.shift()\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 撤销：返回要恢复的快照，current 被压入 redo 栈\r\n   * @param current 当前快照\r\n   * @returns 要恢复的快照，无法撤销时返回 null\r\n   */\r\n  undo(current: HistorySnapshot): HistorySnapshot | null {\r\n    if (this._isExecuting) return null\r\n    if (this._undoStack.length <= 1) return null\r\n    this._isExecuting = true\r\n    try {\r\n      this._redoStack.push(current)\r\n      this._undoStack.pop()\r\n      this._lastCoalesceKey = undefined\r\n      return this._undoStack[this._undoStack.length - 1] ?? null\r\n    } finally {\r\n      this._isExecuting = false\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 重做：将恢复的快照压入 undo 栈并返回\r\n   * @param _current 当前快照（保留接口兼容）\r\n   * @returns 要恢复的快照，无法重做时返回 null\r\n   */\r\n  redo(_current: HistorySnapshot): HistorySnapshot | null {\r\n    if (this._isExecuting) return null\r\n    if (this._redoStack.length === 0) return null\r\n    this._isExecuting = true\r\n    try {\r\n      const next = this._redoStack.pop()!\r\n      this._undoStack.push(next)\r\n      this._lastPushTime = Date.now()\r\n      this._lastCoalesceKey = undefined\r\n      return next\r\n    } finally {\r\n      this._isExecuting = false\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 是否可撤销\r\n   * @returns 可撤销时返回 true\r\n   */\r\n  canUndo(): boolean { return this._undoStack.length > 1 }\r\n\r\n  /**\r\n   * 是否可重做\r\n   * @returns 可重做时返回 true\r\n   */\r\n  canRedo(): boolean { return this._redoStack.length > 0 }\r\n\r\n  /**\r\n   * 历史栈是否为空\r\n   * @returns 撤销栈与重做栈均空时返回 true\r\n   */\r\n  isStackEmpty(): boolean { return this._undoStack.length <= 1 && this._redoStack.length === 0 }\r\n\r\n  /**\r\n   * 清空所有历史记录\r\n   * @returns 无返回值\r\n   */\r\n  clear(): void {\r\n    this._undoStack = []\r\n    this._redoStack = []\r\n    this._lastCoalesceKey = undefined\r\n  }\r\n\r\n  /**\r\n   * 销毁管理器，清空历史记录\r\n   * @returns 无返回值\r\n   */\r\n  destroy(): void { this.clear() }\r\n}\r\n\r\n/**\r\n * 工具：从文档 + range 创建快照（深拷贝 doc，浅拷贝 range）\r\n * @param doc 文档元数据\r\n * @param range 选区范围\r\n * @returns 创建的快照\r\n */\r\nexport function createSnapshot(doc: IDocxDocumentMeta, range: IRange | null): HistorySnapshot {\r\n  return {\r\n    doc: cloneTree(doc),\r\n    range: range ? { anchor: range.anchor, focus: range.focus } : null\r\n  }\r\n}\r\n","/**\r\n * VerveDocs History —— HistoryComponent\r\n *\r\n * 轻载器：创建 HistoryManager 实例，由 core 注入 CommandAdapt。\r\n */\r\n\r\nimport { HistoryManager } from './history-manager'\r\n\r\nexport class HistoryComponent {\r\n  /** 历史管理器实例 */\r\n  private _historyManager: HistoryManager | null = null\r\n\r\n  /**\r\n   * 安装历史组件，创建 HistoryManager 实例\r\n   * @param options 配置选项，包含最大记录数与合并时间窗\r\n   * @returns 创建的 HistoryManager 实例\r\n   */\r\n  public install(options?: { maxRecordCount?: number; coalesceMs?: number }): HistoryManager {\r\n    this._historyManager = new HistoryManager(options)\r\n    return this._historyManager\r\n  }\r\n\r\n  /**\r\n   * 获取历史管理器实例\r\n   * @returns 当前的 HistoryManager 实例，未安装时返回 null\r\n   */\r\n  public getHistoryManager(): HistoryManager | null {\r\n    return this._historyManager\r\n  }\r\n\r\n  /**\r\n   * 销毁历史组件，释放资源\r\n   * @returns 无返回值\r\n   */\r\n  public destroy(): void {\r\n    this._historyManager?.destroy()\r\n    this._historyManager = null\r\n  }\r\n}\r\n","/**\r\n * VerveDocs Keymap —— 快捷键处理\r\n *\r\n * 从 packages/core 迁入的键盘快捷键逻辑，分四组：\r\n *  - 编辑键：复制/剪切/粘贴/全选/删除/Enter/Tab/Escape\r\n *  - 光标键：方向键/Home/End/PageUp/PageDown（含 Ctrl 词移动/文档首尾）\r\n *  - 格式键：加粗/斜体/下划线/删除线/字号/对齐/列表/标题/清除格式\r\n *  - 历史键：撤销/重做/分页\r\n */\r\n\r\nimport type { Draw } from '@vervedoc/docx-editor-view'\r\nimport type { Command, CommandAdapt } from '@vervedoc/docx-editor-transform'\r\nimport type { RangeManager } from '@vervedoc/docx-editor-state'\r\nimport { ROW_FLEX, LIST_TYPE, LIST_STYLE, TITLE_LEVEL } from '@vervedoc/docx-editor-schema'\r\n\r\n/** 快捷键处理器依赖注入接口 */\r\nexport interface ShortcutDeps {\r\n  /** 获取 Draw 视图实例 */\r\n  getDraw: () => Draw\r\n  /** 获取 Command 命令实例 */\r\n  getCommand: () => Command\r\n  dispatchCommand: (command: string, ...args: any[]) => any\r\n  /** 获取 RangeManager 选区管理器 */\r\n  getRange: () => RangeManager\r\n  /** 获取 CommandAdapt 适配器（可能未初始化） */\r\n  getAdapt: () => CommandAdapt | null\r\n}\r\n\r\n/** 键盘快捷键处理器，分编辑/光标/格式/历史四组 */\r\nexport class ShortcutHandler {\r\n  /** 依赖注入 */\r\n  private deps: ShortcutDeps\r\n\r\n  /**\r\n   * 构造快捷键处理器\r\n   * @param deps 依赖注入对象\r\n   */\r\n  constructor(deps: ShortcutDeps) {\r\n    this.deps = deps\r\n  }\r\n\r\n  /**\r\n   * 处理键盘事件，依次尝试编辑/光标/格式/历史四组快捷键\r\n   * @param e 键盘事件\r\n   */\r\n  handle = (e: KeyboardEvent): void => {\r\n    const adapt = this.deps.getAdapt()\r\n    if (!adapt) return\r\n    const draw = this.deps.getDraw()\r\n    const command = this.deps.getCommand()\r\n\r\n    if (this.handleEditKeys(e, adapt, draw)) return\r\n    if (this.handleCursorKeys(e, adapt, draw)) return\r\n    if (this.handleFormatKeys(e, command)) return\r\n    if (this.handleHistoryKeys(e, command)) return\r\n  }\r\n\r\n  /**\r\n   * 处理编辑类快捷键（复制/剪切/粘贴/全选/删除/Enter/Tab/Escape）\r\n   * @param e 键盘事件\r\n   * @param adapt 命令适配器\r\n   * @param draw 视图实例\r\n   * @returns 是否已处理该事件\r\n   */\r\n  private handleEditKeys(e: KeyboardEvent, adapt: CommandAdapt, draw: Draw): boolean {\r\n    const mod = e.ctrlKey || e.metaKey\r\n\r\n    const clipboardCommand = { c: 'executeCopy', x: 'executeCut', v: 'executePaste' }[e.key.toLowerCase()]\r\n    if (mod && !e.altKey && !e.shiftKey && clipboardCommand) {\r\n      e.preventDefault()\r\n      this.deps.dispatchCommand(clipboardCommand)\r\n      return true\r\n    }\r\n    if (mod && e.key === 'a') {\r\n      e.preventDefault()\r\n      draw.selectAll()\r\n      return true\r\n    }\r\n    if (e.key === 'Backspace') { e.preventDefault(); adapt.deleteBackward(); return true }\r\n    if (e.key === 'Delete')    { e.preventDefault(); adapt.deleteForward(); return true }\r\n    if (e.key === 'Enter')     { e.preventDefault(); adapt.splitParagraph(); return true }\r\n    if (e.key === 'Tab')       { e.preventDefault(); adapt.insertText('\\t'); return true }\r\n    if (e.key === 'Escape')    { e.preventDefault(); this.deps.getRange().collapseToStart(); return true }\r\n\r\n    return false\r\n  }\r\n\r\n  /**\r\n   * 处理光标移动快捷键（方向键/Home/End/PageUp/PageDown，含 Ctrl 词移动/文档首尾）\r\n   * @param e 键盘事件\r\n   * @param adapt 命令适配器\r\n   * @param draw 视图实例\r\n   * @returns 是否已处理该事件\r\n   */\r\n  private handleCursorKeys(e: KeyboardEvent, adapt: CommandAdapt, draw: Draw): boolean {\r\n    const mod = e.ctrlKey || e.metaKey\r\n\r\n    if (e.key === 'ArrowLeft') {\r\n      e.preventDefault()\r\n      if (mod) draw.moveCaretWordLeft()\r\n      else adapt.moveCaretLeft()\r\n      return true\r\n    }\r\n    if (e.key === 'ArrowRight') {\r\n      e.preventDefault()\r\n      if (mod) draw.moveCaretWordRight()\r\n      else adapt.moveCaretRight()\r\n      return true\r\n    }\r\n    if (e.key === 'ArrowUp')   { e.preventDefault(); draw.moveCaretUp(); return true }\r\n    if (e.key === 'ArrowDown') { e.preventDefault(); draw.moveCaretDown(); return true }\r\n    if (e.key === 'Home') {\r\n      e.preventDefault()\r\n      if (mod) draw.moveCaretToDocStart()\r\n      else draw.moveCaretToLineStart()\r\n      return true\r\n    }\r\n    if (e.key === 'End') {\r\n      e.preventDefault()\r\n      if (mod) draw.moveCaretToDocEnd()\r\n      else draw.moveCaretToLineEnd()\r\n      return true\r\n    }\r\n    if (e.key === 'PageUp')   { e.preventDefault(); for (let i = 0; i < 10; i++) draw.moveCaretUp(); return true }\r\n    if (e.key === 'PageDown') { e.preventDefault(); for (let i = 0; i < 10; i++) draw.moveCaretDown(); return true }\r\n\r\n    return false\r\n  }\r\n\r\n  /**\r\n   * 处理格式快捷键（加粗/斜体/下划线/删除线/字号/对齐/列表/标题/清除格式）\r\n   * @param e 键盘事件\r\n   * @param command 命令实例\r\n   * @returns 是否已处理该事件\r\n   */\r\n  private handleFormatKeys(e: KeyboardEvent, command: Command): boolean {\r\n    const mod = e.ctrlKey || e.metaKey\r\n    if (!mod) return false\r\n    const k = e.key.toLowerCase()\r\n\r\n    if (!e.shiftKey && !e.altKey) {\r\n      if (k === 'b') { e.preventDefault(); command.executeSetBold(); return true }\r\n      if (k === 'i') { e.preventDefault(); command.executeSetItalic(); return true }\r\n      if (k === 'u') { e.preventDefault(); command.executeSetUnderline(); return true }\r\n      if (k === '\\\\') { e.preventDefault(); command.executeClearFormat(); return true }\r\n      if (k === '[') { e.preventDefault(); command.executeSizeMinus(); return true }\r\n      if (k === ']') { e.preventDefault(); command.executeSizeAdd(); return true }\r\n      if (k === 'l') { e.preventDefault(); command.executeSetRowFlex(ROW_FLEX.LEFT); return true }\r\n      if (k === 'e') { e.preventDefault(); command.executeSetRowFlex(ROW_FLEX.CENTER); return true }\r\n      if (k === 'r') { e.preventDefault(); command.executeSetRowFlex(ROW_FLEX.RIGHT); return true }\r\n      if (k === 'j') { e.preventDefault(); command.executeSetRowFlex(ROW_FLEX.JUSTIFY); return true }\r\n    }\r\n\r\n    if (e.shiftKey && !e.altKey) {\r\n      if (k === 'x') { e.preventDefault(); command.executeSetStrikeout(); return true }\r\n      if (k === 'j') { e.preventDefault(); command.executeSetRowFlex(ROW_FLEX.DISTRIBUTE); return true }\r\n      if (k === 'i') { e.preventDefault(); command.executeSetList(LIST_TYPE.UL, LIST_STYLE.DISC); return true }\r\n      if (k === 'u') { e.preventDefault(); command.executeSetList(LIST_TYPE.OL, LIST_STYLE.DECIMAL); return true }\r\n    }\r\n\r\n    if (e.altKey && !e.shiftKey) {\r\n      if (k === '0') { e.preventDefault(); command.executeSetTitle(null); return true }\r\n      if (k === '1') { e.preventDefault(); command.executeSetTitle(TITLE_LEVEL.FIRST); return true }\r\n      if (k === '2') { e.preventDefault(); command.executeSetTitle(TITLE_LEVEL.SECOND); return true }\r\n      if (k === '3') { e.preventDefault(); command.executeSetTitle(TITLE_LEVEL.THIRD); return true }\r\n      if (k === '4') { e.preventDefault(); command.executeSetTitle(TITLE_LEVEL.FOURTH); return true }\r\n      if (k === '5') { e.preventDefault(); command.executeSetTitle(TITLE_LEVEL.FIFTH); return true }\r\n      if (k === '6') { e.preventDefault(); command.executeSetTitle(TITLE_LEVEL.SIXTH); return true }\r\n    }\r\n\r\n    return false\r\n  }\r\n\r\n  /**\r\n   * 处理历史快捷键（撤销/重做/分页）\r\n   * @param e 键盘事件\r\n   * @param command 命令实例\r\n   * @returns 是否已处理该事件\r\n   */\r\n  private handleHistoryKeys(e: KeyboardEvent, command: Command): boolean {\r\n    const mod = e.ctrlKey || e.metaKey\r\n    if (!mod) return false\r\n    const k = e.key.toLowerCase()\r\n\r\n    if (!e.shiftKey && k === 'z') { e.preventDefault(); command.executeUndo(); return true }\r\n    if ((e.shiftKey && k === 'z') || (!e.shiftKey && k === 'y')) { e.preventDefault(); command.executeRedo(); return true }\r\n    if (k === 'enter') { e.preventDefault(); command.executePageBreak(); return true }\r\n\r\n    return false\r\n  }\r\n}","import { walkTree } from '@vervedoc/docx-editor-schema'\r\nimport type { IElement, ITitleElement, ITextElement, PathSegment } from '@vervedoc/docx-editor-schema'\r\n\r\nconst levelMap: Record<string, number> = { first: 1, second: 2, third: 3, fourth: 4, fifth: 5, sixth: 6 }\r\n\r\nexport function computeToc(elements: IElement[]) {\r\n  const toc: { id: string; level: number; name: string; number?: string }[] = []\r\n  const counters = new Map<string, number>()\r\n  walkTree(elements, (node, ctx) => {\r\n    if (node.type !== 'title') return\r\n    const t = node as ITitleElement\r\n    const name = (t.valueList ?? []).map(v => v.type === 'text' ? (v as ITextElement).value : '').join('')\r\n    const level = levelMap[t.level] ?? 1\r\n    let number: string | undefined\r\n    const num = (t as unknown as { listNumbering?: { numFmt: string; lvlText: string; start: number; numId?: string; abstractNumId?: string; level?: number } }).listNumbering\r\n    if (num && num.numFmt !== 'bullet') {\r\n      const numId = num.numId ?? num.abstractNumId ?? 'default'\r\n      const numLevel = num.level ?? 0\r\n      const key = `${numId}:${numLevel}`\r\n      const prev = counters.get(key)\r\n      const current = (prev == null ? (num.start ?? 1) - 1 : prev) + 1\r\n      counters.set(key, current)\r\n      for (const k of counters.keys()) {\r\n        if (k.startsWith(`${numId}:`) && Number(k.slice(numId.length + 1)) > numLevel) counters.delete(k)\r\n      }\r\n      number = (num.lvlText ?? '%1.').replace(/%([1-9])/g, (_, d: string) => {\r\n        const lvl = Number(d) - 1\r\n        return String(lvl === numLevel ? current : counters.get(`${numId}:${lvl}`) ?? (num.start ?? 1))\r\n      })\r\n    }\r\n    toc.push({ id: JSON.stringify(ctx.path), level, name, number })\r\n  })\r\n  return { toc }\r\n}\r\n\r\nexport function computeSearch(elements: IElement[], keyword: string) {\r\n  const results: { path: PathSegment[]; offset: number; length: number }[] = []\r\n  if (!keyword) return { results, count: 0 }\r\n  const lowerKeyword = keyword.toLowerCase()\r\n  walkTree(elements, (node, ctx) => {\r\n    if (node.type !== 'text') return\r\n    const text = ((node as ITextElement).value || '').toLowerCase()\r\n    let idx = text.indexOf(lowerKeyword)\r\n    while (idx !== -1) {\r\n      results.push({ path: [...ctx.path], offset: idx, length: keyword.length })\r\n      idx = text.indexOf(lowerKeyword, idx + 1)\r\n    }\r\n  })\r\n  return { results, count: results.length }\r\n}\r\n","import type { IElement, PathSegment } from '@vervedoc/docx-editor-schema'\r\nimport { cloneTree } from '@vervedoc/docx-editor-schema'\r\nimport { computeToc, computeSearch } from './compute'\r\n\r\nexport interface TocResult {\r\n  toc: { id: string; level: number; name: string; number?: string }[]\r\n}\r\nexport interface SearchResult {\r\n  results: { path: PathSegment[]; offset: number; length: number }[]\r\n  count: number\r\n}\r\ntype TocListener = (result: TocResult) => void\r\ntype SearchListener = (result: SearchResult) => void\r\ntype CloneListener = (data: unknown) => void\r\ntype ErrorListener = (message: string) => void\r\n\r\nexport class WorkerManager {\r\n  private worker: Worker | null = null\r\n  private failed = false\r\n  private destroyed = false\r\n  private pending = false\r\n  private elements: IElement[] = []\r\n  private tocListeners = new Set<TocListener>()\r\n  private searchListeners = new Set<SearchListener>()\r\n  private cloneListeners = new Set<CloneListener>()\r\n  private errorListeners = new Set<ErrorListener>()\r\n\r\n  init(): void {\r\n    if (this.worker || this.failed || this.destroyed) return\r\n    try {\r\n      this.worker = new Worker(new URL('./editor-worker.ts', import.meta.url), { type: 'module' })\r\n      this.worker.onmessage = (e: MessageEvent) => {\r\n        const msg = e.data\r\n        switch (msg.type) {\r\n          case 'toc-result': this.tocListeners.forEach(fn => fn({ toc: msg.toc })); break\r\n          case 'search-result': this.searchListeners.forEach(fn => fn({ results: msg.results, count: msg.count })); break\r\n          case 'clone-result': this.cloneListeners.forEach(fn => fn(msg.data)); break\r\n          case 'error': this.fallback(msg.message); break\r\n        }\r\n      }\r\n      this.worker.onerror = e => this.fallback(e.message)\r\n      this.worker.onmessageerror = () => this.fallback('Worker message could not be decoded')\r\n    } catch (error) {\r\n      this.failed = true\r\n      this.errorListeners.forEach(fn => fn(String(error)))\r\n    }\r\n  }\r\n\r\n  private fallback(message: string): void {\r\n    this.worker?.terminate()\r\n    this.worker = null\r\n    this.failed = true\r\n    this.errorListeners.forEach(fn => fn(message))\r\n    const result = computeToc(this.elements)\r\n    this.tocListeners.forEach(fn => fn(result))\r\n  }\r\n\r\n  updateElements(elements: IElement[]): void {\r\n    if (this.destroyed) return\r\n    this.elements = elements\r\n    if (this.pending) return\r\n    this.pending = true\r\n    queueMicrotask(() => this.flush())\r\n  }\r\n\r\n  private flush(): void {\r\n    if (!this.pending || this.destroyed) return\r\n    this.pending = false\r\n    this.init()\r\n    if (this.worker) {\r\n      try { this.worker.postMessage({ type: 'update', elements: this.elements }) }\r\n      catch (error) { this.fallback(String(error)) }\r\n    } else {\r\n      const result = computeToc(this.elements)\r\n      this.tocListeners.forEach(fn => fn(result))\r\n    }\r\n  }\r\n\r\n  search(keyword: string): void {\r\n    if (this.destroyed) return\r\n    this.flush()\r\n    this.init()\r\n    if (this.worker) {\r\n      try { this.worker.postMessage({ type: 'search', keyword }); return }\r\n      catch (error) { this.fallback(String(error)) }\r\n    }\r\n    const result = computeSearch(this.elements, keyword)\r\n    this.searchListeners.forEach(fn => fn(result))\r\n  }\r\n\r\n  clone(data: unknown): void {\r\n    if (this.destroyed) return\r\n    this.init()\r\n    if (this.worker) {\r\n      try { this.worker.postMessage({ type: 'clone', data }); return }\r\n      catch (error) { this.fallback(String(error)) }\r\n    }\r\n    const result = cloneTree(data)\r\n    this.cloneListeners.forEach(fn => fn(result))\r\n  }\r\n\r\n  onTocResult(listener: TocListener): () => void {\r\n    this.tocListeners.add(listener)\r\n    return () => this.tocListeners.delete(listener)\r\n  }\r\n  onSearchResult(listener: SearchListener): () => void {\r\n    this.searchListeners.add(listener)\r\n    return () => this.searchListeners.delete(listener)\r\n  }\r\n  onCloneResult(listener: CloneListener): () => void {\r\n    this.cloneListeners.add(listener)\r\n    return () => this.cloneListeners.delete(listener)\r\n  }\r\n  onError(listener: ErrorListener): () => void {\r\n    this.errorListeners.add(listener)\r\n    return () => this.errorListeners.delete(listener)\r\n  }\r\n  destroy(): void {\r\n    this.destroyed = true\r\n    this.worker?.terminate()\r\n    this.worker = null\r\n    this.elements = []\r\n    this.tocListeners.clear()\r\n    this.searchListeners.clear()\r\n    this.cloneListeners.clear()\r\n    this.errorListeners.clear()\r\n  }\r\n}\r\n","/** Background composition is isolated from document search/TOC work. */\r\nexport class ThumbnailManager {\r\n  private worker: Worker | null = null\r\n  private epoch = 0\r\n  private sources: string[] = []\r\n  private color = ''\r\n  private scheduled = false\r\n  private sourcesDirty = false\r\n  private disposed = false\r\n  private failed = false\r\n  private invalidated = false\r\n\r\n  constructor(private publish: (images: string[]) => void) {}\r\n\r\n  invalidate(): void {\r\n    this.epoch++\r\n    this.color = ''\r\n    this.invalidated = true\r\n  }\r\n\r\n  update(sources: string[], color: string): void {\r\n    if (this.disposed || this.failed) return\r\n    this.invalidated = false\r\n    const changed = sources.length !== this.sources.length || sources.some((value, i) => value !== this.sources[i])\r\n    if (!changed && color === this.color) return\r\n    this.sources = sources\r\n    this.color = color\r\n    this.sourcesDirty ||= changed\r\n    this.epoch++\r\n    if (this.scheduled) return\r\n    this.scheduled = true\r\n    queueMicrotask(() => this.flush())\r\n  }\r\n\r\n  private flush(): void {\r\n    this.scheduled = false\r\n    if (this.disposed || this.failed || this.invalidated) return\r\n    try {\r\n      if (!this.worker) {\r\n        this.worker = new Worker(new URL('./thumbnail-worker.ts', import.meta.url), { type: 'module' })\r\n        this.worker.onmessage = (event: MessageEvent<{ id: number; images?: string[]; error?: string }>) => {\r\n          if (this.disposed || event.data.id !== this.epoch) return\r\n          if (event.data.error) { this.fail(event.data.error); return }\r\n          if (event.data.images) this.publish(event.data.images)\r\n        }\r\n        this.worker.onerror = event => this.fail(event.message)\r\n        this.worker.onmessageerror = () => this.fail('Thumbnail worker message could not be decoded')\r\n      }\r\n      this.worker.postMessage({\r\n        id: this.epoch, color: this.color,\r\n        ...(this.sourcesDirty ? { sources: this.sources } : {})\r\n      })\r\n      this.sourcesDirty = false\r\n    } catch (error) {\r\n      this.fail(String(error))\r\n    }\r\n  }\r\n\r\n  private fail(message: string): void {\r\n    this.failed = true\r\n    this.worker?.terminate()\r\n    this.worker = null\r\n    // Keep existing previews rather than falling back to blocking page rendering.\r\n    console.warn('[VerveDocs] Background thumbnails unavailable:', message)\r\n  }\r\n\r\n  destroy(): void {\r\n    this.disposed = true\r\n    this.epoch++\r\n    this.worker?.terminate()\r\n    this.worker = null\r\n    this.sources = []\r\n  }\r\n}\r\n","/**\r\n * VerveDocs Core —— DocxEditor\r\n *\r\n * 全新构造，零兼容：只接受 IDocxDocumentMeta。\r\n */\r\n\r\nimport { createEditorI18n, type EditorI18n, type BuiltinLocale } from '@vervedoc/i18n'\r\nimport type { IDocxDocumentMeta, IEditorOption, EditorPlugin, PluginHost } from '@vervedoc/docx-editor-schema'\r\nimport { cloneTree, formatElementTree, mergeOption } from '@vervedoc/docx-editor-schema'\r\nimport { EventBus, Listener, RangeManager } from '@vervedoc/docx-editor-state'\r\nimport { Draw } from '@vervedoc/docx-editor-view'\r\nimport { CommandChain } from './command-chain'\r\nimport { Command, CommandAdapt } from '@vervedoc/docx-editor-transform'\r\nimport { Search, BlockParticle, DateParticle, LaTexParticle, ControlComponent } from '@vervedoc/docx-editor-commands'\r\nimport { HistoryComponent } from '@vervedoc/docx-editor-history'\r\nimport { ShortcutHandler } from '@vervedoc/docx-editor-keymap'\r\nimport { WorkerManager } from './workers/worker-manager'\r\nimport { ThumbnailManager } from './workers/thumbnail-manager'\r\n\r\n/**\r\n * DocxEditor 文档编辑器主类\r\n *\r\n * 全新构造，零兼容：只接受 IDocxDocumentMeta。\r\n * 组合 Listener / EventBus / RangeManager / Draw / Command / Comment / Revision / Search 等组件。\r\n */\r\nexport class DocxEditor {\r\n  private readonly i18n: EditorI18n\r\n  /** 事件监听器（content/range/page/catalog 等命名空间） */\r\n  public listener: Listener\r\n  /** 全局事件总线（hyperlinkMenuClick / chartClick 等右键菜单事件） */\r\n  public eventBus: EventBus\r\n  /** 选区管理器（anchor/focus 位置与折叠/展开） */\r\n  public range: RangeManager\r\n  /** 视图绘制引擎（布局 + Canvas 渲染 + 交互） */\r\n  public draw: Draw\r\n  /** 命令入口（executeXxx 系列方法） */\r\n  public command: Command\r\n  private adapt: CommandAdapt\r\n  private destroyed = false\r\n  private clipboardEpoch = 0\r\n\r\n  private clipboardGuard(): () => boolean {\r\n    const doc = this.draw.getDocument()\r\n    const epoch = this.clipboardEpoch\r\n    const zone = this.draw.getZone()\r\n    const range = JSON.stringify(this.range.getRange())\r\n    return () => !this.destroyed && epoch === this.clipboardEpoch &&\r\n      doc === this.draw.getDocument() && zone === this.draw.getZone() &&\r\n      range === JSON.stringify(this.range.getRange())\r\n  }\r\n  /** 已注册插件表（按 name 索引） */\r\n  private plugins = new Map<string, EditorPlugin>()\r\n  /** 插件命令注册表（命令名 → 处理函数），责任链中插件命令 handler 查此表分发 */\r\n  private pluginCommands = new Map<string, (...args: any[]) => any>()\r\n  /** 命令分发责任链 */\r\n  private commandChain = new CommandChain()\r\n  /** 插件宿主契约实例，构造完成后赋值，use(plugin) 时注入给插件 */\r\n  private pluginHost: PluginHost | null = null\r\n  /** 搜索组件 */\r\n  public search: Search\r\n  /** 块级粒子组件（图片/视频/音频/图表等块级元素） */\r\n  public block: BlockParticle\r\n  /** 日期粒子组件 */\r\n  public date: DateParticle\r\n  /** LaTeX 公式粒子组件 */\r\n  public laTex: LaTexParticle\r\n  /** 控件组件（checkbox/radio/dropdown 等） */\r\n  public control: ControlComponent\r\n  /** 历史管理组件（撤销/重做） */\r\n  public history: HistoryComponent\r\n\r\n  /** Worker 管理器（后台计算目录/搜索等） */\r\n  public worker: WorkerManager\r\n  private thumbnailWorker: ThumbnailManager\r\n  private thumbnailSources: string[] = []\r\n\r\n\r\n  /**\r\n   * 构造 DocxEditor 实例\r\n   * @param container 编辑器挂载的 DOM 容器（必须为 HTMLDivElement）\r\n   * @param document 文档元数据（必须包含 elements 数组，不再兼容 IElement[] / IEditorData）\r\n   * @param options 编辑器选项（字体/字号/页边距等，缺省时自动合并默认值）\r\n   * @throws {TypeError} container 非 HTMLDivElement 或 document 非 IDocxDocumentMeta 时抛出\r\n   */\r\n  constructor(\r\n    container: HTMLDivElement,\r\n    document: IDocxDocumentMeta,\r\n    options: IEditorOption = {}\r\n  ) {\r\n    if (!container || !(container instanceof HTMLDivElement)) {\r\n      throw new TypeError('[DocxEditor] container 必须是 HTMLDivElement')\r\n    }\r\n    if (!document || typeof document !== 'object' || !Array.isArray(document.elements)) {\r\n      throw new TypeError(\r\n        '[DocxEditor] document 必须是 IDocxDocumentMeta，且 elements 为数组。不再兼容 IElement[] / IEditorData 形态。'\r\n      )\r\n    }\r\n\r\n\r\n    this.i18n = createEditorI18n(options.locale)\r\n    const editorOptions = mergeOption({ ...options, locale: this.i18n.locale })\r\n    const doc: IDocxDocumentMeta = cloneTree(document)\r\n\r\n    formatElementTree(doc.elements, {\r\n      editorOptions,\r\n      styles: doc.styles,\r\n      numbering: doc.numbering\r\n    })\r\n    if (doc.sections !== undefined && !Array.isArray(doc.sections)) {\r\n      throw new TypeError('旧 sections 内容区必须显式迁移到 contentZones')\r\n    }\r\n    for (const elements of [doc.header, doc.footer, ...Object.values(doc.contentZones ?? {}), ...Object.values(doc.headerFooterParts ?? {})]) {\r\n      if (elements) formatElementTree(elements, { editorOptions, styles: doc.styles, numbering: doc.numbering })\r\n    }\r\n\r\n    this.listener = new Listener()\r\n    this.thumbnailWorker = new ThumbnailManager(images => {\r\n      if (!this.destroyed) this.listener.emit('thumbnailChange', images)\r\n    })\r\n    this.listener.on('thumbnailAppearanceChange', () => this.refreshThumbnailAppearance())\r\n    for (const event of ['contentChange', 'documentSet'] as const) {\r\n      this.listener.on(event, () => this.thumbnailWorker.invalidate())\r\n    }\r\n    this.eventBus = new EventBus()\r\n    this.range = new RangeManager(this.listener)\r\n    for (const event of ['contentChange', 'documentSet', 'rangeChange', 'zoneChange', 'abilityChange'] as const) {\r\n      this.listener.on(event, () => { this.clipboardEpoch++ })\r\n    }\r\n\r\n\r\n    // 渲染后联动通过 after-render 事件订阅，Draw 只 emit 事件不直接耦合各组件\r\n    this.wireAfterRenderHooks()\r\n\r\n    // 先声明适配器占位，以便在 Draw 构造时可以引用（onInput 回调需要 CommandAdapt）\r\n    let adapt: CommandAdapt | null = null\r\n\r\n    const shortcut = new ShortcutHandler({\r\n      getDraw: () => this.draw,\r\n      getCommand: () => this.command,\r\n      dispatchCommand: (command, ...args) => this.dispatchCommand(command, ...args),\r\n      getRange: () => this.range,\r\n      getAdapt: () => adapt\r\n    })\r\n\r\n    this.draw = new Draw(container, editorOptions, {\r\n      document: doc,\r\n      i18n: this.i18n,\r\n      listener: this.listener,\r\n      eventBus: this.eventBus,\r\n\r\n      rangeManager: this.range,\r\n      onInput: (text: string) => {\r\n        adapt?.insertText(text)\r\n      },\r\n      onKeyDown: shortcut.handle,\r\n      afterRender: () => {\r\n        this.listener.emit('afterRender')\r\n      },\r\n      onCommand: (command: string, ...args: any[]) => this.commandChain.dispatch(command, ...args),\r\n      onZoneChange: (zone) => {\r\n        this.listener.emit('zoneChange', zone)\r\n      }\r\n    })\r\n\r\n    adapt = new CommandAdapt(\r\n      {\r\n        getDocument: () => this.draw.getDocument(),\r\n        setDocument: (d: IDocxDocumentMeta) => this.draw.setDocument(d),\r\n        getLayout: () => this.draw.getLayout(),\r\n        getScroller: () => this.draw.getScroller(),\r\n        getActiveDocument: () => this.draw.getActiveDocument(),\r\n        applyActiveDocument: (d: IDocxDocumentMeta) => {\r\n          if (this.draw.getZone() === 'main') this.draw.setDocument(d)\r\n          else this.draw.applyActiveDocument(d)\r\n        },\r\n        setScale: (s: number) => this.draw.setScale(s),\r\n        setPageSize: (w: number, h: number) => this.draw.setPageSize(w, h),\r\n        setRulerVisible: (visible: boolean) => this.draw.setRulerVisible(visible),\r\n        setPaperMargins: (margins: [number, number, number, number]) => this.draw.setPaperMargins(margins),\r\n        getOptions: () => this.draw.getOptions(),\r\n        updateOptions: (patch) => this.draw.updateOptions(patch),\r\n        getZone: () => this.draw.getZone(),\r\n        setZone: (zone) => this.draw.setZone(zone),\r\n        setZoneWithCaret: (zone) => this.draw.setZoneWithCaret(zone),\r\n        print: () => this.draw.print(),\r\n        getPageThumbnails: () => this.draw.getPageThumbnails(),\r\n        scrollPositionIntoView: (pos) => this.draw.scrollPositionIntoView(pos)\r\n      },\r\n      this.range,\r\n      this.listener\r\n    )\r\n    this.adapt = adapt\r\n    this.command = new Command(adapt)\r\n\r\n    // 构建命令分发责任链：事件重定向 → 插件命令 → 剪贴板 → 核心命令兜底\r\n    this.commandChain\r\n      .use((cmd, _args, next) => {\r\n        if (cmd === 'requestInsertImage') { this.listener.emit('requestInsertImage'); return }\r\n        if (cmd === 'requestInsertHyperlink') { this.listener.emit('requestInsertHyperlink'); return }\r\n        if (cmd === 'requestInsertFormula') { this.listener.emit('requestInsertFormula'); return }\r\n        if (cmd === 'executeTableProperty') { this.listener.emit('requestTableProperties'); return }\r\n        return next()\r\n      })\r\n      .use((cmd, args, next) => {\r\n        const pluginCmd = this.pluginCommands.get(cmd)\r\n        if (typeof pluginCmd === 'function') return pluginCmd(...args)\r\n        return next()\r\n      })\r\n      .use((cmd, args, next) => {\r\n        if (cmd === 'executeCopy' || cmd === 'executeCut') {\r\n          if (cmd === 'executeCut' && !this.command.getIsCanInput()) return\r\n          const text = this.command.executeCopy()\r\n          if (!navigator.clipboard) return\r\n          const isCurrent = this.clipboardGuard()\r\n          const fragment = adapt.copyFragment()\r\n          const mime = 'web application/x-vervedocs+json'\r\n          const write = fragment && typeof ClipboardItem !== 'undefined' && ClipboardItem.supports?.(mime)\r\n            ? navigator.clipboard.write([new ClipboardItem({\r\n              'text/plain': new Blob([text], { type: 'text/plain' }),\r\n              [mime]: new Blob([JSON.stringify(fragment)], { type: 'application/x-vervedocs+json' })\r\n            })])\r\n            : navigator.clipboard.writeText(text)\r\n          return write.then(() => {\r\n            if (cmd === 'executeCut' && isCurrent()) this.command.executeCut()\r\n            return text\r\n          }).catch(() => {})\r\n        }\r\n        if (['executePaste', 'executePastePlain', 'executePasteNoFormat'].includes(cmd)) {\r\n          if (!this.command.getIsCanInput()) return\r\n          if (args.length > 0) return next()\r\n          if (!navigator.clipboard) return\r\n          const isCurrent = this.clipboardGuard()\r\n          return (async () => {\r\n            const mime = 'web application/x-vervedocs+json'\r\n            if (cmd === 'executePaste' && navigator.clipboard.read) {\r\n              const items = await navigator.clipboard.read()\r\n              for (const item of items) if (item.types.includes(mime)) {\r\n                const fragment = JSON.parse(await (await item.getType(mime)).text())\r\n                if (isCurrent()) adapt.pasteFragment(fragment)\r\n                return\r\n              }\r\n              for (const item of items) if (item.types.includes('text/plain')) {\r\n                const text = await (await item.getType('text/plain')).text()\r\n                if (isCurrent()) this.command.executePaste(text)\r\n                return\r\n              }\r\n            } else {\r\n              const text = await navigator.clipboard.readText()\r\n              if (isCurrent()) this.command.executePasteNoFormat(text)\r\n            }\r\n          })().catch(() => {})\r\n        }\r\n        return next()\r\n      })\r\n      .use((cmd, args, _next) => {\r\n        if (!this.command) return undefined\r\n        const fn = (this.command as unknown as Record<string, ((...a: any[]) => any) | undefined>)[cmd]\r\n        if (typeof fn === 'function') return fn.call(this.command, ...args)\r\n        return undefined\r\n      })\r\n\r\n    // 历史管理：创建 HistoryManager 注入 CommandAdapt\r\n    this.history = new HistoryComponent()\r\n    const historyManager = this.history.install({\r\n      maxRecordCount: Number(editorOptions.historyMaxRecordCount ?? 50),\r\n      coalesceMs: 300\r\n    })\r\n    adapt.setHistoryManager(historyManager)\r\n    adapt.pushInitialHistory()\r\n\r\n    // commands 组件实例化（基于 verve 树模型）\r\n    this.search = new Search(this.draw)\r\n    this.block = new BlockParticle(this.draw)\r\n    this.date = new DateParticle(this.draw)\r\n    this.laTex = new LaTexParticle(this.draw)\r\n    this.control = new ControlComponent()\r\n    this.control.install(this.draw)\r\n\r\n\r\n    // 构造插件宿主契约（桥接视图与文档查询接口），供 use(plugin) 时注入\r\n    // ⚠️ 该对象是 PluginHost 的唯一合法实现，外部严禁替换。\r\n    const drawRef = this.draw\r\n    this.pluginHost = {\r\n      getI18n: () => this.i18n,\r\n      getContainer: () => drawRef.getScroller(),\r\n      getPositionList: () => null,\r\n      getRevisionAnchor: (revisionId: string) => {\r\n        const anchorMap = drawRef.getRevisionAnchorMap()\r\n        return anchorMap.get(revisionId) || null\r\n      },\r\n      getDrawWidth: () => Number(editorOptions.pageWidth ?? 794),\r\n      getDrawHeight: () => Number(editorOptions.pageHeight ?? 1123),\r\n      getPageGap: () => Number((editorOptions as any).pageGap ?? 24),\r\n      getOptions: () => editorOptions,\r\n      getElementList: () => drawRef.getDocument().elements,\r\n      getDocument: () => drawRef.getDocument(),\r\n      commitTransaction: (action) => this.adapt.commitPluginTransaction(action),\r\n      getGroupContext: (groupId: string) => {\r\n        const anchorMap = drawRef.getGroupAnchorMap()\r\n        const anchor = anchorMap.get(groupId)\r\n        if (!anchor) return null\r\n        return {\r\n          isTable: false,\r\n          index: -1,\r\n          startIndex: -1,\r\n          endIndex: -1,\r\n          _anchor: anchor\r\n        }\r\n      },\r\n      executeSetGroup: (update) => this.adapt.setGroup(update),\r\n      executeDeleteGroup: (groupId: string) => { this.command?.executeDeleteGroup(groupId) },\r\n      executeLocationGroup: (groupId: string) => { this.command?.executeLocationGroup(groupId) },\r\n      executeUpdateOptions: (opts: any) => {\r\n        this.adapt.updateOptions(opts)\r\n      },\r\n      setActiveGroup: (groupId: string | null) => { drawRef.setActiveGroup(groupId) },\r\n      setActiveRevision: (revisionId, color) => { drawRef.setActiveRevision(revisionId, color) },\r\n      getEventBus: () => this.eventBus,\r\n      setChartRenderer: (renderer) => drawRef.setChartRenderer(renderer),\r\n      executeInsertChart: (payload: any) => { this.command?.executeInsertChart(payload) },\r\n      executeUpdateChart: (id: string, patch: Record<string, unknown>) => { this.command?.executeUpdateChart(id, patch) }\r\n    }\r\n\r\n    // 订阅 transform 的文档替换事件，通知插件同步数据（反转原 setCommentHandler 耦合）\r\n    this.listener.on('documentSet', (d: IDocxDocumentMeta) => {\r\n      for (const plugin of this.plugins.values()) {\r\n        plugin.hooks?.onSetDocument?.(d)\r\n      }\r\n    })\r\n\r\n    // 初始化 Worker，推送初始文档数据\r\n    this.worker = new WorkerManager()\r\n    // Worker 计算出目录后，通过 listener 推送给 UI\r\n    this.worker.onTocResult((result) => {\r\n      this.listener.emit('tocChange', result.toc)\r\n    })\r\n    this.listener.on('contentChange', () => {\r\n      this.worker.updateElements(this.draw.getDocument().elements)\r\n    })\r\n    this.worker.updateElements(doc.elements)\r\n\r\n    // 鼠标点击 -> hit + setC8 + focus 隐藏输入框\r\n    // 注意：Draw 内 mousedown 已处理 hit，这里不再重复绑定\r\n  }\r\n\r\n  /**\r\n   * 订阅 after-render 生命周期事件，集中管理渲染后各组件的联动。\r\n   *\r\n   * Draw 只 emit `after-render` 事件，不直接调用插件/block/control/worker，\r\n   * 已注册插件的 `hooks.afterRender` 在此遍历调用，核心组件联动也在此集中订阅。\r\n   */\r\n  private wireAfterRenderHooks(): void {\r\n    this.listener.lifecycle.afterRenderListener(() => {\r\n      for (const plugin of this.plugins.values()) {\r\n        plugin.hooks?.afterRender?.()\r\n      }\r\n      this.renderEmbedBlocks()\r\n      this.block?.clear()\r\n      this.control?.clear()\r\n      if (this.listener.hasListeners('thumbnailChange')) {\r\n        const images = this.draw.getPageThumbnails()\r\n        const sources = this.draw.getThumbnailForegrounds()\r\n        if (sources.length !== this.thumbnailSources.length || sources.some((value, i) => value !== this.thumbnailSources[i])) {\r\n          // Publish new content immediately; background composition follows asynchronously.\r\n          this.listener.emit('thumbnailChange', images)\r\n          this.thumbnailSources = sources\r\n        }\r\n        this.refreshThumbnailAppearance(sources)\r\n      }\r\n    })\r\n  }\r\n\r\n  private refreshThumbnailAppearance(sources?: string[]): void {\r\n    if (this.destroyed || !this.draw || !this.listener.hasListeners('thumbnailChange')) return\r\n    const options = this.draw.getOptions()\r\n    const background = options.background as { color?: string } | undefined\r\n    this.thumbnailWorker.update(sources ?? this.draw.getThumbnailForegrounds(),\r\n      options.eyeCare ? '#C7EDCC' : background?.color || '#ffffff')\r\n  }\r\n\r\n  /**\r\n   * 渲染嵌入块（iframe）：遍历 layout 中 kind === 'block' 的节点，\r\n   * 调 BlockParticle.render 挂载/复用 DOM。chart 已由 canvas drawImage 渲染，不在此处理。\r\n   */\r\n  private renderEmbedBlocks(): void {\r\n    if (!this.block) return\r\n    const layout = this.draw.getLayout()\r\n    if (!layout) return\r\n    for (const page of layout.pages) {\r\n      for (const b of page.blocks) {\r\n        if (b.kind === 'block') {\r\n          const x = page.contentRect.x + b.rect.x\r\n          const y = page.contentRect.y + b.rect.y\r\n          this.block.render(page.index, b.block, x, y)\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 获取当前文档元数据\r\n   * @returns 文档元数据（含 elements/sections/comments 等）\r\n   */\r\n  getDocument(): IDocxDocumentMeta { return this.draw.getDocument() }\r\n\r\n  getLocale(): BuiltinLocale { return this.i18n.locale }\r\n  setLocale(locale: BuiltinLocale): void { this.i18n.setLocale(locale) }\r\n  getI18n(): EditorI18n { return this.i18n }\r\n\r\n  /**\r\n   * 设置文档元数据，重置 zone 到 main 并通知插件同步数据\r\n   * @param doc 文档元数据（必须包含 elements 数组）\r\n   * @throws {TypeError} doc 非 IDocxDocumentMeta 时抛出\r\n   */\r\n  setDocument(doc: IDocxDocumentMeta): void {\r\n    if (!doc || !Array.isArray(doc.elements)) {\r\n      throw new TypeError('[DocxEditor.setDocument] 需要 IDocxDocumentMeta')\r\n    }\r\n    this.adapt.replaceDocument(doc, true)\r\n  }\r\n\r\n  // ============================================================\r\n  //   插件注册 —— 可选功能（批注/修订等）的唯一合法入口\r\n  // ============================================================\r\n\r\n  /**\r\n   * 注册插件。core 在注册时自动注入 PluginHost、登记命令表；\r\n   * 若文档已加载，立即触发 `hooks.onSetDocument` 以同步初始数据。\r\n   *\r\n   * 核心引擎（view/transform）保持内置硬编码，不通过此方法注册。\r\n   *\r\n   * @param plugin 满足 EditorPlugin 契约的插件实例\r\n   */\r\n  use(plugin: EditorPlugin): void {\r\n    if (this.plugins.has(plugin.name)) {\r\n      console.warn(`[DocxEditor] 插件 \"${plugin.name}\" 已注册，忽略重复注册`)\r\n      return\r\n    }\r\n    this.plugins.set(plugin.name, plugin)\r\n    if (this.pluginHost) plugin.install(this.pluginHost)\r\n    if (plugin.commands) {\r\n      for (const [name, fn] of Object.entries(plugin.commands)) {\r\n        this.pluginCommands.set(name, fn)\r\n      }\r\n    }\r\n    // 若文档已加载，通知插件同步初始数据\r\n    if (plugin.hooks?.onSetDocument) {\r\n      plugin.hooks.onSetDocument(this.draw.getDocument())\r\n    }\r\n  }\r\n\r\n  /**\r\n   * 获取已注册插件实例，供宿主层调用插件特有方法。\r\n   *\r\n   * @param name 插件名称\r\n   * @returns 插件实例，未注册时返回 undefined\r\n   */\r\n  getPlugin<T extends EditorPlugin>(name: string): T | undefined {\r\n    return this.plugins.get(name) as T | undefined\r\n  }\r\n\r\n  /**\r\n   * 分发命令到责任链（供宿主层触发插件命令）\r\n   */\r\n  dispatchCommand(command: string, ...args: any[]): any {\r\n    return this.commandChain.dispatch(command, ...args)\r\n  }\r\n\r\n  /**\r\n   * 销毁编辑器实例，释放所有资源（DOM/事件监听/定时器/组件/插件）\r\n   */\r\n  destroy(): void {\r\n    this.destroyed = true\r\n    for (const plugin of this.plugins.values()) {\r\n      plugin.destroy?.()\r\n    }\r\n    this.block?.destroy()\r\n    this.date?.clearDatePicker()\r\n    this.control?.destroy()\r\n    this.history?.destroy()\r\n    this.draw.destroy()\r\n    this.thumbnailWorker.destroy()\r\n    this.worker.destroy()\r\n    this.listener = new Listener()\r\n    this.eventBus.clear()\r\n    this.range.clear()\r\n  }\r\n}\r\n\r\nexport default DocxEditor\r\n","/**\r\n * VerveDocs Core —— UI 常量与枚举\r\n *\r\n * PaperDirection / TableBorder 已在 schema/constants.ts 定义，通过 export * 透传。\r\n * 字体字号从 schema 已有常量转换，不重复定义数据。\r\n */\r\n\r\nimport { FONT_FAMILY_MAP, FONT_SIZE, FONT_SIZE_LIST } from '@vervedoc/docx-editor-schema'\r\n\r\n/** 编辑器字体选项（从 schema FONT_FAMILY_MAP 转换为 { label, value } 格式） */\r\nexport const EDITOR_FONT_OPTIONS: { label: string; value: string }[] =\r\n  FONT_FAMILY_MAP.map(e => ({ label: e.label, value: e.value }))\r\n\r\n/** 编辑器字号选项（从 schema FONT_SIZE / FONT_SIZE_LIST 转换为 { label, value } 格式） */\r\nexport const EDITOR_SIZE_OPTIONS: { label: string; value: number }[] =\r\n  FONT_SIZE_LIST.map(name => {\r\n    const value = FONT_SIZE[name]\r\n    return { label: name, value: value != null ? value : Number(name) }\r\n  })\r\n\r\n/** 水印字号选项（对齐 Word 标准水印字号） */\r\nexport const WATERMARK_SIZE_OPTIONS: { label: string; value: number }[] = [\r\n  { label: '自动', value: 120 },\r\n  { label: '40', value: 40 },\r\n  { label: '50', value: 50 },\r\n  { label: '60', value: 60 },\r\n  { label: '70', value: 70 },\r\n  { label: '80', value: 80 },\r\n  { label: '90', value: 90 },\r\n  { label: '100', value: 100 },\r\n  { label: '120', value: 120 },\r\n  { label: '140', value: 140 },\r\n  { label: '160', value: 160 },\r\n  { label: '180', value: 180 },\r\n  { label: '200', value: 200 },\r\n]\r\n\r\n","/**\r\n * VerveDocs Core —— 公共入口\r\n */\r\n\r\nimport DocxEditor from './docx-editor'\r\n\r\nexport default DocxEditor\r\nexport { DocxEditor }\r\nexport { DocxEditor as Editor }\r\n\r\n// 树模型 / 工具（全量透传 schema）\r\nexport * from '@vervedoc/docx-editor-schema'\r\nexport type { TitleLevel } from '@vervedoc/docx-editor-schema'\r\n\r\n// UI 常量与枚举\r\nexport * from './constants'\r\n\r\n// Worker 管理器\r\nexport { WorkerManager } from './workers/worker-manager'\r\nexport type { TocResult, SearchResult } from './workers/worker-manager'\r\n\r\n// 状态层\r\nexport { EventBus, Listener, RangeManager } from '@vervedoc/docx-editor-state'\r\nexport type { IRangeStyle, IEditorAbility, ListenerMap, EventHandler } from '@vervedoc/docx-editor-schema'\r\n\r\n// 视图层\r\nexport {\r\n  Draw,\r\n  LayoutEngine,\r\n  CanvasRenderer,\r\n  TextMeasure,\r\n  getSharedMeasure,\r\n  hitTest\r\n} from '@vervedoc/docx-editor-view'\r\nexport type {\r\n  DocumentLayout, PageLayout, BlockNode, ParagraphBlock,\r\n  ImageBlock, PageBreakBlock, TableBlock, TableRowLayout, TableCellLayout,\r\n  LineBox, InlineBox, Rect\r\n} from '@vervedoc/docx-editor-view'\r\n\r\n// 变换层\r\nexport { Command, CommandAdapt } from '@vervedoc/docx-editor-transform'\r\nexport type { IHistoryManager, HistorySnapshot } from '@vervedoc/docx-editor-schema'\r\n\r\n// 命令分发责任链\r\nexport { CommandChain } from './command-chain'\r\nexport type { CommandHandler, CommandNext } from './command-chain'\r\n\r\n// 历史管理\r\nexport { HistoryManager, HistoryComponent, createSnapshot } from '@vervedoc/docx-editor-history'\r\nexport type { HistorySnapshot as HistorySnapshotType } from '@vervedoc/docx-editor-history'\r\n\r\n\r\n// commands 扩展（搜索 / 块级媒体 / 日期 / LaTeX / 小工具）\r\nexport {\r\n  Search,\r\n  BlockParticle,\r\n  DateParticle,\r\n  LaTexParticle,\r\n\r\n  ControlComponent\r\n} from '@vervedoc/docx-editor-commands'\r\nexport type {\r\n  ISearchResult,\r\n  IReplaceOption,\r\n  INavigateInfo,\r\n  IElementPosition\r\n} from '@vervedoc/docx-editor-schema'\r\n\r\n/** VerveDocs Core 版本号 */\r\nexport const version = '4.0.0-tree'\r\n"],"names":["builtinMessages","createEditorI18n","locale","createI18n","lookup","messages","key","value","segment","bundles","initialLocale","fallbackLocale","listeners","params","_","name","nextLocale","listener","SCHEMA_VERSION","DEFAULT_EDITOR_OPTION","PARAGRAPH_ATTR_KEYS","PARAGRAPH_CONTAINER_TYPES","BLOCK_LEVEL_TYPES","LIST_TYPE","LIST_STYLE","ROW_FLEX","TITLE_LEVEL","FONT_FAMILY","FONT_FAMILY_MAP","FONT_FAMILY_LIST","e","FONT_FAMILY_VALUE","FONT_FAMILY_LABEL","a","FONT_FAMILY_CSS","FONT_SIZE","FONT_SIZE_LIST","PaperDirection","TableBorder","DPI","ptToPx","pt","pxToPt","px","PAPER_SIZE_LIST","DEFAULT_PAPER_SIZE","BULLET_STYLES","NUMBER_STYLES","LINE_HEIGHT_OPTIONS","MARGIN_PRESETS","ZOOM_LEVELS","SEPARATOR_STYLES","TITLE_LEVEL_MAP","AUTHOR_COLORS","getAuthorColor","hash","i","FORMAT_KEYS","BOOLEAN_TAGS","snapshotRevisionFormat","element","source","clearRevision","run","extension","decodeXml","escapeXml","readRunProperties","xml","result","tag","_a","attr","underline","fonts","font","scale","color","vertical","getRevisionOldProps","stored","serializeRunProperties","format","parts","add","style","recordFormatRevision","before","meta","after","changed","existing","oldProps","restoreRevisionFormat","target","rfdc_1","rfdc","copyBuffer","cur","opts","rfdcCircles","constructorHandlers","fn","cloneArray","handler","cloneProto","clone","keys","a2","k","o2","refs","refsNew","o","index","_clone","cloneTree","node","isParagraphContainer","el","isTable","isControl","walkTree","elements","visitor","parentPath","path","tr","row","td","cell","normalizeControlElement","old","checked","dateValue","_b","normalizeControlTree","getByPath","root","current","seg","getParentContainer","replaceAtPath","parent","idx","insertAtPath","removeAtPath","removed","isSamePath","b","comparePath","n","av","bv","comparePosition","c","forEachCell","table","j","getTableColCount","sum","_pathSegAsKey","computeControlDisplayValue","control","dataValue","kind","formatNumberDisplay","opt","values","delimiter","options","selected","ordered","option","v","controlIdCounter","generateControlId","ts","counter","validateControlValue","required","isEmptyValue","validateNumber","num","createControlElement","config","id","controlId","displayValue","updateControlElementValue","newDataValue","validateControlConfig","seen","resolveHeaderFooterPart","doc","zone","sectionIndex","pageIndex","firstPage","section","_c","_e","_d","mergeOption","formatElementTree","ctx","stack","ext","normalizeNode","adjustFloatImagePositions","editorOptions","normalizeText","normalizeTitle","normalizeList","normalizeTable","normalizeImage","normalizePageBreak","normalizeControl","anyNode","applyParagraphStyleId","inheritParagraphAttrsToChildren","numId","ri","normalizeTr","ci","normalizeTd","applyImageLayout","image","layout","child","wrap","updateImageLayout","changes","geometry","namespace","drawing","transform","styleId","indentationBaseline","axis","container","PARA_KEYS","containerAny","childAny","pairBookmarkMarkers","markers","leaves","indices","isContent","startMap","bookmarks","m","startPath","start","end","first","last","anchor","isParagraphTerminator","endsBookmarkParagraph","previous","next","splitParagraphs","out","valueList","segs","splitValueList","runs","startIndex","vi","vStart","toDocxExportDocument","document","contentZones","normalizeIndentation","hanging","normalizeHyperlinks","children","normalizeParagraphRuns","group","boundaries","resolvePoint","point","length","addBoundary","position","entries","bookmark","focus","starts","ends","marker","boundary","convert","entry","offset","pageNumberSequence","PAGE_NUMBER_FORMATS","collectPageFields","parents","fields","type","getPageFieldStyle","field","explicit","match","createPageNumberElements","template","base","text","numberStyle","dash","updatePageFields","pageFields","insideField","standalone","terminator","groupId","isStart","KeyMap","isApple","isMod","evt","has","prefix","Events","EE","context","once","addListener","emitter","event","clearEvent","EventEmitter","names","events","handlers","l","ee","a1","a3","a4","a5","len","args","module","EventBus","__publicField","Listener","RangeManager","pos","range","delta","newOffset","resolveTextFont","ch","defaultFont","fallback","families","code","eastAsia","complex","family","LRU","limit","TextMeasure","size","bold","italic","hit","w","metrics","bounds","_sharedMeasure","getSharedMeasure","CONTROL_MARK","getControlPresentation","printing","bracketed","displayText","PUNCTUATION","balancedSpaceWidth","typography","measure","narrow","wide","full","punctuationCompression","rule","width","ink","left","right","whitespace","minWidth","toRoman","upper","map","s","toLetter","rem","CN_DIGITS","CN_UNITS","CN_BIG_UNITS","CN_UPPER","toChineseCounting","t","toChineseCountingLarge","segStr","u","digit","toChineseUpper","toIdeographDigital","d","toDecimalZero","formatCounter","numFmt","WINGDINGS_FALLBACK","BULLET_FONT_STACK","BULLET_FONT_STACK_FALLBACK","_hasWingdings","detectWingdings","w1","w2","resolveUnorderedChar","list","bulletFont","isWingdings","trimmed","styleMap","level","normalizeBulletChar","hasWingdings","resolveBullet","counters","listType","isOrderedStyle","raw","hasWD","fmt","tpl","prev","lvl","val","fontOf","inl","addBucket","buckets","cmd","groupHighlightColor","active","r","g","paintParagraph","firstLine","bx","by","bgRects","strokes","groupColors","activeColor","line","hasGroupHighlight","gid","gc","revisionType","inserted","deleted","revisionColor","textColor","_f","spacing","x","markOffset","_g","my","cx","y","paintParagraphBorders","block","borders","height","side","edge","lineWidth","x1","y1","x2","y2","stroke","chartTableSignature","page","signBlock","_rows","attrs","_content","cellAttrs","signParagraph","img","wordArtKey","paraKey","runsKey","_path","paint","revision","bulletKey","si","surroundKey","CanvasRenderer","renderer","z","cssWidth","cssHeight","dpr","patch","enabled","quality","pageCount","onForeground","canvas","contentOriginX","contentOriginY","aliveIds","hx","hy","fx","fy","images","resources","withPrintState","render","preload","cache","visit","blocks","blockIds","ids","collect","inline","revisionId","cached","bytes","cfg","widget","alphabet","symbol","small","tens","scales","underThousand","groups","words","irregular","word","lower","ordinal","remainder100","suffix","replacements","char","uppercase","digits","units","ones","hundreds","rest","thousands","ct","scrollY","totalPages","rect","textW","textH","baselineY","relX","relY","greekLower","rects","pageOffsetX","ov","pageBottom","PADDING","pageTop","clampY","min","max","top","bottom","contentTop","contentBottom","pageLeft","pageRight","h","fullLineStartX","fullLineEndX","dividerY","viewportHeight","dirtyRect","dx","dy","dw","dh","dTop","dBottom","viewTop","viewBottom","alive","pw","ph","ml","mt","mr","mb","L","sig","corners","p","layer","originX","originY","needRebuild","bitmap","anyBlock","lineType","dashArray","x0","cy","amp","wave","gap","lines","off","grad","sx","sy","mode","url","rotate","crop","scaledWidth","scaledHeight","wordArt","fontSize","fontFamily","chartBlock","dependency","cacheKey","dataUrl","dataSource","chartType","subtype","blk","tableEl","tableData","bg","cw","contentX","contentY","cb","edges","edgeKey","b1","b2","drawOnce","bs","bt","showTop","showRight","showBottom","showLeft","slashes","rank","borderRank","borderWeight","brightness","rgb","secondaryBrightness","points","candidates","winner","strokeSide","halfOffset","_blockSeq","nextBlockId","LayoutEngine","headerElements","footerElements","pageGap","emptyZoneElements","zoneElements","isDefaultEmptyZone","sectionFirstPage","pageWidth","pageHeight","footerAreaHeight","contentWidth","contentHeight","setSection","footerPartIds","previousZone","previousCounters","partId","pageFooterElements","distance","sectionBreaks","sectionColumns","count","sectionWidths","columnGroups","columnSection","data","rawBlocks","gridSectionIndex","input","columnId","columns","gridType","gridLinePitch","anchorParagraphs","attachedImages","placedAnchors","headerBlocks","footerBlocks","pages","cursorY","currentBlocks","hasVisiblePageContent","activeColumns","activeColumnId","columnIndex","columnTop","columnBottom","columnX","advanceColumn","pushPage","PAGE_FIT_EPSILON","pageOriginY","headerPartId","footerPartId","pageHeaderElements","pageHeaders","pageFooters","headerHeight","footerHeight","headerOffsetY","footerOffsetY","pageRect","contentRect","headerRect","footerRect","legacyColumnId","sourceColumnId","balanced","exclusions","placed","breakType","nextSection","geometryChanged","_h","margin","suppressEmptyNextPage","resume","fragment","origin","remainingLines","bh","_i","remaining","frags","fi","frag","floating","_j","_k","horizontal","_l","_m","resolve","ref","isX","leading","align","_n","_p","_o","_r","_q","fieldCache","sectionPageCounts","_s","number","_t","positioned","lastPage","totalHeight","availableWidth","ignoreParagraphIndents","verticalText","paragraphs","gi","imgEl","issues","issue","feature","reason","reference","hasAnchor","paragraph","supported","item","imgDisplay","imgBlock","runsParentPath","pb","blockEl","anyEl","innerBlock","signature","sameSources","availableHeight","contentEnd","layouts","reflow","column","original","property","flow","nextColumn","whole","fragmentHeight","low","high","iteration","middle","lastBlock","paragraphKind","endIndex","runStartIndex","containerAttrs","collectedRunAttrs","ra","frame","positionedFrame","frameWidth","rowFlex","firstIndent","indentLeft","indentRight","indentHanging","spacingBefore","spacingAfter","paragraphMarkSize","snapToGrid","docGridLinePitch","rawLineHeight","lineHeightRule","bulletKind","bulletText","bulletWidth","bulletSize","bulletColor","bulletBold","bulletX","useWordHanging","bulletHanging","hasNumbering","listEl","res","listHanging","listBaseIndent","proposed","cap","fa","rawBulletFont","symbolGap","glyphW","jc","hangingOffset","inner","bulletWidthForLine","currentInlines","currentLineStart","currentLineWidth","compressionCandidates","currentMaxSize","isFirstLine","firstLineOffset","flowY","lineRegion","exclusion","computeLineHeight","leftWidth","rightWidth","currentLineMaxWidth","compressLine","needed","capacity","ratio","shrink","lh","finalizeLine","isLastLine","naturalLineHeight","region","lineXBase","expandedRuns","rawRun","sourceIndex","presentation","layoutRuns","hyperlink","tocEntry","fitScales","firstTextRun","fitTextWidth","naturalWidth","indentation","baseline","tocPageWidth","runIndex","resumeIndex","runPath","hyperlinkUrl","controlPlaceholder","anyRun","fontForChar","fitScale","runSpacing","customAdvance","bgColor","strikeout","groupIds","emptySize","cursorInRun","spaceWidth","compressions","charWidth","maxLineWidth","advance","wordWidth","firstW","take","takenWidth","segEnd","segWidth","compression","placeholderRun","placeholderRi","pr","rawFont","yy","contentRight","applyRowFlex","rectWidth","occupiedW","occupiedH","colWidths","firstTr","inferred","span","per","totalDefined","tableWidth","occupied","rows","rowHeights","rowCells","rowspanPending","legacyVerticalPeers","indent","colCursor","colspan","rowspan","rr","cc","cellWidth","cellX","sumUp","pl","textRuns","maxTextSize","longestLineHeight","textLength","direction","hasVerticalIndent","hasVerticalLineMetrics","isVerticalText","verticalTextWidth","cellPath","contentPath","content","innerY","rp","acc","rowHeight","cellLayouts","cl","cellH","firstFit","fullHeight","totalRows","repeatRows","repeatHeight","firstEnd","startRow","budget","endRow","fit","subAcc","repeatRowsBefore","bodyRows","headerRows","spanHeight","from","to","headerOffset","rs","hi","cont","bodyFirst","arr","upto","containerWidth","used","free","isJustify","isDistribute","totalChars","gaps","extra","lastTextIndex","hitTest","docX","docY","hitBlocks","ox","oy","distanceX","six","hitParagraph","hitTable","lx","ly","_pb","hitLine","cursor","ls","tbx","tby","contentOX","contentOY","locateCaret","locateInBlocks","locateInParagraph","locateInTable","charCount","charHeight","localX","charOffsetToX","pathStartsWith","offsetInInline","computeSelectionRects","collectSelectionInBlocks","collectSelectionInParagraph","segLeft","segRight","flush","inlStart","inlEnd","clipStartOff","clipEndOff","viewText","viewTranslate","translate","textKeys","translatePanel","preferred","byText","walker","keyedText","PREFIX","SVG","ContextMenu","items","isSub","div","main","icon","label","sc","arrow","inputValue","unit","colorValue","colorInput","clear","parentEl","vw","vh","positionHandle","handle","viewport","visible","panelHtml$3","TablePropertiesWidget","deps","selection","panelHtml","tab","tabs","button","picker","selectColor","controls","invalid","pane","valid","state","preview","columnWidth","command","horizontalAlign","textDirection","paddingNames","paddingValues","repeatHeader","BORDER_HOT","TableWidget","tableIndex","matchesTable","part","tableX","tableY","colX","colY","rowX","rowY","clientX","clientY","icons","fire","hasExplicitDirection","labels","localize","menu","unitKey","info","screenX","screenY","borderX","borderY","border","newSize","createSelectionLayer","updateSelectionLayer","positionSelectionToolbar","toolbar","HANDLE_SIZE","HANDLE_OFFSET","HANDLES","ImageWidget","dir","origW","origH","bar","mkBtn","title","action","onClick","btn","sp","mkSep","sep","delBtn","delIcon","src","overlay","close","onKey","pageOriginX","sel","bp","deleteOnly","hd","ChartWidget","panelHtml$2","PX_PER_CM","ParagraphLayoutWidget","panes","lhType","lhValue","lhUnit","special","specialValue","updateLh","updateSpecial","displayNumber","outline","spAfter","indentPx","alignMap","panelHtml$1","FontLayoutWidget","cjk","sizeKeys","fontValue","fontLabel","fontEntry","styleSel","sizeSel","cnName","doubleStrikeout","hidden","superscript","subscript","styleVal","sizeVal","HyperlinkWidget","onConfirm","onSuccess","textInput","urlInput","error","setError","protocol","ParagraphWidget","onCommand","lastLine","firstInline","lastInline","alignment","addButton","levels","sub","alignments","svg","arrows","savedRange","snapshot","HeaderFooterWidget","make","textEl","f","caret","popup","styleRow","styleLabel","styleSelect","styleKeys","posTitle","posRow","positions","posItems","it","isActive","footer","confirmBtn","hitZone","currentZone","labelY","pageCenterX","btnWidth","btnHeight","popupWidth","popupHeight","RULER_SIZE","BAND_START","BAND_SIZE","BACKGROUND","MARGIN_BACKGROUND","BORDER","MARGINS","INDENTS","RulerWidget","drag","pageX","clamp","movement","margins","createRuler","ruler","isMargin","titles","step","center","firstTick","lastTick","tick","tabStep","aligned","WatermarkWidget","py","opacity","repeat","gapX","gapY","stepX","stepY","diag","cols","startX","startY","offsetX","SystemWatermarkWidget","tileW","tileH","escText","encoded","SelectionToolbarWidget","tb","fontSel","colorBtn","hlBtn","sizePt","btns","colorInputs","CaretWidget","ControlWidget","scaleX","scaleY","multi","panel","search","renderList","query","empty","restoreFocus","readOnly","nextRenderId","prepareRenderState","dirty","topLevel","bi","computeDirtyRect","painted","include","findInlineByPos","findInlineInBlocks","findParagraphByPos","findParagraphInBlocks","findLineByPos","findLineInBlocks","findFirstInline","findFirstInlineInBlocks","findLastInline","findLastInlineInBlocks","onInline","findHyperlinkByPos","collectGroupAnchors","absX","absY","absEndX","absEndY","glyphHeight","absGlyphTop","collectRevisionAnchors","CaretNavigation","localOff","isWord","para","targetY","newPos","inlines","ZoneManager","initialized","baseId","resetCaret","trList","tdList","TEXT_CURSOR","Draw","wasDragging","midY","i18n","assetLoaded","activePage","tableRects","selRects","rowCount","lastRow","lastColIdx","startCol","endCol","paperDirection","printLayout","pageStyles","visualSignature","foreground","previousPageIndex","pageChanged","bookmarkMarkers","diagnostics","notice","wrapperWidth","scrollLeft","skipAfterRender","pn","wm","CommandChain","CONTROL_FORMAT_KEYS","HEADING_SIZES","CommandAdapt","draw","mutate","targets","commit","adjusted","backward","prevIdx","newPath","prevEl","hm","resetHistory","coalesceKey","carrier","atom","adjacent","depth","caretIndex","hasControl","tracking","author","insertIndex","containerPath","nodePath","childIndex","inside","atBoundary","character","controlResult","startRunIdx","endRunIdx","startRun","endRun","startNode","endNode","toDelete","idxs","pageNo","scroller","wrapper","listPath","previousIndex","previousPath","prefixLength","flex","cursorIdx","any","toggleKey","collapsed","selectedRuns","allSet","changedKeys","mergeRuns","sameRun","removedLength","sameParent","isRange","order","forward","shifted","removedPosition","leaf","startOffset","endPath","endOffset","second","startParent","startIdx","endIdx","targetPath","fromStart","fromEnd","anchorNode","focusNode","isTerminator","textFormat","formatRuns","paragraphKeys","restored","candidate","leadingSeparator","bullet","colWidth","trIndex","tdIndex","targetRow","targetCell","columnCount","_doc","insertAt","newRow","totalWidth","newColCount","newTd","lastTr","lastTdIdx","lastValue","lastIdx","lastEl","minRow","maxRow","minCol","maxCol","firstTd","allContent","padding","colIndex","widthValue","startColumn","rowIndex","nextHeight","imgSrc","imgW","imgH","cells","total","col","outer","containerIndex","tail","insertionIndex","payload","file","reader","imageType","response","blob","href","fail","hasRevision","success","selectedText","link","linkIndex","normalized","sepAny","following","catalog","levelMap","blockPath","scrollContainer","all","titleEl","keyword","PAD","textNodes","nodeIdx","needBefore","niBefore","prevValue","needAfter","niAfter","nextValue","replacement","lastSeg","isVisible","metadata","maxLevel","append","role","pass","isPageStart","pageBreak","ownedBreak","requestedStyle","lastNode","cloned","survivor","sections","caretNode","defaultStyle","paraEl","titlePath","rowNo","colNo","maxLinesInRow","cellLines","update","sides","rowSpan","external","uniform","shown","show","resolved","preset","subPath","topLevelIndex","controlElement","currentNode","insertedIndex","afterElement","found","updated","keepContent","cleared","newConfig","Command","adapt","EDITOR_PREFIX","BlockType","TEXTLIKE_ELEMENT_TYPE","EDITOR_COMPONENT","EditorComponent","DatePicker","datePickerContainer","dateWrap","datePickerTitle","preYearTitle","preMonthTitle","nowTitle","nextMonthTitle","nextYearTitle","datePickerWeek","sun","mon","tue","wed","thu","fri","sat","week","weekDom","datePickerDay","timeWrap","hourTime","minuteTime","secondTime","li","timeText","ol","isHour","isMinute","time","datePickerMenu","timeMenu","nowMenu","submitMenu","lineHeight","preY","setDate","defaults","weekList","childElement","hourTitle","minuteTitle","secondTitle","localDate","localYear","localMonth","localDay","pickYear","pickMonth","pickDay","year","month","curDay","curWeek","preDay","preStartDay","dayDom","newMonth","nextEndDay","day","isIntoView","hour","minute","hourDom","minuteDom","secondDom","timeDom","dom","pickDom","offsetParents","pointer","curr","viewRectTop","viewRectBottom","pickDateString","date","dateString","dateOption","reg","DateParticle","elementList","ordR","HERSHEY","compile","bound","xmin","xmax","polylines","ymin","ymax","zmin","zmax","SYMB","asciiMap","CONFIG","tokenize","str","tokens","parseAtom","parse","expr","takeOpt","ret","takeN","j0","cnt","chld","environments","exprs","es","sclx","scly","notFirst","computeBbox","bbox","searchHigh","lvl0","lmin","lmax","rmin","rmax","colws","erows","erow","ybds","shft","plan","tmd","mw","y0","mh","spac","wasBig","nth","ex","m2s","alt","hasLp","hasRp","bb","flatten","flat","ff","xx","isSmallHat","isVerb","nf","LaTexUtils","latex","s0","head","pdf","DEFAULT_SCALE","LaTexParticle","laTex","promise","reject","getUUID","isNumber","isSearchable","Search","matchList","alpha","matchColor","navigateColor","navigateIndexList","replaceIndex","firstMatch","ALLOWED_SRC_PROTOCOLS","isAllowedSrc","_IFrameBlock","iframeWindow","blockItemContainer","iframeBlock","iframe","contentWindow","IFrameBlock","BaseBlock","blockParticle","blockItem","_pageNo","BlockParticle","blockContainer","cacheBlock","newBlock","blockElementIds","ControlComponent","controlContainer","controlIds","DEFAULT_MAX_RECORD_COUNT","DEFAULT_COALESCE_MS","HistoryManager","now","_current","createSnapshot","HistoryComponent","ShortcutHandler","mod","clipboardCommand","computeToc","toc","numLevel","computeSearch","results","lowerKeyword","WorkerManager","_documentCurrentScript","msg","message","ThumbnailManager","publish","sources","DocxEditor","shortcut","_args","pluginCmd","isCurrent","mime","_next","historyManager","drawRef","plugin","epoch","background","EDITOR_FONT_OPTIONS","EDITOR_SIZE_OPTIONS","WATERMARK_SIZE_OPTIONS","version"],"mappings":"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AAK,mEACL,IAAK,uDACL,IAAK,kBACL,IAAK,yBACL,IAAK,8BACL,IAAK,qCACL,IAAK,wBACL,IAAK,gDACL,IAAK,YACL,IAAK,kBACL,IAAK,kCACL,IAAK,6DACL,IAAK,YACL,IAAK,4BACL,IAAK,4BACL,IAAK,YACL,IAAK,YACL,IAAK,kBACL,IAAK,kBACL,IAAK,kBACL,IAAK,wBACL,IAAK,kBACL,IAAK,sBACL,IAAK,sBACL,IAAK,wBACL,IAAK,8BACL,IAAK,gFACL,IAAK,8DACL,IAAK,kBACL,IAAK,kBACL,IAAK,cACL,IAAK,2CACL,IAAK,4EACL,IAAK,4DACL,IAAK,8CACL,IAAK,0GACL,IAAK,sHACL,IAAK,sHACL,IAAK,0CACL,IAAK,sCACL,IAAK,wBACL,IAAK,8DACL,IAAK,0DACL,IAAK,kCACL,IAAK,0BACL,IAAK,4BACL,IAAK,iCACL,IAAK,4BACL,IAAK,oBACL,IAAK,kBACL,IAAK,oBACL,IAAK,oBACL,IAAK,kDACL,IAAK,kDACL,IAAK,sEACL,IAAK,qDACL,IAAK,kEACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,sBACL,IAAK,uBACL,IAAK,wBACL,IAAK,uBACL,IAAK,wBACL,IAAK,wBACL,IAAK,wBACL,IAAK,wBACL,IAAK,gBACL,IAAK,gBACL,IAAK,gBACL,IAAK,gBACL,IAAK,sDACL,IAAK,sDACL,IAAK,oDACL,IAAK,oDACL,IAAK,iDACL,IAAK,6CACL,IAAK,0DACL,IAAK,4BACL,IAAK,wBACL,IAAK,gBACL,IAAK,kBACL,IAAK,wBACL,IAAK,wBACL,IAAK,0CACL,IAAK,kBACL,IAAK,gBACL,IAAK,mBACL,IAAK,8BACL,IAAK,kBACL,IAAK,kBACL,IAAK,wBACL,IAAK,4EACL,IAAK,4DACL,IAAK,wCACL,IAAK,wCACL,IAAK,wCACL,IAAK,wCACL,IAAK,kDACL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,aACN,KAAM,uCACN,KAAM,uCACN,KAAM,kCACN,KAAM,kCACN,KAAM,mFACN,KAAM,mFACN,KAAM,eACN,KAAM,eACN,KAAM,aACN,KAAM,oBACN,KAAM,YACN,KAAM,kBACN,KAAM,wBACN,KAAM,wBACN,KAAM,kBACN,KAAM,kBACN,KAAM,oCACN,KAAM,kBACN,KAAM,wBACN,KAAM,wBACN,KAAM,cACN,KAAM,cACN,KAAM,0BACN,KAAM,0BACN,KAAM,gDACN,KAAM,sCACN,KAAM,sBACN,KAAM,oBACN,KAAM,oBACN,KAAM,kCACN,KAAM,sBACN,KAAM,sBACN,KAAM,sBACN,KAAM,sBACN,KAAM,4BACN,KAAM,4BACN,KAAM,4BACN,KAAM,4BACN,KAAM,kCACN,KAAM,gCACN,KAAM,gCACN,KAAM,gCACN,KAAM,gCACN,KAAM,gFACN,KAAM,oCACN,KAAM,0BACN,KAAM,4DACN,KAAM,wFACN,KAAM,2DACN,KAAM,0DACN,KAAM,wFACN,KAAM,gEACN,KAAM,4EACN,KAAM,gCACN,KAAM,wFACN,KAAM,iEACN,KAAM,2FACN,KAAM,8BACN,KAAM,uDACN,KAAM,wEACN,KAAM,oDACN,KAAM,uDACN,KAAM,wDACN,KAAM,wDACN,KAAM,4DACN,KAAM,4DACN,KAAM,4DACN,KAAM,4DACN,KAAM,8CACN,KAAM,oDACN,KAAM,8BACN,KAAM,0EACN,KAAM,0EACN,KAAM,0DACN,KAAM,kDACN,KAAM,+CACN,KAAM,+CACN,KAAM,8BACN,KAAM,8BACN,KAAM,uFACN,KAAM,uFACN,KAAM,uDACN,KAAM,uDACN,KAAM,gCACN,KAAM,wEACN,KAAM,2CACN,KAAM,gGACN,KAAM,uEACN,KAAM,kEACN,KAAM,mDACN,KAAM,8CACN,KAAM,uFACN,KAAM,8DACN,KAAM,8BACN,KAAM,8CACN,KAAM,6DACN,KAAM,kCACN,KAAM,kEACN,KAAM,iDACN,KAAM,8FACN,KAAM,gEACN,KAAM,uIACN,KAAM,gGACN,KAAM,2EACN,KAAM,uCACN,KAAM,qDACN,KAAM,qCACN,KAAM,sDACN,KAAM,iDACN,KAAM,+CACN,KAAM,uCACN,KAAM,2CACN,KAAM,gGACN,KAAM,kCACN,KAAM,qCACN,KAAM,mDACN,KAAM,uCACN,KAAM,8DACN,KAAM,sHACN,KAAM,8BACN,KAAM,6DACN,KAAM,qCACN,KAAM,kEACN,KAAM,iDACN,KAAM,gFACN,KAAM,8FACN,KAAM,kDACN,KAAM,gEACN,KAAM,8CACN,KAAM,uCACN,KAAM,yEACN,KAAM,sGACN,KAAM,iDACN,KAAM,yFACN,KAAM,4FACN,KAAM,2CACN,KAAM,wFACN,KAAM,2EACN,KAAM,kEACN,KAAM,kDACN,KAAM,+CACN,KAAM,4FACN,KAAM,6DACN,KAAM,8BACN,KAAM,gDACN,KAAM,4DACN,KAAM,mCACN,KAAM,qEACN,KAAM,iDACN,KAAM,0FACN,KAAM,8DACN,KAAM,gIACN,KAAM,0FACN,KAAM,6EACN,KAAM,wCACN,KAAM,yDACN,KAAM,sCACN,KAAM,sDACN,KAAM,iDACN,KAAM,8CACN,KAAM,wCACN,KAAM,mGACN,KAAM,oFACN,KAAM,yEACN,KAAM,8DACN,KAAM,8EACN,KAAM,oEACN,KAAM,kDACN,KAAM,mIACN,KAAM,8DACN,KAAM,0CACN,KAAM,wDACN,KAAM,6DACN,KAAM,8BACN,KAAM,+FACN,KAAM,8DACN,KAAM,+EACN,KAAM,+EACN,KAAM,yEACN,KAAM,oDACN,KAAM,sEACN,KAAM,sCACN,KAAM,8DACN,KAAM,oCACN,KAAM,sDACN,KAAM,iDACN,KAAM,kDACN,KAAM,sCACN,KAAM,sFACN,KAAM,yHACN,KAAM,+DACN,KAAM,+FACN,KAAM,sEACN,KAAM,oEACN,KAAM,sEACN,KAAM,8FACN,KAAM,oCACN,KAAM,iEACN,KAAM,qDACN,KAAM,+DACN,KAAM,uDACN,KAAM,kGACN,KAAM,sEACN,KAAM,kDACN,KAAM,oEACN,KAAM,4EACN,KAAM,uCACN,KAAM,qEACN,KAAM,gFACN,KAAM,oDACN,KAAM,0EACN,KAAM,8FACN,KAAM,qFACN,KAAM,8EACN,KAAM,wDACN,KAAM,2FACN,KAAM,0DACN,KAAM,4EACN,KAAM,6FACN,KAAM,qEACN,KAAM,0DACN,KAAM,sEACN,KAAM,2EACN,KAAM,0CACN,KAAM,kHACN,KAAM,iFACN,KAAM,sEACN,KAAM,2FACN,KAAM,yEACN,KAAM,0DACN,KAAM,8DACN,KAAM,0CACN,KAAM,iFACN,KAAM,2DACN,KAAM,0FACN,KAAM,2FACN,KAAM,yFACN,KAAM,qEACN,KAAM,+FACN,KAAM,wEACN,KAAM,4EACN,KAAM,mHACN,KAAM,wHACN,KAAM,8BACN,KAAM,wDACN,KAAM,6FACN,KAAM,0FACN,KAAM,6DACN,KAAM,iGACN,KAAM,gJACN,KAAM,gHACN,KAAM,qHACN,KAAM,sLACN,KAAM,0LACN,KAAM,8CACN,KAAM,uFACN,KAAM,6BACN,KAAM,iGACN,KAAM,qGACN,KAAM,iCACN,KAAM,qFACN,KAAM,uGACN,KAAM,qEACN,KAAM,qIACN,KAAM,uGACN,KAAM,kBACN,KAAM,uBACN,KAAM,8BACN,KAAM,mCACN,KAAM,oCACN,KAAM,sEACN,KAAM,kBACN,KAAM,8BACN,KAAM,kCACN,KAAM,wBACN,KAAM,YACN,KAAM,+CACN,KAAM,+CACN,KAAM,8BACN,KAAM,8BACN,KAAM,uFACN,KAAM,uFACN,KAAM,cACN,KAAM,cACN,KAAM,YACN,KAAM,kBACN,KAAM,YACN,KAAM,kBACN,KAAM,wBACN,KAAM,wBACN,KAAM,kBACN,KAAM,kBACN,KAAM,oCACN,KAAM,kBACN,KAAM,wBACN,KAAM,wBACN,KAAM,cACN,KAAM,cACN,KAAM,0BACN,KAAM,0BACN,KAAM,gDACN,KAAM,sDACN,KAAM,sBACN,KAAM,oBACN,KAAM,oBACN,KAAM,2CACN,KAAM,sBACN,KAAM,sBACN,KAAM,sBACN,KAAM,sBACN,KAAM,0BACN,KAAM,gCACN,KAAM,gCACN,KAAM,gCACN,KAAM,gCACN,KAAM,sCACN,KAAM,4BACN,KAAM,4BACN,KAAM,4BACN,KAAM,4BACN,KAAM,+FACN,KAAM,qCACN,KAAM,0BACN,KAAM,wEACN,KAAM,4GACN,KAAM,6DACN,KAAM,sEACN,KAAM,4GACN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","x_google_ignoreList":[9,17]}