xiaodao-spreader 0.1.11 → 0.1.12

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.ZH.md CHANGED
@@ -24,6 +24,7 @@
24
24
  - [架构设计](#架构设计)
25
25
  - [键盘快捷键](#键盘快捷键)
26
26
  - [公式引擎](#公式引擎)
27
+ - [数字格式](#数字格式)
27
28
  - [主题与国际化](#主题与国际化)
28
29
  - [开发指南](#开发指南)
29
30
  - [构建发布](#构建发布)
@@ -40,12 +41,13 @@
40
41
 
41
42
  - **Canvas 2D 渲染** — 高 DPI 自适应(DPR 缩放),虚拟视口渲染,支持 200 行 × 26 列
42
43
  - **多 Sheet 工作簿** — 标签栏支持新建、重命名、复制、删除、拖拽排序
43
- - **公式引擎** — 支持 `=SUM()`、`=AVERAGE()` 区间统计,支持依赖追踪与循环引用检测;工具栏与右键菜单提供一键求和/平均值
44
+ - **公式引擎** — 支持 `=SUM()`、`=AVERAGE()`、`=COUNT()`、`=IF()`、`=VLOOKUP()`、`=CONCATENATE()`,支持依赖追踪与循环引用检测;工具栏与右键菜单提供一键求和/平均值/计数
44
45
  - **合并单元格** — 合并居中、跨列合并、取消合并,边框自动同步
45
46
  - **丰富单元格格式** — 字体、字号(5–72)、加粗、斜体、下划线、删除线、文字颜色、填充颜色、水平/垂直对齐、自动换行
46
47
  - **边框** — 上/下/左/右/全部/无,5 种预设样式及自定义颜色
47
48
  - **撤销 / 重做** — 单元格、列宽、行高的完整状态快照(50 步)
48
49
  - **格式刷** — 复制并应用单元格格式到任意区域
50
+ - **数字格式** — Excel 风格数字格式(常规 / 文本 / 数值 / 货币 / 会计 / 百分比 / 科学计数 / 日期 / 时间 / 日期时间 / 持续时间),提供自定义格式对话框;仅影响显示,绝不修改底层单元格值
49
51
 
50
52
  ### 交互体验
51
53
 
@@ -216,7 +218,8 @@ src/
216
218
  │ └── pickers/
217
219
  │ ├── colorPicker.vue
218
220
  │ ├── borderPicker.vue
219
- │ └── mergePicker.vue
221
+ │ ├── mergePicker.vue
222
+ │ └── numberFormatDialog.vue
220
223
  ├── composables/
221
224
  │ ├── core-state.ts # Props、cells/merges/selection、字体度量、导航
222
225
  │ ├── undo-styles.ts # 撤销重做、格式刷、字体/对齐/颜色
@@ -227,6 +230,7 @@ src/
227
230
  ├── constants.ts # 布局常量、国际化、主题调色板
228
231
  ├── types.ts # 全部类型定义
229
232
  ├── formula.ts # 公式引擎(解析、计算、依赖、缓存)
233
+ ├── number-format.ts # 数字格式引擎(Excel 风格显示格式化)
230
234
  ├── theme.ts # 主题 CSS 变量构建
231
235
  └── utils.ts # 纯工具函数(列标签、命中测试、尺寸解析)
232
236
  ```
@@ -292,6 +296,10 @@ src/
292
296
  |------|------|------|
293
297
  | `SUM` | `=SUM(A1:B5)` | 区间求和 |
294
298
  | `AVERAGE` | `=AVERAGE(A1:B5)` | 区间平均值 |
299
+ | `COUNT` | `=COUNT(A1:B5)` | 统计区域内数值单元格数 |
300
+ | `IF` | `=IF(A1>5, A1*2, 0)` | 条件分支;支持比较运算符(`> < >= <= = <>`)与四则运算 |
301
+ | `VLOOKUP` | `=VLOOKUP(value, A1:C5, 2, FALSE)` | 垂直查找;默认精确匹配,`TRUE` 为近似匹配 |
302
+ | `CONCATENATE` | `=CONCATENATE(A1, " ", B1)` | 将多个值拼接为字符串 |
295
303
  | 绝对引用 | `$A$1` | 锁定列与行 |
296
304
  | 混合引用 | `$A1`、`A$1` | 仅锁定列或行 |
297
305
 
@@ -302,7 +310,7 @@ src/
302
310
  - **正向**:`formulaKey` → `[depKey, ...]` — 公式引用了哪些单元格
303
311
  - **反向**:`depKey` → `Set<formulaKey>` — 哪些公式依赖此单元格
304
312
 
305
- 单元格变更时,脏标记通过反向图传播。循环引用(深度 > 20)返回 `#ERROR`。
313
+ 单元格变更时,脏标记通过反向图传播。循环引用通过独立的 `inProgress` 集合检测,返回 `#ERROR`。
306
314
 
307
315
  ### 粘贴时的引用偏移
308
316
 
@@ -310,6 +318,39 @@ src/
310
318
 
311
319
  ---
312
320
 
321
+ ## 数字格式
322
+
323
+ 一套 Excel 风格的数字格式引擎(`spreader/core/number-format.ts`),控制**单元格值的显示方式**——绝不修改存储的 `value`(始终保持原始字符串)。
324
+
325
+ ### 分类
326
+
327
+ | 分类 | 示例显示 | 格式代码 |
328
+ |------|----------|----------|
329
+ | 常规 General | 自动(数值;极大/极小用科学计数法) | ``(空串) |
330
+ | 文本 Text | 原样显示 | `@` |
331
+ | 数值 Number | `1,234.56` | `#,##0.00` |
332
+ | 百分比 Percent | `12.34%` | `0.00%` |
333
+ | 科学计数 Scientific | `1.23E+03` | `0.00E+00` |
334
+ | 货币 Currency | `¥1,234.56` / `$1,234.56` | `¥#,##0.00` |
335
+ | 货币(取整)Currency (rounded) | `¥1,235` | `¥#,##0` |
336
+ | 会计 Accounting | 负数 `(¥1,234.56)` | `¥#,##0.00;(¥#,##0.00);¥"-"` |
337
+ | 财务 Financial | 负数 `[Red](#,##0.00)` | `#,##0.00;[Red](#,##0.00)` |
338
+ | 日期 Date | `2026年8月24日` / `8/24/2026` | `yyyy"年"m"月"d"日"` |
339
+ | 时间 Time | `13:45:30` | `h:mm:ss` |
340
+ | 日期时间 Date & Time | `2026年8月24日 13:45:30` | `yyyy"年"m"月"d"日" h:mm:ss` |
341
+ | 持续时间 Duration | `26:30:00` | `[h]:mm:ss` |
342
+ | 自定义 Custom | 用户自定义 Excel 风格代码 | — |
343
+
344
+ ### 工作原理
345
+
346
+ - **存储**:格式代码按单元格存入 `cell.style.numberFormat`(字符串)。省略该属性(或空串)即常规格式。
347
+ - **界面**:工具栏数字格式下拉框将预设应用到当前选区;**「格式…」** 项打开 `numberFormatDialog.vue`,可自定义格式代码、小数位数与千位分隔符。
348
+ - **显示**:`formatNumber(value, format, locale)` 解析代码(带缓存),应用千位分隔 / 小数位 / 百分比缩放 / 日期序列号转换,返回显示字符串。非法的日期/持续时间序列号渲染为 `###`。
349
+ - **对齐**:数值类格式默认右对齐;文本及常规下的非数值保持左对齐——与 Excel 语义一致。
350
+ - **国际化**:货币符号(`¥` / `$`)、月份与星期名称随 `locale` 属性变化。
351
+
352
+ ---
353
+
313
354
  ## 主题与国际化
314
355
 
315
356
  ### 内置主题
@@ -400,9 +441,9 @@ pnpm build:demo
400
441
 
401
442
  ### 近期
402
443
 
403
- - [ ] 更多公式:`COUNT`、`IF`、`VLOOKUP`、`CONCATENATE`
444
+ - [x] 更多公式:`COUNT`、`IF`、`VLOOKUP`、`CONCATENATE`
404
445
  - [ ] 单元格背景颜色选择器
405
- - [ ] 数字格式(货币、百分比、日期、小数位数)
446
+ - [x] 数字格式(货币、百分比、日期、小数位数)—— *见 [数字格式](#数字格式)*
406
447
  - [ ] 条件格式规则
407
448
  - [ ] 自动填充拖拽手柄
408
449
  - [ ] 查找与替换
package/README.md CHANGED
@@ -24,6 +24,7 @@ A high-performance, canvas-based spreadsheet component for Vue 3 — bringing an
24
24
  - [Architecture](#architecture)
25
25
  - [Keyboard Shortcuts](#keyboard-shortcuts)
26
26
  - [Formula Engine](#formula-engine)
27
+ - [Number Format](#number-format)
27
28
  - [Theming](#theming)
28
29
  - [Development](#development)
29
30
  - [Building](#building)
@@ -39,12 +40,13 @@ A high-performance, canvas-based spreadsheet component for Vue 3 — bringing an
39
40
  ### Core Spreadsheet
40
41
  - **Canvas 2D Rendering** — High-DPI aware with DPR scaling, virtual viewport rendering for 200 × 26 sheets
41
42
  - **Multi-Sheet Workbook** — Tab bar with add, rename, duplicate, delete, reorder
42
- - **Formula Engine** — `=SUM()`, `=AVERAGE()` range calculation with dependency tracking and circular-reference detection; toolbar and context menu provide one-click sum/average
43
+ - **Formula Engine** — `=SUM()`, `=AVERAGE()`, `=COUNT()`, `=IF()`, `=VLOOKUP()`, `=CONCATENATE()` with dependency tracking and circular-reference detection; toolbar and context menu provide one-click sum/average/count
43
44
  - **Merge Cells** — Merge & Center, Merge Across, Unmerge with border synchronization
44
45
  - **Rich Cell Formatting** — Font family, font size (5–72), bold, italic, underline, strikethrough, text color, fill color, horizontal & vertical alignment, wrap text
45
46
  - **Borders** — Top / bottom / left / right / all / none with 5 predefined styles and custom color
46
47
  - **Undo / Redo** — Full state snapshots for cells, column widths, and row heights (50 steps)
47
48
  - **Format Painter** — Copy & apply cell formatting across ranges
49
+ - **Number Format** — Excel-style number formatting (General / Text / Number / Currency / Accounting / Percent / Scientific / Date / Time / DateTime / Duration) with a custom format dialog; display-only, never mutates the stored cell value
48
50
 
49
51
  ### Interaction
50
52
  - **Smart Selection** — Click, drag, Shift+Click, row/column header select, corner-cell select-all
@@ -213,7 +215,8 @@ src/
213
215
  │ └── pickers/
214
216
  │ ├── colorPicker.vue
215
217
  │ ├── borderPicker.vue
216
- │ └── mergePicker.vue
218
+ │ ├── mergePicker.vue
219
+ │ └── numberFormatDialog.vue
217
220
  ├── composables/
218
221
  │ ├── core-state.ts # Props, cells/merges/selection, font metrics, navigation
219
222
  │ ├── undo-styles.ts # Undo/redo, format painter, font/alignment/color
@@ -224,6 +227,7 @@ src/
224
227
  ├── constants.ts # Layout constants, i18n, theme palettes
225
228
  ├── types.ts # All type definitions
226
229
  ├── formula.ts # Formula engine (parse, evaluate, deps, cache)
230
+ ├── number-format.ts # Number format engine (Excel-style display formatting)
227
231
  ├── theme.ts # Theme CSS variable construction
228
232
  └── utils.ts # Pure utilities (col label, hit test, resolve size)
229
233
  ```
@@ -289,6 +293,10 @@ src/
289
293
  |---------|--------|-------------|
290
294
  | `SUM` | `=SUM(A1:B5)` | Range summation |
291
295
  | `AVERAGE` | `=AVERAGE(A1:B5)` | Range average |
296
+ | `COUNT` | `=COUNT(A1:B5)` | Count numeric cells in range |
297
+ | `IF` | `=IF(A1>5, A1*2, 0)` | Conditional branching; supports comparison operators (`> < >= <= = <>`) and arithmetic |
298
+ | `VLOOKUP` | `=VLOOKUP(value, A1:C5, 2, FALSE)` | Vertical lookup; exact match by default, `TRUE` for approximate match |
299
+ | `CONCATENATE` | `=CONCATENATE(A1, " ", B1)` | Concatenate multiple values into a string |
292
300
  | Absolute ref | `$A$1` | Lock column and row |
293
301
  | Mixed ref | `$A1`, `A$1` | Lock column or row only |
294
302
 
@@ -299,7 +307,7 @@ The `FormulaDeps` class maintains a bidirectional dependency graph:
299
307
  - **Forward**: `formulaKey` → `[depKey, ...]` — which cells a formula references
300
308
  - **Reverse**: `depKey` → `Set<formulaKey>` — which formulas depend on a cell
301
309
 
302
- When a cell changes, dirty flags propagate through the reverse graph. Circular references (depth > 20) return `#ERROR`.
310
+ When a cell changes, dirty flags propagate through the reverse graph. Circular references are detected via a separate `inProgress` set and return `#ERROR`.
303
311
 
304
312
  ### Reference Offsetting During Paste
305
313
 
@@ -307,6 +315,39 @@ When a cell changes, dirty flags propagate through the reverse graph. Circular r
307
315
 
308
316
  ---
309
317
 
318
+ ## Number Format
319
+
320
+ An Excel-style number formatting engine (`spreader/core/number-format.ts`) that controls **how a cell value is displayed** — it never mutates the stored `value` (which always remains a raw string).
321
+
322
+ ### Categories
323
+
324
+ | Category | Example display | Format code |
325
+ |----------|-----------------|-------------|
326
+ | General | Auto (numbers, sci-notation for very large/small) | `` (empty) |
327
+ | Text | Verbatim | `@` |
328
+ | Number | `1,234.56` | `#,##0.00` |
329
+ | Percent | `12.34%` | `0.00%` |
330
+ | Scientific | `1.23E+03` | `0.00E+00` |
331
+ | Currency | `¥1,234.56` / `$1,234.56` | `¥#,##0.00` |
332
+ | Currency (rounded) | `¥1,235` | `¥#,##0` |
333
+ | Accounting | `(¥1,234.56)` for negatives | `¥#,##0.00;(¥#,##0.00);¥"-"` |
334
+ | Financial | `[Red](#,##0.00)` for negatives | `#,##0.00;[Red](#,##0.00)` |
335
+ | Date | `2026年8月24日` / `8/24/2026` | `yyyy"年"m"月"d"日"` |
336
+ | Time | `13:45:30` | `h:mm:ss` |
337
+ | Date & Time | `2026年8月24日 13:45:30` | `yyyy"年"m"月"d"日" h:mm:ss` |
338
+ | Duration | `26:30:00` | `[h]:mm:ss` |
339
+ | Custom | User-defined Excel-style code | — |
340
+
341
+ ### How it works
342
+
343
+ - **Storage**: the format code is stored per-cell in `cell.style.numberFormat` (a string). Omitting the property (or empty string) means General.
344
+ - **UI**: the toolbar number-format dropdown applies presets to the current selection; the **「Format…」(格式…)** item opens `numberFormatDialog.vue` for a custom code, decimals, and thousands separator.
345
+ - **Display**: `formatNumber(value, format, locale)` parses the code (cached), applies thousands separators / decimals / percent scaling / date-serial conversion, and returns the display string. Invalid date/duration serials render as `###`.
346
+ - **Alignment**: numeric formats default to right-aligned; Text and General-with-non-numeric keep left alignment — matching Excel semantics.
347
+ - **i18n**: currency symbol (`¥` / `$`), month and weekday names follow the `locale` prop.
348
+
349
+ ---
350
+
310
351
  ## Theming
311
352
 
312
353
  ### Built-in Themes
@@ -397,9 +438,9 @@ The project includes a GitHub Actions workflow (`.github/workflows/publish.yml`)
397
438
 
398
439
  ### Near-term
399
440
 
400
- - [ ] More formulas: `COUNT`, `IF`, `VLOOKUP`, `CONCATENATE`
441
+ - [x] More formulas: `COUNT`, `IF`, `VLOOKUP`, `CONCATENATE`
401
442
  - [ ] Cell background color picker
402
- - [ ] Number format (currency, percentage, date, number of decimals)
443
+ - [x] Number format (currency, percentage, date, number of decimals) — *see [Number Format](#number-format)*
403
444
  - [ ] Conditional formatting rules
404
445
  - [ ] Auto-fill drag handle
405
446
  - [ ] Find & Replace
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- .sp-dropdown[data-v-77df3baf]{position:relative;display:inline-flex;min-width:0}.sp-dropdown__trigger[data-v-77df3baf]{display:flex;align-items:center;justify-content:space-between;gap:4px;width:100%;height:26px;border:1px solid transparent;border-radius:3px;background:transparent;color:var(--sp-toolbar-btn-color, #444);font-size:12px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;cursor:pointer;padding:0 5px;box-sizing:border-box}.sp-dropdown__trigger[data-v-77df3baf]:hover{background:var(--sp-toolbar-btn-hover-bg, #e6e6e6)}.sp-dropdown__trigger--open[data-v-77df3baf]{background:var(--sp-toolbar-btn-hover-bg, #e6e6e6);border-color:var(--sp-toolbar-border, #d8d8d8)}.sp-dropdown__value[data-v-77df3baf]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left}.sp-dropdown__caret[data-v-77df3baf]{width:10px;height:10px;min-width:10px;opacity:.7}.sp-dropdown__menu[data-v-77df3baf]{position:fixed;z-index:20000;display:flex;flex-direction:column;background:#fff;border:1px solid var(--sp-toolbar-border, #d0d0d0);border-radius:4px;box-shadow:0 4px 12px #0000001f;padding:4px;box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;transform-origin:top center}.sp-dropdown__menu--up[data-v-77df3baf]{transform-origin:bottom center}.menu-pop-enter-active[data-v-77df3baf],.menu-pop-leave-active[data-v-77df3baf]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-77df3baf],.menu-pop-leave-to[data-v-77df3baf]{opacity:0;transform:scaleY(.85)}.sp-dropdown__nav[data-v-77df3baf]{display:flex;align-items:center;justify-content:center;height:15px;min-height:15px;border:none;background:transparent;color:var(--sp-toolbar-btn-color, #666);cursor:pointer;padding:0;border-radius:3px}.sp-dropdown__nav[data-v-77df3baf]:hover:not(:disabled){background:#eef3f9}.sp-dropdown__nav[data-v-77df3baf]:disabled{color:#ccc;cursor:default}.sp-dropdown__nav svg[data-v-77df3baf]{width:10px;height:10px}.sp-dropdown__list[data-v-77df3baf]{display:flex;flex-direction:column;overflow:hidden;touch-action:none}.sp-dropdown__icon[data-v-77df3baf]{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto}.sp-dropdown__icon[data-v-77df3baf] svg{width:18px;height:18px;display:block}.sp-dropdown__item-icon[data-v-77df3baf]{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto}.sp-dropdown__item-icon[data-v-77df3baf] svg{width:16px;height:16px;display:block}.sp-dropdown__item-label[data-v-77df3baf]{white-space:nowrap}.sp-dropdown__item[data-v-77df3baf]{display:flex;align-items:center;gap:6px;width:100%;border:none;background:transparent;color:var(--sp-toolbar-btn-color, #444);font-size:12px;cursor:pointer;padding:4px 8px;box-sizing:border-box;border-radius:3px}.sp-dropdown__item[data-v-77df3baf]:hover{background:#eef3f9}.sp-dropdown__item--active[data-v-77df3baf]{background:#e5f1fb;color:#0078d7}.color-picker[data-v-f8fac424]{position:relative;display:inline-flex;height:26px}.color-picker__menu[data-v-f8fac424]{position:fixed;z-index:9999;background:#fff;border:1px solid var(--sp-toolbar-border, #d0d0d0);border-radius:4px;padding:6px;box-shadow:0 4px 12px #0000001f;-webkit-user-select:none;user-select:none;transform-origin:top right}.menu-pop-enter-active[data-v-f8fac424],.menu-pop-leave-active[data-v-f8fac424]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-f8fac424],.menu-pop-leave-to[data-v-f8fac424]{opacity:0;transform:scale(.9)}.color-picker__row[data-v-f8fac424]{display:flex;gap:4px;margin-bottom:4px}.color-picker__row[data-v-f8fac424]:last-child{margin-bottom:0}.color-picker__swatch[data-v-f8fac424]{width:20px;height:20px;padding:0;border-radius:50%;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:transform .08s,box-shadow .08s;position:relative}.color-picker__swatch[data-v-f8fac424]:hover{transform:scale(1.18);box-shadow:0 0 0 1px #0003;z-index:1}.color-picker__swatch--selected[data-v-f8fac424]{box-shadow:0 0 0 2px #0078d7}.border-picker[data-v-f362abdb]{position:relative;display:inline-flex;height:26px}.border-picker__menu[data-v-f362abdb]{position:fixed;z-index:9999;background:#fff;border:1px solid var(--sp-toolbar-border, #d0d0d0);border-radius:4px;box-shadow:0 4px 12px #0000001f;-webkit-user-select:none;user-select:none;padding:4px;transform-origin:top right}.border-picker__item[data-v-f362abdb]{display:flex;align-items:center;gap:6px;width:100%;padding:4px 8px;border:none;background:transparent;color:var(--sp-toolbar-btn-color, #444);cursor:pointer;border-radius:3px;font-size:12px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;white-space:nowrap}.border-picker__item[data-v-f362abdb]:hover{background:#eef3f9}.border-picker__icon[data-v-f362abdb]{width:18px;height:18px;flex-shrink:0}.border-picker__label[data-v-f362abdb]{overflow:hidden;text-overflow:ellipsis}.menu-pop-enter-active[data-v-f362abdb],.menu-pop-leave-active[data-v-f362abdb]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-f362abdb],.menu-pop-leave-to[data-v-f362abdb]{opacity:0;transform:scale(.9)}.merge-picker[data-v-67c0f9e3]{position:relative;display:inline-flex;height:26px}.merge-picker__menu[data-v-67c0f9e3]{position:fixed;z-index:9999;background:#fff;border:1px solid var(--sp-toolbar-border, #d0d0d0);border-radius:4px;box-shadow:0 4px 12px #0000001f;-webkit-user-select:none;user-select:none;padding:4px;transform-origin:top right}.merge-picker__item[data-v-67c0f9e3]{display:flex;align-items:center;gap:6px;width:100%;padding:4px 8px;border:none;background:transparent;color:var(--sp-toolbar-btn-color, #444);cursor:pointer;border-radius:3px;font-size:12px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;white-space:nowrap}.merge-picker__item[data-v-67c0f9e3]:hover{background:#eef3f9}.merge-picker__icon[data-v-67c0f9e3]{width:18px;height:18px;flex-shrink:0;display:flex;align-items:center;justify-content:center}.merge-picker__icon[data-v-67c0f9e3] svg{width:18px;height:18px}.merge-picker__label[data-v-67c0f9e3]{overflow:hidden;text-overflow:ellipsis}.menu-pop-enter-active[data-v-67c0f9e3],.menu-pop-leave-active[data-v-67c0f9e3]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-67c0f9e3],.menu-pop-leave-to[data-v-67c0f9e3]{opacity:0;transform:scale(.9)}.calc-picker[data-v-08615aee]{position:relative;display:inline-flex;height:26px}.calc-picker__menu[data-v-08615aee]{position:fixed;z-index:9999;min-width:120px;background:#fff;border:1px solid var(--sp-toolbar-border, #d0d0d0);border-radius:4px;box-shadow:0 4px 12px #0000001f;-webkit-user-select:none;user-select:none;padding:4px;transform-origin:top right}.calc-picker__item[data-v-08615aee]{display:flex;align-items:center;gap:6px;width:100%;padding:4px 8px;border:none;background:transparent;color:var(--sp-toolbar-btn-color, #444);cursor:pointer;border-radius:3px;font-size:12px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;white-space:nowrap}.calc-picker__item[data-v-08615aee]:hover:not(.calc-picker__item--disabled){background:#eef3f9}.calc-picker__item--disabled[data-v-08615aee]{color:var(--sp-toolbar-btn-disabled-color, #bbb);cursor:default}.calc-picker__label[data-v-08615aee]{overflow:hidden;text-overflow:ellipsis}.menu-pop-enter-active[data-v-08615aee],.menu-pop-leave-active[data-v-08615aee]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-08615aee],.menu-pop-leave-to[data-v-08615aee]{opacity:0;transform:scale(.9)}.toolbar[data-v-a33ba577]{position:relative;display:flex;align-items:center;height:32px;min-height:32px;gap:2px;padding:0 6px;background:var(--sp-toolbar-bg);border-bottom:1px solid var(--sp-toolbar-border);-webkit-user-select:none;user-select:none}.tb-item[data-v-a33ba577]{display:flex;align-items:center;flex:0 0 auto}.toolbar-sep[data-v-a33ba577]{width:1px;height:18px;margin:0 4px;background:var(--sp-toolbar-border)}.toolbar-font[data-v-a33ba577],.toolbar-number-format[data-v-a33ba577],.toolbar-align[data-v-a33ba577]{flex:0 0 auto}.toolbar-font-size[data-v-a33ba577]{display:inline-flex;align-items:center;gap:0;height:26px;position:relative}.toolbar-font-size__input[data-v-a33ba577]{width:36px;height:26px;border:1px solid transparent;border-right:none;border-radius:3px 0 0 3px;background:transparent;color:var(--sp-toolbar-btn-color);font-size:12px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;text-align:left;padding:0 5px;outline:none;box-sizing:border-box;-webkit-appearance:none;appearance:none;-moz-appearance:textfield}.toolbar-font-size__input[data-v-a33ba577]::-webkit-outer-spin-button,.toolbar-font-size__input[data-v-a33ba577]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.toolbar-font-size__input[data-v-a33ba577]:hover{background:var(--sp-toolbar-btn-hover-bg)}.toolbar-font-size__input[data-v-a33ba577]:focus{border-color:var(--sp-toolbar-border);background:#fff}.toolbar-font-size__btn[data-v-a33ba577]{display:flex;align-items:center;justify-content:center;width:16px;height:26px;border:1px solid transparent;border-left:none;border-radius:0 3px 3px 0;background:transparent;color:var(--sp-toolbar-btn-color);cursor:pointer;padding:0}.toolbar-font-size__btn[data-v-a33ba577]:hover{background:var(--sp-toolbar-btn-hover-bg)}.toolbar-font-size__btn svg[data-v-a33ba577]{width:10px;height:10px}.toolbar-font-size__dropdown[data-v-a33ba577]{position:absolute;width:56px;height:26px;pointer-events:none}.toolbar-btn[data-v-a33ba577]{display:flex;align-items:center;justify-content:center;width:30px;height:26px;border:none;border-radius:3px;background:transparent;color:var(--sp-toolbar-btn-color);cursor:pointer;padding:0}.toolbar-btn[data-v-a33ba577]:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.toolbar-btn[data-v-a33ba577]:active:not(:disabled){opacity:.7}.toolbar-btn--active[data-v-a33ba577]{background:var(--sp-toolbar-btn-hover-bg);color:var(--sp-toolbar-btn-active-color)}.toolbar-btn--step[data-v-a33ba577]{width:26px;height:26px}.toolbar-btn--step svg[data-v-a33ba577]{width:16px;height:16px}.toolbar-btn[data-v-a33ba577]:disabled{color:var(--sp-toolbar-btn-disabled-color);cursor:default}.toolbar-btn__icon[data-v-a33ba577]{width:18px;height:18px}.toolbar-btn svg[data-v-a33ba577]:not(.toolbar-btn__icon){width:18px;height:18px}.toolbar-split[data-v-a33ba577]{display:inline-flex;align-items:center;position:relative;height:26px}.toolbar-split__main[data-v-a33ba577]{border:1px solid transparent;border-right:none;border-radius:3px 0 0 3px}.toolbar-split__arrow[data-v-a33ba577]{display:flex;align-items:center;justify-content:center;width:16px;height:26px;border:1px solid transparent;border-radius:0 3px 3px 0;background:transparent;color:var(--sp-toolbar-btn-color);cursor:pointer;padding:0}.toolbar-split__arrow[data-v-a33ba577]:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.toolbar-split__arrow svg[data-v-a33ba577]{width:10px!important;height:10px!important}.toolbar-more[data-v-a33ba577]{display:flex;align-items:center;justify-content:center;width:30px;height:26px;border:none;border-radius:3px;background:transparent;color:var(--sp-toolbar-btn-color);cursor:pointer;padding:0;flex:0 0 auto;margin-left:auto}.toolbar-more[data-v-a33ba577]:hover{background:var(--sp-toolbar-btn-hover-bg)}.toolbar-more--active[data-v-a33ba577]{background:var(--sp-toolbar-btn-hover-bg);color:var(--sp-toolbar-btn-active-color)}.toolbar-more svg[data-v-a33ba577]{width:18px;height:18px}.overflow-menu[data-v-a33ba577]{min-width:180px;max-width:260px;max-height:calc(100vh - 40px);overflow-y:auto;background:var(--sp-toolbar-bg, #fff);border:1px solid var(--sp-toolbar-border);border-radius:4px;box-shadow:0 4px 12px #0000001f;padding:4px 6px;display:flex;flex-direction:column;gap:2px;z-index:1000;transform-origin:top right}.overflow-menu.no-anim[data-v-a33ba577]{transition:none!important}.overflow-menu .tb-item[data-v-a33ba577]{width:100%}.overflow-menu .toolbar-sep[data-v-a33ba577]{width:100%;height:1px;margin:2px 0}.overflow-menu .toolbar-split[data-v-a33ba577]{width:100%}.overflow-menu .toolbar-split__main[data-v-a33ba577]{flex:1 1 auto;justify-content:flex-start;padding-left:6px}.overflow-menu .toolbar-font-size[data-v-a33ba577]{width:100%;justify-content:flex-start}.overflow-menu .toolbar-font[data-v-a33ba577],.overflow-menu .toolbar-number-format[data-v-a33ba577],.overflow-menu .toolbar-align[data-v-a33ba577]{width:100%}.overflow-menu .toolbar-btn[data-v-a33ba577]:not(.toolbar-btn--step):not(.toolbar-split__arrow){width:100%;justify-content:flex-start;padding-left:6px}.overflow-menu .toolbar-color[data-v-a33ba577]{width:100%}.overflow-menu .toolbar-wrap[data-v-a33ba577]{width:100%;justify-content:flex-start}.menu-pop-enter-active[data-v-a33ba577],.menu-pop-leave-active[data-v-a33ba577]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-a33ba577],.menu-pop-leave-to[data-v-a33ba577]{opacity:0;transform:scale(.9)}.overflow-menu .tb-item{width:100%}.overflow-menu .toolbar-sep{width:100%;height:1px;margin:2px 0}.overflow-menu .toolbar-split{width:100%}.overflow-menu .toolbar-split__main{flex:1 1 auto;justify-content:flex-start;padding-left:6px}.overflow-menu .toolbar-font-size{width:100%;justify-content:flex-start}.overflow-menu .toolbar-font,.overflow-menu .toolbar-number-format,.overflow-menu .toolbar-align{width:100%}.overflow-menu .toolbar-btn:not(.toolbar-btn--step):not(.toolbar-split__arrow){width:100%;justify-content:flex-start;padding-left:6px}.overflow-menu .toolbar-color{width:100%}.overflow-menu .toolbar-wrap{width:100%;justify-content:flex-start}.overflow-menu .toolbar-font-size__input{flex:1 1 auto;width:auto;min-width:40px}.overflow-menu .toolbar-btn:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.overflow-menu .toolbar-btn:active:not(:disabled){opacity:.7}.overflow-menu .toolbar-btn--active{background:var(--sp-toolbar-btn-hover-bg);color:var(--sp-toolbar-btn-active-color)}.overflow-menu .toolbar-btn:disabled{color:var(--sp-toolbar-btn-disabled-color);cursor:default}.overflow-menu .toolbar-split__main:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.overflow-menu .toolbar-split__arrow:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.overflow-menu .toolbar-font-size__input:hover{background:var(--sp-toolbar-btn-hover-bg)}.overflow-menu .toolbar-font-size__input:focus{border-color:var(--sp-toolbar-border);background:#fff}.overflow-menu .toolbar-font-size__btn:hover,.overflow-menu .toolbar-more:hover{background:var(--sp-toolbar-btn-hover-bg)}.overflow-menu .toolbar-more--active{background:var(--sp-toolbar-btn-hover-bg);color:var(--sp-toolbar-btn-active-color)}.tab-bar[data-v-454e1a12]{display:flex;align-items:stretch;height:30px;min-height:30px;background:var(--sp-tab-bar-bg);border-top:1px solid var(--sp-tab-bar-border);-webkit-user-select:none;user-select:none;margin-top:4px}.tab-list[data-v-454e1a12]{display:flex;align-items:flex-start;flex:1;overflow:hidden;gap:1px;padding:0 1px}.tab-item[data-v-454e1a12]{display:flex;align-items:center;height:28px;min-width:0;max-width:120px;padding:0 10px;cursor:pointer;border:1px solid var(--sp-tab-inactive-border);background:var(--sp-tab-inactive-bg);color:var(--sp-tab-inactive-color);font-size:14px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;white-space:nowrap;transition:background .1s}.tab-item[data-v-454e1a12]:hover{background:var(--sp-tab-hover-bg)}.tab-item--active[data-v-454e1a12]{height:28px;background:var(--sp-tab-active-bg);color:var(--sp-tab-active-color);border-color:var(--sp-tab-active-bg) var(--sp-tab-bar-border) var(--sp-tab-bar-border);border-top:2px solid var(--sp-tab-active-border);font-size:16px}.tab-item--active[data-v-454e1a12]:hover{background:var(--sp-tab-active-bg)}.tab-item__name[data-v-454e1a12]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tab-rename-input[data-v-454e1a12]{width:100%;height:18px;border:none;border-radius:0;outline:none;padding:0;font-size:16px;font-family:inherit;background:var(--sp-tab-active-bg);color:var(--sp-tab-active-color);box-sizing:border-box}.tab-bar__add-btn[data-v-454e1a12]{width:24px;min-width:24px;height:24px;margin:0 4px 3px 3px;border:none;background:transparent;color:var(--sp-tab-add-btn-color);font-size:16px;line-height:22px;text-align:center;cursor:pointer;padding:0}.tab-bar__add-btn[data-v-454e1a12]:hover{background:var(--sp-tab-add-btn-hover-bg)}.nf-dialog__mask[data-v-69cb36b7]{position:fixed;top:0;right:0;bottom:0;left:0;z-index:30000;background:rgba(0,0,0,.25);display:flex;align-items:center;justify-content:center}.nf-dialog[data-v-69cb36b7]{width:380px;max-width:calc(100vw - 32px);max-height:calc(100vh - 48px);overflow-y:auto;background:#fff;border:1px solid #d0d0d0;border-radius:6px;box-shadow:0 8px 24px #0000002e;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;color:#1a1a1a;-webkit-user-select:none;user-select:none}.nf-dialog__header[data-v-69cb36b7]{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;border-bottom:1px solid #ececec}.nf-dialog__title[data-v-69cb36b7]{font-size:13px;font-weight:600}.nf-dialog__close[data-v-69cb36b7]{display:flex;align-items:center;justify-content:center;width:22px;height:22px;border:none;background:transparent;color:#888;cursor:pointer;border-radius:3px;padding:0}.nf-dialog__close[data-v-69cb36b7]:hover{background:#f0f0f0;color:#444}.nf-dialog__close svg[data-v-69cb36b7]{width:14px;height:14px}.nf-dialog__body[data-v-69cb36b7]{padding:12px 14px;display:flex;flex-direction:column;gap:10px}.nf-field[data-v-69cb36b7]{display:flex;align-items:center;gap:8px}.nf-field--inline[data-v-69cb36b7]{min-height:26px}.nf-field__label[data-v-69cb36b7]{width:88px;min-width:88px;font-size:12px;color:#555}.nf-field__select[data-v-69cb36b7],.nf-field__input[data-v-69cb36b7]{flex:1;height:26px;border:1px solid #c0c0c0;border-radius:3px;background:#fff;font-size:12px;color:#1a1a1a;padding:0 6px;outline:none;box-sizing:border-box;font-family:inherit}.nf-field__select[data-v-69cb36b7]:focus,.nf-field__input[data-v-69cb36b7]:focus{border-color:#0078d7;box-shadow:0 0 0 1px #0078d74d}.nf-field__textarea[data-v-69cb36b7]{flex:1;min-height:44px;border:1px solid #c0c0c0;border-radius:3px;background:#fff;font-size:12px;color:#1a1a1a;padding:4px 6px;outline:none;box-sizing:border-box;resize:none;font-family:Consolas,Courier New,monospace}.nf-field__textarea[data-v-69cb36b7]:focus{border-color:#0078d7;box-shadow:0 0 0 1px #0078d74d}.nf-checkbox[data-v-69cb36b7]{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:#333;cursor:pointer}.nf-checkbox input[data-v-69cb36b7]{margin:0;cursor:pointer}.nf-dialog__footer[data-v-69cb36b7]{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:10px 14px;border-top:1px solid #ececec}.nf-preview[data-v-69cb36b7]{display:flex;flex-direction:column;gap:2px;min-width:0}.nf-preview__label[data-v-69cb36b7]{font-size:11px;color:#888}.nf-preview__value[data-v-69cb36b7]{font-size:13px;color:#1a1a1a;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:180px}.nf-dialog__actions[data-v-69cb36b7]{display:flex;gap:8px}.nf-btn[data-v-69cb36b7]{height:28px;padding:0 16px;border:1px solid #ccc;border-radius:3px;background:#fff;color:#333;font-size:12px;cursor:pointer;font-family:inherit}.nf-btn[data-v-69cb36b7]:hover{background:#f0f0f0}.nf-btn--primary[data-v-69cb36b7]{border-color:#0078d7;background:#0078d7;color:#fff}.nf-btn--primary[data-v-69cb36b7]:hover{background:#0069c0}.nf-dialog-enter-active[data-v-69cb36b7],.nf-dialog-leave-active[data-v-69cb36b7]{transition:opacity .14s ease-out}.nf-dialog-enter-from[data-v-69cb36b7],.nf-dialog-leave-to[data-v-69cb36b7]{opacity:0}.nf-dialog-enter-active .nf-dialog[data-v-69cb36b7],.nf-dialog-leave-active .nf-dialog[data-v-69cb36b7]{transition:transform .14s ease-out}.nf-dialog-enter-from .nf-dialog[data-v-69cb36b7],.nf-dialog-leave-to .nf-dialog[data-v-69cb36b7]{transform:scale(.96)}.spreadsheet-outer[data-v-6321c060]{flex:1;display:flex;flex-direction:column;overflow:hidden;height:100%;min-height:400px;width:100%}.formula-bar[data-v-6321c060]{display:flex;align-items:flex-start;min-height:36px;padding:0;gap:0}.formula-bar--expanded[data-v-6321c060]{min-height:72px}.formula-bar__cell-label[data-v-6321c060]{width:48px;min-width:48px;height:28px;line-height:28px;margin-top:4px;text-align:center;font-size:12px;font-weight:600;color:var(--sp-formula-bar-label-color);background:var(--sp-formula-bar-label-bg);border:1px solid var(--sp-formula-bar-label-border);border-radius:2px;-webkit-user-select:none;user-select:none}.formula-bar__buttons[data-v-6321c060]{display:inline-flex;align-items:stretch;margin-top:4px;margin-left:6px;height:28px;border:1px solid var(--sp-formula-bar-input-border);border-radius:2px;overflow:hidden;background:var(--sp-formula-bar-input-bg)}.formula-bar__btn[data-v-6321c060]{width:22px;height:28px;border:none;border-radius:0;background:transparent;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0;-webkit-user-select:none;user-select:none;color:inherit}.formula-bar__btn+.formula-bar__btn[data-v-6321c060]{border-left:1px solid var(--sp-formula-bar-input-border)}.formula-bar__btn[data-v-6321c060]:hover{background:var(--sp-scroll-btn-hover-bg, #f0f0f0)}.formula-bar__btn--cancel[data-v-6321c060]:hover{color:#e53935;background:#fdecea}.formula-bar__btn--accept[data-v-6321c060]:hover{color:#2e7d32;background:#e8f5e9}.formula-bar__input[data-v-6321c060]{flex:1;min-height:28px;height:28px;line-height:20px;margin-top:4px;border:1px solid var(--sp-formula-bar-input-border);border-radius:2px;outline:none;padding:3px 6px;margin-left:4px;font-size:13px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;color:var(--sp-formula-bar-input-color);background:var(--sp-formula-bar-input-bg);resize:none;overflow:hidden;box-sizing:border-box}.formula-bar__input--expanded[data-v-6321c060]{height:68px;overflow:auto}.formula-bar__input[data-v-6321c060]:focus{border-color:var(--sp-formula-bar-input-focus-border);box-shadow:0 0 0 1px var(--sp-formula-bar-input-focus-shadow)}.formula-bar__toggle[data-v-6321c060]{width:22px;min-width:22px;height:28px;margin-top:4px;margin-left:2px;margin-right:2px;border:1px solid var(--sp-formula-bar-input-border);border-radius:2px;background:var(--sp-formula-bar-input-bg);color:var(--sp-formula-bar-input-color);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0;-webkit-user-select:none;user-select:none}.formula-bar__toggle[data-v-6321c060]:hover{background:var(--sp-scroll-btn-hover-bg, #e8e8e8)}.spreadsheet-wrapper[data-v-6321c060]{flex:1;position:relative;overflow:hidden;background:var(--sp-wrapper-bg)}.grid-canvas[data-v-6321c060]{position:absolute;top:0;left:0;display:block;outline:none;cursor:cell}.grid-canvas[data-v-6321c060]:focus{outline:none}.v-scrollbar[data-v-6321c060]{position:absolute;right:0;top:0;width:11px;height:calc(100% - 11px);display:flex;flex-direction:column;background:var(--sp-wrapper-bg)}.h-scrollbar[data-v-6321c060]{position:absolute;left:0;bottom:0;height:11px;width:calc(100% - 11px);display:flex;background:var(--sp-wrapper-bg)}.sb-corner[data-v-6321c060]{position:absolute;right:0;bottom:0;width:11px;height:11px;background:var(--sp-wrapper-bg)}.sb-btn[data-v-6321c060]{width:11px;height:11px;min-width:11px;min-height:11px;border:none;background:var(--sp-scroll-btn-bg, #e8e8e8);display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0;-webkit-user-select:none;user-select:none}.sb-btn[data-v-6321c060]:hover{background:var(--sp-scroll-btn-hover-bg, #d0d0d0)}.sb-btn[data-v-6321c060]:active{background:var(--sp-scroll-btn-active-bg, #c0c0c0)}.sb-arrow[data-v-6321c060]{display:block;width:0;height:0}.sb-arrow--up[data-v-6321c060]{border-left:3px solid transparent;border-right:3px solid transparent;border-bottom:4px solid var(--sp-scroll-btn-color, #666)}.sb-arrow--down[data-v-6321c060]{border-left:3px solid transparent;border-right:3px solid transparent;border-top:4px solid var(--sp-scroll-btn-color, #666)}.sb-arrow--left[data-v-6321c060]{border-top:3px solid transparent;border-bottom:3px solid transparent;border-right:4px solid var(--sp-scroll-btn-color, #666)}.sb-arrow--right[data-v-6321c060]{border-top:3px solid transparent;border-bottom:3px solid transparent;border-left:4px solid var(--sp-scroll-btn-color, #666)}.sb-track[data-v-6321c060]{flex:1;position:relative;background:var(--sp-scroll-track-bg, rgba(0,0,0,.06))}.sb-track--v[data-v-6321c060]{width:11px}.sb-track--h[data-v-6321c060]{height:11px}.sb-thumb[data-v-6321c060]{position:absolute;border-radius:3px;background:var(--sp-scroll-thumb);cursor:default}.sb-thumb[data-v-6321c060]:hover{background:var(--sp-scroll-thumb-hover)}.sb-thumb--v[data-v-6321c060]{left:1px;right:1px;min-height:16px}.sb-thumb--h[data-v-6321c060]{top:1px;bottom:1px;min-width:16px}.cell-editor[data-v-6321c060]{position:absolute;border:2px solid var(--sp-cell-editor-border);outline:none;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;font-size:13px;color:var(--sp-cell-editor-color);background:var(--sp-cell-editor-bg);box-shadow:0 0 0 1px var(--sp-cell-editor-shadow);z-index:10;box-sizing:border-box;min-width:0;overflow:hidden;padding:0;margin:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;resize:none;white-space:pre-wrap;word-break:break-all}.context-menu{position:fixed;z-index:10000;background:#fff;border:1px solid #ccc;border-radius:4px;box-shadow:0 2px 8px #00000026;padding:4px 0;min-width:120px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;font-size:13px;transform-origin:top left}.context-menu__item{padding:6px 20px;cursor:pointer;color:#333;white-space:nowrap;position:relative;display:flex;align-items:center;justify-content:space-between}.context-menu__item:hover{background:#e8f0fe}.context-menu__item--disabled{color:#bbb;cursor:default}.context-menu__item--disabled:hover{background:transparent}.context-menu__arrow{margin-left:16px;margin-right:-5px;width:0;height:0;border-top:3px solid transparent;border-bottom:3px solid transparent;border-left:4px solid #888}.context-submenu{display:none;position:absolute;left:100%;top:-4px;background:#fff;border:1px solid #ccc;border-radius:4px;box-shadow:0 2px 8px #00000026;padding:4px 0;min-width:100px;z-index:10001}.context-submenu--left{left:auto;right:100%}.context-menu__item:hover>.context-submenu{display:block}.context-submenu .context-menu__item{justify-content:flex-start}.menu-pop-enter-active,.menu-pop-leave-active{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from,.menu-pop-leave-to{opacity:0;transform:scale(.9)}.dim-panel{position:fixed;z-index:10002;width:220px;background:#fff;border:1px solid #ccc;border-radius:4px;box-shadow:0 2px 8px #00000026;padding:10px 12px;box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;-webkit-user-select:none;user-select:none;transform-origin:top left}.dim-panel__title{font-size:13px;font-weight:600;color:#333;margin-bottom:8px}.dim-panel__body{display:flex;align-items:center;gap:6px}.dim-panel__input{flex:1;height:26px;border:1px solid #c0c0c0;border-radius:3px;outline:none;padding:0 6px;font-size:13px;color:#1a1a1a;background:#fff;box-sizing:border-box}.dim-panel__input:focus{border-color:#0078d7;box-shadow:0 0 0 1px #0078d74d}.dim-panel__input--error{border-color:#d93025;box-shadow:0 0 0 1px #d930254d}.dim-panel__unit{font-size:12px;color:#888}.dim-panel__error{margin-top:6px;font-size:12px;color:#d93025;line-height:1.4}.dim-panel__footer{display:flex;justify-content:flex-end;gap:8px;margin-top:10px}.dim-panel__btn{height:26px;padding:0 14px;border:1px solid #ccc;border-radius:3px;background:#fff;color:#333;font-size:13px;cursor:pointer}.dim-panel__btn:hover{background:#f0f0f0}.dim-panel__btn--primary{border-color:#0078d7;background:#0078d7;color:#fff}.dim-panel__btn--primary:hover{background:#0069c0}
1
+ .sp-dropdown[data-v-77df3baf]{position:relative;display:inline-flex;min-width:0}.sp-dropdown__trigger[data-v-77df3baf]{display:flex;align-items:center;justify-content:space-between;gap:4px;width:100%;height:26px;border:1px solid transparent;border-radius:3px;background:transparent;color:var(--sp-toolbar-btn-color, #444);font-size:12px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;cursor:pointer;padding:0 5px;box-sizing:border-box}.sp-dropdown__trigger[data-v-77df3baf]:hover{background:var(--sp-toolbar-btn-hover-bg, #e6e6e6)}.sp-dropdown__trigger--open[data-v-77df3baf]{background:var(--sp-toolbar-btn-hover-bg, #e6e6e6);border-color:var(--sp-toolbar-border, #d8d8d8)}.sp-dropdown__value[data-v-77df3baf]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left}.sp-dropdown__caret[data-v-77df3baf]{width:10px;height:10px;min-width:10px;opacity:.7}.sp-dropdown__menu[data-v-77df3baf]{position:fixed;z-index:20000;display:flex;flex-direction:column;background:#fff;border:1px solid var(--sp-toolbar-border, #d0d0d0);border-radius:4px;box-shadow:0 4px 12px #0000001f;padding:4px;box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;transform-origin:top center}.sp-dropdown__menu--up[data-v-77df3baf]{transform-origin:bottom center}.menu-pop-enter-active[data-v-77df3baf],.menu-pop-leave-active[data-v-77df3baf]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-77df3baf],.menu-pop-leave-to[data-v-77df3baf]{opacity:0;transform:scaleY(.85)}.sp-dropdown__nav[data-v-77df3baf]{display:flex;align-items:center;justify-content:center;height:15px;min-height:15px;border:none;background:transparent;color:var(--sp-toolbar-btn-color, #666);cursor:pointer;padding:0;border-radius:3px}.sp-dropdown__nav[data-v-77df3baf]:hover:not(:disabled){background:#eef3f9}.sp-dropdown__nav[data-v-77df3baf]:disabled{color:#ccc;cursor:default}.sp-dropdown__nav svg[data-v-77df3baf]{width:10px;height:10px}.sp-dropdown__list[data-v-77df3baf]{display:flex;flex-direction:column;overflow:hidden;touch-action:none}.sp-dropdown__icon[data-v-77df3baf]{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto}.sp-dropdown__icon[data-v-77df3baf] svg{width:18px;height:18px;display:block}.sp-dropdown__item-icon[data-v-77df3baf]{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto}.sp-dropdown__item-icon[data-v-77df3baf] svg{width:16px;height:16px;display:block}.sp-dropdown__item-label[data-v-77df3baf]{white-space:nowrap}.sp-dropdown__item[data-v-77df3baf]{display:flex;align-items:center;gap:6px;width:100%;border:none;background:transparent;color:var(--sp-toolbar-btn-color, #444);font-size:12px;cursor:pointer;padding:4px 8px;box-sizing:border-box;border-radius:3px}.sp-dropdown__item[data-v-77df3baf]:hover{background:#eef3f9}.sp-dropdown__item--active[data-v-77df3baf]{background:#e5f1fb;color:#0078d7}.color-picker[data-v-f8fac424]{position:relative;display:inline-flex;height:26px}.color-picker__menu[data-v-f8fac424]{position:fixed;z-index:9999;background:#fff;border:1px solid var(--sp-toolbar-border, #d0d0d0);border-radius:4px;padding:6px;box-shadow:0 4px 12px #0000001f;-webkit-user-select:none;user-select:none;transform-origin:top right}.menu-pop-enter-active[data-v-f8fac424],.menu-pop-leave-active[data-v-f8fac424]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-f8fac424],.menu-pop-leave-to[data-v-f8fac424]{opacity:0;transform:scale(.9)}.color-picker__row[data-v-f8fac424]{display:flex;gap:4px;margin-bottom:4px}.color-picker__row[data-v-f8fac424]:last-child{margin-bottom:0}.color-picker__swatch[data-v-f8fac424]{width:20px;height:20px;padding:0;border-radius:50%;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:transform .08s,box-shadow .08s;position:relative}.color-picker__swatch[data-v-f8fac424]:hover{transform:scale(1.18);box-shadow:0 0 0 1px #0003;z-index:1}.color-picker__swatch--selected[data-v-f8fac424]{box-shadow:0 0 0 2px #0078d7}.border-picker[data-v-f362abdb]{position:relative;display:inline-flex;height:26px}.border-picker__menu[data-v-f362abdb]{position:fixed;z-index:9999;background:#fff;border:1px solid var(--sp-toolbar-border, #d0d0d0);border-radius:4px;box-shadow:0 4px 12px #0000001f;-webkit-user-select:none;user-select:none;padding:4px;transform-origin:top right}.border-picker__item[data-v-f362abdb]{display:flex;align-items:center;gap:6px;width:100%;padding:4px 8px;border:none;background:transparent;color:var(--sp-toolbar-btn-color, #444);cursor:pointer;border-radius:3px;font-size:12px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;white-space:nowrap}.border-picker__item[data-v-f362abdb]:hover{background:#eef3f9}.border-picker__icon[data-v-f362abdb]{width:18px;height:18px;flex-shrink:0}.border-picker__label[data-v-f362abdb]{overflow:hidden;text-overflow:ellipsis}.menu-pop-enter-active[data-v-f362abdb],.menu-pop-leave-active[data-v-f362abdb]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-f362abdb],.menu-pop-leave-to[data-v-f362abdb]{opacity:0;transform:scale(.9)}.merge-picker[data-v-67c0f9e3]{position:relative;display:inline-flex;height:26px}.merge-picker__menu[data-v-67c0f9e3]{position:fixed;z-index:9999;background:#fff;border:1px solid var(--sp-toolbar-border, #d0d0d0);border-radius:4px;box-shadow:0 4px 12px #0000001f;-webkit-user-select:none;user-select:none;padding:4px;transform-origin:top right}.merge-picker__item[data-v-67c0f9e3]{display:flex;align-items:center;gap:6px;width:100%;padding:4px 8px;border:none;background:transparent;color:var(--sp-toolbar-btn-color, #444);cursor:pointer;border-radius:3px;font-size:12px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;white-space:nowrap}.merge-picker__item[data-v-67c0f9e3]:hover{background:#eef3f9}.merge-picker__icon[data-v-67c0f9e3]{width:18px;height:18px;flex-shrink:0;display:flex;align-items:center;justify-content:center}.merge-picker__icon[data-v-67c0f9e3] svg{width:18px;height:18px}.merge-picker__label[data-v-67c0f9e3]{overflow:hidden;text-overflow:ellipsis}.menu-pop-enter-active[data-v-67c0f9e3],.menu-pop-leave-active[data-v-67c0f9e3]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-67c0f9e3],.menu-pop-leave-to[data-v-67c0f9e3]{opacity:0;transform:scale(.9)}.calc-picker[data-v-9029e58c]{position:relative;display:inline-flex;height:26px}.calc-picker__menu[data-v-9029e58c]{position:fixed;z-index:9999;min-width:120px;background:#fff;border:1px solid var(--sp-toolbar-border, #d0d0d0);border-radius:4px;box-shadow:0 4px 12px #0000001f;-webkit-user-select:none;user-select:none;padding:4px;transform-origin:top right}.calc-picker__item[data-v-9029e58c]{display:flex;align-items:center;gap:6px;width:100%;padding:4px 8px;border:none;background:transparent;color:var(--sp-toolbar-btn-color, #444);cursor:pointer;border-radius:3px;font-size:12px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;white-space:nowrap}.calc-picker__item[data-v-9029e58c]:hover:not(.calc-picker__item--disabled){background:#eef3f9}.calc-picker__item--disabled[data-v-9029e58c]{color:var(--sp-toolbar-btn-disabled-color, #bbb);cursor:default}.calc-picker__label[data-v-9029e58c]{overflow:hidden;text-overflow:ellipsis}.menu-pop-enter-active[data-v-9029e58c],.menu-pop-leave-active[data-v-9029e58c]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-9029e58c],.menu-pop-leave-to[data-v-9029e58c]{opacity:0;transform:scale(.9)}.toolbar[data-v-7328a54c]{position:relative;display:flex;align-items:center;height:32px;min-height:32px;gap:2px;padding:0 6px;background:var(--sp-toolbar-bg);border-bottom:1px solid var(--sp-toolbar-border);-webkit-user-select:none;user-select:none}.tb-item[data-v-7328a54c]{display:flex;align-items:center;flex:0 0 auto}.toolbar-sep[data-v-7328a54c]{width:1px;height:18px;margin:0 4px;background:var(--sp-toolbar-border)}.toolbar-font[data-v-7328a54c],.toolbar-number-format[data-v-7328a54c],.toolbar-align[data-v-7328a54c]{flex:0 0 auto}.toolbar-font-size[data-v-7328a54c]{display:inline-flex;align-items:center;gap:0;height:26px;position:relative}.toolbar-font-size__input[data-v-7328a54c]{width:36px;height:26px;border:1px solid transparent;border-right:none;border-radius:3px 0 0 3px;background:transparent;color:var(--sp-toolbar-btn-color);font-size:12px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;text-align:left;padding:0 5px;outline:none;box-sizing:border-box;-webkit-appearance:none;appearance:none;-moz-appearance:textfield}.toolbar-font-size__input[data-v-7328a54c]::-webkit-outer-spin-button,.toolbar-font-size__input[data-v-7328a54c]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.toolbar-font-size__input[data-v-7328a54c]:hover{background:var(--sp-toolbar-btn-hover-bg)}.toolbar-font-size__input[data-v-7328a54c]:focus{border-color:var(--sp-toolbar-border);background:#fff}.toolbar-font-size__btn[data-v-7328a54c]{display:flex;align-items:center;justify-content:center;width:16px;height:26px;border:1px solid transparent;border-left:none;border-radius:0 3px 3px 0;background:transparent;color:var(--sp-toolbar-btn-color);cursor:pointer;padding:0}.toolbar-font-size__btn[data-v-7328a54c]:hover{background:var(--sp-toolbar-btn-hover-bg)}.toolbar-font-size__btn svg[data-v-7328a54c]{width:10px;height:10px}.toolbar-font-size__dropdown[data-v-7328a54c]{position:absolute;width:56px;height:26px;pointer-events:none}.toolbar-btn[data-v-7328a54c]{display:flex;align-items:center;justify-content:center;width:30px;height:26px;border:none;border-radius:3px;background:transparent;color:var(--sp-toolbar-btn-color);cursor:pointer;padding:0}.toolbar-btn[data-v-7328a54c]:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.toolbar-btn[data-v-7328a54c]:active:not(:disabled){opacity:.7}.toolbar-btn--active[data-v-7328a54c]{background:var(--sp-toolbar-btn-hover-bg);color:var(--sp-toolbar-btn-active-color)}.toolbar-btn--step[data-v-7328a54c]{width:26px;height:26px}.toolbar-btn--step svg[data-v-7328a54c]{width:16px;height:16px}.toolbar-btn[data-v-7328a54c]:disabled{color:var(--sp-toolbar-btn-disabled-color);cursor:default}.toolbar-btn__icon[data-v-7328a54c]{width:18px;height:18px}.toolbar-btn svg[data-v-7328a54c]:not(.toolbar-btn__icon){width:18px;height:18px}.toolbar-split[data-v-7328a54c]{display:inline-flex;align-items:center;position:relative;height:26px}.toolbar-split__main[data-v-7328a54c]{border:1px solid transparent;border-right:none;border-radius:3px 0 0 3px}.toolbar-split__arrow[data-v-7328a54c]{display:flex;align-items:center;justify-content:center;width:16px;height:26px;border:1px solid transparent;border-radius:0 3px 3px 0;background:transparent;color:var(--sp-toolbar-btn-color);cursor:pointer;padding:0}.toolbar-split__arrow[data-v-7328a54c]:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.toolbar-split__arrow svg[data-v-7328a54c]{width:10px!important;height:10px!important}.toolbar-more[data-v-7328a54c]{display:flex;align-items:center;justify-content:center;width:30px;height:26px;border:none;border-radius:3px;background:transparent;color:var(--sp-toolbar-btn-color);cursor:pointer;padding:0;flex:0 0 auto;margin-left:auto}.toolbar-more[data-v-7328a54c]:hover{background:var(--sp-toolbar-btn-hover-bg)}.toolbar-more--active[data-v-7328a54c]{background:var(--sp-toolbar-btn-hover-bg);color:var(--sp-toolbar-btn-active-color)}.toolbar-more svg[data-v-7328a54c]{width:18px;height:18px}.overflow-menu[data-v-7328a54c]{min-width:180px;max-width:260px;max-height:calc(100vh - 40px);overflow-y:auto;background:var(--sp-toolbar-bg, #fff);border:1px solid var(--sp-toolbar-border);border-radius:4px;box-shadow:0 4px 12px #0000001f;padding:4px 6px;display:flex;flex-direction:column;gap:2px;z-index:1000;transform-origin:top right}.overflow-menu.no-anim[data-v-7328a54c]{transition:none!important}.overflow-menu .tb-item[data-v-7328a54c]{width:100%}.overflow-menu .toolbar-sep[data-v-7328a54c]{width:100%;height:1px;margin:2px 0}.overflow-menu .toolbar-split[data-v-7328a54c]{width:100%}.overflow-menu .toolbar-split__main[data-v-7328a54c]{flex:1 1 auto;justify-content:flex-start;padding-left:6px}.overflow-menu .toolbar-font-size[data-v-7328a54c]{width:100%;justify-content:flex-start}.overflow-menu .toolbar-font[data-v-7328a54c],.overflow-menu .toolbar-number-format[data-v-7328a54c],.overflow-menu .toolbar-align[data-v-7328a54c]{width:100%}.overflow-menu .toolbar-btn[data-v-7328a54c]:not(.toolbar-btn--step):not(.toolbar-split__arrow){width:100%;justify-content:flex-start;padding-left:6px}.overflow-menu .toolbar-color[data-v-7328a54c]{width:100%}.overflow-menu .toolbar-wrap[data-v-7328a54c]{width:100%;justify-content:flex-start}.menu-pop-enter-active[data-v-7328a54c],.menu-pop-leave-active[data-v-7328a54c]{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from[data-v-7328a54c],.menu-pop-leave-to[data-v-7328a54c]{opacity:0;transform:scale(.9)}.overflow-menu .tb-item{width:100%}.overflow-menu .toolbar-sep{width:100%;height:1px;margin:2px 0}.overflow-menu .toolbar-split{width:100%}.overflow-menu .toolbar-split__main{flex:1 1 auto;justify-content:flex-start;padding-left:6px}.overflow-menu .toolbar-font-size{width:100%;justify-content:flex-start}.overflow-menu .toolbar-font,.overflow-menu .toolbar-number-format,.overflow-menu .toolbar-align{width:100%}.overflow-menu .toolbar-btn:not(.toolbar-btn--step):not(.toolbar-split__arrow){width:100%;justify-content:flex-start;padding-left:6px}.overflow-menu .toolbar-color{width:100%}.overflow-menu .toolbar-wrap{width:100%;justify-content:flex-start}.overflow-menu .toolbar-font-size__input{flex:1 1 auto;width:auto;min-width:40px}.overflow-menu .toolbar-btn:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.overflow-menu .toolbar-btn:active:not(:disabled){opacity:.7}.overflow-menu .toolbar-btn--active{background:var(--sp-toolbar-btn-hover-bg);color:var(--sp-toolbar-btn-active-color)}.overflow-menu .toolbar-btn:disabled{color:var(--sp-toolbar-btn-disabled-color);cursor:default}.overflow-menu .toolbar-split__main:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.overflow-menu .toolbar-split__arrow:hover:not(:disabled){background:var(--sp-toolbar-btn-hover-bg)}.overflow-menu .toolbar-font-size__input:hover{background:var(--sp-toolbar-btn-hover-bg)}.overflow-menu .toolbar-font-size__input:focus{border-color:var(--sp-toolbar-border);background:#fff}.overflow-menu .toolbar-font-size__btn:hover,.overflow-menu .toolbar-more:hover{background:var(--sp-toolbar-btn-hover-bg)}.overflow-menu .toolbar-more--active{background:var(--sp-toolbar-btn-hover-bg);color:var(--sp-toolbar-btn-active-color)}.tab-bar[data-v-454e1a12]{display:flex;align-items:stretch;height:30px;min-height:30px;background:var(--sp-tab-bar-bg);border-top:1px solid var(--sp-tab-bar-border);-webkit-user-select:none;user-select:none;margin-top:4px}.tab-list[data-v-454e1a12]{display:flex;align-items:flex-start;flex:1;overflow:hidden;gap:1px;padding:0 1px}.tab-item[data-v-454e1a12]{display:flex;align-items:center;height:28px;min-width:0;max-width:120px;padding:0 10px;cursor:pointer;border:1px solid var(--sp-tab-inactive-border);background:var(--sp-tab-inactive-bg);color:var(--sp-tab-inactive-color);font-size:14px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;white-space:nowrap;transition:background .1s}.tab-item[data-v-454e1a12]:hover{background:var(--sp-tab-hover-bg)}.tab-item--active[data-v-454e1a12]{height:28px;background:var(--sp-tab-active-bg);color:var(--sp-tab-active-color);border-color:var(--sp-tab-active-bg) var(--sp-tab-bar-border) var(--sp-tab-bar-border);border-top:2px solid var(--sp-tab-active-border);font-size:16px}.tab-item--active[data-v-454e1a12]:hover{background:var(--sp-tab-active-bg)}.tab-item__name[data-v-454e1a12]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tab-rename-input[data-v-454e1a12]{width:100%;height:18px;border:none;border-radius:0;outline:none;padding:0;font-size:16px;font-family:inherit;background:var(--sp-tab-active-bg);color:var(--sp-tab-active-color);box-sizing:border-box}.tab-bar__add-btn[data-v-454e1a12]{width:24px;min-width:24px;height:24px;margin:0 4px 3px 3px;border:none;background:transparent;color:var(--sp-tab-add-btn-color);font-size:16px;line-height:22px;text-align:center;cursor:pointer;padding:0}.tab-bar__add-btn[data-v-454e1a12]:hover{background:var(--sp-tab-add-btn-hover-bg)}.nf-dialog__mask[data-v-69cb36b7]{position:fixed;top:0;right:0;bottom:0;left:0;z-index:30000;background:rgba(0,0,0,.25);display:flex;align-items:center;justify-content:center}.nf-dialog[data-v-69cb36b7]{width:380px;max-width:calc(100vw - 32px);max-height:calc(100vh - 48px);overflow-y:auto;background:#fff;border:1px solid #d0d0d0;border-radius:6px;box-shadow:0 8px 24px #0000002e;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;color:#1a1a1a;-webkit-user-select:none;user-select:none}.nf-dialog__header[data-v-69cb36b7]{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;border-bottom:1px solid #ececec}.nf-dialog__title[data-v-69cb36b7]{font-size:13px;font-weight:600}.nf-dialog__close[data-v-69cb36b7]{display:flex;align-items:center;justify-content:center;width:22px;height:22px;border:none;background:transparent;color:#888;cursor:pointer;border-radius:3px;padding:0}.nf-dialog__close[data-v-69cb36b7]:hover{background:#f0f0f0;color:#444}.nf-dialog__close svg[data-v-69cb36b7]{width:14px;height:14px}.nf-dialog__body[data-v-69cb36b7]{padding:12px 14px;display:flex;flex-direction:column;gap:10px}.nf-field[data-v-69cb36b7]{display:flex;align-items:center;gap:8px}.nf-field--inline[data-v-69cb36b7]{min-height:26px}.nf-field__label[data-v-69cb36b7]{width:88px;min-width:88px;font-size:12px;color:#555}.nf-field__select[data-v-69cb36b7],.nf-field__input[data-v-69cb36b7]{flex:1;height:26px;border:1px solid #c0c0c0;border-radius:3px;background:#fff;font-size:12px;color:#1a1a1a;padding:0 6px;outline:none;box-sizing:border-box;font-family:inherit}.nf-field__select[data-v-69cb36b7]:focus,.nf-field__input[data-v-69cb36b7]:focus{border-color:#0078d7;box-shadow:0 0 0 1px #0078d74d}.nf-field__textarea[data-v-69cb36b7]{flex:1;min-height:44px;border:1px solid #c0c0c0;border-radius:3px;background:#fff;font-size:12px;color:#1a1a1a;padding:4px 6px;outline:none;box-sizing:border-box;resize:none;font-family:Consolas,Courier New,monospace}.nf-field__textarea[data-v-69cb36b7]:focus{border-color:#0078d7;box-shadow:0 0 0 1px #0078d74d}.nf-checkbox[data-v-69cb36b7]{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:#333;cursor:pointer}.nf-checkbox input[data-v-69cb36b7]{margin:0;cursor:pointer}.nf-dialog__footer[data-v-69cb36b7]{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:10px 14px;border-top:1px solid #ececec}.nf-preview[data-v-69cb36b7]{display:flex;flex-direction:column;gap:2px;min-width:0}.nf-preview__label[data-v-69cb36b7]{font-size:11px;color:#888}.nf-preview__value[data-v-69cb36b7]{font-size:13px;color:#1a1a1a;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:180px}.nf-dialog__actions[data-v-69cb36b7]{display:flex;gap:8px}.nf-btn[data-v-69cb36b7]{height:28px;padding:0 16px;border:1px solid #ccc;border-radius:3px;background:#fff;color:#333;font-size:12px;cursor:pointer;font-family:inherit}.nf-btn[data-v-69cb36b7]:hover{background:#f0f0f0}.nf-btn--primary[data-v-69cb36b7]{border-color:#0078d7;background:#0078d7;color:#fff}.nf-btn--primary[data-v-69cb36b7]:hover{background:#0069c0}.nf-dialog-enter-active[data-v-69cb36b7],.nf-dialog-leave-active[data-v-69cb36b7]{transition:opacity .14s ease-out}.nf-dialog-enter-from[data-v-69cb36b7],.nf-dialog-leave-to[data-v-69cb36b7]{opacity:0}.nf-dialog-enter-active .nf-dialog[data-v-69cb36b7],.nf-dialog-leave-active .nf-dialog[data-v-69cb36b7]{transition:transform .14s ease-out}.nf-dialog-enter-from .nf-dialog[data-v-69cb36b7],.nf-dialog-leave-to .nf-dialog[data-v-69cb36b7]{transform:scale(.96)}.spreadsheet-outer[data-v-a54563ff]{flex:1;display:flex;flex-direction:column;overflow:hidden;height:100%;min-height:400px;width:100%}.formula-bar[data-v-a54563ff]{display:flex;align-items:flex-start;min-height:36px;padding:0;gap:0}.formula-bar--expanded[data-v-a54563ff]{min-height:72px}.formula-bar__cell-label[data-v-a54563ff]{width:48px;min-width:48px;height:28px;line-height:28px;margin-top:4px;text-align:center;font-size:12px;font-weight:600;color:var(--sp-formula-bar-label-color);background:var(--sp-formula-bar-label-bg);border:1px solid var(--sp-formula-bar-label-border);border-radius:2px;-webkit-user-select:none;user-select:none}.formula-bar__buttons[data-v-a54563ff]{display:inline-flex;align-items:stretch;margin-top:4px;margin-left:6px;height:28px;border:1px solid var(--sp-formula-bar-input-border);border-radius:2px;overflow:hidden;background:var(--sp-formula-bar-input-bg)}.formula-bar__btn[data-v-a54563ff]{width:22px;height:28px;border:none;border-radius:0;background:transparent;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0;-webkit-user-select:none;user-select:none;color:inherit}.formula-bar__btn+.formula-bar__btn[data-v-a54563ff]{border-left:1px solid var(--sp-formula-bar-input-border)}.formula-bar__btn[data-v-a54563ff]:hover{background:var(--sp-scroll-btn-hover-bg, #f0f0f0)}.formula-bar__btn--cancel[data-v-a54563ff]:hover{color:#e53935;background:#fdecea}.formula-bar__btn--accept[data-v-a54563ff]:hover{color:#2e7d32;background:#e8f5e9}.formula-bar__input[data-v-a54563ff]{flex:1;min-height:28px;height:28px;line-height:20px;margin-top:4px;border:1px solid var(--sp-formula-bar-input-border);border-radius:2px;outline:none;padding:3px 6px;margin-left:4px;font-size:13px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;color:var(--sp-formula-bar-input-color);background:var(--sp-formula-bar-input-bg);resize:none;overflow:hidden;box-sizing:border-box}.formula-bar__input--expanded[data-v-a54563ff]{height:68px;overflow:auto}.formula-bar__input[data-v-a54563ff]:focus{border-color:var(--sp-formula-bar-input-focus-border);box-shadow:0 0 0 1px var(--sp-formula-bar-input-focus-shadow)}.formula-bar__toggle[data-v-a54563ff]{width:22px;min-width:22px;height:28px;margin-top:4px;margin-left:2px;margin-right:2px;border:1px solid var(--sp-formula-bar-input-border);border-radius:2px;background:var(--sp-formula-bar-input-bg);color:var(--sp-formula-bar-input-color);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;padding:0;-webkit-user-select:none;user-select:none}.formula-bar__toggle[data-v-a54563ff]:hover{background:var(--sp-scroll-btn-hover-bg, #e8e8e8)}.spreadsheet-wrapper[data-v-a54563ff]{flex:1;position:relative;overflow:hidden;background:var(--sp-wrapper-bg)}.grid-canvas[data-v-a54563ff]{position:absolute;top:0;left:0;display:block;outline:none;cursor:cell}.grid-canvas[data-v-a54563ff]:focus{outline:none}.v-scrollbar[data-v-a54563ff]{position:absolute;right:0;top:0;width:11px;height:calc(100% - 11px);display:flex;flex-direction:column;background:var(--sp-wrapper-bg)}.h-scrollbar[data-v-a54563ff]{position:absolute;left:0;bottom:0;height:11px;width:calc(100% - 11px);display:flex;background:var(--sp-wrapper-bg)}.sb-corner[data-v-a54563ff]{position:absolute;right:0;bottom:0;width:11px;height:11px;background:var(--sp-wrapper-bg)}.sb-btn[data-v-a54563ff]{width:11px;height:11px;min-width:11px;min-height:11px;border:none;background:var(--sp-scroll-btn-bg, #e8e8e8);display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0;-webkit-user-select:none;user-select:none}.sb-btn[data-v-a54563ff]:hover{background:var(--sp-scroll-btn-hover-bg, #d0d0d0)}.sb-btn[data-v-a54563ff]:active{background:var(--sp-scroll-btn-active-bg, #c0c0c0)}.sb-arrow[data-v-a54563ff]{display:block;width:0;height:0}.sb-arrow--up[data-v-a54563ff]{border-left:3px solid transparent;border-right:3px solid transparent;border-bottom:4px solid var(--sp-scroll-btn-color, #666)}.sb-arrow--down[data-v-a54563ff]{border-left:3px solid transparent;border-right:3px solid transparent;border-top:4px solid var(--sp-scroll-btn-color, #666)}.sb-arrow--left[data-v-a54563ff]{border-top:3px solid transparent;border-bottom:3px solid transparent;border-right:4px solid var(--sp-scroll-btn-color, #666)}.sb-arrow--right[data-v-a54563ff]{border-top:3px solid transparent;border-bottom:3px solid transparent;border-left:4px solid var(--sp-scroll-btn-color, #666)}.sb-track[data-v-a54563ff]{flex:1;position:relative;background:var(--sp-scroll-track-bg, rgba(0,0,0,.06))}.sb-track--v[data-v-a54563ff]{width:11px}.sb-track--h[data-v-a54563ff]{height:11px}.sb-thumb[data-v-a54563ff]{position:absolute;border-radius:3px;background:var(--sp-scroll-thumb);cursor:default}.sb-thumb[data-v-a54563ff]:hover{background:var(--sp-scroll-thumb-hover)}.sb-thumb--v[data-v-a54563ff]{left:1px;right:1px;min-height:16px}.sb-thumb--h[data-v-a54563ff]{top:1px;bottom:1px;min-width:16px}.cell-editor[data-v-a54563ff]{position:absolute;border:2px solid var(--sp-cell-editor-border);outline:none;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;font-size:13px;color:var(--sp-cell-editor-color);background:var(--sp-cell-editor-bg);box-shadow:0 0 0 1px var(--sp-cell-editor-shadow);z-index:10;box-sizing:border-box;min-width:0;overflow:hidden;padding:0;margin:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;resize:none;white-space:pre-wrap;word-break:break-all}.context-menu{position:fixed;z-index:10000;background:#fff;border:1px solid #ccc;border-radius:4px;box-shadow:0 2px 8px #00000026;padding:4px 0;min-width:120px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;font-size:13px;transform-origin:top left}.context-menu__item{padding:6px 20px;cursor:pointer;color:#333;white-space:nowrap;position:relative;display:flex;align-items:center;justify-content:space-between}.context-menu__item:hover{background:#e8f0fe}.context-menu__item--disabled{color:#bbb;cursor:default}.context-menu__item--disabled:hover{background:transparent}.context-menu__arrow{margin-left:16px;margin-right:-5px;width:0;height:0;border-top:3px solid transparent;border-bottom:3px solid transparent;border-left:4px solid #888}.context-submenu{display:none;position:absolute;left:100%;top:-4px;background:#fff;border:1px solid #ccc;border-radius:4px;box-shadow:0 2px 8px #00000026;padding:4px 0;min-width:100px;z-index:10001}.context-submenu--left{left:auto;right:100%}.context-menu__item:hover>.context-submenu{display:block}.context-submenu .context-menu__item{justify-content:flex-start}.menu-pop-enter-active,.menu-pop-leave-active{transition:opacity .12s ease-out,transform .12s ease-out}.menu-pop-enter-from,.menu-pop-leave-to{opacity:0;transform:scale(.9)}.dim-panel{position:fixed;z-index:10002;width:220px;background:#fff;border:1px solid #ccc;border-radius:4px;box-shadow:0 2px 8px #00000026;padding:10px 12px;box-sizing:border-box;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,sans-serif;-webkit-user-select:none;user-select:none;transform-origin:top left}.dim-panel__title{font-size:13px;font-weight:600;color:#333;margin-bottom:8px}.dim-panel__body{display:flex;align-items:center;gap:6px}.dim-panel__input{flex:1;height:26px;border:1px solid #c0c0c0;border-radius:3px;outline:none;padding:0 6px;font-size:13px;color:#1a1a1a;background:#fff;box-sizing:border-box}.dim-panel__input:focus{border-color:#0078d7;box-shadow:0 0 0 1px #0078d74d}.dim-panel__input--error{border-color:#d93025;box-shadow:0 0 0 1px #d930254d}.dim-panel__unit{font-size:12px;color:#888}.dim-panel__error{margin-top:6px;font-size:12px;color:#d93025;line-height:1.4}.dim-panel__footer{display:flex;justify-content:flex-end;gap:8px;margin-top:10px}.dim-panel__btn{height:26px;padding:0 14px;border:1px solid #ccc;border-radius:3px;background:#fff;color:#333;font-size:13px;cursor:pointer}.dim-panel__btn:hover{background:#f0f0f0}.dim-panel__btn--primary{border-color:#0078d7;background:#0078d7;color:#fff}.dim-panel__btn--primary:hover{background:#0069c0}
@@ -1,4 +1,4 @@
1
- export type CalcType = 'sum' | 'avg';
1
+ export type CalcType = 'sum' | 'avg' | 'count';
2
2
  type __VLS_Props = {
3
3
  modelOpen?: boolean;
4
4
  locale?: string;
@@ -57,6 +57,7 @@ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {
57
57
  "apply-merge": () => void;
58
58
  "calc-sum": () => void;
59
59
  "calc-avg": () => void;
60
+ "calc-count": () => void;
60
61
  "font-family-change": (v: string | number) => void;
61
62
  "font-size-change": (v: string | number) => void;
62
63
  "h-align-change": (v: string | number) => void;
@@ -94,6 +95,7 @@ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {
94
95
  "onApply-merge"?: (() => any) | undefined;
95
96
  "onCalc-sum"?: (() => any) | undefined;
96
97
  "onCalc-avg"?: (() => any) | undefined;
98
+ "onCalc-count"?: (() => any) | undefined;
97
99
  "onFont-family-change"?: ((v: string | number) => any) | undefined;
98
100
  "onFont-size-change"?: ((v: string | number) => any) | undefined;
99
101
  "onH-align-change"?: ((v: string | number) => any) | undefined;
@@ -45,9 +45,11 @@ export interface BordersMergeState {
45
45
  clearSelected: () => void;
46
46
  sumSelected: () => void;
47
47
  avgSelected: () => void;
48
+ countSelected: () => void;
48
49
  calcMenuOpen: Ref<boolean>;
49
50
  onCalcMenuToggle: (v: boolean) => void;
50
51
  onCalcSum: () => void;
51
52
  onCalcAvg: () => void;
53
+ onCalcCount: () => void;
52
54
  }
53
55
  export declare function createBordersMerge(s: CoreState, us: UndoStylesState): BordersMergeState;
@@ -1,4 +1,11 @@
1
1
  import type { CellData } from './types';
2
+ /**
3
+ * 公式求值结果:
4
+ * - number:SUM / AVERAGE / COUNT 等数值类公式
5
+ * - string:IF / VLOOKUP 文本返回 / CONCATENATE 等文本类公式
6
+ * - null:求值时出现错误(循环引用、参数非法、未找到等),渲染为 #ERROR
7
+ */
8
+ export type FormulaValue = string | number | null;
2
9
  /** 解析区域引用(如 "A1:B5" → {sc, sr, ec, er}) */
3
10
  export declare function parseRangeRef(rangeRef: string, colCount: number, rowCount: number): {
4
11
  sc: number;
@@ -6,12 +13,14 @@ export declare function parseRangeRef(rangeRef: string, colCount: number, rowCou
6
13
  ec: number;
7
14
  er: number;
8
15
  } | null;
9
- /** 获取单元格数值(用于公式参数求值),返回 0 表示空或非数值 */
16
+ /** 获取单元格标量值(用于公式参数求值)。公式单元格会递归求值,空单元格返回 '' */
17
+ export declare function getCellScalar(col: number, row: number, cells: Record<string, CellData>, colCount: number, rowCount: number): FormulaValue;
18
+ /** 获取单元格数值(用于 SUM/AVERAGE/COUNT 等数值上下文),非数值按 0 处理 */
10
19
  export declare function getNumericValue(col: number, row: number, cells: Record<string, CellData>, colCount: number, rowCount: number): number;
11
20
  export declare function clearEvalCache(): void;
12
- export declare function getEvalCache(): Map<string, number>;
13
- /** 对指定单元格公式求值,返回数值结果;若为普通值则尝试解析为数字 */
14
- export declare function evalFormula(key: string, cells: Record<string, CellData>, colCount: number, rowCount: number): number | null;
21
+ export declare function getEvalCache(): Map<string, FormulaValue>;
22
+ /** 对指定单元格公式求值,返回标量结果;普通值则解析为标量(数字或字符串) */
23
+ export declare function evalFormula(key: string, cells: Record<string, CellData>, colCount: number, rowCount: number): FormulaValue;
15
24
  /** 解析公式中引用的单元格列表(用于依赖追踪) */
16
25
  export declare function parseFormulaRefs(formula: string, colCount: number, rowCount: number): string[];
17
26
  /** 计算单元格显示值(公式则求值,否则返回原值) */