@worm-vue3-print/core 1.3.6 → 1.3.8

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.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @worm-vue3-print/core v1.3.6
2
+ * @worm-vue3-print/core v1.3.8
3
3
  * Copyright (c) 2026 worm <liu_long_qqcom@qq.com>
4
4
  * SPDX-FileCopyrightText: 2026 worm <liu_long_qqcom@qq.com>
5
5
  * SPDX-License-Identifier: MIT
@@ -31,6 +31,13 @@ __export(designer_exports, {
31
31
  BARCODE_MODULE_WIDTH_MM: () => BARCODE_MODULE_WIDTH_MM,
32
32
  BARCODE_QUIET_ZONE_MODULES: () => BARCODE_QUIET_ZONE_MODULES,
33
33
  BARCODE_TEXT_FONT_SIZE_MODULES: () => BARCODE_TEXT_FONT_SIZE_MODULES,
34
+ CROP_AXIS_OPTIONS: () => CROP_AXIS_OPTIONS,
35
+ CROP_GRID_OPTIONS: () => CROP_GRID_OPTIONS,
36
+ CROP_SAMPLE_IMAGE: () => CROP_SAMPLE_IMAGE,
37
+ CROP_SAMPLE_NOTE: () => CROP_SAMPLE_NOTE,
38
+ CROP_SCALE_LABEL: () => CROP_SCALE_LABEL,
39
+ CROP_SCALE_MAX: () => CROP_SCALE_MAX,
40
+ CROP_SCALE_MIN: () => CROP_SCALE_MIN,
34
41
  DEFAULT_DEMO_DATA: () => DEFAULT_DEMO_DATA,
35
42
  DEFAULT_SHRINK_MIN_FONT_SIZE_PT: () => DEFAULT_SHRINK_MIN_FONT_SIZE_PT,
36
43
  ELEMENT_BINDING_REGISTRY: () => ELEMENT_BINDING_REGISTRY,
@@ -38,6 +45,7 @@ __export(designer_exports, {
38
45
  EXTENDED_FUNCTIONS: () => EXTENDED_FUNCTIONS,
39
46
  FIT_SCALE_MIN_PERCENT: () => FIT_SCALE_MIN_PERCENT,
40
47
  GHOST_BORDER_CSS: () => GHOST_BORDER_CSS,
48
+ IMAGE_FIT_OPTIONS: () => IMAGE_FIT_OPTIONS,
41
49
  LABEL_PAPER_GROUP: () => LABEL_PAPER_GROUP,
42
50
  MIN_COL_WIDTH_MM: () => MIN_COL_WIDTH_MM,
43
51
  MIN_SCALE_PERCENT: () => MIN_SCALE_PERCENT,
@@ -54,12 +62,14 @@ __export(designer_exports, {
54
62
  barcodeAvailableBoxMm: () => barcodeAvailableBoxMm,
55
63
  barcodePreferredModuleWidthMm: () => barcodePreferredModuleWidthMm,
56
64
  barcodeUnitsPerModule: () => barcodeUnitsPerModule,
65
+ buildCropAnchor: () => buildCropAnchor,
57
66
  buildRulerTicks: () => buildRulerTicks,
58
67
  calcResizeRect: () => calcResizeRect,
59
68
  canMergeReason: () => canMergeReason,
60
69
  cellFitCapMm: () => cellFitCapMm,
61
70
  cellFitKey: () => cellFitKey,
62
71
  cellFitWidthMm: () => cellFitWidthMm,
72
+ cellImageBoxMm: () => cellImageBoxMm,
63
73
  chooseMajorStepMM: () => chooseMajorStepMM,
64
74
  clampResizedColumnWidth: () => clampResizedColumnWidth,
65
75
  clampScalePercent: () => clampScalePercent,
@@ -71,6 +81,13 @@ __export(designer_exports, {
71
81
  createDefaultTable: () => createDefaultTable,
72
82
  createFieldElement: () => createFieldElement,
73
83
  createRuntimeElement: () => createRuntimeElement,
84
+ cropAxisFields: () => cropAxisFields,
85
+ cropAxisLabel: () => cropAxisLabel,
86
+ cropAxisNote: () => cropAxisNote,
87
+ cropPresetOptions: () => cropPresetOptions,
88
+ cropScalePct: () => cropScalePct,
89
+ cropStyleDeclarations: () => cropStyleDeclarations,
90
+ cropWindow: () => cropWindow,
74
91
  deleteCol: () => deleteCol,
75
92
  deleteRow: () => deleteRow,
76
93
  engine: () => engine2,
@@ -102,18 +119,26 @@ __export(designer_exports, {
102
119
  normalizeSelection: () => normalizeSelection,
103
120
  normalizeTemplateUnits: () => normalizeTemplateUnits,
104
121
  parseCellFitKey: () => parseCellFitKey,
122
+ parseCropAnchor: () => parseCropAnchor,
123
+ propertyTip: () => propertyTip,
105
124
  ptToMm: () => ptToMm,
106
125
  pxToMm: () => pxToMm,
107
126
  resolveBarcodeDesignValue: () => resolveBarcodeDesignValue,
108
127
  resolveBarcodeSize: () => resolveBarcodeSize,
109
128
  resolveCellBorderCss: () => resolveCellBorderCss,
110
129
  resolveCellTextFit: () => resolveCellTextFit,
130
+ resolveCropPreview: () => resolveCropPreview,
131
+ resolveCropTravel: () => resolveCropTravel,
132
+ resolveDesignImageSrc: () => resolveDesignImageSrc,
111
133
  resolveElementBorder: () => resolveElementBorder,
112
134
  resolveElementTextFit: () => resolveElementTextFit,
135
+ resolveOverlayPlacement: () => resolveOverlayPlacement,
113
136
  resolveShrinkMinFontSize: () => resolveShrinkMinFontSize,
114
137
  resolveTextBinding: () => resolveTextBinding,
138
+ resolveToolbarOverflow: () => resolveToolbarOverflow,
115
139
  roundFontSize: () => roundFontSize,
116
140
  safeEval: () => safeEval2,
141
+ sanitizeObjectPosition: () => sanitizeObjectPosition,
117
142
  searchProperties: () => searchProperties,
118
143
  setHeaderRepeat: () => setHeaderRepeat,
119
144
  setRowType: () => setRowType,
@@ -179,6 +204,9 @@ function parseCellFitKey(key) {
179
204
  if (!Number.isFinite(rowIndex) || !Number.isFinite(colIndex)) return void 0;
180
205
  return { elementId: key.slice(0, first), kind, rowIndex, colIndex };
181
206
  }
207
+ function cellImageBoxMm(fit, capMm) {
208
+ return (fit || "contain") === "cover" ? capMm : void 0;
209
+ }
182
210
  function cellFitWidthMm(colWidths, colIndex, cell, defaultPadding = 1) {
183
211
  const span = Math.max(cell?.colspan ?? 1, 1);
184
212
  let width = 0;
@@ -287,6 +315,35 @@ function resolveElementBorder(type, opts) {
287
315
  return { all, edges };
288
316
  }
289
317
 
318
+ // src/render/crop-style.ts
319
+ var OBJECT_POSITION_UNSAFE = /[;"'<>\\(){}\[\]@!#]/;
320
+ var OBJECT_POSITION_MAX_LEN = 64;
321
+ var CROP_SCALE_MIN = 100;
322
+ var CROP_SCALE_MAX = 400;
323
+ function sanitizeObjectPosition(value) {
324
+ const v = (value ?? "").trim();
325
+ if (!v || v.length > OBJECT_POSITION_MAX_LEN || OBJECT_POSITION_UNSAFE.test(v)) return "";
326
+ return v;
327
+ }
328
+ function cropScalePct(fit, scale) {
329
+ if ((fit || "contain") !== "cover") return void 0;
330
+ if (typeof scale !== "number" || !Number.isFinite(scale)) return void 0;
331
+ const pct = Math.round(scale);
332
+ if (pct <= CROP_SCALE_MIN) return void 0;
333
+ return Math.min(pct, CROP_SCALE_MAX);
334
+ }
335
+ function cropStyleDeclarations(fit, scale, objectPosition) {
336
+ const pos = sanitizeObjectPosition(objectPosition);
337
+ const out = {};
338
+ if (pos) out.objectPosition = pos;
339
+ const pct = cropScalePct(fit, scale);
340
+ if (pct !== void 0) {
341
+ out.transform = `scale(${Number((pct / 100).toFixed(2))})`;
342
+ out.transformOrigin = pos || "50% 50%";
343
+ }
344
+ return out;
345
+ }
346
+
290
347
  // src/designer/utils/scale.ts
291
348
  var MIN_SCALE_PERCENT = 25;
292
349
  var FIT_SCALE_MIN_PERCENT = 5;
@@ -304,6 +361,36 @@ function computeFitScale(containerW, containerH, paperW, paperH, ratio = 0.9) {
304
361
  return Math.max(FIT_SCALE_MIN_PERCENT, pct);
305
362
  }
306
363
 
364
+ // src/designer/utils/toolbar-overflow.ts
365
+ var DEFAULT_GAP = 2;
366
+ function resolveToolbarOverflow(input) {
367
+ const gap = input.gap ?? DEFAULT_GAP;
368
+ const chain = [...input.units].sort((a, b) => a.order - b.order);
369
+ if (input.available <= 0) return { movedIds: [], overflowRemains: false };
370
+ if (chain.some((u) => u.width <= 0)) return { movedIds: [], overflowRemains: false };
371
+ const fits = (moved2) => {
372
+ const inline = chain.filter((u) => !moved2.has(u.id));
373
+ const used = input.pinned + inline.reduce((sum2, u) => sum2 + u.width + gap, 0) + (moved2.size > 0 ? input.moreTriggerWidth + gap : 0);
374
+ return used <= input.available;
375
+ };
376
+ if (fits(/* @__PURE__ */ new Set())) return { movedIds: [], overflowRemains: false };
377
+ const moved = /* @__PURE__ */ new Set();
378
+ for (const unit of chain) {
379
+ moved.add(unit.id);
380
+ if (fits(moved)) return { movedIds: [...moved], overflowRemains: false };
381
+ }
382
+ return { movedIds: [...moved], overflowRemains: true };
383
+ }
384
+
385
+ // src/designer/utils/overlay-placement.ts
386
+ function resolveOverlayPlacement(input) {
387
+ const gap = input.gap ?? 4;
388
+ const below = input.boundaryBottom - input.triggerBottom - gap;
389
+ const above = input.triggerTop - input.boundaryTop - gap;
390
+ if (below >= input.overlayHeight) return "down";
391
+ return above > below ? "up" : "down";
392
+ }
393
+
307
394
  // src/designer/utils/migrate.ts
308
395
  var PT_KEYS = ["left", "top", "width", "height"];
309
396
  function convertElement(el) {
@@ -1010,7 +1097,27 @@ var PROPERTY_REGISTRY = [
1010
1097
  { key: "ap-letter-spacing", keywords: ["\u5B57\u95F4\u8DDD", "letterspacing"] },
1011
1098
  { key: "ap-text-fit", keywords: ["\u6EA2\u51FA", "\u6EA2\u51FA\u663E\u793A", "\u622A\u65AD", "\u81EA\u52A8\u7F29\u5C0F", "\u81EA\u9002\u5E94\u884C\u9AD8", "textfit", "overflow"] },
1012
1099
  { key: "ap-shrink-min", keywords: ["\u6700\u5C0F\u5B57\u53F7", "\u7F29\u653E\u4E0B\u9650", "shrinkminfontsize"] },
1013
- { key: "ap-word-wrap", keywords: ["\u81EA\u52A8\u6362\u884C", "\u4E0D\u6362\u884C", "wordwrap"] }
1100
+ { key: "ap-word-wrap", keywords: ["\u81EA\u52A8\u6362\u884C", "\u4E0D\u6362\u884C", "wordwrap"] },
1101
+ {
1102
+ key: "ap-long-text-indent",
1103
+ keywords: ["\u9996\u884C\u7F29\u8FDB", "\u7F29\u8FDB", "indent", "longtextindent", "\u4E24\u5B57\u7B26", "\u6BB5\u9996"],
1104
+ tip: "\u957F\u6587\u672C\u6BCF\u6BB5\u9996\u884C\u7A7A\u51FA\u7684\u5BBD\u5EA6\uFF0C\u5355\u4F4D\u300C\u5B57\u7B26\u300D\uFF1A\u586B 2 \u5373\u7F29\u8FDB\u4E24\u4E2A\u6C49\u5B57\u5BBD\uFF08\u4E2D\u6587\u6392\u7248\u60EF\u4F8B\uFF09\uFF0C\u6309 em \u843D\u7EB8\u2014\u2014\u5B57\u53F7\u88AB\u300C\u81EA\u52A8\u7F29\u5C0F\u300D\u538B\u5C0F\u65F6\u7F29\u8FDB\u540C\u6B65\u53D8\u7A84\u3002\u4EC5\u957F\u6587\u672C\u5143\u7D20\u751F\u6548\uFF0C\u5199\u5728\u666E\u901A\u6587\u672C\u4E0A\u4E0D\u751F\u6548"
1105
+ },
1106
+ {
1107
+ key: "ap-img-fit",
1108
+ keywords: ["\u7F29\u653E\u6A21\u5F0F", "\u62C9\u4F38", "\u7B49\u6BD4", "fit", "contain", "cover", "\u586B\u5145", "\u88C1\u526A", "\u526A\u88C1", "\u951A\u70B9"],
1109
+ tip: "\u56FE\u7247\u5728\u5143\u7D20\u6846\u5185\u7684\u7F29\u653E\u65B9\u5F0F\uFF1A\u5305\u542B\uFF1D\u5B8C\u6574\u663E\u793A\u3001\u53EF\u80FD\u7559\u767D\uFF1B\u526A\u88C1\uFF1D\u94FA\u6EE1\u6846\u5E76\u6309\u300C\u88C1\u526A\u951A\u70B9\u300D\u53D6\u4E00\u5757\uFF1B\u62C9\u4F38\uFF1D\u586B\u6EE1\u6846\u4F1A\u53D8\u5F62\uFF1B\u539F\u59CB\u5C3A\u5BF8\u4E0E\u7F29\u5C0F\u4E0D\u653E\u5927\u3002\u753B\u5E03\u4E0E\u4E09\u6761\u51FA\u7EB8\u94FE\u8DEF\u540C\u4E00\u53E3\u5F84\uFF08\u7F3A\u7701\u5305\u542B\uFF09"
1110
+ },
1111
+ {
1112
+ key: "ap-img-object-position",
1113
+ keywords: ["\u88C1\u526A\u951A\u70B9", "\u526A\u88C1\u951A\u70B9", "\u951A\u70B9", "objectposition", "object-position", "\u5BF9\u9F50\u70B9", "\u4E0A\u79FB", "\u5934\u9876"],
1114
+ tip: "\u53D6\u4F4D\uFF08\u4EC5\u300C\u526A\u88C1\u300D\u6863\u6709\u8FD9\u4E00\u884C\uFF09\uFF1A\u526A\u88C1\u628A\u56FE\u7B49\u6BD4\u94FA\u6EE1\u5143\u7D20\u6846\uFF0C\u591A\u51FA\u6765\u7684\u90A3\u4E00\u6761\u8FB9\u6309\u8FD9\u91CC\u9009\u7684\u4F4D\u7F6E\u53D6\u820D\u3002\u5148\u9009\u4F4D\u7F6E\u6863\uFF08\u8D34\u8FB9\uFF0F\u5C45\u4E2D\uFF0F\u8D34\u53E6\u4E00\u5934\uFF09\uFF0C\u518D\u6309\u767E\u5206\u6BD4\u5FAE\u8C03\uFF0C0 \u8D34\u5DE6\uFF0F\u8D34\u9876\uFF0C100 \u632A\u5230\u53E6\u4E00\u5934\uFF0C\u6C34\u5E73\u4E0E\u5782\u76F4\u5404\u81EA\u72EC\u7ACB\uFF1B\u7F3A\u7701\u53D6\u6B63\u4E2D\u95F4\uFF08\u4FDD\u4F4F\u8BC1\u4EF6\u7167\u5934\u9876\u5C31\u9009\u9876\u90E8\uFF09\u3002\u5176\u4F59\u7F29\u653E\u6A21\u5F0F\u56FE\u6BD4\u6846\u5C0F\u6216\u521A\u597D\u94FA\u6EE1\uFF0C\u6CA1\u6709\u53EF\u88C1\u7684\u8FB9\uFF0C\u6240\u4EE5\u4E0D\u51FA\u672C\u884C"
1115
+ },
1116
+ {
1117
+ key: "ap-img-fit-scale",
1118
+ keywords: ["\u653E\u5927\u6BD4\u4F8B", "\u526A\u88C1\u653E\u5927", "\u653E\u5927\u500D\u6570", "\u53D6\u666F", "\u88C1\u5207\u8303\u56F4", "fitscale", "zoom"],
1119
+ tip: "\u526A\u88C1\u653E\u5927\uFF1A\u7B49\u6BD4\u94FA\u6EE1\u4E4B\u540E\u628A\u753B\u9762\u518D\u63A8\u5927\u8FD9\u4E48\u591A\uFF0C\u4E24\u8F74\u624D\u771F\u7684\u5404\u591A\u51FA\u4E00\u6761\u8FB9\u53EF\u88C1\u2014\u2014\u56FE\u4E0E\u6846\u540C\u6BD4\u4F8B\u65F6\u4E0D\u653E\u5927\u5C31\u4EC0\u4E48\u90FD\u88C1\u4E0D\u6389\u3002100\uFF1D\u4E0D\u653E\u5927\uFF08\u7F3A\u7701\uFF09\uFF0C\u4E0A\u9650 400\uFF1B\u8D85\u51FA\u6846\u7684\u90E8\u5206\u7531\u5143\u7D20\u6846\u88C1\u6389\u3002\u951A\u70B9\u9009\u4E2D\u7684\u90A3\u4E00\u70B9\u65E2\u662F\u53D6\u4F4D\u7684\u9489\u4F4F\u70B9\u3001\u4E5F\u662F\u653E\u5927\u7684\u4E2D\u5FC3\uFF0C\u4E24\u8005\u5171\u7528\u540C\u4E00\u4E2A\u503C\u3002\u4EC5\u300C\u526A\u88C1\u300D\u6863\u751F\u6548\uFF0C\u5176\u4F59\u7F29\u653E\u6A21\u5F0F\u4E0D\u51FA\u672C\u884C"
1120
+ }
1014
1121
  ]
1015
1122
  },
1016
1123
  {
@@ -1023,6 +1130,11 @@ var PROPERTY_REGISTRY = [
1023
1130
  { key: "cd-show-text", keywords: ["\u663E\u793A\u6587\u672C", "\u6761\u7801\u6587\u672C", "\u663E\u793A\u6570\u5B57"] },
1024
1131
  { key: "cd-font-size", keywords: ["\u6761\u7801\u5B57\u53F7", "\u6587\u672C\u5B57\u53F7"] },
1025
1132
  { key: "cd-ec-level", keywords: ["\u7EA0\u9519\u7EA7\u522B", "\u5BB9\u9519", "qrcodelevel"] },
1133
+ {
1134
+ key: "cd-quiet-zone",
1135
+ keywords: ["\u9759\u533A", "\u9759\u533A\u5BBD\u5EA6", "\u767D\u8FB9", "\u7A7A\u767D\u8FB9", "\u7559\u767D", "\u94FA\u6EE1", "quietzone"],
1136
+ tip: "\u4E8C\u7EF4\u7801\u56DB\u5468\u7559\u51FA\u7684\u7A7A\u767D\u683C\u6570\uFF1A0 \u5373\u4E0D\u7559\u767D\u8FB9\u3001\u7801\u9762\u7B49\u6BD4\u94FA\u6EE1\u5143\u7D20\u6846\uFF08\u6B64\u65F6\u9760\u6846\u5916\u7684\u767D\u7EB8\u5145\u5F53\u9759\u533A\uFF09\uFF1B\u6570\u503C\u8D8A\u5927\u767D\u8FB9\u8D8A\u5BBD\u3001\u7801\u9762\u5728\u6846\u5185\u8D8A\u5C0F\uFF08\u7F3A\u7701 0\uFF0C\u9700 ISO/IEC 18004 \u63A8\u8350\u9759\u533A\u65F6\u586B 4\uFF09"
1137
+ },
1026
1138
  { key: "cd-fit", keywords: ["\u7F29\u653E\u6A21\u5F0F", "\u62C9\u4F38", "\u7B49\u6BD4", "fit", "contain", "cover"] },
1027
1139
  { key: "cd-max-width", keywords: ["\u6700\u5927\u5BBD\u5EA6", "\u6700\u5927\u5BBD", "maxwidth"] },
1028
1140
  { key: "cd-max-height", keywords: ["\u6700\u5927\u9AD8\u5EA6", "\u6700\u5927\u9AD8", "maxheight"] }
@@ -1077,6 +1189,13 @@ var PROPERTY_REGISTRY = [
1077
1189
  ]
1078
1190
  }
1079
1191
  ];
1192
+ function propertyTip(key) {
1193
+ for (const group of PROPERTY_REGISTRY) {
1194
+ const hit = group.items.find((item) => item.key === key);
1195
+ if (hit) return hit.tip ?? "";
1196
+ }
1197
+ return "";
1198
+ }
1080
1199
  function matchKeywords(search, keywords) {
1081
1200
  const s = search.trim().toLowerCase();
1082
1201
  if (!s) {
@@ -1099,194 +1218,6 @@ function searchProperties(search) {
1099
1218
  return { groups, itemKeys };
1100
1219
  }
1101
1220
 
1102
- // src/designer/utils/field-groups.ts
1103
- function groupFields(fields) {
1104
- const sorted = [...fields].sort((a, b) => (a.sortOrder ?? 0) - (b.sortOrder ?? 0));
1105
- const groupMap = /* @__PURE__ */ new Map();
1106
- const groupOrder = [];
1107
- for (const f of sorted) {
1108
- const dot = f.fieldKey.indexOf(".");
1109
- if (dot === -1) continue;
1110
- const key = f.fieldKey.slice(0, dot);
1111
- let g = groupMap.get(key);
1112
- if (!g) {
1113
- g = { key, label: key, isList: false, fields: [] };
1114
- groupMap.set(key, g);
1115
- groupOrder.push(key);
1116
- }
1117
- g.fields.push(f);
1118
- }
1119
- const groups = [];
1120
- const standalone = [];
1121
- for (const f of sorted) {
1122
- if (f.fieldKey.includes(".")) continue;
1123
- const g = groupMap.get(f.fieldKey);
1124
- if (g) {
1125
- g.label = f.fieldLabel;
1126
- g.isList = f.fieldType === "list";
1127
- } else {
1128
- standalone.push(f);
1129
- }
1130
- }
1131
- if (standalone.length) groups.push({ key: "", label: "", isList: false, fields: standalone });
1132
- for (const key of groupOrder) groups.push(groupMap.get(key));
1133
- return groups;
1134
- }
1135
- function filterGroups(groups, keyword) {
1136
- const kw = keyword.trim().toLowerCase();
1137
- if (!kw) return groups;
1138
- return groups.map((g) => ({
1139
- ...g,
1140
- fields: g.fields.filter(
1141
- (f) => f.fieldLabel.toLowerCase().includes(kw) || f.fieldKey.toLowerCase().includes(kw)
1142
- )
1143
- })).filter((g) => g.fields.length > 0);
1144
- }
1145
-
1146
- // src/designer/utils/binding-registry.ts
1147
- var ELEMENT_BINDING_REGISTRY = {
1148
- text: [
1149
- { targetPath: "options.formatter", label: "\u5185\u5BB9", dataSource: "main" }
1150
- ],
1151
- longText: [
1152
- { targetPath: "options.formatter", label: "\u5185\u5BB9", dataSource: "main" },
1153
- { targetPath: "options.styler", label: "\u6837\u5F0F", dataSource: "main" }
1154
- ],
1155
- barcode: [
1156
- { targetPath: "options.formatter", label: "\u5185\u5BB9", dataSource: "main" }
1157
- ],
1158
- qrcode: [
1159
- { targetPath: "options.formatter", label: "\u5185\u5BB9", dataSource: "main" }
1160
- ],
1161
- image: [
1162
- { targetPath: "options.src", label: "\u5185\u5BB9", dataSource: "main", placeholder: "\u8F93\u5165\u56FE\u7247\u8DEF\u5F84\uFF0C\u652F\u6301 /docfiles/... \u76F8\u5BF9\u8DEF\u5F84\u3001\u7EDD\u5BF9 URL \u6216 {\u5B57\u6BB5} \u8868\u8FBE\u5F0F" }
1163
- ],
1164
- table: []
1165
- };
1166
- function getTableCellBindings(rowType, rowIndex, cellIndex, listField) {
1167
- if (rowType === "data") {
1168
- return [{
1169
- targetPath: `options.tableRows[${rowIndex}].cells[${cellIndex}].formatter`,
1170
- label: "\u5185\u5BB9",
1171
- dataSource: "list",
1172
- listField,
1173
- placeholder: "{name}"
1174
- }];
1175
- }
1176
- if (rowType === "subtotal") {
1177
- return [{
1178
- targetPath: `options.tableRows[${rowIndex}].cells[${cellIndex}].formatter`,
1179
- label: "\u5185\u5BB9",
1180
- dataSource: "subtotal",
1181
- placeholder: "{MONEY(SUM(amount))}"
1182
- }];
1183
- }
1184
- if (rowType === "summary") {
1185
- return [{
1186
- targetPath: `options.tableRows[${rowIndex}].cells[${cellIndex}].formatter`,
1187
- label: "\u5185\u5BB9",
1188
- dataSource: "summary",
1189
- placeholder: "{MONEY(SUM(amount))}"
1190
- }];
1191
- }
1192
- return [{
1193
- targetPath: `options.tableRows[${rowIndex}].cells[${cellIndex}].formatter`,
1194
- label: "\u5185\u5BB9",
1195
- dataSource: "main",
1196
- placeholder: "\u5408\u8BA1: {order.total}"
1197
- }];
1198
- }
1199
- function getElementBindings(element) {
1200
- const type = element.printElementType.type;
1201
- const staticBindings = ELEMENT_BINDING_REGISTRY[type] ?? [];
1202
- const dynamicBindings = [];
1203
- if (type === "table") {
1204
- const listField = element.options.dataSource;
1205
- for (const [ri, row] of (element.options.tableRows ?? []).entries()) {
1206
- for (const [ci, cell] of row.cells.entries()) {
1207
- if (cell.merged) continue;
1208
- dynamicBindings.push(...getTableCellBindings(row.type, ri, ci, listField));
1209
- }
1210
- }
1211
- }
1212
- return [...staticBindings, ...dynamicBindings];
1213
- }
1214
-
1215
- // src/designer/utils/demo-data.ts
1216
- function getDemoData() {
1217
- return DEFAULT_DEMO_DATA;
1218
- }
1219
- var DEFAULT_DEMO_DATA = {
1220
- supplier: {
1221
- name: "\u946B\u8FBE\u4E94\u91D1\u6709\u9650\u516C\u53F8",
1222
- phone: "0571-88776655",
1223
- address: "\u676D\u5DDE\u5E02\u8427\u5C71\u533A\u7ECF\u6D4E\u5F00\u53D1\u533A88\u53F7"
1224
- },
1225
- receiver: {
1226
- name: "\u674E\u56DB",
1227
- phone: "13912345678",
1228
- address: "\u676D\u5DDE\u5E02\u4F59\u676D\u533A\u6587\u4E00\u897F\u8DEF998\u53F7"
1229
- },
1230
- order: {
1231
- no: "PO20260801001",
1232
- date: "2026-08-01",
1233
- total: 69543.75
1234
- },
1235
- // 50 条商品明细, 用于验证多页分页效果
1236
- goods: [
1237
- { name: "\u78B3\u94A2\u87BA\u4E1D M8", spec: "M14\xD710", unit: "\u4E2A", qty: 100, price: 0.5, amount: 50, remark: "A\u7EA7" },
1238
- { name: "\u4E0D\u9508\u94A2\u87BA\u6BCD M10", spec: "M16\xD711", unit: "\u5957", qty: 117, price: 0.75, amount: 87.75, remark: "" },
1239
- { name: "\u5F39\u7C27\u57AB\u5708 M12", spec: "M6\xD712", unit: "\u76D2", qty: 134, price: 1, amount: 134, remark: "" },
1240
- { name: "\u516D\u89D2\u87BA\u6813 M14", spec: "M5\xD713", unit: "\u652F", qty: 151, price: 1.25, amount: 188.75, remark: "" },
1241
- { name: "\u5185\u516D\u89D2\u87BA\u9489 M16", spec: "M20\xD714", unit: "\u888B", qty: 168, price: 1.5, amount: 252, remark: "" },
1242
- { name: "\u5E73\u57AB\u5708 M6", spec: "M4\xD715", unit: "\u4EF6", qty: 185, price: 1.75, amount: 323.75, remark: "" },
1243
- { name: "\u81EA\u653B\u87BA\u9489 M5", spec: "M3\xD716", unit: "\u6839", qty: 202, price: 2, amount: 404, remark: "" },
1244
- { name: "\u53CC\u5934\u87BA\u67F1 M20", spec: "M8\xD717", unit: "\u5305", qty: 219, price: 2.25, amount: 492.75, remark: "A\u7EA7" },
1245
- { name: "\u7D27\u5B9A\u87BA\u9489 M4", spec: "M10\xD718", unit: "\u53EA", qty: 236, price: 2.5, amount: 590, remark: "" },
1246
- { name: "\u5341\u5B57\u76D8\u5934\u9489 M3", spec: "M12\xD719", unit: "\u7EC4", qty: 253, price: 2.75, amount: 695.75, remark: "" },
1247
- { name: "\u78B3\u94A2\u87BA\u4E1D M8", spec: "M14\xD720", unit: "\u4E2A", qty: 270, price: 3, amount: 810, remark: "" },
1248
- { name: "\u4E0D\u9508\u94A2\u87BA\u6BCD M10", spec: "M16\xD721", unit: "\u5957", qty: 287, price: 3.25, amount: 932.75, remark: "" },
1249
- { name: "\u5F39\u7C27\u57AB\u5708 M12", spec: "M6\xD722", unit: "\u76D2", qty: 304, price: 3.5, amount: 1064, remark: "" },
1250
- { name: "\u516D\u89D2\u87BA\u6813 M14", spec: "M5\xD723", unit: "\u652F", qty: 321, price: 3.75, amount: 1203.75, remark: "" },
1251
- { name: "\u5185\u516D\u89D2\u87BA\u9489 M16", spec: "M20\xD724", unit: "\u888B", qty: 338, price: 4, amount: 1352, remark: "A\u7EA7" },
1252
- { name: "\u5E73\u57AB\u5708 M6", spec: "M4\xD725", unit: "\u4EF6", qty: 355, price: 4.25, amount: 1508.75, remark: "" },
1253
- { name: "\u81EA\u653B\u87BA\u9489 M5", spec: "M3\xD726", unit: "\u6839", qty: 372, price: 4.5, amount: 1674, remark: "" },
1254
- { name: "\u53CC\u5934\u87BA\u67F1 M20", spec: "M8\xD727", unit: "\u5305", qty: 389, price: 4.75, amount: 1847.75, remark: "" },
1255
- { name: "\u7D27\u5B9A\u87BA\u9489 M4", spec: "M10\xD728", unit: "\u53EA", qty: 406, price: 5, amount: 2030, remark: "" },
1256
- { name: "\u5341\u5B57\u76D8\u5934\u9489 M3", spec: "M12\xD729", unit: "\u7EC4", qty: 423, price: 5.25, amount: 2220.75, remark: "" },
1257
- { name: "\u78B3\u94A2\u87BA\u4E1D M8", spec: "M14\xD730", unit: "\u4E2A", qty: 440, price: 0.5, amount: 220, remark: "" },
1258
- { name: "\u4E0D\u9508\u94A2\u87BA\u6BCD M10", spec: "M16\xD731", unit: "\u5957", qty: 457, price: 0.75, amount: 342.75, remark: "A\u7EA7" },
1259
- { name: "\u5F39\u7C27\u57AB\u5708 M12", spec: "M6\xD732", unit: "\u76D2", qty: 474, price: 1, amount: 474, remark: "" },
1260
- { name: "\u516D\u89D2\u87BA\u6813 M14", spec: "M5\xD733", unit: "\u652F", qty: 491, price: 1.25, amount: 613.75, remark: "" },
1261
- { name: "\u5185\u516D\u89D2\u87BA\u9489 M16", spec: "M20\xD734", unit: "\u888B", qty: 508, price: 1.5, amount: 762, remark: "" },
1262
- { name: "\u5E73\u57AB\u5708 M6", spec: "M4\xD735", unit: "\u4EF6", qty: 525, price: 1.75, amount: 918.75, remark: "" },
1263
- { name: "\u81EA\u653B\u87BA\u9489 M5", spec: "M3\xD736", unit: "\u6839", qty: 542, price: 2, amount: 1084, remark: "" },
1264
- { name: "\u53CC\u5934\u87BA\u67F1 M20", spec: "M8\xD737", unit: "\u5305", qty: 559, price: 2.25, amount: 1257.75, remark: "" },
1265
- { name: "\u7D27\u5B9A\u87BA\u9489 M4", spec: "M10\xD738", unit: "\u53EA", qty: 576, price: 2.5, amount: 1440, remark: "A\u7EA7" },
1266
- { name: "\u5341\u5B57\u76D8\u5934\u9489 M3", spec: "M12\xD739", unit: "\u7EC4", qty: 593, price: 2.75, amount: 1630.75, remark: "" },
1267
- { name: "\u78B3\u94A2\u87BA\u4E1D M8", spec: "M14\xD740", unit: "\u4E2A", qty: 610, price: 3, amount: 1830, remark: "" },
1268
- { name: "\u4E0D\u9508\u94A2\u87BA\u6BCD M10", spec: "M16\xD741", unit: "\u5957", qty: 627, price: 3.25, amount: 2037.75, remark: "" },
1269
- { name: "\u5F39\u7C27\u57AB\u5708 M12", spec: "M6\xD742", unit: "\u76D2", qty: 644, price: 3.5, amount: 2254, remark: "" },
1270
- { name: "\u516D\u89D2\u87BA\u6813 M14", spec: "M5\xD743", unit: "\u652F", qty: 661, price: 3.75, amount: 2478.75, remark: "" },
1271
- { name: "\u5185\u516D\u89D2\u87BA\u9489 M16", spec: "M20\xD744", unit: "\u888B", qty: 678, price: 4, amount: 2712, remark: "" },
1272
- { name: "\u5E73\u57AB\u5708 M6", spec: "M4\xD745", unit: "\u4EF6", qty: 695, price: 4.25, amount: 2953.75, remark: "A\u7EA7" },
1273
- { name: "\u81EA\u653B\u87BA\u9489 M5", spec: "M3\xD746", unit: "\u6839", qty: 712, price: 4.5, amount: 3204, remark: "" },
1274
- { name: "\u53CC\u5934\u87BA\u67F1 M20", spec: "M8\xD747", unit: "\u5305", qty: 729, price: 4.75, amount: 3462.75, remark: "" },
1275
- { name: "\u7D27\u5B9A\u87BA\u9489 M4", spec: "M10\xD748", unit: "\u53EA", qty: 746, price: 5, amount: 3730, remark: "" },
1276
- { name: "\u5341\u5B57\u76D8\u5934\u9489 M3", spec: "M12\xD749", unit: "\u7EC4", qty: 763, price: 5.25, amount: 4005.75, remark: "" },
1277
- { name: "\u78B3\u94A2\u87BA\u4E1D M8", spec: "M14\xD710", unit: "\u4E2A", qty: 780, price: 0.5, amount: 390, remark: "" },
1278
- { name: "\u4E0D\u9508\u94A2\u87BA\u6BCD M10", spec: "M16\xD711", unit: "\u5957", qty: 797, price: 0.75, amount: 597.75, remark: "" },
1279
- { name: "\u5F39\u7C27\u57AB\u5708 M12", spec: "M6\xD712", unit: "\u76D2", qty: 814, price: 1, amount: 814, remark: "A\u7EA7" },
1280
- { name: "\u516D\u89D2\u87BA\u6813 M14", spec: "M5\xD713", unit: "\u652F", qty: 831, price: 1.25, amount: 1038.75, remark: "" },
1281
- { name: "\u5185\u516D\u89D2\u87BA\u9489 M16", spec: "M20\xD714", unit: "\u888B", qty: 848, price: 1.5, amount: 1272, remark: "" },
1282
- { name: "\u5E73\u57AB\u5708 M6", spec: "M4\xD715", unit: "\u4EF6", qty: 865, price: 1.75, amount: 1513.75, remark: "" },
1283
- { name: "\u81EA\u653B\u87BA\u9489 M5", spec: "M3\xD716", unit: "\u6839", qty: 882, price: 2, amount: 1764, remark: "" },
1284
- { name: "\u53CC\u5934\u87BA\u67F1 M20", spec: "M8\xD717", unit: "\u5305", qty: 899, price: 2.25, amount: 2022.75, remark: "" },
1285
- { name: "\u7D27\u5B9A\u87BA\u9489 M4", spec: "M10\xD718", unit: "\u53EA", qty: 916, price: 2.5, amount: 2290, remark: "" },
1286
- { name: "\u5341\u5B57\u76D8\u5934\u9489 M3", spec: "M12\xD719", unit: "\u7EC4", qty: 933, price: 2.75, amount: 2565.75, remark: "A\u7EA7" }
1287
- ]
1288
- };
1289
-
1290
1221
  // src/lexer.ts
1291
1222
  var DANGEROUS_PROPS = /* @__PURE__ */ new Set([
1292
1223
  "constructor",
@@ -1998,55 +1929,55 @@ function formatDate(value, fmt) {
1998
1929
  const pad = (n) => String(n).padStart(2, "0");
1999
1930
  return fmt.replace("YYYY", String(date.getFullYear())).replace("MM", pad(date.getMonth() + 1)).replace("DD", pad(date.getDate())).replace("HH", pad(date.getHours())).replace("mm", pad(date.getMinutes())).replace("ss", pad(date.getSeconds()));
2000
1931
  }
1932
+ var CN_DIGITS = ["\u96F6", "\u58F9", "\u8D30", "\u53C1", "\u8086", "\u4F0D", "\u9646", "\u67D2", "\u634C", "\u7396"];
1933
+ var CN_UNITS = ["", "\u62FE", "\u4F70", "\u4EDF"];
1934
+ var CN_GROUP_UNITS = ["", "\u4E07", "\u4EBF", "\u4E07\u4EBF", "\u4EBF\u4EBF"];
1935
+ function fourDigitToCapital(n) {
1936
+ let out = "";
1937
+ let zeroPending = false;
1938
+ for (let pos = 3; pos >= 0; pos--) {
1939
+ const d = Math.floor(n / 10 ** pos) % 10;
1940
+ if (d === 0) {
1941
+ if (out) zeroPending = true;
1942
+ continue;
1943
+ }
1944
+ if (zeroPending) {
1945
+ out += "\u96F6";
1946
+ zeroPending = false;
1947
+ }
1948
+ out += CN_DIGITS[d] + CN_UNITS[pos];
1949
+ }
1950
+ return out;
1951
+ }
2001
1952
  function toUpperCaseAmount(value) {
2002
1953
  const num = Number(value);
2003
1954
  if (isNaN(num)) return String(value);
2004
1955
  if (num === 0) return "\u96F6\u5143\u6574";
2005
- const digits = ["\u96F6", "\u58F9", "\u8D30", "\u53C1", "\u8086", "\u4F0D", "\u9646", "\u67D2", "\u634C", "\u7396"];
2006
- const units = ["", "\u62FE", "\u4F70", "\u4EDF"];
2007
- const bigUnits = ["", "\u4E07", "\u4EBF"];
2008
1956
  const sign = num < 0 ? "\u8D1F" : "";
2009
- const abs = Math.abs(num);
2010
- const [intStr, decStr] = abs.toFixed(2).split(".");
2011
- const intNum = parseInt(intStr, 10);
1957
+ const [intStr, decStr] = Math.abs(num).toFixed(2).split(".");
1958
+ const groupCount = Math.ceil(intStr.length / 4);
2012
1959
  let result = "";
2013
- if (intNum > 0) {
2014
- const intChars = intStr.split("").reverse();
2015
- let groupIdx = 0;
2016
- let lastDigit = 0;
2017
- let needZero = false;
2018
- for (let i = 0; i < intChars.length; i++) {
2019
- const d = parseInt(intChars[i], 10);
2020
- const unit = units[groupIdx % 4];
2021
- const bigUnit = bigUnits[Math.floor(groupIdx / 4)];
2022
- if (d === 0) {
2023
- if (lastDigit !== 0) needZero = true;
2024
- } else {
2025
- if (needZero) {
2026
- result = "\u96F6" + result;
2027
- needZero = false;
2028
- }
2029
- result = digits[d] + unit + result;
2030
- lastDigit = d;
2031
- }
2032
- if (groupIdx % 4 === 3 && groupIdx > 0) {
2033
- result = bigUnit + result;
2034
- }
2035
- groupIdx++;
1960
+ let zeroPending = false;
1961
+ for (let groupIdx = groupCount - 1; groupIdx >= 0; groupIdx--) {
1962
+ const end = intStr.length - groupIdx * 4;
1963
+ const group = parseInt(intStr.slice(Math.max(0, end - 4), end), 10);
1964
+ if (group === 0) {
1965
+ if (result) zeroPending = true;
1966
+ continue;
2036
1967
  }
2037
- result += "\u5143";
1968
+ if (result && (zeroPending || group < 1e3)) result += "\u96F6";
1969
+ zeroPending = false;
1970
+ result += fourDigitToCapital(group) + (CN_GROUP_UNITS[groupIdx] ?? "");
2038
1971
  }
1972
+ result = `${result || "\u96F6"}\u5143`;
2039
1973
  const jiao = parseInt(decStr[0], 10);
2040
1974
  const fen = parseInt(decStr[1], 10);
2041
1975
  if (jiao === 0 && fen === 0) {
2042
1976
  result += "\u6574";
2043
1977
  } else {
2044
- if (jiao > 0) {
2045
- result += digits[jiao] + "\u89D2";
2046
- }
2047
- if (fen > 0) {
2048
- result += digits[fen] + "\u5206";
2049
- }
1978
+ if (jiao === 0) result += "\u96F6";
1979
+ else result += CN_DIGITS[jiao] + "\u89D2";
1980
+ if (fen > 0) result += CN_DIGITS[fen] + "\u5206";
2050
1981
  }
2051
1982
  return sign + result;
2052
1983
  }
@@ -2246,6 +2177,358 @@ function evaluateTemplate2(text, ctx) {
2246
2177
  }
2247
2178
  }
2248
2179
 
2180
+ // src/designer/utils/demo-data.ts
2181
+ function getDemoData() {
2182
+ return DEFAULT_DEMO_DATA;
2183
+ }
2184
+ var DEFAULT_DEMO_DATA = {
2185
+ supplier: {
2186
+ name: "\u946B\u8FBE\u4E94\u91D1\u6709\u9650\u516C\u53F8",
2187
+ phone: "0571-88776655",
2188
+ address: "\u676D\u5DDE\u5E02\u8427\u5C71\u533A\u7ECF\u6D4E\u5F00\u53D1\u533A88\u53F7"
2189
+ },
2190
+ receiver: {
2191
+ name: "\u674E\u56DB",
2192
+ phone: "13912345678",
2193
+ address: "\u676D\u5DDE\u5E02\u4F59\u676D\u533A\u6587\u4E00\u897F\u8DEF998\u53F7"
2194
+ },
2195
+ order: {
2196
+ no: "PO20260801001",
2197
+ date: "2026-08-01",
2198
+ total: 69543.75
2199
+ },
2200
+ // 50 条商品明细, 用于验证多页分页效果
2201
+ goods: [
2202
+ { name: "\u78B3\u94A2\u87BA\u4E1D M8", spec: "M14\xD710", unit: "\u4E2A", qty: 100, price: 0.5, amount: 50, remark: "A\u7EA7" },
2203
+ { name: "\u4E0D\u9508\u94A2\u87BA\u6BCD M10", spec: "M16\xD711", unit: "\u5957", qty: 117, price: 0.75, amount: 87.75, remark: "" },
2204
+ { name: "\u5F39\u7C27\u57AB\u5708 M12", spec: "M6\xD712", unit: "\u76D2", qty: 134, price: 1, amount: 134, remark: "" },
2205
+ { name: "\u516D\u89D2\u87BA\u6813 M14", spec: "M5\xD713", unit: "\u652F", qty: 151, price: 1.25, amount: 188.75, remark: "" },
2206
+ { name: "\u5185\u516D\u89D2\u87BA\u9489 M16", spec: "M20\xD714", unit: "\u888B", qty: 168, price: 1.5, amount: 252, remark: "" },
2207
+ { name: "\u5E73\u57AB\u5708 M6", spec: "M4\xD715", unit: "\u4EF6", qty: 185, price: 1.75, amount: 323.75, remark: "" },
2208
+ { name: "\u81EA\u653B\u87BA\u9489 M5", spec: "M3\xD716", unit: "\u6839", qty: 202, price: 2, amount: 404, remark: "" },
2209
+ { name: "\u53CC\u5934\u87BA\u67F1 M20", spec: "M8\xD717", unit: "\u5305", qty: 219, price: 2.25, amount: 492.75, remark: "A\u7EA7" },
2210
+ { name: "\u7D27\u5B9A\u87BA\u9489 M4", spec: "M10\xD718", unit: "\u53EA", qty: 236, price: 2.5, amount: 590, remark: "" },
2211
+ { name: "\u5341\u5B57\u76D8\u5934\u9489 M3", spec: "M12\xD719", unit: "\u7EC4", qty: 253, price: 2.75, amount: 695.75, remark: "" },
2212
+ { name: "\u78B3\u94A2\u87BA\u4E1D M8", spec: "M14\xD720", unit: "\u4E2A", qty: 270, price: 3, amount: 810, remark: "" },
2213
+ { name: "\u4E0D\u9508\u94A2\u87BA\u6BCD M10", spec: "M16\xD721", unit: "\u5957", qty: 287, price: 3.25, amount: 932.75, remark: "" },
2214
+ { name: "\u5F39\u7C27\u57AB\u5708 M12", spec: "M6\xD722", unit: "\u76D2", qty: 304, price: 3.5, amount: 1064, remark: "" },
2215
+ { name: "\u516D\u89D2\u87BA\u6813 M14", spec: "M5\xD723", unit: "\u652F", qty: 321, price: 3.75, amount: 1203.75, remark: "" },
2216
+ { name: "\u5185\u516D\u89D2\u87BA\u9489 M16", spec: "M20\xD724", unit: "\u888B", qty: 338, price: 4, amount: 1352, remark: "A\u7EA7" },
2217
+ { name: "\u5E73\u57AB\u5708 M6", spec: "M4\xD725", unit: "\u4EF6", qty: 355, price: 4.25, amount: 1508.75, remark: "" },
2218
+ { name: "\u81EA\u653B\u87BA\u9489 M5", spec: "M3\xD726", unit: "\u6839", qty: 372, price: 4.5, amount: 1674, remark: "" },
2219
+ { name: "\u53CC\u5934\u87BA\u67F1 M20", spec: "M8\xD727", unit: "\u5305", qty: 389, price: 4.75, amount: 1847.75, remark: "" },
2220
+ { name: "\u7D27\u5B9A\u87BA\u9489 M4", spec: "M10\xD728", unit: "\u53EA", qty: 406, price: 5, amount: 2030, remark: "" },
2221
+ { name: "\u5341\u5B57\u76D8\u5934\u9489 M3", spec: "M12\xD729", unit: "\u7EC4", qty: 423, price: 5.25, amount: 2220.75, remark: "" },
2222
+ { name: "\u78B3\u94A2\u87BA\u4E1D M8", spec: "M14\xD730", unit: "\u4E2A", qty: 440, price: 0.5, amount: 220, remark: "" },
2223
+ { name: "\u4E0D\u9508\u94A2\u87BA\u6BCD M10", spec: "M16\xD731", unit: "\u5957", qty: 457, price: 0.75, amount: 342.75, remark: "A\u7EA7" },
2224
+ { name: "\u5F39\u7C27\u57AB\u5708 M12", spec: "M6\xD732", unit: "\u76D2", qty: 474, price: 1, amount: 474, remark: "" },
2225
+ { name: "\u516D\u89D2\u87BA\u6813 M14", spec: "M5\xD733", unit: "\u652F", qty: 491, price: 1.25, amount: 613.75, remark: "" },
2226
+ { name: "\u5185\u516D\u89D2\u87BA\u9489 M16", spec: "M20\xD734", unit: "\u888B", qty: 508, price: 1.5, amount: 762, remark: "" },
2227
+ { name: "\u5E73\u57AB\u5708 M6", spec: "M4\xD735", unit: "\u4EF6", qty: 525, price: 1.75, amount: 918.75, remark: "" },
2228
+ { name: "\u81EA\u653B\u87BA\u9489 M5", spec: "M3\xD736", unit: "\u6839", qty: 542, price: 2, amount: 1084, remark: "" },
2229
+ { name: "\u53CC\u5934\u87BA\u67F1 M20", spec: "M8\xD737", unit: "\u5305", qty: 559, price: 2.25, amount: 1257.75, remark: "" },
2230
+ { name: "\u7D27\u5B9A\u87BA\u9489 M4", spec: "M10\xD738", unit: "\u53EA", qty: 576, price: 2.5, amount: 1440, remark: "A\u7EA7" },
2231
+ { name: "\u5341\u5B57\u76D8\u5934\u9489 M3", spec: "M12\xD739", unit: "\u7EC4", qty: 593, price: 2.75, amount: 1630.75, remark: "" },
2232
+ { name: "\u78B3\u94A2\u87BA\u4E1D M8", spec: "M14\xD740", unit: "\u4E2A", qty: 610, price: 3, amount: 1830, remark: "" },
2233
+ { name: "\u4E0D\u9508\u94A2\u87BA\u6BCD M10", spec: "M16\xD741", unit: "\u5957", qty: 627, price: 3.25, amount: 2037.75, remark: "" },
2234
+ { name: "\u5F39\u7C27\u57AB\u5708 M12", spec: "M6\xD742", unit: "\u76D2", qty: 644, price: 3.5, amount: 2254, remark: "" },
2235
+ { name: "\u516D\u89D2\u87BA\u6813 M14", spec: "M5\xD743", unit: "\u652F", qty: 661, price: 3.75, amount: 2478.75, remark: "" },
2236
+ { name: "\u5185\u516D\u89D2\u87BA\u9489 M16", spec: "M20\xD744", unit: "\u888B", qty: 678, price: 4, amount: 2712, remark: "" },
2237
+ { name: "\u5E73\u57AB\u5708 M6", spec: "M4\xD745", unit: "\u4EF6", qty: 695, price: 4.25, amount: 2953.75, remark: "A\u7EA7" },
2238
+ { name: "\u81EA\u653B\u87BA\u9489 M5", spec: "M3\xD746", unit: "\u6839", qty: 712, price: 4.5, amount: 3204, remark: "" },
2239
+ { name: "\u53CC\u5934\u87BA\u67F1 M20", spec: "M8\xD747", unit: "\u5305", qty: 729, price: 4.75, amount: 3462.75, remark: "" },
2240
+ { name: "\u7D27\u5B9A\u87BA\u9489 M4", spec: "M10\xD748", unit: "\u53EA", qty: 746, price: 5, amount: 3730, remark: "" },
2241
+ { name: "\u5341\u5B57\u76D8\u5934\u9489 M3", spec: "M12\xD749", unit: "\u7EC4", qty: 763, price: 5.25, amount: 4005.75, remark: "" },
2242
+ { name: "\u78B3\u94A2\u87BA\u4E1D M8", spec: "M14\xD710", unit: "\u4E2A", qty: 780, price: 0.5, amount: 390, remark: "" },
2243
+ { name: "\u4E0D\u9508\u94A2\u87BA\u6BCD M10", spec: "M16\xD711", unit: "\u5957", qty: 797, price: 0.75, amount: 597.75, remark: "" },
2244
+ { name: "\u5F39\u7C27\u57AB\u5708 M12", spec: "M6\xD712", unit: "\u76D2", qty: 814, price: 1, amount: 814, remark: "A\u7EA7" },
2245
+ { name: "\u516D\u89D2\u87BA\u6813 M14", spec: "M5\xD713", unit: "\u652F", qty: 831, price: 1.25, amount: 1038.75, remark: "" },
2246
+ { name: "\u5185\u516D\u89D2\u87BA\u9489 M16", spec: "M20\xD714", unit: "\u888B", qty: 848, price: 1.5, amount: 1272, remark: "" },
2247
+ { name: "\u5E73\u57AB\u5708 M6", spec: "M4\xD715", unit: "\u4EF6", qty: 865, price: 1.75, amount: 1513.75, remark: "" },
2248
+ { name: "\u81EA\u653B\u87BA\u9489 M5", spec: "M3\xD716", unit: "\u6839", qty: 882, price: 2, amount: 1764, remark: "" },
2249
+ { name: "\u53CC\u5934\u87BA\u67F1 M20", spec: "M8\xD717", unit: "\u5305", qty: 899, price: 2.25, amount: 2022.75, remark: "" },
2250
+ { name: "\u7D27\u5B9A\u87BA\u9489 M4", spec: "M10\xD718", unit: "\u53EA", qty: 916, price: 2.5, amount: 2290, remark: "" },
2251
+ { name: "\u5341\u5B57\u76D8\u5934\u9489 M3", spec: "M12\xD719", unit: "\u7EC4", qty: 933, price: 2.75, amount: 2565.75, remark: "A\u7EA7" }
2252
+ ]
2253
+ };
2254
+
2255
+ // src/designer/utils/crop-anchor.ts
2256
+ var AXIS_X = { left: 0, center: 50, right: 100 };
2257
+ var AXIS_Y = { top: 0, center: 50, bottom: 100 };
2258
+ function clampPct(v) {
2259
+ if (!Number.isFinite(v)) return 50;
2260
+ return Math.round(Math.min(100, Math.max(0, v)));
2261
+ }
2262
+ function roundMm(v) {
2263
+ return Math.round(v * 100) / 100;
2264
+ }
2265
+ function buildCropAnchor(x, y) {
2266
+ const cx = clampPct(x);
2267
+ const cy = clampPct(y);
2268
+ if (cx === 50 && cy === 50) return void 0;
2269
+ return `${cx}% ${cy}%`;
2270
+ }
2271
+ function asPct(token) {
2272
+ return /^\d+(?:\.\d+)?%$/.test(token) ? parseFloat(token) : void 0;
2273
+ }
2274
+ function parseCropAnchor(value) {
2275
+ const raw = (value ?? "").trim();
2276
+ if (!raw) return { kind: "empty" };
2277
+ const tokens = raw.toLowerCase().split(/\s+/);
2278
+ let x;
2279
+ let y;
2280
+ for (let i = 0; i < tokens.length; i++) {
2281
+ const t = tokens[i];
2282
+ const pct = asPct(t);
2283
+ if (i === 0) {
2284
+ if (t in AXIS_X) x = AXIS_X[t];
2285
+ else if (pct !== void 0) x = pct;
2286
+ else if (t in AXIS_Y) y = AXIS_Y[t];
2287
+ else return { kind: "custom", raw: value };
2288
+ } else {
2289
+ if (t in AXIS_Y && y === void 0) y = AXIS_Y[t];
2290
+ else if (pct !== void 0 && x === void 0) x = pct;
2291
+ else if (pct !== void 0 && y === void 0) y = pct;
2292
+ else if (t in AXIS_X && x === void 0) x = AXIS_X[t];
2293
+ else return { kind: "custom", raw: value };
2294
+ }
2295
+ }
2296
+ return { kind: "axes", x: clampPct(x ?? 50), y: clampPct(y ?? 50) };
2297
+ }
2298
+ var MM_PER_PX2 = 25.4 / 96;
2299
+ function contentMm(box) {
2300
+ const { widthMm, heightMm, naturalWidth, naturalHeight } = box;
2301
+ if (!naturalWidth || !naturalHeight || !widthMm || !heightMm) return null;
2302
+ const k = widthMm / naturalWidth;
2303
+ const l = heightMm / naturalHeight;
2304
+ const zoom = (cropScalePct(box.fit, box.scalePct) ?? CROP_SCALE_MIN) / 100;
2305
+ switch (box.fit || "contain") {
2306
+ // 拉伸填满:图被钉成框,两轴都挪不动(放大比例只给剪裁档,这里不受影响)
2307
+ case "fill":
2308
+ return { w: widthMm, h: heightMm };
2309
+ case "cover": {
2310
+ const s = Math.max(k, l) * zoom;
2311
+ return { w: naturalWidth * s, h: naturalHeight * s };
2312
+ }
2313
+ // 原始尺寸不缩放:按图片内在像素尺寸绘制
2314
+ case "none":
2315
+ return { w: naturalWidth * MM_PER_PX2, h: naturalHeight * MM_PER_PX2 };
2316
+ case "scale-down": {
2317
+ const s = Math.min(1, Math.min(k, l));
2318
+ return { w: naturalWidth * s, h: naturalHeight * s };
2319
+ }
2320
+ default: {
2321
+ const s = Math.min(k, l);
2322
+ return { w: naturalWidth * s, h: naturalHeight * s };
2323
+ }
2324
+ }
2325
+ }
2326
+ function resolveCropTravel(box) {
2327
+ const c = contentMm(box);
2328
+ if (!c) return { x: null, y: null };
2329
+ return {
2330
+ x: roundMm(Math.abs(box.widthMm - c.w)),
2331
+ y: roundMm(Math.abs(box.heightMm - c.h))
2332
+ };
2333
+ }
2334
+ function cropWindow(box, x, y) {
2335
+ const c = contentMm(box);
2336
+ if (!c) return null;
2337
+ const fx = Math.min(1, box.widthMm / c.w);
2338
+ const fy = Math.min(1, box.heightMm / c.h);
2339
+ return {
2340
+ leftPct: (1 - fx) * clampPct(x),
2341
+ topPct: (1 - fy) * clampPct(y),
2342
+ widthPct: fx * 100,
2343
+ heightPct: fy * 100
2344
+ };
2345
+ }
2346
+ function resolveDesignImageSrc(raw) {
2347
+ const value = String(raw ?? "");
2348
+ if (!value) return "";
2349
+ return value.includes("{") ? String(evaluateTemplate2(value, DEFAULT_DEMO_DATA)) : value;
2350
+ }
2351
+ var CROP_AXIS_OPTIONS = {
2352
+ vertical: [
2353
+ { value: 0, label: "\u9876\u90E8" },
2354
+ { value: 50, label: "\u5C45\u4E2D" },
2355
+ { value: 100, label: "\u5E95\u90E8" }
2356
+ ],
2357
+ horizontal: [
2358
+ { value: 0, label: "\u5DE6\u4FA7" },
2359
+ { value: 50, label: "\u5C45\u4E2D" },
2360
+ { value: 100, label: "\u53F3\u4FA7" }
2361
+ ]
2362
+ };
2363
+ var CROP_GRID_OPTIONS = [
2364
+ { x: 0, y: 0, label: "\u5DE6\u4E0A" },
2365
+ { x: 50, y: 0, label: "\u4E0A\u4E2D" },
2366
+ { x: 100, y: 0, label: "\u53F3\u4E0A" },
2367
+ { x: 0, y: 50, label: "\u5DE6\u4E2D" },
2368
+ { x: 50, y: 50, label: "\u5C45\u4E2D" },
2369
+ { x: 100, y: 50, label: "\u53F3\u4E2D" },
2370
+ { x: 0, y: 100, label: "\u5DE6\u4E0B" },
2371
+ { x: 50, y: 100, label: "\u4E0B\u4E2D" },
2372
+ { x: 100, y: 100, label: "\u53F3\u4E0B" }
2373
+ ];
2374
+ var IMAGE_FIT_OPTIONS = [
2375
+ { value: "contain", label: "\u5305\u542B\uFF08\u4FDD\u6301\u6BD4\u4F8B\uFF09" },
2376
+ { value: "cover", label: "\u526A\u88C1\uFF08\u7B49\u6BD4\u94FA\u6EE1\u540E\u88C1\u8FB9\uFF09" },
2377
+ { value: "fill", label: "\u62C9\u4F38\u586B\u6EE1" },
2378
+ { value: "none", label: "\u539F\u59CB\u5C3A\u5BF8" },
2379
+ { value: "scale-down", label: "\u7F29\u5C0F\uFF08\u4FDD\u6301\u6BD4\u4F8B\uFF09" }
2380
+ ];
2381
+ var CROP_SAMPLE_IMAGE = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAiIGhlaWdodD0iMTIwIiB2aWV3Qm94PSIwIDAgMTIwIDEyMCI+PHJlY3Qgd2lkdGg9IjEyMCIgaGVpZ2h0PSIxMjAiIGZpbGw9IiNmZmZmZmYiLz48cGF0aCBkPSJNNDAgMFYxMjBNODAgMFYxMjBNMCA0MEgxMjBNMCA4MEgxMjAiIHN0cm9rZT0iI2VlZjFmNiIgc3Ryb2tlLXdpZHRoPSIxIi8+PGNpcmNsZSBjeD0iMjAiIGN5PSIyMCIgcj0iMy41IiBmaWxsPSIjOGI5NWE1Ii8+PGNpcmNsZSBjeD0iMTAwIiBjeT0iMjAiIHI9IjMuNSIgZmlsbD0iIzhiOTVhNSIvPjxjaXJjbGUgY3g9IjIwIiBjeT0iMTAwIiByPSIzLjUiIGZpbGw9IiM4Yjk1YTUiLz48Y2lyY2xlIGN4PSIxMDAiIGN5PSIxMDAiIHI9IjMuNSIgZmlsbD0iIzhiOTVhNSIvPjxjaXJjbGUgY3g9IjYwIiBjeT0iMjAiIHI9IjciIGZpbGw9IiNjMDM5MmIiLz48Y2lyY2xlIGN4PSI2MCIgY3k9IjEwMCIgcj0iNyIgZmlsbD0iIzFmNGZhMyIvPjxjaXJjbGUgY3g9IjIwIiBjeT0iNjAiIHI9IjciIGZpbGw9IiMyYzdhNGEiLz48Y2lyY2xlIGN4PSIxMDAiIGN5PSI2MCIgcj0iNyIgZmlsbD0iI2UwN2EyMCIvPjxjaXJjbGUgY3g9IjYwIiBjeT0iNjAiIHI9IjE0IiBmaWxsPSJub25lIiBzdHJva2U9IiMyZjNhNGEiIHN0cm9rZS13aWR0aD0iNCIvPjxjaXJjbGUgY3g9IjYwIiBjeT0iNjAiIHI9IjYiIGZpbGw9IiMyZjNhNGEiLz48L3N2Zz4=";
2382
+ var CROP_SAMPLE_NOTE = "\u56FE\u7247\u8FD8\u6CA1\u8BBE\u7F6E\uFF0C\u4E0A\u9762\u6309\u5185\u7F6E\u793A\u4F8B\u56FE\u6F14\u793A\u53D6\u4F4D\uFF1B\u6362\u4E0A\u771F\u56FE\u540E\u6863\u4F4D\u4E0E\u53EF\u632A\u91CF\u6309\u771F\u56FE\u91CD\u7B97";
2383
+ function resolveCropPreview(resolvedSrc) {
2384
+ const value = String(resolvedSrc ?? "").trim();
2385
+ if (!value || value.includes("{") || value.includes("}")) return { src: CROP_SAMPLE_IMAGE, isSample: true };
2386
+ return { src: value, isSample: false };
2387
+ }
2388
+ function cropAxisLabel(axis) {
2389
+ return axis === "vertical" ? "\u5782\u76F4\u4F4D\u7F6E (%)" : "\u6C34\u5E73\u4F4D\u7F6E (%)";
2390
+ }
2391
+ var CROP_SCALE_LABEL = "\u653E\u5927\u6BD4\u4F8B (%)";
2392
+ function cropAxisNote(travel, keepRaw = false) {
2393
+ if (keepRaw) return "\u5DF2\u4FDD\u7559\u6A21\u677F\u91CC\u7684\u539F\u503C\uFF1B\u6539\u52A8\u4E0B\u9762\u4EFB\u4E00\u9879\u5C31\u6574\u4F53\u66FF\u6362\u6210\u65B0\u7684\u53D6\u4F4D";
2394
+ const { x, y } = travel;
2395
+ if (x === null || y === null) return "";
2396
+ if (x > 0 && y > 0) return `\u6C34\u5E73\u53EF\u632A ${x}mm\u3001\u5782\u76F4\u53EF\u632A ${y}mm\uFF1A0 \u8D34\u5DE6\uFF0F\u8D34\u9876\uFF0C100 \u8D34\u53F3\uFF0F\u8D34\u5E95`;
2397
+ if (x > 0) return `\u6C34\u5E73\u53EF\u632A ${x}mm\uFF1B\u5782\u76F4\u8FD9\u4E00\u8F74\u5DF2\u8D34\u6EE1\uFF0C\u632A\u4E0D\u52A8`;
2398
+ if (y > 0) return `\u5782\u76F4\u53EF\u632A ${y}mm\uFF1B\u6C34\u5E73\u8FD9\u4E00\u8F74\u5DF2\u8D34\u6EE1\uFF0C\u632A\u4E0D\u52A8`;
2399
+ return "\u8FD9\u4E2A\u7F29\u653E\u4E0B\u56FE\u4E0E\u6846\u6B63\u597D\u4E00\u6837\u5927\uFF0C\u4E24\u8F74\u90FD\u6CA1\u6709\u53EF\u632A\u7684\u4F59\u91CF";
2400
+ }
2401
+ function cropAxisFields(travel, x, y) {
2402
+ return [
2403
+ { name: "horizontal", label: cropAxisLabel("horizontal"), value: x, travelMm: travel.x },
2404
+ { name: "vertical", label: cropAxisLabel("vertical"), value: y, travelMm: travel.y }
2405
+ ];
2406
+ }
2407
+ function cropPresetOptions(travel, x, y) {
2408
+ const movX = travel.x !== null && travel.x > 0;
2409
+ const movY = travel.y !== null && travel.y > 0;
2410
+ if (movY && !movX) {
2411
+ return CROP_AXIS_OPTIONS.vertical.map((o) => ({ value: `${x},${o.value}`, label: o.label }));
2412
+ }
2413
+ if (movX && !movY) {
2414
+ return CROP_AXIS_OPTIONS.horizontal.map((o) => ({ value: `${o.value},${y}`, label: o.label }));
2415
+ }
2416
+ return CROP_GRID_OPTIONS.map((o) => ({ value: `${o.x},${o.y}`, label: o.label }));
2417
+ }
2418
+
2419
+ // src/designer/utils/field-groups.ts
2420
+ function groupFields(fields) {
2421
+ const sorted = [...fields].sort((a, b) => (a.sortOrder ?? 0) - (b.sortOrder ?? 0));
2422
+ const groupMap = /* @__PURE__ */ new Map();
2423
+ const groupOrder = [];
2424
+ for (const f of sorted) {
2425
+ const dot = f.fieldKey.indexOf(".");
2426
+ if (dot === -1) continue;
2427
+ const key = f.fieldKey.slice(0, dot);
2428
+ let g = groupMap.get(key);
2429
+ if (!g) {
2430
+ g = { key, label: key, isList: false, fields: [] };
2431
+ groupMap.set(key, g);
2432
+ groupOrder.push(key);
2433
+ }
2434
+ g.fields.push(f);
2435
+ }
2436
+ const groups = [];
2437
+ const standalone = [];
2438
+ for (const f of sorted) {
2439
+ if (f.fieldKey.includes(".")) continue;
2440
+ const g = groupMap.get(f.fieldKey);
2441
+ if (g) {
2442
+ g.label = f.fieldLabel;
2443
+ g.isList = f.fieldType === "list";
2444
+ } else {
2445
+ standalone.push(f);
2446
+ }
2447
+ }
2448
+ if (standalone.length) groups.push({ key: "", label: "", isList: false, fields: standalone });
2449
+ for (const key of groupOrder) groups.push(groupMap.get(key));
2450
+ return groups;
2451
+ }
2452
+ function filterGroups(groups, keyword) {
2453
+ const kw = keyword.trim().toLowerCase();
2454
+ if (!kw) return groups;
2455
+ return groups.map((g) => ({
2456
+ ...g,
2457
+ fields: g.fields.filter(
2458
+ (f) => f.fieldLabel.toLowerCase().includes(kw) || f.fieldKey.toLowerCase().includes(kw)
2459
+ )
2460
+ })).filter((g) => g.fields.length > 0);
2461
+ }
2462
+
2463
+ // src/designer/utils/binding-registry.ts
2464
+ var ELEMENT_BINDING_REGISTRY = {
2465
+ text: [
2466
+ { targetPath: "options.formatter", label: "\u5185\u5BB9", dataSource: "main" }
2467
+ ],
2468
+ longText: [
2469
+ { targetPath: "options.formatter", label: "\u5185\u5BB9", dataSource: "main" },
2470
+ { targetPath: "options.styler", label: "\u6837\u5F0F", dataSource: "main" }
2471
+ ],
2472
+ barcode: [
2473
+ { targetPath: "options.formatter", label: "\u5185\u5BB9", dataSource: "main" }
2474
+ ],
2475
+ qrcode: [
2476
+ { targetPath: "options.formatter", label: "\u5185\u5BB9", dataSource: "main" }
2477
+ ],
2478
+ image: [
2479
+ { targetPath: "options.src", label: "\u5185\u5BB9", dataSource: "main", placeholder: "\u8F93\u5165\u56FE\u7247\u8DEF\u5F84\uFF0C\u652F\u6301 /docfiles/... \u76F8\u5BF9\u8DEF\u5F84\u3001\u7EDD\u5BF9 URL \u6216 {\u5B57\u6BB5} \u8868\u8FBE\u5F0F" }
2480
+ ],
2481
+ table: []
2482
+ };
2483
+ function getTableCellBindings(rowType, rowIndex, cellIndex, listField) {
2484
+ if (rowType === "data") {
2485
+ return [{
2486
+ targetPath: `options.tableRows[${rowIndex}].cells[${cellIndex}].formatter`,
2487
+ label: "\u5185\u5BB9",
2488
+ dataSource: "list",
2489
+ listField,
2490
+ placeholder: "{name}"
2491
+ }];
2492
+ }
2493
+ if (rowType === "subtotal") {
2494
+ return [{
2495
+ targetPath: `options.tableRows[${rowIndex}].cells[${cellIndex}].formatter`,
2496
+ label: "\u5185\u5BB9",
2497
+ dataSource: "subtotal",
2498
+ placeholder: "{MONEY(SUM(amount))}"
2499
+ }];
2500
+ }
2501
+ if (rowType === "summary") {
2502
+ return [{
2503
+ targetPath: `options.tableRows[${rowIndex}].cells[${cellIndex}].formatter`,
2504
+ label: "\u5185\u5BB9",
2505
+ dataSource: "summary",
2506
+ placeholder: "{MONEY(SUM(amount))}"
2507
+ }];
2508
+ }
2509
+ return [{
2510
+ targetPath: `options.tableRows[${rowIndex}].cells[${cellIndex}].formatter`,
2511
+ label: "\u5185\u5BB9",
2512
+ dataSource: "main",
2513
+ placeholder: "\u5408\u8BA1: {order.total}"
2514
+ }];
2515
+ }
2516
+ function getElementBindings(element) {
2517
+ const type = element.printElementType.type;
2518
+ const staticBindings = ELEMENT_BINDING_REGISTRY[type] ?? [];
2519
+ const dynamicBindings = [];
2520
+ if (type === "table") {
2521
+ const listField = element.options.dataSource;
2522
+ for (const [ri, row] of (element.options.tableRows ?? []).entries()) {
2523
+ for (const [ci, cell] of row.cells.entries()) {
2524
+ if (cell.merged) continue;
2525
+ dynamicBindings.push(...getTableCellBindings(row.type, ri, ci, listField));
2526
+ }
2527
+ }
2528
+ }
2529
+ return [...staticBindings, ...dynamicBindings];
2530
+ }
2531
+
2249
2532
  // src/designer/utils/binding.ts
2250
2533
  function createFieldElement(field) {
2251
2534
  return createRuntimeElement("text", {
@@ -2775,6 +3058,13 @@ function useBindingDisplay() {
2775
3058
  BARCODE_MODULE_WIDTH_MM,
2776
3059
  BARCODE_QUIET_ZONE_MODULES,
2777
3060
  BARCODE_TEXT_FONT_SIZE_MODULES,
3061
+ CROP_AXIS_OPTIONS,
3062
+ CROP_GRID_OPTIONS,
3063
+ CROP_SAMPLE_IMAGE,
3064
+ CROP_SAMPLE_NOTE,
3065
+ CROP_SCALE_LABEL,
3066
+ CROP_SCALE_MAX,
3067
+ CROP_SCALE_MIN,
2778
3068
  DEFAULT_DEMO_DATA,
2779
3069
  DEFAULT_SHRINK_MIN_FONT_SIZE_PT,
2780
3070
  ELEMENT_BINDING_REGISTRY,
@@ -2782,6 +3072,7 @@ function useBindingDisplay() {
2782
3072
  EXTENDED_FUNCTIONS,
2783
3073
  FIT_SCALE_MIN_PERCENT,
2784
3074
  GHOST_BORDER_CSS,
3075
+ IMAGE_FIT_OPTIONS,
2785
3076
  LABEL_PAPER_GROUP,
2786
3077
  MIN_COL_WIDTH_MM,
2787
3078
  MIN_SCALE_PERCENT,
@@ -2798,12 +3089,14 @@ function useBindingDisplay() {
2798
3089
  barcodeAvailableBoxMm,
2799
3090
  barcodePreferredModuleWidthMm,
2800
3091
  barcodeUnitsPerModule,
3092
+ buildCropAnchor,
2801
3093
  buildRulerTicks,
2802
3094
  calcResizeRect,
2803
3095
  canMergeReason,
2804
3096
  cellFitCapMm,
2805
3097
  cellFitKey,
2806
3098
  cellFitWidthMm,
3099
+ cellImageBoxMm,
2807
3100
  chooseMajorStepMM,
2808
3101
  clampResizedColumnWidth,
2809
3102
  clampScalePercent,
@@ -2815,6 +3108,13 @@ function useBindingDisplay() {
2815
3108
  createDefaultTable,
2816
3109
  createFieldElement,
2817
3110
  createRuntimeElement,
3111
+ cropAxisFields,
3112
+ cropAxisLabel,
3113
+ cropAxisNote,
3114
+ cropPresetOptions,
3115
+ cropScalePct,
3116
+ cropStyleDeclarations,
3117
+ cropWindow,
2818
3118
  deleteCol,
2819
3119
  deleteRow,
2820
3120
  engine,
@@ -2846,18 +3146,26 @@ function useBindingDisplay() {
2846
3146
  normalizeSelection,
2847
3147
  normalizeTemplateUnits,
2848
3148
  parseCellFitKey,
3149
+ parseCropAnchor,
3150
+ propertyTip,
2849
3151
  ptToMm,
2850
3152
  pxToMm,
2851
3153
  resolveBarcodeDesignValue,
2852
3154
  resolveBarcodeSize,
2853
3155
  resolveCellBorderCss,
2854
3156
  resolveCellTextFit,
3157
+ resolveCropPreview,
3158
+ resolveCropTravel,
3159
+ resolveDesignImageSrc,
2855
3160
  resolveElementBorder,
2856
3161
  resolveElementTextFit,
3162
+ resolveOverlayPlacement,
2857
3163
  resolveShrinkMinFontSize,
2858
3164
  resolveTextBinding,
3165
+ resolveToolbarOverflow,
2859
3166
  roundFontSize,
2860
3167
  safeEval,
3168
+ sanitizeObjectPosition,
2861
3169
  searchProperties,
2862
3170
  setHeaderRepeat,
2863
3171
  setRowType,