@deepseek-ai/dsh-client-ui-sidebar-documentpreview 0.1.7-alpha.2 → 0.1.7-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/client/ui-sidebar-documentpreview/README.md
5
- README.md: 5507bd89f07bfd6225d4ecc1bc4500ceb2e30fe8
6
- README.zh.md: eec96c28654ae01aca6b89862d503af6c12296e8
5
+ README.md: 03e25deb27591fb5b8864b48a5a0b44da854eb54
6
+ README.zh.md: d90d4932f210e9cff2275bdbadd5d35c1edea860
package/README.md CHANGED
@@ -59,14 +59,14 @@ When Developer tools is enabled, HTML fills the body edge to edge in a Blob ifra
59
59
 
60
60
  PNG, JPEG, GIF, WebP, BMP, ICO, and SVG render through Blob URLs in an `<img>` static-image context, rounded inside a 12px inset. Images default to fit width without enlarging content smaller than the pane; 100% uses the image's intrinsic CSS-pixel width. The shared zoom controls can produce horizontal and vertical scrolling, but do not provide drag-to-pan. Zoom changes retain the same `<img>` and Blob URL, so animated images continue playing. Raster formats can soften above their intrinsic size, while SVG remains on the browser's vector rendering path. SVG markup never enters the application DOM or an iframe, so its scripts cannot execute or reach the parent page. Replacing or unmounting the image revokes its Blob URL.
61
61
 
62
- Shared copy comes from `sidebarDocumentPreview`; each builtin renderer owns its localized labels. PDF and converted Office previews use a graphite background in light mode and a matte-black background in dark mode, with subtle page shadows and original document colors. PDF and image previews share a floating control with **Fit width**, 25%, 50%, 100%, 150%, and 200% choices plus 25% incremental zoom across the 25%–400% fixed range. Fit width is the default and tracks pane resizing; 100% means the PDF's 96-DPI page size or the image's intrinsic CSS-pixel size. On fine pointers, the control starts hidden, slides up when the pointer enters the bottom 72 CSS pixels, and slides down after a 420 ms leave delay; hover, keyboard focus, an open menu, and an active gesture keep it visible, while devices without hover keep it visible continuously. Chromium maps a macOS trackpad pinch to the same live, pointer-anchored path as Ctrl+wheel; the control displays the gesture percentage, and the settled value survives body remounts until the tab closes. HTML previews do not expose zoom controls.
62
+ Shared copy comes from `sidebarDocumentPreview`; each builtin renderer owns its localized labels. PDF and converted Office previews use a graphite background in light mode and a matte-black background in dark mode, with subtle page shadows and original document colors. PDF and image previews share a floating control with **Fit width**, 25%, 50%, 100%, 150%, and 200% choices plus 25% incremental zoom across the 25%–400% fixed range. Fit width is the default and tracks pane resizing; 100% means the PDF's 96-DPI page size or the image's intrinsic CSS-pixel size. On fine pointers, the control starts hidden, slides up when the pointer enters the bottom 72 CSS pixels, and slides down after a 420 ms leave delay; hover, keyboard focus, an open menu, and an active gesture keep it visible, while devices without hover keep it visible continuously. Chromium maps a macOS trackpad pinch to the same live, pointer-anchored path as Ctrl+wheel; the control displays the gesture percentage, and the settled value survives body remounts until the tab closes. HTML previews do not expose zoom controls. After zoom settles or fit width changes, nearby PDF pages redraw at the resolved scale multiplied by the device pixel ratio. The previous bitmap and selectable text stay visible until the replacement bitmap is ready; offscreen pages refresh when they approach the viewport.
63
63
 
64
64
  Initial reads, additional pages, and HTML/PDF/image preparation share the ongoing `StateDot` loader, which exposes its label to assistive technology and respects reduced-motion preferences; every wait before content exists centres the loader in the pane, so opening a file shows one indicator in one position until the body appears. Loaded pages stay visible while another page loads. The PDF body loads its package-local `client.pdf.js` chunk only when a PDF preview mounts; PDF.js, its Worker source, and embedded support data stay out of the startup `client.js`. PDF pages fill the pane's width edge to edge as one vertical sequence and render lazily near the viewport; an unrendered page holds its place as a quiet 3:4 placeholder block. PDF.js’s official TextLayerBuilder manages selection boundaries and normalized copying over an aligned text layer. Its companion styles keep blank line breaks unhighlighted; alignment accounts for PDF page units, page rotation, and viewport resizing, and page disposal cancels both layers. Image-only PDFs contain no selectable text. Code previews show a tertiary-colored language label and a copy icon with a tooltip; wrapping remains in the document toolbar. They show source line numbers by default without including them in copied text; plain text uses the same font size and line height as code. Code sits on the pane's own background rather than the chat card's fill; its banner is adjacent to a full-height inner scrollport, so both scrollbars begin below the copy control.
65
65
 
66
66
  <a id="excel-preview"></a>
67
67
  ## Excel preview
68
68
 
69
- Open `.xlsx`, `.xls`, `.csv`, and `.tsv` directly in the browser with worksheet tabs, cell selection, copying, and a read-only formula bar. XLSX retains fonts, solid fills, borders, number formats, rich text, merged cells, row and column sizes, hidden rows/columns/sheets, and frozen headings. XLS retains saved values, formulas, number formats, merges, and available row/column metadata; fonts, borders, and frozen panes are unsupported. Workbooks display saved formula results without recalculating; missing results remain blank, and a compact formula-bar warning marks workbooks whose displayed results may be incomplete or inaccurate. The workbook viewport follows preview pane size changes without reloading its sheets or selection. Spreadsheet preview does not call the Office conversion service.
69
+ Open `.xlsx`, `.xls`, `.csv`, and `.tsv` directly in the browser with worksheet tabs, cell selection, copying, and a read-only formula bar. XLSX retains fonts, solid fills, borders, number formats, rich text, merged cells, row and column sizes, hidden rows/columns/sheets, and frozen headings. XLS retains saved values, formulas, number formats, merges, and available row/column metadata; fonts, borders, and frozen panes are unsupported. Workbooks display saved formula results without recalculating; missing results remain blank, and a compact formula-bar warning marks workbooks whose displayed results may be incomplete or inaccurate. The workbook viewport fills the preview pane and follows its size changes without reloading its sheets or selection. Worksheet tabs start at the left edge; overflowing tabs scroll with horizontal trackpad gestures or left/right navigation beside a separate zoom control. Spreadsheet controls retain dark text on their light background in both app themes. Pixel-based trackpad gestures pan the grid on both axes together, including diagonally, at the gesture’s speed; frozen headings stay fixed. Selection statistics and inactive worksheet menu arrows are hidden. Frozen headings remain fixed while scrolling, without freeze dividers or drag handles. Spreadsheet preview does not call the Office conversion service.
70
70
 
71
71
  XLSX preview omits DrawingML parts from an in-memory copy before parsing and ignores worksheet drawing references. The original file and worksheet XML remain unchanged. A notice above the table lists detected charts, images, shapes, and conditional formatting that are not displayed, and recommends opening the workbook in a system application. Files without these detected features have no notice; formula warnings remain separate.
72
72
 
@@ -82,7 +82,7 @@ Configure `excel` on the same `ui-sidebar-documentpreview` entry. These limits c
82
82
 
83
83
  The lazy Excel chunk bundles FortuneSheet, ExcelJS for XLSX, SheetJS CE for XLS, and PapaParse for CSV/TSV. Package-local, React-independent adapters map parser output directly to FortuneSheet cells and share cell formatting and initial selection. Third-party license texts remain in the published chunk; SheetJS CE retains its Apache-2.0 terms. Each parse owns a disposable Worker and transfers a copy of retained file bytes; replacement, unmount, failure, and timeout terminate that Worker. The stylesheet is scoped to the Excel preview. Charts, drawings/images, pivot tables, conditional formatting, editing, recalculation, and export are unsupported; font availability, Excel column-width approximation, and theme-tint approximation can affect fidelity. Hyperlinks display as text without loading their targets. ExcelJS decodes entity spellings in cached XLSX string formula results again; a saved literal `&lt;` is displayed as `<`.
84
84
 
85
- The read-only formula bar displays formulas and cell text literally. Copying preserves an HTML table with escaped cell contents, including saved formula results. The [FortuneSheet patch rationale](../../../.agents/notes/implemented/feature/2026-09-16-browser-excel-preview.md) explains the requirements for retaining these behaviors and worksheet selection when upgrading the dependency.
85
+ The read-only formula bar displays formulas and cell text literally on one line, with horizontal scrolling for long content. Copying preserves an HTML table with escaped cell contents, including saved formula results. The [FortuneSheet patch rationale](../../../.agents/notes/implemented/feature/2026-09-16-browser-excel-preview.md) explains the requirements for retaining these behaviors and worksheet selection when upgrading the dependency.
86
86
 
87
87
  The pinned [ExcelJS patch](../../../patches/exceljs@4.4.0.patch) resolves the workbook, styles, shared strings, worksheets, comments, Tables, and VML through package relationships, including absolute and relative targets and ASCII case-equivalent part names, and recognizes SpreadsheetML and VML names by namespace URI. Strict OOXML SpreadsheetML and relationship URIs map to the same supported preview features; this is not full Strict conformance. XML parts accept UTF-8 and either byte order of UTF-16; CDATA contributes literal text. Drawing and conditional-format notices follow relationships regardless of part directories. Unreferenced `xl/drawings/*.xml` parts and their relationship files are also omitted, without adding notices; comment VML remains. Missing referenced parts and ambiguous case-equivalent ZIP entries fail the preview. Comments and Table metadata survive parsing but have no dedicated preview controls. The patch covers the Node sources and `dist/exceljs.js`; its browser entry selects that patched bundle. Dependency upgrades must preserve both entry paths and pass the [independent-writer regressions and fuzz diagnostics](tests/fuzz/README.md).
88
88
 
@@ -134,7 +134,7 @@ No direct effect; what the user reads here never enters a model request.
134
134
  - **Preview, not editing.** The viewers provide no file editing or shared search interface; a directory address fails with `not-regular-file`. Unknown extensions use the plain-text reader and remain subject to its UTF-8/NUL checks.
135
135
  - **Office conversion limits.** The preview does not launch native Office editors or download an engine. Binary `.doc` and `.ppt` files return no missing-font diagnostics. Conversion fidelity and resource limits belong to the [LibreOffice provider](../../document/office-to-pdf/README.md).
136
136
  - **Sequential text and bounded complete files.** Deep source lines require the preceding pages; PDF, HTML, and images require a complete result within the Host's `maxFileBytes` cap.
137
- - **PDF zoom does not increase raster resolution.** PDF pages render at 96 DPI times the device pixel ratio, subject to the existing 16-million-pixel canvas limit, and fixed zoom enlarges that bitmap. High percentages can therefore soften page text; viewport-near rerendering at the settled zoom remains deferred.
137
+ - **PDF raster allocation is bounded.** Each page bitmap is capped at 16,777,216 pixels; very large pages or high zoom on high-density displays can still render below device resolution.
138
138
  - **Byte-view scroll state is not restored.** PDF, HTML, and images can return to the top when their renderer remounts or reloads; fixed PDF and image zoom can overflow horizontally, and HTML iframe scrolling belongs to its opaque browsing context.
139
139
  - **Finite local HTML dependencies.** Only direct classic `.js` and stylesheet `.css` references are packed. Browser-resolved resources retain browser origin and network restrictions; no runtime file-read bridge is exposed to the iframe.
140
140
  - **Scroll writes are unthrottled.** Every scroll event records its offset in the store; the line blocks are memoized so the resulting re-render hands React the same elements back.
package/README.zh.md CHANGED
@@ -59,14 +59,14 @@ Web 和桌面端均通过开发者工具选择 HTML 预览策略。渲染器从
59
59
 
60
60
  PNG、JPEG、GIF、WebP、BMP、ICO 和 SVG 通过 Blob URL 在 `<img>` 静态图片上下文中渲染,带 12px 内边距和圆角。图片默认适应宽度,但不会放大小于面板的内容;100% 使用图片的固有 CSS 像素宽度。共享缩放控件可产生横向和纵向滚动,但不提供拖拽平移。缩放不会替换 `<img>` 或 Blob URL,因此动画图片会继续播放。位图超过固有尺寸后可能变虚,SVG 则继续使用浏览器的矢量渲染路径。SVG 标记绝不进入应用 DOM 或 iframe,因此其中的脚本无法执行,也无法访问父页面。替换或卸载图片会撤销其 Blob URL。
61
61
 
62
- 共享文案来自 `sidebarDocumentPreview`;各内置渲染器拥有自己的本地化标签。PDF 与转换后的 Office 预览在浅色模式下使用石墨灰底色,在深色模式下使用哑黑底色,页面带有轻微阴影并保留文档原色。PDF 与图片预览共用浮动控件,提供**适应宽度**、25%、50%、100%、150% 和 200% 选项,并在 25%–400% 固定范围内按 25% 逐级缩放。适应宽度是默认模式并跟随面板尺寸;100% 表示 PDF 的 96 DPI 页面尺寸或图片的固有 CSS 像素尺寸。在精细指针设备上,控件初始隐藏;指针进入底部 72 个 CSS 像素时向上滑入,离开 420 ms 后向下退出;控件悬停、键盘焦点、菜单展开和手势进行期间保持显示,无 hover 的设备则始终显示。Chromium 将 macOS 触控板捏合映射到与 Ctrl+滚轮相同的实时指针锚定路径;控件同步显示手势比例,静止后的值在正文重新挂载后继续保留,直至 tab 关闭。HTML 预览不显示缩放控件。
62
+ 共享文案来自 `sidebarDocumentPreview`;各内置渲染器拥有自己的本地化标签。PDF 与转换后的 Office 预览在浅色模式下使用石墨灰底色,在深色模式下使用哑黑底色,页面带有轻微阴影并保留文档原色。PDF 与图片预览共用浮动控件,提供**适应宽度**、25%、50%、100%、150% 和 200% 选项,并在 25%–400% 固定范围内按 25% 逐级缩放。适应宽度是默认模式并跟随面板尺寸;100% 表示 PDF 的 96 DPI 页面尺寸或图片的固有 CSS 像素尺寸。在精细指针设备上,控件初始隐藏;指针进入底部 72 个 CSS 像素时向上滑入,离开 420 ms 后向下退出;控件悬停、键盘焦点、菜单展开和手势进行期间保持显示,无 hover 的设备则始终显示。Chromium 将 macOS 触控板捏合映射到与 Ctrl+滚轮相同的实时指针锚定路径;控件同步显示手势比例,静止后的值在正文重新挂载后继续保留,直至 tab 关闭。HTML 预览不显示缩放控件。缩放稳定或适应宽度发生变化后,视口附近的 PDF 页面按最终缩放比例乘以设备像素比重绘。新位图完成前保留原有画面和可选文字层;屏幕外的页面在接近视口时更新。
63
63
 
64
64
  首次读取、追加页及 HTML/PDF/图片准备共用 ongoing `StateDot` loading,其标签暴露给辅助技术,并遵循减少动态效果偏好;内容出现前的每个等待都把 loading 居中在面板中,打开文件到正文出现始终是同一位置的一个标记。下一页加载期间保留已显示的内容。PDF 正文仅在 PDF 预览挂载时加载包内 `client.pdf.js` chunk;PDF.js、Worker 源码和内嵌支持数据不会进入启动 `client.js`。PDF 页面贴边占满面板宽度,组成一个纵向连续序列并在接近视口时惰性渲染;未渲染的页以安静的 3:4 占位块保持位置。PDF.js 官方 TextLayerBuilder 在与画面重合的文字层上管理选区边界和复制文本规范化。配套样式不高亮空白换行;对齐同时考虑 PDF 页面单位、页面旋转与视口宽度变化,页面释放时取消两层渲染。纯图片 PDF 不包含可选取的文字。代码预览使用 tertiary 色的语言名称和带提示的复制图标;换行仍由文档工具栏控制。默认显示源码行号,但复制文本不包含行号;纯文本与代码使用相同字号和行高。代码直接坐在分栏自身的背景上,而不是会话卡片的填充色;复制条与占满剩余高度的内部滚动区相邻,因此横纵滚动条都从复制控件下方开始。
65
65
 
66
66
  <a id="excel-preview"></a>
67
67
  ## Excel 预览
68
68
 
69
- 直接在浏览器中打开 `.xlsx`、`.xls`、`.csv` 和 `.tsv`,支持工作表标签、单元格选择、复制和只读公式栏。XLSX 保留字体、纯色填充、边框、数字格式、富文本、合并单元格、行列尺寸、隐藏行列及工作表,以及冻结标题。XLS 保留已保存的值、公式、数字格式、合并及可用的行列元数据;不支持字体、边框和冻结窗格。工作簿显示已保存的公式结果而不重新计算;缺少的结果保持为空,公式栏旁的紧凑提示会标记显示结果可能不完整或不准确的工作簿。工作簿视图随预览面板尺寸变化自动调整,无需重新加载工作表或选择状态。表格预览不调用 Office 转换服务。
69
+ 直接在浏览器中打开 `.xlsx`、`.xls`、`.csv` 和 `.tsv`,支持工作表标签、单元格选择、复制和只读公式栏。XLSX 保留字体、纯色填充、边框、数字格式、富文本、合并单元格、行列尺寸、隐藏行列及工作表,以及冻结标题。XLS 保留已保存的值、公式、数字格式、合并及可用的行列元数据;不支持字体、边框和冻结窗格。工作簿显示已保存的公式结果而不重新计算;缺少的结果保持为空,公式栏旁的紧凑提示会标记显示结果可能不完整或不准确的工作簿。工作簿视图填满预览面板,并随面板尺寸变化自动调整,无需重新加载工作表或选择状态。工作表标签从左侧边缘开始排列;标签溢出时可用触控板横向手势或左右按钮滚动,缩放控件独立占位。表格控件在应用的明暗两种主题下均保持浅色背景和深色文字。触控板的像素位移可同时平移表格的横纵两个方向,包括斜向平移,移动距离跟随手势;冻结标题保持固定。隐藏选区统计栏及无效的工作表菜单箭头。冻结标题在滚动时保持固定,不显示冻结分隔线和拖拽条。表格预览不调用 Office 转换服务。
70
70
 
71
71
  XLSX 预览在解析前从内存副本中移除 DrawingML 部件,并忽略工作表的绘图引用。原文件和工作表 XML 保持不变。表格上方的提示列出实际检测到但未展示的图表、图片、形状和条件格式,并建议使用系统应用打开工作簿。未检测到这些内容的文件不显示此提示;公式提示保持独立。
72
72
 
@@ -82,7 +82,7 @@ CSV 和 TSV 默认使用表格查看器,也可选择纯文本。两者分别
82
82
 
83
83
  惰性 Excel chunk 打包 FortuneSheet、用于 XLSX 的 ExcelJS、用于 XLS 的 SheetJS CE,以及用于 CSV/TSV 的 PapaParse。包内独立于 React 的适配层将解析结果直接映射为 FortuneSheet 单元格,并复用单元格格式化和初始选区。第三方许可证文本保留在发布的 chunk 中;SheetJS CE 保留其 Apache-2.0 条款。每次解析拥有一个独立可释放的 Worker,并传输所保留文件字节的副本;内容替换、卸载、失败或超时都会终止该 Worker。样式表仅作用于 Excel 预览区域。暂不支持图表、绘图/图片、数据透视表、条件格式、编辑、重新计算和导出;字体可用性、Excel 列宽近似和主题色明暗近似会影响保真度。超链接显示为文本,不加载目标地址。ExcelJS 会再次解码 XLSX 字符串公式缓存结果中的实体写法;保存的字面文本 `&lt;` 会显示为 `<`。
84
84
 
85
- 只读公式栏按字面显示公式和单元格文本。复制时保留 HTML 表格,并转义单元格内容,包括已保存的公式结果。[FortuneSheet 补丁决策](../../../.agents/notes/implemented/feature/2026-09-16-browser-excel-preview.zh.md)说明升级依赖时保留这些行为与工作表选区的要求。
85
+ 只读公式栏以单行按字面显示公式和单元格文本,长内容可横向滚动。复制时保留 HTML 表格,并转义单元格内容,包括已保存的公式结果。[FortuneSheet 补丁决策](../../../.agents/notes/implemented/feature/2026-09-16-browser-excel-preview.zh.md)说明升级依赖时保留这些行为与工作表选区的要求。
86
86
 
87
87
  固定版本的 [ExcelJS 补丁](../../../patches/exceljs@4.4.0.patch)通过包内关系解析工作簿、样式、共享字符串、工作表、批注、Table 和 VML,支持绝对及相对目标,以及 ASCII 大小写等价的部件名,并按命名空间 URI 识别 SpreadsheetML 和 VML 名称。Strict OOXML 的 SpreadsheetML 和关系 URI 映射到相同的已支持预览功能;这不代表完整支持 Strict 标准。XML 部件支持 UTF-8 及两种字节序的 UTF-16;CDATA 按字面文本读取。绘图和条件格式提示按关系查找内容,不依赖部件目录。未被引用的 `xl/drawings/*.xml` 部件及其关系文件也会被移除,但不会产生提示;批注 VML 保持不变。缺失引用部件或存在大小写等价的歧义 ZIP 条目会使预览失败。解析保留批注和 Table 元数据,但预览器没有专门展示它们的控件。补丁同时覆盖 Node 源码和 `dist/exceljs.js`,浏览器入口选择已修补的 bundle。升级依赖时必须保留两个入口的行为,并通过[独立写入器回归测试和 fuzz 诊断](tests/fuzz/README.zh.md)。
88
88
 
@@ -134,7 +134,7 @@ Office Remote 通过 Connection 的 multipart 二进制传输返回原生 `Uint8
134
134
  - **预览而非编辑。** 查看器不提供文件编辑或共享搜索接口;目录地址以 `not-regular-file` 失败。未知扩展名使用纯文本读取,仍受其 UTF-8/NUL 检查限制。
135
135
  - **Office 转换限制。** 预览不启动原生 Office 编辑器,也不下载引擎。二进制 `.doc` 和 `.ppt` 文件不返回缺失字体诊断。转换保真度与资源限制由 [LibreOffice 提供方](../../document/office-to-pdf/README.zh.md)负责。
136
136
  - **文本顺序分页,完整文件受限。** 定位到较深处的源码行需要先加载此前各页;PDF、HTML 和图片必须取得 Host `maxFileBytes` 上限内的完整结果。
137
- - **PDF 缩放不会提高栅格分辨率。** PDF 页面按 96 DPI 乘以设备像素比绘制,并受现有 1600 万像素 Canvas 上限约束;固定缩放会放大这张位图,因此高比例下页面文字可能变虚。按稳定缩放比例重绘视口附近页面仍属于延期工作。
137
+ - **PDF 栅格分配有上限。** 每页位图最多为 16,777,216 像素;超大页面或高像素密度屏幕上的高比例缩放仍可能低于设备分辨率。
138
138
  - **字节视图不恢复滚动位置。** PDF、HTML 与图片的渲染器重新挂载或重新载入时可能回到顶部;固定 PDF 与图片缩放可产生横向滚动,HTML iframe 的滚动属于其不透明浏览上下文。
139
139
  - **本地 HTML 依赖集合有限。** 只打包直接引用的经典 `.js` 脚本和 `.css` 样式表。浏览器解析的资源仍受浏览器源与网络规则限制;iframe 不获得运行时文件读取桥接。
140
140
  - **滚动写入未节流。** 每次滚动事件都把偏移记进 store;行块已 memo 化,于是由此引发的重渲染交还给 React 的是同一批元素。
@@ -28117,7 +28117,7 @@ window.__ModuleLoader__.load({
28117
28117
  return stringify(rnds);
28118
28118
  }
28119
28119
  //#endregion
28120
- //#region ../../../node_modules/.pnpm/@fortune-sheet+core@1.0.4_patch_hash=488dad2a7648b7d4df31f6bd776b7849fd0fb85be8f1acf268efff758caba3c0/node_modules/@fortune-sheet/core/dist/index.esm.js
28120
+ //#region ../../../node_modules/.pnpm/@fortune-sheet+core@1.0.4_patch_hash=886223a70a0cf76d4fa174608852763fe76bbdc9374db127665024c8c150dd68/node_modules/@fortune-sheet/core/dist/index.esm.js
28121
28121
  function _arrayLikeToArray$1(r, a) {
28122
28122
  (null == a || a > r.length) && (a = r.length);
28123
28123
  for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
@@ -117212,6 +117212,7 @@ window.__ModuleLoader__.load({
117212
117212
  {
117213
117213
  key: "drawFreezeLine",
117214
117214
  value: function drawFreezeLine(_ref2) {
117215
+ if (this.sheetCtx.allowEdit === false) return;
117215
117216
  var horizontalTop = _ref2.horizontalTop, verticalLeft = _ref2.verticalLeft;
117216
117217
  var renderCtx = this.canvasElement.getContext("2d");
117217
117218
  if (!renderCtx) return;
@@ -119983,6 +119984,12 @@ window.__ModuleLoader__.load({
119983
119984
  var _cache$searchDialog;
119984
119985
  if (((_cache$searchDialog = cache.searchDialog) === null || _cache$searchDialog === void 0 ? void 0 : _cache$searchDialog.mouseEnter) && ctx.showSearch && ctx.showReplace) return;
119985
119986
  if (ctx.filterContextMenu != null) return;
119987
+ if (ctx.allowEdit === false && e.deltaMode === 0) {
119988
+ scrollbarX.scrollLeft += e.deltaX;
119989
+ scrollbarY.scrollTop += e.deltaY;
119990
+ e.preventDefault();
119991
+ return;
119992
+ }
119986
119993
  var scrollLeft = scrollbarX.scrollLeft;
119987
119994
  var scrollTop = scrollbarY.scrollTop;
119988
119995
  var visibledatacolumn_c = ctx.visibledatacolumn;
@@ -123098,7 +123105,7 @@ window.__ModuleLoader__.load({
123098
123105
  an.createDraft.bind(an);
123099
123106
  an.finishDraft.bind(an);
123100
123107
  //#endregion
123101
- //#region ../../../node_modules/.pnpm/@fortune-sheet+react@1.0.4_patch_hash=c17549e117c8fb99f408497c1e84292c21f25516fb762a325_8b85be79aa50b34ab61b9b25a7ac8f27/node_modules/@fortune-sheet/react/dist/index.esm.js
123108
+ //#region ../../../node_modules/.pnpm/@fortune-sheet+react@1.0.4_patch_hash=2932e52e79afcd4ced08cfa123b5eded786c85043da32f622_87505320529149716b9d208b3b5e2a06/node_modules/@fortune-sheet/react/dist/index.esm.js
123102
123109
  var import_runtime = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
123103
123110
  /**
123104
123111
  * Copyright (c) 2014-present, Facebook, Inc.
@@ -129914,8 +129921,17 @@ window.__ModuleLoader__.load({
129914
129921
  (0, react.useEffect)(function() {
129915
129922
  var tabCurrent = tabContainerRef.current;
129916
129923
  if (!tabCurrent) return;
129917
- setIsShowScrollBtn(tabCurrent.scrollWidth - 2 > tabCurrent.clientWidth);
129918
- }, [context.luckysheetfile]);
129924
+ var availableWidth = tabCurrent.clientWidth;
129925
+ if (context.allowEdit === false) {
129926
+ availableWidth += leftScrollRef.current ? leftScrollRef.current.offsetWidth : 0;
129927
+ availableWidth += rightScrollRef.current ? rightScrollRef.current.offsetWidth : 0;
129928
+ }
129929
+ setIsShowScrollBtn(tabCurrent.scrollWidth - 2 > availableWidth);
129930
+ }, [
129931
+ context.luckysheetfile,
129932
+ context.allowEdit,
129933
+ context.luckysheetTableContentHW[0]
129934
+ ]);
129919
129935
  var onAddSheetClick = (0, react.useCallback)(function() {
129920
129936
  return setTimeout(function() {
129921
129937
  setContext(function(draftCtx) {
@@ -133550,7 +133566,7 @@ window.__ModuleLoader__.load({
133550
133566
  }), /*#__PURE__*/ react.default.createElement("div", { className: "fortune-stat-area" }, /*#__PURE__*/ react.default.createElement("div", { className: "luckysheet-sheet-selection-calInfo" }, !!calInfo.count && /*#__PURE__*/ react.default.createElement("div", { style: { width: "60px" } }, formula.count, ": ", calInfo.count), !!calInfo.numberC && !!calInfo.sum && /*#__PURE__*/ react.default.createElement("div", null, formula.sum, ": ", calInfo.sum), !!calInfo.numberC && !!calInfo.average && /*#__PURE__*/ react.default.createElement("div", null, formula.average, ": ", calInfo.average), !!calInfo.numberC && !!calInfo.max && /*#__PURE__*/ react.default.createElement("div", null, formula.max, ": ", calInfo.max), !!calInfo.numberC && !!calInfo.min && /*#__PURE__*/ react.default.createElement("div", null, formula.min, ": ", calInfo.min))))));
133551
133567
  });
133552
133568
  //#endregion
133553
- //#region \0dsh-inline-css:/home/runner/work/deepseek-harness/deepseek-harness/node_modules/.pnpm/@fortune-sheet+react@1.0.4_patch_hash=c17549e117c8fb99f408497c1e84292c21f25516fb762a325_8b85be79aa50b34ab61b9b25a7ac8f27/node_modules/@fortune-sheet/react/dist/index.css.mjs
133569
+ //#region \0dsh-inline-css:/home/runner/work/deepseek-harness/deepseek-harness/node_modules/.pnpm/@fortune-sheet+react@1.0.4_patch_hash=2932e52e79afcd4ced08cfa123b5eded786c85043da32f622_87505320529149716b9d208b3b5e2a06/node_modules/@fortune-sheet/react/dist/index.css.mjs
133554
133570
  var index_css_default = ".fortune-container{background-color:#fff;flex-direction:column;width:100%;height:100%;margin:0;padding:0;font-family:Helvetica Neue,Helvetica,Arial,PingFang SC,Hiragino Sans GB,Heiti SC,Microsoft YaHei,WenQuanYi Micro Hei,sans-serif;display:flex;position:relative}.fortune-workarea{width:100%}.fortune-popover-backdrop{z-index:1003;width:100%;height:100%;position:absolute;top:0;left:0}.fortune-modal-container{background:#ffffff80;justify-content:center;align-items:center;display:flex}html::-webkit-scrollbar-button{display:none}.fortune-stat-area{justify-content:flex-end;align-items:center;display:flex}.fortune-sheet-container{flex-direction:column;flex:1;display:flex}.fortune-col-body{flex-direction:row;flex:1;display:flex}.fortune-sheet-area{flex:1;position:relative}.fortune-sheet-canvas-placeholder,.fortune-sheet-canvas{width:100%;height:100%;display:block}.fortune-sheet-canvas{position:absolute}.fortune-sheet-overlay{outline-style:none;width:100%;height:100%;position:absolute}.fortune-cell-area{border-collapse:collapse;cursor:default;outline-style:none;position:relative;overflow:hidden}.fortune-row-body{flex-direction:row;display:flex}.fortune-row-header{color:#5e5e5e;cursor:default;outline-style:none;flex-shrink:0;width:45px;margin-top:-2px;padding:2px 0 0;position:relative;overflow:hidden}.fortune-row-header-hover{z-index:11;background-color:#c2c2c266;border:0;width:100%;margin-top:2px;display:none;position:absolute;right:0}.fortune-row-header-selected{z-index:10;background-color:#4c4c4c1a;border-right:1px solid #0188fb;width:100%;margin-top:2px;display:none;position:absolute;right:0}.fortune-col-header-wrap{flex-direction:row;display:flex}.fortune-col-header{color:#5e5e5e;cursor:default;outline-style:none;flex:1;height:19px;padding:0;position:relative;overflow:hidden}.fortune-col-header-hover{color:#5e5e5e;cursor:default;z-index:11;background-color:#c2c2c266;border:0;height:100%;margin-left:0;display:none;position:absolute;bottom:0}.fortune-col-header-hover .header-arrow{position:absolute;top:50%;right:6px;transform:translateY(-44%)}.fortune-col-header-selected{color:#5e5e5e;cursor:default;z-index:10;background-color:#4c4c4c1a;border-bottom:1px solid #0188fb;height:100%;margin-left:0;display:none;position:absolute;bottom:0}.fortune-left-top{cursor:pointer;background-color:#fff;border:1px solid #dfdfdf;border-width:0 1px 1px 0;width:44.5px;height:18.5px;padding-top:0;padding-left:0;position:relative}.fortune-add-row-button{cursor:pointer;color:#262a33;background-color:#fff;border:1px solid #c8c8c8;border-radius:4px;outline:none;align-items:center;margin:0 8px;padding:1px 20px;font-size:14px;line-height:20px;display:inline-flex}.luckysheet-cell-selected-focus{pointer-events:none;z-index:14;background:#0050d026;margin:0;display:none;position:absolute}.fortune-selection-copy{pointer-events:none;z-index:18;border:none;margin:0;position:absolute}.fortune-selection-copy .fortune-copy{z-index:18;background-color:#0000;position:absolute}.fortune-selection-highlight{z-index:14;border:none;margin:0;position:absolute}.fortune-cell-selected-extend{pointer-events:none;z-index:16;border:1px dashed #0188fb;margin:-1px 0 0 -1px;display:none;position:absolute}.fortune-cell-selected-move{cursor:move;z-index:16;border:2px solid #0188fb;margin:-1px 0 0 -1px;display:none;position:absolute}.luckysheet-cell-selected{pointer-events:none;z-index:15;box-sizing:content-box;background:#0188fb26;border:1px solid #0188fb;margin:-1px 0 0 -1px;display:none;position:absolute}.luckysheet-cs-inner-border{pointer-events:none;border:1px solid #fff;position:absolute;inset:0}.luckysheet-cs-fillhandle{cursor:crosshair;z-index:16;pointer-events:auto;background-color:#0188fb;border:1px solid #fff;width:6px;height:6px;position:absolute;bottom:-5px;right:-5px}.luckysheet-cs-draghandle{cursor:move;opacity:.01;z-index:15;pointer-events:auto;background-color:#fff;border:2px solid #fff;position:absolute}.luckysheet-cs-draghandle-top{height:2px;top:-4px;left:-2px;right:-2px}.luckysheet-cs-draghandle-bottom{height:2px;bottom:-4px;left:-2px;right:0}.luckysheet-cs-draghandle-left{width:2px;top:0;bottom:0;left:-4px}.luckysheet-cs-draghandle-right{width:2px;top:0;bottom:0;right:-4px}.luckysheet-cs-touchhandle{z-index:100;pointer-events:auto;touch-action:auto;width:16px;height:16px;padding:5px;display:none;position:absolute}.luckysheet-cs-touchhandle:before{content:\"\";box-sizing:border-box;background-color:#fff;border:.5px solid #00000026;border-radius:50%;width:16px;height:16px;display:block}.luckysheet-cs-touchhandle-lt{top:-13px;left:-13px}.luckysheet-cs-touchhandle-lb{bottom:-13px;left:-13px}.luckysheet-cs-touchhandle-rt{top:-13px;right:-13px}.luckysheet-cs-touchhandle-rb{bottom:-13px;right:-13px}.luckysheet-cs-touchhandle .luckysheet-cs-touchhandle-btn{box-sizing:border-box;z-index:11;background-color:#018ffb;background-position:50%;border-radius:50%;width:10px;height:10px;position:absolute;top:8px;left:8px}.luckysheet-input-box{z-index:15;flex-direction:column;font:400 13px arial,sans,sans-serif;display:flex;position:absolute}.luckysheet-input-box-inner{text-align:left;resize:none;white-space:pre-wrap;word-wrap:break-word;box-sizing:border-box;background-color:#fff;border:1px solid #5292f7;outline:none;max-width:9900px;max-height:9900px;margin:0;padding:0 2px;font:400 13px arial,sans,sans-serif;right:auto;overflow:hidden auto;-webkit-box-shadow:0 2px 5px #0006;-moz-box-shadow:0 2px 5px #0006;box-shadow:0 2px 5px #0006}.luckysheet-cell-input{cursor:text;white-space:pre-wrap;outline:none;width:100%;margin:0}.luckysheet-formula-text-color{color:#000}.luckysheet-formula-text-string{color:#228b22}.luckysheet-cell-flow{touch-action:manipulation;border:0;margin:0;padding:0;position:relative}.luckysheet-cell-flow-clip{border-collapse:collapse;cursor:default;touch-action:manipulation;width:5000000px;overflow:hidden}.luckysheet-cell-flow-col{touch-action:manipulation;float:left;direction:ltr;border:0;margin:0;padding:0;position:relative;overflow:hidden}.luckysheet-cell-sheettable{text-align:left;color:#000;font-size:11pt;text-decoration:none;position:relative}.luckysheet-bottom-controll-row{z-index:1000;height:30px;position:absolute;bottom:38px;left:0}#luckysheet-bottom-add-row{margin-top:-2px;margin-right:5px;padding:5px 20px}#luckysheet-bottom-add-row-input{width:40px;min-width:40px}#luckysheet-bottom-return-top{margin-top:-2px;margin-left:10px;padding:5px 6px}.luckysheet-cell-flow-column{height:inherit;width:inherit;z-index:1;touch-action:manipulation;position:absolute;top:0;left:0}.luckysheet-cell-flow-column-line{height:inherit;border-right:1px solid #d4d4d4;position:absolute}.luckysheet-cell-flow-row{text-align:left;height:inherit;width:inherit;z-index:1;touch-action:manipulation;position:absolute;top:0;left:0}.luckysheet-cell-flow-row-line{width:inherit;border-bottom:1px solid #d4d4d4;position:absolute}.fortune-cols-change-size,.fortune-rows-change-size,.fortune-change-size-line,.fortune-cols-freeze-handle,.fortune-rows-freeze-handle,.fortune-freeze-drag-line{-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;z-index:12;position:absolute}.fortune-cols-change-size{cursor:ew-resize;opacity:0;background:#0188fb;width:5px;height:100%}.fortune-rows-change-size{cursor:ns-resize;opacity:0;background:#0188fb;width:100%;height:5px}.fortune-change-size-line{z-index:15;cursor:ew-resize;border-style:solid;border-color:#0188fb}.fortune-cols-freeze-handle{cursor:grab;z-index:20;background-color:#ddd;width:3px;height:100%;position:absolute;left:0}.fortune-rows-freeze-handle{cursor:grab;z-index:20;background-color:#ddd;width:100%;height:3px;position:absolute;top:0}.fortune-freeze-drag-line{z-index:15;cursor:ew-resize;border-style:solid;border-color:#ccc}.luckysheet-postil-dialog-move{pointer-events:none;margin:0;padding:0;position:absolute;inset:0}.luckysheet-postil-dialog-move .luckysheet-postil-dialog-move-item{pointer-events:all;cursor:move;position:absolute}.luckysheet-postil-dialog-move .luckysheet-postil-dialog-move-item-t{width:100%;height:3px;top:-4px;left:0}.luckysheet-postil-dialog-move .luckysheet-postil-dialog-move-item-r{width:3px;height:100%;top:0;right:-4px}.luckysheet-postil-dialog-move .luckysheet-postil-dialog-move-item-b{width:100%;height:3px;bottom:-4px;left:0}.luckysheet-postil-dialog-move .luckysheet-postil-dialog-move-item-l{width:3px;height:100%;top:0;left:-4px}.luckysheet-postil-show-active .luckysheet-postil-dialog-move .luckysheet-postil-dialog-move-item{border-color:#0188fb}.luckysheet-postil-dialog-resize{pointer-events:none;margin:0;padding:0;position:absolute;inset:-2px}.luckysheet-postil-dialog-resize .luckysheet-postil-dialog-resize-item{pointer-events:all;border:1px solid #0188fb;width:6px;height:6px;position:absolute}.luckysheet-postil-dialog-resize .luckysheet-postil-dialog-resize-item-lt{cursor:nw-resize;top:-6px;left:-6px}.luckysheet-postil-dialog-resize .luckysheet-postil-dialog-resize-item-mt{cursor:n-resize;margin-left:-4px;top:-6px;left:50%}.luckysheet-postil-dialog-resize .luckysheet-postil-dialog-resize-item-lm{cursor:w-resize;margin-top:-4px;top:50%;left:-6px}.luckysheet-postil-dialog-resize .luckysheet-postil-dialog-resize-item-rm{cursor:e-resize;margin-top:-4px;top:50%;right:-6px}.luckysheet-postil-dialog-resize .luckysheet-postil-dialog-resize-item-rt{cursor:ne-resize;top:-6px;right:-6px}.luckysheet-postil-dialog-resize .luckysheet-postil-dialog-resize-item-lb{cursor:sw-resize;bottom:-6px;left:-6px}.luckysheet-postil-dialog-resize .luckysheet-postil-dialog-resize-item-mb{cursor:s-resize;margin-left:-4px;bottom:-6px;left:50%}.luckysheet-postil-dialog-resize .luckysheet-postil-dialog-resize-item-rb{cursor:se-resize;bottom:-6px;right:-6px}.fortune-selection-copy-top{background-position:bottom;height:2px;top:0;left:0;right:0}.fortune-selection-copy-right{width:2px;top:0;bottom:0;right:0}.fortune-selection-copy-bottom{height:2px;bottom:0;left:0;right:0}.fortune-selection-copy-left{background-position:100%;width:2px;top:0;bottom:0;left:0}.fortune-selection-copy-hc{z-index:8;border:2px dashed #12a5ff;position:absolute;inset:0}.luckysheet-modal-dialog-resize{pointer-events:none;border:2px solid #0188fb;margin:0;padding:0;position:absolute;inset:-2px}.luckysheet-modal-dialog-resize-item{pointer-events:all;background:#fff;border:2px solid #0188fb;border-radius:6px;width:6px;height:6px;position:absolute}.luckysheet-modal-dialog-resize-item-lt{cursor:se-resize;top:-6px;left:-6px}.luckysheet-modal-dialog-resize-item-mt{cursor:s-resize;margin-left:-4px;top:-6px;left:50%}.luckysheet-modal-dialog-resize-item-rt{cursor:ne-resize;top:-6px;right:-6px}.luckysheet-modal-dialog-resize-item-lm{cursor:w-resize;margin-top:-4px;top:50%;left:-6px}.luckysheet-modal-dialog-resize-item-rm{cursor:w-resize;margin-top:-4px;top:50%;right:-6px}.luckysheet-modal-dialog-resize-item-lb{cursor:ne-resize;bottom:-6px;left:-6px}.luckysheet-modal-dialog-resize-item-mb{cursor:s-resize;margin-left:-4px;bottom:-6px;left:50%}.luckysheet-modal-dialog-resize-item-rb{cursor:se-resize;bottom:-6px;right:-6px}.fortune-formula-functionrange-highlight .fortune-copy{z-index:18;cursor:move;opacity:.9;box-sizing:content-box;background:#0188fb;position:absolute}.fortune-formula-functionrange-highlight .fortune-selection-copy-top{border-top:2px solid #fff;border-bottom:2px solid #fff;top:-2px}.fortune-formula-functionrange-highlight .fortune-selection-copy-right{border-left:2px solid #fff;border-right:2px solid #fff;right:-2px}.fortune-formula-functionrange-highlight .fortune-selection-copy-bottom{border-top:2px solid #fff;border-bottom:2px solid #fff;bottom:-2px}.fortune-formula-functionrange-highlight .fortune-selection-copy-left{border-left:2px solid #fff;border-right:2px solid #fff;left:-2px}.fortune-formula-functionrange-highlight .fortune-selection-copy-hc{opacity:.03;z-index:initial;border:2px solid #5e5e5e}.fortune-selection-highlight-lt{cursor:se-resize;top:-3px;left:-3px}.fortune-selection-highlight-rt{cursor:ne-resize;top:-3px;right:-3px}.fortune-selection-highlight-lb{cursor:ne-resize;bottom:-3px;left:-3px}.fortune-selection-highlight-rb{cursor:se-resize;bottom:-3px;right:-3px}.fortune-formula-functionrange-highlight .luckysheet-highlight{z-index:19;background:#0188fb;border:1px solid #fff;width:6px;height:6px;position:absolute}.fortune-presence-username{white-space:nowrap;text-overflow:ellipsis;box-sizing:content-box;color:#fff;padding:2px 6px;font-size:12px;position:absolute;left:-2px;overflow:hidden}.fortune-presence-selection{opacity:.7;border-style:solid;border-width:1px;position:absolute}.luckysheet-filter-options{color:#897bff;cursor:pointer;z-index:200;display:\"block\";background:#fff;border:1px solid #897bff;border-radius:3px;height:15px;margin-left:0;padding:0 4px;font-size:12px;position:absolute;top:3px}.luckysheet-filter-options:hover{color:#fff;background:#897bff;border:1px solid #fff}.luckysheet-filter-options-active{color:#fff;background:#897bff;border:1px solid #897bff;padding:0 1px}.caret{border:4px solid #0000;width:0;height:0;margin-top:6px;display:inline-block}.caret.down{border-top-color:#897bff}.luckysheet-filter-options:hover .caret.down{border-top-color:#fff}.luckysheet-filter-selected{background:#fff0}#luckysheet-dataVerification-showHintBox{z-index:1000;-webkit-user-select:none;-moz-user-select:none;user-select:none;cursor:default;white-space:nowrap;background-color:#fff;border:1px solid #ccc;padding:10px;font-size:12px;display:none;position:absolute;box-shadow:0 2px 4px #0003}#luckysheet-dataVerification-dropdown-btn{z-index:10;background-color:#fff;width:20px;height:20px;display:none;position:absolute;overflow:hidden}.sr-only{clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.luckysheet-formula-search-c{color:#535353;z-index:1003;background:#fff;border:1px solid #0003;width:300px;font-size:12px;position:absolute;box-shadow:0 2px 4px #0003}.luckysheet-formula-search-c .luckysheet-formula-search-item{cursor:pointer;background:#fff;padding:5px 10px}.luckysheet-formula-search-c .luckysheet-formula-search-item .luckysheet-formula-search-detail{color:#444;display:none}.luckysheet-formula-search-c .luckysheet-formula-search-item .luckysheet-formula-search-func{color:#222;font-size:14px}.luckysheet-formula-search-c .luckysheet-formula-search-item-active{background:#f5f5f5;border-top:1px solid #ebebeb;border-bottom:1px solid #ebebeb;display:block}.luckysheet-formula-search-c .luckysheet-formula-search-item-active .luckysheet-formula-search-detail{display:block}.luckysheet-formula-help-c{color:#535353;z-index:1003;background:#fff;border:1px solid #0003;width:300px;font-size:12px;position:absolute;box-shadow:0 2px 4px #0003}.luckysheet-formula-help-c .luckysheet-formula-help-content{max-height:300px;overflow-y:scroll}.luckysheet-formula-help-content-example{margin-top:5px}.luckysheet-formula-help-title{background:#f5f5f5;border-top:1px solid #ebebeb;border-bottom:1px solid #ebebeb;padding:2px 10px;font-size:14px;display:block}.luckysheet-formula-help-title-formula{word-break:break-word;width:250px}.luckysheet-arguments-help-section{color:#222;margin-top:5px;margin-bottom:5px}.luckysheet-arguments-help-section-title{color:#666;padding:1px 10px}.luckysheet-arguments-help-parameter-content{word-wrap:break-word;padding:1px 10px;display:inline-block}.luckysheet-arguments-help-formula{padding:1px 10px;font-size:14px}.luckysheet-arguments-help-parameter-active{background-color:#fff9b2}.luckysheet-formula-help-collapse{cursor:pointer;color:#bbb;font-size:16px;position:absolute;top:0;right:25px}.luckysheet-formula-help-close{cursor:pointer;color:#bbb;font-size:16px;position:absolute;top:0;right:5px}.luckysheet-formula-help-close:hover,.luckysheet-formula-help-collapse:hover{color:#555}.luckysheet-scrollbar-ltr{z-index:1003;position:absolute;overflow:hidden}.luckysheet-scrollbar-ltr div{width:1px;height:1px}.luckysheet-scrollbar-x{bottom:0;overflow-x:scroll}.luckysheet-scrollbar-y{top:0;right:0;overflow-y:scroll}.luckysheet-scrollbar-ltr::-webkit-scrollbar{background-color:#0000;width:8px;height:8px}.luckysheet-scrollbar-ltr::-webkit-scrollbar-track{background-color:#0000}.luckysheet-scrollbar-ltr::-webkit-scrollbar-thumb{background-color:#babac0;border-radius:16px}.luckysheet-scrollbar-ltr::-webkit-scrollbar-button{display:none}.fortune-dialog{box-sizing:border-box;background:#fff;border-radius:6px;max-width:90%;max-height:90%;overflow:auto;box-shadow:5px 5px 30px #0000001a}.fortune-dialog-box-button-container{justify-content:center;align-items:center;display:flex}.fortune-dialog-box-content{padding:0 25px}.fortune-dialog-box-button-container{padding-top:10px;padding-bottom:20px}.fortune-message-box-button{cursor:pointer;border:none;border-radius:4px;outline:none;align-items:center;margin:0 8px;padding:6px 12px;font-size:14px;line-height:20px;display:inline-flex}.fortune-message-box-button.button-default{color:#262a33;background-color:#fff;border:1px solid #ebebeb}.fortune-message-box-button.button-primary{color:#fff;background-color:#0188fb}.fortune-modal-dialog-header{outline:0;justify-content:flex-end;display:flex}.fortune-modal-dialog-icon-close{color:#d4d4d4;opacity:.3}.fortune-modal-dialog-icon-close:hover{opacity:.7}#fortune-search-replace{z-index:1002;padding:30px 42px;position:absolute}#fortune-search-replace .icon-close{position:absolute;top:3px;right:3px}#fortune-search-replace .tabBox{margin-top:10px;font-size:0}#fortune-search-replace .tabBox span{text-align:center;border:1px solid #ebebeb;width:100px;font-size:14px;line-height:2;display:inline-block}#fortune-search-replace .tabBox span.on{color:#fff;background-color:#8c89fe;border-color:#726efe}#fortune-search-replace .ctBox{border:1px solid #ebebeb;min-width:500px;padding:5px 10px;font-size:14px}#fortune-search-replace .ctBox .row{flex-direction:row;justify-content:space-between;display:flex}#fortune-search-replace .inputBox{height:90px;position:relative}#fortune-search-replace .inputBox .textboxs{height:30px;line-height:30px}#fortune-search-replace .checkboxs{height:90px}#fortune-search-replace .checkboxs div{height:30px;line-height:30px}#fortune-search-replace .checkboxs input[type=checkbox]{float:left;margin-top:9px}#fortune-search-replace .btnBox{margin-top:10px}#fortune-search-replace .btnBox .button-default{margin-left:0;margin-right:8px}#fortune-search-replace .close-button{margin-top:10px;margin-left:0}#fortune-search-replace #searchAllbox{border:1px solid #d4d4d4;height:210px;margin-top:10px;position:relative;overflow-y:auto}#fortune-search-replace #searchAllbox .boxTitle{box-sizing:border-box;background-color:#fff;border-bottom:1px solid #d4d4d4;width:100%;height:30px;padding:0 5px;line-height:29px;position:sticky;top:0;left:0}#fortune-search-replace #searchAllbox .boxTitle span{text-align:center;display:inline-block}#fortune-search-replace #searchAllbox .boxTitle span:first-of-type,#fortune-search-replace #searchAllbox .boxTitle span:nth-of-type(2){width:25%}#fortune-search-replace #searchAllbox .boxTitle span:nth-of-type(3){width:50%}#fortune-search-replace #searchAllbox .boxMain .boxItem{box-sizing:border-box;border-bottom:1px solid #d4d4d4;height:30px;padding:0 5px;line-height:29px}#fortune-search-replace #searchAllbox .boxMain .boxItem.on{color:#fff;background-color:#8c89fe}#fortune-search-replace #searchAllbox .boxMain .boxItem span{text-align:center;float:left;display:block}#fortune-search-replace #searchAllbox .boxMain .boxItem span:first-of-type,#fortune-search-replace #searchAllbox .boxMain .boxItem span:nth-of-type(2){text-overflow:ellipsis;white-space:nowrap;width:25%;overflow:hidden}#fortune-search-replace #searchAllbox .boxMain .boxItem span:nth-of-type(3){text-overflow:ellipsis;white-space:nowrap;width:50%;overflow:hidden}.fortune-link-modify-modal{z-index:300;background-color:#fff;border:.5px solid #e5e5e5;border-radius:6px;padding:6px 20px 10px;position:absolute;overflow:hidden;box-shadow:0 2px 6px #00000029}.fortune-link-modify-modal.link-toolbar{flex-direction:row;align-items:center;padding:2px 8px 2px 16px;display:flex}.fortune-link-modify-modal .link-content{margin-right:6px}.fortune-link-modify-modal .link-content:hover{color:#2674fb;cursor:pointer}.fortune-link-modify-modal .divider{background-color:#e0e0e0;flex-shrink:0;width:1px;height:16px;margin:0 6px}.fortune-link-modify-modal .fortune-toolbar-button{padding:6px}.fortune-link-modify-modal .fortune-toolbar-button:hover{cursor:pointer;background-color:#0000000f}.fortune-link-modify-modal.range-selection-modal{-webkit-user-select:auto;-moz-user-select:auto;user-select:auto;background-color:#fff;width:380px;padding:22px}.fortune-link-modify-line{padding-top:10px}.fortune-link-modify-title{color:#333;width:74px;height:16px;margin-right:6px;padding:7px 0;font-size:12px;line-height:16px;display:inline-block}.fortune-link-modify-input,.fortune-link-modify-select{box-sizing:border-box;-webkit-user-select:auto;-moz-user-select:auto;-ms-user-select:auto;user-select:auto;border:1px solid #d9d9d9;border-radius:5px;outline:none;width:232px;height:26px;padding:1px 8px;font-size:12px}.fortune-link-modify-input:focus,.fortune-link-modify-modal .range-selection-input:focus{border-color:#4d90fe}.fortune-link-modify-input.error-input,.fortune-link-modify-modal .range-selection-input.error-input{border:1px solid #ef4e2f!important}.fortune-link-modify-cell-selector{cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;width:20px;padding:4px;display:inline-block;position:absolute;right:24px}.fortune-link-modify-modal .modal-title{color:#000000e0;margin-bottom:12px;font-size:16px;font-weight:500;line-height:24px}.fortune-link-modify-modal .range-selection-input{-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:1px solid #e0e0e0;border-radius:4px;outline:none;width:100%;height:32px;margin:0;padding:7px 11px;font-size:14px;display:block}.fortune-link-modify-modal .modal-icon-close{cursor:pointer;position:absolute;top:22px;right:22px}.fortune-link-modify-modal .validation-input-tip{color:#ef4e2f;height:17px;margin:3px 0;font-size:12px}.fortune-link-modify-modal .button-group{display:flex}.fortune-link-modify-modal .modal-footer{justify-content:flex-end;padding:0 0 5px;display:flex}.fortune-link-modify-modal.range-selection-modal .modal-footer{padding:0}.fortune-link-modify-modal .button-basic{cursor:pointer;border-radius:4px;flex-flow:row;justify-content:center;align-items:center;width:88px;height:32px;padding:0;font-size:14px;display:flex}.fortune-link-modify-modal .button-default{color:#262a33;background-color:#fff;border:1px solid #ebebeb}.fortune-link-modify-modal .button-primary{color:#fff;background-color:#0188fb;margin-left:14px}#fortune-data-verification{-webkit-user-select:none;-moz-user-select:none;user-select:none;min-width:500px;padding:10px 0}#fortune-data-verification .title{font-size:16px}#fortune-data-verification .box{font-size:14px}#fortune-data-verification .box .box-item{border-bottom:1px solid #e1e4e8;padding:10px}#fortune-data-verification .box .box-item .box-item-title{margin-bottom:10px;font-size:14px;font-weight:600}#fortune-data-verification .box .box-item .data-verification-range{border:1px solid #d4d4d4;width:100%;height:30px}#fortune-data-verification .box .box-item .show-box-item{margin-top:6px;font-size:12px}#fortune-data-verification .box .box-item .show-box-item .check-box{height:30px;margin-bottom:10px;line-height:30px}#fortune-data-verification .box .box-item .show-box-item .check-box input{box-sizing:border-box;border:1px solid #d4d4d4;height:30px;padding:0 10px}#fortune-data-verification .input-box input{box-sizing:border-box;border:1px solid #d4d4d4;height:30px;margin-top:6px;padding:4px 10px}#fortune-data-verification .input-box span{margin:0 16px}.data-verification-range .formulaInputFocus{width:calc(100% - 30px);height:30px;padding:0 10px px;float:left;box-sizing:border-box;border:none;outline-style:none}.data-verification-range .icon{float:right;cursor:pointer;margin-top:4px;margin-right:5px}#fortune-data-verification .box .box-item .data-verification-type-select{border-color:#d4d4d4;outline-style:none;width:100%;height:30px}#fortune-data-verification .box .box-item .check{font-size:12px;line-height:24px}#fortune-data-verification .box .box-item .check input{vertical-align:text-top}#fortune-data-verification .button-basic{text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;user-select:none;border-radius:2px;margin-top:10px;margin-bottom:0;padding:4px 8px;font-size:14px;font-weight:400;line-height:1.42857;display:inline-block}#fortune-data-verification .button-primary{color:#fff;background:#0188fb;border:1px solid #0188fb;margin-right:10px}#fortune-data-verification .button-close{color:#333;background-color:#fff;border:1px solid #ccc;margin-right:10px}#range-dialog{color:#000;z-index:100003;-webkit-user-select:none;-moz-user-select:none;user-select:none;background:#fff padding-box padding-box;border:1px solid #0005;outline:0;padding:30px 42px;position:fixed;top:50%;left:50%;transform:translate(-50%,-90%);box-shadow:0 4px 16px #0003}#range-dialog .dialog-title{color:#000;cursor:default;background-color:#fff;margin:0 0 16px;font-size:16px;font-weight:400;line-height:24px}#range-dialog input{-webkit-user-select:none;-moz-user-select:none;user-select:none;border:1px solid #d4d4d4;outline-style:none;height:30px;padding:0 10px}#range-dialog .button-primary{color:#fff;background:#0188fb;border:1px solid #0188fb;margin-right:10px}#range-dialog .button-close{color:#333;background-color:#fff;border:1px solid #ccc;margin-right:10px}#luckysheet-dataVerification-dropdown-List{z-index:10000;box-sizing:border-box;background-color:#fff;border:1px solid #ccc;font-size:12px;position:absolute;box-shadow:0 2px 4px #0003}#luckysheet-dataVerification-dropdown-List .dropdown-List-item{box-sizing:border-box;cursor:pointer;padding:5px 10px}#luckysheet-dataVerification-dropdown-List .dropdown-List-item:hover{background-color:#e1e1e1}.condition-format-sub-menu{cursor:default;z-index:1004;box-sizing:border-box;-webkit-user-select:none;-moz-user-select:none;user-select:none;background:#fff;border:1px solid #0003;outline:none;font-size:12px;position:absolute;top:-8px;box-shadow:0 2px 4px #0003}.condition-format-item{z-index:1005;justify-content:space-between;padding:6px 18px;display:flex}.condition-format-item:hover{background:#efefef}.condition-format-item span{color:#afafaf;font-size:10px}.horizontal-line{border-top:1px solid #ebebeb;margin-top:6px;margin-bottom:6px}.condition-rules .button-basic{text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;user-select:none;border-radius:2px;margin-top:10px;margin-bottom:0;padding:4px 8px;font-size:14px;font-weight:400;line-height:1.42857;display:inline-block}.condition-rules .button-primary{color:#fff;background:#0188fb;border:1px solid #0188fb;margin-right:10px}.condition-rules .button-close{color:#333;background-color:#fff;border:1px solid #ccc}.condition-rules{padding:0 42px 34px;font-size:12px}.condition-rules-title{color:#000;cursor:default;margin-bottom:18px;font-size:16px}.conditin-rules-value{margin:5px 0;font-weight:600}.condition-rules-inpbox{border:1px solid #d4d4d4;width:198px;height:28px}.condition-rules-input{float:left;border:none;outline-style:none;width:150px;height:28px;padding:0 10px}.condition-relues-inputicon{float:right;cursor:pointer;margin-top:2px;margin-right:5px}.condition-rules-set-title{margin:6px 0}.condition-rules-setbox{border:1px solid #d4d4d4}.condition-rules-set{padding:5px 10px}.condition-rules-color{height:30px;line-height:30px;position:relative}.condition-rules-check{float:left;margin-top:10px}.condition-rules-label{-webkit-user-select:none;-moz-user-select:none;user-select:none;width:80px;display:inline-block}.condition-rules-select-color{background:#f5f5f5;border:1px solid #e5e5e5;padding:2px;position:absolute;top:50%;left:50%;transform:translate(20%,-50%)}.condition-rules-between-box{align-items:center;display:flex}.condition-rules-between-inpbox{border:1px solid #d4d4d4;width:108px;height:28px}.condition-rules-between-input{float:left;border:none;outline-style:none;width:60px;height:28px;padding:0 10px}.condition-rules-date{border:none;width:98%;line-height:26px}.condition-rules-select{width:150px;height:30px}.condition-rules-project-box{align-items:center;display:flex}.condition-rules-project-input{margin:0 6px}.fortune-toolbar{white-space:nowrap;background:#fafafc;border-bottom:1px solid #d4d4d4;flex-direction:row;align-items:center;padding:5px 0 3px 15px;display:flex;position:relative}.fortune-toolbar-divider{background-color:#e0e0e0;flex-shrink:0;width:1px;height:20px;margin:0 6px}.fortune-toolbar-menu-line{justify-content:space-between;align-items:center;display:flex;position:relative}.fortune-toolbar-menu-divider{width:\"100%\";background-color:#e0e0e0;height:1px;margin:2px 6px}.fortune-toolbar-button,.fortune-toolbar-combo{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;outline:none;align-items:center;margin:2px 4px;padding:2px;text-decoration:none;list-style:none;display:flex}.fortune-toolbar-combo-button,.fortune-toolbar-combo-arrow{align-items:center;display:flex}.fortune-toolbar-button:hover,.fortune-toolbar-combo:hover,.fortune-toolbar-combo-arrow:hover{cursor:pointer;background-color:#0000000f}.fortune-toolbar-button:active,.fortune-toolbar-combo:active{cursor:pointer;background-color:#0000001f}.fortune-toobar-combo-container{position:relative}.fortune-toolbar-combo-popup{white-space:nowrap;z-index:1004;position:absolute;top:32px;left:0}.fortune-toolbar-select,.fortune-toolbar-color-picker{background:#fff;border-radius:6px;padding:10px;box-shadow:2px 2px 10px #0003}.fortune-toolbar-select{max-height:75vh;padding-left:0;padding-right:0;overflow:auto}.fortune-toolbar-combo-button{font-size:12px}.fortune-toolbar-select-option{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;min-width:60px;padding:8px 12px;font-size:12px}.fortune-toolbar-select-option:hover{background:#efefef}.fortune-toolbar-select::-webkit-scrollbar{display:none}.fortune-toolbar-color-picker-row{flex-direction:row;display:flex}.fortune-toolbar-combo-text{margin:0 4px}.fortune-toolbar-color-picker-item{cursor:pointer;width:16px;height:16px;margin:1px}.fortune-tooltip{visibility:hidden;color:#fff;text-align:center;z-index:25;white-space:nowrap;background-color:#666;border-radius:2px;padding:6px;font-size:12px;position:absolute;top:40px}.fortune-toolbar-button:hover .fortune-tooltip,.fortune-toolbar-combo:hover .fortune-tooltip{visibility:visible}.fortune-toolbar-more-container{z-index:1002;background:#fff;flex-flow:wrap;align-self:flex-end;align-items:center;max-width:348px;margin-right:40px;display:flex;position:absolute;top:40px;box-shadow:2px 2px 10px #0003}.fortune-toolbar-subtext{-o-transition:all .218s;text-align:right;opacity:.5;filter:alpha(opacity=50);color:#000;-webkit-user-select:none;-moz-user-select:none;user-select:none;padding-top:1px;padding-left:24px;font-family:Arial;font-size:12px;line-height:100%;-webkit-transition:all .218s;-moz-transition:all .218s;transition:all .218s;left:auto}.toolbar-item-sub-menu{cursor:default;z-index:1004;box-sizing:border-box;-webkit-user-select:none;-moz-user-select:none;user-select:none;background:#fff;border:1px solid #0003;border-radius:6px;outline:none;font-size:12px;position:absolute;box-shadow:0 2px 4px #0003}#fortune-custom-color{background:#f0f0f0;border:1px solid #0003;border-radius:6px;min-width:164px;font-size:12px;box-shadow:0 2px 4px #0003}#fortune-custom-color .color-reset{color:#333;cursor:pointer;white-space:nowrap;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;user-select:none;background:#fff;border-radius:6px;padding:10px 24px 10px 8px;list-style:none;position:relative}#fortune-custom-color .color-reset:hover{background:#e6e6e6}#fortune-custom-color .custom-color{background:#fff;border-radius:6px;justify-content:space-around;align-items:center;margin:1px 0;padding:10px;display:flex;position:relative}.fortune-border-select-menu{position:absolute;bottom:0}.fortune-border-color-preview{height:3px}.fortune-border-select-option{min-width:60px;height:24px;padding:8px 12px;font-size:12px;line-height:24px}.fortune-border-select-option:hover{cursor:pointer;background:#efefef}.fortune-border-style-preview{height:3px;overflow:hidden}.fortune-border-style-picker-menu{padding:0 10px}.fortune-border-style-picker-menu:hover{cursor:pointer;background:#efefef}#luckysheet-search-formula{font-size:12px}#luckysheet-search-formula .inpbox{margin-bottom:5px}#luckysheet-search-formula .inpbox div{margin-bottom:5px;display:block}#luckysheet-search-formula .inpbox input{box-sizing:border-box;border:1px solid #d4d4d4;width:100%;height:24px;padding:0 10px;font-size:12px;line-height:24px}#luckysheet-search-formula .selbox{margin-bottom:5px}#luckysheet-search-formula .selbox select{box-sizing:border-box;border:1px solid #d4d4d4;width:50%;height:24px;font-size:12px;line-height:24px}#luckysheet-search-formula .listbox label{margin-bottom:5px;display:block}#formulaTypeList,.formulaList{border:1px solid #d4d4d4;width:300px;height:170px;overflow-y:scroll}.listBox{border-bottom:1px solid #d4d4d4;padding:5px}.listBox.on{color:#fff;background-color:#8c89fe}#fortune-split-column{min-width:500px}#fortune-split-column label{-webkit-user-select:none;-moz-user-select:none;user-select:none}#fortune-split-column .title{font-size:16px}#fortune-split-column .splitDelimiters{margin-top:10px}#fortune-split-column .splitSymbols{border:1px solid #dfdfdf;margin:5px 0;padding:5px;position:relative}#fortune-split-column .splitSymbol{font-size:14px}#fortune-split-column .splitSimple{position:absolute;top:114px;left:0}#fortune-split-column #otherValue{width:50px;margin-left:5px;padding:0 5px}#fortune-split-column .splitDataPreview{margin-top:26px;font-size:14px}#fortune-split-column .splitColumnData{border:1px solid #dfdfdf;height:100px;margin:5px 0;padding:5px;overflow-y:scroll}#fortune-split-column .button-basic{text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;user-select:none;border-radius:2px;margin-bottom:0;padding:4px 8px;font-size:14px;font-weight:400;line-height:1.42857;display:inline-block}#fortune-split-column .button-primary{color:#fff;background:#0188fb;border:1px solid #0188fb;margin-right:10px}#fortune-split-column .button-close{color:#333;background-color:#fff;border:1px solid #ccc}#fortune-split-column table{border-collapse:collapse}#fortune-split-column tr{vertical-align:inherit;border-color:inherit;display:table-row}#fortune-split-column td{vertical-align:inherit;border:1px solid #333;display:table-cell}label{cursor:default}#fortune-location-condition{min-width:500px}#fortune-location-condition .title{color:#000;cursor:default;background-color:#fff;font-size:16px;font-weight:400;line-height:48px}#fortune-location-condition .listbox{color:#000;border:1px solid #dfdfdf;padding:10px;font-size:14px}#fortune-location-condition .listbox .listItem{padding:5px 0}#fortune-location-condition .listbox .listItem input[type=radio]{float:left;margin-top:5px}#fortune-location-condition .listItem{padding:5px 0}#fortune-location-condition .listItem .subItem{height:30px;padding:0 10px;display:block}#fortune-location-condition input[type=radio]{float:left;margin-top:3px}#fortune-location-condition .listbox .listItem .subbox{height:30px;padding:0 10px}#fortune-location-condition .listbox .listItem .subbox .subItem{float:left;margin-right:5px}#fortune-location-condition .button-basic{text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;user-select:none;border-radius:2px;margin-top:10px;margin-bottom:0;padding:4px 8px;font-size:14px;font-weight:400;line-height:1.42857;display:inline-block}#fortune-location-condition .button-primary{color:#fff;background:#0188fb;border:1px solid #0188fb;margin-right:10px}#fortune-location-condition .button-close{color:#333;background-color:#fff;border:1px solid #ccc}.listBox{justify-content:space-between;display:flex}.inpbox{margin-bottom:10px}.decimal-places-input{width:70px}.format-list{border:1px solid #d4d4d4;width:300px;height:170px;overflow-y:scroll}.fortune-fx-editor{border-bottom:1px solid #d4d4d4;flex-direction:row;height:28px;display:flex}.fortune-fx-icon{align-items:center;margin:0 12px;display:flex}.fortune-name-box-container{border-right:1px solid #d4d4d4;align-items:center;width:99px;font-size:14px;display:flex}.fortune-name-box{text-align:center;cursor:text;white-space:nowrap;word-wrap:break-word;-webkit-nbsp-mode:space;-webkit-line-break:after-white-space;background-color:#fff;outline:none;width:100%;margin:0;overflow:hidden;-webkit-transform:translateZ(0)}.fortune-fx-input-container{border-left:1px solid #e5e5e5;flex:1;align-items:center;padding:0;display:flex;position:relative;overflow:visible}.fortune-fx-input{cursor:text;white-space:pre-wrap;word-wrap:break-word;-webkit-nbsp-mode:space;-webkit-line-break:after-white-space;box-sizing:border-box;color:#000;text-align:left;background-color:#fff;outline:none;flex:1;height:100%;margin:0;padding-top:7px;padding-left:2px;font-size:14px;line-height:14px;overflow-y:scroll;-webkit-transform:translateZ(0)}.fortune-fx-input[contenteditable=true]{-webkit-user-modify:read-write-plaintext-only}.luckysheet-sheet-area{box-sizing:border-box;color:#444;-webkit-touch-callout:none;cursor:default;background-color:#fafafc;justify-content:space-between;align-items:center;width:100%;height:31px;margin:0;padding:0 30px 0 44px;transition:all .3s;display:flex;position:relative}#luckysheet-sheet-content{flex:3;align-items:center;width:0;display:flex}#luckysheet-bottom-pager{z-index:1;text-align:right;white-space:nowrap;background-color:#fafafc;flex:2;width:0}.luckysheet-sheet-area>div,.luckysheet-sheet-area .luckysheet-sheets-item{display:inline-block}.fortune-sheettab-container{vertical-align:bottom;max-width:54%;margin-left:0;padding:0;display:inline-block;position:relative}.fortune-sheettab-container .boundary{z-index:1;background:#fff;width:6px;height:100%;position:absolute;top:0}.fortune-sheettab-container .boundary-left{background-image:linear-gradient(to right, var(--tw-gradient-stops));--tw-gradient-from:#4445;--tw-gradient-stops:var(--tw-gradient-from), var(--tw-gradient-to,#8880);left:0}.fortune-sheettab-container .boundary-right{background-image:linear-gradient(to left, var(--tw-gradient-stops));--tw-gradient-from:#4445;--tw-gradient-stops:var(--tw-gradient-from), var(--tw-gradient-to,#8880);right:0}.fortune-sheettab-container .fortune-sheettab-container-c{white-space:nowrap;vertical-align:bottom;max-width:100%;margin-left:0;padding:0;display:inline-block;position:relative;overflow:hidden}.luckysheet-sheet-container-menu-hide .luckysheet-sheets-item{padding-right:5px!important}.luckysheet-sheet-container-menu-hide .luckysheet-sheets-item-menu{display:none!important}.luckysheet-sheet-area div.luckysheet-sheets-item{color:#676464;cursor:pointer;box-sizing:border-box;vertical-align:middle;background-color:#fafafc;border-left:1px solid #e0e0e0;border-right:1px solid #e0e0e0;min-width:30px;height:29px;margin-right:-1px;padding:2px 19px 0 5px;font-size:13px;line-height:29px;transition:all .1s;position:relative;top:0}.luckysheet-sheet-area div.luckysheet-sheets-item:last-child{margin-right:1px}.luckysheet-sheet-area div.luckysheet-sheets-item:hover{color:#490500;background-color:#efefef}.luckysheet-sheet-area div.luckysheet-sheets-item .luckysheet-sheets-item-menu{color:#a1a1a1;text-align:center;width:15px;height:100%;margin-left:2px;display:inline-block;position:absolute;top:-2px;right:0}.luckysheet-sheet-area div.luckysheet-sheets-item .luckysheet-sheets-item-menu:hover{color:#2a2a2a;cursor:pointer}.luckysheet-sheet-area div.luckysheet-sheets-item .luckysheet-sheets-item-name{padding:0 3px}.luckysheet-sheets-item-color{width:100%;height:10%;position:absolute;bottom:0;left:0}.luckysheet-sheet-area div.luckysheet-sheets-item .luckysheet-sheets-item-name[contenteditable=true]{-moz-user-modify:read-write-plaintext-only;-webkit-user-modify:read-write-plaintext-only;border:1px solid #d9d9d9;min-width:8px;height:18px;margin:-4px -1px;line-height:18px;display:inline-block;-webkit-user-select:text!important;-moz-user-select:text!important;-ms-user-select:text!important}.luckysheet-sheet-area div.luckysheet-sheets-item .luckysheet-sheets-item-name[contenteditable=true]:focus{border:1px solid #4d90fe;outline:none;-webkit-box-shadow:inset 0 1px 2px #0000004d;-moz-box-shadow:inset 0 1px 2px #0000004d;box-shadow:inset 0 1px 2px #0000004d}.luckysheet-sheet-area div.luckysheet-sheets-item-active{color:#222;cursor:default;background-color:#efefef;border-top-color:#fff;height:29px;line-height:29px}.luckysheet-sheet-area div.luckysheet-sheets-item-active:hover{color:#222;background-color:#ececec}.fortune-sheettab-button{justify-content:center;align-items:center;width:29px;height:29px;display:flex}.fortune-sheettab-button:hover{background-color:#efefef;justify-content:center;align-items:center;width:29px;height:29px;display:flex}.luckysheet-noselected-text{-moz-user-select:-moz-test;-khtml-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}.fortune-sheettab-scroll{cursor:pointer;align-items:center;height:29px;padding:0 5px;display:flex}.fortune-sheettab-scroll:hover{background-color:#e0e0e0}.fortune-sheettab-placeholder{vertical-align:middle;width:30px;height:29px;line-height:29px;display:inline-block}.sheet-list-container{flex-direction:column;justify-content:flex-end;display:flex;overflow:visible}.luckysheet-sheet-selection-calInfo{align-content:center;align-self:flex-end;height:22px;padding:0 0 0 44px;font-size:12px;display:flex}.luckysheet-sheet-selection-calInfo div{white-space:nowrap;margin:auto 7px auto 0}.luckysheet-sheets-item-function{width:12px;height:24px;position:absolute;top:4px;right:2px}.fortune-sheet-area-right{display:flex!important}.fortune-zoom-container{white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;user-select:none;align-items:center;display:flex;overflow:visible}.fortune-zoom-button{cursor:pointer;justify-content:center;align-items:center;width:24px;height:24px;display:flex}.fortune-zoom-button:hover{background:#efefef}.fortune-zoom-ratio{color:#1e1e1f;cursor:pointer;justify-content:center;width:48px;font-size:12px;display:flex;position:relative}.fortune-zoom-ratio-current{width:100%}.fortune-zoom-ratio-item:hover{background:#efefef}.fortune-zoom-ratio-menu{z-index:1004;background:#fff;border-radius:6px;padding:10px 0;line-height:24px;position:absolute;bottom:30px;left:0;box-shadow:2px 2px 10px #0003}.fortune-zoom-ratio-text{padding:0 10px}.fortune-context-menu{cursor:default;z-index:1004;box-sizing:border-box;-webkit-user-select:none;-moz-user-select:none;user-select:none;background:#fff;border:1px solid #0003;border-radius:4px;outline:none;max-height:100%;margin:0;padding:6px 0;font-size:13px;transition:opacity .218s;position:absolute;overflow-y:auto;box-shadow:2px 2px 20px #00000026}.fortune-context-menu input.luckysheet-mousedown-cancel{text-align:center;width:35px;margin-left:5px;margin-right:5px}.fortune-context-menu-divider{width:\"100%\";background-color:#e0e0e0;height:1px;margin:4px 0}.luckysheet-cols-menu .luckysheet-cols-menuitem{color:#333;cursor:pointer;white-space:nowrap;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin:0;padding:1px 24px 1px 8px;list-style:none;position:relative}.luckysheet-cols-menu .luckysheet-cols-menuitem:hover,.luckysheet-cols-menu .luckysheet-cols-menuitem-hover{background:#efefef}.luckysheet-cols-menu .luckysheet-cols-menuitem .luckysheet-cols-menuitem-content{color:#333;cursor:pointer;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin:0;padding:6px 7em 6px 30px;list-style:none;position:relative}.fortune-filter-menu .luckysheet-cols-menuitem{padding:0}.fortune-filter-menu .luckysheet-cols-menuitem .luckysheet-cols-menuitem-content{padding:7px 24px}.fortune-menuitem-row{white-space:pre;align-items:center;padding:7px 24px;display:flex}.fortune-byvalue-btn{cursor:pointer;color:#00f;text-decoration:underline}.luckysheet-filter-bycolor-submenu .button-basic,.fortune-filter-menu .button-basic{cursor:pointer;border-radius:4px;flex-flow:row;justify-content:center;align-items:center;padding:4px 8px;font-size:14px;display:flex}.luckysheet-filter-bycolor-submenu .button-basic{margin:5px 20px}.luckysheet-filter-bycolor-submenu .button-default,.fortune-filter-menu .button-default{color:#262a33;background-color:#fff;border:1px solid #ebebeb;margin-left:10px}.luckysheet-filter-bycolor-submenu .button-default:hover,.fortune-filter-menu .button-default:hover{background-color:#e6e6e6}.luckysheet-filter-bycolor-submenu .button-primary,.fortune-filter-menu .button-primary{color:#fff;background-color:#0188fb}.luckysheet-filter-bycolor-submenu .button-primary:hover,.fortune-filter-menu .button-primary:hover{background:#5391ff}.fortune-filter-menu .button-danger{color:#fff;background-color:#d9534f;margin-left:10px}.fortune-filter-menu .button-danger:hover{background-color:#c9302c}.filter-bycolor-container{justify-content:space-between;align-items:center;display:flex}.filtermenu-input-container{padding:0}.filtermenu-input-container input.luckysheet-mousedown-cancel{box-sizing:border-box;-webkit-user-select:auto;-moz-user-select:auto;-ms-user-select:auto;user-select:auto;text-align:start;border:1px solid #a1a1a1;border-radius:3px;outline:none;width:230px;height:26px;margin:0 20px;padding:1px 8px;font-size:12px}.filtermenu-input-container input.luckysheet-mousedown-cancel:focus{border:1px solid #0188fb;outline:none}.byvalue-btn-row{justify-content:space-between;align-items:flex-start;padding-bottom:0}.filter-caret{border:4px solid #0000;width:0;height:0;display:inline-block}.filter-caret.right{border-left-color:#000;margin-left:2px;margin-right:3px}.filter-caret.down{border-top-color:#000;margin-top:5px;margin-right:5px}.filter-checkbox{margin-left:0;margin-right:5px}#luckysheet-filter-byvalue-select{min-height:100px;padding:4px 24px;overflow:hidden auto}#luckysheet-filter-byvalue-select .count,#luckysheet-pivotTableFilter-byvalue-select .count{color:gray;margin-left:5px}#luckysheet-filter-byvalue-select .select-item{align-items:center;display:flex}.luckysheet-filter-bycolor-submenu{z-index:1004;background-color:#fff;border:1px solid #0003;min-width:170px;padding:5px 0;font-size:12px;position:absolute}.luckysheet-filter-bycolor-submenu .title{color:#333;text-align:center;background-color:#f4f4f4;padding:10px;font-weight:600}.luckysheet-filter-bycolor-submenu .one-color-tip{text-align:center;padding:7px 30px}.luckysheet-filter-bycolor-submenu .color-list{max-height:128px;overflow:auto}.luckysheet-filter-bycolor-submenu .item{cursor:pointer;background-color:#fff;padding:5px 40px 5px 20px;position:relative}.luckysheet-filter-bycolor-submenu .item:hover{background-color:#d3d3d3}.luckysheet-filter-bycolor-submenu .item .color-label{border:1px solid #d1d1d1;width:70px;height:20px;display:block}.luckysheet-filter-bycolor-submenu .item input[type=checkbox]{position:absolute;top:6px;right:10px}.change-color-triangle{position:absolute;top:3px;right:-18px}.fortune-sort-title{color:#000;cursor:default;background-color:#fff;margin:0 0 16px;font-size:16px;font-weight:400;line-height:24px}.fortune-sort-modal>div{margin-bottom:10px}.fortune-sort-tablec td{white-space:nowrap;padding:5px}.fortune-sort-button{margin-top:10px;margin-bottom:25px}#fortune-change-color{background:#f0f0f0;border:1px solid #0003;border-radius:6px;min-width:164px;height:252px;position:absolute;bottom:-110px;left:197px;box-shadow:0 2px 4px #0003}#fortune-change-color .color-reset{color:#333;cursor:pointer;white-space:nowrap;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;user-select:none;background:#fff;border-radius:6px;padding:10px 24px 10px 8px;list-style:none;position:relative}#fortune-change-color .color-reset:hover{background:#e6e6e6}#fortune-change-color .custom-color{background:#fff;border-radius:6px;justify-content:space-around;align-items:center;margin:1px 0;padding:10px;display:flex;position:relative}.button-basic{text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;user-select:none;border-radius:2px;margin-bottom:0;padding:4px 8px;font-size:12px;font-weight:400;line-height:1.42857;display:inline-block}.button-primary{color:#fff;background:#0188fb;border:1px solid #0188fb;margin-right:-4px}.fortune-sheet-list{z-index:10002;min-width:120px;max-height:60%;margin-left:72px;position:absolute;bottom:53px;overflow:hidden auto}.fortune-sheet-list-item{cursor:pointer;width:100%;height:30px;margin-right:46px;line-height:30px}.fortune-sheet-list-item-name{margin-right:15px;position:relative}.fortune-sheet-list-item-name .luckysheet-sheets-list-item-color{width:6%;height:100%;position:absolute;bottom:0;left:-6px}.fortune-sheet-list :hover{background-color:#efefef}.fortune-sheet-hidden-button{justify-content:flex-end;margin-right:15px;display:inline-flex;position:absolute;right:0}.fortune-sheet-hidden-button :hover{background-color:#d0d0d0}.fortune-sheet-selected-check-sapce{width:20px;margin-left:15px;display:inline-block}";
133555
133571
  //#endregion
133556
133572
  //#region \0dsh-excel-worker-source
@@ -133650,7 +133666,7 @@ window.__ModuleLoader__.load({
133650
133666
  }
133651
133667
  //#endregion
133652
133668
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-sidebar-documentpreview/src/client/excel/ExcelBody.module.css.mjs
133653
- const css = "._3HaaOG_body{white-space:normal;height:100%;min-height:0;font-family:var(--dsw-font,sans-serif);flex-direction:column;display:flex;overflow:hidden}._3HaaOG_workbook{color-scheme:light;flex:1;min-width:0;min-height:0;position:relative}._3HaaOG_notice{color:var(--dsw-alias-state-warn-label);background:var(--dsw-alias-state-warn-tertiary);font-size:var(--dsh-content-font-size-secondary,13px);overflow-wrap:anywhere;flex:none;align-items:flex-start;gap:8px;padding:8px 12px;line-height:1.5;display:flex}._3HaaOG_notice>svg{flex:none;margin-top:2px}._3HaaOG_formulaWarning{z-index:3;width:20px;height:20px;color:var(--dsw-alias-state-warn-label);background:0 0;border:0;border-radius:4px;padding:3px;display:flex;position:absolute;top:4px;left:142px}._3HaaOG_formulaWarning:hover,._3HaaOG_formulaWarning:focus-visible{background:var(--dsw-alias-state-warn-tertiary);outline:none}._3HaaOG_withFormulaWarning .fortune-fx-input{padding-left:24px}._3HaaOG_status{height:100%;color:var(--dsw-alias-label-secondary);justify-content:center;align-items:center;gap:8px;padding:16px;display:flex}";
133669
+ const css = "._3HaaOG_body{white-space:normal;height:100%;min-height:0;font-family:var(--dsw-font,sans-serif);flex-direction:column;display:flex;overflow:hidden}._3HaaOG_workbook{color-scheme:light;color:canvastext;flex:1;min-width:0;min-height:0;position:relative}._3HaaOG_workbook .fortune-stat-area,._3HaaOG_workbook .luckysheet-sheets-item-function,._3HaaOG_workbook .fortune-cols-freeze-handle,._3HaaOG_workbook .fortune-rows-freeze-handle{display:none}._3HaaOG_workbook .luckysheet-sheet-area div.luckysheet-sheets-item{padding-right:5px}._3HaaOG_workbook .luckysheet-sheet-area{padding:0}._3HaaOG_workbook #luckysheet-sheet-content{flex:1;min-width:0}._3HaaOG_workbook .fortune-sheettab-container{flex:1;min-width:0;max-width:100%}._3HaaOG_workbook .fortune-sheettab-container .fortune-sheettab-container-c{overscroll-behavior-x:contain;scrollbar-width:none;overflow:auto hidden}._3HaaOG_workbook .fortune-sheettab-scroll,._3HaaOG_workbook .fortune-sheet-area-right{flex:none}._3HaaOG_workbook .fortune-fx-input-container{min-width:0}._3HaaOG_workbook .fortune-fx-input{white-space:nowrap;scrollbar-width:none;min-width:0;overflow:auto hidden}._3HaaOG_notice{color:var(--dsw-alias-state-warn-label);background:var(--dsw-alias-state-warn-tertiary);font-size:var(--dsh-content-font-size-secondary,13px);overflow-wrap:anywhere;flex:none;align-items:flex-start;gap:8px;padding:8px 12px;line-height:1.5;display:flex}._3HaaOG_notice>svg{flex:none;margin-top:2px}._3HaaOG_formulaWarning{z-index:3;width:20px;height:20px;color:var(--dsw-alias-state-warn-label);background:0 0;border:0;border-radius:4px;padding:3px;display:flex;position:absolute;top:4px;left:142px}._3HaaOG_formulaWarning:hover,._3HaaOG_formulaWarning:focus-visible{background:var(--dsw-alias-state-warn-tertiary);outline:none}._3HaaOG_withFormulaWarning .fortune-fx-input{padding-left:24px}._3HaaOG_status{height:100%;color:var(--dsw-alias-label-secondary);justify-content:center;align-items:center;gap:8px;padding:16px;display:flex}";
133654
133670
  const tagId = "@deepseek-ai/dsh-client-ui-sidebar-documentpreview/ExcelBody.module.css";
133655
133671
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
133656
133672
  const tag = document.createElement("style");
package/lib/client.js CHANGED
@@ -130,6 +130,16 @@ window.__ModuleLoader__.load({
130
130
  name: trimmed.slice(cut)
131
131
  };
132
132
  }
133
+ /**
134
+ * Address a decoded absolute file path through the authenticated file route.
135
+ * @param base - HTTP(S) application base, including its deployment prefix.
136
+ * @param path - Native file path; URL escapes in authored Markdown must already be decoded.
137
+ * @returns File URL, or undefined for unsupported transports and non-absolute paths.
138
+ */
139
+ function fileMediaUrl(base, path) {
140
+ if (!/^https?:/u.test(base) || !isAbsoluteWorkspacePath(path) || /^[/\\]{2}/u.test(path) || /[\u0000-\u001f\u007f]/u.test(path)) return void 0;
141
+ return new URL(`api/file?path=${encodeURIComponent(path)}`, base).href;
142
+ }
133
143
  //#endregion
134
144
  //#region lib/types/client/failure-line.js
135
145
  /** Render a byte count the way a person reads one. */
@@ -1502,7 +1512,6 @@ window.__ModuleLoader__.load({
1502
1512
  * @returns an HTTP(S) file URL, or undefined for unsupported or malformed destinations.
1503
1513
  */
1504
1514
  function markdownImageUrl(base, documentPath, destination) {
1505
- if (!base.startsWith("http:") && !base.startsWith("https:")) return void 0;
1506
1515
  const suffix = destination.search(/[?#]/u);
1507
1516
  let path;
1508
1517
  try {
@@ -1510,13 +1519,13 @@ window.__ModuleLoader__.load({
1510
1519
  } catch (_error) {
1511
1520
  return;
1512
1521
  }
1513
- if (path.length === 0 || path.includes("\0") || /^[/\\]{2}/u.test(path)) return void 0;
1522
+ if (path.length === 0) return void 0;
1514
1523
  if (!/^[a-z]:[/\\]/iu.test(path) && /^[a-z][a-z\d+.-]*:/iu.test(path)) return void 0;
1515
1524
  if (!isAbsoluteWorkspacePath(path)) {
1516
1525
  if (documentPath === void 0) return void 0;
1517
1526
  path = pathPartsOf(documentPath).directory + path;
1518
1527
  }
1519
- return new URL(`api/file?path=${encodeURIComponent(path)}`, base).href;
1528
+ return fileMediaUrl(base, path);
1520
1529
  }
1521
1530
  //#endregion
1522
1531
  //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-sidebar-documentpreview/src/client/markdown/MarkdownBody.module.css.mjs
@@ -4513,7 +4522,12 @@ document.open();document.write(html);document.close();
4513
4522
  frame.current?.setAttribute("data-document-zoom-mode", props.preference.kind);
4514
4523
  frame.current?.style.setProperty("--document-zoom", String(zoom));
4515
4524
  controls.current?.showZoom(zoom);
4516
- }, [props.preference.kind, zoom]);
4525
+ props.onRenderZoom?.(zoom);
4526
+ }, [
4527
+ props.onRenderZoom,
4528
+ props.preference.kind,
4529
+ zoom
4530
+ ]);
4517
4531
  (0, react.useEffect)(() => {
4518
4532
  const node = scrollport.current;
4519
4533
  const clearPendingPinch = () => {
package/lib/client.pdf.js CHANGED
@@ -959,7 +959,7 @@ window.__ModuleLoader__.load({
959
959
  * @param pageNumber - 1-based selected page.
960
960
  * @param canvas - canvas owned by this render only.
961
961
  * @param signal - render lifetime.
962
- * @param pixelRatio - display pixel ratio.
962
+ * @param pixelRatio - device pixel ratio multiplied by the settled document zoom.
963
963
  * @param renderText - optional selectable text layer sharing this page and viewport.
964
964
  * @returns the page's CSS dimensions after rendering completes.
965
965
  */
@@ -32412,6 +32412,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
32412
32412
  const [load, setLoad] = (0, react.useState)();
32413
32413
  const [attempt, setAttempt] = (0, react.useState)(0);
32414
32414
  const [pageWidth, setPageWidth] = (0, react.useState)();
32415
+ const [renderZoom, setRenderZoom] = (0, react.useState)(1);
32415
32416
  const { retainTab, actions, t, ZoomViewport, zoomSurfaceClass } = props;
32416
32417
  const preference = view.zoom ?? FIT_WIDTH;
32417
32418
  const labels = {
@@ -32502,6 +32503,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
32502
32503
  onVisible: pageVisible,
32503
32504
  signal: tab.signal,
32504
32505
  onWidth: index === 0 ? setPageWidth : void 0,
32506
+ zoom: renderZoom,
32505
32507
  zoomSurfaceClass,
32506
32508
  t
32507
32509
  }, index))
@@ -32513,66 +32515,99 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
32513
32515
  signal: tab.signal,
32514
32516
  scrollportRef: props.scrollportRef,
32515
32517
  onPreference: setPreference,
32518
+ onRenderZoom: setRenderZoom,
32516
32519
  children: pages
32517
32520
  });
32518
32521
  }
32519
- function PdfPage({ document, page, requested: initiallyRequested, onVisible, signal, onWidth, zoomSurfaceClass, t }) {
32522
+ function PdfPage({ document, page, requested: initiallyRequested, onVisible, signal, onWidth, zoom, zoomSurfaceClass, t }) {
32520
32523
  const host = (0, react.useRef)(null);
32521
32524
  const canvas = (0, react.useRef)(null);
32522
32525
  const text = (0, react.useRef)(null);
32523
32526
  const [width, setWidth] = (0, react.useState)();
32524
32527
  const [requested, setRequested] = (0, react.useState)(initiallyRequested);
32528
+ const [visible, setVisible] = (0, react.useState)(initiallyRequested);
32529
+ const renderedZoom = (0, react.useRef)();
32530
+ const pendingRender = (0, react.useRef)(Promise.resolve());
32531
+ const textTask = (0, react.useRef)();
32525
32532
  const [state, setState] = (0, react.useState)("loading");
32526
32533
  const [failure, setFailure] = (0, react.useState)();
32527
32534
  const [attempt, setAttempt] = (0, react.useState)(0);
32528
32535
  (0, react.useEffect)(() => {
32529
- const node = host.current;
32536
+ const node = state === "ready" ? canvas.current : host.current;
32530
32537
  if (typeof IntersectionObserver === "undefined") {
32531
32538
  setRequested(true);
32539
+ setVisible(true);
32532
32540
  return;
32533
32541
  }
32534
32542
  let disposed = false;
32535
32543
  const observer = new IntersectionObserver((entries) => {
32536
- if (disposed || !entries.some((entry) => entry.isIntersecting)) return;
32544
+ if (disposed) return;
32545
+ const intersects = entries.some((entry) => entry.isIntersecting);
32546
+ setVisible(intersects);
32547
+ if (!intersects) return;
32537
32548
  setRequested(true);
32538
32549
  onVisible(page);
32539
- observer.disconnect();
32540
32550
  }, { rootMargin: "100% 0px" });
32541
32551
  observer.observe(node);
32542
32552
  return () => {
32543
32553
  disposed = true;
32544
32554
  observer.disconnect();
32545
32555
  };
32546
- }, [page, onVisible]);
32556
+ }, [
32557
+ page,
32558
+ onVisible,
32559
+ state
32560
+ ]);
32561
+ (0, react.useEffect)(() => () => {
32562
+ textTask.current?.cancel();
32563
+ }, []);
32547
32564
  (0, react.useEffect)(() => {
32548
32565
  if (!requested) return;
32566
+ setFailure(void 0);
32567
+ if (renderedZoom.current !== void 0 && (!visible || renderedZoom.current === zoom)) return;
32549
32568
  const node = canvas.current;
32550
32569
  const lifetime = new AbortController();
32551
32570
  const renderSignal = AbortSignal.any([lifetime.signal, signal]);
32552
- setState("loading");
32553
- setFailure(void 0);
32554
- const createText = pdfTextRenderer(text.current);
32555
- let textTask;
32556
- renderPdfPage(document, page, node, renderSignal, window.devicePixelRatio, (pdfPage, viewport) => {
32557
- textTask = createText(pdfPage, viewport);
32558
- return textTask;
32559
- }).then((size) => {
32560
- if (!renderSignal.aborted) {
32571
+ let newText;
32572
+ pendingRender.current = pendingRender.current.then(async () => {
32573
+ renderSignal.throwIfAborted();
32574
+ const buffer = node.ownerDocument.createElement("canvas");
32575
+ try {
32576
+ const size = await renderPdfPage(document, page, buffer, renderSignal, window.devicePixelRatio * zoom, textTask.current === void 0 ? (pdfPage, viewport) => {
32577
+ newText = pdfTextRenderer(text.current)(pdfPage, viewport);
32578
+ return newText;
32579
+ } : void 0);
32580
+ renderSignal.throwIfAborted();
32581
+ const context = node.getContext("2d");
32582
+ if (context === null) throw new Error("PDF canvas has no 2D context");
32583
+ node.width = buffer.width;
32584
+ node.height = buffer.height;
32585
+ node.style.setProperty("--pdf-page-width", `${size.width}px`);
32586
+ node.style.setProperty("--pdf-page-height", `${size.height}px`);
32587
+ context.drawImage(buffer, 0, 0);
32588
+ textTask.current ??= newText;
32589
+ newText = void 0;
32590
+ renderedZoom.current = zoom;
32561
32591
  setWidth(size.width);
32562
32592
  onWidth?.(size.width);
32563
32593
  setState("ready");
32594
+ } finally {
32595
+ buffer.width = buffer.height = 0;
32596
+ newText?.cancel();
32564
32597
  }
32565
- }, (error) => {
32598
+ }).catch((error) => {
32566
32599
  if (!renderSignal.aborted) setFailure({ error });
32567
32600
  });
32568
32601
  return () => {
32569
32602
  lifetime.abort();
32570
- textTask?.cancel();
32603
+ newText?.cancel();
32571
32604
  };
32572
32605
  }, [
32573
32606
  document,
32574
32607
  page,
32575
32608
  requested,
32609
+ visible,
32610
+ zoom,
32576
32611
  signal,
32577
32612
  attempt,
32578
32613
  onWidth
@@ -32602,7 +32637,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
32602
32637
  className: `${PdfBody_module_css_default.surface} ${zoomSurfaceClass}`,
32603
32638
  "data-document-zoom-surface": true,
32604
32639
  style: { "--document-zoom-width": `${width ?? 0}px` },
32605
- hidden: state !== "ready" || failure !== void 0,
32640
+ hidden: state !== "ready",
32606
32641
  children: [(0, react_jsx_runtime.jsx)("canvas", {
32607
32642
  ref: canvas,
32608
32643
  className: PdfBody_module_css_default.canvas,
@@ -30,7 +30,7 @@ export type RenderPdfText = (page: PDFPageProxy, viewport: PageViewport) => {
30
30
  * @param pageNumber - 1-based selected page.
31
31
  * @param canvas - canvas owned by this render only.
32
32
  * @param signal - render lifetime.
33
- * @param pixelRatio - display pixel ratio.
33
+ * @param pixelRatio - device pixel ratio multiplied by the settled document zoom.
34
34
  * @param renderText - optional selectable text layer sharing this page and viewport.
35
35
  * @returns the page's CSS dimensions after rendering completes.
36
36
  */
@@ -12,6 +12,8 @@ export interface ZoomViewportProps {
12
12
  readonly signal: AbortSignal;
13
13
  readonly scrollportRef: RefCallback<HTMLElement>;
14
14
  readonly onPreference: (preference: ZoomPreference) => void;
15
+ /** Resolved scale after a gesture settles or fit-width measurement changes. */
16
+ readonly onRenderZoom?: (zoom: number) => void;
15
17
  readonly children: ReactNode;
16
18
  }
17
19
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-client-ui-sidebar-documentpreview",
3
3
  "description": "Extensible Sidebar previews for Office documents, spreadsheets, Markdown, code, images, PDF, HTML, and plain text",
4
- "version": "0.1.7-alpha.2",
4
+ "version": "0.1.7-rc.1",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -62,25 +62,25 @@
62
62
  "react-dom": "^18.2.0",
63
63
  "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
64
64
  "@deepseek-ai/cordis": "~4.0.4",
65
- "@deepseek-ai/dsh-api-gateway": "0.1.7-alpha.2",
66
- "@deepseek-ai/dsh-api-remotes": "0.1.7-alpha.2",
67
- "@deepseek-ai/dsh-api-workspace-files": "0.1.7-alpha.2",
68
- "@deepseek-ai/dsh-client-connection": "0.1.7-alpha.2",
69
- "@deepseek-ai/dsh-client-locale": "0.1.7-alpha.2",
70
- "@deepseek-ai/dsh-client-resources": "0.1.7-alpha.2",
71
- "@deepseek-ai/dsh-client-store": "0.1.7-alpha.2",
72
- "@deepseek-ai/dsh-client-test-runtime": "0.1.7-alpha.2",
73
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.7-alpha.2",
74
- "@deepseek-ai/dsh-client-ui-renderer": "0.1.7-alpha.2",
75
- "@deepseek-ai/dsh-client-ui-dockkit": "0.1.7-alpha.2",
76
- "@deepseek-ai/dsh-client-ui-session": "0.1.7-alpha.2",
77
- "@deepseek-ai/dsh-client-ui-settings": "0.1.7-alpha.2",
78
- "@deepseek-ai/dsh-client-ui-sidebar-right": "0.1.7-alpha.2",
79
- "@deepseek-ai/dsh-client-ui-slots": "0.1.7-alpha.2",
80
- "@deepseek-ai/dsh-office-to-pdf": "0.1.7-alpha.2",
81
- "@deepseek-ai/dsh-host-webserver": "0.1.7-alpha.2",
82
- "@deepseek-ai/dsh-session": "0.1.7-alpha.2",
83
- "@deepseek-ai/dsh-util-workspace-path": "0.1.7-alpha.2"
65
+ "@deepseek-ai/dsh-api-gateway": "0.1.7-rc.1",
66
+ "@deepseek-ai/dsh-api-remotes": "0.1.7-rc.1",
67
+ "@deepseek-ai/dsh-api-workspace-files": "0.1.7-rc.1",
68
+ "@deepseek-ai/dsh-client-connection": "0.1.7-rc.1",
69
+ "@deepseek-ai/dsh-client-locale": "0.1.7-rc.1",
70
+ "@deepseek-ai/dsh-client-resources": "0.1.7-rc.1",
71
+ "@deepseek-ai/dsh-client-ui-dockkit": "0.1.7-rc.1",
72
+ "@deepseek-ai/dsh-client-test-runtime": "0.1.7-rc.1",
73
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.7-rc.1",
74
+ "@deepseek-ai/dsh-client-ui-renderer": "0.1.7-rc.1",
75
+ "@deepseek-ai/dsh-client-ui-session": "0.1.7-rc.1",
76
+ "@deepseek-ai/dsh-client-store": "0.1.7-rc.1",
77
+ "@deepseek-ai/dsh-client-ui-sidebar-right": "0.1.7-rc.1",
78
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.7-rc.1",
79
+ "@deepseek-ai/dsh-office-to-pdf": "0.1.7-rc.1",
80
+ "@deepseek-ai/dsh-host-webserver": "0.1.7-rc.1",
81
+ "@deepseek-ai/dsh-session": "0.1.7-rc.1",
82
+ "@deepseek-ai/dsh-util-workspace-path": "0.1.7-rc.1",
83
+ "@deepseek-ai/dsh-client-ui-settings": "0.1.7-rc.1"
84
84
  },
85
85
  "files": [
86
86
  "lib/index.js",