xls-codec 4.4.0 → 4.5.0

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.
Files changed (36) hide show
  1. package/README.md +4 -3
  2. package/dist/biff/record-types.cjs +9 -0
  3. package/dist/biff/record-types.d.cts +7 -1
  4. package/dist/biff/record-types.d.ts +7 -1
  5. package/dist/biff/record-types.js +7 -1
  6. package/dist/biff/substreams.cjs +8 -0
  7. package/dist/biff/substreams.js +8 -0
  8. package/dist/biff/xf-colors.cjs +61 -0
  9. package/dist/biff/xf-colors.d.cts +2 -2
  10. package/dist/biff/xf-colors.d.ts +2 -2
  11. package/dist/biff/xf-colors.js +61 -1
  12. package/dist/biff/xf-writer.d.cts +1 -1
  13. package/dist/biff/xf-writer.d.ts +1 -1
  14. package/dist/conditional-format-12-DdEL5DL0.d.cts +49 -0
  15. package/dist/conditional-format-12-Dw82ECRh.d.ts +49 -0
  16. package/dist/content.cjs +60 -1
  17. package/dist/content.js +61 -2
  18. package/dist/index.cjs +3 -0
  19. package/dist/index.d.cts +2 -2
  20. package/dist/index.d.ts +2 -2
  21. package/dist/index.js +2 -2
  22. package/dist/workbook/conditional-format-12.cjs +255 -0
  23. package/dist/workbook/conditional-format-12.d.cts +2 -0
  24. package/dist/workbook/conditional-format-12.d.ts +2 -0
  25. package/dist/workbook/conditional-format-12.js +254 -0
  26. package/dist/workbook/globals-writer.d.cts +1 -1
  27. package/dist/workbook/globals-writer.d.ts +1 -1
  28. package/dist/workbook/globals.d.cts +1 -1
  29. package/dist/workbook/globals.d.ts +1 -1
  30. package/dist/workbook/sheet.cjs +11 -1
  31. package/dist/workbook/sheet.d.cts +2 -0
  32. package/dist/workbook/sheet.d.ts +2 -0
  33. package/dist/workbook/sheet.js +11 -1
  34. package/dist/{xf-colors--5oxSeI1.d.ts → xf-colors-d3OvRw76.d.ts} +7 -1
  35. package/dist/{xf-colors-BB5MKq6R.d.cts → xf-colors-mqerVt2O.d.cts} +7 -1
  36. package/package.json +1 -1
@@ -0,0 +1,254 @@
1
+ import "../biff/record-types.js";
2
+ import { BiffFormatError } from "../biff/records.js";
3
+ import { BlockCursor } from "../biff/cursor.js";
4
+ import { parseFormulaText } from "../biff/ptg.js";
5
+ //#region src/workbook/conditional-format-12.ts
6
+ const CFVO_TYPE_TO_VALUE_TYPE = /* @__PURE__ */ new Map([
7
+ [1, "num"],
8
+ [2, "min"],
9
+ [3, "max"],
10
+ [4, "percent"],
11
+ [5, "percentile"],
12
+ [7, "formula"]
13
+ ]);
14
+ function readCfvo(cursor, formulaSheets) {
15
+ const cfvoType = cursor.u8();
16
+ const type = CFVO_TYPE_TO_VALUE_TYPE.get(cfvoType);
17
+ const cce = cursor.u16();
18
+ const rgce = cursor.take(cce);
19
+ const hasFormula = cce > 0;
20
+ const numValue = !hasFormula && type !== "min" && type !== "max" ? cursor.f64() : void 0;
21
+ if (type === void 0) return;
22
+ if (type === "min" || type === "max") return { type };
23
+ const value = hasFormula ? parseFormulaText(rgce, formulaSheets) : numValue?.toString() ?? void 0;
24
+ if (value === void 0) return;
25
+ return {
26
+ type,
27
+ value
28
+ };
29
+ }
30
+ const XCLR_INDEXED = 1;
31
+ const XCLR_RGB = 2;
32
+ function readCfColor(cursor) {
33
+ const xclrType = cursor.u32();
34
+ if (xclrType === XCLR_INDEXED) return {
35
+ kind: "icv",
36
+ icv: cursor.u32(),
37
+ tint: cursor.f64()
38
+ };
39
+ if (xclrType === XCLR_RGB) {
40
+ const red = cursor.u8();
41
+ const green = cursor.u8();
42
+ const blue = cursor.u8();
43
+ cursor.skip(1);
44
+ const tint = cursor.f64();
45
+ return {
46
+ kind: "rgb",
47
+ color: {
48
+ r: red / 255,
49
+ g: green / 255,
50
+ b: blue / 255
51
+ },
52
+ tint
53
+ };
54
+ }
55
+ cursor.skip(12);
56
+ }
57
+ function readCfGradient(cursor, formulaSheets) {
58
+ cursor.skip(2);
59
+ cursor.skip(1);
60
+ const cInterpCurve = cursor.u8();
61
+ const cGradientCurve = cursor.u8();
62
+ cursor.skip(1);
63
+ if (cInterpCurve !== cGradientCurve || cInterpCurve < 2 || cInterpCurve > 3) return;
64
+ const values = [];
65
+ for (let index = 0; index < cInterpCurve; index += 1) {
66
+ const value = readCfvo(cursor, formulaSheets);
67
+ cursor.f64();
68
+ if (value === void 0) return;
69
+ values.push(value);
70
+ }
71
+ const colors = [];
72
+ for (let index = 0; index < cGradientCurve; index += 1) {
73
+ cursor.f64();
74
+ const color = readCfColor(cursor);
75
+ if (color === void 0) return;
76
+ colors.push(color);
77
+ }
78
+ const stops = [];
79
+ for (let index = 0; index < values.length; index += 1) {
80
+ const value = values[index];
81
+ const color = colors[index];
82
+ if (value === void 0 || color === void 0) return;
83
+ stops.push({
84
+ value,
85
+ color
86
+ });
87
+ }
88
+ return stops;
89
+ }
90
+ function readCfDatabar(cursor, formulaSheets) {
91
+ cursor.skip(2);
92
+ cursor.skip(1);
93
+ const showValue = (cursor.u8() >>> 1 & 1) !== 0;
94
+ cursor.skip(1);
95
+ cursor.skip(1);
96
+ const color = readCfColor(cursor);
97
+ const min = readCfvo(cursor, formulaSheets);
98
+ const max = readCfvo(cursor, formulaSheets);
99
+ if (color === void 0 || min === void 0 || max === void 0) return;
100
+ return {
101
+ min,
102
+ max,
103
+ color,
104
+ showValue
105
+ };
106
+ }
107
+ const ICON_SET_TYPE_NAMES = [
108
+ "3Arrows",
109
+ "3ArrowsGray",
110
+ "3Flags",
111
+ "3TrafficLights1",
112
+ "3TrafficLights2",
113
+ "3Signs",
114
+ "3Symbols",
115
+ "3Symbols2",
116
+ "4Arrows",
117
+ "4ArrowsGray",
118
+ "4RedToBlack",
119
+ "4Rating",
120
+ "4TrafficLights",
121
+ "5Arrows",
122
+ "5ArrowsGray",
123
+ "5Rating",
124
+ "5Quarters"
125
+ ];
126
+ function readCfMultistate(cursor, formulaSheets) {
127
+ cursor.skip(2);
128
+ cursor.skip(1);
129
+ const cStates = cursor.u8();
130
+ const iIconSet = cursor.u8();
131
+ const flags = cursor.u8();
132
+ const showValue = (flags & 1) === 0;
133
+ const reverse = (flags >>> 2 & 1) !== 0;
134
+ const iconSetType = ICON_SET_TYPE_NAMES[iIconSet];
135
+ if (iconSetType === void 0) return;
136
+ const thresholds = [];
137
+ for (let index = 0; index < cStates; index += 1) {
138
+ const value = readCfvo(cursor, formulaSheets);
139
+ cursor.skip(1);
140
+ cursor.skip(4);
141
+ if (value === void 0) return;
142
+ thresholds.push(value);
143
+ }
144
+ return {
145
+ iconSetType,
146
+ thresholds,
147
+ reverse,
148
+ showValue
149
+ };
150
+ }
151
+ function readCf12(record, ranges, formulaSheets) {
152
+ try {
153
+ const cursor = new BlockCursor(record.blocks);
154
+ cursor.skip(12);
155
+ const ct = cursor.u8();
156
+ cursor.skip(1);
157
+ const cce1 = cursor.u16();
158
+ const cce2 = cursor.u16();
159
+ const cbDxf = cursor.u32();
160
+ cursor.skip(cbDxf);
161
+ cursor.skip(cce1);
162
+ cursor.skip(cce2);
163
+ const cceActive = cursor.u16();
164
+ cursor.skip(cceActive);
165
+ const stopIfTrue = (cursor.u8() & 2) !== 0;
166
+ const priority = cursor.u16();
167
+ cursor.skip(2);
168
+ cursor.skip(1);
169
+ cursor.skip(16);
170
+ const common = {
171
+ priority,
172
+ stopIfTrue,
173
+ ranges
174
+ };
175
+ if (ct === 3) {
176
+ const stops = readCfGradient(cursor, formulaSheets);
177
+ return stops === void 0 ? void 0 : {
178
+ kind: "colorScale",
179
+ stops,
180
+ ...common
181
+ };
182
+ }
183
+ if (ct === 4) {
184
+ const databar = readCfDatabar(cursor, formulaSheets);
185
+ return databar === void 0 ? void 0 : {
186
+ kind: "dataBar",
187
+ ...databar,
188
+ ...common
189
+ };
190
+ }
191
+ if (ct === 6) {
192
+ const iconSet = readCfMultistate(cursor, formulaSheets);
193
+ return iconSet === void 0 ? void 0 : {
194
+ kind: "iconSet",
195
+ ...iconSet,
196
+ ...common
197
+ };
198
+ }
199
+ return;
200
+ } catch (err) {
201
+ if (!(err instanceof BiffFormatError)) throw err;
202
+ return;
203
+ }
204
+ }
205
+ function readCondFmt12Group(records, startIndex, formulaSheets) {
206
+ const condFmt12 = records[startIndex];
207
+ if (condFmt12 === void 0) return {
208
+ formats: [],
209
+ recordsConsumed: 1
210
+ };
211
+ try {
212
+ const cursor = new BlockCursor(condFmt12.blocks);
213
+ cursor.skip(12);
214
+ const ccf = cursor.u16();
215
+ cursor.skip(2);
216
+ cursor.skip(8);
217
+ const crefCount = cursor.u16();
218
+ const ranges = [];
219
+ for (let index = 0; index < crefCount; index += 1) {
220
+ const startRow = cursor.u16();
221
+ const endRow = cursor.u16();
222
+ const startColumn = cursor.u16();
223
+ const endColumn = cursor.u16();
224
+ ranges.push({
225
+ startRow,
226
+ startColumn,
227
+ endRow,
228
+ endColumn
229
+ });
230
+ }
231
+ const formats = [];
232
+ for (let offset = 1; offset <= ccf; offset += 1) {
233
+ const cf12Record = records[startIndex + offset];
234
+ if (cf12Record?.type !== 2170) return {
235
+ formats: [],
236
+ recordsConsumed: 1
237
+ };
238
+ const format = readCf12(cf12Record, ranges, formulaSheets);
239
+ if (format !== void 0) formats.push(format);
240
+ }
241
+ return {
242
+ formats,
243
+ recordsConsumed: 1 + ccf
244
+ };
245
+ } catch (err) {
246
+ if (!(err instanceof BiffFormatError)) throw err;
247
+ return {
248
+ formats: [],
249
+ recordsConsumed: 1
250
+ };
251
+ }
252
+ }
253
+ //#endregion
254
+ export { readCondFmt12Group };
@@ -1,4 +1,4 @@
1
- import { E as XfDecorationFields } from "../xf-colors-BB5MKq6R.cjs";
1
+ import { E as XfDecorationFields } from "../xf-colors-mqerVt2O.cjs";
2
2
  import { t as PrintNamePlanEntry } from "../print-names-DyYloloV.cjs";
3
3
  import { Alignment, Color } from "document-schema.js";
4
4
  //#region src/workbook/globals-writer.d.ts
@@ -1,4 +1,4 @@
1
- import { E as XfDecorationFields } from "../xf-colors--5oxSeI1.js";
1
+ import { E as XfDecorationFields } from "../xf-colors-d3OvRw76.js";
2
2
  import { t as PrintNamePlanEntry } from "../print-names-C-PQ2vAy.js";
3
3
  import { Alignment, Color } from "document-schema.js";
4
4
  //#region src/workbook/globals-writer.d.ts
@@ -1,6 +1,6 @@
1
1
  import { a as SheetRange, t as ExternalSheetLabel } from "../ptg-CCBbJLZJ.cjs";
2
2
  import { t as RecordGroup } from "../substreams-Cpy5Fi3d.cjs";
3
- import { E as XfDecorationFields, w as XfAlignmentFields } from "../xf-colors-BB5MKq6R.cjs";
3
+ import { E as XfDecorationFields, w as XfAlignmentFields } from "../xf-colors-mqerVt2O.cjs";
4
4
  import { n as SheetPrintNames } from "../print-names-DyYloloV.cjs";
5
5
  import { Color } from "document-schema.js";
6
6
  //#region src/workbook/globals.d.ts
@@ -1,6 +1,6 @@
1
1
  import { a as SheetRange, t as ExternalSheetLabel } from "../ptg-CCBbJLZJ.js";
2
2
  import { t as RecordGroup } from "../substreams-CmyZMtuM.js";
3
- import { E as XfDecorationFields, w as XfAlignmentFields } from "../xf-colors--5oxSeI1.js";
3
+ import { E as XfDecorationFields, w as XfAlignmentFields } from "../xf-colors-d3OvRw76.js";
4
4
  import { n as SheetPrintNames } from "../print-names-C-PQ2vAy.js";
5
5
  import { Color } from "document-schema.js";
6
6
  //#region src/workbook/globals.d.ts
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- require("../biff/record-types.cjs");
2
+ const require_biff_record_types = require("../biff/record-types.cjs");
3
3
  const require_biff_records = require("../biff/records.cjs");
4
4
  const require_units = require("../units.cjs");
5
5
  const require_biff_print_setup = require("../biff/print-setup.cjs");
@@ -10,6 +10,7 @@ const require_biff_errors = require("../biff/errors.cjs");
10
10
  const require_biff_ptg = require("../biff/ptg.cjs");
11
11
  const require_biff_rk = require("../biff/rk.cjs");
12
12
  const require_workbook_conditional_format = require("./conditional-format.cjs");
13
+ const require_workbook_conditional_format_12 = require("./conditional-format-12.cjs");
13
14
  const require_workbook_data_validation = require("./data-validation.cjs");
14
15
  //#region src/workbook/sheet.ts
15
16
  /** Row record flag bits, in the 32-bit field following unused1 ([MS-XLS] 2.4.221). */
@@ -114,6 +115,7 @@ function readSheetRecords(records, sharedStrings, formulaSheets = EMPTY_FORMULA_
114
115
  const merges = [];
115
116
  const dataValidations = [];
116
117
  const conditionalFormats = [];
118
+ const conditionalFormats12 = [];
117
119
  let usedRange;
118
120
  const marginsPt = {};
119
121
  const rowBreaks = [];
@@ -149,6 +151,12 @@ function readSheetRecords(records, sharedStrings, formulaSheets = EMPTY_FORMULA_
149
151
  index += group.recordsConsumed - 1;
150
152
  break;
151
153
  }
154
+ case require_biff_record_types.RECORD_CONDFMT12: {
155
+ const group = require_workbook_conditional_format_12.readCondFmt12Group(records, index, formulaSheets);
156
+ conditionalFormats12.push(...group.formats);
157
+ index += group.recordsConsumed - 1;
158
+ break;
159
+ }
152
160
  case 513:
153
161
  cells.push(readBlank(record));
154
162
  break;
@@ -224,6 +232,7 @@ function readSheetRecords(records, sharedStrings, formulaSheets = EMPTY_FORMULA_
224
232
  merges,
225
233
  dataValidations,
226
234
  conditionalFormats,
235
+ conditionalFormats12,
227
236
  print
228
237
  } : {
229
238
  cells,
@@ -232,6 +241,7 @@ function readSheetRecords(records, sharedStrings, formulaSheets = EMPTY_FORMULA_
232
241
  merges,
233
242
  dataValidations,
234
243
  conditionalFormats,
244
+ conditionalFormats12,
235
245
  usedRange,
236
246
  print
237
247
  };
@@ -2,6 +2,7 @@ import { n as SetupFields } from "../print-setup-B_ihDvm5.cjs";
2
2
  import { r as FormulaSheetContext } from "../ptg-CCBbJLZJ.cjs";
3
3
  import { t as RecordGroup } from "../substreams-Cpy5Fi3d.cjs";
4
4
  import { n as RawConditionalFormat } from "../conditional-format-DUQuOrNW.cjs";
5
+ import { i as RawConditionalFormat12 } from "../conditional-format-12-DdEL5DL0.cjs";
5
6
  import { t as RawDataValidation } from "../data-validation-DZPzAW-8.cjs";
6
7
  //#region src/workbook/sheet.d.ts
7
8
  /** A cell's value as its own record carries it, before number-format classification decides whether a number is really a date, a percentage, or an amount of money. */
@@ -85,6 +86,7 @@ interface RawSheet {
85
86
  readonly merges: readonly RawRange[];
86
87
  readonly dataValidations: readonly RawDataValidation[];
87
88
  readonly conditionalFormats: readonly RawConditionalFormat[];
89
+ readonly conditionalFormats12: readonly RawConditionalFormat12[];
88
90
  /** The used range from the Dimensions record ([MS-XLS] 2.4.90), when the sheet declared one. */
89
91
  readonly usedRange?: RawRange;
90
92
  /** The sheet's own page setup, as far as its records state it. */
@@ -2,6 +2,7 @@ import { n as SetupFields } from "../print-setup-B_ihDvm5.js";
2
2
  import { r as FormulaSheetContext } from "../ptg-CCBbJLZJ.js";
3
3
  import { t as RecordGroup } from "../substreams-CmyZMtuM.js";
4
4
  import { n as RawConditionalFormat } from "../conditional-format-BV2313jL.js";
5
+ import { i as RawConditionalFormat12 } from "../conditional-format-12-Dw82ECRh.js";
5
6
  import { t as RawDataValidation } from "../data-validation-DsVG0Mms.js";
6
7
  //#region src/workbook/sheet.d.ts
7
8
  /** A cell's value as its own record carries it, before number-format classification decides whether a number is really a date, a percentage, or an amount of money. */
@@ -85,6 +86,7 @@ interface RawSheet {
85
86
  readonly merges: readonly RawRange[];
86
87
  readonly dataValidations: readonly RawDataValidation[];
87
88
  readonly conditionalFormats: readonly RawConditionalFormat[];
89
+ readonly conditionalFormats12: readonly RawConditionalFormat12[];
88
90
  /** The used range from the Dimensions record ([MS-XLS] 2.4.90), when the sheet declared one. */
89
91
  readonly usedRange?: RawRange;
90
92
  /** The sheet's own page setup, as far as its records state it. */
@@ -1,4 +1,4 @@
1
- import "../biff/record-types.js";
1
+ import { RECORD_CONDFMT12 } from "../biff/record-types.js";
2
2
  import { BiffFormatError } from "../biff/records.js";
3
3
  import { columnWidthToPoints, inchesToPoints, twipsToPoints } from "../units.js";
4
4
  import { unpackSetupFlags } from "../biff/print-setup.js";
@@ -9,6 +9,7 @@ import { errorTextOf } from "../biff/errors.js";
9
9
  import { parseFormulaText, readPtgExpBase } from "../biff/ptg.js";
10
10
  import { decodeRkNumber } from "../biff/rk.js";
11
11
  import { readCondFmtGroup } from "./conditional-format.js";
12
+ import { readCondFmt12Group } from "./conditional-format-12.js";
12
13
  import { readDv } from "./data-validation.js";
13
14
  //#region src/workbook/sheet.ts
14
15
  /** Row record flag bits, in the 32-bit field following unused1 ([MS-XLS] 2.4.221). */
@@ -113,6 +114,7 @@ function readSheetRecords(records, sharedStrings, formulaSheets = EMPTY_FORMULA_
113
114
  const merges = [];
114
115
  const dataValidations = [];
115
116
  const conditionalFormats = [];
117
+ const conditionalFormats12 = [];
116
118
  let usedRange;
117
119
  const marginsPt = {};
118
120
  const rowBreaks = [];
@@ -148,6 +150,12 @@ function readSheetRecords(records, sharedStrings, formulaSheets = EMPTY_FORMULA_
148
150
  index += group.recordsConsumed - 1;
149
151
  break;
150
152
  }
153
+ case RECORD_CONDFMT12: {
154
+ const group = readCondFmt12Group(records, index, formulaSheets);
155
+ conditionalFormats12.push(...group.formats);
156
+ index += group.recordsConsumed - 1;
157
+ break;
158
+ }
151
159
  case 513:
152
160
  cells.push(readBlank(record));
153
161
  break;
@@ -223,6 +231,7 @@ function readSheetRecords(records, sharedStrings, formulaSheets = EMPTY_FORMULA_
223
231
  merges,
224
232
  dataValidations,
225
233
  conditionalFormats,
234
+ conditionalFormats12,
226
235
  print
227
236
  } : {
228
237
  cells,
@@ -231,6 +240,7 @@ function readSheetRecords(records, sharedStrings, formulaSheets = EMPTY_FORMULA_
231
240
  merges,
232
241
  dataValidations,
233
242
  conditionalFormats,
243
+ conditionalFormats12,
234
244
  usedRange,
235
245
  print
236
246
  };
@@ -49,6 +49,12 @@ declare const DEFAULT_PALETTE_HEX_TO_ICV: ReadonlyMap<string, number>;
49
49
  * `palette`, when given, is the workbook's own Palette record contents (56 entries, icv 8 first); when undefined, icv 8-63 resolve through the fixed default table instead -- [MS-XLS] "Icv"'s own documented fallback for a file carrying no Palette record.
50
50
  */
51
51
  declare function resolveIcvColor(icv: number, palette: readonly Color[] | undefined): Color | undefined;
52
+ /**
53
+ * Applies Excel's own "TintAndShade" colour model to an already-resolved colour: a single -1.0..1.0 value shading a colour toward black (negative) or tinting it toward white (positive), the model CFColor's own numTint field ([MS-XLS] 2.4, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-xls/fd8e679d-069f-486b-ab48-2382cc167305) carries -- distinct from DrawingML's own separate shade/tint elements (ooxml.js's typed/shared/color.ts), which apply in linear light rather than adjusting HSL lightness directly.
54
+ *
55
+ * The formula itself -- Lum' = Lum*(1+tint) for a negative tint, Lum' = Lum*(1-tint) + tint for a positive one -- is Microsoft's own documented Color.TintAndShade algorithm, cross-checked against Apache POI's XSSFColor#getTint/#setTint javadoc (a completely independent implementation carrying the identical formula) rather than trusted from memory alone.
56
+ */
57
+ declare function applyTint(color: Color, tint: number): Color;
52
58
  /** One border edge's own raw fields, as the CellXF/StyleXF trailing payload packs them: a BorderStyle line-style token and a 7-bit icv colour index. */
53
59
  interface XfBorderEdge {
54
60
  readonly style: number;
@@ -95,4 +101,4 @@ declare function readLongRgbColor(cursor: BlockCursor): Color;
95
101
  /** The inverse of readLongRgbColor: a colour's own red/green/blue/reserved bytes, rounded to the nearest byte (the same rounding colorToRgbHex applies) -- exact for any colour this package itself constructed via rgbHexToColor, which is what write.ts's own palette-colour interning does. */
96
102
  declare function longRgbBytesOf(color: Color): readonly [number, number, number, number];
97
103
  //#endregion
98
- export { packXfDecorationWords as A, UNDECORATED_XF_FIELDS as C, borderStyleTokenFor as D, XfDecorationFields as E, resolveIcvColor as F, resolveVerticalAlignment as I, unpackXfAlignment as L, resolveBorderEdge as M, resolveFillBackground as N, horizAlignTokenFor as O, resolveHorizontalAlignment as P, unpackXfDecoration as R, PATTERN_TYPE_TO_FILL_PATTERN as S, XfBorderEdge as T, FILL_PATTERN_SOLID as _, BORDER_STYLE_DOUBLE as a, PALETTE_BASE_ICV as b, BORDER_STYLE_MEDIUM_DASHDOT as c, BORDER_STYLE_NONE as d, BORDER_STYLE_SLANT_DASHDOT as f, FILL_PATTERN_NONE as g, DEFAULT_PALETTE_HEX_TO_ICV as h, BORDER_STYLE_DOTTED as i, readLongRgbColor as j, longRgbBytesOf as k, BORDER_STYLE_MEDIUM_DASHDOTDOT as l, BORDER_STYLE_THIN as m, BORDER_STYLE_DASHDOTDOT as n, BORDER_STYLE_HAIR as o, BORDER_STYLE_THICK as p, BORDER_STYLE_DASHED as r, BORDER_STYLE_MEDIUM as s, BORDER_STYLE_DASHDOT as t, BORDER_STYLE_MEDIUM_DASHED as u, ICV_AUTOMATIC_BACKGROUND as v, XfAlignmentFields as w, PALETTE_ENTRY_COUNT as x, ICV_AUTOMATIC_FOREGROUND as y, vertAlignTokenFor as z };
104
+ export { longRgbBytesOf as A, vertAlignTokenFor as B, UNDECORATED_XF_FIELDS as C, applyTint as D, XfDecorationFields as E, resolveHorizontalAlignment as F, resolveIcvColor as I, resolveVerticalAlignment as L, readLongRgbColor as M, resolveBorderEdge as N, borderStyleTokenFor as O, resolveFillBackground as P, unpackXfAlignment as R, PATTERN_TYPE_TO_FILL_PATTERN as S, XfBorderEdge as T, FILL_PATTERN_SOLID as _, BORDER_STYLE_DOUBLE as a, PALETTE_BASE_ICV as b, BORDER_STYLE_MEDIUM_DASHDOT as c, BORDER_STYLE_NONE as d, BORDER_STYLE_SLANT_DASHDOT as f, FILL_PATTERN_NONE as g, DEFAULT_PALETTE_HEX_TO_ICV as h, BORDER_STYLE_DOTTED as i, packXfDecorationWords as j, horizAlignTokenFor as k, BORDER_STYLE_MEDIUM_DASHDOTDOT as l, BORDER_STYLE_THIN as m, BORDER_STYLE_DASHDOTDOT as n, BORDER_STYLE_HAIR as o, BORDER_STYLE_THICK as p, BORDER_STYLE_DASHED as r, BORDER_STYLE_MEDIUM as s, BORDER_STYLE_DASHDOT as t, BORDER_STYLE_MEDIUM_DASHED as u, ICV_AUTOMATIC_BACKGROUND as v, XfAlignmentFields as w, PALETTE_ENTRY_COUNT as x, ICV_AUTOMATIC_FOREGROUND as y, unpackXfDecoration as z };
@@ -49,6 +49,12 @@ declare const DEFAULT_PALETTE_HEX_TO_ICV: ReadonlyMap<string, number>;
49
49
  * `palette`, when given, is the workbook's own Palette record contents (56 entries, icv 8 first); when undefined, icv 8-63 resolve through the fixed default table instead -- [MS-XLS] "Icv"'s own documented fallback for a file carrying no Palette record.
50
50
  */
51
51
  declare function resolveIcvColor(icv: number, palette: readonly Color[] | undefined): Color | undefined;
52
+ /**
53
+ * Applies Excel's own "TintAndShade" colour model to an already-resolved colour: a single -1.0..1.0 value shading a colour toward black (negative) or tinting it toward white (positive), the model CFColor's own numTint field ([MS-XLS] 2.4, https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-xls/fd8e679d-069f-486b-ab48-2382cc167305) carries -- distinct from DrawingML's own separate shade/tint elements (ooxml.js's typed/shared/color.ts), which apply in linear light rather than adjusting HSL lightness directly.
54
+ *
55
+ * The formula itself -- Lum' = Lum*(1+tint) for a negative tint, Lum' = Lum*(1-tint) + tint for a positive one -- is Microsoft's own documented Color.TintAndShade algorithm, cross-checked against Apache POI's XSSFColor#getTint/#setTint javadoc (a completely independent implementation carrying the identical formula) rather than trusted from memory alone.
56
+ */
57
+ declare function applyTint(color: Color, tint: number): Color;
52
58
  /** One border edge's own raw fields, as the CellXF/StyleXF trailing payload packs them: a BorderStyle line-style token and a 7-bit icv colour index. */
53
59
  interface XfBorderEdge {
54
60
  readonly style: number;
@@ -95,4 +101,4 @@ declare function readLongRgbColor(cursor: BlockCursor): Color;
95
101
  /** The inverse of readLongRgbColor: a colour's own red/green/blue/reserved bytes, rounded to the nearest byte (the same rounding colorToRgbHex applies) -- exact for any colour this package itself constructed via rgbHexToColor, which is what write.ts's own palette-colour interning does. */
96
102
  declare function longRgbBytesOf(color: Color): readonly [number, number, number, number];
97
103
  //#endregion
98
- export { packXfDecorationWords as A, UNDECORATED_XF_FIELDS as C, borderStyleTokenFor as D, XfDecorationFields as E, resolveIcvColor as F, resolveVerticalAlignment as I, unpackXfAlignment as L, resolveBorderEdge as M, resolveFillBackground as N, horizAlignTokenFor as O, resolveHorizontalAlignment as P, unpackXfDecoration as R, PATTERN_TYPE_TO_FILL_PATTERN as S, XfBorderEdge as T, FILL_PATTERN_SOLID as _, BORDER_STYLE_DOUBLE as a, PALETTE_BASE_ICV as b, BORDER_STYLE_MEDIUM_DASHDOT as c, BORDER_STYLE_NONE as d, BORDER_STYLE_SLANT_DASHDOT as f, FILL_PATTERN_NONE as g, DEFAULT_PALETTE_HEX_TO_ICV as h, BORDER_STYLE_DOTTED as i, readLongRgbColor as j, longRgbBytesOf as k, BORDER_STYLE_MEDIUM_DASHDOTDOT as l, BORDER_STYLE_THIN as m, BORDER_STYLE_DASHDOTDOT as n, BORDER_STYLE_HAIR as o, BORDER_STYLE_THICK as p, BORDER_STYLE_DASHED as r, BORDER_STYLE_MEDIUM as s, BORDER_STYLE_DASHDOT as t, BORDER_STYLE_MEDIUM_DASHED as u, ICV_AUTOMATIC_BACKGROUND as v, XfAlignmentFields as w, PALETTE_ENTRY_COUNT as x, ICV_AUTOMATIC_FOREGROUND as y, vertAlignTokenFor as z };
104
+ export { longRgbBytesOf as A, vertAlignTokenFor as B, UNDECORATED_XF_FIELDS as C, applyTint as D, XfDecorationFields as E, resolveHorizontalAlignment as F, resolveIcvColor as I, resolveVerticalAlignment as L, readLongRgbColor as M, resolveBorderEdge as N, borderStyleTokenFor as O, resolveFillBackground as P, unpackXfAlignment as R, PATTERN_TYPE_TO_FILL_PATTERN as S, XfBorderEdge as T, FILL_PATTERN_SOLID as _, BORDER_STYLE_DOUBLE as a, PALETTE_BASE_ICV as b, BORDER_STYLE_MEDIUM_DASHDOT as c, BORDER_STYLE_NONE as d, BORDER_STYLE_SLANT_DASHDOT as f, FILL_PATTERN_NONE as g, DEFAULT_PALETTE_HEX_TO_ICV as h, BORDER_STYLE_DOTTED as i, packXfDecorationWords as j, horizAlignTokenFor as k, BORDER_STYLE_MEDIUM_DASHDOTDOT as l, BORDER_STYLE_THIN as m, BORDER_STYLE_DASHDOTDOT as n, BORDER_STYLE_HAIR as o, BORDER_STYLE_THICK as p, BORDER_STYLE_DASHED as r, BORDER_STYLE_MEDIUM as s, BORDER_STYLE_DASHDOT as t, BORDER_STYLE_MEDIUM_DASHED as u, ICV_AUTOMATIC_BACKGROUND as v, XfAlignmentFields as w, PALETTE_ENTRY_COUNT as x, ICV_AUTOMATIC_FOREGROUND as y, unpackXfDecoration as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xls-codec",
3
- "version": "4.4.0",
3
+ "version": "4.5.0",
4
4
  "description": "Hand-written reader for the legacy Excel Binary File Format (.xls, BIFF8) as specified by [MS-XLS], mapping a workbook's record stream onto the shared document-schema.js spreadsheet model - the .xls codec for the documents.js family.",
5
5
  "type": "module",
6
6
  "repository": {