@office-kit/xlsx 0.17.0 → 0.18.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 (61) hide show
  1. package/README.md +78 -4
  2. package/dist/{cell-style-DjKKPWDL.mjs → cell-style-CbB4nXTY.mjs} +11 -4
  3. package/dist/cell-style-CbB4nXTY.mjs.map +1 -0
  4. package/dist/{differential-7KGzbliB.mjs → differential-QLaKEiBk.mjs} +2 -2
  5. package/dist/{differential-7KGzbliB.mjs.map → differential-QLaKEiBk.mjs.map} +1 -1
  6. package/dist/io/load.d.ts +2 -0
  7. package/dist/io.mjs +2 -2
  8. package/dist/{iterparse-DZE0zy2M.mjs → iterparse-CZoRXvZW.mjs} +2 -2
  9. package/dist/{iterparse-DZE0zy2M.mjs.map → iterparse-CZoRXvZW.mjs.map} +1 -1
  10. package/dist/{load-DIdQ_zum.mjs → load-BpnCPv1S.mjs} +25 -13
  11. package/dist/load-BpnCPv1S.mjs.map +1 -0
  12. package/dist/{manifest-BHUYpjUG.mjs → manifest-9p0ccqmR.mjs} +10 -11
  13. package/dist/manifest-9p0ccqmR.mjs.map +1 -0
  14. package/dist/node.mjs +1 -1
  15. package/dist/packaging.mjs +1 -1
  16. package/dist/{parser-By6RWZVW.mjs → parser-B1tB9YaE.mjs} +15 -5
  17. package/dist/parser-B1tB9YaE.mjs.map +1 -0
  18. package/dist/{save-ax11Gsw0.mjs → save-1Z3344nz.mjs} +6 -6
  19. package/dist/{save-ax11Gsw0.mjs.map → save-1Z3344nz.mjs.map} +1 -1
  20. package/dist/schema.mjs +1 -1
  21. package/dist/{serialize-Dmb6Vtt9.mjs → serialize-BtxgssFK.mjs} +2 -2
  22. package/dist/{serialize-Dmb6Vtt9.mjs.map → serialize-BtxgssFK.mjs.map} +1 -1
  23. package/dist/{serializer-dhv07Z6F.mjs → serializer-N6XIwsgp.mjs} +2 -2
  24. package/dist/{serializer-dhv07Z6F.mjs.map → serializer-N6XIwsgp.mjs.map} +1 -1
  25. package/dist/streaming.mjs +34 -17
  26. package/dist/streaming.mjs.map +1 -1
  27. package/dist/styles/display-text.d.ts +95 -0
  28. package/dist/styles/format-code.d.ts +125 -0
  29. package/dist/styles/index.d.ts +1 -0
  30. package/dist/styles/numbers.d.ts +7 -0
  31. package/dist/styles.mjs +1161 -4
  32. package/dist/styles.mjs.map +1 -0
  33. package/dist/{stylesheet-writer-BBYjNSMA.mjs → stylesheet-writer-BEn-0P0x.mjs} +341 -105
  34. package/dist/stylesheet-writer-BEn-0P0x.mjs.map +1 -0
  35. package/dist/{table-BFi2WmgG.mjs → table-BxOLUZs3.mjs} +2 -2
  36. package/dist/{table-BFi2WmgG.mjs.map → table-BxOLUZs3.mjs.map} +1 -1
  37. package/dist/{tree-BX-sRRVp.mjs → tree-CspNjuYl.mjs} +12 -2
  38. package/dist/tree-CspNjuYl.mjs.map +1 -0
  39. package/dist/workbook/index.d.ts +1 -1
  40. package/dist/workbook/workbook.d.ts +9 -46
  41. package/dist/{workbook-CMel6UcI.mjs → workbook-tG9oYtzU.mjs} +46 -9
  42. package/dist/workbook-tG9oYtzU.mjs.map +1 -0
  43. package/dist/workbook.mjs +2 -2
  44. package/dist/worksheet/index.d.ts +1 -1
  45. package/dist/worksheet/worksheet.d.ts +55 -14
  46. package/dist/{worksheet-Cxn2c-jz.mjs → worksheet-DLMyDD7W.mjs} +85 -20
  47. package/dist/worksheet-DLMyDD7W.mjs.map +1 -0
  48. package/dist/worksheet.mjs +3 -3
  49. package/dist/xml/namespaces.d.ts +7 -0
  50. package/dist/xml/parser.d.ts +12 -0
  51. package/dist/xml/strict-package.d.ts +14 -0
  52. package/dist/xml.mjs +4 -4
  53. package/package.json +1 -1
  54. package/dist/cell-style-DjKKPWDL.mjs.map +0 -1
  55. package/dist/load-DIdQ_zum.mjs.map +0 -1
  56. package/dist/manifest-BHUYpjUG.mjs.map +0 -1
  57. package/dist/parser-By6RWZVW.mjs.map +0 -1
  58. package/dist/stylesheet-writer-BBYjNSMA.mjs.map +0 -1
  59. package/dist/tree-BX-sRRVp.mjs.map +0 -1
  60. package/dist/workbook-CMel6UcI.mjs.map +0 -1
  61. package/dist/worksheet-Cxn2c-jz.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.mjs","names":[],"sources":["../src/styles/format-code.ts","../src/styles/display-text.ts"],"sourcesContent":["// Interpreter for Excel number-format codes: a `formatCode` plus a value in,\n// the text Excel prints in the cell out.\n//\n// ECMA-376 types `numFmt@formatCode` as a plain string (§18.8.30) and leaves\n// the grammar to the application, so Excel's own rules are the specification\n// here. A code is up to four `;`-separated sections chosen by the value's sign\n// (positive, negative, zero, text), and each section mixes literals with\n// placeholders: `0` `#` `?` for digits, `y` `m` `d` `h` `s` for date parts, `@`\n// for text.\n//\n// `parseFormatCode` returns `undefined` for a code outside the subset\n// `getCellDisplayText` documents, so callers degrade to a plain coercion rather\n// than print a guess.\n\nimport { excelToDate, type ExcelEpoch } from '../utils/datetime.js';\nimport { FORMAT_COLOR_NAMES } from './numbers.js';\n\n/** Excel carries 15 significant decimal digits and never shows more. */\nconst EXCEL_SIGNIFICANT_DIGITS = 15;\n/** Positive, negative, zero, text. */\nconst MAX_SECTIONS = 4;\nconst GROUP_SEPARATOR = ',';\nconst GROUP_SIZE = 3;\nconst SCALE_DIVISOR = 1000;\nconst PERCENT_MULTIPLIER = 100;\n/** `mmm` and wider render a month or weekday name, never a minute. */\nconst NAME_TOKEN_WIDTH = 3;\nconst MONTH_FULL_WIDTH = 4;\n/** Excel pads a `General` exponent to two digits, so 1e-7 shows as `1E-07`. */\nconst GENERAL_EXPONENT_DIGITS = 2;\nconst FULL_YEAR_DIGITS = 4;\n/** Excel stores time to the millisecond, so `.0000` gains nothing over `.000`. */\nconst MAX_SUBSECOND_DIGITS = 3;\nconst SECONDS_PER_DAY = 86_400;\nconst SECONDS_PER_HOUR = 3_600;\nconst SECONDS_PER_MINUTE = 60;\nconst MINUTES_PER_HOUR = 60;\nconst HOURS_PER_DAY = 24;\nconst HOURS_PER_HALF_DAY = 12;\nconst ZERO_CHAR_CODE = '0'.charCodeAt(0);\nconst FIVE_CHAR_CODE = '5'.charCodeAt(0);\nconst NINE_CHAR_CODE = '9'.charCodeAt(0);\n/** Terms and closeness at which the fraction search stops chasing a double. */\nconst FRACTION_MAX_TERMS = 64;\nconst FRACTION_EPSILON = 1e-12;\n\nconst MONTH_NAMES = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n] as const;\n\nconst WEEKDAY_NAMES = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] as const;\n\nconst COLOR_NAMES: ReadonlySet<string> = new Set(FORMAT_COLOR_NAMES.toLowerCase().split('|'));\nconst INDEXED_COLOR_RE = /^color\\s*\\d+$/i;\n/**\n * The body of an elapsed-time bracket: one letter repeated, as in `[h]` or\n * `[mm]`. `isTimedeltaFormat` in `./numbers.js` answers the different question\n * of whether a whole code is a duration, so it cannot stand in here.\n */\nconst ELAPSED_RE = /^([hms])\\1*$/i;\n\n// ---- tokens ----------------------------------------------------------------\n\ntype DigitPlaceholder = '0' | '#' | '?';\n\ntype DatePart = 'year' | 'month' | 'day' | 'hour' | 'minute' | 'second' | 'monthOrMinute';\ntype ElapsedPart = 'hour' | 'minute' | 'second';\n\ninterface DatePartToken {\n readonly kind: 'datePart';\n readonly part: DatePart;\n readonly width: number;\n}\n\ninterface ElapsedToken {\n readonly kind: 'elapsed';\n readonly part: ElapsedPart;\n readonly width: number;\n}\n\ntype Token =\n | { readonly kind: 'literal'; readonly text: string }\n | { readonly kind: 'general' }\n | { readonly kind: 'digit'; readonly placeholder: DigitPlaceholder }\n | { readonly kind: 'point' }\n | { readonly kind: 'comma' }\n | { readonly kind: 'percent' }\n | { readonly kind: 'exponent'; readonly explicitSign: boolean }\n | { readonly kind: 'slash' }\n | { readonly kind: 'fixedDenominator'; readonly text: string }\n | { readonly kind: 'textPlaceholder' }\n /** Excel prints the meridiem in the case the code carries, so `am/pm` stays lowercase. */\n | { readonly kind: 'meridiem'; readonly am: string; readonly pm: string }\n | { readonly kind: 'subsecond'; readonly digits: number }\n | DatePartToken\n | ElapsedToken;\n\n// ---- sections --------------------------------------------------------------\n\ninterface NumberFormatSection {\n readonly kind: 'number';\n readonly tokens: readonly Token[];\n readonly grouped: boolean;\n /** Trailing commas; each one divides the value by a thousand. */\n readonly scale: number;\n /** `%` occurrences; each one multiplies the value by a hundred. */\n readonly percents: number;\n /** Token index where the integer region ends (exclusive). */\n readonly intEnd: number;\n readonly intPlaceholders: readonly DigitPlaceholder[];\n readonly fracPlaceholders: readonly DigitPlaceholder[];\n /** Token index of the `E+` / `E-` marker, or -1 outside scientific codes. */\n readonly exponentIndex: number;\n readonly exponentDigits: number;\n readonly exponentExplicitSign: boolean;\n}\n\ninterface DateFormatSection {\n readonly kind: 'date';\n readonly tokens: readonly Token[];\n readonly elapsed: boolean;\n /** A year, month or day part: the section names a day, not just a time within one. */\n readonly calendar: boolean;\n readonly hasMeridiem: boolean;\n /** Widest fractional-second group in the section; the serial is rounded once at this precision. */\n readonly subsecondDigits: number;\n}\n\ninterface FractionFormatSection {\n readonly kind: 'fraction';\n readonly tokens: readonly Token[];\n readonly slashIndex: number;\n /** Token range holding the whole-number run, or -1 when the code has none. */\n readonly wholeStart: number;\n readonly wholeEnd: number;\n readonly numeratorStart: number;\n readonly denominatorEnd: number;\n /** Placeholder count in the denominator run; caps the denominator at 10^n - 1. */\n readonly denominatorDigits: number;\n /** Non-zero when the code spells the denominator out, as in `# ?/16`. */\n readonly fixedDenominator: number;\n}\n\ninterface TextFormatSection {\n readonly kind: 'text';\n readonly tokens: readonly Token[];\n}\n\ntype FormatSection =\n | { readonly kind: 'general' }\n | { readonly kind: 'blank' }\n | { readonly kind: 'literal'; readonly text: string }\n | NumberFormatSection\n | DateFormatSection\n | FractionFormatSection\n | TextFormatSection;\n\nexport interface ParsedFormat {\n readonly sections: readonly FormatSection[];\n}\n\n// ---- decimal arithmetic ----------------------------------------------------\n\ninterface DecimalParts {\n readonly int: string;\n readonly frac: string;\n}\n\n/**\n * Plain (never exponential) decimal digits of a finite non-negative number at\n * Excel's precision. Rounding has to go through this string: `(1.005).toFixed(2)`\n * is `\"1.00\"` because the double nearest 1.005 sits just below it, while Excel\n * rounds the 15-digit decimal it shows and prints `1.01`.\n */\nconst toPlainDecimal = (value: number): string => {\n const text = value.toPrecision(EXCEL_SIGNIFICANT_DIGITS);\n const parsed = /^(\\d+)(?:\\.(\\d+))?e([+-]\\d+)$/.exec(text);\n if (parsed === null) return text;\n const intPart = parsed[1] ?? '';\n const digits = intPart + (parsed[2] ?? '');\n const point = intPart.length + Number(parsed[3] ?? '0');\n if (point <= 0) return `0.${'0'.repeat(-point)}${digits}`;\n if (point >= digits.length) return digits + '0'.repeat(point - digits.length);\n return `${digits.slice(0, point)}.${digits.slice(point)}`;\n};\n\n/** Add one to the last digit of a digit string, growing it on overflow. */\nconst carryOne = (digits: string): string => {\n let i = digits.length - 1;\n let tail = '';\n while (i >= 0 && digits.charCodeAt(i) === NINE_CHAR_CODE) {\n tail = `0${tail}`;\n i--;\n }\n if (i < 0) return `1${tail}`;\n return digits.slice(0, i) + String(digits.charCodeAt(i) - ZERO_CHAR_CODE + 1) + tail;\n};\n\n/** Round `int`.`frac` to `decimals` places, half away from zero. */\nconst roundParts = (int: string, frac: string, decimals: number): DecimalParts => {\n if (frac.length <= decimals) return { int, frac: frac.padEnd(decimals, '0') };\n const kept = frac.slice(0, decimals);\n if (frac.charCodeAt(decimals) < FIVE_CHAR_CODE) return { int, frac: kept };\n const bumped = carryOne(int + kept);\n return { int: bumped.slice(0, bumped.length - decimals), frac: bumped.slice(bumped.length - decimals) };\n};\n\nconst roundDecimal = (value: number, decimals: number): DecimalParts => {\n const text = toPlainDecimal(value);\n const dot = text.indexOf('.');\n if (dot === -1) return roundParts(text, '', decimals);\n return roundParts(text.slice(0, dot), text.slice(dot + 1), decimals);\n};\n\n/** Significant digits of a non-negative number, most significant first. */\nconst significantDigits = (value: number): string => toPlainDecimal(value).replace('.', '').replace(/^0+/, '');\n\n/** Power of ten of the leading significant digit; 0 for a zero value. */\nconst decimalOrder = (value: number): number => {\n const text = toPlainDecimal(value);\n const dot = text.indexOf('.');\n const int = (dot === -1 ? text : text.slice(0, dot)).replace(/^0+/, '');\n if (int.length > 0) return int.length - 1;\n const frac = dot === -1 ? '' : text.slice(dot + 1);\n const leading = frac.search(/[1-9]/);\n return leading === -1 ? 0 : -(leading + 1);\n};\n\n// ---- tokenizer -------------------------------------------------------------\n\nconst pushLiteral = (tokens: Token[], text: string): void => {\n const last = tokens[tokens.length - 1];\n if (last?.kind === 'literal') tokens[tokens.length - 1] = { kind: 'literal', text: last.text + text };\n else tokens.push({ kind: 'literal', text });\n};\n\nconst datePartOf = (letter: string): DatePart => {\n if (letter === 'y') return 'year';\n if (letter === 'd') return 'day';\n if (letter === 'h') return 'hour';\n if (letter === 's') return 'second';\n return 'monthOrMinute';\n};\n\n/** `[Red]`, `[$€-407]`, `[hh]`, `[>100]`: everything Excel puts in brackets. */\nconst tokenizeBracket = (body: string, tokens: Token[]): boolean => {\n const elapsed = ELAPSED_RE.exec(body);\n if (elapsed !== null) {\n const letter = (elapsed[1] ?? 'h').toLowerCase();\n const part: ElapsedPart = letter === 'h' ? 'hour' : letter === 'm' ? 'minute' : 'second';\n tokens.push({ kind: 'elapsed', part, width: body.length });\n return true;\n }\n if (body.startsWith('$')) {\n // `[$<symbol>-<locale>]`: the symbol prints, the locale id only picks\n // number words and calendar names this renderer does not vary.\n const symbol = body.slice(1).split('-')[0] ?? '';\n if (symbol.length > 0) pushLiteral(tokens, symbol);\n return true;\n }\n const lower = body.toLowerCase();\n if (COLOR_NAMES.has(lower) || INDEXED_COLOR_RE.test(body)) return true;\n // Comparison sections (`[>=100]\"big\"`) and calendar modifiers (`[DBNum1]`)\n // change the value that prints, so a code carrying one is out of scope.\n return false;\n};\n\nconst MERIDIEM_LONG = 'AM/PM';\nconst MERIDIEM_SHORT = 'A/P';\n\nconst meridiemToken = (raw: string): Token => {\n const slash = raw.indexOf('/');\n return { kind: 'meridiem', am: raw.slice(0, slash), pm: raw.slice(slash + 1) };\n};\n\nconst tokenizeSection = (src: string): Token[] | undefined => {\n const tokens: Token[] = [];\n let i = 0;\n while (i < src.length) {\n const ch = src.charAt(i);\n if (ch === '\"') {\n const end = src.indexOf('\"', i + 1);\n if (end === -1) return undefined;\n pushLiteral(tokens, src.slice(i + 1, end));\n i = end + 1;\n continue;\n }\n if (ch === '\\\\') {\n pushLiteral(tokens, src.charAt(i + 1));\n i += 2;\n continue;\n }\n if (ch === '_') {\n // `_x` reserves the width of `x`; the cell shows a space there.\n pushLiteral(tokens, ' ');\n i += 2;\n continue;\n }\n if (ch === '*') {\n // `*x` repeats `x` until the column is full, so how much it prints is not\n // a property of the cell. Nothing is emitted for it.\n i += 2;\n continue;\n }\n if (ch === '[') {\n const end = src.indexOf(']', i + 1);\n if (end === -1) return undefined;\n if (!tokenizeBracket(src.slice(i + 1, end), tokens)) return undefined;\n i = end + 1;\n continue;\n }\n if (ch === '0' || ch === '#' || ch === '?') {\n tokens.push({ kind: 'digit', placeholder: ch });\n i++;\n continue;\n }\n if (ch === '.') {\n tokens.push({ kind: 'point' });\n i++;\n continue;\n }\n if (ch === ',') {\n tokens.push({ kind: 'comma' });\n i++;\n continue;\n }\n if (ch === '%') {\n tokens.push({ kind: 'percent' });\n i++;\n continue;\n }\n if (ch === '/') {\n tokens.push({ kind: 'slash' });\n i++;\n // A denominator beginning with 1–9 is a fixed integer, including zeros.\n const fixed = /^[1-9][0-9]*/.exec(src.slice(i));\n if (fixed !== null) {\n tokens.push({ kind: 'fixedDenominator', text: fixed[0] });\n i += fixed[0].length;\n }\n continue;\n }\n if (ch === '@') {\n tokens.push({ kind: 'textPlaceholder' });\n i++;\n continue;\n }\n const long = src.slice(i, i + MERIDIEM_LONG.length);\n if (long.toUpperCase() === MERIDIEM_LONG) {\n tokens.push(meridiemToken(long));\n i += MERIDIEM_LONG.length;\n continue;\n }\n const short = src.slice(i, i + MERIDIEM_SHORT.length);\n if (short.toUpperCase() === MERIDIEM_SHORT) {\n tokens.push(meridiemToken(short));\n i += MERIDIEM_SHORT.length;\n continue;\n }\n if (src.slice(i, i + 'General'.length).toLowerCase() === 'general') {\n tokens.push({ kind: 'general' });\n i += 'General'.length;\n continue;\n }\n const lower = ch.toLowerCase();\n if (lower === 'e') {\n const sign = src.charAt(i + 1);\n // A bare `e` is the era-year token, which needs a calendar this renderer\n // does not carry.\n if (sign !== '+' && sign !== '-') return undefined;\n tokens.push({ kind: 'exponent', explicitSign: sign === '+' });\n i += 2;\n continue;\n }\n if (lower === 'y' || lower === 'm' || lower === 'd' || lower === 'h' || lower === 's') {\n let width = 1;\n while (src.charAt(i + width).toLowerCase() === lower) width++;\n tokens.push({ kind: 'datePart', part: datePartOf(lower), width });\n i += width;\n continue;\n }\n // `g` (era) and `b` (Buddhist calendar) shift the calendar system.\n if (lower === 'g' || lower === 'b') return undefined;\n pushLiteral(tokens, ch);\n i++;\n }\n return tokens;\n};\n\n// ---- section parsing -------------------------------------------------------\n\nconst splitSections = (code: string): string[] | undefined => {\n const out: string[] = [];\n let start = 0;\n let i = 0;\n while (i < code.length) {\n const ch = code.charAt(i);\n if (ch === '\"') {\n const end = code.indexOf('\"', i + 1);\n if (end === -1) return undefined;\n i = end + 1;\n continue;\n }\n if (ch === '[') {\n const end = code.indexOf(']', i + 1);\n if (end === -1) return undefined;\n i = end + 1;\n continue;\n }\n if (ch === '\\\\' || ch === '_' || ch === '*') {\n i += 2;\n continue;\n }\n if (ch === ';') {\n out.push(code.slice(start, i));\n start = i + 1;\n }\n i++;\n }\n out.push(code.slice(start));\n return out;\n};\n\nconst literalFor = (token: Token): string => {\n switch (token.kind) {\n case 'literal':\n case 'fixedDenominator':\n return token.text;\n case 'percent':\n return '%';\n case 'slash':\n return '/';\n case 'point':\n return '.';\n case 'comma':\n return GROUP_SEPARATOR;\n default:\n return '';\n }\n};\n\nconst onlyCommasBetween = (tokens: readonly Token[], from: number, to: number): boolean => {\n for (let i = from + 1; i < to; i++) {\n if (tokens[i]?.kind !== 'comma') return false;\n }\n return true;\n};\n\ninterface CommaResolution {\n readonly tokens: Token[];\n readonly grouped: boolean;\n readonly scale: number;\n}\n\n/**\n * A comma means three different things depending on where it sits: thousands\n * grouping between digit placeholders, division by a thousand after the last\n * one, and a plain comma anywhere else.\n */\nconst resolveCommas = (tokens: readonly Token[]): CommaResolution => {\n const isDigit = tokens.map((t) => t.kind === 'digit');\n const firstDigit = isDigit.indexOf(true);\n const lastDigit = isDigit.lastIndexOf(true);\n const out: Token[] = [];\n let grouped = false;\n let scale = 0;\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n if (token === undefined) continue;\n if (token.kind !== 'comma') {\n out.push(token);\n continue;\n }\n if (firstDigit !== -1 && i > firstDigit && i < lastDigit) {\n grouped = true;\n continue;\n }\n if (lastDigit !== -1 && i > lastDigit && onlyCommasBetween(tokens, lastDigit, i)) {\n scale++;\n continue;\n }\n pushLiteral(out, GROUP_SEPARATOR);\n }\n return { tokens: out, grouped, scale };\n};\n\nconst placeholdersIn = (tokens: readonly Token[], from: number, to: number): DigitPlaceholder[] => {\n const out: DigitPlaceholder[] = [];\n for (let i = from; i < to; i++) {\n const token = tokens[i];\n if (token?.kind === 'digit') out.push(token.placeholder);\n }\n return out;\n};\n\nconst resolveNumberSection = (resolved: CommaResolution): NumberFormatSection | undefined => {\n const { tokens } = resolved;\n // A second decimal point or exponent splices two numeric layouts into one\n // section (`0.00\" (\"0.00\")\"`), leaving no single number to lay out.\n if (tokens.filter((t) => t.kind === 'point').length > 1) return undefined;\n if (tokens.filter((t) => t.kind === 'exponent').length > 1) return undefined;\n const pointIndex = tokens.findIndex((t) => t.kind === 'point');\n const exponentIndex = tokens.findIndex((t) => t.kind === 'exponent');\n const intEnd = pointIndex !== -1 ? pointIndex : exponentIndex !== -1 ? exponentIndex : tokens.length;\n const fracEnd = exponentIndex !== -1 ? exponentIndex : tokens.length;\n const exponentToken = exponentIndex === -1 ? undefined : tokens[exponentIndex];\n return {\n kind: 'number',\n tokens,\n grouped: resolved.grouped,\n scale: resolved.scale,\n percents: tokens.filter((t) => t.kind === 'percent').length,\n intEnd,\n intPlaceholders: placeholdersIn(tokens, 0, intEnd),\n fracPlaceholders: pointIndex === -1 ? [] : placeholdersIn(tokens, pointIndex + 1, fracEnd),\n exponentIndex,\n exponentDigits: exponentIndex === -1 ? 0 : placeholdersIn(tokens, exponentIndex + 1, tokens.length).length,\n exponentExplicitSign: exponentToken?.kind === 'exponent' ? exponentToken.explicitSign : false,\n };\n};\n\nconst digitRunStart = (tokens: readonly Token[], end: number): number => {\n let start = end;\n while (start > 0 && tokens[start - 1]?.kind === 'digit') start--;\n return start;\n};\n\n/** `# ??/??`: a slash with digit placeholders on both sides is a fraction. */\nconst resolveFractionSection = (tokens: readonly Token[]): FractionFormatSection | undefined => {\n const slashIndex = tokens.findIndex((t) => t.kind === 'slash');\n if (slashIndex < 1 || tokens[slashIndex - 1]?.kind !== 'digit') return undefined;\n\n const numeratorStart = digitRunStart(tokens, slashIndex);\n const after = tokens[slashIndex + 1];\n let denominatorEnd: number;\n let fixedDenominator = 0;\n if (after?.kind === 'digit') {\n denominatorEnd = slashIndex + 1;\n while (tokens[denominatorEnd]?.kind === 'digit') denominatorEnd++;\n } else if (after?.kind === 'fixedDenominator') {\n denominatorEnd = slashIndex + 2;\n fixedDenominator = Number(after.text);\n if (!Number.isSafeInteger(fixedDenominator) || fixedDenominator === 0) return undefined;\n } else {\n return undefined;\n }\n\n let wholeEnd = -1;\n let wholeStart = -1;\n for (let i = numeratorStart - 1; i >= 0; i--) {\n if (tokens[i]?.kind !== 'digit') continue;\n wholeEnd = i + 1;\n wholeStart = digitRunStart(tokens, wholeEnd);\n break;\n }\n\n return {\n kind: 'fraction',\n tokens,\n slashIndex,\n wholeStart,\n wholeEnd,\n numeratorStart,\n denominatorEnd,\n denominatorDigits: fixedDenominator > 0 ? 0 : placeholdersIn(tokens, slashIndex + 1, denominatorEnd).length,\n fixedDenominator,\n };\n};\n\nconst nextDateToken = (tokens: readonly Token[], index: number, step: number): DatePartToken | ElapsedToken | undefined => {\n for (let i = index + step; i >= 0 && i < tokens.length; i += step) {\n const token = tokens[i];\n if (token === undefined) return undefined;\n if (token.kind === 'datePart' || token.kind === 'elapsed') return token;\n }\n return undefined;\n};\n\nconst resolveDateSection = (tokens: readonly Token[]): DateFormatSection | undefined => {\n // `.0` right after a seconds token is fractional seconds, not a decimal point.\n const withSubseconds: Token[] = [];\n let subsecondDigits = 0;\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n if (token === undefined) continue;\n if (token.kind !== 'point') {\n withSubseconds.push(token);\n continue;\n }\n let digits = 0;\n for (let j = i + 1; j < tokens.length; j++) {\n const next = tokens[j];\n if (next?.kind !== 'digit' || next.placeholder !== '0') break;\n digits++;\n }\n const previous = withSubseconds[withSubseconds.length - 1];\n const afterSeconds = previous?.kind === 'datePart' || previous?.kind === 'elapsed' ? previous.part === 'second' : false;\n if (digits === 0 || !afterSeconds) {\n pushLiteral(withSubseconds, '.');\n continue;\n }\n withSubseconds.push({ kind: 'subsecond', digits });\n subsecondDigits = Math.max(subsecondDigits, digits);\n i += digits;\n }\n\n // Excel reads `m` as a minute next to an hour or a second, and as a month\n // everywhere else. `mmm` and wider are always month or weekday names.\n const resolved: Token[] = withSubseconds.map((token, index) => {\n if (token.kind !== 'datePart' || token.part !== 'monthOrMinute') return token;\n if (token.width >= NAME_TOKEN_WIDTH) return { kind: 'datePart', part: 'month', width: token.width };\n const previous = nextDateToken(withSubseconds, index, -1);\n const next = nextDateToken(withSubseconds, index, 1);\n const minute = previous?.part === 'hour' || next?.part === 'second';\n return { kind: 'datePart', part: minute ? 'minute' : 'month', width: token.width };\n });\n\n const elapsed = resolved.some((t) => t.kind === 'elapsed');\n const calendarPart = resolved.some(\n (t) => t.kind === 'datePart' && (t.part === 'year' || t.part === 'month' || t.part === 'day'),\n );\n // A leftover digit placeholder means the code mixes a numeric layout into a\n // date layout, and an elapsed duration has no calendar date to print.\n if (resolved.some((t) => t.kind === 'digit' || t.kind === 'exponent')) return undefined;\n if (elapsed && calendarPart) return undefined;\n\n return {\n kind: 'date',\n tokens: resolved,\n elapsed,\n calendar: calendarPart,\n hasMeridiem: resolved.some((t) => t.kind === 'meridiem'),\n subsecondDigits,\n };\n};\n\nconst parseSection = (src: string): FormatSection | undefined => {\n const tokens = tokenizeSection(src);\n if (tokens === undefined) return undefined;\n if (tokens.length === 0) return { kind: 'blank' };\n if (tokens.some((t) => t.kind === 'general')) {\n // `General` is a whole format, not a placeholder that combines with others.\n return tokens.length === 1 ? { kind: 'general' } : undefined;\n }\n const hasText = tokens.some((t) => t.kind === 'textPlaceholder');\n const hasDate = tokens.some((t) => t.kind === 'datePart' || t.kind === 'elapsed' || t.kind === 'meridiem');\n if (hasText && hasDate) return undefined;\n if (hasText) return { kind: 'text', tokens };\n if (hasDate) return resolveDateSection(tokens);\n if (tokens.every((token) => token.kind === 'literal')) {\n return { kind: 'literal', text: tokens.map(literalFor).join('') };\n }\n const resolved = resolveCommas(tokens);\n return resolveFractionSection(resolved.tokens) ?? resolveNumberSection(resolved);\n};\n\n/**\n * Distinct format codes in a workbook number in the tens while cells number in\n * the millions, so the parse is memoised. Both bounds exist because the codes\n * arrive from an untrusted `styles.xml`: a full map drops its oldest entry\n * rather than every entry, so a workbook carrying more codes than fit loses one\n * cached parse per new code instead of all of them, and a code longer than the\n * 255 characters Excel itself allows is parsed on each call rather than stored.\n */\nconst PARSE_CACHE_LIMIT = 256;\nconst MAX_CACHED_CODE_LENGTH = 255;\nconst parseCache = new Map<string, { readonly format: ParsedFormat | undefined }>();\n\nconst buildFormat = (code: string): ParsedFormat | undefined => {\n const raw = splitSections(code);\n if (raw === undefined || raw.length > MAX_SECTIONS) return undefined;\n const sections: FormatSection[] = [];\n for (const src of raw) {\n const section = parseSection(src);\n if (section === undefined) return undefined;\n sections.push(section);\n }\n return { sections };\n};\n\n/** Parse a `numFmt` format code, or `undefined` when it is out of scope. */\nexport function parseFormatCode(code: string): ParsedFormat | undefined {\n const cached = parseCache.get(code);\n if (cached !== undefined) return cached.format;\n const format = buildFormat(code);\n if (code.length > MAX_CACHED_CODE_LENGTH) return format;\n if (parseCache.size >= PARSE_CACHE_LIMIT) {\n const oldest = parseCache.keys().next().value;\n if (oldest !== undefined) parseCache.delete(oldest);\n }\n parseCache.set(code, { format });\n return format;\n}\n\n/**\n * True when the format reads as a calendar date: a date section carrying a\n * year, month or day, rather than a time of day (`h:mm`), an elapsed span\n * (`[h]:mm`) or a numeric layout. The section selected for the value decides.\n */\nexport function hasCalendarDate(format: ParsedFormat, value: number): boolean {\n const first = pickSection(format.sections, value)?.section;\n return first?.kind === 'date' && first.calendar;\n}\n\n// ---- rendering: numeric layouts -------------------------------------------\n\nconst padFor = (placeholder: DigitPlaceholder): string => {\n if (placeholder === '0') return '0';\n return placeholder === '?' ? ' ' : '';\n};\n\nconst withGrouping = (digits: string, grouped: boolean): string => {\n if (!grouped || digits.length <= GROUP_SIZE) return digits;\n const groups: string[] = [];\n for (let end = digits.length; end > 0; end -= GROUP_SIZE) {\n groups.unshift(digits.slice(Math.max(0, end - GROUP_SIZE), end));\n }\n return groups.join(GROUP_SEPARATOR);\n};\n\n/**\n * Render `[from, to)` right to left, feeding `digits` into the placeholders from\n * the low-order end. The leftmost placeholder absorbs whatever is left over,\n * which is how `#,##0` still prints all seven digits of 1,234,567.\n */\nconst renderDigitsRightToLeft = (tokens: readonly Token[], from: number, to: number, digits: string): string => {\n const leftmost = placeholderIndex(tokens, from, to);\n const pieces: string[] = [];\n let pos = digits.length;\n for (let i = to - 1; i >= from; i--) {\n const token = tokens[i];\n if (token === undefined) continue;\n if (token.kind !== 'digit') {\n pieces.push(literalFor(token));\n continue;\n }\n if (i === leftmost) {\n pieces.push(pos > 0 ? digits.slice(0, pos) : padFor(token.placeholder));\n pos = 0;\n continue;\n }\n if (pos === 0) {\n pieces.push(padFor(token.placeholder));\n continue;\n }\n let take = pos - 1;\n // A grouping separator belongs to the digit on its right.\n while (take > 0 && digits.charAt(take - 1) === GROUP_SEPARATOR) take--;\n pieces.push(digits.slice(take, pos));\n pos = take;\n }\n pieces.reverse();\n return pieces.join('');\n};\n\nconst placeholderIndex = (tokens: readonly Token[], from: number, to: number): number => {\n for (let i = from; i < to; i++) {\n if (tokens[i]?.kind === 'digit') return i;\n }\n return -1;\n};\n\n/** `#` drops trailing zeros, `?` blanks them, `0` keeps them. */\nconst renderFracDigits = (placeholders: readonly DigitPlaceholder[], digits: string): string => {\n const pieces: string[] = [];\n let trailing = true;\n for (let i = placeholders.length - 1; i >= 0; i--) {\n const placeholder = placeholders[i];\n if (placeholder === undefined) continue;\n const digit = digits.charAt(i);\n if (trailing && digit === '0' && placeholder !== '0') {\n pieces.push(placeholder === '?' ? ' ' : '');\n continue;\n }\n trailing = false;\n pieces.push(digit);\n }\n pieces.reverse();\n return pieces.join('');\n};\n\nconst assembleNumber = (section: NumberFormatSection, parts: DecimalParts, exponentText: string): string => {\n const minIntDigits = section.intPlaceholders.filter((p) => p === '0').length;\n const intDigits = withGrouping(parts.int.replace(/^0+/, '').padStart(minIntDigits, '0'), section.grouped);\n const head = renderDigitsRightToLeft(section.tokens, 0, section.intEnd, intDigits);\n // `.00` has no integer placeholder to feed the digits into, and Excel prints\n // them anyway: immediately left of the point, with nothing for a zero.\n const intText = section.intPlaceholders.length === 0 ? head + intDigits : head;\n const fracText = renderFracDigits(section.fracPlaceholders, parts.frac);\n\n const tail: string[] = [];\n let fracEmitted = false;\n for (let i = section.intEnd; i < section.tokens.length; i++) {\n const token = section.tokens[i];\n if (token === undefined) continue;\n if (token.kind === 'point') {\n tail.push(fracText.length > 0 ? '.' : '');\n continue;\n }\n if (token.kind === 'exponent') {\n tail.push(exponentText);\n continue;\n }\n if (token.kind === 'digit') {\n // Exponent digits already went into `exponentText`.\n if (section.exponentIndex !== -1 && i > section.exponentIndex) continue;\n if (!fracEmitted) {\n tail.push(fracText);\n fracEmitted = true;\n }\n continue;\n }\n tail.push(literalFor(token));\n }\n return intText + tail.join('');\n};\n\ninterface RenderedSection {\n readonly text: string;\n /** True when every digit the section printed is a zero. */\n readonly zero: boolean;\n}\n\nconst partsAreZero = (parts: DecimalParts): boolean => !/[1-9]/.test(parts.int + parts.frac);\n\nconst renderScientificSection = (section: NumberFormatSection, magnitude: number): RenderedSection => {\n const decimals = section.fracPlaceholders.length;\n // `##0.0E+0` asks for up to three integer digits, so the exponent moves in\n // steps of three: engineering notation.\n const step = Math.max(1, section.intPlaceholders.length);\n let digits = significantDigits(magnitude);\n let order = decimalOrder(magnitude);\n for (;;) {\n const exponent = magnitude === 0 ? 0 : Math.floor(order / step) * step;\n const intWidth = order - exponent + 1;\n const parts = roundParts(digits.slice(0, intWidth).padEnd(intWidth, '0') || '0', digits.slice(intWidth), decimals);\n if (parts.int.length > intWidth) {\n // Rounding pushed the mantissa to the next power of ten (9.99 became\n // 10.0 at one integer digit); step the exponent instead of widening.\n order += 1;\n digits = '1';\n continue;\n }\n const sign = exponent < 0 ? '-' : section.exponentExplicitSign ? '+' : '';\n const exponentText = `E${sign}${String(Math.abs(exponent)).padStart(section.exponentDigits, '0')}`;\n return { text: assembleNumber(section, parts, exponentText), zero: partsAreZero(parts) };\n }\n};\n\nconst renderNumberSection = (section: NumberFormatSection, magnitude: number): RenderedSection | undefined => {\n const scaled = (magnitude * PERCENT_MULTIPLIER ** section.percents) / SCALE_DIVISOR ** section.scale;\n if (!Number.isFinite(scaled)) return undefined;\n if (section.exponentIndex !== -1) return renderScientificSection(section, scaled);\n const parts = roundDecimal(scaled, section.fracPlaceholders.length);\n return { text: assembleNumber(section, parts, ''), zero: partsAreZero(parts) };\n};\n\n/**\n * Closest `p/q` with `q <= maxDenominator`. Continued-fraction convergents alone\n * are not always the closest (0.7 gives 2/3 before 5/7), so the last step also\n * weighs the best semiconvergent.\n */\nconst bestFraction = (value: number, maxDenominator: number): { numerator: number; denominator: number } => {\n let numeratorPrev = 0;\n let numerator = 1;\n let denominatorPrev = 1;\n let denominator = 0;\n let best = { numerator: Math.round(value), denominator: 1 };\n let x = value;\n for (let term = 0; term < FRACTION_MAX_TERMS; term++) {\n const a = Math.floor(x);\n const nextNumerator = a * numerator + numeratorPrev;\n const nextDenominator = a * denominator + denominatorPrev;\n if (nextDenominator > maxDenominator) {\n const steps = Math.floor((maxDenominator - denominatorPrev) / denominator);\n if (steps > 0) {\n const candidate = { numerator: steps * numerator + numeratorPrev, denominator: steps * denominator + denominatorPrev };\n if (Math.abs(value - candidate.numerator / candidate.denominator) < Math.abs(value - best.numerator / best.denominator)) {\n best = candidate;\n }\n }\n break;\n }\n numeratorPrev = numerator;\n numerator = nextNumerator;\n denominatorPrev = denominator;\n denominator = nextDenominator;\n best = { numerator, denominator };\n const remainder = x - a;\n if (remainder < FRACTION_EPSILON) break;\n x = 1 / remainder;\n }\n return best;\n};\n\nconst blankFor = (placeholder: DigitPlaceholder): string => (placeholder === '#' ? '' : ' ');\n\nconst renderDigitsLeftToRight = (tokens: readonly Token[], from: number, to: number, digits: string): string => {\n const pieces: string[] = [];\n let pos = 0;\n const lastPlaceholder = lastPlaceholderIndex(tokens, from, to);\n for (let i = from; i < to; i++) {\n const token = tokens[i];\n if (token === undefined) continue;\n if (token.kind !== 'digit') {\n pieces.push(literalFor(token));\n continue;\n }\n if (i === lastPlaceholder) {\n pieces.push(pos < digits.length ? digits.slice(pos) : padFor(token.placeholder));\n pos = digits.length;\n continue;\n }\n if (pos < digits.length) {\n pieces.push(digits.charAt(pos));\n pos++;\n continue;\n }\n pieces.push(padFor(token.placeholder));\n }\n return pieces.join('');\n};\n\nconst lastPlaceholderIndex = (tokens: readonly Token[], from: number, to: number): number => {\n for (let i = to - 1; i >= from; i--) {\n if (tokens[i]?.kind === 'digit') return i;\n }\n return -1;\n};\n\nconst blankRange = (tokens: readonly Token[], from: number, to: number): string => {\n const pieces: string[] = [];\n for (let i = from; i < to; i++) {\n const token = tokens[i];\n if (token === undefined) continue;\n pieces.push(token.kind === 'digit' ? blankFor(token.placeholder) : token.kind === 'slash' ? ' ' : literalFor(token));\n }\n return pieces.join('');\n};\n\n/** The digits a code spells the denominator out as: `16` in `# ?/16`. */\nconst fixedDenominatorText = (section: FractionFormatSection): string => {\n const token = section.tokens[section.slashIndex + 1];\n return token?.kind === 'fixedDenominator' ? token.text : '';\n};\n\n/**\n * `?` and `#` pad the denominator on the right, which is what lines the slash up\n * down a column. A `0` cannot: a pad zero on the right would multiply the\n * denominator by ten, so a run carrying one fills from the right instead.\n */\nconst denominatorText = (section: FractionFormatSection, denominator: number): string => {\n const from = section.slashIndex + 1;\n const digits = String(denominator);\n return placeholdersIn(section.tokens, from, section.denominatorEnd).includes('0')\n ? renderDigitsRightToLeft(section.tokens, from, section.denominatorEnd, digits)\n : renderDigitsLeftToRight(section.tokens, from, section.denominatorEnd, digits);\n};\n\nconst renderFractionSection = (section: FractionFormatSection, magnitude: number): RenderedSection => {\n const hasWhole = section.wholeStart !== -1;\n const maxDenominator =\n section.fixedDenominator > 0 ? section.fixedDenominator : 10 ** section.denominatorDigits - 1;\n let whole = hasWhole ? Math.floor(magnitude) : 0;\n const remainder = magnitude - whole;\n const approximation =\n section.fixedDenominator > 0\n ? { numerator: Math.round(remainder * section.fixedDenominator), denominator: section.fixedDenominator }\n : bestFraction(remainder, Math.max(1, maxDenominator));\n const denominator = approximation.denominator;\n let numerator = approximation.numerator;\n if (hasWhole && numerator === denominator && numerator !== 0) {\n whole += 1;\n numerator = 0;\n }\n\n const pieces: string[] = [];\n if (hasWhole) {\n pieces.push(renderDigitsRightToLeft(section.tokens, 0, section.wholeStart, ''));\n const wholeDigits = whole === 0 ? '' : String(whole);\n pieces.push(renderDigitsRightToLeft(section.tokens, section.wholeStart, section.wholeEnd, wholeDigits));\n pieces.push(blankRange(section.tokens, section.wholeEnd, section.numeratorStart));\n } else {\n pieces.push(renderDigitsRightToLeft(section.tokens, 0, section.numeratorStart, ''));\n }\n\n if (numerator === 0 && hasWhole) {\n // An exact whole number leaves the fraction blank, the way Excel does. A\n // spelled-out denominator goes with it: it is a literal rather than a run of\n // placeholders, so blanking only the placeholders leaves a stray `16` behind.\n pieces.push(blankRange(section.tokens, section.numeratorStart, section.slashIndex + 1));\n pieces.push(\n section.fixedDenominator > 0\n ? ' '.repeat(fixedDenominatorText(section).length)\n : blankRange(section.tokens, section.slashIndex + 1, section.denominatorEnd),\n );\n } else {\n pieces.push(renderDigitsRightToLeft(section.tokens, section.numeratorStart, section.slashIndex, String(numerator)));\n pieces.push('/');\n pieces.push(section.fixedDenominator > 0 ? fixedDenominatorText(section) : denominatorText(section, denominator));\n }\n pieces.push(renderDigitsRightToLeft(section.tokens, section.denominatorEnd, section.tokens.length, ''));\n return { text: pieces.join(''), zero: whole === 0 && numerator === 0 };\n};\n\n/**\n * Excel's `General`: the value at the 15 significant digits Excel stores, which\n * is what turns `1.1 + 2.2` into `3.3` instead of `3.3000000000000003`. How\n * many of those digits Excel shows, and where it gives up and switches to\n * scientific notation, also depends on the column width, which is not part of\n * the cell data, so every stored digit is kept and the notation switches where\n * JavaScript's own shortest round-trip form does.\n */\nconst renderGeneral = (magnitude: number): string => {\n const plain = String(Number(magnitude.toPrecision(EXCEL_SIGNIFICANT_DIGITS)));\n const exponential = /^(\\d(?:\\.\\d+)?)e([+-])(\\d+)$/.exec(plain);\n if (exponential === null) return plain;\n return `${exponential[1] ?? ''}E${exponential[2] ?? ''}${(exponential[3] ?? '').padStart(GENERAL_EXPONENT_DIGITS, '0')}`;\n};\n\n// ---- rendering: date layouts ----------------------------------------------\n\ninterface DateFields {\n readonly year: number;\n readonly month: number;\n readonly day: number;\n readonly weekday: number;\n readonly hour: number;\n readonly minute: number;\n readonly second: number;\n readonly totalSeconds: number;\n readonly subsecond: string;\n}\n\nconst twoDigits = (value: number, width: number): string => (width === 1 ? String(value) : String(value).padStart(2, '0'));\n\nconst renderDatePart = (token: DatePartToken, fields: DateFields, hasMeridiem: boolean): string => {\n switch (token.part) {\n case 'year':\n return token.width <= 2\n ? String(fields.year % 100).padStart(2, '0')\n : String(fields.year).padStart(FULL_YEAR_DIGITS, '0');\n case 'month': {\n if (token.width < NAME_TOKEN_WIDTH) return twoDigits(fields.month, token.width);\n const name = MONTH_NAMES[fields.month - 1] ?? '';\n if (token.width === NAME_TOKEN_WIDTH) return name.slice(0, NAME_TOKEN_WIDTH);\n return token.width === MONTH_FULL_WIDTH ? name : name.slice(0, 1);\n }\n case 'day': {\n if (token.width < NAME_TOKEN_WIDTH) return twoDigits(fields.day, token.width);\n const name = WEEKDAY_NAMES[fields.weekday] ?? '';\n return token.width === NAME_TOKEN_WIDTH ? name.slice(0, NAME_TOKEN_WIDTH) : name;\n }\n case 'hour': {\n const hour = hasMeridiem ? fields.hour % HOURS_PER_HALF_DAY || HOURS_PER_HALF_DAY : fields.hour;\n return twoDigits(hour, token.width);\n }\n case 'minute':\n return twoDigits(fields.minute, token.width);\n case 'second':\n return twoDigits(fields.second, token.width);\n default:\n return '';\n }\n};\n\nconst renderElapsed = (token: ElapsedToken, fields: DateFields): string => {\n const total =\n token.part === 'hour'\n ? Math.floor(fields.totalSeconds / SECONDS_PER_HOUR)\n : token.part === 'minute'\n ? Math.floor(fields.totalSeconds / SECONDS_PER_MINUTE)\n : fields.totalSeconds;\n return String(total).padStart(token.width, '0');\n};\n\n/**\n * A section can carry two fractional-second groups of different widths\n * (`[ss].000\" \"ss.0`). The serial is rounded once, at the widest, so a narrower\n * group rounds the digits that rounding already produced.\n */\nconst subsecondText = (subsecond: string, digits: number): string => {\n if (digits >= subsecond.length) return subsecond.padEnd(digits, '0');\n const kept = subsecond.slice(0, digits);\n if (subsecond.charCodeAt(digits) < FIVE_CHAR_CODE) return kept;\n const bumped = carryOne(kept);\n // Carrying out of the leading digit would have to bump the second as well,\n // which the wider group in the same section does not show.\n return bumped.length > digits ? '9'.repeat(digits) : bumped;\n};\n\nconst renderDateTokens = (section: DateFormatSection, fields: DateFields): string => {\n const pieces: string[] = [];\n for (const token of section.tokens) {\n switch (token.kind) {\n case 'datePart':\n pieces.push(renderDatePart(token, fields, section.hasMeridiem));\n break;\n case 'elapsed':\n pieces.push(renderElapsed(token, fields));\n break;\n case 'meridiem':\n pieces.push(fields.hour < HOURS_PER_HALF_DAY ? token.am : token.pm);\n break;\n case 'subsecond':\n pieces.push(`.${subsecondText(fields.subsecond, token.digits)}`);\n break;\n default:\n pieces.push(literalFor(token));\n }\n }\n return pieces.join('');\n};\n\nconst renderDateSection = (section: DateFormatSection, serial: number, epoch: ExcelEpoch): string | undefined => {\n const subDigits = Math.min(section.subsecondDigits, MAX_SUBSECOND_DIGITS);\n const subUnits = 10 ** subDigits;\n const unitsPerDay = SECONDS_PER_DAY * subUnits;\n const units = Math.round(serial * unitsPerDay);\n if (!Number.isSafeInteger(units)) return undefined;\n const totalSeconds = Math.floor(units / subUnits);\n const subsecond = String(units % subUnits).padStart(subDigits, '0');\n\n if (section.elapsed) {\n return renderDateTokens(section, {\n year: 0,\n month: 1,\n day: 1,\n weekday: 0,\n hour: Math.floor(totalSeconds / SECONDS_PER_HOUR) % HOURS_PER_DAY,\n minute: Math.floor(totalSeconds / SECONDS_PER_MINUTE) % MINUTES_PER_HOUR,\n second: totalSeconds % SECONDS_PER_MINUTE,\n totalSeconds,\n subsecond,\n });\n }\n\n const date = excelToDate(units / unitsPerDay, { epoch });\n // A serial can be a safe integer of sub-second units and still land outside\n // the range a `Date` covers, which would print NaN into every field.\n if (Number.isNaN(date.getTime())) return undefined;\n return renderDateTokens(section, {\n year: date.getUTCFullYear(),\n month: date.getUTCMonth() + 1,\n day: date.getUTCDate(),\n weekday: date.getUTCDay(),\n hour: date.getUTCHours(),\n minute: date.getUTCMinutes(),\n second: date.getUTCSeconds(),\n totalSeconds,\n subsecond,\n });\n};\n\n// ---- rendering: entry points ----------------------------------------------\n\ninterface PickedSection {\n readonly section: FormatSection;\n /** True when the caller has to supply the minus sign itself. */\n readonly signed: boolean;\n}\n\n/**\n * Excel picks the section by sign: one section covers everything, two split\n * at zero, three or four add a dedicated zero branch. Only a lone section has\n * to be handed the sign, because the others spell their own.\n */\nconst pickSection = (sections: readonly FormatSection[], value: number): PickedSection | undefined => {\n const first = sections[0];\n if (first === undefined) return undefined;\n if (sections.length === 1) return { section: first, signed: value < 0 };\n if (value < 0) {\n const negative = sections[1];\n return negative === undefined ? undefined : { section: negative, signed: false };\n }\n if (value === 0 && sections.length > 2) {\n const zero = sections[2];\n return zero === undefined ? undefined : { section: zero, signed: false };\n }\n return { section: first, signed: false };\n};\n\nconst renderSection = (section: FormatSection, magnitude: number, epoch: ExcelEpoch): RenderedSection | undefined => {\n switch (section.kind) {\n case 'literal':\n return { text: section.text, zero: true };\n case 'blank':\n return { text: '', zero: true };\n // A numeric value in a text-formatted cell falls back to General.\n case 'general':\n case 'text':\n return { text: renderGeneral(magnitude), zero: magnitude === 0 };\n case 'number':\n return renderNumberSection(section, magnitude);\n case 'fraction':\n return renderFractionSection(section, magnitude);\n case 'date': {\n const text = renderDateSection(section, magnitude, epoch);\n return text === undefined ? undefined : { text, zero: false };\n }\n }\n};\n\n/**\n * Render a numeric cell value (a plain number, or a date / duration already\n * converted to its Excel serial). `undefined` means the value has no reading\n * under this format and the caller should degrade.\n */\nexport function renderNumericValue(format: ParsedFormat, value: number, epoch: ExcelEpoch): string | undefined {\n if (!Number.isFinite(value)) return undefined;\n const picked = pickSection(format.sections, value);\n if (picked === undefined) return undefined;\n // A negative serial is not a calendar date. Excel fills the cell with `#`\n // characters, and how many depends on the column width, so there is nothing\n // to print. An elapsed span is different: it has a sign, and `picked.signed`\n // puts it in front.\n if (picked.section.kind === 'date' && !picked.section.elapsed && value < 0) return undefined;\n const rendered = renderSection(picked.section, Math.abs(value), epoch);\n if (rendered === undefined) return undefined;\n if (!picked.signed || rendered.zero) return rendered.text;\n return `-${rendered.text}`;\n}\n\n/**\n * Render a string cell value. Only the fourth section of a code applies to\n * text, plus a lone section that is itself a text layout (`@\" pcs\"`); under any\n * other code Excel prints the string unchanged.\n */\nexport function renderTextValue(format: ParsedFormat, text: string): string {\n const section =\n format.sections.length === MAX_SECTIONS\n ? format.sections[MAX_SECTIONS - 1]\n : format.sections.length === 1\n ? format.sections[0]\n : undefined;\n if (section === undefined) return text;\n if (section.kind === 'blank') return '';\n if (section.kind === 'literal' && format.sections.length === MAX_SECTIONS) return section.text;\n if (section.kind !== 'text') return text;\n return section.tokens.map((token) => (token.kind === 'textPlaceholder' ? text : literalFor(token))).join('');\n}\n","// Format-aware readers for a cell: the text Excel prints in it, and the date a\n// date-formatted serial stands for. Both need the workbook stylesheet, which is\n// why they live here rather than next to the value coercions in `src/cell/`.\n\nimport type { Cell, CellValue } from '../cell/cell.js';\nimport { cellValueAsString, isDurationValue, isErrorValue, isFormulaValue, isRichTextValue } from '../cell/cell.js';\nimport { richTextToString } from '../cell/rich-text.js';\nimport { dateToExcel, durationToExcel, excelToDate, type ExcelEpoch } from '../utils/datetime.js';\nimport type { Workbook } from '../workbook/workbook.js';\nimport { getCellNumberFormat } from './cell-style.js';\nimport {\n hasCalendarDate,\n parseFormatCode,\n renderNumericValue,\n renderTextValue,\n type ParsedFormat,\n} from './format-code.js';\n\nconst epochOf = (wb: Workbook): ExcelEpoch => (wb.date1904 ? 'mac' : 'windows');\n\nconst renderValue = (format: ParsedFormat, value: CellValue, epoch: ExcelEpoch): string | undefined => {\n if (isRichTextValue(value)) return renderTextValue(format, richTextToString(value.runs));\n if (typeof value === 'string') return renderTextValue(format, value);\n if (value instanceof Date) return renderNumericValue(format, dateToExcel(value, { epoch }), epoch);\n // A span that is not a finite number of milliseconds has no serial to put\n // through the format, and `durationToExcel` throws on one.\n if (isDurationValue(value)) {\n return Number.isFinite(value.ms) ? renderNumericValue(format, durationToExcel(value.ms), epoch) : undefined;\n }\n if (typeof value === 'number') return renderNumericValue(format, value, epoch);\n return undefined;\n};\n\nconst displayText = (code: string, value: CellValue, epoch: ExcelEpoch): string => {\n if (value === null) return '';\n // A number format never applies to a boolean or an error token: Excel prints\n // the literal `TRUE` / `FALSE` and the error code whatever the format says.\n if (typeof value === 'boolean') return value ? 'TRUE' : 'FALSE';\n if (isErrorValue(value)) return value.code;\n // An invalid Date has no serial either, and the `cellValueAsString` fallback\n // would throw on it rather than degrade, so it reads as its own string form.\n if (value instanceof Date && Number.isNaN(value.getTime())) return String(value);\n if (isFormulaValue(value)) {\n if (value.cachedValue === undefined) return '';\n if (value.cachedValueType === 'error') return String(value.cachedValue);\n return displayText(code, value.cachedValue, epoch);\n }\n const format = parseFormatCode(code);\n if (format === undefined) return cellValueAsString(value);\n return renderValue(format, value, epoch) ?? cellValueAsString(value);\n};\n\n/**\n * The text Excel prints in `c`: the cell's value put through the number format\n * its style points at.\n *\n * This is not a shorter `cellValueAsString`. That one takes a `CellValue` and\n * answers \"what is this value in JavaScript terms\", so it never sees the\n * stylesheet and cannot know that `0.5` is a percentage or that `45365` is a\n * date. This one takes the workbook and the cell, resolves the cell's `numFmt`,\n * and answers \"what would somebody looking at this file in Excel read\". Pick\n * `cellValueAsString` when you want the value and this when you want the text:\n * writing a sheet out as CSV, rendering it as HTML, diffing two workbooks by\n * what they show, or logging a cell for a human. Choosing wrong fails quietly,\n * which is why both say so.\n *\n * Covered:\n *\n * - `General`, at the 15 significant digits Excel stores. This is what turns\n * `=1.1+2.2` into `3.3` rather than `3.3000000000000003`.\n * - Every code in `BUILTIN_FORMATS`, including the accounting codes,\n * scientific notation and the two fraction codes. The one exception is that\n * catalogue's entry for numFmtId 44, whose stored form is missing the `;`\n * section separators Excel's own accounting code carries, so it reads as a\n * text layout.\n * - Custom numeric codes: `0` `#` `?` digit placeholders, thousands grouping,\n * trailing commas that divide by a thousand, `%`, `E+`/`E-` (including the\n * engineering step `##0.0E+0`), `?/?` fractions with a placeholder or a\n * spelled-out denominator, quoted and `\\`-escaped literals, `_x` width\n * reservations, currency symbols, and colour codes (which change nothing\n * about the text).\n * - The positive / negative / zero / text sections of a multi-section code. A\n * lone section takes the minus sign in front of it; a value that rounds to\n * zero prints without one.\n * - Dates and times: `y` `m` `d` `h` `s` runs, `mmm` / `mmmm` month names,\n * `ddd` / `dddd` weekday names, `AM/PM` and `A/P`, fractional seconds, and\n * the elapsed forms `[h]` `[mm]` `[ss]`.\n * - Booleans as `TRUE` / `FALSE`, error cells as their token, rich text as its\n * runs joined, a formula cell from the value Excel cached for it, and an\n * empty cell as `''`.\n *\n * Not covered, and the cell falls back to `cellValueAsString` so the reading is\n * a plain coercion rather than a guess:\n *\n * - Comparison sections (`[>=100]\"over\";[<0]\"under\";0`).\n * - A section splicing two numeric layouts together (`0.00\" (\"0.00\")\"`).\n * - Calendar and numbering modifiers: era tokens (`g`, `e`, `b`) and bracket\n * groups such as `[DBNum1]` that replace the digits themselves.\n * - More than four sections, or an unterminated `\"` or `[`.\n *\n * Three more places where the text is a judgement call, because Excel's own\n * answer is not recoverable from the cell:\n *\n * - `*x` repeats `x` until the column is full, so nothing is printed for it.\n * - Month and weekday names come out in English; a `[$-409]`-style locale tag\n * is read for its currency symbol and otherwise ignored.\n * - How wide the column is decides how many digits `General` shows and when it\n * gives up and switches to scientific notation. Every stored digit is kept.\n *\n * A `Date` cell value is converted to its serial and run through the format, so\n * it reads as a date only if the cell carries a date format. That is the same\n * rule the file itself follows: the worksheet stores a serial and the style\n * decides what it means. Use `setCellAsDate` on the write side.\n */\nexport function getCellDisplayText(wb: Workbook, c: Cell): string {\n return displayText(getCellNumberFormat(wb, c), c.value, epochOf(wb));\n}\n\n/**\n * The `Date` a date-formatted cell stands for, or `undefined` when the cell has\n * no date reading.\n *\n * Excel stores a date as a plain number of days since the workbook epoch, so\n * nothing in a loaded cell's value distinguishes `45365` the date from `45365`\n * the count: the cell's number format is the only evidence, and\n * `cellValueAsDate` deliberately does not consult it. This composes the three\n * steps that reading one otherwise takes, `getCellNumberFormat` then the\n * format's own reading then `excelToDate` with the epoch from `wb.date1904`,\n * into the call that reading a foreign workbook actually needs.\n *\n * - A `Date` value passes through, formatted or not.\n * - A number needs a format that names a day: a year, month or day part.\n * Without one it is a count, and the answer is `undefined`.\n * - A formula cell is read from the value Excel cached for it.\n * - A time-of-day format (`h:mm`) names a moment inside a day but not which\n * day, and an elapsed-time format (`[h]:mm`) measures a span rather than\n * naming a moment, so neither has a date reading. Neither does a `duration`\n * value: its `ms` is already the span.\n * - The format is read by the parser {@link getCellDisplayText} renders with,\n * so the two agree on what any one cell is. A code outside the subset that\n * one documents has no date reading here either.\n *\n * The returned `Date` is built in UTC, which is how `excelToDate` and\n * `dateToExcel` read every serial in this library. Use `getUTCFullYear` and\n * friends, or the local-time accessors will shift the day for anybody east or\n * west of UTC.\n */\nexport function getCellDate(wb: Workbook, c: Cell): Date | undefined {\n const value = isFormulaValue(c.value) ? c.value.cachedValue : c.value;\n if (value instanceof Date) return value;\n if (typeof value !== 'number' || !Number.isFinite(value)) return undefined;\n const format = parseFormatCode(getCellNumberFormat(wb, c));\n if (format === undefined || !hasCalendarDate(format, value)) return undefined;\n const date = excelToDate(value, { epoch: epochOf(wb) });\n // A serial far outside the range a `Date` covers has no reading to hand back.\n return Number.isNaN(date.getTime()) ? undefined : date;\n}\n"],"mappings":"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"}