@trebco/treb 32.4.1 → 32.6.4

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 (31) hide show
  1. package/README.md +0 -6
  2. package/dist/treb-spreadsheet.mjs +12 -12
  3. package/package.json +2 -2
  4. package/treb-base-types/src/import.ts +14 -10
  5. package/treb-calculator/src/calculator.ts +5 -0
  6. package/treb-charts/src/chart-types.ts +2 -0
  7. package/treb-charts/src/chart-utils.ts +45 -4
  8. package/treb-charts/src/default-chart-renderer.ts +84 -24
  9. package/treb-data-model/src/sheet.ts +9 -0
  10. package/treb-embed/src/embedded-spreadsheet.ts +2 -2
  11. package/treb-embed/style/tab-bar.scss +1 -0
  12. package/treb-export/src/{drawing2/drawing2.ts → drawing/drawing.ts} +2 -2
  13. package/treb-export/src/export.ts +11 -11
  14. package/treb-export/src/import.ts +216 -20
  15. package/treb-export/src/metadata.ts +187 -0
  16. package/treb-export/src/{workbook-sheet2.ts → workbook-sheet.ts} +2 -2
  17. package/treb-export/src/{workbook-style2.ts → workbook-style.ts} +1 -1
  18. package/treb-export/src/{workbook-theme2.ts → workbook-theme.ts} +0 -2
  19. package/treb-export/src/{workbook2.ts → workbook.ts} +157 -11
  20. package/treb-grid/src/types/grid.ts +9 -9
  21. package/treb-grid/src/types/grid_base.ts +2 -1
  22. package/treb-grid/src/types/grid_command.ts +3 -0
  23. package/treb-grid/src/types/tab_bar.ts +36 -7
  24. /package/treb-export/src/{drawing2 → drawing}/bubble-chart-template.ts +0 -0
  25. /package/treb-export/src/{drawing2 → drawing}/chart-template-components2.ts +0 -0
  26. /package/treb-export/src/{drawing2/chart2.ts → drawing/chart.ts} +0 -0
  27. /package/treb-export/src/{drawing2 → drawing}/column-chart-template2.ts +0 -0
  28. /package/treb-export/src/{drawing2 → drawing}/donut-chart-template2.ts +0 -0
  29. /package/treb-export/src/{drawing2 → drawing}/embedded-image.ts +0 -0
  30. /package/treb-export/src/{drawing2 → drawing}/scatter-chart-template2.ts +0 -0
  31. /package/treb-export/src/{shared-strings2.ts → shared-strings.ts} +0 -0
@@ -24,17 +24,17 @@
24
24
  // import UZip from 'uzip';
25
25
  import Base64JS from 'base64-js';
26
26
 
27
- import type { AnchoredChartDescription, AnchoredImageDescription, AnchoredTextBoxDescription} from './workbook2';
28
- import { ChartType, ConditionalFormatOperators, Workbook } from './workbook2';
29
- import type { ParseResult } from 'treb-parser';
27
+ import type { AnchoredChartDescription, AnchoredImageDescription, AnchoredTextBoxDescription} from './workbook';
28
+ import { ChartType, ConditionalFormatOperators, Workbook } from './workbook';
29
+ import type { ExpressionUnit, ParseResult, UnitCall } from 'treb-parser';
30
30
  import { DecimalMarkType, Parser } from 'treb-parser';
31
31
  import type { RangeType, AddressType, HyperlinkType } from './address-type';
32
32
  import { is_range, ShiftRange, InRange, is_address } from './address-type';
33
33
  import { type ImportedSheetData, type AnchoredAnnotation, type CellParseResult, type AnnotationLayout, type Corner as LayoutCorner, type IArea, type GradientStop, type Color, type HTMLColor, type ThemeColor, Area } from 'treb-base-types';
34
34
  import type { SerializedValueType } from 'treb-base-types';
35
- import type { Sheet} from './workbook-sheet2';
36
- import { VisibleState } from './workbook-sheet2';
37
- import type { CellAnchor } from './drawing2/drawing2';
35
+ import type { Sheet} from './workbook-sheet';
36
+ import { VisibleState } from './workbook-sheet';
37
+ import type { CellAnchor } from './drawing/drawing';
38
38
  import { type GenericDOMElement, XMLUtils } from './xml-utils';
39
39
 
40
40
  // import { one_hundred_pixels } from './constants';
@@ -42,6 +42,7 @@ import { ColumnWidthToPixels } from './column-width';
42
42
  import type { DataValidation, AnnotationType } from 'treb-data-model';
43
43
  import { ZipWrapper } from './zip-wrapper';
44
44
  import type { ConditionalFormat } from 'treb-data-model';
45
+ import { LookupMetadata, type MetadataFlags } from './metadata';
45
46
 
46
47
  interface SharedFormula {
47
48
  row: number;
@@ -57,6 +58,7 @@ interface CellElementType {
57
58
  r?: string;
58
59
  t?: string;
59
60
  s?: string;
61
+ cm?: string;
60
62
  };
61
63
  v?: string|number|{
62
64
  t$: string;
@@ -79,7 +81,26 @@ interface ConditionalFormatRule {
79
81
  priority?: string;
80
82
  operator?: string;
81
83
  };
84
+
82
85
  formula?: string|[number,number]|{t$: string};
86
+
87
+ dataBar?: {
88
+ a$?: {
89
+ showValue?: string;
90
+ },
91
+ color?: {
92
+ a$: {
93
+ rgb?: string;
94
+ }
95
+ }
96
+ }
97
+
98
+ extLst?: {
99
+ ext?: {
100
+ 'x14:id'?: string;
101
+ }
102
+ }
103
+
83
104
  colorScale?: {
84
105
  cfvo?: {
85
106
  a$: {
@@ -128,6 +149,7 @@ export class Importer {
128
149
  element: CellElementType,
129
150
  shared_formulae: SharedFormulaMap,
130
151
  arrays: RangeType[],
152
+ dynamic_arrays: RangeType[],
131
153
  merges: RangeType[],
132
154
  links: HyperlinkType[],
133
155
  // validations: Array<{ address: ICellAddress, validation: DataValidation }>,
@@ -146,6 +168,15 @@ export class Importer {
146
168
  return undefined;
147
169
  }
148
170
 
171
+ // new (to us) metadata
172
+ let metadata_flags: MetadataFlags = {};
173
+ if (element.a$?.cm) {
174
+ const cm_index = Number(element.a$?.cm);
175
+ if (this.workbook?.metadata) {
176
+ metadata_flags = LookupMetadata(this.workbook.metadata, 'cell', cm_index).flags;
177
+ }
178
+ }
179
+
149
180
  // console.info(element);
150
181
 
151
182
  let value: undefined | number | boolean | string;
@@ -194,6 +225,8 @@ export class Importer {
194
225
 
195
226
  if (formula) {
196
227
 
228
+ // console.info("F", formula);
229
+
197
230
  // doing it like this is sloppy (also does not work properly).
198
231
  value = '=' + formula.replace(/^_xll\./g, '');
199
232
 
@@ -202,10 +235,66 @@ export class Importer {
202
235
  value = formula;
203
236
  }
204
237
  else {
238
+
205
239
  const parse_result = this.parser.Parse(formula); // l10n?
206
240
  if (parse_result.expression) {
207
- this.parser.Walk(parse_result.expression, (unit) => {
241
+
242
+ const TrimPrefixes = (name: string) => {
243
+
244
+ if (/^_xll\./.test(name)) {
245
+ name = name.substring(5);
246
+ }
247
+ if (/^_xlfn\./.test(name)) {
248
+ console.info("xlfn:", name);
249
+ name = name.substring(6);
250
+ }
251
+ if (/^_xlws\./.test(name)) {
252
+ console.info("xlws:", name);
253
+ name = name.substring(6);
254
+ }
255
+
256
+ return name;
257
+ };
258
+
259
+ const TreeWalker = (unit: ExpressionUnit) => {
260
+
208
261
  if (unit.type === 'call') {
262
+
263
+ // if we see _xlfn.SINGLE, translate that into
264
+ // @ + the name of the first parameter...
265
+ //
266
+ // this is solving the case where single appears, but it
267
+ // doesn't solve the case where it does not appear -- they
268
+ // may be using the array flag of the cell as an indicator?
269
+ // but how then do they know it _should_ be an array? not
270
+ // sure, and I don't see any other indication.
271
+
272
+ if (/^_xlfn\.single/i.test(unit.name)) {
273
+
274
+ const first = unit.args[0];
275
+ if (first.type === 'call') {
276
+
277
+ // we could do this in place, we don't need to copy...
278
+ // although it seems like a good idea. also watch out,
279
+ // these SINGLEs could be nested.
280
+
281
+ const replacement: UnitCall = JSON.parse(JSON.stringify(first));
282
+ replacement.name = '@' + TrimPrefixes(replacement.name);
283
+
284
+ for (let i = 0; i < replacement.args.length; i++) {
285
+ replacement.args[i] = this.parser.Walk2(replacement.args[i], TreeWalker);
286
+ }
287
+
288
+ return replacement;
289
+ }
290
+ else {
291
+ console.info("_xlfn.SINGLE unexpected argument", unit.args[0]);
292
+ }
293
+ }
294
+
295
+ unit.name = TrimPrefixes(unit.name);
296
+
297
+ /*
209
298
  if (/^_xll\./.test(unit.name)) {
210
299
  unit.name = unit.name.substring(5);
211
300
  }
@@ -217,9 +306,15 @@ export class Importer {
217
306
  console.info("xlws:", unit.name);
218
307
  unit.name = unit.name.substring(6);
219
308
  }
309
+ */
310
+
220
311
  }
221
312
  return true;
222
- });
313
+
314
+ };
315
+
316
+ parse_result.expression = this.parser.Walk2(parse_result.expression, TreeWalker);
317
+
223
318
  value = '=' + this.parser.Render(parse_result.expression, { missing: '' });
224
319
  }
225
320
  }
@@ -255,10 +350,38 @@ export class Importer {
255
350
  }
256
351
  }
257
352
 
353
+ //
354
+ // arrays and spill/dynamic arrays
355
+ //
356
+
258
357
  if (typeof element.f !== 'string' && element.f.a$?.t === 'array') {
259
358
  const translated = sheet.TranslateAddress(element.f.a$.ref || '');
260
- if (is_range(translated)) {
261
- arrays.push(ShiftRange(translated, -1, -1));
359
+
360
+ // why are we checking "is_range" here? this should be valid
361
+ // even if the ref attribute is one cell, if it explicitly
362
+ // says t="array"
363
+
364
+ // we will need to adjust it, though? yes, because the lists
365
+ // only accept ranges. note that range type has a superfluous
366
+ // sheet parameter? ...
367
+
368
+ let range = translated;
369
+ if (!is_range(range)) {
370
+ range = {
371
+ to: { ...range },
372
+ from: { ...range },
373
+ sheet: range.sheet,
374
+ };
375
+ }
376
+
377
+ // if (is_range(translated))
378
+ {
379
+ if (metadata_flags['dynamic-array']) {
380
+ dynamic_arrays.push(ShiftRange(range, -1, -1));
381
+ }
382
+ else {
383
+ arrays.push(ShiftRange(range, -1, -1));
384
+ }
262
385
  }
263
386
  }
264
387
 
@@ -298,12 +421,14 @@ export class Importer {
298
421
  // but perhaps we should check that... although at this point we have
299
422
  // already added the array so we need to check for root
300
423
 
301
- for (const array of arrays) {
302
- if (InRange(array, shifted) && (shifted.row !== array.from.row || shifted.col !== array.from.col)) {
303
- calculated_type = type;
304
- calculated_value = value;
305
- value = undefined;
306
- type = 'undefined'; // ValueType.undefined;
424
+ for (const set of [arrays, dynamic_arrays]) {
425
+ for (const array of set) {
426
+ if (InRange(array, shifted) && (shifted.row !== array.from.row || shifted.col !== array.from.col)) {
427
+ calculated_type = type;
428
+ calculated_value = value;
429
+ value = undefined;
430
+ type = 'undefined'; // ValueType.undefined;
431
+ }
307
432
  }
308
433
  }
309
434
 
@@ -350,6 +475,20 @@ export class Importer {
350
475
  }
351
476
  }
352
477
 
478
+ for (const range of dynamic_arrays) {
479
+ if (InRange(range, shifted)) {
480
+ result.spill = {
481
+ start: {
482
+ row: range.from.row,
483
+ column: range.from.col,
484
+ }, end: {
485
+ row: range.to.row,
486
+ column: range.to.col,
487
+ },
488
+ }
489
+ }
490
+ }
491
+
353
492
  for (const range of arrays) {
354
493
  if (InRange(range, shifted)) {
355
494
  result.area = {
@@ -383,7 +522,7 @@ export class Importer {
383
522
 
384
523
  }
385
524
 
386
- public ParseConditionalFormat(address: RangeType|AddressType, rule: ConditionalFormatRule): ConditionalFormat|ConditionalFormat[]|undefined {
525
+ public ParseConditionalFormat(address: RangeType|AddressType, rule: ConditionalFormatRule, extensions?: any[]): ConditionalFormat|ConditionalFormat[]|undefined {
387
526
 
388
527
  const area = this.AddressToArea(address);
389
528
  const operators = ConditionalFormatOperators;
@@ -543,6 +682,44 @@ export class Importer {
543
682
  }
544
683
  break;
545
684
 
685
+ case 'dataBar':
686
+ {
687
+ const hide_values = (rule.dataBar?.a$?.showValue === '0');
688
+ let extension: any = undefined;
689
+
690
+ if (rule.extLst?.ext?.['x14:id']) {
691
+ for (const test of (extensions || [])) {
692
+ if (test['x14:cfRule']?.a$?.id === rule.extLst.ext['x14:id']) {
693
+ extension = test;
694
+ break;
695
+ }
696
+ }
697
+ if (!extension) {
698
+ console.info("conditional format extension not found");
699
+ }
700
+ }
701
+
702
+ if (rule.dataBar?.color?.a$?.rgb) {
703
+
704
+ let negative: Color|undefined = undefined;
705
+
706
+ if (extension?.['x14:cfRule']?.['x14:dataBar']?.['x14:negativeFillColor']?.a$?.rgb) {
707
+ const rgb = extension['x14:cfRule']['x14:dataBar']['x14:negativeFillColor'].a$.rgb;
708
+ negative = { text: '#' + rgb.toString().substring(2) };
709
+ }
710
+
711
+ const fill: Color = { text: '#' + rule.dataBar.color.a$.rgb.substring(2) };
712
+ return {
713
+ type: 'data-bar',
714
+ area,
715
+ fill,
716
+ hide_values,
717
+ negative,
718
+ };
719
+ }
720
+ }
721
+ break;
722
+
546
723
  case 'colorScale':
547
724
  if (rule.colorScale && Array.isArray(rule.colorScale.cfvo) && Array.isArray(rule.colorScale.color)) {
548
725
 
@@ -618,6 +795,7 @@ export class Importer {
618
795
  const data: CellParseResult[] = [];
619
796
  const shared_formulae: {[index: string]: SharedFormula} = {};
620
797
  const arrays: RangeType[] = [];
798
+ const dynamic_arrays: RangeType[] = [];
621
799
  const merges: RangeType[] = [];
622
800
  const conditional_formats: ConditionalFormat[] = [];
623
801
  const links: HyperlinkType[] = [];
@@ -665,6 +843,11 @@ export class Importer {
665
843
  // conditionals
666
844
 
667
845
  const conditional_formatting = FindAll('worksheet/conditionalFormatting');
846
+
847
+ // we might need extensions as well? TODO
848
+
849
+ const conditional_formattings = FindAll('worksheet/extLst/ext/x14:conditionalFormattings/x14:conditionalFormatting');
850
+
668
851
  for (const element of conditional_formatting) {
669
852
  if (element.a$?.sqref ){
670
853
 
@@ -678,7 +861,7 @@ export class Importer {
678
861
  if (element.cfRule) {
679
862
  const rules = Array.isArray(element.cfRule) ? element.cfRule : [element.cfRule];
680
863
  for (const rule of rules) {
681
- const format = this.ParseConditionalFormat(area, rule as unknown as ConditionalFormatRule);
864
+ const format = this.ParseConditionalFormat(area, rule as unknown as ConditionalFormatRule, conditional_formattings);
682
865
  if (format) {
683
866
  if (Array.isArray(format)) {
684
867
  conditional_formats.push(...format);
@@ -905,7 +1088,7 @@ export class Importer {
905
1088
  const cells = row.c ? Array.isArray(row.c) ? row.c : [row.c] : [];
906
1089
 
907
1090
  for (const element of cells) {
908
- const cell = this.ParseCell(sheet, element as unknown as CellElementType, shared_formulae, arrays, merges, links); // , validations);
1091
+ const cell = this.ParseCell(sheet, element as unknown as CellElementType, shared_formulae, arrays, dynamic_arrays, merges, links); // , validations);
909
1092
  if (cell) {
910
1093
  data.push(cell);
911
1094
  }
@@ -1192,12 +1375,21 @@ export class Importer {
1192
1375
 
1193
1376
  break;
1194
1377
 
1378
+ case ChartType.Histogram:
1379
+ type = 'treb-chart';
1380
+ func = 'Histogram.Plot';
1381
+ if (series?.length) {
1382
+ // ...
1383
+ }
1384
+ args[1] = descriptor.chart.title;
1385
+ break;
1386
+
1195
1387
  case ChartType.Box:
1196
1388
  type = 'treb-chart';
1197
1389
  func = 'Box.Plot';
1198
1390
  if (series?.length) {
1199
1391
  args[0] = `Group(${series.map(s => `Series(${s.title || ''},,${s.values||''})`).join(', ')})`;
1200
- console.info("S?", {series}, args[0])
1392
+ // console.info("S?", {series}, args[0])
1201
1393
  }
1202
1394
  args[1] = descriptor.chart.title;
1203
1395
  break;
@@ -1255,6 +1447,10 @@ export class Importer {
1255
1447
  args[1] = series[0]?.categories || '';
1256
1448
  }
1257
1449
 
1450
+ if (descriptor.chart.type === ChartType.Column && descriptor.chart.flags?.includes('stacked')) {
1451
+ args[3] = '"stacked"';
1452
+ }
1453
+
1258
1454
  break;
1259
1455
  }
1260
1456
 
@@ -0,0 +1,187 @@
1
+ import { XMLUtils } from './xml-utils';
2
+
3
+ /**
4
+ * https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet.metadatarecord?view=openxml-3.0.1
5
+ *
6
+ * ah, mixing 0-based and 1-based indexes. that's great. not at all confusing.
7
+ */
8
+ export interface MetadataRecord {
9
+
10
+ //
11
+ // A 1-based index to the metadata record type in metadataTypes.
12
+ //
13
+ t: number;
14
+
15
+ //
16
+ // A zero based index to a specific metadata record. If the corresponding
17
+ // metadataType has name="XLMDX", then this is an index to a record in
18
+ // mdxMetadata, otherwise this is an index to a record in the futureMetadata
19
+ // section whose name matches the name of the metadataType.
20
+ //
21
+ v: number;
22
+
23
+ }
24
+
25
+ /**
26
+ * https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet.metadatatype?view=openxml-3.0.1
27
+ *
28
+ * punting on all these attributes for now, except the ones we specifically
29
+ * want.
30
+ */
31
+ export interface MetadataType {
32
+
33
+ //
34
+ // Represents the name of this particular metadata type. This name shall be
35
+ // unique amongst all other metadataTypes.
36
+ //
37
+ name: string;
38
+
39
+ //
40
+ // A Boolean flag indicating whether metadata is cell metadata. True when
41
+ // the metadata is cell metadata, false otherwise - in the false case it
42
+ // is considered to be value metadata.
43
+ //
44
+ cell_meta?: boolean;
45
+
46
+ }
47
+
48
+ /**
49
+ * the type `Future Feature Data Storage Area` is not actually defined? not
50
+ * sure. maybe it's just a standard extension type and I need to look that up?
51
+ *
52
+ * for the time being we'll use a list of flags...
53
+ */
54
+ export interface MetadataFlags {
55
+ 'dynamic-array'?: boolean;
56
+ }
57
+
58
+ /**
59
+ * https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet.futuremetadata?view=openxml-3.0.1
60
+ * https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet.futuremetadatablock?view=openxml-3.0.1
61
+ *
62
+ * these are named, matching the names in "MetadataType"; we'll use those
63
+ * as indexes, and not store them in the object.
64
+ *
65
+ */
66
+ export interface FutureMetadata {
67
+ flags: MetadataFlags;
68
+ }
69
+
70
+ /**
71
+ * we're just reflecting the actual data at this point, not simplifying
72
+ * (although we should simplify). will require some lookups.
73
+ */
74
+ export interface Metadata {
75
+ cell_metadata: MetadataRecord[];
76
+ metadata_types: MetadataType[];
77
+
78
+ // TODO
79
+ // value_metadata: MetadataRecord[];
80
+
81
+ future_metadata: Record<string, FutureMetadata[]>;
82
+
83
+ }
84
+
85
+ export const LookupMetadata = (source: Metadata, type: 'cell'|'value', index: number): FutureMetadata => {
86
+
87
+ if (type === 'cell') {
88
+
89
+ //
90
+ // the docs say "zero based", but this looks to be one based -- there's
91
+ // only one entry when we create a doc, but the cm index in cells is "1".
92
+ //
93
+ // https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet.cell?view=openxml-3.0.1&redirectedfrom=MSDN
94
+ //
95
+
96
+ const metadata_type = source.cell_metadata[index - 1];
97
+
98
+ if (metadata_type) {
99
+ const record_type = source.metadata_types[metadata_type.t - 1]; // 1-based
100
+ if (record_type) {
101
+ if (record_type.name === 'XLMDX') {
102
+ // ...
103
+ }
104
+ else {
105
+ const future_metadata_list = source.future_metadata[record_type.name];
106
+ if (future_metadata_list) {
107
+ return future_metadata_list[metadata_type.v] || {}; // 0-based
108
+ }
109
+ }
110
+ }
111
+ }
112
+ }
113
+ else {
114
+ console.warn('value metadata not implemented')
115
+ }
116
+
117
+ return {flags: {}}; // null, essentially
118
+
119
+ };
120
+
121
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
122
+ export const ParseMetadataXML = (xml: any): Metadata => {
123
+
124
+ const metadata: Metadata = {
125
+ metadata_types: [],
126
+ cell_metadata: [],
127
+ future_metadata: {},
128
+ };
129
+
130
+ const metadata_types = XMLUtils.FindAll(xml, 'metadata/metadataTypes/metadataType');
131
+ for (const entry of metadata_types) {
132
+
133
+ const name: string = entry.a$?.name || '';
134
+ const value = entry.a$?.cellMeta;
135
+ const cell_meta: boolean = (value === '1' || value === 'true');
136
+
137
+ metadata.metadata_types.push({
138
+ name, cell_meta
139
+ });
140
+
141
+ }
142
+
143
+ const future_metadata_blocks = XMLUtils.FindAll(xml, 'metadata/futureMetadata');
144
+ for (const entry of future_metadata_blocks) {
145
+
146
+ const name: string = entry.a$?.name || '';
147
+ if (name) {
148
+
149
+ const future_metadata_list: FutureMetadata[] = [];
150
+
151
+ // `extLst` entries can be inside of `bk` entries, but aparently not
152
+ // required? what's the case where they are _not_ in `bk` elements?
153
+
154
+ for (const block of XMLUtils.FindAll(entry, 'bk')) {
155
+
156
+ const future_metadata: FutureMetadata = { flags: {} };
157
+
158
+ // I guess metadata attributes are elements? we'll probably
159
+ // have to look them up individually
160
+
161
+ for (const child of XMLUtils.FindAll(block, 'extLst/ext/xda:dynamicArrayProperties')) {
162
+ if (child?.a$.fDynamic === '1') {
163
+ future_metadata.flags['dynamic-array'] = true;
164
+ }
165
+ }
166
+
167
+ future_metadata_list.push(future_metadata);
168
+
169
+ }
170
+
171
+ metadata.future_metadata[name] = future_metadata_list;
172
+
173
+ }
174
+ }
175
+
176
+ for (const entry of XMLUtils.FindAll(xml, 'metadata/cellMetadata/bk/rc')) {
177
+ metadata.cell_metadata.push({
178
+ t: Number(entry.a$?.t || -1),
179
+ v: Number(entry.a$?.v || -1),
180
+ });
181
+ }
182
+
183
+ // console.info({metadata});
184
+
185
+ return metadata;
186
+
187
+ }
@@ -43,8 +43,8 @@
43
43
 
44
44
  import type { AddressType, RangeType} from './address-type';
45
45
  import { is_range } from './address-type';
46
- import type { SharedStrings } from './shared-strings2';
47
- import type { Drawing } from './drawing2/drawing2';
46
+ import type { SharedStrings } from './shared-strings';
47
+ import type { Drawing } from './drawing/drawing';
48
48
  import type { RelationshipMap } from './relationship';
49
49
 
50
50
  export interface SheetOptions {
@@ -23,7 +23,7 @@
23
23
  // import { Element, ElementTree as Tree } from 'elementtree';
24
24
 
25
25
  import { type CompositeBorderEdge, Style, type CellStyle, type PropertyKeys, type Color, IsHTMLColor, IsThemeColor, type ThemeColor, type HTMLColor, ThemeColorIndex } from 'treb-base-types';
26
- import { Theme } from './workbook-theme2';
26
+ import { Theme } from './workbook-theme';
27
27
  import { NumberFormatCache } from 'treb-format';
28
28
  import { XMLUtils } from './xml-utils';
29
29
 
@@ -19,8 +19,6 @@
19
19
  *
20
20
  */
21
21
 
22
- import { XMLUtils } from './xml-utils';
23
-
24
22
  export interface ColorSchemeElement {
25
23
  name?: string;
26
24
  value?: string;