@a3s-lab/office 0.19.0 → 0.21.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.
package/dist/4104.js CHANGED
@@ -5,7 +5,7 @@ import { OFFICE_COLLABORATION_PROTOCOL as WORK_OFFICE_COLLABORATION_PROTOCOL, Of
5
5
  import { contentTypeForPart, directChildren, bytesToDataUrl, OoxmlPackage as work_ooxml_package_OoxmlPackage, parseXml, firstDescendant, xmlNamespacePrefix, descendants, directChild, createArtifact as createWorkArtifact, xmlContainsAnyElement, createOfficeId as createWorkId, attribute as work_ooxml_package_attribute } from "./5184.js";
6
6
  import { mountWorkLiveDocumentCapture, materializeWorkDocumentContent as work_document_model_codec_materializeWorkDocumentContent, documentPageSurfaceGeometryForElement, createWorkDocumentModel, documentContentLayoutProperties, documentModelForContent, createWorkDocumentExtensions, positionWorkLiveDocumentCapture } from "./6282.js";
7
7
  import { normalizeWorkSpreadsheetDataLabels, workSpreadsheetChartSupportsGrouping, normalizeSpreadsheetPrintArea, normalizeWorkSpreadsheetChartLegendPosition, formatSpreadsheetCellRanges, spreadsheetCellAddress, normalizeWorkSpreadsheetChartSmoothLines, spreadsheetFormulaRangeForCell, normalizeWorkSpreadsheetChartColor, readXlsxDrawingAnchor, sparseArrayEntries, qualifySpreadsheetRange, normalizeWorkSpreadsheetBubbleScale, normalizeWorkSpreadsheetChartSeriesStyle, normalizeSpreadsheetPrintTitleRows, normalizeSpreadsheetPrintTitleColumns, spreadsheetPivotFilterValueKey, normalizeWorkSpreadsheetErrorBars, normalizeWorkSpreadsheetBubbleSizeRepresents, workSpreadsheetChartSupportsTrendlines, stripSpreadsheetSheetQualifier, normalizeWorkSpreadsheetChartLegendOverlay, normalizeWorkSpreadsheetChartGapWidth, normalizeWorkSpreadsheetChartGrouping, workSpreadsheetChartSupportsBarSpacing, workSpreadsheetChartSupportsSmoothLines, workSpreadsheetChartGroupingIsStacked, xlsxDrawingAnchorToBounds, xlsxTwoCellAnchorMarkers, workSpreadsheetChartSupportsErrorBars, sparseMatrixColumnCount, refreshSpreadsheetPivotTables, normalizeWorkSpreadsheetChartAxisGroup, isValidSpreadsheetDefinedName, normalizeWorkSpreadsheetScatterStyle, workSpreadsheetChartAxisDefaultLabelPosition, spreadsheetPivotValidation, resolveSpreadsheetChart, parseSpreadsheetCellRanges, workSpreadsheetChartAxisIsCategoryAxis, spreadsheetPivotFields, normalizeWorkSpreadsheetDoughnutHoleSize, normalizeWorkSpreadsheetChartAxes, parseSpreadsheetPrintTitles, spreadsheetFormulaRangeConflict, spreadsheetFormulaForXlsx, editableSpreadsheetFormula, workSpreadsheetChartUsesNumericXAxis, normalizeWorkSpreadsheetChartOverlap, workSpreadsheetChartSupportsAxes, workSpreadsheetChartAxisShowsMajorGridlinesByDefault, normalizeWorkSpreadsheetCombinationSeriesType, effectiveSpreadsheetCalculationSettings, normalizeWorkSpreadsheetTrendline, normalizeWorkSpreadsheetRadarStyle } from "./8715.js";
8
- import { normalizeSpreadsheetDateValidationBoundary, freezeImportedSpreadsheetCell, editableRangeRequiresCredentials, spreadsheetTextOrientationCellStyle, normalizeSpreadsheetConditionalIconSetFormat, defaultSpreadsheetDataBarOptions, normalizeSpreadsheetConditionalVisualOptions, normalizeSpreadsheetPaperSize, spreadsheetTextOrientationXlsxValueFromCell, normalizeSheetProtectionAuthority, defaultSpreadsheetColorScaleThresholds, importedSheetProtectionAuthority, spreadsheetDateValidationFormula, spreadsheetUnderlineCellValueFromXlsx, sheetHasProtectionState, spreadsheetTextOrientationFromXlsx, spreadsheetConditionalComparisonNeedsUpperValue, isSpreadsheetConditionalComparisonOperator, registerImportedSpreadsheetMatrix, spreadsheetExplicitTextOrientationFromCell, spreadsheetUnderlineStyle, defaultSpreadsheetConditionalIconThresholds, isSpreadsheetConditionalIconSetName, DEFAULT_PROTECTION_HINT, spreadsheetConditionalThresholdsEqual, spreadsheetUnderlineCellValueFromSheetJs, spreadsheetConditionalIconSetCount } from "./6164.js";
8
+ import { freezeImportedSpreadsheetCell, normalizeSpreadsheetPaperSize, spreadsheetCellValueWithDiagonalBorder, normalizeSpreadsheetConditionalVisualOptions, spreadsheetTextOrientationXlsxValueFromCell, spreadsheetTextOrientationFromXlsx, isSpreadsheetConditionalComparisonOperator, registerImportedSpreadsheetMatrix, spreadsheetExplicitTextOrientationFromCell, normalizeSpreadsheetDateValidationBoundary, spreadsheetUnderlineStyle, defaultSpreadsheetConditionalIconThresholds, DEFAULT_PROTECTION_HINT, editableRangeRequiresCredentials, spreadsheetTextOrientationCellStyle, normalizeSpreadsheetConditionalIconSetFormat, defaultSpreadsheetDataBarOptions, normalizeSheetProtectionAuthority, importedSheetProtectionAuthority, spreadsheetDateValidationFormula, defaultSpreadsheetColorScaleThresholds, spreadsheetDiagonalBorderFromCellValue, spreadsheetUnderlineCellValueFromXlsx, sheetHasProtectionState, spreadsheetConditionalComparisonNeedsUpperValue, isSpreadsheetConditionalIconSetName, spreadsheetConditionalThresholdsEqual, spreadsheetUnderlineCellValueFromSheetJs, spreadsheetConditionalIconSetCount } from "./5045.js";
9
9
  import { WorkFileImportController, materializeWorkFileSource } from "./9356.js";
10
10
  import "./2591.js";
11
11
  import "./3818.js";
@@ -3112,7 +3112,19 @@ function fortuneBorderInfoFromXlsxCells(entries) {
3112
3112
  setFortuneBorderLine(value, 'r', border.right);
3113
3113
  setFortuneBorderLine(value, 't', border.top);
3114
3114
  setFortuneBorderLine(value, 'b', border.bottom);
3115
- if (border.diagonal) setFortuneBorderLine(value, 's', border.diagonal);
3115
+ if (border.diagonal && (true === border.diagonalDown || true === border.diagonalUp)) {
3116
+ const line = fortuneBorderLine(border.diagonal);
3117
+ if (line) return [
3118
+ {
3119
+ rangeType: 'cell',
3120
+ value: spreadsheetCellValueWithDiagonalBorder(value, {
3121
+ down: true === border.diagonalDown,
3122
+ line,
3123
+ up: true === border.diagonalUp
3124
+ })
3125
+ }
3126
+ ];
3127
+ }
3116
3128
  return Object.keys(value).length > 2 ? [
3117
3129
  {
3118
3130
  rangeType: 'cell',
@@ -3170,11 +3182,18 @@ function applySpreadsheetCellBorderRecord(record, targets, borders) {
3170
3182
  applyCellLine(border, 'right', record.value.r);
3171
3183
  applyCellLine(border, 'top', record.value.t);
3172
3184
  applyCellLine(border, 'bottom', record.value.b);
3173
- const diagonal = xlsxCellBorderLineFromFortune(record.value.s);
3174
- if (void 0 !== diagonal) {
3175
- border.diagonal = diagonal;
3176
- border.diagonalUp = null !== diagonal;
3185
+ const diagonal = spreadsheetDiagonalBorderFromCellValue(record.value);
3186
+ if (void 0 !== diagonal) if (diagonal) {
3187
+ const line = xlsxCellBorderLineFromFortune(diagonal.line);
3188
+ if (void 0 !== line) {
3189
+ border.diagonal = line;
3190
+ border.diagonalDown = null !== line && diagonal.down;
3191
+ border.diagonalUp = null !== line && diagonal.up;
3192
+ }
3193
+ } else {
3194
+ border.diagonal = null;
3177
3195
  border.diagonalDown = false;
3196
+ border.diagonalUp = false;
3178
3197
  }
3179
3198
  borders.set(key, border);
3180
3199
  }
@@ -3240,9 +3259,10 @@ function applySpreadsheetRangeBorder(borders, target, range, borderType, line) {
3240
3259
  if (!onRight) border.right = line;
3241
3260
  break;
3242
3261
  case 'border-slash':
3243
- border.diagonal = line;
3244
- border.diagonalUp = null !== line;
3245
- border.diagonalDown = false;
3262
+ border.diagonalDown = null !== line;
3263
+ border.diagonalUp = true === border.diagonalUp;
3264
+ if (line) border.diagonal = line;
3265
+ else if (!border.diagonalUp) border.diagonal = null;
3246
3266
  break;
3247
3267
  default:
3248
3268
  return;
@@ -3285,6 +3305,13 @@ function setFortuneBorderLine(target, name, line) {
3285
3305
  style: fortuneBorderStyle(line.style)
3286
3306
  };
3287
3307
  }
3308
+ function fortuneBorderLine(line) {
3309
+ const color = normalizeRgbColor(line.color);
3310
+ return color ? {
3311
+ color,
3312
+ style: fortuneBorderStyle(line.style)
3313
+ } : null;
3314
+ }
3288
3315
  function normalizeRgbColor(value) {
3289
3316
  if ('string' != typeof value) return null;
3290
3317
  const color = value.trim().toLowerCase();
@@ -3410,265 +3437,6 @@ function insertXlsxOrderedChild(parent, child, order) {
3410
3437
  const anchor = directChildren(parent).find((candidate)=>order.indexOf(candidate.localName) > requested);
3411
3438
  parent.insertBefore(child, anchor ?? null);
3412
3439
  }
3413
- const fontChildOrder = [
3414
- 'name',
3415
- 'charset',
3416
- 'family',
3417
- 'b',
3418
- 'i',
3419
- 'strike',
3420
- 'outline',
3421
- 'shadow',
3422
- 'condense',
3423
- 'extend',
3424
- 'color',
3425
- 'sz',
3426
- 'u',
3427
- 'vertAlign',
3428
- 'scheme'
3429
- ];
3430
- class XlsxDirectCellStyleWriter {
3431
- styles;
3432
- fonts;
3433
- fills;
3434
- borders;
3435
- cellXfs;
3436
- generatedFonts = new Map();
3437
- generatedFills = new Map();
3438
- generatedBorders = new Map();
3439
- generatedStyles = new Map();
3440
- changed = false;
3441
- constructor(styles){
3442
- this.styles = styles;
3443
- const root = styles.documentElement;
3444
- this.fonts = ensureXlsxStyleCollection(styles, 'fonts', [
3445
- 'fills',
3446
- 'borders',
3447
- 'cellStyleXfs',
3448
- 'cellXfs',
3449
- 'cellStyles',
3450
- 'dxfs',
3451
- 'tableStyles',
3452
- 'colors',
3453
- 'extLst'
3454
- ]);
3455
- if (!directChildren(this.fonts, 'font').length) {
3456
- this.fonts.append(styles.createElementNS(root.namespaceURI, 'font'));
3457
- this.changed = true;
3458
- }
3459
- this.fills = ensureXlsxStyleCollection(styles, 'fills', [
3460
- 'borders',
3461
- 'cellStyleXfs',
3462
- 'cellXfs',
3463
- 'cellStyles',
3464
- 'dxfs',
3465
- 'tableStyles',
3466
- 'colors',
3467
- 'extLst'
3468
- ]);
3469
- if (!directChildren(this.fills, 'fill').length) {
3470
- this.fills.append(defaultXlsxFill(styles, 'none'));
3471
- this.fills.append(defaultXlsxFill(styles, 'gray125'));
3472
- this.changed = true;
3473
- }
3474
- this.borders = ensureXlsxStyleCollection(styles, 'borders', [
3475
- 'cellStyleXfs',
3476
- 'cellXfs',
3477
- 'cellStyles',
3478
- 'dxfs',
3479
- 'tableStyles',
3480
- 'colors',
3481
- 'extLst'
3482
- ]);
3483
- if (!directChildren(this.borders, 'border').length) {
3484
- this.borders.append(defaultXlsxBorder(styles));
3485
- this.changed = true;
3486
- }
3487
- this.cellXfs = ensureXlsxStyleCollection(styles, 'cellXfs', [
3488
- 'cellStyles',
3489
- 'dxfs',
3490
- 'tableStyles',
3491
- 'colors',
3492
- 'extLst'
3493
- ]);
3494
- if (!directChildren(this.cellXfs, 'xf').length) {
3495
- const base = styles.createElementNS(root.namespaceURI, 'xf');
3496
- base.setAttribute('numFmtId', '0');
3497
- base.setAttribute('fontId', '0');
3498
- base.setAttribute('fillId', '0');
3499
- base.setAttribute('borderId', '0');
3500
- base.setAttribute('xfId', '0');
3501
- this.cellXfs.append(base);
3502
- this.changed = true;
3503
- }
3504
- this.updateCounts();
3505
- }
3506
- styleId(baseStyleId, cell, border) {
3507
- const styles = directChildren(this.cellXfs, 'xf');
3508
- const baseIndex = Number.isInteger(baseStyleId) && styles[baseStyleId] ? baseStyleId : 0;
3509
- const base = styles[baseIndex];
3510
- const fontId = this.fontId(work_xlsx_cell_style_writer_nonNegativeInteger(work_ooxml_package_attribute(base, 'fontId')) ?? 0, cell);
3511
- const fillId = this.fillId(work_xlsx_cell_style_writer_nonNegativeInteger(work_ooxml_package_attribute(base, 'fillId')) ?? 0, cell);
3512
- const borderId = this.borderId(work_xlsx_cell_style_writer_nonNegativeInteger(work_ooxml_package_attribute(base, 'borderId')) ?? 0, border);
3513
- const alignment = directAlignment(cell);
3514
- const key = `${baseIndex}:${fontId}:${fillId}:${borderId}:${JSON.stringify(alignment)}`;
3515
- const cached = this.generatedStyles.get(key);
3516
- if (void 0 !== cached) return cached;
3517
- const clone = base.cloneNode(true);
3518
- clone.setAttribute('fontId', String(fontId));
3519
- clone.setAttribute('fillId', String(fillId));
3520
- clone.setAttribute('borderId', String(borderId));
3521
- if (hasXlsxDirectFontStyle(cell)) clone.setAttribute('applyFont', '1');
3522
- if (void 0 !== cell.bg) clone.setAttribute('applyFill', '1');
3523
- if (border) clone.setAttribute('applyBorder', '1');
3524
- if (alignment) {
3525
- writeXlsxAlignment(this.styles, clone, alignment);
3526
- clone.setAttribute('applyAlignment', '1');
3527
- }
3528
- const index = styles.length;
3529
- this.cellXfs.append(clone);
3530
- this.generatedStyles.set(key, index);
3531
- this.changed = true;
3532
- this.updateCounts();
3533
- return index;
3534
- }
3535
- fontId(baseFontId, cell) {
3536
- if (!hasXlsxDirectFontStyle(cell)) return baseFontId;
3537
- const fonts = directChildren(this.fonts, 'font');
3538
- const baseIndex = fonts[baseFontId] ? baseFontId : 0;
3539
- const style = directFontStyle(cell);
3540
- const key = `${baseIndex}:${JSON.stringify(style)}`;
3541
- const cached = this.generatedFonts.get(key);
3542
- if (void 0 !== cached) return cached;
3543
- const font = fonts[baseIndex].cloneNode(true);
3544
- if (void 0 !== style.name) setXlsxValueChild(this.styles, font, 'name', style.name, fontChildOrder);
3545
- if (void 0 !== style.size) setXlsxValueChild(this.styles, font, 'sz', String(style.size), fontChildOrder);
3546
- if (void 0 !== style.color) setXlsxColorChild(this.styles, font, style.color, fontChildOrder);
3547
- if (void 0 !== style.bold) setXlsxToggleChild(this.styles, font, 'b', style.bold, fontChildOrder);
3548
- if (void 0 !== style.italic) setXlsxToggleChild(this.styles, font, 'i', style.italic, fontChildOrder);
3549
- if (void 0 !== style.strike) setXlsxToggleChild(this.styles, font, 'strike', style.strike, fontChildOrder);
3550
- if (void 0 !== style.underline) setXlsxUnderlineChild(this.styles, font, style.underline, fontChildOrder);
3551
- const index = fonts.length;
3552
- this.fonts.append(font);
3553
- this.generatedFonts.set(key, index);
3554
- this.changed = true;
3555
- this.updateCounts();
3556
- return index;
3557
- }
3558
- fillId(baseFillId, cell) {
3559
- if (void 0 === cell.bg) return baseFillId;
3560
- const color = xlsxRgbColor(cell.bg);
3561
- if (!color) return baseFillId;
3562
- const cached = this.generatedFills.get(color);
3563
- if (void 0 !== cached) return cached;
3564
- const fill = this.styles.createElementNS(this.styles.documentElement.namespaceURI, 'fill');
3565
- const pattern = this.styles.createElementNS(this.styles.documentElement.namespaceURI, 'patternFill');
3566
- pattern.setAttribute('patternType', 'solid');
3567
- const foreground = this.styles.createElementNS(this.styles.documentElement.namespaceURI, 'fgColor');
3568
- foreground.setAttribute('rgb', color);
3569
- const background = this.styles.createElementNS(this.styles.documentElement.namespaceURI, 'bgColor');
3570
- background.setAttribute('indexed', '64');
3571
- pattern.append(foreground, background);
3572
- fill.append(pattern);
3573
- const index = directChildren(this.fills, 'fill').length;
3574
- this.fills.append(fill);
3575
- this.generatedFills.set(color, index);
3576
- this.changed = true;
3577
- this.updateCounts();
3578
- return index;
3579
- }
3580
- borderId(baseBorderId, update) {
3581
- if (!update) return baseBorderId;
3582
- const borders = directChildren(this.borders, 'border');
3583
- const baseIndex = borders[baseBorderId] ? baseBorderId : 0;
3584
- const key = `${baseIndex}:${JSON.stringify(update)}`;
3585
- const cached = this.generatedBorders.get(key);
3586
- if (void 0 !== cached) return cached;
3587
- const border = borders[baseIndex].cloneNode(true);
3588
- for (const [name, line] of [
3589
- [
3590
- 'left',
3591
- update.left
3592
- ],
3593
- [
3594
- 'right',
3595
- update.right
3596
- ],
3597
- [
3598
- 'top',
3599
- update.top
3600
- ],
3601
- [
3602
- 'bottom',
3603
- update.bottom
3604
- ],
3605
- [
3606
- 'diagonal',
3607
- update.diagonal
3608
- ]
3609
- ])if (void 0 !== line) setXlsxBorderLine(this.styles, border, name, line);
3610
- if (void 0 !== update.diagonalUp) border.setAttribute('diagonalUp', update.diagonalUp ? '1' : '0');
3611
- if (void 0 !== update.diagonalDown) border.setAttribute('diagonalDown', update.diagonalDown ? '1' : '0');
3612
- const index = borders.length;
3613
- this.borders.append(border);
3614
- this.generatedBorders.set(key, index);
3615
- this.changed = true;
3616
- this.updateCounts();
3617
- return index;
3618
- }
3619
- updateCounts() {
3620
- this.fonts.setAttribute('count', String(directChildren(this.fonts, 'font').length));
3621
- this.fills.setAttribute('count', String(directChildren(this.fills, 'fill').length));
3622
- this.borders.setAttribute('count', String(directChildren(this.borders, 'border').length));
3623
- this.cellXfs.setAttribute('count', String(directChildren(this.cellXfs, 'xf').length));
3624
- }
3625
- }
3626
- function hasXlsxDirectCellStyle(cell) {
3627
- return Boolean(hasXlsxDirectFontStyle(cell) || void 0 !== cell.bg || void 0 !== cell.ht || void 0 !== cell.vt || void 0 !== cell.tb || void 0 !== cell.rt || void 0 !== cell.tr);
3628
- }
3629
- function hasXlsxDirectFontStyle(cell) {
3630
- return Boolean(void 0 !== cell.bl || void 0 !== cell.it || void 0 !== cell.un || void 0 !== cell.cl || void 0 !== cell.ff || void 0 !== cell.fs || void 0 !== cell.fc);
3631
- }
3632
- function directFontStyle(cell) {
3633
- const color = void 0 !== cell.fc ? xlsxRgbColor(cell.fc) : null;
3634
- return {
3635
- ...void 0 !== cell.bl ? {
3636
- bold: 1 === Number(cell.bl)
3637
- } : {},
3638
- ...color ? {
3639
- color
3640
- } : {},
3641
- ...void 0 !== cell.it ? {
3642
- italic: 1 === Number(cell.it)
3643
- } : {},
3644
- ...'string' == typeof cell.ff && cell.ff.trim() ? {
3645
- name: cell.ff.trim()
3646
- } : {},
3647
- ...'number' == typeof cell.fs && Number.isFinite(cell.fs) && cell.fs > 0 ? {
3648
- size: cell.fs
3649
- } : {},
3650
- ...void 0 !== cell.cl ? {
3651
- strike: 1 === Number(cell.cl)
3652
- } : {},
3653
- ...void 0 !== cell.un ? {
3654
- underline: spreadsheetUnderlineStyle(cell.un)
3655
- } : {}
3656
- };
3657
- }
3658
- function directAlignment(cell) {
3659
- const alignment = {};
3660
- if (void 0 !== cell.ht) alignment.horizontal = 0 === Number(cell.ht) ? 'center' : 2 === Number(cell.ht) ? 'right' : 'left';
3661
- if (void 0 !== cell.vt) alignment.vertical = 0 === Number(cell.vt) ? 'center' : 1 === Number(cell.vt) ? 'top' : 'bottom';
3662
- if (void 0 !== cell.tb) alignment.wrapText = '2' === cell.tb;
3663
- const rotation = spreadsheetTextOrientationXlsxValueFromCell(cell);
3664
- if (null !== rotation) alignment.textRotation = rotation;
3665
- return Object.keys(alignment).length ? alignment : null;
3666
- }
3667
- function work_xlsx_cell_style_writer_nonNegativeInteger(value) {
3668
- if (null === value || !/^\d+$/.test(value)) return null;
3669
- const parsed = Number(value);
3670
- return Number.isSafeInteger(parsed) ? parsed : null;
3671
- }
3672
3440
  const defaultThemeColors = [
3673
3441
  'ffffff',
3674
3442
  '000000',
@@ -3870,19 +3638,633 @@ function hslToRgb(hue, saturation, lightness) {
3870
3638
  }
3871
3639
  return channels;
3872
3640
  }
3873
- function normalizedHexColor(value) {
3874
- if (!value || !/^[0-9a-f]{6,8}$/i.test(value)) return;
3875
- return value.slice(-6).toLowerCase();
3641
+ function normalizedHexColor(value) {
3642
+ if (!value || !/^[0-9a-f]{6,8}$/i.test(value)) return;
3643
+ return value.slice(-6).toLowerCase();
3644
+ }
3645
+ function boundedInteger(value, maximum) {
3646
+ if (null === value || !/^\d+$/.test(value)) return null;
3647
+ const parsed = Number(value);
3648
+ return Number.isSafeInteger(parsed) && parsed <= maximum ? parsed : null;
3649
+ }
3650
+ function work_xlsx_colors_booleanAttribute(element, name) {
3651
+ const value = work_ooxml_package_attribute(element, name)?.trim().toLowerCase();
3652
+ return '1' === value || 'true' === value || 'on' === value;
3653
+ }
3654
+ const THEME_COLOR_NAMES = [
3655
+ 'lt1',
3656
+ 'dk1',
3657
+ 'lt2',
3658
+ 'dk2',
3659
+ 'accent1',
3660
+ 'accent2',
3661
+ 'accent3',
3662
+ 'accent4',
3663
+ 'accent5',
3664
+ 'accent6',
3665
+ 'hlink',
3666
+ 'folHlink'
3667
+ ];
3668
+ const MAX_INDEXED_COLOR = 255;
3669
+ function readXlsxSemanticColorOrigin(element, colors) {
3670
+ if (!element || work_ooxml_package_attribute(element, 'rgb')) return;
3671
+ const renderedColor = resolveXlsxColor(element, colors);
3672
+ if (!renderedColor) return;
3673
+ const tint = boundedTint(work_ooxml_package_attribute(element, 'tint'));
3674
+ const theme = work_xlsx_cell_style_origin_boundedInteger(work_ooxml_package_attribute(element, 'theme'), THEME_COLOR_NAMES.length - 1);
3675
+ if (null !== theme && colors.theme[theme]) return {
3676
+ kind: 'theme',
3677
+ baseColor: `#${colors.theme[theme]}`,
3678
+ index: theme,
3679
+ renderedColor,
3680
+ ...null === tint ? {} : {
3681
+ tint
3682
+ }
3683
+ };
3684
+ const indexed = work_xlsx_cell_style_origin_boundedInteger(work_ooxml_package_attribute(element, 'indexed'), MAX_INDEXED_COLOR);
3685
+ if (null !== indexed && colors.indexed[indexed]) return {
3686
+ kind: 'indexed',
3687
+ baseColor: `#${colors.indexed[indexed]}`,
3688
+ index: indexed,
3689
+ renderedColor,
3690
+ ...null === tint ? {} : {
3691
+ tint
3692
+ }
3693
+ };
3694
+ if (xlsxBooleanAttribute(element, 'auto')) return {
3695
+ kind: 'automatic',
3696
+ baseColor: '#000000',
3697
+ renderedColor,
3698
+ ...null === tint ? {} : {
3699
+ tint
3700
+ }
3701
+ };
3702
+ }
3703
+ function withXlsxCellStyleOrigin(cell, origin) {
3704
+ return origin && xlsxCellStyleOriginHasValues(origin) ? {
3705
+ ...cell,
3706
+ a3sXlsxStyleOrigin: origin
3707
+ } : cell;
3708
+ }
3709
+ function xlsxCellStyleOrigin(cell) {
3710
+ const candidate = cell?.a3sXlsxStyleOrigin;
3711
+ if (!work_xlsx_cell_style_origin_isRecord(candidate)) return;
3712
+ const fontColor = normalizedXlsxSemanticColor(candidate.fontColor);
3713
+ const fillColor = normalizedXlsxSemanticColor(candidate.fillColor);
3714
+ const borderColors = normalizedBorderColors(candidate.borderColors);
3715
+ const origin = {
3716
+ ...fontColor ? {
3717
+ fontColor
3718
+ } : {},
3719
+ ...fillColor ? {
3720
+ fillColor
3721
+ } : {},
3722
+ ...borderColors ? {
3723
+ borderColors
3724
+ } : {}
3725
+ };
3726
+ return xlsxCellStyleOriginHasValues(origin) ? origin : void 0;
3727
+ }
3728
+ function xlsxSemanticColorMatchesValue(origin, value) {
3729
+ return normalizedColor(value) === origin.renderedColor.toLowerCase();
3730
+ }
3731
+ function xlsxColorElementMatchesOrigin(element, origin) {
3732
+ if (!element || work_ooxml_package_attribute(element, 'rgb')) return false;
3733
+ if ('theme' === origin.kind) {
3734
+ if (work_ooxml_package_attribute(element, 'theme') !== String(origin.index)) return false;
3735
+ } else if ('indexed' === origin.kind) {
3736
+ if (work_ooxml_package_attribute(element, 'indexed') !== String(origin.index)) return false;
3737
+ } else if (!xlsxBooleanAttribute(element, 'auto')) return false;
3738
+ const tint = boundedTint(work_ooxml_package_attribute(element, 'tint'));
3739
+ return tint === (origin.tint ?? null);
3740
+ }
3741
+ function applyXlsxSemanticColorOrigin(element, origin) {
3742
+ for (const name of [
3743
+ 'rgb',
3744
+ 'theme',
3745
+ 'indexed',
3746
+ 'auto',
3747
+ 'tint'
3748
+ ])element.removeAttribute(name);
3749
+ if ('theme' === origin.kind) element.setAttribute('theme', String(origin.index));
3750
+ else if ('indexed' === origin.kind) element.setAttribute('indexed', String(origin.index));
3751
+ else element.setAttribute('auto', '1');
3752
+ if (void 0 !== origin.tint) element.setAttribute('tint', String(origin.tint));
3753
+ }
3754
+ function xlsxSemanticColorOriginKey(origin) {
3755
+ return origin ? `${origin.kind}:${'index' in origin ? origin.index : ''}:${origin.baseColor}:${origin.renderedColor}:${origin.tint ?? ''}` : '';
3756
+ }
3757
+ function xlsxSemanticColorOriginSupported(origin, palette) {
3758
+ if ('automatic' === origin.kind) return true;
3759
+ return palette?.[origin.kind].get(origin.index)?.toLowerCase() === origin.baseColor.toLowerCase();
3760
+ }
3761
+ function prepareXlsxSemanticPalette(styles, theme, origins) {
3762
+ const candidates = semanticPaletteCandidates(origins);
3763
+ const supportedTheme = new Map();
3764
+ let themeChanged = false;
3765
+ const scheme = theme ? firstDescendant(theme, 'clrScheme') : void 0;
3766
+ for (const [index, color] of candidates.theme){
3767
+ const name = THEME_COLOR_NAMES[index];
3768
+ const entry = name && scheme ? directChild(scheme, name) : void 0;
3769
+ if (entry) {
3770
+ themeChanged = writeThemeColor(entry, color) || themeChanged;
3771
+ supportedTheme.set(index, color);
3772
+ }
3773
+ }
3774
+ const supportedIndexed = new Map();
3775
+ let stylesChanged = false;
3776
+ if (candidates.indexed.size) {
3777
+ const colors = ensureXlsxStyleCollection(styles, 'colors', [
3778
+ 'extLst'
3779
+ ]);
3780
+ let indexedColors = directChild(colors, 'indexedColors');
3781
+ if (!indexedColors) {
3782
+ indexedColors = styles.createElementNS(styles.documentElement.namespaceURI, 'indexedColors');
3783
+ colors.prepend(indexedColors);
3784
+ stylesChanged = true;
3785
+ }
3786
+ const resolver = createXlsxColorResolver(styles, theme);
3787
+ const highestIndex = Math.max(...candidates.indexed.keys());
3788
+ while(directChildren(indexedColors, 'rgbColor').length <= highestIndex){
3789
+ const index = directChildren(indexedColors, 'rgbColor').length;
3790
+ const element = styles.createElementNS(styles.documentElement.namespaceURI, 'rgbColor');
3791
+ element.setAttribute('rgb', `FF${(resolver.indexed[index] ?? '000000').toUpperCase()}`);
3792
+ indexedColors.append(element);
3793
+ stylesChanged = true;
3794
+ }
3795
+ const entries = directChildren(indexedColors, 'rgbColor');
3796
+ for (const [index, color] of candidates.indexed){
3797
+ const expected = `FF${color.slice(1).toUpperCase()}`;
3798
+ const entry = entries[index];
3799
+ if (entry) {
3800
+ if (work_ooxml_package_attribute(entry, 'rgb')?.toUpperCase() !== expected) {
3801
+ entry.setAttribute('rgb', expected);
3802
+ stylesChanged = true;
3803
+ }
3804
+ supportedIndexed.set(index, color);
3805
+ }
3806
+ }
3807
+ }
3808
+ return {
3809
+ palette: {
3810
+ indexed: supportedIndexed,
3811
+ theme: supportedTheme
3812
+ },
3813
+ stylesChanged,
3814
+ themeChanged
3815
+ };
3816
+ }
3817
+ function semanticPaletteCandidates(origins) {
3818
+ const theme = new Map();
3819
+ const indexed = new Map();
3820
+ const themeConflicts = new Set();
3821
+ const indexedConflicts = new Set();
3822
+ for (const origin of origins)for (const color of xlsxCellStyleOriginColors(origin)){
3823
+ if ('automatic' === color.kind) continue;
3824
+ const target = 'theme' === color.kind ? theme : indexed;
3825
+ const conflicts = 'theme' === color.kind ? themeConflicts : indexedConflicts;
3826
+ const current = target.get(color.index);
3827
+ if (current && current.toLowerCase() !== color.baseColor.toLowerCase()) conflicts.add(color.index);
3828
+ else if (!current) target.set(color.index, color.baseColor);
3829
+ }
3830
+ for (const index of themeConflicts)theme.delete(index);
3831
+ for (const index of indexedConflicts)indexed.delete(index);
3832
+ return {
3833
+ indexed,
3834
+ theme
3835
+ };
3836
+ }
3837
+ function xlsxCellStyleOriginColors(origin) {
3838
+ return [
3839
+ origin.fontColor,
3840
+ origin.fillColor,
3841
+ ...Object.values(origin.borderColors ?? {})
3842
+ ].filter((value)=>Boolean(value));
3843
+ }
3844
+ function writeThemeColor(entry, color) {
3845
+ const current = directChildren(entry)[0];
3846
+ if (current?.localName === 'srgbClr' && work_ooxml_package_attribute(current, 'val')?.toLowerCase() === color.slice(1).toLowerCase()) return false;
3847
+ for (const child of directChildren(entry))child.remove();
3848
+ const qualifiedName = entry.prefix ? `${entry.prefix}:srgbClr` : 'srgbClr';
3849
+ const replacement = entry.ownerDocument.createElementNS(entry.namespaceURI, qualifiedName);
3850
+ replacement.setAttribute('val', color.slice(1).toUpperCase());
3851
+ entry.append(replacement);
3852
+ return true;
3853
+ }
3854
+ function normalizedBorderColors(value) {
3855
+ if (!work_xlsx_cell_style_origin_isRecord(value)) return;
3856
+ const result = {};
3857
+ for (const side of [
3858
+ 'bottom',
3859
+ 'diagonal',
3860
+ 'left',
3861
+ 'right',
3862
+ 'top'
3863
+ ]){
3864
+ const color = normalizedXlsxSemanticColor(value[side]);
3865
+ if (color) result[side] = color;
3866
+ }
3867
+ return Object.keys(result).length ? result : void 0;
3868
+ }
3869
+ function normalizedXlsxSemanticColor(value) {
3870
+ if (!work_xlsx_cell_style_origin_isRecord(value)) return;
3871
+ const baseColor = normalizedColor(value.baseColor);
3872
+ const renderedColor = normalizedColor(value.renderedColor);
3873
+ const tint = normalizedTint(value.tint);
3874
+ if (!baseColor || !renderedColor || void 0 === tint) return;
3875
+ if ('automatic' === value.kind) return {
3876
+ kind: 'automatic',
3877
+ baseColor,
3878
+ renderedColor,
3879
+ ...null === tint ? {} : {
3880
+ tint
3881
+ }
3882
+ };
3883
+ const maximum = 'theme' === value.kind ? THEME_COLOR_NAMES.length - 1 : MAX_INDEXED_COLOR;
3884
+ const index = boundedNumber(value.index, maximum);
3885
+ if ('theme' !== value.kind && 'indexed' !== value.kind || null === index) return;
3886
+ return {
3887
+ kind: value.kind,
3888
+ baseColor,
3889
+ index,
3890
+ renderedColor,
3891
+ ...null === tint ? {} : {
3892
+ tint
3893
+ }
3894
+ };
3895
+ }
3896
+ function xlsxCellStyleOriginHasValues(origin) {
3897
+ return Boolean(origin.fontColor || origin.fillColor || Object.keys(origin.borderColors ?? {}).length);
3898
+ }
3899
+ function normalizedColor(value) {
3900
+ const rgb = xlsxRgbColor(value);
3901
+ return rgb ? `#${rgb.slice(-6).toLowerCase()}` : null;
3902
+ }
3903
+ function normalizedTint(value) {
3904
+ if (void 0 === value) return null;
3905
+ return 'number' == typeof value && Number.isFinite(value) && value >= -1 && value <= 1 ? value : void 0;
3906
+ }
3907
+ function boundedTint(value) {
3908
+ if (null === value) return null;
3909
+ const tint = Number(value);
3910
+ return Number.isFinite(tint) && tint >= -1 && tint <= 1 ? tint : null;
3911
+ }
3912
+ function work_xlsx_cell_style_origin_boundedInteger(value, maximum) {
3913
+ if (null === value || !/^\d+$/.test(value)) return null;
3914
+ return boundedNumber(Number(value), maximum);
3915
+ }
3916
+ function boundedNumber(value, maximum) {
3917
+ return 'number' == typeof value && Number.isSafeInteger(value) && value >= 0 && value <= maximum ? value : null;
3918
+ }
3919
+ function xlsxBooleanAttribute(element, name) {
3920
+ const value = work_ooxml_package_attribute(element, name)?.trim().toLowerCase();
3921
+ return '1' === value || 'true' === value || 'on' === value;
3922
+ }
3923
+ function work_xlsx_cell_style_origin_isRecord(value) {
3924
+ return 'object' == typeof value && null !== value && !Array.isArray(value);
3925
+ }
3926
+ function hasXlsxDirectFontStyle(cell) {
3927
+ return Boolean(void 0 !== cell.bl || void 0 !== cell.it || void 0 !== cell.un || void 0 !== cell.cl || void 0 !== cell.ff || void 0 !== cell.fs || void 0 !== cell.fc);
3928
+ }
3929
+ function directXlsxFontStyle(cell) {
3930
+ const color = void 0 !== cell.fc ? xlsxRgbColor(cell.fc) : null;
3931
+ return {
3932
+ ...void 0 !== cell.bl ? {
3933
+ bold: 1 === Number(cell.bl)
3934
+ } : {},
3935
+ ...color ? {
3936
+ color
3937
+ } : {},
3938
+ ...void 0 !== cell.it ? {
3939
+ italic: 1 === Number(cell.it)
3940
+ } : {},
3941
+ ...'string' == typeof cell.ff && cell.ff.trim() ? {
3942
+ name: cell.ff.trim()
3943
+ } : {},
3944
+ ...'number' == typeof cell.fs && Number.isFinite(cell.fs) && cell.fs > 0 ? {
3945
+ size: cell.fs
3946
+ } : {},
3947
+ ...void 0 !== cell.cl ? {
3948
+ strike: 1 === Number(cell.cl)
3949
+ } : {},
3950
+ ...void 0 !== cell.un ? {
3951
+ underline: spreadsheetUnderlineStyle(cell.un)
3952
+ } : {}
3953
+ };
3954
+ }
3955
+ function directXlsxAlignment(cell) {
3956
+ const alignment = {};
3957
+ if (void 0 !== cell.ht) alignment.horizontal = 0 === Number(cell.ht) ? 'center' : 2 === Number(cell.ht) ? 'right' : 'left';
3958
+ if (void 0 !== cell.vt) alignment.vertical = 0 === Number(cell.vt) ? 'center' : 1 === Number(cell.vt) ? 'top' : 'bottom';
3959
+ if (void 0 !== cell.tb) alignment.wrapText = '2' === cell.tb;
3960
+ const rotation = spreadsheetTextOrientationXlsxValueFromCell(cell);
3961
+ if (null !== rotation) alignment.textRotation = rotation;
3962
+ return Object.keys(alignment).length ? alignment : null;
3876
3963
  }
3877
- function boundedInteger(value, maximum) {
3878
- if (null === value || !/^\d+$/.test(value)) return null;
3879
- const parsed = Number(value);
3880
- return Number.isSafeInteger(parsed) && parsed <= maximum ? parsed : null;
3964
+ function xlsxStyleCollectionIndex(collection, childName, value) {
3965
+ const index = work_xlsx_cell_style_values_nonNegativeInteger(value) ?? 0;
3966
+ return directChildren(collection, childName)[index] ? index : 0;
3881
3967
  }
3882
- function work_xlsx_colors_booleanAttribute(element, name) {
3968
+ function xlsxColorMatches(element, value, colors, fallback) {
3969
+ const rgb = xlsxRgbColor(value);
3970
+ const resolved = resolveXlsxColor(element, colors) ?? fallback;
3971
+ return Boolean(rgb && resolved && `#${rgb.slice(-6).toLowerCase()}` === resolved.toLowerCase());
3972
+ }
3973
+ function xlsxToggleEnabled(element) {
3974
+ if (!element) return false;
3975
+ const value = work_ooxml_package_attribute(element, 'val')?.trim().toLowerCase();
3976
+ return '0' !== value && 'false' !== value && 'off' !== value;
3977
+ }
3978
+ function xlsxUnderlineStyle(element) {
3979
+ return element ? spreadsheetUnderlineStyle(spreadsheetUnderlineCellValueFromXlsx(work_ooxml_package_attribute(element, 'val'))) : 'none';
3980
+ }
3981
+ function xlsxBorderLineMatches(element, line, colors, semanticColor) {
3982
+ const style = element ? work_ooxml_package_attribute(element, 'style') : null;
3983
+ if (!line) return !style;
3984
+ return style === line.style && (semanticColor ? xlsxColorElementMatchesOrigin(element ? directChild(element, 'color') : void 0, semanticColor) : xlsxColorMatches(element ? directChild(element, 'color') : void 0, line.color, colors, '#000000'));
3985
+ }
3986
+ function activeXlsxSemanticColorOrigin(origin, value, palette) {
3987
+ return origin && xlsxSemanticColorMatchesValue(origin, value) && xlsxSemanticColorOriginSupported(origin, palette) ? origin : void 0;
3988
+ }
3989
+ function work_xlsx_cell_style_values_xlsxBooleanAttribute(element, name) {
3990
+ if (!element) return false;
3883
3991
  const value = work_ooxml_package_attribute(element, name)?.trim().toLowerCase();
3884
3992
  return '1' === value || 'true' === value || 'on' === value;
3885
3993
  }
3994
+ function xlsxAlignmentMatches(xf, style) {
3995
+ const alignment = directChild(xf, 'alignment');
3996
+ if (void 0 !== style.horizontal && work_ooxml_package_attribute(alignment ?? xf, 'horizontal') !== style.horizontal) return false;
3997
+ if (void 0 !== style.vertical && work_ooxml_package_attribute(alignment ?? xf, 'vertical') !== style.vertical) return false;
3998
+ if (void 0 !== style.wrapText && (!alignment || null === work_ooxml_package_attribute(alignment, 'wrapText') || work_xlsx_cell_style_values_xlsxBooleanAttribute(alignment, 'wrapText') !== style.wrapText)) return false;
3999
+ if (void 0 !== style.textRotation) {
4000
+ const rotation = work_xlsx_cell_style_values_nonNegativeInteger(alignment ? work_ooxml_package_attribute(alignment, 'textRotation') : null);
4001
+ if (rotation !== style.textRotation) return false;
4002
+ }
4003
+ return true;
4004
+ }
4005
+ function work_xlsx_cell_style_values_nonNegativeInteger(value) {
4006
+ if (null === value || !/^\d+$/.test(value)) return null;
4007
+ const parsed = Number(value);
4008
+ return Number.isSafeInteger(parsed) ? parsed : null;
4009
+ }
4010
+ const fontChildOrder = [
4011
+ 'name',
4012
+ 'charset',
4013
+ 'family',
4014
+ 'b',
4015
+ 'i',
4016
+ 'strike',
4017
+ 'outline',
4018
+ 'shadow',
4019
+ 'condense',
4020
+ 'extend',
4021
+ 'color',
4022
+ 'sz',
4023
+ 'u',
4024
+ 'vertAlign',
4025
+ 'scheme'
4026
+ ];
4027
+ class XlsxDirectCellStyleWriter {
4028
+ styles;
4029
+ semanticPalette;
4030
+ fonts;
4031
+ fills;
4032
+ borders;
4033
+ cellXfs;
4034
+ generatedFonts = new Map();
4035
+ generatedFills = new Map();
4036
+ generatedBorders = new Map();
4037
+ generatedStyles = new Map();
4038
+ colors;
4039
+ changed = false;
4040
+ constructor(styles, theme = null, semanticPalette){
4041
+ this.styles = styles;
4042
+ this.semanticPalette = semanticPalette;
4043
+ this.colors = createXlsxColorResolver(styles, theme);
4044
+ const root = styles.documentElement;
4045
+ this.fonts = ensureXlsxStyleCollection(styles, 'fonts', [
4046
+ 'fills',
4047
+ 'borders',
4048
+ 'cellStyleXfs',
4049
+ 'cellXfs',
4050
+ 'cellStyles',
4051
+ 'dxfs',
4052
+ 'tableStyles',
4053
+ 'colors',
4054
+ 'extLst'
4055
+ ]);
4056
+ if (!directChildren(this.fonts, 'font').length) {
4057
+ this.fonts.append(styles.createElementNS(root.namespaceURI, 'font'));
4058
+ this.changed = true;
4059
+ }
4060
+ this.fills = ensureXlsxStyleCollection(styles, 'fills', [
4061
+ 'borders',
4062
+ 'cellStyleXfs',
4063
+ 'cellXfs',
4064
+ 'cellStyles',
4065
+ 'dxfs',
4066
+ 'tableStyles',
4067
+ 'colors',
4068
+ 'extLst'
4069
+ ]);
4070
+ if (!directChildren(this.fills, 'fill').length) {
4071
+ this.fills.append(defaultXlsxFill(styles, 'none'));
4072
+ this.fills.append(defaultXlsxFill(styles, 'gray125'));
4073
+ this.changed = true;
4074
+ }
4075
+ this.borders = ensureXlsxStyleCollection(styles, 'borders', [
4076
+ 'cellStyleXfs',
4077
+ 'cellXfs',
4078
+ 'cellStyles',
4079
+ 'dxfs',
4080
+ 'tableStyles',
4081
+ 'colors',
4082
+ 'extLst'
4083
+ ]);
4084
+ if (!directChildren(this.borders, 'border').length) {
4085
+ this.borders.append(defaultXlsxBorder(styles));
4086
+ this.changed = true;
4087
+ }
4088
+ this.cellXfs = ensureXlsxStyleCollection(styles, 'cellXfs', [
4089
+ 'cellStyles',
4090
+ 'dxfs',
4091
+ 'tableStyles',
4092
+ 'colors',
4093
+ 'extLst'
4094
+ ]);
4095
+ if (!directChildren(this.cellXfs, 'xf').length) {
4096
+ const base = styles.createElementNS(root.namespaceURI, 'xf');
4097
+ base.setAttribute('numFmtId', '0');
4098
+ base.setAttribute('fontId', '0');
4099
+ base.setAttribute('fillId', '0');
4100
+ base.setAttribute('borderId', '0');
4101
+ base.setAttribute('xfId', '0');
4102
+ this.cellXfs.append(base);
4103
+ this.changed = true;
4104
+ }
4105
+ this.updateCounts();
4106
+ }
4107
+ styleId(baseStyleId, cell, border) {
4108
+ const styles = directChildren(this.cellXfs, 'xf');
4109
+ const baseIndex = Number.isInteger(baseStyleId) && styles[baseStyleId] ? baseStyleId : 0;
4110
+ const base = styles[baseIndex];
4111
+ const baseFontId = xlsxStyleCollectionIndex(this.fonts, 'font', work_ooxml_package_attribute(base, 'fontId'));
4112
+ const baseFillId = xlsxStyleCollectionIndex(this.fills, 'fill', work_ooxml_package_attribute(base, 'fillId'));
4113
+ const baseBorderId = xlsxStyleCollectionIndex(this.borders, 'border', work_ooxml_package_attribute(base, 'borderId'));
4114
+ const origin = xlsxCellStyleOrigin(cell);
4115
+ const fontId = this.fontId(baseFontId, cell, origin?.fontColor);
4116
+ const fillId = this.fillId(baseFillId, cell, origin?.fillColor);
4117
+ const borderId = this.borderId(baseBorderId, border, origin?.borderColors);
4118
+ const alignment = directXlsxAlignment(cell);
4119
+ const alignmentChanged = Boolean(alignment && !xlsxAlignmentMatches(base, alignment));
4120
+ if (fontId === baseFontId && fillId === baseFillId && borderId === baseBorderId && !alignmentChanged) return baseIndex;
4121
+ const key = `${baseIndex}:${fontId}:${fillId}:${borderId}:${alignmentChanged ? JSON.stringify(alignment) : ''}`;
4122
+ const cached = this.generatedStyles.get(key);
4123
+ if (void 0 !== cached) return cached;
4124
+ const clone = base.cloneNode(true);
4125
+ clone.setAttribute('fontId', String(fontId));
4126
+ clone.setAttribute('fillId', String(fillId));
4127
+ clone.setAttribute('borderId', String(borderId));
4128
+ if (fontId !== baseFontId) clone.setAttribute('applyFont', '1');
4129
+ if (fillId !== baseFillId) clone.setAttribute('applyFill', '1');
4130
+ if (borderId !== baseBorderId) clone.setAttribute('applyBorder', '1');
4131
+ if (alignment && alignmentChanged) {
4132
+ writeXlsxAlignment(this.styles, clone, alignment);
4133
+ clone.setAttribute('applyAlignment', '1');
4134
+ }
4135
+ const index = styles.length;
4136
+ this.cellXfs.append(clone);
4137
+ this.generatedStyles.set(key, index);
4138
+ this.changed = true;
4139
+ this.updateCounts();
4140
+ return index;
4141
+ }
4142
+ fontId(baseFontId, cell, colorOrigin) {
4143
+ if (!hasXlsxDirectFontStyle(cell)) return baseFontId;
4144
+ const fonts = directChildren(this.fonts, 'font');
4145
+ const baseIndex = fonts[baseFontId] ? baseFontId : 0;
4146
+ const style = directXlsxFontStyle(cell);
4147
+ const base = fonts[baseIndex];
4148
+ const semanticColor = activeXlsxSemanticColorOrigin(colorOrigin, style.color, this.semanticPalette);
4149
+ const nameChanged = void 0 !== style.name && work_ooxml_package_attribute(directChild(base, 'name') ?? base, 'val')?.trim() !== style.name;
4150
+ const sizeChanged = void 0 !== style.size && Number(work_ooxml_package_attribute(directChild(base, 'sz') ?? base, 'val')) !== style.size;
4151
+ const colorChanged = void 0 !== style.color && (semanticColor ? !xlsxColorElementMatchesOrigin(directChild(base, 'color'), semanticColor) : !xlsxColorMatches(directChild(base, 'color'), style.color, this.colors, '#000000'));
4152
+ const boldChanged = void 0 !== style.bold && xlsxToggleEnabled(directChild(base, 'b')) !== style.bold;
4153
+ const italicChanged = void 0 !== style.italic && xlsxToggleEnabled(directChild(base, 'i')) !== style.italic;
4154
+ const strikeChanged = void 0 !== style.strike && xlsxToggleEnabled(directChild(base, 'strike')) !== style.strike;
4155
+ const underlineChanged = void 0 !== style.underline && xlsxUnderlineStyle(directChild(base, 'u')) !== style.underline;
4156
+ if (!nameChanged && !sizeChanged && !colorChanged && !boldChanged && !italicChanged && !strikeChanged && !underlineChanged) return baseIndex;
4157
+ const key = `${baseIndex}:${JSON.stringify(style)}:${xlsxSemanticColorOriginKey(semanticColor)}`;
4158
+ const cached = this.generatedFonts.get(key);
4159
+ if (void 0 !== cached) return cached;
4160
+ const font = base.cloneNode(true);
4161
+ if (nameChanged && void 0 !== style.name) setXlsxValueChild(this.styles, font, 'name', style.name, fontChildOrder);
4162
+ if (sizeChanged && void 0 !== style.size) setXlsxValueChild(this.styles, font, 'sz', String(style.size), fontChildOrder);
4163
+ if (colorChanged && void 0 !== style.color) {
4164
+ setXlsxColorChild(this.styles, font, style.color, fontChildOrder);
4165
+ const color = directChild(font, 'color');
4166
+ if (color && semanticColor) applyXlsxSemanticColorOrigin(color, semanticColor);
4167
+ }
4168
+ if (boldChanged && void 0 !== style.bold) setXlsxToggleChild(this.styles, font, 'b', style.bold, fontChildOrder);
4169
+ if (italicChanged && void 0 !== style.italic) setXlsxToggleChild(this.styles, font, 'i', style.italic, fontChildOrder);
4170
+ if (strikeChanged && void 0 !== style.strike) setXlsxToggleChild(this.styles, font, 'strike', style.strike, fontChildOrder);
4171
+ if (underlineChanged && void 0 !== style.underline) setXlsxUnderlineChild(this.styles, font, style.underline, fontChildOrder);
4172
+ const index = fonts.length;
4173
+ this.fonts.append(font);
4174
+ this.generatedFonts.set(key, index);
4175
+ this.changed = true;
4176
+ this.updateCounts();
4177
+ return index;
4178
+ }
4179
+ fillId(baseFillId, cell, colorOrigin) {
4180
+ if (void 0 === cell.bg) return baseFillId;
4181
+ const color = xlsxRgbColor(cell.bg);
4182
+ if (!color) return baseFillId;
4183
+ const fills = directChildren(this.fills, 'fill');
4184
+ const baseIndex = fills[baseFillId] ? baseFillId : 0;
4185
+ const basePattern = directChild(fills[baseIndex], 'patternFill');
4186
+ const semanticColor = activeXlsxSemanticColorOrigin(colorOrigin, color, this.semanticPalette);
4187
+ if ('solid' === work_ooxml_package_attribute(basePattern ?? fills[baseIndex], 'patternType') && (semanticColor ? xlsxColorElementMatchesOrigin(directChild(basePattern ?? fills[baseIndex], 'fgColor'), semanticColor) : xlsxColorMatches(directChild(basePattern ?? fills[baseIndex], 'fgColor'), color, this.colors))) return baseIndex;
4188
+ const key = `${color}:${xlsxSemanticColorOriginKey(semanticColor)}`;
4189
+ const cached = this.generatedFills.get(key);
4190
+ if (void 0 !== cached) return cached;
4191
+ const fill = this.styles.createElementNS(this.styles.documentElement.namespaceURI, 'fill');
4192
+ const pattern = this.styles.createElementNS(this.styles.documentElement.namespaceURI, 'patternFill');
4193
+ pattern.setAttribute('patternType', 'solid');
4194
+ const foreground = this.styles.createElementNS(this.styles.documentElement.namespaceURI, 'fgColor');
4195
+ foreground.setAttribute('rgb', color);
4196
+ if (semanticColor) applyXlsxSemanticColorOrigin(foreground, semanticColor);
4197
+ const background = this.styles.createElementNS(this.styles.documentElement.namespaceURI, 'bgColor');
4198
+ background.setAttribute('indexed', '64');
4199
+ pattern.append(foreground, background);
4200
+ fill.append(pattern);
4201
+ const index = directChildren(this.fills, 'fill').length;
4202
+ this.fills.append(fill);
4203
+ this.generatedFills.set(key, index);
4204
+ this.changed = true;
4205
+ this.updateCounts();
4206
+ return index;
4207
+ }
4208
+ borderId(baseBorderId, update, colorOrigins) {
4209
+ if (!update) return baseBorderId;
4210
+ const borders = directChildren(this.borders, 'border');
4211
+ const baseIndex = borders[baseBorderId] ? baseBorderId : 0;
4212
+ const base = borders[baseIndex];
4213
+ const lineUpdates = [
4214
+ [
4215
+ 'left',
4216
+ update.left
4217
+ ],
4218
+ [
4219
+ 'right',
4220
+ update.right
4221
+ ],
4222
+ [
4223
+ 'top',
4224
+ update.top
4225
+ ],
4226
+ [
4227
+ 'bottom',
4228
+ update.bottom
4229
+ ],
4230
+ [
4231
+ 'diagonal',
4232
+ update.diagonal
4233
+ ]
4234
+ ];
4235
+ const lineChanged = lineUpdates.some(([name, line])=>void 0 !== line && !xlsxBorderLineMatches(directChild(base, name), line, this.colors, line ? activeXlsxSemanticColorOrigin(colorOrigins?.[name], line.color, this.semanticPalette) : void 0));
4236
+ const diagonalUpChanged = void 0 !== update.diagonalUp && work_xlsx_cell_style_values_xlsxBooleanAttribute(base, 'diagonalUp') !== update.diagonalUp;
4237
+ const diagonalDownChanged = void 0 !== update.diagonalDown && work_xlsx_cell_style_values_xlsxBooleanAttribute(base, 'diagonalDown') !== update.diagonalDown;
4238
+ if (!lineChanged && !diagonalUpChanged && !diagonalDownChanged) return baseIndex;
4239
+ const key = `${baseIndex}:${JSON.stringify(update)}:${JSON.stringify(colorOrigins ?? {})}`;
4240
+ const cached = this.generatedBorders.get(key);
4241
+ if (void 0 !== cached) return cached;
4242
+ const border = base.cloneNode(true);
4243
+ for (const [name, line] of lineUpdates)if (void 0 !== line && !xlsxBorderLineMatches(directChild(base, name), line, this.colors, line ? activeXlsxSemanticColorOrigin(colorOrigins?.[name], line.color, this.semanticPalette) : void 0)) {
4244
+ setXlsxBorderLine(this.styles, border, name, line);
4245
+ const semanticColor = line ? activeXlsxSemanticColorOrigin(colorOrigins?.[name], line.color, this.semanticPalette) : void 0;
4246
+ const color = directChild(directChild(border, name) ?? border, 'color');
4247
+ if (color && semanticColor) applyXlsxSemanticColorOrigin(color, semanticColor);
4248
+ }
4249
+ if (diagonalUpChanged && void 0 !== update.diagonalUp) border.setAttribute('diagonalUp', update.diagonalUp ? '1' : '0');
4250
+ if (diagonalDownChanged && void 0 !== update.diagonalDown) border.setAttribute('diagonalDown', update.diagonalDown ? '1' : '0');
4251
+ const index = borders.length;
4252
+ this.borders.append(border);
4253
+ this.generatedBorders.set(key, index);
4254
+ this.changed = true;
4255
+ this.updateCounts();
4256
+ return index;
4257
+ }
4258
+ updateCounts() {
4259
+ this.fonts.setAttribute('count', String(directChildren(this.fonts, 'font').length));
4260
+ this.fills.setAttribute('count', String(directChildren(this.fills, 'fill').length));
4261
+ this.borders.setAttribute('count', String(directChildren(this.borders, 'border').length));
4262
+ this.cellXfs.setAttribute('count', String(directChildren(this.cellXfs, 'xf').length));
4263
+ }
4264
+ }
4265
+ function hasXlsxDirectCellStyle(cell) {
4266
+ return Boolean(hasXlsxDirectFontStyle(cell) || void 0 !== cell.bg || void 0 !== cell.ht || void 0 !== cell.vt || void 0 !== cell.tb || void 0 !== cell.rt || void 0 !== cell.tr);
4267
+ }
3886
4268
  const xlsxCellBorderStyles = new Set([
3887
4269
  'dashDot',
3888
4270
  'dashDotDot',
@@ -3913,10 +4295,12 @@ function readXlsxDirectCellStyles(worksheet, styles, theme = null) {
3913
4295
  if (!coordinate || !xf) return [];
3914
4296
  const style = readDirectCellStyle(xf, fonts, fills, colors);
3915
4297
  const border = readDirectCellBorder(xf, borders, colors);
4298
+ const origin = readDirectCellStyleOrigin(xf, fonts, fills, borders, colors);
3916
4299
  return Object.keys(style).length || border ? [
3917
4300
  {
3918
4301
  ...coordinate,
3919
4302
  border,
4303
+ origin,
3920
4304
  style
3921
4305
  }
3922
4306
  ] : [];
@@ -3961,6 +4345,43 @@ function readDirectCellStyle(xf, fonts, fills, colors) {
3961
4345
  if (alignment) readDirectAlignmentStyle(style, alignment);
3962
4346
  return style;
3963
4347
  }
4348
+ function readDirectCellStyleOrigin(xf, fonts, fills, borders, colors) {
4349
+ const fontId = work_xlsx_cell_styles_nonNegativeInteger(work_ooxml_package_attribute(xf, 'fontId')) ?? 0;
4350
+ const font = fonts[fontId];
4351
+ const fontColor = font && (0 !== fontId || work_xlsx_cell_styles_booleanAttribute(xf, 'applyFont')) ? readXlsxSemanticColorOrigin(directChild(font, 'color'), colors) : void 0;
4352
+ const fillId = work_xlsx_cell_styles_nonNegativeInteger(work_ooxml_package_attribute(xf, 'fillId')) ?? 0;
4353
+ const fill = fills[fillId];
4354
+ const pattern = fill ? directChild(fill, 'patternFill') : void 0;
4355
+ const fillColor = pattern && 'solid' === work_ooxml_package_attribute(pattern, 'patternType') && (0 !== fillId || work_xlsx_cell_styles_booleanAttribute(xf, 'applyFill')) ? readXlsxSemanticColorOrigin(directChild(pattern, 'fgColor'), colors) : void 0;
4356
+ const borderId = work_xlsx_cell_styles_nonNegativeInteger(work_ooxml_package_attribute(xf, 'borderId')) ?? 0;
4357
+ const border = borders[borderId];
4358
+ const borderColors = {};
4359
+ if (border && (0 !== borderId || work_xlsx_cell_styles_booleanAttribute(xf, 'applyBorder'))) for (const side of [
4360
+ 'bottom',
4361
+ 'diagonal',
4362
+ 'left',
4363
+ 'right',
4364
+ 'top'
4365
+ ]){
4366
+ const line = directChild(border, side);
4367
+ const lineStyle = line ? work_ooxml_package_attribute(line, 'style') : null;
4368
+ if (!line || !lineStyle || !xlsxCellBorderStyles.has(lineStyle)) continue;
4369
+ const color = readXlsxSemanticColorOrigin(directChild(line, 'color'), colors);
4370
+ if (color) borderColors[side] = color;
4371
+ }
4372
+ if (!fontColor && !fillColor && !Object.keys(borderColors).length) return;
4373
+ return {
4374
+ ...fontColor ? {
4375
+ fontColor
4376
+ } : {},
4377
+ ...fillColor ? {
4378
+ fillColor
4379
+ } : {},
4380
+ ...Object.keys(borderColors).length ? {
4381
+ borderColors
4382
+ } : {}
4383
+ };
4384
+ }
3964
4385
  function readDirectFontStyle(style, font, colors) {
3965
4386
  const bold = directChild(font, 'b');
3966
4387
  if (bold && toggleEnabled(bold)) style.bl = 1;
@@ -6381,8 +6802,10 @@ async function patchXlsxSheetFeatures(buffer, content) {
6381
6802
  const worksheetParts = await work_xlsx_interop_readWorksheetParts(archive);
6382
6803
  const zip = await jszip.loadAsync(buffer);
6383
6804
  const styles = archive.has('xl/styles.xml') ? await archive.xml('xl/styles.xml') : null;
6805
+ const theme = archive.has('xl/theme/theme1.xml') ? await archive.xml('xl/theme/theme1.xml') : null;
6806
+ const semanticPalette = styles ? prepareXlsxSemanticPalette(styles, theme, spreadsheetXlsxStyleOrigins(content)) : void 0;
6384
6807
  const differentialFormats = styles ? new XlsxDifferentialFormatWriter(styles) : void 0;
6385
- const directCellStyles = styles ? new XlsxDirectCellStyleWriter(styles) : void 0;
6808
+ const directCellStyles = styles ? new XlsxDirectCellStyleWriter(styles, theme, semanticPalette?.palette) : void 0;
6386
6809
  const cellProtection = styles ? new XlsxCellProtectionWriter(styles) : void 0;
6387
6810
  for (const sheet of sheets){
6388
6811
  const pageBreaks = sheet.id ? pageBreaksBySheetId.get(sheet.id) : void 0;
@@ -6402,12 +6825,21 @@ async function patchXlsxSheetFeatures(buffer, content) {
6402
6825
  writeXlsxManualPageBreaks(document1, pageBreaks);
6403
6826
  zip.file(partPath, new XMLSerializer().serializeToString(document1));
6404
6827
  }
6405
- if (styles && (differentialFormats?.changed || directCellStyles?.changed || cellProtection?.changed)) zip.file('xl/styles.xml', new XMLSerializer().serializeToString(styles));
6828
+ if (styles && (differentialFormats?.changed || directCellStyles?.changed || cellProtection?.changed || semanticPalette?.stylesChanged)) zip.file('xl/styles.xml', new XMLSerializer().serializeToString(styles));
6829
+ if (theme && semanticPalette?.themeChanged) zip.file('xl/theme/theme1.xml', new XMLSerializer().serializeToString(theme));
6406
6830
  return zip.generateAsync({
6407
6831
  type: 'arraybuffer',
6408
6832
  compression: 'DEFLATE'
6409
6833
  });
6410
6834
  }
6835
+ function spreadsheetXlsxStyleOrigins(content) {
6836
+ const origins = [];
6837
+ for (const sheet of content.sheets)for (const [, row] of sparseArrayEntries(sheet.data))for (const [, cell] of sparseArrayEntries(row)){
6838
+ const origin = xlsxCellStyleOrigin(cell);
6839
+ if (origin) origins.push(origin);
6840
+ }
6841
+ return origins;
6842
+ }
6411
6843
  async function work_xlsx_interop_readWorksheetParts(archive, workbookDocument) {
6412
6844
  if (!archive.has('xl/workbook.xml')) return new Map();
6413
6845
  const workbook = workbookDocument ?? await archive.xml('xl/workbook.xml');
@@ -8320,7 +8752,7 @@ async function importWorkSpreadsheetFile(file, extension, context) {
8320
8752
  const directCellStyle = directCellStyles.get(spreadsheetCellKey(row, column));
8321
8753
  directCellStyles.delete(spreadsheetCellKey(row, column));
8322
8754
  data[row] ??= [];
8323
- data[row][column] = freezeImportedSpreadsheetCell(fortuneCellFromXlsx(source, row, column, id, hyperlink, comment, XLSX, directCellStyle?.style));
8755
+ data[row][column] = freezeImportedSpreadsheetCell(withXlsxCellStyleOrigin(fortuneCellFromXlsx(source, row, column, id, hyperlink, comment, XLSX, directCellStyle?.style), directCellStyle?.origin));
8324
8756
  if (source.f) formulaCells.push({
8325
8757
  column,
8326
8758
  row
@@ -8333,15 +8765,15 @@ async function importWorkSpreadsheetFile(file, extension, context) {
8333
8765
  }
8334
8766
  releaseImportedWorksheetCells(worksheet);
8335
8767
  }
8336
- for (const { column, row, style } of directCellStyles.values()){
8768
+ for (const { column, origin, row, style } of directCellStyles.values()){
8337
8769
  rowCount = Math.max(rowCount, row + 1);
8338
8770
  columnCount = Math.max(columnCount, column + 1);
8339
8771
  data[row] ??= [];
8340
8772
  const existing = data[row][column];
8341
- data[row][column] = freezeImportedSpreadsheetCell({
8773
+ data[row][column] = freezeImportedSpreadsheetCell(withXlsxCellStyleOrigin({
8342
8774
  ...existing ?? {},
8343
8775
  ...style
8344
- });
8776
+ }, origin));
8345
8777
  if (!existing) entryIndex += 1;
8346
8778
  }
8347
8779
  populatedCellCount += entryIndex;