@ryuzaki13/react-foundation-lib 2.33.0 → 2.34.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/analytical-table/index.js +1 -1
- package/dist/chunks/{formatters-CMfD97RB.js → formatters-4P9iq3wB.js} +384 -377
- package/dist/chunks/formatters-4P9iq3wB.js.map +1 -0
- package/dist/chunks/{validate-rivmPJyV.js → validate-Drrm-CCz.js} +177 -168
- package/dist/chunks/validate-Drrm-CCz.js.map +1 -0
- package/dist/error-report/index.js +1 -1
- package/dist/excel/index.js +114 -112
- package/dist/excel/index.js.map +1 -1
- package/dist/excel/tableExport.d.ts.map +1 -1
- package/dist/formatters/index.js +3 -3
- package/dist/formatters/number/formatNumber.d.ts +2 -2
- package/dist/formatters/number/formatNumber.d.ts.map +1 -1
- package/dist/formatters/number/index.d.ts +1 -0
- package/dist/formatters/number/index.d.ts.map +1 -1
- package/dist/formatters/number/numberFormatConstants.d.ts +5 -0
- package/dist/formatters/number/numberFormatConstants.d.ts.map +1 -1
- package/dist/formatters/number/numberPresetNameConstants.d.ts +1 -0
- package/dist/formatters/number/numberPresetNameConstants.d.ts.map +1 -1
- package/dist/formatters/number/presets.d.ts +2 -1
- package/dist/formatters/number/presets.d.ts.map +1 -1
- package/dist/formatters/number/types.d.ts +3 -1
- package/dist/formatters/number/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/excel/README.mdx +12 -0
- package/src/formatters/number/README.mdx +41 -7
- package/dist/chunks/formatters-CMfD97RB.js.map +0 -1
- package/dist/chunks/validate-rivmPJyV.js.map +0 -1
package/dist/excel/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/excel/excelWorkbookConstants.ts","../../src/excel/excel.ts","../../src/excel/matrixWorkbook.ts","../../src/excel/tableExport.ts"],"sourcesContent":["/** Табличный и матричный writer одинаково отклоняют книгу без листов. */\nexport const EXCEL_WORKBOOK_EMPTY_MESSAGE = \"Для формирования Excel-книги нужен минимум один лист\";\n\n/** Адрес колонки использует латинский алфавит и одинаков в обоих видах книги. */\nexport const EXCEL_COLUMN_ALPHABET_LENGTH = 26;\nexport const EXCEL_COLUMN_FIRST_CHARACTER_CODE = 65;\n","import writeXlsxFile, { type Cell, type CellObject, type Feature, type Sheet, type SheetData } from \"write-excel-file/browser\";\n\nimport { parseDate } from \"../formatters/date\";\nimport { type State } from \"../types\";\n\nimport { EXCEL_COLUMN_ALPHABET_LENGTH, EXCEL_COLUMN_FIRST_CHARACTER_CODE, EXCEL_WORKBOOK_EMPTY_MESSAGE } from \"./excelWorkbookConstants\";\n\nexport type ExcelColumn = {\n\tid: string;\n\theader: string;\n\twidth?: number;\n\ttype?: StringConstructor | NumberConstructor | DateConstructor | BooleanConstructor;\n\tformat?: string;\n};\n\nexport type ExcelRow = Record<string, unknown>;\n\nexport type ExcelCellStyle = Omit<CellObject, \"value\" | \"type\" | \"format\">;\n\nexport type DownloadExcelFileArgs = {\n\tfileName: string;\n\tcolumns: ExcelColumn[];\n\trows: ExcelRow[];\n\tautoFilter?: boolean;\n\tgetCellStyle?: (args: { row: ExcelRow; column: ExcelColumn; rowIndex: number; columnIndex: number }) => ExcelCellStyle | undefined;\n};\n\n/** Описание одного табличного листа внутри Excel-книги. */\nexport type ExcelWorkbookSheet = Omit<DownloadExcelFileArgs, \"fileName\"> & {\n\t/** Желаемое имя листа; writer нормализует ограничения формата и конфликты имён. */\n\tname: string;\n};\n\n/** Аргументы формирования Excel-книги с одним или несколькими табличными листами. */\nexport type DownloadExcelWorkbookArgs = {\n\t/** Имя скачиваемого `.xlsx` файла. */\n\tfileName: string;\n\t/** Листы книги в порядке отображения в Excel. */\n\tsheets: ExcelWorkbookSheet[];\n};\n\ntype BrowserExcelFileContent = File | Blob | ArrayBuffer;\n\nconst VALUE_STATE_TEXT_COLORS: Partial<Record<State, string>> = {\n\tinformation: \"#2563EB\",\n\tsuccess: \"#107C10\",\n\twarning: \"#B7791F\",\n\terror: \"#C50F1F\"\n};\n\nconst HEADER_CELL_STYLE = {\n\tfontWeight: \"bold\",\n\tbottomBorderStyle: \"thin\",\n\tbottomBorderColor: \"#D9D9D9\"\n} satisfies ExcelCellStyle;\n\nconst EXCEL_SHEET_NAME_MAX_LENGTH = 31;\nconst EXCEL_SHEET_NAME_INVALID_CHARACTERS = /[\\u0000-\\u001f[\\]/\\\\:*?]+/g;\nconst EXCEL_SHEET_NAME_EDGE_APOSTROPHES = /^'+|'+$/g;\nconst EXCEL_SHEET_NAME_WHITESPACE = /\\s+/g;\n\n/**\n * Приводит общий value-state проекта к базовому Excel-стилю.\n *\n * Helper живет в shared Excel-слое, чтобы analytical/detail экспорт не\n * дублировали палитру статусов и одинаково подсвечивали warning/error/success.\n */\nexport function resolveExcelCellStyleFromState(state: State | undefined): ExcelCellStyle | undefined {\n\tconst textColor = state ? VALUE_STATE_TEXT_COLORS[state] : undefined;\n\treturn textColor ? { textColor } : undefined;\n}\n\n/**\n * Переводит zero-based индекс колонки в Excel-адрес (`0 -> A`, `27 -> AB`).\n * Нужен для XML-диапазонов, потому что `write-excel-file` не предоставляет\n * отдельного API для построения ссылок вида `A1:C10`.\n */\nfunction numberToColumnName(index: number): string {\n\tlet value = index + 1;\n\tlet out = \"\";\n\n\twhile (value > 0) {\n\t\tconst remainder = (value - 1) % EXCEL_COLUMN_ALPHABET_LENGTH;\n\t\tout = String.fromCharCode(EXCEL_COLUMN_FIRST_CHARACTER_CODE + remainder) + out;\n\t\tvalue = Math.floor((value - 1) / EXCEL_COLUMN_ALPHABET_LENGTH);\n\t}\n\n\treturn out;\n}\n\n/**\n * Строит диапазон автофильтра для всей выгруженной таблицы.\n *\n * Возвращает `undefined` для пустой сетки, чтобы не вставлять в xlsx\n * невалидный `<autoFilter>` без реального диапазона.\n */\nexport function buildExcelAutoFilterRef(columnCount: number, rowCount: number): string | undefined {\n\tif (columnCount <= 0 || rowCount <= 0) return undefined;\n\n\treturn `A1:${numberToColumnName(columnCount - 1)}${rowCount}`;\n}\n\n/**\n * Добавляет autoFilter через feature-transform `write-excel-file`.\n *\n * Библиотека умеет трансформировать XML листа, но не имеет высокоуровневого\n * параметра `autoFilter`, поэтому здесь изолирован низкоуровневый OpenXML-хук.\n */\nfunction createAutoFilterFeature<FileContent>(refs: readonly (string | undefined)[]): Feature<FileContent> | undefined {\n\tif (!refs.some(Boolean)) return undefined;\n\n\treturn {\n\t\tfiles: {\n\t\t\ttransform: {\n\t\t\t\t\"xl/worksheets/sheet{id}.xml\": {\n\t\t\t\t\ttransform: (content, _options, properties) => {\n\t\t\t\t\t\tconst ref = refs[properties.sheetIndex];\n\t\t\t\t\t\treturn ref ? content.replace(\"</sheetData>\", `</sheetData><autoFilter ref=\"${ref}\"/>`) : content;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Нормализует имена листов по ограничениям Excel и делает их уникальными.\n *\n * Runtime-заголовки могут содержать запрещённые символы, превышать 31 знак или\n * совпадать между несколькими представлениями одной конфигурации. Нормализация\n * выполняется централизованно, чтобы все consumers получали открываемую книгу.\n */\nexport function resolveExcelSheetNames(names: readonly string[]): string[] {\n\tconst usedNames = new Set<string>();\n\tconst resolvedNames: string[] = [];\n\n\tfor (let index = 0; index < names.length; index += 1) {\n\t\tconst fallbackName = `Лист ${index + 1}`;\n\t\tconst normalizedName = names[index]\n\t\t\t?.replace(EXCEL_SHEET_NAME_INVALID_CHARACTERS, \" \")\n\t\t\t.replace(EXCEL_SHEET_NAME_WHITESPACE, \" \")\n\t\t\t.trim()\n\t\t\t.replace(EXCEL_SHEET_NAME_EDGE_APOSTROPHES, \"\")\n\t\t\t.trim();\n\t\tconst baseName = normalizedName || fallbackName;\n\t\tlet resolvedName = baseName.slice(0, EXCEL_SHEET_NAME_MAX_LENGTH);\n\t\tlet duplicateIndex = 2;\n\n\t\twhile (usedNames.has(resolvedName.toLocaleLowerCase())) {\n\t\t\tconst suffix = ` (${duplicateIndex})`;\n\t\t\tresolvedName = `${baseName.slice(0, EXCEL_SHEET_NAME_MAX_LENGTH - suffix.length)}${suffix}`;\n\t\t\tduplicateIndex += 1;\n\t\t}\n\n\t\tusedNames.add(resolvedName.toLocaleLowerCase());\n\t\tresolvedNames.push(resolvedName);\n\t}\n\n\treturn resolvedNames;\n}\n\n/**\n * Приводит входное значение к типу Excel-ячейки.\n *\n * Важный смысл: если колонка числовая, в файл должен попасть настоящий Number,\n * а не уже отформатированная строка. Тогда Excel сможет применять `format`.\n */\nfunction normalizeCellValue(value: unknown, type: ExcelColumn[\"type\"]) {\n\tif (value == null || value === \"\") return undefined;\n\n\tif (type === Number) {\n\t\tconst numberValue = typeof value === \"number\" ? value : Number(value);\n\t\treturn Number.isFinite(numberValue) ? numberValue : undefined;\n\t}\n\n\tif (type === String) return String(value);\n\tif (type === Boolean) return Boolean(value);\n\tif (type === Date) return value instanceof Date ? value : (parseDate(value) ?? undefined);\n\n\treturn value as CellObject[\"value\"];\n}\n\n/**\n * Собирает SheetData для `write-excel-file`.\n *\n * Функция намеренно не знает о бизнес-сущностях: ей передают уже готовые\n * колонки/строки и необязательный callback стилей конкретных ячеек.\n */\nexport function buildExcelSheetData(args: Omit<DownloadExcelFileArgs, \"fileName\" | \"autoFilter\">): SheetData {\n\tconst headerRow: Cell[] = args.columns.map((column) => ({\n\t\ttype: String,\n\t\tvalue: column.header,\n\t\t...HEADER_CELL_STYLE\n\t}));\n\n\tconst sheetRows: SheetData = [headerRow];\n\n\tfor (let rowIndex = 0; rowIndex < args.rows.length; rowIndex++) {\n\t\tconst row = args.rows[rowIndex];\n\t\tconst sheetRow: Cell[] = [];\n\n\t\tfor (let columnIndex = 0; columnIndex < args.columns.length; columnIndex++) {\n\t\t\tconst column = args.columns[columnIndex];\n\t\t\tconst value = normalizeCellValue(row[column.id], column.type);\n\t\t\tconst style = args.getCellStyle?.({ row, column, rowIndex, columnIndex });\n\n\t\t\tsheetRow.push({\n\t\t\t\tvalue,\n\t\t\t\ttype: column.type,\n\t\t\t\tformat: column.format,\n\t\t\t\t...style\n\t\t\t});\n\t\t}\n\n\t\tsheetRows.push(sheetRow);\n\t}\n\n\treturn sheetRows;\n}\n\n/**\n * Формирует и скачивает Excel-книгу с независимыми табличными листами.\n *\n * Каждый лист получает собственные ширины колонок, стили ячеек и диапазон\n * автофильтра. Доменная подготовка колонок и строк остаётся у вызывающей стороны.\n */\nexport async function downloadExcelWorkbook(args: DownloadExcelWorkbookArgs): Promise<void> {\n\tif (args.sheets.length === 0) {\n\t\tthrow new Error(EXCEL_WORKBOOK_EMPTY_MESSAGE);\n\t}\n\n\tconst sheetNames = resolveExcelSheetNames(args.sheets.map((sheet) => sheet.name));\n\tconst autoFilterRefs: Array<string | undefined> = [];\n\tconst sheets: Sheet<BrowserExcelFileContent>[] = args.sheets.map((sheet, index) => {\n\t\tconst data = buildExcelSheetData(sheet);\n\t\tautoFilterRefs.push(sheet.autoFilter ? buildExcelAutoFilterRef(sheet.columns.length, data.length) : undefined);\n\n\t\treturn {\n\t\t\tdata,\n\t\t\tsheet: sheetNames[index],\n\t\t\tcolumns: sheet.columns.map((column) => ({\n\t\t\t\twidth: column.width\n\t\t\t}))\n\t\t};\n\t});\n\tconst autoFilterFeature = createAutoFilterFeature<BrowserExcelFileContent>(autoFilterRefs);\n\n\tawait writeXlsxFile(sheets, {\n\t\tfeatures: autoFilterFeature ? [autoFilterFeature] : undefined\n\t}).toFile(args.fileName);\n}\n\n/**\n * Формирует и скачивает `.xlsx` в браузере.\n *\n * Это публичная generic-точка shared-слоя: она отвечает только за Excel-файл,\n * а подготовка доменных данных остаётся на вызывающей стороне.\n */\nexport async function downloadExcelFile(args: DownloadExcelFileArgs): Promise<void> {\n\tawait downloadExcelWorkbook({\n\t\tfileName: args.fileName,\n\t\tsheets: [\n\t\t\t{\n\t\t\t\tname: \"Sheet1\",\n\t\t\t\tcolumns: args.columns,\n\t\t\t\trows: args.rows,\n\t\t\t\tautoFilter: args.autoFilter,\n\t\t\t\tgetCellStyle: args.getCellStyle\n\t\t\t}\n\t\t]\n\t});\n}\n","import writeXlsxFile, { type Cell, type Feature, type Sheet } from \"write-excel-file/browser\";\n\nimport { downloadFileFromBlob } from \"../dom\";\nimport { escapeXmlValue } from \"../xml\";\n\nimport { resolveExcelSheetNames } from \"./excel\";\nimport { EXCEL_COLUMN_ALPHABET_LENGTH, EXCEL_COLUMN_FIRST_CHARACTER_CODE, EXCEL_WORKBOOK_EMPTY_MESSAGE } from \"./excelWorkbookConstants\";\n\n// XML-имена согласованы между типами допустимых элементов и их формированием.\nconst EXCEL_HEADER_FOOTER_ELEMENT = \"headerFooter\";\nconst EXCEL_COLUMN_BREAKS_ELEMENT = \"colBreaks\";\nconst EXCEL_ROW_BREAKS_ELEMENT = \"rowBreaks\";\nconst EXCEL_DEFINED_NAMES_END_TAG = \"</definedNames>\";\n\ntype BrowserExcelFileContent = File | Blob | ArrayBuffer;\n\n/** Одна строка произвольной Excel-матрицы. Объединения задаются стилями первой ячейки диапазона. */\nexport type ExcelMatrixRow = readonly Cell[];\n\n/** Поля задаются в дюймах, как в OpenXML и диалоге параметров страницы Excel. */\nexport type ExcelPrintMargins = {\n\treadonly left: number;\n\treadonly right: number;\n\treadonly top: number;\n\treadonly bottom: number;\n\treadonly header: number;\n\treadonly footer: number;\n};\n\n/** Видимый колонтитул не принимает raw Excel-коды, чтобы текст не мог случайно изменить разметку секций. */\nexport type ExcelPrintHeaderFooter = {\n\treadonly left?: string;\n\treadonly center?: string;\n\treadonly right?: string;\n\treadonly includePageNumber?: boolean;\n};\n\n/** One-based прямоугольник печати соответствует координатам строк и столбцов Excel. */\nexport type ExcelPrintArea = {\n\treadonly firstRow: number;\n\treadonly lastRow: number;\n\treadonly firstColumn: number;\n\treadonly lastColumn: number;\n};\n\n/**\n * Печатный контракт одного листа.\n *\n * `columnBreaksAfter` и `rowBreaksAfter` используют one-based координату\n * последней ячейки страницы. Явная модель не позволяет consumer перепутать\n * индекс массива с адресом Excel и разрезать составной блок на печати.\n */\nexport type ExcelPrintSetup = {\n\treadonly orientation: \"portrait\" | \"landscape\";\n\treadonly paperSize?: keyof typeof PAPER_SIZE;\n\treadonly fitToWidthPages?: number;\n\treadonly fitToHeightPages?: number;\n\treadonly pageOrder?: \"downThenOver\" | \"overThenDown\";\n\treadonly margins?: ExcelPrintMargins;\n\treadonly repeatRows?: readonly [firstRow: number, lastRow: number];\n\treadonly repeatColumns?: readonly [firstColumn: number, lastColumn: number];\n\treadonly printArea?: ExcelPrintArea;\n\treadonly columnBreaksAfter?: readonly number[];\n\treadonly rowBreaksAfter?: readonly number[];\n\treadonly header?: ExcelPrintHeaderFooter;\n\treadonly footer?: ExcelPrintHeaderFooter;\n};\n\n/** Произвольный лист сохраняет готовую матрицу и не навязывает табличную строку заголовков. */\nexport type ExcelMatrixWorkbookSheet = {\n\treadonly name: string;\n\treadonly rows: readonly ExcelMatrixRow[];\n\treadonly columns?: readonly { readonly width?: number }[];\n\treadonly showGridLines?: boolean;\n\treadonly zoomScale?: number;\n\treadonly print?: ExcelPrintSetup;\n};\n\n/**\n * Базовый шрифт стиля Normal задаёт метрику символьной ширины столбцов Excel.\n *\n * Шрифт отдельных ячеек может отличаться: эта настройка нужна прежде всего\n * для воспроизводимого преобразования `columns[].width` в экранные пиксели.\n */\nexport type ExcelMatrixWorkbookDefaultFont = {\n\treadonly fontFamily: string;\n\treadonly fontSize: number;\n};\n\n/** Аргументы generic-книги, пригодной как для скачивания, так и для file validation. */\nexport type ExcelMatrixWorkbookArgs = {\n\treadonly defaultFont?: ExcelMatrixWorkbookDefaultFont;\n\treadonly sheets: readonly ExcelMatrixWorkbookSheet[];\n};\n\nconst DEFAULT_PRINT_MARGINS = {\n\tleft: 0.2,\n\tright: 0.2,\n\ttop: 0.25,\n\tbottom: 0.25,\n\theader: 0.1,\n\tfooter: 0.1\n} as const satisfies ExcelPrintMargins;\n\nconst PAPER_SIZE = { a4: 9, a3: 8 } as const;\nconst DEFAULT_PAPER_SIZE: keyof typeof PAPER_SIZE = \"a4\";\n// Сохраняет прежнюю верхнюю границу индекса в XML ручного разрыва страницы.\nconst PAGE_BREAK_MAX_INDEX = 16383;\n\nfunction escapeHeaderFooterText(value: string): string {\n\treturn escapeXmlValue(value.replaceAll(\"&\", \"&&\"));\n}\n\nfunction numberToColumnName(index: number): string {\n\tlet value = index;\n\tlet result = \"\";\n\twhile (value > 0) {\n\t\tconst remainder = (value - 1) % EXCEL_COLUMN_ALPHABET_LENGTH;\n\t\tresult = String.fromCharCode(EXCEL_COLUMN_FIRST_CHARACTER_CODE + remainder) + result;\n\t\tvalue = Math.floor((value - 1) / EXCEL_COLUMN_ALPHABET_LENGTH);\n\t}\n\treturn result;\n}\n\nfunction assertPositiveInteger(value: number, name: string): void {\n\tif (!Number.isInteger(value) || value <= 0) throw new Error(`${name} должен быть положительным целым числом`);\n}\n\nfunction assertNonnegativeInteger(value: number, name: string): void {\n\tif (!Number.isInteger(value) || value < 0) throw new Error(`${name} должен быть целым неотрицательным числом`);\n}\n\nfunction validateRange(range: readonly [number, number], name: string): void {\n\tassertPositiveInteger(range[0], `${name}: начало`);\n\tassertPositiveInteger(range[1], `${name}: конец`);\n\tif (range[0] > range[1]) throw new Error(`${name}: начало не может быть больше конца`);\n}\n\nfunction validatePrintSetup(print: ExcelPrintSetup): void {\n\t// В OpenXML ноль означает автоматическое число страниц по соответствующей оси.\n\tif (print.fitToWidthPages !== undefined) assertNonnegativeInteger(print.fitToWidthPages, \"fitToWidthPages\");\n\tif (print.fitToHeightPages !== undefined) assertNonnegativeInteger(print.fitToHeightPages, \"fitToHeightPages\");\n\tif (print.repeatRows) validateRange(print.repeatRows, \"repeatRows\");\n\tif (print.repeatColumns) validateRange(print.repeatColumns, \"repeatColumns\");\n\tfor (const value of print.columnBreaksAfter ?? []) assertPositiveInteger(value, \"columnBreaksAfter\");\n\tfor (const value of print.rowBreaksAfter ?? []) assertPositiveInteger(value, \"rowBreaksAfter\");\n\tif (print.printArea) {\n\t\tassertPositiveInteger(print.printArea.firstRow, \"printArea.firstRow\");\n\t\tassertPositiveInteger(print.printArea.lastRow, \"printArea.lastRow\");\n\t\tassertPositiveInteger(print.printArea.firstColumn, \"printArea.firstColumn\");\n\t\tassertPositiveInteger(print.printArea.lastColumn, \"printArea.lastColumn\");\n\t\tif (print.printArea.firstRow > print.printArea.lastRow || print.printArea.firstColumn > print.printArea.lastColumn) {\n\t\t\tthrow new Error(\"printArea должен задавать непустой прямоугольник\");\n\t\t}\n\t}\n}\n\nfunction buildHeaderFooterXml(\n\ttagName: typeof EXCEL_HEADER_FOOTER_ELEMENT,\n\theader: ExcelPrintHeaderFooter | undefined,\n\tfooter: ExcelPrintHeaderFooter | undefined\n): string {\n\tif (!header && !footer) return \"\";\n\tconst buildSection = (value: ExcelPrintHeaderFooter | undefined) => {\n\t\tif (!value) return \"\";\n\t\tconst content = [\n\t\t\tvalue.left ? `&L${escapeHeaderFooterText(value.left)}` : \"\",\n\t\t\tvalue.center ? `&C${escapeHeaderFooterText(value.center)}` : \"\",\n\t\t\tvalue.right ? `&R${escapeHeaderFooterText(value.right)}` : \"\",\n\t\t\tvalue.includePageNumber ? \"&RСтраница &P из &N\" : \"\"\n\t\t].join(\"\");\n\t\treturn content;\n\t};\n\tconst oddHeader = buildSection(header);\n\tconst oddFooter = buildSection(footer);\n\treturn `<${tagName}>${oddHeader ? `<oddHeader>${oddHeader}</oddHeader>` : \"\"}${oddFooter ? `<oddFooter>${oddFooter}</oddFooter>` : \"\"}</${tagName}>`;\n}\n\nfunction buildBreaksXml(\n\ttagName: typeof EXCEL_COLUMN_BREAKS_ELEMENT | typeof EXCEL_ROW_BREAKS_ELEMENT,\n\tvalues: readonly number[] | undefined\n): string {\n\tif (!values || values.length === 0) return \"\";\n\tconst uniqueValues = [...new Set(values)].sort((left, right) => left - right);\n\treturn `<${tagName} count=\"${uniqueValues.length}\" manualBreakCount=\"${uniqueValues.length}\">${uniqueValues\n\t\t.map((value) => `<brk id=\"${value}\" min=\"0\" max=\"${PAGE_BREAK_MAX_INDEX}\" man=\"1\"/>`)\n\t\t.join(\"\")}</${tagName}>`;\n}\n\nfunction applyWorksheetPrintSetup(content: string, print: ExcelPrintSetup): string {\n\tconst margins = print.margins ?? DEFAULT_PRINT_MARGINS;\n\tconst fitToPage = print.fitToWidthPages !== undefined || print.fitToHeightPages !== undefined;\n\tconst sheetProperties = fitToPage ? '<sheetPr><pageSetUpPr fitToPage=\"1\" autoPageBreaks=\"0\"/></sheetPr>' : \"\";\n\tconst result = sheetProperties ? content.replace(\"<sheetViews\", `${sheetProperties}<sheetViews`) : content;\n\tconst pageMargins = `<pageMargins left=\"${margins.left}\" right=\"${margins.right}\" top=\"${margins.top}\" bottom=\"${margins.bottom}\" header=\"${margins.header}\" footer=\"${margins.footer}\"/>`;\n\tconst pageSetupAttributes = [\n\t\t`paperSize=\"${PAPER_SIZE[print.paperSize ?? DEFAULT_PAPER_SIZE]}\"`,\n\t\t`orientation=\"${print.orientation}\"`,\n\t\tprint.fitToWidthPages !== undefined ? `fitToWidth=\"${print.fitToWidthPages}\"` : \"\",\n\t\tprint.fitToHeightPages !== undefined ? `fitToHeight=\"${print.fitToHeightPages}\"` : \"\",\n\t\tprint.pageOrder ? `pageOrder=\"${print.pageOrder}\"` : \"\",\n\t\t'usePrinterDefaults=\"0\"'\n\t]\n\t\t.filter(Boolean)\n\t\t.join(\" \");\n\tconst additions = [\n\t\tpageMargins,\n\t\t`<pageSetup ${pageSetupAttributes}/>`,\n\t\tbuildHeaderFooterXml(EXCEL_HEADER_FOOTER_ELEMENT, print.header, print.footer),\n\t\tbuildBreaksXml(EXCEL_ROW_BREAKS_ELEMENT, print.rowBreaksAfter),\n\t\tbuildBreaksXml(EXCEL_COLUMN_BREAKS_ELEMENT, print.columnBreaksAfter)\n\t].join(\"\");\n\tconst drawingIndex = result.indexOf(\"<drawing\");\n\treturn drawingIndex >= 0\n\t\t? `${result.slice(0, drawingIndex)}${additions}${result.slice(drawingIndex)}`\n\t\t: result.replace(\"</worksheet>\", `${additions}</worksheet>`);\n}\n\nfunction quoteFormulaSheetName(name: string): string {\n\treturn `'${name.replaceAll(\"'\", \"''\")}'`;\n}\n\nfunction buildDefinedNames(sheetNames: readonly string[], sheets: readonly ExcelMatrixWorkbookSheet[]): string {\n\tconst definitions: string[] = [];\n\tfor (let sheetIndex = 0; sheetIndex < sheets.length; sheetIndex += 1) {\n\t\tconst print = sheets[sheetIndex]?.print;\n\t\tif (!print) continue;\n\t\tconst sheetName = quoteFormulaSheetName(sheetNames[sheetIndex] ?? `Лист ${sheetIndex + 1}`);\n\t\tconst titles = [\n\t\t\tprint.repeatRows ? `${sheetName}!$${print.repeatRows[0]}:$${print.repeatRows[1]}` : \"\",\n\t\t\tprint.repeatColumns\n\t\t\t\t? `${sheetName}!$${numberToColumnName(print.repeatColumns[0])}:$${numberToColumnName(print.repeatColumns[1])}`\n\t\t\t\t: \"\"\n\t\t]\n\t\t\t.filter(Boolean)\n\t\t\t.join(\",\");\n\t\tif (titles) {\n\t\t\tdefinitions.push(`<definedName name=\"_xlnm.Print_Titles\" localSheetId=\"${sheetIndex}\">${escapeXmlValue(titles)}</definedName>`);\n\t\t}\n\t\tif (print.printArea) {\n\t\t\tconst { firstRow, lastRow, firstColumn, lastColumn } = print.printArea;\n\t\t\tconst area = `${sheetName}!$${numberToColumnName(firstColumn)}$${firstRow}:$${numberToColumnName(lastColumn)}$${lastRow}`;\n\t\t\tdefinitions.push(`<definedName name=\"_xlnm.Print_Area\" localSheetId=\"${sheetIndex}\">${escapeXmlValue(area)}</definedName>`);\n\t\t}\n\t}\n\treturn definitions.join(\"\");\n}\n\n/**\n * Дополняет штатный контейнер definedNames, который write-excel-file уже\n * создаёт в workbook.xml. Два одноимённых контейнера формально нарушают схему\n * OOXML: Numbers читает такую книгу, а Microsoft Excel отклоняет её.\n */\nfunction applyWorkbookDefinedNames(content: string, definedNames: string): string {\n\tif (/<definedNames\\s*\\/>/.test(content)) {\n\t\treturn content.replace(/<definedNames\\s*\\/>/, `<definedNames>${definedNames}</definedNames>`);\n\t}\n\tif (content.includes(EXCEL_DEFINED_NAMES_END_TAG)) {\n\t\treturn content.replace(EXCEL_DEFINED_NAMES_END_TAG, `${definedNames}</definedNames>`);\n\t}\n\treturn content.replace(\"</sheets>\", `</sheets><definedNames>${definedNames}</definedNames>`);\n}\n\n/** Настройки печати требуют двух согласованных OpenXML-частей: worksheet и workbook defined names. */\nfunction createMatrixPrintFeature(\n\tsheetNames: readonly string[],\n\tsheets: readonly ExcelMatrixWorkbookSheet[]\n): Feature<BrowserExcelFileContent> | undefined {\n\tif (!sheets.some(({ print }) => print)) return undefined;\n\tconst definedNames = buildDefinedNames(sheetNames, sheets);\n\treturn {\n\t\tfiles: {\n\t\t\ttransform: {\n\t\t\t\t\"xl/worksheets/sheet{id}.xml\": {\n\t\t\t\t\ttransform: (content, _options, properties) => {\n\t\t\t\t\t\tconst setup = sheets[properties.sheetIndex]?.print;\n\t\t\t\t\t\treturn setup ? applyWorksheetPrintSetup(content, setup) : content;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\"xl/workbook.xml\": {\n\t\t\t\t\ttransform: (content) => (definedNames ? applyWorkbookDefinedNames(content, definedNames) : content)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Формирует Blob без побочного эффекта скачивания.\n *\n * Этот вход нужен предпросмотру, file validation и сценариям, где download\n * выполняет отдельный browser-owner. KTK-specific layout сюда не передаётся.\n */\nexport async function createExcelMatrixWorkbookBlob(args: ExcelMatrixWorkbookArgs): Promise<Blob> {\n\tif (args.sheets.length === 0) throw new Error(EXCEL_WORKBOOK_EMPTY_MESSAGE);\n\tif (args.defaultFont) {\n\t\tif (!args.defaultFont.fontFamily.trim()) throw new Error(\"Имя базового шрифта Excel-книги не может быть пустым\");\n\t\tif (!Number.isFinite(args.defaultFont.fontSize) || args.defaultFont.fontSize <= 0) {\n\t\t\tthrow new Error(\"Размер базового шрифта Excel-книги должен быть положительным числом\");\n\t\t}\n\t}\n\tfor (const sheet of args.sheets) {\n\t\tif (sheet.rows.length === 0) throw new Error(`Лист «${sheet.name}» не содержит строк`);\n\t\tif (sheet.print) validatePrintSetup(sheet.print);\n\t}\n\n\tconst sheetNames = resolveExcelSheetNames(args.sheets.map(({ name }) => name));\n\tconst sheets: Sheet<BrowserExcelFileContent>[] = args.sheets.map((sheet, index) => ({\n\t\tdata: sheet.rows.map((row) => [...row]),\n\t\tsheet: sheetNames[index],\n\t\tcolumns: sheet.columns?.map((column) => ({ width: column.width })),\n\t\tshowGridLines: sheet.showGridLines,\n\t\tzoomScale: sheet.zoomScale\n\t}));\n\tconst printFeature = createMatrixPrintFeature(sheetNames, args.sheets);\n\treturn writeXlsxFile(sheets, {\n\t\tfontFamily: args.defaultFont?.fontFamily,\n\t\tfontSize: args.defaultFont?.fontSize,\n\t\tfeatures: printFeature ? [printFeature] : undefined\n\t}).toBlob();\n}\n\n/** Скачивает готовую матричную книгу из явного пользовательского действия. */\nexport async function downloadExcelMatrixWorkbook(fileName: string, args: ExcelMatrixWorkbookArgs): Promise<void> {\n\tconst blob = await createExcelMatrixWorkbookBlob(args);\n\tdownloadFileFromBlob(fileName, blob);\n}\n","import { DEFAULT_DATE_PRESET_NAMES, getDatePreset, type DateFormatPreset } from \"../formatters/date\";\nimport { getNumberPreset } from \"../formatters/number\";\nimport { NUMBER_PRESET_NAME_DECIMAL, NUMBER_PRESET_NAME_INTEGER } from \"../formatters/number/numberPresetNameConstants\";\nimport {\n\tvalidateFormattersPipelineConfig,\n\ttype FormattersPipelineConfig,\n\ttype FormattersPipelineTypedValueFormatConfig\n} from \"../formatters/pipeline\";\nimport { PIPELINE_FORMATTER_TYPED_VALUE_FORMAT } from \"../formatters/pipeline/formattersPipelineConstants\";\nimport { type ColumnRole, type ScalarMetaType } from \"../metadata/metadataTypes\";\nimport { isScalarBooleanType, isScalarDateType, isScalarIntegerType, isScalarNumericType } from \"../metadata/scalarTypeClassification\";\nimport { SCALAR_ROLE_MEASURE, SCALAR_TYPE_DATETIME, SCALAR_TYPE_DATETIME_OFFSET, SCALAR_TYPE_TIME } from \"../metadata/scalarTypeConstants\";\n\nimport { downloadExcelFile, downloadExcelWorkbook, type ExcelCellStyle, type ExcelColumn, type ExcelRow } from \"./excel\";\n\nexport type TableExcelColumnDescriptor = {\n\tid: string;\n\theader: string;\n\twidth?: number;\n\trole?: ColumnRole;\n\todataType?: ScalarMetaType;\n\tclientOnly?: boolean;\n\tformattersPipeline?: FormattersPipelineConfig;\n};\n\nexport type ResolvedExcelTable = {\n\tcolumns: ExcelColumn[];\n\trows: ExcelRow[];\n\tcellStyles?: ReadonlyArray<Readonly<Record<string, ExcelCellStyle | undefined>>>;\n};\n\nexport type DownloadResolvedExcelTableArgs = {\n\tfileName: string;\n\ttable: ResolvedExcelTable;\n\tautoFilter?: boolean;\n};\n\n/** Один подготовленный табличный лист generic Excel-книги. */\nexport type ResolvedExcelWorkbookSheet = {\n\t/** Желаемое имя листа. */\n\tname: string;\n\t/** Подготовленные колонки, строки и optional стили ячеек. */\n\ttable: ResolvedExcelTable;\n\t/** Включить автофильтр для этого листа. По умолчанию включён. */\n\tautoFilter?: boolean;\n};\n\n/** Аргументы скачивания книги из нескольких подготовленных таблиц. */\nexport type DownloadResolvedExcelWorkbookArgs = {\n\t/** Имя скачиваемого `.xlsx` файла. */\n\tfileName: string;\n\t/** Табличные листы в порядке отображения в книге. */\n\tsheets: ResolvedExcelWorkbookSheet[];\n};\n\nconst INTEGER_EXCEL_FORMAT = \"#,##0\";\nconst DEFAULT_DECIMAL_EXCEL_FORMAT = \"#,##0.0\";\n// Prefix определяет семейство встроенного date preset, а не скалярный тип данных.\nconst DATE_PRESET_PREFIX_DATE = \"date\";\nconst DATE_PRESET_PREFIX_TIME = \"time\";\nconst DATE_PRESET_PREFIX_DATETIME = \"datetime\";\nconst EXCEL_DATE_FORMAT = \"dd.mm.yyyy\";\n/**\n * Excel-маски календарных пресетов сохраняют экранную детализацию:\n * month-* выводит день и месяц без года, а month-year-* — месяц и год без дня.\n */\nconst EXCEL_DAY_MONTH_SHORT_FORMAT = \"dd.mm\";\nconst EXCEL_DAY_MONTH_MEDIUM_FORMAT = \"d mmm\";\nconst EXCEL_DAY_MONTH_LONG_FORMAT = \"d mmmm\";\nconst EXCEL_MONTH_YEAR_MEDIUM_FORMAT = \"mmm yyyy\";\nconst EXCEL_MONTH_YEAR_LONG_FORMAT = \"mmmm yyyy\";\nconst EXCEL_TIME_FORMAT = \"hh:mm\";\nconst EXCEL_TIME_SECONDS_FORMAT = \"hh:mm:ss\";\nconst EXCEL_DATETIME_FORMAT = `${EXCEL_DATE_FORMAT} ${EXCEL_TIME_FORMAT}`;\nconst EXCEL_DATETIME_SECONDS_FORMAT = `${EXCEL_DATE_FORMAT} ${EXCEL_TIME_SECONDS_FORMAT}`;\n\nfunction resolveTypedValueFormatConfig(\n\tformattersPipeline: FormattersPipelineConfig | undefined\n): FormattersPipelineTypedValueFormatConfig | undefined {\n\tconst validation = validateFormattersPipelineConfig(formattersPipeline);\n\tconst typedValueFormatStep = validation.plan?.steps.find((step) => step.type === PIPELINE_FORMATTER_TYPED_VALUE_FORMAT);\n\n\treturn typedValueFormatStep?.type === PIPELINE_FORMATTER_TYPED_VALUE_FORMAT ? typedValueFormatStep.config : undefined;\n}\n\nexport function resolveTableExcelColumnType(descriptor: TableExcelColumnDescriptor): ExcelColumn[\"type\"] {\n\tif (descriptor.clientOnly) return Number;\n\tif (isScalarDateType(descriptor.odataType)) return Date;\n\tif (isScalarBooleanType(descriptor.odataType)) return Boolean;\n\tif (isScalarNumericType(descriptor.odataType)) return Number;\n\tif (descriptor.role === SCALAR_ROLE_MEASURE) return Number;\n\treturn String;\n}\n\nfunction resolveNumberPresetName(descriptor: TableExcelColumnDescriptor): string {\n\tconst configuredPresetName = resolveTypedValueFormatConfig(descriptor.formattersPipeline)?.numberPresetName?.trim();\n\tif (configuredPresetName && getNumberPreset(configuredPresetName)) return configuredPresetName;\n\tif (isScalarIntegerType(descriptor.odataType)) return NUMBER_PRESET_NAME_INTEGER;\n\treturn NUMBER_PRESET_NAME_DECIMAL;\n}\n\nfunction resolveExcelNumberFormat(descriptor: TableExcelColumnDescriptor): string {\n\tconst preset = getNumberPreset(resolveNumberPresetName(descriptor));\n\tif (!preset) return DEFAULT_DECIMAL_EXCEL_FORMAT;\n\treturn preset.decimals > 0 ? `#,##0.${\"0\".repeat(preset.decimals)}` : INTEGER_EXCEL_FORMAT;\n}\n\nfunction resolveDatePresetName(descriptor: TableExcelColumnDescriptor): string {\n\tconst configuredPresetName = resolveTypedValueFormatConfig(descriptor.formattersPipeline)?.datePresetName?.trim();\n\tif (configuredPresetName) return configuredPresetName;\n\tif (descriptor.odataType === SCALAR_TYPE_TIME) return DEFAULT_DATE_PRESET_NAMES.time;\n\tif (descriptor.odataType === SCALAR_TYPE_DATETIME || descriptor.odataType === SCALAR_TYPE_DATETIME_OFFSET)\n\t\treturn DEFAULT_DATE_PRESET_NAMES.datetime;\n\treturn DEFAULT_DATE_PRESET_NAMES.date;\n}\n\nfunction normalizeDatePatternForExcel(pattern: string): string {\n\treturn pattern.replace(/H/g, \"h\").replace(/M/g, \"m\");\n}\n\nfunction resolveBuiltinDatePresetExcelFormat(presetName: string): string | undefined {\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.odataDatetime || presetName === DEFAULT_DATE_PRESET_NAMES.abapDatetime) {\n\t\treturn EXCEL_DATETIME_SECONDS_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.odataDate || presetName === DEFAULT_DATE_PRESET_NAMES.abapDate) {\n\t\treturn EXCEL_DATE_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.monthShort) {\n\t\treturn EXCEL_DAY_MONTH_SHORT_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.monthMedium) {\n\t\treturn EXCEL_DAY_MONTH_MEDIUM_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.monthLong) {\n\t\treturn EXCEL_DAY_MONTH_LONG_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.monthYearMedium) {\n\t\treturn EXCEL_MONTH_YEAR_MEDIUM_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.monthYearLong) {\n\t\treturn EXCEL_MONTH_YEAR_LONG_FORMAT;\n\t}\n\n\tif (presetName.startsWith(DATE_PRESET_PREFIX_DATETIME)) {\n\t\treturn presetName === DEFAULT_DATE_PRESET_NAMES.datetime || presetName === DEFAULT_DATE_PRESET_NAMES.datetimeShort\n\t\t\t? EXCEL_DATETIME_FORMAT\n\t\t\t: EXCEL_DATETIME_SECONDS_FORMAT;\n\t}\n\n\tif (presetName.startsWith(DATE_PRESET_PREFIX_TIME)) {\n\t\treturn presetName === DEFAULT_DATE_PRESET_NAMES.time || presetName === DEFAULT_DATE_PRESET_NAMES.timeShort\n\t\t\t? EXCEL_TIME_FORMAT\n\t\t\t: EXCEL_TIME_SECONDS_FORMAT;\n\t}\n\n\tif (presetName.startsWith(DATE_PRESET_PREFIX_DATE)) return EXCEL_DATE_FORMAT;\n\n\treturn undefined;\n}\n\nfunction resolveExcelDateFormatFromPreset(presetName: string, preset: DateFormatPreset | undefined): string {\n\tconst builtinFormat = resolveBuiltinDatePresetExcelFormat(presetName);\n\tif (builtinFormat) return builtinFormat;\n\tif (preset?.pattern) return normalizeDatePatternForExcel(preset.pattern);\n\n\t// Настройка datePresetName исторически хранит и ручной шаблон. Если имени\n\t// нет в реестре, передаём шаблон в Excel как есть после нормализации токенов.\n\treturn normalizeDatePatternForExcel(presetName);\n}\n\nfunction resolveExcelDateFormat(descriptor: TableExcelColumnDescriptor): string {\n\tconst presetName = resolveDatePresetName(descriptor);\n\treturn resolveExcelDateFormatFromPreset(presetName, getDatePreset(presetName));\n}\n\nfunction resolveTableExcelColumnFormat(descriptor: TableExcelColumnDescriptor, type: ExcelColumn[\"type\"]): string | undefined {\n\tif (type === Number) return resolveExcelNumberFormat(descriptor);\n\tif (type === Date) return resolveExcelDateFormat(descriptor);\n\treturn undefined;\n}\n\nexport function createTableExcelColumn(descriptor: TableExcelColumnDescriptor): ExcelColumn {\n\tconst type = resolveTableExcelColumnType(descriptor);\n\treturn {\n\t\tid: descriptor.id,\n\t\theader: descriptor.header,\n\t\twidth: descriptor.width,\n\t\ttype,\n\t\tformat: resolveTableExcelColumnFormat(descriptor, type)\n\t};\n}\n\nexport async function downloadResolvedExcelTable({ fileName, table, autoFilter = true }: DownloadResolvedExcelTableArgs): Promise<void> {\n\tawait downloadExcelFile({\n\t\tfileName,\n\t\tcolumns: table.columns,\n\t\trows: table.rows,\n\t\tautoFilter,\n\t\tgetCellStyle: ({ rowIndex, column }) => table.cellStyles?.[rowIndex]?.[column.id]\n\t});\n}\n\n/** Скачивает многолистовую книгу из таблиц, уже подготовленных доменными consumers. */\nexport async function downloadResolvedExcelWorkbook({ fileName, sheets }: DownloadResolvedExcelWorkbookArgs): Promise<void> {\n\tawait downloadExcelWorkbook({\n\t\tfileName,\n\t\tsheets: sheets.map(({ name, table, autoFilter = true }) => ({\n\t\t\tname,\n\t\t\tcolumns: table.columns,\n\t\t\trows: table.rows,\n\t\t\tautoFilter,\n\t\t\tgetCellStyle: ({ rowIndex, column }) => table.cellStyles?.[rowIndex]?.[column.id]\n\t\t}))\n\t});\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/excel/excelWorkbookConstants.ts","../../src/excel/excel.ts","../../src/excel/matrixWorkbook.ts","../../src/excel/tableExport.ts"],"sourcesContent":["/** Табличный и матричный writer одинаково отклоняют книгу без листов. */\nexport const EXCEL_WORKBOOK_EMPTY_MESSAGE = \"Для формирования Excel-книги нужен минимум один лист\";\n\n/** Адрес колонки использует латинский алфавит и одинаков в обоих видах книги. */\nexport const EXCEL_COLUMN_ALPHABET_LENGTH = 26;\nexport const EXCEL_COLUMN_FIRST_CHARACTER_CODE = 65;\n","import writeXlsxFile, { type Cell, type CellObject, type Feature, type Sheet, type SheetData } from \"write-excel-file/browser\";\n\nimport { parseDate } from \"../formatters/date\";\nimport { type State } from \"../types\";\n\nimport { EXCEL_COLUMN_ALPHABET_LENGTH, EXCEL_COLUMN_FIRST_CHARACTER_CODE, EXCEL_WORKBOOK_EMPTY_MESSAGE } from \"./excelWorkbookConstants\";\n\nexport type ExcelColumn = {\n\tid: string;\n\theader: string;\n\twidth?: number;\n\ttype?: StringConstructor | NumberConstructor | DateConstructor | BooleanConstructor;\n\tformat?: string;\n};\n\nexport type ExcelRow = Record<string, unknown>;\n\nexport type ExcelCellStyle = Omit<CellObject, \"value\" | \"type\" | \"format\">;\n\nexport type DownloadExcelFileArgs = {\n\tfileName: string;\n\tcolumns: ExcelColumn[];\n\trows: ExcelRow[];\n\tautoFilter?: boolean;\n\tgetCellStyle?: (args: { row: ExcelRow; column: ExcelColumn; rowIndex: number; columnIndex: number }) => ExcelCellStyle | undefined;\n};\n\n/** Описание одного табличного листа внутри Excel-книги. */\nexport type ExcelWorkbookSheet = Omit<DownloadExcelFileArgs, \"fileName\"> & {\n\t/** Желаемое имя листа; writer нормализует ограничения формата и конфликты имён. */\n\tname: string;\n};\n\n/** Аргументы формирования Excel-книги с одним или несколькими табличными листами. */\nexport type DownloadExcelWorkbookArgs = {\n\t/** Имя скачиваемого `.xlsx` файла. */\n\tfileName: string;\n\t/** Листы книги в порядке отображения в Excel. */\n\tsheets: ExcelWorkbookSheet[];\n};\n\ntype BrowserExcelFileContent = File | Blob | ArrayBuffer;\n\nconst VALUE_STATE_TEXT_COLORS: Partial<Record<State, string>> = {\n\tinformation: \"#2563EB\",\n\tsuccess: \"#107C10\",\n\twarning: \"#B7791F\",\n\terror: \"#C50F1F\"\n};\n\nconst HEADER_CELL_STYLE = {\n\tfontWeight: \"bold\",\n\tbottomBorderStyle: \"thin\",\n\tbottomBorderColor: \"#D9D9D9\"\n} satisfies ExcelCellStyle;\n\nconst EXCEL_SHEET_NAME_MAX_LENGTH = 31;\nconst EXCEL_SHEET_NAME_INVALID_CHARACTERS = /[\\u0000-\\u001f[\\]/\\\\:*?]+/g;\nconst EXCEL_SHEET_NAME_EDGE_APOSTROPHES = /^'+|'+$/g;\nconst EXCEL_SHEET_NAME_WHITESPACE = /\\s+/g;\n\n/**\n * Приводит общий value-state проекта к базовому Excel-стилю.\n *\n * Helper живет в shared Excel-слое, чтобы analytical/detail экспорт не\n * дублировали палитру статусов и одинаково подсвечивали warning/error/success.\n */\nexport function resolveExcelCellStyleFromState(state: State | undefined): ExcelCellStyle | undefined {\n\tconst textColor = state ? VALUE_STATE_TEXT_COLORS[state] : undefined;\n\treturn textColor ? { textColor } : undefined;\n}\n\n/**\n * Переводит zero-based индекс колонки в Excel-адрес (`0 -> A`, `27 -> AB`).\n * Нужен для XML-диапазонов, потому что `write-excel-file` не предоставляет\n * отдельного API для построения ссылок вида `A1:C10`.\n */\nfunction numberToColumnName(index: number): string {\n\tlet value = index + 1;\n\tlet out = \"\";\n\n\twhile (value > 0) {\n\t\tconst remainder = (value - 1) % EXCEL_COLUMN_ALPHABET_LENGTH;\n\t\tout = String.fromCharCode(EXCEL_COLUMN_FIRST_CHARACTER_CODE + remainder) + out;\n\t\tvalue = Math.floor((value - 1) / EXCEL_COLUMN_ALPHABET_LENGTH);\n\t}\n\n\treturn out;\n}\n\n/**\n * Строит диапазон автофильтра для всей выгруженной таблицы.\n *\n * Возвращает `undefined` для пустой сетки, чтобы не вставлять в xlsx\n * невалидный `<autoFilter>` без реального диапазона.\n */\nexport function buildExcelAutoFilterRef(columnCount: number, rowCount: number): string | undefined {\n\tif (columnCount <= 0 || rowCount <= 0) return undefined;\n\n\treturn `A1:${numberToColumnName(columnCount - 1)}${rowCount}`;\n}\n\n/**\n * Добавляет autoFilter через feature-transform `write-excel-file`.\n *\n * Библиотека умеет трансформировать XML листа, но не имеет высокоуровневого\n * параметра `autoFilter`, поэтому здесь изолирован низкоуровневый OpenXML-хук.\n */\nfunction createAutoFilterFeature<FileContent>(refs: readonly (string | undefined)[]): Feature<FileContent> | undefined {\n\tif (!refs.some(Boolean)) return undefined;\n\n\treturn {\n\t\tfiles: {\n\t\t\ttransform: {\n\t\t\t\t\"xl/worksheets/sheet{id}.xml\": {\n\t\t\t\t\ttransform: (content, _options, properties) => {\n\t\t\t\t\t\tconst ref = refs[properties.sheetIndex];\n\t\t\t\t\t\treturn ref ? content.replace(\"</sheetData>\", `</sheetData><autoFilter ref=\"${ref}\"/>`) : content;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Нормализует имена листов по ограничениям Excel и делает их уникальными.\n *\n * Runtime-заголовки могут содержать запрещённые символы, превышать 31 знак или\n * совпадать между несколькими представлениями одной конфигурации. Нормализация\n * выполняется централизованно, чтобы все consumers получали открываемую книгу.\n */\nexport function resolveExcelSheetNames(names: readonly string[]): string[] {\n\tconst usedNames = new Set<string>();\n\tconst resolvedNames: string[] = [];\n\n\tfor (let index = 0; index < names.length; index += 1) {\n\t\tconst fallbackName = `Лист ${index + 1}`;\n\t\tconst normalizedName = names[index]\n\t\t\t?.replace(EXCEL_SHEET_NAME_INVALID_CHARACTERS, \" \")\n\t\t\t.replace(EXCEL_SHEET_NAME_WHITESPACE, \" \")\n\t\t\t.trim()\n\t\t\t.replace(EXCEL_SHEET_NAME_EDGE_APOSTROPHES, \"\")\n\t\t\t.trim();\n\t\tconst baseName = normalizedName || fallbackName;\n\t\tlet resolvedName = baseName.slice(0, EXCEL_SHEET_NAME_MAX_LENGTH);\n\t\tlet duplicateIndex = 2;\n\n\t\twhile (usedNames.has(resolvedName.toLocaleLowerCase())) {\n\t\t\tconst suffix = ` (${duplicateIndex})`;\n\t\t\tresolvedName = `${baseName.slice(0, EXCEL_SHEET_NAME_MAX_LENGTH - suffix.length)}${suffix}`;\n\t\t\tduplicateIndex += 1;\n\t\t}\n\n\t\tusedNames.add(resolvedName.toLocaleLowerCase());\n\t\tresolvedNames.push(resolvedName);\n\t}\n\n\treturn resolvedNames;\n}\n\n/**\n * Приводит входное значение к типу Excel-ячейки.\n *\n * Важный смысл: если колонка числовая, в файл должен попасть настоящий Number,\n * а не уже отформатированная строка. Тогда Excel сможет применять `format`.\n */\nfunction normalizeCellValue(value: unknown, type: ExcelColumn[\"type\"]) {\n\tif (value == null || value === \"\") return undefined;\n\n\tif (type === Number) {\n\t\tconst numberValue = typeof value === \"number\" ? value : Number(value);\n\t\treturn Number.isFinite(numberValue) ? numberValue : undefined;\n\t}\n\n\tif (type === String) return String(value);\n\tif (type === Boolean) return Boolean(value);\n\tif (type === Date) return value instanceof Date ? value : (parseDate(value) ?? undefined);\n\n\treturn value as CellObject[\"value\"];\n}\n\n/**\n * Собирает SheetData для `write-excel-file`.\n *\n * Функция намеренно не знает о бизнес-сущностях: ей передают уже готовые\n * колонки/строки и необязательный callback стилей конкретных ячеек.\n */\nexport function buildExcelSheetData(args: Omit<DownloadExcelFileArgs, \"fileName\" | \"autoFilter\">): SheetData {\n\tconst headerRow: Cell[] = args.columns.map((column) => ({\n\t\ttype: String,\n\t\tvalue: column.header,\n\t\t...HEADER_CELL_STYLE\n\t}));\n\n\tconst sheetRows: SheetData = [headerRow];\n\n\tfor (let rowIndex = 0; rowIndex < args.rows.length; rowIndex++) {\n\t\tconst row = args.rows[rowIndex];\n\t\tconst sheetRow: Cell[] = [];\n\n\t\tfor (let columnIndex = 0; columnIndex < args.columns.length; columnIndex++) {\n\t\t\tconst column = args.columns[columnIndex];\n\t\t\tconst value = normalizeCellValue(row[column.id], column.type);\n\t\t\tconst style = args.getCellStyle?.({ row, column, rowIndex, columnIndex });\n\n\t\t\tsheetRow.push({\n\t\t\t\tvalue,\n\t\t\t\ttype: column.type,\n\t\t\t\tformat: column.format,\n\t\t\t\t...style\n\t\t\t});\n\t\t}\n\n\t\tsheetRows.push(sheetRow);\n\t}\n\n\treturn sheetRows;\n}\n\n/**\n * Формирует и скачивает Excel-книгу с независимыми табличными листами.\n *\n * Каждый лист получает собственные ширины колонок, стили ячеек и диапазон\n * автофильтра. Доменная подготовка колонок и строк остаётся у вызывающей стороны.\n */\nexport async function downloadExcelWorkbook(args: DownloadExcelWorkbookArgs): Promise<void> {\n\tif (args.sheets.length === 0) {\n\t\tthrow new Error(EXCEL_WORKBOOK_EMPTY_MESSAGE);\n\t}\n\n\tconst sheetNames = resolveExcelSheetNames(args.sheets.map((sheet) => sheet.name));\n\tconst autoFilterRefs: Array<string | undefined> = [];\n\tconst sheets: Sheet<BrowserExcelFileContent>[] = args.sheets.map((sheet, index) => {\n\t\tconst data = buildExcelSheetData(sheet);\n\t\tautoFilterRefs.push(sheet.autoFilter ? buildExcelAutoFilterRef(sheet.columns.length, data.length) : undefined);\n\n\t\treturn {\n\t\t\tdata,\n\t\t\tsheet: sheetNames[index],\n\t\t\tcolumns: sheet.columns.map((column) => ({\n\t\t\t\twidth: column.width\n\t\t\t}))\n\t\t};\n\t});\n\tconst autoFilterFeature = createAutoFilterFeature<BrowserExcelFileContent>(autoFilterRefs);\n\n\tawait writeXlsxFile(sheets, {\n\t\tfeatures: autoFilterFeature ? [autoFilterFeature] : undefined\n\t}).toFile(args.fileName);\n}\n\n/**\n * Формирует и скачивает `.xlsx` в браузере.\n *\n * Это публичная generic-точка shared-слоя: она отвечает только за Excel-файл,\n * а подготовка доменных данных остаётся на вызывающей стороне.\n */\nexport async function downloadExcelFile(args: DownloadExcelFileArgs): Promise<void> {\n\tawait downloadExcelWorkbook({\n\t\tfileName: args.fileName,\n\t\tsheets: [\n\t\t\t{\n\t\t\t\tname: \"Sheet1\",\n\t\t\t\tcolumns: args.columns,\n\t\t\t\trows: args.rows,\n\t\t\t\tautoFilter: args.autoFilter,\n\t\t\t\tgetCellStyle: args.getCellStyle\n\t\t\t}\n\t\t]\n\t});\n}\n","import writeXlsxFile, { type Cell, type Feature, type Sheet } from \"write-excel-file/browser\";\n\nimport { downloadFileFromBlob } from \"../dom\";\nimport { escapeXmlValue } from \"../xml\";\n\nimport { resolveExcelSheetNames } from \"./excel\";\nimport { EXCEL_COLUMN_ALPHABET_LENGTH, EXCEL_COLUMN_FIRST_CHARACTER_CODE, EXCEL_WORKBOOK_EMPTY_MESSAGE } from \"./excelWorkbookConstants\";\n\n// XML-имена согласованы между типами допустимых элементов и их формированием.\nconst EXCEL_HEADER_FOOTER_ELEMENT = \"headerFooter\";\nconst EXCEL_COLUMN_BREAKS_ELEMENT = \"colBreaks\";\nconst EXCEL_ROW_BREAKS_ELEMENT = \"rowBreaks\";\nconst EXCEL_DEFINED_NAMES_END_TAG = \"</definedNames>\";\n\ntype BrowserExcelFileContent = File | Blob | ArrayBuffer;\n\n/** Одна строка произвольной Excel-матрицы. Объединения задаются стилями первой ячейки диапазона. */\nexport type ExcelMatrixRow = readonly Cell[];\n\n/** Поля задаются в дюймах, как в OpenXML и диалоге параметров страницы Excel. */\nexport type ExcelPrintMargins = {\n\treadonly left: number;\n\treadonly right: number;\n\treadonly top: number;\n\treadonly bottom: number;\n\treadonly header: number;\n\treadonly footer: number;\n};\n\n/** Видимый колонтитул не принимает raw Excel-коды, чтобы текст не мог случайно изменить разметку секций. */\nexport type ExcelPrintHeaderFooter = {\n\treadonly left?: string;\n\treadonly center?: string;\n\treadonly right?: string;\n\treadonly includePageNumber?: boolean;\n};\n\n/** One-based прямоугольник печати соответствует координатам строк и столбцов Excel. */\nexport type ExcelPrintArea = {\n\treadonly firstRow: number;\n\treadonly lastRow: number;\n\treadonly firstColumn: number;\n\treadonly lastColumn: number;\n};\n\n/**\n * Печатный контракт одного листа.\n *\n * `columnBreaksAfter` и `rowBreaksAfter` используют one-based координату\n * последней ячейки страницы. Явная модель не позволяет consumer перепутать\n * индекс массива с адресом Excel и разрезать составной блок на печати.\n */\nexport type ExcelPrintSetup = {\n\treadonly orientation: \"portrait\" | \"landscape\";\n\treadonly paperSize?: keyof typeof PAPER_SIZE;\n\treadonly fitToWidthPages?: number;\n\treadonly fitToHeightPages?: number;\n\treadonly pageOrder?: \"downThenOver\" | \"overThenDown\";\n\treadonly margins?: ExcelPrintMargins;\n\treadonly repeatRows?: readonly [firstRow: number, lastRow: number];\n\treadonly repeatColumns?: readonly [firstColumn: number, lastColumn: number];\n\treadonly printArea?: ExcelPrintArea;\n\treadonly columnBreaksAfter?: readonly number[];\n\treadonly rowBreaksAfter?: readonly number[];\n\treadonly header?: ExcelPrintHeaderFooter;\n\treadonly footer?: ExcelPrintHeaderFooter;\n};\n\n/** Произвольный лист сохраняет готовую матрицу и не навязывает табличную строку заголовков. */\nexport type ExcelMatrixWorkbookSheet = {\n\treadonly name: string;\n\treadonly rows: readonly ExcelMatrixRow[];\n\treadonly columns?: readonly { readonly width?: number }[];\n\treadonly showGridLines?: boolean;\n\treadonly zoomScale?: number;\n\treadonly print?: ExcelPrintSetup;\n};\n\n/**\n * Базовый шрифт стиля Normal задаёт метрику символьной ширины столбцов Excel.\n *\n * Шрифт отдельных ячеек может отличаться: эта настройка нужна прежде всего\n * для воспроизводимого преобразования `columns[].width` в экранные пиксели.\n */\nexport type ExcelMatrixWorkbookDefaultFont = {\n\treadonly fontFamily: string;\n\treadonly fontSize: number;\n};\n\n/** Аргументы generic-книги, пригодной как для скачивания, так и для file validation. */\nexport type ExcelMatrixWorkbookArgs = {\n\treadonly defaultFont?: ExcelMatrixWorkbookDefaultFont;\n\treadonly sheets: readonly ExcelMatrixWorkbookSheet[];\n};\n\nconst DEFAULT_PRINT_MARGINS = {\n\tleft: 0.2,\n\tright: 0.2,\n\ttop: 0.25,\n\tbottom: 0.25,\n\theader: 0.1,\n\tfooter: 0.1\n} as const satisfies ExcelPrintMargins;\n\nconst PAPER_SIZE = { a4: 9, a3: 8 } as const;\nconst DEFAULT_PAPER_SIZE: keyof typeof PAPER_SIZE = \"a4\";\n// Сохраняет прежнюю верхнюю границу индекса в XML ручного разрыва страницы.\nconst PAGE_BREAK_MAX_INDEX = 16383;\n\nfunction escapeHeaderFooterText(value: string): string {\n\treturn escapeXmlValue(value.replaceAll(\"&\", \"&&\"));\n}\n\nfunction numberToColumnName(index: number): string {\n\tlet value = index;\n\tlet result = \"\";\n\twhile (value > 0) {\n\t\tconst remainder = (value - 1) % EXCEL_COLUMN_ALPHABET_LENGTH;\n\t\tresult = String.fromCharCode(EXCEL_COLUMN_FIRST_CHARACTER_CODE + remainder) + result;\n\t\tvalue = Math.floor((value - 1) / EXCEL_COLUMN_ALPHABET_LENGTH);\n\t}\n\treturn result;\n}\n\nfunction assertPositiveInteger(value: number, name: string): void {\n\tif (!Number.isInteger(value) || value <= 0) throw new Error(`${name} должен быть положительным целым числом`);\n}\n\nfunction assertNonnegativeInteger(value: number, name: string): void {\n\tif (!Number.isInteger(value) || value < 0) throw new Error(`${name} должен быть целым неотрицательным числом`);\n}\n\nfunction validateRange(range: readonly [number, number], name: string): void {\n\tassertPositiveInteger(range[0], `${name}: начало`);\n\tassertPositiveInteger(range[1], `${name}: конец`);\n\tif (range[0] > range[1]) throw new Error(`${name}: начало не может быть больше конца`);\n}\n\nfunction validatePrintSetup(print: ExcelPrintSetup): void {\n\t// В OpenXML ноль означает автоматическое число страниц по соответствующей оси.\n\tif (print.fitToWidthPages !== undefined) assertNonnegativeInteger(print.fitToWidthPages, \"fitToWidthPages\");\n\tif (print.fitToHeightPages !== undefined) assertNonnegativeInteger(print.fitToHeightPages, \"fitToHeightPages\");\n\tif (print.repeatRows) validateRange(print.repeatRows, \"repeatRows\");\n\tif (print.repeatColumns) validateRange(print.repeatColumns, \"repeatColumns\");\n\tfor (const value of print.columnBreaksAfter ?? []) assertPositiveInteger(value, \"columnBreaksAfter\");\n\tfor (const value of print.rowBreaksAfter ?? []) assertPositiveInteger(value, \"rowBreaksAfter\");\n\tif (print.printArea) {\n\t\tassertPositiveInteger(print.printArea.firstRow, \"printArea.firstRow\");\n\t\tassertPositiveInteger(print.printArea.lastRow, \"printArea.lastRow\");\n\t\tassertPositiveInteger(print.printArea.firstColumn, \"printArea.firstColumn\");\n\t\tassertPositiveInteger(print.printArea.lastColumn, \"printArea.lastColumn\");\n\t\tif (print.printArea.firstRow > print.printArea.lastRow || print.printArea.firstColumn > print.printArea.lastColumn) {\n\t\t\tthrow new Error(\"printArea должен задавать непустой прямоугольник\");\n\t\t}\n\t}\n}\n\nfunction buildHeaderFooterXml(\n\ttagName: typeof EXCEL_HEADER_FOOTER_ELEMENT,\n\theader: ExcelPrintHeaderFooter | undefined,\n\tfooter: ExcelPrintHeaderFooter | undefined\n): string {\n\tif (!header && !footer) return \"\";\n\tconst buildSection = (value: ExcelPrintHeaderFooter | undefined) => {\n\t\tif (!value) return \"\";\n\t\tconst content = [\n\t\t\tvalue.left ? `&L${escapeHeaderFooterText(value.left)}` : \"\",\n\t\t\tvalue.center ? `&C${escapeHeaderFooterText(value.center)}` : \"\",\n\t\t\tvalue.right ? `&R${escapeHeaderFooterText(value.right)}` : \"\",\n\t\t\tvalue.includePageNumber ? \"&RСтраница &P из &N\" : \"\"\n\t\t].join(\"\");\n\t\treturn content;\n\t};\n\tconst oddHeader = buildSection(header);\n\tconst oddFooter = buildSection(footer);\n\treturn `<${tagName}>${oddHeader ? `<oddHeader>${oddHeader}</oddHeader>` : \"\"}${oddFooter ? `<oddFooter>${oddFooter}</oddFooter>` : \"\"}</${tagName}>`;\n}\n\nfunction buildBreaksXml(\n\ttagName: typeof EXCEL_COLUMN_BREAKS_ELEMENT | typeof EXCEL_ROW_BREAKS_ELEMENT,\n\tvalues: readonly number[] | undefined\n): string {\n\tif (!values || values.length === 0) return \"\";\n\tconst uniqueValues = [...new Set(values)].sort((left, right) => left - right);\n\treturn `<${tagName} count=\"${uniqueValues.length}\" manualBreakCount=\"${uniqueValues.length}\">${uniqueValues\n\t\t.map((value) => `<brk id=\"${value}\" min=\"0\" max=\"${PAGE_BREAK_MAX_INDEX}\" man=\"1\"/>`)\n\t\t.join(\"\")}</${tagName}>`;\n}\n\nfunction applyWorksheetPrintSetup(content: string, print: ExcelPrintSetup): string {\n\tconst margins = print.margins ?? DEFAULT_PRINT_MARGINS;\n\tconst fitToPage = print.fitToWidthPages !== undefined || print.fitToHeightPages !== undefined;\n\tconst sheetProperties = fitToPage ? '<sheetPr><pageSetUpPr fitToPage=\"1\" autoPageBreaks=\"0\"/></sheetPr>' : \"\";\n\tconst result = sheetProperties ? content.replace(\"<sheetViews\", `${sheetProperties}<sheetViews`) : content;\n\tconst pageMargins = `<pageMargins left=\"${margins.left}\" right=\"${margins.right}\" top=\"${margins.top}\" bottom=\"${margins.bottom}\" header=\"${margins.header}\" footer=\"${margins.footer}\"/>`;\n\tconst pageSetupAttributes = [\n\t\t`paperSize=\"${PAPER_SIZE[print.paperSize ?? DEFAULT_PAPER_SIZE]}\"`,\n\t\t`orientation=\"${print.orientation}\"`,\n\t\tprint.fitToWidthPages !== undefined ? `fitToWidth=\"${print.fitToWidthPages}\"` : \"\",\n\t\tprint.fitToHeightPages !== undefined ? `fitToHeight=\"${print.fitToHeightPages}\"` : \"\",\n\t\tprint.pageOrder ? `pageOrder=\"${print.pageOrder}\"` : \"\",\n\t\t'usePrinterDefaults=\"0\"'\n\t]\n\t\t.filter(Boolean)\n\t\t.join(\" \");\n\tconst additions = [\n\t\tpageMargins,\n\t\t`<pageSetup ${pageSetupAttributes}/>`,\n\t\tbuildHeaderFooterXml(EXCEL_HEADER_FOOTER_ELEMENT, print.header, print.footer),\n\t\tbuildBreaksXml(EXCEL_ROW_BREAKS_ELEMENT, print.rowBreaksAfter),\n\t\tbuildBreaksXml(EXCEL_COLUMN_BREAKS_ELEMENT, print.columnBreaksAfter)\n\t].join(\"\");\n\tconst drawingIndex = result.indexOf(\"<drawing\");\n\treturn drawingIndex >= 0\n\t\t? `${result.slice(0, drawingIndex)}${additions}${result.slice(drawingIndex)}`\n\t\t: result.replace(\"</worksheet>\", `${additions}</worksheet>`);\n}\n\nfunction quoteFormulaSheetName(name: string): string {\n\treturn `'${name.replaceAll(\"'\", \"''\")}'`;\n}\n\nfunction buildDefinedNames(sheetNames: readonly string[], sheets: readonly ExcelMatrixWorkbookSheet[]): string {\n\tconst definitions: string[] = [];\n\tfor (let sheetIndex = 0; sheetIndex < sheets.length; sheetIndex += 1) {\n\t\tconst print = sheets[sheetIndex]?.print;\n\t\tif (!print) continue;\n\t\tconst sheetName = quoteFormulaSheetName(sheetNames[sheetIndex] ?? `Лист ${sheetIndex + 1}`);\n\t\tconst titles = [\n\t\t\tprint.repeatRows ? `${sheetName}!$${print.repeatRows[0]}:$${print.repeatRows[1]}` : \"\",\n\t\t\tprint.repeatColumns\n\t\t\t\t? `${sheetName}!$${numberToColumnName(print.repeatColumns[0])}:$${numberToColumnName(print.repeatColumns[1])}`\n\t\t\t\t: \"\"\n\t\t]\n\t\t\t.filter(Boolean)\n\t\t\t.join(\",\");\n\t\tif (titles) {\n\t\t\tdefinitions.push(`<definedName name=\"_xlnm.Print_Titles\" localSheetId=\"${sheetIndex}\">${escapeXmlValue(titles)}</definedName>`);\n\t\t}\n\t\tif (print.printArea) {\n\t\t\tconst { firstRow, lastRow, firstColumn, lastColumn } = print.printArea;\n\t\t\tconst area = `${sheetName}!$${numberToColumnName(firstColumn)}$${firstRow}:$${numberToColumnName(lastColumn)}$${lastRow}`;\n\t\t\tdefinitions.push(`<definedName name=\"_xlnm.Print_Area\" localSheetId=\"${sheetIndex}\">${escapeXmlValue(area)}</definedName>`);\n\t\t}\n\t}\n\treturn definitions.join(\"\");\n}\n\n/**\n * Дополняет штатный контейнер definedNames, который write-excel-file уже\n * создаёт в workbook.xml. Два одноимённых контейнера формально нарушают схему\n * OOXML: Numbers читает такую книгу, а Microsoft Excel отклоняет её.\n */\nfunction applyWorkbookDefinedNames(content: string, definedNames: string): string {\n\tif (/<definedNames\\s*\\/>/.test(content)) {\n\t\treturn content.replace(/<definedNames\\s*\\/>/, `<definedNames>${definedNames}</definedNames>`);\n\t}\n\tif (content.includes(EXCEL_DEFINED_NAMES_END_TAG)) {\n\t\treturn content.replace(EXCEL_DEFINED_NAMES_END_TAG, `${definedNames}</definedNames>`);\n\t}\n\treturn content.replace(\"</sheets>\", `</sheets><definedNames>${definedNames}</definedNames>`);\n}\n\n/** Настройки печати требуют двух согласованных OpenXML-частей: worksheet и workbook defined names. */\nfunction createMatrixPrintFeature(\n\tsheetNames: readonly string[],\n\tsheets: readonly ExcelMatrixWorkbookSheet[]\n): Feature<BrowserExcelFileContent> | undefined {\n\tif (!sheets.some(({ print }) => print)) return undefined;\n\tconst definedNames = buildDefinedNames(sheetNames, sheets);\n\treturn {\n\t\tfiles: {\n\t\t\ttransform: {\n\t\t\t\t\"xl/worksheets/sheet{id}.xml\": {\n\t\t\t\t\ttransform: (content, _options, properties) => {\n\t\t\t\t\t\tconst setup = sheets[properties.sheetIndex]?.print;\n\t\t\t\t\t\treturn setup ? applyWorksheetPrintSetup(content, setup) : content;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\"xl/workbook.xml\": {\n\t\t\t\t\ttransform: (content) => (definedNames ? applyWorkbookDefinedNames(content, definedNames) : content)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Формирует Blob без побочного эффекта скачивания.\n *\n * Этот вход нужен предпросмотру, file validation и сценариям, где download\n * выполняет отдельный browser-owner. KTK-specific layout сюда не передаётся.\n */\nexport async function createExcelMatrixWorkbookBlob(args: ExcelMatrixWorkbookArgs): Promise<Blob> {\n\tif (args.sheets.length === 0) throw new Error(EXCEL_WORKBOOK_EMPTY_MESSAGE);\n\tif (args.defaultFont) {\n\t\tif (!args.defaultFont.fontFamily.trim()) throw new Error(\"Имя базового шрифта Excel-книги не может быть пустым\");\n\t\tif (!Number.isFinite(args.defaultFont.fontSize) || args.defaultFont.fontSize <= 0) {\n\t\t\tthrow new Error(\"Размер базового шрифта Excel-книги должен быть положительным числом\");\n\t\t}\n\t}\n\tfor (const sheet of args.sheets) {\n\t\tif (sheet.rows.length === 0) throw new Error(`Лист «${sheet.name}» не содержит строк`);\n\t\tif (sheet.print) validatePrintSetup(sheet.print);\n\t}\n\n\tconst sheetNames = resolveExcelSheetNames(args.sheets.map(({ name }) => name));\n\tconst sheets: Sheet<BrowserExcelFileContent>[] = args.sheets.map((sheet, index) => ({\n\t\tdata: sheet.rows.map((row) => [...row]),\n\t\tsheet: sheetNames[index],\n\t\tcolumns: sheet.columns?.map((column) => ({ width: column.width })),\n\t\tshowGridLines: sheet.showGridLines,\n\t\tzoomScale: sheet.zoomScale\n\t}));\n\tconst printFeature = createMatrixPrintFeature(sheetNames, args.sheets);\n\treturn writeXlsxFile(sheets, {\n\t\tfontFamily: args.defaultFont?.fontFamily,\n\t\tfontSize: args.defaultFont?.fontSize,\n\t\tfeatures: printFeature ? [printFeature] : undefined\n\t}).toBlob();\n}\n\n/** Скачивает готовую матричную книгу из явного пользовательского действия. */\nexport async function downloadExcelMatrixWorkbook(fileName: string, args: ExcelMatrixWorkbookArgs): Promise<void> {\n\tconst blob = await createExcelMatrixWorkbookBlob(args);\n\tdownloadFileFromBlob(fileName, blob);\n}\n","import { DEFAULT_DATE_PRESET_NAMES, getDatePreset, type DateFormatPreset } from \"../formatters/date\";\nimport { NUMBER_FORMAT_STYLE_PERCENT } from \"../formatters/number/numberFormatConstants\";\nimport { NUMBER_PRESET_NAME_DECIMAL, NUMBER_PRESET_NAME_INTEGER } from \"../formatters/number/numberPresetNameConstants\";\nimport { getNumberPreset, resolveNumberPreset } from \"../formatters/number/presets\";\nimport {\n\tvalidateFormattersPipelineConfig,\n\ttype FormattersPipelineConfig,\n\ttype FormattersPipelineTypedValueFormatConfig\n} from \"../formatters/pipeline\";\nimport { PIPELINE_FORMATTER_TYPED_VALUE_FORMAT } from \"../formatters/pipeline/formattersPipelineConstants\";\nimport { type ColumnRole, type ScalarMetaType } from \"../metadata/metadataTypes\";\nimport { isScalarBooleanType, isScalarDateType, isScalarIntegerType, isScalarNumericType } from \"../metadata/scalarTypeClassification\";\nimport { SCALAR_ROLE_MEASURE, SCALAR_TYPE_DATETIME, SCALAR_TYPE_DATETIME_OFFSET, SCALAR_TYPE_TIME } from \"../metadata/scalarTypeConstants\";\n\nimport { downloadExcelFile, downloadExcelWorkbook, type ExcelCellStyle, type ExcelColumn, type ExcelRow } from \"./excel\";\n\nexport type TableExcelColumnDescriptor = {\n\tid: string;\n\theader: string;\n\twidth?: number;\n\trole?: ColumnRole;\n\todataType?: ScalarMetaType;\n\tclientOnly?: boolean;\n\tformattersPipeline?: FormattersPipelineConfig;\n};\n\nexport type ResolvedExcelTable = {\n\tcolumns: ExcelColumn[];\n\trows: ExcelRow[];\n\tcellStyles?: ReadonlyArray<Readonly<Record<string, ExcelCellStyle | undefined>>>;\n};\n\nexport type DownloadResolvedExcelTableArgs = {\n\tfileName: string;\n\ttable: ResolvedExcelTable;\n\tautoFilter?: boolean;\n};\n\n/** Один подготовленный табличный лист generic Excel-книги. */\nexport type ResolvedExcelWorkbookSheet = {\n\t/** Желаемое имя листа. */\n\tname: string;\n\t/** Подготовленные колонки, строки и optional стили ячеек. */\n\ttable: ResolvedExcelTable;\n\t/** Включить автофильтр для этого листа. По умолчанию включён. */\n\tautoFilter?: boolean;\n};\n\n/** Аргументы скачивания книги из нескольких подготовленных таблиц. */\nexport type DownloadResolvedExcelWorkbookArgs = {\n\t/** Имя скачиваемого `.xlsx` файла. */\n\tfileName: string;\n\t/** Табличные листы в порядке отображения в книге. */\n\tsheets: ResolvedExcelWorkbookSheet[];\n};\n\nconst INTEGER_EXCEL_FORMAT = \"#,##0\";\nconst DEFAULT_DECIMAL_EXCEL_FORMAT = \"#,##0.0\";\n// Prefix определяет семейство встроенного date preset, а не скалярный тип данных.\nconst DATE_PRESET_PREFIX_DATE = \"date\";\nconst DATE_PRESET_PREFIX_TIME = \"time\";\nconst DATE_PRESET_PREFIX_DATETIME = \"datetime\";\nconst EXCEL_DATE_FORMAT = \"dd.mm.yyyy\";\n/**\n * Excel-маски календарных пресетов сохраняют экранную детализацию:\n * month-* выводит день и месяц без года, а month-year-* — месяц и год без дня.\n */\nconst EXCEL_DAY_MONTH_SHORT_FORMAT = \"dd.mm\";\nconst EXCEL_DAY_MONTH_MEDIUM_FORMAT = \"d mmm\";\nconst EXCEL_DAY_MONTH_LONG_FORMAT = \"d mmmm\";\nconst EXCEL_MONTH_YEAR_MEDIUM_FORMAT = \"mmm yyyy\";\nconst EXCEL_MONTH_YEAR_LONG_FORMAT = \"mmmm yyyy\";\nconst EXCEL_TIME_FORMAT = \"hh:mm\";\nconst EXCEL_TIME_SECONDS_FORMAT = \"hh:mm:ss\";\nconst EXCEL_DATETIME_FORMAT = `${EXCEL_DATE_FORMAT} ${EXCEL_TIME_FORMAT}`;\nconst EXCEL_DATETIME_SECONDS_FORMAT = `${EXCEL_DATE_FORMAT} ${EXCEL_TIME_SECONDS_FORMAT}`;\n\nfunction resolveTypedValueFormatConfig(\n\tformattersPipeline: FormattersPipelineConfig | undefined\n): FormattersPipelineTypedValueFormatConfig | undefined {\n\tconst validation = validateFormattersPipelineConfig(formattersPipeline);\n\tconst typedValueFormatStep = validation.plan?.steps.find((step) => step.type === PIPELINE_FORMATTER_TYPED_VALUE_FORMAT);\n\n\treturn typedValueFormatStep?.type === PIPELINE_FORMATTER_TYPED_VALUE_FORMAT ? typedValueFormatStep.config : undefined;\n}\n\nexport function resolveTableExcelColumnType(descriptor: TableExcelColumnDescriptor): ExcelColumn[\"type\"] {\n\tif (descriptor.clientOnly) return Number;\n\tif (isScalarDateType(descriptor.odataType)) return Date;\n\tif (isScalarBooleanType(descriptor.odataType)) return Boolean;\n\tif (isScalarNumericType(descriptor.odataType)) return Number;\n\tif (descriptor.role === SCALAR_ROLE_MEASURE) return Number;\n\treturn String;\n}\n\nfunction resolveNumberPresetName(descriptor: TableExcelColumnDescriptor): string {\n\tconst configuredPresetName = resolveTypedValueFormatConfig(descriptor.formattersPipeline)?.numberPresetName?.trim();\n\tif (configuredPresetName && getNumberPreset(configuredPresetName)) return configuredPresetName;\n\tif (isScalarIntegerType(descriptor.odataType)) return NUMBER_PRESET_NAME_INTEGER;\n\treturn NUMBER_PRESET_NAME_DECIMAL;\n}\n\nfunction resolveExcelNumberFormat(descriptor: TableExcelColumnDescriptor): string {\n\tconst preset = getNumberPreset(resolveNumberPresetName(descriptor));\n\tif (!preset) return DEFAULT_DECIMAL_EXCEL_FORMAT;\n\n\tconst resolvedPreset = resolveNumberPreset(preset);\n\tconst format = resolvedPreset.decimals > 0 ? `#,##0.${\"0\".repeat(resolvedPreset.decimals)}` : INTEGER_EXCEL_FORMAT;\n\n\t// Excel масштабирует числовую долю только при отображении native %-маски.\n\t// Имя preset не задаёт семантику: старый percent без style остаётся decimal.\n\treturn resolvedPreset.style === NUMBER_FORMAT_STYLE_PERCENT ? `${format}%` : format;\n}\n\nfunction resolveDatePresetName(descriptor: TableExcelColumnDescriptor): string {\n\tconst configuredPresetName = resolveTypedValueFormatConfig(descriptor.formattersPipeline)?.datePresetName?.trim();\n\tif (configuredPresetName) return configuredPresetName;\n\tif (descriptor.odataType === SCALAR_TYPE_TIME) return DEFAULT_DATE_PRESET_NAMES.time;\n\tif (descriptor.odataType === SCALAR_TYPE_DATETIME || descriptor.odataType === SCALAR_TYPE_DATETIME_OFFSET)\n\t\treturn DEFAULT_DATE_PRESET_NAMES.datetime;\n\treturn DEFAULT_DATE_PRESET_NAMES.date;\n}\n\nfunction normalizeDatePatternForExcel(pattern: string): string {\n\treturn pattern.replace(/H/g, \"h\").replace(/M/g, \"m\");\n}\n\nfunction resolveBuiltinDatePresetExcelFormat(presetName: string): string | undefined {\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.odataDatetime || presetName === DEFAULT_DATE_PRESET_NAMES.abapDatetime) {\n\t\treturn EXCEL_DATETIME_SECONDS_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.odataDate || presetName === DEFAULT_DATE_PRESET_NAMES.abapDate) {\n\t\treturn EXCEL_DATE_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.monthShort) {\n\t\treturn EXCEL_DAY_MONTH_SHORT_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.monthMedium) {\n\t\treturn EXCEL_DAY_MONTH_MEDIUM_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.monthLong) {\n\t\treturn EXCEL_DAY_MONTH_LONG_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.monthYearMedium) {\n\t\treturn EXCEL_MONTH_YEAR_MEDIUM_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.monthYearLong) {\n\t\treturn EXCEL_MONTH_YEAR_LONG_FORMAT;\n\t}\n\n\tif (presetName.startsWith(DATE_PRESET_PREFIX_DATETIME)) {\n\t\treturn presetName === DEFAULT_DATE_PRESET_NAMES.datetime || presetName === DEFAULT_DATE_PRESET_NAMES.datetimeShort\n\t\t\t? EXCEL_DATETIME_FORMAT\n\t\t\t: EXCEL_DATETIME_SECONDS_FORMAT;\n\t}\n\n\tif (presetName.startsWith(DATE_PRESET_PREFIX_TIME)) {\n\t\treturn presetName === DEFAULT_DATE_PRESET_NAMES.time || presetName === DEFAULT_DATE_PRESET_NAMES.timeShort\n\t\t\t? EXCEL_TIME_FORMAT\n\t\t\t: EXCEL_TIME_SECONDS_FORMAT;\n\t}\n\n\tif (presetName.startsWith(DATE_PRESET_PREFIX_DATE)) return EXCEL_DATE_FORMAT;\n\n\treturn undefined;\n}\n\nfunction resolveExcelDateFormatFromPreset(presetName: string, preset: DateFormatPreset | undefined): string {\n\tconst builtinFormat = resolveBuiltinDatePresetExcelFormat(presetName);\n\tif (builtinFormat) return builtinFormat;\n\tif (preset?.pattern) return normalizeDatePatternForExcel(preset.pattern);\n\n\t// Настройка datePresetName исторически хранит и ручной шаблон. Если имени\n\t// нет в реестре, передаём шаблон в Excel как есть после нормализации токенов.\n\treturn normalizeDatePatternForExcel(presetName);\n}\n\nfunction resolveExcelDateFormat(descriptor: TableExcelColumnDescriptor): string {\n\tconst presetName = resolveDatePresetName(descriptor);\n\treturn resolveExcelDateFormatFromPreset(presetName, getDatePreset(presetName));\n}\n\nfunction resolveTableExcelColumnFormat(descriptor: TableExcelColumnDescriptor, type: ExcelColumn[\"type\"]): string | undefined {\n\tif (type === Number) return resolveExcelNumberFormat(descriptor);\n\tif (type === Date) return resolveExcelDateFormat(descriptor);\n\treturn undefined;\n}\n\nexport function createTableExcelColumn(descriptor: TableExcelColumnDescriptor): ExcelColumn {\n\tconst type = resolveTableExcelColumnType(descriptor);\n\treturn {\n\t\tid: descriptor.id,\n\t\theader: descriptor.header,\n\t\twidth: descriptor.width,\n\t\ttype,\n\t\tformat: resolveTableExcelColumnFormat(descriptor, type)\n\t};\n}\n\nexport async function downloadResolvedExcelTable({ fileName, table, autoFilter = true }: DownloadResolvedExcelTableArgs): Promise<void> {\n\tawait downloadExcelFile({\n\t\tfileName,\n\t\tcolumns: table.columns,\n\t\trows: table.rows,\n\t\tautoFilter,\n\t\tgetCellStyle: ({ rowIndex, column }) => table.cellStyles?.[rowIndex]?.[column.id]\n\t});\n}\n\n/** Скачивает многолистовую книгу из таблиц, уже подготовленных доменными consumers. */\nexport async function downloadResolvedExcelWorkbook({ fileName, sheets }: DownloadResolvedExcelWorkbookArgs): Promise<void> {\n\tawait downloadExcelWorkbook({\n\t\tfileName,\n\t\tsheets: sheets.map(({ name, table, autoFilter = true }) => ({\n\t\t\tname,\n\t\t\tcolumns: table.columns,\n\t\t\trows: table.rows,\n\t\t\tautoFilter,\n\t\t\tgetCellStyle: ({ rowIndex, column }) => table.cellStyles?.[rowIndex]?.[column.id]\n\t\t}))\n\t});\n}\n"],"mappings":";;;;;;;AACA,IAAa,IAA+B,wDC0CtC,KAA0D;CAC/D,aAAa;CACb,SAAS;CACT,SAAS;CACT,OAAO;AACR,GAEM,IAAoB;CACzB,YAAY;CACZ,mBAAmB;CACnB,mBAAmB;AACpB,GAEM,IAA8B,IAC9B,KAAsC,8BACtC,KAAoC,YACpC,IAA8B;AAQpC,SAAgB,EAA+B,GAAsD;CACpG,IAAM,IAAY,IAAQ,GAAwB,KAAS,KAAA;CAC3D,OAAO,IAAY,EAAE,aAAU,IAAI,KAAA;AACpC;AAOA,SAAS,EAAmB,GAAuB;CAClD,IAAI,IAAQ,IAAQ,GAChB,IAAM;CAEV,OAAO,IAAQ,IAAG;EACjB,IAAM,KAAa,IAAQ,KAAA;EAE3B,AADA,IAAM,OAAO,aAAA,KAAiD,CAAS,IAAI,GAC3E,IAAQ,KAAK,OAAO,IAAQ,KAAA,EAAiC;CAC9D;CAEA,OAAO;AACR;AAQA,SAAgB,EAAwB,GAAqB,GAAsC;CAC9F,WAAe,KAAK,KAAY,IAEpC,OAAO,MAAM,EAAmB,IAAc,CAAC,IAAI;AACpD;AAQA,SAAS,EAAqC,GAAyE;CACjH,MAAK,KAAK,OAAO,GAEtB,OAAO,EACN,OAAO,EACN,WAAW,EACV,+BAA+B,EAC9B,YAAY,GAAS,GAAU,MAAe;EAC7C,IAAM,IAAM,EAAK,EAAW;EAC5B,OAAO,IAAM,EAAQ,QAAQ,gBAAgB,gCAAgC,EAAI,IAAI,IAAI;CAC1F,EACD,EACD,EACD,EACD;AACD;AASA,SAAgB,EAAuB,GAAoC;CAC1E,IAAM,oBAAY,IAAI,IAAY,GAC5B,IAA0B,CAAC;CAEjC,KAAK,IAAI,IAAQ,GAAG,IAAQ,EAAM,QAAQ,KAAS,GAAG;EACrD,IAAM,IAAe,QAAQ,IAAQ,KAO/B,IANiB,EAAM,EAAM,EAChC,QAAQ,IAAqC,GAAG,CAAC,CAClD,QAAQ,GAA6B,GAAG,CAAC,CACzC,KAAK,CAAC,CACN,QAAQ,IAAmC,EAAE,CAAC,CAC9C,KAAK,KAC4B,GAC/B,IAAe,EAAS,MAAM,GAAG,CAA2B,GAC5D,IAAiB;EAErB,OAAO,EAAU,IAAI,EAAa,kBAAkB,CAAC,IAAG;GACvD,IAAM,IAAS,KAAK,EAAe;GAEnC,AADA,IAAe,GAAG,EAAS,MAAM,GAAG,IAA8B,EAAO,MAAM,IAAI,KACnF,KAAkB;EACnB;EAGA,AADA,EAAU,IAAI,EAAa,kBAAkB,CAAC,GAC9C,EAAc,KAAK,CAAY;CAChC;CAEA,OAAO;AACR;AAQA,SAAS,GAAmB,GAAgB,GAA2B;CAClE,SAAS,QAAQ,MAAU,IAE/B;MAAI,MAAS,QAAQ;GACpB,IAAM,IAAc,OAAO,KAAU,WAAW,IAAQ,OAAO,CAAK;GACpE,OAAO,OAAO,SAAS,CAAW,IAAI,IAAc,KAAA;EACrD;EAMA,OAJI,MAAS,SAAe,OAAO,CAAK,IACpC,MAAS,UAAgB,EAAQ,IACjC,MAAS,OAAa,aAAiB,OAAO,IAAS,EAAU,CAAK,KAAK,KAAA,IAExE;CANP;AAOD;AAQA,SAAgB,EAAoB,GAAyE;CAO5G,IAAM,IAAuB,CANH,EAAK,QAAQ,KAAK,OAAY;EACvD,MAAM;EACN,OAAO,EAAO;EACd,GAAG;CACJ,EAE8B,CAAS;CAEvC,KAAK,IAAI,IAAW,GAAG,IAAW,EAAK,KAAK,QAAQ,KAAY;EAC/D,IAAM,IAAM,EAAK,KAAK,IAChB,IAAmB,CAAC;EAE1B,KAAK,IAAI,IAAc,GAAG,IAAc,EAAK,QAAQ,QAAQ,KAAe;GAC3E,IAAM,IAAS,EAAK,QAAQ,IACtB,IAAQ,GAAmB,EAAI,EAAO,KAAK,EAAO,IAAI,GACtD,IAAQ,EAAK,eAAe;IAAE;IAAK;IAAQ;IAAU;GAAY,CAAC;GAExE,EAAS,KAAK;IACb;IACA,MAAM,EAAO;IACb,QAAQ,EAAO;IACf,GAAG;GACJ,CAAC;EACF;EAEA,EAAU,KAAK,CAAQ;CACxB;CAEA,OAAO;AACR;AAQA,eAAsB,EAAsB,GAAgD;CAC3F,IAAI,EAAK,OAAO,WAAW,GAC1B,MAAU,MAAM,CAA4B;CAG7C,IAAM,IAAa,EAAuB,EAAK,OAAO,KAAK,MAAU,EAAM,IAAI,CAAC,GAC1E,IAA4C,CAAC,GAC7C,IAA2C,EAAK,OAAO,KAAK,GAAO,MAAU;EAClF,IAAM,IAAO,EAAoB,CAAK;EAGtC,OAFA,EAAe,KAAK,EAAM,aAAa,EAAwB,EAAM,QAAQ,QAAQ,EAAK,MAAM,IAAI,KAAA,CAAS,GAEtG;GACN;GACA,OAAO,EAAW;GAClB,SAAS,EAAM,QAAQ,KAAK,OAAY,EACvC,OAAO,EAAO,MACf,EAAE;EACH;CACD,CAAC,GACK,IAAoB,EAAiD,CAAc;CAEzF,MAAM,EAAc,GAAQ,EAC3B,UAAU,IAAoB,CAAC,CAAiB,IAAI,KAAA,EACrD,CAAC,CAAC,CAAC,OAAO,EAAK,QAAQ;AACxB;AAQA,eAAsB,EAAkB,GAA4C;CACnF,MAAM,EAAsB;EAC3B,UAAU,EAAK;EACf,QAAQ,CACP;GACC,MAAM;GACN,SAAS,EAAK;GACd,MAAM,EAAK;GACX,YAAY,EAAK;GACjB,cAAc,EAAK;EACpB,CACD;CACD,CAAC;AACF;;;ACtQA,IAAM,KAA8B,gBAC9B,KAA8B,aAC9B,KAA2B,aAC3B,IAA8B,mBAmF9B,IAAwB;CAC7B,MAAM;CACN,OAAO;CACP,KAAK;CACL,QAAQ;CACR,QAAQ;CACR,QAAQ;AACT,GAEM,IAAa;CAAE,IAAI;CAAG,IAAI;AAAE,GAC5B,IAA8C,MAE9C,IAAuB;AAE7B,SAAS,EAAuB,GAAuB;CACtD,OAAO,EAAe,EAAM,WAAW,KAAK,IAAI,CAAC;AAClD;AAEA,SAAS,EAAmB,GAAuB;CAClD,IAAI,IAAQ,GACR,IAAS;CACb,OAAO,IAAQ,IAAG;EACjB,IAAM,KAAa,IAAQ,KAAA;EAE3B,AADA,IAAS,OAAO,aAAA,KAAiD,CAAS,IAAI,GAC9E,IAAQ,KAAK,OAAO,IAAQ,KAAA,EAAiC;CAC9D;CACA,OAAO;AACR;AAEA,SAAS,EAAsB,GAAe,GAAoB;CACjE,IAAI,CAAC,OAAO,UAAU,CAAK,KAAK,KAAS,GAAG,MAAU,MAAM,GAAG,EAAK,wCAAwC;AAC7G;AAEA,SAAS,EAAyB,GAAe,GAAoB;CACpE,IAAI,CAAC,OAAO,UAAU,CAAK,KAAK,IAAQ,GAAG,MAAU,MAAM,GAAG,EAAK,0CAA0C;AAC9G;AAEA,SAAS,EAAc,GAAkC,GAAoB;CAG5E,IAFA,EAAsB,EAAM,IAAI,GAAG,EAAK,SAAS,GACjD,EAAsB,EAAM,IAAI,GAAG,EAAK,QAAQ,GAC5C,EAAM,KAAK,EAAM,IAAI,MAAU,MAAM,GAAG,EAAK,oCAAoC;AACtF;AAEA,SAAS,EAAmB,GAA8B;CAKzD,AAHI,EAAM,oBAAoB,KAAA,KAAW,EAAyB,EAAM,iBAAiB,iBAAiB,GACtG,EAAM,qBAAqB,KAAA,KAAW,EAAyB,EAAM,kBAAkB,kBAAkB,GACzG,EAAM,cAAY,EAAc,EAAM,YAAY,YAAY,GAC9D,EAAM,iBAAe,EAAc,EAAM,eAAe,eAAe;CAC3E,KAAK,IAAM,KAAS,EAAM,qBAAqB,CAAC,GAAG,EAAsB,GAAO,mBAAmB;CACnG,KAAK,IAAM,KAAS,EAAM,kBAAkB,CAAC,GAAG,EAAsB,GAAO,gBAAgB;CAC7F,IAAI,EAAM,cACT,EAAsB,EAAM,UAAU,UAAU,oBAAoB,GACpE,EAAsB,EAAM,UAAU,SAAS,mBAAmB,GAClE,EAAsB,EAAM,UAAU,aAAa,uBAAuB,GAC1E,EAAsB,EAAM,UAAU,YAAY,sBAAsB,GACpE,EAAM,UAAU,WAAW,EAAM,UAAU,WAAW,EAAM,UAAU,cAAc,EAAM,UAAU,aACvG,MAAU,MAAM,kDAAkD;AAGrE;AAEA,SAAS,EACR,GACA,GACA,GACS;CACT,IAAI,CAAC,KAAU,CAAC,GAAQ,OAAO;CAC/B,IAAM,KAAgB,MAChB,IACW;EACf,EAAM,OAAO,SAAS,EAAuB,EAAM,IAAI,MAAM;EAC7D,EAAM,SAAS,SAAS,EAAuB,EAAM,MAAM,MAAM;EACjE,EAAM,QAAQ,SAAS,EAAuB,EAAM,KAAK,MAAM;EAC/D,EAAM,oBAAoB,oCAAoC;CAC/D,CAAC,CAAC,KAAK,EACA,IAPY,IASd,IAAY,EAAa,CAAM,GAC/B,IAAY,EAAa,CAAM;CACrC,OAAO,IAAI,EAAQ,GAAG,IAAY,cAAc,EAAU,gBAAgB,KAAK,IAAY,cAAc,EAAU,gBAAgB,GAAG,IAAI,EAAQ;AACnJ;AAEA,SAAS,EACR,GACA,GACS;CACT,IAAI,CAAC,KAAU,EAAO,WAAW,GAAG,OAAO;CAC3C,IAAM,IAAe,CAAC,GAAG,IAAI,IAAI,CAAM,CAAC,CAAC,CAAC,MAAM,GAAM,MAAU,IAAO,CAAK;CAC5E,OAAO,IAAI,EAAQ,UAAU,EAAa,OAAO,sBAAsB,EAAa,OAAO,IAAI,EAC7F,KAAK,MAAU,YAAY,EAAM,iBAAiB,EAAqB,YAAY,CAAC,CACpF,KAAK,EAAE,EAAE,IAAI,EAAQ;AACxB;AAEA,SAAS,EAAyB,GAAiB,GAAgC;CAClF,IAAM,IAAU,EAAM,WAAW,GAE3B,IADY,EAAM,oBAAoB,KAAA,KAAa,EAAM,qBAAqB,KAAA,IAChD,2EAAuE,IACrG,IAAS,IAAkB,EAAQ,QAAQ,eAAe,GAAG,EAAgB,YAAY,IAAI,GAY7F,IAAY;EACjB,sBAZyC,EAAQ,KAAK,WAAW,EAAQ,MAAM,SAAS,EAAQ,IAAI,YAAY,EAAQ,OAAO,YAAY,EAAQ,OAAO,YAAY,EAAQ,OAAO;EAarL,cAZ2B;GAC3B,cAAc,EAAW,EAAM,aAAa,GAAoB;GAChE,gBAAgB,EAAM,YAAY;GAClC,EAAM,oBAAoB,KAAA,IAAsD,KAA1C,eAAe,EAAM,gBAAgB;GAC3E,EAAM,qBAAqB,KAAA,IAAwD,KAA5C,gBAAgB,EAAM,iBAAiB;GAC9E,EAAM,YAAY,cAAc,EAAM,UAAU,KAAK;GACrD;EACD,CAAC,CACC,OAAO,OAAO,CAAC,CACf,KAAK,GAGQ,EAAoB;EAClC,EAAqB,IAA6B,EAAM,QAAQ,EAAM,MAAM;EAC5E,EAAe,IAA0B,EAAM,cAAc;EAC7D,EAAe,IAA6B,EAAM,iBAAiB;CACpE,CAAC,CAAC,KAAK,EAAE,GACH,IAAe,EAAO,QAAQ,UAAU;CAC9C,OAAO,KAAgB,IACpB,GAAG,EAAO,MAAM,GAAG,CAAY,IAAI,IAAY,EAAO,MAAM,CAAY,MACxE,EAAO,QAAQ,gBAAgB,GAAG,EAAU,aAAa;AAC7D;AAEA,SAAS,EAAsB,GAAsB;CACpD,OAAO,IAAI,EAAK,WAAW,KAAK,IAAI,EAAE;AACvC;AAEA,SAAS,EAAkB,GAA+B,GAAqD;CAC9G,IAAM,IAAwB,CAAC;CAC/B,KAAK,IAAI,IAAa,GAAG,IAAa,EAAO,QAAQ,KAAc,GAAG;EACrE,IAAM,IAAQ,EAAO,EAAW,EAAE;EAClC,IAAI,CAAC,GAAO;EACZ,IAAM,IAAY,EAAsB,EAAW,MAAe,QAAQ,IAAa,GAAG,GACpF,IAAS,CACd,EAAM,aAAa,GAAG,EAAU,IAAI,EAAM,WAAW,GAAG,IAAI,EAAM,WAAW,OAAO,IACpF,EAAM,gBACH,GAAG,EAAU,IAAI,EAAmB,EAAM,cAAc,EAAE,EAAE,IAAI,EAAmB,EAAM,cAAc,EAAE,MACzG,EACJ,CAAC,CACC,OAAO,OAAO,CAAC,CACf,KAAK,GAAG;EAIV,IAHI,KACH,EAAY,KAAK,wDAAwD,EAAW,IAAI,EAAe,CAAM,EAAE,eAAe,GAE3H,EAAM,WAAW;GACpB,IAAM,EAAE,aAAU,YAAS,gBAAa,kBAAe,EAAM,WACvD,IAAO,GAAG,EAAU,IAAI,EAAmB,CAAW,EAAE,GAAG,EAAS,IAAI,EAAmB,CAAU,EAAE,GAAG;GAChH,EAAY,KAAK,sDAAsD,EAAW,IAAI,EAAe,CAAI,EAAE,eAAe;EAC3H;CACD;CACA,OAAO,EAAY,KAAK,EAAE;AAC3B;AAOA,SAAS,EAA0B,GAAiB,GAA8B;CAOjF,OANI,sBAAsB,KAAK,CAAO,IAC9B,EAAQ,QAAQ,uBAAuB,iBAAiB,EAAa,gBAAgB,IAEzF,EAAQ,SAAS,CAA2B,IACxC,EAAQ,QAAQ,GAA6B,GAAG,EAAa,gBAAgB,IAE9E,EAAQ,QAAQ,aAAa,0BAA0B,EAAa,gBAAgB;AAC5F;AAGA,SAAS,EACR,GACA,GAC+C;CAC/C,IAAI,CAAC,EAAO,MAAM,EAAE,eAAY,CAAK,GAAG;CACxC,IAAM,IAAe,EAAkB,GAAY,CAAM;CACzD,OAAO,EACN,OAAO,EACN,WAAW;EACV,+BAA+B,EAC9B,YAAY,GAAS,GAAU,MAAe;GAC7C,IAAM,IAAQ,EAAO,EAAW,WAAW,EAAE;GAC7C,OAAO,IAAQ,EAAyB,GAAS,CAAK,IAAI;EAC3D,EACD;EACA,mBAAmB,EAClB,YAAY,MAAa,IAAe,EAA0B,GAAS,CAAY,IAAI,EAC5F;CACD,EACD,EACD;AACD;AAQA,eAAsB,EAA8B,GAA8C;CACjG,IAAI,EAAK,OAAO,WAAW,GAAG,MAAU,MAAM,CAA4B;CAC1E,IAAI,EAAK,aAAa;EACrB,IAAI,CAAC,EAAK,YAAY,WAAW,KAAK,GAAG,MAAU,MAAM,sDAAsD;EAC/G,IAAI,CAAC,OAAO,SAAS,EAAK,YAAY,QAAQ,KAAK,EAAK,YAAY,YAAY,GAC/E,MAAU,MAAM,qEAAqE;CAEvF;CACA,KAAK,IAAM,KAAS,EAAK,QAAQ;EAChC,IAAI,EAAM,KAAK,WAAW,GAAG,MAAU,MAAM,SAAS,EAAM,KAAK,oBAAoB;EACrF,AAAI,EAAM,SAAO,EAAmB,EAAM,KAAK;CAChD;CAEA,IAAM,IAAa,EAAuB,EAAK,OAAO,KAAK,EAAE,cAAW,CAAI,CAAC,GACvE,IAA2C,EAAK,OAAO,KAAK,GAAO,OAAW;EACnF,MAAM,EAAM,KAAK,KAAK,MAAQ,CAAC,GAAG,CAAG,CAAC;EACtC,OAAO,EAAW;EAClB,SAAS,EAAM,SAAS,KAAK,OAAY,EAAE,OAAO,EAAO,MAAM,EAAE;EACjE,eAAe,EAAM;EACrB,WAAW,EAAM;CAClB,EAAE,GACI,IAAe,EAAyB,GAAY,EAAK,MAAM;CACrE,OAAO,EAAc,GAAQ;EAC5B,YAAY,EAAK,aAAa;EAC9B,UAAU,EAAK,aAAa;EAC5B,UAAU,IAAe,CAAC,CAAY,IAAI,KAAA;CAC3C,CAAC,CAAC,CAAC,OAAO;AACX;AAGA,eAAsB,EAA4B,GAAkB,GAA8C;CACjH,IAAM,IAAO,MAAM,EAA8B,CAAI;CACrD,EAAqB,GAAU,CAAI;AACpC;;;AC9QA,IAAM,KAAuB,SACvB,KAA+B,WAE/B,KAA0B,QAC1B,KAA0B,QAC1B,KAA8B,YAC9B,IAAoB,cAKpB,KAA+B,SAC/B,KAAgC,SAChC,KAA8B,UAC9B,KAAiC,YACjC,KAA+B,aAC/B,IAAoB,SACpB,IAA4B,YAC5B,KAAwB,GAAG,EAAkB,GAAG,KAChD,IAAgC,GAAG,EAAkB,GAAG;AAE9D,SAAS,EACR,GACuD;CAEvD,IAAM,IADa,EAAiC,CACvB,CAAA,CAAW,MAAM,MAAM,MAAM,MAAS,EAAK,SAAS,CAAqC;CAEtH,OAAO,GAAsB,SAAA,qBAAiD,EAAqB,SAAS,KAAA;AAC7G;AAEA,SAAgB,EAA4B,GAA6D;CAMxG,OALI,EAAW,aAAmB,SAC9B,EAAiB,EAAW,SAAS,IAAU,OAC/C,EAAoB,EAAW,SAAS,IAAU,UAClD,EAAoB,EAAW,SAAS,KACxC,EAAW,SAAA,YAAqC,SAC7C;AACR;AAEA,SAAS,GAAwB,GAAgD;CAChF,IAAM,IAAuB,EAA8B,EAAW,kBAAkB,CAAC,EAAE,kBAAkB,KAAK;CAGlH,OAFI,KAAwB,EAAgB,CAAoB,IAAU,IACtE,EAAoB,EAAW,SAAS,IAAU,KAC/C;AACR;AAEA,SAAS,GAAyB,GAAgD;CACjF,IAAM,IAAS,EAAgB,GAAwB,CAAU,CAAC;CAClE,IAAI,CAAC,GAAQ,OAAO;CAEpB,IAAM,IAAiB,EAAoB,CAAM,GAC3C,IAAS,EAAe,WAAW,IAAI,SAAS,IAAI,OAAO,EAAe,QAAQ,MAAM;CAI9F,OAAO,EAAe,UAAA,YAAwC,GAAG,EAAO,KAAK;AAC9E;AAEA,SAAS,GAAsB,GAAgD;CAM9E,OAL6B,EAA8B,EAAW,kBAAkB,CAAC,EAAE,gBAAgB,KAAK,MAE5G,EAAW,cAAA,SAAuC,EAA0B,OAC5E,EAAW,cAAA,cAAsC,EAAW,cAAA,mBACxD,EAA0B,WAC3B,EAA0B;AAClC;AAEA,SAAS,EAA6B,GAAyB;CAC9D,OAAO,EAAQ,QAAQ,MAAM,GAAG,CAAC,CAAC,QAAQ,MAAM,GAAG;AACpD;AAEA,SAAS,GAAoC,GAAwC;CACpF,IAAI,MAAe,EAA0B,iBAAiB,MAAe,EAA0B,cACtG,OAAO;CAGR,IAAI,MAAe,EAA0B,aAAa,MAAe,EAA0B,UAClG,OAAO;CAGR,IAAI,MAAe,EAA0B,YAC5C,OAAO;CAGR,IAAI,MAAe,EAA0B,aAC5C,OAAO;CAGR,IAAI,MAAe,EAA0B,WAC5C,OAAO;CAGR,IAAI,MAAe,EAA0B,iBAC5C,OAAO;CAGR,IAAI,MAAe,EAA0B,eAC5C,OAAO;CAGR,IAAI,EAAW,WAAW,EAA2B,GACpD,OAAO,MAAe,EAA0B,YAAY,MAAe,EAA0B,gBAClG,KACA;CAGJ,IAAI,EAAW,WAAW,EAAuB,GAChD,OAAO,MAAe,EAA0B,QAAQ,MAAe,EAA0B,YAC9F,IACA;CAGJ,IAAI,EAAW,WAAW,EAAuB,GAAG,OAAO;AAG5D;AAEA,SAAS,GAAiC,GAAoB,GAA8C;CAO3G,OANsB,GAAoC,CACtD,MACA,GAAQ,UAAgB,EAA6B,EAAO,OAAO,IAIhE,EAA6B,CAAU;AAC/C;AAEA,SAAS,GAAuB,GAAgD;CAC/E,IAAM,IAAa,GAAsB,CAAU;CACnD,OAAO,GAAiC,GAAY,EAAc,CAAU,CAAC;AAC9E;AAEA,SAAS,GAA8B,GAAwC,GAA+C;CAC7H,IAAI,MAAS,QAAQ,OAAO,GAAyB,CAAU;CAC/D,IAAI,MAAS,MAAM,OAAO,GAAuB,CAAU;AAE5D;AAEA,SAAgB,GAAuB,GAAqD;CAC3F,IAAM,IAAO,EAA4B,CAAU;CACnD,OAAO;EACN,IAAI,EAAW;EACf,QAAQ,EAAW;EACnB,OAAO,EAAW;EAClB;EACA,QAAQ,GAA8B,GAAY,CAAI;CACvD;AACD;AAEA,eAAsB,GAA2B,EAAE,aAAU,UAAO,gBAAa,MAAuD;CACvI,MAAM,EAAkB;EACvB;EACA,SAAS,EAAM;EACf,MAAM,EAAM;EACZ;EACA,eAAe,EAAE,aAAU,gBAAa,EAAM,aAAa,EAAS,GAAG,EAAO;CAC/E,CAAC;AACF;AAGA,eAAsB,GAA8B,EAAE,aAAU,aAA4D;CAC3H,MAAM,EAAsB;EAC3B;EACA,QAAQ,EAAO,KAAK,EAAE,SAAM,UAAO,gBAAa,UAAY;GAC3D;GACA,SAAS,EAAM;GACf,MAAM,EAAM;GACZ;GACA,eAAe,EAAE,aAAU,gBAAa,EAAM,aAAa,EAAS,GAAG,EAAO;EAC/E,EAAE;CACH,CAAC;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tableExport.d.ts","sourceRoot":"","sources":["../../src/excel/tableExport.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tableExport.d.ts","sourceRoot":"","sources":["../../src/excel/tableExport.ts"],"names":[],"mappings":"AAIA,OAAO,EAEN,KAAK,wBAAwB,EAE7B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAIjF,OAAO,EAA4C,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEzH,MAAM,MAAM,0BAA0B,GAAG;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kBAAkB,CAAC,EAAE,wBAAwB,CAAC;CAC9C,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAChC,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,UAAU,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;CACjF,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,kBAAkB,CAAC;IAC1B,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,8DAA8D;AAC9D,MAAM,MAAM,0BAA0B,GAAG;IACxC,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,KAAK,EAAE,kBAAkB,CAAC;IAC1B,iEAAiE;IACjE,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,sEAAsE;AACtE,MAAM,MAAM,iCAAiC,GAAG;IAC/C,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,MAAM,EAAE,0BAA0B,EAAE,CAAC;CACrC,CAAC;AAgCF,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,0BAA0B,GAAG,WAAW,CAAC,MAAM,CAAC,CAOvG;AAqGD,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,0BAA0B,GAAG,WAAW,CAS1F;AAED,wBAAsB,0BAA0B,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAiB,EAAE,EAAE,8BAA8B,GAAG,OAAO,CAAC,IAAI,CAAC,CAQtI;AAED,uFAAuF;AACvF,wBAAsB,6BAA6B,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,iCAAiC,GAAG,OAAO,CAAC,IAAI,CAAC,CAW1H"}
|
package/dist/formatters/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { $ as e, A as t, At as n, B as r, Bt as i, C as a, Ct as o, D as s, Dt as c, E as l, Et as u, F as d, Ft as f, G as p, Gt as m, H as h, Ht as g, I as _, It as v, J as y, Jt as b, K as x, Kt as S, L as C, Lt as w, M as T, Mt as E, N as D, Nt as O, O as k, Ot as A, P as j, Pt as M, Q as N, R as P, Rt as F, S as I, St as L, T as R, Tt as z, U as B, Ut as V, V as H, Vt as U, W, Wt as G, X as K, Y as q, Z as J, _ as Y, _t as X, a as Z, at as Q, b as $, bt as ee, c as te, ct as ne, d as re, dt as ie, et as ae, f as oe, ft as se, g as ce, gt as le, h as ue, ht as de, i as fe, it as pe, j as me, jt as he, k as ge, kt as _e, l as ve, lt as ye, m as be, mt as xe, n as Se, nt as Ce, o as we, ot as Te, p as Ee, pt as De, q as Oe, qt as ke, r as Ae, rt as je, s as Me, st as Ne, t as Pe, tt as Fe, u as Ie, ut as Le, v as Re, vt as ze, w as Be, wt as Ve, x as He, xt as Ue, y as We, yt as Ge, z as Ke, zt as qe } from "../chunks/formatters-
|
|
1
|
+
import { $ as e, A as t, At as n, B as r, Bt as i, C as a, Ct as o, D as s, Dt as c, E as l, Et as u, F as d, Ft as f, G as p, Gt as m, H as h, Ht as g, I as _, It as v, J as y, Jt as b, K as x, Kt as S, L as C, Lt as w, M as T, Mt as E, N as D, Nt as O, O as k, Ot as A, P as j, Pt as M, Q as N, R as P, Rt as F, S as I, St as L, T as R, Tt as z, U as B, Ut as V, V as H, Vt as U, W, Wt as G, X as K, Y as q, Z as J, _ as Y, _t as X, a as Z, at as Q, b as $, bt as ee, c as te, ct as ne, d as re, dt as ie, et as ae, f as oe, ft as se, g as ce, gt as le, h as ue, ht as de, i as fe, it as pe, j as me, jt as he, k as ge, kt as _e, l as ve, lt as ye, m as be, mt as xe, n as Se, nt as Ce, o as we, ot as Te, p as Ee, pt as De, q as Oe, qt as ke, r as Ae, rt as je, s as Me, st as Ne, t as Pe, tt as Fe, u as Ie, ut as Le, v as Re, vt as ze, w as Be, wt as Ve, x as He, xt as Ue, y as We, yt as Ge, z as Ke, zt as qe } from "../chunks/formatters-4P9iq3wB.js";
|
|
2
2
|
import { _ as Je, b as Ye, g as Xe, v as Ze, x as Qe, y as $e } from "../chunks/array-bd7LYFto.js";
|
|
3
3
|
import { C as et, D as tt, E as nt, O as rt, S as it, T as at, _ as ot, at as st, b as ct, c as lt, d as ut, f as dt, it as ft, l as pt, m as mt, o as ht, ot as gt, p as _t, s as vt, st as yt, u as bt, v as xt, w as St, x as Ct, y as wt } from "../chunks/scalarTypeClassification-D4YcGxtQ.js";
|
|
4
4
|
import { C as Tt, D as Et, E as Dt, O as Ot, S as kt, T as At, _ as jt, a as Mt, b as Nt, c as Pt, d as Ft, f as It, g as Lt, h as Rt, i as zt, k as Bt, l as Vt, m as Ht, n as Ut, o as Wt, p as Gt, r as Kt, s as qt, t as Jt, u as Yt, v as Xt, w as Zt, x as Qt, y as $t } from "../chunks/formatDate-CNPcfNte.js";
|
|
5
|
-
import { B as en, H as tn,
|
|
6
|
-
export { dt as DATE_FORMAT_DEFAULTS, _t as DATE_FORMAT_STYLE_PRESET_NAMES, at as DATE_PATTERN_DATE_TOKENS, nt as DATE_PATTERN_TIME_TOKENS, tt as DATE_PATTERN_TOKENS, rt as DATE_PATTERN_TOKEN_RE, mt as DEFAULT_DATE_PRESET_NAMES,
|
|
5
|
+
import { B as en, H as tn, Q as nn, R as rn, U as an, V as on, _ as sn, c as cn, d as ln, f as un, g as dn, h as fn, l as pn, m as mn, n as hn, o as gn, p as _n, r as vn, s as yn, t as bn, u as xn, z as Sn } from "../chunks/validate-Drrm-CCz.js";
|
|
6
|
+
export { dt as DATE_FORMAT_DEFAULTS, _t as DATE_FORMAT_STYLE_PRESET_NAMES, at as DATE_PATTERN_DATE_TOKENS, nt as DATE_PATTERN_TIME_TOKENS, tt as DATE_PATTERN_TOKENS, rt as DATE_PATTERN_TOKEN_RE, mt as DEFAULT_DATE_PRESET_NAMES, rn as DEFAULT_NUMBER_PRESET_NAMES, Se as DEFAULT_VALUE_STATES, Sn as NUMBER_FORMAT_DEFAULTS, nn as NUMBER_PRESET_NAME_RATIO_PERCENT, Ae as VALUE_STATE_COLOR_TOKENS, Te as addCalendarDays, Ne as addCalendarMonths, ne as addCalendarYears, ee as clearFormatCache, le as clearPhone, q as cloneDate, ln as cloneFormatterPipelinePlanStep, un as cloneFormatterPipelinePlanStepToNode, _n as cloneFormattersPipelineConfig, mn as cloneNormalizeLeadingZerosConfig, fn as cloneResolveValueStateConfig, dn as cloneRowBasedOverrideConfig, sn as cloneTypedValueFormatConfig, Be as collectFormattersPipelineDependencyIds, R as collectRuntimeFieldDependencyIds, re as compileFormattersPipelineExecutor, fe as compileFormattersPipelineRuntime, Z as compileFormattersPipelineRuntimeFields, Y as computeShortHash, gn as configureRowBasedFormatterRegistry, K as countCalendarDaysInDateRange, ye as createCalendarDate, d as createEducationDateTime, ue as createFixedResolver, xn as createRowBasedFormatterContext, yn as createRowBasedFormatterRegistry, Ee as createThresholdResolver, Re as findResolverByCanonicalKey, Jt as formatDate, Ut as formatDateAsAbapDate, Kt as formatDateAsAbapDatetime, zt as formatDateAsAbapMonth, Mt as formatDateAsAbapYear, Wt as formatDateAsDate, qt as formatDateAsDateLong, Pt as formatDateAsDateMedium, Vt as formatDateAsDateShort, Yt as formatDateAsDateTime, Ft as formatDateAsDatetimeLong, It as formatDateAsDatetimeMedium, Gt as formatDateAsDatetimeShort, Ht as formatDateAsMonthLong, Rt as formatDateAsMonthMedium, Lt as formatDateAsMonthShort, jt as formatDateAsMonthYearLong, Xt as formatDateAsMonthYearMedium, $t as formatDateAsODataDate, Nt as formatDateAsODataDatetime, Qt as formatDateAsODataTime, kt as formatDateAsTime, Tt as formatDateAsTimeLong, Zt as formatDateAsTimeMedium, At as formatDateAsTimeSeconds, Dt as formatDateAsTimeShort, Et as formatDateRange, ze as formatDurationMinutes, _ as formatEducationDateKey, C as formatEducationTimeKey, Ge as formatFileSize, i as formatFullName, j as formatInstantDateTime, Ue as formatNumber, L as formatNumberAsCurrency, o as formatNumberAsCurrencyOrEmpty, Ve as formatNumberAsDecimal, z as formatNumberAsDecimal2, u as formatNumberAsDecimal2OrEmpty, c as formatNumberAsDecimal3, A as formatNumberAsDecimal3OrEmpty, _e as formatNumberAsDecimalOrEmpty, n as formatNumberAsInteger, he as formatNumberAsIntegerOrEmpty, E as formatNumberAsPercent, O as formatNumberAsPercentOrEmpty, M as formatNumberAsPrice, f as formatNumberAsPriceOrEmpty, v as formatNumberAsTonnage, w as formatNumberAsTonnageOrEmpty, X as formatPhone, we as formatPipelineDisplayValue, ke as formatRussianPlural, U as formatShortName, oe as formatTypedCellValue, je as getCalendarPeriod, P as getCurrentEducationWeekKey, ot as getDatePreset, xt as getDatePresetNames, Ke as getEducationWeekDays, r as getEducationWeekRange, H as getEducationWeekStartDate, h as getEducationYear, B as getEducationYearRange, Le as getEndOfDay, te as getFormattersPipelineDefinitionById, ve as getFormattersPipelineDefinitions, en as getNumberPreset, on as getNumberPresetNames, cn as getRowBasedFormatterById, pn as getRowBasedFormatterList, ie as getStartOfDay, se as getStartOfMonth, De as getStartOfWeek, xe as getStartOfYear, We as getValueStateResolver, $ as getValueStateResolverIds, pe as isCalendarPeriodWithinDateBounds, W as isCurrentEducationWeek, wt as isDateFormatPrecision, ct as isDateFormatStyle, Q as isDateInsideCalendarPeriod, J as isDateRangeTuple, p as isEducationDateInCurrentYear, ft as isPositiveValue, de as isSameCalendarDay, N as isValidDate, qe as isZeroValue, e as normalizeDateRange, k as normalizeDateRangeReferenceDate, x as normalizeEducationWeekKey, Ie as normalizeFormattersPipelineConfig, l as normalizeLeadingZeros, s as normalizeLeadingZerosStrict, Xe as normalizeRequiredText, Je as normalizeText, Ze as normalizeTextSpaces, $e as normalizeTextToLower, Ye as normalizeTextWithFallback, ae as orderDates, Ot as parseAbapBoolean, Bt as parseBoolean, ht as parseDate, vt as parseDateByFormat, lt as parseDateByPattern, pt as parseDateTZ, bt as parseDateValue, ut as parseDateValueTZ, Oe as parseEducationDateKey, st as parseNumber, Ct as registerDatePreset, ce as registerFixedResolver, tn as registerNumberPreset, He as registerResolver, be as registerThresholdResolver, Me as rekeyFormattersPipelineConfig, Fe as requireDateRange, it as resetDatePresets, an as resetNumberPresets, I as resetValueStateResolvers, et as resolveDateFormatName, St as resolveDateFormatPreset, Ce as resolveDateRangePair, y as resolveEducationWeekKey, ge as resolveMonthAgoRange, t as resolveMonthStartToTodayRange, me as resolveMonthStartToYesterdayRange, T as resolveTodayRange, a as resolveValueState, Pe as resolveValueStateClassName, D as resolveYesterdayRange, b as selectRussianPluralForm, S as startsWithIgnoringZeros, m as stripInnerSpaces, G as stripLeadingZeros, g as toAbapBoolean, gt as toFiniteNumber, yt as toPositiveInteger, Qe as toSafeString, F as truncateNumber, V as truncateText, bn as validateFormattersPipelineConfig, hn as validateFormattersPipelineGraph, vn as validateFormattersPipelinePlan };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type NumberFormatPreset } from "./types";
|
|
2
2
|
/** Усечение дробной части без округления: 1234.789 → 1234.7 (при decimals=1) */
|
|
3
3
|
export declare function truncateNumber(num: number, decimals: number): number;
|
|
4
4
|
/**
|
|
5
5
|
* Форматирование числа по предустановке.
|
|
6
6
|
* Оптимизировано для 500+ вызовов: кеш Intl.NumberFormat + быстрый путь через format().
|
|
7
7
|
*
|
|
8
|
-
*
|
|
8
|
+
* Для именованных и собственных presets используется этот public API; `formatNumberAs*` выбирают готовые имена.
|
|
9
9
|
*/
|
|
10
10
|
export declare function formatNumber(value: unknown, presetOrName: string | NumberFormatPreset): string;
|
|
11
11
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatNumber.d.ts","sourceRoot":"","sources":["../../../src/formatters/number/formatNumber.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"formatNumber.d.ts","sourceRoot":"","sources":["../../../src/formatters/number/formatNumber.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAKlD,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAIpE;AAsGD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,kBAAkB,GAAG,MAAM,CAoB9F;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAE5D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAE7D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAE5D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAE7D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAE7D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAE5D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAE1D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAGnE;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAGpE;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAGnE;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAGpE;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAGpE;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAGnE;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAGjE;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAGnE;AAED,qCAAqC;AACrC,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from "./formatNumber";
|
|
2
2
|
export * from "./isZeroValue";
|
|
3
3
|
export * from "./parseNumber";
|
|
4
|
+
export { NUMBER_PRESET_NAME_RATIO_PERCENT } from "./numberPresetNameConstants";
|
|
4
5
|
export { DEFAULT_NUMBER_PRESET_NAMES, getNumberPreset, getNumberPresetNames, NUMBER_FORMAT_DEFAULTS, registerNumberPreset, resetNumberPresets } from "./presets";
|
|
5
6
|
export type { NumberFormatCompactOptions, NumberFormatCompactRoundingMode, NumberFormatCompactUnit, NumberFormatPreset, NumberFormatPresetConfig } from "./types";
|
|
6
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/formatters/number/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,OAAO,EACN,2BAA2B,EAC3B,eAAe,EACf,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EAClB,MAAM,WAAW,CAAC;AAEnB,YAAY,EACX,0BAA0B,EAC1B,+BAA+B,EAC/B,uBAAuB,EACvB,kBAAkB,EAClB,wBAAwB,EACxB,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/formatters/number/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,gCAAgC,EAAE,MAAM,6BAA6B,CAAC;AAC/E,OAAO,EACN,2BAA2B,EAC3B,eAAe,EACf,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EAClB,MAAM,WAAW,CAAC;AAEnB,YAAY,EACX,0BAA0B,EAC1B,+BAA+B,EAC/B,uBAAuB,EACvB,kBAAkB,EAClB,wBAAwB,EACxB,MAAM,SAAS,CAAC"}
|
|
@@ -4,8 +4,13 @@ export declare const COMPACT_ROUNDING_MODE_FLOOR = "floor";
|
|
|
4
4
|
export declare const COMPACT_ROUNDING_MODE_CEIL = "ceil";
|
|
5
5
|
export declare const COMPACT_ROUNDING_MODE_TRUNC = "trunc";
|
|
6
6
|
export declare const NUMBER_FORMAT_LOCALE = "ru-RU";
|
|
7
|
+
/** Style управляет представлением доли, а не изменяет исходное числовое значение. */
|
|
8
|
+
export declare const NUMBER_FORMAT_STYLE_DECIMAL = "decimal";
|
|
9
|
+
export declare const NUMBER_FORMAT_STYLE_PERCENT = "percent";
|
|
7
10
|
export declare const INTL_NUMBER_PART_GROUP = "group";
|
|
8
11
|
export declare const INTL_NUMBER_PART_DECIMAL = "decimal";
|
|
12
|
+
export declare const INTL_NUMBER_PART_PERCENT_SIGN = "percentSign";
|
|
13
|
+
export declare const INTL_NUMBER_PART_LITERAL = "literal";
|
|
9
14
|
export declare const STANDARD_NUMBER_GROUP_SIZE = 3;
|
|
10
15
|
export declare const FORMATTED_NUMBER_ZERO = "0";
|
|
11
16
|
//# sourceMappingURL=numberFormatConstants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"numberFormatConstants.d.ts","sourceRoot":"","sources":["../../../src/formatters/number/numberFormatConstants.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,eAAO,MAAM,2BAA2B,UAAU,CAAC;AACnD,eAAO,MAAM,2BAA2B,UAAU,CAAC;AACnD,eAAO,MAAM,0BAA0B,SAAS,CAAC;AACjD,eAAO,MAAM,2BAA2B,UAAU,CAAC;AACnD,eAAO,MAAM,oBAAoB,UAAU,CAAC;AAC5C,eAAO,MAAM,sBAAsB,UAAU,CAAC;AAC9C,eAAO,MAAM,wBAAwB,YAAY,CAAC;AAClD,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAC5C,eAAO,MAAM,qBAAqB,MAAM,CAAC"}
|
|
1
|
+
{"version":3,"file":"numberFormatConstants.d.ts","sourceRoot":"","sources":["../../../src/formatters/number/numberFormatConstants.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,eAAO,MAAM,2BAA2B,UAAU,CAAC;AACnD,eAAO,MAAM,2BAA2B,UAAU,CAAC;AACnD,eAAO,MAAM,0BAA0B,SAAS,CAAC;AACjD,eAAO,MAAM,2BAA2B,UAAU,CAAC;AACnD,eAAO,MAAM,oBAAoB,UAAU,CAAC;AAC5C,qFAAqF;AACrF,eAAO,MAAM,2BAA2B,YAAY,CAAC;AACrD,eAAO,MAAM,2BAA2B,YAAY,CAAC;AACrD,eAAO,MAAM,sBAAsB,UAAU,CAAC;AAC9C,eAAO,MAAM,wBAAwB,YAAY,CAAC;AAClD,eAAO,MAAM,6BAA6B,gBAAgB,CAAC;AAC3D,eAAO,MAAM,wBAAwB,YAAY,CAAC;AAClD,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAC5C,eAAO,MAAM,qBAAqB,MAAM,CAAC"}
|
|
@@ -6,6 +6,7 @@ export declare const NUMBER_PRESET_NAME_DECIMAL3 = "decimal-3";
|
|
|
6
6
|
export declare const NUMBER_PRESET_NAME_CURRENCY = "currency";
|
|
7
7
|
export declare const NUMBER_PRESET_NAME_PRICE = "price";
|
|
8
8
|
export declare const NUMBER_PRESET_NAME_PERCENT = "percent";
|
|
9
|
+
export declare const NUMBER_PRESET_NAME_RATIO_PERCENT = "ratio-percent";
|
|
9
10
|
export declare const NUMBER_PRESET_NAME_TONNAGE = "tonnage";
|
|
10
11
|
export declare const NUMBER_PRESET_NAME_COMPACT_CURRENCY = "compact-currency";
|
|
11
12
|
export declare const NUMBER_PRESET_NAME_COMPACT_CURRENCY_ROUND = "compact-currency-round";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"numberPresetNameConstants.d.ts","sourceRoot":"","sources":["../../../src/formatters/number/numberPresetNameConstants.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,eAAO,MAAM,0BAA0B,YAAY,CAAC;AACpD,eAAO,MAAM,0BAA0B,YAAY,CAAC;AACpD,eAAO,MAAM,2BAA2B,cAAc,CAAC;AACvD,eAAO,MAAM,2BAA2B,cAAc,CAAC;AACvD,eAAO,MAAM,2BAA2B,aAAa,CAAC;AACtD,eAAO,MAAM,wBAAwB,UAAU,CAAC;AAChD,eAAO,MAAM,0BAA0B,YAAY,CAAC;AACpD,eAAO,MAAM,0BAA0B,YAAY,CAAC;AACpD,eAAO,MAAM,mCAAmC,qBAAqB,CAAC;AACtE,eAAO,MAAM,yCAAyC,2BAA2B,CAAC;AAClF,eAAO,MAAM,kCAAkC,oBAAoB,CAAC;AACpE,eAAO,MAAM,wCAAwC,0BAA0B,CAAC;AAChF,eAAO,MAAM,kCAAkC,oBAAoB,CAAC;AACpE,eAAO,MAAM,wCAAwC,0BAA0B,CAAC"}
|
|
1
|
+
{"version":3,"file":"numberPresetNameConstants.d.ts","sourceRoot":"","sources":["../../../src/formatters/number/numberPresetNameConstants.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,eAAO,MAAM,0BAA0B,YAAY,CAAC;AACpD,eAAO,MAAM,0BAA0B,YAAY,CAAC;AACpD,eAAO,MAAM,2BAA2B,cAAc,CAAC;AACvD,eAAO,MAAM,2BAA2B,cAAc,CAAC;AACvD,eAAO,MAAM,2BAA2B,aAAa,CAAC;AACtD,eAAO,MAAM,wBAAwB,UAAU,CAAC;AAChD,eAAO,MAAM,0BAA0B,YAAY,CAAC;AACpD,eAAO,MAAM,gCAAgC,kBAAkB,CAAC;AAChE,eAAO,MAAM,0BAA0B,YAAY,CAAC;AACpD,eAAO,MAAM,mCAAmC,qBAAqB,CAAC;AACtE,eAAO,MAAM,yCAAyC,2BAA2B,CAAC;AAClF,eAAO,MAAM,kCAAkC,oBAAoB,CAAC;AACpE,eAAO,MAAM,wCAAwC,0BAA0B,CAAC;AAChF,eAAO,MAAM,kCAAkC,oBAAoB,CAAC;AACpE,eAAO,MAAM,wCAAwC,0BAA0B,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type NumberFormatPreset, type NumberFormatPresetConfig } from "./types";
|
|
2
2
|
/** Значения по умолчанию — совпадают с ru-RU форматированием */
|
|
3
3
|
export declare const NUMBER_FORMAT_DEFAULTS: Omit<NumberFormatPreset, "name">;
|
|
4
4
|
export declare const DEFAULT_NUMBER_PRESET_NAMES: Readonly<{
|
|
@@ -9,6 +9,7 @@ export declare const DEFAULT_NUMBER_PRESET_NAMES: Readonly<{
|
|
|
9
9
|
currency: "currency";
|
|
10
10
|
price: "price";
|
|
11
11
|
percent: "percent";
|
|
12
|
+
ratioPercent: "ratio-percent";
|
|
12
13
|
tonnage: "tonnage";
|
|
13
14
|
compactCurrency: "compact-currency";
|
|
14
15
|
compactCurrencyRound: "compact-currency-round";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../../src/formatters/number/presets.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../../src/formatters/number/presets.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAUjF,gEAAgE;AAChE,eAAO,MAAM,sBAAsB,EAAE,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAMnE,CAAC;AAEF,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;EAgBtC,CAAC;AAqDH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAE5E;AAED,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAE/C;AAED,oGAAoG;AACpG,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,wBAAwB,GAAG,kBAAkB,CAOzF;AAED,4EAA4E;AAC5E,wBAAgB,kBAAkB,IAAI,IAAI,CAGzC;AAED,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,kBAAkB,GAAG,kBAAkB,CAajG"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type COMPACT_ROUNDING_MODE_ROUND, type COMPACT_ROUNDING_MODE_FLOOR, type COMPACT_ROUNDING_MODE_CEIL, type COMPACT_ROUNDING_MODE_TRUNC } from "./numberFormatConstants";
|
|
1
|
+
import { type COMPACT_ROUNDING_MODE_ROUND, type COMPACT_ROUNDING_MODE_FLOOR, type COMPACT_ROUNDING_MODE_CEIL, type COMPACT_ROUNDING_MODE_TRUNC, type NUMBER_FORMAT_STYLE_DECIMAL, type NUMBER_FORMAT_STYLE_PERCENT } from "./numberFormatConstants";
|
|
2
2
|
export type NumberFormatCompactRoundingMode = typeof COMPACT_ROUNDING_MODE_ROUND | typeof COMPACT_ROUNDING_MODE_FLOOR | typeof COMPACT_ROUNDING_MODE_CEIL | typeof COMPACT_ROUNDING_MODE_TRUNC;
|
|
3
3
|
export type NumberFormatCompactUnit = {
|
|
4
4
|
value: number;
|
|
@@ -29,6 +29,8 @@ export type NumberFormatCompactOptions = {
|
|
|
29
29
|
/** Параметры предустановки форматирования чисел */
|
|
30
30
|
export interface NumberFormatPreset {
|
|
31
31
|
name: string;
|
|
32
|
+
/** Без style сохраняется обычное число; percent отображает долю как процент. С compact не совмещается. */
|
|
33
|
+
style?: typeof NUMBER_FORMAT_STYLE_DECIMAL | typeof NUMBER_FORMAT_STYLE_PERCENT;
|
|
32
34
|
/** Количество десятичных знаков */
|
|
33
35
|
decimals: number;
|
|
34
36
|
/** Разделитель дробной части */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/formatters/number/types.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,2BAA2B,EAChC,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,EAChC,MAAM,yBAAyB,CAAC;AAEjC,MAAM,MAAM,+BAA+B,GACxC,OAAO,2BAA2B,GAClC,OAAO,2BAA2B,GAClC,OAAO,0BAA0B,GACjC,OAAO,2BAA2B,CAAC;AAEtC,MAAM,MAAM,uBAAuB,GAAG;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACxC;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,YAAY,CAAC,EAAE,+BAA+B,CAAC;IAE/C;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,uBAAuB,EAAE,CAAC;CAC3C,CAAC;AAEF,mDAAmD;AACnD,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,2BAA2B;IAC3B,QAAQ,EAAE,OAAO,CAAC;IAClB,iCAAiC;IACjC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,6BAA6B;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,0BAA0B,CAAC;CACrC;AAED,gFAAgF;AAChF,MAAM,MAAM,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/formatters/number/types.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,2BAA2B,EAChC,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,EAChC,KAAK,2BAA2B,EAChC,KAAK,2BAA2B,EAChC,MAAM,yBAAyB,CAAC;AAEjC,MAAM,MAAM,+BAA+B,GACxC,OAAO,2BAA2B,GAClC,OAAO,2BAA2B,GAClC,OAAO,0BAA0B,GACjC,OAAO,2BAA2B,CAAC;AAEtC,MAAM,MAAM,uBAAuB,GAAG;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACxC;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,YAAY,CAAC,EAAE,+BAA+B,CAAC;IAE/C;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,uBAAuB,EAAE,CAAC;CAC3C,CAAC;AAEF,mDAAmD;AACnD,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,0GAA0G;IAC1G,KAAK,CAAC,EAAE,OAAO,2BAA2B,GAAG,OAAO,2BAA2B,CAAC;IAChF,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,2BAA2B;IAC3B,QAAQ,EAAE,OAAO,CAAC;IAClB,iCAAiC;IACjC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,6BAA6B;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,0BAA0B,CAAC;CACrC;AAED,gFAAgF;AAChF,MAAM,MAAM,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC"}
|
package/package.json
CHANGED
package/src/excel/README.mdx
CHANGED
|
@@ -379,6 +379,18 @@ decimals = 2 → #,##0.00
|
|
|
379
379
|
|
|
380
380
|
Для OData integer по умолчанию выбирается preset `integer`, для других чисел — `decimal`. Неизвестное имя preset игнорируется и заменяется подходящим default.
|
|
381
381
|
|
|
382
|
+
Preset с `style: "percent"` создаёт native процентную маску Excel по собственной точности. Встроенный `ratio-percent` использует два знака:
|
|
383
|
+
|
|
384
|
+
```text
|
|
385
|
+
decimals = 0 → #,##0%
|
|
386
|
+
decimals = 2 → #,##0.00%
|
|
387
|
+
decimals = 3 → #,##0.000%
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
В строке сохраняется исходная числовая доля: `0.2` с маской `#,##0.00%` Excel отображает как `20.00%`, а `1` — как `100.00%`. Разделитель при отображении зависит от локали Excel. Не умножайте значение заранее и не передавайте строку `"20%"`: масштабирование выполняет сама процентная маска.
|
|
391
|
+
|
|
392
|
+
Имена пользовательских presets не задают семантику: любой preset с `style: "percent"` получает процентную маску, а `style: "decimal"` или отсутствие `style` сохраняют обычную числовую маску. В частности, существующий `percent` без `style` по-прежнему создаёт `#,##0.00`. Сочетание процентного style с `compact` отклоняется общим resolver числовых presets; Excel не вводит отдельные правила валидации.
|
|
393
|
+
|
|
382
394
|
### Форматы дат из presets
|
|
383
395
|
|
|
384
396
|
По умолчанию:
|
|
@@ -74,6 +74,7 @@ const text = value === undefined ? "Некорректно" : formatNumber(value
|
|
|
74
74
|
| `currency` | 0 | Денежное число без символа валюты |
|
|
75
75
|
| `price` | 0 | Цена без символа валюты |
|
|
76
76
|
| `percent` | 2 | Процентное число без автоматического умножения и знака `%` |
|
|
77
|
+
| `ratio-percent` | 2 | Доля с процентным масштабированием и знаком `%` |
|
|
77
78
|
| `tonnage` | 1 | Тоннаж |
|
|
78
79
|
| `compact-currency` | 0 | Компактное число, усечение |
|
|
79
80
|
| `compact-currency-round` | 0 | Компактное число, округление |
|
|
@@ -97,6 +98,38 @@ import { DEFAULT_NUMBER_PRESET_NAMES, formatNumber } from "@ryuzaki13/react-foun
|
|
|
97
98
|
formatNumber(1234.5, DEFAULT_NUMBER_PRESET_NAMES.decimal2);
|
|
98
99
|
```
|
|
99
100
|
|
|
101
|
+
## Числовой процент и доля
|
|
102
|
+
|
|
103
|
+
`percent` и `formatNumberAsPercent` форматируют уже подготовленное число с двумя дробными знаками. `ratio-percent` принимает долю: числу `0.2` соответствует отображение `20,00%`. Передавать предварительно умноженное на 100 значение для этого preset не нужно.
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import {
|
|
107
|
+
DEFAULT_NUMBER_PRESET_NAMES,
|
|
108
|
+
NUMBER_PRESET_NAME_RATIO_PERCENT,
|
|
109
|
+
formatNumber,
|
|
110
|
+
formatNumberAsPercent
|
|
111
|
+
} from "@ryuzaki13/react-foundation-lib/formatters";
|
|
112
|
+
|
|
113
|
+
formatNumber(0.2, "percent"); // "0,20"
|
|
114
|
+
formatNumberAsPercent(0.2); // "0,20"
|
|
115
|
+
formatNumber(0.2, NUMBER_PRESET_NAME_RATIO_PERCENT); // "20,00%"
|
|
116
|
+
formatNumber(1, DEFAULT_NUMBER_PRESET_NAMES.ratioPercent); // "100,00%"
|
|
117
|
+
formatNumber(0, "ratio-percent"); // "0,00%"
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Число остаётся неизменным; процентное масштабирование относится только к представлению. Для formatter pipeline достаточно обычного `typedValueFormat` с `numberPresetName: "ratio-percent"`, в том числе у числовой колонки с целочисленным типом `int`. Смена preset не изменяет числовую семантику формул.
|
|
121
|
+
|
|
122
|
+
Необязательное поле `NumberFormatPreset.style` задаёт способ представления: отсутствие поля или `"decimal"` сохраняет обычный числовой формат, `"percent"` отображает долю со знаком `%`. Встроенный `ratio-percent` использует два дробных знака, собственный preset использует свой `decimals`:
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
registerNumberPreset({ name: "ratio-3", style: "percent", decimals: 3 });
|
|
126
|
+
formatNumber(0.12345, "ratio-3"); // "12,345%"
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
`style: "percent"` нельзя сочетать с `compact`: такая комбинация явно отклоняется. Существующие compact presets без marker сохраняют своё поведение.
|
|
130
|
+
|
|
131
|
+
При экспорте через `createTableExcelColumn` из `/excel` этот style создаёт native percentage mask с точностью preset. В строку книги передаётся исходное число `0.2`, а Excel отображает процент. Готовую строку `"20%"` или число `20` вместо доли передавать не следует. Формат старого `percent` остаётся обычным числовым.
|
|
132
|
+
|
|
100
133
|
## `formatNumber(value, presetOrName)`
|
|
101
134
|
|
|
102
135
|
```ts
|
|
@@ -109,7 +142,7 @@ function formatNumber(value: unknown, presetOrName: string | NumberFormatPreset)
|
|
|
109
142
|
2. вызывает `Number(value)`;
|
|
110
143
|
3. для `NaN` и бесконечности возвращает `"0"`;
|
|
111
144
|
4. находит preset по имени или использует переданный объект;
|
|
112
|
-
5. округляет и форматирует
|
|
145
|
+
5. округляет и форматирует число с учётом выбранного `style`;
|
|
113
146
|
6. применяет compact-семантику, если она задана.
|
|
114
147
|
|
|
115
148
|
```ts
|
|
@@ -175,7 +208,7 @@ formatNumberAsCurrency(1250); // "1 250", без ₽
|
|
|
175
208
|
formatNumberAsPercent(12.5); // "12,50", без %
|
|
176
209
|
```
|
|
177
210
|
|
|
178
|
-
|
|
211
|
+
Для доли со знаком `%` используйте `ratio-percent`. Другие суффиксы добавляйте на UI-уровне или используйте специализированный модуль единиц измерения.
|
|
179
212
|
|
|
180
213
|
## Wrappers `OrEmpty`
|
|
181
214
|
|
|
@@ -388,7 +421,7 @@ formatNumber(1234.5, "accounting-2"); // "1 234,50"
|
|
|
388
421
|
|
|
389
422
|
Регистрация глобальна для текущего экземпляра модуля. Выполняйте её один раз при старте приложения до компиляции formatter pipeline.
|
|
390
423
|
|
|
391
|
-
Имя не trim
|
|
424
|
+
Имя не trim-ится. Передавайте непустое устойчивое имя, не меняйте встроенные presets без явной необходимости и проверяйте числовые параметры. Сочетание `style: "percent"` с `compact` не поддерживается и отклоняется при регистрации или разрешении preset.
|
|
392
425
|
|
|
393
426
|
### `resetNumberPresets()`
|
|
394
427
|
|
|
@@ -426,7 +459,7 @@ formatNumber(1234567.89, {
|
|
|
426
459
|
|
|
427
460
|
Такой объект не попадает в реестр. Он полезен для локального стабильного правила; переиспользуемый формат лучше зарегистрировать централизованно.
|
|
428
461
|
|
|
429
|
-
|
|
462
|
+
Числовые параметры автоматически не валидируются. Используйте:
|
|
430
463
|
|
|
431
464
|
- `decimals` — целое неотрицательное число в диапазоне, допустимом `Intl.NumberFormat`;
|
|
432
465
|
- `groupingSize` — положительное целое число;
|
|
@@ -450,7 +483,7 @@ truncateNumber(123.789, -1); // 120
|
|
|
450
483
|
|
|
451
484
|
## Кеш `Intl.NumberFormat`
|
|
452
485
|
|
|
453
|
-
Модуль кеширует formatter по комбинации `decimals + grouping`, что важно для сотен ячеек таблицы.
|
|
486
|
+
Модуль кеширует formatter по комбинации `style + decimals + grouping`, что важно для сотен ячеек таблицы. Числовой и процентный режимы не используют один formatter даже при одинаковой точности.
|
|
454
487
|
|
|
455
488
|
```ts
|
|
456
489
|
clearFormatCache();
|
|
@@ -506,7 +539,7 @@ const text = parsed === undefined ? "—" : formatNumber(parsed, "decimal-2");
|
|
|
506
539
|
|
|
507
540
|
### Считать `percent` математическим процентом
|
|
508
541
|
|
|
509
|
-
Preset не умножает `0.25` на 100 и не добавляет `%`. Он выведет `0,25`.
|
|
542
|
+
Preset не умножает `0.25` на 100 и не добавляет `%`. Он выведет `0,25`. Для отображения доли как `25,00%` выбирайте `ratio-percent`.
|
|
510
543
|
|
|
511
544
|
### Ожидать валютный символ
|
|
512
545
|
|
|
@@ -529,7 +562,7 @@ Preset не умножает `0.25` на 100 и не добавляет `%`. О
|
|
|
529
562
|
| Ноль как пустое | все перечисленные wrappers с суффиксом `OrEmpty` |
|
|
530
563
|
| Парсинг | `toFiniteNumber`, `parseNumber`, `isPositiveValue`, `toPositiveInteger` |
|
|
531
564
|
| Проверка нуля | `isZeroValue` |
|
|
532
|
-
| Presets | `DEFAULT_NUMBER_PRESET_NAMES`, `NUMBER_FORMAT_DEFAULTS`, `getNumberPreset`, `getNumberPresetNames`, `registerNumberPreset`, `resetNumberPresets`
|
|
565
|
+
| Presets | `DEFAULT_NUMBER_PRESET_NAMES`, `NUMBER_PRESET_NAME_RATIO_PERCENT`, `NUMBER_FORMAT_DEFAULTS`, `getNumberPreset`, `getNumberPresetNames`, `registerNumberPreset`, `resetNumberPresets` |
|
|
533
566
|
| Низкоуровневое | `truncateNumber`, `clearFormatCache` |
|
|
534
567
|
| Типы | `NumberFormatPreset`, `NumberFormatPresetConfig`, `NumberFormatCompactOptions`, `NumberFormatCompactUnit`, `NumberFormatCompactRoundingMode` |
|
|
535
568
|
|
|
@@ -540,3 +573,4 @@ Preset не умножает `0.25` на 100 и не добавляет `%`. О
|
|
|
540
573
|
- [Обзор `formatters`](../README.mdx)
|
|
541
574
|
- [Строковая нормализация](../strings/README.mdx)
|
|
542
575
|
- [Formatter pipeline](../pipeline/README.mdx)
|
|
576
|
+
- [Excel](../../excel/README.mdx)
|