@ryuzaki13/react-foundation-lib 2.20.0 → 2.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +2 -0
  2. package/dist/analytical-table/aggregation.d.ts +4 -0
  3. package/dist/analytical-table/aggregation.d.ts.map +1 -0
  4. package/dist/analytical-table/buildAnalyticalTableModel.d.ts +4 -0
  5. package/dist/analytical-table/buildAnalyticalTableModel.d.ts.map +1 -0
  6. package/dist/analytical-table/calculationTypes.d.ts +11 -0
  7. package/dist/analytical-table/calculationTypes.d.ts.map +1 -0
  8. package/dist/analytical-table/calculations.d.ts +6 -0
  9. package/dist/analytical-table/calculations.d.ts.map +1 -0
  10. package/dist/analytical-table/columnTypes.d.ts +30 -0
  11. package/dist/analytical-table/columnTypes.d.ts.map +1 -0
  12. package/dist/analytical-table/dataTypes.d.ts +14 -0
  13. package/dist/analytical-table/dataTypes.d.ts.map +1 -0
  14. package/dist/analytical-table/dateColumnTypes.d.ts +31 -0
  15. package/dist/analytical-table/dateColumnTypes.d.ts.map +1 -0
  16. package/dist/analytical-table/dateColumns.d.ts +11 -0
  17. package/dist/analytical-table/dateColumns.d.ts.map +1 -0
  18. package/dist/analytical-table/expansion.d.ts +4 -0
  19. package/dist/analytical-table/expansion.d.ts.map +1 -0
  20. package/dist/analytical-table/exportProjection.d.ts +4 -0
  21. package/dist/analytical-table/exportProjection.d.ts.map +1 -0
  22. package/dist/analytical-table/exportTypes.d.ts +31 -0
  23. package/dist/analytical-table/exportTypes.d.ts.map +1 -0
  24. package/dist/analytical-table/filtering.d.ts +4 -0
  25. package/dist/analytical-table/filtering.d.ts.map +1 -0
  26. package/dist/analytical-table/index.d.ts +8 -0
  27. package/dist/analytical-table/index.d.ts.map +1 -0
  28. package/dist/analytical-table/index.js +364 -0
  29. package/dist/analytical-table/index.js.map +1 -0
  30. package/dist/analytical-table/indexAnalyticalRows.d.ts +4 -0
  31. package/dist/analytical-table/indexAnalyticalRows.d.ts.map +1 -0
  32. package/dist/analytical-table/modelTypes.d.ts +43 -0
  33. package/dist/analytical-table/modelTypes.d.ts.map +1 -0
  34. package/dist/analytical-table/types.d.ts +8 -0
  35. package/dist/analytical-table/types.d.ts.map +1 -0
  36. package/dist/analytical-table/valueComparison.d.ts +5 -0
  37. package/dist/analytical-table/valueComparison.d.ts.map +1 -0
  38. package/dist/analytical-table/viewTypes.d.ts +24 -0
  39. package/dist/analytical-table/viewTypes.d.ts.map +1 -0
  40. package/dist/chunks/{formatters-hHUJpZqD.js → formatters-CEltML3y.js} +224 -224
  41. package/dist/chunks/{formatters-hHUJpZqD.js.map → formatters-CEltML3y.js.map} +1 -1
  42. package/dist/chunks/{validate-DnkaY38p.js → validate-M2zPiLXn.js} +24 -24
  43. package/dist/chunks/{validate-DnkaY38p.js.map → validate-M2zPiLXn.js.map} +1 -1
  44. package/dist/error-report/index.js +20 -20
  45. package/dist/excel/index.js +36 -36
  46. package/dist/excel/index.js.map +1 -1
  47. package/dist/formatters/index.js +2 -2
  48. package/dist/hooks/useFloatingListbox.d.ts +1 -1
  49. package/dist/odata-service/formatters.d.ts +2 -2
  50. package/package.json +5 -1
  51. package/src/analytical-table/README.mdx +169 -0
@@ -1,5 +1,5 @@
1
- import { Lt as e } from "./odata-service-CWkHASdw.js";
2
- import { validateTableFormulaDependencies as t } from "../formulas/index.js";
1
+ import { validateTableFormulaDependencies as e } from "../formulas/index.js";
2
+ import { Lt as t } from "./odata-service-CWkHASdw.js";
3
3
  var n = {
4
4
  decimals: 1,
5
5
  decimalSeparator: ",",
@@ -225,30 +225,30 @@ function x(e) {
225
225
  }
226
226
  //#endregion
227
227
  //#region src/formatters/rowBased/context.ts
228
- function S(t) {
229
- let n = [...t.keys ?? []], r = (e) => {
230
- if (!Number.isInteger(e) || e < 0) {
231
- t.instrumentation?.onOutOfRangeIndex?.(e);
228
+ function S(e) {
229
+ let n = [...e.keys ?? []], r = (t) => {
230
+ if (!Number.isInteger(t) || t < 0) {
231
+ e.instrumentation?.onOutOfRangeIndex?.(t);
232
232
  return;
233
233
  }
234
- if (t.instrumentation?.onReadIndex?.(e), e >= n.length) {
235
- t.instrumentation?.onOutOfRangeIndex?.(e);
234
+ if (e.instrumentation?.onReadIndex?.(t), t >= n.length) {
235
+ e.instrumentation?.onOutOfRangeIndex?.(t);
236
236
  return;
237
237
  }
238
- return n[e];
238
+ return n[t];
239
239
  };
240
240
  return {
241
- rowData: t.rowData,
242
- rawValue: t.rawValue,
243
- columnId: t.columnId,
241
+ rowData: e.rowData,
242
+ rawValue: e.rawValue,
243
+ columnId: e.columnId,
244
244
  key: r,
245
- value: (e) => {
246
- let n = r(e);
247
- if (n) return t.rowData[n];
245
+ value: (t) => {
246
+ let n = r(t);
247
+ if (n) return e.rowData[n];
248
248
  },
249
249
  num: (n) => {
250
250
  let i = r(n);
251
- return i ? e(t.rowData[i]) : 0;
251
+ return i ? t(e.rowData[i]) : 0;
252
252
  }
253
253
  };
254
254
  }
@@ -341,19 +341,19 @@ function M(e, t) {
341
341
  let u = r.filter((e, t) => !i.has(t));
342
342
  u.length > 0 && k(t, "step_row_based_override_unused_dependencies", `Выбраны, но не используются формулой rowBasedOverride: ${u.join(", ")}.`), o > 0 && k(t, "step_row_based_override_formula_runtime_error", "На тестовых данных формула rowBasedOverride завершилась с ошибкой.");
343
343
  }
344
- function N(e, n) {
345
- if (!e.formulaId.trim()) {
344
+ function N(t, n) {
345
+ if (!t.formulaId.trim()) {
346
346
  O(n, "step_value_state_formula_id_empty", "Для источника состояния необходимо выбрать формулу.");
347
347
  return;
348
348
  }
349
- if (e.dependencyIds.some((e) => !e.trim())) {
349
+ if (t.dependencyIds.some((e) => !e.trim())) {
350
350
  O(n, "step_value_state_dependency_id_empty", "Зависимость формулы состояния не может иметь пустой id.");
351
351
  return;
352
352
  }
353
- let r = t({
354
- formulaId: e.formulaId,
355
- dependencies: e.dependencyIds,
356
- availableColumnIds: e.dependencyIds
353
+ let r = e({
354
+ formulaId: t.formulaId,
355
+ dependencies: t.dependencyIds,
356
+ availableColumnIds: t.dependencyIds
357
357
  });
358
358
  for (let e of r.errors) e.code === "formula_not_found" ? O(n, "step_value_state_formula_not_found", "Формула источника состояния не найдена в реестре.") : e.code === "dependency_index_out_of_range" && O(n, "step_value_state_dependency_index_out_of_range", e.message);
359
359
  for (let e of r.warnings) switch (e.code) {
@@ -605,4 +605,4 @@ function R(e) {
605
605
  //#endregion
606
606
  export { d as S, n as _, C as a, l as b, S as c, x as d, p as f, r as g, f as h, T as i, g as l, m, L as n, D as o, h as p, F as r, E as s, R as t, _ as u, s as v, u as x, c as y };
607
607
 
608
- //# sourceMappingURL=validate-DnkaY38p.js.map
608
+ //# sourceMappingURL=validate-M2zPiLXn.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate-DnkaY38p.js","names":[],"sources":["../../src/formatters/number/presets.ts","../../src/formatters/pipeline/clone.ts","../../src/formatters/rowBased/context.ts","../../src/formatters/rowBased/registry.ts","../../src/formatters/pipeline/validate.ts"],"sourcesContent":["import type { NumberFormatPreset, NumberFormatPresetConfig } from \"./types\";\n\n/** Символ группировки из ru-RU (U+00A0 или U+202F в зависимости от среды) */\nconst ruGroupChar = new Intl.NumberFormat(\"ru-RU\").formatToParts(1000).find((p) => p.type === \"group\")?.value ?? \"\\u00A0\";\n\n/** Значения по умолчанию — совпадают с ru-RU форматированием */\nexport const NUMBER_FORMAT_DEFAULTS: Omit<NumberFormatPreset, \"name\"> = {\n\tdecimals: 1,\n\tdecimalSeparator: \",\",\n\tgrouping: true,\n\tgroupingSeparator: ruGroupChar,\n\tgroupingSize: 3\n};\n\nexport const DEFAULT_NUMBER_PRESET_NAMES = Object.freeze({\n\tinteger: \"integer\",\n\tdecimal: \"decimal\",\n\tdecimal2: \"decimal-2\",\n\tdecimal3: \"decimal-3\",\n\tcurrency: \"currency\",\n\tprice: \"price\",\n\tpercent: \"percent\",\n\ttonnage: \"tonnage\",\n\tcompactCurrency: \"compact-currency\",\n\tcompactCurrencyRound: \"compact-currency-round\",\n\tcompactPercent: \"compact-percent\",\n\tcompactPercentRound: \"compact-percent-round\",\n\tcompactTonnage: \"compact-tonnage\",\n\tcompactTonnageRound: \"compact-tonnage-round\"\n});\n\n/**\n * Типовые предустановки числового форматирования.\n *\n * Compact-пресеты без суффикса сохраняют консервативное усечение, а парные\n * `*-round` дают явный математический режим без runtime-переопределения пресета.\n * Недостающие поля каждой предустановки заполняются из `NUMBER_FORMAT_DEFAULTS`.\n */\nconst BUILTIN: NumberFormatPresetConfig[] = [\n\t{ name: \"integer\", decimals: 0, decimalSeparator: \"\" },\n\t{ name: \"decimal\" },\n\t{ name: \"decimal-2\", decimals: 2 },\n\t{ name: \"decimal-3\", decimals: 3 },\n\t{ name: \"currency\", decimals: 0, decimalSeparator: \"\" },\n\t{ name: \"price\", decimals: 0, decimalSeparator: \"\" },\n\t{ name: \"percent\", decimals: 2 },\n\t{ name: \"tonnage\" },\n\t{ name: \"compact-currency\", decimals: 0, decimalSeparator: \"\", compact: {} },\n\t{ name: \"compact-currency-round\", decimals: 0, decimalSeparator: \"\", compact: { roundingMode: \"round\" } },\n\t{ name: \"compact-percent\", decimals: 2, compact: { maxDecimals: 2 } },\n\t{ name: \"compact-percent-round\", decimals: 2, compact: { maxDecimals: 2, roundingMode: \"round\" } },\n\t{ name: \"compact-tonnage\", compact: { maxDecimals: 1 } },\n\t{ name: \"compact-tonnage-round\", compact: { maxDecimals: 1, roundingMode: \"round\" } }\n];\n\nconst registry = new Map<string, NumberFormatPreset>();\n\nfunction init(): void {\n\tfor (const cfg of BUILTIN) {\n\t\tregistry.set(cfg.name, { ...NUMBER_FORMAT_DEFAULTS, ...cfg });\n\t}\n}\n\ninit();\n\nexport function getNumberPreset(name: string): NumberFormatPreset | undefined {\n\treturn registry.get(name);\n}\n\nexport function getNumberPresetNames(): string[] {\n\treturn Array.from(registry.keys());\n}\n\n/** Зарегистрировать или перезаписать предустановку. Недостающие поля берутся из FORMAT_DEFAULTS. */\nexport function registerNumberPreset(config: NumberFormatPresetConfig): NumberFormatPreset {\n\tconst preset: NumberFormatPreset = { ...NUMBER_FORMAT_DEFAULTS, ...config };\n\tregistry.set(preset.name, preset);\n\treturn preset;\n}\n\n/** Сбросить реестр к начальному состоянию (только типовые предустановки) */\nexport function resetNumberPresets(): void {\n\tregistry.clear();\n\tinit();\n}\n\nexport function resolveNumberPreset(presetOrName: string | NumberFormatPreset): NumberFormatPreset {\n\tif (typeof presetOrName !== \"string\") return presetOrName;\n\n\tconst found = getNumberPreset(presetOrName);\n\tif (!found) throw new Error(`Предустановка \"${presetOrName}\" не найдена`);\n\n\treturn found;\n}\n","import type {\n\tFormattersPipelineConfig,\n\tFormattersPipelineGraph,\n\tFormattersPipelineNode,\n\tFormattersPipelineNormalizeLeadingZerosConfig,\n\tFormattersPipelinePlan,\n\tFormattersPipelineResolveValueStateConfig,\n\tFormattersPipelineRowBasedOverrideConfig,\n\tFormattersPipelineStep,\n\tFormattersPipelineTypedValueFormatConfig\n} from \"./types\";\n\nexport function cloneTypedValueFormatConfig(\n\tconfig: FormattersPipelineTypedValueFormatConfig | undefined\n): FormattersPipelineTypedValueFormatConfig | undefined {\n\treturn config ? { ...config } : undefined;\n}\n\nexport function cloneNormalizeLeadingZerosConfig(\n\tconfig: FormattersPipelineNormalizeLeadingZerosConfig | undefined\n): FormattersPipelineNormalizeLeadingZerosConfig | undefined {\n\treturn config ? { ...config } : undefined;\n}\n\nexport function cloneRowBasedOverrideConfig(config: FormattersPipelineRowBasedOverrideConfig): FormattersPipelineRowBasedOverrideConfig {\n\treturn config.mode === \"formula\"\n\t\t? { ...config, dependencyIds: config.dependencyIds ? [...config.dependencyIds] : undefined }\n\t\t: { ...config };\n}\n\nexport function cloneResolveValueStateConfig(config: FormattersPipelineResolveValueStateConfig): FormattersPipelineResolveValueStateConfig {\n\treturn {\n\t\tresolver:\n\t\t\tconfig.resolver.kind === \"fixed\"\n\t\t\t\t? {\n\t\t\t\t\t\tkind: \"fixed\",\n\t\t\t\t\t\tentries: { ...config.resolver.entries },\n\t\t\t\t\t\tfallbackState: config.resolver.fallbackState\n\t\t\t\t\t}\n\t\t\t\t: {\n\t\t\t\t\t\tkind: \"threshold\",\n\t\t\t\t\t\tthresholds: config.resolver.thresholds.map((item) => (typeof item === \"number\" ? item : { ...item })),\n\t\t\t\t\t\tstates: [...config.resolver.states],\n\t\t\t\t\t\tinvalidState: config.resolver.invalidState\n\t\t\t\t\t},\n\t\tvalueSource:\n\t\t\tconfig.valueSource?.kind === \"formula\"\n\t\t\t\t? { ...config.valueSource, dependencyIds: [...config.valueSource.dependencyIds] }\n\t\t\t\t: config.valueSource\n\t\t\t\t\t? { ...config.valueSource }\n\t\t\t\t\t: undefined,\n\t\ticon: config.icon ? { ...config.icon } : undefined\n\t};\n}\n\nexport function cloneFormatterPipelinePlanStep(step: FormattersPipelineStep): FormattersPipelineStep {\n\tswitch (step.type) {\n\t\tcase \"typedValueFormat\":\n\t\t\treturn {\n\t\t\t\t...step,\n\t\t\t\tconfig: cloneTypedValueFormatConfig(step.config)\n\t\t\t};\n\t\tcase \"normalizeLeadingZeros\":\n\t\t\treturn {\n\t\t\t\t...step,\n\t\t\t\tconfig: cloneNormalizeLeadingZerosConfig(step.config)\n\t\t\t};\n\t\tcase \"rowBasedOverride\":\n\t\t\treturn {\n\t\t\t\t...step,\n\t\t\t\tconfig: cloneRowBasedOverrideConfig(step.config)\n\t\t\t};\n\t\tcase \"resolveValueState\":\n\t\t\treturn {\n\t\t\t\t...step,\n\t\t\t\tconfig: cloneResolveValueStateConfig(step.config)\n\t\t\t};\n\t\tdefault: {\n\t\t\tconst checker: never = step;\n\t\t\tvoid checker;\n\t\t}\n\t}\n\n\tthrow new Error(`Недопустимый тип '${(step as Record<string, unknown>)?.type}' для шага FormatterPipeline`);\n}\n\nexport function cloneFormatterPipelinePlanStepToNode(\n\tstep: FormattersPipelineStep,\n\tposition: { x: number; y: number }\n): FormattersPipelineNode {\n\tswitch (step.type) {\n\t\tcase \"typedValueFormat\":\n\t\t\treturn {\n\t\t\t\t...step,\n\t\t\t\tposition: { ...position },\n\t\t\t\tconfig: cloneTypedValueFormatConfig(step.config)\n\t\t\t};\n\t\tcase \"normalizeLeadingZeros\":\n\t\t\treturn {\n\t\t\t\t...step,\n\t\t\t\tposition: { ...position },\n\t\t\t\tconfig: cloneNormalizeLeadingZerosConfig(step.config)\n\t\t\t};\n\t\tcase \"rowBasedOverride\":\n\t\t\treturn {\n\t\t\t\t...step,\n\t\t\t\tposition: { ...position },\n\t\t\t\tconfig: cloneRowBasedOverrideConfig(step.config)\n\t\t\t};\n\t\tcase \"resolveValueState\":\n\t\t\treturn {\n\t\t\t\t...step,\n\t\t\t\tposition: { ...position },\n\t\t\t\tconfig: cloneResolveValueStateConfig(step.config)\n\t\t\t};\n\t\tdefault: {\n\t\t\tconst checker: never = step;\n\t\t\tvoid checker;\n\t\t}\n\t}\n\n\tthrow new Error(`Недопустимый тип '${(step as Record<string, unknown>)?.type}' для шага FormatterPipeline`);\n}\n\nfunction cloneNode(node: FormattersPipelineNode): FormattersPipelineNode {\n\tswitch (node.type) {\n\t\tcase \"source\":\n\t\tcase \"sink\":\n\t\t\treturn {\n\t\t\t\t...node,\n\t\t\t\tposition: { ...node.position }\n\t\t\t};\n\t\tdefault:\n\t\t\treturn cloneFormatterPipelinePlanStepToNode(node, node.position);\n\t}\n}\n\nfunction cloneGraph(graph: FormattersPipelineGraph): FormattersPipelineGraph {\n\treturn {\n\t\tnodes: graph.nodes.map(cloneNode),\n\t\tedges: graph.edges.map((edge) => ({ ...edge })),\n\t\tviewport: graph.viewport ? { ...graph.viewport } : undefined\n\t};\n}\n\nfunction clonePlan(plan: FormattersPipelinePlan): FormattersPipelinePlan {\n\treturn {\n\t\tsteps: plan.steps.map(cloneFormatterPipelinePlanStep)\n\t};\n}\n\n/**\n * Возвращает полную копию конфигурации pipeline для безопасного хранения в сторе.\n */\nexport function cloneFormattersPipelineConfig(config: FormattersPipelineConfig | undefined): FormattersPipelineConfig | undefined {\n\tif (!config) return undefined;\n\n\tconst version = config.version;\n\tconst graph = config.graph ? cloneGraph(config.graph) : undefined;\n\tconst plan = config.plan ? clonePlan(config.plan) : undefined;\n\n\treturn { version, graph, plan };\n}\n","import { parseNumber } from \"../number\";\n\nimport type { RowBasedFormatterContext, RowBasedFormatterContextInstrumentation } from \"./types\";\n\nexport function createRowBasedFormatterContext(args: {\n\trowData: Record<string, unknown>;\n\trawValue: unknown;\n\tcolumnId: string;\n\tkeys?: readonly string[];\n\tinstrumentation?: RowBasedFormatterContextInstrumentation;\n}): RowBasedFormatterContext {\n\t// TODO: duplicate createTableFormulaContext src\\shared\\lib\\formulas\\execute.ts\n\tconst keys = [...(args.keys ?? [])];\n\n\tconst readKey = (index: number): string | undefined => {\n\t\tif (!Number.isInteger(index) || index < 0) {\n\t\t\targs.instrumentation?.onOutOfRangeIndex?.(index);\n\t\t\treturn undefined;\n\t\t}\n\n\t\targs.instrumentation?.onReadIndex?.(index);\n\n\t\tif (index >= keys.length) {\n\t\t\targs.instrumentation?.onOutOfRangeIndex?.(index);\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn keys[index];\n\t};\n\n\tconst readValue = (index: number): unknown => {\n\t\tconst key = readKey(index);\n\t\tif (!key) return undefined;\n\t\treturn args.rowData[key];\n\t};\n\n\tconst readNum = (index: number): number => {\n\t\tconst key = readKey(index);\n\t\tif (!key) return 0;\n\t\treturn parseNumber(args.rowData[key]);\n\t};\n\n\treturn {\n\t\trowData: args.rowData,\n\t\trawValue: args.rawValue,\n\t\tcolumnId: args.columnId,\n\t\tkey: readKey,\n\t\tvalue: readValue,\n\t\tnum: readNum\n\t};\n}\n","import type { RowBasedFormatterDefinition } from \"./types\";\n\nexport type RowBasedFormatterRegistry = Readonly<{\n\tlist: readonly RowBasedFormatterDefinition[];\n\tbyId: ReadonlyMap<string, RowBasedFormatterDefinition>;\n}>;\n\n/**\n * Создаёт реестр формул для подмены значения в групповой строке.\n */\nexport function createRowBasedFormatterRegistry(definitions: readonly RowBasedFormatterDefinition[]): RowBasedFormatterRegistry {\n\tconst byId = new Map<string, RowBasedFormatterDefinition>();\n\tconst list: RowBasedFormatterDefinition[] = [];\n\n\tfor (const definition of definitions) {\n\t\tconst normalizedId = definition.id.trim();\n\t\tif (!normalizedId) {\n\t\t\tthrow new Error(\"Formula id для RowBasedFormatter не может быть пустым\");\n\t\t}\n\n\t\tif (byId.has(normalizedId)) {\n\t\t\tthrow new Error(`Найден дублирующийся formulaId в RowBasedFormatter: ${normalizedId}`);\n\t\t}\n\n\t\tconst normalizedDefinition: RowBasedFormatterDefinition = Object.freeze({\n\t\t\t...definition,\n\t\t\tid: normalizedId,\n\t\t\tname: definition.name.trim(),\n\t\t\tdescription: definition.description.trim()\n\t\t});\n\n\t\tbyId.set(normalizedId, normalizedDefinition);\n\t\tlist.push(normalizedDefinition);\n\t}\n\n\treturn Object.freeze({\n\t\tlist: Object.freeze(list),\n\t\tbyId\n\t});\n}\n\nlet rowBasedFormatterRegistry = createRowBasedFormatterRegistry([]);\n\n/**\n * Устанавливает реестр row-based форматтеров host-приложения.\n *\n * Pipeline использует этот реестр при валидации и компиляции formula-режима,\n * поэтому конфигурация должна завершиться до первого построения runtime.\n */\nexport function configureRowBasedFormatterRegistry(registry: RowBasedFormatterRegistry): void {\n\trowBasedFormatterRegistry = registry;\n}\n\n/**\n * Возвращает список доступных формул для групповой подмены.\n */\nexport function getRowBasedFormatterList(): readonly RowBasedFormatterDefinition[] {\n\treturn rowBasedFormatterRegistry.list;\n}\n\n/**\n * Возвращает формулу по id.\n */\nexport function getRowBasedFormatterById(formulaId: string | undefined): RowBasedFormatterDefinition | undefined {\n\tconst normalizedId = formulaId?.trim();\n\tif (!normalizedId) return undefined;\n\treturn rowBasedFormatterRegistry.byId.get(normalizedId);\n}\n","import { validateTableFormulaDependencies } from \"../../formulas\";\nimport { getNumberPreset } from \"../number\";\nimport { createRowBasedFormatterContext, getRowBasedFormatterById } from \"../rowBased\";\n\nimport { cloneResolveValueStateConfig } from \"./clone\";\n\nimport type {\n\tFormattersPipelineConfig,\n\tFormattersPipelineEdge,\n\tFormattersPipelineGraph,\n\tFormattersPipelineNode,\n\tFormattersPipelinePlan,\n\tFormattersPipelineRowBasedOverrideFormulaConfig,\n\tFormattersPipelineStep,\n\tFormattersPipelineValueStateFormulaSource\n} from \"./types\";\n\nexport type FormattersPipelineValidationCode =\n\t| \"config_not_defined\"\n\t| \"unsupported_version\"\n\t| \"graph_or_plan_required\"\n\t| \"node_id_duplicate\"\n\t| \"edge_id_duplicate\"\n\t| \"edge_node_not_found\"\n\t| \"source_count_invalid\"\n\t| \"sink_count_invalid\"\n\t| \"source_incoming_invalid\"\n\t| \"sink_outgoing_invalid\"\n\t| \"node_degree_invalid\"\n\t| \"path_broken\"\n\t| \"path_cycle_detected\"\n\t| \"path_disconnected_nodes\"\n\t| \"step_id_duplicate\"\n\t| \"step_resolve_value_state_multiple\"\n\t| \"step_typed_value_format_multiple\"\n\t| \"step_row_based_override_multiple\"\n\t| \"step_normalize_leading_zeros_multiple\"\n\t| \"step_typed_before_value_state\"\n\t| \"step_row_based_override_field_key_empty\"\n\t| \"step_row_based_override_formula_id_empty\"\n\t| \"step_row_based_override_formula_not_found\"\n\t| \"step_row_based_override_dependency_index_out_of_range\"\n\t| \"step_row_based_override_unused_dependencies\"\n\t| \"step_row_based_override_formula_does_not_use_dependencies\"\n\t| \"step_row_based_override_formula_runtime_error\"\n\t| \"step_value_state_formula_id_empty\"\n\t| \"step_value_state_formula_not_found\"\n\t| \"step_value_state_dependency_id_empty\"\n\t| \"step_value_state_dependency_index_out_of_range\"\n\t| \"step_value_state_unused_dependencies\"\n\t| \"step_value_state_formula_does_not_use_dependencies\"\n\t| \"step_value_state_formula_runtime_error\"\n\t| \"step_threshold_states_count_invalid\"\n\t| \"step_value_hidden_without_icon\"\n\t| \"step_typed_value_format_preset_empty\"\n\t| \"step_typed_value_format_preset_not_found\";\n\nexport type FormattersPipelineValidationMessage = {\n\tcode: FormattersPipelineValidationCode;\n\tmessage: string;\n};\n\nexport type FormattersPipelineValidationResult = {\n\tok: boolean;\n\terrors: FormattersPipelineValidationMessage[];\n\twarnings: FormattersPipelineValidationMessage[];\n\tplan?: FormattersPipelinePlan;\n};\n\ntype MutableValidationState = {\n\terrors: FormattersPipelineValidationMessage[];\n\twarnings: FormattersPipelineValidationMessage[];\n};\n\nfunction pushError(state: MutableValidationState, code: FormattersPipelineValidationCode, message: string) {\n\tstate.errors.push({ code, message });\n}\n\nfunction pushWarning(state: MutableValidationState, code: FormattersPipelineValidationCode, message: string) {\n\tstate.warnings.push({ code, message });\n}\n\nfunction toSortedArray(items: Set<number>): number[] {\n\treturn [...items].sort((left, right) => left - right);\n}\n\nfunction createSampleRowData(dependencies: readonly string[], multiplier: number): Record<string, unknown> {\n\treturn dependencies.reduce<Record<string, unknown>>((acc, dependencyId, index) => {\n\t\tacc[dependencyId] = (index + 1) * multiplier;\n\t\treturn acc;\n\t}, {});\n}\n\nfunction validateRowBasedOverrideFormulaConfig(config: FormattersPipelineRowBasedOverrideFormulaConfig, state: MutableValidationState) {\n\tif (!config.formulaId.trim()) {\n\t\tpushError(state, \"step_row_based_override_formula_id_empty\", \"Для rowBasedOverride (formula) необходимо заполнить formulaId.\");\n\t\treturn;\n\t}\n\n\tconst formula = getRowBasedFormatterById(config.formulaId);\n\tconst dependencies = [...(config.dependencyIds ?? [])];\n\n\tif (!formula) {\n\t\tpushError(state, \"step_row_based_override_formula_not_found\", \"Формула rowBasedOverride не найдена в реестре.\");\n\t\treturn;\n\t}\n\n\tconst usedIndexes = new Set<number>();\n\tconst outOfRangeIndexes = new Set<number>();\n\tlet runtimeErrorCount = 0;\n\n\tconst runValidationPass = (sampleRowData: Record<string, unknown>) => {\n\t\ttry {\n\t\t\tconst context = createRowBasedFormatterContext({\n\t\t\t\trowData: sampleRowData,\n\t\t\t\trawValue: 100,\n\t\t\t\tcolumnId: \"__validation__\",\n\t\t\t\tkeys: dependencies,\n\t\t\t\tinstrumentation: {\n\t\t\t\t\tonReadIndex: (index) => {\n\t\t\t\t\t\tusedIndexes.add(index);\n\t\t\t\t\t},\n\t\t\t\t\tonOutOfRangeIndex: (index) => {\n\t\t\t\t\t\toutOfRangeIndexes.add(index);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tformula.fn(context);\n\t\t} catch {\n\t\t\truntimeErrorCount += 1;\n\t\t}\n\t};\n\n\t// Несколько прогонов повышают шанс увидеть обращения к индексам в разных ветках формулы.\n\trunValidationPass(createSampleRowData(dependencies, 100));\n\trunValidationPass(createSampleRowData(dependencies, -100));\n\n\tconst sortedUsedIndexes = toSortedArray(usedIndexes);\n\tconst requiredDependencyCount = sortedUsedIndexes.length > 0 ? sortedUsedIndexes[sortedUsedIndexes.length - 1] + 1 : 0;\n\n\tif (outOfRangeIndexes.size > 0) {\n\t\tpushError(\n\t\t\tstate,\n\t\t\t\"step_row_based_override_dependency_index_out_of_range\",\n\t\t\t`Формула rowBasedOverride обращается к несуществующим индексам. Минимально требуется зависимостей: ${requiredDependencyCount}, выбрано: ${dependencies.length}.`\n\t\t);\n\t}\n\n\tif (sortedUsedIndexes.length === 0) {\n\t\tpushWarning(\n\t\t\tstate,\n\t\t\t\"step_row_based_override_formula_does_not_use_dependencies\",\n\t\t\t\"Формула rowBasedOverride не использует dependencyIds.\"\n\t\t);\n\t}\n\n\tconst unusedDependencies = dependencies.filter((_, index) => !usedIndexes.has(index));\n\tif (unusedDependencies.length > 0) {\n\t\tpushWarning(\n\t\t\tstate,\n\t\t\t\"step_row_based_override_unused_dependencies\",\n\t\t\t`Выбраны, но не используются формулой rowBasedOverride: ${unusedDependencies.join(\", \")}.`\n\t\t);\n\t}\n\n\tif (runtimeErrorCount > 0) {\n\t\tpushWarning(\n\t\t\tstate,\n\t\t\t\"step_row_based_override_formula_runtime_error\",\n\t\t\t\"На тестовых данных формула rowBasedOverride завершилась с ошибкой.\"\n\t\t);\n\t}\n}\n\n/**\n * Pipeline проверяет контракт формулы и индексы, а наличие полей в конкретном\n * источнике данных проверяет потребитель через collectRuntimeFieldDependencyIds.\n */\nfunction validateValueStateFormulaSource(source: FormattersPipelineValueStateFormulaSource, state: MutableValidationState) {\n\tif (!source.formulaId.trim()) {\n\t\tpushError(state, \"step_value_state_formula_id_empty\", \"Для источника состояния необходимо выбрать формулу.\");\n\t\treturn;\n\t}\n\n\tif (source.dependencyIds.some((dependencyId) => !dependencyId.trim())) {\n\t\tpushError(state, \"step_value_state_dependency_id_empty\", \"Зависимость формулы состояния не может иметь пустой id.\");\n\t\treturn;\n\t}\n\n\tconst validation = validateTableFormulaDependencies({\n\t\tformulaId: source.formulaId,\n\t\tdependencies: source.dependencyIds,\n\t\tavailableColumnIds: source.dependencyIds\n\t});\n\tfor (const error of validation.errors) {\n\t\tif (error.code === \"formula_not_found\") {\n\t\t\tpushError(state, \"step_value_state_formula_not_found\", \"Формула источника состояния не найдена в реестре.\");\n\t\t} else if (error.code === \"dependency_index_out_of_range\") {\n\t\t\tpushError(state, \"step_value_state_dependency_index_out_of_range\", error.message);\n\t\t}\n\t}\n\tfor (const warning of validation.warnings) {\n\t\tswitch (warning.code) {\n\t\t\tcase \"unused_dependencies\":\n\t\t\t\tpushWarning(state, \"step_value_state_unused_dependencies\", warning.message);\n\t\t\t\tbreak;\n\t\t\tcase \"formula_does_not_use_dependencies\":\n\t\t\t\tpushWarning(state, \"step_value_state_formula_does_not_use_dependencies\", warning.message);\n\t\t\t\tbreak;\n\t\t\tcase \"formula_runtime_error\":\n\t\t\t\tpushWarning(state, \"step_value_state_formula_runtime_error\", warning.message);\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\nfunction validateStepDefinitions(steps: readonly FormattersPipelineStep[], state: MutableValidationState) {\n\tconst stepIdSet = new Set<string>();\n\tconst counters = {\n\t\tnormalizeLeadingZeros: 0,\n\t\trowBasedOverride: 0,\n\t\tresolveValueState: 0,\n\t\ttypedValueFormat: 0\n\t};\n\n\tfor (const step of steps) {\n\t\tconst normalizedId = step.id.trim();\n\t\tif (!normalizedId) {\n\t\t\tpushError(state, \"step_id_duplicate\", \"Шаг pipeline не может иметь пустой id.\");\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (stepIdSet.has(normalizedId)) {\n\t\t\tpushError(state, \"step_id_duplicate\", `Найден дублирующийся id шага pipeline: ${normalizedId}.`);\n\t\t}\n\t\tstepIdSet.add(normalizedId);\n\n\t\tswitch (step.type) {\n\t\t\tcase \"normalizeLeadingZeros\":\n\t\t\t\tcounters.normalizeLeadingZeros += 1;\n\t\t\t\tbreak;\n\t\t\tcase \"rowBasedOverride\":\n\t\t\t\tcounters.rowBasedOverride += 1;\n\n\t\t\t\tif (step.config.mode === \"field\" && !step.config.fieldKey.trim()) {\n\t\t\t\t\tpushError(\n\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\"step_row_based_override_field_key_empty\",\n\t\t\t\t\t\t\"Для rowBasedOverride (field) необходимо заполнить fieldKey.\"\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (step.config.mode === \"formula\") {\n\t\t\t\t\tvalidateRowBasedOverrideFormulaConfig(step.config, state);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"resolveValueState\":\n\t\t\t\tcounters.resolveValueState += 1;\n\t\t\t\tif (step.config.valueSource?.kind === \"formula\") {\n\t\t\t\t\tvalidateValueStateFormulaSource(step.config.valueSource, state);\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\tstep.config.resolver.kind === \"threshold\" &&\n\t\t\t\t\tstep.config.resolver.states.length !== step.config.resolver.thresholds.length + 1\n\t\t\t\t) {\n\t\t\t\t\tpushError(\n\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\"step_threshold_states_count_invalid\",\n\t\t\t\t\t\t\"Для threshold-резолвера количество states должно быть равно thresholds + 1.\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"typedValueFormat\":\n\t\t\t\tcounters.typedValueFormat += 1;\n\t\t\t\tif (step.config?.numberPresetName !== undefined) {\n\t\t\t\t\tconst normalizedPresetName = step.config.numberPresetName.trim();\n\t\t\t\t\tif (!normalizedPresetName) {\n\t\t\t\t\t\tpushError(state, \"step_typed_value_format_preset_empty\", \"Для typedValueFormat указан пустой numberPresetName.\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!getNumberPreset(normalizedPresetName)) {\n\t\t\t\t\t\tpushError(\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\t\"step_typed_value_format_preset_not_found\",\n\t\t\t\t\t\t\t`Для typedValueFormat указан неизвестный пресет: ${normalizedPresetName}.`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (counters.normalizeLeadingZeros > 1) {\n\t\tpushError(state, \"step_normalize_leading_zeros_multiple\", \"В pipeline может быть только один шаг normalizeLeadingZeros.\");\n\t}\n\n\tif (counters.rowBasedOverride > 1) {\n\t\tpushError(state, \"step_row_based_override_multiple\", \"В pipeline может быть только один шаг rowBasedOverride.\");\n\t}\n\n\tif (counters.resolveValueState > 1) {\n\t\tpushError(state, \"step_resolve_value_state_multiple\", \"В pipeline может быть только один шаг resolveValueState.\");\n\t}\n\n\tif (counters.typedValueFormat > 1) {\n\t\tpushError(state, \"step_typed_value_format_multiple\", \"В pipeline может быть только один шаг typedValueFormat.\");\n\t}\n\n\tconst resolveIndex = steps.findIndex((step) => step.type === \"resolveValueState\");\n\tconst typedIndex = steps.findIndex((step) => step.type === \"typedValueFormat\");\n\tif (resolveIndex !== -1 && typedIndex !== -1 && typedIndex < resolveIndex) {\n\t\tpushError(state, \"step_typed_before_value_state\", \"Шаг typedValueFormat не может выполняться до шага resolveValueState.\");\n\t}\n\n\tfor (const step of steps) {\n\t\tif (step.type !== \"resolveValueState\") continue;\n\t\tif (!step.config.icon?.enabled && step.config.icon?.showValue === false) {\n\t\t\tpushWarning(\n\t\t\t\tstate,\n\t\t\t\t\"step_value_hidden_without_icon\",\n\t\t\t\t\"Для resolveValueState установлено showValue=false при выключенной иконке: значение не будет отображаться.\"\n\t\t\t);\n\t\t}\n\t}\n}\n\n/**\n * Валидация облегчённого плана pipeline.\n */\nexport function validateFormattersPipelinePlan(plan: FormattersPipelinePlan): FormattersPipelineValidationResult {\n\tconst state: MutableValidationState = { errors: [], warnings: [] };\n\n\tvalidateStepDefinitions(plan.steps, state);\n\n\treturn {\n\t\tok: state.errors.length === 0,\n\t\terrors: state.errors,\n\t\twarnings: state.warnings,\n\t\tplan: state.errors.length === 0 ? { steps: [...plan.steps] } : undefined\n\t};\n}\n\nfunction buildLinearPathFromGraph(\n\tnodes: readonly FormattersPipelineNode[],\n\tedges: readonly FormattersPipelineEdge[],\n\tstate: MutableValidationState\n): string[] | undefined {\n\tconst nodeById = new Map(nodes.map((node) => [node.id, node]));\n\tconst outgoing = new Map<string, string[]>();\n\tconst incoming = new Map<string, string[]>();\n\n\tfor (const node of nodes) {\n\t\toutgoing.set(node.id, []);\n\t\tincoming.set(node.id, []);\n\t}\n\n\tfor (const edge of edges) {\n\t\tconst source = edge.source.trim();\n\t\tconst target = edge.target.trim();\n\t\tif (!nodeById.has(source) || !nodeById.has(target)) {\n\t\t\tpushError(state, \"edge_node_not_found\", `Ребро ${edge.id} ссылается на несуществующий узел: ${source} -> ${target}.`);\n\t\t\tcontinue;\n\t\t}\n\n\t\toutgoing.get(source)?.push(target);\n\t\tincoming.get(target)?.push(source);\n\t}\n\n\tconst sources = nodes.filter((node) => node.type === \"source\");\n\tconst sinks = nodes.filter((node) => node.type === \"sink\");\n\n\tif (sources.length !== 1) {\n\t\tpushError(state, \"source_count_invalid\", \"В графе должен быть ровно один узел source.\");\n\t}\n\tif (sinks.length !== 1) {\n\t\tpushError(state, \"sink_count_invalid\", \"В графе должен быть ровно один узел sink.\");\n\t}\n\tif (state.errors.length > 0) return undefined;\n\n\tconst sourceNodeId = sources[0]!.id;\n\tconst sinkNodeId = sinks[0]!.id;\n\n\tfor (const node of nodes) {\n\t\tconst inDegree = incoming.get(node.id)?.length ?? 0;\n\t\tconst outDegree = outgoing.get(node.id)?.length ?? 0;\n\n\t\tif (node.type === \"source\") {\n\t\t\tif (inDegree !== 0) {\n\t\t\t\tpushError(state, \"source_incoming_invalid\", \"Узел source не должен иметь входящих рёбер.\");\n\t\t\t}\n\t\t\tif (outDegree !== 1) {\n\t\t\t\tpushError(state, \"node_degree_invalid\", \"Узел source должен иметь ровно одно исходящее ребро.\");\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (node.type === \"sink\") {\n\t\t\tif (outDegree !== 0) {\n\t\t\t\tpushError(state, \"sink_outgoing_invalid\", \"Узел sink не должен иметь исходящих рёбер.\");\n\t\t\t}\n\t\t\tif (inDegree !== 1) {\n\t\t\t\tpushError(state, \"node_degree_invalid\", \"Узел sink должен иметь ровно одно входящее ребро.\");\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (inDegree !== 1 || outDegree !== 1) {\n\t\t\tpushError(\n\t\t\t\tstate,\n\t\t\t\t\"node_degree_invalid\",\n\t\t\t\t`Узел ${node.id} должен иметь ровно одно входящее и одно исходящее ребро для линейного pipeline.`\n\t\t\t);\n\t\t}\n\t}\n\n\tif (state.errors.length > 0) return undefined;\n\n\tconst visited = new Set<string>();\n\tconst path: string[] = [];\n\tlet cursor = sourceNodeId;\n\n\twhile (true) {\n\t\tif (visited.has(cursor)) {\n\t\t\tpushError(state, \"path_cycle_detected\", \"В графе pipeline обнаружен цикл.\");\n\t\t\treturn undefined;\n\t\t}\n\t\tvisited.add(cursor);\n\t\tpath.push(cursor);\n\n\t\tif (cursor === sinkNodeId) {\n\t\t\tbreak;\n\t\t}\n\n\t\tconst nextCandidates = outgoing.get(cursor) ?? [];\n\t\tif (nextCandidates.length !== 1) {\n\t\t\tpushError(state, \"path_broken\", \"Не удалось построить линейный путь от source к sink.\");\n\t\t\treturn undefined;\n\t\t}\n\n\t\tcursor = nextCandidates[0]!;\n\t}\n\n\tif (visited.size !== nodes.length) {\n\t\tpushError(state, \"path_disconnected_nodes\", \"Граф содержит узлы, которые не входят в линейный путь source -> sink.\");\n\t\treturn undefined;\n\t}\n\n\treturn path;\n}\n\n/**\n * Валидация графа pipeline и построение линейного плана исполнения.\n */\nexport function validateFormattersPipelineGraph(graph: FormattersPipelineGraph): FormattersPipelineValidationResult {\n\tconst state: MutableValidationState = { errors: [], warnings: [] };\n\n\tif (!graph.nodes.length) {\n\t\tpushError(state, \"path_broken\", \"Граф pipeline не содержит узлов.\");\n\t\treturn { ok: false, errors: state.errors, warnings: state.warnings };\n\t}\n\n\tconst nodeById = new Map<string, FormattersPipelineNode>();\n\tfor (const node of graph.nodes) {\n\t\tconst normalizedId = node.id.trim();\n\t\tif (!normalizedId) {\n\t\t\tpushError(state, \"node_id_duplicate\", \"Узел pipeline не может иметь пустой id.\");\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (nodeById.has(normalizedId)) {\n\t\t\tpushError(state, \"node_id_duplicate\", `Найден дублирующийся id узла pipeline: ${normalizedId}.`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tnodeById.set(normalizedId, node);\n\t}\n\n\tconst edgeIdSet = new Set<string>();\n\tfor (const edge of graph.edges) {\n\t\tconst normalizedEdgeId = edge.id.trim();\n\t\tif (!normalizedEdgeId) {\n\t\t\tpushError(state, \"edge_id_duplicate\", \"Ребро pipeline не может иметь пустой id.\");\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (edgeIdSet.has(normalizedEdgeId)) {\n\t\t\tpushError(state, \"edge_id_duplicate\", `Найден дублирующийся id ребра pipeline: ${normalizedEdgeId}.`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tedgeIdSet.add(normalizedEdgeId);\n\t}\n\n\tif (state.errors.length > 0) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terrors: state.errors,\n\t\t\twarnings: state.warnings\n\t\t};\n\t}\n\n\tconst path = buildLinearPathFromGraph(graph.nodes, graph.edges, state);\n\tif (!path) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terrors: state.errors,\n\t\t\twarnings: state.warnings\n\t\t};\n\t}\n\n\tconst steps: FormattersPipelineStep[] = [];\n\tfor (const nodeId of path) {\n\t\tconst node = nodeById.get(nodeId);\n\t\tif (!node || node.type === \"source\" || node.type === \"sink\") continue;\n\n\t\tswitch (node.type) {\n\t\t\tcase \"normalizeLeadingZeros\":\n\t\t\t\tsteps.push({\n\t\t\t\t\tid: node.id,\n\t\t\t\t\ttype: \"normalizeLeadingZeros\",\n\t\t\t\t\tconfig: node.config ? { ...node.config } : undefined\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"rowBasedOverride\":\n\t\t\t\tsteps.push({\n\t\t\t\t\tid: node.id,\n\t\t\t\t\ttype: \"rowBasedOverride\",\n\t\t\t\t\tconfig:\n\t\t\t\t\t\tnode.config.mode === \"formula\"\n\t\t\t\t\t\t\t? { ...node.config, dependencyIds: node.config.dependencyIds ? [...node.config.dependencyIds] : undefined }\n\t\t\t\t\t\t\t: { ...node.config }\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"resolveValueState\":\n\t\t\t\tsteps.push({\n\t\t\t\t\tid: node.id,\n\t\t\t\t\ttype: \"resolveValueState\",\n\t\t\t\t\tconfig: cloneResolveValueStateConfig(node.config)\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"typedValueFormat\":\n\t\t\t\tsteps.push({\n\t\t\t\t\tid: node.id,\n\t\t\t\t\ttype: \"typedValueFormat\",\n\t\t\t\t\tconfig: node.config ? { ...node.config } : undefined\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tvalidateStepDefinitions(steps, state);\n\n\treturn {\n\t\tok: state.errors.length === 0,\n\t\terrors: state.errors,\n\t\twarnings: state.warnings,\n\t\tplan: state.errors.length === 0 ? { steps } : undefined\n\t};\n}\n\n/**\n * Валидация конфигурации pipeline c выбором рабочего плана исполнения.\n *\n * Приоритет источника плана:\n * 1) `plan` из конфигурации;\n * 2) построение плана из `graph`.\n */\nexport function validateFormattersPipelineConfig(config: FormattersPipelineConfig | undefined): FormattersPipelineValidationResult {\n\tconst state: MutableValidationState = { errors: [], warnings: [] };\n\n\tif (!config) {\n\t\tpushError(state, \"config_not_defined\", \"Конфигурация pipeline не задана.\");\n\t\treturn {\n\t\t\tok: false,\n\t\t\terrors: state.errors,\n\t\t\twarnings: state.warnings\n\t\t};\n\t}\n\n\tif (config.version !== 1) {\n\t\tpushError(state, \"unsupported_version\", `Неподдерживаемая версия pipeline: ${String(config.version)}.`);\n\t\treturn {\n\t\t\tok: false,\n\t\t\terrors: state.errors,\n\t\t\twarnings: state.warnings\n\t\t};\n\t}\n\n\tif (!config.plan && !config.graph) {\n\t\tpushError(state, \"graph_or_plan_required\", \"Для pipeline должен быть задан хотя бы один источник: graph или plan.\");\n\t\treturn {\n\t\t\tok: false,\n\t\t\terrors: state.errors,\n\t\t\twarnings: state.warnings\n\t\t};\n\t}\n\n\tif (config.plan) {\n\t\tconst planResult = validateFormattersPipelinePlan(config.plan);\n\t\tstate.errors.push(...planResult.errors);\n\t\tstate.warnings.push(...planResult.warnings);\n\n\t\tif (planResult.ok && planResult.plan) {\n\t\t\treturn {\n\t\t\t\tok: true,\n\t\t\t\terrors: state.errors,\n\t\t\t\twarnings: state.warnings,\n\t\t\t\tplan: planResult.plan\n\t\t\t};\n\t\t}\n\n\t\tif (config.graph) {\n\t\t\tpushWarning(state, \"path_broken\", \"Линейный plan невалиден. Выполнена попытка построить план из graph.\");\n\t\t\tstate.errors.length = 0;\n\t\t} else {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terrors: state.errors,\n\t\t\t\twarnings: state.warnings\n\t\t\t};\n\t\t}\n\t}\n\n\tif (config.graph) {\n\t\tconst graphResult = validateFormattersPipelineGraph(config.graph);\n\t\treturn {\n\t\t\tok: graphResult.ok,\n\t\t\terrors: [...state.errors, ...graphResult.errors],\n\t\t\twarnings: [...state.warnings, ...graphResult.warnings],\n\t\t\tplan: graphResult.plan\n\t\t};\n\t}\n\n\treturn {\n\t\tok: false,\n\t\terrors: state.errors,\n\t\twarnings: state.warnings\n\t};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"validate-M2zPiLXn.js","names":[],"sources":["../../src/formatters/number/presets.ts","../../src/formatters/pipeline/clone.ts","../../src/formatters/rowBased/context.ts","../../src/formatters/rowBased/registry.ts","../../src/formatters/pipeline/validate.ts"],"sourcesContent":["import type { NumberFormatPreset, NumberFormatPresetConfig } from \"./types\";\n\n/** Символ группировки из ru-RU (U+00A0 или U+202F в зависимости от среды) */\nconst ruGroupChar = new Intl.NumberFormat(\"ru-RU\").formatToParts(1000).find((p) => p.type === \"group\")?.value ?? \"\\u00A0\";\n\n/** Значения по умолчанию — совпадают с ru-RU форматированием */\nexport const NUMBER_FORMAT_DEFAULTS: Omit<NumberFormatPreset, \"name\"> = {\n\tdecimals: 1,\n\tdecimalSeparator: \",\",\n\tgrouping: true,\n\tgroupingSeparator: ruGroupChar,\n\tgroupingSize: 3\n};\n\nexport const DEFAULT_NUMBER_PRESET_NAMES = Object.freeze({\n\tinteger: \"integer\",\n\tdecimal: \"decimal\",\n\tdecimal2: \"decimal-2\",\n\tdecimal3: \"decimal-3\",\n\tcurrency: \"currency\",\n\tprice: \"price\",\n\tpercent: \"percent\",\n\ttonnage: \"tonnage\",\n\tcompactCurrency: \"compact-currency\",\n\tcompactCurrencyRound: \"compact-currency-round\",\n\tcompactPercent: \"compact-percent\",\n\tcompactPercentRound: \"compact-percent-round\",\n\tcompactTonnage: \"compact-tonnage\",\n\tcompactTonnageRound: \"compact-tonnage-round\"\n});\n\n/**\n * Типовые предустановки числового форматирования.\n *\n * Compact-пресеты без суффикса сохраняют консервативное усечение, а парные\n * `*-round` дают явный математический режим без runtime-переопределения пресета.\n * Недостающие поля каждой предустановки заполняются из `NUMBER_FORMAT_DEFAULTS`.\n */\nconst BUILTIN: NumberFormatPresetConfig[] = [\n\t{ name: \"integer\", decimals: 0, decimalSeparator: \"\" },\n\t{ name: \"decimal\" },\n\t{ name: \"decimal-2\", decimals: 2 },\n\t{ name: \"decimal-3\", decimals: 3 },\n\t{ name: \"currency\", decimals: 0, decimalSeparator: \"\" },\n\t{ name: \"price\", decimals: 0, decimalSeparator: \"\" },\n\t{ name: \"percent\", decimals: 2 },\n\t{ name: \"tonnage\" },\n\t{ name: \"compact-currency\", decimals: 0, decimalSeparator: \"\", compact: {} },\n\t{ name: \"compact-currency-round\", decimals: 0, decimalSeparator: \"\", compact: { roundingMode: \"round\" } },\n\t{ name: \"compact-percent\", decimals: 2, compact: { maxDecimals: 2 } },\n\t{ name: \"compact-percent-round\", decimals: 2, compact: { maxDecimals: 2, roundingMode: \"round\" } },\n\t{ name: \"compact-tonnage\", compact: { maxDecimals: 1 } },\n\t{ name: \"compact-tonnage-round\", compact: { maxDecimals: 1, roundingMode: \"round\" } }\n];\n\nconst registry = new Map<string, NumberFormatPreset>();\n\nfunction init(): void {\n\tfor (const cfg of BUILTIN) {\n\t\tregistry.set(cfg.name, { ...NUMBER_FORMAT_DEFAULTS, ...cfg });\n\t}\n}\n\ninit();\n\nexport function getNumberPreset(name: string): NumberFormatPreset | undefined {\n\treturn registry.get(name);\n}\n\nexport function getNumberPresetNames(): string[] {\n\treturn Array.from(registry.keys());\n}\n\n/** Зарегистрировать или перезаписать предустановку. Недостающие поля берутся из FORMAT_DEFAULTS. */\nexport function registerNumberPreset(config: NumberFormatPresetConfig): NumberFormatPreset {\n\tconst preset: NumberFormatPreset = { ...NUMBER_FORMAT_DEFAULTS, ...config };\n\tregistry.set(preset.name, preset);\n\treturn preset;\n}\n\n/** Сбросить реестр к начальному состоянию (только типовые предустановки) */\nexport function resetNumberPresets(): void {\n\tregistry.clear();\n\tinit();\n}\n\nexport function resolveNumberPreset(presetOrName: string | NumberFormatPreset): NumberFormatPreset {\n\tif (typeof presetOrName !== \"string\") return presetOrName;\n\n\tconst found = getNumberPreset(presetOrName);\n\tif (!found) throw new Error(`Предустановка \"${presetOrName}\" не найдена`);\n\n\treturn found;\n}\n","import type {\n\tFormattersPipelineConfig,\n\tFormattersPipelineGraph,\n\tFormattersPipelineNode,\n\tFormattersPipelineNormalizeLeadingZerosConfig,\n\tFormattersPipelinePlan,\n\tFormattersPipelineResolveValueStateConfig,\n\tFormattersPipelineRowBasedOverrideConfig,\n\tFormattersPipelineStep,\n\tFormattersPipelineTypedValueFormatConfig\n} from \"./types\";\n\nexport function cloneTypedValueFormatConfig(\n\tconfig: FormattersPipelineTypedValueFormatConfig | undefined\n): FormattersPipelineTypedValueFormatConfig | undefined {\n\treturn config ? { ...config } : undefined;\n}\n\nexport function cloneNormalizeLeadingZerosConfig(\n\tconfig: FormattersPipelineNormalizeLeadingZerosConfig | undefined\n): FormattersPipelineNormalizeLeadingZerosConfig | undefined {\n\treturn config ? { ...config } : undefined;\n}\n\nexport function cloneRowBasedOverrideConfig(config: FormattersPipelineRowBasedOverrideConfig): FormattersPipelineRowBasedOverrideConfig {\n\treturn config.mode === \"formula\"\n\t\t? { ...config, dependencyIds: config.dependencyIds ? [...config.dependencyIds] : undefined }\n\t\t: { ...config };\n}\n\nexport function cloneResolveValueStateConfig(config: FormattersPipelineResolveValueStateConfig): FormattersPipelineResolveValueStateConfig {\n\treturn {\n\t\tresolver:\n\t\t\tconfig.resolver.kind === \"fixed\"\n\t\t\t\t? {\n\t\t\t\t\t\tkind: \"fixed\",\n\t\t\t\t\t\tentries: { ...config.resolver.entries },\n\t\t\t\t\t\tfallbackState: config.resolver.fallbackState\n\t\t\t\t\t}\n\t\t\t\t: {\n\t\t\t\t\t\tkind: \"threshold\",\n\t\t\t\t\t\tthresholds: config.resolver.thresholds.map((item) => (typeof item === \"number\" ? item : { ...item })),\n\t\t\t\t\t\tstates: [...config.resolver.states],\n\t\t\t\t\t\tinvalidState: config.resolver.invalidState\n\t\t\t\t\t},\n\t\tvalueSource:\n\t\t\tconfig.valueSource?.kind === \"formula\"\n\t\t\t\t? { ...config.valueSource, dependencyIds: [...config.valueSource.dependencyIds] }\n\t\t\t\t: config.valueSource\n\t\t\t\t\t? { ...config.valueSource }\n\t\t\t\t\t: undefined,\n\t\ticon: config.icon ? { ...config.icon } : undefined\n\t};\n}\n\nexport function cloneFormatterPipelinePlanStep(step: FormattersPipelineStep): FormattersPipelineStep {\n\tswitch (step.type) {\n\t\tcase \"typedValueFormat\":\n\t\t\treturn {\n\t\t\t\t...step,\n\t\t\t\tconfig: cloneTypedValueFormatConfig(step.config)\n\t\t\t};\n\t\tcase \"normalizeLeadingZeros\":\n\t\t\treturn {\n\t\t\t\t...step,\n\t\t\t\tconfig: cloneNormalizeLeadingZerosConfig(step.config)\n\t\t\t};\n\t\tcase \"rowBasedOverride\":\n\t\t\treturn {\n\t\t\t\t...step,\n\t\t\t\tconfig: cloneRowBasedOverrideConfig(step.config)\n\t\t\t};\n\t\tcase \"resolveValueState\":\n\t\t\treturn {\n\t\t\t\t...step,\n\t\t\t\tconfig: cloneResolveValueStateConfig(step.config)\n\t\t\t};\n\t\tdefault: {\n\t\t\tconst checker: never = step;\n\t\t\tvoid checker;\n\t\t}\n\t}\n\n\tthrow new Error(`Недопустимый тип '${(step as Record<string, unknown>)?.type}' для шага FormatterPipeline`);\n}\n\nexport function cloneFormatterPipelinePlanStepToNode(\n\tstep: FormattersPipelineStep,\n\tposition: { x: number; y: number }\n): FormattersPipelineNode {\n\tswitch (step.type) {\n\t\tcase \"typedValueFormat\":\n\t\t\treturn {\n\t\t\t\t...step,\n\t\t\t\tposition: { ...position },\n\t\t\t\tconfig: cloneTypedValueFormatConfig(step.config)\n\t\t\t};\n\t\tcase \"normalizeLeadingZeros\":\n\t\t\treturn {\n\t\t\t\t...step,\n\t\t\t\tposition: { ...position },\n\t\t\t\tconfig: cloneNormalizeLeadingZerosConfig(step.config)\n\t\t\t};\n\t\tcase \"rowBasedOverride\":\n\t\t\treturn {\n\t\t\t\t...step,\n\t\t\t\tposition: { ...position },\n\t\t\t\tconfig: cloneRowBasedOverrideConfig(step.config)\n\t\t\t};\n\t\tcase \"resolveValueState\":\n\t\t\treturn {\n\t\t\t\t...step,\n\t\t\t\tposition: { ...position },\n\t\t\t\tconfig: cloneResolveValueStateConfig(step.config)\n\t\t\t};\n\t\tdefault: {\n\t\t\tconst checker: never = step;\n\t\t\tvoid checker;\n\t\t}\n\t}\n\n\tthrow new Error(`Недопустимый тип '${(step as Record<string, unknown>)?.type}' для шага FormatterPipeline`);\n}\n\nfunction cloneNode(node: FormattersPipelineNode): FormattersPipelineNode {\n\tswitch (node.type) {\n\t\tcase \"source\":\n\t\tcase \"sink\":\n\t\t\treturn {\n\t\t\t\t...node,\n\t\t\t\tposition: { ...node.position }\n\t\t\t};\n\t\tdefault:\n\t\t\treturn cloneFormatterPipelinePlanStepToNode(node, node.position);\n\t}\n}\n\nfunction cloneGraph(graph: FormattersPipelineGraph): FormattersPipelineGraph {\n\treturn {\n\t\tnodes: graph.nodes.map(cloneNode),\n\t\tedges: graph.edges.map((edge) => ({ ...edge })),\n\t\tviewport: graph.viewport ? { ...graph.viewport } : undefined\n\t};\n}\n\nfunction clonePlan(plan: FormattersPipelinePlan): FormattersPipelinePlan {\n\treturn {\n\t\tsteps: plan.steps.map(cloneFormatterPipelinePlanStep)\n\t};\n}\n\n/**\n * Возвращает полную копию конфигурации pipeline для безопасного хранения в сторе.\n */\nexport function cloneFormattersPipelineConfig(config: FormattersPipelineConfig | undefined): FormattersPipelineConfig | undefined {\n\tif (!config) return undefined;\n\n\tconst version = config.version;\n\tconst graph = config.graph ? cloneGraph(config.graph) : undefined;\n\tconst plan = config.plan ? clonePlan(config.plan) : undefined;\n\n\treturn { version, graph, plan };\n}\n","import { parseNumber } from \"../number\";\n\nimport type { RowBasedFormatterContext, RowBasedFormatterContextInstrumentation } from \"./types\";\n\nexport function createRowBasedFormatterContext(args: {\n\trowData: Record<string, unknown>;\n\trawValue: unknown;\n\tcolumnId: string;\n\tkeys?: readonly string[];\n\tinstrumentation?: RowBasedFormatterContextInstrumentation;\n}): RowBasedFormatterContext {\n\t// TODO: duplicate createTableFormulaContext src\\shared\\lib\\formulas\\execute.ts\n\tconst keys = [...(args.keys ?? [])];\n\n\tconst readKey = (index: number): string | undefined => {\n\t\tif (!Number.isInteger(index) || index < 0) {\n\t\t\targs.instrumentation?.onOutOfRangeIndex?.(index);\n\t\t\treturn undefined;\n\t\t}\n\n\t\targs.instrumentation?.onReadIndex?.(index);\n\n\t\tif (index >= keys.length) {\n\t\t\targs.instrumentation?.onOutOfRangeIndex?.(index);\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn keys[index];\n\t};\n\n\tconst readValue = (index: number): unknown => {\n\t\tconst key = readKey(index);\n\t\tif (!key) return undefined;\n\t\treturn args.rowData[key];\n\t};\n\n\tconst readNum = (index: number): number => {\n\t\tconst key = readKey(index);\n\t\tif (!key) return 0;\n\t\treturn parseNumber(args.rowData[key]);\n\t};\n\n\treturn {\n\t\trowData: args.rowData,\n\t\trawValue: args.rawValue,\n\t\tcolumnId: args.columnId,\n\t\tkey: readKey,\n\t\tvalue: readValue,\n\t\tnum: readNum\n\t};\n}\n","import type { RowBasedFormatterDefinition } from \"./types\";\n\nexport type RowBasedFormatterRegistry = Readonly<{\n\tlist: readonly RowBasedFormatterDefinition[];\n\tbyId: ReadonlyMap<string, RowBasedFormatterDefinition>;\n}>;\n\n/**\n * Создаёт реестр формул для подмены значения в групповой строке.\n */\nexport function createRowBasedFormatterRegistry(definitions: readonly RowBasedFormatterDefinition[]): RowBasedFormatterRegistry {\n\tconst byId = new Map<string, RowBasedFormatterDefinition>();\n\tconst list: RowBasedFormatterDefinition[] = [];\n\n\tfor (const definition of definitions) {\n\t\tconst normalizedId = definition.id.trim();\n\t\tif (!normalizedId) {\n\t\t\tthrow new Error(\"Formula id для RowBasedFormatter не может быть пустым\");\n\t\t}\n\n\t\tif (byId.has(normalizedId)) {\n\t\t\tthrow new Error(`Найден дублирующийся formulaId в RowBasedFormatter: ${normalizedId}`);\n\t\t}\n\n\t\tconst normalizedDefinition: RowBasedFormatterDefinition = Object.freeze({\n\t\t\t...definition,\n\t\t\tid: normalizedId,\n\t\t\tname: definition.name.trim(),\n\t\t\tdescription: definition.description.trim()\n\t\t});\n\n\t\tbyId.set(normalizedId, normalizedDefinition);\n\t\tlist.push(normalizedDefinition);\n\t}\n\n\treturn Object.freeze({\n\t\tlist: Object.freeze(list),\n\t\tbyId\n\t});\n}\n\nlet rowBasedFormatterRegistry = createRowBasedFormatterRegistry([]);\n\n/**\n * Устанавливает реестр row-based форматтеров host-приложения.\n *\n * Pipeline использует этот реестр при валидации и компиляции formula-режима,\n * поэтому конфигурация должна завершиться до первого построения runtime.\n */\nexport function configureRowBasedFormatterRegistry(registry: RowBasedFormatterRegistry): void {\n\trowBasedFormatterRegistry = registry;\n}\n\n/**\n * Возвращает список доступных формул для групповой подмены.\n */\nexport function getRowBasedFormatterList(): readonly RowBasedFormatterDefinition[] {\n\treturn rowBasedFormatterRegistry.list;\n}\n\n/**\n * Возвращает формулу по id.\n */\nexport function getRowBasedFormatterById(formulaId: string | undefined): RowBasedFormatterDefinition | undefined {\n\tconst normalizedId = formulaId?.trim();\n\tif (!normalizedId) return undefined;\n\treturn rowBasedFormatterRegistry.byId.get(normalizedId);\n}\n","import { validateTableFormulaDependencies } from \"../../formulas\";\nimport { getNumberPreset } from \"../number\";\nimport { createRowBasedFormatterContext, getRowBasedFormatterById } from \"../rowBased\";\n\nimport { cloneResolveValueStateConfig } from \"./clone\";\n\nimport type {\n\tFormattersPipelineConfig,\n\tFormattersPipelineEdge,\n\tFormattersPipelineGraph,\n\tFormattersPipelineNode,\n\tFormattersPipelinePlan,\n\tFormattersPipelineRowBasedOverrideFormulaConfig,\n\tFormattersPipelineStep,\n\tFormattersPipelineValueStateFormulaSource\n} from \"./types\";\n\nexport type FormattersPipelineValidationCode =\n\t| \"config_not_defined\"\n\t| \"unsupported_version\"\n\t| \"graph_or_plan_required\"\n\t| \"node_id_duplicate\"\n\t| \"edge_id_duplicate\"\n\t| \"edge_node_not_found\"\n\t| \"source_count_invalid\"\n\t| \"sink_count_invalid\"\n\t| \"source_incoming_invalid\"\n\t| \"sink_outgoing_invalid\"\n\t| \"node_degree_invalid\"\n\t| \"path_broken\"\n\t| \"path_cycle_detected\"\n\t| \"path_disconnected_nodes\"\n\t| \"step_id_duplicate\"\n\t| \"step_resolve_value_state_multiple\"\n\t| \"step_typed_value_format_multiple\"\n\t| \"step_row_based_override_multiple\"\n\t| \"step_normalize_leading_zeros_multiple\"\n\t| \"step_typed_before_value_state\"\n\t| \"step_row_based_override_field_key_empty\"\n\t| \"step_row_based_override_formula_id_empty\"\n\t| \"step_row_based_override_formula_not_found\"\n\t| \"step_row_based_override_dependency_index_out_of_range\"\n\t| \"step_row_based_override_unused_dependencies\"\n\t| \"step_row_based_override_formula_does_not_use_dependencies\"\n\t| \"step_row_based_override_formula_runtime_error\"\n\t| \"step_value_state_formula_id_empty\"\n\t| \"step_value_state_formula_not_found\"\n\t| \"step_value_state_dependency_id_empty\"\n\t| \"step_value_state_dependency_index_out_of_range\"\n\t| \"step_value_state_unused_dependencies\"\n\t| \"step_value_state_formula_does_not_use_dependencies\"\n\t| \"step_value_state_formula_runtime_error\"\n\t| \"step_threshold_states_count_invalid\"\n\t| \"step_value_hidden_without_icon\"\n\t| \"step_typed_value_format_preset_empty\"\n\t| \"step_typed_value_format_preset_not_found\";\n\nexport type FormattersPipelineValidationMessage = {\n\tcode: FormattersPipelineValidationCode;\n\tmessage: string;\n};\n\nexport type FormattersPipelineValidationResult = {\n\tok: boolean;\n\terrors: FormattersPipelineValidationMessage[];\n\twarnings: FormattersPipelineValidationMessage[];\n\tplan?: FormattersPipelinePlan;\n};\n\ntype MutableValidationState = {\n\terrors: FormattersPipelineValidationMessage[];\n\twarnings: FormattersPipelineValidationMessage[];\n};\n\nfunction pushError(state: MutableValidationState, code: FormattersPipelineValidationCode, message: string) {\n\tstate.errors.push({ code, message });\n}\n\nfunction pushWarning(state: MutableValidationState, code: FormattersPipelineValidationCode, message: string) {\n\tstate.warnings.push({ code, message });\n}\n\nfunction toSortedArray(items: Set<number>): number[] {\n\treturn [...items].sort((left, right) => left - right);\n}\n\nfunction createSampleRowData(dependencies: readonly string[], multiplier: number): Record<string, unknown> {\n\treturn dependencies.reduce<Record<string, unknown>>((acc, dependencyId, index) => {\n\t\tacc[dependencyId] = (index + 1) * multiplier;\n\t\treturn acc;\n\t}, {});\n}\n\nfunction validateRowBasedOverrideFormulaConfig(config: FormattersPipelineRowBasedOverrideFormulaConfig, state: MutableValidationState) {\n\tif (!config.formulaId.trim()) {\n\t\tpushError(state, \"step_row_based_override_formula_id_empty\", \"Для rowBasedOverride (formula) необходимо заполнить formulaId.\");\n\t\treturn;\n\t}\n\n\tconst formula = getRowBasedFormatterById(config.formulaId);\n\tconst dependencies = [...(config.dependencyIds ?? [])];\n\n\tif (!formula) {\n\t\tpushError(state, \"step_row_based_override_formula_not_found\", \"Формула rowBasedOverride не найдена в реестре.\");\n\t\treturn;\n\t}\n\n\tconst usedIndexes = new Set<number>();\n\tconst outOfRangeIndexes = new Set<number>();\n\tlet runtimeErrorCount = 0;\n\n\tconst runValidationPass = (sampleRowData: Record<string, unknown>) => {\n\t\ttry {\n\t\t\tconst context = createRowBasedFormatterContext({\n\t\t\t\trowData: sampleRowData,\n\t\t\t\trawValue: 100,\n\t\t\t\tcolumnId: \"__validation__\",\n\t\t\t\tkeys: dependencies,\n\t\t\t\tinstrumentation: {\n\t\t\t\t\tonReadIndex: (index) => {\n\t\t\t\t\t\tusedIndexes.add(index);\n\t\t\t\t\t},\n\t\t\t\t\tonOutOfRangeIndex: (index) => {\n\t\t\t\t\t\toutOfRangeIndexes.add(index);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tformula.fn(context);\n\t\t} catch {\n\t\t\truntimeErrorCount += 1;\n\t\t}\n\t};\n\n\t// Несколько прогонов повышают шанс увидеть обращения к индексам в разных ветках формулы.\n\trunValidationPass(createSampleRowData(dependencies, 100));\n\trunValidationPass(createSampleRowData(dependencies, -100));\n\n\tconst sortedUsedIndexes = toSortedArray(usedIndexes);\n\tconst requiredDependencyCount = sortedUsedIndexes.length > 0 ? sortedUsedIndexes[sortedUsedIndexes.length - 1] + 1 : 0;\n\n\tif (outOfRangeIndexes.size > 0) {\n\t\tpushError(\n\t\t\tstate,\n\t\t\t\"step_row_based_override_dependency_index_out_of_range\",\n\t\t\t`Формула rowBasedOverride обращается к несуществующим индексам. Минимально требуется зависимостей: ${requiredDependencyCount}, выбрано: ${dependencies.length}.`\n\t\t);\n\t}\n\n\tif (sortedUsedIndexes.length === 0) {\n\t\tpushWarning(\n\t\t\tstate,\n\t\t\t\"step_row_based_override_formula_does_not_use_dependencies\",\n\t\t\t\"Формула rowBasedOverride не использует dependencyIds.\"\n\t\t);\n\t}\n\n\tconst unusedDependencies = dependencies.filter((_, index) => !usedIndexes.has(index));\n\tif (unusedDependencies.length > 0) {\n\t\tpushWarning(\n\t\t\tstate,\n\t\t\t\"step_row_based_override_unused_dependencies\",\n\t\t\t`Выбраны, но не используются формулой rowBasedOverride: ${unusedDependencies.join(\", \")}.`\n\t\t);\n\t}\n\n\tif (runtimeErrorCount > 0) {\n\t\tpushWarning(\n\t\t\tstate,\n\t\t\t\"step_row_based_override_formula_runtime_error\",\n\t\t\t\"На тестовых данных формула rowBasedOverride завершилась с ошибкой.\"\n\t\t);\n\t}\n}\n\n/**\n * Pipeline проверяет контракт формулы и индексы, а наличие полей в конкретном\n * источнике данных проверяет потребитель через collectRuntimeFieldDependencyIds.\n */\nfunction validateValueStateFormulaSource(source: FormattersPipelineValueStateFormulaSource, state: MutableValidationState) {\n\tif (!source.formulaId.trim()) {\n\t\tpushError(state, \"step_value_state_formula_id_empty\", \"Для источника состояния необходимо выбрать формулу.\");\n\t\treturn;\n\t}\n\n\tif (source.dependencyIds.some((dependencyId) => !dependencyId.trim())) {\n\t\tpushError(state, \"step_value_state_dependency_id_empty\", \"Зависимость формулы состояния не может иметь пустой id.\");\n\t\treturn;\n\t}\n\n\tconst validation = validateTableFormulaDependencies({\n\t\tformulaId: source.formulaId,\n\t\tdependencies: source.dependencyIds,\n\t\tavailableColumnIds: source.dependencyIds\n\t});\n\tfor (const error of validation.errors) {\n\t\tif (error.code === \"formula_not_found\") {\n\t\t\tpushError(state, \"step_value_state_formula_not_found\", \"Формула источника состояния не найдена в реестре.\");\n\t\t} else if (error.code === \"dependency_index_out_of_range\") {\n\t\t\tpushError(state, \"step_value_state_dependency_index_out_of_range\", error.message);\n\t\t}\n\t}\n\tfor (const warning of validation.warnings) {\n\t\tswitch (warning.code) {\n\t\t\tcase \"unused_dependencies\":\n\t\t\t\tpushWarning(state, \"step_value_state_unused_dependencies\", warning.message);\n\t\t\t\tbreak;\n\t\t\tcase \"formula_does_not_use_dependencies\":\n\t\t\t\tpushWarning(state, \"step_value_state_formula_does_not_use_dependencies\", warning.message);\n\t\t\t\tbreak;\n\t\t\tcase \"formula_runtime_error\":\n\t\t\t\tpushWarning(state, \"step_value_state_formula_runtime_error\", warning.message);\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\nfunction validateStepDefinitions(steps: readonly FormattersPipelineStep[], state: MutableValidationState) {\n\tconst stepIdSet = new Set<string>();\n\tconst counters = {\n\t\tnormalizeLeadingZeros: 0,\n\t\trowBasedOverride: 0,\n\t\tresolveValueState: 0,\n\t\ttypedValueFormat: 0\n\t};\n\n\tfor (const step of steps) {\n\t\tconst normalizedId = step.id.trim();\n\t\tif (!normalizedId) {\n\t\t\tpushError(state, \"step_id_duplicate\", \"Шаг pipeline не может иметь пустой id.\");\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (stepIdSet.has(normalizedId)) {\n\t\t\tpushError(state, \"step_id_duplicate\", `Найден дублирующийся id шага pipeline: ${normalizedId}.`);\n\t\t}\n\t\tstepIdSet.add(normalizedId);\n\n\t\tswitch (step.type) {\n\t\t\tcase \"normalizeLeadingZeros\":\n\t\t\t\tcounters.normalizeLeadingZeros += 1;\n\t\t\t\tbreak;\n\t\t\tcase \"rowBasedOverride\":\n\t\t\t\tcounters.rowBasedOverride += 1;\n\n\t\t\t\tif (step.config.mode === \"field\" && !step.config.fieldKey.trim()) {\n\t\t\t\t\tpushError(\n\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\"step_row_based_override_field_key_empty\",\n\t\t\t\t\t\t\"Для rowBasedOverride (field) необходимо заполнить fieldKey.\"\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (step.config.mode === \"formula\") {\n\t\t\t\t\tvalidateRowBasedOverrideFormulaConfig(step.config, state);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"resolveValueState\":\n\t\t\t\tcounters.resolveValueState += 1;\n\t\t\t\tif (step.config.valueSource?.kind === \"formula\") {\n\t\t\t\t\tvalidateValueStateFormulaSource(step.config.valueSource, state);\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\tstep.config.resolver.kind === \"threshold\" &&\n\t\t\t\t\tstep.config.resolver.states.length !== step.config.resolver.thresholds.length + 1\n\t\t\t\t) {\n\t\t\t\t\tpushError(\n\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\"step_threshold_states_count_invalid\",\n\t\t\t\t\t\t\"Для threshold-резолвера количество states должно быть равно thresholds + 1.\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"typedValueFormat\":\n\t\t\t\tcounters.typedValueFormat += 1;\n\t\t\t\tif (step.config?.numberPresetName !== undefined) {\n\t\t\t\t\tconst normalizedPresetName = step.config.numberPresetName.trim();\n\t\t\t\t\tif (!normalizedPresetName) {\n\t\t\t\t\t\tpushError(state, \"step_typed_value_format_preset_empty\", \"Для typedValueFormat указан пустой numberPresetName.\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!getNumberPreset(normalizedPresetName)) {\n\t\t\t\t\t\tpushError(\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t\t\"step_typed_value_format_preset_not_found\",\n\t\t\t\t\t\t\t`Для typedValueFormat указан неизвестный пресет: ${normalizedPresetName}.`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (counters.normalizeLeadingZeros > 1) {\n\t\tpushError(state, \"step_normalize_leading_zeros_multiple\", \"В pipeline может быть только один шаг normalizeLeadingZeros.\");\n\t}\n\n\tif (counters.rowBasedOverride > 1) {\n\t\tpushError(state, \"step_row_based_override_multiple\", \"В pipeline может быть только один шаг rowBasedOverride.\");\n\t}\n\n\tif (counters.resolveValueState > 1) {\n\t\tpushError(state, \"step_resolve_value_state_multiple\", \"В pipeline может быть только один шаг resolveValueState.\");\n\t}\n\n\tif (counters.typedValueFormat > 1) {\n\t\tpushError(state, \"step_typed_value_format_multiple\", \"В pipeline может быть только один шаг typedValueFormat.\");\n\t}\n\n\tconst resolveIndex = steps.findIndex((step) => step.type === \"resolveValueState\");\n\tconst typedIndex = steps.findIndex((step) => step.type === \"typedValueFormat\");\n\tif (resolveIndex !== -1 && typedIndex !== -1 && typedIndex < resolveIndex) {\n\t\tpushError(state, \"step_typed_before_value_state\", \"Шаг typedValueFormat не может выполняться до шага resolveValueState.\");\n\t}\n\n\tfor (const step of steps) {\n\t\tif (step.type !== \"resolveValueState\") continue;\n\t\tif (!step.config.icon?.enabled && step.config.icon?.showValue === false) {\n\t\t\tpushWarning(\n\t\t\t\tstate,\n\t\t\t\t\"step_value_hidden_without_icon\",\n\t\t\t\t\"Для resolveValueState установлено showValue=false при выключенной иконке: значение не будет отображаться.\"\n\t\t\t);\n\t\t}\n\t}\n}\n\n/**\n * Валидация облегчённого плана pipeline.\n */\nexport function validateFormattersPipelinePlan(plan: FormattersPipelinePlan): FormattersPipelineValidationResult {\n\tconst state: MutableValidationState = { errors: [], warnings: [] };\n\n\tvalidateStepDefinitions(plan.steps, state);\n\n\treturn {\n\t\tok: state.errors.length === 0,\n\t\terrors: state.errors,\n\t\twarnings: state.warnings,\n\t\tplan: state.errors.length === 0 ? { steps: [...plan.steps] } : undefined\n\t};\n}\n\nfunction buildLinearPathFromGraph(\n\tnodes: readonly FormattersPipelineNode[],\n\tedges: readonly FormattersPipelineEdge[],\n\tstate: MutableValidationState\n): string[] | undefined {\n\tconst nodeById = new Map(nodes.map((node) => [node.id, node]));\n\tconst outgoing = new Map<string, string[]>();\n\tconst incoming = new Map<string, string[]>();\n\n\tfor (const node of nodes) {\n\t\toutgoing.set(node.id, []);\n\t\tincoming.set(node.id, []);\n\t}\n\n\tfor (const edge of edges) {\n\t\tconst source = edge.source.trim();\n\t\tconst target = edge.target.trim();\n\t\tif (!nodeById.has(source) || !nodeById.has(target)) {\n\t\t\tpushError(state, \"edge_node_not_found\", `Ребро ${edge.id} ссылается на несуществующий узел: ${source} -> ${target}.`);\n\t\t\tcontinue;\n\t\t}\n\n\t\toutgoing.get(source)?.push(target);\n\t\tincoming.get(target)?.push(source);\n\t}\n\n\tconst sources = nodes.filter((node) => node.type === \"source\");\n\tconst sinks = nodes.filter((node) => node.type === \"sink\");\n\n\tif (sources.length !== 1) {\n\t\tpushError(state, \"source_count_invalid\", \"В графе должен быть ровно один узел source.\");\n\t}\n\tif (sinks.length !== 1) {\n\t\tpushError(state, \"sink_count_invalid\", \"В графе должен быть ровно один узел sink.\");\n\t}\n\tif (state.errors.length > 0) return undefined;\n\n\tconst sourceNodeId = sources[0]!.id;\n\tconst sinkNodeId = sinks[0]!.id;\n\n\tfor (const node of nodes) {\n\t\tconst inDegree = incoming.get(node.id)?.length ?? 0;\n\t\tconst outDegree = outgoing.get(node.id)?.length ?? 0;\n\n\t\tif (node.type === \"source\") {\n\t\t\tif (inDegree !== 0) {\n\t\t\t\tpushError(state, \"source_incoming_invalid\", \"Узел source не должен иметь входящих рёбер.\");\n\t\t\t}\n\t\t\tif (outDegree !== 1) {\n\t\t\t\tpushError(state, \"node_degree_invalid\", \"Узел source должен иметь ровно одно исходящее ребро.\");\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (node.type === \"sink\") {\n\t\t\tif (outDegree !== 0) {\n\t\t\t\tpushError(state, \"sink_outgoing_invalid\", \"Узел sink не должен иметь исходящих рёбер.\");\n\t\t\t}\n\t\t\tif (inDegree !== 1) {\n\t\t\t\tpushError(state, \"node_degree_invalid\", \"Узел sink должен иметь ровно одно входящее ребро.\");\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (inDegree !== 1 || outDegree !== 1) {\n\t\t\tpushError(\n\t\t\t\tstate,\n\t\t\t\t\"node_degree_invalid\",\n\t\t\t\t`Узел ${node.id} должен иметь ровно одно входящее и одно исходящее ребро для линейного pipeline.`\n\t\t\t);\n\t\t}\n\t}\n\n\tif (state.errors.length > 0) return undefined;\n\n\tconst visited = new Set<string>();\n\tconst path: string[] = [];\n\tlet cursor = sourceNodeId;\n\n\twhile (true) {\n\t\tif (visited.has(cursor)) {\n\t\t\tpushError(state, \"path_cycle_detected\", \"В графе pipeline обнаружен цикл.\");\n\t\t\treturn undefined;\n\t\t}\n\t\tvisited.add(cursor);\n\t\tpath.push(cursor);\n\n\t\tif (cursor === sinkNodeId) {\n\t\t\tbreak;\n\t\t}\n\n\t\tconst nextCandidates = outgoing.get(cursor) ?? [];\n\t\tif (nextCandidates.length !== 1) {\n\t\t\tpushError(state, \"path_broken\", \"Не удалось построить линейный путь от source к sink.\");\n\t\t\treturn undefined;\n\t\t}\n\n\t\tcursor = nextCandidates[0]!;\n\t}\n\n\tif (visited.size !== nodes.length) {\n\t\tpushError(state, \"path_disconnected_nodes\", \"Граф содержит узлы, которые не входят в линейный путь source -> sink.\");\n\t\treturn undefined;\n\t}\n\n\treturn path;\n}\n\n/**\n * Валидация графа pipeline и построение линейного плана исполнения.\n */\nexport function validateFormattersPipelineGraph(graph: FormattersPipelineGraph): FormattersPipelineValidationResult {\n\tconst state: MutableValidationState = { errors: [], warnings: [] };\n\n\tif (!graph.nodes.length) {\n\t\tpushError(state, \"path_broken\", \"Граф pipeline не содержит узлов.\");\n\t\treturn { ok: false, errors: state.errors, warnings: state.warnings };\n\t}\n\n\tconst nodeById = new Map<string, FormattersPipelineNode>();\n\tfor (const node of graph.nodes) {\n\t\tconst normalizedId = node.id.trim();\n\t\tif (!normalizedId) {\n\t\t\tpushError(state, \"node_id_duplicate\", \"Узел pipeline не может иметь пустой id.\");\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (nodeById.has(normalizedId)) {\n\t\t\tpushError(state, \"node_id_duplicate\", `Найден дублирующийся id узла pipeline: ${normalizedId}.`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tnodeById.set(normalizedId, node);\n\t}\n\n\tconst edgeIdSet = new Set<string>();\n\tfor (const edge of graph.edges) {\n\t\tconst normalizedEdgeId = edge.id.trim();\n\t\tif (!normalizedEdgeId) {\n\t\t\tpushError(state, \"edge_id_duplicate\", \"Ребро pipeline не может иметь пустой id.\");\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (edgeIdSet.has(normalizedEdgeId)) {\n\t\t\tpushError(state, \"edge_id_duplicate\", `Найден дублирующийся id ребра pipeline: ${normalizedEdgeId}.`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tedgeIdSet.add(normalizedEdgeId);\n\t}\n\n\tif (state.errors.length > 0) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terrors: state.errors,\n\t\t\twarnings: state.warnings\n\t\t};\n\t}\n\n\tconst path = buildLinearPathFromGraph(graph.nodes, graph.edges, state);\n\tif (!path) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\terrors: state.errors,\n\t\t\twarnings: state.warnings\n\t\t};\n\t}\n\n\tconst steps: FormattersPipelineStep[] = [];\n\tfor (const nodeId of path) {\n\t\tconst node = nodeById.get(nodeId);\n\t\tif (!node || node.type === \"source\" || node.type === \"sink\") continue;\n\n\t\tswitch (node.type) {\n\t\t\tcase \"normalizeLeadingZeros\":\n\t\t\t\tsteps.push({\n\t\t\t\t\tid: node.id,\n\t\t\t\t\ttype: \"normalizeLeadingZeros\",\n\t\t\t\t\tconfig: node.config ? { ...node.config } : undefined\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"rowBasedOverride\":\n\t\t\t\tsteps.push({\n\t\t\t\t\tid: node.id,\n\t\t\t\t\ttype: \"rowBasedOverride\",\n\t\t\t\t\tconfig:\n\t\t\t\t\t\tnode.config.mode === \"formula\"\n\t\t\t\t\t\t\t? { ...node.config, dependencyIds: node.config.dependencyIds ? [...node.config.dependencyIds] : undefined }\n\t\t\t\t\t\t\t: { ...node.config }\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"resolveValueState\":\n\t\t\t\tsteps.push({\n\t\t\t\t\tid: node.id,\n\t\t\t\t\ttype: \"resolveValueState\",\n\t\t\t\t\tconfig: cloneResolveValueStateConfig(node.config)\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"typedValueFormat\":\n\t\t\t\tsteps.push({\n\t\t\t\t\tid: node.id,\n\t\t\t\t\ttype: \"typedValueFormat\",\n\t\t\t\t\tconfig: node.config ? { ...node.config } : undefined\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tvalidateStepDefinitions(steps, state);\n\n\treturn {\n\t\tok: state.errors.length === 0,\n\t\terrors: state.errors,\n\t\twarnings: state.warnings,\n\t\tplan: state.errors.length === 0 ? { steps } : undefined\n\t};\n}\n\n/**\n * Валидация конфигурации pipeline c выбором рабочего плана исполнения.\n *\n * Приоритет источника плана:\n * 1) `plan` из конфигурации;\n * 2) построение плана из `graph`.\n */\nexport function validateFormattersPipelineConfig(config: FormattersPipelineConfig | undefined): FormattersPipelineValidationResult {\n\tconst state: MutableValidationState = { errors: [], warnings: [] };\n\n\tif (!config) {\n\t\tpushError(state, \"config_not_defined\", \"Конфигурация pipeline не задана.\");\n\t\treturn {\n\t\t\tok: false,\n\t\t\terrors: state.errors,\n\t\t\twarnings: state.warnings\n\t\t};\n\t}\n\n\tif (config.version !== 1) {\n\t\tpushError(state, \"unsupported_version\", `Неподдерживаемая версия pipeline: ${String(config.version)}.`);\n\t\treturn {\n\t\t\tok: false,\n\t\t\terrors: state.errors,\n\t\t\twarnings: state.warnings\n\t\t};\n\t}\n\n\tif (!config.plan && !config.graph) {\n\t\tpushError(state, \"graph_or_plan_required\", \"Для pipeline должен быть задан хотя бы один источник: graph или plan.\");\n\t\treturn {\n\t\t\tok: false,\n\t\t\terrors: state.errors,\n\t\t\twarnings: state.warnings\n\t\t};\n\t}\n\n\tif (config.plan) {\n\t\tconst planResult = validateFormattersPipelinePlan(config.plan);\n\t\tstate.errors.push(...planResult.errors);\n\t\tstate.warnings.push(...planResult.warnings);\n\n\t\tif (planResult.ok && planResult.plan) {\n\t\t\treturn {\n\t\t\t\tok: true,\n\t\t\t\terrors: state.errors,\n\t\t\t\twarnings: state.warnings,\n\t\t\t\tplan: planResult.plan\n\t\t\t};\n\t\t}\n\n\t\tif (config.graph) {\n\t\t\tpushWarning(state, \"path_broken\", \"Линейный plan невалиден. Выполнена попытка построить план из graph.\");\n\t\t\tstate.errors.length = 0;\n\t\t} else {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terrors: state.errors,\n\t\t\t\twarnings: state.warnings\n\t\t\t};\n\t\t}\n\t}\n\n\tif (config.graph) {\n\t\tconst graphResult = validateFormattersPipelineGraph(config.graph);\n\t\treturn {\n\t\t\tok: graphResult.ok,\n\t\t\terrors: [...state.errors, ...graphResult.errors],\n\t\t\twarnings: [...state.warnings, ...graphResult.warnings],\n\t\t\tplan: graphResult.plan\n\t\t};\n\t}\n\n\treturn {\n\t\tok: false,\n\t\terrors: state.errors,\n\t\twarnings: state.warnings\n\t};\n}\n"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
- import { Vt as e } from "../chunks/formatters-hHUJpZqD.js";
1
+ import { Vt as e } from "../chunks/formatters-CEltML3y.js";
2
2
  import { _ as t } from "../chunks/array-D-_yMMUK.js";
3
3
  import { stableStringify as n } from "../utils/index.js";
4
- import { hashString128 as r, uuidv4 as i } from "../crypto/index.js";
5
- import { ERROR_REPORT_BUILD_ID_PATTERN as a } from "../error-report-build/index.js";
6
- import { an as o } from "../chunks/odata-service-CWkHASdw.js";
4
+ import { an as r } from "../chunks/odata-service-CWkHASdw.js";
5
+ import { hashString128 as i, uuidv4 as a } from "../crypto/index.js";
6
+ import { ERROR_REPORT_BUILD_ID_PATTERN as o } from "../error-report-build/index.js";
7
7
  import { g as s } from "../chunks/query-client-Gk7lxFz7.js";
8
8
  import { getSessionStorageId as ee } from "../session-storage/index.js";
9
9
  import { z as c } from "zod";
@@ -737,7 +737,7 @@ function dt(e) {
737
737
  if (e) return e.split("\n").map((e) => e.trim()).filter(Boolean);
738
738
  }
739
739
  function ft(e) {
740
- return r(n({
740
+ return i(n({
741
741
  category: e.category,
742
742
  source: e.source,
743
743
  error: {
@@ -985,7 +985,7 @@ function jt(e) {
985
985
  } catch {}
986
986
  }
987
987
  function Mt() {
988
- return B ? (kt ??= i(), kt) : ee(Dt);
988
+ return B ? (kt ??= a(), kt) : ee(Dt);
989
989
  }
990
990
  //#endregion
991
991
  //#region src/error-report/diagnostics.ts
@@ -997,10 +997,10 @@ function Ft(e, t, n) {
997
997
  });
998
998
  }
999
999
  function W(e) {
1000
- let t = u(), i = v(e.queryKey, { scope: "query-key" }) ?? { type: "redacted" }, a = t.valuePolicy === "verbatim" ? r(e.queryHash) : r(n(i));
1000
+ let t = u(), r = v(e.queryKey, { scope: "query-key" }) ?? { type: "redacted" }, a = t.valuePolicy === "verbatim" ? i(e.queryHash) : i(n(r));
1001
1001
  return {
1002
1002
  queryHash: a,
1003
- queryKey: i,
1003
+ queryKey: r,
1004
1004
  status: e.state.status,
1005
1005
  fetchStatus: e.state.fetchStatus,
1006
1006
  dataUpdatedAt: e.state.dataUpdatedAt,
@@ -1041,18 +1041,18 @@ function K(e) {
1041
1041
  };
1042
1042
  }
1043
1043
  function It(e) {
1044
- let t = u(), i = e.state, a = v(e.queryKey, { scope: "persisted-query-key" }), o = t.valuePolicy === "verbatim" ? r(e.queryHash) : a ? r(n(a)) : void 0;
1044
+ let t = u(), r = e.state, a = v(e.queryKey, { scope: "persisted-query-key" }), o = t.valuePolicy === "verbatim" ? i(e.queryHash) : a ? i(n(a)) : void 0;
1045
1045
  return {
1046
1046
  buster: e.buster ? p(e.buster, 512) : void 0,
1047
1047
  queryHash: o,
1048
1048
  queryKey: a,
1049
- status: i.status,
1050
- fetchStatus: i.fetchStatus,
1051
- dataUpdatedAt: i.dataUpdatedAt,
1052
- errorUpdatedAt: i.errorUpdatedAt,
1053
- failureCount: i.fetchFailureCount,
1054
- dataPreview: t.valuePolicy === "verbatim" && t.dataPreviewBytes.persistedQuery > 0 && i.data !== void 0 ? w(i.data, t.dataPreviewBytes.persistedQuery) : void 0,
1055
- error: i.error ? M(i.error) : void 0
1049
+ status: r.status,
1050
+ fetchStatus: r.fetchStatus,
1051
+ dataUpdatedAt: r.dataUpdatedAt,
1052
+ errorUpdatedAt: r.errorUpdatedAt,
1053
+ failureCount: r.fetchFailureCount,
1054
+ dataPreview: t.valuePolicy === "verbatim" && t.dataPreviewBytes.persistedQuery > 0 && r.data !== void 0 ? w(r.data, t.dataPreviewBytes.persistedQuery) : void 0,
1055
+ error: r.error ? M(r.error) : void 0
1056
1056
  };
1057
1057
  }
1058
1058
  async function q() {
@@ -1088,7 +1088,7 @@ function zt() {
1088
1088
  //#endregion
1089
1089
  //#region src/error-report/drafts.ts
1090
1090
  function Bt() {
1091
- return o(/* @__PURE__ */ new Date());
1091
+ return r(/* @__PURE__ */ new Date());
1092
1092
  }
1093
1093
  function Vt() {
1094
1094
  if (typeof window > "u") return;
@@ -1134,7 +1134,7 @@ function Kt() {
1134
1134
  }
1135
1135
  function J(e) {
1136
1136
  if (!Lt()) return;
1137
- let t = i(), n = Mt(), r = Bt(), a = at({
1137
+ let t = a(), n = Mt(), r = Bt(), i = at({
1138
1138
  payloadVersion: 1,
1139
1139
  application: __APP_ID__,
1140
1140
  reportId: t,
@@ -1163,7 +1163,7 @@ function J(e) {
1163
1163
  createdUtc: r,
1164
1164
  category: e.category,
1165
1165
  status: "pending",
1166
- payload: a
1166
+ payload: i
1167
1167
  });
1168
1168
  if (o) return jt([...U(), o]), o;
1169
1169
  }
@@ -1539,6 +1539,6 @@ async function En(e, t = {}) {
1539
1539
  } catch {}
1540
1540
  }
1541
1541
  //#endregion
1542
- export { a as ERROR_REPORT_BUILD_ID_PATTERN, T as ERROR_REPORT_PAYLOAD_MAX_BYTES, Ge as ERROR_REPORT_PAYLOAD_VERSION, fn as ERROR_REPORT_QUEUE_LEASE_MS, un as ERROR_REPORT_QUEUE_MAX_ITEMS, dn as ERROR_REPORT_QUEUE_TTL_MS, ln as ERROR_REPORT_QUEUE_VERSION, E as ERROR_REPORT_STACK_TRACE_MAX_BYTES, Ke as ERROR_REPORT_VERBATIM_MESSAGE_MAX_BYTES, x as addErrorReportBreadcrumb, J as captureErrorReportDraft, sn as captureMutationErrorReport, on as captureQueryErrorReport, cn as captureRuntimeErrorReport, Te as clearErrorReportBreadcrumbs, G as collectMutationDiagnostics, q as collectPersistedQueryDiagnostics, K as collectQueryClientDiagnostics, W as collectQueryDiagnostics, _ as createDataShape, _e as createDiagnosticValue, M as createErrorInfo, Cn as createErrorReportQueue, At as disableErrorReportBrowserStorage, we as getErrorReportBreadcrumbs, zt as getErrorReportClientEnvironment, Wt as getErrorReportDraft, Kt as getErrorReportDrafts, Rt as getErrorReportEnvironment, k as getErrorReportPayloadSize, m as getUtf8TextSize, Le as installErrorReportBrowserBreadcrumbs, Lt as isErrorReportingEnabled, nn as isTransportErrorReportScheduled, at as limitErrorReportPayload, Z as normalizeErrorReportQueueRecords, z as parseErrorReportDraft, Tt as parseErrorReportDrafts, R as parseErrorReportPayload, vn as parseErrorReportQueueRecord, En as reportRuntimeError, an as reportTransportError, y as sanitizeDetail, p as sanitizeDiagnosticText, h as sanitizeDiagnosticTextBytes, v as sanitizeErrorReportValue, ie as setErrorReportCaptureOptions, Tn as setErrorReportRuntimeErrorReporter, ve as setErrorReportSanitizer, tn as setErrorReportTransportErrorReporter, rn as suppressTransportErrorReport, Gt as updateErrorReportDraft };
1542
+ export { o as ERROR_REPORT_BUILD_ID_PATTERN, T as ERROR_REPORT_PAYLOAD_MAX_BYTES, Ge as ERROR_REPORT_PAYLOAD_VERSION, fn as ERROR_REPORT_QUEUE_LEASE_MS, un as ERROR_REPORT_QUEUE_MAX_ITEMS, dn as ERROR_REPORT_QUEUE_TTL_MS, ln as ERROR_REPORT_QUEUE_VERSION, E as ERROR_REPORT_STACK_TRACE_MAX_BYTES, Ke as ERROR_REPORT_VERBATIM_MESSAGE_MAX_BYTES, x as addErrorReportBreadcrumb, J as captureErrorReportDraft, sn as captureMutationErrorReport, on as captureQueryErrorReport, cn as captureRuntimeErrorReport, Te as clearErrorReportBreadcrumbs, G as collectMutationDiagnostics, q as collectPersistedQueryDiagnostics, K as collectQueryClientDiagnostics, W as collectQueryDiagnostics, _ as createDataShape, _e as createDiagnosticValue, M as createErrorInfo, Cn as createErrorReportQueue, At as disableErrorReportBrowserStorage, we as getErrorReportBreadcrumbs, zt as getErrorReportClientEnvironment, Wt as getErrorReportDraft, Kt as getErrorReportDrafts, Rt as getErrorReportEnvironment, k as getErrorReportPayloadSize, m as getUtf8TextSize, Le as installErrorReportBrowserBreadcrumbs, Lt as isErrorReportingEnabled, nn as isTransportErrorReportScheduled, at as limitErrorReportPayload, Z as normalizeErrorReportQueueRecords, z as parseErrorReportDraft, Tt as parseErrorReportDrafts, R as parseErrorReportPayload, vn as parseErrorReportQueueRecord, En as reportRuntimeError, an as reportTransportError, y as sanitizeDetail, p as sanitizeDiagnosticText, h as sanitizeDiagnosticTextBytes, v as sanitizeErrorReportValue, ie as setErrorReportCaptureOptions, Tn as setErrorReportRuntimeErrorReporter, ve as setErrorReportSanitizer, tn as setErrorReportTransportErrorReporter, rn as suppressTransportErrorReport, Gt as updateErrorReportDraft };
1543
1543
 
1544
1544
  //# sourceMappingURL=index.js.map
@@ -1,6 +1,6 @@
1
- import { p as e } from "../chunks/dom-Dbq_09-K.js";
2
- import { Sn as t, c as n, l as r, pn as i, s as a, u as o, xn as s } from "../chunks/odata-service-CWkHASdw.js";
3
- import { t as c, v as l } from "../chunks/validate-DnkaY38p.js";
1
+ import { Sn as e, c as t, l as n, pn as r, s as i, u as a, xn as o } from "../chunks/odata-service-CWkHASdw.js";
2
+ import { t as s, v as c } from "../chunks/validate-M2zPiLXn.js";
3
+ import { p as l } from "../chunks/dom-Dbq_09-K.js";
4
4
  import { escapeXmlValue as u } from "../xml/index.js";
5
5
  import d from "write-excel-file/browser";
6
6
  //#region src/excel/excel.ts
@@ -13,8 +13,8 @@ var ee = {
13
13
  fontWeight: "bold",
14
14
  bottomBorderStyle: "thin",
15
15
  bottomBorderColor: "#D9D9D9"
16
- }, f = 31, p = /[\u0000-\u001f[\]/\\:*?]+/g, m = /^'+|'+$/g, h = /\s+/g;
17
- function ne(e) {
16
+ }, f = 31, ne = /[\u0000-\u001f[\]/\\:*?]+/g, p = /^'+|'+$/g, m = /\s+/g;
17
+ function h(e) {
18
18
  let t = e ? ee[e] : void 0;
19
19
  return t ? { textColor: t } : void 0;
20
20
  }
@@ -29,16 +29,16 @@ function g(e) {
29
29
  function _(e, t) {
30
30
  if (!(e <= 0 || t <= 0)) return `A1:${g(e - 1)}${t}`;
31
31
  }
32
- function re(e) {
32
+ function v(e) {
33
33
  if (e.some(Boolean)) return { files: { transform: { "xl/worksheets/sheet{id}.xml": { transform: (t, n, r) => {
34
34
  let i = e[r.sheetIndex];
35
35
  return i ? t.replace("</sheetData>", `</sheetData><autoFilter ref="${i}"/>`) : t;
36
36
  } } } } };
37
37
  }
38
- function v(e) {
38
+ function y(e) {
39
39
  let t = /* @__PURE__ */ new Set(), n = [];
40
40
  for (let r = 0; r < e.length; r += 1) {
41
- let i = `Лист ${r + 1}`, a = e[r]?.replace(p, " ").replace(h, " ").trim().replace(m, "").trim() || i, o = a.slice(0, f), s = 2;
41
+ let i = `Лист ${r + 1}`, a = e[r]?.replace(ne, " ").replace(m, " ").trim().replace(p, "").trim() || i, o = a.slice(0, f), s = 2;
42
42
  for (; t.has(o.toLocaleLowerCase());) {
43
43
  let e = ` (${s})`;
44
44
  o = `${a.slice(0, f - e.length)}${e}`, s += 1;
@@ -47,13 +47,13 @@ function v(e) {
47
47
  }
48
48
  return n;
49
49
  }
50
- function y(e, t) {
50
+ function re(e, t) {
51
51
  if (e != null && e !== "") {
52
52
  if (t === Number) {
53
53
  let t = typeof e == "number" ? e : Number(e);
54
54
  return Number.isFinite(t) ? t : void 0;
55
55
  }
56
- return t === String ? String(e) : t === Boolean ? !!e : t === Date ? e instanceof Date ? e : i(e) ?? void 0 : e;
56
+ return t === String ? String(e) : t === Boolean ? !!e : t === Date ? e instanceof Date ? e : r(e) ?? void 0 : e;
57
57
  }
58
58
  }
59
59
  function b(e) {
@@ -65,7 +65,7 @@ function b(e) {
65
65
  for (let n = 0; n < e.rows.length; n++) {
66
66
  let r = e.rows[n], i = [];
67
67
  for (let t = 0; t < e.columns.length; t++) {
68
- let a = e.columns[t], o = y(r[a.id], a.type), s = e.getCellStyle?.({
68
+ let a = e.columns[t], o = re(r[a.id], a.type), s = e.getCellStyle?.({
69
69
  row: r,
70
70
  column: a,
71
71
  rowIndex: n,
@@ -84,14 +84,14 @@ function b(e) {
84
84
  }
85
85
  async function x(e) {
86
86
  if (e.sheets.length === 0) throw Error("Для формирования Excel-книги нужен минимум один лист");
87
- let t = v(e.sheets.map((e) => e.name)), n = [], r = e.sheets.map((e, r) => {
87
+ let t = y(e.sheets.map((e) => e.name)), n = [], r = e.sheets.map((e, r) => {
88
88
  let i = b(e);
89
89
  return n.push(e.autoFilter ? _(e.columns.length, i.length) : void 0), {
90
90
  data: i,
91
91
  sheet: t[r],
92
92
  columns: e.columns.map((e) => ({ width: e.width }))
93
93
  };
94
- }), i = re(n);
94
+ }), i = v(n);
95
95
  await d(r, { features: i ? [i] : void 0 }).toFile(e.fileName);
96
96
  }
97
97
  async function S(e) {
@@ -217,7 +217,7 @@ async function R(e) {
217
217
  if (t.rows.length === 0) throw Error(`Лист «${t.name}» не содержит строк`);
218
218
  t.print && A(t.print);
219
219
  }
220
- let t = v(e.sheets.map(({ name: e }) => e)), n = e.sheets.map((e, n) => ({
220
+ let t = y(e.sheets.map(({ name: e }) => e)), n = e.sheets.map((e, n) => ({
221
221
  data: e.rows.map((e) => [...e]),
222
222
  sheet: t[n],
223
223
  columns: e.columns?.map((e) => ({ width: e.width })),
@@ -230,52 +230,52 @@ async function R(e) {
230
230
  features: r ? [r] : void 0
231
231
  }).toBlob();
232
232
  }
233
- async function z(t, n) {
234
- let r = await R(n);
235
- e(t, r);
233
+ async function z(e, t) {
234
+ let n = await R(t);
235
+ l(e, n);
236
236
  }
237
237
  //#endregion
238
238
  //#region src/excel/tableExport.ts
239
- var B = "#,##0", V = "#,##0.0", H = "dd.mm.yyyy", U = "dd.mm", W = "d mmm", ie = "d mmmm", G = "mmm yyyy", K = "mmmm yyyy", q = "hh:mm", J = "hh:mm:ss", Y = `${H} ${q}`, X = `${H} ${J}`;
239
+ var B = "#,##0", V = "#,##0.0", H = "dd.mm.yyyy", U = "dd.mm", ie = "d mmm", W = "d mmmm", G = "mmm yyyy", K = "mmmm yyyy", q = "hh:mm", J = "hh:mm:ss", Y = `${H} ${q}`, X = `${H} ${J}`;
240
240
  function Z(e) {
241
- let t = c(e).plan?.steps.find((e) => e.type === "typedValueFormat");
241
+ let t = s(e).plan?.steps.find((e) => e.type === "typedValueFormat");
242
242
  return t?.type === "typedValueFormat" ? t.config : void 0;
243
243
  }
244
244
  function Q(e) {
245
- return e.clientOnly ? Number : n(e.odataType) ? Date : a(e.odataType) ? Boolean : o(e.odataType) || e.role === "measure" ? Number : String;
245
+ return e.clientOnly ? Number : t(e.odataType) ? Date : i(e.odataType) ? Boolean : a(e.odataType) || e.role === "measure" ? Number : String;
246
246
  }
247
247
  function ae(e) {
248
248
  let t = Z(e.formattersPipeline)?.numberPresetName?.trim();
249
- return t && l(t) ? t : r(e.odataType) ? "integer" : "decimal";
249
+ return t && c(t) ? t : n(e.odataType) ? "integer" : "decimal";
250
250
  }
251
251
  function oe(e) {
252
- let t = l(ae(e));
252
+ let t = c(ae(e));
253
253
  return t ? t.decimals > 0 ? `#,##0.${"0".repeat(t.decimals)}` : B : V;
254
254
  }
255
255
  function se(e) {
256
- return Z(e.formattersPipeline)?.datePresetName?.trim() || (e.odataType === "time" ? s.time : e.odataType === "datetime" || e.odataType === "datetimeOffset" ? s.datetime : s.date);
256
+ return Z(e.formattersPipeline)?.datePresetName?.trim() || (e.odataType === "time" ? o.time : e.odataType === "datetime" || e.odataType === "datetimeOffset" ? o.datetime : o.date);
257
257
  }
258
258
  function $(e) {
259
259
  return e.replace(/H/g, "h").replace(/M/g, "m");
260
260
  }
261
261
  function ce(e) {
262
- if (e === s.odataDatetime || e === s.abapDatetime) return X;
263
- if (e === s.odataDate || e === s.abapDate) return H;
264
- if (e === s.monthShort) return U;
265
- if (e === s.monthMedium) return W;
266
- if (e === s.monthLong) return ie;
267
- if (e === s.monthYearMedium) return G;
268
- if (e === s.monthYearLong) return K;
269
- if (e.startsWith("datetime")) return e === s.datetime || e === s.datetimeShort ? Y : X;
270
- if (e.startsWith("time")) return e === s.time || e === s.timeShort ? q : J;
262
+ if (e === o.odataDatetime || e === o.abapDatetime) return X;
263
+ if (e === o.odataDate || e === o.abapDate) return H;
264
+ if (e === o.monthShort) return U;
265
+ if (e === o.monthMedium) return ie;
266
+ if (e === o.monthLong) return W;
267
+ if (e === o.monthYearMedium) return G;
268
+ if (e === o.monthYearLong) return K;
269
+ if (e.startsWith("datetime")) return e === o.datetime || e === o.datetimeShort ? Y : X;
270
+ if (e.startsWith("time")) return e === o.time || e === o.timeShort ? q : J;
271
271
  if (e.startsWith("date")) return H;
272
272
  }
273
273
  function le(e, t) {
274
274
  return ce(e) || (t?.pattern ? $(t.pattern) : $(e));
275
275
  }
276
- function ue(e) {
277
- let n = se(e);
278
- return le(n, t(n));
276
+ function ue(t) {
277
+ let n = se(t);
278
+ return le(n, e(n));
279
279
  }
280
280
  function de(e, t) {
281
281
  if (t === Number) return oe(e);
@@ -313,6 +313,6 @@ async function me({ fileName: e, sheets: t }) {
313
313
  });
314
314
  }
315
315
  //#endregion
316
- export { _ as buildExcelAutoFilterRef, b as buildExcelSheetData, R as createExcelMatrixWorkbookBlob, fe as createTableExcelColumn, S as downloadExcelFile, z as downloadExcelMatrixWorkbook, x as downloadExcelWorkbook, pe as downloadResolvedExcelTable, me as downloadResolvedExcelWorkbook, ne as resolveExcelCellStyleFromState, v as resolveExcelSheetNames, Q as resolveTableExcelColumnType };
316
+ export { _ as buildExcelAutoFilterRef, b as buildExcelSheetData, R as createExcelMatrixWorkbookBlob, fe as createTableExcelColumn, S as downloadExcelFile, z as downloadExcelMatrixWorkbook, x as downloadExcelWorkbook, pe as downloadResolvedExcelTable, me as downloadResolvedExcelWorkbook, h as resolveExcelCellStyleFromState, y as resolveExcelSheetNames, Q as resolveTableExcelColumnType };
317
317
 
318
318
  //# sourceMappingURL=index.js.map